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