]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QTabular.C
25e4c0586714836dd0757b8489c87599c0cf66e3
[lyx.git] / src / frontends / qt2 / 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 Juergen Spitzmueller
8  * \author Herbert Voss
9  *
10  * Full author contact details are available in file CREDITS
11  */
12
13 #include <config.h>
14
15
16 #include "ControlTabular.h"
17 #include "insets/insettabular.h"
18 #include "qt_helpers.h"
19 #include "support/lstrings.h"
20 #include "lyxrc.h"
21
22 #include "QTabularDialog.h"
23 #include "QTabular.h"
24 #include "Qt2BC.h"
25
26 #include <qpushbutton.h>
27 #include <qlineedit.h>
28 #include <qcheckbox.h>
29 #include "lengthcombo.h"
30 #include "qsetborder.h"
31
32 typedef Qt2CB<ControlTabular, Qt2DB<QTabularDialog> > base_class;
33
34 QTabular::QTabular()
35         : base_class(qt_("LyX: Table Settings"))
36 {
37 }
38
39
40 void QTabular::build_dialog()
41 {
42         dialog_.reset(new QTabularDialog(this));
43
44         bc().setCancel(dialog_->closePB);
45
46         bc().addReadOnly(dialog_->multicolumnCB);
47         bc().addReadOnly(dialog_->rotateCellCB);
48         bc().addReadOnly(dialog_->rotateTabularCB);
49         bc().addReadOnly(dialog_->specialAlignmentED);
50         bc().addReadOnly(dialog_->widthED);
51         bc().addReadOnly(dialog_->widthUnit);
52         bc().addReadOnly(dialog_->hAlignCB);
53         bc().addReadOnly(dialog_->vAlignCB);
54         bc().addReadOnly(dialog_->columnAddPB);
55         bc().addReadOnly(dialog_->columnDeletePB);
56         bc().addReadOnly(dialog_->rowAddPB);
57         bc().addReadOnly(dialog_->rowDeletePB);
58         bc().addReadOnly(dialog_->borderSetPB);
59         bc().addReadOnly(dialog_->borderUnsetPB);
60         bc().addReadOnly(dialog_->borders);
61         bc().addReadOnly(dialog_->longTabularCB);
62         bc().addReadOnly(dialog_->headerStatusCB);
63         bc().addReadOnly(dialog_->headerBorderAboveCB);
64         bc().addReadOnly(dialog_->headerBorderBelowCB);
65         bc().addReadOnly(dialog_->firstheaderStatusCB);
66         bc().addReadOnly(dialog_->firstheaderBorderAboveCB);
67         bc().addReadOnly(dialog_->firstheaderBorderBelowCB);
68         bc().addReadOnly(dialog_->firstheaderNoContentsCB);
69         bc().addReadOnly(dialog_->footerStatusCB);
70         bc().addReadOnly(dialog_->footerBorderAboveCB);
71         bc().addReadOnly(dialog_->footerBorderBelowCB);
72         bc().addReadOnly(dialog_->lastfooterStatusCB);
73         bc().addReadOnly(dialog_->lastfooterBorderAboveCB);
74         bc().addReadOnly(dialog_->lastfooterBorderBelowCB);
75         bc().addReadOnly(dialog_->lastfooterNoContentsCB);
76         bc().addReadOnly(dialog_->newpageCB);
77 }
78
79
80 bool QTabular::isValid()
81 {
82         return true;
83 }
84
85
86 void QTabular::update_borders()
87 {
88         LyXTabular * tabular(controller().tabular());
89         int cell(controller().inset()->getActCell());
90
91         if (!controller().isMulticolumnCell()) {
92                 dialog_->borders->setLeftEnabled(true);
93                 dialog_->borders->setRightEnabled(true);
94                 dialog_->borders->setTop(tabular->TopLine(cell, true));
95                 dialog_->borders->setBottom(tabular->BottomLine(cell, true));
96                 dialog_->borders->setLeft(tabular->LeftLine(cell, true));
97                 dialog_->borders->setRight(tabular->RightLine(cell, true));
98                 // repaint the setborder widget
99                 dialog_->borders->repaint();
100                 return;
101         }
102
103         dialog_->borders->setTop(tabular->TopLine(cell));
104         dialog_->borders->setBottom(tabular->BottomLine(cell));
105         // pay attention to left/right lines: they are only allowed
106         // to set if we are in first/last cell of row or if the left/right
107         // cell is also a multicolumn.
108         if (tabular->IsFirstCellInRow(cell) || tabular->IsMultiColumn(cell - 1)) {
109                 dialog_->borders->setLeftEnabled(true);
110                 dialog_->borders->setLeft(tabular->LeftLine(cell));
111         } else {
112                 dialog_->borders->setLeft(false);
113                 dialog_->borders->setLeftEnabled(false);
114         }
115         if (tabular->IsLastCellInRow(cell) || tabular->IsMultiColumn(cell + 1)) {
116                 dialog_->borders->setRightEnabled(true);
117                 dialog_->borders->setRight(tabular->RightLine(cell));
118         } else {
119                 dialog_->borders->setRight(false);
120                 dialog_->borders->setRightEnabled(false);
121         }
122         // repaint the setborder widget
123         dialog_->borders->repaint();
124 }
125
126
127 void QTabular::update_contents()
128 {
129         LyXTabular * tabular(controller().tabular());
130         int cell(controller().inset()->getActCell());
131
132         int const row(tabular->row_of_cell(cell));
133         int const col(tabular->column_of_cell(cell));
134
135         dialog_->tabularRowED->setText(toqstr(tostr(row + 1)));
136         dialog_->tabularColumnED->setText(toqstr(tostr(col + 1)));
137
138         bool const multicol(controller().isMulticolumnCell());
139
140         dialog_->multicolumnCB->setChecked(multicol);
141
142         dialog_->rotateCellCB->setChecked(tabular->GetRotateCell(cell));
143         dialog_->rotateTabularCB->setChecked(tabular->GetRotateTabular());
144
145         dialog_->longTabularCB->setChecked(tabular->IsLongTabular());
146
147         update_borders();
148
149         LyXLength pwidth;
150         string special;
151
152         if (multicol) {
153                 special = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_MULTI);
154                 pwidth = tabular->GetMColumnPWidth(cell);
155         } else {
156                 special = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_COLUMN);
157                 pwidth = tabular->GetColumnPWidth(cell);
158         }
159
160         dialog_->specialAlignmentED->setText(toqstr(special));
161
162         bool const isReadonly = bc().bp().isReadOnly();
163         dialog_->specialAlignmentED->setEnabled(!isReadonly);
164
165         LyXLength::UNIT default_unit = controller().metric() ? LyXLength::CM : LyXLength::IN;
166         if (!pwidth.zero()) {
167                 dialog_->widthED->setText(toqstr(tostr(pwidth.value())));
168                 dialog_->widthUnit->setCurrentItem(pwidth.unit());
169         } else {
170                 dialog_->widthED->setText("");
171                 dialog_->widthUnit->setCurrentItem(default_unit);
172         }
173         dialog_->widthED->setEnabled(!isReadonly);
174         dialog_->widthUnit->setEnabled(!isReadonly);
175
176         dialog_->hAlignCB->clear();
177         dialog_->hAlignCB->insertItem(qt_("Left"));
178         dialog_->hAlignCB->insertItem(qt_("Center"));
179         dialog_->hAlignCB->insertItem(qt_("Right"));
180         if (!multicol && !pwidth.zero())
181                 dialog_->hAlignCB->insertItem(qt_("Block"));
182
183         int align = 0;
184         switch (tabular->GetAlignment(cell)) {
185         case LYX_ALIGN_LEFT:
186                 align = 0;
187                 break;
188         case LYX_ALIGN_CENTER:
189                 align = 1;
190                 break;
191         case LYX_ALIGN_RIGHT:
192                 align = 2;
193                 break;
194         case LYX_ALIGN_BLOCK:
195         {
196                 if (!multicol && !pwidth.zero())
197                         align = 3;
198                 break;
199         }
200         default:
201                 align = 0;
202                 break;
203         }
204         dialog_->hAlignCB->setCurrentItem(align);
205
206         int valign = 0;
207         switch (tabular->GetVAlignment(cell)) {
208         case LyXTabular::LYX_VALIGN_TOP:
209                 valign = 0;
210                 break;
211         case LyXTabular::LYX_VALIGN_CENTER:
212                 valign = 1;
213                 break;
214         case LyXTabular::LYX_VALIGN_BOTTOM:
215                 valign = 2;
216                 break;
217         default:
218                 valign = 1;
219                 break;
220         }
221         if (pwidth.zero())
222                 valign = 1;
223         dialog_->vAlignCB->setCurrentItem(valign);
224
225         dialog_->hAlignCB->setEnabled(true);
226         dialog_->vAlignCB->setEnabled(!pwidth.zero());
227
228         if (!tabular->IsLongTabular()) {
229                 dialog_->headerStatusCB->setChecked(false);
230                 dialog_->headerBorderAboveCB->setChecked(false);
231                 dialog_->headerBorderBelowCB->setChecked(false);
232                 dialog_->firstheaderStatusCB->setChecked(false);
233                 dialog_->firstheaderBorderAboveCB->setChecked(false);
234                 dialog_->firstheaderBorderBelowCB->setChecked(false);
235                 dialog_->firstheaderNoContentsCB->setChecked(false);
236                 dialog_->footerStatusCB->setChecked(false);
237                 dialog_->footerBorderAboveCB->setChecked(false);
238                 dialog_->footerBorderBelowCB->setChecked(false);
239                 dialog_->lastfooterStatusCB->setChecked(false);
240                 dialog_->lastfooterBorderAboveCB->setChecked(false);
241                 dialog_->lastfooterBorderBelowCB->setChecked(false);
242                 dialog_->lastfooterNoContentsCB->setChecked(false);
243                 dialog_->newpageCB->setChecked(false);
244                 return;
245         }
246
247         LyXTabular::ltType ltt;
248         bool use_empty;
249         bool row_set = tabular->GetRowOfLTHead(row, ltt);
250         dialog_->headerStatusCB->setChecked(row_set);
251         if (ltt.set) {
252                 dialog_->headerBorderAboveCB->setChecked(ltt.topDL);
253                 dialog_->headerBorderBelowCB->setChecked(ltt.bottomDL);
254                 use_empty = true;
255         } else {
256                 dialog_->headerBorderAboveCB->setChecked(false);
257                 dialog_->headerBorderBelowCB->setChecked(false);
258                 dialog_->headerBorderAboveCB->setEnabled(false);
259                 dialog_->headerBorderBelowCB->setEnabled(false);
260                 dialog_->firstheaderNoContentsCB->setChecked(false);
261                 dialog_->firstheaderNoContentsCB->setEnabled(false);
262                 use_empty = false;
263         }
264
265         row_set = tabular->GetRowOfLTFirstHead(row, ltt);
266         dialog_->firstheaderStatusCB->setChecked(row_set);
267         if (ltt.set && (!ltt.empty || !use_empty)) {
268                 dialog_->firstheaderBorderAboveCB->setChecked(ltt.topDL);
269                 dialog_->firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
270         } else {
271                 dialog_->firstheaderBorderAboveCB->setEnabled(false);
272                 dialog_->firstheaderBorderBelowCB->setEnabled(false);
273                 dialog_->firstheaderBorderAboveCB->setChecked(false);
274                 dialog_->firstheaderBorderBelowCB->setChecked(false);
275                 if (use_empty) {
276                         dialog_->firstheaderNoContentsCB->setChecked(ltt.empty);
277                         if (ltt.empty)
278                                 dialog_->firstheaderStatusCB->setEnabled(false);
279                 }
280         }
281
282         row_set = tabular->GetRowOfLTFoot(row, ltt);
283         dialog_->footerStatusCB->setChecked(row_set);
284         if (ltt.set) {
285                 dialog_->footerBorderAboveCB->setChecked(ltt.topDL);
286                 dialog_->footerBorderBelowCB->setChecked(ltt.bottomDL);
287                 use_empty = true;
288         } else {
289                 dialog_->footerBorderAboveCB->setChecked(false);
290                 dialog_->footerBorderBelowCB->setChecked(false);
291                 dialog_->footerBorderAboveCB->setEnabled(false);
292                 dialog_->footerBorderBelowCB->setEnabled(false);
293                 dialog_->lastfooterNoContentsCB->setChecked(false);
294                 dialog_->lastfooterNoContentsCB->setEnabled(false);
295                 use_empty = false;
296         }
297
298         row_set = tabular->GetRowOfLTLastFoot(row, ltt);
299                 dialog_->lastfooterStatusCB->setChecked(row_set);
300         if (ltt.set && (!ltt.empty || !use_empty)) {
301                 dialog_->lastfooterBorderAboveCB->setChecked(ltt.topDL);
302                 dialog_->lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
303         } else {
304                 dialog_->lastfooterBorderAboveCB->setEnabled(false);
305                 dialog_->lastfooterBorderBelowCB->setEnabled(false);
306                 dialog_->lastfooterBorderAboveCB->setChecked(false);
307                 dialog_->lastfooterBorderBelowCB->setChecked(false);
308                 if (use_empty) {
309                         dialog_->lastfooterNoContentsCB->setChecked(ltt.empty);
310                         if (ltt.empty)
311                                 dialog_->lastfooterStatusCB->setEnabled(false);
312                 }
313         }
314         dialog_->newpageCB->setChecked(tabular->GetLTNewPage(row));
315 }
316
317
318 void QTabular::closeGUI()
319 {
320         // ugly hack to auto-apply the stuff that hasn't been
321         // yet. don't let this continue to exist ...
322
323         InsetTabular * inset(controller().inset());
324         LyXTabular * tabular(controller().tabular());
325
326         // apply the fixed width values
327         int cell = inset->getActCell();
328         bool const multicol(controller().isMulticolumnCell());
329         string str1 = widgetsToLength(dialog_->widthED, dialog_->widthUnit);
330         string str2;
331
332         LyXLength llen(tabular->GetColumnPWidth(cell));
333         LyXLength llenMulti(tabular->GetMColumnPWidth(cell));
334
335         if (multicol && !llenMulti.zero())
336                         str2 = llenMulti.asString();
337         else if (!multicol && !llen.zero())
338                         str2 = llen.asString();
339
340         if (str1 != str2) {
341                 if (multicol)
342                         controller().set(LyXTabular::SET_MPWIDTH, str1);
343                 else
344                         controller().set(LyXTabular::SET_PWIDTH, str1);
345         }
346
347         // apply the special alignment
348         str1 = fromqstr(dialog_->specialAlignmentED->text());
349         if (multicol)
350                 str2 = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_MULTI);
351         else
352                 str2 = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_COLUMN);
353
354         if (str1 != str2) {
355                 if (multicol)
356                         controller().set(LyXTabular::SET_SPECIAL_MULTI, str1);
357                 else
358                         controller().set(LyXTabular::SET_SPECIAL_COLUMN, str1);
359         }
360 }