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