]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QPrefsDialog.C
* MSVC Compilation fix: #warning is not supported.
[lyx.git] / src / frontends / qt4 / QPrefsDialog.C
1 /**
2  * \file QPrefsDialog.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Abdelrazak Younes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13 #include "debug.h"
14 #include "qt_helpers.h"
15
16 #include "ColorCache.h"
17 #include "Qt2BC.h"
18 #include "qt_helpers.h"
19
20 #include "debug.h"
21 #include "session.h"
22 #include "LColor.h"
23 #include "lyxfont.h"
24
25 #include "support/lstrings.h"
26 #include "support/os.h"
27
28 #include "controllers/ControlPrefs.h"
29 #include "controllers/frnt_lang.h"
30 #include "controllers/helper_funcs.h"
31
32 #include "frontends/Alert.h"
33 #include "frontends/lyx_gui.h"
34
35 #include "QPrefsDialog.h"
36 #include "QPrefs.h"
37
38 #include "panelstack.h"
39 #include "qfontexample.h"
40
41 #include "gettext.h"
42 #include "LColor.h"
43 #include "ColorCache.h"
44
45 #include "controllers/ControlPrefs.h"
46
47 #include <QCheckBox>
48 #include <QColorDialog>
49 #include <QFontDatabase>
50 #include <QLineEdit>
51 #include <QPushButton>
52 #include <QSpinBox>
53 #include <QString>
54 #include <QValidator>
55 #include <QCloseEvent>
56
57 #include <boost/tuple/tuple.hpp>
58 #include <iomanip>
59 #include <sstream>
60
61 using lyx::support::compare_no_case;
62
63 using std::distance;
64 using std::endl;
65 using std::setfill;
66 using std::setw;
67 using std::string;
68 using std::ostringstream;
69 using std::pair;
70 using std::vector;
71
72
73 namespace lyx {
74 namespace frontend {
75
76 string const LookAndFeel = "Look and feel";
77 string const LanguageSettings = "Language settings";
78 string const Outputs = "Outputs";
79
80
81 // FIXME: move to helper_funcs.h
82 namespace {
83
84 template<class A>
85 typename std::vector<A>::size_type
86 findPos(std::vector<A> const & vec, A const & val)
87 {
88         typedef typename std::vector<A>::const_iterator Cit;
89
90         Cit it = std::find(vec.begin(), vec.end(), val);
91         if (it == vec.end())
92                 return 0;
93         return distance(vec.begin(), it);
94 }
95
96 void setComboxFont(QComboBox * cb, string const & family, string const & foundry)
97 {
98         string const name = makeFontName(family, foundry);
99         for (int i = 0; i < cb->count(); ++i) {
100                 if (fromqstr(cb->text(i)) == name) {
101                         cb->setCurrentItem(i);
102                         return;
103                 }
104         }
105
106         // Try matching without foundry name
107
108         // We count in reverse in order to prefer the Xft foundry
109         for (int i = cb->count() - 1; i >= 0; --i) {
110                 pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
111                 if (compare_no_case(tmp.first, family) == 0) {
112                         cb->setCurrentItem(i);
113                         return;
114                 }
115         }
116
117         // family alone can contain e.g. "Helvetica [Adobe]"
118         pair<string, string> tmpfam = parseFontName(family);
119
120         // We count in reverse in order to prefer the Xft foundry
121         for (int i = cb->count() - 1; i >= 0; --i) {
122                 pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
123                 if (compare_no_case(tmp.first, tmpfam.first) == 0) {
124                         cb->setCurrentItem(i);
125                         return;
126                 }
127         }
128
129         // Bleh, default fonts, and the names couldn't be found. Hack
130         // for bug 1063. Qt makes baby Jesus cry.
131
132         QFont font;
133
134         if (family == lyx_gui::roman_font_name()) {
135                 font.setStyleHint(QFont::Serif);
136                 font.setFamily(family.c_str());
137         } else if (family == lyx_gui::sans_font_name()) {
138                 font.setStyleHint(QFont::SansSerif);
139                 font.setFamily(family.c_str());
140         } else if (family == lyx_gui::typewriter_font_name()) {
141                 font.setStyleHint(QFont::TypeWriter);
142                 font.setFamily(family.c_str());
143         } else {
144                 lyxerr << "FAILED to find the default font: '"
145                        << foundry << "', '" << family << '\''<< endl;
146                 return;
147         }
148
149         QFontInfo info(font);
150         pair<string, string> tmp = parseFontName(fromqstr(info.family()));
151         string const & default_font_name = tmp.first;
152         lyxerr << "Apparent font is " << default_font_name << endl;
153
154         for (int i = 0; i < cb->count(); ++i) {
155                 lyxerr << "Looking at " << fromqstr(cb->text(i)) << endl;
156                 if (compare_no_case(fromqstr(cb->text(i)),
157                                     default_font_name) == 0) {
158                         cb->setCurrentItem(i);
159                         return;
160                 }
161         }
162
163         lyxerr << "FAILED to find the font: '"
164                << foundry << "', '" << family << '\'' <<endl;
165 }
166
167
168 QString const external_path(string const & input)
169 {
170         return toqstr(lyx::support::os::external_path(input));
171 }
172
173
174 string const internal_path(QString const & input)
175 {
176         return lyx::support::os::internal_path(fromqstr(input));
177 }
178
179 } // end namespace anon
180
181
182 PrefAscii::PrefAscii(QWidget * parent)
183 : PrefModule(_(Outputs), _("Plain text"), 0, parent)
184 {
185         setupUi(this);
186         connect(asciiLinelengthSB, SIGNAL(valueChanged(int)),
187                 this, SIGNAL(changed()));
188         connect(asciiRoffED, SIGNAL(textChanged(const QString&)),
189                 this, SIGNAL(changed()));
190 }
191
192
193 void PrefAscii::apply(LyXRC & rc) const
194 {
195         rc.ascii_linelen = asciiLinelengthSB->value();
196         rc.ascii_roff_command = fromqstr(asciiRoffED->text());
197 }
198
199
200 void PrefAscii::update(LyXRC const & rc)
201 {
202         asciiLinelengthSB->setValue(rc.ascii_linelen);
203         asciiRoffED->setText(toqstr(rc.ascii_roff_command));
204 }
205
206
207 PrefDate::PrefDate(QWidget * parent)
208 : PrefModule(_(Outputs), _("Date format"), 0, parent)
209 {
210         setupUi(this);
211         connect(DateED, SIGNAL(textChanged(const QString&)),
212                 this, SIGNAL(changed()));
213 }
214
215
216 void PrefDate::apply(LyXRC & rc) const
217 {
218         rc.date_insert_format = fromqstr(DateED->text());
219 }
220
221
222 void PrefDate::update(LyXRC const & rc)
223 {
224         DateED->setText(toqstr(rc.date_insert_format));
225 }
226
227
228 PrefKeyboard::PrefKeyboard(QPrefs * form, QWidget * parent)
229 : PrefModule(_(LookAndFeel), _("Keyboard"), form, parent)
230 {
231         setupUi(this);
232
233         connect(keymapCB, SIGNAL( toggled(bool) ),
234                 firstKeymapLA, SLOT( setEnabled(bool) ) );
235         connect(keymapCB, SIGNAL( toggled(bool) ),
236                 secondKeymapLA, SLOT( setEnabled(bool) ) );
237         connect(keymapCB, SIGNAL( toggled(bool) ),
238                 firstKeymapED, SLOT( setEnabled(bool) ) );
239         connect(keymapCB, SIGNAL( toggled(bool) ),
240                 secondKeymapED, SLOT( setEnabled(bool) ) );
241         connect(keymapCB, SIGNAL( toggled(bool) ),
242                 firstKeymapPB, SLOT( setEnabled(bool) ) );
243         connect(keymapCB, SIGNAL( toggled(bool) ),
244                 secondKeymapPB, SLOT( setEnabled(bool) ) );
245
246         connect(keymapCB, SIGNAL(toggled(bool)),
247                 this, SIGNAL(changed()));
248         connect(firstKeymapED, SIGNAL(textChanged(const QString&)),
249                 this, SIGNAL(changed()));
250         connect(secondKeymapED, SIGNAL(textChanged(const QString&)),
251                 this, SIGNAL(changed()));
252 }
253
254
255 void PrefKeyboard::apply(LyXRC & rc) const
256 {
257         // FIXME: can derive CB from the two EDs
258         rc.use_kbmap = keymapCB->isChecked();
259         rc.primary_kbmap = internal_path(firstKeymapED->text());
260         rc.secondary_kbmap = internal_path(secondKeymapED->text());
261 }
262
263
264 void PrefKeyboard::update(LyXRC const & rc)
265 {
266         // FIXME: can derive CB from the two EDs
267         keymapCB->setChecked(rc.use_kbmap);
268         // no idea why we need these. Fscking Qt.
269         firstKeymapED->setEnabled(rc.use_kbmap);
270         firstKeymapPB->setEnabled(rc.use_kbmap);
271         firstKeymapLA->setEnabled(rc.use_kbmap);
272         secondKeymapED->setEnabled(rc.use_kbmap);
273         secondKeymapPB->setEnabled(rc.use_kbmap);
274         secondKeymapLA->setEnabled(rc.use_kbmap);
275         firstKeymapED->setText(external_path(rc.primary_kbmap));
276         secondKeymapED->setText(external_path(rc.secondary_kbmap));
277 }
278
279
280 QString PrefKeyboard::testKeymap(QString keymap)
281 {
282         return toqstr(form_->controller().browsekbmap(fromqstr(keymap)));
283 }
284
285
286 void PrefKeyboard::on_firstKeymapPB_clicked(bool)
287 {
288         QString file = testKeymap(firstKeymapED->text());
289         if (!file.isEmpty())
290                 firstKeymapED->setText(file);
291 }
292
293
294 void PrefKeyboard::on_secondKeymapPB_clicked(bool)
295 {
296         QString file = testKeymap(secondKeymapED->text());
297         if (!file.isEmpty())
298                 secondKeymapED->setText(file);
299 }
300
301
302 PrefLatex::PrefLatex(QPrefs * form, QWidget * parent)
303 : PrefModule(_(Outputs), _("LaTeX"), form, parent)
304 {
305         setupUi(this);
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(toggled(bool)),
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()));
320 }
321
322
323 void PrefLatex::apply(LyXRC & rc) const
324 {
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->currentItem());
333 }
334
335
336 void PrefLatex::update(LyXRC const & rc)
337 {
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));
346 }
347
348
349 PrefScreenFonts::PrefScreenFonts(QPrefs * form, QWidget * parent)
350 : PrefModule(_(LookAndFeel), _("Screen fonts"), form, parent)
351 {
352         setupUi(this);
353
354         connect(screenRomanCO, SIGNAL(activated(const QString&)),
355                 this, SLOT(select_roman(const QString&)));
356         connect(screenSansCO, SIGNAL(activated(const QString&)),
357                 this, SLOT(select_sans(const QString&)));
358         connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
359                 this, SLOT(select_typewriter(const QString&)));
360
361         QFontDatabase fontdb;
362         QStringList families(fontdb.families());
363         for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
364                 screenRomanCO->insertItem(*it);
365                 screenSansCO->insertItem(*it);
366                 screenTypewriterCO->insertItem(*it);
367         }
368         connect(screenRomanCO, SIGNAL(activated(const QString&)),
369                 this, SIGNAL(changed()));
370         connect(screenSansCO, SIGNAL(activated(const QString&)),
371                 this, SIGNAL(changed()));
372         connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
373                 this, SIGNAL(changed()));
374         connect(screenZoomSB, SIGNAL(valueChanged(int)),
375                 this, SIGNAL(changed()));
376         connect(screenDpiSB, SIGNAL(valueChanged(int)),
377                 this, SIGNAL(changed()));
378         connect(screenTinyED, SIGNAL(textChanged(const QString&)),
379                 this, SIGNAL(changed()));
380         connect(screenSmallestED, SIGNAL(textChanged(const QString&)),
381                 this, SIGNAL(changed()));
382         connect(screenSmallerED, SIGNAL(textChanged(const QString&)),
383                 this, SIGNAL(changed()));
384         connect(screenSmallED, SIGNAL(textChanged(const QString&)),
385                 this, SIGNAL(changed()));
386         connect(screenNormalED, SIGNAL(textChanged(const QString&)),
387                 this, SIGNAL(changed()));
388         connect(screenLargeED, SIGNAL(textChanged(const QString&)),
389                 this, SIGNAL(changed()));
390         connect(screenLargerED, SIGNAL(textChanged(const QString&)),
391                 this, SIGNAL(changed()));
392         connect(screenLargestED, SIGNAL(textChanged(const QString&)),
393                 this, SIGNAL(changed()));
394         connect(screenHugeED, SIGNAL(textChanged(const QString&)),
395                 this, SIGNAL(changed()));
396         connect(screenHugerED, SIGNAL(textChanged(const QString&)),
397                 this, SIGNAL(changed()));
398
399         screenTinyED->setValidator(new QDoubleValidator(
400                 screenTinyED));
401         screenSmallestED->setValidator(new QDoubleValidator(
402                 screenSmallestED));
403         screenSmallerED->setValidator(new QDoubleValidator(
404                 screenSmallerED));
405         screenSmallED->setValidator(new QDoubleValidator(
406                 screenSmallED));
407         screenNormalED->setValidator(new QDoubleValidator(
408                 screenNormalED));
409         screenLargeED->setValidator(new QDoubleValidator(
410                 screenLargeED));
411         screenLargerED->setValidator(new QDoubleValidator(
412                 screenLargerED));
413         screenLargestED->setValidator(new QDoubleValidator(
414                 screenLargestED));
415         screenHugeED->setValidator(new QDoubleValidator(
416                 screenHugeED));
417         screenHugerED->setValidator(new QDoubleValidator(
418                 screenHugerED));
419 }
420
421
422 void PrefScreenFonts::apply(LyXRC & rc) const
423 {
424         LyXRC const oldrc(rc);
425
426         boost::tie(rc.roman_font_name, rc.roman_font_foundry)
427                 = parseFontName(fromqstr(screenRomanCO->currentText()));
428         boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
429                 parseFontName(fromqstr(screenSansCO->currentText()));
430         boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
431                 parseFontName(fromqstr(screenTypewriterCO->currentText()));
432
433         rc.zoom = screenZoomSB->value();
434         rc.dpi = screenDpiSB->value();
435         rc.font_sizes[LyXFont::SIZE_TINY] = fromqstr(screenTinyED->text());
436         rc.font_sizes[LyXFont::SIZE_SCRIPT] = fromqstr(screenSmallestED->text());
437         rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text());
438         rc.font_sizes[LyXFont::SIZE_SMALL] = fromqstr(screenSmallED->text());
439         rc.font_sizes[LyXFont::SIZE_NORMAL] = fromqstr(screenNormalED->text());
440         rc.font_sizes[LyXFont::SIZE_LARGE] = fromqstr(screenLargeED->text());
441         rc.font_sizes[LyXFont::SIZE_LARGER] = fromqstr(screenLargerED->text());
442         rc.font_sizes[LyXFont::SIZE_LARGEST] = fromqstr(screenLargestED->text());
443         rc.font_sizes[LyXFont::SIZE_HUGE] = fromqstr(screenHugeED->text());
444         rc.font_sizes[LyXFont::SIZE_HUGER] = fromqstr(screenHugerED->text());
445
446         if (rc.font_sizes != oldrc.font_sizes
447                 || rc.roman_font_name != oldrc.roman_font_name
448                 || rc.sans_font_name != oldrc.sans_font_name
449                 || rc.typewriter_font_name != oldrc.typewriter_font_name
450                 || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
451                 form_->controller().updateScreenFonts();
452         }
453 }
454
455
456 void PrefScreenFonts::update(LyXRC const & rc)
457 {
458         setComboxFont(screenRomanCO, rc.roman_font_name,
459                         rc.roman_font_foundry);
460         setComboxFont(screenSansCO, rc.sans_font_name,
461                         rc.sans_font_foundry);
462         setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
463                         rc.typewriter_font_foundry);
464
465         select_roman(screenRomanCO->currentText());
466         select_sans(screenSansCO->currentText());
467         select_typewriter(screenTypewriterCO->currentText());
468
469         screenZoomSB->setValue(rc.zoom);
470         screenDpiSB->setValue(rc.dpi);
471         screenTinyED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_TINY]));
472         screenSmallestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SCRIPT]));
473         screenSmallerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]));
474         screenSmallED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SMALL]));
475         screenNormalED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_NORMAL]));
476         screenLargeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGE]));
477         screenLargerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGER]));
478         screenLargestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGEST]));
479         screenHugeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGE]));
480         screenHugerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGER]));
481 }
482
483 void PrefScreenFonts::select_roman(const QString& name)
484 {
485         screenRomanFE->set(QFont(name), name);
486 }
487
488
489 void PrefScreenFonts::select_sans(const QString& name)
490 {
491         screenSansFE->set(QFont(name), name);
492 }
493
494
495 void PrefScreenFonts::select_typewriter(const QString& name)
496 {
497         screenTypewriterFE->set(QFont(name), name);
498 }
499
500
501 PrefColors::PrefColors(QPrefs * form, QWidget * parent)
502 : PrefModule(_(LookAndFeel), _("Colors"), form, parent)
503 {
504         setupUi(this);
505
506         // FIXME: put in controller
507         for (int i = 0; i < LColor::ignore; ++i) {
508                 LColor::color lc = static_cast<LColor::color>(i);
509                 if (lc == LColor::none
510                         || lc == LColor::black
511                         || lc == LColor::white
512                         || lc == LColor::red
513                         || lc == LColor::green
514                         || lc == LColor::blue
515                         || lc == LColor::cyan
516                         || lc == LColor::magenta
517                         || lc == LColor::yellow
518                         || lc == LColor::inherit
519                         || lc == LColor::ignore) continue;
520
521                 lcolors_.push_back(lc);
522                 QColor color = QColor(lcolorcache.get(lc));
523                 prefcolors_.push_back(color.name());
524                 QPixmap coloritem(32, 32);
525                 coloritem.fill(color);
526                 // This is not a memory leak:
527                 /*QListWidgetItem * newItem =*/ new QListWidgetItem(QIcon(coloritem),
528                         toqstr(lcolor.getGUIName(lc)), lyxObjectsLW);
529         }
530         newcolors_ = prefcolors_;
531
532         connect(colorChangePB, SIGNAL(clicked()),
533                 this, SLOT(change_color()));
534         connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
535                 this, SLOT(change_color()));
536 }
537
538
539 void PrefColors::apply(LyXRC & /*rc*/) const
540 {
541         for (unsigned int i = 0; i < lcolors_.size(); ++i) {
542                 if (prefcolors_[i]!=newcolors_[i])
543                         form_->controller().setColor(lcolors_[i], fromqstr(newcolors_[i]));
544         }
545 }
546
547
548 void PrefColors::update(LyXRC const & /*rc*/)
549 {
550 }
551
552 void PrefColors::change_color()
553 {
554         int const row = lyxObjectsLW->currentRow();
555         QString color = newcolors_[row];
556         QColor c(QColorDialog::getColor(QColor(color),
557                 qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget()));
558
559         if (c.name()!=color) {
560                 newcolors_[row] = c.name();
561                 QPixmap coloritem(32, 32);
562                 coloritem.fill(c);
563                 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
564                 // emit signal
565                 changed();
566         }
567 }
568
569
570 PrefCygwinPath::PrefCygwinPath(QWidget * parent)
571 : PrefModule(_(Outputs), _("Paths"), 0, parent)
572 {
573         setupUi(this);
574         connect(pathCB, SIGNAL(toggled(bool)),
575                 this, SIGNAL(changed()));
576 }
577
578
579 void PrefCygwinPath::apply(LyXRC & rc) const
580 {
581         rc.windows_style_tex_paths = pathCB->isChecked();
582 }
583
584
585 void PrefCygwinPath::update(LyXRC const & rc)
586 {
587         pathCB->setChecked(rc.windows_style_tex_paths);
588 }
589
590
591 PrefDisplay::PrefDisplay(QWidget * parent)
592 : PrefModule(_(LookAndFeel), _("Graphics"), 0, parent)
593 {
594         setupUi(this);
595         connect(instantPreviewCO, SIGNAL(activated(int)),
596                 this, SIGNAL(changed()));
597         connect(displayGraphicsCO, SIGNAL(activated(int)),
598                 this, SIGNAL(changed()));
599 }
600
601
602 void PrefDisplay::apply(LyXRC & rc) const
603 {
604         switch (instantPreviewCO->currentItem()) {
605         case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
606         case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
607         case 2: rc.preview = LyXRC::PREVIEW_ON; break;
608         }
609
610         lyx::graphics::DisplayType dtype;
611         switch (displayGraphicsCO->currentItem()) {
612         case 3: dtype = lyx::graphics::NoDisplay; break;
613         case 2: dtype = lyx::graphics::ColorDisplay; break;
614         case 1: dtype = lyx::graphics::GrayscaleDisplay;        break;
615         case 0: dtype = lyx::graphics::MonochromeDisplay; break;
616         default: dtype = lyx::graphics::GrayscaleDisplay;
617         }
618         rc.display_graphics = dtype;
619
620 #ifdef WITH_WARNINGS
621 #warning FIXME!! The graphics cache no longer has a changeDisplay method.
622 #endif
623 #if 0
624         if (old_value != rc.display_graphics) {
625                 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
626                 gc.changeDisplay();
627         }
628 #endif
629 }
630
631
632 void PrefDisplay::update(LyXRC const & rc)
633 {
634         switch (rc.preview) {
635         case LyXRC::PREVIEW_OFF:
636                 instantPreviewCO->setCurrentIndex(0);
637                 break;
638         case LyXRC::PREVIEW_NO_MATH :
639                 instantPreviewCO->setCurrentIndex(1);
640                 break;
641         case LyXRC::PREVIEW_ON :
642                 instantPreviewCO->setCurrentIndex(2);
643                 break;
644         }
645
646         int item = 2;
647         switch (rc.display_graphics) {
648                 case lyx::graphics::NoDisplay:          item = 3; break;
649                 case lyx::graphics::ColorDisplay:       item = 2; break;
650                 case lyx::graphics::GrayscaleDisplay:   item = 1; break;
651                 case lyx::graphics::MonochromeDisplay:  item = 0; break;
652                 default: break;
653         }
654         displayGraphicsCO->setCurrentIndex(item);
655 }
656
657
658 PrefPaths::PrefPaths(QPrefs * form, QWidget * parent)
659 : PrefModule(string(), _("Paths"), form, parent)
660 {
661         setupUi(this);
662         connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
663         connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
664         connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
665         connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
666         connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
667         connect(workingDirED, SIGNAL(textChanged(const QString&)),
668                 this, SIGNAL(changed()));
669         connect(templateDirED, SIGNAL(textChanged(const QString&)),
670                 this, SIGNAL(changed()));
671         connect(backupDirED, SIGNAL(textChanged(const QString&)),
672                 this, SIGNAL(changed()));
673         connect(tempDirED, SIGNAL(textChanged(const QString&)),
674                 this, SIGNAL(changed()));
675         connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
676                 this, SIGNAL(changed()));
677         connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
678                 this, SIGNAL(changed()));
679 }
680
681
682 void PrefPaths::apply(LyXRC & rc) const
683 {
684         rc.document_path = internal_path(workingDirED->text());
685         rc.template_path = internal_path(templateDirED->text());
686         rc.backupdir_path = internal_path(backupDirED->text());
687         rc.tempdir_path = internal_path(tempDirED->text());
688         rc.path_prefix = fromqstr(pathPrefixED->text());
689         // FIXME: should be a checkbox only
690         rc.lyxpipes = internal_path(lyxserverDirED->text());
691 }
692
693
694 void PrefPaths::update(LyXRC const & rc)
695 {
696         workingDirED->setText(external_path(rc.document_path));
697         templateDirED->setText(external_path(rc.template_path));
698         backupDirED->setText(external_path(rc.backupdir_path));
699         tempDirED->setText(external_path(rc.tempdir_path));
700         pathPrefixED->setText(toqstr(rc.path_prefix));
701         // FIXME: should be a checkbox only
702         lyxserverDirED->setText(external_path(rc.lyxpipes));
703 }
704
705 // NB: the _() is OK here because it gets passed back and we toqstr() them
706
707 void PrefPaths::select_templatedir()
708 {
709         string file(form_->controller().browsedir(fromqstr(templateDirED->text()), _("Select a document templates directory")));
710         if (!file.empty())
711                 templateDirED->setText(toqstr(file));
712 }
713
714
715 void PrefPaths::select_tempdir()
716 {
717         string file(form_->controller().browsedir(fromqstr(tempDirED->text()), _("Select a temporary directory")));
718         if (!file.empty())
719                 tempDirED->setText(toqstr(file));
720 }
721
722
723 void PrefPaths::select_backupdir()
724 {
725         string file(form_->controller().browsedir(fromqstr(backupDirED->text()), _("Select a backups directory")));
726         if (!file.empty())
727                 backupDirED->setText(toqstr(file));
728 }
729
730
731 void PrefPaths::select_workingdir()
732 {
733         string file(form_->controller().browsedir(fromqstr(workingDirED->text()), _("Select a document directory")));
734         if (!file.empty())
735                 workingDirED->setText(toqstr(file));
736 }
737
738
739 void PrefPaths::select_lyxpipe()
740 {
741         string file(form_->controller().browse(fromqstr(lyxserverDirED->text()), _("Give a filename for the LyX server pipe")));
742         if (!file.empty())
743                 lyxserverDirED->setText(toqstr(file));
744 }
745
746
747 PrefSpellchecker::PrefSpellchecker(QPrefs * form, QWidget * parent)
748 : PrefModule(_(LanguageSettings), _("Spellchecker"), form, parent)
749 {
750         setupUi(this);
751
752         connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
753 #if defined (USE_ISPELL)
754         connect(spellCommandCO, SIGNAL(activated(int)),
755                 this, SIGNAL(changed()));
756 #else
757         spellCommandCO->setEnabled(false);
758 #endif
759         connect(altLanguageED, SIGNAL(textChanged(const QString&)),
760                 this, SIGNAL(changed()));
761         connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
762                 this, SIGNAL(changed()));
763         connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
764                 this, SIGNAL(changed()));
765         connect(compoundWordCB, SIGNAL(toggled(bool)),
766                 this, SIGNAL(changed()));
767         connect(inputEncodingCB, SIGNAL(toggled(bool)),
768                 this, SIGNAL(changed()));
769
770         spellCommandCO->insertItem(qt_("ispell"));
771         spellCommandCO->insertItem(qt_("aspell"));
772         spellCommandCO->insertItem(qt_("hspell"));
773 #ifdef USE_PSPELL
774         spellCommandCO->insertItem(qt_("pspell (library)"));
775 #else
776 #ifdef USE_ASPELL
777         spellCommandCO->insertItem(qt_("aspell (library)"));
778 #endif
779 #endif
780 }
781
782
783 void PrefSpellchecker::apply(LyXRC & rc) const
784 {
785         switch (spellCommandCO->currentItem()) {
786                 case 0:
787                 case 1:
788                 case 2:
789                         rc.use_spell_lib = false;
790                         rc.isp_command = fromqstr(spellCommandCO->currentText());
791                         break;
792                 case 3:
793                         rc.use_spell_lib = true;
794                         break;
795         }
796
797         // FIXME: remove isp_use_alt_lang
798         rc.isp_alt_lang = fromqstr(altLanguageED->text());
799         rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
800         // FIXME: remove isp_use_esc_chars
801         rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
802         rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
803         // FIXME: remove isp_use_pers_dict
804         rc.isp_pers_dict = internal_path(persDictionaryED->text());
805         rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
806         rc.isp_accept_compound = compoundWordCB->isChecked();
807         rc.isp_use_input_encoding = inputEncodingCB->isChecked();
808 }
809
810
811 void PrefSpellchecker::update(LyXRC const & rc)
812 {
813         spellCommandCO->setCurrentIndex(0);
814
815         if (rc.isp_command == "ispell") {
816                 spellCommandCO->setCurrentIndex(0);
817         } else if (rc.isp_command == "aspell") {
818                 spellCommandCO->setCurrentIndex(1);
819         } else if (rc.isp_command == "hspell") {
820                 spellCommandCO->setCurrentIndex(2);
821         }
822
823         if (rc.use_spell_lib) {
824 #if defined(USE_ASPELL) || defined(USE_PSPELL)
825                 spellCommandCO->setCurrentIndex(3);
826 #endif
827         }
828
829         // FIXME: remove isp_use_alt_lang
830         altLanguageED->setText(toqstr(rc.isp_alt_lang));
831         // FIXME: remove isp_use_esc_chars
832         escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
833         // FIXME: remove isp_use_pers_dict
834         persDictionaryED->setText(external_path(rc.isp_pers_dict));
835         compoundWordCB->setChecked(rc.isp_accept_compound);
836         inputEncodingCB->setChecked(rc.isp_use_input_encoding);
837 }
838
839
840 void PrefSpellchecker::select_dict()
841 {
842         string file(form_->controller().browsedict(fromqstr(persDictionaryED->text())));
843         if (!file.empty())
844                 persDictionaryED->setText(toqstr(file));
845 }
846
847
848 PrefConverters::PrefConverters(QPrefs * form, QWidget * parent)
849 : PrefModule(string(), _("Converters"), form, parent)
850 {
851         setupUi(this);
852
853         connect(converterNewPB, SIGNAL(clicked()),
854                 this, SLOT(new_converter()));
855         connect(converterRemovePB, SIGNAL(clicked()),
856                 this, SLOT(remove_converter()));
857         connect(converterModifyPB, SIGNAL(clicked()),
858                 this, SLOT(modify_converter()));
859         connect(convertersLW, SIGNAL(currentRowChanged(int)),
860                 this, SLOT(switch_converter(int)));
861         connect(converterFromCO, SIGNAL(activated(const QString&)),
862                 this, SLOT(converter_changed()));
863         connect(converterToCO, SIGNAL(activated(const QString&)),
864                 this, SLOT(converter_changed()));
865         connect(converterED, SIGNAL(textChanged(const QString&)),
866                 this, SLOT(converter_changed()));
867         connect(converterFlagED, SIGNAL(textChanged(const QString&)),
868                 this, SLOT(converter_changed()));
869         connect(converterNewPB, SIGNAL(clicked()),
870                 this, SIGNAL(changed()));
871         connect(converterRemovePB, SIGNAL(clicked()),
872                 this, SIGNAL(changed()));
873         connect(converterModifyPB, SIGNAL(clicked()),
874                 this, SIGNAL(changed()));
875 }
876
877
878 void PrefConverters::apply(LyXRC & /*rc*/) const
879 {
880 }
881
882
883 void PrefConverters::update(LyXRC const & /*rc*/)
884 {
885         updateGui();
886 }
887
888
889 void PrefConverters::updateGui()
890 {
891         // save current selection
892         QString current = converterFromCO->currentText()
893                 + " -> " + converterToCO->currentText();
894
895         converterFromCO->clear();
896         converterToCO->clear();
897
898         Formats::const_iterator cit = form_->formats().begin();
899         Formats::const_iterator end = form_->formats().end();
900         for (; cit != end; ++cit) {
901                 converterFromCO->insertItem(toqstr(cit->prettyname()));
902                 converterToCO->insertItem(toqstr(cit->prettyname()));
903         }
904
905         convertersLW->clear();
906
907         Converters::const_iterator ccit = form_->converters().begin();
908         Converters::const_iterator cend = form_->converters().end();
909         for (; ccit != cend; ++ccit) {
910                 std::string const name = ccit->From->prettyname() + " -> "
911                                                                 + ccit->To->prettyname();
912                 new QListWidgetItem(toqstr(name), convertersLW,
913                                                         form_->converters().getNumber(ccit->From->name(), ccit->To->name()));
914         }
915         convertersLW->sortItems(Qt::AscendingOrder);
916
917         // restore selection
918         if (!current.isEmpty()) {
919                 QList<QListWidgetItem *> const item =
920                         convertersLW->findItems(current, Qt::MatchExactly);
921                 if (item.size()>0)
922                         convertersLW->setCurrentItem(item.at(0));
923         }
924         // select first element if restoring failed
925         if (convertersLW->currentRow() == -1)
926                 convertersLW->setCurrentRow(0);
927
928         updateButtons();
929 }
930
931
932 void PrefConverters::switch_converter(int nr)
933 {
934         if (nr<0)
935                 return;
936
937         int const cnr = convertersLW->currentItem()->type();
938         Converter const & c(form_->converters().get(cnr));
939         converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
940         converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
941         converterED->setText(toqstr(c.command));
942         converterFlagED->setText(toqstr(c.flags));
943
944         updateButtons();
945 }
946
947
948 void PrefConverters::converter_changed()
949 {
950         updateButtons();
951 }
952
953
954 void PrefConverters::updateButtons()
955 {
956         Format const & from(form_->formats().get(
957                 converterFromCO->currentItem()));
958         Format const & to(form_->formats().get(
959                 converterToCO->currentItem()));
960         int const sel = form_->converters().getNumber(from.name(), to.name());
961         bool const known = !(sel < 0);
962         bool const valid = !(converterED->text().isEmpty()
963                 || from.name() == to.name());
964
965         int const cnr = convertersLW->currentItem()->type();
966         Converter const & c(form_->converters().get(cnr));
967         string const old_command = c.command;
968         string const old_flag = c.flags;
969         string const new_command(fromqstr(converterED->text()));
970         string const new_flag(fromqstr(converterFlagED->text()));
971
972         bool modified = ((old_command != new_command) || (old_flag != new_flag));
973
974         converterModifyPB->setEnabled(valid && known && modified);
975         converterNewPB->setEnabled(valid && !known);
976         converterRemovePB->setEnabled(known);
977 }
978
979
980 // FIXME: user must
981 // specify unique from/to or it doesn't appear. This is really bad UI
982 void PrefConverters::new_converter()
983 {
984         Format const & from(form_->formats().get(converterFromCO->currentItem()));
985         Format const & to(form_->formats().get(converterToCO->currentItem()));
986         string const command(fromqstr(converterED->text()));
987         string const flags(fromqstr(converterFlagED->text()));
988
989         Converter const * old = form_->converters().getConverter(from.name(), to.name());
990         form_->converters().add(from.name(), to.name(), command, flags);
991         if (!old) {
992                 form_->converters().updateLast(form_->formats());
993         }
994         updateGui();
995
996         QString const name = toqstr(from.name() + " -> " + to.name());
997         QList<QListWidgetItem *> const item =
998                 convertersLW->findItems(name, Qt::MatchExactly);
999         if (item.size()>0)
1000                 convertersLW->setCurrentItem(item.at(0));
1001 }
1002
1003
1004 void PrefConverters::modify_converter()
1005 {
1006         QString const current_text =
1007                 convertersLW->currentItem()->text();
1008
1009         Format const & from(form_->formats().get(converterFromCO->currentItem()));
1010         Format const & to(form_->formats().get(converterToCO->currentItem()));
1011         string flags(fromqstr(converterFlagED->text()));
1012         string name(fromqstr(converterED->text()));
1013
1014         Converter const * old = form_->converters().getConverter(from.name(), to.name());
1015         form_->converters().add(from.name(), to.name(), name, flags);
1016         if (!old) {
1017                 form_->converters().updateLast(form_->formats());
1018         }
1019         updateGui();
1020
1021         QList<QListWidgetItem *> const item =
1022                 convertersLW->findItems(current_text, Qt::MatchExactly);
1023         if (item.size()>0)
1024                 convertersLW->setCurrentItem(item.at(0));
1025 }
1026
1027
1028 void PrefConverters::remove_converter()
1029 {
1030         Format const & from(form_->formats().get(converterFromCO->currentItem()));
1031         Format const & to(form_->formats().get(converterToCO->currentItem()));
1032         form_->converters().erase(from.name(), to.name());
1033         updateGui();
1034 }
1035
1036
1037 PrefCopiers::PrefCopiers(QPrefs * form, QWidget * parent)
1038 : PrefModule(string(), _("Copiers"), form, parent)
1039 {
1040         setupUi(this);
1041
1042         connect(copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier()));
1043         connect(copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier()));
1044         connect(copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier()));
1045         connect(AllCopiersLW, SIGNAL(currentRowChanged(int)),
1046                 this, SLOT(switch_copierLB(int)));
1047         connect(copierFormatCO, SIGNAL(activated(int)), this, SLOT(switch_copierCO(int)));
1048         connect(copierNewPB, SIGNAL(clicked()),
1049                 this, SIGNAL(changed()));
1050         connect(copierRemovePB, SIGNAL(clicked()),
1051                 this, SIGNAL(changed()));
1052         connect(copierModifyPB, SIGNAL(clicked()),
1053                 this, SIGNAL(changed()));
1054         connect(copierFormatCO, SIGNAL(activated(const QString&)), this, SLOT(copiers_changed()));
1055         connect(copierED, SIGNAL(textChanged(const QString&)), this, SLOT(copiers_changed()));
1056 }
1057
1058
1059 void PrefCopiers::apply(LyXRC & /*rc*/) const
1060 {
1061 }
1062
1063
1064 void PrefCopiers::update(LyXRC const & /*rc*/)
1065 {
1066         update();
1067 }
1068
1069
1070 void PrefCopiers::update()
1071 {
1072         // The choice widget
1073         // save current selection
1074         QString current = copierFormatCO->currentText();
1075         copierFormatCO->clear();
1076
1077         for (Formats::const_iterator it = form_->formats().begin(),
1078                      end = form_->formats().end();
1079              it != end; ++it) {
1080                 copierFormatCO->insertItem(toqstr(it->prettyname()));
1081         }
1082
1083         // The browser widget
1084         AllCopiersLW->clear();
1085
1086         for (Movers::iterator it = form_->movers().begin(),
1087                      end = form_->movers().end();
1088              it != end; ++it) {
1089                 std::string const & command = it->second.command();
1090                 if (command.empty())
1091                         continue;
1092                 QString const pretty = toqstr(form_->formats().prettyName(it->first));
1093                 AllCopiersLW->addItem(pretty);
1094         }
1095         AllCopiersLW->sortItems(Qt::AscendingOrder);
1096
1097         // restore selection
1098         if (!current.isEmpty()) {
1099                 QList<QListWidgetItem *> item =
1100                         AllCopiersLW->findItems(current, Qt::MatchExactly);
1101                 if (item.size()>0)
1102                         AllCopiersLW->setCurrentItem(item.at(0));
1103         }
1104         // select first element if restoring failed
1105         if (AllCopiersLW->currentRow() == -1)
1106                 AllCopiersLW->setCurrentRow(0);
1107 }
1108
1109
1110 namespace {
1111
1112 class SamePrettyName {
1113 public:
1114         SamePrettyName(string const & n) : pretty_name_(n) {}
1115
1116         bool operator()(::Format const & fmt) const {
1117                 return fmt.prettyname() == pretty_name_;
1118         }
1119
1120 private:
1121         string const pretty_name_;
1122 };
1123
1124
1125 Format const * getFormat(std::string const & prettyname)
1126 {
1127         Formats::const_iterator it = ::formats.begin();
1128         Formats::const_iterator const end = ::formats.end();
1129         it = std::find_if(it, end, SamePrettyName(prettyname));
1130         return it == end ? 0 : &*it;
1131 }
1132
1133 } // namespace anon
1134
1135
1136 void PrefCopiers::switch_copierLB(int row)
1137 {
1138         if (row<0)
1139                 return;
1140
1141         std::string const browser_text =
1142                 fromqstr(AllCopiersLW->currentItem()->text());
1143         Format const * fmt = getFormat(browser_text);
1144         if (fmt == 0)
1145                 return;
1146
1147         QString const gui_name = toqstr(fmt->prettyname());
1148         QString const command = toqstr(form_->movers().command(fmt->name()));
1149
1150         copierED->clear();
1151         int const combo_size = copierFormatCO->count();
1152         for (int i = 0; i < combo_size; ++i) {
1153                 QString const text = copierFormatCO->text(i);
1154                 if (text == gui_name) {
1155                         copierFormatCO->setCurrentIndex(i);
1156                         copierED->setText(command);
1157                         break;
1158                 }
1159         }
1160         updateButtons();
1161 }
1162
1163
1164 void PrefCopiers::switch_copierCO(int row)
1165 {
1166         if (row<0)
1167                 return;
1168
1169         std::string const combo_text =
1170                 fromqstr(copierFormatCO->currentText());
1171         Format const * fmt = getFormat(combo_text);
1172         if (fmt == 0)
1173                 return;
1174
1175         QString const command = toqstr(form_->movers().command(fmt->name()));
1176         copierED->setText(command);
1177
1178         QListWidgetItem * const index = AllCopiersLW->currentItem();
1179         if (index >= 0)
1180                 AllCopiersLW->setItemSelected(index, false);
1181
1182         QString const gui_name = toqstr(fmt->prettyname());
1183         int const browser_size = AllCopiersLW->count();
1184         for (int i = 0; i < browser_size; ++i) {
1185                 QString const text = AllCopiersLW->item(i)->text();
1186                 if (text == gui_name) {
1187                         QListWidgetItem * item = AllCopiersLW->item(i);
1188                         AllCopiersLW->setItemSelected(item, true);
1189                         break;
1190                 }
1191         }
1192 }
1193
1194
1195 void PrefCopiers::copiers_changed()
1196 {
1197         updateButtons();
1198 }
1199
1200
1201 void PrefCopiers::updateButtons()
1202 {
1203         QString selected = copierFormatCO->currentText();
1204
1205         bool known = false;
1206         for (int i = 0; i < AllCopiersLW->count(); ++i) {
1207                 if (AllCopiersLW->item(i)->text() == selected)
1208                         known = true;
1209         }
1210
1211         bool const valid = !copierED->text().isEmpty();
1212
1213         Format const * fmt = getFormat(fromqstr(selected));
1214         string const old_command = form_->movers().command(fmt->name());
1215         string const new_command(fromqstr(copierED->text()));
1216
1217         bool modified = (old_command != new_command);
1218
1219         copierModifyPB->setEnabled(valid && known && modified);
1220         copierNewPB->setEnabled(valid && !known);
1221         copierRemovePB->setEnabled(known);
1222 }
1223
1224
1225 void PrefCopiers::new_copier()
1226 {
1227         std::string const combo_text =
1228                 fromqstr(copierFormatCO->currentText());
1229         Format const * fmt = getFormat(combo_text);
1230         if (fmt == 0)
1231                 return;
1232
1233         string const command = fromqstr(copierED->text());
1234         if (command.empty())
1235                 return;
1236
1237         form_->movers().set(fmt->name(), command);
1238
1239         update();
1240         int const last = AllCopiersLW->count() - 1;
1241         AllCopiersLW->setCurrentRow(last);
1242
1243         updateButtons();
1244 }
1245
1246
1247 void PrefCopiers::modify_copier()
1248 {
1249         std::string const combo_text =
1250                 fromqstr(copierFormatCO->currentText());
1251         Format const * fmt = getFormat(combo_text);
1252         if (fmt == 0)
1253                 return;
1254
1255         string const command = fromqstr(copierED->text());
1256         form_->movers().set(fmt->name(), command);
1257
1258         update();
1259         updateButtons();
1260 }
1261
1262
1263 void PrefCopiers::remove_copier()
1264 {
1265         std::string const combo_text =
1266                 fromqstr(copierFormatCO->currentText());
1267         Format const * fmt = getFormat(combo_text);
1268         if (fmt == 0)
1269                 return;
1270
1271         string const & fmt_name = fmt->name();
1272         form_->movers().set(fmt_name, string());
1273
1274         update();
1275         updateButtons();
1276 }
1277
1278
1279
1280 PrefFileformats::PrefFileformats(QPrefs * form, QWidget * parent)
1281 : PrefModule(string(), _("File formats"), form, parent)
1282 {
1283         setupUi(this);
1284
1285         connect(formatNewPB, SIGNAL(clicked()), this, SLOT(new_format()));
1286         connect(formatRemovePB, SIGNAL(clicked()), this, SLOT(remove_format()));
1287         connect(formatModifyPB, SIGNAL(clicked()), this, SLOT(modify_format()));
1288         connect(formatsLW, SIGNAL(currentRowChanged(int)),
1289                 this, SLOT(switch_format(int)));
1290         connect(formatED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1291         connect(guiNameED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1292         connect(shortcutED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1293         connect(extensionED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1294         connect(viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1295         connect(editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1296         connect(documentCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed()));
1297         connect(formatNewPB, SIGNAL(clicked()),
1298                 this, SIGNAL(changed()));
1299         connect(formatRemovePB, SIGNAL(clicked()),
1300                 this, SIGNAL(changed()));
1301         connect(formatModifyPB, SIGNAL(clicked()),
1302                 this, SIGNAL(changed()));
1303 }
1304
1305
1306 void PrefFileformats::apply(LyXRC & /*rc*/) const
1307 {
1308 }
1309
1310
1311 void PrefFileformats::update(LyXRC const & /*rc*/)
1312 {
1313         update();
1314 }
1315
1316
1317 void PrefFileformats::update()
1318 {
1319         // save current selection
1320         QString current = guiNameED->text();
1321
1322         formatsLW->clear();
1323
1324         Formats::const_iterator cit = form_->formats().begin();
1325         Formats::const_iterator end = form_->formats().end();
1326         for (; cit != end; ++cit) {
1327                 new QListWidgetItem(toqstr(cit->prettyname()),
1328                                                         formatsLW,
1329                                                         form_->formats().getNumber(cit->name()) );
1330         }
1331         formatsLW->sortItems(Qt::AscendingOrder);
1332
1333         // restore selection
1334         if (!current.isEmpty()) {
1335                 QList<QListWidgetItem *>  item = formatsLW->findItems(current, Qt::MatchExactly);
1336                 if (item.size()>0)
1337                         formatsLW->setCurrentItem(item.at(0));
1338         }
1339         // select first element if restoring failed
1340         if (formatsLW->currentRow() == -1)
1341                 formatsLW->setCurrentRow(0);
1342 }
1343
1344
1345 void PrefFileformats::switch_format(int nr)
1346 {
1347         if (nr<0)
1348                 return;
1349
1350         int const ftype = formatsLW->item(nr)->type();
1351         Format const f(form_->formats().get(ftype));
1352
1353         formatED->setText(toqstr(f.name()));
1354         guiNameED->setText(toqstr(f.prettyname()));
1355         extensionED->setText(toqstr(f.extension()));
1356         shortcutED->setText(toqstr(f.shortcut()));
1357         viewerED->setText(toqstr(f.viewer()));
1358         editorED->setText(toqstr(f.editor()));
1359         documentCB->setChecked((f.documentFormat()));
1360         formatRemovePB->setEnabled(
1361                 !form_->converters().formatIsUsed(f.name()));
1362
1363         updateButtons();
1364 }
1365
1366
1367 void PrefFileformats::fileformat_changed()
1368 {
1369         updateButtons();
1370 }
1371
1372
1373 void PrefFileformats::updateButtons()
1374 {
1375         QString const format = formatED->text();
1376         QString const gui_name = guiNameED->text();
1377         int const sel = form_->formats().getNumber(fromqstr(format));
1378         bool gui_name_known = false;
1379         int where = sel;
1380         for (int i = 0; i < formatsLW->count(); ++i) {
1381                 if (formatsLW->item(i)->text() == gui_name) {
1382                         gui_name_known = true;
1383                         where = formatsLW->item(i)->type();
1384                 }
1385         }
1386
1387         // assure that a gui name cannot be chosen twice
1388         bool const known_otherwise = gui_name_known && (where != sel);
1389
1390         bool const known = !(sel < 0);
1391         bool const valid = (!formatED->text().isEmpty()
1392                 && !guiNameED->text().isEmpty());
1393
1394         int const ftype = formatsLW->currentItem()->type();
1395         Format const & f(form_->formats().get(ftype));
1396         string const old_pretty(f.prettyname());
1397         string const old_shortcut(f.shortcut());
1398         string const old_extension(f.extension());
1399         string const old_viewer(f.viewer());
1400         string const old_editor(f.editor());
1401         bool const old_document(f.documentFormat());
1402
1403         string const new_pretty(fromqstr(gui_name));
1404         string const new_shortcut(fromqstr(shortcutED->text()));
1405         string const new_extension(fromqstr(extensionED->text()));
1406         string const new_viewer(fromqstr(viewerED->text()));
1407         string const new_editor(fromqstr(editorED->text()));
1408         bool const new_document(documentCB->isChecked());
1409
1410         bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut)
1411                 || (old_extension != new_extension) || (old_viewer != new_viewer)
1412                 || (old_editor != new_editor) || old_document != new_document);
1413
1414         formatModifyPB->setEnabled(
1415                 valid && known && modified && !known_otherwise);
1416         formatNewPB->setEnabled(valid && !known && !gui_name_known);
1417         formatRemovePB->setEnabled(known);
1418 }
1419
1420 void PrefFileformats::setConverters(PrefConverters * converters)
1421 {
1422         converters_ = converters;
1423 }
1424
1425 void PrefFileformats::new_format()
1426 {
1427         string const name = fromqstr(formatED->text());
1428         string const prettyname = fromqstr(guiNameED->text());
1429         string const extension = fromqstr(extensionED->text());
1430         string const shortcut = fromqstr(shortcutED->text());
1431         string const viewer = fromqstr(viewerED->text());
1432         string const editor = fromqstr(editorED->text());
1433         bool const document = documentCB->isChecked();
1434
1435         form_->formats().add(name, extension, prettyname, shortcut, viewer,
1436                              editor, document);
1437         form_->formats().sort();
1438         update();
1439
1440         QList<QListWidgetItem *>  const item =
1441                 formatsLW->findItems(toqstr(prettyname), Qt::MatchExactly);
1442         if (item.size()>0)
1443                 formatsLW->setCurrentItem(item.at(0));
1444
1445         form_->converters().update(form_->formats());
1446
1447         converters_->updateGui();
1448         updateButtons();
1449 }
1450
1451
1452 void PrefFileformats::modify_format()
1453 {
1454         int const current_item = formatsLW->currentItem()->type();
1455         QString const current_text =
1456                 formatsLW->currentItem()->text();
1457
1458         Format const & oldformat(form_->formats().get(current_item));
1459         string const oldpretty(oldformat.prettyname());
1460         string const name(fromqstr(formatED->text()));
1461         form_->formats().erase(oldformat.name());
1462
1463         string const prettyname = fromqstr(guiNameED->text());
1464         string const extension = fromqstr(extensionED->text());
1465         string const shortcut = fromqstr(shortcutED->text());
1466         string const viewer = fromqstr(viewerED->text());
1467         string const editor = fromqstr(editorED->text());
1468         bool const document = documentCB->isChecked();
1469
1470         form_->formats().add(name, extension, prettyname, shortcut, viewer,
1471                              editor, document);
1472         form_->formats().sort();
1473
1474         formatsLW->setUpdatesEnabled(false);
1475         update();
1476         formatsLW->setUpdatesEnabled(true);
1477         formatsLW->update();
1478
1479         converters_->updateGui();
1480         updateButtons();
1481
1482         QList<QListWidgetItem *>  const item =
1483                 formatsLW->findItems(current_text, Qt::MatchExactly);
1484         if (item.size()>0)
1485                 formatsLW->setCurrentItem(item.at(0));
1486 }
1487
1488
1489 void PrefFileformats::remove_format()
1490 {
1491         int const nr = formatsLW->currentItem()->type();
1492         if (nr < 0)
1493                 return;
1494         string const current_text = form_->formats().get(nr).name();
1495         if (form_->converters().formatIsUsed(current_text)) {
1496                 Alert::error(_("Format in use"),
1497                                 _("Cannot remove a Format used by a Converter. "
1498                                       "Remove the converter first."));
1499                 return;
1500         }
1501
1502         form_->formats().erase(current_text);
1503         update();
1504         form_->converters().update(form_->formats());
1505
1506         converters_->updateGui();
1507         updateButtons();
1508 }
1509
1510
1511
1512 PrefLanguage::PrefLanguage(QWidget * parent)
1513 : PrefModule(string(), _("Language"), 0, parent)
1514 {
1515         setupUi(this);
1516
1517         connect(rtlCB, SIGNAL(toggled(bool)),
1518                 this, SIGNAL(changed()));
1519         connect(markForeignCB, SIGNAL(toggled(bool)),
1520                 this, SIGNAL(changed()));
1521         connect(autoBeginCB, SIGNAL(toggled(bool)),
1522                 this, SIGNAL(changed()));
1523         connect(autoEndCB, SIGNAL(toggled(bool)),
1524                 this, SIGNAL(changed()));
1525         connect(useBabelCB, SIGNAL(toggled(bool)),
1526                 this, SIGNAL(changed()));
1527         connect(globalCB, SIGNAL(toggled(bool)),
1528                 this, SIGNAL(changed()));
1529         connect(languagePackageED, SIGNAL(textChanged(const QString&)),
1530                 this, SIGNAL(changed()));
1531         connect(startCommandED, SIGNAL(textChanged(const QString&)),
1532                 this, SIGNAL(changed()));
1533         connect(endCommandED, SIGNAL(textChanged(const QString&)),
1534                 this, SIGNAL(changed()));
1535         connect(defaultLanguageCO, SIGNAL(activated(int)),
1536                 this, SIGNAL(changed()));
1537
1538         defaultLanguageCO->clear();
1539
1540         // store the lang identifiers for later
1541         using lyx::frontend::LanguagePair;
1542         std::vector<LanguagePair> const langs =
1543                 lyx::frontend::getLanguageData(false);
1544         lang_ = getSecond(langs);
1545
1546         std::vector<LanguagePair>::const_iterator lit  = langs.begin();
1547         std::vector<LanguagePair>::const_iterator lend = langs.end();
1548         for (; lit != lend; ++lit) {
1549                 defaultLanguageCO->insertItem(toqstr(lit->first));
1550         }
1551 }
1552
1553
1554 void PrefLanguage::apply(LyXRC & rc) const
1555 {
1556         // FIXME: remove rtl_support bool
1557         rc.rtl_support = rtlCB->isChecked();
1558         rc.mark_foreign_language = markForeignCB->isChecked();
1559         rc.language_auto_begin = autoBeginCB->isChecked();
1560         rc.language_auto_end = autoEndCB->isChecked();
1561         rc.language_use_babel = useBabelCB->isChecked();
1562         rc.language_global_options = globalCB->isChecked();
1563         rc.language_package = fromqstr(languagePackageED->text());
1564         rc.language_command_begin = fromqstr(startCommandED->text());
1565         rc.language_command_end = fromqstr(endCommandED->text());
1566         rc.default_language = lang_[defaultLanguageCO->currentItem()];
1567 }
1568
1569
1570 void PrefLanguage::update(LyXRC const & rc)
1571 {
1572         // FIXME: remove rtl_support bool
1573         rtlCB->setChecked(rc.rtl_support);
1574         markForeignCB->setChecked(rc.mark_foreign_language);
1575         autoBeginCB->setChecked(rc.language_auto_begin);
1576         autoEndCB->setChecked(rc.language_auto_end);
1577         useBabelCB->setChecked(rc.language_use_babel);
1578         globalCB->setChecked(rc.language_global_options);
1579         languagePackageED->setText(toqstr(rc.language_package));
1580         startCommandED->setText(toqstr(rc.language_command_begin));
1581         endCommandED->setText(toqstr(rc.language_command_end));
1582
1583         int const pos = int(findPos(lang_, rc.default_language));
1584         defaultLanguageCO->setCurrentIndex(pos);
1585 }
1586
1587
1588 PrefPrinter::PrefPrinter(QWidget * parent)
1589 : PrefModule(_(Outputs), _("Printer"), 0, parent)
1590 {
1591         setupUi(this);
1592
1593         connect(printerAdaptCB, SIGNAL(toggled(bool)),
1594                 this, SIGNAL(changed()));
1595         connect(printerCommandED, SIGNAL(textChanged(const QString&)),
1596                 this, SIGNAL(changed()));
1597         connect(printerNameED, SIGNAL(textChanged(const QString&)),
1598                 this, SIGNAL(changed()));
1599         connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
1600                 this, SIGNAL(changed()));
1601         connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
1602                 this, SIGNAL(changed()));
1603         connect(printerReverseED, SIGNAL(textChanged(const QString&)),
1604                 this, SIGNAL(changed()));
1605         connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
1606                 this, SIGNAL(changed()));
1607         connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
1608                 this, SIGNAL(changed()));
1609         connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
1610                 this, SIGNAL(changed()));
1611         connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
1612                 this, SIGNAL(changed()));
1613         connect(printerEvenED, SIGNAL(textChanged(const QString&)),
1614                 this, SIGNAL(changed()));
1615         connect(printerOddED, SIGNAL(textChanged(const QString&)),
1616                 this, SIGNAL(changed()));
1617         connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
1618                 this, SIGNAL(changed()));
1619         connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
1620                 this, SIGNAL(changed()));
1621         connect(printerToFileED, SIGNAL(textChanged(const QString&)),
1622                 this, SIGNAL(changed()));
1623         connect(printerExtraED, SIGNAL(textChanged(const QString&)),
1624                 this, SIGNAL(changed()));
1625         connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
1626                 this, SIGNAL(changed()));
1627         connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
1628                 this, SIGNAL(changed()));
1629 }
1630
1631
1632 void PrefPrinter::apply(LyXRC & rc) const
1633 {
1634         rc.print_adapt_output = printerAdaptCB->isChecked();
1635         rc.print_command = fromqstr(printerCommandED->text());
1636         rc.printer = fromqstr(printerNameED->text());
1637
1638         rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
1639         rc.print_copies_flag = fromqstr(printerCopiesED->text());
1640         rc.print_reverse_flag = fromqstr(printerReverseED->text());
1641         rc.print_to_printer = fromqstr(printerToPrinterED->text());
1642         rc.print_file_extension = fromqstr(printerExtensionED->text());
1643         rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
1644         rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
1645         rc.print_evenpage_flag = fromqstr(printerEvenED->text());
1646         rc.print_oddpage_flag = fromqstr(printerOddED->text());
1647         rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
1648         rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
1649         rc.print_to_file = internal_path(printerToFileED->text());
1650         rc.print_extra_options = fromqstr(printerExtraED->text());
1651         rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
1652         rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
1653 }
1654
1655
1656 void PrefPrinter::update(LyXRC const & rc)
1657 {
1658         printerAdaptCB->setChecked(rc.print_adapt_output);
1659         printerCommandED->setText(toqstr(rc.print_command));
1660         printerNameED->setText(toqstr(rc.printer));
1661
1662         printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
1663         printerCopiesED->setText(toqstr(rc.print_copies_flag));
1664         printerReverseED->setText(toqstr(rc.print_reverse_flag));
1665         printerToPrinterED->setText(toqstr(rc.print_to_printer));
1666         printerExtensionED->setText(toqstr(rc.print_file_extension));
1667         printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
1668         printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
1669         printerEvenED->setText(toqstr(rc.print_evenpage_flag));
1670         printerOddED->setText(toqstr(rc.print_oddpage_flag));
1671         printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
1672         printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
1673         printerToFileED->setText(external_path(rc.print_to_file));
1674         printerExtraED->setText(toqstr(rc.print_extra_options));
1675         printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
1676         printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
1677 }
1678
1679
1680 PrefUserInterface::PrefUserInterface(QPrefs * form, QWidget * parent)
1681 : PrefModule(_(LookAndFeel), _("User interface"), form, parent)
1682 {
1683         setupUi(this);
1684
1685         connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveLA, SLOT( setEnabled(bool) ) );
1686         connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveSB, SLOT( setEnabled(bool) ) );
1687         connect(autoSaveCB, SIGNAL( toggled(bool) ), TextLabel1, SLOT( setEnabled(bool) ) );
1688         connect(uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui()));
1689         connect(bindFilePB, SIGNAL(clicked()), this, SLOT(select_bind()));
1690         connect(uiFileED, SIGNAL(textChanged(const QString&)),
1691                 this, SIGNAL(changed()));
1692         connect(bindFileED, SIGNAL(textChanged(const QString&)),
1693                 this, SIGNAL(changed()));
1694         connect(restoreCursorCB, SIGNAL(toggled(bool)),
1695                 this, SIGNAL(changed()));
1696         connect(loadSessionCB, SIGNAL(toggled(bool)),
1697                 this, SIGNAL(changed()));
1698         connect(cursorFollowsCB, SIGNAL(toggled(bool)),
1699                 this, SIGNAL(changed()));
1700         connect(autoSaveSB, SIGNAL(valueChanged(int)),
1701                 this, SIGNAL(changed()));
1702         connect(autoSaveCB, SIGNAL(toggled(bool)),
1703                 this, SIGNAL(changed()));
1704         connect(lastfilesSB, SIGNAL(valueChanged(int)),
1705                 this, SIGNAL(changed()));
1706         lastfilesSB->setMaxValue(maxlastfiles);
1707 }
1708
1709
1710 void PrefUserInterface::apply(LyXRC & rc) const
1711 {
1712         rc.ui_file = internal_path(uiFileED->text());
1713         rc.bind_file = internal_path(bindFileED->text());
1714         rc.use_lastfilepos = restoreCursorCB->isChecked();
1715         rc.load_session = loadSessionCB->isChecked();
1716         rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
1717         rc.autosave = autoSaveSB->value() * 60;
1718         rc.make_backup = autoSaveCB->isChecked();
1719         rc.num_lastfiles = lastfilesSB->value();
1720 }
1721
1722
1723 void PrefUserInterface::update(LyXRC const & rc)
1724 {
1725         uiFileED->setText(external_path(rc.ui_file));
1726         bindFileED->setText(external_path(rc.bind_file));
1727         restoreCursorCB->setChecked(rc.use_lastfilepos);
1728         loadSessionCB->setChecked(rc.load_session);
1729         cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
1730         // convert to minutes
1731         int mins(rc.autosave / 60);
1732         if (rc.autosave && !mins)
1733                 mins = 1;
1734         autoSaveSB->setValue(mins);
1735         autoSaveCB->setChecked(rc.make_backup);
1736         lastfilesSB->setValue(rc.num_lastfiles);
1737 }
1738
1739
1740
1741 void PrefUserInterface::select_ui()
1742 {
1743         string file(form_->controller().browseUI(fromqstr(uiFileED->text())));
1744         if (!file.empty())
1745                 uiFileED->setText(toqstr(file));
1746 }
1747
1748
1749 void PrefUserInterface::select_bind()
1750 {
1751         string file(form_->controller().browsebind(fromqstr(bindFileED->text())));
1752         if (!file.empty())
1753                 bindFileED->setText(toqstr(file));
1754 }
1755
1756
1757 PrefIdentity::PrefIdentity(QWidget * parent)
1758 : PrefModule(string(), _("Identity"), 0, parent)
1759 {
1760         setupUi(this);
1761
1762         connect(nameED, SIGNAL(textChanged(const QString&)),
1763                 this, SIGNAL(changed()));
1764         connect(emailED, SIGNAL(textChanged(const QString&)),
1765                 this, SIGNAL(changed()));
1766 }
1767
1768
1769 void PrefIdentity::apply(LyXRC & rc) const
1770 {
1771         rc.user_name = fromqstr(nameED->text());
1772         rc.user_email = fromqstr(emailED->text());
1773 }
1774
1775
1776 void PrefIdentity::update(LyXRC const & rc)
1777 {
1778         nameED->setText(toqstr(rc.user_name));
1779         emailED->setText(toqstr(rc.user_email));
1780 }
1781
1782
1783
1784 QPrefsDialog::QPrefsDialog(QPrefs * form)
1785         : form_(form)
1786 {
1787         setupUi(this);
1788         QDialog::setModal(true);
1789
1790         connect(savePB, SIGNAL(clicked()),
1791                 form, SLOT(slotOK()));
1792         connect(applyPB, SIGNAL(clicked()),
1793                 form, SLOT(slotApply()));
1794         connect(closePB, SIGNAL(clicked()),
1795                 form, SLOT(slotClose()));
1796         connect(restorePB, SIGNAL(clicked()),
1797                 form, SLOT(slotRestore()));
1798
1799         add(new PrefAscii);
1800         add(new PrefDate);
1801         add(new PrefKeyboard(form_));
1802         add(new PrefLatex(form_));
1803         add(new PrefScreenFonts(form_));
1804         add(new PrefColors(form_));
1805
1806 #if defined(__CYGWIN__) || defined(_WIN32)
1807         add(new PrefCygwinPath);
1808 #endif
1809
1810         add(new PrefDisplay);
1811         add(new PrefPaths(form_));
1812         add(new PrefSpellchecker(form_));
1813
1814         PrefConverters * converters = new PrefConverters(form_);
1815         PrefFileformats * formats = new PrefFileformats(form_);
1816         formats->setConverters(converters);
1817         add(converters);
1818         add(formats);
1819
1820         add(new PrefCopiers(form_));
1821
1822         add(new PrefLanguage);
1823         add(new PrefPrinter);
1824         add(new PrefUserInterface(form_));
1825         add(new PrefIdentity);
1826
1827         prefsPS->setCurrentPanel(_("User interface"));
1828
1829         form_->bcview().setOK(savePB);
1830         form_->bcview().setApply(applyPB);
1831         form_->bcview().setCancel(closePB);
1832         form_->bcview().setRestore(restorePB);
1833 }
1834
1835
1836 QPrefsDialog::~QPrefsDialog()
1837 {
1838 }
1839
1840
1841 void QPrefsDialog::add(PrefModule * module)
1842 {
1843         BOOST_ASSERT(module);
1844
1845 //      if (module->category().empty())
1846 //              prefsPS->addPanel(module, module->title());
1847 //      else
1848                 prefsPS->addPanel(module, module->title(), module->category());
1849
1850         connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
1851
1852         modules_.push_back(module);
1853 }
1854
1855 void QPrefsDialog::closeEvent(QCloseEvent * e)
1856 {
1857         form_->slotWMHide();
1858         e->accept();
1859 }
1860
1861
1862 void QPrefsDialog::change_adaptor()
1863 {
1864         form_->changed();
1865 }
1866
1867
1868 void QPrefsDialog::apply(LyXRC & rc) const
1869 {
1870         size_t end = modules_.size();
1871         for (size_t i = 0; i != end; ++i)
1872                 modules_[i]->apply(rc);
1873 }
1874
1875
1876 void QPrefsDialog::update(LyXRC const & rc)
1877 {
1878         size_t end = modules_.size();
1879         for (size_t i = 0; i != end; ++i)
1880                 modules_[i]->update(rc);
1881 }
1882
1883
1884 } // namespace frontend
1885 } // namespace lyx
1886
1887 #include "QPrefsDialog_moc.cpp"