]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTabular.cpp
renaming of some methods that hurt the eyes + removal of:
[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 "GuiSetBorder.h"
18 #include "LengthCombo.h"
19 #include "Validator.h"
20 #include "qt_helpers.h"
21
22 #include "support/convert.h"
23
24 #include <QCloseEvent>
25 #include <QCheckBox>
26 #include <QPushButton>
27 #include <QRadioButton>
28 #include <QLineEdit>
29
30 using std::string;
31
32 namespace lyx {
33 namespace frontend {
34
35 /////////////////////////////////////////////////////////////////////
36 //
37 // GuiTabularDialog
38 //
39 /////////////////////////////////////////////////////////////////////
40
41 GuiTabularDialog::GuiTabularDialog(GuiTabular * form)
42         : form_(form)
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
103
104 void GuiTabularDialog::change_adaptor()
105 {
106         form_->changed();
107 }
108
109
110 void GuiTabularDialog::closeEvent(QCloseEvent * e)
111 {
112         form_->slotWMHide();
113         e->accept();
114 }
115
116
117 void GuiTabularDialog::booktabsChanged(bool)
118 {
119         form_->changed();
120         form_->controller().booktabs(booktabsRB->isChecked());
121         form_->update_borders();
122 }
123
124
125 void GuiTabularDialog::topspace_changed()
126 {
127         switch(topspaceCO->currentIndex()) {
128                 case 0: {
129                         form_->controller().set(Tabular::SET_TOP_SPACE, "");
130                                 topspaceED->setEnabled(false);
131                                 topspaceUnit->setEnabled(false);
132                         break;
133                 }
134                 case 1: {
135                         form_->controller().set(Tabular::SET_TOP_SPACE, "default");
136                         topspaceED->setEnabled(false);
137                         topspaceUnit->setEnabled(false);
138                         break;
139                 }
140                 case 2: {
141                         if (!topspaceED->text().isEmpty())
142                                 form_->controller().set(Tabular::SET_TOP_SPACE,
143                                         widgetsToLength(topspaceED, topspaceUnit));
144                         if (!form_->bc().policy().isReadOnly()) {
145                                 topspaceED->setEnabled(true);
146                                 topspaceUnit->setEnabled(true);
147                         }
148                         break;
149                 }
150         }
151         form_->changed();
152 }
153
154
155 void GuiTabularDialog::bottomspace_changed()
156 {
157         switch(bottomspaceCO->currentIndex()) {
158                 case 0: {
159                         form_->controller().set(Tabular::SET_BOTTOM_SPACE, "");
160                                 bottomspaceED->setEnabled(false);
161                                 bottomspaceUnit->setEnabled(false);
162                         break;
163                 }
164                 case 1: {
165                         form_->controller().set(Tabular::SET_BOTTOM_SPACE, "default");
166                         bottomspaceED->setEnabled(false);
167                         bottomspaceUnit->setEnabled(false);
168                         break;
169                 }
170                 case 2: {
171                         if (!bottomspaceED->text().isEmpty())
172                                 form_->controller().set(Tabular::SET_BOTTOM_SPACE,
173                                         widgetsToLength(bottomspaceED, bottomspaceUnit));
174                         if (!form_->bc().policy().isReadOnly()) {
175                                 bottomspaceED->setEnabled(true);
176                                 bottomspaceUnit->setEnabled(true);
177                         }
178                         break;
179                 }
180         }
181         form_->changed();
182 }
183
184
185 void GuiTabularDialog::interlinespace_changed()
186 {
187         switch(interlinespaceCO->currentIndex()) {
188                 case 0: {
189                         form_->controller().set(Tabular::SET_INTERLINE_SPACE, "");
190                                 interlinespaceED->setEnabled(false);
191                                 interlinespaceUnit->setEnabled(false);
192                         break;
193                 }
194                 case 1: {
195                         form_->controller().set(Tabular::SET_INTERLINE_SPACE, "default");
196                         interlinespaceED->setEnabled(false);
197                         interlinespaceUnit->setEnabled(false);
198                         break;
199                 }
200                 case 2: {
201                         if (!interlinespaceED->text().isEmpty())
202                                 form_->controller().set(Tabular::SET_INTERLINE_SPACE,
203                                         widgetsToLength(interlinespaceED, interlinespaceUnit));
204                         if (!form_->bc().policy().isReadOnly()) {
205                                 interlinespaceED->setEnabled(true);
206                                 interlinespaceUnit->setEnabled(true);
207                         }
208                         break;
209                 }
210         }
211         form_->changed();
212 }
213
214
215 void GuiTabularDialog::close_clicked()
216 {
217         form_->closeGUI();
218         form_->slotClose();
219 }
220
221
222 void GuiTabularDialog::borderSet_clicked()
223 {
224         form_->controller().set(Tabular::SET_ALL_LINES);
225         form_->update_borders();
226         form_->changed();
227 }
228
229
230 void GuiTabularDialog::borderUnset_clicked()
231 {
232         form_->controller().set(Tabular::UNSET_ALL_LINES);
233         form_->update_borders();
234         form_->changed();
235 }
236
237
238 void GuiTabularDialog::leftBorder_changed()
239 {
240         form_->controller().toggleLeftLine();
241         form_->changed();
242 }
243
244
245 void GuiTabularDialog::rightBorder_changed()
246 {
247         form_->controller().toggleRightLine();
248         form_->changed();
249 }
250
251
252 void GuiTabularDialog::topBorder_changed()
253 {
254         form_->controller().toggleTopLine();
255         form_->changed();
256 }
257
258
259 void GuiTabularDialog::bottomBorder_changed()
260 {
261         form_->controller().toggleBottomLine();
262         form_->changed();
263 }
264
265
266 void GuiTabularDialog::specialAlignment_changed()
267 {
268         string special = fromqstr(specialAlignmentED->text());
269         form_->controller().setSpecial(special);
270         form_->changed();
271 }
272
273
274 void GuiTabularDialog::width_changed()
275 {
276         form_->changed();
277         string const width = widgetsToLength(widthED, widthUnit);
278         form_->controller().setWidth(width);
279 }
280
281
282 void GuiTabularDialog::multicolumn_clicked()
283 {
284         form_->controller().toggleMultiColumn();
285         form_->changed();
286 }
287
288
289 void GuiTabularDialog::rotateTabular()
290 {
291         form_->controller().rotateTabular(rotateTabularCB->isChecked());
292         form_->changed();
293 }
294
295
296 void GuiTabularDialog::rotateCell()
297 {
298         form_->controller().rotateCell(rotateCellCB->isChecked());
299         form_->changed();
300 }
301
302
303 void GuiTabularDialog::hAlign_changed(int align)
304 {
305         ControlTabular::HALIGN h = ControlTabular::LEFT;
306
307         switch (align) {
308                 case 0: h = ControlTabular::LEFT; break;
309                 case 1: h = ControlTabular::CENTER; break;
310                 case 2: h = ControlTabular::RIGHT; break;
311                 case 3: h = ControlTabular::BLOCK; break;
312         }
313
314         form_->controller().halign(h);
315 }
316
317
318 void GuiTabularDialog::vAlign_changed(int align)
319 {
320         ControlTabular::VALIGN v = ControlTabular::TOP;
321
322         switch (align) {
323                 case 0: v = ControlTabular::TOP; break;
324                 case 1: v = ControlTabular::MIDDLE; break;
325                 case 2: v = ControlTabular::BOTTOM; break;
326         }
327
328         form_->controller().valign(v);
329 }
330
331
332 void GuiTabularDialog::longTabular()
333 {
334         form_->controller().longTabular(longTabularCB->isChecked());
335         form_->changed();
336 }
337
338
339 void GuiTabularDialog::ltNewpage_clicked()
340 {
341         form_->controller().set(Tabular::SET_LTNEWPAGE);
342         form_->changed();
343 }
344
345
346 void GuiTabularDialog::ltHeaderStatus_clicked()
347 {
348         bool enable(headerStatusCB->isChecked());
349         if (enable)
350                 form_->controller().set(Tabular::SET_LTHEAD, "");
351         else
352                 form_->controller().set(Tabular::UNSET_LTHEAD, "");
353         headerBorderAboveCB->setEnabled(enable);
354         headerBorderBelowCB->setEnabled(enable);
355         firstheaderNoContentsCB->setEnabled(enable);
356         form_->changed();
357 }
358
359
360 void GuiTabularDialog::ltHeaderBorderAbove_clicked()
361 {
362         if (headerBorderAboveCB->isChecked())
363                 form_->controller().set(Tabular::SET_LTHEAD, "dl_above");
364         else
365                 form_->controller().set(Tabular::UNSET_LTHEAD, "dl_above");
366         form_->changed();
367 }
368
369
370 void GuiTabularDialog::ltHeaderBorderBelow_clicked()
371 {
372         if (headerBorderBelowCB->isChecked())
373                 form_->controller().set(Tabular::SET_LTHEAD, "dl_below");
374         else
375                 form_->controller().set(Tabular::UNSET_LTHEAD, "dl_below");
376         form_->changed();
377 }
378
379
380 void GuiTabularDialog::ltFirstHeaderBorderAbove_clicked()
381 {
382         if (firstheaderBorderAboveCB->isChecked())
383                 form_->controller().set(Tabular::SET_LTFIRSTHEAD, "dl_above");
384         else
385                 form_->controller().set(Tabular::UNSET_LTFIRSTHEAD, "dl_above");
386         form_->changed();
387 }
388
389
390 void GuiTabularDialog::ltFirstHeaderBorderBelow_clicked()
391 {
392         if (firstheaderBorderBelowCB->isChecked())
393                 form_->controller().set(Tabular::SET_LTFIRSTHEAD, "dl_below");
394         else
395                 form_->controller().set(Tabular::UNSET_LTFIRSTHEAD, "dl_below");
396         form_->changed();
397 }
398
399
400 void GuiTabularDialog::ltFirstHeaderStatus_clicked()
401 {
402         bool enable(firstheaderStatusCB->isChecked());
403         if (enable)
404                 form_->controller().set(Tabular::SET_LTFIRSTHEAD, "");
405         else
406                 form_->controller().set(Tabular::UNSET_LTFIRSTHEAD, "");
407         firstheaderBorderAboveCB->setEnabled(enable);
408         firstheaderBorderBelowCB->setEnabled(enable);
409         form_->changed();
410 }
411
412
413 void GuiTabularDialog::ltFirstHeaderEmpty_clicked()
414 {
415         bool enable(firstheaderNoContentsCB->isChecked());
416         if (enable)
417                 form_->controller().set(Tabular::SET_LTFIRSTHEAD, "empty");
418         else
419                 form_->controller().set(Tabular::UNSET_LTFIRSTHEAD, "empty");
420         firstheaderStatusCB->setEnabled(!enable);
421         firstheaderBorderAboveCB->setEnabled(!enable);
422         firstheaderBorderBelowCB->setEnabled(!enable);
423         form_->changed();
424 }
425
426
427 void GuiTabularDialog::ltFooterStatus_clicked()
428 {
429         bool enable(footerStatusCB->isChecked());
430         if (enable)
431                 form_->controller().set(Tabular::SET_LTFOOT, "");
432         else
433                 form_->controller().set(Tabular::UNSET_LTFOOT, "");
434         footerBorderAboveCB->setEnabled(enable);
435         footerBorderBelowCB->setEnabled(enable);
436         lastfooterNoContentsCB->setEnabled(enable);
437         form_->changed();
438 }
439
440
441 void GuiTabularDialog::ltFooterBorderAbove_clicked()
442 {
443         if (footerBorderAboveCB->isChecked())
444                 form_->controller().set(Tabular::SET_LTFOOT, "dl_above");
445         else
446                 form_->controller().set(Tabular::UNSET_LTFOOT, "dl_above");
447         form_->changed();
448 }
449
450
451 void GuiTabularDialog::ltFooterBorderBelow_clicked()
452 {
453         if (footerBorderBelowCB->isChecked())
454                 form_->controller().set(Tabular::SET_LTFOOT, "dl_below");
455         else
456                 form_->controller().set(Tabular::UNSET_LTFOOT, "dl_below");
457         form_->changed();
458 }
459
460
461 void GuiTabularDialog::ltLastFooterStatus_clicked()
462 {
463         bool enable(lastfooterStatusCB->isChecked());
464         if (enable)
465                 form_->controller().set(Tabular::SET_LTLASTFOOT, "");
466         else
467                 form_->controller().set(Tabular::UNSET_LTLASTFOOT, "");
468         lastfooterBorderAboveCB->setEnabled(enable);
469         lastfooterBorderBelowCB->setEnabled(enable);
470         form_->changed();
471 }
472
473
474 void GuiTabularDialog::ltLastFooterBorderAbove_clicked()
475 {
476         if (lastfooterBorderAboveCB->isChecked())
477                 form_->controller().set(Tabular::SET_LTLASTFOOT, "dl_above");
478         else
479                 form_->controller().set(Tabular::UNSET_LTLASTFOOT, "dl_above");
480         form_->changed();
481 }
482
483
484 void GuiTabularDialog::ltLastFooterBorderBelow_clicked()
485 {
486         if (lastfooterBorderBelowCB->isChecked())
487                 form_->controller().set(Tabular::SET_LTLASTFOOT, "dl_below");
488         else
489                 form_->controller().set(Tabular::UNSET_LTLASTFOOT, "dl_below");
490         form_->changed();
491 }
492
493
494 void GuiTabularDialog::ltLastFooterEmpty_clicked()
495 {
496         bool enable(lastfooterNoContentsCB->isChecked());
497         if (enable)
498                 form_->controller().set(Tabular::SET_LTLASTFOOT, "empty");
499         else
500                 form_->controller().set(Tabular::UNSET_LTLASTFOOT, "empty");
501         lastfooterStatusCB->setEnabled(!enable);
502         lastfooterBorderAboveCB->setEnabled(!enable);
503         lastfooterBorderBelowCB->setEnabled(!enable);
504         form_->changed();
505 }
506
507
508 /////////////////////////////////////////////////////////////////////
509 //
510 // GuiTabular
511 //
512 /////////////////////////////////////////////////////////////////////
513
514
515 GuiTabular::GuiTabular(GuiDialog & parent)
516         : GuiView<GuiTabularDialog>(parent, _("Table Settings"))
517 {
518 }
519
520
521 void GuiTabular::build_dialog()
522 {
523         dialog_.reset(new GuiTabularDialog(this));
524
525         bc().setCancel(dialog_->closePB);
526
527         bc().addReadOnly(dialog_->topspaceED);
528         bc().addReadOnly(dialog_->topspaceUnit);
529         bc().addReadOnly(dialog_->topspaceCO);
530         bc().addReadOnly(dialog_->bottomspaceED);
531         bc().addReadOnly(dialog_->bottomspaceUnit);
532         bc().addReadOnly(dialog_->bottomspaceCO);
533         bc().addReadOnly(dialog_->interlinespaceED);
534         bc().addReadOnly(dialog_->interlinespaceUnit);
535         bc().addReadOnly(dialog_->interlinespaceCO);
536         bc().addReadOnly(dialog_->borderDefaultRB);
537         bc().addReadOnly(dialog_->booktabsRB);
538
539         bc().addReadOnly(dialog_->multicolumnCB);
540         bc().addReadOnly(dialog_->rotateCellCB);
541         bc().addReadOnly(dialog_->rotateTabularCB);
542         bc().addReadOnly(dialog_->specialAlignmentED);
543         bc().addReadOnly(dialog_->widthED);
544         bc().addReadOnly(dialog_->widthUnit);
545         bc().addReadOnly(dialog_->hAlignCB);
546         bc().addReadOnly(dialog_->vAlignCB);
547         bc().addReadOnly(dialog_->borderSetPB);
548         bc().addReadOnly(dialog_->borderUnsetPB);
549         bc().addReadOnly(dialog_->borders);
550         bc().addReadOnly(dialog_->longTabularCB);
551         bc().addReadOnly(dialog_->headerStatusCB);
552         bc().addReadOnly(dialog_->headerBorderAboveCB);
553         bc().addReadOnly(dialog_->headerBorderBelowCB);
554         bc().addReadOnly(dialog_->firstheaderStatusCB);
555         bc().addReadOnly(dialog_->firstheaderBorderAboveCB);
556         bc().addReadOnly(dialog_->firstheaderBorderBelowCB);
557         bc().addReadOnly(dialog_->firstheaderNoContentsCB);
558         bc().addReadOnly(dialog_->footerStatusCB);
559         bc().addReadOnly(dialog_->footerBorderAboveCB);
560         bc().addReadOnly(dialog_->footerBorderBelowCB);
561         bc().addReadOnly(dialog_->lastfooterStatusCB);
562         bc().addReadOnly(dialog_->lastfooterBorderAboveCB);
563         bc().addReadOnly(dialog_->lastfooterBorderBelowCB);
564         bc().addReadOnly(dialog_->lastfooterNoContentsCB);
565         bc().addReadOnly(dialog_->newpageCB);
566
567         // initialize the length validator
568         bc().addCheckedLineEdit(dialog_->widthED, dialog_->fixedWidthColLA);
569         bc().addCheckedLineEdit(dialog_->topspaceED, dialog_->topspaceLA);
570         bc().addCheckedLineEdit(dialog_->bottomspaceED, dialog_->bottomspaceLA);
571         bc().addCheckedLineEdit(dialog_->interlinespaceED, dialog_->interlinespaceLA);
572 }
573
574
575 bool GuiTabular::isValid()
576 {
577         return true;
578 }
579
580
581 void GuiTabular::update_borders()
582 {
583         Tabular const & tabular = controller().tabular();
584         Tabular::idx_type const cell = controller().getActiveCell();
585         bool const isMulticolumnCell = tabular.isMultiColumn(cell);
586
587         if (!isMulticolumnCell) {
588                 dialog_->borders->setLeftEnabled(true);
589                 dialog_->borders->setRightEnabled(true);
590                 dialog_->borders->setTop(tabular.topLine(cell, true));
591                 dialog_->borders->setBottom(tabular.bottomLine(cell, true));
592                 dialog_->borders->setLeft(tabular.leftLine(cell, true));
593                 dialog_->borders->setRight(tabular.rightLine(cell, true));
594                 // repaint the setborder widget
595                 dialog_->borders->update();
596                 return;
597         }
598
599         dialog_->borders->setTop(tabular.topLine(cell));
600         dialog_->borders->setBottom(tabular.bottomLine(cell));
601         // pay attention to left/right lines: they are only allowed
602         // to set if we are in first/last cell of row or if the left/right
603         // cell is also a multicolumn.
604         if (tabular.isFirstCellInRow(cell) || tabular.isMultiColumn(cell - 1)) {
605                 dialog_->borders->setLeftEnabled(true);
606                 dialog_->borders->setLeft(tabular.leftLine(cell));
607         } else {
608                 dialog_->borders->setLeft(false);
609                 dialog_->borders->setLeftEnabled(false);
610         }
611         if (tabular.isLastCellInRow(cell) || tabular.isMultiColumn(cell + 1)) {
612                 dialog_->borders->setRightEnabled(true);
613                 dialog_->borders->setRight(tabular.rightLine(cell));
614         } else {
615                 dialog_->borders->setRight(false);
616                 dialog_->borders->setRightEnabled(false);
617         }
618         // repaint the setborder widget
619         dialog_->borders->update();
620 }
621
622
623 void GuiTabular::update_contents()
624 {
625         controller().initialiseParams(string());
626
627         Tabular const & tabular(controller().tabular());
628         Tabular::idx_type const cell = controller().getActiveCell();
629
630         Tabular::row_type const row(tabular.cellRow(cell));
631         Tabular::col_type const col(tabular.cellColumn(cell));
632
633         dialog_->tabularRowED->setText(toqstr(convert<string>(row + 1)));
634         dialog_->tabularColumnED->setText(toqstr(convert<string>(col + 1)));
635
636         bool const multicol(tabular.isMultiColumn(cell));
637
638         dialog_->multicolumnCB->setChecked(multicol);
639
640         dialog_->rotateCellCB->setChecked(tabular.getRotateCell(cell));
641         dialog_->rotateTabularCB->setChecked(tabular.getRotateTabular());
642
643         dialog_->longTabularCB->setChecked(tabular.isLongTabular());
644
645         update_borders();
646
647         Length pwidth;
648         docstring special;
649
650         if (multicol) {
651                 special = tabular.getAlignSpecial(cell, Tabular::SET_SPECIAL_MULTI);
652                 pwidth = tabular.getMColumnPWidth(cell);
653         } else {
654                 special = tabular.getAlignSpecial(cell, Tabular::SET_SPECIAL_COLUMN);
655                 pwidth = tabular.getColumnPWidth(cell);
656         }
657
658         dialog_->specialAlignmentED->setText(toqstr(special));
659
660         bool const isReadonly = bc().policy().isReadOnly();
661         dialog_->specialAlignmentED->setEnabled(!isReadonly);
662
663         Length::UNIT default_unit =
664                 controller().useMetricUnits() ? Length::CM : Length::IN;
665
666         dialog_->borderDefaultRB->setChecked(!tabular.useBookTabs());
667         dialog_->booktabsRB->setChecked(tabular.useBookTabs());
668
669         if (tabular.row_info[row].top_space.empty()
670             && !tabular.row_info[row].top_space_default) {
671                 dialog_->topspaceCO->setCurrentIndex(0);
672         } else if (tabular.row_info[row].top_space_default) {
673                 dialog_->topspaceCO->setCurrentIndex(1);
674         } else {
675                 dialog_->topspaceCO->setCurrentIndex(2);
676                 lengthToWidgets(dialog_->topspaceED,
677                                 dialog_->topspaceUnit,
678                                 tabular.row_info[row].top_space.asString(),
679                                 default_unit);
680         }
681         dialog_->topspaceED->setEnabled(!isReadonly
682                 && (dialog_->topspaceCO->currentIndex() == 2));
683         dialog_->topspaceUnit->setEnabled(!isReadonly
684                 && (dialog_->topspaceCO->currentIndex() == 2));
685         dialog_->topspaceCO->setEnabled(!isReadonly);
686
687         if (tabular.row_info[row].bottom_space.empty()
688             && !tabular.row_info[row].bottom_space_default) {
689                 dialog_->bottomspaceCO->setCurrentIndex(0);
690         } else if (tabular.row_info[row].bottom_space_default) {
691                 dialog_->bottomspaceCO->setCurrentIndex(1);
692         } else {
693                 dialog_->bottomspaceCO->setCurrentIndex(2);
694                 lengthToWidgets(dialog_->bottomspaceED,
695                                 dialog_->bottomspaceUnit,
696                                 tabular.row_info[row].bottom_space.asString(),
697                                 default_unit);
698         }
699         dialog_->bottomspaceED->setEnabled(!isReadonly
700                 && (dialog_->bottomspaceCO->currentIndex() == 2));
701         dialog_->bottomspaceUnit->setEnabled(!isReadonly
702                 && (dialog_->bottomspaceCO->currentIndex() == 2));
703         dialog_->bottomspaceCO->setEnabled(!isReadonly);
704
705         if (tabular.row_info[row].interline_space.empty()
706             && !tabular.row_info[row].interline_space_default) {
707                 dialog_->interlinespaceCO->setCurrentIndex(0);
708         } else if (tabular.row_info[row].interline_space_default) {
709                 dialog_->interlinespaceCO->setCurrentIndex(1);
710         } else {
711                 dialog_->interlinespaceCO->setCurrentIndex(2);
712                 lengthToWidgets(dialog_->interlinespaceED,
713                                 dialog_->interlinespaceUnit,
714                                 tabular.row_info[row].interline_space.asString(),
715                                 default_unit);
716         }
717         dialog_->interlinespaceED->setEnabled(!isReadonly
718                 && (dialog_->interlinespaceCO->currentIndex() == 2));
719         dialog_->interlinespaceUnit->setEnabled(!isReadonly
720                 && (dialog_->interlinespaceCO->currentIndex() == 2));
721         dialog_->interlinespaceCO->setEnabled(!isReadonly);
722
723         string colwidth;
724         if (!pwidth.zero())
725                 colwidth = pwidth.asString();
726         lengthToWidgets(dialog_->widthED, dialog_->widthUnit,
727                 colwidth, default_unit);
728
729         dialog_->widthED->setEnabled(!isReadonly);
730         dialog_->widthUnit->setEnabled(!isReadonly);
731
732         dialog_->hAlignCB->clear();
733         dialog_->hAlignCB->addItem(qt_("Left"));
734         dialog_->hAlignCB->addItem(qt_("Center"));
735         dialog_->hAlignCB->addItem(qt_("Right"));
736         if (!multicol && !pwidth.zero())
737                 dialog_->hAlignCB->addItem(qt_("Justified"));
738
739         int align = 0;
740         switch (tabular.getAlignment(cell)) {
741         case LYX_ALIGN_LEFT:
742                 align = 0;
743                 break;
744         case LYX_ALIGN_CENTER:
745                 align = 1;
746                 break;
747         case LYX_ALIGN_RIGHT:
748                 align = 2;
749                 break;
750         case LYX_ALIGN_BLOCK:
751         {
752                 if (!multicol && !pwidth.zero())
753                         align = 3;
754                 break;
755         }
756         default:
757                 align = 0;
758                 break;
759         }
760         dialog_->hAlignCB->setCurrentIndex(align);
761
762         int valign = 0;
763         switch (tabular.getVAlignment(cell)) {
764         case Tabular::LYX_VALIGN_TOP:
765                 valign = 0;
766                 break;
767         case Tabular::LYX_VALIGN_MIDDLE:
768                 valign = 1;
769                 break;
770         case Tabular::LYX_VALIGN_BOTTOM:
771                 valign = 2;
772                 break;
773         default:
774                 valign = 1;
775                 break;
776         }
777         if (pwidth.zero())
778                 valign = 1;
779         dialog_->vAlignCB->setCurrentIndex(valign);
780
781         dialog_->hAlignCB->setEnabled(true);
782         dialog_->vAlignCB->setEnabled(!pwidth.zero());
783
784         if (!tabular.isLongTabular()) {
785                 dialog_->headerStatusCB->setChecked(false);
786                 dialog_->headerBorderAboveCB->setChecked(false);
787                 dialog_->headerBorderBelowCB->setChecked(false);
788                 dialog_->firstheaderStatusCB->setChecked(false);
789                 dialog_->firstheaderBorderAboveCB->setChecked(false);
790                 dialog_->firstheaderBorderBelowCB->setChecked(false);
791                 dialog_->firstheaderNoContentsCB->setChecked(false);
792                 dialog_->footerStatusCB->setChecked(false);
793                 dialog_->footerBorderAboveCB->setChecked(false);
794                 dialog_->footerBorderBelowCB->setChecked(false);
795                 dialog_->lastfooterStatusCB->setChecked(false);
796                 dialog_->lastfooterBorderAboveCB->setChecked(false);
797                 dialog_->lastfooterBorderBelowCB->setChecked(false);
798                 dialog_->lastfooterNoContentsCB->setChecked(false);
799                 dialog_->newpageCB->setChecked(false);
800                 dialog_->newpageCB->setEnabled(false);
801                 return;
802         }
803
804         Tabular::ltType ltt;
805         bool use_empty;
806         bool row_set = tabular.getRowOfLTHead(row, ltt);
807         dialog_->headerStatusCB->setChecked(row_set);
808         if (ltt.set) {
809                 dialog_->headerBorderAboveCB->setChecked(ltt.topDL);
810                 dialog_->headerBorderBelowCB->setChecked(ltt.bottomDL);
811                 use_empty = true;
812         } else {
813                 dialog_->headerBorderAboveCB->setChecked(false);
814                 dialog_->headerBorderBelowCB->setChecked(false);
815                 dialog_->headerBorderAboveCB->setEnabled(false);
816                 dialog_->headerBorderBelowCB->setEnabled(false);
817                 dialog_->firstheaderNoContentsCB->setChecked(false);
818                 dialog_->firstheaderNoContentsCB->setEnabled(false);
819                 use_empty = false;
820         }
821
822         row_set = tabular.getRowOfLTFirstHead(row, ltt);
823         dialog_->firstheaderStatusCB->setChecked(row_set);
824         if (ltt.set && (!ltt.empty || !use_empty)) {
825                 dialog_->firstheaderBorderAboveCB->setChecked(ltt.topDL);
826                 dialog_->firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
827         } else {
828                 dialog_->firstheaderBorderAboveCB->setEnabled(false);
829                 dialog_->firstheaderBorderBelowCB->setEnabled(false);
830                 dialog_->firstheaderBorderAboveCB->setChecked(false);
831                 dialog_->firstheaderBorderBelowCB->setChecked(false);
832                 if (use_empty) {
833                         dialog_->firstheaderNoContentsCB->setChecked(ltt.empty);
834                         if (ltt.empty)
835                                 dialog_->firstheaderStatusCB->setEnabled(false);
836                 }
837         }
838
839         row_set = tabular.getRowOfLTFoot(row, ltt);
840         dialog_->footerStatusCB->setChecked(row_set);
841         if (ltt.set) {
842                 dialog_->footerBorderAboveCB->setChecked(ltt.topDL);
843                 dialog_->footerBorderBelowCB->setChecked(ltt.bottomDL);
844                 use_empty = true;
845         } else {
846                 dialog_->footerBorderAboveCB->setChecked(false);
847                 dialog_->footerBorderBelowCB->setChecked(false);
848                 dialog_->footerBorderAboveCB->setEnabled(false);
849                 dialog_->footerBorderBelowCB->setEnabled(false);
850                 dialog_->lastfooterNoContentsCB->setChecked(false);
851                 dialog_->lastfooterNoContentsCB->setEnabled(false);
852                 use_empty = false;
853         }
854
855         row_set = tabular.getRowOfLTLastFoot(row, ltt);
856                 dialog_->lastfooterStatusCB->setChecked(row_set);
857         if (ltt.set && (!ltt.empty || !use_empty)) {
858                 dialog_->lastfooterBorderAboveCB->setChecked(ltt.topDL);
859                 dialog_->lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
860         } else {
861                 dialog_->lastfooterBorderAboveCB->setEnabled(false);
862                 dialog_->lastfooterBorderBelowCB->setEnabled(false);
863                 dialog_->lastfooterBorderAboveCB->setChecked(false);
864                 dialog_->lastfooterBorderBelowCB->setChecked(false);
865                 if (use_empty) {
866                         dialog_->lastfooterNoContentsCB->setChecked(ltt.empty);
867                         if (ltt.empty)
868                                 dialog_->lastfooterStatusCB->setEnabled(false);
869                 }
870         }
871         dialog_->newpageCB->setChecked(tabular.getLTNewPage(row));
872 }
873
874
875 void GuiTabular::closeGUI()
876 {
877         // ugly hack to auto-apply the stuff that hasn't been
878         // yet. don't let this continue to exist ...
879
880         // Subtle here, we must /not/ apply any changes and
881         // then refer to tabular, as it will have been freed
882         // since the changes update the actual controller().tabular()
883         Tabular const & tabular(controller().tabular());
884
885         // apply the fixed width values
886         Tabular::idx_type const cell = controller().getActiveCell();
887         bool const multicol = tabular.isMultiColumn(cell);
888         string width = widgetsToLength(dialog_->widthED, dialog_->widthUnit);
889         string width2;
890
891         Length llen = tabular.getColumnPWidth(cell);
892         Length llenMulti = tabular.getMColumnPWidth(cell);
893
894         if (multicol && !llenMulti.zero())
895                         width2 = llenMulti.asString();
896         else if (!multicol && !llen.zero())
897                         width2 = llen.asString();
898
899         // apply the special alignment
900         docstring const sa1 = qstring_to_ucs4(dialog_->specialAlignmentED->text());
901         docstring sa2;
902
903         if (multicol)
904                 sa2 = tabular.getAlignSpecial(cell, Tabular::SET_SPECIAL_MULTI);
905         else
906                 sa2 = tabular.getAlignSpecial(cell, Tabular::SET_SPECIAL_COLUMN);
907
908         if (sa1 != sa2) {
909                 if (multicol)
910                         controller().set(Tabular::SET_SPECIAL_MULTI, to_utf8(sa1));
911                 else
912                         controller().set(Tabular::SET_SPECIAL_COLUMN, to_utf8(sa1));
913         }
914
915         if (width != width2) {
916                 if (multicol)
917                         controller().set(Tabular::SET_MPWIDTH, width);
918                 else
919                         controller().set(Tabular::SET_PWIDTH, width);
920         }
921
922         /* DO WE NEED THIS?
923         switch (dialog_->topspaceCO->currentIndex()) {
924                 case 0:
925                         controller().set(Tabular::SET_TOP_SPACE, "");
926                         break;
927                 case 1:
928                         controller().set(Tabular::SET_TOP_SPACE, "default");
929                         break;
930                 case 2:
931                         controller().set(Tabular::SET_TOP_SPACE,
932                                 widgetsToLength(dialog_->topspaceED,
933                                         dialog_->topspaceUnit));
934                         break;
935         }
936
937         switch (dialog_->bottomspaceCO->currentIndex()) {
938                 case 0:
939                         controller().set(Tabular::SET_BOTTOM_SPACE, "");
940                         break;
941                 case 1:
942                         controller().set(Tabular::SET_BOTTOM_SPACE, "default");
943                         break;
944                 case 2:
945                         controller().set(Tabular::SET_BOTTOM_SPACE,
946                                 widgetsToLength(dialog_->bottomspaceED,
947                                         dialog_->bottomspaceUnit));
948                         break;
949         }
950
951         switch (dialog_->interlinespaceCO->currentIndex()) {
952                 case 0:
953                         controller().set(Tabular::SET_INTERLINE_SPACE, "");
954                         break;
955                 case 1:
956                         controller().set(Tabular::SET_INTERLINE_SPACE, "default");
957                         break;
958                 case 2:
959                         controller().set(Tabular::SET_INTERLINE_SPACE,
960                                 widgetsToLength(dialog_->interlinespaceED,
961                                         dialog_->interlinespaceUnit));
962                         break;
963         }
964 */
965 }
966
967 } // namespace frontend
968 } // namespace lyx
969
970 #include "GuiTabular_moc.cpp"