]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTabular.cpp
Complete the removal of the embedding stuff. Maybe. It's hard to be sure we got every...
[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  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiTabular.h"
16
17 #include "BufferView.h"
18 #include "Cursor.h"
19 #include "FuncRequest.h"
20 #include "GuiSetBorder.h"
21 #include "LengthCombo.h"
22 #include "LyXRC.h"
23 #include "qt_helpers.h"
24 #include "Validator.h"
25
26 #include "insets/InsetTabular.h"
27
28 #include <QCheckBox>
29 #include <QPushButton>
30 #include <QRadioButton>
31 #include <QLineEdit>
32
33 using namespace std;
34
35 namespace lyx {
36 namespace frontend {
37
38 GuiTabular::GuiTabular(GuiView & lv)
39         : GuiDialog(lv, "tabular", qt_("Table Settings"))
40 {
41         active_cell_ = Tabular::npos;
42
43         setupUi(this);
44
45         widthED->setValidator(unsignedLengthValidator(widthED));
46         topspaceED->setValidator(new LengthValidator(topspaceED));
47         bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
48         interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
49
50         connect(topspaceED, SIGNAL(returnPressed()),
51                 this, SLOT(topspace_changed()));
52         connect(topspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
53                 this, SLOT(topspace_changed()));
54         connect(topspaceCO, SIGNAL(activated(int)), this, SLOT(topspace_changed()));
55         connect(bottomspaceED, SIGNAL(returnPressed()),
56                 this, SLOT(bottomspace_changed()));
57         connect(bottomspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
58                 this, SLOT(bottomspace_changed()));
59         connect(bottomspaceCO, SIGNAL(activated(int)), this, SLOT(bottomspace_changed()));
60         connect(interlinespaceED, SIGNAL(returnPressed()),
61                 this, SLOT(interlinespace_changed()));
62         connect(interlinespaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
63                 this, SLOT(interlinespace_changed()));
64         connect(interlinespaceCO, SIGNAL(activated(int)), this, SLOT(interlinespace_changed()));
65         connect(booktabsRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
66         connect(borderDefaultRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
67         connect(borderSetPB, SIGNAL(clicked()), this, SLOT(borderSet_clicked()));
68         connect(borderUnsetPB, SIGNAL(clicked()), this, SLOT(borderUnset_clicked()));
69         connect(longTabularCB, SIGNAL(toggled(bool)), longtableGB, SLOT(setEnabled(bool)));
70         connect(longTabularCB, SIGNAL(toggled(bool)), newpageCB, SLOT(setEnabled(bool)));
71         connect(hAlignCB, SIGNAL(activated(int)), this, SLOT(hAlign_changed(int)));
72         connect(vAlignCB, SIGNAL(activated(int)), this, SLOT(vAlign_changed(int)));
73         connect(multicolumnCB, SIGNAL(clicked()), this, SLOT(multicolumn_clicked()));
74         connect(newpageCB, SIGNAL(clicked()), this, SLOT(ltNewpage_clicked()));
75         connect(headerStatusCB, SIGNAL(clicked()), this, SLOT(ltHeaderStatus_clicked()));
76         connect(headerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderAbove_clicked()));
77         connect(headerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderBelow_clicked()));
78         connect(firstheaderStatusCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderStatus_clicked()));
79         connect(firstheaderBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderAbove_clicked()));
80         connect(firstheaderBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderBelow_clicked()));
81         connect(firstheaderNoContentsCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderEmpty_clicked()));
82         connect(footerStatusCB, SIGNAL(clicked()), this, SLOT(ltFooterStatus_clicked()));
83         connect(footerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderAbove_clicked()));
84         connect(footerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderBelow_clicked()));
85         connect(lastfooterStatusCB, SIGNAL(clicked()), this, SLOT(ltLastFooterStatus_clicked()));
86         connect(lastfooterBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderAbove_clicked()));
87         connect(lastfooterBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderBelow_clicked()));
88         connect(lastfooterNoContentsCB, SIGNAL(clicked()), this, SLOT(ltLastFooterEmpty_clicked()));
89         connect(specialAlignmentED, SIGNAL(returnPressed()), this, SLOT(specialAlignment_changed()));
90         connect(widthED, SIGNAL(returnPressed()), this, SLOT(width_changed()));
91         connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)), this, SLOT(width_changed()));
92         connect(closePB, SIGNAL(clicked()), this, SLOT(close_clicked()));
93         connect(borders, SIGNAL(topSet(bool)), this, SLOT(topBorder_changed()));
94         connect(borders, SIGNAL(bottomSet(bool)), this, SLOT(bottomBorder_changed()));
95         connect(borders, SIGNAL(rightSet(bool)), this, SLOT(rightBorder_changed()));
96         connect(borders, SIGNAL(leftSet(bool)), this, SLOT(leftBorder_changed()));
97         connect(rotateTabularCB, SIGNAL(clicked()), this, SLOT(rotateTabular()));
98         connect(rotateCellCB, SIGNAL(clicked()), this, SLOT(rotateCell()));
99         connect(longTabularCB, SIGNAL(clicked()), this, SLOT(longTabular()));
100
101         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
102         bc().setCancel(closePB);
103
104         bc().addReadOnly(topspaceED);
105         bc().addReadOnly(topspaceUnit);
106         bc().addReadOnly(topspaceCO);
107         bc().addReadOnly(bottomspaceED);
108         bc().addReadOnly(bottomspaceUnit);
109         bc().addReadOnly(bottomspaceCO);
110         bc().addReadOnly(interlinespaceED);
111         bc().addReadOnly(interlinespaceUnit);
112         bc().addReadOnly(interlinespaceCO);
113         bc().addReadOnly(borderDefaultRB);
114         bc().addReadOnly(booktabsRB);
115
116         bc().addReadOnly(multicolumnCB);
117         bc().addReadOnly(rotateCellCB);
118         bc().addReadOnly(rotateTabularCB);
119         bc().addReadOnly(specialAlignmentED);
120         bc().addReadOnly(widthED);
121         bc().addReadOnly(widthUnit);
122         bc().addReadOnly(hAlignCB);
123         bc().addReadOnly(vAlignCB);
124         bc().addReadOnly(borderSetPB);
125         bc().addReadOnly(borderUnsetPB);
126         bc().addReadOnly(borders);
127         bc().addReadOnly(longTabularCB);
128         bc().addReadOnly(headerStatusCB);
129         bc().addReadOnly(headerBorderAboveCB);
130         bc().addReadOnly(headerBorderBelowCB);
131         bc().addReadOnly(firstheaderStatusCB);
132         bc().addReadOnly(firstheaderBorderAboveCB);
133         bc().addReadOnly(firstheaderBorderBelowCB);
134         bc().addReadOnly(firstheaderNoContentsCB);
135         bc().addReadOnly(footerStatusCB);
136         bc().addReadOnly(footerBorderAboveCB);
137         bc().addReadOnly(footerBorderBelowCB);
138         bc().addReadOnly(lastfooterStatusCB);
139         bc().addReadOnly(lastfooterBorderAboveCB);
140         bc().addReadOnly(lastfooterBorderBelowCB);
141         bc().addReadOnly(lastfooterNoContentsCB);
142         bc().addReadOnly(newpageCB);
143
144         // initialize the length validator
145         bc().addCheckedLineEdit(widthED, fixedWidthColLA);
146         bc().addCheckedLineEdit(topspaceED, topspaceLA);
147         bc().addCheckedLineEdit(bottomspaceED, bottomspaceLA);
148         bc().addCheckedLineEdit(interlinespaceED, interlinespaceLA);
149 }
150
151
152 GuiTabular::~GuiTabular()
153 {
154 }
155
156
157 void GuiTabular::change_adaptor()
158 {
159         changed();
160 }
161
162
163 void GuiTabular::booktabsChanged(bool)
164 {
165         changed();
166         booktabs(booktabsRB->isChecked());
167         update_borders();
168 }
169
170
171 void GuiTabular::topspace_changed()
172 {
173         switch (topspaceCO->currentIndex()) {
174                 case 0: {
175                         set(Tabular::SET_TOP_SPACE, "");
176                         topspaceED->setEnabled(false);
177                         topspaceUnit->setEnabled(false);
178                         break;
179                 }
180                 case 1: {
181                         set(Tabular::SET_TOP_SPACE, "default");
182                         topspaceED->setEnabled(false);
183                         topspaceUnit->setEnabled(false);
184                         break;
185                 }
186                 case 2: {
187                         if (!topspaceED->text().isEmpty())
188                                 set(Tabular::SET_TOP_SPACE,
189                                         widgetsToLength(topspaceED, topspaceUnit));
190                         if (!bc().policy().isReadOnly()) {
191                                 topspaceED->setEnabled(true);
192                                 topspaceUnit->setEnabled(true);
193                         }
194                         break;
195                 }
196         }
197         changed();
198 }
199
200
201 void GuiTabular::bottomspace_changed()
202 {
203         switch (bottomspaceCO->currentIndex()) {
204                 case 0: {
205                         set(Tabular::SET_BOTTOM_SPACE, "");
206                                 bottomspaceED->setEnabled(false);
207                                 bottomspaceUnit->setEnabled(false);
208                         break;
209                 }
210                 case 1: {
211                         set(Tabular::SET_BOTTOM_SPACE, "default");
212                         bottomspaceED->setEnabled(false);
213                         bottomspaceUnit->setEnabled(false);
214                         break;
215                 }
216                 case 2: {
217                         if (!bottomspaceED->text().isEmpty())
218                                 set(Tabular::SET_BOTTOM_SPACE,
219                                         widgetsToLength(bottomspaceED, bottomspaceUnit));
220                         if (!bc().policy().isReadOnly()) {
221                                 bottomspaceED->setEnabled(true);
222                                 bottomspaceUnit->setEnabled(true);
223                         }
224                         break;
225                 }
226         }
227         changed();
228 }
229
230
231 void GuiTabular::interlinespace_changed()
232 {
233         switch (interlinespaceCO->currentIndex()) {
234                 case 0: {
235                         set(Tabular::SET_INTERLINE_SPACE, "");
236                                 interlinespaceED->setEnabled(false);
237                                 interlinespaceUnit->setEnabled(false);
238                         break;
239                 }
240                 case 1: {
241                         set(Tabular::SET_INTERLINE_SPACE, "default");
242                         interlinespaceED->setEnabled(false);
243                         interlinespaceUnit->setEnabled(false);
244                         break;
245                 }
246                 case 2: {
247                         if (!interlinespaceED->text().isEmpty())
248                                 set(Tabular::SET_INTERLINE_SPACE,
249                                         widgetsToLength(interlinespaceED, interlinespaceUnit));
250                         if (!bc().policy().isReadOnly()) {
251                                 interlinespaceED->setEnabled(true);
252                                 interlinespaceUnit->setEnabled(true);
253                         }
254                         break;
255                 }
256         }
257         changed();
258 }
259
260
261 void GuiTabular::close_clicked()
262 {
263         closeGUI();
264         slotClose();
265 }
266
267
268 void GuiTabular::borderSet_clicked()
269 {
270         set(Tabular::SET_ALL_LINES);
271         update_borders();
272         changed();
273 }
274
275
276 void GuiTabular::borderUnset_clicked()
277 {
278         set(Tabular::UNSET_ALL_LINES);
279         update_borders();
280         changed();
281 }
282
283
284 void GuiTabular::leftBorder_changed()
285 {
286         set(Tabular::TOGGLE_LINE_LEFT);
287         changed();
288 }
289
290
291 void GuiTabular::rightBorder_changed()
292 {
293         set(Tabular::TOGGLE_LINE_RIGHT);
294         changed();
295 }
296
297
298 void GuiTabular::topBorder_changed()
299 {
300         set(Tabular::TOGGLE_LINE_TOP);
301         changed();
302 }
303
304
305 void GuiTabular::bottomBorder_changed()
306 {
307         set(Tabular::TOGGLE_LINE_BOTTOM);
308         changed();
309 }
310
311
312 void GuiTabular::specialAlignment_changed()
313 {
314         string special = fromqstr(specialAlignmentED->text());
315         setSpecial(special);
316         changed();
317 }
318
319
320 void GuiTabular::width_changed()
321 {
322         changed();
323         string const width = widgetsToLength(widthED, widthUnit);
324         setWidth(width);
325 }
326
327
328 void GuiTabular::multicolumn_clicked()
329 {
330         toggleMultiColumn();
331         changed();
332 }
333
334
335 void GuiTabular::rotateTabular()
336 {
337         rotateTabular(rotateTabularCB->isChecked());
338         changed();
339 }
340
341
342 void GuiTabular::rotateCell()
343 {
344         rotateCell(rotateCellCB->isChecked());
345         changed();
346 }
347
348
349 void GuiTabular::hAlign_changed(int align)
350 {
351         GuiTabular::HALIGN h = GuiTabular::LEFT;
352
353         switch (align) {
354                 case 0: h = GuiTabular::LEFT; break;
355                 case 1: h = GuiTabular::CENTER; break;
356                 case 2: h = GuiTabular::RIGHT; break;
357                 case 3: h = GuiTabular::BLOCK; break;
358         }
359
360         halign(h);
361 }
362
363
364 void GuiTabular::vAlign_changed(int align)
365 {
366         GuiTabular::VALIGN v = GuiTabular::TOP;
367
368         switch (align) {
369                 case 0: v = GuiTabular::TOP; break;
370                 case 1: v = GuiTabular::MIDDLE; break;
371                 case 2: v = GuiTabular::BOTTOM; break;
372         }
373
374         valign(v);
375 }
376
377
378 void GuiTabular::longTabular()
379 {
380         longTabular(longTabularCB->isChecked());
381         changed();
382 }
383
384
385 void GuiTabular::ltNewpage_clicked()
386 {
387         set(Tabular::SET_LTNEWPAGE);
388         changed();
389 }
390
391
392 void GuiTabular::ltHeaderStatus_clicked()
393 {
394         bool enable = headerStatusCB->isChecked();
395         if (enable)
396                 set(Tabular::SET_LTHEAD, "");
397         else
398                 set(Tabular::UNSET_LTHEAD, "");
399         headerBorderAboveCB->setEnabled(enable);
400         headerBorderBelowCB->setEnabled(enable);
401         firstheaderNoContentsCB->setEnabled(enable);
402         changed();
403 }
404
405
406 void GuiTabular::ltHeaderBorderAbove_clicked()
407 {
408         if (headerBorderAboveCB->isChecked())
409                 set(Tabular::SET_LTHEAD, "dl_above");
410         else
411                 set(Tabular::UNSET_LTHEAD, "dl_above");
412         changed();
413 }
414
415
416 void GuiTabular::ltHeaderBorderBelow_clicked()
417 {
418         if (headerBorderBelowCB->isChecked())
419                 set(Tabular::SET_LTHEAD, "dl_below");
420         else
421                 set(Tabular::UNSET_LTHEAD, "dl_below");
422         changed();
423 }
424
425
426 void GuiTabular::ltFirstHeaderBorderAbove_clicked()
427 {
428         if (firstheaderBorderAboveCB->isChecked())
429                 set(Tabular::SET_LTFIRSTHEAD, "dl_above");
430         else
431                 set(Tabular::UNSET_LTFIRSTHEAD, "dl_above");
432         changed();
433 }
434
435
436 void GuiTabular::ltFirstHeaderBorderBelow_clicked()
437 {
438         if (firstheaderBorderBelowCB->isChecked())
439                 set(Tabular::SET_LTFIRSTHEAD, "dl_below");
440         else
441                 set(Tabular::UNSET_LTFIRSTHEAD, "dl_below");
442         changed();
443 }
444
445
446 void GuiTabular::ltFirstHeaderStatus_clicked()
447 {
448         bool enable = firstheaderStatusCB->isChecked();
449         if (enable)
450                 set(Tabular::SET_LTFIRSTHEAD, "");
451         else
452                 set(Tabular::UNSET_LTFIRSTHEAD, "");
453         firstheaderBorderAboveCB->setEnabled(enable);
454         firstheaderBorderBelowCB->setEnabled(enable);
455         changed();
456 }
457
458
459 void GuiTabular::ltFirstHeaderEmpty_clicked()
460 {
461         bool enable = firstheaderNoContentsCB->isChecked();
462         if (enable)
463                 set(Tabular::SET_LTFIRSTHEAD, "empty");
464         else
465                 set(Tabular::UNSET_LTFIRSTHEAD, "empty");
466         firstheaderStatusCB->setEnabled(!enable);
467         firstheaderBorderAboveCB->setEnabled(!enable);
468         firstheaderBorderBelowCB->setEnabled(!enable);
469         changed();
470 }
471
472
473 void GuiTabular::ltFooterStatus_clicked()
474 {
475         bool enable = footerStatusCB->isChecked();
476         if (enable)
477                 set(Tabular::SET_LTFOOT, "");
478         else
479                 set(Tabular::UNSET_LTFOOT, "");
480         footerBorderAboveCB->setEnabled(enable);
481         footerBorderBelowCB->setEnabled(enable);
482         lastfooterNoContentsCB->setEnabled(enable);
483         changed();
484 }
485
486
487 void GuiTabular::ltFooterBorderAbove_clicked()
488 {
489         if (footerBorderAboveCB->isChecked())
490                 set(Tabular::SET_LTFOOT, "dl_above");
491         else
492                 set(Tabular::UNSET_LTFOOT, "dl_above");
493         changed();
494 }
495
496
497 void GuiTabular::ltFooterBorderBelow_clicked()
498 {
499         if (footerBorderBelowCB->isChecked())
500                 set(Tabular::SET_LTFOOT, "dl_below");
501         else
502                 set(Tabular::UNSET_LTFOOT, "dl_below");
503         changed();
504 }
505
506
507 void GuiTabular::ltLastFooterStatus_clicked()
508 {
509         bool enable = lastfooterStatusCB->isChecked();
510         if (enable)
511                 set(Tabular::SET_LTLASTFOOT, "");
512         else
513                 set(Tabular::UNSET_LTLASTFOOT, "");
514         lastfooterBorderAboveCB->setEnabled(enable);
515         lastfooterBorderBelowCB->setEnabled(enable);
516         changed();
517 }
518
519
520 void GuiTabular::ltLastFooterBorderAbove_clicked()
521 {
522         if (lastfooterBorderAboveCB->isChecked())
523                 set(Tabular::SET_LTLASTFOOT, "dl_above");
524         else
525                 set(Tabular::UNSET_LTLASTFOOT, "dl_above");
526         changed();
527 }
528
529
530 void GuiTabular::ltLastFooterBorderBelow_clicked()
531 {
532         if (lastfooterBorderBelowCB->isChecked())
533                 set(Tabular::SET_LTLASTFOOT, "dl_below");
534         else
535                 set(Tabular::UNSET_LTLASTFOOT, "dl_below");
536         changed();
537 }
538
539
540 void GuiTabular::ltLastFooterEmpty_clicked()
541 {
542         bool enable = lastfooterNoContentsCB->isChecked();
543         if (enable)
544                 set(Tabular::SET_LTLASTFOOT, "empty");
545         else
546                 set(Tabular::UNSET_LTLASTFOOT, "empty");
547         lastfooterStatusCB->setEnabled(!enable);
548         lastfooterBorderAboveCB->setEnabled(!enable);
549         lastfooterBorderBelowCB->setEnabled(!enable);
550         changed();
551 }
552
553
554 void GuiTabular::update_borders()
555 {
556         Tabular::idx_type const cell = getActiveCell();
557         borders->setTop(tabular_.topLine(cell));
558         borders->setBottom(tabular_.bottomLine(cell));
559         borders->setLeft(tabular_.leftLine(cell));
560         borders->setRight(tabular_.rightLine(cell));
561         // repaint the setborder widget
562         borders->update();
563 }
564
565
566 void GuiTabular::updateContents()
567 {
568         initialiseParams(string());
569
570         Tabular::idx_type const cell = getActiveCell();
571
572         Tabular::row_type const row = tabular_.cellRow(cell);
573         Tabular::col_type const col = tabular_.cellColumn(cell);
574
575         tabularRowED->setText(QString::number(row + 1));
576         tabularColumnED->setText(QString::number(col + 1));
577
578         bool const multicol(tabular_.isMultiColumn(cell));
579
580         multicolumnCB->setChecked(multicol);
581
582         rotateCellCB->setChecked(tabular_.getRotateCell(cell));
583         rotateTabularCB->setChecked(tabular_.getRotateTabular());
584
585         longTabularCB->setChecked(tabular_.isLongTabular());
586
587         update_borders();
588
589         Length pwidth;
590         docstring special;
591
592         if (multicol) {
593                 special = tabular_.getAlignSpecial(cell, Tabular::SET_SPECIAL_MULTI);
594                 pwidth = tabular_.getMColumnPWidth(cell);
595         } else {
596                 special = tabular_.getAlignSpecial(cell, Tabular::SET_SPECIAL_COLUMN);
597                 pwidth = tabular_.getColumnPWidth(cell);
598         }
599
600         specialAlignmentED->setText(toqstr(special));
601
602         bool const isReadonly = bc().policy().isReadOnly();
603         specialAlignmentED->setEnabled(!isReadonly);
604
605         Length::UNIT default_unit =
606                 useMetricUnits() ? Length::CM : Length::IN;
607
608         borderDefaultRB->setChecked(!tabular_.useBookTabs());
609         booktabsRB->setChecked(tabular_.useBookTabs());
610
611         if (tabular_.row_info[row].top_space.empty()
612             && !tabular_.row_info[row].top_space_default) {
613                 topspaceCO->setCurrentIndex(0);
614         } else if (tabular_.row_info[row].top_space_default) {
615                 topspaceCO->setCurrentIndex(1);
616         } else {
617                 topspaceCO->setCurrentIndex(2);
618                 lengthToWidgets(topspaceED,
619                                 topspaceUnit,
620                                 tabular_.row_info[row].top_space.asString(),
621                                 default_unit);
622         }
623         topspaceED->setEnabled(!isReadonly
624                 && (topspaceCO->currentIndex() == 2));
625         topspaceUnit->setEnabled(!isReadonly
626                 && (topspaceCO->currentIndex() == 2));
627         topspaceCO->setEnabled(!isReadonly);
628
629         if (tabular_.row_info[row].bottom_space.empty()
630             && !tabular_.row_info[row].bottom_space_default) {
631                 bottomspaceCO->setCurrentIndex(0);
632         } else if (tabular_.row_info[row].bottom_space_default) {
633                 bottomspaceCO->setCurrentIndex(1);
634         } else {
635                 bottomspaceCO->setCurrentIndex(2);
636                 lengthToWidgets(bottomspaceED,
637                                 bottomspaceUnit,
638                                 tabular_.row_info[row].bottom_space.asString(),
639                                 default_unit);
640         }
641         bottomspaceED->setEnabled(!isReadonly
642                 && (bottomspaceCO->currentIndex() == 2));
643         bottomspaceUnit->setEnabled(!isReadonly
644                 && (bottomspaceCO->currentIndex() == 2));
645         bottomspaceCO->setEnabled(!isReadonly);
646
647         if (tabular_.row_info[row].interline_space.empty()
648             && !tabular_.row_info[row].interline_space_default) {
649                 interlinespaceCO->setCurrentIndex(0);
650         } else if (tabular_.row_info[row].interline_space_default) {
651                 interlinespaceCO->setCurrentIndex(1);
652         } else {
653                 interlinespaceCO->setCurrentIndex(2);
654                 lengthToWidgets(interlinespaceED,
655                                 interlinespaceUnit,
656                                 tabular_.row_info[row].interline_space.asString(),
657                                 default_unit);
658         }
659         interlinespaceED->setEnabled(!isReadonly
660                 && (interlinespaceCO->currentIndex() == 2));
661         interlinespaceUnit->setEnabled(!isReadonly
662                 && (interlinespaceCO->currentIndex() == 2));
663         interlinespaceCO->setEnabled(!isReadonly);
664
665         string colwidth;
666         if (!pwidth.zero())
667                 colwidth = pwidth.asString();
668         lengthToWidgets(widthED, widthUnit,
669                 colwidth, default_unit);
670
671         widthED->setEnabled(!isReadonly);
672         widthUnit->setEnabled(!isReadonly);
673
674         hAlignCB->clear();
675         hAlignCB->addItem(qt_("Left"));
676         hAlignCB->addItem(qt_("Center"));
677         hAlignCB->addItem(qt_("Right"));
678         if (!multicol && !pwidth.zero())
679                 hAlignCB->addItem(qt_("Justified"));
680
681         int align = 0;
682         switch (tabular_.getAlignment(cell)) {
683         case LYX_ALIGN_LEFT:
684                 align = 0;
685                 break;
686         case LYX_ALIGN_CENTER:
687                 align = 1;
688                 break;
689         case LYX_ALIGN_RIGHT:
690                 align = 2;
691                 break;
692         case LYX_ALIGN_BLOCK:
693         {
694                 if (!multicol && !pwidth.zero())
695                         align = 3;
696                 break;
697         }
698         default:
699                 align = 0;
700                 break;
701         }
702         hAlignCB->setCurrentIndex(align);
703
704         int valign = 0;
705         switch (tabular_.getVAlignment(cell)) {
706         case Tabular::LYX_VALIGN_TOP:
707                 valign = 0;
708                 break;
709         case Tabular::LYX_VALIGN_MIDDLE:
710                 valign = 1;
711                 break;
712         case Tabular::LYX_VALIGN_BOTTOM:
713                 valign = 2;
714                 break;
715         default:
716                 valign = 1;
717                 break;
718         }
719         if (pwidth.zero())
720                 valign = 1;
721         vAlignCB->setCurrentIndex(valign);
722
723         hAlignCB->setEnabled(true);
724         vAlignCB->setEnabled(!pwidth.zero());
725
726         if (!tabular_.isLongTabular()) {
727                 headerStatusCB->setChecked(false);
728                 headerBorderAboveCB->setChecked(false);
729                 headerBorderBelowCB->setChecked(false);
730                 firstheaderStatusCB->setChecked(false);
731                 firstheaderBorderAboveCB->setChecked(false);
732                 firstheaderBorderBelowCB->setChecked(false);
733                 firstheaderNoContentsCB->setChecked(false);
734                 footerStatusCB->setChecked(false);
735                 footerBorderAboveCB->setChecked(false);
736                 footerBorderBelowCB->setChecked(false);
737                 lastfooterStatusCB->setChecked(false);
738                 lastfooterBorderAboveCB->setChecked(false);
739                 lastfooterBorderBelowCB->setChecked(false);
740                 lastfooterNoContentsCB->setChecked(false);
741                 newpageCB->setChecked(false);
742                 newpageCB->setEnabled(false);
743                 return;
744         }
745
746         Tabular::ltType ltt;
747         bool use_empty;
748         bool row_set = tabular_.getRowOfLTHead(row, ltt);
749         headerStatusCB->setChecked(row_set);
750         if (ltt.set) {
751                 headerBorderAboveCB->setChecked(ltt.topDL);
752                 headerBorderBelowCB->setChecked(ltt.bottomDL);
753                 use_empty = true;
754         } else {
755                 headerBorderAboveCB->setChecked(false);
756                 headerBorderBelowCB->setChecked(false);
757                 headerBorderAboveCB->setEnabled(false);
758                 headerBorderBelowCB->setEnabled(false);
759                 firstheaderNoContentsCB->setChecked(false);
760                 firstheaderNoContentsCB->setEnabled(false);
761                 use_empty = false;
762         }
763
764         row_set = tabular_.getRowOfLTFirstHead(row, ltt);
765         firstheaderStatusCB->setChecked(row_set);
766         if (ltt.set && (!ltt.empty || !use_empty)) {
767                 firstheaderBorderAboveCB->setChecked(ltt.topDL);
768                 firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
769         } else {
770                 firstheaderBorderAboveCB->setEnabled(false);
771                 firstheaderBorderBelowCB->setEnabled(false);
772                 firstheaderBorderAboveCB->setChecked(false);
773                 firstheaderBorderBelowCB->setChecked(false);
774                 if (use_empty) {
775                         firstheaderNoContentsCB->setChecked(ltt.empty);
776                         if (ltt.empty)
777                                 firstheaderStatusCB->setEnabled(false);
778                 }
779         }
780
781         row_set = tabular_.getRowOfLTFoot(row, ltt);
782         footerStatusCB->setChecked(row_set);
783         if (ltt.set) {
784                 footerBorderAboveCB->setChecked(ltt.topDL);
785                 footerBorderBelowCB->setChecked(ltt.bottomDL);
786                 use_empty = true;
787         } else {
788                 footerBorderAboveCB->setChecked(false);
789                 footerBorderBelowCB->setChecked(false);
790                 footerBorderAboveCB->setEnabled(false);
791                 footerBorderBelowCB->setEnabled(false);
792                 lastfooterNoContentsCB->setChecked(false);
793                 lastfooterNoContentsCB->setEnabled(false);
794                 use_empty = false;
795         }
796
797         row_set = tabular_.getRowOfLTLastFoot(row, ltt);
798                 lastfooterStatusCB->setChecked(row_set);
799         if (ltt.set && (!ltt.empty || !use_empty)) {
800                 lastfooterBorderAboveCB->setChecked(ltt.topDL);
801                 lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
802         } else {
803                 lastfooterBorderAboveCB->setEnabled(false);
804                 lastfooterBorderBelowCB->setEnabled(false);
805                 lastfooterBorderAboveCB->setChecked(false);
806                 lastfooterBorderBelowCB->setChecked(false);
807                 if (use_empty) {
808                         lastfooterNoContentsCB->setChecked(ltt.empty);
809                         if (ltt.empty)
810                                 lastfooterStatusCB->setEnabled(false);
811                 }
812         }
813         newpageCB->setChecked(tabular_.getLTNewPage(row));
814 }
815
816
817 void GuiTabular::closeGUI()
818 {
819         // ugly hack to auto-apply the stuff that hasn't been
820         // yet. don't let this continue to exist ...
821
822         // Subtle here, we must /not/ apply any changes and
823         // then refer to tabular, as it will have been freed
824         // since the changes update the actual tabular_
825         //
826         // apply the fixed width values
827         Tabular::idx_type const cell = getActiveCell();
828         bool const multicol = tabular_.isMultiColumn(cell);
829         string width = widgetsToLength(widthED, widthUnit);
830         string width2;
831
832         Length llen = tabular_.getColumnPWidth(cell);
833         Length llenMulti = tabular_.getMColumnPWidth(cell);
834
835         if (multicol && !llenMulti.zero())
836                 width2 = llenMulti.asString();
837         else if (!multicol && !llen.zero())
838                 width2 = llen.asString();
839
840         // apply the special alignment
841         docstring const sa1 = qstring_to_ucs4(specialAlignmentED->text());
842         docstring sa2;
843
844         if (multicol)
845                 sa2 = tabular_.getAlignSpecial(cell, Tabular::SET_SPECIAL_MULTI);
846         else
847                 sa2 = tabular_.getAlignSpecial(cell, Tabular::SET_SPECIAL_COLUMN);
848
849         if (sa1 != sa2) {
850                 if (multicol)
851                         set(Tabular::SET_SPECIAL_MULTI, to_utf8(sa1));
852                 else
853                         set(Tabular::SET_SPECIAL_COLUMN, to_utf8(sa1));
854         }
855
856         if (width != width2) {
857                 if (multicol)
858                         set(Tabular::SET_MPWIDTH, width);
859                 else
860                         set(Tabular::SET_PWIDTH, width);
861         }
862
863         /* DO WE NEED THIS?
864         switch (topspaceCO->currentIndex()) {
865                 case 0:
866                         set(Tabular::SET_TOP_SPACE, "");
867                         break;
868                 case 1:
869                         set(Tabular::SET_TOP_SPACE, "default");
870                         break;
871                 case 2:
872                         set(Tabular::SET_TOP_SPACE,
873                                 widgetsToLength(topspaceED, topspaceUnit));
874                         break;
875         }
876
877         switch (bottomspaceCO->currentIndex()) {
878                 case 0:
879                         set(Tabular::SET_BOTTOM_SPACE, "");
880                         break;
881                 case 1:
882                         set(Tabular::SET_BOTTOM_SPACE, "default");
883                         break;
884                 case 2:
885                         set(Tabular::SET_BOTTOM_SPACE,
886                                 widgetsToLength(bottomspaceED, bottomspaceUnit));
887                         break;
888         }
889
890         switch (interlinespaceCO->currentIndex()) {
891                 case 0:
892                         set(Tabular::SET_INTERLINE_SPACE, "");
893                         break;
894                 case 1:
895                         set(Tabular::SET_INTERLINE_SPACE, "default");
896                         break;
897                 case 2:
898                         set(Tabular::SET_INTERLINE_SPACE,
899                                 widgetsToLength(interlinespaceED, interlinespaceUnit));
900                         break;
901         }
902 */
903 }
904
905
906 bool GuiTabular::initialiseParams(string const & data)
907 {
908         // try to get the current cell
909         BufferView const * const bv = bufferview();
910         InsetTabular const * current_inset = 0;
911         if (bv) {
912                 Cursor const & cur = bv->cursor();
913                 // get the innermost tabular inset;
914                 // assume that it is "ours"
915                 for (int i = cur.depth() - 1; i >= 0; --i)
916                         if (cur[i].inset().lyxCode() == TABULAR_CODE) {
917                                 current_inset = static_cast<InsetTabular const *>(&cur[i].inset());
918                                 active_cell_ = cur[i].idx();
919                                 break;
920                         }
921         }
922
923         if (current_inset && data.empty()) {
924                 tabular_ = Tabular(current_inset->tabular);
925                 return true;
926         }
927
928         InsetTabular tmp(buffer());
929         InsetTabular::string2params(data, tmp);
930         tabular_ = Tabular(tmp.tabular);
931         return true;
932 }
933
934
935 void GuiTabular::clearParams()
936 {
937         InsetTabular tmp(buffer());
938         tabular_ = tmp.tabular;
939         active_cell_ = Tabular::npos;
940 }
941
942
943 Tabular::idx_type GuiTabular::getActiveCell() const
944 {
945         return active_cell_;
946 }
947
948
949 void GuiTabular::set(Tabular::Feature f, string const & arg)
950 {
951         string const data = featureAsString(f) + ' ' + arg;
952         dispatch(FuncRequest(getLfun(), data));
953 }
954
955
956 bool GuiTabular::useMetricUnits() const
957 {
958         return lyxrc.default_papersize > PAPER_USEXECUTIVE;
959 }
960
961
962 void GuiTabular::setSpecial(string const & special)
963 {
964         if (tabular_.isMultiColumn(getActiveCell()))
965                 set(Tabular::SET_SPECIAL_MULTI, special);
966         else
967                 set(Tabular::SET_SPECIAL_COLUMN, special);
968 }
969
970
971 void GuiTabular::setWidth(string const & width)
972 {
973         if (tabular_.isMultiColumn(getActiveCell()))
974                 set(Tabular::SET_MPWIDTH, width);
975         else
976                 set(Tabular::SET_PWIDTH, width);
977
978         updateView();
979 }
980
981
982 void GuiTabular::toggleMultiColumn()
983 {
984         set(Tabular::MULTICOLUMN);
985         updateView();
986 }
987
988
989 void GuiTabular::rotateTabular(bool yes)
990 {
991         if (yes)
992                 set(Tabular::SET_ROTATE_TABULAR);
993         else
994                 set(Tabular::UNSET_ROTATE_TABULAR);
995 }
996
997
998 void GuiTabular::rotateCell(bool yes)
999 {
1000         if (yes)
1001                 set(Tabular::SET_ROTATE_CELL);
1002         else
1003                 set(Tabular::UNSET_ROTATE_CELL);
1004 }
1005
1006
1007 void GuiTabular::halign(GuiTabular::HALIGN h)
1008 {
1009         Tabular::Feature num = Tabular::ALIGN_LEFT;
1010         Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
1011
1012         switch (h) {
1013                 case LEFT:
1014                         num = Tabular::ALIGN_LEFT;
1015                         multi_num = Tabular::M_ALIGN_LEFT;
1016                         break;
1017                 case CENTER:
1018                         num = Tabular::ALIGN_CENTER;
1019                         multi_num = Tabular::M_ALIGN_CENTER;
1020                         break;
1021                 case RIGHT:
1022                         num = Tabular::ALIGN_RIGHT;
1023                         multi_num = Tabular::M_ALIGN_RIGHT;
1024                         break;
1025                 case BLOCK:
1026                         num = Tabular::ALIGN_BLOCK;
1027                         //multi_num: no equivalent
1028                         break;
1029         }
1030
1031         if (tabular_.isMultiColumn(getActiveCell()))
1032                 set(multi_num);
1033         else
1034                 set(num);
1035 }
1036
1037
1038 void GuiTabular::valign(GuiTabular::VALIGN v)
1039 {
1040         Tabular::Feature num = Tabular::VALIGN_MIDDLE;
1041         Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
1042
1043         switch (v) {
1044                 case TOP:
1045                         num = Tabular::VALIGN_TOP;
1046                         multi_num = Tabular::M_VALIGN_TOP;
1047                         break;
1048                 case MIDDLE:
1049                         num = Tabular::VALIGN_MIDDLE;
1050                         multi_num = Tabular::M_VALIGN_MIDDLE;
1051                         break;
1052                 case BOTTOM:
1053                         num = Tabular::VALIGN_BOTTOM;
1054                         multi_num = Tabular::M_VALIGN_BOTTOM;
1055                         break;
1056         }
1057
1058         if (tabular_.isMultiColumn(getActiveCell()))
1059                 set(multi_num);
1060         else
1061                 set(num);
1062 }
1063
1064
1065 void GuiTabular::booktabs(bool yes)
1066 {
1067         if (yes)
1068                 set(Tabular::SET_BOOKTABS);
1069         else
1070                 set(Tabular::UNSET_BOOKTABS);
1071 }
1072
1073
1074 void GuiTabular::longTabular(bool yes)
1075 {
1076         if (yes)
1077                 set(Tabular::SET_LONGTABULAR);
1078         else
1079                 set(Tabular::UNSET_LONGTABULAR);
1080 }
1081
1082
1083 Dialog * createGuiTabular(GuiView & lv) { return new GuiTabular(lv); }
1084
1085
1086 } // namespace frontend
1087 } // namespace lyx
1088
1089 #include "GuiTabular_moc.cpp"