1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2001 The LyX Team.
9 *======================================================*/
11 * FormTabular Interface Class Implementation
17 #pragma implementation
20 #include "FormTabular.h"
21 #include "form_tabular.h"
24 #include "insets/insettabular.h"
26 #include "xforms_helpers.h"
27 #include "helper_funcs.h"
28 #include "input_validators.h"
29 #include "support/lstrings.h"
33 FormTabular::FormTabular(LyXView * lv, Dialogs * d)
34 : FormInset(lv, d, _("Tabular Layout")),
35 inset_(0), actCell_(-1)
37 // let the dialog be shown
38 // This is a permanent connection so we won't bother
39 // storing a copy because we won't be disconnecting.
40 d->showTabular.connect(slot(this, &FormTabular::showInset));
41 d->updateTabular.connect(slot(this, &FormTabular::updateInset));
45 void FormTabular::redraw()
47 if(form() && form()->visible)
48 fl_redraw_form(form());
52 FL_FORM * outer_form = fl_get_active_folder(dialog_->tabFolder);
53 if (outer_form && outer_form->visible)
54 fl_redraw_form(outer_form);
58 FL_FORM * FormTabular::form() const
66 void FormTabular::disconnect()
69 FormInset::disconnect();
73 void FormTabular::showInset(InsetTabular * inset)
75 if (inset == 0) return;
77 // If connected to another inset, disconnect from it.
78 if (inset_ != inset) {
80 ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide));
88 void FormTabular::updateInset(InsetTabular * inset)
90 if (inset == 0 || inset_ == 0) return;
92 // If connected to another inset, disconnect from it.
93 if (inset_ != inset) {
95 ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide));
103 void FormTabular::build()
105 dialog_.reset(build_tabular());
106 tabular_options_.reset(build_tabular_options());
107 column_options_.reset(build_column_options());
108 cell_options_.reset(build_cell_options());
109 longtable_options_.reset(build_longtable_options());
111 fl_set_input_return(column_options_->input_column_width,
113 fl_set_input_return(column_options_->input_special_alignment,
115 fl_set_input_return(cell_options_->input_mcolumn_width,
117 fl_set_input_return(cell_options_->input_special_multialign,
120 fl_addto_tabfolder(dialog_->tabFolder, _("Tabular"),
121 tabular_options_->form);
122 fl_addto_tabfolder(dialog_->tabFolder, _("Column/Row"),
123 column_options_->form);
124 fl_addto_tabfolder(dialog_->tabFolder, _("Cell"),
125 cell_options_->form);
126 fl_addto_tabfolder(dialog_->tabFolder, _("LongTable"),
127 longtable_options_->form);
129 // We should set these input filters on width fields to make them accept
130 // only unsigned numbers.
131 // But this leeds to trouble with the current apply behaviour (JSpitzm).
132 // fl_set_input_filter(column_options_->input_column_width,
133 // fl_unsigned_float_filter);
134 // fl_set_input_filter(cell_options_->input_mcolumn_width,
135 // fl_unsigned_float_filter);
137 // Create the contents of the unit choices
138 // Don't include the "%" terms...
139 std::vector<string> units_vec = getLatexUnits();
140 for (std::vector<string>::iterator it = units_vec.begin();
141 it != units_vec.end(); ++it) {
142 if (contains(*it, "%"))
143 it = units_vec.erase(it, it+1) - 1;
145 string units = getStringFromVector(units_vec, "|");
147 fl_addto_choice(column_options_->choice_value_column_width,
149 fl_addto_choice(cell_options_->choice_value_mcolumn_width,
154 void FormTabular::update()
156 if (!inset_ || !inset_->tabular.get())
159 LyXTabular * tabular = inset_->tabular.get();
165 int cell = inset_->getActCell();
167 int column = tabular->column_of_cell(cell)+1;
168 fl_set_object_label(dialog_->text_warning,"");
169 fl_activate_object(column_options_->input_special_alignment);
170 fl_activate_object(cell_options_->input_special_multialign);
171 fl_activate_object(column_options_->input_column_width);
172 fl_activate_object(column_options_->choice_value_column_width);
173 sprintf(buf,"%d",column);
174 fl_set_input(dialog_->input_tabular_column, buf);
175 fl_deactivate_object(dialog_->input_tabular_column);
176 int row = tabular->row_of_cell(cell)+1;
177 sprintf(buf,"%d",row);
178 fl_set_input(dialog_->input_tabular_row, buf);
179 fl_deactivate_object(dialog_->input_tabular_row);
180 if (tabular->IsMultiColumn(cell)) {
181 fl_set_button(cell_options_->radio_multicolumn, 1);
182 fl_set_button(cell_options_->radio_border_top,
183 tabular->TopLine(cell)?1:0);
184 setEnabled(cell_options_->radio_border_top, true);
185 fl_set_button(cell_options_->radio_border_bottom,
186 tabular->BottomLine(cell)?1:0);
187 setEnabled(cell_options_->radio_border_bottom, true);
188 fl_set_button(cell_options_->radio_border_left,
189 tabular->LeftLine(cell)?1:0);
190 setEnabled(cell_options_->radio_border_left, true);
191 fl_set_button(cell_options_->radio_border_right,
192 tabular->RightLine(cell)?1:0);
193 setEnabled(cell_options_->radio_border_right, true);
194 pwidth = tabular->GetMColumnPWidth(cell);
195 align = tabular->GetAlignment(cell);
196 if (!pwidth.empty() || (align == LYX_ALIGN_LEFT))
197 fl_set_button(cell_options_->radio_align_left, 1);
198 else if (align == LYX_ALIGN_RIGHT)
199 fl_set_button(cell_options_->radio_align_right, 1);
201 fl_set_button(cell_options_->radio_align_center, 1);
202 setEnabled(cell_options_->radio_align_left, true);
203 setEnabled(cell_options_->radio_align_right, true);
204 setEnabled(cell_options_->radio_align_center, true);
205 align = tabular->GetVAlignment(cell);
206 fl_set_button(cell_options_->radio_valign_top, 0);
207 fl_set_button(cell_options_->radio_valign_bottom, 0);
208 fl_set_button(cell_options_->radio_valign_center, 0);
209 if (pwidth.empty() || (align == LyXTabular::LYX_VALIGN_CENTER))
210 fl_set_button(cell_options_->radio_valign_center, 1);
211 else if (align == LyXTabular::LYX_VALIGN_BOTTOM)
212 fl_set_button(cell_options_->radio_valign_bottom, 1);
214 fl_set_button(cell_options_->radio_valign_top, 1);
215 setEnabled(cell_options_->radio_valign_top, true);
216 setEnabled(cell_options_->radio_valign_bottom, true);
217 setEnabled(cell_options_->radio_valign_center, true);
218 special = tabular->GetAlignSpecial(cell,LyXTabular::SET_SPECIAL_MULTI);
219 fl_set_input(cell_options_->input_special_multialign, special.c_str());
220 string const default_unit = "cm";
221 updateWidgetsFromLengthString(cell_options_->input_mcolumn_width,
222 cell_options_->choice_value_mcolumn_width,
223 pwidth.c_str(), default_unit);
225 if (!lv_->buffer()->isReadonly()) {
226 setEnabled(cell_options_->input_special_multialign, true);
227 setEnabled(cell_options_->input_mcolumn_width, true);
228 setEnabled(cell_options_->choice_value_mcolumn_width, true);
231 setEnabled(cell_options_->radio_valign_top, !pwidth.empty());
232 setEnabled(cell_options_->radio_valign_bottom, !pwidth.empty());
233 setEnabled(cell_options_->radio_valign_center, !pwidth.empty());
235 setEnabled(cell_options_->radio_align_left, pwidth.empty());
236 setEnabled(cell_options_->radio_align_right, pwidth.empty());
237 setEnabled(cell_options_->radio_align_center, pwidth.empty());
239 fl_set_button(cell_options_->radio_multicolumn, 0);
241 fl_set_button(cell_options_->radio_border_top, 0);
242 setEnabled(cell_options_->radio_border_top, false);
244 fl_set_button(cell_options_->radio_border_bottom, 0);
245 setEnabled(cell_options_->radio_border_bottom, false);
247 fl_set_button(cell_options_->radio_border_left, 0);
248 setEnabled(cell_options_->radio_border_left, false);
250 fl_set_button(cell_options_->radio_border_right, 0);
251 setEnabled(cell_options_->radio_border_right, false);
253 fl_set_button(cell_options_->radio_align_left, 0);
254 setEnabled(cell_options_->radio_align_left, false);
256 fl_set_button(cell_options_->radio_align_right, 0);
257 setEnabled(cell_options_->radio_align_right, false);
259 fl_set_button(cell_options_->radio_align_center, 0);
260 setEnabled(cell_options_->radio_align_center, false);
262 fl_set_button(cell_options_->radio_valign_top, 0);
263 setEnabled(cell_options_->radio_valign_top, false);
265 fl_set_button(cell_options_->radio_valign_bottom, 0);
266 setEnabled(cell_options_->radio_valign_bottom, false);
268 fl_set_button(cell_options_->radio_valign_center, 0);
269 setEnabled(cell_options_->radio_valign_center, false);
271 fl_set_input(cell_options_->input_special_multialign, "");
272 setEnabled(cell_options_->input_special_multialign, false);
274 fl_set_input(cell_options_->input_mcolumn_width, "");
275 setEnabled(cell_options_->input_mcolumn_width, false);
276 setEnabled(cell_options_->choice_value_mcolumn_width, false);
278 if (tabular->GetRotateCell(cell))
279 fl_set_button(cell_options_->radio_rotate_cell, 1);
281 fl_set_button(cell_options_->radio_rotate_cell, 0);
282 if (tabular->TopLine(cell, true))
283 fl_set_button(column_options_->radio_border_top, 1);
285 fl_set_button(column_options_->radio_border_top, 0);
286 if (tabular->BottomLine(cell, true))
287 fl_set_button(column_options_->radio_border_bottom, 1);
289 fl_set_button(column_options_->radio_border_bottom, 0);
290 if (tabular->LeftLine(cell, true))
291 fl_set_button(column_options_->radio_border_left, 1);
293 fl_set_button(column_options_->radio_border_left, 0);
294 if (tabular->RightLine(cell, true))
295 fl_set_button(column_options_->radio_border_right, 1);
297 fl_set_button(column_options_->radio_border_right, 0);
298 special = tabular->GetAlignSpecial(cell,LyXTabular::SET_SPECIAL_COLUMN);
299 fl_set_input(column_options_->input_special_alignment, special.c_str());
301 bool const isReadonly = lv_->buffer()->isReadonly();
302 setEnabled(column_options_->input_special_alignment, !isReadonly);
304 pwidth = tabular->GetColumnPWidth(cell);
305 string const default_unit = "cm";
306 updateWidgetsFromLengthString(column_options_->input_column_width,
307 column_options_->choice_value_column_width,
308 pwidth.c_str(), default_unit);
309 setEnabled(column_options_->input_column_width, !isReadonly);
310 setEnabled(column_options_->choice_value_column_width, !isReadonly);
312 setEnabled(cell_options_->radio_useminipage, !pwidth.empty());
313 if (!pwidth.empty()) {
314 if (tabular->GetUsebox(cell) == 2)
315 fl_set_button(cell_options_->radio_useminipage, 1);
317 fl_set_button(cell_options_->radio_useminipage, 0);
319 fl_set_button(cell_options_->radio_useminipage,0);
321 align = tabular->GetAlignment(cell, true);
322 fl_set_button(column_options_->radio_align_left, 0);
323 fl_set_button(column_options_->radio_align_right, 0);
324 fl_set_button(column_options_->radio_align_center, 0);
325 if (!pwidth.empty() || (align == LYX_ALIGN_LEFT))
326 fl_set_button(column_options_->radio_align_left, 1);
327 else if (align == LYX_ALIGN_RIGHT)
328 fl_set_button(column_options_->radio_align_right, 1);
330 fl_set_button(column_options_->radio_align_center, 1);
331 align = tabular->GetVAlignment(cell, true);
332 fl_set_button(column_options_->radio_valign_top, 0);
333 fl_set_button(column_options_->radio_valign_bottom, 0);
334 fl_set_button(column_options_->radio_valign_center, 0);
335 if (pwidth.empty() || (align == LyXTabular::LYX_VALIGN_CENTER))
336 fl_set_button(column_options_->radio_valign_center, 1);
337 else if (align == LyXTabular::LYX_VALIGN_BOTTOM)
338 fl_set_button(column_options_->radio_valign_bottom, 1);
340 fl_set_button(column_options_->radio_valign_top, 1);
342 setEnabled(column_options_->radio_align_left, pwidth.empty());
343 setEnabled(column_options_->radio_align_right, pwidth.empty());
344 setEnabled(column_options_->radio_align_center, pwidth.empty());
346 setEnabled(column_options_->radio_valign_top, !pwidth.empty());
347 setEnabled(column_options_->radio_valign_bottom, !pwidth.empty());
348 setEnabled(column_options_->radio_valign_center, !pwidth.empty());
350 fl_set_button(tabular_options_->radio_longtable,
351 tabular->IsLongTabular());
353 bool const enable = tabular->IsLongTabular();
354 setEnabled(longtable_options_->radio_lt_firsthead, enable);
355 setEnabled(longtable_options_->radio_lt_head, enable);
356 setEnabled(longtable_options_->radio_lt_foot, enable);
357 setEnabled(longtable_options_->radio_lt_lastfoot, enable);
358 setEnabled(longtable_options_->radio_lt_newpage, enable);
361 LyXTabular::ltType dummyltt;
362 fl_set_button(longtable_options_->radio_lt_firsthead,
363 tabular->GetRowOfLTFirstHead(row-1, dummyltt));
364 fl_set_button(longtable_options_->radio_lt_head,
365 tabular->GetRowOfLTHead(row-1, dummyltt));
366 fl_set_button(longtable_options_->radio_lt_foot,
367 tabular->GetRowOfLTFoot(row-1, dummyltt));
368 fl_set_button(longtable_options_->radio_lt_lastfoot,
369 tabular->GetRowOfLTLastFoot(row-1, dummyltt));
370 fl_set_button(longtable_options_->radio_lt_newpage,
371 tabular->GetLTNewPage(cell));
373 fl_set_button(longtable_options_->radio_lt_firsthead,0);
374 fl_set_button(longtable_options_->radio_lt_head,0);
375 fl_set_button(longtable_options_->radio_lt_foot,0);
376 fl_set_button(longtable_options_->radio_lt_lastfoot,0);
377 fl_set_button(longtable_options_->radio_lt_newpage,0);
379 fl_set_button(tabular_options_->radio_rotate_tabular,
380 tabular->GetRotateTabular());
384 bool FormTabular::input(FL_OBJECT * ob, long)
389 LyXTabular * tabular = inset_->tabular.get();
391 LyXTabular::Feature num = LyXTabular::LAST_ACTION;
394 int cell = inset_->getActCell();
395 int row = tabular->row_of_cell(cell);
397 if (actCell_ != cell) {
399 fl_set_object_label(dialog_->text_warning,
400 _("Warning: Wrong Cursor position, updated window"));
401 fl_show_object(dialog_->text_warning);
404 // No point in processing directives that you can't do anything with
405 // anyhow, so exit now if the buffer is read-only.
406 if (lv_->buffer()->isReadonly()) {
410 if (ob == column_options_->input_column_width) {
412 getLengthFromWidgets(column_options_->input_column_width,
413 column_options_->choice_value_column_width);
414 inset_->tabularFeatures(lv_->view(), LyXTabular::SET_PWIDTH,str);
415 update(); // update for alignment
418 if (ob == cell_options_->input_mcolumn_width) {
420 getLengthFromWidgets(cell_options_->input_mcolumn_width,
421 cell_options_->choice_value_mcolumn_width);
422 inset_->tabularFeatures(lv_->view(), LyXTabular::SET_MPWIDTH,str);
423 update(); // update for alignment
427 if (ob == tabular_options_->button_append_row)
428 num = LyXTabular::APPEND_ROW;
429 else if (ob == tabular_options_->button_append_column)
430 num = LyXTabular::APPEND_COLUMN;
431 else if (ob == tabular_options_->button_delete_row)
432 num = LyXTabular::DELETE_ROW;
433 else if (ob == tabular_options_->button_delete_column)
434 num = LyXTabular::DELETE_COLUMN;
435 else if (ob == tabular_options_->button_set_borders)
436 num = LyXTabular::SET_ALL_LINES;
437 else if (ob == tabular_options_->button_unset_borders)
438 num = LyXTabular::UNSET_ALL_LINES;
439 else if (ob == column_options_->radio_border_top)
440 num = LyXTabular::TOGGLE_LINE_TOP;
441 else if (ob == column_options_->radio_border_bottom)
442 num = LyXTabular::TOGGLE_LINE_BOTTOM;
443 else if (ob == column_options_->radio_border_left)
444 num = LyXTabular::TOGGLE_LINE_LEFT;
445 else if (ob == column_options_->radio_border_right)
446 num = LyXTabular::TOGGLE_LINE_RIGHT;
447 else if (ob == column_options_->radio_align_left)
448 num = LyXTabular::ALIGN_LEFT;
449 else if (ob == column_options_->radio_align_right)
450 num = LyXTabular::ALIGN_RIGHT;
451 else if (ob == column_options_->radio_align_center)
452 num = LyXTabular::ALIGN_CENTER;
453 else if (ob == column_options_->radio_valign_top)
454 num = LyXTabular::VALIGN_TOP;
455 else if (ob == column_options_->radio_valign_bottom)
456 num = LyXTabular::VALIGN_BOTTOM;
457 else if (ob == column_options_->radio_valign_center)
458 num = LyXTabular::VALIGN_CENTER;
459 else if (ob == cell_options_->radio_multicolumn)
460 num = LyXTabular::MULTICOLUMN;
461 else if (ob == tabular_options_->radio_longtable) {
463 fl_get_button(tabular_options_->radio_longtable);
465 setEnabled(longtable_options_->radio_lt_firsthead, enable);
466 setEnabled(longtable_options_->radio_lt_head, enable);
467 setEnabled(longtable_options_->radio_lt_foot, enable);
468 setEnabled(longtable_options_->radio_lt_lastfoot, enable);
469 setEnabled(longtable_options_->radio_lt_newpage, enable);
472 num = LyXTabular::SET_LONGTABULAR;
473 LyXTabular::ltType dummyltt;
474 fl_set_button(longtable_options_->radio_lt_firsthead,
475 tabular->GetRowOfLTFirstHead(row, dummyltt));
476 fl_set_button(longtable_options_->radio_lt_head,
477 tabular->GetRowOfLTHead(row, dummyltt));
478 fl_set_button(longtable_options_->radio_lt_foot,
479 tabular->GetRowOfLTFoot(row, dummyltt));
480 fl_set_button(longtable_options_->radio_lt_lastfoot,
481 tabular->GetRowOfLTLastFoot(row, dummyltt));
482 fl_set_button(longtable_options_->radio_lt_firsthead,
483 tabular->GetLTNewPage(cell));
485 num = LyXTabular::UNSET_LONGTABULAR;
486 fl_set_button(longtable_options_->radio_lt_firsthead,0);
487 fl_set_button(longtable_options_->radio_lt_head,0);
488 fl_set_button(longtable_options_->radio_lt_foot,0);
489 fl_set_button(longtable_options_->radio_lt_lastfoot,0);
490 fl_set_button(longtable_options_->radio_lt_newpage,0);
492 } else if (ob == tabular_options_->radio_rotate_tabular) {
493 s = fl_get_button(tabular_options_->radio_rotate_tabular);
495 num = LyXTabular::SET_ROTATE_TABULAR;
497 num = LyXTabular::UNSET_ROTATE_TABULAR;
498 } else if (ob == cell_options_->radio_rotate_cell) {
499 s = fl_get_button(cell_options_->radio_rotate_cell);
501 num = LyXTabular::SET_ROTATE_CELL;
503 num = LyXTabular::UNSET_ROTATE_CELL;
504 } else if (ob == cell_options_->radio_useminipage) {
505 num = LyXTabular::SET_USEBOX;
507 } else if (ob == longtable_options_->radio_lt_firsthead) {
508 if (fl_get_button(ob))
509 num = LyXTabular::SET_LTFIRSTHEAD;
511 num = LyXTabular::UNSET_LTFIRSTHEAD;
512 } else if (ob == longtable_options_->radio_lt_head) {
513 if (fl_get_button(ob))
514 num = LyXTabular::SET_LTHEAD;
516 num = LyXTabular::UNSET_LTHEAD;
517 } else if (ob == longtable_options_->radio_lt_foot) {
518 if (fl_get_button(ob))
519 num = LyXTabular::SET_LTFOOT;
521 num = LyXTabular::UNSET_LTFOOT;
522 } else if (ob == longtable_options_->radio_lt_lastfoot) {
523 if (fl_get_button(ob))
524 num = LyXTabular::SET_LTLASTFOOT;
526 num = LyXTabular::UNSET_LTLASTFOOT;
527 } else if (ob == longtable_options_->radio_lt_newpage) {
528 num = LyXTabular::SET_LTNEWPAGE;
529 } else if (ob == column_options_->input_special_alignment) {
530 special = fl_get_input(column_options_->input_special_alignment);
531 num = LyXTabular::SET_SPECIAL_COLUMN;
532 } else if (ob == cell_options_->input_special_multialign) {
533 special = fl_get_input(cell_options_->input_special_multialign);
534 num = LyXTabular::SET_SPECIAL_MULTI;
535 } else if (ob == cell_options_->radio_border_top)
536 num = LyXTabular::M_TOGGLE_LINE_TOP;
537 else if (ob == cell_options_->radio_border_bottom)
538 num = LyXTabular::M_TOGGLE_LINE_BOTTOM;
539 else if (ob == cell_options_->radio_border_left)
540 num = LyXTabular::M_TOGGLE_LINE_LEFT;
541 else if (ob == cell_options_->radio_border_right)
542 num = LyXTabular::M_TOGGLE_LINE_RIGHT;
543 else if (ob == cell_options_->radio_align_left)
544 num = LyXTabular::M_ALIGN_LEFT;
545 else if (ob == cell_options_->radio_align_right)
546 num = LyXTabular::M_ALIGN_RIGHT;
547 else if (ob == cell_options_->radio_align_center)
548 num = LyXTabular::M_ALIGN_CENTER;
549 else if (ob == cell_options_->radio_valign_top)
550 num = LyXTabular::M_VALIGN_TOP;
551 else if (ob == cell_options_->radio_valign_bottom)
552 num = LyXTabular::M_VALIGN_BOTTOM;
553 else if (ob == cell_options_->radio_valign_center)
554 num = LyXTabular::M_VALIGN_CENTER;
558 inset_->tabularFeatures(lv_->view(), num, special);