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