]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QDocument.C
The big Qt toqstr/fromqstr patch.
[lyx.git] / src / frontends / qt2 / QDocument.C
1 /**
2  * \file QDocument.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "qt_helpers.h"
18
19 #include "ControlDocument.h"
20 #include "QDocument.h"
21 #include "QDocumentDialog.h"
22 #include "Qt2BC.h"
23
24 #include "language.h"
25 #include "helper_funcs.h" // getSecond()
26 #include "insets/insetquotes.h"
27 #include "frnt_lang.h"
28 #include "lyxrc.h" // defaultUnit
29 #include "tex-strings.h" // tex_graphics
30 #include "support/lstrings.h" // tostr()
31 #include "support/filetools.h" // LibFileSearch()
32 #include "lyxtextclasslist.h"
33 #include "vspace.h"
34 #include "bufferparams.h"
35 #include "qt_helpers.h"
36
37 #include <qpushbutton.h>
38 #include <qmultilineedit.h>
39 #include <qradiobutton.h>
40 #include <qcombobox.h>
41 #include <qcheckbox.h>
42 #include <qspinbox.h>
43 #include <qlineedit.h>
44 #include <qstringlist.h>
45 #include "lengthcombo.h"
46
47 #include "QBrowseBox.h"
48
49 #include <vector>
50
51 using std::vector;
52
53 typedef Qt2CB<ControlDocument, Qt2DB<QDocumentDialog> > base_class;
54
55
56 QDocument::QDocument()
57         : base_class(qt_("Document Settings"))
58 {
59         vector<frnt::LanguagePair> const langs = frnt::getLanguageData(false);
60         lang_ = getSecond(langs);
61 }
62
63
64 void QDocument::build_dialog()
65 {
66         dialog_.reset(new QDocumentDialog(this));
67
68         // biblio
69         dialog_->biblioModule->citeStyleCO->insertItem(qt_("Author-year"));
70         dialog_->biblioModule->citeStyleCO->insertItem(qt_("Numerical"));
71         dialog_->biblioModule->citeStyleCO->setCurrentItem(0);
72
73         // language & quotes
74         vector<frnt::LanguagePair> const langs = frnt::getLanguageData(false);
75         vector<frnt::LanguagePair>::const_iterator lit  = langs.begin();
76         vector<frnt::LanguagePair>::const_iterator lend = langs.end();
77         for (; lit != lend; ++lit) {
78                 dialog_->langModule->languageCO->insertItem(
79                         toqstr(lit->first));
80         }
81
82         dialog_->langModule->quoteStyleCO->insertItem(qt_("``text''"));
83         dialog_->langModule->quoteStyleCO->insertItem(qt_("''text''"));
84         dialog_->langModule->quoteStyleCO->insertItem(qt_(",,text``"));
85         dialog_->langModule->quoteStyleCO->insertItem(qt_(",,text''"));
86         dialog_->langModule->quoteStyleCO->insertItem(qt_("«text»"));
87         dialog_->langModule->quoteStyleCO->insertItem(qt_("»text«"));
88
89         // packages
90         char const * items[] = {"default", "auto", "latin1", "latin2",
91                              "latin3", "latin4", "latin5", "latin9",
92                              "koi8-r", "koi8-u", "cp866", "cp1251",
93                              "iso88595", "pt154", 0};
94         dialog_->packagesModule->encodingCO->insertStrList(items);
95
96         dialog_->packagesModule->lspacingCO->insertItem(
97                 qt_("Single"), Spacing::Single);
98         dialog_->packagesModule->lspacingCO->insertItem(
99                 qt_("OneHalf"), Spacing::Onehalf);
100         dialog_->packagesModule->lspacingCO->insertItem(
101                 qt_("Double"), Spacing::Double);
102         dialog_->packagesModule->lspacingCO->insertItem(
103                 qt_("Custom"), Spacing::Other);
104
105         for (int n = 0; tex_graphics[n][0]; ++n) {
106                 QString enc = tex_graphics[n];
107                 dialog_->packagesModule->psdriverCO->insertItem(enc);
108         }
109
110         // paper
111         QComboBox * cb = dialog_->paperModule->papersizeCO;
112         cb->insertItem(qt_("Default"));
113         cb->insertItem(qt_("Custom"));
114         cb->insertItem(qt_("US letter"));
115         cb->insertItem(qt_("US legal"));
116         cb->insertItem(qt_("US executive"));
117         cb->insertItem(qt_("A3"));
118         cb->insertItem(qt_("A4"));
119         cb->insertItem(qt_("A5"));
120         cb->insertItem(qt_("B3"));
121         cb->insertItem(qt_("B4"));
122         cb->insertItem(qt_("B5"));
123
124         // layout
125         for (LyXTextClassList::const_iterator cit = textclasslist.begin();
126              cit != textclasslist.end(); ++cit) {
127                 dialog_->layoutModule->classCO->insertItem(toqstr(cit->description()));
128         }
129
130         for (int n = 0; tex_fonts[n][0]; ++n) {
131                 QString font = tex_fonts[n];
132                 dialog_->layoutModule->fontsCO->insertItem(font);
133         }
134
135         dialog_->layoutModule->fontsizeCO->insertItem(qt_("default"));
136         dialog_->layoutModule->fontsizeCO->insertItem(qt_("10"));
137         dialog_->layoutModule->fontsizeCO->insertItem(qt_("11"));
138         dialog_->layoutModule->fontsizeCO->insertItem(qt_("12"));
139
140         dialog_->layoutModule->skipCO->insertItem(qt_("Smallskip"));
141         dialog_->layoutModule->skipCO->insertItem(qt_("Medskip"));
142         dialog_->layoutModule->skipCO->insertItem(qt_("Bigskip"));
143         dialog_->layoutModule->skipCO->insertItem(qt_("Length"));
144
145         dialog_->layoutModule->pagestyleCO->insertItem(qt_("default"));
146         dialog_->layoutModule->pagestyleCO->insertItem(qt_("empty"));
147         dialog_->layoutModule->pagestyleCO->insertItem(qt_("plain"));
148         dialog_->layoutModule->pagestyleCO->insertItem(qt_("headings"));
149         dialog_->layoutModule->pagestyleCO->insertItem(qt_("fancy"));
150
151         // margins
152         dialog_->setMargins(0);
153
154         // Manage the restore, ok, apply, restore and cancel/close buttons
155         bc().setOK(dialog_->okPB);
156         bc().setApply(dialog_->applyPB);
157         bc().setCancel(dialog_->closePB);
158         bc().setRestore(dialog_->restorePB);
159 }
160
161
162 void QDocument::apply()
163 {
164         BufferParams & params = controller().params();
165
166         // preamble
167         params.preamble =
168                 fromqstr(dialog_->preambleModule->preambleMLE->text());
169
170         // biblio
171         params.use_natbib =
172                 dialog_->biblioModule->natbibCB->isChecked();
173         params.use_numerical_citations  =
174                 dialog_->biblioModule->citeStyleCO->currentItem();
175
176         // language & quotes
177         if (dialog_->langModule->singleQuoteRB->isChecked())
178                 params.quotes_times = InsetQuotes::SingleQ;
179         else
180                 params.quotes_times = InsetQuotes::DoubleQ;
181
182
183         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
184         switch (dialog_->langModule->quoteStyleCO->currentItem()) {
185         case 0:
186                 lga = InsetQuotes::EnglishQ;
187                 break;
188         case 1:
189                 lga = InsetQuotes::SwedishQ;
190                 break;
191         case 2:
192                 lga = InsetQuotes::GermanQ;
193                 break;
194         case 3:
195                 lga = InsetQuotes::PolishQ;
196                 break;
197         case 4:
198                 lga = InsetQuotes::FrenchQ;
199                 break;
200         case 5:
201                 lga = InsetQuotes::DanishQ;
202                 break;
203         }
204         params.quotes_language = lga;
205
206         int const pos = dialog_->langModule->languageCO->currentItem();
207         params.language = languages.getLanguage(lang_[pos]);
208
209         // numbering
210         params.secnumdepth =
211                 dialog_->numberingModule->tocDepthSB->value();
212         params.tocdepth =
213                 dialog_->numberingModule->sectionnrDepthSB->value();
214
215         // bullets
216         params.user_defined_bullets[0] = dialog_->bulletsModule->getBullet(0);
217         params.user_defined_bullets[1] = dialog_->bulletsModule->getBullet(1);
218         params.user_defined_bullets[2] = dialog_->bulletsModule->getBullet(2);
219         params.user_defined_bullets[3] = dialog_->bulletsModule->getBullet(3);
220
221         // packages
222         switch (dialog_->packagesModule->lspacingCO->currentItem()) {
223         case 0:
224                 params.spacing.set(Spacing::Single);
225                 break;
226         case 1:
227                 params.spacing.set(Spacing::Onehalf);
228                 break;
229         case 2:
230                 params.spacing.set(Spacing::Double);
231                 break;
232         case 3:
233                 params.spacing.set(Spacing::Other,
234                                    dialog_->packagesModule->
235                                    lspacingLE->text().toFloat()
236                                    );
237                 break;
238         }
239
240         params.graphicsDriver =
241                 fromqstr(dialog_->packagesModule->psdriverCO->currentText());
242
243         params.use_amsmath =
244                 dialog_->packagesModule->amsCB->isChecked();
245
246         params.inputenc =
247                 fromqstr(dialog_->packagesModule->encodingCO->currentText());
248
249         // layout
250         params.textclass =
251                 dialog_->layoutModule->classCO->currentItem();
252
253         //bool succes = controller().classApply();
254
255         params.fonts =
256                 fromqstr(dialog_->layoutModule->fontsCO->currentText());
257
258         params.fontsize =
259                 fromqstr(dialog_->layoutModule->fontsizeCO->currentText());
260
261         params.pagestyle =
262                 fromqstr(dialog_->layoutModule->pagestyleCO->currentText());
263
264         if (dialog_->layoutModule->indentRB->isChecked())
265                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
266         else
267                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
268
269         switch (dialog_->layoutModule->skipCO->currentItem()) {
270         case 0:
271                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
272                 break;
273         case 1:
274                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
275                 break;
276         case 2:
277                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
278                 break;
279         case 3:
280         {
281                 LyXLength::UNIT unit =
282                         dialog_->layoutModule->skipLengthCO->
283                         currentLengthItem();
284                 double length =
285                         dialog_->layoutModule->skipLE->text().toDouble();
286                 VSpace vs = VSpace(LyXGlueLength(LyXLength(length,unit)));
287                 params.setDefSkip(vs);
288                 break;
289         }
290         default:
291                 // DocumentDefskipCB assures that this never happens
292                 // so Assert then !!!  - jbl
293                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
294                 break;
295         }
296
297         params.options =
298                 fromqstr(dialog_->layoutModule->optionsLE->text());
299
300         params.float_placement =
301                 fromqstr(dialog_->layoutModule->floatPlacementLE->text());
302
303         // paper
304         params.papersize2 =
305                 dialog_->paperModule->papersizeCO->currentItem();
306
307         params.paperwidth = widgetsToLength(dialog_->paperModule->paperwidthLE,
308                 dialog_->paperModule->paperwidthUnitCO);
309
310         params.paperheight = widgetsToLength(dialog_->paperModule->paperheightLE,
311                 dialog_->paperModule->paperheightUnitCO);
312
313         if (dialog_->paperModule->twoColumnCB->isChecked())
314                 params.columns = 2;
315         else
316                 params.columns = 1;
317
318         if (dialog_->paperModule->facingPagesCB->isChecked())
319                 params.sides = LyXTextClass::TwoSides;
320         else
321                 params.sides = LyXTextClass::OneSide;
322
323         if (dialog_->paperModule->landscapeRB->isChecked())
324                 params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
325         else
326                 params.orientation = BufferParams::ORIENTATION_PORTRAIT;
327
328         // margins
329         params.use_geometry =
330                 (dialog_->marginsModule->marginCO->currentItem() == 1);
331
332         int margin = dialog_->marginsModule->marginCO->currentItem();
333         if (margin > 0) {
334                 margin = margin - 1;
335         }
336         params.paperpackage = char(margin);
337
338         MarginsModuleBase const * m(dialog_->marginsModule);
339
340         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
341
342         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
343
344         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
345
346         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
347
348         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
349
350         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
351
352         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
353 }
354
355
356 namespace {
357
358 /** Return the position of val in the vector if found.
359     If not found, return 0.
360  */
361 template<class A>
362 typename std::vector<A>::size_type
363 findPos(std::vector<A> const & vec, A const & val)
364 {
365         typename std::vector<A>::const_iterator it =
366                 std::find(vec.begin(), vec.end(), val);
367         if (it == vec.end())
368                 return 0;
369         return std::distance(vec.begin(), it);
370 }
371
372 } // namespace anom
373
374
375 void QDocument::update_contents()
376 {
377         if (!dialog_.get())
378                 return;
379
380         BufferParams const & params = controller().params();
381
382         // set the default unit
383         // FIXME: move to controller
384         LyXLength::UNIT defaultUnit = LyXLength::CM;
385         switch (lyxrc.default_papersize) {
386                 case BufferParams::PAPER_DEFAULT: break;
387
388                 case BufferParams::PAPER_USLETTER:
389                 case BufferParams::PAPER_LEGALPAPER:
390                 case BufferParams::PAPER_EXECUTIVEPAPER:
391                         defaultUnit = LyXLength::IN;
392                         break;
393
394                 case BufferParams::PAPER_A3PAPER:
395                 case BufferParams::PAPER_A4PAPER:
396                 case BufferParams::PAPER_A5PAPER:
397                 case BufferParams::PAPER_B5PAPER:
398                         defaultUnit = LyXLength::CM;
399                         break;
400         }
401
402         // preamble
403         QString preamble = toqstr(params.preamble);
404         dialog_->preambleModule->preambleMLE->setText(preamble);
405
406         // biblio
407         dialog_->biblioModule->natbibCB->setChecked(
408                 params.use_natbib);
409         dialog_->biblioModule->citeStyleCO->setCurrentItem(
410                 params.use_numerical_citations ? 1 : 0);
411
412         // language & quotes
413         dialog_->langModule->singleQuoteRB->setChecked(
414                 params.quotes_times == InsetQuotes::SingleQ);
415         dialog_->langModule->doubleQuoteRB->setChecked(
416                 params.quotes_times == InsetQuotes::DoubleQ);
417
418         int const pos = int(findPos(lang_,
419                                     params.language->lang()));
420         dialog_->langModule->languageCO->setCurrentItem(pos);
421
422         dialog_->langModule->quoteStyleCO->setCurrentItem(
423                 params.quotes_language);
424
425         // numbering
426         dialog_->numberingModule->tocDepthSB->setValue(
427                 params.secnumdepth);
428         dialog_->numberingModule->sectionnrDepthSB->setValue(
429                 params.tocdepth);
430
431         // bullets
432         dialog_->bulletsModule->setBullet(0,params.user_defined_bullets[0]);
433         dialog_->bulletsModule->setBullet(1,params.user_defined_bullets[1]);
434         dialog_->bulletsModule->setBullet(2,params.user_defined_bullets[2]);
435         dialog_->bulletsModule->setBullet(3,params.user_defined_bullets[3]);
436
437         // packages
438         char const * enc[] = {
439                 "default" , "auto" , "latin1" , "latin2" , "latin3" ,
440                 "latin4" , "latin5" , "latin9" , "koi8-r" , "koi8-u" ,
441                 "cp866" , "cp1251" , "iso88595" , "pt154" };
442         for (size_t i = 0; i < sizeof(enc)/sizeof(char *); ++i) {
443                 if (params.inputenc == enc[i])
444                         dialog_->packagesModule->encodingCO->setCurrentItem(i);
445         }
446
447         QString text = toqstr(params.graphicsDriver);
448         int nitem = dialog_->packagesModule->psdriverCO->count();
449         for (int n = 0; n < nitem ; ++n) {
450                 QString enc = tex_graphics[n];
451                 if (enc == text) {
452                         dialog_->packagesModule->psdriverCO->setCurrentItem(n);
453                 }
454         }
455
456
457         dialog_->packagesModule->amsCB->setChecked(
458                 params.use_amsmath);
459
460         switch (params.spacing.getSpace()) {
461                 case Spacing::Other: nitem = 3; break;
462                 case Spacing::Double: nitem = 2; break;
463                 case Spacing::Onehalf: nitem = 1; break;
464                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
465         }
466
467         dialog_->packagesModule->lspacingCO->setCurrentItem(nitem);
468         if (params.spacing.getSpace() == Spacing::Other) {
469                 dialog_->packagesModule->lspacingLE->setText(
470                         toqstr(tostr(params.spacing.getValue())));
471                 dialog_->setLSpacing(3);
472         }
473
474         // layout
475         for (int n = 0; n<dialog_->layoutModule->classCO->count(); ++n) {
476                 if (dialog_->layoutModule->classCO->text(n) ==
477                     toqstr(controller().textClass().description())) {
478                         dialog_->layoutModule->classCO->setCurrentItem(n);
479                         break;
480                 }
481         }
482
483         dialog_->updateFontsize(controller().textClass().opt_fontsize(),
484                                 params.fontsize);
485
486         dialog_->updatePagestyle(controller().textClass().opt_pagestyle(),
487                                  params.pagestyle);
488
489         for (int n = 0; tex_fonts[n][0]; ++n) {
490                 if (tex_fonts[n] == params.fonts) {
491                         dialog_->layoutModule->fontsCO->setCurrentItem(n);
492                         break;
493                 }
494         }
495
496         if (params.paragraph_separation
497             == BufferParams::PARSEP_INDENT) {
498                 dialog_->layoutModule->indentRB->setChecked(true);
499         } else {
500                 dialog_->layoutModule->skipRB->setChecked(true);
501         }
502
503         int skip = 0;
504         switch (params.getDefSkip().kind()) {
505         case VSpace::SMALLSKIP:
506                 skip = 0;
507                 break;
508         case VSpace::MEDSKIP:
509                 skip = 1;
510                 break;
511         case VSpace::BIGSKIP:
512                 skip = 2;
513                 break;
514         case VSpace::LENGTH:
515         {
516                 skip = 3;
517                 string const length = params.getDefSkip().asLyXCommand();
518                 dialog_->layoutModule->skipLengthCO->setCurrentItem(LyXLength(length).unit());
519                 dialog_->layoutModule->skipLE->setText(toqstr(tostr(LyXLength(length).value())));
520                 break;
521         }
522         default:
523                 skip = 0;
524                 break;
525         }
526         dialog_->layoutModule->skipCO->setCurrentItem(skip);
527         dialog_->setSkip(skip);
528
529         if (!params.options.empty()) {
530                 dialog_->layoutModule->optionsLE->setText(
531                         toqstr(params.options));
532         } else {
533                 dialog_->layoutModule->optionsLE->setText("");
534         }
535
536         // paper
537         int const psize = params.papersize2;
538         dialog_->paperModule->papersizeCO->setCurrentItem(psize);
539         dialog_->setMargins(psize);
540         dialog_->setCustomPapersize(psize);
541
542         bool const landscape =
543                 params.orientation == BufferParams::ORIENTATION_LANDSCAPE;
544         dialog_->paperModule->landscapeRB->setChecked(landscape);
545         dialog_->paperModule->portraitRB->setChecked(!landscape);
546
547         dialog_->paperModule->facingPagesCB->setChecked(
548                 params.sides == LyXTextClass::TwoSides);
549
550         dialog_->paperModule->twoColumnCB->setChecked(
551                 params.columns == 2);
552
553
554         lengthToWidgets(dialog_->paperModule->paperwidthLE,
555                 dialog_->paperModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
556
557         lengthToWidgets(dialog_->paperModule->paperheightLE,
558                 dialog_->paperModule->paperheightUnitCO, params.paperheight, defaultUnit);
559
560         // margins
561
562         MarginsModuleBase * m(dialog_->marginsModule);
563
564         int item = params.paperpackage;
565         if (params.use_geometry) {
566                 item = 1;
567         } else if (item > 0) {
568                 item = item + 1;
569         }
570         m->marginCO->setCurrentItem(item);
571         dialog_->setCustomMargins(item);
572
573         lengthToWidgets(m->topLE, m->topUnit,
574                 params.topmargin, defaultUnit);
575
576         lengthToWidgets(m->bottomLE, m->bottomUnit,
577                 params.bottommargin, defaultUnit);
578
579         lengthToWidgets(m->innerLE, m->innerUnit,
580                 params.leftmargin, defaultUnit);
581
582         lengthToWidgets(m->outerLE, m->outerUnit,
583                 params.rightmargin, defaultUnit);
584
585         lengthToWidgets(m->headheightLE, m->headheightUnit,
586                 params.headheight, defaultUnit);
587
588         lengthToWidgets(m->headsepLE, m->headsepUnit,
589                 params.headsep, defaultUnit);
590
591         lengthToWidgets(m->footskipLE, m->footskipUnit,
592                 params.footskip, defaultUnit);
593 }
594
595
596 void QDocument::saveDocDefault()
597 {
598         // we have to apply the params first
599         apply();
600         controller().saveAsDefault();
601 }
602
603
604 void QDocument::useClassDefaults()
605 {
606         BufferParams & params = controller().params();
607
608         params.textclass = dialog_->layoutModule->classCO->currentItem();
609         params.useClassDefaults();
610         update_contents();
611 }