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