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.
15 #include "qt_helpers.h"
16 #include "GuiApplication.h"
18 #include "BufferList.h"
20 #include "ConverterCache.h"
23 #include "FuncRequest.h"
25 #include "GuiFontExample.h"
26 #include "PanelStack.h"
30 #include "support/lstrings.h"
31 #include "support/os.h"
32 #include "support/FileFilterList.h"
34 #include "frontend_helpers.h"
36 #include "frontends/alert.h"
37 #include "frontends/Application.h"
40 #include <QColorDialog>
41 #include <QFontDatabase>
43 #include <QPushButton>
47 #include <QCloseEvent>
57 using std::ostringstream;
65 using support::compare_ascii_no_case;
66 using support::os::external_path;
67 using support::os::external_path_list;
68 using support::os::internal_path;
69 using support::os::internal_path_list;
70 using support::FileFilterList;
73 /////////////////////////////////////////////////////////////////////
77 /////////////////////////////////////////////////////////////////////
80 static size_t findPos_helper(std::vector<A> const & vec, A const & val)
82 typedef typename std::vector<A>::const_iterator Cit;
84 Cit it = std::find(vec.begin(), vec.end(), val);
87 return std::distance(vec.begin(), it);
91 static std::pair<string, string> parseFontName(string const & name)
93 string::size_type const idx = name.find('[');
94 if (idx == string::npos || idx == 0)
95 return make_pair(name, string());
96 return make_pair(name.substr(0, idx - 1),
97 name.substr(idx + 1, name.size() - idx - 2));
101 static void setComboxFont(QComboBox * cb, string const & family,
102 string const & foundry)
104 QString fontname = toqstr(family);
105 if (!foundry.empty())
106 fontname += " [" + toqstr(foundry) + ']';
108 for (int i = 0; i < cb->count(); ++i) {
109 if (cb->itemText(i) == fontname) {
110 cb->setCurrentIndex(i);
115 // Try matching without foundry name
117 // We count in reverse in order to prefer the Xft foundry
118 for (int i = cb->count(); --i >= 0;) {
119 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
120 if (compare_ascii_no_case(tmp.first, family) == 0) {
121 cb->setCurrentIndex(i);
126 // family alone can contain e.g. "Helvetica [Adobe]"
127 pair<string, string> tmpfam = parseFontName(family);
129 // We count in reverse in order to prefer the Xft foundry
130 for (int i = cb->count() - 1; i >= 0; --i) {
131 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
132 if (compare_ascii_no_case(tmp.first, tmpfam.first) == 0) {
133 cb->setCurrentIndex(i);
138 // Bleh, default fonts, and the names couldn't be found. Hack
142 font.setKerning(false);
144 if (family == theApp()->romanFontName()) {
145 font.setStyleHint(QFont::Serif);
146 font.setFamily(family.c_str());
147 } else if (family == theApp()->sansFontName()) {
148 font.setStyleHint(QFont::SansSerif);
149 font.setFamily(family.c_str());
150 } else if (family == theApp()->typewriterFontName()) {
151 font.setStyleHint(QFont::TypeWriter);
152 font.setFamily(family.c_str());
154 lyxerr << "FAILED to find the default font: '"
155 << foundry << "', '" << family << '\''<< endl;
159 QFontInfo info(font);
160 pair<string, string> tmp = parseFontName(fromqstr(info.family()));
161 string const & default_font_name = tmp.first;
162 lyxerr << "Apparent font is " << default_font_name << endl;
164 for (int i = 0; i < cb->count(); ++i) {
165 lyxerr << "Looking at " << fromqstr(cb->itemText(i)) << endl;
166 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
167 default_font_name) == 0) {
168 cb->setCurrentIndex(i);
173 lyxerr << "FAILED to find the font: '"
174 << foundry << "', '" << family << '\'' <<endl;
178 /////////////////////////////////////////////////////////////////////
182 /////////////////////////////////////////////////////////////////////
184 PrefPlaintext::PrefPlaintext(QWidget * parent)
185 : PrefModule(_("Plain text"), 0, parent)
188 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
189 this, SIGNAL(changed()));
190 connect(plaintextRoffED, SIGNAL(textChanged(const QString&)),
191 this, SIGNAL(changed()));
195 void PrefPlaintext::apply(LyXRC & rc) const
197 rc.plaintext_linelen = plaintextLinelengthSB->value();
198 rc.plaintext_roff_command = fromqstr(plaintextRoffED->text());
202 void PrefPlaintext::update(LyXRC const & rc)
204 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
205 plaintextRoffED->setText(toqstr(rc.plaintext_roff_command));
209 /////////////////////////////////////////////////////////////////////
213 /////////////////////////////////////////////////////////////////////
215 PrefDate::PrefDate(QWidget * parent)
216 : PrefModule(_("Date format"), 0, parent)
219 connect(DateED, SIGNAL(textChanged(const QString &)),
220 this, SIGNAL(changed()));
224 void PrefDate::apply(LyXRC & rc) const
226 rc.date_insert_format = fromqstr(DateED->text());
230 void PrefDate::update(LyXRC const & rc)
232 DateED->setText(toqstr(rc.date_insert_format));
236 /////////////////////////////////////////////////////////////////////
240 /////////////////////////////////////////////////////////////////////
242 PrefKeyboard::PrefKeyboard(GuiPreferences * form, QWidget * parent)
243 : PrefModule(_("Keyboard"), form, parent)
247 connect(keymapCB, SIGNAL(clicked()),
248 this, SIGNAL(changed()));
249 connect(firstKeymapED, SIGNAL(textChanged(const QString&)),
250 this, SIGNAL(changed()));
251 connect(secondKeymapED, SIGNAL(textChanged(const QString&)),
252 this, SIGNAL(changed()));
256 void PrefKeyboard::apply(LyXRC & rc) const
258 // FIXME: can derive CB from the two EDs
259 rc.use_kbmap = keymapCB->isChecked();
260 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
261 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
265 void PrefKeyboard::update(LyXRC const & rc)
267 // FIXME: can derive CB from the two EDs
268 keymapCB->setChecked(rc.use_kbmap);
269 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
270 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
274 QString PrefKeyboard::testKeymap(QString keymap)
276 return toqstr(form_->browsekbmap(from_utf8(internal_path(fromqstr(keymap)))));
280 void PrefKeyboard::on_firstKeymapPB_clicked(bool)
282 QString const file = testKeymap(firstKeymapED->text());
284 firstKeymapED->setText(file);
288 void PrefKeyboard::on_secondKeymapPB_clicked(bool)
290 QString const file = testKeymap(secondKeymapED->text());
292 secondKeymapED->setText(file);
296 void PrefKeyboard::on_keymapCB_toggled(bool keymap)
298 firstKeymapLA->setEnabled(keymap);
299 secondKeymapLA->setEnabled(keymap);
300 firstKeymapED->setEnabled(keymap);
301 secondKeymapED->setEnabled(keymap);
302 firstKeymapPB->setEnabled(keymap);
303 secondKeymapPB->setEnabled(keymap);
307 /////////////////////////////////////////////////////////////////////
311 /////////////////////////////////////////////////////////////////////
313 PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent)
314 : PrefModule(_("LaTeX"), form, parent)
317 connect(latexEncodingED, SIGNAL(textChanged(const QString&)),
318 this, SIGNAL(changed()));
319 connect(latexChecktexED, SIGNAL(textChanged(const QString&)),
320 this, SIGNAL(changed()));
321 connect(latexBibtexED, SIGNAL(textChanged(const QString&)),
322 this, SIGNAL(changed()));
323 connect(latexIndexED, SIGNAL(textChanged(const QString&)),
324 this, SIGNAL(changed()));
325 connect(latexAutoresetCB, SIGNAL(clicked()),
326 this, SIGNAL(changed()));
327 connect(latexDviPaperED, SIGNAL(textChanged(const QString&)),
328 this, SIGNAL(changed()));
329 connect(latexPaperSizeCO, SIGNAL(activated(int)),
330 this, SIGNAL(changed()));
332 #if defined(__CYGWIN__) || defined(_WIN32)
333 pathCB->setVisible(true);
334 connect(pathCB, SIGNAL(clicked()),
335 this, SIGNAL(changed()));
337 pathCB->setVisible(false);
342 void PrefLatex::apply(LyXRC & rc) const
344 rc.fontenc = fromqstr(latexEncodingED->text());
345 rc.chktex_command = fromqstr(latexChecktexED->text());
346 rc.bibtex_command = fromqstr(latexBibtexED->text());
347 rc.index_command = fromqstr(latexIndexED->text());
348 rc.auto_reset_options = latexAutoresetCB->isChecked();
349 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
350 rc.default_papersize =
351 form_->toPaperSize(latexPaperSizeCO->currentIndex());
352 #if defined(__CYGWIN__) || defined(_WIN32)
353 rc.windows_style_tex_paths = pathCB->isChecked();
358 void PrefLatex::update(LyXRC const & rc)
360 latexEncodingED->setText(toqstr(rc.fontenc));
361 latexChecktexED->setText(toqstr(rc.chktex_command));
362 latexBibtexED->setText(toqstr(rc.bibtex_command));
363 latexIndexED->setText(toqstr(rc.index_command));
364 latexAutoresetCB->setChecked(rc.auto_reset_options);
365 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
366 latexPaperSizeCO->setCurrentIndex(
367 form_->fromPaperSize(rc.default_papersize));
368 #if defined(__CYGWIN__) || defined(_WIN32)
369 pathCB->setChecked(rc.windows_style_tex_paths);
374 /////////////////////////////////////////////////////////////////////
378 /////////////////////////////////////////////////////////////////////
380 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * parent)
381 : PrefModule(_("Screen fonts"), form, parent)
385 connect(screenRomanCO, SIGNAL(activated(const QString&)),
386 this, SLOT(select_roman(const QString&)));
387 connect(screenSansCO, SIGNAL(activated(const QString&)),
388 this, SLOT(select_sans(const QString&)));
389 connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
390 this, SLOT(select_typewriter(const QString&)));
392 QFontDatabase fontdb;
393 QStringList families(fontdb.families());
394 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
395 screenRomanCO->addItem(*it);
396 screenSansCO->addItem(*it);
397 screenTypewriterCO->addItem(*it);
399 connect(screenRomanCO, SIGNAL(activated(const QString&)),
400 this, SIGNAL(changed()));
401 connect(screenSansCO, SIGNAL(activated(const QString&)),
402 this, SIGNAL(changed()));
403 connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
404 this, SIGNAL(changed()));
405 connect(screenZoomSB, SIGNAL(valueChanged(int)),
406 this, SIGNAL(changed()));
407 connect(screenDpiSB, SIGNAL(valueChanged(int)),
408 this, SIGNAL(changed()));
409 connect(screenTinyED, SIGNAL(textChanged(const QString&)),
410 this, SIGNAL(changed()));
411 connect(screenSmallestED, SIGNAL(textChanged(const QString&)),
412 this, SIGNAL(changed()));
413 connect(screenSmallerED, SIGNAL(textChanged(const QString&)),
414 this, SIGNAL(changed()));
415 connect(screenSmallED, SIGNAL(textChanged(const QString&)),
416 this, SIGNAL(changed()));
417 connect(screenNormalED, SIGNAL(textChanged(const QString&)),
418 this, SIGNAL(changed()));
419 connect(screenLargeED, SIGNAL(textChanged(const QString&)),
420 this, SIGNAL(changed()));
421 connect(screenLargerED, SIGNAL(textChanged(const QString&)),
422 this, SIGNAL(changed()));
423 connect(screenLargestED, SIGNAL(textChanged(const QString&)),
424 this, SIGNAL(changed()));
425 connect(screenHugeED, SIGNAL(textChanged(const QString&)),
426 this, SIGNAL(changed()));
427 connect(screenHugerED, SIGNAL(textChanged(const QString&)),
428 this, SIGNAL(changed()));
430 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
431 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
432 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
433 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
434 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
435 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
436 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
437 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
438 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
439 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
443 void PrefScreenFonts::apply(LyXRC & rc) const
445 LyXRC const oldrc(rc);
447 boost::tie(rc.roman_font_name, rc.roman_font_foundry)
448 = parseFontName(fromqstr(screenRomanCO->currentText()));
449 boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
450 parseFontName(fromqstr(screenSansCO->currentText()));
451 boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
452 parseFontName(fromqstr(screenTypewriterCO->currentText()));
454 rc.zoom = screenZoomSB->value();
455 rc.dpi = screenDpiSB->value();
456 rc.font_sizes[Font::SIZE_TINY] = fromqstr(screenTinyED->text());
457 rc.font_sizes[Font::SIZE_SCRIPT] = fromqstr(screenSmallestED->text());
458 rc.font_sizes[Font::SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text());
459 rc.font_sizes[Font::SIZE_SMALL] = fromqstr(screenSmallED->text());
460 rc.font_sizes[Font::SIZE_NORMAL] = fromqstr(screenNormalED->text());
461 rc.font_sizes[Font::SIZE_LARGE] = fromqstr(screenLargeED->text());
462 rc.font_sizes[Font::SIZE_LARGER] = fromqstr(screenLargerED->text());
463 rc.font_sizes[Font::SIZE_LARGEST] = fromqstr(screenLargestED->text());
464 rc.font_sizes[Font::SIZE_HUGE] = fromqstr(screenHugeED->text());
465 rc.font_sizes[Font::SIZE_HUGER] = fromqstr(screenHugerED->text());
467 if (rc.font_sizes != oldrc.font_sizes
468 || rc.roman_font_name != oldrc.roman_font_name
469 || rc.sans_font_name != oldrc.sans_font_name
470 || rc.typewriter_font_name != oldrc.typewriter_font_name
471 || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
472 form_->updateScreenFonts();
477 void PrefScreenFonts::update(LyXRC const & rc)
479 setComboxFont(screenRomanCO, rc.roman_font_name,
480 rc.roman_font_foundry);
481 setComboxFont(screenSansCO, rc.sans_font_name,
482 rc.sans_font_foundry);
483 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
484 rc.typewriter_font_foundry);
486 select_roman(screenRomanCO->currentText());
487 select_sans(screenSansCO->currentText());
488 select_typewriter(screenTypewriterCO->currentText());
490 screenZoomSB->setValue(rc.zoom);
491 screenDpiSB->setValue(rc.dpi);
492 screenTinyED->setText(toqstr(rc.font_sizes[Font::SIZE_TINY]));
493 screenSmallestED->setText(toqstr(rc.font_sizes[Font::SIZE_SCRIPT]));
494 screenSmallerED->setText(toqstr(rc.font_sizes[Font::SIZE_FOOTNOTE]));
495 screenSmallED->setText(toqstr(rc.font_sizes[Font::SIZE_SMALL]));
496 screenNormalED->setText(toqstr(rc.font_sizes[Font::SIZE_NORMAL]));
497 screenLargeED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGE]));
498 screenLargerED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGER]));
499 screenLargestED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGEST]));
500 screenHugeED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGE]));
501 screenHugerED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGER]));
504 void PrefScreenFonts::select_roman(const QString& name)
506 screenRomanFE->set(QFont(name), name);
510 void PrefScreenFonts::select_sans(const QString& name)
512 screenSansFE->set(QFont(name), name);
516 void PrefScreenFonts::select_typewriter(const QString& name)
518 screenTypewriterFE->set(QFont(name), name);
522 /////////////////////////////////////////////////////////////////////
526 /////////////////////////////////////////////////////////////////////
532 bool operator()(Color::color const & lhs, Color::color const & rhs) const {
533 return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs);
539 PrefColors::PrefColors(GuiPreferences * form, QWidget * parent)
540 : PrefModule( _("Colors"), form, parent)
544 // FIXME: all of this initialization should be put into the controller.
545 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
546 // for some discussion of why that is not trivial.
547 QPixmap icon(32, 32);
548 for (int i = 0; i < Color::ignore; ++i) {
549 Color::color lc = static_cast<Color::color>(i);
550 if (lc == Color::none
551 || lc == Color::black
552 || lc == Color::white
554 || lc == Color::green
557 || lc == Color::magenta
558 || lc == Color::yellow
559 || lc == Color::inherit
560 || lc == Color::ignore) continue;
562 lcolors_.push_back(lc);
564 std::sort(lcolors_.begin(), lcolors_.end(), ColorSorter());
565 vector<Color_color>::const_iterator cit = lcolors_.begin();
566 vector<Color_color>::const_iterator const end = lcolors_.end();
567 for (; cit != end; ++cit) {
568 (void) new QListWidgetItem(QIcon(icon),
569 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
571 curcolors_.resize(lcolors_.size());
572 newcolors_.resize(lcolors_.size());
573 // End initialization
575 connect(colorChangePB, SIGNAL(clicked()),
576 this, SLOT(change_color()));
577 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
578 this, SLOT(change_lyxObjects_selection()));
579 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
580 this, SLOT(change_color()));
584 void PrefColors::apply(LyXRC & /*rc*/) const
586 for (unsigned int i = 0; i < lcolors_.size(); ++i)
587 if (curcolors_[i] != newcolors_[i])
588 form_->setColor(lcolors_[i], fromqstr(newcolors_[i]));
592 void PrefColors::update(LyXRC const & /*rc*/)
594 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
595 QColor color = QColor(guiApp->colorCache().get(lcolors_[i]));
596 QPixmap coloritem(32, 32);
597 coloritem.fill(color);
598 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
599 newcolors_[i] = curcolors_[i] = color.name();
601 change_lyxObjects_selection();
604 void PrefColors::change_color()
606 int const row = lyxObjectsLW->currentRow();
612 QString const color = newcolors_[row];
613 QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
615 if (c.isValid() && c.name() != color) {
616 newcolors_[row] = c.name();
617 QPixmap coloritem(32, 32);
619 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
625 void PrefColors::change_lyxObjects_selection()
627 colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
631 /////////////////////////////////////////////////////////////////////
635 /////////////////////////////////////////////////////////////////////
637 PrefDisplay::PrefDisplay(QWidget * parent)
638 : PrefModule(_("Graphics"), 0, parent)
641 connect(instantPreviewCO, SIGNAL(activated(int)),
642 this, SIGNAL(changed()));
643 connect(displayGraphicsCO, SIGNAL(activated(int)),
644 this, SIGNAL(changed()));
648 void PrefDisplay::apply(LyXRC & rc) const
650 switch (instantPreviewCO->currentIndex()) {
651 case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
652 case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
653 case 2: rc.preview = LyXRC::PREVIEW_ON; break;
656 lyx::graphics::DisplayType dtype;
657 switch (displayGraphicsCO->currentIndex()) {
658 case 3: dtype = lyx::graphics::NoDisplay; break;
659 case 2: dtype = lyx::graphics::ColorDisplay; break;
660 case 1: dtype = lyx::graphics::GrayscaleDisplay; break;
661 case 0: dtype = lyx::graphics::MonochromeDisplay; break;
662 default: dtype = lyx::graphics::GrayscaleDisplay;
664 rc.display_graphics = dtype;
666 // FIXME!! The graphics cache no longer has a changeDisplay method.
668 if (old_value != rc.display_graphics) {
669 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
676 void PrefDisplay::update(LyXRC const & rc)
678 switch (rc.preview) {
679 case LyXRC::PREVIEW_OFF:
680 instantPreviewCO->setCurrentIndex(0);
682 case LyXRC::PREVIEW_NO_MATH :
683 instantPreviewCO->setCurrentIndex(1);
685 case LyXRC::PREVIEW_ON :
686 instantPreviewCO->setCurrentIndex(2);
691 switch (rc.display_graphics) {
692 case lyx::graphics::NoDisplay: item = 3; break;
693 case lyx::graphics::ColorDisplay: item = 2; break;
694 case lyx::graphics::GrayscaleDisplay: item = 1; break;
695 case lyx::graphics::MonochromeDisplay: item = 0; break;
698 displayGraphicsCO->setCurrentIndex(item);
702 /////////////////////////////////////////////////////////////////////
706 /////////////////////////////////////////////////////////////////////
708 PrefPaths::PrefPaths(GuiPreferences * form, QWidget * parent)
709 : PrefModule(_("Paths"), form, parent)
712 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
713 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
714 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
715 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
716 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
717 connect(workingDirED, SIGNAL(textChanged(const QString&)),
718 this, SIGNAL(changed()));
719 connect(templateDirED, SIGNAL(textChanged(const QString&)),
720 this, SIGNAL(changed()));
721 connect(backupDirED, SIGNAL(textChanged(const QString&)),
722 this, SIGNAL(changed()));
723 connect(tempDirED, SIGNAL(textChanged(const QString&)),
724 this, SIGNAL(changed()));
725 connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
726 this, SIGNAL(changed()));
727 connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
728 this, SIGNAL(changed()));
732 void PrefPaths::apply(LyXRC & rc) const
734 rc.document_path = internal_path(fromqstr(workingDirED->text()));
735 rc.template_path = internal_path(fromqstr(templateDirED->text()));
736 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
737 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
738 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
739 // FIXME: should be a checkbox only
740 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
744 void PrefPaths::update(LyXRC const & rc)
746 workingDirED->setText(toqstr(external_path(rc.document_path)));
747 templateDirED->setText(toqstr(external_path(rc.template_path)));
748 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
749 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
750 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
751 // FIXME: should be a checkbox only
752 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
756 void PrefPaths::select_templatedir()
758 docstring file(form_->browsedir(
759 from_utf8(internal_path(fromqstr(templateDirED->text()))),
760 _("Select a document templates directory")));
762 templateDirED->setText(toqstr(file));
766 void PrefPaths::select_tempdir()
768 docstring file(form_->browsedir(
769 from_utf8(internal_path(fromqstr(tempDirED->text()))),
770 _("Select a temporary directory")));
772 tempDirED->setText(toqstr(file));
776 void PrefPaths::select_backupdir()
778 docstring file(form_->browsedir(
779 from_utf8(internal_path(fromqstr(backupDirED->text()))),
780 _("Select a backups directory")));
782 backupDirED->setText(toqstr(file));
786 void PrefPaths::select_workingdir()
788 docstring file(form_->browsedir(
789 from_utf8(internal_path(fromqstr(workingDirED->text()))),
790 _("Select a document directory")));
792 workingDirED->setText(toqstr(file));
796 void PrefPaths::select_lyxpipe()
798 docstring file(form_->browse(
799 from_utf8(internal_path(fromqstr(lyxserverDirED->text()))),
800 _("Give a filename for the LyX server pipe")));
802 lyxserverDirED->setText(toqstr(file));
806 /////////////////////////////////////////////////////////////////////
810 /////////////////////////////////////////////////////////////////////
812 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form, QWidget * parent)
813 : PrefModule(_("Spellchecker"), form, parent)
817 connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
818 #if defined (USE_ISPELL)
819 connect(spellCommandCO, SIGNAL(activated(int)),
820 this, SIGNAL(changed()));
822 spellCommandCO->setEnabled(false);
824 connect(altLanguageED, SIGNAL(textChanged(const QString&)),
825 this, SIGNAL(changed()));
826 connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
827 this, SIGNAL(changed()));
828 connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
829 this, SIGNAL(changed()));
830 connect(compoundWordCB, SIGNAL(clicked()),
831 this, SIGNAL(changed()));
832 connect(inputEncodingCB, SIGNAL(clicked()),
833 this, SIGNAL(changed()));
835 spellCommandCO->addItem(qt_("ispell"));
836 spellCommandCO->addItem(qt_("aspell"));
837 spellCommandCO->addItem(qt_("hspell"));
839 spellCommandCO->addItem(qt_("pspell (library)"));
842 spellCommandCO->addItem(qt_("aspell (library)"));
848 void PrefSpellchecker::apply(LyXRC & rc) const
850 switch (spellCommandCO->currentIndex()) {
854 rc.use_spell_lib = false;
855 rc.isp_command = fromqstr(spellCommandCO->currentText());
858 rc.use_spell_lib = true;
862 // FIXME: remove isp_use_alt_lang
863 rc.isp_alt_lang = fromqstr(altLanguageED->text());
864 rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
865 // FIXME: remove isp_use_esc_chars
866 rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
867 rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
868 // FIXME: remove isp_use_pers_dict
869 rc.isp_pers_dict = internal_path(fromqstr(persDictionaryED->text()));
870 rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
871 rc.isp_accept_compound = compoundWordCB->isChecked();
872 rc.isp_use_input_encoding = inputEncodingCB->isChecked();
876 void PrefSpellchecker::update(LyXRC const & rc)
878 spellCommandCO->setCurrentIndex(0);
880 if (rc.isp_command == "ispell") {
881 spellCommandCO->setCurrentIndex(0);
882 } else if (rc.isp_command == "aspell") {
883 spellCommandCO->setCurrentIndex(1);
884 } else if (rc.isp_command == "hspell") {
885 spellCommandCO->setCurrentIndex(2);
888 if (rc.use_spell_lib) {
889 #if defined(USE_ASPELL) || defined(USE_PSPELL)
890 spellCommandCO->setCurrentIndex(3);
894 // FIXME: remove isp_use_alt_lang
895 altLanguageED->setText(toqstr(rc.isp_alt_lang));
896 // FIXME: remove isp_use_esc_chars
897 escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
898 // FIXME: remove isp_use_pers_dict
899 persDictionaryED->setText(toqstr(external_path(rc.isp_pers_dict)));
900 compoundWordCB->setChecked(rc.isp_accept_compound);
901 inputEncodingCB->setChecked(rc.isp_use_input_encoding);
905 void PrefSpellchecker::select_dict()
907 docstring file(form_->browsedict(
908 from_utf8(internal_path(fromqstr(persDictionaryED->text())))));
910 persDictionaryED->setText(toqstr(file));
915 /////////////////////////////////////////////////////////////////////
919 /////////////////////////////////////////////////////////////////////
922 PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent)
923 : PrefModule(_("Converters"), form, parent)
927 connect(converterNewPB, SIGNAL(clicked()),
928 this, SLOT(update_converter()));
929 connect(converterRemovePB, SIGNAL(clicked()),
930 this, SLOT(remove_converter()));
931 connect(converterModifyPB, SIGNAL(clicked()),
932 this, SLOT(update_converter()));
933 connect(convertersLW, SIGNAL(currentRowChanged(int)),
934 this, SLOT(switch_converter()));
935 connect(converterFromCO, SIGNAL(activated(const QString&)),
936 this, SLOT(converter_changed()));
937 connect(converterToCO, SIGNAL(activated(const QString&)),
938 this, SLOT(converter_changed()));
939 connect(converterED, SIGNAL(textEdited(const QString&)),
940 this, SLOT(converter_changed()));
941 connect(converterFlagED, SIGNAL(textEdited(const QString&)),
942 this, SLOT(converter_changed()));
943 connect(converterNewPB, SIGNAL(clicked()),
944 this, SIGNAL(changed()));
945 connect(converterRemovePB, SIGNAL(clicked()),
946 this, SIGNAL(changed()));
947 connect(converterModifyPB, SIGNAL(clicked()),
948 this, SIGNAL(changed()));
949 connect(maxAgeLE, SIGNAL(textEdited(const QString&)),
950 this, SIGNAL(changed()));
952 maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE));
953 //converterDefGB->setFocusProxy(convertersLW);
957 void PrefConverters::apply(LyXRC & rc) const
959 rc.use_converter_cache = cacheCB->isChecked();
960 rc.converter_cache_maxage = int(maxAgeLE->text().toDouble() * 86400.0);
964 void PrefConverters::update(LyXRC const & rc)
966 cacheCB->setChecked(rc.use_converter_cache);
968 max_age.setNum(double(rc.converter_cache_maxage) / 86400.0, 'g', 6);
969 maxAgeLE->setText(max_age);
974 void PrefConverters::updateGui()
976 form_->formats().sort();
977 form_->converters().update(form_->formats());
978 // save current selection
979 QString current = converterFromCO->currentText()
980 + " -> " + converterToCO->currentText();
982 converterFromCO->clear();
983 converterToCO->clear();
985 Formats::const_iterator cit = form_->formats().begin();
986 Formats::const_iterator end = form_->formats().end();
987 for (; cit != end; ++cit) {
988 converterFromCO->addItem(toqstr(cit->prettyname()));
989 converterToCO->addItem(toqstr(cit->prettyname()));
992 // currentRowChanged(int) is also triggered when updating the listwidget
993 // block signals to avoid unnecessary calls to switch_converter()
994 convertersLW->blockSignals(true);
995 convertersLW->clear();
997 Converters::const_iterator ccit = form_->converters().begin();
998 Converters::const_iterator cend = form_->converters().end();
999 for (; ccit != cend; ++ccit) {
1000 std::string const name =
1001 ccit->From->prettyname() + " -> " + ccit->To->prettyname();
1002 int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name());
1003 new QListWidgetItem(toqstr(name), convertersLW, type);
1005 convertersLW->sortItems(Qt::AscendingOrder);
1006 convertersLW->blockSignals(false);
1008 // restore selection
1009 if (!current.isEmpty()) {
1010 QList<QListWidgetItem *> const item =
1011 convertersLW->findItems(current, Qt::MatchExactly);
1012 if (!item.isEmpty())
1013 convertersLW->setCurrentItem(item.at(0));
1016 // select first element if restoring failed
1017 if (convertersLW->currentRow() == -1)
1018 convertersLW->setCurrentRow(0);
1024 void PrefConverters::switch_converter()
1026 int const cnr = convertersLW->currentItem()->type();
1027 Converter const & c(form_->converters().get(cnr));
1028 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
1029 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
1030 converterED->setText(toqstr(c.command));
1031 converterFlagED->setText(toqstr(c.flags));
1037 void PrefConverters::converter_changed()
1043 void PrefConverters::updateButtons()
1045 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1046 Format const & to = form_->formats().get(converterToCO->currentIndex());
1047 int const sel = form_->converters().getNumber(from.name(), to.name());
1048 bool const known = !(sel < 0);
1049 bool const valid = !(converterED->text().isEmpty()
1050 || from.name() == to.name());
1052 int const cnr = convertersLW->currentItem()->type();
1053 Converter const & c(form_->converters().get(cnr));
1054 string const old_command = c.command;
1055 string const old_flag = c.flags;
1056 string const new_command(fromqstr(converterED->text()));
1057 string const new_flag(fromqstr(converterFlagED->text()));
1059 bool modified = ((old_command != new_command) || (old_flag != new_flag));
1061 converterModifyPB->setEnabled(valid && known && modified);
1062 converterNewPB->setEnabled(valid && !known);
1063 converterRemovePB->setEnabled(known);
1065 maxAgeLE->setEnabled(cacheCB->isChecked());
1066 maxAgeLA->setEnabled(cacheCB->isChecked());
1071 // specify unique from/to or it doesn't appear. This is really bad UI
1072 // this is why we can use the same function for both new and modify
1073 void PrefConverters::update_converter()
1075 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1076 Format const & to = form_->formats().get(converterToCO->currentIndex());
1077 string const flags = fromqstr(converterFlagED->text());
1078 string const command = fromqstr(converterED->text());
1080 Converter const * old =
1081 form_->converters().getConverter(from.name(), to.name());
1082 form_->converters().add(from.name(), to.name(), command, flags);
1085 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 /////////////////////////////////////////////////////////////////////
1122 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1123 : QValidator(parent), formats_(f)
1128 void FormatValidator::fixup(QString & input) const
1130 Formats::const_iterator cit = formats_.begin();
1131 Formats::const_iterator end = formats_.end();
1132 for (; cit != end; ++cit) {
1133 string const name = str(cit);
1134 if (distance(formats_.begin(), cit) == nr()) {
1135 input = toqstr(name);
1143 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1145 Formats::const_iterator cit = formats_.begin();
1146 Formats::const_iterator end = formats_.end();
1147 bool unknown = true;
1148 for (; unknown && cit != end; ++cit) {
1149 string const name = str(cit);
1150 if (distance(formats_.begin(), cit) != nr())
1151 unknown = toqstr(name) != input;
1154 if (unknown && !input.isEmpty())
1155 return QValidator::Acceptable;
1157 return QValidator::Intermediate;
1161 int FormatValidator::nr() const
1163 QComboBox * p = qobject_cast<QComboBox *>(parent());
1164 return p->itemData(p->currentIndex()).toInt();
1168 FormatNameValidator::FormatNameValidator(QWidget * parent, Formats const & f)
1169 : FormatValidator(parent, f)
1173 std::string FormatNameValidator::str(Formats::const_iterator it) const
1179 FormatPrettynameValidator::FormatPrettynameValidator(QWidget * parent, Formats const & f)
1180 : FormatValidator(parent, f)
1185 std::string FormatPrettynameValidator::str(Formats::const_iterator it) const
1187 return it->prettyname();
1191 PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent)
1192 : PrefModule(_("File formats"), form, parent)
1195 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
1196 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
1198 connect(documentCB, SIGNAL(clicked()),
1199 this, SLOT(setFlags()));
1200 connect(vectorCB, SIGNAL(clicked()),
1201 this, SLOT(setFlags()));
1202 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
1203 this, SLOT(updatePrettyname()));
1204 connect(formatsCB->lineEdit(), SIGNAL(textEdited(const QString &)),
1205 this, SIGNAL(changed()));
1209 void PrefFileformats::apply(LyXRC & /*rc*/) const
1214 void PrefFileformats::update(LyXRC const & /*rc*/)
1220 void PrefFileformats::updateView()
1222 QString const current = formatsCB->currentText();
1224 // update combobox with formats
1225 formatsCB->blockSignals(true);
1227 form_->formats().sort();
1228 Formats::const_iterator cit = form_->formats().begin();
1229 Formats::const_iterator end = form_->formats().end();
1230 for (; cit != end; ++cit)
1231 formatsCB->addItem(toqstr(cit->prettyname()),
1232 QVariant(form_->formats().getNumber(cit->name())) );
1234 // restore selection
1235 int const item = formatsCB->findText(current, Qt::MatchExactly);
1236 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
1237 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
1238 formatsCB->blockSignals(false);
1242 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
1244 int const nr = formatsCB->itemData(i).toInt();
1245 Format const f = form_->formats().get(nr);
1247 formatED->setText(toqstr(f.name()));
1248 copierED->setText(toqstr(form_->movers().command(f.name())));
1249 extensionED->setText(toqstr(f.extension()));
1250 shortcutED->setText(toqstr(f.shortcut()));
1251 viewerED->setText(toqstr(f.viewer()));
1252 editorED->setText(toqstr(f.editor()));
1253 documentCB->setChecked((f.documentFormat()));
1254 vectorCB->setChecked((f.vectorFormat()));
1258 void PrefFileformats::setFlags()
1260 int flags = Format::none;
1261 if (documentCB->isChecked())
1262 flags |= Format::document;
1263 if (vectorCB->isChecked())
1264 flags |= Format::vector;
1265 currentFormat().setFlags(flags);
1270 void PrefFileformats::on_copierED_textEdited(const QString & s)
1272 string const fmt = fromqstr(formatED->text());
1273 form_->movers().set(fmt, fromqstr(s));
1278 void PrefFileformats::on_extensionED_textEdited(const QString & s)
1280 currentFormat().setExtension(fromqstr(s));
1284 void PrefFileformats::on_viewerED_textEdited(const QString & s)
1286 currentFormat().setViewer(fromqstr(s));
1291 void PrefFileformats::on_editorED_textEdited(const QString & s)
1293 currentFormat().setEditor(fromqstr(s));
1298 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
1300 currentFormat().setShortcut(fromqstr(s));
1305 void PrefFileformats::on_formatED_editingFinished()
1307 string const newname = fromqstr(formatED->displayText());
1308 if (newname == currentFormat().name())
1311 currentFormat().setName(newname);
1316 void PrefFileformats::on_formatED_textChanged(const QString &)
1318 QString t = formatED->text();
1320 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
1321 setValid(formatLA, valid);
1325 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
1327 QString t = formatsCB->currentText();
1329 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
1330 setValid(formatsLA, valid);
1334 void PrefFileformats::updatePrettyname()
1336 string const newname = fromqstr(formatsCB->currentText());
1337 if (newname == currentFormat().prettyname())
1340 currentFormat().setPrettyname(newname);
1347 Format & PrefFileformats::currentFormat()
1349 int const i = formatsCB->currentIndex();
1350 int const nr = formatsCB->itemData(i).toInt();
1351 return form_->formats().get(nr);
1355 void PrefFileformats::on_formatNewPB_clicked()
1357 form_->formats().add("", "", "", "", "", "", Format::none);
1359 formatsCB->setCurrentIndex(0);
1360 formatsCB->setFocus(Qt::OtherFocusReason);
1364 void PrefFileformats::on_formatRemovePB_clicked()
1366 int const i = formatsCB->currentIndex();
1367 int const nr = formatsCB->itemData(i).toInt();
1368 string const current_text = form_->formats().get(nr).name();
1369 if (form_->converters().formatIsUsed(current_text)) {
1370 Alert::error(_("Format in use"),
1371 _("Cannot remove a Format used by a Converter. "
1372 "Remove the converter first."));
1376 form_->formats().erase(current_text);
1379 on_formatsCB_editTextChanged(formatsCB->currentText());
1384 /////////////////////////////////////////////////////////////////////
1388 /////////////////////////////////////////////////////////////////////
1390 PrefLanguage::PrefLanguage(QWidget * parent)
1391 : PrefModule(_("Language"), 0, parent)
1395 connect(rtlCB, SIGNAL(clicked()),
1396 this, SIGNAL(changed()));
1397 connect(markForeignCB, SIGNAL(clicked()),
1398 this, SIGNAL(changed()));
1399 connect(autoBeginCB, SIGNAL(clicked()),
1400 this, SIGNAL(changed()));
1401 connect(autoEndCB, SIGNAL(clicked()),
1402 this, SIGNAL(changed()));
1403 connect(useBabelCB, SIGNAL(clicked()),
1404 this, SIGNAL(changed()));
1405 connect(globalCB, SIGNAL(clicked()),
1406 this, SIGNAL(changed()));
1407 connect(languagePackageED, SIGNAL(textChanged(const QString&)),
1408 this, SIGNAL(changed()));
1409 connect(startCommandED, SIGNAL(textChanged(const QString&)),
1410 this, SIGNAL(changed()));
1411 connect(endCommandED, SIGNAL(textChanged(const QString&)),
1412 this, SIGNAL(changed()));
1413 connect(defaultLanguageCO, SIGNAL(activated(int)),
1414 this, SIGNAL(changed()));
1416 defaultLanguageCO->clear();
1418 // store the lang identifiers for later
1419 std::vector<LanguagePair> const langs = frontend::getLanguageData(false);
1420 std::vector<LanguagePair>::const_iterator lit = langs.begin();
1421 std::vector<LanguagePair>::const_iterator lend = langs.end();
1423 for (; lit != lend; ++lit) {
1424 defaultLanguageCO->addItem(toqstr(lit->first));
1425 lang_.push_back(lit->second);
1430 void PrefLanguage::apply(LyXRC & rc) const
1432 // FIXME: remove rtl_support bool
1433 rc.rtl_support = rtlCB->isChecked();
1434 rc.mark_foreign_language = markForeignCB->isChecked();
1435 rc.language_auto_begin = autoBeginCB->isChecked();
1436 rc.language_auto_end = autoEndCB->isChecked();
1437 rc.language_use_babel = useBabelCB->isChecked();
1438 rc.language_global_options = globalCB->isChecked();
1439 rc.language_package = fromqstr(languagePackageED->text());
1440 rc.language_command_begin = fromqstr(startCommandED->text());
1441 rc.language_command_end = fromqstr(endCommandED->text());
1442 rc.default_language = lang_[defaultLanguageCO->currentIndex()];
1446 void PrefLanguage::update(LyXRC const & rc)
1448 // FIXME: remove rtl_support bool
1449 rtlCB->setChecked(rc.rtl_support);
1450 markForeignCB->setChecked(rc.mark_foreign_language);
1451 autoBeginCB->setChecked(rc.language_auto_begin);
1452 autoEndCB->setChecked(rc.language_auto_end);
1453 useBabelCB->setChecked(rc.language_use_babel);
1454 globalCB->setChecked(rc.language_global_options);
1455 languagePackageED->setText(toqstr(rc.language_package));
1456 startCommandED->setText(toqstr(rc.language_command_begin));
1457 endCommandED->setText(toqstr(rc.language_command_end));
1459 int const pos = int(findPos_helper(lang_, rc.default_language));
1460 defaultLanguageCO->setCurrentIndex(pos);
1464 /////////////////////////////////////////////////////////////////////
1468 /////////////////////////////////////////////////////////////////////
1470 PrefPrinter::PrefPrinter(QWidget * parent)
1471 : PrefModule(_("Printer"), 0, parent)
1475 connect(printerAdaptCB, SIGNAL(clicked()),
1476 this, SIGNAL(changed()));
1477 connect(printerCommandED, SIGNAL(textChanged(const QString&)),
1478 this, SIGNAL(changed()));
1479 connect(printerNameED, SIGNAL(textChanged(const QString&)),
1480 this, SIGNAL(changed()));
1481 connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
1482 this, SIGNAL(changed()));
1483 connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
1484 this, SIGNAL(changed()));
1485 connect(printerReverseED, SIGNAL(textChanged(const QString&)),
1486 this, SIGNAL(changed()));
1487 connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
1488 this, SIGNAL(changed()));
1489 connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
1490 this, SIGNAL(changed()));
1491 connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
1492 this, SIGNAL(changed()));
1493 connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
1494 this, SIGNAL(changed()));
1495 connect(printerEvenED, SIGNAL(textChanged(const QString&)),
1496 this, SIGNAL(changed()));
1497 connect(printerOddED, SIGNAL(textChanged(const QString&)),
1498 this, SIGNAL(changed()));
1499 connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
1500 this, SIGNAL(changed()));
1501 connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
1502 this, SIGNAL(changed()));
1503 connect(printerToFileED, SIGNAL(textChanged(const QString&)),
1504 this, SIGNAL(changed()));
1505 connect(printerExtraED, SIGNAL(textChanged(const QString&)),
1506 this, SIGNAL(changed()));
1507 connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
1508 this, SIGNAL(changed()));
1509 connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
1510 this, SIGNAL(changed()));
1514 void PrefPrinter::apply(LyXRC & rc) const
1516 rc.print_adapt_output = printerAdaptCB->isChecked();
1517 rc.print_command = fromqstr(printerCommandED->text());
1518 rc.printer = fromqstr(printerNameED->text());
1520 rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
1521 rc.print_copies_flag = fromqstr(printerCopiesED->text());
1522 rc.print_reverse_flag = fromqstr(printerReverseED->text());
1523 rc.print_to_printer = fromqstr(printerToPrinterED->text());
1524 rc.print_file_extension = fromqstr(printerExtensionED->text());
1525 rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
1526 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
1527 rc.print_evenpage_flag = fromqstr(printerEvenED->text());
1528 rc.print_oddpage_flag = fromqstr(printerOddED->text());
1529 rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
1530 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
1531 rc.print_to_file = internal_path(fromqstr(printerToFileED->text()));
1532 rc.print_extra_options = fromqstr(printerExtraED->text());
1533 rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
1534 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
1538 void PrefPrinter::update(LyXRC const & rc)
1540 printerAdaptCB->setChecked(rc.print_adapt_output);
1541 printerCommandED->setText(toqstr(rc.print_command));
1542 printerNameED->setText(toqstr(rc.printer));
1544 printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
1545 printerCopiesED->setText(toqstr(rc.print_copies_flag));
1546 printerReverseED->setText(toqstr(rc.print_reverse_flag));
1547 printerToPrinterED->setText(toqstr(rc.print_to_printer));
1548 printerExtensionED->setText(toqstr(rc.print_file_extension));
1549 printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
1550 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
1551 printerEvenED->setText(toqstr(rc.print_evenpage_flag));
1552 printerOddED->setText(toqstr(rc.print_oddpage_flag));
1553 printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
1554 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
1555 printerToFileED->setText(toqstr(external_path(rc.print_to_file)));
1556 printerExtraED->setText(toqstr(rc.print_extra_options));
1557 printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
1558 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
1562 /////////////////////////////////////////////////////////////////////
1564 // PrefUserInterface
1566 /////////////////////////////////////////////////////////////////////
1568 PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent)
1569 : PrefModule(_("User interface"), form, parent)
1573 connect(autoSaveCB, SIGNAL(toggled(bool)),
1574 autoSaveSB, SLOT(setEnabled(bool)));
1575 connect(autoSaveCB, SIGNAL(toggled(bool)),
1576 TextLabel1, SLOT(setEnabled(bool)));
1577 connect(uiFilePB, SIGNAL(clicked()),
1578 this, SLOT(select_ui()));
1579 connect(bindFilePB, SIGNAL(clicked()),
1580 this, SLOT(select_bind()));
1581 connect(uiFileED, SIGNAL(textChanged(const QString &)),
1582 this, SIGNAL(changed()));
1583 connect(bindFileED, SIGNAL(textChanged(const QString &)),
1584 this, SIGNAL(changed()));
1585 connect(restoreCursorCB, SIGNAL(clicked()),
1586 this, SIGNAL(changed()));
1587 connect(loadSessionCB, SIGNAL(clicked()),
1588 this, SIGNAL(changed()));
1589 connect(loadWindowSizeCB, SIGNAL(clicked()),
1590 this, SIGNAL(changed()));
1591 connect(loadWindowLocationCB, SIGNAL(clicked()),
1592 this, SIGNAL(changed()));
1593 connect(windowWidthSB, SIGNAL(valueChanged(int)),
1594 this, SIGNAL(changed()));
1595 connect(windowHeightSB, SIGNAL(valueChanged(int)),
1596 this, SIGNAL(changed()));
1597 connect(cursorFollowsCB, SIGNAL(clicked()),
1598 this, SIGNAL(changed()));
1599 connect(autoSaveSB, SIGNAL(valueChanged(int)),
1600 this, SIGNAL(changed()));
1601 connect(autoSaveCB, SIGNAL(clicked()),
1602 this, SIGNAL(changed()));
1603 connect(lastfilesSB, SIGNAL(valueChanged(int)),
1604 this, SIGNAL(changed()));
1605 lastfilesSB->setMaximum(maxlastfiles);
1609 void PrefUserInterface::apply(LyXRC & rc) const
1611 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
1612 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
1613 rc.use_lastfilepos = restoreCursorCB->isChecked();
1614 rc.load_session = loadSessionCB->isChecked();
1615 if (loadWindowSizeCB->isChecked()) {
1616 rc.geometry_width = 0;
1617 rc.geometry_height = 0;
1619 rc.geometry_width = windowWidthSB->value();
1620 rc.geometry_height = windowHeightSB->value();
1622 rc.geometry_xysaved = loadWindowLocationCB->isChecked();
1623 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
1624 rc.autosave = autoSaveSB->value() * 60;
1625 rc.make_backup = autoSaveCB->isChecked();
1626 rc.num_lastfiles = lastfilesSB->value();
1630 void PrefUserInterface::update(LyXRC const & rc)
1632 uiFileED->setText(toqstr(external_path(rc.ui_file)));
1633 bindFileED->setText(toqstr(external_path(rc.bind_file)));
1634 restoreCursorCB->setChecked(rc.use_lastfilepos);
1635 loadSessionCB->setChecked(rc.load_session);
1636 bool loadWindowSize = rc.geometry_width == 0 && rc.geometry_height == 0;
1637 loadWindowSizeCB->setChecked(loadWindowSize);
1638 if (!loadWindowSize) {
1639 windowWidthSB->setValue(rc.geometry_width);
1640 windowHeightSB->setValue(rc.geometry_height);
1642 loadWindowLocationCB->setChecked(rc.geometry_xysaved);
1643 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
1644 // convert to minutes
1645 int mins(rc.autosave / 60);
1646 if (rc.autosave && !mins)
1648 autoSaveSB->setValue(mins);
1649 autoSaveCB->setChecked(rc.make_backup);
1650 lastfilesSB->setValue(rc.num_lastfiles);
1654 void PrefUserInterface::select_ui()
1656 docstring const name =
1657 from_utf8(internal_path(fromqstr(uiFileED->text())));
1658 docstring file = form_->browseUI(name);
1660 uiFileED->setText(toqstr(file));
1664 void PrefUserInterface::select_bind()
1666 docstring const name =
1667 from_utf8(internal_path(fromqstr(bindFileED->text())));
1668 docstring file = form_->browsebind(name);
1670 bindFileED->setText(toqstr(file));
1674 void PrefUserInterface::on_loadWindowSizeCB_toggled(bool loadwindowsize)
1676 windowWidthLA->setDisabled(loadwindowsize);
1677 windowHeightLA->setDisabled(loadwindowsize);
1678 windowWidthSB->setDisabled(loadwindowsize);
1679 windowHeightSB->setDisabled(loadwindowsize);
1683 PrefIdentity::PrefIdentity(QWidget * parent)
1684 : PrefModule(_("Identity"), 0, parent)
1688 connect(nameED, SIGNAL(textChanged(const QString&)),
1689 this, SIGNAL(changed()));
1690 connect(emailED, SIGNAL(textChanged(const QString&)),
1691 this, SIGNAL(changed()));
1695 void PrefIdentity::apply(LyXRC & rc) const
1697 rc.user_name = fromqstr(nameED->text());
1698 rc.user_email = fromqstr(emailED->text());
1702 void PrefIdentity::update(LyXRC const & rc)
1704 nameED->setText(toqstr(rc.user_name));
1705 emailED->setText(toqstr(rc.user_email));
1710 /////////////////////////////////////////////////////////////////////
1714 /////////////////////////////////////////////////////////////////////
1716 GuiPreferences::GuiPreferences(LyXView & lv)
1717 : GuiDialog(lv, "prefs"), Controller(this), update_screen_font_(false)
1720 setViewTitle(_("Preferences"));
1721 setController(this, false);
1723 QDialog::setModal(false);
1725 connect(savePB, SIGNAL(clicked()), this, SLOT(slotOK()));
1726 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
1727 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
1728 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
1730 add(new PrefUserInterface(this));
1731 add(new PrefScreenFonts(this));
1732 add(new PrefColors(this));
1733 add(new PrefDisplay);
1734 add(new PrefKeyboard(this));
1736 add(new PrefPaths(this));
1738 add(new PrefIdentity);
1740 add(new PrefLanguage);
1741 add(new PrefSpellchecker(this));
1743 add(new PrefPrinter);
1745 add(new PrefPlaintext);
1746 add(new PrefLatex(this));
1748 PrefConverters * converters = new PrefConverters(this);
1749 PrefFileformats * formats = new PrefFileformats(this);
1750 connect(formats, SIGNAL(formatsChanged()),
1751 converters, SLOT(updateGui()));
1755 prefsPS->setCurrentPanel(_("User interface"));
1756 // FIXME: hack to work around resizing bug in Qt >= 4.2
1757 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1758 #if QT_VERSION >= 0x040200
1759 prefsPS->updateGeometry();
1762 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
1764 bc().setApply(applyPB);
1765 bc().setCancel(closePB);
1766 bc().setRestore(restorePB);
1770 void GuiPreferences::add(PrefModule * module)
1772 BOOST_ASSERT(module);
1773 prefsPS->addPanel(module, module->title());
1774 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
1775 modules_.push_back(module);
1779 void GuiPreferences::closeEvent(QCloseEvent * e)
1786 void GuiPreferences::change_adaptor()
1792 void GuiPreferences::apply(LyXRC & rc) const
1794 size_t end = modules_.size();
1795 for (size_t i = 0; i != end; ++i)
1796 modules_[i]->apply(rc);
1800 void GuiPreferences::updateRc(LyXRC const & rc)
1802 size_t const end = modules_.size();
1803 for (size_t i = 0; i != end; ++i)
1804 modules_[i]->update(rc);
1808 void GuiPreferences::applyView()
1814 void GuiPreferences::updateContents()
1820 bool GuiPreferences::initialiseParams(std::string const &)
1823 formats_ = lyx::formats;
1824 converters_ = theConverters();
1825 converters_.update(formats_);
1826 movers_ = theMovers();
1828 update_screen_font_ = false;
1834 void GuiPreferences::dispatchParams()
1837 rc_.write(ss, true);
1838 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
1839 // FIXME: these need lfuns
1841 theBufferList().setCurrentAuthor(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
1843 lyx::formats = formats_;
1845 theConverters() = converters_;
1846 theConverters().update(lyx::formats);
1847 theConverters().buildGraph();
1849 theMovers() = movers_;
1851 vector<string>::const_iterator it = colors_.begin();
1852 vector<string>::const_iterator const end = colors_.end();
1853 for (; it != end; ++it)
1854 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
1857 if (update_screen_font_) {
1858 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
1859 update_screen_font_ = false;
1862 // The Save button has been pressed
1863 if (dialog().isClosing()) {
1864 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
1869 void GuiPreferences::setColor(Color_color col, string const & hex)
1871 colors_.push_back(lcolor.getLyXName(col) + ' ' + hex);
1875 void GuiPreferences::updateScreenFonts()
1877 update_screen_font_ = true;
1881 docstring const GuiPreferences::browsebind(docstring const & file) const
1883 return browseLibFile(from_ascii("bind"), file, from_ascii("bind"),
1884 _("Choose bind file"),
1885 FileFilterList(_("LyX bind files (*.bind)")));
1889 docstring const GuiPreferences::browseUI(docstring const & file) const
1891 return browseLibFile(from_ascii("ui"), file, from_ascii("ui"),
1892 _("Choose UI file"),
1893 FileFilterList(_("LyX UI files (*.ui)")));
1897 docstring const GuiPreferences::browsekbmap(docstring const & file) const
1899 return browseLibFile(from_ascii("kbd"), file, from_ascii("kmap"),
1900 _("Choose keyboard map"),
1901 FileFilterList(_("LyX keyboard maps (*.kmap)")));
1905 docstring const GuiPreferences::browsedict(docstring const & file) const
1907 if (lyxrc.use_spell_lib)
1908 return browseFile(file,
1909 _("Choose personal dictionary"),
1910 FileFilterList(_("*.pws")));
1912 return browseFile(file,
1913 _("Choose personal dictionary"),
1914 FileFilterList(_("*.ispell")));
1918 docstring const GuiPreferences::browse(docstring const & file,
1919 docstring const & title) const
1921 return browseFile(file, title, FileFilterList(), true);
1925 docstring const GuiPreferences::browsedir(docstring const & path,
1926 docstring const & title) const
1928 return browseDir(path, title);
1932 // We support less paper sizes than the document dialog
1933 // Therefore this adjustment is needed.
1934 PAPER_SIZE GuiPreferences::toPaperSize(int i) const
1938 return PAPER_DEFAULT;
1940 return PAPER_USLETTER;
1942 return PAPER_USLEGAL;
1944 return PAPER_USEXECUTIVE;
1954 // should not happen
1955 return PAPER_DEFAULT;
1960 int GuiPreferences::fromPaperSize(PAPER_SIZE papersize) const
1962 switch (papersize) {
1965 case PAPER_USLETTER:
1969 case PAPER_USEXECUTIVE:
1980 // should not happen
1986 Dialog * createGuiPreferences(LyXView & lv) { return new GuiPreferences(lv); }
1989 } // namespace frontend
1992 #include "GuiPrefs_moc.cpp"