]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormTabular.C
810efead1db6ca50ab4bcfeae1f197cf9970adb2
[lyx.git] / src / frontends / xforms / FormTabular.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ======================================================
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1995 Matthias Ettrich
8  *          Copyright 1995-2000 The LyX Team.
9  *
10  *======================================================*/
11 /* FormTabular.C
12  * FormTabular Interface Class Implementation
13  */
14
15 #include <config.h>
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20
21 #include "FormTabular.h"
22 #include "form_tabular.h"
23 #include "LyXView.h"
24 #include "Dialogs.h"
25 #include "insets/insettabular.h"
26 #include "buffer.h"
27 #include "xforms_helpers.h"
28
29
30 FormTabular::FormTabular(LyXView * lv, Dialogs * d)
31         : FormInset(lv, d, _("Tabular Layout")),
32           inset_(0), actCell_(-1)
33 {
34         // let the dialog be shown
35         // This is a permanent connection so we won't bother
36         // storing a copy because we won't be disconnecting.
37         d->showTabular.connect(slot(this, &FormTabular::showInset));
38         d->updateTabular.connect(slot(this, &FormTabular::updateInset));
39 }
40
41
42 void FormTabular::redraw()
43 {
44         if(form() && form()->visible)
45                 fl_redraw_form(form());
46         else
47                 return;
48
49         FL_FORM * outer_form = fl_get_active_folder(dialog_->tabFolder);
50         if (outer_form && outer_form->visible)
51                 fl_redraw_form(outer_form);
52 }
53
54
55 FL_FORM * FormTabular::form() const
56 {
57         if (dialog_.get())
58                 return dialog_->form;
59         return 0;
60 }
61
62
63 void FormTabular::disconnect()
64 {
65         inset_ = 0;
66         FormInset::disconnect();
67 }
68
69
70 void FormTabular::showInset(InsetTabular * inset)
71 {
72         if (inset == 0) return;
73
74         // If connected to another inset, disconnect from it.
75         if (inset_ != inset) {
76                 ih_.disconnect();
77                 ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide));
78                 inset_ = inset;
79         }
80
81         show();
82 }
83
84
85 void FormTabular::updateInset(InsetTabular * inset)
86 {
87         if (inset == 0 || inset_ == 0) return;
88
89         // If connected to another inset, disconnect from it.
90         if (inset_ != inset) {
91                 ih_.disconnect();
92                 ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide));
93                 inset_ = inset;
94         }
95
96         update();
97 }
98
99
100 void FormTabular::build()
101 {
102         dialog_.reset(build_tabular());
103         tabular_options_.reset(build_tabular_options());
104         column_options_.reset(build_column_options());
105         cell_options_.reset(build_cell_options());
106         longtable_options_.reset(build_longtable_options());
107
108         // Workaround dumb xforms sizing bug
109         minw_ = form()->w;
110         minh_ = form()->h;
111
112         fl_set_input_return(column_options_->input_column_width,
113                             FL_RETURN_END);
114         fl_set_input_return(column_options_->input_special_alignment,
115                             FL_RETURN_END);
116         fl_set_input_return(cell_options_->input_mcolumn_width,
117                             FL_RETURN_END);
118         fl_set_input_return(cell_options_->input_special_multialign,
119                             FL_RETURN_END);
120
121         fl_addto_tabfolder(dialog_->tabFolder, _("Tabular"),
122                            tabular_options_->form);
123         fl_addto_tabfolder(dialog_->tabFolder, _("Column/Row"),
124                            column_options_->form);
125         fl_addto_tabfolder(dialog_->tabFolder, _("Cell"),
126                            cell_options_->form);
127         fl_addto_tabfolder(dialog_->tabFolder, _("LongTable"),
128                            longtable_options_->form);
129 }
130
131
132 void FormTabular::update()
133 {
134         if (!inset_ || !inset_->tabular)
135                 return;
136
137         LyXTabular * tabular = inset_->tabular;
138         int
139                 align,
140                 cell;
141         char
142                 buf[12];
143         string
144                 pwidth, special;
145
146         actCell_ = cell = inset_->GetActCell();
147         int column = tabular->column_of_cell(cell)+1;
148         fl_set_object_label(dialog_->text_warning,"");
149         fl_activate_object(column_options_->input_special_alignment);
150         fl_activate_object(cell_options_->input_special_multialign);
151         fl_activate_object(column_options_->input_column_width);
152         sprintf(buf,"%d",column);
153         fl_set_input(dialog_->input_tabular_column, buf);
154         fl_deactivate_object(dialog_->input_tabular_column);
155         int row = tabular->row_of_cell(cell)+1;
156         sprintf(buf,"%d",row);
157         fl_set_input(dialog_->input_tabular_row, buf);
158         fl_deactivate_object(dialog_->input_tabular_row);
159         if (tabular->IsMultiColumn(cell)) {
160                 fl_set_button(cell_options_->radio_multicolumn, 1);
161                 fl_set_button(cell_options_->radio_border_top,
162                               tabular->TopLine(cell)?1:0);
163                 setEnabled(cell_options_->radio_border_top, true);
164                 fl_set_button(cell_options_->radio_border_bottom,
165                               tabular->BottomLine(cell)?1:0);
166                 setEnabled(cell_options_->radio_border_bottom, true);
167                 fl_set_button(cell_options_->radio_border_left,
168                               tabular->LeftLine(cell)?1:0);
169                 setEnabled(cell_options_->radio_border_left, true);
170                 fl_set_button(cell_options_->radio_border_right,
171                               tabular->RightLine(cell)?1:0);
172                 setEnabled(cell_options_->radio_border_right, true);
173                 pwidth = tabular->GetMColumnPWidth(cell);
174                 align = tabular->GetAlignment(cell);
175                 if (!pwidth.empty() || (align == LYX_ALIGN_LEFT))
176                         fl_set_button(cell_options_->radio_align_left, 1);
177                 else if (align == LYX_ALIGN_RIGHT)
178                         fl_set_button(cell_options_->radio_align_right, 1);
179                 else
180                         fl_set_button(cell_options_->radio_align_center, 1);
181                 setEnabled(cell_options_->radio_align_left,   true);
182                 setEnabled(cell_options_->radio_align_right,  true);
183                 setEnabled(cell_options_->radio_align_center, true);
184                 align = tabular->GetVAlignment(cell);
185                 fl_set_button(cell_options_->radio_valign_top, 0);
186                 fl_set_button(cell_options_->radio_valign_bottom, 0);
187                 fl_set_button(cell_options_->radio_valign_center, 0);
188                 if (pwidth.empty() || (align == LyXTabular::LYX_VALIGN_CENTER))
189                         fl_set_button(cell_options_->radio_valign_center, 1);
190                 else if (align == LyXTabular::LYX_VALIGN_BOTTOM)
191                         fl_set_button(cell_options_->radio_valign_bottom, 1);
192                 else
193                         fl_set_button(cell_options_->radio_valign_top, 1);
194                 setEnabled(cell_options_->radio_valign_top,    true);
195                 setEnabled(cell_options_->radio_valign_bottom, true);
196                 setEnabled(cell_options_->radio_valign_center, true);
197                 special = tabular->GetAlignSpecial(cell,LyXTabular::SET_SPECIAL_MULTI);
198                 fl_set_input(cell_options_->input_special_multialign, special.c_str());
199                 fl_set_input(cell_options_->input_mcolumn_width,pwidth.c_str());
200                 if (!lv_->buffer()->isReadonly()) {
201                         setEnabled(cell_options_->input_special_multialign, true);
202                         setEnabled(cell_options_->input_mcolumn_width, true);
203                 }
204
205                 setEnabled(cell_options_->radio_valign_top,    !pwidth.empty());
206                 setEnabled(cell_options_->radio_valign_bottom, !pwidth.empty());
207                 setEnabled(cell_options_->radio_valign_center, !pwidth.empty());
208                 
209                 setEnabled(cell_options_->radio_align_left,   pwidth.empty());
210                 setEnabled(cell_options_->radio_align_right,  pwidth.empty());
211                 setEnabled(cell_options_->radio_align_center, pwidth.empty());
212         } else {
213                 fl_set_button(cell_options_->radio_multicolumn, 0);
214
215                 fl_set_button(cell_options_->radio_border_top, 0);
216                 setEnabled(cell_options_->radio_border_top, false);
217
218                 fl_set_button(cell_options_->radio_border_bottom, 0);
219                 setEnabled(cell_options_->radio_border_bottom, false);
220
221                 fl_set_button(cell_options_->radio_border_left, 0);
222                 setEnabled(cell_options_->radio_border_left, false);
223
224                 fl_set_button(cell_options_->radio_border_right, 0);
225                 setEnabled(cell_options_->radio_border_right, false);
226
227                 fl_set_button(cell_options_->radio_align_left, 0);
228                 setEnabled(cell_options_->radio_align_left, false);
229
230                 fl_set_button(cell_options_->radio_align_right, 0);
231                 setEnabled(cell_options_->radio_align_right, false);
232
233                 fl_set_button(cell_options_->radio_align_center, 0);
234                 setEnabled(cell_options_->radio_align_center, false);
235
236                 fl_set_button(cell_options_->radio_valign_top, 0);
237                 setEnabled(cell_options_->radio_valign_top, false);
238
239                 fl_set_button(cell_options_->radio_valign_bottom, 0);
240                 setEnabled(cell_options_->radio_valign_bottom, false);
241
242                 fl_set_button(cell_options_->radio_valign_center, 0);
243                 setEnabled(cell_options_->radio_valign_center, false);
244
245                 fl_set_input(cell_options_->input_special_multialign, "");
246                 setEnabled(cell_options_->input_special_multialign, false);
247
248                 fl_set_input(cell_options_->input_mcolumn_width, "");
249                 setEnabled(cell_options_->input_mcolumn_width, false);
250         }
251         if (tabular->GetRotateCell(cell))
252                 fl_set_button(cell_options_->radio_rotate_cell, 1);
253         else
254                 fl_set_button(cell_options_->radio_rotate_cell, 0);
255         if (tabular->TopLine(cell, true))
256                 fl_set_button(column_options_->radio_border_top, 1);
257         else
258                 fl_set_button(column_options_->radio_border_top, 0);
259         if (tabular->BottomLine(cell, true))
260                 fl_set_button(column_options_->radio_border_bottom, 1);
261         else
262                 fl_set_button(column_options_->radio_border_bottom, 0);
263         if (tabular->LeftLine(cell, true))
264                 fl_set_button(column_options_->radio_border_left, 1);
265         else
266                 fl_set_button(column_options_->radio_border_left, 0);
267         if (tabular->RightLine(cell, true))
268                 fl_set_button(column_options_->radio_border_right, 1);
269         else
270                 fl_set_button(column_options_->radio_border_right, 0);
271         special = tabular->GetAlignSpecial(cell,LyXTabular::SET_SPECIAL_COLUMN);
272         fl_set_input(column_options_->input_special_alignment, special.c_str());
273
274         bool const isReadonly = lv_->buffer()->isReadonly();
275         setEnabled(column_options_->input_special_alignment, !isReadonly);
276
277         pwidth = tabular->GetColumnPWidth(cell);
278         fl_set_input(column_options_->input_column_width,pwidth.c_str());
279         setEnabled(column_options_->input_column_width, !isReadonly);
280
281         setEnabled(cell_options_->radio_useminipage, !pwidth.empty());
282         if (!pwidth.empty()) {
283                 if (tabular->GetUsebox(cell) == 2)
284                         fl_set_button(cell_options_->radio_useminipage, 1);
285                 else
286                         fl_set_button(cell_options_->radio_useminipage, 0);
287         } else {
288                 fl_set_button(cell_options_->radio_useminipage,0);
289         }
290         align = tabular->GetAlignment(cell, true);
291         fl_set_button(column_options_->radio_align_left, 0);
292         fl_set_button(column_options_->radio_align_right, 0);
293         fl_set_button(column_options_->radio_align_center, 0);
294         if (!pwidth.empty() || (align == LYX_ALIGN_LEFT))
295                 fl_set_button(column_options_->radio_align_left, 1);
296         else if (align == LYX_ALIGN_RIGHT)
297                 fl_set_button(column_options_->radio_align_right, 1);
298         else
299                 fl_set_button(column_options_->radio_align_center, 1);
300         align = tabular->GetVAlignment(cell, true);
301         fl_set_button(column_options_->radio_valign_top, 0);
302         fl_set_button(column_options_->radio_valign_bottom, 0);
303         fl_set_button(column_options_->radio_valign_center, 0);
304         if (pwidth.empty() || (align == LyXTabular::LYX_VALIGN_CENTER))
305                 fl_set_button(column_options_->radio_valign_center, 1);
306         else if (align == LyXTabular::LYX_VALIGN_BOTTOM)
307                 fl_set_button(column_options_->radio_valign_bottom, 1);
308         else
309                 fl_set_button(column_options_->radio_valign_top, 1);
310
311         setEnabled(column_options_->radio_align_left,   pwidth.empty());
312         setEnabled(column_options_->radio_align_right,  pwidth.empty());
313         setEnabled(column_options_->radio_align_center, pwidth.empty());
314         
315         setEnabled(column_options_->radio_valign_top,    !pwidth.empty());
316         setEnabled(column_options_->radio_valign_bottom, !pwidth.empty());
317         setEnabled(column_options_->radio_valign_center, !pwidth.empty());
318
319         fl_set_button(tabular_options_->radio_longtable,
320                       tabular->IsLongTabular());
321
322         bool const enable = tabular->IsLongTabular();
323         setEnabled(longtable_options_->radio_lt_firsthead, enable);
324         setEnabled(longtable_options_->radio_lt_head,      enable);
325         setEnabled(longtable_options_->radio_lt_foot,      enable);
326         setEnabled(longtable_options_->radio_lt_lastfoot,  enable);
327         setEnabled(longtable_options_->radio_lt_newpage,   enable);
328
329         if (enable) {
330                 int dummy;
331                 fl_set_button(longtable_options_->radio_lt_firsthead,
332                               tabular->GetRowOfLTFirstHead(cell, dummy));
333                 fl_set_button(longtable_options_->radio_lt_head,
334                               tabular->GetRowOfLTHead(cell, dummy));
335                 fl_set_button(longtable_options_->radio_lt_foot,
336                               tabular->GetRowOfLTFoot(cell, dummy));
337                 fl_set_button(longtable_options_->radio_lt_lastfoot,
338                               tabular->GetRowOfLTLastFoot(cell, dummy));
339                 fl_set_button(longtable_options_->radio_lt_newpage,
340                               tabular->GetLTNewPage(cell));
341         } else {
342                 fl_set_button(longtable_options_->radio_lt_firsthead,0);
343                 fl_set_button(longtable_options_->radio_lt_head,0);
344                 fl_set_button(longtable_options_->radio_lt_foot,0);
345                 fl_set_button(longtable_options_->radio_lt_lastfoot,0);
346                 fl_set_button(longtable_options_->radio_lt_newpage,0);
347         }
348         fl_set_button(tabular_options_->radio_rotate_tabular,
349                       tabular->GetRotateTabular());
350 }
351
352 bool FormTabular::input(FL_OBJECT * ob, long)
353 {
354     if (!inset_)
355         return false;
356
357     LyXTabular * tabular = inset_->tabular;
358     int s;
359     LyXTabular::Feature num = LyXTabular::LAST_ACTION;
360     string special;;
361
362     int cell = inset_->GetActCell();
363     if (actCell_ != cell) {
364         update();
365         fl_set_object_label(dialog_->text_warning,
366                      _("Warning: Wrong Cursor position, updated window"));
367         fl_show_object(dialog_->text_warning);
368         return false;
369     }
370     // No point in processing directives that you can't do anything with
371     // anyhow, so exit now if the buffer is read-only.
372     if (lv_->buffer()->isReadonly()) {
373       update();
374       return false;
375     }
376     if (ob == column_options_->input_column_width) {
377         string str = fl_get_input(ob);
378         if (!str.empty() && !isValidLength(str)) {
379             fl_set_object_label(dialog_->text_warning,
380                  _("Warning: Invalid Length (valid example: 10mm)"));
381             fl_show_object(dialog_->text_warning);
382             return false;
383         }
384         inset_->TabularFeatures(lv_->view(), LyXTabular::SET_PWIDTH,str);
385         update(); // update for alignment
386         return true;
387     }
388     if (ob == cell_options_->input_mcolumn_width) {
389         string str = fl_get_input(ob);
390         if (!str.empty() && !isValidLength(str)) {
391             fl_set_object_label(dialog_->text_warning,
392                  _("Warning: Invalid Length (valid example: 10mm)"));
393             fl_show_object(dialog_->text_warning);
394             return false;
395         }
396         inset_->TabularFeatures(lv_->view(), LyXTabular::SET_MPWIDTH,str);
397         update(); // update for alignment
398         return true;
399     }
400     string str = fl_get_input(column_options_->input_column_width);
401     if (!str.empty() && !isValidLength(str)) {
402         fl_set_object_label(
403             dialog_->text_warning,
404             _("Warning: Invalid Length (valid example: 10mm)"));
405         fl_show_object(dialog_->text_warning);
406         return false;
407     }
408     if (ob == tabular_options_->button_append_row)
409         num = LyXTabular::APPEND_ROW;
410     else if (ob == tabular_options_->button_append_column)
411         num = LyXTabular::APPEND_COLUMN;
412     else if (ob == tabular_options_->button_delete_row)
413         num = LyXTabular::DELETE_ROW;
414     else if (ob == tabular_options_->button_delete_column)
415         num = LyXTabular::DELETE_COLUMN;
416     else if (ob == tabular_options_->button_set_borders)
417         num = LyXTabular::SET_ALL_LINES;
418     else if (ob == tabular_options_->button_unset_borders)
419         num = LyXTabular::UNSET_ALL_LINES;
420     else if (ob == column_options_->radio_border_top)
421         num = LyXTabular::TOGGLE_LINE_TOP;
422     else if (ob == column_options_->radio_border_bottom)
423         num = LyXTabular::TOGGLE_LINE_BOTTOM;
424     else if (ob == column_options_->radio_border_left)
425         num = LyXTabular::TOGGLE_LINE_LEFT;
426     else if (ob == column_options_->radio_border_right)
427         num = LyXTabular::TOGGLE_LINE_RIGHT;
428     else if (ob == column_options_->radio_align_left)
429         num = LyXTabular::ALIGN_LEFT;
430     else if (ob == column_options_->radio_align_right)
431         num = LyXTabular::ALIGN_RIGHT;
432     else if (ob == column_options_->radio_align_center)
433         num = LyXTabular::ALIGN_CENTER;
434     else if (ob == column_options_->radio_valign_top)
435         num = LyXTabular::VALIGN_TOP;
436     else if (ob == column_options_->radio_valign_bottom)
437         num = LyXTabular::VALIGN_BOTTOM;
438     else if (ob == column_options_->radio_valign_center)
439         num = LyXTabular::VALIGN_CENTER;
440     else if (ob == cell_options_->radio_multicolumn)
441         num = LyXTabular::MULTICOLUMN;
442     else if (ob == tabular_options_->radio_longtable) {
443             bool const enable =
444                     fl_get_button(tabular_options_->radio_longtable);
445             
446             setEnabled(longtable_options_->radio_lt_firsthead, enable);
447             setEnabled(longtable_options_->radio_lt_head,      enable);
448             setEnabled(longtable_options_->radio_lt_foot,      enable);
449             setEnabled(longtable_options_->radio_lt_lastfoot,  enable);
450             setEnabled(longtable_options_->radio_lt_newpage,   enable);
451
452             if (enable) {
453                     num = LyXTabular::SET_LONGTABULAR;
454                     int dummy;
455                     fl_set_button(longtable_options_->radio_lt_firsthead,
456                                   tabular->GetRowOfLTFirstHead(cell, dummy));
457                     fl_set_button(longtable_options_->radio_lt_head,
458                                   tabular->GetRowOfLTHead(cell, dummy));
459                     fl_set_button(longtable_options_->radio_lt_foot,
460                                   tabular->GetRowOfLTFoot(cell, dummy));
461                     fl_set_button(longtable_options_->radio_lt_lastfoot,
462                                   tabular->GetRowOfLTLastFoot(cell, dummy));
463                     fl_set_button(longtable_options_->radio_lt_firsthead,
464                                   tabular->GetLTNewPage(cell));
465             } else {
466                     num = LyXTabular::UNSET_LONGTABULAR;
467                     fl_set_button(longtable_options_->radio_lt_firsthead,0);
468                     fl_set_button(longtable_options_->radio_lt_head,0);
469                     fl_set_button(longtable_options_->radio_lt_foot,0);
470                     fl_set_button(longtable_options_->radio_lt_lastfoot,0);
471                     fl_set_button(longtable_options_->radio_lt_newpage,0);
472             }
473     } else if (ob == tabular_options_->radio_rotate_tabular) {
474         s = fl_get_button(tabular_options_->radio_rotate_tabular);
475         if (s)
476             num = LyXTabular::SET_ROTATE_TABULAR;
477         else
478             num = LyXTabular::UNSET_ROTATE_TABULAR;
479     } else if (ob == cell_options_->radio_rotate_cell) {
480         s = fl_get_button(cell_options_->radio_rotate_cell);
481         if (s)
482             num = LyXTabular::SET_ROTATE_CELL;
483         else
484             num = LyXTabular::UNSET_ROTATE_CELL;
485     } else if (ob == cell_options_->radio_useminipage) {
486         num = LyXTabular::SET_USEBOX;
487         special = "2";
488     } else if (ob == longtable_options_->radio_lt_firsthead) {
489         num = LyXTabular::SET_LTFIRSTHEAD;
490     } else if (ob == longtable_options_->radio_lt_head) {
491         num = LyXTabular::SET_LTHEAD;
492     } else if (ob == longtable_options_->radio_lt_foot) {
493         num = LyXTabular::SET_LTFOOT;
494     } else if (ob == longtable_options_->radio_lt_lastfoot) {
495         num = LyXTabular::SET_LTLASTFOOT;
496     } else if (ob == longtable_options_->radio_lt_newpage) {
497         num = LyXTabular::SET_LTNEWPAGE;
498     } else if (ob == column_options_->input_special_alignment) {
499         special = fl_get_input(column_options_->input_special_alignment);
500         num = LyXTabular::SET_SPECIAL_COLUMN;
501     } else if (ob == cell_options_->input_special_multialign) {
502         special = fl_get_input(cell_options_->input_special_multialign);
503         num = LyXTabular::SET_SPECIAL_MULTI;
504     } else if (ob == cell_options_->radio_border_top)
505         num = LyXTabular::M_TOGGLE_LINE_TOP;
506     else if (ob == cell_options_->radio_border_bottom)
507         num = LyXTabular::M_TOGGLE_LINE_BOTTOM;
508     else if (ob == cell_options_->radio_border_left)
509         num = LyXTabular::M_TOGGLE_LINE_LEFT;
510     else if (ob == cell_options_->radio_border_right)
511         num = LyXTabular::M_TOGGLE_LINE_RIGHT;
512     else if (ob == cell_options_->radio_align_left)
513         num = LyXTabular::M_ALIGN_LEFT;
514     else if (ob == cell_options_->radio_align_right)
515         num = LyXTabular::M_ALIGN_RIGHT;
516     else if (ob == cell_options_->radio_align_center)
517         num = LyXTabular::M_ALIGN_CENTER;
518     else if (ob == cell_options_->radio_valign_top)
519         num = LyXTabular::M_VALIGN_TOP;
520     else if (ob == cell_options_->radio_valign_bottom)
521         num = LyXTabular::M_VALIGN_BOTTOM;
522     else if (ob == cell_options_->radio_valign_center)
523         num = LyXTabular::M_VALIGN_CENTER;
524     else
525         return false;
526     
527     inset_->TabularFeatures(lv_->view(), num, special);
528     update();
529
530     return true;
531 }