]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QPrefsDialog.C
* src/format.[Ch]
[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 "lcolorcache.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 "lcolorcache.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_firstKeymapED_clicked()
287 {
288         QString file = testKeymap(firstKeymapED->text());
289         if (!file.isEmpty())
290                 firstKeymapED->setText(file);
291 }
292
293
294 void PrefKeyboard::on_secondKeymapED_clicked()
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                 QListWidgetItem * newItem = new QListWidgetItem(QIcon(coloritem),
527                         toqstr(lcolor.getGUIName(lc)), lyxObjectsLW);
528         }
529         newcolors_ = prefcolors_;
530
531         connect(colorChangePB, SIGNAL(clicked()), 
532                 this, SLOT(change_color()));
533         connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)), 
534                 this, SLOT(change_color()));
535 }
536
537
538 void PrefColors::apply(LyXRC & rc) const
539 {
540         for (int i = 0; i < lcolors_.size(); ++i) {
541                 if (prefcolors_[i]!=newcolors_[i])
542                         form_->controller().setColor(lcolors_[i], fromqstr(newcolors_[i]));
543         }
544 }
545
546
547 void PrefColors::update(LyXRC const & rc)
548 {
549 }
550
551 void PrefColors::change_color()
552 {
553         int const row = lyxObjectsLW->currentRow();
554         QString color = newcolors_[row];
555         QColor c(QColorDialog::getColor(QColor(color), 
556                 qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget()));
557
558         if (c.name()!=color) {
559                 newcolors_[row] = c.name();
560                 QPixmap coloritem(32, 32);
561                 coloritem.fill(c);
562                 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
563                 emit changed();
564         }
565 }
566
567
568 PrefCygwinPath::PrefCygwinPath(QWidget * parent)
569 : PrefModule(_(Outputs), _("Paths"), 0, parent)
570 {
571         setupUi(this);
572         connect(pathCB, SIGNAL(toggled(bool)),
573                 this, SIGNAL(changed()));
574 }
575
576
577 void PrefCygwinPath::apply(LyXRC & rc) const
578 {
579         rc.cygwin_path_fix = pathCB->isChecked();
580 }
581
582
583 void PrefCygwinPath::update(LyXRC const & rc)
584 {
585         pathCB->setChecked(rc.cygwin_path_fix);
586 }
587
588
589 PrefDisplay::PrefDisplay(QWidget * parent)
590 : PrefModule(_(LookAndFeel), _("Graphics"), 0, parent)
591 {
592         setupUi(this);
593         connect(instantPreviewCO, SIGNAL(activated(int)),
594                 this, SIGNAL(changed()));
595         connect(displayGraphicsCO, SIGNAL(activated(int)),
596                 this, SIGNAL(changed()));
597 }
598
599
600 void PrefDisplay::apply(LyXRC & rc) const
601 {
602         switch (instantPreviewCO->currentItem()) {
603         case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
604         case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
605         case 2: rc.preview = LyXRC::PREVIEW_ON; break;
606         }
607
608         lyx::graphics::DisplayType dtype;
609         switch (displayGraphicsCO->currentItem()) {
610         case 3: dtype = lyx::graphics::NoDisplay; break;
611         case 2: dtype = lyx::graphics::ColorDisplay; break;
612         case 1: dtype = lyx::graphics::GrayscaleDisplay;        break;
613         case 0: dtype = lyx::graphics::MonochromeDisplay; break;
614         default: dtype = lyx::graphics::GrayscaleDisplay;
615         }
616         rc.display_graphics = dtype;
617
618 #ifdef WITH_WARNINGS
619 #warning FIXME!! The graphics cache no longer has a changeDisplay method.
620 #endif
621 #if 0
622         if (old_value != rc.display_graphics) {
623                 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
624                 gc.changeDisplay();
625         }
626 #endif
627 }
628
629
630 void PrefDisplay::update(LyXRC const & rc)
631 {
632         switch (rc.preview) {
633         case LyXRC::PREVIEW_OFF:
634                 instantPreviewCO->setCurrentIndex(0);
635                 break;
636         case LyXRC::PREVIEW_NO_MATH :
637                 instantPreviewCO->setCurrentIndex(1);
638                 break;
639         case LyXRC::PREVIEW_ON :
640                 instantPreviewCO->setCurrentIndex(2);
641                 break;
642         }
643
644         int item = 2;
645         switch (rc.display_graphics) {
646                 case lyx::graphics::NoDisplay:          item = 3; break;
647                 case lyx::graphics::ColorDisplay:       item = 2; break;
648                 case lyx::graphics::GrayscaleDisplay:   item = 1; break;
649                 case lyx::graphics::MonochromeDisplay:  item = 0; break;
650                 default: break;
651         }
652         displayGraphicsCO->setCurrentIndex(item);
653 }
654
655
656 PrefPaths::PrefPaths(QPrefs * form, QWidget * parent)
657 : PrefModule(string(), _("Paths"), form, parent)
658 {
659         setupUi(this);
660         connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
661         connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
662         connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
663         connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
664         connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
665         connect(workingDirED, SIGNAL(textChanged(const QString&)),
666                 this, SIGNAL(changed()));
667         connect(templateDirED, SIGNAL(textChanged(const QString&)),
668                 this, SIGNAL(changed()));
669         connect(backupDirED, SIGNAL(textChanged(const QString&)),
670                 this, SIGNAL(changed()));
671         connect(tempDirED, SIGNAL(textChanged(const QString&)),
672                 this, SIGNAL(changed()));
673         connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
674                 this, SIGNAL(changed()));
675         connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
676                 this, SIGNAL(changed()));
677 }
678
679
680 void PrefPaths::apply(LyXRC & rc) const
681 {
682         rc.document_path = internal_path(workingDirED->text());
683         rc.template_path = internal_path(templateDirED->text());
684         rc.backupdir_path = internal_path(backupDirED->text());
685         rc.tempdir_path = internal_path(tempDirED->text());
686         rc.path_prefix = fromqstr(pathPrefixED->text());
687         // FIXME: should be a checkbox only
688         rc.lyxpipes = internal_path(lyxserverDirED->text());
689 }
690
691
692 void PrefPaths::update(LyXRC const & rc)
693 {
694         workingDirED->setText(external_path(rc.document_path));
695         templateDirED->setText(external_path(rc.template_path));
696         backupDirED->setText(external_path(rc.backupdir_path));
697         tempDirED->setText(external_path(rc.tempdir_path));
698         pathPrefixED->setText(toqstr(rc.path_prefix));
699         // FIXME: should be a checkbox only
700         lyxserverDirED->setText(external_path(rc.lyxpipes));
701 }
702
703 // NB: the _() is OK here because it gets passed back and we toqstr() them
704
705 void PrefPaths::select_templatedir()
706 {
707         string file(form_->controller().browsedir(fromqstr(templateDirED->text()), _("Select a document templates directory")));
708         if (!file.empty())
709                 templateDirED->setText(toqstr(file));
710 }
711
712
713 void PrefPaths::select_tempdir()
714 {
715         string file(form_->controller().browsedir(fromqstr(tempDirED->text()), _("Select a temporary directory")));
716         if (!file.empty())
717                 tempDirED->setText(toqstr(file));
718 }
719
720
721 void PrefPaths::select_backupdir()
722 {
723         string file(form_->controller().browsedir(fromqstr(backupDirED->text()), _("Select a backups directory")));
724         if (!file.empty())
725                 backupDirED->setText(toqstr(file));
726 }
727
728
729 void PrefPaths::select_workingdir()
730 {
731         string file(form_->controller().browsedir(fromqstr(workingDirED->text()), _("Select a document directory")));
732         if (!file.empty())
733                 workingDirED->setText(toqstr(file));
734 }
735
736
737 void PrefPaths::select_lyxpipe()
738 {
739         string file(form_->controller().browse(fromqstr(lyxserverDirED->text()), _("Give a filename for the LyX server pipe")));
740         if (!file.empty())
741                 lyxserverDirED->setText(toqstr(file));
742 }
743
744
745 PrefSpellchecker::PrefSpellchecker(QPrefs * form, QWidget * parent)
746 : PrefModule(_(LanguageSettings), _("Spellchecker"), form, parent)
747 {
748         setupUi(this);
749
750         connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
751 #if defined (USE_ISPELL)
752         connect(spellCommandCO, SIGNAL(activated(int)),
753                 this, SIGNAL(changed()));
754 #else
755         spellCommandCO->setEnabled(false);
756 #endif
757         connect(altLanguageED, SIGNAL(textChanged(const QString&)),
758                 this, SIGNAL(changed()));
759         connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
760                 this, SIGNAL(changed()));
761         connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
762                 this, SIGNAL(changed()));
763         connect(compoundWordCB, SIGNAL(toggled(bool)),
764                 this, SIGNAL(changed()));
765         connect(inputEncodingCB, SIGNAL(toggled(bool)),
766                 this, SIGNAL(changed()));
767
768         spellCommandCO->insertItem(qt_("ispell"));
769         spellCommandCO->insertItem(qt_("aspell"));
770         spellCommandCO->insertItem(qt_("hspell"));
771 #ifdef USE_PSPELL
772         spellCommandCO->insertItem(qt_("pspell (library)"));
773 #else
774 #ifdef USE_ASPELL
775         spellCommandCO->insertItem(qt_("aspell (library)"));
776 #endif
777 #endif
778 }
779
780
781 void PrefSpellchecker::apply(LyXRC & rc) const
782 {
783         switch (spellCommandCO->currentItem()) {
784                 case 0:
785                 case 1:
786                 case 2:
787                         rc.use_spell_lib = false;
788                         rc.isp_command = fromqstr(spellCommandCO->currentText());
789                         break;
790                 case 3:
791                         rc.use_spell_lib = true;
792                         break;
793         }
794
795         // FIXME: remove isp_use_alt_lang
796         rc.isp_alt_lang = fromqstr(altLanguageED->text());
797         rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
798         // FIXME: remove isp_use_esc_chars
799         rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
800         rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
801         // FIXME: remove isp_use_pers_dict
802         rc.isp_pers_dict = internal_path(persDictionaryED->text());
803         rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
804         rc.isp_accept_compound = compoundWordCB->isChecked();
805         rc.isp_use_input_encoding = inputEncodingCB->isChecked();
806 }
807
808
809 void PrefSpellchecker::update(LyXRC const & rc)
810 {
811         spellCommandCO->setCurrentIndex(0);
812
813         if (rc.isp_command == "ispell") {
814                 spellCommandCO->setCurrentIndex(0);
815         } else if (rc.isp_command == "aspell") {
816                 spellCommandCO->setCurrentIndex(1);
817         } else if (rc.isp_command == "hspell") {
818                 spellCommandCO->setCurrentIndex(2);
819         }
820
821         if (rc.use_spell_lib) {
822 #if defined(USE_ASPELL) || defined(USE_PSPELL)
823                 spellCommandCO->setCurrentIndex(3);
824 #endif
825         }
826
827         // FIXME: remove isp_use_alt_lang
828         altLanguageED->setText(toqstr(rc.isp_alt_lang));
829         // FIXME: remove isp_use_esc_chars
830         escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
831         // FIXME: remove isp_use_pers_dict
832         persDictionaryED->setText(external_path(rc.isp_pers_dict));
833         compoundWordCB->setChecked(rc.isp_accept_compound);
834         inputEncodingCB->setChecked(rc.isp_use_input_encoding);
835 }
836
837
838 void PrefSpellchecker::select_dict()
839 {
840         string file(form_->controller().browsedict(fromqstr(persDictionaryED->text())));
841         if (!file.empty())
842                 persDictionaryED->setText(toqstr(file));
843 }
844
845
846 PrefConverters::PrefConverters(QPrefs * form, QWidget * parent)
847 : PrefModule(string(), _("Converters"), form, parent)
848 {
849         setupUi(this);
850
851         connect(converterNewPB, SIGNAL(clicked()), 
852                 this, SLOT(new_converter()));
853         connect(converterRemovePB, SIGNAL(clicked()), 
854                 this, SLOT(remove_converter()));
855         connect(converterModifyPB, SIGNAL(clicked()), 
856                 this, SLOT(modify_converter()));
857         connect(convertersLW, SIGNAL(currentRowChanged(int)), 
858                 this, SLOT(switch_converter(int)));
859         connect(converterFromCO, SIGNAL(activated(const QString&)), 
860                 this, SLOT(converter_changed()));
861         connect(converterToCO, SIGNAL(activated(const QString&)), 
862                 this, SLOT(converter_changed()));
863         connect(converterED, SIGNAL(textChanged(const QString&)), 
864                 this, SLOT(converter_changed()));
865         connect(converterFlagED, SIGNAL(textChanged(const QString&)), 
866                 this, SLOT(converter_changed()));
867         connect(converterNewPB, SIGNAL(clicked()), 
868                 this, SIGNAL(changed()));
869         connect(converterRemovePB, SIGNAL(clicked()), 
870                 this, SIGNAL(changed()));
871         connect(converterModifyPB, SIGNAL(clicked()), 
872                 this, SIGNAL(changed()));
873 }
874
875
876 void PrefConverters::apply(LyXRC & rc) const
877 {
878 }
879
880
881 void PrefConverters::update(LyXRC const & rc)
882 {
883         updateGui();
884 }
885
886
887 void PrefConverters::updateGui()
888 {
889         // save current selection
890         QString current = converterFromCO->currentText()
891                 + " -> " + converterToCO->currentText();
892
893         converterFromCO->clear();
894         converterToCO->clear();
895
896         Formats::const_iterator cit = form_->formats().begin();
897         Formats::const_iterator end = form_->formats().end();
898         for (; cit != end; ++cit) {
899                 converterFromCO->insertItem(toqstr(cit->prettyname()));
900                 converterToCO->insertItem(toqstr(cit->prettyname()));
901         }
902
903         convertersLW->clear();
904
905         Converters::const_iterator ccit = form_->converters().begin();
906         Converters::const_iterator cend = form_->converters().end();
907         for (; ccit != cend; ++ccit) {
908                 std::string const name = ccit->From->prettyname() + " -> "
909                                                                 + ccit->To->prettyname();
910                 new QListWidgetItem(toqstr(name), convertersLW,
911                                                         form_->converters().getNumber(ccit->From->name(), ccit->To->name()));
912         }
913         convertersLW->sortItems(Qt::AscendingOrder);
914
915         // restore selection
916         if (!current.isEmpty()) {
917                 QList<QListWidgetItem *> const item = 
918                         convertersLW->findItems(current, Qt::MatchExactly);
919                 if (item.size()>0)
920                         convertersLW->setCurrentItem(item.at(0));
921         }
922         // select first element if restoring failed
923         if (convertersLW->currentRow() == -1)
924                 convertersLW->setCurrentRow(0);
925
926         updateButtons();
927 }
928
929
930 void PrefConverters::switch_converter(int nr)
931 {
932         if (nr<0)
933                 return;
934
935         int const cnr = convertersLW->currentItem()->type();
936         Converter const & c(form_->converters().get(cnr));
937         converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
938         converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
939         converterED->setText(toqstr(c.command));
940         converterFlagED->setText(toqstr(c.flags));
941
942         updateButtons();
943 }
944
945
946 void PrefConverters::converter_changed()
947 {
948         updateButtons();
949 }
950
951
952 void PrefConverters::updateButtons()
953 {
954         Format const & from(form_->formats().get(
955                 converterFromCO->currentItem()));
956         Format const & to(form_->formats().get(
957                 converterToCO->currentItem()));
958         int const sel = form_->converters().getNumber(from.name(), to.name());
959         bool const known = !(sel < 0);
960         bool const valid = !(converterED->text().isEmpty()
961                 || from.name() == to.name());
962
963         int const cnr = convertersLW->currentItem()->type();
964         Converter const & c(form_->converters().get(cnr));
965         string const old_command = c.command;
966         string const old_flag = c.flags;
967         string const new_command(fromqstr(converterED->text()));
968         string const new_flag(fromqstr(converterFlagED->text()));
969
970         bool modified = ((old_command != new_command) || (old_flag != new_flag));
971
972         converterModifyPB->setEnabled(valid && known && modified);
973         converterNewPB->setEnabled(valid && !known);
974         converterRemovePB->setEnabled(known);
975 }
976
977
978 // FIXME: user must
979 // specify unique from/to or it doesn't appear. This is really bad UI
980 void PrefConverters::new_converter()
981 {
982         Format const & from(form_->formats().get(converterFromCO->currentItem()));
983         Format const & to(form_->formats().get(converterToCO->currentItem()));
984         string const command(fromqstr(converterED->text()));
985         string const flags(fromqstr(converterFlagED->text()));
986
987         Converter const * old = form_->converters().getConverter(from.name(), to.name());
988         form_->converters().add(from.name(), to.name(), command, flags);
989         if (!old) {
990                 form_->converters().updateLast(form_->formats());
991         }
992         updateGui();
993
994         QString const name = toqstr(from.name() + " -> " + to.name());
995         QList<QListWidgetItem *> const item =
996                 convertersLW->findItems(name, Qt::MatchExactly);
997         if (item.size()>0)
998                 convertersLW->setCurrentItem(item.at(0));
999 }
1000
1001
1002 void PrefConverters::modify_converter()
1003 {
1004         QString const current_text =
1005                 convertersLW->currentItem()->text();
1006
1007         Format const & from(form_->formats().get(converterFromCO->currentItem()));
1008         Format const & to(form_->formats().get(converterToCO->currentItem()));
1009         string flags(fromqstr(converterFlagED->text()));
1010         string name(fromqstr(converterED->text()));
1011
1012         Converter const * old = form_->converters().getConverter(from.name(), to.name());
1013         form_->converters().add(from.name(), to.name(), name, flags);
1014         if (!old) {
1015                 form_->converters().updateLast(form_->formats());
1016         }
1017         updateGui();
1018
1019         QList<QListWidgetItem *> const item =
1020                 convertersLW->findItems(current_text, Qt::MatchExactly);
1021         if (item.size()>0)
1022                 convertersLW->setCurrentItem(item.at(0));
1023 }
1024
1025
1026 void PrefConverters::remove_converter()
1027 {
1028         Format const & from(form_->formats().get(converterFromCO->currentItem()));
1029         Format const & to(form_->formats().get(converterToCO->currentItem()));
1030         form_->converters().erase(from.name(), to.name());
1031         updateGui();
1032 }
1033
1034
1035 PrefCopiers::PrefCopiers(QPrefs * form, QWidget * parent)
1036 : PrefModule(string(), _("Copiers"), form, parent)
1037 {
1038         setupUi(this);
1039
1040         connect(copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier()));
1041         connect(copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier()));
1042         connect(copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier()));
1043         connect(AllCopiersLW, SIGNAL(currentRowChanged(int)), 
1044                 this, SLOT(switch_copierLB(int)));
1045         connect(copierFormatCO, SIGNAL(activated(int)), this, SLOT(switch_copierCO(int)));
1046         connect(copierNewPB, SIGNAL(clicked()),
1047                 this, SIGNAL(changed()));
1048         connect(copierRemovePB, SIGNAL(clicked()),
1049                 this, SIGNAL(changed()));
1050         connect(copierModifyPB, SIGNAL(clicked()),
1051                 this, SIGNAL(changed()));
1052         connect(copierFormatCO, SIGNAL(activated(const QString&)), this, SLOT(copiers_changed()));
1053         connect(copierED, SIGNAL(textChanged(const QString&)), this, SLOT(copiers_changed()));
1054 }
1055
1056
1057 void PrefCopiers::apply(LyXRC & rc) const
1058 {
1059 }
1060
1061
1062 void PrefCopiers::update(LyXRC const & rc)
1063 {
1064         update();
1065 }
1066
1067
1068 void PrefCopiers::update()
1069 {
1070         // The choice widget
1071         // save current selection
1072         QString current = copierFormatCO->currentText();
1073         copierFormatCO->clear();
1074
1075         for (Formats::const_iterator it = form_->formats().begin(),
1076                      end = form_->formats().end();
1077              it != end; ++it) {
1078                 copierFormatCO->insertItem(toqstr(it->prettyname()));
1079         }
1080
1081         // The browser widget
1082         AllCopiersLW->clear();
1083
1084         for (Movers::iterator it = form_->movers().begin(),
1085                      end = form_->movers().end();
1086              it != end; ++it) {
1087                 std::string const & command = it->second.command();
1088                 if (command.empty())
1089                         continue;
1090                 QString const pretty = toqstr(form_->formats().prettyName(it->first));
1091                 AllCopiersLW->addItem(pretty);
1092         }
1093         AllCopiersLW->sortItems(Qt::AscendingOrder);
1094
1095         // restore selection
1096         if (!current.isEmpty()) {
1097                 QList<QListWidgetItem *> item = 
1098                         AllCopiersLW->findItems(current, Qt::MatchExactly);
1099                 if (item.size()>0)
1100                         AllCopiersLW->setCurrentItem(item.at(0));
1101         }
1102         // select first element if restoring failed
1103         if (AllCopiersLW->currentRow() == -1)
1104                 AllCopiersLW->setCurrentRow(0);
1105 }
1106
1107
1108 namespace {
1109
1110 class SamePrettyName {
1111 public:
1112         SamePrettyName(string const & n) : pretty_name_(n) {}
1113
1114         bool operator()(::Format const & fmt) const {
1115                 return fmt.prettyname() == pretty_name_;
1116         }
1117
1118 private:
1119         string const pretty_name_;
1120 };
1121
1122
1123 Format const * getFormat(std::string const & prettyname)
1124 {
1125         Formats::const_iterator it = ::formats.begin();
1126         Formats::const_iterator const end = ::formats.end();
1127         it = std::find_if(it, end, SamePrettyName(prettyname));
1128         return it == end ? 0 : &*it;
1129 }
1130
1131 } // namespace anon
1132
1133
1134 void PrefCopiers::switch_copierLB(int row)
1135 {
1136         if (row<0)
1137                 return;
1138
1139         std::string const browser_text =
1140                 fromqstr(AllCopiersLW->currentItem()->text());
1141         Format const * fmt = getFormat(browser_text);
1142         if (fmt == 0)
1143                 return;
1144
1145         QString const gui_name = toqstr(fmt->prettyname());
1146         QString const command = toqstr(form_->movers().command(fmt->name()));
1147
1148         copierED->clear();
1149         int const combo_size = copierFormatCO->count();
1150         for (int i = 0; i < combo_size; ++i) {
1151                 QString const text = copierFormatCO->text(i);
1152                 if (text == gui_name) {
1153                         copierFormatCO->setCurrentIndex(i);
1154                         copierED->setText(command);
1155                         break;
1156                 }
1157         }
1158         updateButtons();
1159 }
1160
1161
1162 void PrefCopiers::switch_copierCO(int row)
1163 {
1164         if (row<0)
1165                 return;
1166
1167         std::string const combo_text =
1168                 fromqstr(copierFormatCO->currentText());
1169         Format const * fmt = getFormat(combo_text);
1170         if (fmt == 0)
1171                 return;
1172
1173         QString const command = toqstr(form_->movers().command(fmt->name()));
1174         copierED->setText(command);
1175
1176         QListWidgetItem * const index = AllCopiersLW->currentItem();
1177         if (index >= 0)
1178                 AllCopiersLW->setItemSelected(index, false);
1179
1180         QString const gui_name = toqstr(fmt->prettyname());
1181         int const browser_size = AllCopiersLW->count();
1182         for (int i = 0; i < browser_size; ++i) {
1183                 QString const text = AllCopiersLW->item(i)->text();
1184                 if (text == gui_name) {
1185                         QListWidgetItem * item = AllCopiersLW->item(i);
1186                         AllCopiersLW->setItemSelected(item, true);
1187                         break;
1188                 }
1189         }
1190 }
1191
1192
1193 void PrefCopiers::copiers_changed()
1194 {
1195         updateButtons();
1196 }
1197
1198
1199 void PrefCopiers::updateButtons()
1200 {
1201         QString selected = copierFormatCO->currentText();
1202
1203         bool known = false;
1204         for (unsigned int i = 0; i != AllCopiersLW->count(); i++) {
1205                 if (AllCopiersLW->item(i)->text() == selected)
1206                         known = true;
1207         }
1208
1209         bool const valid = !copierED->text().isEmpty();
1210
1211         Format const * fmt = getFormat(fromqstr(selected));
1212         string const old_command = form_->movers().command(fmt->name());
1213         string const new_command(fromqstr(copierED->text()));
1214
1215         bool modified = (old_command != new_command);
1216
1217         copierModifyPB->setEnabled(valid && known && modified);
1218         copierNewPB->setEnabled(valid && !known);
1219         copierRemovePB->setEnabled(known);
1220 }
1221
1222
1223 void PrefCopiers::new_copier()
1224 {
1225         std::string const combo_text =
1226                 fromqstr(copierFormatCO->currentText());
1227         Format const * fmt = getFormat(combo_text);
1228         if (fmt == 0)
1229                 return;
1230
1231         string const command = fromqstr(copierED->text());
1232         if (command.empty())
1233                 return;
1234
1235         form_->movers().set(fmt->name(), command);
1236
1237         update();
1238         int const last = AllCopiersLW->count() - 1;
1239         AllCopiersLW->setCurrentRow(last);
1240
1241         updateButtons();
1242 }
1243
1244
1245 void PrefCopiers::modify_copier()
1246 {
1247         std::string const combo_text =
1248                 fromqstr(copierFormatCO->currentText());
1249         Format const * fmt = getFormat(combo_text);
1250         if (fmt == 0)
1251                 return;
1252
1253         string const command = fromqstr(copierED->text());
1254         form_->movers().set(fmt->name(), command);
1255
1256         update();
1257         updateButtons();
1258 }
1259
1260
1261 void PrefCopiers::remove_copier()
1262 {
1263         std::string const combo_text =
1264                 fromqstr(copierFormatCO->currentText());
1265         Format const * fmt = getFormat(combo_text);
1266         if (fmt == 0)
1267                 return;
1268
1269         string const & fmt_name = fmt->name();
1270         form_->movers().set(fmt_name, string());
1271
1272         update();
1273         updateButtons();
1274 }
1275
1276
1277
1278 PrefFileformats::PrefFileformats(QPrefs * form, QWidget * parent)
1279 : PrefModule(string(), _("File formats"), form, parent)
1280 {
1281         setupUi(this);
1282
1283         connect(formatNewPB, SIGNAL(clicked()), this, SLOT(new_format()));
1284         connect(formatRemovePB, SIGNAL(clicked()), this, SLOT(remove_format()));
1285         connect(formatModifyPB, SIGNAL(clicked()), this, SLOT(modify_format()));
1286         connect(formatsLW, SIGNAL(currentRowChanged(int)), 
1287                 this, SLOT(switch_format(int)));
1288         connect(formatED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1289         connect(guiNameED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1290         connect(shortcutED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1291         connect(extensionED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1292         connect(viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1293         connect(editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
1294         connect(documentCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed()));
1295         connect(formatNewPB, SIGNAL(clicked()),
1296                 this, SIGNAL(changed()));
1297         connect(formatRemovePB, SIGNAL(clicked()),
1298                 this, SIGNAL(changed()));
1299         connect(formatModifyPB, SIGNAL(clicked()),
1300                 this, SIGNAL(changed()));
1301 }
1302
1303
1304 void PrefFileformats::apply(LyXRC & rc) const
1305 {
1306 }
1307
1308
1309 void PrefFileformats::update(LyXRC const & rc)
1310 {
1311         update();
1312 }
1313
1314
1315 void PrefFileformats::update()
1316 {
1317         // save current selection
1318         QString current = guiNameED->text();
1319
1320         formatsLW->clear();
1321
1322         Formats::const_iterator cit = form_->formats().begin();
1323         Formats::const_iterator end = form_->formats().end();
1324         for (; cit != end; ++cit) {
1325                 new QListWidgetItem(toqstr(cit->prettyname()),
1326                                                         formatsLW,
1327                                                         form_->formats().getNumber(cit->name()) );
1328         }
1329         formatsLW->sortItems(Qt::AscendingOrder);
1330
1331         // restore selection
1332         if (!current.isEmpty()) {
1333                 QList<QListWidgetItem *>  item = formatsLW->findItems(current, Qt::MatchExactly);
1334                 if (item.size()>0)
1335                         formatsLW->setCurrentItem(item.at(0));
1336         }
1337         // select first element if restoring failed
1338         if (formatsLW->currentRow() == -1)
1339                 formatsLW->setCurrentRow(0);
1340 }
1341
1342
1343 void PrefFileformats::switch_format(int nr)
1344 {
1345         if (nr<0)
1346                 return;
1347
1348         int const ftype = formatsLW->item(nr)->type();
1349         Format const f(form_->formats().get(ftype));
1350
1351         formatED->setText(toqstr(f.name()));
1352         guiNameED->setText(toqstr(f.prettyname()));
1353         extensionED->setText(toqstr(f.extension()));
1354         shortcutED->setText(toqstr(f.shortcut()));
1355         viewerED->setText(toqstr(f.viewer()));
1356         editorED->setText(toqstr(f.editor()));
1357         documentCB->setChecked((f.documentFormat()));
1358         formatRemovePB->setEnabled(
1359                 !form_->converters().formatIsUsed(f.name()));
1360
1361         updateButtons();
1362 }
1363
1364
1365 void PrefFileformats::fileformat_changed()
1366 {
1367         updateButtons();
1368 }
1369
1370
1371 void PrefFileformats::updateButtons()
1372 {
1373         QString const format = formatED->text();
1374         QString const gui_name = guiNameED->text();
1375         int const sel = form_->formats().getNumber(fromqstr(format));
1376         bool gui_name_known = false;
1377         int where = sel;
1378         for (unsigned int i = 0; i != formatsLW->count(); i++) {
1379                 if (formatsLW->item(i)->text() == gui_name) {
1380                         gui_name_known = true;
1381                         where = formatsLW->item(i)->type();
1382                 }
1383         }
1384
1385         // assure that a gui name cannot be chosen twice
1386         bool const known_otherwise = gui_name_known && (where != sel);
1387
1388         bool const known = !(sel < 0);
1389         bool const valid = (!formatED->text().isEmpty()
1390                 && !guiNameED->text().isEmpty());
1391
1392         int const ftype = formatsLW->currentItem()->type();
1393         Format const & f(form_->formats().get(ftype));
1394         string const old_pretty(f.prettyname());
1395         string const old_shortcut(f.shortcut());
1396         string const old_extension(f.extension());
1397         string const old_viewer(f.viewer());
1398         string const old_editor(f.editor());
1399         bool const old_document(f.documentFormat());
1400
1401         string const new_pretty(fromqstr(gui_name));
1402         string const new_shortcut(fromqstr(shortcutED->text()));
1403         string const new_extension(fromqstr(extensionED->text()));
1404         string const new_viewer(fromqstr(viewerED->text()));
1405         string const new_editor(fromqstr(editorED->text()));
1406         bool const new_document(documentCB->isChecked());
1407
1408         bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut)
1409                 || (old_extension != new_extension) || (old_viewer != new_viewer)
1410                 || (old_editor != new_editor) || old_document != new_document);
1411
1412         formatModifyPB->setEnabled(
1413                 valid && known && modified && !known_otherwise);
1414         formatNewPB->setEnabled(valid && !known && !gui_name_known);
1415         formatRemovePB->setEnabled(known);
1416 }
1417
1418 void PrefFileformats::setConverters(PrefConverters * converters)
1419 {
1420         converters_ = converters;
1421 }
1422
1423 void PrefFileformats::new_format()
1424 {
1425         string const name = fromqstr(formatED->text());
1426         string const prettyname = fromqstr(guiNameED->text());
1427         string const extension = fromqstr(extensionED->text());
1428         string const shortcut = fromqstr(shortcutED->text());
1429         string const viewer = fromqstr(viewerED->text());
1430         string const editor = fromqstr(editorED->text());
1431         bool const document = documentCB->isChecked();
1432
1433         form_->formats().add(name, extension, prettyname, shortcut, viewer,
1434                              editor, document);
1435         form_->formats().sort();
1436         update();
1437
1438         QList<QListWidgetItem *>  const item =
1439                 formatsLW->findItems(toqstr(prettyname), Qt::MatchExactly);
1440         if (item.size()>0)
1441                 formatsLW->setCurrentItem(item.at(0));
1442
1443         form_->converters().update(form_->formats());
1444
1445         converters_->updateGui();
1446         updateButtons();
1447 }
1448
1449
1450 void PrefFileformats::modify_format()
1451 {
1452         int const current_item = formatsLW->currentItem()->type();
1453         QString const current_text =
1454                 formatsLW->currentItem()->text();
1455
1456         Format const & oldformat(form_->formats().get(current_item));
1457         string const oldpretty(oldformat.prettyname());
1458         string const name(fromqstr(formatED->text()));
1459         form_->formats().erase(oldformat.name());
1460
1461         string const prettyname = fromqstr(guiNameED->text());
1462         string const extension = fromqstr(extensionED->text());
1463         string const shortcut = fromqstr(shortcutED->text());
1464         string const viewer = fromqstr(viewerED->text());
1465         string const editor = fromqstr(editorED->text());
1466         bool const document = documentCB->isChecked();
1467
1468         form_->formats().add(name, extension, prettyname, shortcut, viewer,
1469                              editor, document);
1470         form_->formats().sort();
1471
1472         formatsLW->setUpdatesEnabled(false);
1473         update();
1474         formatsLW->setUpdatesEnabled(true);
1475         formatsLW->update();
1476
1477         converters_->updateGui();
1478         updateButtons();
1479
1480         QList<QListWidgetItem *>  const item =
1481                 formatsLW->findItems(current_text, Qt::MatchExactly);
1482         if (item.size()>0)
1483                 formatsLW->setCurrentItem(item.at(0));
1484 }
1485
1486
1487 void PrefFileformats::remove_format()
1488 {
1489         int const nr = formatsLW->currentItem()->type();
1490         if (nr < 0)
1491                 return;
1492         string const current_text = form_->formats().get(nr).name();
1493         if (form_->converters().formatIsUsed(current_text)) {
1494                 Alert::error(_("Format in use"),
1495                                 _("Cannot remove a Format used by a Converter. "
1496                                       "Remove the converter first."));
1497                 return;
1498         }
1499
1500         form_->formats().erase(current_text);
1501         update();
1502         form_->converters().update(form_->formats());
1503
1504         converters_->updateGui();
1505         updateButtons();
1506 }
1507
1508
1509
1510 PrefLanguage::PrefLanguage(QWidget * parent)
1511 : PrefModule(string(), _("Language"), 0, parent)
1512 {
1513         setupUi(this);
1514
1515         connect(rtlCB, SIGNAL(toggled(bool)),
1516                 this, SIGNAL(changed()));
1517         connect(markForeignCB, SIGNAL(toggled(bool)),
1518                 this, SIGNAL(changed()));
1519         connect(autoBeginCB, SIGNAL(toggled(bool)),
1520                 this, SIGNAL(changed()));
1521         connect(autoEndCB, SIGNAL(toggled(bool)),
1522                 this, SIGNAL(changed()));
1523         connect(useBabelCB, SIGNAL(toggled(bool)),
1524                 this, SIGNAL(changed()));
1525         connect(globalCB, SIGNAL(toggled(bool)),
1526                 this, SIGNAL(changed()));
1527         connect(languagePackageED, SIGNAL(textChanged(const QString&)),
1528                 this, SIGNAL(changed()));
1529         connect(startCommandED, SIGNAL(textChanged(const QString&)),
1530                 this, SIGNAL(changed()));
1531         connect(endCommandED, SIGNAL(textChanged(const QString&)),
1532                 this, SIGNAL(changed()));
1533         connect(defaultLanguageCO, SIGNAL(activated(int)),
1534                 this, SIGNAL(changed()));
1535
1536         defaultLanguageCO->clear();
1537
1538         // store the lang identifiers for later
1539         using lyx::frontend::LanguagePair;
1540         std::vector<LanguagePair> const langs =
1541                 lyx::frontend::getLanguageData(false);
1542         lang_ = getSecond(langs);
1543
1544         std::vector<LanguagePair>::const_iterator lit  = langs.begin();
1545         std::vector<LanguagePair>::const_iterator lend = langs.end();
1546         for (; lit != lend; ++lit) {
1547                 defaultLanguageCO->insertItem(toqstr(lit->first));
1548         }
1549 }
1550
1551
1552 void PrefLanguage::apply(LyXRC & rc) const
1553 {
1554         // FIXME: remove rtl_support bool
1555         rc.rtl_support = rtlCB->isChecked();
1556         rc.mark_foreign_language = markForeignCB->isChecked();
1557         rc.language_auto_begin = autoBeginCB->isChecked();
1558         rc.language_auto_end = autoEndCB->isChecked();
1559         rc.language_use_babel = useBabelCB->isChecked();
1560         rc.language_global_options = globalCB->isChecked();
1561         rc.language_package = fromqstr(languagePackageED->text());
1562         rc.language_command_begin = fromqstr(startCommandED->text());
1563         rc.language_command_end = fromqstr(endCommandED->text());
1564         rc.default_language = lang_[defaultLanguageCO->currentItem()];
1565 }
1566
1567
1568 void PrefLanguage::update(LyXRC const & rc)
1569 {
1570         // FIXME: remove rtl_support bool
1571         rtlCB->setChecked(rc.rtl_support);
1572         markForeignCB->setChecked(rc.mark_foreign_language);
1573         autoBeginCB->setChecked(rc.language_auto_begin);
1574         autoEndCB->setChecked(rc.language_auto_end);
1575         useBabelCB->setChecked(rc.language_use_babel);
1576         globalCB->setChecked(rc.language_global_options);
1577         languagePackageED->setText(toqstr(rc.language_package));
1578         startCommandED->setText(toqstr(rc.language_command_begin));
1579         endCommandED->setText(toqstr(rc.language_command_end));
1580
1581         int const pos = int(findPos(lang_, rc.default_language));
1582         defaultLanguageCO->setCurrentIndex(pos);
1583 }
1584
1585
1586 PrefPrinter::PrefPrinter(QWidget * parent)
1587 : PrefModule(_(Outputs), _("Printer"), 0, parent)
1588 {
1589         setupUi(this);
1590
1591         connect(printerAdaptCB, SIGNAL(toggled(bool)),
1592                 this, SIGNAL(changed()));
1593         connect(printerCommandED, SIGNAL(textChanged(const QString&)),
1594                 this, SIGNAL(changed()));
1595         connect(printerNameED, SIGNAL(textChanged(const QString&)),
1596                 this, SIGNAL(changed()));
1597         connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
1598                 this, SIGNAL(changed()));
1599         connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
1600                 this, SIGNAL(changed()));
1601         connect(printerReverseED, SIGNAL(textChanged(const QString&)),
1602                 this, SIGNAL(changed()));
1603         connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
1604                 this, SIGNAL(changed()));
1605         connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
1606                 this, SIGNAL(changed()));
1607         connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
1608                 this, SIGNAL(changed()));
1609         connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
1610                 this, SIGNAL(changed()));
1611         connect(printerEvenED, SIGNAL(textChanged(const QString&)),
1612                 this, SIGNAL(changed()));
1613         connect(printerOddED, SIGNAL(textChanged(const QString&)),
1614                 this, SIGNAL(changed()));
1615         connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
1616                 this, SIGNAL(changed()));
1617         connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
1618                 this, SIGNAL(changed()));
1619         connect(printerToFileED, SIGNAL(textChanged(const QString&)),
1620                 this, SIGNAL(changed()));
1621         connect(printerExtraED, SIGNAL(textChanged(const QString&)),
1622                 this, SIGNAL(changed()));
1623         connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
1624                 this, SIGNAL(changed()));
1625         connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
1626                 this, SIGNAL(changed()));
1627 }
1628
1629
1630 void PrefPrinter::apply(LyXRC & rc) const
1631 {
1632         rc.print_adapt_output = printerAdaptCB->isChecked();
1633         rc.print_command = fromqstr(printerCommandED->text());
1634         rc.printer = fromqstr(printerNameED->text());
1635
1636         rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
1637         rc.print_copies_flag = fromqstr(printerCopiesED->text());
1638         rc.print_reverse_flag = fromqstr(printerReverseED->text());
1639         rc.print_to_printer = fromqstr(printerToPrinterED->text());
1640         rc.print_file_extension = fromqstr(printerExtensionED->text());
1641         rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
1642         rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
1643         rc.print_evenpage_flag = fromqstr(printerEvenED->text());
1644         rc.print_oddpage_flag = fromqstr(printerOddED->text());
1645         rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
1646         rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
1647         rc.print_to_file = internal_path(printerToFileED->text());
1648         rc.print_extra_options = fromqstr(printerExtraED->text());
1649         rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
1650         rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
1651 }
1652
1653
1654 void PrefPrinter::update(LyXRC const & rc)
1655 {
1656         printerAdaptCB->setChecked(rc.print_adapt_output);
1657         printerCommandED->setText(toqstr(rc.print_command));
1658         printerNameED->setText(toqstr(rc.printer));
1659
1660         printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
1661         printerCopiesED->setText(toqstr(rc.print_copies_flag));
1662         printerReverseED->setText(toqstr(rc.print_reverse_flag));
1663         printerToPrinterED->setText(toqstr(rc.print_to_printer));
1664         printerExtensionED->setText(toqstr(rc.print_file_extension));
1665         printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
1666         printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
1667         printerEvenED->setText(toqstr(rc.print_evenpage_flag));
1668         printerOddED->setText(toqstr(rc.print_oddpage_flag));
1669         printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
1670         printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
1671         printerToFileED->setText(external_path(rc.print_to_file));
1672         printerExtraED->setText(toqstr(rc.print_extra_options));
1673         printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
1674         printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
1675 }
1676
1677
1678 PrefUserInterface::PrefUserInterface(QPrefs * form, QWidget * parent)
1679 : PrefModule(_(LookAndFeel), _("User interface"), form, parent)
1680 {
1681         setupUi(this);
1682
1683         connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveLA, SLOT( setEnabled(bool) ) );
1684         connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveSB, SLOT( setEnabled(bool) ) );
1685         connect(autoSaveCB, SIGNAL( toggled(bool) ), TextLabel1, SLOT( setEnabled(bool) ) );
1686         connect(uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui()));
1687         connect(bindFilePB, SIGNAL(clicked()), this, SLOT(select_bind()));
1688         connect(uiFileED, SIGNAL(textChanged(const QString&)),
1689                 this, SIGNAL(changed()));
1690         connect(bindFileED, SIGNAL(textChanged(const QString&)),
1691                 this, SIGNAL(changed()));
1692         connect(restoreCursorCB, SIGNAL(toggled(bool)),
1693                 this, SIGNAL(changed()));
1694         connect(loadSessionCB, SIGNAL(toggled(bool)),
1695                 this, SIGNAL(changed()));
1696         connect(cursorFollowsCB, SIGNAL(toggled(bool)),
1697                 this, SIGNAL(changed()));
1698         connect(autoSaveSB, SIGNAL(valueChanged(int)),
1699                 this, SIGNAL(changed()));
1700         connect(autoSaveCB, SIGNAL(toggled(bool)),
1701                 this, SIGNAL(changed()));
1702         connect(lastfilesSB, SIGNAL(valueChanged(int)),
1703                 this, SIGNAL(changed()));
1704         lastfilesSB->setMaxValue(maxlastfiles);
1705 }
1706
1707
1708 void PrefUserInterface::apply(LyXRC & rc) const
1709 {
1710         rc.ui_file = internal_path(uiFileED->text());
1711         rc.bind_file = internal_path(bindFileED->text());
1712         rc.use_lastfilepos = restoreCursorCB->isChecked();
1713         rc.load_session = loadSessionCB->isChecked();
1714         rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
1715         rc.autosave = autoSaveSB->value() * 60;
1716         rc.make_backup = autoSaveCB->isChecked();
1717         rc.num_lastfiles = lastfilesSB->value();
1718 }
1719
1720
1721 void PrefUserInterface::update(LyXRC const & rc)
1722 {
1723         uiFileED->setText(external_path(rc.ui_file));
1724         bindFileED->setText(external_path(rc.bind_file));
1725         restoreCursorCB->setChecked(rc.use_lastfilepos);
1726         loadSessionCB->setChecked(rc.load_session);
1727         cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
1728         // convert to minutes
1729         int mins(rc.autosave / 60);
1730         if (rc.autosave && !mins)
1731                 mins = 1;
1732         autoSaveSB->setValue(mins);
1733         autoSaveCB->setChecked(rc.make_backup);
1734         lastfilesSB->setValue(rc.num_lastfiles);
1735 }
1736
1737
1738
1739 void PrefUserInterface::select_ui()
1740 {
1741         string file(form_->controller().browseUI(fromqstr(uiFileED->text())));
1742         if (!file.empty())
1743                 uiFileED->setText(toqstr(file));
1744 }
1745
1746
1747 void PrefUserInterface::select_bind()
1748 {
1749         string file(form_->controller().browsebind(fromqstr(bindFileED->text())));
1750         if (!file.empty())
1751                 bindFileED->setText(toqstr(file));
1752 }
1753
1754
1755 PrefIdentity::PrefIdentity(QWidget * parent)
1756 : PrefModule(string(), _("Identity"), 0, parent)
1757 {
1758         setupUi(this);
1759
1760         connect(nameED, SIGNAL(textChanged(const QString&)),
1761                 this, SIGNAL(changed()));
1762         connect(emailED, SIGNAL(textChanged(const QString&)),
1763                 this, SIGNAL(changed()));
1764 }
1765
1766
1767 void PrefIdentity::apply(LyXRC & rc) const
1768 {
1769         rc.user_name = fromqstr(nameED->text());
1770         rc.user_email = fromqstr(emailED->text());
1771 }
1772
1773
1774 void PrefIdentity::update(LyXRC const & rc)
1775 {
1776         nameED->setText(toqstr(rc.user_name));
1777         emailED->setText(toqstr(rc.user_email));
1778 }
1779
1780
1781
1782 QPrefsDialog::QPrefsDialog(QPrefs * form)
1783         : form_(form)
1784 {
1785         setupUi(this);
1786         QDialog::setModal(true);
1787
1788         connect(savePB, SIGNAL(clicked()),
1789                 form, SLOT(slotOK()));
1790         connect(applyPB, SIGNAL(clicked()),
1791                 form, SLOT(slotApply()));
1792         connect(closePB, SIGNAL(clicked()),
1793                 form, SLOT(slotClose()));
1794         connect(restorePB, SIGNAL(clicked()),
1795                 form, SLOT(slotRestore()));
1796
1797         add(new PrefAscii);
1798         add(new PrefDate);
1799         add(new PrefKeyboard(form_));
1800         add(new PrefLatex(form_));
1801         add(new PrefScreenFonts(form_));
1802         add(new PrefColors(form_));
1803
1804 #if defined(__CYGWIN__) || defined(__CYGWIN32__)
1805         add(new PrefCygwinPath);
1806 #endif
1807
1808         add(new PrefDisplay);
1809         add(new PrefPaths(form_));
1810         add(new PrefSpellchecker(form_));
1811
1812         PrefConverters * converters = new PrefConverters(form_);
1813         PrefFileformats * formats = new PrefFileformats(form_);
1814         formats->setConverters(converters);
1815         add(converters);
1816         add(formats);
1817
1818         add(new PrefCopiers(form_));
1819         
1820         add(new PrefLanguage);
1821         add(new PrefPrinter);
1822         add(new PrefUserInterface(form_));
1823         add(new PrefIdentity);
1824
1825         prefsPS->setCurrentPanel(_("User interface"));
1826
1827         form_->bcview().setOK(savePB);
1828         form_->bcview().setApply(applyPB);
1829         form_->bcview().setCancel(closePB);
1830         form_->bcview().setRestore(restorePB);
1831 }
1832
1833
1834 QPrefsDialog::~QPrefsDialog()
1835 {
1836 }
1837
1838
1839 void QPrefsDialog::add(PrefModule * module)
1840 {
1841         BOOST_ASSERT(module);
1842
1843 //      if (module->category().empty())
1844 //              prefsPS->addPanel(module, module->title());
1845 //      else
1846                 prefsPS->addPanel(module, module->title(), module->category());
1847
1848         connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
1849
1850         modules_.push_back(module);
1851 }
1852
1853 void QPrefsDialog::closeEvent(QCloseEvent * e)
1854 {
1855         form_->slotWMHide();
1856         e->accept();
1857 }
1858
1859
1860 void QPrefsDialog::change_adaptor()
1861 {
1862         form_->changed();
1863 }
1864
1865
1866 void QPrefsDialog::apply(LyXRC & rc) const
1867 {
1868         size_t end = modules_.size();
1869         for (size_t i = 0; i != end; ++i)
1870                 modules_[i]->apply(rc);
1871 }
1872
1873
1874 void QPrefsDialog::update(LyXRC const & rc)
1875 {
1876         size_t end = modules_.size();
1877         for (size_t i = 0; i != end; ++i)
1878                 modules_[i]->update(rc);
1879 }
1880
1881
1882 } // namespace frontend
1883 } // namespace lyx
1884
1885 #include "QPrefsDialog_moc.cpp"