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