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.zoom = 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.zoom != oldrc.zoom) {
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.zoom);
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 void PrefConverters::updateRC(LyXRC const & rc)
1706 cacheCB->setChecked(rc.use_converter_cache);
1707 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1708 needauthCB->setChecked(rc.use_converter_needauth);
1710 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1715 void PrefConverters::updateGui()
1717 QString const pattern("%1 -> %2");
1718 form_->formats().sort();
1719 form_->converters().update(form_->formats());
1720 // save current selection
1723 .arg(converterFromCO->currentText())
1724 .arg(converterToCO->currentText());
1726 converterFromCO->clear();
1727 converterToCO->clear();
1729 for (Format const & f : form_->formats()) {
1730 QString const name = toqstr(translateIfPossible(f.prettyname()));
1731 converterFromCO->addItem(name);
1732 converterToCO->addItem(name);
1735 // currentRowChanged(int) is also triggered when updating the listwidget
1736 // block signals to avoid unnecessary calls to switchConverter()
1737 convertersLW->blockSignals(true);
1738 convertersLW->clear();
1740 for (Converter const & c : form_->converters()) {
1741 QString const name =
1743 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1744 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1745 int type = form_->converters().getNumber(c.From()->name(),
1747 new QListWidgetItem(name, convertersLW, type);
1749 convertersLW->sortItems(Qt::AscendingOrder);
1750 convertersLW->blockSignals(false);
1752 // restore selection
1753 if (current != pattern.arg(QString()).arg(QString())) {
1754 QList<QListWidgetItem *> const item =
1755 convertersLW->findItems(current, Qt::MatchExactly);
1756 if (!item.isEmpty())
1757 convertersLW->setCurrentItem(item.at(0));
1760 // select first element if restoring failed
1761 if (convertersLW->currentRow() == -1)
1762 convertersLW->setCurrentRow(0);
1768 void PrefConverters::switchConverter()
1770 int const cnr = convertersLW->currentItem()->type();
1771 Converter const & c(form_->converters().get(cnr));
1772 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1773 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1774 converterED->setText(toqstr(c.command()));
1775 converterFlagED->setText(toqstr(c.flags()));
1781 void PrefConverters::changeConverter()
1787 void PrefConverters::updateButtons()
1789 if (form_->formats().empty())
1791 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1792 Format const & to = form_->formats().get(converterToCO->currentIndex());
1793 int const sel = form_->converters().getNumber(from.name(), to.name());
1794 bool const known = sel >= 0;
1795 bool const valid = !(converterED->text().isEmpty()
1796 || from.name() == to.name());
1801 if (convertersLW->count() > 0) {
1802 int const cnr = convertersLW->currentItem()->type();
1803 Converter const & c = form_->converters().get(cnr);
1804 old_command = c.command();
1805 old_flag = c.flags();
1808 string const new_command = fromqstr(converterED->text());
1809 string const new_flag = fromqstr(converterFlagED->text());
1811 bool modified = (old_command != new_command || old_flag != new_flag);
1813 converterModifyPB->setEnabled(valid && known && modified);
1814 converterNewPB->setEnabled(valid && !known);
1815 converterRemovePB->setEnabled(known);
1817 maxAgeLE->setEnabled(cacheCB->isChecked());
1818 maxAgeLA->setEnabled(cacheCB->isChecked());
1823 // specify unique from/to or it doesn't appear. This is really bad UI
1824 // this is why we can use the same function for both new and modify
1825 void PrefConverters::updateConverter()
1827 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1828 Format const & to = form_->formats().get(converterToCO->currentIndex());
1829 string const flags = fromqstr(converterFlagED->text());
1830 string const command = fromqstr(converterED->text());
1832 Converter const * old =
1833 form_->converters().getConverter(from.name(), to.name());
1834 form_->converters().add(from.name(), to.name(), command, flags);
1837 form_->converters().updateLast(form_->formats());
1841 // Remove all files created by this converter from the cache, since
1842 // the modified converter might create different files.
1843 ConverterCache::get().remove_all(from.name(), to.name());
1847 void PrefConverters::removeConverter()
1849 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1850 Format const & to = form_->formats().get(converterToCO->currentIndex());
1851 form_->converters().erase(from.name(), to.name());
1855 // Remove all files created by this converter from the cache, since
1856 // a possible new converter might create different files.
1857 ConverterCache::get().remove_all(from.name(), to.name());
1861 void PrefConverters::on_cacheCB_stateChanged(int state)
1863 maxAgeLE->setEnabled(state == Qt::Checked);
1864 maxAgeLA->setEnabled(state == Qt::Checked);
1869 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1871 needauthCB->setEnabled(!checked);
1875 void PrefConverters::on_needauthCB_toggled(bool checked)
1880 int ret = frontend::Alert::prompt(
1881 _("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!"),
1882 0, 0, _("&No"), _("&Yes"));
1886 needauthCB->setChecked(true);
1890 /////////////////////////////////////////////////////////////////////
1894 /////////////////////////////////////////////////////////////////////
1896 class FormatValidator : public QValidator
1899 FormatValidator(QWidget *, Formats const & f);
1900 void fixup(QString & input) const;
1901 QValidator::State validate(QString & input, int & pos) const;
1903 virtual QString toString(Format const & format) const = 0;
1905 Formats const & formats_;
1909 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1910 : QValidator(parent), formats_(f)
1915 void FormatValidator::fixup(QString & input) const
1917 Formats::const_iterator cit = formats_.begin();
1918 Formats::const_iterator end = formats_.end();
1919 for (; cit != end; ++cit) {
1920 QString const name = toString(*cit);
1921 if (distance(formats_.begin(), cit) == nr()) {
1929 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1931 Formats::const_iterator cit = formats_.begin();
1932 Formats::const_iterator end = formats_.end();
1933 bool unknown = true;
1934 for (; unknown && cit != end; ++cit) {
1935 QString const name = toString(*cit);
1936 if (distance(formats_.begin(), cit) != nr())
1937 unknown = name != input;
1940 if (unknown && !input.isEmpty())
1941 return QValidator::Acceptable;
1943 return QValidator::Intermediate;
1947 int FormatValidator::nr() const
1949 QComboBox * p = qobject_cast<QComboBox *>(parent());
1950 return p->itemData(p->currentIndex()).toInt();
1954 /////////////////////////////////////////////////////////////////////
1956 // FormatNameValidator
1958 /////////////////////////////////////////////////////////////////////
1960 class FormatNameValidator : public FormatValidator
1963 FormatNameValidator(QWidget * parent, Formats const & f)
1964 : FormatValidator(parent, f)
1967 QString toString(Format const & format) const
1969 return toqstr(format.name());
1974 /////////////////////////////////////////////////////////////////////
1976 // FormatPrettynameValidator
1978 /////////////////////////////////////////////////////////////////////
1980 class FormatPrettynameValidator : public FormatValidator
1983 FormatPrettynameValidator(QWidget * parent, Formats const & f)
1984 : FormatValidator(parent, f)
1987 QString toString(Format const & format) const
1989 return toqstr(translateIfPossible(format.prettyname()));
1994 /////////////////////////////////////////////////////////////////////
1998 /////////////////////////////////////////////////////////////////////
2000 PrefFileformats::PrefFileformats(GuiPreferences * form)
2001 : PrefModule(catFiles, N_("File Formats"), form)
2005 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
2006 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
2007 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
2008 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
2009 editorED->setValidator(new NoNewLineValidator(editorED));
2010 viewerED->setValidator(new NoNewLineValidator(viewerED));
2011 copierED->setValidator(new NoNewLineValidator(copierED));
2013 connect(documentCB, SIGNAL(clicked()),
2014 this, SLOT(setFlags()));
2015 connect(vectorCB, SIGNAL(clicked()),
2016 this, SLOT(setFlags()));
2017 connect(exportMenuCB, SIGNAL(clicked()),
2018 this, SLOT(setFlags()));
2019 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
2020 this, SLOT(updatePrettyname()));
2021 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
2022 this, SIGNAL(changed()));
2023 connect(defaultFormatCB, SIGNAL(activated(QString)),
2024 this, SIGNAL(changed()));
2025 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
2026 this, SIGNAL(changed()));
2027 connect(viewerCO, SIGNAL(activated(int)),
2028 this, SIGNAL(changed()));
2029 connect(editorCO, SIGNAL(activated(int)),
2030 this, SIGNAL(changed()));
2036 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
2038 if (shortcut.empty())
2041 string l10n_format =
2042 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
2043 return split(l10n_format, '|');
2049 void PrefFileformats::applyRC(LyXRC & rc) const
2051 QString const default_format = defaultFormatCB->itemData(
2052 defaultFormatCB->currentIndex()).toString();
2053 rc.default_view_format = fromqstr(default_format);
2054 QString const default_otf_format = defaultOTFFormatCB->itemData(
2055 defaultOTFFormatCB->currentIndex()).toString();
2056 rc.default_otf_view_format = fromqstr(default_otf_format);
2060 void PrefFileformats::updateRC(LyXRC const & rc)
2062 viewer_alternatives = rc.viewer_alternatives;
2063 editor_alternatives = rc.editor_alternatives;
2064 bool const init = defaultFormatCB->currentText().isEmpty();
2068 defaultFormatCB->findData(toqstr(rc.default_view_format));
2069 defaultFormatCB->setCurrentIndex(pos);
2070 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2071 defaultOTFFormatCB->setCurrentIndex(pos);
2072 defaultOTFFormatCB->setCurrentIndex(pos);
2077 void PrefFileformats::updateView()
2079 QString const current = formatsCB->currentText();
2080 QString const current_def = defaultFormatCB->currentText();
2081 QString const current_def_otf = defaultOTFFormatCB->currentText();
2083 // update comboboxes with formats
2084 formatsCB->blockSignals(true);
2085 defaultFormatCB->blockSignals(true);
2086 defaultOTFFormatCB->blockSignals(true);
2088 defaultFormatCB->clear();
2089 defaultOTFFormatCB->clear();
2090 form_->formats().sort();
2091 for (Format const & f : form_->formats()) {
2092 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2093 formatsCB->addItem(prettyname,
2094 QVariant(form_->formats().getNumber(f.name())));
2095 if (f.viewer().empty())
2097 if (form_->converters().isReachable("xhtml", f.name())
2098 || form_->converters().isReachable("dviluatex", f.name())
2099 || form_->converters().isReachable("luatex", f.name())
2100 || form_->converters().isReachable("xetex", f.name())) {
2101 defaultFormatCB->addItem(prettyname,
2102 QVariant(toqstr(f.name())));
2103 defaultOTFFormatCB->addItem(prettyname,
2104 QVariant(toqstr(f.name())));
2105 } else if (form_->converters().isReachable("latex", f.name())
2106 || form_->converters().isReachable("pdflatex", f.name()))
2107 defaultFormatCB->addItem(prettyname,
2108 QVariant(toqstr(f.name())));
2111 // restore selections
2112 int item = formatsCB->findText(current, Qt::MatchExactly);
2113 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2114 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2115 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2116 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2117 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2118 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2119 formatsCB->blockSignals(false);
2120 defaultFormatCB->blockSignals(false);
2121 defaultOTFFormatCB->blockSignals(false);
2125 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2127 if (form_->formats().empty())
2129 int const nr = formatsCB->itemData(i).toInt();
2130 Format const f = form_->formats().get(nr);
2132 formatED->setText(toqstr(f.name()));
2133 copierED->setText(toqstr(form_->movers().command(f.name())));
2134 extensionsED->setText(toqstr(f.extensions()));
2135 mimeED->setText(toqstr(f.mime()));
2136 shortcutED->setText(
2137 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2138 documentCB->setChecked((f.documentFormat()));
2139 vectorCB->setChecked((f.vectorFormat()));
2140 exportMenuCB->setChecked((f.inExportMenu()));
2141 exportMenuCB->setEnabled((f.documentFormat()));
2147 void PrefFileformats::setFlags()
2149 int flags = Format::none;
2150 if (documentCB->isChecked())
2151 flags |= Format::document;
2152 if (vectorCB->isChecked())
2153 flags |= Format::vector;
2154 if (exportMenuCB->isChecked())
2155 flags |= Format::export_menu;
2156 currentFormat().setFlags(flags);
2157 exportMenuCB->setEnabled(documentCB->isChecked());
2162 void PrefFileformats::on_copierED_textEdited(const QString & s)
2164 string const fmt = fromqstr(formatED->text());
2165 form_->movers().set(fmt, fromqstr(s));
2170 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2172 currentFormat().setExtensions(fromqstr(s));
2177 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2179 currentFormat().setViewer(fromqstr(s));
2184 void PrefFileformats::on_editorED_textEdited(const QString & s)
2186 currentFormat().setEditor(fromqstr(s));
2191 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2193 currentFormat().setMime(fromqstr(s));
2198 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2200 string const new_shortcut = fromqstr(s);
2201 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2202 currentFormat().shortcut()))
2204 currentFormat().setShortcut(new_shortcut);
2209 void PrefFileformats::on_formatED_editingFinished()
2211 string const newname = fromqstr(formatED->displayText());
2212 string const oldname = currentFormat().name();
2213 if (newname == oldname)
2215 if (form_->converters().formatIsUsed(oldname)) {
2216 Alert::error(_("Format in use"),
2217 _("You cannot change a format's short name "
2218 "if the format is used by a converter. "
2219 "Please remove the converter first."));
2224 currentFormat().setName(newname);
2229 void PrefFileformats::on_formatED_textChanged(const QString &)
2231 QString t = formatED->text();
2233 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2234 setValid(formatLA, valid);
2238 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2240 QString t = formatsCB->currentText();
2242 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2243 setValid(formatsLA, valid);
2247 void PrefFileformats::updatePrettyname()
2249 QString const newname = formatsCB->currentText();
2250 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2253 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2261 void updateComboBox(LyXRC::Alternatives const & alts,
2262 string const & fmt, QComboBox * combo)
2264 LyXRC::Alternatives::const_iterator it =
2266 if (it != alts.end()) {
2267 LyXRC::CommandSet const & cmds = it->second;
2268 LyXRC::CommandSet::const_iterator sit =
2270 LyXRC::CommandSet::const_iterator const sen =
2272 for (; sit != sen; ++sit) {
2273 QString const qcmd = toqstr(*sit);
2274 combo->addItem(qcmd, qcmd);
2281 void PrefFileformats::updateViewers()
2283 Format const f = currentFormat();
2284 viewerCO->blockSignals(true);
2286 viewerCO->addItem(qt_("None"), QString());
2287 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2288 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2289 viewerCO->blockSignals(false);
2291 int pos = viewerCO->findData(toqstr(f.viewer()));
2294 viewerED->setEnabled(false);
2295 viewerCO->setCurrentIndex(pos);
2297 viewerED->setEnabled(true);
2298 viewerED->setText(toqstr(f.viewer()));
2299 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2304 void PrefFileformats::updateEditors()
2306 Format const f = currentFormat();
2307 editorCO->blockSignals(true);
2309 editorCO->addItem(qt_("None"), QString());
2310 updateComboBox(editor_alternatives, f.name(), editorCO);
2311 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2312 editorCO->blockSignals(false);
2314 int pos = editorCO->findData(toqstr(f.editor()));
2317 editorED->setEnabled(false);
2318 editorCO->setCurrentIndex(pos);
2320 editorED->setEnabled(true);
2321 editorED->setText(toqstr(f.editor()));
2322 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2327 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2329 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2330 viewerED->setEnabled(custom);
2332 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2336 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2338 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2339 editorED->setEnabled(custom);
2341 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2345 Format & PrefFileformats::currentFormat()
2347 int const i = formatsCB->currentIndex();
2348 int const nr = formatsCB->itemData(i).toInt();
2349 return form_->formats().get(nr);
2353 void PrefFileformats::on_formatNewPB_clicked()
2355 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2357 formatsCB->setCurrentIndex(0);
2358 formatsCB->setFocus(Qt::OtherFocusReason);
2362 void PrefFileformats::on_formatRemovePB_clicked()
2364 int const i = formatsCB->currentIndex();
2365 int const nr = formatsCB->itemData(i).toInt();
2366 string const current_text = form_->formats().get(nr).name();
2367 if (form_->converters().formatIsUsed(current_text)) {
2368 Alert::error(_("Format in use"),
2369 _("Cannot remove a Format used by a Converter. "
2370 "Remove the converter first."));
2374 form_->formats().erase(current_text);
2377 on_formatsCB_editTextChanged(formatsCB->currentText());
2382 /////////////////////////////////////////////////////////////////////
2386 /////////////////////////////////////////////////////////////////////
2388 PrefLanguage::PrefLanguage(GuiPreferences * form)
2389 : PrefModule(catLanguage, N_("Language"), form)
2393 connect(visualCursorRB, SIGNAL(clicked()),
2394 this, SIGNAL(changed()));
2395 connect(logicalCursorRB, SIGNAL(clicked()),
2396 this, SIGNAL(changed()));
2397 connect(markForeignCB, SIGNAL(clicked()),
2398 this, SIGNAL(changed()));
2399 connect(autoBeginCB, SIGNAL(clicked()),
2400 this, SIGNAL(changed()));
2401 connect(autoEndCB, SIGNAL(clicked()),
2402 this, SIGNAL(changed()));
2403 connect(languagePackageCO, SIGNAL(activated(int)),
2404 this, SIGNAL(changed()));
2405 connect(languagePackageED, SIGNAL(textChanged(QString)),
2406 this, SIGNAL(changed()));
2407 connect(globalCB, SIGNAL(clicked()),
2408 this, SIGNAL(changed()));
2409 connect(startCommandED, SIGNAL(textChanged(QString)),
2410 this, SIGNAL(changed()));
2411 connect(endCommandED, SIGNAL(textChanged(QString)),
2412 this, SIGNAL(changed()));
2413 connect(uiLanguageCO, SIGNAL(activated(int)),
2414 this, SIGNAL(changed()));
2415 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2416 this, SIGNAL(changed()));
2417 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2418 this, SIGNAL(changed()));
2420 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2421 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2422 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2424 defaultDecimalPointLE->setInputMask("X; ");
2425 defaultDecimalPointLE->setMaxLength(1);
2427 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2428 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2430 QAbstractItemModel * language_model = guiApp->languageModel();
2431 language_model->sort(0);
2432 uiLanguageCO->blockSignals(true);
2433 uiLanguageCO->clear();
2434 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2435 for (int i = 0; i != language_model->rowCount(); ++i) {
2436 QModelIndex index = language_model->index(i, 0);
2437 // Filter the list based on the available translation and add
2438 // each language code only once
2439 string const name = fromqstr(index.data(Qt::UserRole).toString());
2440 Language const * lang = languages.getLanguage(name);
2443 // never remove the currently selected language
2444 if (name != form->rc().gui_language
2445 && name != lyxrc.gui_language
2446 && (!Messages::available(lang->code())
2447 || !lang->hasGuiSupport()))
2449 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2450 index.data(Qt::UserRole).toString());
2452 uiLanguageCO->blockSignals(false);
2456 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2458 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2459 qt_("The change of user interface language will be fully "
2460 "effective only after a restart."));
2464 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2466 languagePackageED->setEnabled(i == 2);
2470 void PrefLanguage::applyRC(LyXRC & rc) const
2472 rc.visual_cursor = visualCursorRB->isChecked();
2473 rc.mark_foreign_language = markForeignCB->isChecked();
2474 rc.language_auto_begin = autoBeginCB->isChecked();
2475 rc.language_auto_end = autoEndCB->isChecked();
2476 int const p = languagePackageCO->currentIndex();
2478 rc.language_package_selection = LyXRC::LP_AUTO;
2480 rc.language_package_selection = LyXRC::LP_BABEL;
2482 rc.language_package_selection = LyXRC::LP_CUSTOM;
2484 rc.language_package_selection = LyXRC::LP_NONE;
2485 rc.language_custom_package = fromqstr(languagePackageED->text());
2486 rc.language_global_options = globalCB->isChecked();
2487 rc.language_command_begin = fromqstr(startCommandED->text());
2488 rc.language_command_end = fromqstr(endCommandED->text());
2489 rc.gui_language = fromqstr(
2490 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2491 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2492 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2496 void PrefLanguage::updateRC(LyXRC const & rc)
2498 if (rc.visual_cursor)
2499 visualCursorRB->setChecked(true);
2501 logicalCursorRB->setChecked(true);
2502 markForeignCB->setChecked(rc.mark_foreign_language);
2503 autoBeginCB->setChecked(rc.language_auto_begin);
2504 autoEndCB->setChecked(rc.language_auto_end);
2505 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2506 languagePackageED->setText(toqstr(rc.language_custom_package));
2507 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2508 globalCB->setChecked(rc.language_global_options);
2509 startCommandED->setText(toqstr(rc.language_command_begin));
2510 endCommandED->setText(toqstr(rc.language_command_end));
2511 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2512 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2513 defaultLengthUnitCO->setCurrentIndex(pos);
2515 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2516 uiLanguageCO->blockSignals(true);
2517 uiLanguageCO->setCurrentIndex(pos);
2518 uiLanguageCO->blockSignals(false);
2522 /////////////////////////////////////////////////////////////////////
2524 // PrefUserInterface
2526 /////////////////////////////////////////////////////////////////////
2528 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2529 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2533 connect(uiFilePB, SIGNAL(clicked()),
2534 this, SLOT(selectUi()));
2535 connect(uiFileED, SIGNAL(textChanged(QString)),
2536 this, SIGNAL(changed()));
2537 connect(iconSetCO, SIGNAL(activated(int)),
2538 this, SIGNAL(changed()));
2539 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2540 this, SIGNAL(changed()));
2541 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2542 this, SIGNAL(changed()));
2543 connect(tooltipCB, SIGNAL(toggled(bool)),
2544 this, SIGNAL(changed()));
2545 lastfilesSB->setMaximum(maxlastfiles);
2547 iconSetCO->addItem(qt_("Default"), QString());
2548 iconSetCO->addItem(qt_("Classic"), "classic");
2549 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2551 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2552 useSystemThemeIconsCB->hide();
2557 void PrefUserInterface::applyRC(LyXRC & rc) const
2559 rc.icon_set = fromqstr(iconSetCO->itemData(
2560 iconSetCO->currentIndex()).toString());
2562 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2563 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2564 rc.num_lastfiles = lastfilesSB->value();
2565 rc.use_tooltip = tooltipCB->isChecked();
2569 void PrefUserInterface::updateRC(LyXRC const & rc)
2571 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2574 iconSetCO->setCurrentIndex(iconset);
2575 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2576 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2577 lastfilesSB->setValue(rc.num_lastfiles);
2578 tooltipCB->setChecked(rc.use_tooltip);
2582 void PrefUserInterface::selectUi()
2584 QString file = form_->browseUI(internalPath(uiFileED->text()));
2585 if (!file.isEmpty())
2586 uiFileED->setText(file);
2590 /////////////////////////////////////////////////////////////////////
2592 // PrefDocumentHandling
2594 /////////////////////////////////////////////////////////////////////
2596 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2597 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2601 connect(autoSaveCB, SIGNAL(toggled(bool)),
2602 autoSaveSB, SLOT(setEnabled(bool)));
2603 connect(autoSaveCB, SIGNAL(toggled(bool)),
2604 TextLabel1, SLOT(setEnabled(bool)));
2605 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2606 this, SIGNAL(changed()));
2607 connect(singleInstanceCB, SIGNAL(clicked()),
2608 this, SIGNAL(changed()));
2609 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2610 this, SIGNAL(changed()));
2611 connect(closeLastViewCO, SIGNAL(activated(int)),
2612 this, SIGNAL(changed()));
2613 connect(restoreCursorCB, SIGNAL(clicked()),
2614 this, SIGNAL(changed()));
2615 connect(loadSessionCB, SIGNAL(clicked()),
2616 this, SIGNAL(changed()));
2617 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2618 this, SIGNAL(changed()));
2619 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2620 this, SIGNAL(changed()));
2621 connect(autoSaveCB, SIGNAL(clicked()),
2622 this, SIGNAL(changed()));
2623 connect(backupCB, SIGNAL(clicked()),
2624 this, SIGNAL(changed()));
2625 connect(saveCompressedCB, SIGNAL(clicked()),
2626 this, SIGNAL(changed()));
2627 connect(saveOriginCB, SIGNAL(clicked()),
2628 this, SIGNAL(changed()));
2632 void PrefDocHandling::applyRC(LyXRC & rc) const
2634 rc.use_lastfilepos = restoreCursorCB->isChecked();
2635 rc.load_session = loadSessionCB->isChecked();
2636 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2637 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2638 rc.make_backup = backupCB->isChecked();
2639 rc.save_compressed = saveCompressedCB->isChecked();
2640 rc.save_origin = saveOriginCB->isChecked();
2641 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2642 rc.single_instance = singleInstanceCB->isChecked();
2643 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2645 switch (closeLastViewCO->currentIndex()) {
2647 rc.close_buffer_with_last_view = "yes";
2650 rc.close_buffer_with_last_view = "no";
2653 rc.close_buffer_with_last_view = "ask";
2661 void PrefDocHandling::updateRC(LyXRC const & rc)
2663 restoreCursorCB->setChecked(rc.use_lastfilepos);
2664 loadSessionCB->setChecked(rc.load_session);
2665 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2666 // convert to minutes
2667 bool autosave = rc.autosave > 0;
2668 int mins = rc.autosave / 60;
2671 autoSaveSB->setValue(mins);
2672 autoSaveCB->setChecked(autosave);
2673 autoSaveSB->setEnabled(autosave);
2674 backupCB->setChecked(rc.make_backup);
2675 saveCompressedCB->setChecked(rc.save_compressed);
2676 saveOriginCB->setChecked(rc.save_origin);
2677 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2678 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2679 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2680 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2681 if (rc.close_buffer_with_last_view == "yes")
2682 closeLastViewCO->setCurrentIndex(0);
2683 else if (rc.close_buffer_with_last_view == "no")
2684 closeLastViewCO->setCurrentIndex(1);
2685 else if (rc.close_buffer_with_last_view == "ask")
2686 closeLastViewCO->setCurrentIndex(2);
2690 void PrefDocHandling::on_clearSessionPB_clicked()
2692 guiApp->clearSession();
2697 /////////////////////////////////////////////////////////////////////
2701 /////////////////////////////////////////////////////////////////////
2703 PrefEdit::PrefEdit(GuiPreferences * form)
2704 : PrefModule(catEditing, N_("Control"), form)
2708 connect(cursorFollowsCB, SIGNAL(clicked()),
2709 this, SIGNAL(changed()));
2710 connect(scrollBelowCB, SIGNAL(clicked()),
2711 this, SIGNAL(changed()));
2712 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2713 this, SIGNAL(changed()));
2714 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2715 this, SIGNAL(changed()));
2716 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2717 this, SIGNAL(changed()));
2718 connect(macroEditStyleCO, SIGNAL(activated(int)),
2719 this, SIGNAL(changed()));
2720 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2721 this, SIGNAL(changed()));
2722 connect(fullscreenLimitGB, SIGNAL(clicked()),
2723 this, SIGNAL(changed()));
2724 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2725 this, SIGNAL(changed()));
2726 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2727 this, SIGNAL(changed()));
2728 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2729 this, SIGNAL(changed()));
2730 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2731 this, SIGNAL(changed()));
2732 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2733 this, SIGNAL(changed()));
2734 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2735 this, SIGNAL(changed()));
2739 void PrefEdit::applyRC(LyXRC & rc) const
2741 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2742 rc.scroll_below_document = scrollBelowCB->isChecked();
2743 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2744 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2745 rc.group_layouts = groupEnvironmentsCB->isChecked();
2746 switch (macroEditStyleCO->currentIndex()) {
2747 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2748 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2749 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2751 rc.cursor_width = cursorWidthSB->value();
2752 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2753 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2754 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2755 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2756 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2757 rc.full_screen_width = fullscreenWidthSB->value();
2758 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2762 void PrefEdit::updateRC(LyXRC const & rc)
2764 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2765 scrollBelowCB->setChecked(rc.scroll_below_document);
2766 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2767 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2768 groupEnvironmentsCB->setChecked(rc.group_layouts);
2769 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2770 cursorWidthSB->setValue(rc.cursor_width);
2771 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2772 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2773 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2774 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2775 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2776 fullscreenWidthSB->setValue(rc.full_screen_width);
2777 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2781 /////////////////////////////////////////////////////////////////////
2785 /////////////////////////////////////////////////////////////////////
2788 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2790 Ui::shortcutUi::setupUi(this);
2791 QDialog::setModal(true);
2795 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2796 : PrefModule(catEditing, N_("Shortcuts"), form),
2797 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2802 shortcutsTW->setColumnCount(2);
2803 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2804 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2805 shortcutsTW->setSortingEnabled(true);
2806 // Multi-selection can be annoying.
2807 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2809 connect(bindFilePB, SIGNAL(clicked()),
2810 this, SLOT(selectBind()));
2811 connect(bindFileED, SIGNAL(textChanged(QString)),
2812 this, SIGNAL(changed()));
2814 shortcut_ = new GuiShortcutDialog(this);
2815 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2816 shortcut_bc_.setOK(shortcut_->okPB);
2817 shortcut_bc_.setCancel(shortcut_->cancelPB);
2819 connect(shortcut_->okPB, SIGNAL(clicked()),
2820 this, SIGNAL(changed()));
2821 connect(shortcut_->cancelPB, SIGNAL(clicked()),
2822 shortcut_, SLOT(reject()));
2823 connect(shortcut_->clearPB, SIGNAL(clicked()),
2824 this, SLOT(shortcutClearPressed()));
2825 connect(shortcut_->removePB, SIGNAL(clicked()),
2826 this, SLOT(shortcutRemovePressed()));
2827 connect(shortcut_->okPB, SIGNAL(clicked()),
2828 this, SLOT(shortcutOkPressed()));
2829 connect(shortcut_->cancelPB, SIGNAL(clicked()),
2830 this, SLOT(shortcutCancelPressed()));
2834 void PrefShortcuts::applyRC(LyXRC & rc) const
2836 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2837 // write user_bind and user_unbind to .lyx/bind/user.bind
2838 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2839 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2840 lyxerr << "LyX could not create the user bind directory '"
2841 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2844 if (!bind_dir.isDirWritable()) {
2845 lyxerr << "LyX could not write to the user bind directory '"
2846 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2849 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2850 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2851 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2852 // immediately apply the keybindings. Why this is not done before?
2853 // The good thing is that the menus are updated automatically.
2854 theTopLevelKeymap().clear();
2855 theTopLevelKeymap().read("site");
2856 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2857 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2861 void PrefShortcuts::updateRC(LyXRC const & rc)
2863 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2865 system_bind_.clear();
2867 user_unbind_.clear();
2868 system_bind_.read("site");
2869 system_bind_.read(rc.bind_file);
2870 // \unbind in user.bind is added to user_unbind_
2871 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2872 updateShortcutsTW();
2876 void PrefShortcuts::updateShortcutsTW()
2878 shortcutsTW->clear();
2880 editItem_ = new QTreeWidgetItem(shortcutsTW);
2881 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2882 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2884 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2885 mathItem_->setText(0, qt_("Mathematical Symbols"));
2886 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2888 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2889 bufferItem_->setText(0, qt_("Document and Window"));
2890 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2892 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2893 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2894 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2896 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2897 systemItem_->setText(0, qt_("System and Miscellaneous"));
2898 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2900 // listBindings(unbound=true) lists all bound and unbound lfuns
2901 // Items in this list is tagged by its source.
2902 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2904 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2906 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2907 KeyMap::UserUnbind);
2908 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2909 user_bindinglist.end());
2910 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2911 user_unbindinglist.end());
2913 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2914 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2915 for (; it != it_end; ++it)
2916 insertShortcutItem(it->request, it->sequence, it->tag);
2918 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2919 on_shortcutsTW_itemSelectionChanged();
2920 on_searchLE_textEdited();
2921 shortcutsTW->resizeColumnToContents(0);
2926 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2928 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2933 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2935 // Hide rebound system settings that are empty
2936 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2940 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2942 item->setData(0, Qt::UserRole, QVariant(tag));
2946 case KeyMap::System:
2948 case KeyMap::UserBind:
2951 case KeyMap::UserUnbind:
2952 font.setStrikeOut(true);
2954 // this item is not displayed now.
2955 case KeyMap::UserExtraUnbind:
2956 font.setStrikeOut(true);
2959 item->setHidden(isAlwaysHidden(*item));
2960 item->setFont(1, font);
2964 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2965 KeySequence const & seq, KeyMap::ItemType tag)
2967 FuncCode const action = lfun.action();
2968 string const action_name = lyxaction.getActionName(action);
2969 QString const lfun_name = toqstr(from_utf8(action_name)
2970 + ' ' + lfun.argument());
2971 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
2973 QTreeWidgetItem * newItem = 0;
2974 // for unbind items, try to find an existing item in the system bind list
2975 if (tag == KeyMap::UserUnbind) {
2976 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
2977 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
2978 for (int i = 0; i < items.size(); ++i) {
2979 if (items[i]->text(1) == shortcut) {
2984 // if not found, this unbind item is KeyMap::UserExtraUnbind
2985 // Such an item is not displayed to avoid confusion (what is
2986 // unmatched removed?).
2992 switch(lyxaction.getActionType(action)) {
2993 case LyXAction::Hidden:
2995 case LyXAction::Edit:
2996 newItem = new QTreeWidgetItem(editItem_);
2998 case LyXAction::Math:
2999 newItem = new QTreeWidgetItem(mathItem_);
3001 case LyXAction::Buffer:
3002 newItem = new QTreeWidgetItem(bufferItem_);
3004 case LyXAction::Layout:
3005 newItem = new QTreeWidgetItem(layoutItem_);
3007 case LyXAction::System:
3008 newItem = new QTreeWidgetItem(systemItem_);
3011 // this should not happen
3012 newItem = new QTreeWidgetItem(shortcutsTW);
3016 newItem->setText(0, lfun_name);
3017 newItem->setText(1, shortcut);
3018 // record BindFile representation to recover KeySequence when needed.
3019 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
3020 setItemType(newItem, tag);
3025 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
3027 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3028 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
3029 modifyPB->setEnabled(!items.isEmpty());
3030 if (items.isEmpty())
3033 if (itemType(*items[0]) == KeyMap::UserUnbind)
3034 removePB->setText(qt_("Res&tore"));
3036 removePB->setText(qt_("Remo&ve"));
3040 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3046 void PrefShortcuts::modifyShortcut()
3048 QTreeWidgetItem * item = shortcutsTW->currentItem();
3049 if (item->flags() & Qt::ItemIsSelectable) {
3050 shortcut_->lfunLE->setText(item->text(0));
3051 save_lfun_ = item->text(0).trimmed();
3052 shortcut_->shortcutWG->setText(item->text(1));
3054 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3055 shortcut_->shortcutWG->setKeySequence(seq);
3056 shortcut_->shortcutWG->setFocus();
3062 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3064 // list of items that match lfun
3065 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3066 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3067 for (int i = 0; i < items.size(); ++i) {
3068 QTreeWidgetItem * item = items[i];
3069 if (isAlwaysHidden(*item)) {
3070 setItemType(item, KeyMap::System);
3072 shortcutsTW->setCurrentItem(item);
3079 void PrefShortcuts::removeShortcut()
3081 // it seems that only one item can be selected, but I am
3082 // removing all selected items anyway.
3083 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3084 for (int i = 0; i < items.size(); ++i) {
3085 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3086 string lfun = fromqstr(items[i]->text(0));
3087 FuncRequest func = lyxaction.lookupFunc(lfun);
3089 switch (itemType(*items[i])) {
3090 case KeyMap::System: {
3091 // for system bind, we do not touch the item
3092 // but add an user unbind item
3093 user_unbind_.bind(shortcut, func);
3094 setItemType(items[i], KeyMap::UserUnbind);
3095 removePB->setText(qt_("Res&tore"));
3098 case KeyMap::UserBind: {
3099 // for user_bind, we remove this bind
3100 QTreeWidgetItem * parent = items[i]->parent();
3101 int itemIdx = parent->indexOfChild(items[i]);
3102 parent->takeChild(itemIdx);
3104 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3106 shortcutsTW->scrollToItem(parent);
3107 user_bind_.unbind(shortcut, func);
3108 // If this user binding hid an empty system binding, unhide the
3109 // latter and select it.
3110 unhideEmpty(items[i]->text(0), true);
3113 case KeyMap::UserUnbind: {
3114 // for user_unbind, we remove the unbind, and the item
3115 // become KeyMap::System again.
3117 seq.parse(shortcut);
3118 // Ask the user to replace current binding
3119 if (!validateNewShortcut(func, seq, QString()))
3121 user_unbind_.unbind(shortcut, func);
3122 setItemType(items[i], KeyMap::System);
3123 removePB->setText(qt_("Remo&ve"));
3126 case KeyMap::UserExtraUnbind: {
3127 // for user unbind that is not in system bind file,
3128 // remove this unbind file
3129 QTreeWidgetItem * parent = items[i]->parent();
3130 parent->takeChild(parent->indexOfChild(items[i]));
3131 user_unbind_.unbind(shortcut, func);
3138 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3140 for (int i = 0; i < items.size(); ++i) {
3141 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3142 string lfun = fromqstr(items[i]->text(0));
3143 FuncRequest func = lyxaction.lookupFunc(lfun);
3145 switch (itemType(*items[i])) {
3146 case KeyMap::System:
3147 // for system bind, we do not touch the item
3148 // but add an user unbind item
3149 user_unbind_.bind(shortcut, func);
3150 setItemType(items[i], KeyMap::UserUnbind);
3153 case KeyMap::UserBind: {
3154 // for user_bind, we remove this bind
3155 QTreeWidgetItem * parent = items[i]->parent();
3156 int itemIdx = parent->indexOfChild(items[i]);
3157 parent->takeChild(itemIdx);
3158 user_bind_.unbind(shortcut, func);
3159 unhideEmpty(items[i]->text(0), false);
3169 void PrefShortcuts::selectBind()
3171 QString file = form_->browsebind(internalPath(bindFileED->text()));
3172 if (!file.isEmpty()) {
3173 bindFileED->setText(file);
3174 system_bind_ = KeyMap();
3175 system_bind_.read(fromqstr(file));
3176 updateShortcutsTW();
3181 void PrefShortcuts::on_modifyPB_pressed()
3187 void PrefShortcuts::on_newPB_pressed()
3189 shortcut_->lfunLE->clear();
3190 shortcut_->shortcutWG->reset();
3191 save_lfun_ = QString();
3196 void PrefShortcuts::on_removePB_pressed()
3203 void PrefShortcuts::on_searchLE_textEdited()
3205 if (searchLE->text().isEmpty()) {
3206 // show all hidden items
3207 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3209 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3210 // close all categories
3211 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3212 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3215 // search both columns
3216 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3217 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3218 matched += shortcutsTW->findItems(searchLE->text(),
3219 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3221 // hide everyone (to avoid searching in matched QList repeatedly
3222 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3224 shortcutsTW->setItemHidden(*it++, true);
3225 // show matched items
3226 for (int i = 0; i < matched.size(); ++i)
3227 if (!isAlwaysHidden(*matched[i])) {
3228 shortcutsTW->setItemHidden(matched[i], false);
3229 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3234 docstring makeCmdString(FuncRequest const & f)
3236 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3237 if (!f.argument().empty())
3238 actionStr += " " + f.argument();
3243 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3245 FuncRequest res = user_bind_.getBinding(k);
3246 if (res.action() != LFUN_UNKNOWN_ACTION)
3248 res = system_bind_.getBinding(k);
3249 // Check if it is unbound. Note: user_unbind_ can only unbind one
3250 // FuncRequest per key sequence.
3251 if (user_unbind_.getBinding(k) == res)
3252 return FuncRequest::unknown;
3257 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3258 KeySequence const & k,
3259 QString const & lfun_to_modify)
3261 if (func.action() == LFUN_UNKNOWN_ACTION) {
3262 Alert::error(_("Failed to create shortcut"),
3263 _("Unknown or invalid LyX function"));
3267 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3268 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3269 // and how it is used in GuiPrefs::shortcutOkPressed.
3270 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3271 Alert::error(_("Failed to create shortcut"),
3272 _("This LyX function is hidden and cannot be bound."));
3276 if (k.length() == 0) {
3277 Alert::error(_("Failed to create shortcut"),
3278 _("Invalid or empty key sequence"));
3282 FuncRequest oldBinding = currentBinding(k);
3283 if (oldBinding == func)
3284 // nothing to change
3287 // make sure this key isn't already bound---and, if so, prompt user
3288 // (exclude the lfun the user already wants to modify)
3289 docstring const action_string = makeCmdString(oldBinding);
3290 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3291 && lfun_to_modify != toqstr(action_string)) {
3292 docstring const new_action_string = makeCmdString(func);
3293 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3295 "Are you sure you want to unbind the "
3296 "current shortcut and bind it to %3$s?"),
3297 k.print(KeySequence::ForGui), action_string,
3299 int ret = Alert::prompt(_("Redefine shortcut?"),
3300 text, 0, 1, _("&Redefine"), _("&Cancel"));
3303 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3304 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3305 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3306 deactivateShortcuts(items);
3312 void PrefShortcuts::shortcutOkPressed()
3314 QString const new_lfun = shortcut_->lfunLE->text();
3315 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3316 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3318 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3319 // "modify", or is empty if they clicked "new" (which I do not really like)
3320 if (!validateNewShortcut(func, k, save_lfun_))
3323 if (!save_lfun_.isEmpty()) {
3324 // real modification of the lfun's shortcut,
3325 // so remove the previous one
3326 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3327 deactivateShortcuts(to_modify);
3330 shortcut_->accept();
3332 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3334 user_bind_.bind(&k, func);
3335 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3336 shortcutsTW->setItemExpanded(item->parent(), true);
3337 shortcutsTW->setCurrentItem(item);
3338 shortcutsTW->scrollToItem(item);
3340 Alert::error(_("Failed to create shortcut"),
3341 _("Can not insert shortcut to the list"));
3347 void PrefShortcuts::shortcutCancelPressed()
3349 shortcut_->shortcutWG->reset();
3353 void PrefShortcuts::shortcutClearPressed()
3355 shortcut_->shortcutWG->reset();
3359 void PrefShortcuts::shortcutRemovePressed()
3361 shortcut_->shortcutWG->removeFromSequence();
3365 /////////////////////////////////////////////////////////////////////
3369 /////////////////////////////////////////////////////////////////////
3371 PrefIdentity::PrefIdentity(GuiPreferences * form)
3372 : PrefModule(QString(), N_("Identity"), form)
3376 connect(nameED, SIGNAL(textChanged(QString)),
3377 this, SIGNAL(changed()));
3378 connect(emailED, SIGNAL(textChanged(QString)),
3379 this, SIGNAL(changed()));
3381 nameED->setValidator(new NoNewLineValidator(nameED));
3382 emailED->setValidator(new NoNewLineValidator(emailED));
3386 void PrefIdentity::applyRC(LyXRC & rc) const
3388 rc.user_name = fromqstr(nameED->text());
3389 rc.user_email = fromqstr(emailED->text());
3393 void PrefIdentity::updateRC(LyXRC const & rc)
3395 nameED->setText(toqstr(rc.user_name));
3396 emailED->setText(toqstr(rc.user_email));
3401 /////////////////////////////////////////////////////////////////////
3405 /////////////////////////////////////////////////////////////////////
3407 GuiPreferences::GuiPreferences(GuiView & lv)
3408 : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false),
3409 update_previews_(false)
3413 QDialog::setModal(false);
3415 connect(savePB, SIGNAL(clicked()), this, SLOT(slotOK()));
3416 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
3417 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
3418 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
3420 addModule(new PrefUserInterface(this));
3421 addModule(new PrefDocHandling(this));
3422 addModule(new PrefEdit(this));
3423 addModule(new PrefShortcuts(this));
3424 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3425 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3426 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3427 addModule(screenfonts);
3428 addModule(new PrefColors(this));
3429 addModule(new PrefDisplay(this));
3430 addModule(new PrefInput(this));
3431 addModule(new PrefCompletion(this));
3433 addModule(new PrefPaths(this));
3435 addModule(new PrefIdentity(this));
3437 addModule(new PrefLanguage(this));
3438 addModule(new PrefSpellchecker(this));
3440 //for strftime validator
3441 PrefOutput * output = new PrefOutput(this);
3443 addModule(new PrefLatex(this));
3445 PrefConverters * converters = new PrefConverters(this);
3446 PrefFileformats * formats = new PrefFileformats(this);
3447 connect(formats, SIGNAL(formatsChanged()),
3448 converters, SLOT(updateGui()));
3449 addModule(converters);
3452 prefsPS->setCurrentPanel("User Interface");
3453 // FIXME: hack to work around resizing bug in Qt >= 4.2
3454 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3455 #if QT_VERSION >= 0x040200
3456 prefsPS->updateGeometry();
3459 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3461 bc().setApply(applyPB);
3462 bc().setCancel(closePB);
3463 bc().setRestore(restorePB);
3465 // initialize the strftime validator
3466 bc().addCheckedLineEdit(output->DateED);
3470 void GuiPreferences::addModule(PrefModule * module)
3472 LASSERT(module, return);
3473 if (module->category().isEmpty())
3474 prefsPS->addPanel(module, module->title());
3476 prefsPS->addPanel(module, module->title(), module->category());
3477 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3478 modules_.push_back(module);
3482 void GuiPreferences::change_adaptor()
3488 void GuiPreferences::applyRC(LyXRC & rc) const
3490 size_t end = modules_.size();
3491 for (size_t i = 0; i != end; ++i)
3492 modules_[i]->applyRC(rc);
3496 void GuiPreferences::updateRC(LyXRC const & rc)
3498 size_t const end = modules_.size();
3499 for (size_t i = 0; i != end; ++i)
3500 modules_[i]->updateRC(rc);
3504 void GuiPreferences::applyView()
3510 bool GuiPreferences::initialiseParams(string const &)
3513 formats_ = theFormats();
3514 converters_ = theConverters();
3515 converters_.update(formats_);
3516 movers_ = theMovers();
3518 update_screen_font_ = false;
3519 update_previews_ = false;
3522 // Make sure that the bc is in the INITIAL state
3523 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3530 void GuiPreferences::dispatchParams()
3533 rc_.write(ss, true);
3534 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3535 // issue prefsApplied signal. This will update the
3536 // localized screen font sizes.
3538 // FIXME: these need lfuns
3540 Author const & author =
3541 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3542 theBufferList().recordCurrentAuthor(author);
3544 theFormats() = formats_;
3546 theConverters() = converters_;
3547 theConverters().update(formats_);
3548 theConverters().buildGraph();
3549 theBufferList().invalidateConverterCache();
3551 theMovers() = movers_;
3553 vector<string>::const_iterator it = colors_.begin();
3554 vector<string>::const_iterator const end = colors_.end();
3555 for (; it != end; ++it)
3556 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
3559 if (update_screen_font_) {
3560 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
3561 // resets flag in case second apply in same dialog
3562 update_screen_font_ = false;
3565 if (update_previews_) {
3566 // resets flag in case second apply in same dialog
3567 theBufferList().updatePreviews();
3568 update_previews_ = false;
3571 // The Save button has been pressed
3573 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3577 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3579 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3583 void GuiPreferences::updateScreenFonts()
3585 update_screen_font_ = true;
3589 void GuiPreferences::updatePreviews()
3591 update_previews_ = true;
3595 QString GuiPreferences::browsebind(QString const & file) const
3597 return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
3598 QStringList(qt_("LyX bind files (*.bind)")));
3602 QString GuiPreferences::browseUI(QString const & file) const
3604 return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
3605 QStringList(qt_("LyX UI files (*.ui)")));
3609 QString GuiPreferences::browsekbmap(QString const & file) const
3611 return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
3612 QStringList(qt_("LyX keyboard maps (*.kmap)")));
3616 QString GuiPreferences::browse(QString const & file,
3617 QString const & title) const
3619 return browseFile(file, title, QStringList(), true);
3623 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3626 } // namespace frontend
3629 #include "moc_GuiPrefs.cpp"