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