3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
16 #include "ColorCache.h"
17 #include "FileDialog.h"
18 #include "GuiApplication.h"
19 #include "GuiFontExample.h"
20 #include "GuiFontLoader.h"
21 #include "GuiKeySymbol.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
26 #include "BufferList.h"
29 #include "ConverterCache.h"
30 #include "FontEnums.h"
31 #include "FuncRequest.h"
33 #include "KeySequence.h"
35 #include "LyXAction.h"
37 #include "PanelStack.h"
39 #include "SpellChecker.h"
41 #include "support/debug.h"
42 #include "support/FileName.h"
43 #include "support/filetools.h"
44 #include "support/gettext.h"
45 #include "support/lassert.h"
46 #include "support/lstrings.h"
47 #include "support/Messages.h"
48 #include "support/os.h"
49 #include "support/Package.h"
51 #include "graphics/GraphicsTypes.h"
53 #include "frontends/alert.h"
54 #include "frontends/Application.h"
55 #include "frontends/FontLoader.h"
57 #include <QAbstractItemModel>
59 #include <QColorDialog>
60 #include <QFontDatabase>
61 #include <QHeaderView>
63 #include <QMessageBox>
64 #include <QPixmapCache>
65 #include <QPushButton>
68 #include <QTreeWidget>
69 #include <QTreeWidgetItem>
80 using namespace lyx::support;
81 using namespace lyx::support::os;
86 /////////////////////////////////////////////////////////////////////
90 /////////////////////////////////////////////////////////////////////
92 /** Launch a file dialog and return the chosen file.
93 filename: a suggested filename.
94 title: the title of the dialog.
96 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
98 QString browseFile(QString const & filename,
99 QString const & title,
100 QStringList const & filters,
102 QString const & label1 = QString(),
103 QString const & dir1 = QString(),
104 QString const & label2 = QString(),
105 QString const & dir2 = QString(),
106 QString const & fallback_dir = QString())
108 QString lastPath = ".";
109 if (!filename.isEmpty())
110 lastPath = onlyPath(filename);
111 else if(!fallback_dir.isEmpty())
112 lastPath = fallback_dir;
114 FileDialog dlg(title);
115 dlg.setButton2(label1, dir1);
116 dlg.setButton2(label2, dir2);
118 FileDialog::Result result;
121 result = dlg.save(lastPath, filters, onlyFileName(filename));
123 result = dlg.open(lastPath, filters, onlyFileName(filename));
125 return result.second;
129 /** Wrapper around browseFile which tries to provide a filename
130 * relative to the user or system directory. The dir, name and ext
131 * parameters have the same meaning as in the
132 * support::LibFileSearch function.
134 QString browseLibFile(QString const & dir,
135 QString const & name,
137 QString const & title,
138 QStringList const & filters)
141 QString const label1 = qt_("System files|#S#s");
143 toqstr(addName(package().system_support().absFileName(), fromqstr(dir)));
145 QString const label2 = qt_("User files|#U#u");
147 toqstr(addName(package().user_support().absFileName(), fromqstr(dir)));
149 QString const result = browseFile(toqstr(
150 libFileSearch(dir, name, ext).absFileName()),
151 title, filters, false, dir1, dir2, QString(), QString(), dir1);
153 // remove the extension if it is the default one
155 if (getExtension(result) == ext)
156 noextresult = removeExtension(result);
158 noextresult = result;
160 // remove the directory, if it is the default one
161 QString const file = onlyFileName(noextresult);
162 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
169 /** Launch a file dialog and return the chosen directory.
170 pathname: a suggested pathname.
171 title: the title of the dialog.
172 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
174 QString browseDir(QString const & pathname,
175 QString const & title,
176 QString const & label1 = QString(),
177 QString const & dir1 = QString(),
178 QString const & label2 = QString(),
179 QString const & dir2 = QString())
181 QString lastPath = ".";
182 if (!pathname.isEmpty())
183 lastPath = onlyPath(pathname);
185 FileDialog dlg(title);
186 dlg.setButton1(label1, dir1);
187 dlg.setButton2(label2, dir2);
189 FileDialog::Result const result =
190 dlg.opendir(lastPath, onlyFileName(pathname));
192 return result.second;
196 } // namespace frontend
199 QString browseRelToParent(QString const & filename, QString const & relpath,
200 QString const & title, QStringList const & filters, bool save,
201 QString const & label1, QString const & dir1,
202 QString const & label2, QString const & dir2)
204 QString const fname = makeAbsPath(filename, relpath);
206 QString const outname =
207 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
209 QString const reloutname =
210 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
212 if (reloutname.startsWith("../"))
219 QString browseRelToSub(QString const & filename, QString const & relpath,
220 QString const & title, QStringList const & filters, bool save,
221 QString const & label1, QString const & dir1,
222 QString const & label2, QString const & dir2)
224 QString const fname = makeAbsPath(filename, relpath);
226 QString const outname =
227 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
229 QString const reloutname =
230 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
232 QString testname = reloutname;
233 testname.remove(QRegExp("^(\\.\\./)+"));
235 if (testname.contains("/"))
243 /////////////////////////////////////////////////////////////////////
247 /////////////////////////////////////////////////////////////////////
251 QString const catLookAndFeel = N_("Look & Feel");
252 QString const catEditing = N_("Editing");
253 QString const catLanguage = N_("Language Settings");
254 QString const catOutput = N_("Output");
255 QString const catFiles = N_("File Handling");
257 static void parseFontName(QString const & mangled0,
258 string & name, string & foundry)
260 string mangled = fromqstr(mangled0);
261 size_t const idx = mangled.find('[');
262 if (idx == string::npos || idx == 0) {
266 name = mangled.substr(0, idx - 1),
267 foundry = mangled.substr(idx + 1, mangled.size() - idx - 2);
272 static void setComboxFont(QComboBox * cb, string const & family,
273 string const & foundry)
275 QString fontname = toqstr(family);
276 if (!foundry.empty())
277 fontname += " [" + toqstr(foundry) + ']';
279 for (int i = 0; i != cb->count(); ++i) {
280 if (cb->itemText(i) == fontname) {
281 cb->setCurrentIndex(i);
286 // Try matching without foundry name
288 // We count in reverse in order to prefer the Xft foundry
289 for (int i = cb->count(); --i >= 0;) {
290 string name, foundry;
291 parseFontName(cb->itemText(i), name, foundry);
292 if (compare_ascii_no_case(name, family) == 0) {
293 cb->setCurrentIndex(i);
298 // family alone can contain e.g. "Helvetica [Adobe]"
299 string tmpname, tmpfoundry;
300 parseFontName(toqstr(family), tmpname, tmpfoundry);
302 // We count in reverse in order to prefer the Xft foundry
303 for (int i = cb->count(); --i >= 0; ) {
304 string name, foundry;
305 parseFontName(cb->itemText(i), name, foundry);
306 if (compare_ascii_no_case(name, foundry) == 0) {
307 cb->setCurrentIndex(i);
312 // Bleh, default fonts, and the names couldn't be found. Hack
317 QString const font_family = toqstr(family);
318 if (font_family == guiApp->romanFontName()) {
319 font.setStyleHint(QFont::Serif);
320 font.setFamily(font_family);
321 } else if (font_family == guiApp->sansFontName()) {
322 font.setStyleHint(QFont::SansSerif);
323 font.setFamily(font_family);
324 } else if (font_family == guiApp->typewriterFontName()) {
325 font.setStyleHint(QFont::TypeWriter);
326 font.setFamily(font_family);
328 LYXERR0("FAILED to find the default font: '"
329 << foundry << "', '" << family << '\'');
333 QFontInfo info(font);
334 string default_font_name, dummyfoundry;
335 parseFontName(info.family(), default_font_name, dummyfoundry);
336 LYXERR0("Apparent font is " << default_font_name);
338 for (int i = 0; i < cb->count(); ++i) {
339 LYXERR0("Looking at " << cb->itemText(i));
340 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
341 default_font_name) == 0) {
342 cb->setCurrentIndex(i);
347 LYXERR0("FAILED to find the font: '"
348 << foundry << "', '" << family << '\'');
352 /////////////////////////////////////////////////////////////////////
356 /////////////////////////////////////////////////////////////////////
358 class StrftimeValidator : public QValidator
361 StrftimeValidator(QWidget *);
362 QValidator::State validate(QString & input, int & pos) const;
366 StrftimeValidator::StrftimeValidator(QWidget * parent)
372 QValidator::State StrftimeValidator::validate(QString & input, int & /*pos*/) const
374 if (is_valid_strftime(fromqstr(input)))
375 return QValidator::Acceptable;
377 return QValidator::Intermediate;
381 /////////////////////////////////////////////////////////////////////
385 /////////////////////////////////////////////////////////////////////
387 PrefOutput::PrefOutput(GuiPreferences * form)
388 : PrefModule(catOutput, N_("General"), form)
392 DateED->setValidator(new StrftimeValidator(DateED));
393 dviCB->setValidator(new NoNewLineValidator(dviCB));
394 pdfCB->setValidator(new NoNewLineValidator(pdfCB));
396 connect(DateED, SIGNAL(textChanged(QString)),
397 this, SIGNAL(changed()));
398 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
399 this, SIGNAL(changed()));
400 connect(overwriteCO, SIGNAL(activated(int)),
401 this, SIGNAL(changed()));
402 connect(dviCB, SIGNAL(editTextChanged(QString)),
403 this, SIGNAL(changed()));
404 connect(pdfCB, SIGNAL(editTextChanged(QString)),
405 this, SIGNAL(changed()));
406 connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
407 this, SIGNAL(changed()));
408 connect(printerLandscapeED, SIGNAL(textChanged(QString)),
409 this, SIGNAL(changed()));
410 connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
411 this, SIGNAL(changed()));
413 printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
414 printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
415 printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
418 dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
419 dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
420 dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
421 dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
423 pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
424 pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
425 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
426 pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
427 pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
428 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
429 pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
433 void PrefOutput::on_DateED_textChanged(const QString &)
435 QString t = DateED->text();
437 bool valid = DateED->validator()->validate(t, p)
438 == QValidator::Acceptable;
439 setValid(DateLA, valid);
443 void PrefOutput::applyRC(LyXRC & rc) const
445 rc.date_insert_format = fromqstr(DateED->text());
446 rc.plaintext_linelen = plaintextLinelengthSB->value();
447 rc.forward_search_dvi = fromqstr(dviCB->currentText());
448 rc.forward_search_pdf = fromqstr(pdfCB->currentText());
450 switch (overwriteCO->currentIndex()) {
452 rc.export_overwrite = NO_FILES;
455 rc.export_overwrite = MAIN_FILE;
458 rc.export_overwrite = ALL_FILES;
462 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
463 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
464 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
468 void PrefOutput::updateRC(LyXRC const & rc)
470 DateED->setText(toqstr(rc.date_insert_format));
471 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
472 dviCB->setEditText(toqstr(rc.forward_search_dvi));
473 pdfCB->setEditText(toqstr(rc.forward_search_pdf));
475 switch (rc.export_overwrite) {
477 overwriteCO->setCurrentIndex(0);
480 overwriteCO->setCurrentIndex(1);
483 overwriteCO->setCurrentIndex(2);
487 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
488 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
489 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
493 /////////////////////////////////////////////////////////////////////
497 /////////////////////////////////////////////////////////////////////
499 PrefInput::PrefInput(GuiPreferences * form)
500 : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
504 connect(keymapCB, SIGNAL(clicked()),
505 this, SIGNAL(changed()));
506 connect(firstKeymapED, SIGNAL(textChanged(QString)),
507 this, SIGNAL(changed()));
508 connect(secondKeymapED, SIGNAL(textChanged(QString)),
509 this, SIGNAL(changed()));
510 connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)),
511 this, SIGNAL(changed()));
512 connect(scrollzoomEnableCB, SIGNAL(clicked()),
513 this, SIGNAL(changed()));
514 connect(scrollzoomValueCO, SIGNAL(activated(int)),
515 this, SIGNAL(changed()));
516 connect(dontswapCB, SIGNAL(toggled(bool)),
517 this, SIGNAL(changed()));
518 connect(mmPasteCB, SIGNAL(toggled(bool)),
519 this, SIGNAL(changed()));
521 // reveal checkbox for switching Ctrl and Meta on Mac:
524 #if QT_VERSION > 0x040600
528 dontswapCB->setVisible(swapcb);
532 void PrefInput::applyRC(LyXRC & rc) const
534 // FIXME: can derive CB from the two EDs
535 rc.use_kbmap = keymapCB->isChecked();
536 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
537 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
538 rc.mouse_wheel_speed = mouseWheelSpeedSB->value();
539 if (scrollzoomEnableCB->isChecked()) {
540 switch (scrollzoomValueCO->currentIndex()) {
542 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_CTRL;
545 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_SHIFT;
548 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_ALT;
552 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
554 rc.mac_dontswap_ctrl_meta = dontswapCB->isChecked();
555 rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
559 void PrefInput::updateRC(LyXRC const & rc)
561 // FIXME: can derive CB from the two EDs
562 keymapCB->setChecked(rc.use_kbmap);
563 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
564 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
565 mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed);
566 switch (rc.scroll_wheel_zoom) {
567 case LyXRC::SCROLL_WHEEL_ZOOM_OFF:
568 scrollzoomEnableCB->setChecked(false);
570 case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
571 scrollzoomEnableCB->setChecked(true);
572 scrollzoomValueCO->setCurrentIndex(0);
574 case LyXRC::SCROLL_WHEEL_ZOOM_SHIFT:
575 scrollzoomEnableCB->setChecked(true);
576 scrollzoomValueCO->setCurrentIndex(1);
578 case LyXRC::SCROLL_WHEEL_ZOOM_ALT:
579 scrollzoomEnableCB->setChecked(true);
580 scrollzoomValueCO->setCurrentIndex(2);
583 dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
584 mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
588 QString PrefInput::testKeymap(QString const & keymap)
590 return form_->browsekbmap(internalPath(keymap));
594 void PrefInput::on_firstKeymapPB_clicked(bool)
596 QString const file = testKeymap(firstKeymapED->text());
598 firstKeymapED->setText(file);
602 void PrefInput::on_secondKeymapPB_clicked(bool)
604 QString const file = testKeymap(secondKeymapED->text());
606 secondKeymapED->setText(file);
610 void PrefInput::on_keymapCB_toggled(bool keymap)
612 firstKeymapLA->setEnabled(keymap);
613 secondKeymapLA->setEnabled(keymap);
614 firstKeymapED->setEnabled(keymap);
615 secondKeymapED->setEnabled(keymap);
616 firstKeymapPB->setEnabled(keymap);
617 secondKeymapPB->setEnabled(keymap);
621 void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
623 scrollzoomValueCO->setEnabled(enabled);
627 /////////////////////////////////////////////////////////////////////
631 /////////////////////////////////////////////////////////////////////
633 PrefCompletion::PrefCompletion(GuiPreferences * form)
634 : PrefModule(catEditing, N_("Input Completion"), form)
638 connect(inlineDelaySB, SIGNAL(valueChanged(double)),
639 this, SIGNAL(changed()));
640 connect(inlineMathCB, SIGNAL(clicked()),
641 this, SIGNAL(changed()));
642 connect(inlineTextCB, SIGNAL(clicked()),
643 this, SIGNAL(changed()));
644 connect(inlineDotsCB, SIGNAL(clicked()),
645 this, SIGNAL(changed()));
646 connect(popupDelaySB, SIGNAL(valueChanged(double)),
647 this, SIGNAL(changed()));
648 connect(popupMathCB, SIGNAL(clicked()),
649 this, SIGNAL(changed()));
650 connect(autocorrectionCB, SIGNAL(clicked()),
651 this, SIGNAL(changed()));
652 connect(popupTextCB, SIGNAL(clicked()),
653 this, SIGNAL(changed()));
654 connect(popupAfterCompleteCB, SIGNAL(clicked()),
655 this, SIGNAL(changed()));
656 connect(cursorTextCB, SIGNAL(clicked()),
657 this, SIGNAL(changed()));
658 connect(minlengthSB, SIGNAL(valueChanged(int)),
659 this, SIGNAL(changed()));
663 void PrefCompletion::on_inlineTextCB_clicked()
669 void PrefCompletion::on_popupTextCB_clicked()
675 void PrefCompletion::enableCB()
677 cursorTextCB->setEnabled(
678 popupTextCB->isChecked() || inlineTextCB->isChecked());
682 void PrefCompletion::applyRC(LyXRC & rc) const
684 rc.completion_inline_delay = inlineDelaySB->value();
685 rc.completion_inline_math = inlineMathCB->isChecked();
686 rc.completion_inline_text = inlineTextCB->isChecked();
687 rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1;
688 rc.completion_popup_delay = popupDelaySB->value();
689 rc.completion_popup_math = popupMathCB->isChecked();
690 rc.autocorrection_math = autocorrectionCB->isChecked();
691 rc.completion_popup_text = popupTextCB->isChecked();
692 rc.completion_cursor_text = cursorTextCB->isChecked();
693 rc.completion_popup_after_complete =
694 popupAfterCompleteCB->isChecked();
695 rc.completion_minlength = minlengthSB->value();
699 void PrefCompletion::updateRC(LyXRC const & rc)
701 inlineDelaySB->setValue(rc.completion_inline_delay);
702 inlineMathCB->setChecked(rc.completion_inline_math);
703 inlineTextCB->setChecked(rc.completion_inline_text);
704 inlineDotsCB->setChecked(rc.completion_inline_dots != -1);
705 popupDelaySB->setValue(rc.completion_popup_delay);
706 popupMathCB->setChecked(rc.completion_popup_math);
707 autocorrectionCB->setChecked(rc.autocorrection_math);
708 popupTextCB->setChecked(rc.completion_popup_text);
709 cursorTextCB->setChecked(rc.completion_cursor_text);
710 popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
712 minlengthSB->setValue(rc.completion_minlength);
717 /////////////////////////////////////////////////////////////////////
721 /////////////////////////////////////////////////////////////////////
723 PrefLatex::PrefLatex(GuiPreferences * form)
724 : PrefModule(catOutput, N_("LaTeX"), form)
728 latexEncodingED->setValidator(new NoNewLineValidator(latexEncodingED));
729 latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
730 latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
731 latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
732 latexIndexED->setValidator(new NoNewLineValidator(latexIndexED));
733 latexJIndexED->setValidator(new NoNewLineValidator(latexJIndexED));
734 latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
735 latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
737 connect(latexEncodingCB, SIGNAL(clicked()),
738 this, SIGNAL(changed()));
739 connect(latexEncodingED, SIGNAL(textChanged(QString)),
740 this, SIGNAL(changed()));
741 connect(latexChecktexED, SIGNAL(textChanged(QString)),
742 this, SIGNAL(changed()));
743 connect(latexBibtexCO, SIGNAL(activated(int)),
744 this, SIGNAL(changed()));
745 connect(latexBibtexED, SIGNAL(textChanged(QString)),
746 this, SIGNAL(changed()));
747 connect(latexJBibtexCO, SIGNAL(activated(int)),
748 this, SIGNAL(changed()));
749 connect(latexJBibtexED, SIGNAL(textChanged(QString)),
750 this, SIGNAL(changed()));
751 connect(latexIndexCO, SIGNAL(activated(int)),
752 this, SIGNAL(changed()));
753 connect(latexIndexED, SIGNAL(textChanged(QString)),
754 this, SIGNAL(changed()));
755 connect(latexJIndexED, SIGNAL(textChanged(QString)),
756 this, SIGNAL(changed()));
757 connect(latexAutoresetCB, SIGNAL(clicked()),
758 this, SIGNAL(changed()));
759 connect(latexDviPaperED, SIGNAL(textChanged(QString)),
760 this, SIGNAL(changed()));
761 connect(latexNomenclED, SIGNAL(textChanged(QString)),
762 this, SIGNAL(changed()));
764 #if defined(__CYGWIN__) || defined(_WIN32)
765 pathCB->setVisible(true);
766 connect(pathCB, SIGNAL(clicked()),
767 this, SIGNAL(changed()));
769 pathCB->setVisible(false);
774 void PrefLatex::on_latexEncodingCB_stateChanged(int state)
776 latexEncodingED->setEnabled(state == Qt::Checked);
780 void PrefLatex::on_latexBibtexCO_activated(int n)
782 QString const bibtex = latexBibtexCO->itemData(n).toString();
783 if (bibtex.isEmpty()) {
784 latexBibtexED->clear();
785 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
788 for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
789 it != bibtex_alternatives.end(); ++it) {
790 QString const bib = toqstr(*it);
791 int ind = bib.indexOf(" ");
792 QString sel_command = bib.left(ind);
793 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
794 if (bibtex == sel_command) {
796 latexBibtexED->clear();
798 latexBibtexED->setText(sel_options.trimmed());
801 latexBibtexOptionsLA->setText(qt_("&Options:"));
805 void PrefLatex::on_latexJBibtexCO_activated(int n)
807 QString const jbibtex = latexJBibtexCO->itemData(n).toString();
808 if (jbibtex.isEmpty()) {
809 latexJBibtexED->clear();
810 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
813 for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
814 it != jbibtex_alternatives.end(); ++it) {
815 QString const bib = toqstr(*it);
816 int ind = bib.indexOf(" ");
817 QString sel_command = bib.left(ind);
818 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
819 if (jbibtex == sel_command) {
821 latexJBibtexED->clear();
823 latexJBibtexED->setText(sel_options.trimmed());
826 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
830 void PrefLatex::on_latexIndexCO_activated(int n)
832 QString const index = latexIndexCO->itemData(n).toString();
833 if (index.isEmpty()) {
834 latexIndexED->clear();
835 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
838 for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin();
839 it != index_alternatives.end(); ++it) {
840 QString const idx = toqstr(*it);
841 int ind = idx.indexOf(" ");
842 QString sel_command = idx.left(ind);
843 QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
844 if (index == sel_command) {
846 latexIndexED->clear();
848 latexIndexED->setText(sel_options.trimmed());
851 latexIndexOptionsLA->setText(qt_("Op&tions:"));
855 void PrefLatex::applyRC(LyXRC & rc) const
857 // If bibtex is not empty, bibopt contains the options, otherwise
858 // it is a customized bibtex command with options.
859 QString const bibtex = latexBibtexCO->itemData(
860 latexBibtexCO->currentIndex()).toString();
861 QString const bibopt = latexBibtexED->text();
862 if (bibtex.isEmpty())
863 rc.bibtex_command = fromqstr(bibopt);
864 else if (bibopt.isEmpty())
865 rc.bibtex_command = fromqstr(bibtex);
867 rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
869 // If jbibtex is not empty, jbibopt contains the options, otherwise
870 // it is a customized bibtex command with options.
871 QString const jbibtex = latexJBibtexCO->itemData(
872 latexJBibtexCO->currentIndex()).toString();
873 QString const jbibopt = latexJBibtexED->text();
874 if (jbibtex.isEmpty())
875 rc.jbibtex_command = fromqstr(jbibopt);
876 else if (jbibopt.isEmpty())
877 rc.jbibtex_command = fromqstr(jbibtex);
879 rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
881 // If index is not empty, idxopt contains the options, otherwise
882 // it is a customized index command with options.
883 QString const index = latexIndexCO->itemData(
884 latexIndexCO->currentIndex()).toString();
885 QString const idxopt = latexIndexED->text();
887 rc.index_command = fromqstr(idxopt);
888 else if (idxopt.isEmpty())
889 rc.index_command = fromqstr(index);
891 rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
893 if (latexEncodingCB->isChecked())
894 rc.fontenc = fromqstr(latexEncodingED->text());
896 rc.fontenc = "default";
897 rc.chktex_command = fromqstr(latexChecktexED->text());
898 rc.jindex_command = fromqstr(latexJIndexED->text());
899 rc.nomencl_command = fromqstr(latexNomenclED->text());
900 rc.auto_reset_options = latexAutoresetCB->isChecked();
901 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
902 #if defined(__CYGWIN__) || defined(_WIN32)
903 rc.windows_style_tex_paths = pathCB->isChecked();
908 void PrefLatex::updateRC(LyXRC const & rc)
910 latexBibtexCO->clear();
912 latexBibtexCO->addItem(qt_("Automatic"), "automatic");
913 latexBibtexCO->addItem(qt_("Custom"), QString());
914 for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
915 it != rc.bibtex_alternatives.end(); ++it) {
916 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
917 latexBibtexCO->addItem(command, command);
920 bibtex_alternatives = rc.bibtex_alternatives;
922 QString const bib = toqstr(rc.bibtex_command);
923 int ind = bib.indexOf(" ");
924 QString sel_command = bib.left(ind);
925 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
927 int pos = latexBibtexCO->findData(sel_command);
929 latexBibtexCO->setCurrentIndex(pos);
930 latexBibtexED->setText(sel_options.trimmed());
931 latexBibtexOptionsLA->setText(qt_("&Options:"));
933 latexBibtexED->setText(toqstr(rc.bibtex_command));
934 latexBibtexCO->setCurrentIndex(0);
935 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
938 latexJBibtexCO->clear();
940 latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
941 latexJBibtexCO->addItem(qt_("Custom"), QString());
942 for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
943 it != rc.jbibtex_alternatives.end(); ++it) {
944 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
945 latexJBibtexCO->addItem(command, command);
948 jbibtex_alternatives = rc.jbibtex_alternatives;
950 QString const jbib = toqstr(rc.jbibtex_command);
951 ind = jbib.indexOf(" ");
952 sel_command = jbib.left(ind);
953 sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
955 pos = latexJBibtexCO->findData(sel_command);
957 latexJBibtexCO->setCurrentIndex(pos);
958 latexJBibtexED->setText(sel_options.trimmed());
959 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
961 latexJBibtexED->setText(toqstr(rc.bibtex_command));
962 latexJBibtexCO->setCurrentIndex(0);
963 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
966 latexIndexCO->clear();
968 latexIndexCO->addItem(qt_("Custom"), QString());
969 for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin();
970 it != rc.index_alternatives.end(); ++it) {
971 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
972 latexIndexCO->addItem(command, command);
975 index_alternatives = rc.index_alternatives;
977 QString const idx = toqstr(rc.index_command);
978 ind = idx.indexOf(" ");
979 sel_command = idx.left(ind);
980 sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
982 pos = latexIndexCO->findData(sel_command);
984 latexIndexCO->setCurrentIndex(pos);
985 latexIndexED->setText(sel_options.trimmed());
986 latexIndexOptionsLA->setText(qt_("Op&tions:"));
988 latexIndexED->setText(toqstr(rc.index_command));
989 latexIndexCO->setCurrentIndex(0);
990 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
993 if (rc.fontenc == "default") {
994 latexEncodingCB->setChecked(false);
995 latexEncodingED->setEnabled(false);
997 latexEncodingCB->setChecked(true);
998 latexEncodingED->setEnabled(true);
999 latexEncodingED->setText(toqstr(rc.fontenc));
1001 latexChecktexED->setText(toqstr(rc.chktex_command));
1002 latexJIndexED->setText(toqstr(rc.jindex_command));
1003 latexNomenclED->setText(toqstr(rc.nomencl_command));
1004 latexAutoresetCB->setChecked(rc.auto_reset_options);
1005 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
1006 #if defined(__CYGWIN__) || defined(_WIN32)
1007 pathCB->setChecked(rc.windows_style_tex_paths);
1012 /////////////////////////////////////////////////////////////////////
1016 /////////////////////////////////////////////////////////////////////
1018 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
1019 : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
1023 connect(screenRomanCO, SIGNAL(activated(QString)),
1024 this, SLOT(selectRoman(QString)));
1025 connect(screenSansCO, SIGNAL(activated(QString)),
1026 this, SLOT(selectSans(QString)));
1027 connect(screenTypewriterCO, SIGNAL(activated(QString)),
1028 this, SLOT(selectTypewriter(QString)));
1030 QFontDatabase fontdb;
1031 QStringList families(fontdb.families());
1032 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1033 screenRomanCO->addItem(*it);
1034 screenSansCO->addItem(*it);
1035 screenTypewriterCO->addItem(*it);
1037 connect(screenRomanCO, SIGNAL(activated(QString)),
1038 this, SIGNAL(changed()));
1039 connect(screenSansCO, SIGNAL(activated(QString)),
1040 this, SIGNAL(changed()));
1041 connect(screenTypewriterCO, SIGNAL(activated(QString)),
1042 this, SIGNAL(changed()));
1043 connect(screenZoomSB, SIGNAL(valueChanged(int)),
1044 this, SIGNAL(changed()));
1045 connect(screenTinyED, SIGNAL(textChanged(QString)),
1046 this, SIGNAL(changed()));
1047 connect(screenSmallestED, SIGNAL(textChanged(QString)),
1048 this, SIGNAL(changed()));
1049 connect(screenSmallerED, SIGNAL(textChanged(QString)),
1050 this, SIGNAL(changed()));
1051 connect(screenSmallED, SIGNAL(textChanged(QString)),
1052 this, SIGNAL(changed()));
1053 connect(screenNormalED, SIGNAL(textChanged(QString)),
1054 this, SIGNAL(changed()));
1055 connect(screenLargeED, SIGNAL(textChanged(QString)),
1056 this, SIGNAL(changed()));
1057 connect(screenLargerED, SIGNAL(textChanged(QString)),
1058 this, SIGNAL(changed()));
1059 connect(screenLargestED, SIGNAL(textChanged(QString)),
1060 this, SIGNAL(changed()));
1061 connect(screenHugeED, SIGNAL(textChanged(QString)),
1062 this, SIGNAL(changed()));
1063 connect(screenHugerED, SIGNAL(textChanged(QString)),
1064 this, SIGNAL(changed()));
1065 connect(pixmapCacheCB, SIGNAL(toggled(bool)),
1066 this, SIGNAL(changed()));
1068 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
1069 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
1070 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
1071 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
1072 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
1073 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
1074 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
1075 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
1076 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
1077 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
1081 void PrefScreenFonts::applyRC(LyXRC & rc) const
1083 LyXRC const oldrc = rc;
1085 parseFontName(screenRomanCO->currentText(),
1086 rc.roman_font_name, rc.roman_font_foundry);
1087 parseFontName(screenSansCO->currentText(),
1088 rc.sans_font_name, rc.sans_font_foundry);
1089 parseFontName(screenTypewriterCO->currentText(),
1090 rc.typewriter_font_name, rc.typewriter_font_foundry);
1092 rc.defaultZoom = screenZoomSB->value();
1093 rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED);
1094 rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED);
1095 rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED);
1096 rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED);
1097 rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED);
1098 rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED);
1099 rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED);
1100 rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED);
1101 rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED);
1102 rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED);
1103 rc.use_pixmap_cache = pixmapCacheCB->isChecked();
1105 if (rc.font_sizes != oldrc.font_sizes
1106 || rc.roman_font_name != oldrc.roman_font_name
1107 || rc.sans_font_name != oldrc.sans_font_name
1108 || rc.typewriter_font_name != oldrc.typewriter_font_name
1109 || rc.defaultZoom != oldrc.defaultZoom) {
1110 // The global QPixmapCache is used in GuiPainter to cache text
1111 // painting so we must reset it in case any of the above
1112 // parameter is changed.
1113 QPixmapCache::clear();
1114 guiApp->fontLoader().update();
1115 form_->updateScreenFonts();
1120 void PrefScreenFonts::updateRC(LyXRC const & rc)
1122 setComboxFont(screenRomanCO, rc.roman_font_name,
1123 rc.roman_font_foundry);
1124 setComboxFont(screenSansCO, rc.sans_font_name,
1125 rc.sans_font_foundry);
1126 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
1127 rc.typewriter_font_foundry);
1129 selectRoman(screenRomanCO->currentText());
1130 selectSans(screenSansCO->currentText());
1131 selectTypewriter(screenTypewriterCO->currentText());
1133 screenZoomSB->setValue(rc.defaultZoom);
1134 updateScreenFontSizes(rc);
1136 pixmapCacheCB->setChecked(rc.use_pixmap_cache);
1137 #if defined(Q_WS_X11) || defined(QPA_XCB)
1138 pixmapCacheCB->setEnabled(false);
1144 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
1146 doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]);
1147 doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]);
1148 doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]);
1149 doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]);
1150 doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]);
1151 doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]);
1152 doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]);
1153 doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]);
1154 doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]);
1155 doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]);
1159 void PrefScreenFonts::selectRoman(const QString & name)
1161 screenRomanFE->set(QFont(name), name);
1165 void PrefScreenFonts::selectSans(const QString & name)
1167 screenSansFE->set(QFont(name), name);
1171 void PrefScreenFonts::selectTypewriter(const QString & name)
1173 screenTypewriterFE->set(QFont(name), name);
1177 /////////////////////////////////////////////////////////////////////
1181 /////////////////////////////////////////////////////////////////////
1184 PrefColors::PrefColors(GuiPreferences * form)
1185 : PrefModule(catLookAndFeel, N_("Colors"), form)
1189 // FIXME: all of this initialization should be put into the controller.
1190 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
1191 // for some discussion of why that is not trivial.
1192 QPixmap icon(32, 32);
1193 for (int i = 0; i < Color_ignore; ++i) {
1194 ColorCode lc = static_cast<ColorCode>(i);
1195 if (lc == Color_none
1196 || lc == Color_black
1197 || lc == Color_white
1199 || lc == Color_brown
1201 || lc == Color_darkgray
1203 || lc == Color_green
1204 || lc == Color_lightgray
1206 || lc == Color_magenta
1207 || lc == Color_olive
1208 || lc == Color_orange
1210 || lc == Color_purple
1213 || lc == Color_violet
1214 || lc == Color_yellow
1215 || lc == Color_inherit
1216 || lc == Color_ignore)
1218 lcolors_.push_back(lc);
1220 qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
1221 vector<ColorCode>::const_iterator cit = lcolors_.begin();
1222 vector<ColorCode>::const_iterator const end = lcolors_.end();
1223 for (; cit != end; ++cit) {
1224 (void) new QListWidgetItem(QIcon(icon),
1225 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
1227 curcolors_.resize(lcolors_.size());
1228 newcolors_.resize(lcolors_.size());
1229 // End initialization
1231 connect(colorChangePB, SIGNAL(clicked()),
1232 this, SLOT(changeColor()));
1233 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
1234 this, SLOT(changeLyxObjectsSelection()));
1235 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
1236 this, SLOT(changeColor()));
1237 connect(syscolorsCB, SIGNAL(toggled(bool)),
1238 this, SIGNAL(changed()));
1239 connect(syscolorsCB, SIGNAL(toggled(bool)),
1240 this, SLOT(changeSysColor()));
1244 void PrefColors::applyRC(LyXRC & rc) const
1248 for (unsigned int i = 0; i < lcolors_.size(); ++i)
1249 if (curcolors_[i] != newcolors_[i])
1250 form_->setColor(lcolors_[i], newcolors_[i]);
1251 rc.use_system_colors = syscolorsCB->isChecked();
1253 if (oldrc.use_system_colors != rc.use_system_colors)
1254 guiApp->colorCache().clear();
1258 void PrefColors::updateRC(LyXRC const & rc)
1260 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
1261 QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
1262 QPixmap coloritem(32, 32);
1263 coloritem.fill(color);
1264 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
1265 newcolors_[i] = curcolors_[i] = color.name();
1267 syscolorsCB->setChecked(rc.use_system_colors);
1268 changeLyxObjectsSelection();
1272 void PrefColors::changeColor()
1274 int const row = lyxObjectsLW->currentRow();
1280 QString const color = newcolors_[row];
1281 QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
1283 if (c.isValid() && c.name() != color) {
1284 newcolors_[row] = c.name();
1285 QPixmap coloritem(32, 32);
1287 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
1293 void PrefColors::changeSysColor()
1295 for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
1296 // skip colors that are taken from system palette
1297 bool const disable = syscolorsCB->isChecked()
1298 && guiApp->colorCache().isSystem(lcolors_[row]);
1300 QListWidgetItem * const item = lyxObjectsLW->item(row);
1301 Qt::ItemFlags const flags = item->flags();
1304 item->setFlags(flags & ~Qt::ItemIsEnabled);
1306 item->setFlags(flags | Qt::ItemIsEnabled);
1310 void PrefColors::changeLyxObjectsSelection()
1312 colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
1316 /////////////////////////////////////////////////////////////////////
1320 /////////////////////////////////////////////////////////////////////
1322 PrefDisplay::PrefDisplay(GuiPreferences * form)
1323 : PrefModule(catLookAndFeel, N_("Display"), form)
1326 connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1327 connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
1328 connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed()));
1329 connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1333 void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
1335 previewSizeSB->setEnabled(index != 0);
1339 void PrefDisplay::applyRC(LyXRC & rc) const
1341 switch (instantPreviewCO->currentIndex()) {
1343 rc.preview = LyXRC::PREVIEW_OFF;
1346 if (rc.preview != LyXRC::PREVIEW_NO_MATH) {
1347 rc.preview = LyXRC::PREVIEW_NO_MATH;
1348 form_->updatePreviews();
1352 if (rc.preview != LyXRC::PREVIEW_ON) {
1353 rc.preview = LyXRC::PREVIEW_ON;
1354 form_->updatePreviews();
1359 rc.display_graphics = displayGraphicsCB->isChecked();
1360 rc.preview_scale_factor = previewSizeSB->value();
1361 rc.paragraph_markers = paragraphMarkerCB->isChecked();
1363 // FIXME!! The graphics cache no longer has a changeDisplay method.
1365 if (old_value != rc.display_graphics) {
1366 graphics::GCache & gc = graphics::GCache::get();
1373 void PrefDisplay::updateRC(LyXRC const & rc)
1375 switch (rc.preview) {
1376 case LyXRC::PREVIEW_OFF:
1377 instantPreviewCO->setCurrentIndex(0);
1379 case LyXRC::PREVIEW_NO_MATH :
1380 instantPreviewCO->setCurrentIndex(1);
1382 case LyXRC::PREVIEW_ON :
1383 instantPreviewCO->setCurrentIndex(2);
1387 displayGraphicsCB->setChecked(rc.display_graphics);
1388 previewSizeSB->setValue(rc.preview_scale_factor);
1389 paragraphMarkerCB->setChecked(rc.paragraph_markers);
1390 previewSizeSB->setEnabled(
1392 && rc.preview != LyXRC::PREVIEW_OFF);
1396 /////////////////////////////////////////////////////////////////////
1400 /////////////////////////////////////////////////////////////////////
1402 PrefPaths::PrefPaths(GuiPreferences * form)
1403 : PrefModule(QString(), N_("Paths"), form)
1407 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir()));
1408 connect(workingDirED, SIGNAL(textChanged(QString)),
1409 this, SIGNAL(changed()));
1411 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir()));
1412 connect(templateDirED, SIGNAL(textChanged(QString)),
1413 this, SIGNAL(changed()));
1415 connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir()));
1416 connect(exampleDirED, SIGNAL(textChanged(QString)),
1417 this, SIGNAL(changed()));
1419 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir()));
1420 connect(backupDirED, SIGNAL(textChanged(QString)),
1421 this, SIGNAL(changed()));
1423 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe()));
1424 connect(lyxserverDirED, SIGNAL(textChanged(QString)),
1425 this, SIGNAL(changed()));
1427 connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir()));
1428 connect(thesaurusDirED, SIGNAL(textChanged(QString)),
1429 this, SIGNAL(changed()));
1431 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir()));
1432 connect(tempDirED, SIGNAL(textChanged(QString)),
1433 this, SIGNAL(changed()));
1435 #if defined(USE_HUNSPELL)
1436 connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir()));
1437 connect(hunspellDirED, SIGNAL(textChanged(QString)),
1438 this, SIGNAL(changed()));
1440 hunspellDirPB->setEnabled(false);
1441 hunspellDirED->setEnabled(false);
1444 connect(pathPrefixED, SIGNAL(textChanged(QString)),
1445 this, SIGNAL(changed()));
1447 connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
1448 this, SIGNAL(changed()));
1450 pathPrefixED->setValidator(new NoNewLineValidator(pathPrefixED));
1451 texinputsPrefixED->setValidator(new NoNewLineValidator(texinputsPrefixED));
1455 void PrefPaths::applyRC(LyXRC & rc) const
1457 rc.document_path = internal_path(fromqstr(workingDirED->text()));
1458 rc.example_path = internal_path(fromqstr(exampleDirED->text()));
1459 rc.template_path = internal_path(fromqstr(templateDirED->text()));
1460 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
1461 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
1462 rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
1463 rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
1464 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
1465 rc.texinputs_prefix = internal_path_list(fromqstr(texinputsPrefixED->text()));
1466 // FIXME: should be a checkbox only
1467 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
1471 void PrefPaths::updateRC(LyXRC const & rc)
1473 workingDirED->setText(toqstr(external_path(rc.document_path)));
1474 exampleDirED->setText(toqstr(external_path(rc.example_path)));
1475 templateDirED->setText(toqstr(external_path(rc.template_path)));
1476 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
1477 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
1478 thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
1479 hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
1480 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
1481 texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
1482 // FIXME: should be a checkbox only
1483 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
1487 void PrefPaths::selectExampledir()
1489 QString file = browseDir(internalPath(exampleDirED->text()),
1490 qt_("Select directory for example files"));
1491 if (!file.isEmpty())
1492 exampleDirED->setText(file);
1496 void PrefPaths::selectTemplatedir()
1498 QString file = browseDir(internalPath(templateDirED->text()),
1499 qt_("Select a document templates directory"));
1500 if (!file.isEmpty())
1501 templateDirED->setText(file);
1505 void PrefPaths::selectTempdir()
1507 QString file = browseDir(internalPath(tempDirED->text()),
1508 qt_("Select a temporary directory"));
1509 if (!file.isEmpty())
1510 tempDirED->setText(file);
1514 void PrefPaths::selectBackupdir()
1516 QString file = browseDir(internalPath(backupDirED->text()),
1517 qt_("Select a backups directory"));
1518 if (!file.isEmpty())
1519 backupDirED->setText(file);
1523 void PrefPaths::selectWorkingdir()
1525 QString file = browseDir(internalPath(workingDirED->text()),
1526 qt_("Select a document directory"));
1527 if (!file.isEmpty())
1528 workingDirED->setText(file);
1532 void PrefPaths::selectThesaurusdir()
1534 QString file = browseDir(internalPath(thesaurusDirED->text()),
1535 qt_("Set the path to the thesaurus dictionaries"));
1536 if (!file.isEmpty())
1537 thesaurusDirED->setText(file);
1541 void PrefPaths::selectHunspelldir()
1543 QString file = browseDir(internalPath(hunspellDirED->text()),
1544 qt_("Set the path to the Hunspell dictionaries"));
1545 if (!file.isEmpty())
1546 hunspellDirED->setText(file);
1550 void PrefPaths::selectLyxPipe()
1552 QString file = form_->browse(internalPath(lyxserverDirED->text()),
1553 qt_("Give a filename for the LyX server pipe"));
1554 if (!file.isEmpty())
1555 lyxserverDirED->setText(file);
1559 /////////////////////////////////////////////////////////////////////
1563 /////////////////////////////////////////////////////////////////////
1565 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
1566 : PrefModule(catLanguage, N_("Spellchecker"), form)
1570 // FIXME: this check should test the target platform (darwin)
1571 #if defined(USE_MACOSX_PACKAGING)
1572 spellcheckerCB->addItem(qt_("Native"), QString("native"));
1573 #define CONNECT_APPLESPELL
1575 #undef CONNECT_APPLESPELL
1577 #if defined(USE_ASPELL)
1578 spellcheckerCB->addItem(qt_("Aspell"), QString("aspell"));
1580 #if defined(USE_ENCHANT)
1581 spellcheckerCB->addItem(qt_("Enchant"), QString("enchant"));
1583 #if defined(USE_HUNSPELL)
1584 spellcheckerCB->addItem(qt_("Hunspell"), QString("hunspell"));
1587 #if defined(CONNECT_APPLESPELL) || defined(USE_ASPELL) || defined(USE_ENCHANT) || defined(USE_HUNSPELL)
1588 connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)),
1589 this, SIGNAL(changed()));
1590 connect(altLanguageED, SIGNAL(textChanged(QString)),
1591 this, SIGNAL(changed()));
1592 connect(escapeCharactersED, SIGNAL(textChanged(QString)),
1593 this, SIGNAL(changed()));
1594 connect(compoundWordCB, SIGNAL(clicked()),
1595 this, SIGNAL(changed()));
1596 connect(spellcheckContinuouslyCB, SIGNAL(clicked()),
1597 this, SIGNAL(changed()));
1598 connect(spellcheckNotesCB, SIGNAL(clicked()),
1599 this, SIGNAL(changed()));
1601 altLanguageED->setValidator(new NoNewLineValidator(altLanguageED));
1602 escapeCharactersED->setValidator(new NoNewLineValidator(escapeCharactersED));
1604 spellcheckerCB->setEnabled(false);
1605 altLanguageED->setEnabled(false);
1606 escapeCharactersED->setEnabled(false);
1607 compoundWordCB->setEnabled(false);
1608 spellcheckContinuouslyCB->setEnabled(false);
1609 spellcheckNotesCB->setEnabled(false);
1614 void PrefSpellchecker::applyRC(LyXRC & rc) const
1616 string const speller = fromqstr(spellcheckerCB->
1617 itemData(spellcheckerCB->currentIndex()).toString());
1618 if (!speller.empty())
1619 rc.spellchecker = speller;
1620 rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
1621 rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
1622 rc.spellchecker_accept_compound = compoundWordCB->isChecked();
1623 rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked();
1624 rc.spellcheck_notes = spellcheckNotesCB->isChecked();
1628 void PrefSpellchecker::updateRC(LyXRC const & rc)
1630 spellcheckerCB->setCurrentIndex(
1631 spellcheckerCB->findData(toqstr(rc.spellchecker)));
1632 altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
1633 escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
1634 compoundWordCB->setChecked(rc.spellchecker_accept_compound);
1635 spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously);
1636 spellcheckNotesCB->setChecked(rc.spellcheck_notes);
1640 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
1642 QString spellchecker = spellcheckerCB->itemData(index).toString();
1644 compoundWordCB->setEnabled(spellchecker == QString("aspell"));
1649 /////////////////////////////////////////////////////////////////////
1653 /////////////////////////////////////////////////////////////////////
1656 PrefConverters::PrefConverters(GuiPreferences * form)
1657 : PrefModule(catFiles, N_("Converters"), form)
1661 connect(converterNewPB, SIGNAL(clicked()),
1662 this, SLOT(updateConverter()));
1663 connect(converterRemovePB, SIGNAL(clicked()),
1664 this, SLOT(removeConverter()));
1665 connect(converterModifyPB, SIGNAL(clicked()),
1666 this, SLOT(updateConverter()));
1667 connect(convertersLW, SIGNAL(currentRowChanged(int)),
1668 this, SLOT(switchConverter()));
1669 connect(converterFromCO, SIGNAL(activated(QString)),
1670 this, SLOT(changeConverter()));
1671 connect(converterToCO, SIGNAL(activated(QString)),
1672 this, SLOT(changeConverter()));
1673 connect(converterED, SIGNAL(textEdited(QString)),
1674 this, SLOT(changeConverter()));
1675 connect(converterFlagED, SIGNAL(textEdited(QString)),
1676 this, SLOT(changeConverter()));
1677 connect(converterNewPB, SIGNAL(clicked()),
1678 this, SIGNAL(changed()));
1679 connect(converterRemovePB, SIGNAL(clicked()),
1680 this, SIGNAL(changed()));
1681 connect(converterModifyPB, SIGNAL(clicked()),
1682 this, SIGNAL(changed()));
1683 connect(maxAgeLE, SIGNAL(textEdited(QString)),
1684 this, SIGNAL(changed()));
1685 connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
1686 this, SIGNAL(changed()));
1688 converterED->setValidator(new NoNewLineValidator(converterED));
1689 converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
1690 maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
1691 //converterDefGB->setFocusProxy(convertersLW);
1695 void PrefConverters::applyRC(LyXRC & rc) const
1697 rc.use_converter_cache = cacheCB->isChecked();
1698 rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
1699 rc.use_converter_needauth = needauthCB->isChecked();
1700 rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
1704 static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
1705 cb->blockSignals(true);
1706 cb->setChecked(checked);
1707 cb->blockSignals(false);
1711 void PrefConverters::updateRC(LyXRC const & rc)
1713 cacheCB->setChecked(rc.use_converter_cache);
1714 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1715 setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
1717 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1722 void PrefConverters::updateGui()
1724 QString const pattern("%1 -> %2");
1725 form_->formats().sort();
1726 form_->converters().update(form_->formats());
1727 // save current selection
1730 .arg(converterFromCO->currentText())
1731 .arg(converterToCO->currentText());
1733 converterFromCO->clear();
1734 converterToCO->clear();
1736 for (Format const & f : form_->formats()) {
1737 QString const name = toqstr(translateIfPossible(f.prettyname()));
1738 converterFromCO->addItem(name);
1739 converterToCO->addItem(name);
1742 // currentRowChanged(int) is also triggered when updating the listwidget
1743 // block signals to avoid unnecessary calls to switchConverter()
1744 convertersLW->blockSignals(true);
1745 convertersLW->clear();
1747 for (Converter const & c : form_->converters()) {
1748 QString const name =
1750 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1751 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1752 int type = form_->converters().getNumber(c.From()->name(),
1754 new QListWidgetItem(name, convertersLW, type);
1756 convertersLW->sortItems(Qt::AscendingOrder);
1757 convertersLW->blockSignals(false);
1759 // restore selection
1760 if (current != pattern.arg(QString()).arg(QString())) {
1761 QList<QListWidgetItem *> const item =
1762 convertersLW->findItems(current, Qt::MatchExactly);
1763 if (!item.isEmpty())
1764 convertersLW->setCurrentItem(item.at(0));
1767 // select first element if restoring failed
1768 if (convertersLW->currentRow() == -1)
1769 convertersLW->setCurrentRow(0);
1775 void PrefConverters::switchConverter()
1777 int const cnr = convertersLW->currentItem()->type();
1778 Converter const & c(form_->converters().get(cnr));
1779 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1780 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1781 converterED->setText(toqstr(c.command()));
1782 converterFlagED->setText(toqstr(c.flags()));
1788 void PrefConverters::changeConverter()
1794 void PrefConverters::updateButtons()
1796 if (form_->formats().empty())
1798 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1799 Format const & to = form_->formats().get(converterToCO->currentIndex());
1800 int const sel = form_->converters().getNumber(from.name(), to.name());
1801 bool const known = sel >= 0;
1802 bool const valid = !(converterED->text().isEmpty()
1803 || from.name() == to.name());
1808 if (convertersLW->count() > 0) {
1809 int const cnr = convertersLW->currentItem()->type();
1810 Converter const & c = form_->converters().get(cnr);
1811 old_command = c.command();
1812 old_flag = c.flags();
1815 string const new_command = fromqstr(converterED->text());
1816 string const new_flag = fromqstr(converterFlagED->text());
1818 bool modified = (old_command != new_command || old_flag != new_flag);
1820 converterModifyPB->setEnabled(valid && known && modified);
1821 converterNewPB->setEnabled(valid && !known);
1822 converterRemovePB->setEnabled(known);
1824 maxAgeLE->setEnabled(cacheCB->isChecked());
1825 maxAgeLA->setEnabled(cacheCB->isChecked());
1830 // specify unique from/to or it doesn't appear. This is really bad UI
1831 // this is why we can use the same function for both new and modify
1832 void PrefConverters::updateConverter()
1834 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1835 Format const & to = form_->formats().get(converterToCO->currentIndex());
1836 string const flags = fromqstr(converterFlagED->text());
1837 string const command = fromqstr(converterED->text());
1839 Converter const * old =
1840 form_->converters().getConverter(from.name(), to.name());
1841 form_->converters().add(from.name(), to.name(), command, flags);
1844 form_->converters().updateLast(form_->formats());
1848 // Remove all files created by this converter from the cache, since
1849 // the modified converter might create different files.
1850 ConverterCache::get().remove_all(from.name(), to.name());
1854 void PrefConverters::removeConverter()
1856 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1857 Format const & to = form_->formats().get(converterToCO->currentIndex());
1858 form_->converters().erase(from.name(), to.name());
1862 // Remove all files created by this converter from the cache, since
1863 // a possible new converter might create different files.
1864 ConverterCache::get().remove_all(from.name(), to.name());
1868 void PrefConverters::on_cacheCB_stateChanged(int state)
1870 maxAgeLE->setEnabled(state == Qt::Checked);
1871 maxAgeLA->setEnabled(state == Qt::Checked);
1876 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1878 needauthCB->setEnabled(!checked);
1882 void PrefConverters::on_needauthCB_toggled(bool checked)
1889 int ret = frontend::Alert::prompt(
1890 _("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!"),
1891 0, 0, _("&No"), _("&Yes"));
1895 setCheckboxBlockSignals(needauthCB, true);
1899 /////////////////////////////////////////////////////////////////////
1903 /////////////////////////////////////////////////////////////////////
1905 class FormatValidator : public QValidator
1908 FormatValidator(QWidget *, Formats const & f);
1909 void fixup(QString & input) const;
1910 QValidator::State validate(QString & input, int & pos) const;
1912 virtual QString toString(Format const & format) const = 0;
1914 Formats const & formats_;
1918 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1919 : QValidator(parent), formats_(f)
1924 void FormatValidator::fixup(QString & input) const
1926 Formats::const_iterator cit = formats_.begin();
1927 Formats::const_iterator end = formats_.end();
1928 for (; cit != end; ++cit) {
1929 QString const name = toString(*cit);
1930 if (distance(formats_.begin(), cit) == nr()) {
1938 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1940 Formats::const_iterator cit = formats_.begin();
1941 Formats::const_iterator end = formats_.end();
1942 bool unknown = true;
1943 for (; unknown && cit != end; ++cit) {
1944 QString const name = toString(*cit);
1945 if (distance(formats_.begin(), cit) != nr())
1946 unknown = name != input;
1949 if (unknown && !input.isEmpty())
1950 return QValidator::Acceptable;
1952 return QValidator::Intermediate;
1956 int FormatValidator::nr() const
1958 QComboBox * p = qobject_cast<QComboBox *>(parent());
1959 return p->itemData(p->currentIndex()).toInt();
1963 /////////////////////////////////////////////////////////////////////
1965 // FormatNameValidator
1967 /////////////////////////////////////////////////////////////////////
1969 class FormatNameValidator : public FormatValidator
1972 FormatNameValidator(QWidget * parent, Formats const & f)
1973 : FormatValidator(parent, f)
1976 QString toString(Format const & format) const
1978 return toqstr(format.name());
1983 /////////////////////////////////////////////////////////////////////
1985 // FormatPrettynameValidator
1987 /////////////////////////////////////////////////////////////////////
1989 class FormatPrettynameValidator : public FormatValidator
1992 FormatPrettynameValidator(QWidget * parent, Formats const & f)
1993 : FormatValidator(parent, f)
1996 QString toString(Format const & format) const
1998 return toqstr(translateIfPossible(format.prettyname()));
2003 /////////////////////////////////////////////////////////////////////
2007 /////////////////////////////////////////////////////////////////////
2009 PrefFileformats::PrefFileformats(GuiPreferences * form)
2010 : PrefModule(catFiles, N_("File Formats"), form)
2014 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
2015 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
2016 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
2017 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
2018 editorED->setValidator(new NoNewLineValidator(editorED));
2019 viewerED->setValidator(new NoNewLineValidator(viewerED));
2020 copierED->setValidator(new NoNewLineValidator(copierED));
2022 connect(documentCB, SIGNAL(clicked()),
2023 this, SLOT(setFlags()));
2024 connect(vectorCB, SIGNAL(clicked()),
2025 this, SLOT(setFlags()));
2026 connect(exportMenuCB, SIGNAL(clicked()),
2027 this, SLOT(setFlags()));
2028 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
2029 this, SLOT(updatePrettyname()));
2030 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
2031 this, SIGNAL(changed()));
2032 connect(defaultFormatCB, SIGNAL(activated(QString)),
2033 this, SIGNAL(changed()));
2034 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
2035 this, SIGNAL(changed()));
2036 connect(viewerCO, SIGNAL(activated(int)),
2037 this, SIGNAL(changed()));
2038 connect(editorCO, SIGNAL(activated(int)),
2039 this, SIGNAL(changed()));
2045 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
2047 if (shortcut.empty())
2050 string l10n_format =
2051 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
2052 return split(l10n_format, '|');
2058 void PrefFileformats::applyRC(LyXRC & rc) const
2060 QString const default_format = defaultFormatCB->itemData(
2061 defaultFormatCB->currentIndex()).toString();
2062 rc.default_view_format = fromqstr(default_format);
2063 QString const default_otf_format = defaultOTFFormatCB->itemData(
2064 defaultOTFFormatCB->currentIndex()).toString();
2065 rc.default_otf_view_format = fromqstr(default_otf_format);
2069 void PrefFileformats::updateRC(LyXRC const & rc)
2071 viewer_alternatives = rc.viewer_alternatives;
2072 editor_alternatives = rc.editor_alternatives;
2073 bool const init = defaultFormatCB->currentText().isEmpty();
2077 defaultFormatCB->findData(toqstr(rc.default_view_format));
2078 defaultFormatCB->setCurrentIndex(pos);
2079 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2080 defaultOTFFormatCB->setCurrentIndex(pos);
2081 defaultOTFFormatCB->setCurrentIndex(pos);
2086 void PrefFileformats::updateView()
2088 QString const current = formatsCB->currentText();
2089 QString const current_def = defaultFormatCB->currentText();
2090 QString const current_def_otf = defaultOTFFormatCB->currentText();
2092 // update comboboxes with formats
2093 formatsCB->blockSignals(true);
2094 defaultFormatCB->blockSignals(true);
2095 defaultOTFFormatCB->blockSignals(true);
2097 defaultFormatCB->clear();
2098 defaultOTFFormatCB->clear();
2099 form_->formats().sort();
2100 for (Format const & f : form_->formats()) {
2101 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2102 formatsCB->addItem(prettyname,
2103 QVariant(form_->formats().getNumber(f.name())));
2104 if (f.viewer().empty())
2106 if (form_->converters().isReachable("xhtml", f.name())
2107 || form_->converters().isReachable("dviluatex", f.name())
2108 || form_->converters().isReachable("luatex", f.name())
2109 || form_->converters().isReachable("xetex", f.name())) {
2110 defaultFormatCB->addItem(prettyname,
2111 QVariant(toqstr(f.name())));
2112 defaultOTFFormatCB->addItem(prettyname,
2113 QVariant(toqstr(f.name())));
2114 } else if (form_->converters().isReachable("latex", f.name())
2115 || form_->converters().isReachable("pdflatex", f.name()))
2116 defaultFormatCB->addItem(prettyname,
2117 QVariant(toqstr(f.name())));
2120 // restore selections
2121 int item = formatsCB->findText(current, Qt::MatchExactly);
2122 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2123 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2124 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2125 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2126 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2127 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2128 formatsCB->blockSignals(false);
2129 defaultFormatCB->blockSignals(false);
2130 defaultOTFFormatCB->blockSignals(false);
2134 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2136 if (form_->formats().empty())
2138 int const nr = formatsCB->itemData(i).toInt();
2139 Format const f = form_->formats().get(nr);
2141 formatED->setText(toqstr(f.name()));
2142 copierED->setText(toqstr(form_->movers().command(f.name())));
2143 extensionsED->setText(toqstr(f.extensions()));
2144 mimeED->setText(toqstr(f.mime()));
2145 shortcutED->setText(
2146 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2147 documentCB->setChecked((f.documentFormat()));
2148 vectorCB->setChecked((f.vectorFormat()));
2149 exportMenuCB->setChecked((f.inExportMenu()));
2150 exportMenuCB->setEnabled((f.documentFormat()));
2156 void PrefFileformats::setFlags()
2158 int flags = Format::none;
2159 if (documentCB->isChecked())
2160 flags |= Format::document;
2161 if (vectorCB->isChecked())
2162 flags |= Format::vector;
2163 if (exportMenuCB->isChecked())
2164 flags |= Format::export_menu;
2165 currentFormat().setFlags(flags);
2166 exportMenuCB->setEnabled(documentCB->isChecked());
2171 void PrefFileformats::on_copierED_textEdited(const QString & s)
2173 string const fmt = fromqstr(formatED->text());
2174 form_->movers().set(fmt, fromqstr(s));
2179 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2181 currentFormat().setExtensions(fromqstr(s));
2186 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2188 currentFormat().setViewer(fromqstr(s));
2193 void PrefFileformats::on_editorED_textEdited(const QString & s)
2195 currentFormat().setEditor(fromqstr(s));
2200 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2202 currentFormat().setMime(fromqstr(s));
2207 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2209 string const new_shortcut = fromqstr(s);
2210 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2211 currentFormat().shortcut()))
2213 currentFormat().setShortcut(new_shortcut);
2218 void PrefFileformats::on_formatED_editingFinished()
2220 string const newname = fromqstr(formatED->displayText());
2221 string const oldname = currentFormat().name();
2222 if (newname == oldname)
2224 if (form_->converters().formatIsUsed(oldname)) {
2225 Alert::error(_("Format in use"),
2226 _("You cannot change a format's short name "
2227 "if the format is used by a converter. "
2228 "Please remove the converter first."));
2233 currentFormat().setName(newname);
2238 void PrefFileformats::on_formatED_textChanged(const QString &)
2240 QString t = formatED->text();
2242 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2243 setValid(formatLA, valid);
2247 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2249 QString t = formatsCB->currentText();
2251 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2252 setValid(formatsLA, valid);
2256 void PrefFileformats::updatePrettyname()
2258 QString const newname = formatsCB->currentText();
2259 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2262 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2270 void updateComboBox(LyXRC::Alternatives const & alts,
2271 string const & fmt, QComboBox * combo)
2273 LyXRC::Alternatives::const_iterator it =
2275 if (it != alts.end()) {
2276 LyXRC::CommandSet const & cmds = it->second;
2277 LyXRC::CommandSet::const_iterator sit =
2279 LyXRC::CommandSet::const_iterator const sen =
2281 for (; sit != sen; ++sit) {
2282 QString const qcmd = toqstr(*sit);
2283 combo->addItem(qcmd, qcmd);
2290 void PrefFileformats::updateViewers()
2292 Format const f = currentFormat();
2293 viewerCO->blockSignals(true);
2295 viewerCO->addItem(qt_("None"), QString());
2296 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2297 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2298 viewerCO->blockSignals(false);
2300 int pos = viewerCO->findData(toqstr(f.viewer()));
2303 viewerED->setEnabled(false);
2304 viewerCO->setCurrentIndex(pos);
2306 viewerED->setEnabled(true);
2307 viewerED->setText(toqstr(f.viewer()));
2308 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2313 void PrefFileformats::updateEditors()
2315 Format const f = currentFormat();
2316 editorCO->blockSignals(true);
2318 editorCO->addItem(qt_("None"), QString());
2319 updateComboBox(editor_alternatives, f.name(), editorCO);
2320 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2321 editorCO->blockSignals(false);
2323 int pos = editorCO->findData(toqstr(f.editor()));
2326 editorED->setEnabled(false);
2327 editorCO->setCurrentIndex(pos);
2329 editorED->setEnabled(true);
2330 editorED->setText(toqstr(f.editor()));
2331 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2336 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2338 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2339 viewerED->setEnabled(custom);
2341 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2345 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2347 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2348 editorED->setEnabled(custom);
2350 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2354 Format & PrefFileformats::currentFormat()
2356 int const i = formatsCB->currentIndex();
2357 int const nr = formatsCB->itemData(i).toInt();
2358 return form_->formats().get(nr);
2362 void PrefFileformats::on_formatNewPB_clicked()
2364 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2366 formatsCB->setCurrentIndex(0);
2367 formatsCB->setFocus(Qt::OtherFocusReason);
2371 void PrefFileformats::on_formatRemovePB_clicked()
2373 int const i = formatsCB->currentIndex();
2374 int const nr = formatsCB->itemData(i).toInt();
2375 string const current_text = form_->formats().get(nr).name();
2376 if (form_->converters().formatIsUsed(current_text)) {
2377 Alert::error(_("Format in use"),
2378 _("Cannot remove a Format used by a Converter. "
2379 "Remove the converter first."));
2383 form_->formats().erase(current_text);
2386 on_formatsCB_editTextChanged(formatsCB->currentText());
2391 /////////////////////////////////////////////////////////////////////
2395 /////////////////////////////////////////////////////////////////////
2397 PrefLanguage::PrefLanguage(GuiPreferences * form)
2398 : PrefModule(catLanguage, N_("Language"), form)
2402 connect(visualCursorRB, SIGNAL(clicked()),
2403 this, SIGNAL(changed()));
2404 connect(logicalCursorRB, SIGNAL(clicked()),
2405 this, SIGNAL(changed()));
2406 connect(markForeignCB, SIGNAL(clicked()),
2407 this, SIGNAL(changed()));
2408 connect(autoBeginCB, SIGNAL(clicked()),
2409 this, SIGNAL(changed()));
2410 connect(autoEndCB, SIGNAL(clicked()),
2411 this, SIGNAL(changed()));
2412 connect(languagePackageCO, SIGNAL(activated(int)),
2413 this, SIGNAL(changed()));
2414 connect(languagePackageED, SIGNAL(textChanged(QString)),
2415 this, SIGNAL(changed()));
2416 connect(globalCB, SIGNAL(clicked()),
2417 this, SIGNAL(changed()));
2418 connect(startCommandED, SIGNAL(textChanged(QString)),
2419 this, SIGNAL(changed()));
2420 connect(endCommandED, SIGNAL(textChanged(QString)),
2421 this, SIGNAL(changed()));
2422 connect(uiLanguageCO, SIGNAL(activated(int)),
2423 this, SIGNAL(changed()));
2424 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2425 this, SIGNAL(changed()));
2426 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2427 this, SIGNAL(changed()));
2429 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2430 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2431 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2433 defaultDecimalPointLE->setInputMask("X; ");
2434 defaultDecimalPointLE->setMaxLength(1);
2436 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2437 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2439 QAbstractItemModel * language_model = guiApp->languageModel();
2440 language_model->sort(0);
2441 uiLanguageCO->blockSignals(true);
2442 uiLanguageCO->clear();
2443 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2444 for (int i = 0; i != language_model->rowCount(); ++i) {
2445 QModelIndex index = language_model->index(i, 0);
2446 // Filter the list based on the available translation and add
2447 // each language code only once
2448 string const name = fromqstr(index.data(Qt::UserRole).toString());
2449 Language const * lang = languages.getLanguage(name);
2452 // never remove the currently selected language
2453 if (name != form->rc().gui_language
2454 && name != lyxrc.gui_language
2455 && (!Messages::available(lang->code())
2456 || !lang->hasGuiSupport()))
2458 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2459 index.data(Qt::UserRole).toString());
2461 uiLanguageCO->blockSignals(false);
2465 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2467 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2468 qt_("The change of user interface language will be fully "
2469 "effective only after a restart."));
2473 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2475 languagePackageED->setEnabled(i == 2);
2479 void PrefLanguage::applyRC(LyXRC & rc) const
2481 rc.visual_cursor = visualCursorRB->isChecked();
2482 rc.mark_foreign_language = markForeignCB->isChecked();
2483 rc.language_auto_begin = autoBeginCB->isChecked();
2484 rc.language_auto_end = autoEndCB->isChecked();
2485 int const p = languagePackageCO->currentIndex();
2487 rc.language_package_selection = LyXRC::LP_AUTO;
2489 rc.language_package_selection = LyXRC::LP_BABEL;
2491 rc.language_package_selection = LyXRC::LP_CUSTOM;
2493 rc.language_package_selection = LyXRC::LP_NONE;
2494 rc.language_custom_package = fromqstr(languagePackageED->text());
2495 rc.language_global_options = globalCB->isChecked();
2496 rc.language_command_begin = fromqstr(startCommandED->text());
2497 rc.language_command_end = fromqstr(endCommandED->text());
2498 rc.gui_language = fromqstr(
2499 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2500 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2501 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2505 void PrefLanguage::updateRC(LyXRC const & rc)
2507 if (rc.visual_cursor)
2508 visualCursorRB->setChecked(true);
2510 logicalCursorRB->setChecked(true);
2511 markForeignCB->setChecked(rc.mark_foreign_language);
2512 autoBeginCB->setChecked(rc.language_auto_begin);
2513 autoEndCB->setChecked(rc.language_auto_end);
2514 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2515 languagePackageED->setText(toqstr(rc.language_custom_package));
2516 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2517 globalCB->setChecked(rc.language_global_options);
2518 startCommandED->setText(toqstr(rc.language_command_begin));
2519 endCommandED->setText(toqstr(rc.language_command_end));
2520 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2521 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2522 defaultLengthUnitCO->setCurrentIndex(pos);
2524 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2525 uiLanguageCO->blockSignals(true);
2526 uiLanguageCO->setCurrentIndex(pos);
2527 uiLanguageCO->blockSignals(false);
2531 /////////////////////////////////////////////////////////////////////
2533 // PrefUserInterface
2535 /////////////////////////////////////////////////////////////////////
2537 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2538 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2542 connect(uiFilePB, SIGNAL(clicked()),
2543 this, SLOT(selectUi()));
2544 connect(uiFileED, SIGNAL(textChanged(QString)),
2545 this, SIGNAL(changed()));
2546 connect(iconSetCO, SIGNAL(activated(int)),
2547 this, SIGNAL(changed()));
2548 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2549 this, SIGNAL(changed()));
2550 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2551 this, SIGNAL(changed()));
2552 connect(tooltipCB, SIGNAL(toggled(bool)),
2553 this, SIGNAL(changed()));
2554 lastfilesSB->setMaximum(maxlastfiles);
2556 iconSetCO->addItem(qt_("Default"), QString());
2557 iconSetCO->addItem(qt_("Classic"), "classic");
2558 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2560 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2561 useSystemThemeIconsCB->hide();
2566 void PrefUserInterface::applyRC(LyXRC & rc) const
2568 rc.icon_set = fromqstr(iconSetCO->itemData(
2569 iconSetCO->currentIndex()).toString());
2571 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2572 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2573 rc.num_lastfiles = lastfilesSB->value();
2574 rc.use_tooltip = tooltipCB->isChecked();
2578 void PrefUserInterface::updateRC(LyXRC const & rc)
2580 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2583 iconSetCO->setCurrentIndex(iconset);
2584 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2585 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2586 lastfilesSB->setValue(rc.num_lastfiles);
2587 tooltipCB->setChecked(rc.use_tooltip);
2591 void PrefUserInterface::selectUi()
2593 QString file = form_->browseUI(internalPath(uiFileED->text()));
2594 if (!file.isEmpty())
2595 uiFileED->setText(file);
2599 /////////////////////////////////////////////////////////////////////
2601 // PrefDocumentHandling
2603 /////////////////////////////////////////////////////////////////////
2605 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2606 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2610 connect(autoSaveCB, SIGNAL(toggled(bool)),
2611 autoSaveSB, SLOT(setEnabled(bool)));
2612 connect(autoSaveCB, SIGNAL(toggled(bool)),
2613 TextLabel1, SLOT(setEnabled(bool)));
2614 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2615 this, SIGNAL(changed()));
2616 connect(singleInstanceCB, SIGNAL(clicked()),
2617 this, SIGNAL(changed()));
2618 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2619 this, SIGNAL(changed()));
2620 connect(closeLastViewCO, SIGNAL(activated(int)),
2621 this, SIGNAL(changed()));
2622 connect(restoreCursorCB, SIGNAL(clicked()),
2623 this, SIGNAL(changed()));
2624 connect(loadSessionCB, SIGNAL(clicked()),
2625 this, SIGNAL(changed()));
2626 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2627 this, SIGNAL(changed()));
2628 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2629 this, SIGNAL(changed()));
2630 connect(autoSaveCB, SIGNAL(clicked()),
2631 this, SIGNAL(changed()));
2632 connect(backupCB, SIGNAL(clicked()),
2633 this, SIGNAL(changed()));
2634 connect(saveCompressedCB, SIGNAL(clicked()),
2635 this, SIGNAL(changed()));
2636 connect(saveOriginCB, SIGNAL(clicked()),
2637 this, SIGNAL(changed()));
2641 void PrefDocHandling::applyRC(LyXRC & rc) const
2643 rc.use_lastfilepos = restoreCursorCB->isChecked();
2644 rc.load_session = loadSessionCB->isChecked();
2645 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2646 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2647 rc.make_backup = backupCB->isChecked();
2648 rc.save_compressed = saveCompressedCB->isChecked();
2649 rc.save_origin = saveOriginCB->isChecked();
2650 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2651 rc.single_instance = singleInstanceCB->isChecked();
2652 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2654 switch (closeLastViewCO->currentIndex()) {
2656 rc.close_buffer_with_last_view = "yes";
2659 rc.close_buffer_with_last_view = "no";
2662 rc.close_buffer_with_last_view = "ask";
2670 void PrefDocHandling::updateRC(LyXRC const & rc)
2672 restoreCursorCB->setChecked(rc.use_lastfilepos);
2673 loadSessionCB->setChecked(rc.load_session);
2674 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2675 // convert to minutes
2676 bool autosave = rc.autosave > 0;
2677 int mins = rc.autosave / 60;
2680 autoSaveSB->setValue(mins);
2681 autoSaveCB->setChecked(autosave);
2682 autoSaveSB->setEnabled(autosave);
2683 backupCB->setChecked(rc.make_backup);
2684 saveCompressedCB->setChecked(rc.save_compressed);
2685 saveOriginCB->setChecked(rc.save_origin);
2686 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2687 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2688 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2689 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2690 if (rc.close_buffer_with_last_view == "yes")
2691 closeLastViewCO->setCurrentIndex(0);
2692 else if (rc.close_buffer_with_last_view == "no")
2693 closeLastViewCO->setCurrentIndex(1);
2694 else if (rc.close_buffer_with_last_view == "ask")
2695 closeLastViewCO->setCurrentIndex(2);
2699 void PrefDocHandling::on_clearSessionPB_clicked()
2701 guiApp->clearSession();
2706 /////////////////////////////////////////////////////////////////////
2710 /////////////////////////////////////////////////////////////////////
2712 PrefEdit::PrefEdit(GuiPreferences * form)
2713 : PrefModule(catEditing, N_("Control"), form)
2717 connect(cursorFollowsCB, SIGNAL(clicked()),
2718 this, SIGNAL(changed()));
2719 connect(scrollBelowCB, SIGNAL(clicked()),
2720 this, SIGNAL(changed()));
2721 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2722 this, SIGNAL(changed()));
2723 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2724 this, SIGNAL(changed()));
2725 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2726 this, SIGNAL(changed()));
2727 connect(macroEditStyleCO, SIGNAL(activated(int)),
2728 this, SIGNAL(changed()));
2729 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2730 this, SIGNAL(changed()));
2731 connect(fullscreenLimitGB, SIGNAL(clicked()),
2732 this, SIGNAL(changed()));
2733 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2734 this, SIGNAL(changed()));
2735 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2736 this, SIGNAL(changed()));
2737 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2738 this, SIGNAL(changed()));
2739 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2740 this, SIGNAL(changed()));
2741 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2742 this, SIGNAL(changed()));
2743 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2744 this, SIGNAL(changed()));
2748 void PrefEdit::applyRC(LyXRC & rc) const
2750 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2751 rc.scroll_below_document = scrollBelowCB->isChecked();
2752 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2753 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2754 rc.group_layouts = groupEnvironmentsCB->isChecked();
2755 switch (macroEditStyleCO->currentIndex()) {
2756 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2757 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2758 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2760 rc.cursor_width = cursorWidthSB->value();
2761 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2762 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2763 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2764 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2765 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2766 rc.full_screen_width = fullscreenWidthSB->value();
2767 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2771 void PrefEdit::updateRC(LyXRC const & rc)
2773 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2774 scrollBelowCB->setChecked(rc.scroll_below_document);
2775 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2776 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2777 groupEnvironmentsCB->setChecked(rc.group_layouts);
2778 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2779 cursorWidthSB->setValue(rc.cursor_width);
2780 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2781 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2782 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2783 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2784 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2785 fullscreenWidthSB->setValue(rc.full_screen_width);
2786 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2790 /////////////////////////////////////////////////////////////////////
2794 /////////////////////////////////////////////////////////////////////
2797 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2799 Ui::shortcutUi::setupUi(this);
2800 QDialog::setModal(true);
2804 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2805 : PrefModule(catEditing, N_("Shortcuts"), form),
2806 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2811 shortcutsTW->setColumnCount(2);
2812 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2813 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2814 shortcutsTW->setSortingEnabled(true);
2815 // Multi-selection can be annoying.
2816 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2818 connect(bindFilePB, SIGNAL(clicked()),
2819 this, SLOT(selectBind()));
2820 connect(bindFileED, SIGNAL(textChanged(QString)),
2821 this, SIGNAL(changed()));
2823 shortcut_ = new GuiShortcutDialog(this);
2824 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2825 shortcut_bc_.setOK(shortcut_->okPB);
2826 shortcut_bc_.setCancel(shortcut_->cancelPB);
2828 connect(shortcut_->okPB, SIGNAL(clicked()),
2829 this, SIGNAL(changed()));
2830 connect(shortcut_->cancelPB, SIGNAL(clicked()),
2831 shortcut_, SLOT(reject()));
2832 connect(shortcut_->clearPB, SIGNAL(clicked()),
2833 this, SLOT(shortcutClearPressed()));
2834 connect(shortcut_->removePB, SIGNAL(clicked()),
2835 this, SLOT(shortcutRemovePressed()));
2836 connect(shortcut_->okPB, SIGNAL(clicked()),
2837 this, SLOT(shortcutOkPressed()));
2838 connect(shortcut_->cancelPB, SIGNAL(clicked()),
2839 this, SLOT(shortcutCancelPressed()));
2843 void PrefShortcuts::applyRC(LyXRC & rc) const
2845 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2846 // write user_bind and user_unbind to .lyx/bind/user.bind
2847 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2848 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2849 lyxerr << "LyX could not create the user bind directory '"
2850 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2853 if (!bind_dir.isDirWritable()) {
2854 lyxerr << "LyX could not write to the user bind directory '"
2855 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2858 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2859 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2860 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2861 // immediately apply the keybindings. Why this is not done before?
2862 // The good thing is that the menus are updated automatically.
2863 theTopLevelKeymap().clear();
2864 theTopLevelKeymap().read("site");
2865 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2866 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2870 void PrefShortcuts::updateRC(LyXRC const & rc)
2872 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2874 system_bind_.clear();
2876 user_unbind_.clear();
2877 system_bind_.read("site");
2878 system_bind_.read(rc.bind_file);
2879 // \unbind in user.bind is added to user_unbind_
2880 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2881 updateShortcutsTW();
2885 void PrefShortcuts::updateShortcutsTW()
2887 shortcutsTW->clear();
2889 editItem_ = new QTreeWidgetItem(shortcutsTW);
2890 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2891 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2893 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2894 mathItem_->setText(0, qt_("Mathematical Symbols"));
2895 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2897 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2898 bufferItem_->setText(0, qt_("Document and Window"));
2899 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2901 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2902 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2903 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2905 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2906 systemItem_->setText(0, qt_("System and Miscellaneous"));
2907 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2909 // listBindings(unbound=true) lists all bound and unbound lfuns
2910 // Items in this list is tagged by its source.
2911 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2913 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2915 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2916 KeyMap::UserUnbind);
2917 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2918 user_bindinglist.end());
2919 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2920 user_unbindinglist.end());
2922 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2923 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2924 for (; it != it_end; ++it)
2925 insertShortcutItem(it->request, it->sequence, it->tag);
2927 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2928 on_shortcutsTW_itemSelectionChanged();
2929 on_searchLE_textEdited();
2930 shortcutsTW->resizeColumnToContents(0);
2935 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2937 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2942 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2944 // Hide rebound system settings that are empty
2945 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2949 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2951 item->setData(0, Qt::UserRole, QVariant(tag));
2955 case KeyMap::System:
2957 case KeyMap::UserBind:
2960 case KeyMap::UserUnbind:
2961 font.setStrikeOut(true);
2963 // this item is not displayed now.
2964 case KeyMap::UserExtraUnbind:
2965 font.setStrikeOut(true);
2968 item->setHidden(isAlwaysHidden(*item));
2969 item->setFont(1, font);
2973 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2974 KeySequence const & seq, KeyMap::ItemType tag)
2976 FuncCode const action = lfun.action();
2977 string const action_name = lyxaction.getActionName(action);
2978 QString const lfun_name = toqstr(from_utf8(action_name)
2979 + ' ' + lfun.argument());
2980 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
2982 QTreeWidgetItem * newItem = 0;
2983 // for unbind items, try to find an existing item in the system bind list
2984 if (tag == KeyMap::UserUnbind) {
2985 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
2986 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
2987 for (int i = 0; i < items.size(); ++i) {
2988 if (items[i]->text(1) == shortcut) {
2993 // if not found, this unbind item is KeyMap::UserExtraUnbind
2994 // Such an item is not displayed to avoid confusion (what is
2995 // unmatched removed?).
3001 switch(lyxaction.getActionType(action)) {
3002 case LyXAction::Hidden:
3004 case LyXAction::Edit:
3005 newItem = new QTreeWidgetItem(editItem_);
3007 case LyXAction::Math:
3008 newItem = new QTreeWidgetItem(mathItem_);
3010 case LyXAction::Buffer:
3011 newItem = new QTreeWidgetItem(bufferItem_);
3013 case LyXAction::Layout:
3014 newItem = new QTreeWidgetItem(layoutItem_);
3016 case LyXAction::System:
3017 newItem = new QTreeWidgetItem(systemItem_);
3020 // this should not happen
3021 newItem = new QTreeWidgetItem(shortcutsTW);
3025 newItem->setText(0, lfun_name);
3026 newItem->setText(1, shortcut);
3027 // record BindFile representation to recover KeySequence when needed.
3028 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
3029 setItemType(newItem, tag);
3034 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
3036 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3037 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
3038 modifyPB->setEnabled(!items.isEmpty());
3039 if (items.isEmpty())
3042 if (itemType(*items[0]) == KeyMap::UserUnbind)
3043 removePB->setText(qt_("Res&tore"));
3045 removePB->setText(qt_("Remo&ve"));
3049 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3055 void PrefShortcuts::modifyShortcut()
3057 QTreeWidgetItem * item = shortcutsTW->currentItem();
3058 if (item->flags() & Qt::ItemIsSelectable) {
3059 shortcut_->lfunLE->setText(item->text(0));
3060 save_lfun_ = item->text(0).trimmed();
3061 shortcut_->shortcutWG->setText(item->text(1));
3063 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3064 shortcut_->shortcutWG->setKeySequence(seq);
3065 shortcut_->shortcutWG->setFocus();
3071 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3073 // list of items that match lfun
3074 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3075 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3076 for (int i = 0; i < items.size(); ++i) {
3077 QTreeWidgetItem * item = items[i];
3078 if (isAlwaysHidden(*item)) {
3079 setItemType(item, KeyMap::System);
3081 shortcutsTW->setCurrentItem(item);
3088 void PrefShortcuts::removeShortcut()
3090 // it seems that only one item can be selected, but I am
3091 // removing all selected items anyway.
3092 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3093 for (int i = 0; i < items.size(); ++i) {
3094 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3095 string lfun = fromqstr(items[i]->text(0));
3096 FuncRequest func = lyxaction.lookupFunc(lfun);
3098 switch (itemType(*items[i])) {
3099 case KeyMap::System: {
3100 // for system bind, we do not touch the item
3101 // but add an user unbind item
3102 user_unbind_.bind(shortcut, func);
3103 setItemType(items[i], KeyMap::UserUnbind);
3104 removePB->setText(qt_("Res&tore"));
3107 case KeyMap::UserBind: {
3108 // for user_bind, we remove this bind
3109 QTreeWidgetItem * parent = items[i]->parent();
3110 int itemIdx = parent->indexOfChild(items[i]);
3111 parent->takeChild(itemIdx);
3113 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3115 shortcutsTW->scrollToItem(parent);
3116 user_bind_.unbind(shortcut, func);
3117 // If this user binding hid an empty system binding, unhide the
3118 // latter and select it.
3119 unhideEmpty(items[i]->text(0), true);
3122 case KeyMap::UserUnbind: {
3123 // for user_unbind, we remove the unbind, and the item
3124 // become KeyMap::System again.
3126 seq.parse(shortcut);
3127 // Ask the user to replace current binding
3128 if (!validateNewShortcut(func, seq, QString()))
3130 user_unbind_.unbind(shortcut, func);
3131 setItemType(items[i], KeyMap::System);
3132 removePB->setText(qt_("Remo&ve"));
3135 case KeyMap::UserExtraUnbind: {
3136 // for user unbind that is not in system bind file,
3137 // remove this unbind file
3138 QTreeWidgetItem * parent = items[i]->parent();
3139 parent->takeChild(parent->indexOfChild(items[i]));
3140 user_unbind_.unbind(shortcut, func);
3147 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3149 for (int i = 0; i < items.size(); ++i) {
3150 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3151 string lfun = fromqstr(items[i]->text(0));
3152 FuncRequest func = lyxaction.lookupFunc(lfun);
3154 switch (itemType(*items[i])) {
3155 case KeyMap::System:
3156 // for system bind, we do not touch the item
3157 // but add an user unbind item
3158 user_unbind_.bind(shortcut, func);
3159 setItemType(items[i], KeyMap::UserUnbind);
3162 case KeyMap::UserBind: {
3163 // for user_bind, we remove this bind
3164 QTreeWidgetItem * parent = items[i]->parent();
3165 int itemIdx = parent->indexOfChild(items[i]);
3166 parent->takeChild(itemIdx);
3167 user_bind_.unbind(shortcut, func);
3168 unhideEmpty(items[i]->text(0), false);
3178 void PrefShortcuts::selectBind()
3180 QString file = form_->browsebind(internalPath(bindFileED->text()));
3181 if (!file.isEmpty()) {
3182 bindFileED->setText(file);
3183 system_bind_ = KeyMap();
3184 system_bind_.read(fromqstr(file));
3185 updateShortcutsTW();
3190 void PrefShortcuts::on_modifyPB_pressed()
3196 void PrefShortcuts::on_newPB_pressed()
3198 shortcut_->lfunLE->clear();
3199 shortcut_->shortcutWG->reset();
3200 save_lfun_ = QString();
3205 void PrefShortcuts::on_removePB_pressed()
3212 void PrefShortcuts::on_searchLE_textEdited()
3214 if (searchLE->text().isEmpty()) {
3215 // show all hidden items
3216 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3218 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3219 // close all categories
3220 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3221 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3224 // search both columns
3225 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3226 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3227 matched += shortcutsTW->findItems(searchLE->text(),
3228 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3230 // hide everyone (to avoid searching in matched QList repeatedly
3231 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3233 shortcutsTW->setItemHidden(*it++, true);
3234 // show matched items
3235 for (int i = 0; i < matched.size(); ++i)
3236 if (!isAlwaysHidden(*matched[i])) {
3237 shortcutsTW->setItemHidden(matched[i], false);
3238 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3243 docstring makeCmdString(FuncRequest const & f)
3245 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3246 if (!f.argument().empty())
3247 actionStr += " " + f.argument();
3252 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3254 FuncRequest res = user_bind_.getBinding(k);
3255 if (res.action() != LFUN_UNKNOWN_ACTION)
3257 res = system_bind_.getBinding(k);
3258 // Check if it is unbound. Note: user_unbind_ can only unbind one
3259 // FuncRequest per key sequence.
3260 if (user_unbind_.getBinding(k) == res)
3261 return FuncRequest::unknown;
3266 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3267 KeySequence const & k,
3268 QString const & lfun_to_modify)
3270 if (func.action() == LFUN_UNKNOWN_ACTION) {
3271 Alert::error(_("Failed to create shortcut"),
3272 _("Unknown or invalid LyX function"));
3276 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3277 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3278 // and how it is used in GuiPrefs::shortcutOkPressed.
3279 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3280 Alert::error(_("Failed to create shortcut"),
3281 _("This LyX function is hidden and cannot be bound."));
3285 if (k.length() == 0) {
3286 Alert::error(_("Failed to create shortcut"),
3287 _("Invalid or empty key sequence"));
3291 FuncRequest oldBinding = currentBinding(k);
3292 if (oldBinding == func)
3293 // nothing to change
3296 // make sure this key isn't already bound---and, if so, prompt user
3297 // (exclude the lfun the user already wants to modify)
3298 docstring const action_string = makeCmdString(oldBinding);
3299 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3300 && lfun_to_modify != toqstr(action_string)) {
3301 docstring const new_action_string = makeCmdString(func);
3302 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3304 "Are you sure you want to unbind the "
3305 "current shortcut and bind it to %3$s?"),
3306 k.print(KeySequence::ForGui), action_string,
3308 int ret = Alert::prompt(_("Redefine shortcut?"),
3309 text, 0, 1, _("&Redefine"), _("&Cancel"));
3312 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3313 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3314 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3315 deactivateShortcuts(items);
3321 void PrefShortcuts::shortcutOkPressed()
3323 QString const new_lfun = shortcut_->lfunLE->text();
3324 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3325 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3327 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3328 // "modify", or is empty if they clicked "new" (which I do not really like)
3329 if (!validateNewShortcut(func, k, save_lfun_))
3332 if (!save_lfun_.isEmpty()) {
3333 // real modification of the lfun's shortcut,
3334 // so remove the previous one
3335 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3336 deactivateShortcuts(to_modify);
3339 shortcut_->accept();
3341 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3343 user_bind_.bind(&k, func);
3344 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3345 shortcutsTW->setItemExpanded(item->parent(), true);
3346 shortcutsTW->setCurrentItem(item);
3347 shortcutsTW->scrollToItem(item);
3349 Alert::error(_("Failed to create shortcut"),
3350 _("Can not insert shortcut to the list"));
3356 void PrefShortcuts::shortcutCancelPressed()
3358 shortcut_->shortcutWG->reset();
3362 void PrefShortcuts::shortcutClearPressed()
3364 shortcut_->shortcutWG->reset();
3368 void PrefShortcuts::shortcutRemovePressed()
3370 shortcut_->shortcutWG->removeFromSequence();
3374 /////////////////////////////////////////////////////////////////////
3378 /////////////////////////////////////////////////////////////////////
3380 PrefIdentity::PrefIdentity(GuiPreferences * form)
3381 : PrefModule(QString(), N_("Identity"), form)
3385 connect(nameED, SIGNAL(textChanged(QString)),
3386 this, SIGNAL(changed()));
3387 connect(emailED, SIGNAL(textChanged(QString)),
3388 this, SIGNAL(changed()));
3390 nameED->setValidator(new NoNewLineValidator(nameED));
3391 emailED->setValidator(new NoNewLineValidator(emailED));
3395 void PrefIdentity::applyRC(LyXRC & rc) const
3397 rc.user_name = fromqstr(nameED->text());
3398 rc.user_email = fromqstr(emailED->text());
3402 void PrefIdentity::updateRC(LyXRC const & rc)
3404 nameED->setText(toqstr(rc.user_name));
3405 emailED->setText(toqstr(rc.user_email));
3410 /////////////////////////////////////////////////////////////////////
3414 /////////////////////////////////////////////////////////////////////
3416 GuiPreferences::GuiPreferences(GuiView & lv)
3417 : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false),
3418 update_previews_(false)
3422 QDialog::setModal(false);
3424 connect(savePB, SIGNAL(clicked()), this, SLOT(slotOK()));
3425 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
3426 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
3427 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
3429 addModule(new PrefUserInterface(this));
3430 addModule(new PrefDocHandling(this));
3431 addModule(new PrefEdit(this));
3432 addModule(new PrefShortcuts(this));
3433 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3434 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3435 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3436 addModule(screenfonts);
3437 addModule(new PrefColors(this));
3438 addModule(new PrefDisplay(this));
3439 addModule(new PrefInput(this));
3440 addModule(new PrefCompletion(this));
3442 addModule(new PrefPaths(this));
3444 addModule(new PrefIdentity(this));
3446 addModule(new PrefLanguage(this));
3447 addModule(new PrefSpellchecker(this));
3449 //for strftime validator
3450 PrefOutput * output = new PrefOutput(this);
3452 addModule(new PrefLatex(this));
3454 PrefConverters * converters = new PrefConverters(this);
3455 PrefFileformats * formats = new PrefFileformats(this);
3456 connect(formats, SIGNAL(formatsChanged()),
3457 converters, SLOT(updateGui()));
3458 addModule(converters);
3461 prefsPS->setCurrentPanel("User Interface");
3462 // FIXME: hack to work around resizing bug in Qt >= 4.2
3463 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3464 #if QT_VERSION >= 0x040200
3465 prefsPS->updateGeometry();
3468 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3470 bc().setApply(applyPB);
3471 bc().setCancel(closePB);
3472 bc().setRestore(restorePB);
3474 // initialize the strftime validator
3475 bc().addCheckedLineEdit(output->DateED);
3479 void GuiPreferences::addModule(PrefModule * module)
3481 LASSERT(module, return);
3482 if (module->category().isEmpty())
3483 prefsPS->addPanel(module, module->title());
3485 prefsPS->addPanel(module, module->title(), module->category());
3486 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3487 modules_.push_back(module);
3491 void GuiPreferences::change_adaptor()
3497 void GuiPreferences::applyRC(LyXRC & rc) const
3499 size_t end = modules_.size();
3500 for (size_t i = 0; i != end; ++i)
3501 modules_[i]->applyRC(rc);
3505 void GuiPreferences::updateRC(LyXRC const & rc)
3507 size_t const end = modules_.size();
3508 for (size_t i = 0; i != end; ++i)
3509 modules_[i]->updateRC(rc);
3513 void GuiPreferences::applyView()
3519 bool GuiPreferences::initialiseParams(string const &)
3522 formats_ = theFormats();
3523 converters_ = theConverters();
3524 converters_.update(formats_);
3525 movers_ = theMovers();
3527 update_screen_font_ = false;
3528 update_previews_ = false;
3531 // Make sure that the bc is in the INITIAL state
3532 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3539 void GuiPreferences::dispatchParams()
3542 rc_.write(ss, true);
3543 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3544 // issue prefsApplied signal. This will update the
3545 // localized screen font sizes.
3547 // FIXME: these need lfuns
3549 Author const & author =
3550 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3551 theBufferList().recordCurrentAuthor(author);
3553 theFormats() = formats_;
3555 theConverters() = converters_;
3556 theConverters().update(formats_);
3557 theConverters().buildGraph();
3558 theBufferList().invalidateConverterCache();
3560 theMovers() = movers_;
3562 vector<string>::const_iterator it = colors_.begin();
3563 vector<string>::const_iterator const end = colors_.end();
3564 for (; it != end; ++it)
3565 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
3568 if (update_screen_font_) {
3569 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
3570 // resets flag in case second apply in same dialog
3571 update_screen_font_ = false;
3574 if (update_previews_) {
3575 // resets flag in case second apply in same dialog
3576 theBufferList().updatePreviews();
3577 update_previews_ = false;
3580 // The Save button has been pressed
3582 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3586 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3588 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3592 void GuiPreferences::updateScreenFonts()
3594 update_screen_font_ = true;
3598 void GuiPreferences::updatePreviews()
3600 update_previews_ = true;
3604 QString GuiPreferences::browsebind(QString const & file) const
3606 return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
3607 QStringList(qt_("LyX bind files (*.bind)")));
3611 QString GuiPreferences::browseUI(QString const & file) const
3613 return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
3614 QStringList(qt_("LyX UI files (*.ui)")));
3618 QString GuiPreferences::browsekbmap(QString const & file) const
3620 return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
3621 QStringList(qt_("LyX keyboard maps (*.kmap)")));
3625 QString GuiPreferences::browse(QString const & file,
3626 QString const & title) const
3628 return browseFile(file, title, QStringList(), true);
3632 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3635 } // namespace frontend
3638 #include "moc_GuiPrefs.cpp"