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