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