]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QDocument.C
widthcache ting
[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 "gettext.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(_("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(_("Author-year"));
70         dialog_->biblioModule->citeStyleCO->insertItem(_("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                         lit->first.c_str());
80         }
81
82         dialog_->langModule->quoteStyleCO->insertItem(_("``text''"));
83         dialog_->langModule->quoteStyleCO->insertItem(_("''text''"));
84         dialog_->langModule->quoteStyleCO->insertItem(_(",,text``"));
85         dialog_->langModule->quoteStyleCO->insertItem(_(",,text''"));
86         dialog_->langModule->quoteStyleCO->insertItem(_("«text»"));
87         dialog_->langModule->quoteStyleCO->insertItem(_("»text«"));
88
89         // packages
90         char const * items[] = {"default", "auto", "latin1", "latin2",
91                              "latin3", "latin4", "latin5", "latin9",
92                              "koi8-r", "koi8-u", "cp866", "cp1251",
93                              "iso88595", "pt154", 0};
94         dialog_->packagesModule->encodingCO->insertStrList(items);
95
96         dialog_->packagesModule->lspacingCO->insertItem(
97                 _("Single"), Spacing::Single);
98         dialog_->packagesModule->lspacingCO->insertItem(
99                 _("OneHalf"), Spacing::Onehalf);
100         dialog_->packagesModule->lspacingCO->insertItem(
101                 _("Double"), Spacing::Double);
102         dialog_->packagesModule->lspacingCO->insertItem(
103                 _("Custom"), Spacing::Other);
104
105         for (int n = 0; tex_graphics[n][0]; ++n) {
106                 QString enc = tex_graphics[n];
107                 dialog_->packagesModule->psdriverCO->insertItem(enc);
108         }
109
110         // paper
111         char const * sizes[] = {
112                 _("Default") , _("Custom") , _("US letter") , _("US legal")
113                    , _("US executive") , _("A3") , _("A4") , _("A5")
114                    , _("B3") , _("B4") , _("B5"), 0 };
115         dialog_->paperModule->papersizeCO->insertStrList(sizes);
116
117         // layout
118         for (LyXTextClassList::const_iterator cit = textclasslist.begin();
119              cit != textclasslist.end(); ++cit) {
120                 dialog_->layoutModule->classCO->insertItem(cit->description().c_str());
121         }
122
123         for (int n = 0; tex_fonts[n][0]; ++n) {
124                 QString font = tex_fonts[n];
125                 dialog_->layoutModule->fontsCO->insertItem(font);
126         }
127
128         dialog_->layoutModule->fontsizeCO->insertItem(_("default"));
129         dialog_->layoutModule->fontsizeCO->insertItem(_("10"));
130         dialog_->layoutModule->fontsizeCO->insertItem(_("11"));
131         dialog_->layoutModule->fontsizeCO->insertItem(_("12"));
132
133         dialog_->layoutModule->skipCO->insertItem(_("Smallskip"));
134         dialog_->layoutModule->skipCO->insertItem(_("Medskip"));
135         dialog_->layoutModule->skipCO->insertItem(_("Bigskip"));
136         dialog_->layoutModule->skipCO->insertItem(_("Length"));
137
138         dialog_->layoutModule->pagestyleCO->insertItem(_("default"));
139         dialog_->layoutModule->pagestyleCO->insertItem(_("empty"));
140         dialog_->layoutModule->pagestyleCO->insertItem(_("plain"));
141         dialog_->layoutModule->pagestyleCO->insertItem(_("headings"));
142         dialog_->layoutModule->pagestyleCO->insertItem(_("fancy"));
143
144         // margins
145         dialog_->setMargins(0);
146
147         // Manage the restore, ok, apply, restore and cancel/close buttons
148         bc().setOK(dialog_->okPB);
149         bc().setApply(dialog_->applyPB);
150         bc().setCancel(dialog_->closePB);
151         bc().setRestore(dialog_->restorePB);
152 }
153
154
155 void QDocument::apply()
156 {
157         BufferParams & params = controller().params();
158
159         // preamble
160         params.preamble =
161                 dialog_->preambleModule->preambleMLE->text().latin1();
162
163         // biblio
164         params.use_natbib =
165                 dialog_->biblioModule->natbibCB->isChecked();
166         params.use_numerical_citations  =
167                 dialog_->biblioModule->citeStyleCO->currentItem();
168
169         // language & quotes
170         if (dialog_->langModule->singleQuoteRB->isChecked())
171                 params.quotes_times = InsetQuotes::SingleQ;
172         else
173                 params.quotes_times = InsetQuotes::DoubleQ;
174
175
176         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
177         switch (dialog_->langModule->quoteStyleCO->currentItem()) {
178         case 0:
179                 lga = InsetQuotes::EnglishQ;
180                 break;
181         case 1:
182                 lga = InsetQuotes::SwedishQ;
183                 break;
184         case 2:
185                 lga = InsetQuotes::GermanQ;
186                 break;
187         case 3:
188                 lga = InsetQuotes::PolishQ;
189                 break;
190         case 4:
191                 lga = InsetQuotes::FrenchQ;
192                 break;
193         case 5:
194                 lga = InsetQuotes::DanishQ;
195                 break;
196         }
197         params.quotes_language = lga;
198
199         int const pos = dialog_->langModule->languageCO->currentItem();
200         params.language = languages.getLanguage(lang_[pos]);
201
202         // numbering
203         params.secnumdepth =
204                 dialog_->numberingModule->tocDepthSB->value();
205         params.tocdepth =
206                 dialog_->numberingModule->sectionnrDepthSB->value();
207
208         // bullets
209         params.user_defined_bullets[0].setText(dialog_->bulletsModule->bullet1LE->text().latin1());
210         params.user_defined_bullets[1].setText(dialog_->bulletsModule->bullet2LE->text().latin1());
211         params.user_defined_bullets[2].setText(dialog_->bulletsModule->bullet3LE->text().latin1());
212         params.user_defined_bullets[3].setText(dialog_->bulletsModule->bullet4LE->text().latin1());
213
214         params.user_defined_bullets[0].setSize(dialog_->bulletsModule->bulletsize1CO->currentItem()-1);
215         params.user_defined_bullets[1].setSize(dialog_->bulletsModule->bulletsize2CO->currentItem()-1);
216         params.user_defined_bullets[2].setSize(dialog_->bulletsModule->bulletsize3CO->currentItem()-1);
217         params.user_defined_bullets[3].setSize(dialog_->bulletsModule->bulletsize4CO->currentItem()-1);
218
219         // packages
220         switch (dialog_->packagesModule->lspacingCO->currentItem()) {
221         case 0:
222                 params.spacing.set(Spacing::Single);
223                 break;
224         case 1:
225                 params.spacing.set(Spacing::Onehalf);
226                 break;
227         case 2:
228                 params.spacing.set(Spacing::Double);
229                 break;
230         case 3:
231                 params.spacing.set(Spacing::Other,
232                                    dialog_->packagesModule->
233                                    lspacingLE->text().toFloat()
234                                    );
235                 break;
236         }
237
238         params.graphicsDriver =
239                 dialog_->packagesModule->psdriverCO->currentText().latin1();
240
241         params.use_amsmath =
242                 dialog_->packagesModule->amsCB->isChecked();
243
244         params.inputenc =
245                 dialog_->packagesModule->encodingCO->currentText().latin1();
246
247         // layout
248         params.textclass =
249                 dialog_->layoutModule->classCO->currentItem();
250
251         //bool succes = controller().classApply();
252
253         params.fonts =
254                 dialog_->layoutModule->fontsCO->currentText().latin1();
255
256         params.fontsize =
257                 dialog_->layoutModule->fontsizeCO->currentText().latin1();
258
259         params.pagestyle =
260                 dialog_->layoutModule->pagestyleCO->currentText().latin1();
261
262         if (dialog_->layoutModule->indentRB->isChecked())
263                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
264         else
265                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
266
267         switch (dialog_->layoutModule->skipCO->currentItem()) {
268         case 0:
269                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
270                 break;
271         case 1:
272                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
273                 break;
274         case 2:
275                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
276                 break;
277         case 3:
278         {
279                 LyXLength::UNIT unit =
280                         dialog_->layoutModule->skipLengthCO->
281                         currentLengthItem();
282                 double length =
283                         dialog_->layoutModule->skipLE->text().toDouble();
284                 VSpace vs = VSpace(LyXGlueLength(LyXLength(length,unit)));
285                 params.setDefSkip(vs);
286                 break;
287         }
288         default:
289                 // DocumentDefskipCB assures that this never happens
290                 // so Assert then !!!  - jbl
291                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
292                 break;
293         }
294
295         params.options =
296                 dialog_->layoutModule->optionsLE->text().latin1();
297
298         params.float_placement =
299                 dialog_->layoutModule->floatPlacementLE->text().latin1();
300
301         // paper
302         params.papersize2 =
303                 dialog_->paperModule->papersizeCO->currentItem();
304
305         params.paperwidth = widgetsToLength(dialog_->paperModule->paperwidthLE,
306                 dialog_->paperModule->paperwidthUnitCO);
307
308         params.paperheight = widgetsToLength(dialog_->paperModule->paperheightLE,
309                 dialog_->paperModule->paperheightUnitCO);
310
311         if (dialog_->paperModule->twoColumnCB->isChecked())
312                 params.columns = 2;
313         else
314                 params.columns = 1;
315
316         if (dialog_->paperModule->facingPagesCB->isChecked())
317                 params.sides = LyXTextClass::TwoSides;
318         else
319                 params.sides = LyXTextClass::OneSide;
320
321         if (dialog_->paperModule->landscapeRB->isChecked())
322                 params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
323         else
324                 params.orientation = BufferParams::ORIENTATION_PORTRAIT;
325
326         // margins
327         params.use_geometry =
328                 (dialog_->marginsModule->marginCO->currentItem() == 1);
329
330         int margin = dialog_->marginsModule->marginCO->currentItem();
331         if (margin > 0) {
332                 margin = margin - 1;
333         }
334         params.paperpackage = char(margin);
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 = params.preamble.c_str();
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         // numbering
424         dialog_->numberingModule->tocDepthSB->setValue(
425                 params.secnumdepth);
426         dialog_->numberingModule->sectionnrDepthSB->setValue(
427                 params.tocdepth);
428
429         // bullets
430         QString s;
431         s = params.user_defined_bullets[0].getText().c_str();
432         dialog_->bulletsModule->bullet1LE->setText(s);
433         s = params.user_defined_bullets[1].getText().c_str();
434         dialog_->bulletsModule->bullet2LE->setText(s);
435         s = params.user_defined_bullets[2].getText().c_str();
436         dialog_->bulletsModule->bullet3LE->setText(s);
437         s = params.user_defined_bullets[3].getText().c_str();
438         dialog_->bulletsModule->bullet4LE->setText(s);
439
440         dialog_->bulletsModule->bulletsize1CO->setCurrentItem(
441                 params.user_defined_bullets[0].getSize() + 1);
442         dialog_->bulletsModule->bulletsize2CO->setCurrentItem(
443                 params.user_defined_bullets[1].getSize() + 1);
444         dialog_->bulletsModule->bulletsize3CO->setCurrentItem(
445                 params.user_defined_bullets[2].getSize() + 1);
446         dialog_->bulletsModule->bulletsize4CO->setCurrentItem(
447                 params.user_defined_bullets[3].getSize() + 1);
448
449         // packages
450         char const * enc[] = {
451                 "default" , "auto" , "latin1" , "latin2" , "latin3" ,
452                 "latin4" , "latin5" , "latin9" , "koi8-r" , "koi8-u" ,
453                 "cp866" , "cp1251" , "iso88595" , "pt154" };
454         for (size_t i = 0; i < sizeof(enc)/sizeof(char *); ++i) {
455                 if (params.inputenc == enc[i])
456                         dialog_->packagesModule->encodingCO->setCurrentItem(i);
457         }
458
459         QString text = params.graphicsDriver.c_str();
460         int nitem = dialog_->packagesModule->psdriverCO->count();
461         for (int n = 0; n < nitem ; ++n) {
462                 QString enc = tex_graphics[n];
463                 if (enc == text) {
464                         dialog_->packagesModule->psdriverCO->setCurrentItem(n);
465                 }
466         }
467
468
469         dialog_->packagesModule->amsCB->setChecked(
470                 params.use_amsmath);
471
472         switch (params.spacing.getSpace()) {
473                 case Spacing::Other: nitem = 3; break;
474                 case Spacing::Double: nitem = 2; break;
475                 case Spacing::Onehalf: nitem = 1; break;
476                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
477         }
478
479         dialog_->packagesModule->lspacingCO->setCurrentItem(nitem);
480         if (params.spacing.getSpace() == Spacing::Other) {
481                 dialog_->packagesModule->lspacingLE->setText(
482                         tostr(params.spacing.getValue()).c_str());
483                 dialog_->setLSpacing(3);
484         }
485
486         // layout
487         for (int n = 0; n<dialog_->layoutModule->classCO->count(); ++n) {
488                 if (dialog_->layoutModule->classCO->text(n) ==
489                     controller().textClass().description().c_str()) {
490                         dialog_->layoutModule->classCO->setCurrentItem(n);
491                         break;
492                 }
493         }
494
495         dialog_->updateFontsize(controller().textClass().opt_fontsize(),
496                                 params.fontsize);
497
498         dialog_->updatePagestyle(controller().textClass().opt_pagestyle(),
499                                  params.pagestyle);
500
501         for (int n = 0; tex_fonts[n][0]; ++n) {
502                 if (tex_fonts[n] == params.fonts) {
503                         dialog_->layoutModule->fontsCO->setCurrentItem(n);
504                         break;
505                 }
506         }
507
508         if (params.paragraph_separation
509             == BufferParams::PARSEP_INDENT) {
510                 dialog_->layoutModule->indentRB->setChecked(true);
511         } else {
512                 dialog_->layoutModule->skipRB->setChecked(true);
513         }
514
515         int skip = 0;
516         switch (params.getDefSkip().kind()) {
517         case VSpace::SMALLSKIP:
518                 skip = 0;
519                 break;
520         case VSpace::MEDSKIP:
521                 skip = 1;
522                 break;
523         case VSpace::BIGSKIP:
524                 skip = 2;
525                 break;
526         case VSpace::LENGTH:
527         {
528                 skip = 3;
529                 string const length = params.getDefSkip().asLyXCommand();
530                 dialog_->layoutModule->skipLengthCO->setCurrentItem(LyXLength(length).unit());
531                 dialog_->layoutModule->skipLE->setText(tostr(LyXLength(length).value()).c_str());
532                 break;
533         }
534         default:
535                 skip = 0;
536                 break;
537         }
538         dialog_->layoutModule->skipCO->setCurrentItem(skip);
539         dialog_->setSkip(skip);
540
541         if (!params.options.empty()) {
542                 dialog_->layoutModule->optionsLE->setText(
543                         params.options.c_str());
544         } else {
545                 dialog_->layoutModule->optionsLE->setText("");
546         }
547
548         // paper
549         int const psize = params.papersize2;
550         dialog_->paperModule->papersizeCO->setCurrentItem(psize);
551         dialog_->setMargins(psize);
552         dialog_->setCustomPapersize(psize);
553
554         bool const landscape =
555                 params.orientation == BufferParams::ORIENTATION_LANDSCAPE;
556         dialog_->paperModule->landscapeRB->setChecked(landscape);
557         dialog_->paperModule->portraitRB->setChecked(!landscape);
558
559         dialog_->paperModule->facingPagesCB->setChecked(
560                 params.sides == LyXTextClass::TwoSides);
561
562         dialog_->paperModule->twoColumnCB->setChecked(
563                 params.columns == 2);
564
565
566         lengthToWidgets(dialog_->paperModule->paperwidthLE,
567                 dialog_->paperModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
568
569         lengthToWidgets(dialog_->paperModule->paperheightLE,
570                 dialog_->paperModule->paperheightUnitCO, params.paperheight, defaultUnit);
571
572         // margins
573
574         MarginsModuleBase * m(dialog_->marginsModule);
575
576         int item = params.paperpackage;
577         if (params.use_geometry) {
578                 item = 1;
579         } else if (item > 0) {
580                 item = item + 1;
581         }
582         m->marginCO->setCurrentItem(item);
583         dialog_->setCustomMargins(item);
584
585         lengthToWidgets(m->topLE, m->topUnit,
586                 params.topmargin, defaultUnit);
587
588         lengthToWidgets(m->bottomLE, m->bottomUnit,
589                 params.bottommargin, defaultUnit);
590
591         lengthToWidgets(m->innerLE, m->innerUnit,
592                 params.leftmargin, defaultUnit);
593
594         lengthToWidgets(m->outerLE, m->outerUnit,
595                 params.rightmargin, defaultUnit);
596
597         lengthToWidgets(m->headheightLE, m->headheightUnit,
598                 params.headheight, defaultUnit);
599
600         lengthToWidgets(m->headsepLE, m->headsepUnit,
601                 params.headsep, defaultUnit);
602
603         lengthToWidgets(m->footskipLE, m->footskipUnit,
604                 params.footskip, defaultUnit);
605 }
606
607
608 void QDocument::saveDocDefault()
609 {
610         // we have to apply the params first
611         apply();
612         controller().saveAsDefault();
613 }
614
615
616 void QDocument::useClassDefaults()
617 {
618         BufferParams & params = controller().params();
619
620         params.textclass = dialog_->layoutModule->classCO->currentItem();
621         params.useClassDefaults();
622         update_contents();
623 }