3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
16 #include "ColorCache.h"
17 #include "FileDialog.h"
18 #include "GuiApplication.h"
19 #include "GuiFontExample.h"
20 #include "GuiFontLoader.h"
21 #include "GuiKeySymbol.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
26 #include "BufferList.h"
29 #include "ConverterCache.h"
30 #include "FontEnums.h"
31 #include "FuncRequest.h"
33 #include "KeySequence.h"
35 #include "LyXAction.h"
37 #include "PanelStack.h"
39 #include "SpellChecker.h"
41 #include "support/debug.h"
42 #include "support/FileName.h"
43 #include "support/filetools.h"
44 #include "support/gettext.h"
45 #include "support/lassert.h"
46 #include "support/lstrings.h"
47 #include "support/Messages.h"
48 #include "support/os.h"
49 #include "support/Package.h"
51 #include "graphics/GraphicsTypes.h"
53 #include "frontends/alert.h"
54 #include "frontends/Application.h"
55 #include "frontends/FontLoader.h"
57 #include <QAbstractItemModel>
59 #include <QColorDialog>
60 #include <QFontDatabase>
61 #include <QHeaderView>
63 #include <QMessageBox>
64 #include <QPushButton>
67 #include <QTreeWidget>
68 #include <QTreeWidgetItem>
79 using namespace lyx::support;
80 using namespace lyx::support::os;
85 /////////////////////////////////////////////////////////////////////
89 /////////////////////////////////////////////////////////////////////
91 /** Launch a file dialog and return the chosen file.
92 filename: a suggested filename.
93 title: the title of the dialog.
95 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
97 QString browseFile(QString const & filename,
98 QString const & title,
99 QStringList const & filters,
101 QString const & label1 = QString(),
102 QString const & dir1 = QString(),
103 QString const & label2 = QString(),
104 QString const & dir2 = QString(),
105 QString const & fallback_dir = QString())
107 QString lastPath = ".";
108 if (!filename.isEmpty())
109 lastPath = onlyPath(filename);
110 else if(!fallback_dir.isEmpty())
111 lastPath = fallback_dir;
113 FileDialog dlg(title);
114 dlg.setButton1(label1, dir1);
115 dlg.setButton2(label2, dir2);
117 FileDialog::Result result;
120 result = dlg.save(lastPath, filters, onlyFileName(filename));
122 result = dlg.open(lastPath, filters, onlyFileName(filename));
124 return result.second;
128 /** Wrapper around browseFile which tries to provide a filename
129 * relative to the user or system directory. The dir, name and ext
130 * parameters have the same meaning as in the
131 * support::LibFileSearch function.
133 QString browseLibFile(QString const & dir,
134 QString const & name,
136 QString const & title,
137 QStringList const & filters)
140 QString const label1 = qt_("&System files");
142 toqstr(addName(package().system_support().absFileName(), fromqstr(dir)));
144 QString const label2 = qt_("&User files");
146 toqstr(addName(package().user_support().absFileName(), fromqstr(dir)));
148 QString const result = browseFile(toqstr(
149 libFileSearch(dir, name, ext).absFileName()),
150 title, filters, false, dir1, dir2, QString(), QString(), dir1);
152 // remove the extension if it is the default one
154 if (getExtension(result) == ext)
155 noextresult = removeExtension(result);
157 noextresult = result;
159 // remove the directory, if it is the default one
160 QString const file = onlyFileName(noextresult);
161 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
168 /** Launch a file dialog and return the chosen directory.
169 pathname: a suggested pathname.
170 title: the title of the dialog.
171 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
173 QString browseDir(QString const & pathname,
174 QString const & title,
175 QString const & label1 = QString(),
176 QString const & dir1 = QString(),
177 QString const & label2 = QString(),
178 QString const & dir2 = QString())
180 QString lastPath = ".";
181 if (!pathname.isEmpty())
182 lastPath = onlyPath(pathname);
184 FileDialog dlg(title);
185 dlg.setButton1(label1, dir1);
186 dlg.setButton2(label2, dir2);
188 FileDialog::Result const result =
189 dlg.opendir(lastPath, onlyFileName(pathname));
191 return result.second;
195 } // namespace frontend
198 QString browseRelToParent(QString const & filename, QString const & relpath,
199 QString const & title, QStringList const & filters, bool save,
200 QString const & label1, QString const & dir1,
201 QString const & label2, QString const & dir2)
203 QString const fname = makeAbsPath(filename, relpath);
205 QString const outname =
206 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
208 QString const reloutname =
209 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
211 if (reloutname.startsWith("../"))
218 QString browseRelToSub(QString const & filename, QString const & relpath,
219 QString const & title, QStringList const & filters, bool save,
220 QString const & label1, QString const & dir1,
221 QString const & label2, QString const & dir2)
223 QString const fname = makeAbsPath(filename, relpath);
225 QString const outname =
226 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
228 QString const reloutname =
229 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
231 QString testname = reloutname;
232 testname.remove(QRegExp("^(\\.\\./)+"));
234 if (testname.contains("/"))
242 /////////////////////////////////////////////////////////////////////
246 /////////////////////////////////////////////////////////////////////
250 QString const catLookAndFeel = N_("Look & Feel");
251 QString const catEditing = N_("Editing");
252 QString const catLanguage = N_("Language Settings");
253 QString const catOutput = N_("Output");
254 QString const catFiles = N_("File Handling");
256 static void parseFontName(QString const & mangled0,
257 string & name, string & foundry)
259 string mangled = fromqstr(mangled0);
260 size_t const idx = mangled.find('[');
261 if (idx == string::npos || idx == 0) {
265 name = mangled.substr(0, idx - 1),
266 foundry = mangled.substr(idx + 1, mangled.size() - idx - 2);
271 static void setComboxFont(QComboBox * cb, string const & family,
272 string const & foundry)
274 QString fontname = toqstr(family);
275 if (!foundry.empty())
276 fontname += " [" + toqstr(foundry) + ']';
278 for (int i = 0; i != cb->count(); ++i) {
279 if (cb->itemText(i) == fontname) {
280 cb->setCurrentIndex(i);
285 // Try matching without foundry name
287 // We count in reverse in order to prefer the Xft foundry
288 for (int i = cb->count(); --i >= 0;) {
289 string name, fnt_foundry;
290 parseFontName(cb->itemText(i), name, fnt_foundry);
291 if (compare_ascii_no_case(name, family) == 0) {
292 cb->setCurrentIndex(i);
297 // family alone can contain e.g. "Helvetica [Adobe]"
298 string tmpname, tmpfoundry;
299 parseFontName(toqstr(family), tmpname, tmpfoundry);
301 // We count in reverse in order to prefer the Xft foundry
302 for (int i = cb->count(); --i >= 0; ) {
303 string name, fnt_foundry;
304 parseFontName(cb->itemText(i), name, fnt_foundry);
305 if (compare_ascii_no_case(name, fnt_foundry) == 0) {
306 cb->setCurrentIndex(i);
311 // Bleh, default fonts, and the names couldn't be found. Hack
316 QString const font_family = toqstr(family);
317 if (font_family == guiApp->romanFontName()) {
318 font.setStyleHint(QFont::Serif);
319 font.setFamily(font_family);
320 } else if (font_family == guiApp->sansFontName()) {
321 font.setStyleHint(QFont::SansSerif);
322 font.setFamily(font_family);
323 } else if (font_family == guiApp->typewriterFontName()) {
324 font.setStyleHint(QFont::TypeWriter);
325 font.setFamily(font_family);
327 LYXERR0("FAILED to find the default font: '"
328 << foundry << "', '" << family << '\'');
332 QFontInfo info(font);
333 string default_font_name, dummyfoundry;
334 parseFontName(info.family(), default_font_name, dummyfoundry);
335 LYXERR0("Apparent font is " << default_font_name);
337 for (int i = 0; i < cb->count(); ++i) {
338 LYXERR0("Looking at " << cb->itemText(i));
339 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
340 default_font_name) == 0) {
341 cb->setCurrentIndex(i);
346 LYXERR0("FAILED to find the font: '"
347 << foundry << "', '" << family << '\'');
351 /////////////////////////////////////////////////////////////////////
355 /////////////////////////////////////////////////////////////////////
357 PrefOutput::PrefOutput(GuiPreferences * form)
358 : PrefModule(catOutput, N_("General"), form)
362 dviCB->setValidator(new NoNewLineValidator(dviCB));
363 pdfCB->setValidator(new NoNewLineValidator(pdfCB));
365 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
366 this, SIGNAL(changed()));
367 connect(overwriteCO, SIGNAL(activated(int)),
368 this, SIGNAL(changed()));
369 connect(dviCB, SIGNAL(editTextChanged(QString)),
370 this, SIGNAL(changed()));
371 connect(pdfCB, SIGNAL(editTextChanged(QString)),
372 this, SIGNAL(changed()));
373 connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
374 this, SIGNAL(changed()));
375 connect(printerLandscapeED, SIGNAL(textChanged(QString)),
376 this, SIGNAL(changed()));
377 connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
378 this, SIGNAL(changed()));
380 printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
381 printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
382 printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
385 dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
386 dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
387 dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
388 dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
390 pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
391 pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
392 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
393 pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
394 pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
395 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
396 pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
400 void PrefOutput::applyRC(LyXRC & rc) const
402 rc.plaintext_linelen = plaintextLinelengthSB->value();
403 rc.forward_search_dvi = fromqstr(dviCB->currentText());
404 rc.forward_search_pdf = fromqstr(pdfCB->currentText());
406 switch (overwriteCO->currentIndex()) {
408 rc.export_overwrite = NO_FILES;
411 rc.export_overwrite = MAIN_FILE;
414 rc.export_overwrite = ALL_FILES;
418 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
419 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
420 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
424 void PrefOutput::updateRC(LyXRC const & rc)
426 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
427 dviCB->setEditText(toqstr(rc.forward_search_dvi));
428 pdfCB->setEditText(toqstr(rc.forward_search_pdf));
430 switch (rc.export_overwrite) {
432 overwriteCO->setCurrentIndex(0);
435 overwriteCO->setCurrentIndex(1);
438 overwriteCO->setCurrentIndex(2);
442 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
443 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
444 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
448 /////////////////////////////////////////////////////////////////////
452 /////////////////////////////////////////////////////////////////////
454 PrefInput::PrefInput(GuiPreferences * form)
455 : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
459 connect(keymapCB, SIGNAL(clicked()),
460 this, SIGNAL(changed()));
461 connect(firstKeymapED, SIGNAL(textChanged(QString)),
462 this, SIGNAL(changed()));
463 connect(secondKeymapED, SIGNAL(textChanged(QString)),
464 this, SIGNAL(changed()));
465 connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)),
466 this, SIGNAL(changed()));
467 connect(scrollzoomEnableCB, SIGNAL(clicked()),
468 this, SIGNAL(changed()));
469 connect(scrollzoomValueCO, SIGNAL(activated(int)),
470 this, SIGNAL(changed()));
471 connect(dontswapCB, SIGNAL(toggled(bool)),
472 this, SIGNAL(changed()));
473 connect(mmPasteCB, SIGNAL(toggled(bool)),
474 this, SIGNAL(changed()));
476 // reveal checkbox for switching Ctrl and Meta on Mac:
479 #if QT_VERSION > 0x040600
483 dontswapCB->setVisible(swapcb);
487 void PrefInput::applyRC(LyXRC & rc) const
489 // FIXME: can derive CB from the two EDs
490 rc.use_kbmap = keymapCB->isChecked();
491 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
492 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
493 rc.mouse_wheel_speed = mouseWheelSpeedSB->value();
494 if (scrollzoomEnableCB->isChecked()) {
495 switch (scrollzoomValueCO->currentIndex()) {
497 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_CTRL;
500 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_SHIFT;
503 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_ALT;
507 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
509 rc.mac_dontswap_ctrl_meta = dontswapCB->isChecked();
510 rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
514 void PrefInput::updateRC(LyXRC const & rc)
516 // FIXME: can derive CB from the two EDs
517 keymapCB->setChecked(rc.use_kbmap);
518 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
519 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
520 mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed);
521 switch (rc.scroll_wheel_zoom) {
522 case LyXRC::SCROLL_WHEEL_ZOOM_OFF:
523 scrollzoomEnableCB->setChecked(false);
525 case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
526 scrollzoomEnableCB->setChecked(true);
527 scrollzoomValueCO->setCurrentIndex(0);
529 case LyXRC::SCROLL_WHEEL_ZOOM_SHIFT:
530 scrollzoomEnableCB->setChecked(true);
531 scrollzoomValueCO->setCurrentIndex(1);
533 case LyXRC::SCROLL_WHEEL_ZOOM_ALT:
534 scrollzoomEnableCB->setChecked(true);
535 scrollzoomValueCO->setCurrentIndex(2);
538 dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
539 mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
543 QString PrefInput::testKeymap(QString const & keymap)
545 return form_->browsekbmap(internalPath(keymap));
549 void PrefInput::on_firstKeymapPB_clicked(bool)
551 QString const file = testKeymap(firstKeymapED->text());
553 firstKeymapED->setText(file);
557 void PrefInput::on_secondKeymapPB_clicked(bool)
559 QString const file = testKeymap(secondKeymapED->text());
561 secondKeymapED->setText(file);
565 void PrefInput::on_keymapCB_toggled(bool keymap)
567 firstKeymapLA->setEnabled(keymap);
568 secondKeymapLA->setEnabled(keymap);
569 firstKeymapED->setEnabled(keymap);
570 secondKeymapED->setEnabled(keymap);
571 firstKeymapPB->setEnabled(keymap);
572 secondKeymapPB->setEnabled(keymap);
576 void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
578 scrollzoomValueCO->setEnabled(enabled);
582 /////////////////////////////////////////////////////////////////////
586 /////////////////////////////////////////////////////////////////////
588 PrefCompletion::PrefCompletion(GuiPreferences * form)
589 : PrefModule(catEditing, N_("Input Completion"), form)
593 connect(inlineDelaySB, SIGNAL(valueChanged(double)),
594 this, SIGNAL(changed()));
595 connect(inlineMathCB, SIGNAL(clicked()),
596 this, SIGNAL(changed()));
597 connect(inlineTextCB, SIGNAL(clicked()),
598 this, SIGNAL(changed()));
599 connect(inlineDotsCB, SIGNAL(clicked()),
600 this, SIGNAL(changed()));
601 connect(popupDelaySB, SIGNAL(valueChanged(double)),
602 this, SIGNAL(changed()));
603 connect(popupMathCB, SIGNAL(clicked()),
604 this, SIGNAL(changed()));
605 connect(autocorrectionCB, SIGNAL(clicked()),
606 this, SIGNAL(changed()));
607 connect(popupTextCB, SIGNAL(clicked()),
608 this, SIGNAL(changed()));
609 connect(popupAfterCompleteCB, SIGNAL(clicked()),
610 this, SIGNAL(changed()));
611 connect(cursorTextCB, SIGNAL(clicked()),
612 this, SIGNAL(changed()));
613 connect(minlengthSB, SIGNAL(valueChanged(int)),
614 this, SIGNAL(changed()));
618 void PrefCompletion::on_inlineTextCB_clicked()
624 void PrefCompletion::on_popupTextCB_clicked()
630 void PrefCompletion::enableCB()
632 cursorTextCB->setEnabled(
633 popupTextCB->isChecked() || inlineTextCB->isChecked());
637 void PrefCompletion::applyRC(LyXRC & rc) const
639 rc.completion_inline_delay = inlineDelaySB->value();
640 rc.completion_inline_math = inlineMathCB->isChecked();
641 rc.completion_inline_text = inlineTextCB->isChecked();
642 rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1;
643 rc.completion_popup_delay = popupDelaySB->value();
644 rc.completion_popup_math = popupMathCB->isChecked();
645 rc.autocorrection_math = autocorrectionCB->isChecked();
646 rc.completion_popup_text = popupTextCB->isChecked();
647 rc.completion_cursor_text = cursorTextCB->isChecked();
648 rc.completion_popup_after_complete =
649 popupAfterCompleteCB->isChecked();
650 rc.completion_minlength = minlengthSB->value();
654 void PrefCompletion::updateRC(LyXRC const & rc)
656 inlineDelaySB->setValue(rc.completion_inline_delay);
657 inlineMathCB->setChecked(rc.completion_inline_math);
658 inlineTextCB->setChecked(rc.completion_inline_text);
659 inlineDotsCB->setChecked(rc.completion_inline_dots != -1);
660 popupDelaySB->setValue(rc.completion_popup_delay);
661 popupMathCB->setChecked(rc.completion_popup_math);
662 autocorrectionCB->setChecked(rc.autocorrection_math);
663 popupTextCB->setChecked(rc.completion_popup_text);
664 cursorTextCB->setChecked(rc.completion_cursor_text);
665 popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
667 minlengthSB->setValue(rc.completion_minlength);
672 /////////////////////////////////////////////////////////////////////
676 /////////////////////////////////////////////////////////////////////
678 PrefLatex::PrefLatex(GuiPreferences * form)
679 : PrefModule(catOutput, N_("LaTeX"), form)
683 latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
684 latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
685 latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
686 latexIndexED->setValidator(new NoNewLineValidator(latexIndexED));
687 latexJIndexED->setValidator(new NoNewLineValidator(latexJIndexED));
688 latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
689 latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
691 connect(latexChecktexED, SIGNAL(textChanged(QString)),
692 this, SIGNAL(changed()));
693 connect(latexBibtexCO, SIGNAL(activated(int)),
694 this, SIGNAL(changed()));
695 connect(latexBibtexED, SIGNAL(textChanged(QString)),
696 this, SIGNAL(changed()));
697 connect(latexJBibtexCO, SIGNAL(activated(int)),
698 this, SIGNAL(changed()));
699 connect(latexJBibtexED, SIGNAL(textChanged(QString)),
700 this, SIGNAL(changed()));
701 connect(latexIndexCO, SIGNAL(activated(int)),
702 this, SIGNAL(changed()));
703 connect(latexIndexED, SIGNAL(textChanged(QString)),
704 this, SIGNAL(changed()));
705 connect(latexJIndexED, SIGNAL(textChanged(QString)),
706 this, SIGNAL(changed()));
707 connect(latexAutoresetCB, SIGNAL(clicked()),
708 this, SIGNAL(changed()));
709 connect(latexDviPaperED, SIGNAL(textChanged(QString)),
710 this, SIGNAL(changed()));
711 connect(latexNomenclED, SIGNAL(textChanged(QString)),
712 this, SIGNAL(changed()));
714 #if defined(__CYGWIN__) || defined(_WIN32)
715 pathCB->setVisible(true);
716 connect(pathCB, SIGNAL(clicked()),
717 this, SIGNAL(changed()));
719 pathCB->setVisible(false);
724 void PrefLatex::on_latexBibtexCO_activated(int n)
726 QString const bibtex = latexBibtexCO->itemData(n).toString();
727 if (bibtex.isEmpty()) {
728 latexBibtexED->clear();
729 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
732 for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
733 it != bibtex_alternatives.end(); ++it) {
734 QString const bib = toqstr(*it);
735 int ind = bib.indexOf(" ");
736 QString sel_command = bib.left(ind);
737 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
738 if (bibtex == sel_command) {
740 latexBibtexED->clear();
742 latexBibtexED->setText(sel_options.trimmed());
745 latexBibtexOptionsLA->setText(qt_("&Options:"));
749 void PrefLatex::on_latexJBibtexCO_activated(int n)
751 QString const jbibtex = latexJBibtexCO->itemData(n).toString();
752 if (jbibtex.isEmpty()) {
753 latexJBibtexED->clear();
754 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
757 for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
758 it != jbibtex_alternatives.end(); ++it) {
759 QString const bib = toqstr(*it);
760 int ind = bib.indexOf(" ");
761 QString sel_command = bib.left(ind);
762 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
763 if (jbibtex == sel_command) {
765 latexJBibtexED->clear();
767 latexJBibtexED->setText(sel_options.trimmed());
770 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
774 void PrefLatex::on_latexIndexCO_activated(int n)
776 QString const index = latexIndexCO->itemData(n).toString();
777 if (index.isEmpty()) {
778 latexIndexED->clear();
779 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
782 for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin();
783 it != index_alternatives.end(); ++it) {
784 QString const idx = toqstr(*it);
785 int ind = idx.indexOf(" ");
786 QString sel_command = idx.left(ind);
787 QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
788 if (index == sel_command) {
790 latexIndexED->clear();
792 latexIndexED->setText(sel_options.trimmed());
795 latexIndexOptionsLA->setText(qt_("Op&tions:"));
799 void PrefLatex::applyRC(LyXRC & rc) const
801 // If bibtex is not empty, bibopt contains the options, otherwise
802 // it is a customized bibtex command with options.
803 QString const bibtex = latexBibtexCO->itemData(
804 latexBibtexCO->currentIndex()).toString();
805 QString const bibopt = latexBibtexED->text();
806 if (bibtex.isEmpty())
807 rc.bibtex_command = fromqstr(bibopt);
808 else if (bibopt.isEmpty())
809 rc.bibtex_command = fromqstr(bibtex);
811 rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
813 // If jbibtex is not empty, jbibopt contains the options, otherwise
814 // it is a customized bibtex command with options.
815 QString const jbibtex = latexJBibtexCO->itemData(
816 latexJBibtexCO->currentIndex()).toString();
817 QString const jbibopt = latexJBibtexED->text();
818 if (jbibtex.isEmpty())
819 rc.jbibtex_command = fromqstr(jbibopt);
820 else if (jbibopt.isEmpty())
821 rc.jbibtex_command = fromqstr(jbibtex);
823 rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
825 // If index is not empty, idxopt contains the options, otherwise
826 // it is a customized index command with options.
827 QString const index = latexIndexCO->itemData(
828 latexIndexCO->currentIndex()).toString();
829 QString const idxopt = latexIndexED->text();
831 rc.index_command = fromqstr(idxopt);
832 else if (idxopt.isEmpty())
833 rc.index_command = fromqstr(index);
835 rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
837 rc.chktex_command = fromqstr(latexChecktexED->text());
838 rc.jindex_command = fromqstr(latexJIndexED->text());
839 rc.nomencl_command = fromqstr(latexNomenclED->text());
840 rc.auto_reset_options = latexAutoresetCB->isChecked();
841 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
842 #if defined(__CYGWIN__) || defined(_WIN32)
843 rc.windows_style_tex_paths = pathCB->isChecked();
848 void PrefLatex::updateRC(LyXRC const & rc)
850 latexBibtexCO->clear();
852 latexBibtexCO->addItem(qt_("Automatic"), "automatic");
853 latexBibtexCO->addItem(qt_("Custom"), QString());
854 for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
855 it != rc.bibtex_alternatives.end(); ++it) {
856 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
857 latexBibtexCO->addItem(command, command);
860 bibtex_alternatives = rc.bibtex_alternatives;
862 QString const bib = toqstr(rc.bibtex_command);
863 int ind = bib.indexOf(" ");
864 QString sel_command = bib.left(ind);
865 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
867 int pos = latexBibtexCO->findData(sel_command);
869 latexBibtexCO->setCurrentIndex(pos);
870 latexBibtexED->setText(sel_options.trimmed());
871 latexBibtexOptionsLA->setText(qt_("&Options:"));
873 latexBibtexED->setText(toqstr(rc.bibtex_command));
874 latexBibtexCO->setCurrentIndex(0);
875 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
878 latexJBibtexCO->clear();
880 latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
881 latexJBibtexCO->addItem(qt_("Custom"), QString());
882 for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
883 it != rc.jbibtex_alternatives.end(); ++it) {
884 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
885 latexJBibtexCO->addItem(command, command);
888 jbibtex_alternatives = rc.jbibtex_alternatives;
890 QString const jbib = toqstr(rc.jbibtex_command);
891 ind = jbib.indexOf(" ");
892 sel_command = jbib.left(ind);
893 sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
895 pos = latexJBibtexCO->findData(sel_command);
897 latexJBibtexCO->setCurrentIndex(pos);
898 latexJBibtexED->setText(sel_options.trimmed());
899 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
901 latexJBibtexED->setText(toqstr(rc.bibtex_command));
902 latexJBibtexCO->setCurrentIndex(0);
903 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
906 latexIndexCO->clear();
908 latexIndexCO->addItem(qt_("Custom"), QString());
909 for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin();
910 it != rc.index_alternatives.end(); ++it) {
911 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
912 latexIndexCO->addItem(command, command);
915 index_alternatives = rc.index_alternatives;
917 QString const idx = toqstr(rc.index_command);
918 ind = idx.indexOf(" ");
919 sel_command = idx.left(ind);
920 sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
922 pos = latexIndexCO->findData(sel_command);
924 latexIndexCO->setCurrentIndex(pos);
925 latexIndexED->setText(sel_options.trimmed());
926 latexIndexOptionsLA->setText(qt_("Op&tions:"));
928 latexIndexED->setText(toqstr(rc.index_command));
929 latexIndexCO->setCurrentIndex(0);
930 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
933 latexChecktexED->setText(toqstr(rc.chktex_command));
934 latexJIndexED->setText(toqstr(rc.jindex_command));
935 latexNomenclED->setText(toqstr(rc.nomencl_command));
936 latexAutoresetCB->setChecked(rc.auto_reset_options);
937 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
938 #if defined(__CYGWIN__) || defined(_WIN32)
939 pathCB->setChecked(rc.windows_style_tex_paths);
944 /////////////////////////////////////////////////////////////////////
948 /////////////////////////////////////////////////////////////////////
950 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
951 : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
955 connect(screenRomanCO, SIGNAL(activated(QString)),
956 this, SLOT(selectRoman(QString)));
957 connect(screenSansCO, SIGNAL(activated(QString)),
958 this, SLOT(selectSans(QString)));
959 connect(screenTypewriterCO, SIGNAL(activated(QString)),
960 this, SLOT(selectTypewriter(QString)));
962 QFontDatabase fontdb;
963 QStringList families(fontdb.families());
964 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
965 screenRomanCO->addItem(*it);
966 screenSansCO->addItem(*it);
967 screenTypewriterCO->addItem(*it);
969 connect(screenRomanCO, SIGNAL(activated(QString)),
970 this, SIGNAL(changed()));
971 connect(screenSansCO, SIGNAL(activated(QString)),
972 this, SIGNAL(changed()));
973 connect(screenTypewriterCO, SIGNAL(activated(QString)),
974 this, SIGNAL(changed()));
975 connect(screenZoomSB, SIGNAL(valueChanged(int)),
976 this, SIGNAL(changed()));
977 connect(screenTinyED, SIGNAL(textChanged(QString)),
978 this, SIGNAL(changed()));
979 connect(screenSmallestED, SIGNAL(textChanged(QString)),
980 this, SIGNAL(changed()));
981 connect(screenSmallerED, SIGNAL(textChanged(QString)),
982 this, SIGNAL(changed()));
983 connect(screenSmallED, SIGNAL(textChanged(QString)),
984 this, SIGNAL(changed()));
985 connect(screenNormalED, SIGNAL(textChanged(QString)),
986 this, SIGNAL(changed()));
987 connect(screenLargeED, SIGNAL(textChanged(QString)),
988 this, SIGNAL(changed()));
989 connect(screenLargerED, SIGNAL(textChanged(QString)),
990 this, SIGNAL(changed()));
991 connect(screenLargestED, SIGNAL(textChanged(QString)),
992 this, SIGNAL(changed()));
993 connect(screenHugeED, SIGNAL(textChanged(QString)),
994 this, SIGNAL(changed()));
995 connect(screenHugerED, SIGNAL(textChanged(QString)),
996 this, SIGNAL(changed()));
998 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
999 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
1000 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
1001 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
1002 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
1003 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
1004 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
1005 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
1006 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
1007 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
1011 void PrefScreenFonts::applyRC(LyXRC & rc) const
1013 LyXRC const oldrc = rc;
1015 parseFontName(screenRomanCO->currentText(),
1016 rc.roman_font_name, rc.roman_font_foundry);
1017 parseFontName(screenSansCO->currentText(),
1018 rc.sans_font_name, rc.sans_font_foundry);
1019 parseFontName(screenTypewriterCO->currentText(),
1020 rc.typewriter_font_name, rc.typewriter_font_foundry);
1022 rc.defaultZoom = screenZoomSB->value();
1023 rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED);
1024 rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED);
1025 rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED);
1026 rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED);
1027 rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED);
1028 rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED);
1029 rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED);
1030 rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED);
1031 rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED);
1032 rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED);
1036 void PrefScreenFonts::updateRC(LyXRC const & rc)
1038 setComboxFont(screenRomanCO, rc.roman_font_name,
1039 rc.roman_font_foundry);
1040 setComboxFont(screenSansCO, rc.sans_font_name,
1041 rc.sans_font_foundry);
1042 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
1043 rc.typewriter_font_foundry);
1045 selectRoman(screenRomanCO->currentText());
1046 selectSans(screenSansCO->currentText());
1047 selectTypewriter(screenTypewriterCO->currentText());
1049 screenZoomSB->setValue(rc.defaultZoom);
1050 updateScreenFontSizes(rc);
1054 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
1056 doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]);
1057 doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]);
1058 doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]);
1059 doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]);
1060 doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]);
1061 doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]);
1062 doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]);
1063 doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]);
1064 doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]);
1065 doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]);
1069 void PrefScreenFonts::selectRoman(const QString & name)
1071 screenRomanFE->set(QFont(name), name);
1075 void PrefScreenFonts::selectSans(const QString & name)
1077 screenSansFE->set(QFont(name), name);
1081 void PrefScreenFonts::selectTypewriter(const QString & name)
1083 screenTypewriterFE->set(QFont(name), name);
1087 /////////////////////////////////////////////////////////////////////
1091 /////////////////////////////////////////////////////////////////////
1094 PrefColors::PrefColors(GuiPreferences * form)
1095 : PrefModule(catLookAndFeel, N_("Colors"), form)
1099 // FIXME: all of this initialization should be put into the controller.
1100 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
1101 // for some discussion of why that is not trivial.
1102 QPixmap icon(32, 32);
1103 for (int i = 0; i < Color_ignore; ++i) {
1104 ColorCode lc = static_cast<ColorCode>(i);
1105 if (lc == Color_none
1106 || lc == Color_black
1107 || lc == Color_white
1109 || lc == Color_brown
1111 || lc == Color_darkgray
1113 || lc == Color_green
1114 || lc == Color_lightgray
1116 || lc == Color_magenta
1117 || lc == Color_olive
1118 || lc == Color_orange
1120 || lc == Color_purple
1123 || lc == Color_violet
1124 || lc == Color_yellow
1125 || lc == Color_inherit
1126 || lc == Color_ignore)
1128 lcolors_.push_back(lc);
1130 qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
1131 vector<ColorCode>::const_iterator cit = lcolors_.begin();
1132 vector<ColorCode>::const_iterator const end = lcolors_.end();
1133 for (; cit != end; ++cit) {
1134 (void) new QListWidgetItem(QIcon(icon),
1135 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
1137 curcolors_.resize(lcolors_.size());
1138 newcolors_.resize(lcolors_.size());
1139 // End initialization
1141 connect(colorChangePB, SIGNAL(clicked()),
1142 this, SLOT(changeColor()));
1143 connect(colorResetPB, SIGNAL(clicked()),
1144 this, SLOT(resetColor()));
1145 connect(colorResetAllPB, SIGNAL(clicked()),
1146 this, SLOT(resetAllColor()));
1147 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
1148 this, SLOT(changeLyxObjectsSelection()));
1149 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
1150 this, SLOT(changeColor()));
1151 connect(syscolorsCB, SIGNAL(toggled(bool)),
1152 this, SIGNAL(changed()));
1153 connect(syscolorsCB, SIGNAL(toggled(bool)),
1154 this, SLOT(changeSysColor()));
1158 void PrefColors::applyRC(LyXRC & rc) const
1162 for (unsigned int i = 0; i < lcolors_.size(); ++i)
1163 if (curcolors_[i] != newcolors_[i])
1164 form_->setColor(lcolors_[i], newcolors_[i]);
1165 rc.use_system_colors = syscolorsCB->isChecked();
1167 if (oldrc.use_system_colors != rc.use_system_colors)
1168 guiApp->colorCache().clear();
1172 void PrefColors::updateRC(LyXRC const & rc)
1174 for (size_type i = 0; i < lcolors_.size(); ++i) {
1175 QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
1176 QPixmap coloritem(32, 32);
1177 coloritem.fill(color);
1178 lyxObjectsLW->item(int(i))->setIcon(QIcon(coloritem));
1179 newcolors_[i] = curcolors_[i] = color.name();
1181 syscolorsCB->setChecked(rc.use_system_colors);
1182 changeLyxObjectsSelection();
1184 setDisabledResets();
1188 void PrefColors::changeColor()
1190 int const row = lyxObjectsLW->currentRow();
1196 QString const color = newcolors_[size_t(row)];
1197 QColor const c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
1199 if (setColor(row, c, color)) {
1200 setDisabledResets();
1207 void PrefColors::resetColor()
1209 int const row = lyxObjectsLW->currentRow();
1215 QString const color = newcolors_[size_t(row)];
1216 QColor const c = getDefaultColorByRow(row);
1218 if (setColor(row, c, color)) {
1219 setDisabledResets();
1226 void PrefColors::resetAllColor()
1228 bool isChanged = false;
1230 colorResetAllPB->setDisabled(true);
1232 for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
1233 QString const color = newcolors_[size_t(irow)];
1234 QColor const c = getDefaultColorByRow(irow);
1236 if (setColor(irow, c, color))
1241 setDisabledResets();
1248 bool PrefColors::setColor(int const row, QColor const new_color,
1249 QString const old_color)
1251 if (new_color.isValid() && new_color.name() != old_color) {
1252 newcolors_[size_t(row)] = new_color.name();
1253 QPixmap coloritem(32, 32);
1254 coloritem.fill(new_color);
1255 lyxObjectsLW->item(row)->setIcon(QIcon(coloritem));
1262 void PrefColors::setDisabledResets()
1264 int const row = lyxObjectsLW->currentRow();
1265 // set disable reset buttons ...
1267 colorResetPB->setDisabled(isDefaultColor(row, newcolors_[size_t(row)]));
1269 colorResetAllPB->setDisabled(true);
1271 // ... in between process qt events to give quicker visual feedback to the user ...
1272 guiApp->processEvents();
1274 // ... set disable Reset All button
1275 for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
1276 if (!isDefaultColor(irow, newcolors_[size_t(irow)])) {
1277 colorResetAllPB->setDisabled(false);
1278 // the break condition might hide performance issues
1279 // if a non-default color is at the top of the list
1286 bool PrefColors::isDefaultColor(int const row, QString const color)
1288 return color == getDefaultColorByRow(row).name();
1292 QColor PrefColors::getDefaultColorByRow(int const row)
1294 ColorSet const defaultcolor;
1295 return defaultcolor.getX11Name(lcolors_[size_t(row)]).c_str();
1299 void PrefColors::changeSysColor()
1301 for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
1302 // skip colors that are taken from system palette
1303 bool const disable = syscolorsCB->isChecked()
1304 && guiApp->colorCache().isSystem(lcolors_[size_t(row)]);
1306 QListWidgetItem * const item = lyxObjectsLW->item(row);
1307 Qt::ItemFlags const flags = item->flags();
1310 item->setFlags(flags & ~Qt::ItemIsEnabled);
1312 item->setFlags(flags | Qt::ItemIsEnabled);
1317 void PrefColors::changeLyxObjectsSelection()
1319 int currentRow = lyxObjectsLW->currentRow();
1320 colorChangePB->setDisabled(currentRow < 0);
1323 colorResetPB->setDisabled(true);
1325 colorResetPB->setDisabled(
1326 isDefaultColor(currentRow, newcolors_[size_t(currentRow)]));
1330 /////////////////////////////////////////////////////////////////////
1334 /////////////////////////////////////////////////////////////////////
1336 PrefDisplay::PrefDisplay(GuiPreferences * form)
1337 : PrefModule(catLookAndFeel, N_("Display"), form)
1340 connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1341 connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
1342 connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed()));
1343 connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1347 void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
1349 previewSizeSB->setEnabled(index != 0);
1353 void PrefDisplay::applyRC(LyXRC & rc) const
1355 switch (instantPreviewCO->currentIndex()) {
1357 rc.preview = LyXRC::PREVIEW_OFF;
1360 rc.preview = LyXRC::PREVIEW_NO_MATH;
1363 rc.preview = LyXRC::PREVIEW_ON;
1367 rc.display_graphics = displayGraphicsCB->isChecked();
1368 rc.preview_scale_factor = previewSizeSB->value();
1369 rc.paragraph_markers = paragraphMarkerCB->isChecked();
1371 // FIXME!! The graphics cache no longer has a changeDisplay method.
1373 if (old_value != rc.display_graphics) {
1374 graphics::GCache & gc = graphics::GCache::get();
1381 void PrefDisplay::updateRC(LyXRC const & rc)
1383 switch (rc.preview) {
1384 case LyXRC::PREVIEW_OFF:
1385 instantPreviewCO->setCurrentIndex(0);
1387 case LyXRC::PREVIEW_NO_MATH :
1388 instantPreviewCO->setCurrentIndex(1);
1390 case LyXRC::PREVIEW_ON :
1391 instantPreviewCO->setCurrentIndex(2);
1395 displayGraphicsCB->setChecked(rc.display_graphics);
1396 previewSizeSB->setValue(rc.preview_scale_factor);
1397 paragraphMarkerCB->setChecked(rc.paragraph_markers);
1398 previewSizeSB->setEnabled(
1400 && rc.preview != LyXRC::PREVIEW_OFF);
1404 /////////////////////////////////////////////////////////////////////
1408 /////////////////////////////////////////////////////////////////////
1410 PrefPaths::PrefPaths(GuiPreferences * form)
1411 : PrefModule(QString(), N_("Paths"), form)
1415 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir()));
1416 connect(workingDirED, SIGNAL(textChanged(QString)),
1417 this, SIGNAL(changed()));
1419 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir()));
1420 connect(templateDirED, SIGNAL(textChanged(QString)),
1421 this, SIGNAL(changed()));
1423 connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir()));
1424 connect(exampleDirED, SIGNAL(textChanged(QString)),
1425 this, SIGNAL(changed()));
1427 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir()));
1428 connect(backupDirED, SIGNAL(textChanged(QString)),
1429 this, SIGNAL(changed()));
1431 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe()));
1432 connect(lyxserverDirED, SIGNAL(textChanged(QString)),
1433 this, SIGNAL(changed()));
1435 connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir()));
1436 connect(thesaurusDirED, SIGNAL(textChanged(QString)),
1437 this, SIGNAL(changed()));
1439 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir()));
1440 connect(tempDirED, SIGNAL(textChanged(QString)),
1441 this, SIGNAL(changed()));
1443 #if defined(USE_HUNSPELL)
1444 connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir()));
1445 connect(hunspellDirED, SIGNAL(textChanged(QString)),
1446 this, SIGNAL(changed()));
1448 hunspellDirPB->setEnabled(false);
1449 hunspellDirED->setEnabled(false);
1452 connect(pathPrefixED, SIGNAL(textChanged(QString)),
1453 this, SIGNAL(changed()));
1455 connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
1456 this, SIGNAL(changed()));
1458 pathPrefixED->setValidator(new NoNewLineValidator(pathPrefixED));
1459 texinputsPrefixED->setValidator(new NoNewLineValidator(texinputsPrefixED));
1463 void PrefPaths::applyRC(LyXRC & rc) const
1465 rc.document_path = internal_path(fromqstr(workingDirED->text()));
1466 rc.example_path = internal_path(fromqstr(exampleDirED->text()));
1467 rc.template_path = internal_path(fromqstr(templateDirED->text()));
1468 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
1469 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
1470 rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
1471 rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
1472 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
1473 rc.texinputs_prefix = internal_path_list(fromqstr(texinputsPrefixED->text()));
1474 // FIXME: should be a checkbox only
1475 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
1479 void PrefPaths::updateRC(LyXRC const & rc)
1481 workingDirED->setText(toqstr(external_path(rc.document_path)));
1482 exampleDirED->setText(toqstr(external_path(rc.example_path)));
1483 templateDirED->setText(toqstr(external_path(rc.template_path)));
1484 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
1485 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
1486 thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
1487 hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
1488 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
1489 texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
1490 // FIXME: should be a checkbox only
1491 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
1495 void PrefPaths::selectExampledir()
1497 QString file = browseDir(internalPath(exampleDirED->text()),
1498 qt_("Select directory for example files"));
1499 if (!file.isEmpty())
1500 exampleDirED->setText(file);
1504 void PrefPaths::selectTemplatedir()
1506 QString file = browseDir(internalPath(templateDirED->text()),
1507 qt_("Select a document templates directory"));
1508 if (!file.isEmpty())
1509 templateDirED->setText(file);
1513 void PrefPaths::selectTempdir()
1515 QString file = browseDir(internalPath(tempDirED->text()),
1516 qt_("Select a temporary directory"));
1517 if (!file.isEmpty())
1518 tempDirED->setText(file);
1522 void PrefPaths::selectBackupdir()
1524 QString file = browseDir(internalPath(backupDirED->text()),
1525 qt_("Select a backups directory"));
1526 if (!file.isEmpty())
1527 backupDirED->setText(file);
1531 void PrefPaths::selectWorkingdir()
1533 QString file = browseDir(internalPath(workingDirED->text()),
1534 qt_("Select a document directory"));
1535 if (!file.isEmpty())
1536 workingDirED->setText(file);
1540 void PrefPaths::selectThesaurusdir()
1542 QString file = browseDir(internalPath(thesaurusDirED->text()),
1543 qt_("Set the path to the thesaurus dictionaries"));
1544 if (!file.isEmpty())
1545 thesaurusDirED->setText(file);
1549 void PrefPaths::selectHunspelldir()
1551 QString file = browseDir(internalPath(hunspellDirED->text()),
1552 qt_("Set the path to the Hunspell dictionaries"));
1553 if (!file.isEmpty())
1554 hunspellDirED->setText(file);
1558 void PrefPaths::selectLyxPipe()
1560 QString file = form_->browse(internalPath(lyxserverDirED->text()),
1561 qt_("Give a filename for the LyX server pipe"));
1562 if (!file.isEmpty())
1563 lyxserverDirED->setText(file);
1567 /////////////////////////////////////////////////////////////////////
1571 /////////////////////////////////////////////////////////////////////
1573 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
1574 : PrefModule(catLanguage, N_("Spellchecker"), form)
1578 // FIXME: this check should test the target platform (darwin)
1579 #if defined(USE_MACOSX_PACKAGING)
1580 spellcheckerCB->addItem(qt_("Native"), QString("native"));
1581 #define CONNECT_APPLESPELL
1583 #undef CONNECT_APPLESPELL
1585 #if defined(USE_ASPELL)
1586 spellcheckerCB->addItem(qt_("Aspell"), QString("aspell"));
1588 #if defined(USE_ENCHANT)
1589 spellcheckerCB->addItem(qt_("Enchant"), QString("enchant"));
1591 #if defined(USE_HUNSPELL)
1592 spellcheckerCB->addItem(qt_("Hunspell"), QString("hunspell"));
1595 #if defined(CONNECT_APPLESPELL) || defined(USE_ASPELL) || defined(USE_ENCHANT) || defined(USE_HUNSPELL)
1596 connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)),
1597 this, SIGNAL(changed()));
1598 connect(altLanguageED, SIGNAL(textChanged(QString)),
1599 this, SIGNAL(changed()));
1600 connect(escapeCharactersED, SIGNAL(textChanged(QString)),
1601 this, SIGNAL(changed()));
1602 connect(compoundWordCB, SIGNAL(clicked()),
1603 this, SIGNAL(changed()));
1604 connect(spellcheckContinuouslyCB, SIGNAL(clicked()),
1605 this, SIGNAL(changed()));
1606 connect(spellcheckNotesCB, SIGNAL(clicked()),
1607 this, SIGNAL(changed()));
1609 altLanguageED->setValidator(new NoNewLineValidator(altLanguageED));
1610 escapeCharactersED->setValidator(new NoNewLineValidator(escapeCharactersED));
1612 spellcheckerCB->setEnabled(false);
1613 altLanguageED->setEnabled(false);
1614 escapeCharactersED->setEnabled(false);
1615 compoundWordCB->setEnabled(false);
1616 spellcheckContinuouslyCB->setEnabled(false);
1617 spellcheckNotesCB->setEnabled(false);
1622 void PrefSpellchecker::applyRC(LyXRC & rc) const
1624 string const speller = fromqstr(spellcheckerCB->
1625 itemData(spellcheckerCB->currentIndex()).toString());
1626 if (!speller.empty())
1627 rc.spellchecker = speller;
1628 rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
1629 rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
1630 rc.spellchecker_accept_compound = compoundWordCB->isChecked();
1631 rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked();
1632 rc.spellcheck_notes = spellcheckNotesCB->isChecked();
1636 void PrefSpellchecker::updateRC(LyXRC const & rc)
1638 spellcheckerCB->setCurrentIndex(
1639 spellcheckerCB->findData(toqstr(rc.spellchecker)));
1640 altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
1641 escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
1642 compoundWordCB->setChecked(rc.spellchecker_accept_compound);
1643 spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously);
1644 spellcheckNotesCB->setChecked(rc.spellcheck_notes);
1648 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
1650 QString spellchecker = spellcheckerCB->itemData(index).toString();
1652 compoundWordCB->setEnabled(spellchecker == QString("aspell"));
1657 /////////////////////////////////////////////////////////////////////
1661 /////////////////////////////////////////////////////////////////////
1664 PrefConverters::PrefConverters(GuiPreferences * form)
1665 : PrefModule(catFiles, N_("Converters"), form)
1669 connect(converterNewPB, SIGNAL(clicked()),
1670 this, SLOT(updateConverter()));
1671 connect(converterRemovePB, SIGNAL(clicked()),
1672 this, SLOT(removeConverter()));
1673 connect(converterModifyPB, SIGNAL(clicked()),
1674 this, SLOT(updateConverter()));
1675 connect(convertersLW, SIGNAL(currentRowChanged(int)),
1676 this, SLOT(switchConverter()));
1677 connect(converterFromCO, SIGNAL(activated(QString)),
1678 this, SLOT(changeConverter()));
1679 connect(converterToCO, SIGNAL(activated(QString)),
1680 this, SLOT(changeConverter()));
1681 connect(converterED, SIGNAL(textEdited(QString)),
1682 this, SLOT(changeConverter()));
1683 connect(converterFlagED, SIGNAL(textEdited(QString)),
1684 this, SLOT(changeConverter()));
1685 connect(converterNewPB, SIGNAL(clicked()),
1686 this, SIGNAL(changed()));
1687 connect(converterRemovePB, SIGNAL(clicked()),
1688 this, SIGNAL(changed()));
1689 connect(converterModifyPB, SIGNAL(clicked()),
1690 this, SIGNAL(changed()));
1691 connect(maxAgeLE, SIGNAL(textEdited(QString)),
1692 this, SIGNAL(changed()));
1693 connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
1694 this, SIGNAL(changed()));
1696 converterED->setValidator(new NoNewLineValidator(converterED));
1697 converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
1698 maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
1699 //converterDefGB->setFocusProxy(convertersLW);
1703 void PrefConverters::applyRC(LyXRC & rc) const
1705 rc.use_converter_cache = cacheCB->isChecked();
1706 rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
1707 rc.use_converter_needauth = needauthCB->isChecked();
1708 rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
1712 static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
1713 cb->blockSignals(true);
1714 cb->setChecked(checked);
1715 cb->blockSignals(false);
1719 void PrefConverters::updateRC(LyXRC const & rc)
1721 cacheCB->setChecked(rc.use_converter_cache);
1722 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1723 setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
1725 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1730 void PrefConverters::updateGui()
1732 QString const pattern("%1 -> %2");
1733 form_->formats().sort();
1734 form_->converters().update(form_->formats());
1735 // save current selection
1738 .arg(converterFromCO->currentText())
1739 .arg(converterToCO->currentText());
1741 converterFromCO->clear();
1742 converterToCO->clear();
1744 for (Format const & f : form_->formats()) {
1745 QString const name = toqstr(translateIfPossible(f.prettyname()));
1746 converterFromCO->addItem(name);
1747 converterToCO->addItem(name);
1750 // currentRowChanged(int) is also triggered when updating the listwidget
1751 // block signals to avoid unnecessary calls to switchConverter()
1752 convertersLW->blockSignals(true);
1753 convertersLW->clear();
1755 for (Converter const & c : form_->converters()) {
1756 QString const name =
1758 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1759 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1760 int type = form_->converters().getNumber(c.From()->name(),
1762 new QListWidgetItem(name, convertersLW, type);
1764 convertersLW->sortItems(Qt::AscendingOrder);
1765 convertersLW->blockSignals(false);
1767 // restore selection
1768 if (current != pattern.arg(QString()).arg(QString())) {
1769 QList<QListWidgetItem *> const item =
1770 convertersLW->findItems(current, Qt::MatchExactly);
1771 if (!item.isEmpty())
1772 convertersLW->setCurrentItem(item.at(0));
1775 // select first element if restoring failed
1776 if (convertersLW->currentRow() == -1)
1777 convertersLW->setCurrentRow(0);
1783 void PrefConverters::switchConverter()
1785 int const cnr = convertersLW->currentItem()->type();
1786 Converter const & c(form_->converters().get(cnr));
1787 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1788 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1789 converterED->setText(toqstr(c.command()));
1790 converterFlagED->setText(toqstr(c.flags()));
1796 void PrefConverters::changeConverter()
1802 void PrefConverters::updateButtons()
1804 if (form_->formats().empty())
1806 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1807 Format const & to = form_->formats().get(converterToCO->currentIndex());
1808 int const sel = form_->converters().getNumber(from.name(), to.name());
1809 bool const known = sel >= 0;
1810 bool const valid = !(converterED->text().isEmpty()
1811 || from.name() == to.name());
1816 if (convertersLW->count() > 0) {
1817 int const cnr = convertersLW->currentItem()->type();
1818 Converter const & c = form_->converters().get(cnr);
1819 old_command = c.command();
1820 old_flag = c.flags();
1823 string const new_command = fromqstr(converterED->text());
1824 string const new_flag = fromqstr(converterFlagED->text());
1826 bool modified = (old_command != new_command || old_flag != new_flag);
1828 converterModifyPB->setEnabled(valid && known && modified);
1829 converterNewPB->setEnabled(valid && !known);
1830 converterRemovePB->setEnabled(known);
1832 maxAgeLE->setEnabled(cacheCB->isChecked());
1833 maxAgeLA->setEnabled(cacheCB->isChecked());
1838 // specify unique from/to or it doesn't appear. This is really bad UI
1839 // this is why we can use the same function for both new and modify
1840 void PrefConverters::updateConverter()
1842 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1843 Format const & to = form_->formats().get(converterToCO->currentIndex());
1844 string const flags = fromqstr(converterFlagED->text());
1845 string const command = fromqstr(converterED->text());
1847 Converter const * old =
1848 form_->converters().getConverter(from.name(), to.name());
1849 form_->converters().add(from.name(), to.name(), command, flags);
1852 form_->converters().updateLast(form_->formats());
1856 // Remove all files created by this converter from the cache, since
1857 // the modified converter might create different files.
1858 ConverterCache::get().remove_all(from.name(), to.name());
1862 void PrefConverters::removeConverter()
1864 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1865 Format const & to = form_->formats().get(converterToCO->currentIndex());
1866 form_->converters().erase(from.name(), to.name());
1870 // Remove all files created by this converter from the cache, since
1871 // a possible new converter might create different files.
1872 ConverterCache::get().remove_all(from.name(), to.name());
1876 void PrefConverters::on_cacheCB_stateChanged(int state)
1878 maxAgeLE->setEnabled(state == Qt::Checked);
1879 maxAgeLA->setEnabled(state == Qt::Checked);
1884 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1886 needauthCB->setEnabled(!checked);
1890 void PrefConverters::on_needauthCB_toggled(bool checked)
1897 int ret = frontend::Alert::prompt(
1898 _("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!"),
1899 0, 0, _("&No"), _("&Yes"));
1903 setCheckboxBlockSignals(needauthCB, true);
1907 /////////////////////////////////////////////////////////////////////
1911 /////////////////////////////////////////////////////////////////////
1913 class FormatValidator : public QValidator
1916 FormatValidator(QWidget *, Formats const & f);
1917 void fixup(QString & input) const;
1918 QValidator::State validate(QString & input, int & pos) const;
1920 virtual QString toString(Format const & format) const = 0;
1922 Formats const & formats_;
1926 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1927 : QValidator(parent), formats_(f)
1932 void FormatValidator::fixup(QString & input) const
1934 Formats::const_iterator cit = formats_.begin();
1935 Formats::const_iterator end = formats_.end();
1936 for (; cit != end; ++cit) {
1937 QString const name = toString(*cit);
1938 if (distance(formats_.begin(), cit) == nr()) {
1946 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1948 Formats::const_iterator cit = formats_.begin();
1949 Formats::const_iterator end = formats_.end();
1950 bool unknown = true;
1951 for (; unknown && cit != end; ++cit) {
1952 QString const name = toString(*cit);
1953 if (distance(formats_.begin(), cit) != nr())
1954 unknown = name != input;
1957 if (unknown && !input.isEmpty())
1958 return QValidator::Acceptable;
1960 return QValidator::Intermediate;
1964 int FormatValidator::nr() const
1966 QComboBox * p = qobject_cast<QComboBox *>(parent());
1967 return p->itemData(p->currentIndex()).toInt();
1971 /////////////////////////////////////////////////////////////////////
1973 // FormatNameValidator
1975 /////////////////////////////////////////////////////////////////////
1977 class FormatNameValidator : public FormatValidator
1980 FormatNameValidator(QWidget * parent, Formats const & f)
1981 : FormatValidator(parent, f)
1984 QString toString(Format const & format) const
1986 return toqstr(format.name());
1991 /////////////////////////////////////////////////////////////////////
1993 // FormatPrettynameValidator
1995 /////////////////////////////////////////////////////////////////////
1997 class FormatPrettynameValidator : public FormatValidator
2000 FormatPrettynameValidator(QWidget * parent, Formats const & f)
2001 : FormatValidator(parent, f)
2004 QString toString(Format const & format) const
2006 return toqstr(translateIfPossible(format.prettyname()));
2011 /////////////////////////////////////////////////////////////////////
2015 /////////////////////////////////////////////////////////////////////
2017 PrefFileformats::PrefFileformats(GuiPreferences * form)
2018 : PrefModule(catFiles, N_("File Formats"), form)
2022 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
2023 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
2024 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
2025 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
2026 editorED->setValidator(new NoNewLineValidator(editorED));
2027 viewerED->setValidator(new NoNewLineValidator(viewerED));
2028 copierED->setValidator(new NoNewLineValidator(copierED));
2030 connect(documentCB, SIGNAL(clicked()),
2031 this, SLOT(setFlags()));
2032 connect(vectorCB, SIGNAL(clicked()),
2033 this, SLOT(setFlags()));
2034 connect(exportMenuCB, SIGNAL(clicked()),
2035 this, SLOT(setFlags()));
2036 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
2037 this, SLOT(updatePrettyname()));
2038 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
2039 this, SIGNAL(changed()));
2040 connect(defaultFormatCB, SIGNAL(activated(QString)),
2041 this, SIGNAL(changed()));
2042 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
2043 this, SIGNAL(changed()));
2044 connect(defaultPlatexFormatCB, SIGNAL(activated(QString)),
2045 this, SIGNAL(changed()));
2046 connect(viewerCO, SIGNAL(activated(int)),
2047 this, SIGNAL(changed()));
2048 connect(editorCO, SIGNAL(activated(int)),
2049 this, SIGNAL(changed()));
2055 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
2057 if (shortcut.empty())
2060 string l10n_format =
2061 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
2062 return split(l10n_format, '|');
2068 void PrefFileformats::applyRC(LyXRC & rc) const
2070 QString const default_format = defaultFormatCB->itemData(
2071 defaultFormatCB->currentIndex()).toString();
2072 rc.default_view_format = fromqstr(default_format);
2073 QString const default_otf_format = defaultOTFFormatCB->itemData(
2074 defaultOTFFormatCB->currentIndex()).toString();
2075 rc.default_otf_view_format = fromqstr(default_otf_format);
2076 QString const default_platex_format = defaultPlatexFormatCB->itemData(
2077 defaultPlatexFormatCB->currentIndex()).toString();
2078 rc.default_platex_view_format = fromqstr(default_platex_format);
2082 void PrefFileformats::updateRC(LyXRC const & rc)
2084 viewer_alternatives = rc.viewer_alternatives;
2085 editor_alternatives = rc.editor_alternatives;
2086 bool const init = defaultFormatCB->currentText().isEmpty();
2090 defaultFormatCB->findData(toqstr(rc.default_view_format));
2091 defaultFormatCB->setCurrentIndex(pos);
2092 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2093 defaultOTFFormatCB->setCurrentIndex(pos);
2094 defaultOTFFormatCB->setCurrentIndex(pos);
2095 pos = defaultPlatexFormatCB->findData(toqstr(rc.default_platex_view_format));
2096 defaultPlatexFormatCB->setCurrentIndex(pos);
2097 defaultPlatexFormatCB->setCurrentIndex(pos);
2102 void PrefFileformats::updateView()
2104 QString const current = formatsCB->currentText();
2105 QString const current_def = defaultFormatCB->currentText();
2106 QString const current_def_otf = defaultOTFFormatCB->currentText();
2107 QString const current_def_platex = defaultPlatexFormatCB->currentText();
2109 // update comboboxes with formats
2110 formatsCB->blockSignals(true);
2111 defaultFormatCB->blockSignals(true);
2112 defaultOTFFormatCB->blockSignals(true);
2113 defaultPlatexFormatCB->blockSignals(true);
2115 defaultFormatCB->clear();
2116 defaultOTFFormatCB->clear();
2117 defaultPlatexFormatCB->clear();
2118 form_->formats().sort();
2119 for (Format const & f : form_->formats()) {
2120 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2121 formatsCB->addItem(prettyname,
2122 QVariant(form_->formats().getNumber(f.name())));
2123 if (f.viewer().empty())
2125 if (form_->converters().isReachable("xhtml", f.name())
2126 || form_->converters().isReachable("dviluatex", f.name())
2127 || form_->converters().isReachable("luatex", f.name())
2128 || form_->converters().isReachable("xetex", f.name())) {
2129 defaultFormatCB->addItem(prettyname,
2130 QVariant(toqstr(f.name())));
2131 defaultOTFFormatCB->addItem(prettyname,
2132 QVariant(toqstr(f.name())));
2134 if (form_->converters().isReachable("latex", f.name())
2135 || form_->converters().isReachable("pdflatex", f.name()))
2136 defaultFormatCB->addItem(prettyname,
2137 QVariant(toqstr(f.name())));
2138 if (form_->converters().isReachable("platex", f.name()))
2139 defaultPlatexFormatCB->addItem(prettyname,
2140 QVariant(toqstr(f.name())));
2144 // restore selections
2145 int item = formatsCB->findText(current, Qt::MatchExactly);
2146 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2147 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2148 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2149 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2150 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2151 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2152 item = defaultPlatexFormatCB->findText(current_def_platex, Qt::MatchExactly);
2153 defaultPlatexFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2154 formatsCB->blockSignals(false);
2155 defaultFormatCB->blockSignals(false);
2156 defaultOTFFormatCB->blockSignals(false);
2157 defaultPlatexFormatCB->blockSignals(false);
2161 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2163 if (form_->formats().empty())
2165 int const nr = formatsCB->itemData(i).toInt();
2166 Format const f = form_->formats().get(nr);
2168 formatED->setText(toqstr(f.name()));
2169 copierED->setText(toqstr(form_->movers().command(f.name())));
2170 extensionsED->setText(toqstr(f.extensions()));
2171 mimeED->setText(toqstr(f.mime()));
2172 shortcutED->setText(
2173 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2174 documentCB->setChecked((f.documentFormat()));
2175 vectorCB->setChecked((f.vectorFormat()));
2176 exportMenuCB->setChecked((f.inExportMenu()));
2177 exportMenuCB->setEnabled((f.documentFormat()));
2183 void PrefFileformats::setFlags()
2185 int flags = Format::none;
2186 if (documentCB->isChecked())
2187 flags |= Format::document;
2188 if (vectorCB->isChecked())
2189 flags |= Format::vector;
2190 if (exportMenuCB->isChecked())
2191 flags |= Format::export_menu;
2192 currentFormat().setFlags(flags);
2193 exportMenuCB->setEnabled(documentCB->isChecked());
2198 void PrefFileformats::on_copierED_textEdited(const QString & s)
2200 string const fmt = fromqstr(formatED->text());
2201 form_->movers().set(fmt, fromqstr(s));
2206 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2208 currentFormat().setExtensions(fromqstr(s));
2213 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2215 currentFormat().setViewer(fromqstr(s));
2220 void PrefFileformats::on_editorED_textEdited(const QString & s)
2222 currentFormat().setEditor(fromqstr(s));
2227 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2229 currentFormat().setMime(fromqstr(s));
2234 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2236 string const new_shortcut = fromqstr(s);
2237 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2238 currentFormat().shortcut()))
2240 currentFormat().setShortcut(new_shortcut);
2245 void PrefFileformats::on_formatED_editingFinished()
2247 string const newname = fromqstr(formatED->displayText());
2248 string const oldname = currentFormat().name();
2249 if (newname == oldname)
2251 if (form_->converters().formatIsUsed(oldname)) {
2252 Alert::error(_("Format in use"),
2253 _("You cannot change a format's short name "
2254 "if the format is used by a converter. "
2255 "Please remove the converter first."));
2260 currentFormat().setName(newname);
2265 void PrefFileformats::on_formatED_textChanged(const QString &)
2267 QString t = formatED->text();
2269 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2270 setValid(formatLA, valid);
2274 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2276 QString t = formatsCB->currentText();
2278 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2279 setValid(formatsLA, valid);
2283 void PrefFileformats::updatePrettyname()
2285 QString const newname = formatsCB->currentText();
2286 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2289 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2297 void updateComboBox(LyXRC::Alternatives const & alts,
2298 string const & fmt, QComboBox * combo)
2300 LyXRC::Alternatives::const_iterator it =
2302 if (it != alts.end()) {
2303 LyXRC::CommandSet const & cmds = it->second;
2304 LyXRC::CommandSet::const_iterator sit =
2306 LyXRC::CommandSet::const_iterator const sen =
2308 for (; sit != sen; ++sit) {
2309 QString const qcmd = toqstr(*sit);
2310 combo->addItem(qcmd, qcmd);
2317 void PrefFileformats::updateViewers()
2319 Format const f = currentFormat();
2320 viewerCO->blockSignals(true);
2322 viewerCO->addItem(qt_("None"), QString());
2323 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2324 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2325 viewerCO->blockSignals(false);
2327 int pos = viewerCO->findData(toqstr(f.viewer()));
2330 viewerED->setEnabled(false);
2331 viewerCO->setCurrentIndex(pos);
2333 viewerED->setEnabled(true);
2334 viewerED->setText(toqstr(f.viewer()));
2335 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2340 void PrefFileformats::updateEditors()
2342 Format const f = currentFormat();
2343 editorCO->blockSignals(true);
2345 editorCO->addItem(qt_("None"), QString());
2346 updateComboBox(editor_alternatives, f.name(), editorCO);
2347 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2348 editorCO->blockSignals(false);
2350 int pos = editorCO->findData(toqstr(f.editor()));
2353 editorED->setEnabled(false);
2354 editorCO->setCurrentIndex(pos);
2356 editorED->setEnabled(true);
2357 editorED->setText(toqstr(f.editor()));
2358 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2363 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2365 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2366 viewerED->setEnabled(custom);
2368 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2372 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2374 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2375 editorED->setEnabled(custom);
2377 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2381 Format & PrefFileformats::currentFormat()
2383 int const i = formatsCB->currentIndex();
2384 int const nr = formatsCB->itemData(i).toInt();
2385 return form_->formats().get(nr);
2389 void PrefFileformats::on_formatNewPB_clicked()
2391 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2393 formatsCB->setCurrentIndex(0);
2394 formatsCB->setFocus(Qt::OtherFocusReason);
2398 void PrefFileformats::on_formatRemovePB_clicked()
2400 int const i = formatsCB->currentIndex();
2401 int const nr = formatsCB->itemData(i).toInt();
2402 string const current_text = form_->formats().get(nr).name();
2403 if (form_->converters().formatIsUsed(current_text)) {
2404 Alert::error(_("Format in use"),
2405 _("Cannot remove a Format used by a Converter. "
2406 "Remove the converter first."));
2410 form_->formats().erase(current_text);
2413 on_formatsCB_editTextChanged(formatsCB->currentText());
2418 /////////////////////////////////////////////////////////////////////
2422 /////////////////////////////////////////////////////////////////////
2424 PrefLanguage::PrefLanguage(GuiPreferences * form)
2425 : PrefModule(catLanguage, N_("Language"), form)
2429 connect(visualCursorRB, SIGNAL(clicked()),
2430 this, SIGNAL(changed()));
2431 connect(logicalCursorRB, SIGNAL(clicked()),
2432 this, SIGNAL(changed()));
2433 connect(markForeignCB, SIGNAL(clicked()),
2434 this, SIGNAL(changed()));
2435 connect(autoBeginCB, SIGNAL(clicked()),
2436 this, SIGNAL(changed()));
2437 connect(autoEndCB, SIGNAL(clicked()),
2438 this, SIGNAL(changed()));
2439 connect(languagePackageCO, SIGNAL(activated(int)),
2440 this, SIGNAL(changed()));
2441 connect(languagePackageED, SIGNAL(textChanged(QString)),
2442 this, SIGNAL(changed()));
2443 connect(globalCB, SIGNAL(clicked()),
2444 this, SIGNAL(changed()));
2445 connect(startCommandED, SIGNAL(textChanged(QString)),
2446 this, SIGNAL(changed()));
2447 connect(endCommandED, SIGNAL(textChanged(QString)),
2448 this, SIGNAL(changed()));
2449 connect(uiLanguageCO, SIGNAL(activated(int)),
2450 this, SIGNAL(changed()));
2451 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2452 this, SIGNAL(changed()));
2453 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2454 this, SIGNAL(changed()));
2456 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2457 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2458 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2460 defaultDecimalPointLE->setInputMask("X; ");
2461 defaultDecimalPointLE->setMaxLength(1);
2463 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2464 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2466 QAbstractItemModel * language_model = guiApp->languageModel();
2467 language_model->sort(0);
2468 uiLanguageCO->blockSignals(true);
2469 uiLanguageCO->clear();
2470 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2471 for (int i = 0; i != language_model->rowCount(); ++i) {
2472 QModelIndex index = language_model->index(i, 0);
2473 // Filter the list based on the available translation and add
2474 // each language code only once
2475 string const name = fromqstr(index.data(Qt::UserRole).toString());
2476 Language const * lang = languages.getLanguage(name);
2479 // never remove the currently selected language
2480 if (name != form->rc().gui_language
2481 && name != lyxrc.gui_language
2482 && (!Messages::available(lang->code())
2483 || !lang->hasGuiSupport()))
2485 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2486 index.data(Qt::UserRole).toString());
2488 uiLanguageCO->blockSignals(false);
2492 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2494 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2495 qt_("The change of user interface language will be fully "
2496 "effective only after a restart."));
2500 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2502 languagePackageED->setEnabled(i == 2);
2506 void PrefLanguage::applyRC(LyXRC & rc) const
2508 rc.visual_cursor = visualCursorRB->isChecked();
2509 rc.mark_foreign_language = markForeignCB->isChecked();
2510 rc.language_auto_begin = autoBeginCB->isChecked();
2511 rc.language_auto_end = autoEndCB->isChecked();
2512 int const p = languagePackageCO->currentIndex();
2514 rc.language_package_selection = LyXRC::LP_AUTO;
2516 rc.language_package_selection = LyXRC::LP_BABEL;
2518 rc.language_package_selection = LyXRC::LP_CUSTOM;
2520 rc.language_package_selection = LyXRC::LP_NONE;
2521 rc.language_custom_package = fromqstr(languagePackageED->text());
2522 rc.language_global_options = globalCB->isChecked();
2523 rc.language_command_begin = fromqstr(startCommandED->text());
2524 rc.language_command_end = fromqstr(endCommandED->text());
2525 rc.gui_language = fromqstr(
2526 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2527 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2528 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2532 void PrefLanguage::updateRC(LyXRC const & rc)
2534 if (rc.visual_cursor)
2535 visualCursorRB->setChecked(true);
2537 logicalCursorRB->setChecked(true);
2538 markForeignCB->setChecked(rc.mark_foreign_language);
2539 autoBeginCB->setChecked(rc.language_auto_begin);
2540 autoEndCB->setChecked(rc.language_auto_end);
2541 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2542 languagePackageED->setText(toqstr(rc.language_custom_package));
2543 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2544 globalCB->setChecked(rc.language_global_options);
2545 startCommandED->setText(toqstr(rc.language_command_begin));
2546 endCommandED->setText(toqstr(rc.language_command_end));
2547 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2548 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2549 defaultLengthUnitCO->setCurrentIndex(pos);
2551 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2552 uiLanguageCO->blockSignals(true);
2553 uiLanguageCO->setCurrentIndex(pos);
2554 uiLanguageCO->blockSignals(false);
2558 /////////////////////////////////////////////////////////////////////
2560 // PrefUserInterface
2562 /////////////////////////////////////////////////////////////////////
2564 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2565 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2569 connect(uiFilePB, SIGNAL(clicked()),
2570 this, SLOT(selectUi()));
2571 connect(uiFileED, SIGNAL(textChanged(QString)),
2572 this, SIGNAL(changed()));
2573 connect(iconSetCO, SIGNAL(activated(int)),
2574 this, SIGNAL(changed()));
2575 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2576 this, SIGNAL(changed()));
2577 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2578 this, SIGNAL(changed()));
2579 connect(tooltipCB, SIGNAL(toggled(bool)),
2580 this, SIGNAL(changed()));
2581 lastfilesSB->setMaximum(maxlastfiles);
2583 iconSetCO->addItem(qt_("Default"), QString());
2584 iconSetCO->addItem(qt_("Classic"), "classic");
2585 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2587 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2588 useSystemThemeIconsCB->hide();
2593 void PrefUserInterface::applyRC(LyXRC & rc) const
2595 rc.icon_set = fromqstr(iconSetCO->itemData(
2596 iconSetCO->currentIndex()).toString());
2598 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2599 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2600 rc.num_lastfiles = lastfilesSB->value();
2601 rc.use_tooltip = tooltipCB->isChecked();
2605 void PrefUserInterface::updateRC(LyXRC const & rc)
2607 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2610 iconSetCO->setCurrentIndex(iconset);
2611 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2612 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2613 lastfilesSB->setValue(rc.num_lastfiles);
2614 tooltipCB->setChecked(rc.use_tooltip);
2618 void PrefUserInterface::selectUi()
2620 QString file = form_->browseUI(internalPath(uiFileED->text()));
2621 if (!file.isEmpty())
2622 uiFileED->setText(file);
2626 /////////////////////////////////////////////////////////////////////
2628 // PrefDocumentHandling
2630 /////////////////////////////////////////////////////////////////////
2632 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2633 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2637 connect(autoSaveCB, SIGNAL(toggled(bool)),
2638 autoSaveSB, SLOT(setEnabled(bool)));
2639 connect(autoSaveCB, SIGNAL(toggled(bool)),
2640 TextLabel1, SLOT(setEnabled(bool)));
2641 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2642 this, SIGNAL(changed()));
2643 connect(singleInstanceCB, SIGNAL(clicked()),
2644 this, SIGNAL(changed()));
2645 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2646 this, SIGNAL(changed()));
2647 connect(closeLastViewCO, SIGNAL(activated(int)),
2648 this, SIGNAL(changed()));
2649 connect(restoreCursorCB, SIGNAL(clicked()),
2650 this, SIGNAL(changed()));
2651 connect(loadSessionCB, SIGNAL(clicked()),
2652 this, SIGNAL(changed()));
2653 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2654 this, SIGNAL(changed()));
2655 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2656 this, SIGNAL(changed()));
2657 connect(autoSaveCB, SIGNAL(clicked()),
2658 this, SIGNAL(changed()));
2659 connect(backupCB, SIGNAL(clicked()),
2660 this, SIGNAL(changed()));
2661 connect(saveCompressedCB, SIGNAL(clicked()),
2662 this, SIGNAL(changed()));
2663 connect(saveOriginCB, SIGNAL(clicked()),
2664 this, SIGNAL(changed()));
2668 void PrefDocHandling::applyRC(LyXRC & rc) const
2670 rc.use_lastfilepos = restoreCursorCB->isChecked();
2671 rc.load_session = loadSessionCB->isChecked();
2672 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2673 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2674 rc.make_backup = backupCB->isChecked();
2675 rc.save_compressed = saveCompressedCB->isChecked();
2676 rc.save_origin = saveOriginCB->isChecked();
2677 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2678 rc.single_instance = singleInstanceCB->isChecked();
2679 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2681 switch (closeLastViewCO->currentIndex()) {
2683 rc.close_buffer_with_last_view = "yes";
2686 rc.close_buffer_with_last_view = "no";
2689 rc.close_buffer_with_last_view = "ask";
2697 void PrefDocHandling::updateRC(LyXRC const & rc)
2699 restoreCursorCB->setChecked(rc.use_lastfilepos);
2700 loadSessionCB->setChecked(rc.load_session);
2701 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2702 // convert to minutes
2703 bool autosave = rc.autosave > 0;
2704 int mins = rc.autosave / 60;
2707 autoSaveSB->setValue(mins);
2708 autoSaveCB->setChecked(autosave);
2709 autoSaveSB->setEnabled(autosave);
2710 backupCB->setChecked(rc.make_backup);
2711 saveCompressedCB->setChecked(rc.save_compressed);
2712 saveOriginCB->setChecked(rc.save_origin);
2713 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2714 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2715 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2716 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2717 if (rc.close_buffer_with_last_view == "yes")
2718 closeLastViewCO->setCurrentIndex(0);
2719 else if (rc.close_buffer_with_last_view == "no")
2720 closeLastViewCO->setCurrentIndex(1);
2721 else if (rc.close_buffer_with_last_view == "ask")
2722 closeLastViewCO->setCurrentIndex(2);
2726 void PrefDocHandling::on_clearSessionPB_clicked()
2728 guiApp->clearSession();
2733 /////////////////////////////////////////////////////////////////////
2737 /////////////////////////////////////////////////////////////////////
2739 PrefEdit::PrefEdit(GuiPreferences * form)
2740 : PrefModule(catEditing, N_("Control"), form)
2744 connect(cursorFollowsCB, SIGNAL(clicked()),
2745 this, SIGNAL(changed()));
2746 connect(scrollBelowCB, SIGNAL(clicked()),
2747 this, SIGNAL(changed()));
2748 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2749 this, SIGNAL(changed()));
2750 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2751 this, SIGNAL(changed()));
2752 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2753 this, SIGNAL(changed()));
2754 connect(macroEditStyleCO, SIGNAL(activated(int)),
2755 this, SIGNAL(changed()));
2756 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2757 this, SIGNAL(changed()));
2758 connect(fullscreenLimitGB, SIGNAL(clicked()),
2759 this, SIGNAL(changed()));
2760 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2761 this, SIGNAL(changed()));
2762 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2763 this, SIGNAL(changed()));
2764 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2765 this, SIGNAL(changed()));
2766 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2767 this, SIGNAL(changed()));
2768 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2769 this, SIGNAL(changed()));
2770 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2771 this, SIGNAL(changed()));
2775 void PrefEdit::applyRC(LyXRC & rc) const
2777 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2778 rc.scroll_below_document = scrollBelowCB->isChecked();
2779 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2780 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2781 rc.group_layouts = groupEnvironmentsCB->isChecked();
2782 switch (macroEditStyleCO->currentIndex()) {
2783 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2784 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2785 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2787 rc.cursor_width = cursorWidthSB->value();
2788 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2789 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2790 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2791 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2792 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2793 rc.full_screen_width = fullscreenWidthSB->value();
2794 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2798 void PrefEdit::updateRC(LyXRC const & rc)
2800 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2801 scrollBelowCB->setChecked(rc.scroll_below_document);
2802 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2803 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2804 groupEnvironmentsCB->setChecked(rc.group_layouts);
2805 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2806 cursorWidthSB->setValue(rc.cursor_width);
2807 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2808 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2809 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2810 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2811 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2812 fullscreenWidthSB->setValue(rc.full_screen_width);
2813 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2817 /////////////////////////////////////////////////////////////////////
2821 /////////////////////////////////////////////////////////////////////
2824 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2826 Ui::shortcutUi::setupUi(this);
2827 QDialog::setModal(true);
2831 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2832 : PrefModule(catEditing, N_("Shortcuts"), form),
2833 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2838 shortcutsTW->setColumnCount(2);
2839 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2840 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2841 shortcutsTW->setSortingEnabled(true);
2842 // Multi-selection can be annoying.
2843 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2845 connect(bindFilePB, SIGNAL(clicked()),
2846 this, SLOT(selectBind()));
2847 connect(bindFileED, SIGNAL(textChanged(QString)),
2848 this, SIGNAL(changed()));
2850 shortcut_ = new GuiShortcutDialog(this);
2851 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2852 shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
2853 shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
2855 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2856 this, SIGNAL(changed()));
2857 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2858 shortcut_, SLOT(reject()));
2859 connect(shortcut_->clearPB, SIGNAL(clicked()),
2860 this, SLOT(shortcutClearPressed()));
2861 connect(shortcut_->removePB, SIGNAL(clicked()),
2862 this, SLOT(shortcutRemovePressed()));
2863 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2864 this, SLOT(shortcutOkPressed()));
2865 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2866 this, SLOT(shortcutCancelPressed()));
2870 void PrefShortcuts::applyRC(LyXRC & rc) const
2872 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2873 // write user_bind and user_unbind to .lyx/bind/user.bind
2874 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2875 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2876 lyxerr << "LyX could not create the user bind directory '"
2877 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2880 if (!bind_dir.isDirWritable()) {
2881 lyxerr << "LyX could not write to the user bind directory '"
2882 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2885 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2886 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2887 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2888 // immediately apply the keybindings. Why this is not done before?
2889 // The good thing is that the menus are updated automatically.
2890 theTopLevelKeymap().clear();
2891 theTopLevelKeymap().read("site");
2892 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2893 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2897 void PrefShortcuts::updateRC(LyXRC const & rc)
2899 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2901 system_bind_.clear();
2903 user_unbind_.clear();
2904 system_bind_.read("site");
2905 system_bind_.read(rc.bind_file);
2906 // \unbind in user.bind is added to user_unbind_
2907 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2908 updateShortcutsTW();
2912 void PrefShortcuts::updateShortcutsTW()
2914 shortcutsTW->clear();
2916 editItem_ = new QTreeWidgetItem(shortcutsTW);
2917 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2918 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2920 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2921 mathItem_->setText(0, qt_("Mathematical Symbols"));
2922 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2924 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2925 bufferItem_->setText(0, qt_("Document and Window"));
2926 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2928 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2929 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2930 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2932 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2933 systemItem_->setText(0, qt_("System and Miscellaneous"));
2934 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2936 // listBindings(unbound=true) lists all bound and unbound lfuns
2937 // Items in this list is tagged by its source.
2938 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2940 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2942 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2943 KeyMap::UserUnbind);
2944 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2945 user_bindinglist.end());
2946 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2947 user_unbindinglist.end());
2949 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2950 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2951 for (; it != it_end; ++it)
2952 insertShortcutItem(it->request, it->sequence, it->tag);
2954 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2955 on_shortcutsTW_itemSelectionChanged();
2956 on_searchLE_textEdited();
2957 shortcutsTW->resizeColumnToContents(0);
2962 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2964 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2969 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2971 // Hide rebound system settings that are empty
2972 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2976 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2978 item->setData(0, Qt::UserRole, QVariant(tag));
2982 case KeyMap::System:
2984 case KeyMap::UserBind:
2987 case KeyMap::UserUnbind:
2988 font.setStrikeOut(true);
2990 // this item is not displayed now.
2991 case KeyMap::UserExtraUnbind:
2992 font.setStrikeOut(true);
2995 item->setHidden(isAlwaysHidden(*item));
2996 item->setFont(1, font);
3000 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
3001 KeySequence const & seq, KeyMap::ItemType tag)
3003 FuncCode const action = lfun.action();
3004 string const action_name = lyxaction.getActionName(action);
3005 QString const lfun_name = toqstr(from_utf8(action_name)
3006 + ' ' + lfun.argument());
3007 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
3009 QTreeWidgetItem * newItem = 0;
3010 // for unbind items, try to find an existing item in the system bind list
3011 if (tag == KeyMap::UserUnbind) {
3012 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
3013 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3014 for (int i = 0; i < items.size(); ++i) {
3015 if (items[i]->text(1) == shortcut) {
3020 // if not found, this unbind item is KeyMap::UserExtraUnbind
3021 // Such an item is not displayed to avoid confusion (what is
3022 // unmatched removed?).
3028 switch(lyxaction.getActionType(action)) {
3029 case LyXAction::Hidden:
3031 case LyXAction::Edit:
3032 newItem = new QTreeWidgetItem(editItem_);
3034 case LyXAction::Math:
3035 newItem = new QTreeWidgetItem(mathItem_);
3037 case LyXAction::Buffer:
3038 newItem = new QTreeWidgetItem(bufferItem_);
3040 case LyXAction::Layout:
3041 newItem = new QTreeWidgetItem(layoutItem_);
3043 case LyXAction::System:
3044 newItem = new QTreeWidgetItem(systemItem_);
3047 // this should not happen
3048 newItem = new QTreeWidgetItem(shortcutsTW);
3052 newItem->setText(0, lfun_name);
3053 newItem->setText(1, shortcut);
3054 // record BindFile representation to recover KeySequence when needed.
3055 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
3056 setItemType(newItem, tag);
3061 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
3063 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3064 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
3065 modifyPB->setEnabled(!items.isEmpty());
3066 if (items.isEmpty())
3069 if (itemType(*items[0]) == KeyMap::UserUnbind)
3070 removePB->setText(qt_("Res&tore"));
3072 removePB->setText(qt_("Remo&ve"));
3076 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3082 void PrefShortcuts::modifyShortcut()
3084 QTreeWidgetItem * item = shortcutsTW->currentItem();
3085 if (item->flags() & Qt::ItemIsSelectable) {
3086 shortcut_->lfunLE->setText(item->text(0));
3087 save_lfun_ = item->text(0).trimmed();
3088 shortcut_->shortcutWG->setText(item->text(1));
3090 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3091 shortcut_->shortcutWG->setKeySequence(seq);
3092 shortcut_->shortcutWG->setFocus();
3098 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3100 // list of items that match lfun
3101 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3102 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3103 for (int i = 0; i < items.size(); ++i) {
3104 QTreeWidgetItem * item = items[i];
3105 if (isAlwaysHidden(*item)) {
3106 setItemType(item, KeyMap::System);
3108 shortcutsTW->setCurrentItem(item);
3115 void PrefShortcuts::removeShortcut()
3117 // it seems that only one item can be selected, but I am
3118 // removing all selected items anyway.
3119 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3120 for (int i = 0; i < items.size(); ++i) {
3121 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3122 string lfun = fromqstr(items[i]->text(0));
3123 FuncRequest func = lyxaction.lookupFunc(lfun);
3125 switch (itemType(*items[i])) {
3126 case KeyMap::System: {
3127 // for system bind, we do not touch the item
3128 // but add an user unbind item
3129 user_unbind_.bind(shortcut, func);
3130 setItemType(items[i], KeyMap::UserUnbind);
3131 removePB->setText(qt_("Res&tore"));
3134 case KeyMap::UserBind: {
3135 // for user_bind, we remove this bind
3136 QTreeWidgetItem * parent = items[i]->parent();
3137 int itemIdx = parent->indexOfChild(items[i]);
3138 parent->takeChild(itemIdx);
3140 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3142 shortcutsTW->scrollToItem(parent);
3143 user_bind_.unbind(shortcut, func);
3144 // If this user binding hid an empty system binding, unhide the
3145 // latter and select it.
3146 unhideEmpty(items[i]->text(0), true);
3149 case KeyMap::UserUnbind: {
3150 // for user_unbind, we remove the unbind, and the item
3151 // become KeyMap::System again.
3153 seq.parse(shortcut);
3154 // Ask the user to replace current binding
3155 if (!validateNewShortcut(func, seq, QString()))
3157 user_unbind_.unbind(shortcut, func);
3158 setItemType(items[i], KeyMap::System);
3159 removePB->setText(qt_("Remo&ve"));
3162 case KeyMap::UserExtraUnbind: {
3163 // for user unbind that is not in system bind file,
3164 // remove this unbind file
3165 QTreeWidgetItem * parent = items[i]->parent();
3166 parent->takeChild(parent->indexOfChild(items[i]));
3167 user_unbind_.unbind(shortcut, func);
3174 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3176 for (int i = 0; i < items.size(); ++i) {
3177 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3178 string lfun = fromqstr(items[i]->text(0));
3179 FuncRequest func = lyxaction.lookupFunc(lfun);
3181 switch (itemType(*items[i])) {
3182 case KeyMap::System:
3183 // for system bind, we do not touch the item
3184 // but add an user unbind item
3185 user_unbind_.bind(shortcut, func);
3186 setItemType(items[i], KeyMap::UserUnbind);
3189 case KeyMap::UserBind: {
3190 // for user_bind, we remove this bind
3191 QTreeWidgetItem * parent = items[i]->parent();
3192 int itemIdx = parent->indexOfChild(items[i]);
3193 parent->takeChild(itemIdx);
3194 user_bind_.unbind(shortcut, func);
3195 unhideEmpty(items[i]->text(0), false);
3205 void PrefShortcuts::selectBind()
3207 QString file = form_->browsebind(internalPath(bindFileED->text()));
3208 if (!file.isEmpty()) {
3209 bindFileED->setText(file);
3210 system_bind_ = KeyMap();
3211 system_bind_.read(fromqstr(file));
3212 updateShortcutsTW();
3217 void PrefShortcuts::on_modifyPB_pressed()
3223 void PrefShortcuts::on_newPB_pressed()
3225 shortcut_->lfunLE->clear();
3226 shortcut_->shortcutWG->reset();
3227 save_lfun_ = QString();
3232 void PrefShortcuts::on_removePB_pressed()
3239 void PrefShortcuts::on_searchLE_textEdited()
3241 if (searchLE->text().isEmpty()) {
3242 // show all hidden items
3243 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3245 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3246 // close all categories
3247 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3248 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3251 // search both columns
3252 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3253 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3254 matched += shortcutsTW->findItems(searchLE->text(),
3255 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3257 // hide everyone (to avoid searching in matched QList repeatedly
3258 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3260 shortcutsTW->setItemHidden(*it++, true);
3261 // show matched items
3262 for (int i = 0; i < matched.size(); ++i)
3263 if (!isAlwaysHidden(*matched[i])) {
3264 shortcutsTW->setItemHidden(matched[i], false);
3265 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3270 docstring makeCmdString(FuncRequest const & f)
3272 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3273 if (!f.argument().empty())
3274 actionStr += " " + f.argument();
3279 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3281 FuncRequest res = user_bind_.getBinding(k);
3282 if (res.action() != LFUN_UNKNOWN_ACTION)
3284 res = system_bind_.getBinding(k);
3285 // Check if it is unbound. Note: user_unbind_ can only unbind one
3286 // FuncRequest per key sequence.
3287 if (user_unbind_.getBinding(k) == res)
3288 return FuncRequest::unknown;
3293 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3294 KeySequence const & k,
3295 QString const & lfun_to_modify)
3297 if (func.action() == LFUN_UNKNOWN_ACTION) {
3298 Alert::error(_("Failed to create shortcut"),
3299 _("Unknown or invalid LyX function"));
3303 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3304 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3305 // and how it is used in GuiPrefs::shortcutOkPressed.
3306 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3307 Alert::error(_("Failed to create shortcut"),
3308 _("This LyX function is hidden and cannot be bound."));
3312 if (k.length() == 0) {
3313 Alert::error(_("Failed to create shortcut"),
3314 _("Invalid or empty key sequence"));
3318 FuncRequest oldBinding = currentBinding(k);
3319 if (oldBinding == func)
3320 // nothing to change
3323 // make sure this key isn't already bound---and, if so, prompt user
3324 // (exclude the lfun the user already wants to modify)
3325 docstring const action_string = makeCmdString(oldBinding);
3326 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3327 && lfun_to_modify != toqstr(action_string)) {
3328 docstring const new_action_string = makeCmdString(func);
3329 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3331 "Are you sure you want to unbind the "
3332 "current shortcut and bind it to %3$s?"),
3333 k.print(KeySequence::ForGui), action_string,
3335 int ret = Alert::prompt(_("Redefine shortcut?"),
3336 text, 0, 1, _("&Redefine"), _("&Cancel"));
3339 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3340 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3341 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3342 deactivateShortcuts(items);
3348 void PrefShortcuts::shortcutOkPressed()
3350 QString const new_lfun = shortcut_->lfunLE->text();
3351 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3352 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3354 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3355 // "modify", or is empty if they clicked "new" (which I do not really like)
3356 if (!validateNewShortcut(func, k, save_lfun_))
3359 if (!save_lfun_.isEmpty()) {
3360 // real modification of the lfun's shortcut,
3361 // so remove the previous one
3362 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3363 deactivateShortcuts(to_modify);
3366 shortcut_->accept();
3368 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3370 user_bind_.bind(&k, func);
3371 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3372 shortcutsTW->setItemExpanded(item->parent(), true);
3373 shortcutsTW->setCurrentItem(item);
3374 shortcutsTW->scrollToItem(item);
3376 Alert::error(_("Failed to create shortcut"),
3377 _("Can not insert shortcut to the list"));
3383 void PrefShortcuts::shortcutCancelPressed()
3385 shortcut_->shortcutWG->reset();
3389 void PrefShortcuts::shortcutClearPressed()
3391 shortcut_->shortcutWG->reset();
3395 void PrefShortcuts::shortcutRemovePressed()
3397 shortcut_->shortcutWG->removeFromSequence();
3401 /////////////////////////////////////////////////////////////////////
3405 /////////////////////////////////////////////////////////////////////
3407 PrefIdentity::PrefIdentity(GuiPreferences * form)
3408 : PrefModule(QString(), N_("Identity"), form)
3412 connect(nameED, SIGNAL(textChanged(QString)),
3413 this, SIGNAL(changed()));
3414 connect(emailED, SIGNAL(textChanged(QString)),
3415 this, SIGNAL(changed()));
3417 nameED->setValidator(new NoNewLineValidator(nameED));
3418 emailED->setValidator(new NoNewLineValidator(emailED));
3422 void PrefIdentity::applyRC(LyXRC & rc) const
3424 rc.user_name = fromqstr(nameED->text());
3425 rc.user_email = fromqstr(emailED->text());
3429 void PrefIdentity::updateRC(LyXRC const & rc)
3431 nameED->setText(toqstr(rc.user_name));
3432 emailED->setText(toqstr(rc.user_email));
3437 /////////////////////////////////////////////////////////////////////
3441 /////////////////////////////////////////////////////////////////////
3443 GuiPreferences::GuiPreferences(GuiView & lv)
3444 : GuiDialog(lv, "prefs", qt_("Preferences"))
3448 QDialog::setModal(false);
3450 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
3451 this, SLOT(slotButtonBox(QAbstractButton *)));
3453 addModule(new PrefUserInterface(this));
3454 addModule(new PrefDocHandling(this));
3455 addModule(new PrefEdit(this));
3456 addModule(new PrefShortcuts(this));
3457 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3458 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3459 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3460 addModule(screenfonts);
3461 addModule(new PrefColors(this));
3462 addModule(new PrefDisplay(this));
3463 addModule(new PrefInput(this));
3464 addModule(new PrefCompletion(this));
3466 addModule(new PrefPaths(this));
3468 addModule(new PrefIdentity(this));
3470 addModule(new PrefLanguage(this));
3471 addModule(new PrefSpellchecker(this));
3473 PrefOutput * output = new PrefOutput(this);
3475 addModule(new PrefLatex(this));
3477 PrefConverters * converters = new PrefConverters(this);
3478 PrefFileformats * formats = new PrefFileformats(this);
3479 connect(formats, SIGNAL(formatsChanged()),
3480 converters, SLOT(updateGui()));
3481 addModule(converters);
3484 prefsPS->setCurrentPanel("User Interface");
3485 // FIXME: hack to work around resizing bug in Qt >= 4.2
3486 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3487 #if QT_VERSION >= 0x040200
3488 prefsPS->updateGeometry();
3491 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3492 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
3493 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
3494 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
3495 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
3499 void GuiPreferences::addModule(PrefModule * module)
3501 LASSERT(module, return);
3502 if (module->category().isEmpty())
3503 prefsPS->addPanel(module, module->title());
3505 prefsPS->addPanel(module, module->title(), module->category());
3506 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3507 modules_.push_back(module);
3511 void GuiPreferences::change_adaptor()
3517 void GuiPreferences::applyRC(LyXRC & rc) const
3519 size_t end = modules_.size();
3520 for (size_t i = 0; i != end; ++i)
3521 modules_[i]->applyRC(rc);
3525 void GuiPreferences::updateRC(LyXRC const & rc)
3527 size_t const end = modules_.size();
3528 for (size_t i = 0; i != end; ++i)
3529 modules_[i]->updateRC(rc);
3533 void GuiPreferences::applyView()
3539 bool GuiPreferences::initialiseParams(string const &)
3542 formats_ = theFormats();
3543 converters_ = theConverters();
3544 converters_.update(formats_);
3545 movers_ = theMovers();
3549 // Make sure that the bc is in the INITIAL state
3550 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3557 void GuiPreferences::dispatchParams()
3560 rc_.write(ss, true);
3561 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3562 // issue prefsApplied signal. This will update the
3563 // localized screen font sizes.
3565 // FIXME: these need lfuns
3567 Author const & author =
3568 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3569 theBufferList().recordCurrentAuthor(author);
3571 theFormats() = formats_;
3573 theConverters() = converters_;
3574 theConverters().update(formats_);
3575 theConverters().buildGraph();
3576 theBufferList().invalidateConverterCache();
3578 theMovers() = movers_;
3580 for (string const & color : colors_)
3581 dispatch(FuncRequest(LFUN_SET_COLOR, color));
3585 if (!tempSaveCB->isChecked())
3586 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3590 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3592 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3596 QString GuiPreferences::browsebind(QString const & file) const
3598 return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
3599 QStringList(qt_("LyX bind files (*.bind)")));
3603 QString GuiPreferences::browseUI(QString const & file) const
3605 return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
3606 QStringList(qt_("LyX UI files (*.ui)")));
3610 QString GuiPreferences::browsekbmap(QString const & file) const
3612 return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
3613 QStringList(qt_("LyX keyboard maps (*.kmap)")));
3617 QString GuiPreferences::browse(QString const & file,
3618 QString const & title) const
3620 return browseFile(file, title, QStringList(), true);
3624 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3627 } // namespace frontend
3630 #include "moc_GuiPrefs.cpp"