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