/* This file is part of * ====================================================== * * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich * Copyright 1995-2001 The LyX Team. * *======================================================*/ /* FormTabular.C * FormTabular Interface Class Implementation */ #include #ifdef __GNUG__ #pragma implementation #endif #include "FormTabular.h" #include "form_tabular.h" #include "LyXView.h" #include "Dialogs.h" #include "insets/insettabular.h" #include "buffer.h" #include "xforms_helpers.h" #include "helper_funcs.h" #include "input_validators.h" #include "support/lstrings.h" using SigC::slot; FormTabular::FormTabular(LyXView * lv, Dialogs * d) : FormInset(lv, d, _("Tabular Layout")), inset_(0), actCell_(-1) { // let the dialog be shown // This is a permanent connection so we won't bother // storing a copy because we won't be disconnecting. d->showTabular.connect(slot(this, &FormTabular::showInset)); d->updateTabular.connect(slot(this, &FormTabular::updateInset)); } void FormTabular::redraw() { if(form() && form()->visible) fl_redraw_form(form()); else return; FL_FORM * outer_form = fl_get_active_folder(dialog_->tabFolder); if (outer_form && outer_form->visible) fl_redraw_form(outer_form); } FL_FORM * FormTabular::form() const { if (dialog_.get()) return dialog_->form; return 0; } void FormTabular::disconnect() { inset_ = 0; FormInset::disconnect(); } void FormTabular::showInset(InsetTabular * inset) { if (inset == 0) return; // If connected to another inset, disconnect from it. if (inset_ != inset) { ih_.disconnect(); ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide)); inset_ = inset; } show(); } void FormTabular::updateInset(InsetTabular * inset) { if (inset == 0 || inset_ == 0) return; // If connected to another inset, disconnect from it. if (inset_ != inset) { ih_.disconnect(); ih_ = inset->hideDialog.connect(slot(this, &FormTabular::hide)); inset_ = inset; } update(); } void FormTabular::build() { dialog_.reset(build_tabular()); tabular_options_.reset(build_tabular_options()); column_options_.reset(build_column_options()); cell_options_.reset(build_cell_options()); longtable_options_.reset(build_longtable_options()); fl_set_input_return(column_options_->input_column_width, FL_RETURN_END); fl_set_input_return(column_options_->input_special_alignment, FL_RETURN_END); fl_set_input_return(cell_options_->input_mcolumn_width, FL_RETURN_END); fl_set_input_return(cell_options_->input_special_multialign, FL_RETURN_END); fl_addto_tabfolder(dialog_->tabFolder, _("Tabular"), tabular_options_->form); fl_addto_tabfolder(dialog_->tabFolder, _("Column/Row"), column_options_->form); fl_addto_tabfolder(dialog_->tabFolder, _("Cell"), cell_options_->form); fl_addto_tabfolder(dialog_->tabFolder, _("LongTable"), longtable_options_->form); // We should set these input filters on width fields to make them accept // only unsigned numbers. // But this leeds to trouble with the current apply behaviour (JSpitzm). // fl_set_input_filter(column_options_->input_column_width, // fl_unsigned_float_filter); // fl_set_input_filter(cell_options_->input_mcolumn_width, // fl_unsigned_float_filter); // Create the contents of the unit choices // Don't include the "%" terms... std::vector units_vec = getLatexUnits(); for (std::vector::iterator it = units_vec.begin(); it != units_vec.end(); ++it) { if (contains(*it, "%")) it = units_vec.erase(it, it + 1) - 1; } string units = getStringFromVector(units_vec, "|"); fl_addto_choice(column_options_->choice_value_column_width, units.c_str()); fl_addto_choice(cell_options_->choice_value_mcolumn_width, units.c_str()); } void FormTabular::update() { if (!inset_ || !inset_->tabular.get()) return; LyXTabular * tabular = inset_->tabular.get(); int align; char buf[12]; LyXLength pwidth; string special; int cell = inset_->getActCell(); actCell_ = cell; int column = tabular->column_of_cell(cell) + 1; fl_set_object_label(dialog_->text_warning, ""); fl_activate_object(column_options_->input_special_alignment); fl_activate_object(cell_options_->input_special_multialign); fl_activate_object(column_options_->input_column_width); fl_activate_object(column_options_->choice_value_column_width); sprintf(buf, "%d", column); fl_set_input(dialog_->input_tabular_column, buf); fl_deactivate_object(dialog_->input_tabular_column); int row = tabular->row_of_cell(cell) + 1; sprintf(buf, "%d", row); fl_set_input(dialog_->input_tabular_row, buf); fl_deactivate_object(dialog_->input_tabular_row); if (tabular->IsMultiColumn(cell)) { fl_set_button(cell_options_->radio_multicolumn, 1); fl_set_button(cell_options_->radio_border_top, tabular->TopLine(cell)?1:0); setEnabled(cell_options_->radio_border_top, true); fl_set_button(cell_options_->radio_border_bottom, tabular->BottomLine(cell)?1:0); setEnabled(cell_options_->radio_border_bottom, true); fl_set_button(cell_options_->radio_border_left, tabular->LeftLine(cell)?1:0); setEnabled(cell_options_->radio_border_left, true); fl_set_button(cell_options_->radio_border_right, tabular->RightLine(cell)?1:0); setEnabled(cell_options_->radio_border_right, true); pwidth = tabular->GetMColumnPWidth(cell); align = tabular->GetAlignment(cell); if (!pwidth.zero() || (align == LYX_ALIGN_LEFT)) fl_set_button(cell_options_->radio_align_left, 1); else if (align == LYX_ALIGN_RIGHT) fl_set_button(cell_options_->radio_align_right, 1); else fl_set_button(cell_options_->radio_align_center, 1); setEnabled(cell_options_->radio_align_left, true); setEnabled(cell_options_->radio_align_right, true); setEnabled(cell_options_->radio_align_center, true); align = tabular->GetVAlignment(cell); fl_set_button(cell_options_->radio_valign_top, 0); fl_set_button(cell_options_->radio_valign_bottom, 0); fl_set_button(cell_options_->radio_valign_center, 0); if (pwidth.zero() || (align == LyXTabular::LYX_VALIGN_CENTER)) fl_set_button(cell_options_->radio_valign_center, 1); else if (align == LyXTabular::LYX_VALIGN_BOTTOM) fl_set_button(cell_options_->radio_valign_bottom, 1); else fl_set_button(cell_options_->radio_valign_top, 1); setEnabled(cell_options_->radio_valign_top, true); setEnabled(cell_options_->radio_valign_bottom, true); setEnabled(cell_options_->radio_valign_center, true); special = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_MULTI); fl_set_input(cell_options_->input_special_multialign, special.c_str()); string const default_unit = "cm"; updateWidgetsFromLength(cell_options_->input_mcolumn_width, cell_options_->choice_value_mcolumn_width, pwidth, default_unit); if (!lv_->buffer()->isReadonly()) { setEnabled(cell_options_->input_special_multialign, true); setEnabled(cell_options_->input_mcolumn_width, true); setEnabled(cell_options_->choice_value_mcolumn_width, true); } setEnabled(cell_options_->radio_valign_top, !pwidth.zero()); setEnabled(cell_options_->radio_valign_bottom, !pwidth.zero()); setEnabled(cell_options_->radio_valign_center, !pwidth.zero()); setEnabled(cell_options_->radio_align_left, pwidth.zero()); setEnabled(cell_options_->radio_align_right, pwidth.zero()); setEnabled(cell_options_->radio_align_center, pwidth.zero()); } else { fl_set_button(cell_options_->radio_multicolumn, 0); fl_set_button(cell_options_->radio_border_top, 0); setEnabled(cell_options_->radio_border_top, false); fl_set_button(cell_options_->radio_border_bottom, 0); setEnabled(cell_options_->radio_border_bottom, false); fl_set_button(cell_options_->radio_border_left, 0); setEnabled(cell_options_->radio_border_left, false); fl_set_button(cell_options_->radio_border_right, 0); setEnabled(cell_options_->radio_border_right, false); fl_set_button(cell_options_->radio_align_left, 0); setEnabled(cell_options_->radio_align_left, false); fl_set_button(cell_options_->radio_align_right, 0); setEnabled(cell_options_->radio_align_right, false); fl_set_button(cell_options_->radio_align_center, 0); setEnabled(cell_options_->radio_align_center, false); fl_set_button(cell_options_->radio_valign_top, 0); setEnabled(cell_options_->radio_valign_top, false); fl_set_button(cell_options_->radio_valign_bottom, 0); setEnabled(cell_options_->radio_valign_bottom, false); fl_set_button(cell_options_->radio_valign_center, 0); setEnabled(cell_options_->radio_valign_center, false); fl_set_input(cell_options_->input_special_multialign, ""); setEnabled(cell_options_->input_special_multialign, false); fl_set_input(cell_options_->input_mcolumn_width, ""); setEnabled(cell_options_->input_mcolumn_width, false); setEnabled(cell_options_->choice_value_mcolumn_width, false); } if (tabular->GetRotateCell(cell)) fl_set_button(cell_options_->radio_rotate_cell, 1); else fl_set_button(cell_options_->radio_rotate_cell, 0); if (tabular->TopLine(cell, true)) fl_set_button(column_options_->radio_border_top, 1); else fl_set_button(column_options_->radio_border_top, 0); if (tabular->BottomLine(cell, true)) fl_set_button(column_options_->radio_border_bottom, 1); else fl_set_button(column_options_->radio_border_bottom, 0); if (tabular->LeftLine(cell, true)) fl_set_button(column_options_->radio_border_left, 1); else fl_set_button(column_options_->radio_border_left, 0); if (tabular->RightLine(cell, true)) fl_set_button(column_options_->radio_border_right, 1); else fl_set_button(column_options_->radio_border_right, 0); special = tabular->GetAlignSpecial(cell, LyXTabular::SET_SPECIAL_COLUMN); fl_set_input(column_options_->input_special_alignment, special.c_str()); bool const isReadonly = lv_->buffer()->isReadonly(); setEnabled(column_options_->input_special_alignment, !isReadonly); pwidth = tabular->GetColumnPWidth(cell); string const default_unit = "cm"; updateWidgetsFromLength(column_options_->input_column_width, column_options_->choice_value_column_width, pwidth, default_unit); setEnabled(column_options_->input_column_width, !isReadonly); setEnabled(column_options_->choice_value_column_width, !isReadonly); setEnabled(cell_options_->radio_useminipage, !pwidth.zero()); if (!pwidth.zero()) { if (tabular->GetUsebox(cell) == 2) fl_set_button(cell_options_->radio_useminipage, 1); else fl_set_button(cell_options_->radio_useminipage, 0); } else { fl_set_button(cell_options_->radio_useminipage, 0); } align = tabular->GetAlignment(cell, true); fl_set_button(column_options_->radio_align_left, 0); fl_set_button(column_options_->radio_align_right, 0); fl_set_button(column_options_->radio_align_center, 0); if (!pwidth.zero() || (align == LYX_ALIGN_LEFT)) fl_set_button(column_options_->radio_align_left, 1); else if (align == LYX_ALIGN_RIGHT) fl_set_button(column_options_->radio_align_right, 1); else fl_set_button(column_options_->radio_align_center, 1); align = tabular->GetVAlignment(cell, true); fl_set_button(column_options_->radio_valign_top, 0); fl_set_button(column_options_->radio_valign_bottom, 0); fl_set_button(column_options_->radio_valign_center, 0); if (pwidth.zero() || (align == LyXTabular::LYX_VALIGN_CENTER)) fl_set_button(column_options_->radio_valign_center, 1); else if (align == LyXTabular::LYX_VALIGN_BOTTOM) fl_set_button(column_options_->radio_valign_bottom, 1); else fl_set_button(column_options_->radio_valign_top, 1); setEnabled(column_options_->radio_align_left, pwidth.zero()); setEnabled(column_options_->radio_align_right, pwidth.zero()); setEnabled(column_options_->radio_align_center, pwidth.zero()); setEnabled(column_options_->radio_valign_top, !pwidth.zero()); setEnabled(column_options_->radio_valign_bottom, !pwidth.zero()); setEnabled(column_options_->radio_valign_center, !pwidth.zero()); fl_set_button(tabular_options_->radio_longtable, tabular->IsLongTabular()); bool const enable = tabular->IsLongTabular(); setEnabled(longtable_options_->radio_lt_firsthead, enable); setEnabled(longtable_options_->radio_lt_head, enable); setEnabled(longtable_options_->radio_lt_foot, enable); setEnabled(longtable_options_->radio_lt_lastfoot, enable); setEnabled(longtable_options_->radio_lt_newpage, enable); if (enable) { LyXTabular::ltType dummyltt; fl_set_button(longtable_options_->radio_lt_firsthead, tabular->GetRowOfLTFirstHead(row - 1, dummyltt)); fl_set_button(longtable_options_->radio_lt_head, tabular->GetRowOfLTHead(row - 1, dummyltt)); fl_set_button(longtable_options_->radio_lt_foot, tabular->GetRowOfLTFoot(row - 1, dummyltt)); fl_set_button(longtable_options_->radio_lt_lastfoot, tabular->GetRowOfLTLastFoot(row - 1, dummyltt)); fl_set_button(longtable_options_->radio_lt_newpage, tabular->GetLTNewPage(cell)); } else { fl_set_button(longtable_options_->radio_lt_firsthead, 0); fl_set_button(longtable_options_->radio_lt_head, 0); fl_set_button(longtable_options_->radio_lt_foot, 0); fl_set_button(longtable_options_->radio_lt_lastfoot, 0); fl_set_button(longtable_options_->radio_lt_newpage, 0); } fl_set_button(tabular_options_->radio_rotate_tabular, tabular->GetRotateTabular()); } bool FormTabular::input(FL_OBJECT * ob, long) { if (!inset_) return false; LyXTabular * tabular = inset_->tabular.get(); int s; LyXTabular::Feature num = LyXTabular::LAST_ACTION; string special;; int cell = inset_->getActCell(); int row = tabular->row_of_cell(cell); if (actCell_ != cell) { update(); fl_set_object_label(dialog_->text_warning, _("Warning: Wrong Cursor position, updated window")); fl_show_object(dialog_->text_warning); return false; } // No point in processing directives that you can't do anything with // anyhow, so exit now if the buffer is read-only. if (lv_->buffer()->isReadonly()) { update(); return false; } if (ob == column_options_->input_column_width) { string const str = getLengthFromWidgets(column_options_->input_column_width, column_options_->choice_value_column_width); inset_->tabularFeatures(lv_->view(), LyXTabular::SET_PWIDTH, str); update(); // update for alignment return true; } if (ob == cell_options_->input_mcolumn_width) { string const str = getLengthFromWidgets(cell_options_->input_mcolumn_width, cell_options_->choice_value_mcolumn_width); inset_->tabularFeatures(lv_->view(), LyXTabular::SET_MPWIDTH, str); update(); // update for alignment return true; } if (ob == tabular_options_->button_append_row) num = LyXTabular::APPEND_ROW; else if (ob == tabular_options_->button_append_column) num = LyXTabular::APPEND_COLUMN; else if (ob == tabular_options_->button_delete_row) num = LyXTabular::DELETE_ROW; else if (ob == tabular_options_->button_delete_column) num = LyXTabular::DELETE_COLUMN; else if (ob == tabular_options_->button_set_borders) num = LyXTabular::SET_ALL_LINES; else if (ob == tabular_options_->button_unset_borders) num = LyXTabular::UNSET_ALL_LINES; else if (ob == column_options_->radio_border_top) num = LyXTabular::TOGGLE_LINE_TOP; else if (ob == column_options_->radio_border_bottom) num = LyXTabular::TOGGLE_LINE_BOTTOM; else if (ob == column_options_->radio_border_left) num = LyXTabular::TOGGLE_LINE_LEFT; else if (ob == column_options_->radio_border_right) num = LyXTabular::TOGGLE_LINE_RIGHT; else if (ob == column_options_->radio_align_left) num = LyXTabular::ALIGN_LEFT; else if (ob == column_options_->radio_align_right) num = LyXTabular::ALIGN_RIGHT; else if (ob == column_options_->radio_align_center) num = LyXTabular::ALIGN_CENTER; else if (ob == column_options_->radio_valign_top) num = LyXTabular::VALIGN_TOP; else if (ob == column_options_->radio_valign_bottom) num = LyXTabular::VALIGN_BOTTOM; else if (ob == column_options_->radio_valign_center) num = LyXTabular::VALIGN_CENTER; else if (ob == cell_options_->radio_multicolumn) num = LyXTabular::MULTICOLUMN; else if (ob == tabular_options_->radio_longtable) { bool const enable = fl_get_button(tabular_options_->radio_longtable); setEnabled(longtable_options_->radio_lt_firsthead, enable); setEnabled(longtable_options_->radio_lt_head, enable); setEnabled(longtable_options_->radio_lt_foot, enable); setEnabled(longtable_options_->radio_lt_lastfoot, enable); setEnabled(longtable_options_->radio_lt_newpage, enable); if (enable) { num = LyXTabular::SET_LONGTABULAR; LyXTabular::ltType dummyltt; fl_set_button(longtable_options_->radio_lt_firsthead, tabular->GetRowOfLTFirstHead(row, dummyltt)); fl_set_button(longtable_options_->radio_lt_head, tabular->GetRowOfLTHead(row, dummyltt)); fl_set_button(longtable_options_->radio_lt_foot, tabular->GetRowOfLTFoot(row, dummyltt)); fl_set_button(longtable_options_->radio_lt_lastfoot, tabular->GetRowOfLTLastFoot(row, dummyltt)); fl_set_button(longtable_options_->radio_lt_firsthead, tabular->GetLTNewPage(cell)); } else { num = LyXTabular::UNSET_LONGTABULAR; fl_set_button(longtable_options_->radio_lt_firsthead, 0); fl_set_button(longtable_options_->radio_lt_head, 0); fl_set_button(longtable_options_->radio_lt_foot, 0); fl_set_button(longtable_options_->radio_lt_lastfoot, 0); fl_set_button(longtable_options_->radio_lt_newpage, 0); } } else if (ob == tabular_options_->radio_rotate_tabular) { s = fl_get_button(tabular_options_->radio_rotate_tabular); if (s) num = LyXTabular::SET_ROTATE_TABULAR; else num = LyXTabular::UNSET_ROTATE_TABULAR; } else if (ob == cell_options_->radio_rotate_cell) { s = fl_get_button(cell_options_->radio_rotate_cell); if (s) num = LyXTabular::SET_ROTATE_CELL; else num = LyXTabular::UNSET_ROTATE_CELL; } else if (ob == cell_options_->radio_useminipage) { num = LyXTabular::SET_USEBOX; special = "2"; } else if (ob == longtable_options_->radio_lt_firsthead) { if (fl_get_button(ob)) num = LyXTabular::SET_LTFIRSTHEAD; else num = LyXTabular::UNSET_LTFIRSTHEAD; } else if (ob == longtable_options_->radio_lt_head) { if (fl_get_button(ob)) num = LyXTabular::SET_LTHEAD; else num = LyXTabular::UNSET_LTHEAD; } else if (ob == longtable_options_->radio_lt_foot) { if (fl_get_button(ob)) num = LyXTabular::SET_LTFOOT; else num = LyXTabular::UNSET_LTFOOT; } else if (ob == longtable_options_->radio_lt_lastfoot) { if (fl_get_button(ob)) num = LyXTabular::SET_LTLASTFOOT; else num = LyXTabular::UNSET_LTLASTFOOT; } else if (ob == longtable_options_->radio_lt_newpage) { num = LyXTabular::SET_LTNEWPAGE; } else if (ob == column_options_->input_special_alignment) { special = fl_get_input(column_options_->input_special_alignment); num = LyXTabular::SET_SPECIAL_COLUMN; } else if (ob == cell_options_->input_special_multialign) { special = fl_get_input(cell_options_->input_special_multialign); num = LyXTabular::SET_SPECIAL_MULTI; } else if (ob == cell_options_->radio_border_top) num = LyXTabular::M_TOGGLE_LINE_TOP; else if (ob == cell_options_->radio_border_bottom) num = LyXTabular::M_TOGGLE_LINE_BOTTOM; else if (ob == cell_options_->radio_border_left) num = LyXTabular::M_TOGGLE_LINE_LEFT; else if (ob == cell_options_->radio_border_right) num = LyXTabular::M_TOGGLE_LINE_RIGHT; else if (ob == cell_options_->radio_align_left) num = LyXTabular::M_ALIGN_LEFT; else if (ob == cell_options_->radio_align_right) num = LyXTabular::M_ALIGN_RIGHT; else if (ob == cell_options_->radio_align_center) num = LyXTabular::M_ALIGN_CENTER; else if (ob == cell_options_->radio_valign_top) num = LyXTabular::M_VALIGN_TOP; else if (ob == cell_options_->radio_valign_bottom) num = LyXTabular::M_VALIGN_BOTTOM; else if (ob == cell_options_->radio_valign_center) num = LyXTabular::M_VALIGN_CENTER; else return false; inset_->tabularFeatures(lv_->view(), num, special); update(); return true; }