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