]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTabular.cpp
Table dialog: Fix enabling/disabling of first header and last footer
[lyx.git] / src / frontends / qt4 / GuiTabular.cpp
1 /**
2  * \file GuiTabular.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Jürgen Spitzmüller
8  * \author Herbert Voß
9  * \author Uwe Stöhr
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "GuiTabular.h"
17
18 #include "GuiApplication.h"
19 #include "GuiSetBorder.h"
20 #include "GuiView.h"
21 #include "LengthCombo.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
24
25 #include "BufferView.h"
26 #include "Cursor.h"
27 #include "FuncRequest.h"
28 #include "FuncStatus.h"
29 #include "LyX.h"
30 #include "LyXRC.h"
31
32 #include "insets/InsetTabular.h"
33
34 #include "support/debug.h"
35
36 #include <QCheckBox>
37 #include <QPushButton>
38 #include <QRadioButton>
39 #include <QLineEdit>
40
41 using namespace std;
42
43 namespace lyx {
44 namespace frontend {
45
46 GuiTabular::GuiTabular(QWidget * parent)
47         : InsetParamsWidget(parent)
48 {
49         setupUi(this);
50
51         widthED->setValidator(unsignedLengthValidator(widthED));
52         topspaceED->setValidator(new LengthValidator(topspaceED));
53         bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
54         interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
55
56         widthUnitCB->setCurrentItem(Length::defaultUnit());
57
58         connect(topspaceED, SIGNAL(textEdited(QString)),
59                 this, SLOT(checkEnabled()));
60         connect(topspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
61                 this, SLOT(checkEnabled()));
62         connect(topspaceCO, SIGNAL(activated(int)),
63                 this, SLOT(checkEnabled()));
64         connect(bottomspaceED, SIGNAL(textEdited(QString)),
65                 this, SLOT(checkEnabled()));
66         connect(bottomspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
67                 this, SLOT(checkEnabled()));
68         connect(bottomspaceCO, SIGNAL(activated(int)),
69                 this, SLOT(checkEnabled()));
70         connect(interlinespaceED, SIGNAL(textEdited(QString)),
71                 this, SLOT(checkEnabled()));
72         connect(interlinespaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
73                 this, SLOT(checkEnabled()));
74         connect(interlinespaceCO, SIGNAL(activated(int)),
75                 this, SLOT(checkEnabled()));
76         connect(booktabsRB, SIGNAL(clicked(bool)),
77                 this, SLOT(checkEnabled()));
78         connect(borderDefaultRB, SIGNAL(clicked(bool)),
79                 this, SLOT(checkEnabled()));
80         connect(borderSetPB, SIGNAL(clicked()),
81                 this, SLOT(borderSet_clicked()));
82         connect(borderUnsetPB, SIGNAL(clicked()),
83                 this, SLOT(borderUnset_clicked()));
84         connect(hAlignCB, SIGNAL(activated(int)),
85                 this, SLOT(checkEnabled()));
86         connect(vAlignCB, SIGNAL(activated(int)),
87                 this, SLOT(checkEnabled()));
88         connect(multicolumnCB, SIGNAL(clicked()),
89                 this, SLOT(checkEnabled()));
90         connect(multirowCB, SIGNAL(clicked()),
91                 this, SLOT(checkEnabled()));
92         connect(newpageCB, SIGNAL(clicked()),
93                 this, SLOT(checkEnabled()));
94         connect(headerStatusCB, SIGNAL(clicked()),
95                 this, SLOT(checkEnabled()));
96         connect(headerBorderAboveCB, SIGNAL(clicked()),
97                 this, SLOT(checkEnabled()));
98         connect(headerBorderBelowCB, SIGNAL(clicked()),
99                 this, SLOT(checkEnabled()));
100         connect(firstheaderStatusCB, SIGNAL(clicked()),
101                 this, SLOT(checkEnabled()));
102         connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
103                 this, SLOT(checkEnabled()));
104         connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
105                 this, SLOT(checkEnabled()));
106         connect(firstheaderNoContentsCB, SIGNAL(clicked()),
107                 this, SLOT(checkEnabled()));
108         connect(footerStatusCB, SIGNAL(clicked()),
109                 this, SLOT(checkEnabled()));
110         connect(footerBorderAboveCB, SIGNAL(clicked()),
111                 this, SLOT(checkEnabled()));
112         connect(footerBorderBelowCB, SIGNAL(clicked()),
113                 this, SLOT(checkEnabled()));
114         connect(lastfooterStatusCB, SIGNAL(clicked()),
115                 this, SLOT(checkEnabled()));
116         connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
117                 this, SLOT(checkEnabled()));
118         connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
119                 this, SLOT(checkEnabled()));
120         connect(lastfooterNoContentsCB, SIGNAL(clicked()),
121                 this, SLOT(checkEnabled()));
122         connect(captionStatusCB, SIGNAL(clicked()),
123                 this, SLOT(checkEnabled()));
124         connect(specialAlignmentED, SIGNAL(textEdited(QString)),
125                 this, SLOT(checkEnabled()));
126         connect(widthED, SIGNAL(textEdited(QString)),
127                 this, SLOT(checkEnabled()));
128         connect(widthUnitCB, SIGNAL(selectionChanged(lyx::Length::UNIT)),
129                 this, SLOT(checkEnabled()));
130         connect(borders, SIGNAL(topSet(bool)),
131                 this, SLOT(checkEnabled()));
132         connect(borders, SIGNAL(bottomSet(bool)),
133                 this, SLOT(checkEnabled()));
134         connect(borders, SIGNAL(rightSet(bool)),
135                 this, SLOT(checkEnabled()));
136         connect(borders, SIGNAL(leftSet(bool)),
137                 this, SLOT(checkEnabled()));
138         connect(rotateTabularCB, SIGNAL(clicked()),
139                 this, SLOT(checkEnabled()));
140         connect(rotateCellCB, SIGNAL(clicked()),
141                 this, SLOT(checkEnabled()));
142         connect(TableAlignCB, SIGNAL(activated(int)),
143                 this, SLOT(checkEnabled()));
144         connect(longTabularCB, SIGNAL(clicked()),
145                 this, SLOT(checkEnabled()));
146         connect(leftRB, SIGNAL(clicked()),
147                 this, SLOT(checkEnabled()));
148         connect(centerRB, SIGNAL(clicked()),
149                 this, SLOT(checkEnabled()));
150         connect(rightRB, SIGNAL(clicked()),
151                 this, SLOT(checkEnabled()));
152
153
154         // initialize the length validator
155         addCheckedWidget(widthED, fixedWidthColLA);
156         addCheckedWidget(topspaceED, topspaceLA);
157         addCheckedWidget(bottomspaceED, bottomspaceLA);
158         addCheckedWidget(interlinespaceED, interlinespaceLA);
159 }
160
161
162 void GuiTabular::checkEnabled()
163 {
164         // multirows don't have their own alignment
165         hAlignCB->setEnabled(!multirowCB->isChecked());
166         bool dalign =
167                 hAlignCB->itemData(hAlignCB->currentIndex()).toString() == QString("decimal");
168         decimalPointLE->setEnabled(dalign);
169         decimalL->setEnabled(dalign);
170
171         vAlignCB->setEnabled(!multirowCB->isChecked()
172                 && !widgetsToLength(widthED, widthUnitCB).empty());
173
174         topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
175         topspaceUnit->setEnabled(topspaceCO->currentIndex() == 2);
176         bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
177         bottomspaceUnit->setEnabled(bottomspaceCO->currentIndex() == 2);
178         interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
179         interlinespaceUnit->setEnabled(interlinespaceCO->currentIndex() == 2);
180
181         // setting as longtable is not allowed when table is inside a float
182         longTabularCB->setEnabled(funcEnabled(Tabular::SET_LONGTABULAR));
183         bool const longtabular = longTabularCB->isChecked();
184         longtableGB->setEnabled(true);
185         newpageCB->setEnabled(longtabular);
186         alignmentGB->setEnabled(longtabular);
187         // longtables cannot have a vertical alignment
188         TableAlignCB->setDisabled(longtabular);
189
190         // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
191         // depending on the cursor position is very very unintuitive...
192         // We need some edit boxes to show which rows are header/footer/etc
193         // without having to move the cursor first.
194         headerStatusCB->setEnabled(longtabular);
195         headerBorderAboveCB->setEnabled(longtabular
196                 && headerStatusCB->isChecked());
197         headerBorderBelowCB->setEnabled(longtabular
198                 && headerStatusCB->isChecked());
199
200         firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
201         // check if setting a first header is allowed
202         // additionally check firstheaderNoContentsCB because when this is
203         // the case a first header makes no sense
204         firstheaderStatusCB->setEnabled(funcEnabled(Tabular::SET_LTFIRSTHEAD)
205                 && longtabular && !firstheaderNoContentsCB->isChecked());
206         firstheaderBorderAboveCB->setEnabled(longtabular
207                 && firstheaderStatusCB->isChecked());
208         firstheaderBorderBelowCB->setEnabled(longtabular
209                 && firstheaderStatusCB->isChecked());
210
211         footerStatusCB->setEnabled(longtabular);
212         footerBorderAboveCB->setEnabled(longtabular
213                 && footerBorderAboveCB->isChecked());
214         footerBorderBelowCB->setEnabled(longtabular
215                 && footerBorderAboveCB->isChecked());
216
217         lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
218         // check if setting a last footer is allowed
219         // additionally check lastfooterNoContentsCB because when this is
220         // the case a last footer makes no sense
221         lastfooterStatusCB->setEnabled(funcEnabled(Tabular::SET_LTLASTFOOT)
222                 && longtabular && !lastfooterNoContentsCB->isChecked());
223         lastfooterBorderAboveCB->setEnabled(longtabular
224                 && lastfooterBorderAboveCB->isChecked());
225         lastfooterBorderBelowCB->setEnabled(longtabular
226                 && lastfooterBorderAboveCB->isChecked());
227
228         captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
229                 && longtabular);
230
231         multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN));
232         multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW));
233
234         changed();
235 }
236
237
238 void GuiTabular::borderSet_clicked()
239 {
240         borders->setTop(true);
241         borders->setBottom(true);
242         borders->setLeft(true);
243         borders->setRight(true);
244         // repaint the setborder widget
245         borders->update();
246         checkEnabled();
247 }
248
249
250 void GuiTabular::borderUnset_clicked()
251 {
252         borders->setTop(false);
253         borders->setBottom(false);
254         borders->setLeft(false);
255         borders->setRight(false);
256         // repaint the setborder widget
257         borders->update();
258         checkEnabled();
259 }
260
261
262 static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
263 {
264         param_str += ' ';
265         param_str += featureAsString(f) + ' ' + arg;
266 }
267
268
269 void GuiTabular::setHAlign(string & param_str) const
270 {
271         Tabular::Feature num = Tabular::ALIGN_LEFT;
272         Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
273         string const align =
274                 fromqstr(hAlignCB->itemData(hAlignCB->currentIndex()).toString());
275         if (align == "left") {
276                 num = Tabular::ALIGN_LEFT;
277                 multi_num = Tabular::M_ALIGN_LEFT;
278         } else if (align == "center") {
279                 num = Tabular::ALIGN_CENTER;
280                 multi_num = Tabular::M_ALIGN_CENTER;
281         } else if (align == "right") {
282                 num = Tabular::ALIGN_RIGHT;
283                 multi_num = Tabular::M_ALIGN_RIGHT;
284         } else if (align == "justified") {
285                 num = Tabular::ALIGN_BLOCK;
286                 //multi_num: no equivalent
287         } else if (align == "decimal") {
288                 num = Tabular::ALIGN_DECIMAL;
289                 //multi_num: no equivalent
290         }
291
292         if (multicolumnCB->isChecked())
293                 setParam(param_str, multi_num);
294         else
295                 setParam(param_str, num);
296 }
297
298
299 void GuiTabular::setVAlign(string & param_str) const
300 {
301         int const align = vAlignCB->currentIndex();
302         enum VALIGN { TOP, MIDDLE, BOTTOM };
303         VALIGN v = TOP;
304
305         switch (align) {
306                 case 0: v = TOP; break;
307                 case 1: v = MIDDLE; break;
308                 case 2: v = BOTTOM; break;
309         }
310
311         Tabular::Feature num = Tabular::VALIGN_MIDDLE;
312         Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
313
314         switch (v) {
315                 case TOP:
316                         num = Tabular::VALIGN_TOP;
317                         multi_num = Tabular::M_VALIGN_TOP;
318                         break;
319                 case MIDDLE:
320                         num = Tabular::VALIGN_MIDDLE;
321                         multi_num = Tabular::M_VALIGN_MIDDLE;
322                         break;
323                 case BOTTOM:
324                         num = Tabular::VALIGN_BOTTOM;
325                         multi_num = Tabular::M_VALIGN_BOTTOM;
326                         break;
327         }
328         if (multicolumnCB->isChecked() || multirowCB->isChecked())
329                 setParam(param_str, multi_num);
330         else
331                 setParam(param_str, num);
332 }
333
334
335 void GuiTabular::setTableAlignment(string & param_str) const
336 {
337         int const align = TableAlignCB->currentIndex();
338         switch (align) {
339                 case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
340                         break;
341                 case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
342                         break;
343                 case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
344                         break;
345         }
346 }
347
348
349 docstring GuiTabular::dialogToParams() const
350 {
351         // FIXME: We should use Tabular directly.
352         string param_str = "tabular";
353         setHAlign(param_str);
354
355         // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
356         string decimal_point = fromqstr(decimalPointLE->text());
357         if (decimal_point.empty())
358                 decimal_point = lyxrc.default_decimal_point;
359         setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
360
361         setVAlign(param_str);
362         setTableAlignment(param_str);
363         //
364         if (booktabsRB->isChecked())
365                 setParam(param_str, Tabular::SET_BOOKTABS);
366         else
367                 setParam(param_str, Tabular::UNSET_BOOKTABS);
368
369         //
370         switch (topspaceCO->currentIndex()) {
371                 case 0:
372                         setParam(param_str, Tabular::SET_TOP_SPACE, "none");
373                         break;
374                 case 1:
375                         setParam(param_str, Tabular::SET_TOP_SPACE, "default");
376                         break;
377                 case 2:
378                         if (!topspaceED->text().isEmpty())
379                                 setParam(param_str, Tabular::SET_TOP_SPACE,
380                                          widgetsToLength(topspaceED, topspaceUnit));
381                         break;
382         }
383
384         //
385         switch (bottomspaceCO->currentIndex()) {
386                 case 0:
387                         setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
388                         break;
389                 case 1:
390                         setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
391                         break;
392                 case 2:
393                         if (!bottomspaceED->text().isEmpty())
394                                 setParam(param_str, Tabular::SET_BOTTOM_SPACE,
395                                         widgetsToLength(bottomspaceED,
396                                                         bottomspaceUnit));
397                         break;
398         }
399
400         //
401         switch (interlinespaceCO->currentIndex()) {
402                 case 0:
403                         setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
404                         break;
405                 case 1:
406                         setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
407                         break;
408                 case 2:
409                         if (!interlinespaceED->text().isEmpty())
410                                 setParam(param_str, Tabular::SET_INTERLINE_SPACE,
411                                         widgetsToLength(interlinespaceED,
412                                                         interlinespaceUnit));
413                         break;
414         }
415
416         //
417         if (borders->getTop() && borders->getBottom() && borders->getLeft()
418                 && borders->getRight())
419                 setParam(param_str, Tabular::SET_ALL_LINES);
420         else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
421                 && !borders->getRight())
422                 setParam(param_str, Tabular::UNSET_ALL_LINES);
423         else {
424                 setParam(param_str, Tabular::SET_LINE_LEFT,
425                          borders->getLeft() ? "true" : "false");
426                 setParam(param_str, Tabular::SET_LINE_RIGHT,
427                          borders->getRight() ? "true" : "false");
428                 setParam(param_str, Tabular::SET_LINE_TOP,
429                          borders->getTop() ? "true" : "false");
430                 setParam(param_str, Tabular::SET_LINE_BOTTOM,
431                          borders->getBottom() ? "true" : "false");
432         }
433
434         // apply the special alignment
435         string special = fromqstr(specialAlignmentED->text());
436         if (special.empty())
437                 special = "none";
438         if (multicolumnCB->isChecked())
439                 setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
440         else
441                 setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
442
443         // apply the fixed width values
444         string width = widgetsToLength(widthED, widthUnitCB);
445         if (width.empty())
446                 width = "0pt";
447         if (multicolumnCB->isChecked())
448                 setParam(param_str, Tabular::SET_MPWIDTH, width);
449         else
450                 setParam(param_str, Tabular::SET_PWIDTH, width);
451
452         //
453         if (multicolumnCB->isChecked())
454                 setParam(param_str, Tabular::SET_MULTICOLUMN);
455         else
456                 setParam(param_str, Tabular::UNSET_MULTICOLUMN);
457         //
458         if (multirowCB->isChecked())
459                 setParam(param_str, Tabular::SET_MULTIROW);
460         else
461                 setParam(param_str, Tabular::UNSET_MULTIROW);
462         //
463         if (rotateTabularCB->isChecked())
464                 setParam(param_str, Tabular::SET_ROTATE_TABULAR);
465         else
466                 setParam(param_str, Tabular::UNSET_ROTATE_TABULAR);
467         //
468         if (rotateCellCB->isChecked())
469                 setParam(param_str, Tabular::SET_ROTATE_CELL);
470         else
471                 setParam(param_str, Tabular::UNSET_ROTATE_CELL);
472         //
473         if (longTabularCB->isChecked())
474                 setParam(param_str, Tabular::SET_LONGTABULAR);
475         else
476                 setParam(param_str, Tabular::UNSET_LONGTABULAR);
477         //
478         if (newpageCB->isChecked())
479                 setParam(param_str, Tabular::SET_LTNEWPAGE);
480         //
481         if (captionStatusCB->isChecked())
482                 setParam(param_str, Tabular::SET_LTCAPTION);
483         else
484                 setParam(param_str, Tabular::UNSET_LTCAPTION);
485         //
486         if (headerStatusCB->isChecked())
487                 setParam(param_str, Tabular::SET_LTHEAD, "none");
488         else
489                 setParam(param_str, Tabular::UNSET_LTHEAD, "none");
490         //
491         if (headerBorderAboveCB->isChecked())
492                 setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
493         else
494                 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
495         //
496         if (headerBorderBelowCB->isChecked())
497                 setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
498         else
499                 setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
500         if (firstheaderBorderAboveCB->isChecked())
501                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
502         else
503                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
504         if (firstheaderBorderBelowCB->isChecked())
505                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
506         else
507                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
508         if (firstheaderStatusCB->isChecked())
509                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
510         else
511                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
512         if (firstheaderNoContentsCB->isChecked())
513                 setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
514         else
515                 setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
516         if (footerStatusCB->isChecked())
517                 setParam(param_str, Tabular::SET_LTFOOT, "none");
518         else
519                 setParam(param_str, Tabular::UNSET_LTFOOT, "none");
520         if (footerBorderAboveCB->isChecked())
521                 setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
522         else
523                 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
524         if (footerBorderBelowCB->isChecked())
525                 setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
526         else
527                 setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
528         if (lastfooterStatusCB->isChecked())
529                 setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
530         else
531                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
532         if (lastfooterBorderAboveCB->isChecked())
533                 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
534         else
535                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
536         if (lastfooterBorderBelowCB->isChecked())
537                 setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
538         else
539                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
540         if (lastfooterNoContentsCB->isChecked())
541                 setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
542         else
543                 setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
544
545         if (leftRB->isChecked())
546                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
547         else if (centerRB->isChecked())
548                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
549         else if (rightRB->isChecked())
550                 setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
551
552         return from_utf8(param_str);
553 }
554
555
556 static Length getColumnPWidth(Tabular const & t, size_t cell)
557 {
558         return t.column_info[t.cellColumn(cell)].p_width;
559 }
560
561
562 static Length getMColumnPWidth(Tabular const & t, size_t cell)
563 {
564         if (t.isMultiColumn(cell) || t.isMultiRow(cell))
565                 return t.cellInfo(cell).p_width;
566         return Length();
567 }
568
569
570 static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
571 {
572         if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
573                 return t.cellInfo(cell).align_special;
574         return t.column_info[t.cellColumn(cell)].align_special;
575 }
576
577
578 void GuiTabular::paramsToDialog(Inset const * inset)
579 {
580         InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
581         // Copy Tabular of current inset.
582         Tabular const & tabular = itab->tabular;
583
584         BufferView const * bv = guiApp->currentView()->currentBufferView();
585         size_t const cell = bv->cursor().idx();
586
587         Tabular::row_type const row = tabular.cellRow(cell);
588         Tabular::col_type const col = tabular.cellColumn(cell);
589
590         tabularRowED->setText(QString::number(row + 1));
591         tabularColumnED->setText(QString::number(col + 1));
592
593         bool const multicol = tabular.isMultiColumn(cell);
594         multicolumnCB->setChecked(multicol);
595
596         bool const multirow = tabular.isMultiRow(cell);
597         multirowCB->setChecked(multirow);
598
599         rotateCellCB->setChecked(tabular.getRotateCell(cell));
600         rotateTabularCB->setChecked(tabular.rotate);
601
602         longTabularCB->setChecked(tabular.is_long_tabular);
603
604         borders->setTop(tabular.topLine(cell));
605         borders->setBottom(tabular.bottomLine(cell));
606         borders->setLeft(tabular.leftLine(cell));
607         borders->setRight(tabular.rightLine(cell));
608         // repaint the setborder widget
609         borders->update();
610
611         Length::UNIT const default_unit = Length::defaultUnit();
612
613         ///////////////////////////////////
614         // Set width and alignment
615         Length pwidth;
616         docstring special;
617         if (multicol) {
618                 special = getAlignSpecial(tabular, cell,
619                         Tabular::SET_SPECIAL_MULTICOLUMN);
620                 pwidth = getMColumnPWidth(tabular, cell);
621         } else {
622                 special = getAlignSpecial(tabular, cell,
623                         Tabular::SET_SPECIAL_COLUMN);
624                 pwidth = getColumnPWidth(tabular, cell);
625         }
626         string colwidth;
627         if (pwidth.zero())
628                 widthED->clear();
629         else {
630                 colwidth = pwidth.asString();
631                 lengthToWidgets(widthED, widthUnitCB,
632                         colwidth, default_unit);
633         }
634         specialAlignmentED->setText(toqstr(special));
635         ///////////////////////////////////
636
637
638         borderDefaultRB->setChecked(!tabular.use_booktabs);
639         booktabsRB->setChecked(tabular.use_booktabs);
640
641         if (tabular.row_info[row].top_space.empty()
642             && !tabular.row_info[row].top_space_default) {
643                 topspaceCO->setCurrentIndex(0);
644         } else if (tabular.row_info[row].top_space_default) {
645                 topspaceCO->setCurrentIndex(1);
646         } else {
647                 topspaceCO->setCurrentIndex(2);
648                 lengthToWidgets(topspaceED,
649                                 topspaceUnit,
650                                 tabular.row_info[row].top_space.asString(),
651                                 default_unit);
652         }
653
654         if (tabular.row_info[row].bottom_space.empty()
655             && !tabular.row_info[row].bottom_space_default) {
656                 bottomspaceCO->setCurrentIndex(0);
657         } else if (tabular.row_info[row].bottom_space_default) {
658                 bottomspaceCO->setCurrentIndex(1);
659         } else {
660                 bottomspaceCO->setCurrentIndex(2);
661                 lengthToWidgets(bottomspaceED,
662                                 bottomspaceUnit,
663                                 tabular.row_info[row].bottom_space.asString(),
664                                 default_unit);
665         }
666
667         if (tabular.row_info[row].interline_space.empty()
668             && !tabular.row_info[row].interline_space_default) {
669                 interlinespaceCO->setCurrentIndex(0);
670         } else if (tabular.row_info[row].interline_space_default) {
671                 interlinespaceCO->setCurrentIndex(1);
672         } else {
673                 interlinespaceCO->setCurrentIndex(2);
674                 lengthToWidgets(interlinespaceED,
675                                 interlinespaceUnit,
676                                 tabular.row_info[row].interline_space.asString(),
677                                 default_unit);
678         }
679
680         hAlignCB->clear();
681         hAlignCB->addItem(qt_("Left"), toqstr("left"));
682         hAlignCB->addItem(qt_("Center"), toqstr("center"));
683         hAlignCB->addItem(qt_("Right"), toqstr("right"));
684         if (!multicol && !pwidth.zero())
685                 hAlignCB->addItem(qt_("Justified"), toqstr("justified"));
686         if (!multicol)
687                 hAlignCB->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
688
689         string align;
690         switch (tabular.getAlignment(cell)) {
691                 case LYX_ALIGN_LEFT:
692                         align = "left";
693                         break;
694                 case LYX_ALIGN_CENTER:
695                         align = "center";
696                         break;
697                 case LYX_ALIGN_RIGHT:
698                         align = "right";
699                         break;
700                 case LYX_ALIGN_BLOCK:
701                 {
702                         if (!multicol && !pwidth.zero())
703                                 align = "justified";
704                         break;
705                 }
706                 case LYX_ALIGN_DECIMAL:
707                 {
708                         if (!multicol)
709                                 align = "decimal";
710                         break;
711                 }
712                 default:
713                         // we should never end up here
714                         break;
715         }
716         hAlignCB->setCurrentIndex(hAlignCB->findData(toqstr(align)));
717
718         //
719         QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
720         if (decimal_point.isEmpty())
721                 decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
722         decimalPointLE->setText(decimal_point);
723
724         int valign = 0;
725         switch (tabular.getVAlignment(cell)) {
726         case Tabular::LYX_VALIGN_TOP:
727                 valign = 0;
728                 break;
729         case Tabular::LYX_VALIGN_MIDDLE:
730                 valign = 1;
731                 break;
732         case Tabular::LYX_VALIGN_BOTTOM:
733                 valign = 2;
734                 break;
735         default:
736                 valign = 0;
737                 break;
738         }
739         if (pwidth.zero())
740                 valign = 0;
741         vAlignCB->setCurrentIndex(valign);
742
743         int tableValign = 1;
744         switch (tabular.tabular_valignment) {
745         case Tabular::LYX_VALIGN_TOP:
746                 tableValign = 0;
747                 break;
748         case Tabular::LYX_VALIGN_MIDDLE:
749                 tableValign = 1;
750                 break;
751         case Tabular::LYX_VALIGN_BOTTOM:
752                 tableValign = 2;
753                 break;
754         default:
755                 tableValign = 0;
756                 break;
757         }
758         TableAlignCB->setCurrentIndex(tableValign);
759
760         if (!tabular.is_long_tabular) {
761                 headerStatusCB->setChecked(false);
762                 headerBorderAboveCB->setChecked(false);
763                 headerBorderBelowCB->setChecked(false);
764                 firstheaderStatusCB->setChecked(false);
765                 firstheaderBorderAboveCB->setChecked(false);
766                 firstheaderBorderBelowCB->setChecked(false);
767                 firstheaderNoContentsCB->setChecked(false);
768                 footerStatusCB->setChecked(false);
769                 footerBorderAboveCB->setChecked(false);
770                 footerBorderBelowCB->setChecked(false);
771                 lastfooterStatusCB->setChecked(false);
772                 lastfooterBorderAboveCB->setChecked(false);
773                 lastfooterBorderBelowCB->setChecked(false);
774                 lastfooterNoContentsCB->setChecked(false);
775                 newpageCB->setChecked(false);
776                 captionStatusCB->blockSignals(true);
777                 captionStatusCB->setChecked(false);
778                 captionStatusCB->blockSignals(false);
779                 checkEnabled();
780                 return;
781         } else {
782                 // longtables cannot have a vertical alignment
783                 TableAlignCB->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
784         }
785         switch (tabular.longtabular_alignment) {
786         case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
787                 leftRB->setChecked(true);
788                 break;
789         case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
790                 centerRB->setChecked(true);
791                 break;
792         case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
793                 rightRB->setChecked(true);
794                 break;
795         default:
796                 centerRB->setChecked(true);
797                 break;
798         }
799         captionStatusCB->blockSignals(true);
800         captionStatusCB->setChecked(tabular.ltCaption(row));
801         captionStatusCB->blockSignals(false);
802
803         Tabular::ltType ltt;
804         bool use_empty;
805         bool row_set = tabular.getRowOfLTHead(row, ltt);
806         headerStatusCB->setChecked(row_set);
807         if (ltt.set) {
808                 headerBorderAboveCB->setChecked(ltt.topDL);
809                 headerBorderBelowCB->setChecked(ltt.bottomDL);
810                 use_empty = true;
811         } else {
812                 headerBorderAboveCB->setChecked(false);
813                 headerBorderBelowCB->setChecked(false);
814                 firstheaderNoContentsCB->setChecked(false);
815                 use_empty = false;
816         }
817
818         row_set = tabular.getRowOfLTFirstHead(row, ltt);
819         firstheaderStatusCB->setChecked(row_set);
820         if (ltt.set && (!ltt.empty || !use_empty)) {
821                 firstheaderBorderAboveCB->setChecked(ltt.topDL);
822                 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
823         } else {
824                 firstheaderBorderAboveCB->setChecked(false);
825                 firstheaderBorderBelowCB->setChecked(false);
826         }
827
828         row_set = tabular.getRowOfLTFoot(row, ltt);
829         footerStatusCB->setChecked(row_set);
830         if (ltt.set) {
831                 footerBorderAboveCB->setChecked(ltt.topDL);
832                 footerBorderBelowCB->setChecked(ltt.bottomDL);
833                 use_empty = true;
834         } else {
835                 footerBorderAboveCB->setChecked(false);
836                 footerBorderBelowCB->setChecked(false);
837                 lastfooterNoContentsCB->setChecked(false);
838                 use_empty = false;
839         }
840
841         row_set = tabular.getRowOfLTLastFoot(row, ltt);
842         lastfooterStatusCB->setChecked(row_set);
843         if (ltt.set && (!ltt.empty || !use_empty)) {
844                 lastfooterBorderAboveCB->setChecked(ltt.topDL);
845                 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
846         } else {
847                 lastfooterBorderAboveCB->setChecked(false);
848                 lastfooterBorderBelowCB->setChecked(false);
849         }
850         newpageCB->setChecked(tabular.getLTNewPage(row));
851
852         // first header can only be suppressed when there is a header
853         firstheader_suppressable_ = tabular.haveLTHead()
854                         && !tabular.haveLTFirstHead();
855         // last footer can only be suppressed when there is a footer
856         lastfooter_suppressable_ = tabular.haveLTFoot()
857                         && !tabular.haveLTLastFoot();
858
859         // after setting the features, check if they are enabled
860         checkEnabled();
861 }
862
863
864 bool GuiTabular::funcEnabled(Tabular::Feature f) const
865 {
866         string cmd = "tabular " + featureAsString(f);
867         return getStatus(FuncRequest(LFUN_INSET_MODIFY, cmd)).enabled();
868 }
869
870
871 } // namespace frontend
872 } // namespace lyx
873
874 #include "moc_GuiTabular.cpp"