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