3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
16 #include "qt_helpers.h"
17 #include "GuiApplication.h"
19 #include "ConverterCache.h"
24 #include "PanelStack.h"
25 #include "QFontExample.h"
28 #include "support/lstrings.h"
29 #include "support/os.h"
31 #include "controllers/ControlPrefs.h"
32 #include "controllers/frontend_helpers.h"
34 #include "frontends/alert.h"
35 #include "frontends/Application.h"
38 #include <QColorDialog>
39 #include <QFontDatabase>
41 #include <QPushButton>
45 #include <QCloseEvent>
47 #include <boost/tuple/tuple.hpp>
53 using lyx::support::compare_ascii_no_case;
54 using lyx::support::os::external_path;
55 using lyx::support::os::external_path_list;
56 using lyx::support::os::internal_path;
57 using lyx::support::os::internal_path_list;
68 /////////////////////////////////////////////////////////////////////
72 /////////////////////////////////////////////////////////////////////
74 string const LookAndFeel = N_("Look and feel");
75 string const LanguageSettings = N_("Language settings");
76 string const Outputs = N_("Outputs");
79 // FIXME: move to frontend_helpers.h
82 static size_t findPos_helper(std::vector<A> const & vec, A const & val)
84 typedef typename std::vector<A>::const_iterator Cit;
86 Cit it = std::find(vec.begin(), vec.end(), val);
89 return std::distance(vec.begin(), it);
93 static void setComboxFont(QComboBox * cb, string const & family,
94 string const & foundry)
96 string const name = makeFontName(family, foundry);
97 for (int i = 0; i < cb->count(); ++i) {
98 if (fromqstr(cb->itemText(i)) == name) {
99 cb->setCurrentIndex(i);
104 // Try matching without foundry name
106 // We count in reverse in order to prefer the Xft foundry
107 for (int i = cb->count() - 1; i >= 0; --i) {
108 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
109 if (compare_ascii_no_case(tmp.first, family) == 0) {
110 cb->setCurrentIndex(i);
115 // family alone can contain e.g. "Helvetica [Adobe]"
116 pair<string, string> tmpfam = parseFontName(family);
118 // We count in reverse in order to prefer the Xft foundry
119 for (int i = cb->count() - 1; i >= 0; --i) {
120 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
121 if (compare_ascii_no_case(tmp.first, tmpfam.first) == 0) {
122 cb->setCurrentIndex(i);
127 // Bleh, default fonts, and the names couldn't be found. Hack
131 font.setKerning(false);
133 if (family == theApp()->romanFontName()) {
134 font.setStyleHint(QFont::Serif);
135 font.setFamily(family.c_str());
136 } else if (family == theApp()->sansFontName()) {
137 font.setStyleHint(QFont::SansSerif);
138 font.setFamily(family.c_str());
139 } else if (family == theApp()->typewriterFontName()) {
140 font.setStyleHint(QFont::TypeWriter);
141 font.setFamily(family.c_str());
143 lyxerr << "FAILED to find the default font: '"
144 << foundry << "', '" << family << '\''<< endl;
148 QFontInfo info(font);
149 pair<string, string> tmp = parseFontName(fromqstr(info.family()));
150 string const & default_font_name = tmp.first;
151 lyxerr << "Apparent font is " << default_font_name << endl;
153 for (int i = 0; i < cb->count(); ++i) {
154 lyxerr << "Looking at " << fromqstr(cb->itemText(i)) << endl;
155 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
156 default_font_name) == 0) {
157 cb->setCurrentIndex(i);
162 lyxerr << "FAILED to find the font: '"
163 << foundry << "', '" << family << '\'' <<endl;
167 /////////////////////////////////////////////////////////////////////
171 /////////////////////////////////////////////////////////////////////
173 PrefPlaintext::PrefPlaintext(QWidget * parent)
174 : PrefModule(_(Outputs), _("Plain text"), 0, parent)
177 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
178 this, SIGNAL(changed()));
179 connect(plaintextRoffED, SIGNAL(textChanged(const QString&)),
180 this, SIGNAL(changed()));
184 void PrefPlaintext::apply(LyXRC & rc) const
186 rc.plaintext_linelen = plaintextLinelengthSB->value();
187 rc.plaintext_roff_command = fromqstr(plaintextRoffED->text());
191 void PrefPlaintext::update(LyXRC const & rc)
193 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
194 plaintextRoffED->setText(toqstr(rc.plaintext_roff_command));
198 /////////////////////////////////////////////////////////////////////
202 /////////////////////////////////////////////////////////////////////
204 PrefDate::PrefDate(QWidget * parent)
205 : PrefModule(_(Outputs), _("Date format"), 0, parent)
208 connect(DateED, SIGNAL(textChanged(const QString &)),
209 this, SIGNAL(changed()));
213 void PrefDate::apply(LyXRC & rc) const
215 rc.date_insert_format = fromqstr(DateED->text());
219 void PrefDate::update(LyXRC const & rc)
221 DateED->setText(toqstr(rc.date_insert_format));
225 /////////////////////////////////////////////////////////////////////
229 /////////////////////////////////////////////////////////////////////
231 PrefKeyboard::PrefKeyboard(QPrefs * form, QWidget * parent)
232 : PrefModule(_(LookAndFeel), _("Keyboard"), form, parent)
236 connect(keymapCB, SIGNAL(clicked()),
237 this, SIGNAL(changed()));
238 connect(firstKeymapED, SIGNAL(textChanged(const QString&)),
239 this, SIGNAL(changed()));
240 connect(secondKeymapED, SIGNAL(textChanged(const QString&)),
241 this, SIGNAL(changed()));
245 void PrefKeyboard::apply(LyXRC & rc) const
247 // FIXME: can derive CB from the two EDs
248 rc.use_kbmap = keymapCB->isChecked();
249 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
250 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
254 void PrefKeyboard::update(LyXRC const & rc)
256 // FIXME: can derive CB from the two EDs
257 keymapCB->setChecked(rc.use_kbmap);
258 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
259 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
263 QString PrefKeyboard::testKeymap(QString keymap)
265 return toqstr(form_->controller().browsekbmap(from_utf8(internal_path(fromqstr(keymap)))));
269 void PrefKeyboard::on_firstKeymapPB_clicked(bool)
271 QString const file = testKeymap(firstKeymapED->text());
273 firstKeymapED->setText(file);
277 void PrefKeyboard::on_secondKeymapPB_clicked(bool)
279 QString const file = testKeymap(secondKeymapED->text());
281 secondKeymapED->setText(file);
285 void PrefKeyboard::on_keymapCB_toggled(bool keymap)
287 firstKeymapLA->setEnabled(keymap);
288 secondKeymapLA->setEnabled(keymap);
289 firstKeymapED->setEnabled(keymap);
290 secondKeymapED->setEnabled(keymap);
291 firstKeymapPB->setEnabled(keymap);
292 secondKeymapPB->setEnabled(keymap);
296 /////////////////////////////////////////////////////////////////////
300 /////////////////////////////////////////////////////////////////////
302 PrefLatex::PrefLatex(QPrefs * form, QWidget * parent)
303 : PrefModule(_(Outputs), _("LaTeX"), form, parent)
306 connect(latexEncodingED, SIGNAL(textChanged(const QString&)),
307 this, SIGNAL(changed()));
308 connect(latexChecktexED, SIGNAL(textChanged(const QString&)),
309 this, SIGNAL(changed()));
310 connect(latexBibtexED, SIGNAL(textChanged(const QString&)),
311 this, SIGNAL(changed()));
312 connect(latexIndexED, SIGNAL(textChanged(const QString&)),
313 this, SIGNAL(changed()));
314 connect(latexAutoresetCB, SIGNAL(clicked()),
315 this, SIGNAL(changed()));
316 connect(latexDviPaperED, SIGNAL(textChanged(const QString&)),
317 this, SIGNAL(changed()));
318 connect(latexPaperSizeCO, SIGNAL(activated(int)),
319 this, SIGNAL(changed()));
323 void PrefLatex::apply(LyXRC & rc) const
325 rc.fontenc = fromqstr(latexEncodingED->text());
326 rc.chktex_command = fromqstr(latexChecktexED->text());
327 rc.bibtex_command = fromqstr(latexBibtexED->text());
328 rc.index_command = fromqstr(latexIndexED->text());
329 rc.auto_reset_options = latexAutoresetCB->isChecked();
330 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
331 rc.default_papersize =
332 form_->controller().toPaperSize(latexPaperSizeCO->currentIndex());
336 void PrefLatex::update(LyXRC const & rc)
338 latexEncodingED->setText(toqstr(rc.fontenc));
339 latexChecktexED->setText(toqstr(rc.chktex_command));
340 latexBibtexED->setText(toqstr(rc.bibtex_command));
341 latexIndexED->setText(toqstr(rc.index_command));
342 latexAutoresetCB->setChecked(rc.auto_reset_options);
343 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
344 latexPaperSizeCO->setCurrentIndex(
345 form_->controller().fromPaperSize(rc.default_papersize));
349 /////////////////////////////////////////////////////////////////////
353 /////////////////////////////////////////////////////////////////////
355 PrefScreenFonts::PrefScreenFonts(QPrefs * form, QWidget * parent)
356 : PrefModule(_(LookAndFeel), _("Screen fonts"), form, parent)
360 connect(screenRomanCO, SIGNAL(activated(const QString&)),
361 this, SLOT(select_roman(const QString&)));
362 connect(screenSansCO, SIGNAL(activated(const QString&)),
363 this, SLOT(select_sans(const QString&)));
364 connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
365 this, SLOT(select_typewriter(const QString&)));
367 QFontDatabase fontdb;
368 QStringList families(fontdb.families());
369 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
370 screenRomanCO->addItem(*it);
371 screenSansCO->addItem(*it);
372 screenTypewriterCO->addItem(*it);
374 connect(screenRomanCO, SIGNAL(activated(const QString&)),
375 this, SIGNAL(changed()));
376 connect(screenSansCO, SIGNAL(activated(const QString&)),
377 this, SIGNAL(changed()));
378 connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
379 this, SIGNAL(changed()));
380 connect(screenZoomSB, SIGNAL(valueChanged(int)),
381 this, SIGNAL(changed()));
382 connect(screenDpiSB, SIGNAL(valueChanged(int)),
383 this, SIGNAL(changed()));
384 connect(screenTinyED, SIGNAL(textChanged(const QString&)),
385 this, SIGNAL(changed()));
386 connect(screenSmallestED, SIGNAL(textChanged(const QString&)),
387 this, SIGNAL(changed()));
388 connect(screenSmallerED, SIGNAL(textChanged(const QString&)),
389 this, SIGNAL(changed()));
390 connect(screenSmallED, SIGNAL(textChanged(const QString&)),
391 this, SIGNAL(changed()));
392 connect(screenNormalED, SIGNAL(textChanged(const QString&)),
393 this, SIGNAL(changed()));
394 connect(screenLargeED, SIGNAL(textChanged(const QString&)),
395 this, SIGNAL(changed()));
396 connect(screenLargerED, SIGNAL(textChanged(const QString&)),
397 this, SIGNAL(changed()));
398 connect(screenLargestED, SIGNAL(textChanged(const QString&)),
399 this, SIGNAL(changed()));
400 connect(screenHugeED, SIGNAL(textChanged(const QString&)),
401 this, SIGNAL(changed()));
402 connect(screenHugerED, SIGNAL(textChanged(const QString&)),
403 this, SIGNAL(changed()));
405 screenTinyED->setValidator(new QDoubleValidator(
407 screenSmallestED->setValidator(new QDoubleValidator(
409 screenSmallerED->setValidator(new QDoubleValidator(
411 screenSmallED->setValidator(new QDoubleValidator(
413 screenNormalED->setValidator(new QDoubleValidator(
415 screenLargeED->setValidator(new QDoubleValidator(
417 screenLargerED->setValidator(new QDoubleValidator(
419 screenLargestED->setValidator(new QDoubleValidator(
421 screenHugeED->setValidator(new QDoubleValidator(
423 screenHugerED->setValidator(new QDoubleValidator(
428 void PrefScreenFonts::apply(LyXRC & rc) const
430 LyXRC const oldrc(rc);
432 boost::tie(rc.roman_font_name, rc.roman_font_foundry)
433 = parseFontName(fromqstr(screenRomanCO->currentText()));
434 boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
435 parseFontName(fromqstr(screenSansCO->currentText()));
436 boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
437 parseFontName(fromqstr(screenTypewriterCO->currentText()));
439 rc.zoom = screenZoomSB->value();
440 rc.dpi = screenDpiSB->value();
441 rc.font_sizes[Font::SIZE_TINY] = fromqstr(screenTinyED->text());
442 rc.font_sizes[Font::SIZE_SCRIPT] = fromqstr(screenSmallestED->text());
443 rc.font_sizes[Font::SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text());
444 rc.font_sizes[Font::SIZE_SMALL] = fromqstr(screenSmallED->text());
445 rc.font_sizes[Font::SIZE_NORMAL] = fromqstr(screenNormalED->text());
446 rc.font_sizes[Font::SIZE_LARGE] = fromqstr(screenLargeED->text());
447 rc.font_sizes[Font::SIZE_LARGER] = fromqstr(screenLargerED->text());
448 rc.font_sizes[Font::SIZE_LARGEST] = fromqstr(screenLargestED->text());
449 rc.font_sizes[Font::SIZE_HUGE] = fromqstr(screenHugeED->text());
450 rc.font_sizes[Font::SIZE_HUGER] = fromqstr(screenHugerED->text());
452 if (rc.font_sizes != oldrc.font_sizes
453 || rc.roman_font_name != oldrc.roman_font_name
454 || rc.sans_font_name != oldrc.sans_font_name
455 || rc.typewriter_font_name != oldrc.typewriter_font_name
456 || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
457 form_->controller().updateScreenFonts();
462 void PrefScreenFonts::update(LyXRC const & rc)
464 setComboxFont(screenRomanCO, rc.roman_font_name,
465 rc.roman_font_foundry);
466 setComboxFont(screenSansCO, rc.sans_font_name,
467 rc.sans_font_foundry);
468 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
469 rc.typewriter_font_foundry);
471 select_roman(screenRomanCO->currentText());
472 select_sans(screenSansCO->currentText());
473 select_typewriter(screenTypewriterCO->currentText());
475 screenZoomSB->setValue(rc.zoom);
476 screenDpiSB->setValue(rc.dpi);
477 screenTinyED->setText(toqstr(rc.font_sizes[Font::SIZE_TINY]));
478 screenSmallestED->setText(toqstr(rc.font_sizes[Font::SIZE_SCRIPT]));
479 screenSmallerED->setText(toqstr(rc.font_sizes[Font::SIZE_FOOTNOTE]));
480 screenSmallED->setText(toqstr(rc.font_sizes[Font::SIZE_SMALL]));
481 screenNormalED->setText(toqstr(rc.font_sizes[Font::SIZE_NORMAL]));
482 screenLargeED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGE]));
483 screenLargerED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGER]));
484 screenLargestED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGEST]));
485 screenHugeED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGE]));
486 screenHugerED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGER]));
489 void PrefScreenFonts::select_roman(const QString& name)
491 screenRomanFE->set(QFont(name), name);
495 void PrefScreenFonts::select_sans(const QString& name)
497 screenSansFE->set(QFont(name), name);
501 void PrefScreenFonts::select_typewriter(const QString& name)
503 screenTypewriterFE->set(QFont(name), name);
507 /////////////////////////////////////////////////////////////////////
511 /////////////////////////////////////////////////////////////////////
513 PrefColors::PrefColors(QPrefs * form, QWidget * parent)
514 : PrefModule(_(LookAndFeel), _("Colors"), form, parent)
518 // FIXME: all of this initialization should be put into the controller.
519 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
520 // for some discussion of why that is not trivial.
521 QPixmap icon(32, 32);
522 for (int i = 0; i < Color::ignore; ++i) {
523 Color::color lc = static_cast<Color::color>(i);
524 if (lc == Color::none
525 || lc == Color::black
526 || lc == Color::white
528 || lc == Color::green
531 || lc == Color::magenta
532 || lc == Color::yellow
533 || lc == Color::inherit
534 || lc == Color::ignore) continue;
536 lcolors_.push_back(lc);
538 lcolors_ = frontend::getSortedColors(lcolors_);
539 vector<Color_color>::const_iterator cit = lcolors_.begin();
540 vector<Color_color>::const_iterator const end = lcolors_.end();
541 for (; cit != end; ++cit)
543 // This is not a memory leak:
544 /*QListWidgetItem * newItem =*/ new QListWidgetItem(QIcon(icon),
545 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
547 curcolors_.resize(lcolors_.size());
548 newcolors_.resize(lcolors_.size());
549 // End initialization
551 connect(colorChangePB, SIGNAL(clicked()),
552 this, SLOT(change_color()));
553 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
554 this, SLOT(change_lyxObjects_selection()));
555 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
556 this, SLOT(change_color()));
560 void PrefColors::apply(LyXRC & /*rc*/) const
562 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
563 if (curcolors_[i] != newcolors_[i]) {
564 form_->controller().setColor(lcolors_[i], fromqstr(newcolors_[i]));
570 void PrefColors::update(LyXRC const & /*rc*/)
572 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
573 QColor color = QColor(guiApp->colorCache().get(lcolors_[i]));
574 QPixmap coloritem(32, 32);
575 coloritem.fill(color);
576 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
577 newcolors_[i] = curcolors_[i] = color.name();
579 change_lyxObjects_selection();
582 void PrefColors::change_color()
584 int const row = lyxObjectsLW->currentRow();
589 QString const color = newcolors_[row];
590 QColor c(QColorDialog::getColor(QColor(color), qApp->focusWidget()));
592 if (c.isValid() && c.name() != color) {
593 newcolors_[row] = c.name();
594 QPixmap coloritem(32, 32);
596 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
602 void PrefColors::change_lyxObjects_selection()
604 colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
608 /////////////////////////////////////////////////////////////////////
612 /////////////////////////////////////////////////////////////////////
614 PrefCygwinPath::PrefCygwinPath(QWidget * parent)
615 : PrefModule(_(Outputs), _("Paths"), 0, parent)
618 connect(pathCB, SIGNAL(clicked()), this, SIGNAL(changed()));
622 void PrefCygwinPath::apply(LyXRC & rc) const
624 rc.windows_style_tex_paths = pathCB->isChecked();
628 void PrefCygwinPath::update(LyXRC const & rc)
630 pathCB->setChecked(rc.windows_style_tex_paths);
634 /////////////////////////////////////////////////////////////////////
638 /////////////////////////////////////////////////////////////////////
640 PrefDisplay::PrefDisplay(QWidget * parent)
641 : PrefModule(_(LookAndFeel), _("Graphics"), 0, parent)
644 connect(instantPreviewCO, SIGNAL(activated(int)),
645 this, SIGNAL(changed()));
646 connect(displayGraphicsCO, SIGNAL(activated(int)),
647 this, SIGNAL(changed()));
651 void PrefDisplay::apply(LyXRC & rc) const
653 switch (instantPreviewCO->currentIndex()) {
654 case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
655 case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
656 case 2: rc.preview = LyXRC::PREVIEW_ON; break;
659 lyx::graphics::DisplayType dtype;
660 switch (displayGraphicsCO->currentIndex()) {
661 case 3: dtype = lyx::graphics::NoDisplay; break;
662 case 2: dtype = lyx::graphics::ColorDisplay; break;
663 case 1: dtype = lyx::graphics::GrayscaleDisplay; break;
664 case 0: dtype = lyx::graphics::MonochromeDisplay; break;
665 default: dtype = lyx::graphics::GrayscaleDisplay;
667 rc.display_graphics = dtype;
669 // FIXME!! The graphics cache no longer has a changeDisplay method.
671 if (old_value != rc.display_graphics) {
672 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
679 void PrefDisplay::update(LyXRC const & rc)
681 switch (rc.preview) {
682 case LyXRC::PREVIEW_OFF:
683 instantPreviewCO->setCurrentIndex(0);
685 case LyXRC::PREVIEW_NO_MATH :
686 instantPreviewCO->setCurrentIndex(1);
688 case LyXRC::PREVIEW_ON :
689 instantPreviewCO->setCurrentIndex(2);
694 switch (rc.display_graphics) {
695 case lyx::graphics::NoDisplay: item = 3; break;
696 case lyx::graphics::ColorDisplay: item = 2; break;
697 case lyx::graphics::GrayscaleDisplay: item = 1; break;
698 case lyx::graphics::MonochromeDisplay: item = 0; break;
701 displayGraphicsCO->setCurrentIndex(item);
705 /////////////////////////////////////////////////////////////////////
709 /////////////////////////////////////////////////////////////////////
711 PrefPaths::PrefPaths(QPrefs * form, QWidget * parent)
712 : PrefModule(docstring(), _("Paths"), form, parent)
715 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
716 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
717 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
718 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
719 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
720 connect(workingDirED, SIGNAL(textChanged(const QString&)),
721 this, SIGNAL(changed()));
722 connect(templateDirED, SIGNAL(textChanged(const QString&)),
723 this, SIGNAL(changed()));
724 connect(backupDirED, SIGNAL(textChanged(const QString&)),
725 this, SIGNAL(changed()));
726 connect(tempDirED, SIGNAL(textChanged(const QString&)),
727 this, SIGNAL(changed()));
728 connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
729 this, SIGNAL(changed()));
730 connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
731 this, SIGNAL(changed()));
735 void PrefPaths::apply(LyXRC & rc) const
737 rc.document_path = internal_path(fromqstr(workingDirED->text()));
738 rc.template_path = internal_path(fromqstr(templateDirED->text()));
739 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
740 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
741 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
742 // FIXME: should be a checkbox only
743 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
747 void PrefPaths::update(LyXRC const & rc)
749 workingDirED->setText(toqstr(external_path(rc.document_path)));
750 templateDirED->setText(toqstr(external_path(rc.template_path)));
751 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
752 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
753 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
754 // FIXME: should be a checkbox only
755 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
759 void PrefPaths::select_templatedir()
761 docstring file(form_->controller().browsedir(
762 from_utf8(internal_path(fromqstr(templateDirED->text()))),
763 _("Select a document templates directory")));
765 templateDirED->setText(toqstr(file));
769 void PrefPaths::select_tempdir()
771 docstring file(form_->controller().browsedir(
772 from_utf8(internal_path(fromqstr(tempDirED->text()))),
773 _("Select a temporary directory")));
775 tempDirED->setText(toqstr(file));
779 void PrefPaths::select_backupdir()
781 docstring file(form_->controller().browsedir(
782 from_utf8(internal_path(fromqstr(backupDirED->text()))),
783 _("Select a backups directory")));
785 backupDirED->setText(toqstr(file));
789 void PrefPaths::select_workingdir()
791 docstring file(form_->controller().browsedir(
792 from_utf8(internal_path(fromqstr(workingDirED->text()))),
793 _("Select a document directory")));
795 workingDirED->setText(toqstr(file));
799 void PrefPaths::select_lyxpipe()
801 docstring file(form_->controller().browse(
802 from_utf8(internal_path(fromqstr(lyxserverDirED->text()))),
803 _("Give a filename for the LyX server pipe")));
805 lyxserverDirED->setText(toqstr(file));
809 /////////////////////////////////////////////////////////////////////
813 /////////////////////////////////////////////////////////////////////
815 PrefSpellchecker::PrefSpellchecker(QPrefs * form, QWidget * parent)
816 : PrefModule(_(LanguageSettings), _("Spellchecker"), form, parent)
820 connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
821 #if defined (USE_ISPELL)
822 connect(spellCommandCO, SIGNAL(activated(int)),
823 this, SIGNAL(changed()));
825 spellCommandCO->setEnabled(false);
827 connect(altLanguageED, SIGNAL(textChanged(const QString&)),
828 this, SIGNAL(changed()));
829 connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
830 this, SIGNAL(changed()));
831 connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
832 this, SIGNAL(changed()));
833 connect(compoundWordCB, SIGNAL(clicked()),
834 this, SIGNAL(changed()));
835 connect(inputEncodingCB, SIGNAL(clicked()),
836 this, SIGNAL(changed()));
838 spellCommandCO->addItem(qt_("ispell"));
839 spellCommandCO->addItem(qt_("aspell"));
840 spellCommandCO->addItem(qt_("hspell"));
842 spellCommandCO->addItem(qt_("pspell (library)"));
845 spellCommandCO->addItem(qt_("aspell (library)"));
851 void PrefSpellchecker::apply(LyXRC & rc) const
853 switch (spellCommandCO->currentIndex()) {
857 rc.use_spell_lib = false;
858 rc.isp_command = fromqstr(spellCommandCO->currentText());
861 rc.use_spell_lib = true;
865 // FIXME: remove isp_use_alt_lang
866 rc.isp_alt_lang = fromqstr(altLanguageED->text());
867 rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
868 // FIXME: remove isp_use_esc_chars
869 rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
870 rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
871 // FIXME: remove isp_use_pers_dict
872 rc.isp_pers_dict = internal_path(fromqstr(persDictionaryED->text()));
873 rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
874 rc.isp_accept_compound = compoundWordCB->isChecked();
875 rc.isp_use_input_encoding = inputEncodingCB->isChecked();
879 void PrefSpellchecker::update(LyXRC const & rc)
881 spellCommandCO->setCurrentIndex(0);
883 if (rc.isp_command == "ispell") {
884 spellCommandCO->setCurrentIndex(0);
885 } else if (rc.isp_command == "aspell") {
886 spellCommandCO->setCurrentIndex(1);
887 } else if (rc.isp_command == "hspell") {
888 spellCommandCO->setCurrentIndex(2);
891 if (rc.use_spell_lib) {
892 #if defined(USE_ASPELL) || defined(USE_PSPELL)
893 spellCommandCO->setCurrentIndex(3);
897 // FIXME: remove isp_use_alt_lang
898 altLanguageED->setText(toqstr(rc.isp_alt_lang));
899 // FIXME: remove isp_use_esc_chars
900 escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
901 // FIXME: remove isp_use_pers_dict
902 persDictionaryED->setText(toqstr(external_path(rc.isp_pers_dict)));
903 compoundWordCB->setChecked(rc.isp_accept_compound);
904 inputEncodingCB->setChecked(rc.isp_use_input_encoding);
908 void PrefSpellchecker::select_dict()
910 docstring file(form_->controller().browsedict(
911 from_utf8(internal_path(fromqstr(persDictionaryED->text())))));
913 persDictionaryED->setText(toqstr(file));
918 /////////////////////////////////////////////////////////////////////
922 /////////////////////////////////////////////////////////////////////
925 PrefConverters::PrefConverters(QPrefs * form, QWidget * parent)
926 : PrefModule(docstring(), _("Converters"), form, parent)
930 connect(converterNewPB, SIGNAL(clicked()),
931 this, SLOT(update_converter()));
932 connect(converterRemovePB, SIGNAL(clicked()),
933 this, SLOT(remove_converter()));
934 connect(converterModifyPB, SIGNAL(clicked()),
935 this, SLOT(update_converter()));
936 connect(convertersLW, SIGNAL(currentRowChanged(int)),
937 this, SLOT(switch_converter()));
938 connect(converterFromCO, SIGNAL(activated(const QString&)),
939 this, SLOT(converter_changed()));
940 connect(converterToCO, SIGNAL(activated(const QString&)),
941 this, SLOT(converter_changed()));
942 connect(converterED, SIGNAL(textChanged(const QString&)),
943 this, SLOT(converter_changed()));
944 connect(converterFlagED, SIGNAL(textChanged(const QString&)),
945 this, SLOT(converter_changed()));
946 connect(converterNewPB, SIGNAL(clicked()),
947 this, SIGNAL(changed()));
948 connect(converterRemovePB, SIGNAL(clicked()),
949 this, SIGNAL(changed()));
950 connect(converterModifyPB, SIGNAL(clicked()),
951 this, SIGNAL(changed()));
952 connect(maxAgeLE, SIGNAL(textChanged(const QString&)),
953 this, SIGNAL(changed()));
955 maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE));
956 converterDefGB->setFocusProxy(convertersLW);
960 void PrefConverters::apply(LyXRC & rc) const
962 rc.use_converter_cache = cacheCB->isChecked();
963 rc.converter_cache_maxage = int(maxAgeLE->text().toDouble() * 86400.0);
967 void PrefConverters::update(LyXRC const & rc)
969 cacheCB->setChecked(rc.use_converter_cache);
971 max_age.setNum(double(rc.converter_cache_maxage) / 86400.0, 'g', 6);
972 maxAgeLE->setText(max_age);
977 void PrefConverters::updateGui()
979 // save current selection
980 QString current = converterFromCO->currentText()
981 + " -> " + converterToCO->currentText();
983 converterFromCO->clear();
984 converterToCO->clear();
986 Formats::const_iterator cit = form_->formats().begin();
987 Formats::const_iterator end = form_->formats().end();
988 for (; cit != end; ++cit) {
989 converterFromCO->addItem(toqstr(cit->prettyname()));
990 converterToCO->addItem(toqstr(cit->prettyname()));
993 // currentRowChanged(int) is also triggered when updating the listwidget
994 // block signals to avoid unnecessary calls to switch_converter()
995 convertersLW->blockSignals(true);
996 convertersLW->clear();
998 Converters::const_iterator ccit = form_->converters().begin();
999 Converters::const_iterator cend = form_->converters().end();
1000 for (; ccit != cend; ++ccit) {
1001 std::string const name =
1002 ccit->From->prettyname() + " -> " + ccit->To->prettyname();
1003 int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name());
1004 new QListWidgetItem(toqstr(name), convertersLW, type);
1006 convertersLW->sortItems(Qt::AscendingOrder);
1007 convertersLW->blockSignals(false);
1009 // restore selection
1010 if (!current.isEmpty()) {
1011 QList<QListWidgetItem *> const item =
1012 convertersLW->findItems(current, Qt::MatchExactly);
1014 convertersLW->setCurrentItem(item.at(0));
1017 // select first element if restoring failed
1018 if (convertersLW->currentRow() == -1)
1019 convertersLW->setCurrentRow(0);
1025 void PrefConverters::switch_converter()
1027 int const cnr = convertersLW->currentItem()->type();
1028 Converter const & c(form_->converters().get(cnr));
1029 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
1030 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
1031 converterED->setText(toqstr(c.command));
1032 converterFlagED->setText(toqstr(c.flags));
1038 void PrefConverters::converter_changed()
1044 void PrefConverters::updateButtons()
1046 Format const & from(form_->formats().get(converterFromCO->currentIndex()));
1047 Format const & to(form_->formats().get(converterToCO->currentIndex()));
1048 int const sel = form_->converters().getNumber(from.name(), to.name());
1049 bool const known = !(sel < 0);
1050 bool const valid = !(converterED->text().isEmpty()
1051 || from.name() == to.name());
1053 int const cnr = convertersLW->currentItem()->type();
1054 Converter const & c(form_->converters().get(cnr));
1055 string const old_command = c.command;
1056 string const old_flag = c.flags;
1057 string const new_command(fromqstr(converterED->text()));
1058 string const new_flag(fromqstr(converterFlagED->text()));
1060 bool modified = ((old_command != new_command) || (old_flag != new_flag));
1062 converterModifyPB->setEnabled(valid && known && modified);
1063 converterNewPB->setEnabled(valid && !known);
1064 converterRemovePB->setEnabled(known);
1066 maxAgeLE->setEnabled(cacheCB->isChecked());
1067 maxAgeLA->setEnabled(cacheCB->isChecked());
1072 // specify unique from/to or it doesn't appear. This is really bad UI
1073 // this is why we can use the same function for both new and modify
1074 void PrefConverters::update_converter()
1076 Format const & from(form_->formats().get(converterFromCO->currentIndex()));
1077 Format const & to(form_->formats().get(converterToCO->currentIndex()));
1078 string const flags = fromqstr(converterFlagED->text());
1079 string const command = fromqstr(converterED->text());
1081 Converter const * old = form_->converters().getConverter(from.name(), to.name());
1082 form_->converters().add(from.name(), to.name(), command, flags);
1084 form_->converters().updateLast(form_->formats());
1089 // Remove all files created by this converter from the cache, since
1090 // the modified converter might create different files.
1091 ConverterCache::get().remove_all(from.name(), to.name());
1095 void PrefConverters::remove_converter()
1097 Format const & from(form_->formats().get(converterFromCO->currentIndex()));
1098 Format const & to(form_->formats().get(converterToCO->currentIndex()));
1099 form_->converters().erase(from.name(), to.name());
1103 // Remove all files created by this converter from the cache, since
1104 // a possible new converter might create different files.
1105 ConverterCache::get().remove_all(from.name(), to.name());
1109 void PrefConverters::on_cacheCB_stateChanged(int state)
1111 maxAgeLE->setEnabled(state == Qt::Checked);
1112 maxAgeLA->setEnabled(state == Qt::Checked);
1117 /////////////////////////////////////////////////////////////////////
1121 /////////////////////////////////////////////////////////////////////
1123 PrefCopiers::PrefCopiers(QPrefs * form, QWidget * parent)
1124 : PrefModule(docstring(), _("Copiers"), form, parent)
1128 connect(copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier()));
1129 connect(copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier()));
1130 connect(copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier()));
1131 connect(AllCopiersLW, SIGNAL(currentRowChanged(int)),
1132 this, SLOT(switch_copierLB(int)));
1133 connect(copierFormatCO, SIGNAL(activated(int)),
1134 this, SLOT(switch_copierCO(int)));
1135 connect(copierNewPB, SIGNAL(clicked()),
1136 this, SIGNAL(changed()));
1137 connect(copierRemovePB, SIGNAL(clicked()),
1138 this, SIGNAL(changed()));
1139 connect(copierModifyPB, SIGNAL(clicked()),
1140 this, SIGNAL(changed()));
1141 connect(copierFormatCO, SIGNAL(activated(const QString &)),
1142 this, SLOT(copiers_changed()));
1143 connect(copierED, SIGNAL(textChanged(const QString &)),
1144 this, SLOT(copiers_changed()));
1148 void PrefCopiers::apply(LyXRC & /*rc*/) const
1153 void PrefCopiers::update(LyXRC const & /*rc*/)
1159 void PrefCopiers::update()
1161 // The choice widget
1162 // save current selection
1163 QString current = copierFormatCO->currentText();
1164 copierFormatCO->clear();
1166 for (Formats::const_iterator it = form_->formats().begin(),
1167 end = form_->formats().end();
1169 copierFormatCO->addItem(toqstr(it->prettyname()));
1172 // The browser widget
1173 AllCopiersLW->clear();
1175 for (Movers::const_iterator it = form_->movers().begin(),
1176 end = form_->movers().end();
1178 std::string const & command = it->second.command();
1179 if (command.empty())
1181 QString const pretty = toqstr(form_->formats().prettyName(it->first));
1182 AllCopiersLW->addItem(pretty);
1184 AllCopiersLW->sortItems(Qt::AscendingOrder);
1186 // restore selection
1187 if (!current.isEmpty()) {
1188 QList<QListWidgetItem *> item =
1189 AllCopiersLW->findItems(current, Qt::MatchExactly);
1191 AllCopiersLW->setCurrentItem(item.at(0));
1193 // select first element if restoring failed
1194 if (AllCopiersLW->currentRow() == -1)
1195 AllCopiersLW->setCurrentRow(0);
1201 class SamePrettyName {
1203 SamePrettyName(string const & n) : pretty_name_(n) {}
1205 bool operator()(Format const & fmt) const {
1206 return fmt.prettyname() == pretty_name_;
1210 string const pretty_name_;
1214 Format const * getFormat(std::string const & prettyname)
1216 Formats::const_iterator it = formats.begin();
1217 Formats::const_iterator const end = formats.end();
1218 it = std::find_if(it, end, SamePrettyName(prettyname));
1219 return it == end ? 0 : &*it;
1225 void PrefCopiers::switch_copierLB(int row)
1231 std::string const browser_text =
1232 fromqstr(AllCopiersLW->currentItem()->text());
1233 Format const * fmt = getFormat(browser_text);
1237 QString const gui_name = toqstr(fmt->prettyname());
1238 QString const command = toqstr(form_->movers().command(fmt->name()));
1241 int const combo_size = copierFormatCO->count();
1242 for (int i = 0; i < combo_size; ++i) {
1243 QString const text = copierFormatCO->itemText(i);
1244 if (text == gui_name) {
1245 copierFormatCO->setCurrentIndex(i);
1246 copierED->setText(command);
1254 void PrefCopiers::switch_copierCO(int row)
1259 std::string const combo_text =
1260 fromqstr(copierFormatCO->currentText());
1261 Format const * fmt = getFormat(combo_text);
1265 QString const command = toqstr(form_->movers().command(fmt->name()));
1266 copierED->setText(command);
1268 QListWidgetItem * const index = AllCopiersLW->currentItem();
1270 AllCopiersLW->setItemSelected(index, false);
1272 QString const gui_name = toqstr(fmt->prettyname());
1273 int const browser_size = AllCopiersLW->count();
1274 for (int i = 0; i < browser_size; ++i) {
1275 QString const text = AllCopiersLW->item(i)->text();
1276 if (text == gui_name) {
1277 QListWidgetItem * item = AllCopiersLW->item(i);
1278 AllCopiersLW->setItemSelected(item, true);
1285 void PrefCopiers::copiers_changed()
1291 void PrefCopiers::updateButtons()
1293 QString selected = copierFormatCO->currentText();
1296 for (int i = 0; i < AllCopiersLW->count(); ++i) {
1297 if (AllCopiersLW->item(i)->text() == selected)
1301 bool const valid = !copierED->text().isEmpty();
1303 Format const * fmt = getFormat(fromqstr(selected));
1304 string const old_command = form_->movers().command(fmt->name());
1305 string const new_command(fromqstr(copierED->text()));
1307 bool modified = (old_command != new_command);
1309 copierModifyPB->setEnabled(valid && known && modified);
1310 copierNewPB->setEnabled(valid && !known);
1311 copierRemovePB->setEnabled(known);
1315 void PrefCopiers::new_copier()
1317 std::string const combo_text =
1318 fromqstr(copierFormatCO->currentText());
1319 Format const * fmt = getFormat(combo_text);
1323 string const command = fromqstr(copierED->text());
1324 if (command.empty())
1327 form_->movers().set(fmt->name(), command);
1330 int const last = AllCopiersLW->count() - 1;
1331 AllCopiersLW->setCurrentRow(last);
1337 void PrefCopiers::modify_copier()
1339 std::string const combo_text =
1340 fromqstr(copierFormatCO->currentText());
1341 Format const * fmt = getFormat(combo_text);
1345 string const command = fromqstr(copierED->text());
1346 form_->movers().set(fmt->name(), command);
1353 void PrefCopiers::remove_copier()
1355 std::string const combo_text =
1356 fromqstr(copierFormatCO->currentText());
1357 Format const * fmt = getFormat(combo_text);
1361 string const & fmt_name = fmt->name();
1362 form_->movers().set(fmt_name, string());
1370 /////////////////////////////////////////////////////////////////////
1374 /////////////////////////////////////////////////////////////////////
1376 PrefFileformats::PrefFileformats(QPrefs * form, QWidget * parent)
1377 : PrefModule(docstring(), _("File formats"), form, parent)
1381 connect(formatNewPB, SIGNAL(clicked()),
1382 this, SLOT(new_format()));
1383 connect(formatRemovePB, SIGNAL(clicked()),
1384 this, SLOT(remove_format()));
1385 connect(formatModifyPB, SIGNAL(clicked()),
1386 this, SLOT(modify_format()));
1387 connect(formatsLW, SIGNAL(currentRowChanged(int)),
1388 this, SLOT(switch_format(int)));
1389 connect(formatED, SIGNAL(textChanged(const QString&)),
1390 this, SLOT(fileformat_changed()));
1391 connect(guiNameED, SIGNAL(textChanged(const QString&)),
1392 this, SLOT(fileformat_changed()));
1393 connect(shortcutED, SIGNAL(textChanged(const QString&)),
1394 this, SLOT(fileformat_changed()));
1395 connect(extensionED, SIGNAL(textChanged(const QString&)),
1396 this, SLOT(fileformat_changed()));
1397 connect(viewerED, SIGNAL(textChanged(const QString&)),
1398 this, SLOT(fileformat_changed()));
1399 connect(editorED, SIGNAL(textChanged(const QString&)),
1400 this, SLOT(fileformat_changed()));
1401 connect(documentCB, SIGNAL(clicked()),
1402 this, SLOT(fileformat_changed()));
1403 connect(vectorCB, SIGNAL(clicked()),
1404 this, SLOT(fileformat_changed()));
1405 connect(formatNewPB, SIGNAL(clicked()),
1406 this, SIGNAL(changed()));
1407 connect(formatRemovePB, SIGNAL(clicked()),
1408 this, SIGNAL(changed()));
1409 connect(formatModifyPB, SIGNAL(clicked()),
1410 this, SIGNAL(changed()));
1414 void PrefFileformats::apply(LyXRC & /*rc*/) const
1419 void PrefFileformats::update(LyXRC const & /*rc*/)
1425 void PrefFileformats::update()
1427 // save current selection
1428 QString current = guiNameED->text();
1430 // update listwidget with formats
1431 formatsLW->blockSignals(true);
1433 Formats::const_iterator cit = form_->formats().begin();
1434 Formats::const_iterator end = form_->formats().end();
1435 for (; cit != end; ++cit) {
1436 new QListWidgetItem(toqstr(cit->prettyname()),
1438 form_->formats().getNumber(cit->name()) );
1440 formatsLW->sortItems(Qt::AscendingOrder);
1441 formatsLW->blockSignals(false);
1443 // restore selection
1444 if (!current.isEmpty()) {
1445 QList<QListWidgetItem *> item = formatsLW->findItems(current, Qt::MatchExactly);
1447 formatsLW->setCurrentItem(item.at(0));
1449 // select first element if restoring failed
1450 if (formatsLW->currentRow() == -1)
1451 formatsLW->setCurrentRow(0);
1455 void PrefFileformats::switch_format(int nr)
1457 int const ftype = formatsLW->item(nr)->type();
1458 Format const f = form_->formats().get(ftype);
1460 formatED->setText(toqstr(f.name()));
1461 guiNameED->setText(toqstr(f.prettyname()));
1462 extensionED->setText(toqstr(f.extension()));
1463 shortcutED->setText(toqstr(f.shortcut()));
1464 viewerED->setText(toqstr(f.viewer()));
1465 editorED->setText(toqstr(f.editor()));
1466 documentCB->setChecked((f.documentFormat()));
1467 vectorCB->setChecked((f.vectorFormat()));
1473 void PrefFileformats::fileformat_changed()
1479 void PrefFileformats::updateButtons()
1481 QString const format = formatED->text();
1482 QString const gui_name = guiNameED->text();
1483 int const sel = form_->formats().getNumber(fromqstr(format));
1484 bool gui_name_known = false;
1486 for (int i = 0; i < formatsLW->count(); ++i) {
1487 if (formatsLW->item(i)->text() == gui_name) {
1488 gui_name_known = true;
1489 where = formatsLW->item(i)->type();
1493 // assure that a gui name cannot be chosen twice
1494 bool const known_otherwise = gui_name_known && (where != sel);
1496 bool const known = !(sel < 0);
1497 bool const valid = (!formatED->text().isEmpty()
1498 && !guiNameED->text().isEmpty());
1500 int const ftype = formatsLW->currentItem()->type();
1501 Format const & f(form_->formats().get(ftype));
1502 string const old_pretty(f.prettyname());
1503 string const old_shortcut(f.shortcut());
1504 string const old_extension(f.extension());
1505 string const old_viewer(f.viewer());
1506 string const old_editor(f.editor());
1507 bool const old_document(f.documentFormat());
1508 bool const old_vector(f.vectorFormat());
1510 string const new_pretty(fromqstr(gui_name));
1511 string const new_shortcut(fromqstr(shortcutED->text()));
1512 string const new_extension(fromqstr(extensionED->text()));
1513 string const new_viewer(fromqstr(viewerED->text()));
1514 string const new_editor(fromqstr(editorED->text()));
1515 bool const new_document(documentCB->isChecked());
1516 bool const new_vector(vectorCB->isChecked());
1518 bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut)
1519 || (old_extension != new_extension) || (old_viewer != new_viewer)
1520 || old_editor != new_editor || old_document != new_document
1521 || old_vector != new_vector);
1523 formatModifyPB->setEnabled(valid && known && modified && !known_otherwise);
1524 formatNewPB->setEnabled(valid && !known && !gui_name_known);
1525 formatRemovePB->setEnabled(known);
1529 void PrefFileformats::new_format()
1531 string const name = fromqstr(formatED->text());
1532 string const prettyname = fromqstr(guiNameED->text());
1533 string const extension = fromqstr(extensionED->text());
1534 string const shortcut = fromqstr(shortcutED->text());
1535 string const viewer = fromqstr(viewerED->text());
1536 string const editor = fromqstr(editorED->text());
1537 int flags = Format::none;
1538 if (documentCB->isChecked())
1539 flags |= Format::document;
1540 if (vectorCB->isChecked())
1541 flags |= Format::vector;
1543 form_->formats().add(name, extension, prettyname, shortcut, viewer,
1545 form_->formats().sort();
1546 form_->converters().update(form_->formats());
1554 void PrefFileformats::modify_format()
1556 int const current_item = formatsLW->currentItem()->type();
1557 Format const & oldformat = form_->formats().get(current_item);
1558 form_->formats().erase(oldformat.name());
1564 void PrefFileformats::remove_format()
1566 int const nr = formatsLW->currentItem()->type();
1567 string const current_text = form_->formats().get(nr).name();
1568 if (form_->converters().formatIsUsed(current_text)) {
1569 Alert::error(_("Format in use"),
1570 _("Cannot remove a Format used by a Converter. "
1571 "Remove the converter first."));
1575 form_->formats().erase(current_text);
1576 form_->converters().update(form_->formats());
1584 /////////////////////////////////////////////////////////////////////
1588 /////////////////////////////////////////////////////////////////////
1590 PrefLanguage::PrefLanguage(QWidget * parent)
1591 : PrefModule(_(LanguageSettings), _("Language"), 0, parent)
1595 connect(rtlCB, SIGNAL(clicked()),
1596 this, SIGNAL(changed()));
1597 connect(markForeignCB, SIGNAL(clicked()),
1598 this, SIGNAL(changed()));
1599 connect(autoBeginCB, SIGNAL(clicked()),
1600 this, SIGNAL(changed()));
1601 connect(autoEndCB, SIGNAL(clicked()),
1602 this, SIGNAL(changed()));
1603 connect(useBabelCB, SIGNAL(clicked()),
1604 this, SIGNAL(changed()));
1605 connect(globalCB, SIGNAL(clicked()),
1606 this, SIGNAL(changed()));
1607 connect(languagePackageED, SIGNAL(textChanged(const QString&)),
1608 this, SIGNAL(changed()));
1609 connect(startCommandED, SIGNAL(textChanged(const QString&)),
1610 this, SIGNAL(changed()));
1611 connect(endCommandED, SIGNAL(textChanged(const QString&)),
1612 this, SIGNAL(changed()));
1613 connect(defaultLanguageCO, SIGNAL(activated(int)),
1614 this, SIGNAL(changed()));
1616 defaultLanguageCO->clear();
1618 // store the lang identifiers for later
1619 std::vector<LanguagePair> const langs = frontend::getLanguageData(false);
1620 lang_ = getSecond(langs);
1622 std::vector<LanguagePair>::const_iterator lit = langs.begin();
1623 std::vector<LanguagePair>::const_iterator lend = langs.end();
1624 for (; lit != lend; ++lit) {
1625 defaultLanguageCO->addItem(toqstr(lit->first));
1630 void PrefLanguage::apply(LyXRC & rc) const
1632 // FIXME: remove rtl_support bool
1633 rc.rtl_support = rtlCB->isChecked();
1634 rc.mark_foreign_language = markForeignCB->isChecked();
1635 rc.language_auto_begin = autoBeginCB->isChecked();
1636 rc.language_auto_end = autoEndCB->isChecked();
1637 rc.language_use_babel = useBabelCB->isChecked();
1638 rc.language_global_options = globalCB->isChecked();
1639 rc.language_package = fromqstr(languagePackageED->text());
1640 rc.language_command_begin = fromqstr(startCommandED->text());
1641 rc.language_command_end = fromqstr(endCommandED->text());
1642 rc.default_language = lang_[defaultLanguageCO->currentIndex()];
1646 void PrefLanguage::update(LyXRC const & rc)
1648 // FIXME: remove rtl_support bool
1649 rtlCB->setChecked(rc.rtl_support);
1650 markForeignCB->setChecked(rc.mark_foreign_language);
1651 autoBeginCB->setChecked(rc.language_auto_begin);
1652 autoEndCB->setChecked(rc.language_auto_end);
1653 useBabelCB->setChecked(rc.language_use_babel);
1654 globalCB->setChecked(rc.language_global_options);
1655 languagePackageED->setText(toqstr(rc.language_package));
1656 startCommandED->setText(toqstr(rc.language_command_begin));
1657 endCommandED->setText(toqstr(rc.language_command_end));
1659 int const pos = int(findPos_helper(lang_, rc.default_language));
1660 defaultLanguageCO->setCurrentIndex(pos);
1664 /////////////////////////////////////////////////////////////////////
1668 /////////////////////////////////////////////////////////////////////
1670 PrefPrinter::PrefPrinter(QWidget * parent)
1671 : PrefModule(_(Outputs), _("Printer"), 0, parent)
1675 connect(printerAdaptCB, SIGNAL(clicked()),
1676 this, SIGNAL(changed()));
1677 connect(printerCommandED, SIGNAL(textChanged(const QString&)),
1678 this, SIGNAL(changed()));
1679 connect(printerNameED, SIGNAL(textChanged(const QString&)),
1680 this, SIGNAL(changed()));
1681 connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
1682 this, SIGNAL(changed()));
1683 connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
1684 this, SIGNAL(changed()));
1685 connect(printerReverseED, SIGNAL(textChanged(const QString&)),
1686 this, SIGNAL(changed()));
1687 connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
1688 this, SIGNAL(changed()));
1689 connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
1690 this, SIGNAL(changed()));
1691 connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
1692 this, SIGNAL(changed()));
1693 connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
1694 this, SIGNAL(changed()));
1695 connect(printerEvenED, SIGNAL(textChanged(const QString&)),
1696 this, SIGNAL(changed()));
1697 connect(printerOddED, SIGNAL(textChanged(const QString&)),
1698 this, SIGNAL(changed()));
1699 connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
1700 this, SIGNAL(changed()));
1701 connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
1702 this, SIGNAL(changed()));
1703 connect(printerToFileED, SIGNAL(textChanged(const QString&)),
1704 this, SIGNAL(changed()));
1705 connect(printerExtraED, SIGNAL(textChanged(const QString&)),
1706 this, SIGNAL(changed()));
1707 connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
1708 this, SIGNAL(changed()));
1709 connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
1710 this, SIGNAL(changed()));
1714 void PrefPrinter::apply(LyXRC & rc) const
1716 rc.print_adapt_output = printerAdaptCB->isChecked();
1717 rc.print_command = fromqstr(printerCommandED->text());
1718 rc.printer = fromqstr(printerNameED->text());
1720 rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
1721 rc.print_copies_flag = fromqstr(printerCopiesED->text());
1722 rc.print_reverse_flag = fromqstr(printerReverseED->text());
1723 rc.print_to_printer = fromqstr(printerToPrinterED->text());
1724 rc.print_file_extension = fromqstr(printerExtensionED->text());
1725 rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
1726 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
1727 rc.print_evenpage_flag = fromqstr(printerEvenED->text());
1728 rc.print_oddpage_flag = fromqstr(printerOddED->text());
1729 rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
1730 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
1731 rc.print_to_file = internal_path(fromqstr(printerToFileED->text()));
1732 rc.print_extra_options = fromqstr(printerExtraED->text());
1733 rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
1734 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
1738 void PrefPrinter::update(LyXRC const & rc)
1740 printerAdaptCB->setChecked(rc.print_adapt_output);
1741 printerCommandED->setText(toqstr(rc.print_command));
1742 printerNameED->setText(toqstr(rc.printer));
1744 printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
1745 printerCopiesED->setText(toqstr(rc.print_copies_flag));
1746 printerReverseED->setText(toqstr(rc.print_reverse_flag));
1747 printerToPrinterED->setText(toqstr(rc.print_to_printer));
1748 printerExtensionED->setText(toqstr(rc.print_file_extension));
1749 printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
1750 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
1751 printerEvenED->setText(toqstr(rc.print_evenpage_flag));
1752 printerOddED->setText(toqstr(rc.print_oddpage_flag));
1753 printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
1754 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
1755 printerToFileED->setText(toqstr(external_path(rc.print_to_file)));
1756 printerExtraED->setText(toqstr(rc.print_extra_options));
1757 printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
1758 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
1762 /////////////////////////////////////////////////////////////////////
1764 // PrefUserInterface
1766 /////////////////////////////////////////////////////////////////////
1768 PrefUserInterface::PrefUserInterface(QPrefs * form, QWidget * parent)
1769 : PrefModule(_(LookAndFeel), _("User interface"), form, parent)
1773 connect(autoSaveCB, SIGNAL(toggled(bool)),
1774 autoSaveLA, SLOT(setEnabled(bool)));
1775 connect(autoSaveCB, SIGNAL(toggled(bool)),
1776 autoSaveSB, SLOT(setEnabled(bool)));
1777 connect(autoSaveCB, SIGNAL(toggled(bool)),
1778 TextLabel1, SLOT(setEnabled(bool)));
1779 connect(uiFilePB, SIGNAL(clicked()),
1780 this, SLOT(select_ui()));
1781 connect(bindFilePB, SIGNAL(clicked()),
1782 this, SLOT(select_bind()));
1783 connect(uiFileED, SIGNAL(textChanged(const QString &)),
1784 this, SIGNAL(changed()));
1785 connect(bindFileED, SIGNAL(textChanged(const QString &)),
1786 this, SIGNAL(changed()));
1787 connect(restoreCursorCB, SIGNAL(clicked()),
1788 this, SIGNAL(changed()));
1789 connect(loadSessionCB, SIGNAL(clicked()),
1790 this, SIGNAL(changed()));
1791 connect(loadWindowSizeCB, SIGNAL(clicked()),
1792 this, SIGNAL(changed()));
1793 connect(loadWindowLocationCB, SIGNAL(clicked()),
1794 this, SIGNAL(changed()));
1795 connect(windowWidthSB, SIGNAL(valueChanged(int)),
1796 this, SIGNAL(changed()));
1797 connect(windowHeightSB, SIGNAL(valueChanged(int)),
1798 this, SIGNAL(changed()));
1799 connect(cursorFollowsCB, SIGNAL(clicked()),
1800 this, SIGNAL(changed()));
1801 connect(autoSaveSB, SIGNAL(valueChanged(int)),
1802 this, SIGNAL(changed()));
1803 connect(autoSaveCB, SIGNAL(clicked()),
1804 this, SIGNAL(changed()));
1805 connect(lastfilesSB, SIGNAL(valueChanged(int)),
1806 this, SIGNAL(changed()));
1807 lastfilesSB->setMaximum(maxlastfiles);
1811 void PrefUserInterface::apply(LyXRC & rc) const
1813 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
1814 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
1815 rc.use_lastfilepos = restoreCursorCB->isChecked();
1816 rc.load_session = loadSessionCB->isChecked();
1817 if (loadWindowSizeCB->isChecked()) {
1818 rc.geometry_width = 0;
1819 rc.geometry_height = 0;
1821 rc.geometry_width = windowWidthSB->value();
1822 rc.geometry_height = windowHeightSB->value();
1824 rc.geometry_xysaved = loadWindowLocationCB->isChecked();
1825 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
1826 rc.autosave = autoSaveSB->value() * 60;
1827 rc.make_backup = autoSaveCB->isChecked();
1828 rc.num_lastfiles = lastfilesSB->value();
1832 void PrefUserInterface::update(LyXRC const & rc)
1834 uiFileED->setText(toqstr(external_path(rc.ui_file)));
1835 bindFileED->setText(toqstr(external_path(rc.bind_file)));
1836 restoreCursorCB->setChecked(rc.use_lastfilepos);
1837 loadSessionCB->setChecked(rc.load_session);
1838 bool loadWindowSize = rc.geometry_width == 0 && rc.geometry_height == 0;
1839 loadWindowSizeCB->setChecked(loadWindowSize);
1840 if (!loadWindowSize) {
1841 windowWidthSB->setValue(rc.geometry_width);
1842 windowHeightSB->setValue(rc.geometry_height);
1844 loadWindowLocationCB->setChecked(rc.geometry_xysaved);
1845 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
1846 // convert to minutes
1847 int mins(rc.autosave / 60);
1848 if (rc.autosave && !mins)
1850 autoSaveSB->setValue(mins);
1851 autoSaveCB->setChecked(rc.make_backup);
1852 lastfilesSB->setValue(rc.num_lastfiles);
1857 void PrefUserInterface::select_ui()
1859 docstring const name =
1860 from_utf8(internal_path(fromqstr(uiFileED->text())));
1861 docstring file(form_->controller().browseUI(name));
1863 uiFileED->setText(toqstr(file));
1867 void PrefUserInterface::select_bind()
1869 docstring const name =
1870 from_utf8(internal_path(fromqstr(bindFileED->text())));
1871 docstring file(form_->controller().browsebind(name));
1873 bindFileED->setText(toqstr(file));
1877 void PrefUserInterface::on_loadWindowSizeCB_toggled(bool loadwindowsize)
1879 windowWidthLA->setDisabled(loadwindowsize);
1880 windowHeightLA->setDisabled(loadwindowsize);
1881 windowWidthSB->setDisabled(loadwindowsize);
1882 windowHeightSB->setDisabled(loadwindowsize);
1886 PrefIdentity::PrefIdentity(QWidget * parent)
1887 : PrefModule(docstring(), _("Identity"), 0, parent)
1891 connect(nameED, SIGNAL(textChanged(const QString&)),
1892 this, SIGNAL(changed()));
1893 connect(emailED, SIGNAL(textChanged(const QString&)),
1894 this, SIGNAL(changed()));
1898 void PrefIdentity::apply(LyXRC & rc) const
1900 rc.user_name = fromqstr(nameED->text());
1901 rc.user_email = fromqstr(emailED->text());
1905 void PrefIdentity::update(LyXRC const & rc)
1907 nameED->setText(toqstr(rc.user_name));
1908 emailED->setText(toqstr(rc.user_email));
1913 /////////////////////////////////////////////////////////////////////
1917 /////////////////////////////////////////////////////////////////////
1919 QPrefsDialog::QPrefsDialog(QPrefs * form)
1923 QDialog::setModal(false);
1925 connect(savePB, SIGNAL(clicked()), form, SLOT(slotOK()));
1926 connect(applyPB, SIGNAL(clicked()), form, SLOT(slotApply()));
1927 connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose()));
1928 connect(restorePB, SIGNAL(clicked()), form, SLOT(slotRestore()));
1930 add(new PrefUserInterface(form_));
1931 add(new PrefScreenFonts(form_));
1932 add(new PrefColors(form_));
1933 add(new PrefDisplay);
1934 add(new PrefKeyboard(form_));
1936 add(new PrefPaths(form_));
1938 add(new PrefIdentity);
1940 add(new PrefLanguage);
1941 add(new PrefSpellchecker(form_));
1943 add(new PrefPrinter);
1945 add(new PrefPlaintext);
1946 add(new PrefLatex(form_));
1948 #if defined(__CYGWIN__) || defined(_WIN32)
1949 add(new PrefCygwinPath);
1953 PrefConverters * converters = new PrefConverters(form_);
1954 PrefFileformats * formats = new PrefFileformats(form_);
1955 connect(formats, SIGNAL(formatsChanged()),
1956 converters, SLOT(updateGui()));
1960 add(new PrefCopiers(form_));
1963 prefsPS->setCurrentPanel(_("User interface"));
1964 // FIXME: hack to work around resizing bug in Qt >= 4.2
1965 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1966 #if QT_VERSION >= 0x040200
1967 prefsPS->updateGeometry();
1970 form_->bcview().setOK(savePB);
1971 form_->bcview().setApply(applyPB);
1972 form_->bcview().setCancel(closePB);
1973 form_->bcview().setRestore(restorePB);
1977 void QPrefsDialog::add(PrefModule * module)
1979 BOOST_ASSERT(module);
1981 // if (module->category().empty())
1982 // prefsPS->addPanel(module, module->title());
1984 prefsPS->addPanel(module, module->title(), module->category());
1986 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
1988 modules_.push_back(module);
1991 void QPrefsDialog::closeEvent(QCloseEvent * e)
1993 form_->slotWMHide();
1998 void QPrefsDialog::change_adaptor()
2004 void QPrefsDialog::apply(LyXRC & rc) const
2006 size_t end = modules_.size();
2007 for (size_t i = 0; i != end; ++i)
2008 modules_[i]->apply(rc);
2012 void QPrefsDialog::updateRc(LyXRC const & rc)
2014 size_t const end = modules_.size();
2015 for (size_t i = 0; i != end; ++i)
2016 modules_[i]->update(rc);
2020 /////////////////////////////////////////////////////////////////////
2024 /////////////////////////////////////////////////////////////////////
2026 typedef QController<ControlPrefs, QView<QPrefsDialog> > PrefsBase;
2028 QPrefs::QPrefs(Dialog & parent)
2029 : PrefsBase(parent, _("Preferences"))
2033 Converters & QPrefs::converters()
2035 return controller().converters();
2038 Formats & QPrefs::formats()
2040 return controller().formats();
2043 Movers & QPrefs::movers()
2045 return controller().movers();
2048 void QPrefs::build_dialog()
2050 dialog_.reset(new QPrefsDialog(this));
2053 void QPrefs::apply()
2055 dialog_->apply(controller().rc());
2058 void QPrefs::update_contents()
2060 dialog_->updateRc(controller().rc());
2063 } // namespace frontend
2066 #include "QPrefs_moc.cpp"