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