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