]> git.lyx.org Git - lyx.git/blob - src/TableLayout.C
Forgot to add this files.
[lyx.git] / src / TableLayout.C
1 #include <config.h>
2
3 #include <cstdlib>
4 #include FORMS_H_LOCATION
5
6 #include "layout_forms.h"
7 #include "lyx_main.h"
8 #include "lyxrc.h"
9 #include "LString.h"
10 #include "support/filetools.h"
11 #include "buffer.h"
12 #include "vspace.h"
13 #include "lyx_gui_misc.h"
14 #include "BufferView.h"
15 #include "gettext.h"
16 #include "lyxtext.h"
17 #include "layout.h"
18 #include "insets/lyxinset.h"
19
20 // Prototypes
21 extern FD_form_table_options * fd_form_table_options;
22 extern FD_form_table_extra * fd_form_table_extra;
23 extern BufferView * current_view;
24
25 #ifndef NEW_TABULAR
26 static int Confirmed = false;
27 static int ActCell;
28
29 // hack to keep the cursor from jumping to the end of the text in the Extra
30 // form input fields during editing. The values in LyXTable itself is
31 // changed in real-time, but we have no callbacks for the input fields,
32 // so I simply store and restore the cursor position for now.
33 // (too much of a hazzle to do it proper; we'll trash all this code
34 // in 1.1 anyway)
35 static int extra_col_cursor_x; // need no y's, one-line input fields
36 static int extra_multicol_cursor_x;
37 #endif
38 // Joacim
39
40
41 bool UpdateLayoutTable(int flag)
42 {
43     bool update = true;
44     if (!current_view->available())
45         update = false;
46
47 #ifndef NEW_TABULAR
48     if (update && current_view->text->cursor.par()->table) {
49         char buf[12];
50         string pwidth, special;
51    
52         LyXTable * table = current_view->text->cursor.par()->table;
53
54         int cell = current_view->text->
55             NumberOfCell(current_view->text->cursor.par(), 
56                          current_view->text->cursor.pos());
57         ActCell = cell;
58         int column = table->column_of_cell(cell)+1;
59         fl_set_object_label(fd_form_table_options->text_warning, "");
60         Confirmed = false;
61         fl_activate_object(fd_form_table_extra->input_special_alignment);
62         fl_activate_object(fd_form_table_extra->input_special_multialign);
63         fl_activate_object(fd_form_table_options->input_column_width);
64         sprintf(buf, "%d", column);
65         fl_set_input(fd_form_table_options->input_table_column, buf);
66         fl_deactivate_object(fd_form_table_options->input_table_column);
67         int row = table->row_of_cell(cell)+1;
68         sprintf(buf, "%d", row);
69         fl_set_input(fd_form_table_options->input_table_row, buf);
70         fl_deactivate_object(fd_form_table_options->input_table_row);
71         if (table->IsMultiColumn(cell))
72             fl_set_button(fd_form_table_options->radio_multicolumn, 1);
73         else
74             fl_set_button(fd_form_table_options->radio_multicolumn, 0);
75         if (table->RotateCell(cell))
76             fl_set_button(fd_form_table_options->radio_rotate_cell, 1);
77         else
78             fl_set_button(fd_form_table_options->radio_rotate_cell, 0);
79         if (table->TopLine(cell))
80             fl_set_button(fd_form_table_options->radio_border_top, 1);
81         else
82             fl_set_button(fd_form_table_options->radio_border_top, 0);
83         if (table->BottomLine(cell))
84             fl_set_button(fd_form_table_options->radio_border_bottom, 1);
85         else
86             fl_set_button(fd_form_table_options->radio_border_bottom, 0);
87         if (table->LeftLine(cell))
88             fl_set_button(fd_form_table_options->radio_border_left, 1);
89         else
90             fl_set_button(fd_form_table_options->radio_border_left, 0);
91         if (table->RightLine(cell))
92             fl_set_button(fd_form_table_options->radio_border_right, 1);
93         else
94             fl_set_button(fd_form_table_options->radio_border_right, 0);
95         int align = table->GetAlignment(cell);
96         fl_set_button(fd_form_table_options->radio_align_left, 0);
97         fl_set_button(fd_form_table_options->radio_align_right, 0);
98         fl_set_button(fd_form_table_options->radio_align_center, 0);
99         special = table->GetAlignSpecial(cell, LyXTable::SET_SPECIAL_COLUMN);
100         if (flag)
101         {
102             fl_set_input(fd_form_table_extra->input_special_alignment,
103                          special.c_str());
104             fl_set_input_cursorpos(fd_form_table_extra->input_special_alignment,
105                     extra_col_cursor_x, 0); // restore the cursor
106         }
107         if (current_view->buffer()->isReadonly()) 
108             fl_deactivate_object(fd_form_table_extra->input_special_alignment);
109         special = table->GetAlignSpecial(cell, LyXTable::SET_SPECIAL_MULTI);
110         if (flag)
111         {
112             fl_set_input(fd_form_table_extra->input_special_multialign,
113                          special.c_str());
114             fl_set_input_cursorpos(fd_form_table_extra->input_special_multialign,
115                     extra_multicol_cursor_x, 0); // restore the cursor
116         }
117         if (current_view->buffer()->isReadonly()) 
118             fl_deactivate_object(fd_form_table_extra->input_special_multialign);
119         pwidth = table->GetPWidth(cell);
120         if (flag)
121             fl_set_input(fd_form_table_options->input_column_width, pwidth.c_str());
122         if (current_view->buffer()->isReadonly()) 
123             fl_deactivate_object(fd_form_table_options->input_column_width);
124         if (!pwidth.empty()) {
125             fl_activate_object(fd_form_table_options->radio_linebreak_cell);
126             fl_set_object_lcol(fd_form_table_options->radio_linebreak_cell,
127                                FL_BLACK);
128             fl_set_button(fd_form_table_options->radio_linebreak_cell,
129                           table->Linebreaks(table->FirstVirtualCell(cell)));
130         } else {
131             fl_deactivate_object(fd_form_table_options->radio_linebreak_cell);
132             fl_set_object_lcol(fd_form_table_options->radio_linebreak_cell,
133                                FL_INACTIVE);
134             fl_set_button(fd_form_table_options->radio_linebreak_cell, 0);
135         }
136         if ((!pwidth.empty() && !table->IsMultiColumn(cell)) ||
137             (align == LYX_ALIGN_LEFT))
138             fl_set_button(fd_form_table_options->radio_align_left, 1);
139         else if (align == LYX_ALIGN_RIGHT)
140             fl_set_button(fd_form_table_options->radio_align_right, 1);
141         else
142             fl_set_button(fd_form_table_options->radio_align_center, 1);
143         if (!pwidth.empty() && !table->IsMultiColumn(cell)) {
144             fl_deactivate_object(fd_form_table_options->radio_align_left);
145             fl_deactivate_object(fd_form_table_options->radio_align_right);
146             fl_deactivate_object(fd_form_table_options->radio_align_center);
147             fl_set_object_lcol(fd_form_table_options->radio_align_left,
148                                FL_INACTIVE);
149             fl_set_object_lcol(fd_form_table_options->radio_align_right,
150                                FL_INACTIVE);
151             fl_set_object_lcol(fd_form_table_options->radio_align_center,
152                                FL_INACTIVE);
153         } else {
154             fl_activate_object(fd_form_table_options->radio_align_left);
155             fl_activate_object(fd_form_table_options->radio_align_right);
156             fl_activate_object(fd_form_table_options->radio_align_center);
157             fl_set_object_lcol(fd_form_table_options->radio_align_left,
158                                FL_BLACK);
159             fl_set_object_lcol(fd_form_table_options->radio_align_right,
160                                FL_BLACK);
161             fl_set_object_lcol(fd_form_table_options->radio_align_center,
162                                FL_BLACK);
163         }
164         fl_set_button(fd_form_table_options->radio_longtable, table->IsLongTable());
165         if (table->IsLongTable()) {
166             fl_activate_object(fd_form_table_options->radio_lt_firsthead);
167             fl_activate_object(fd_form_table_options->radio_lt_head);
168             fl_activate_object(fd_form_table_options->radio_lt_foot);
169             fl_activate_object(fd_form_table_options->radio_lt_lastfoot);
170             fl_activate_object(fd_form_table_options->radio_lt_newpage);
171             fl_set_object_lcol(fd_form_table_options->radio_lt_firsthead,
172                                FL_BLACK);
173             fl_set_object_lcol(fd_form_table_options->radio_lt_head,
174                                FL_BLACK);
175             fl_set_object_lcol(fd_form_table_options->radio_lt_foot,
176                                FL_BLACK);
177             fl_set_object_lcol(fd_form_table_options->radio_lt_lastfoot,
178                                FL_BLACK);
179             fl_set_object_lcol(fd_form_table_options->radio_lt_newpage,
180                                FL_BLACK);
181             fl_set_button(fd_form_table_options->radio_lt_firsthead,
182                           table->RowOfLTFirstHead(cell));
183             fl_set_button(fd_form_table_options->radio_lt_head,
184                           table->RowOfLTHead(cell));
185             fl_set_button(fd_form_table_options->radio_lt_foot,
186                           table->RowOfLTFoot(cell));
187             fl_set_button(fd_form_table_options->radio_lt_lastfoot,
188                           table->RowOfLTLastFoot(cell));
189             fl_set_button(fd_form_table_options->radio_lt_newpage,
190                           table->LTNewPage(cell));
191         } else {
192             fl_deactivate_object(fd_form_table_options->radio_lt_firsthead);
193             fl_deactivate_object(fd_form_table_options->radio_lt_head);
194             fl_deactivate_object(fd_form_table_options->radio_lt_foot);
195             fl_deactivate_object(fd_form_table_options->radio_lt_lastfoot);
196             fl_deactivate_object(fd_form_table_options->radio_lt_newpage);
197             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
198             fl_set_button(fd_form_table_options->radio_lt_head, 0);
199             fl_set_button(fd_form_table_options->radio_lt_foot, 0);
200             fl_set_button(fd_form_table_options->radio_lt_lastfoot, 0);
201             fl_set_button(fd_form_table_options->radio_lt_newpage, 0);
202             fl_set_object_lcol(fd_form_table_options->radio_lt_firsthead,
203                                FL_INACTIVE);
204             fl_set_object_lcol(fd_form_table_options->radio_lt_head,
205                                FL_INACTIVE);
206             fl_set_object_lcol(fd_form_table_options->radio_lt_foot,
207                                FL_INACTIVE);
208             fl_set_object_lcol(fd_form_table_options->radio_lt_lastfoot,
209                                FL_INACTIVE);
210             fl_set_object_lcol(fd_form_table_options->radio_lt_newpage,
211                                FL_INACTIVE);
212         }
213         fl_set_button(fd_form_table_options->radio_rotate_table,
214                       table->RotateTable());
215         fl_set_focus_object(fd_form_table_options->form_table_options,
216                             fd_form_table_options->button_table_delete);
217     } else
218 #endif
219             if (fd_form_table_options->form_table_options->visible) {
220         fl_set_focus_object(fd_form_table_options->form_table_options,
221                             fd_form_table_options->button_table_delete);
222         fl_hide_form(fd_form_table_options->form_table_options);
223     }
224     return update;
225 }
226
227
228 void OpenLayoutTableExtra()
229 {
230
231         if (fd_form_table_extra->form_table_extra->visible) {
232                 fl_raise_form(fd_form_table_extra->form_table_extra);
233         } else {
234                 static int ow = -1, oh;
235                 fl_show_form(fd_form_table_extra->form_table_extra,
236                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
237                              _("Table Extra Form"));
238                 if (ow < 0) {
239                         ow = fd_form_table_extra->form_table_extra->w;
240                         oh = fd_form_table_extra->form_table_extra->h;
241                 }
242                 fl_set_form_minsize(fd_form_table_extra->form_table_extra,
243                                     ow, oh);
244         }
245 }
246
247 void MenuLayoutTable(int flag)
248 {
249     if (UpdateLayoutTable(flag)) {
250         if (fd_form_table_options->form_table_options->visible) {
251             fl_raise_form(fd_form_table_options->form_table_options);
252         }
253         else {
254             fl_show_form(fd_form_table_options->form_table_options,
255                          FL_PLACE_MOUSE, FL_FULLBORDER,
256                          _("Table Layout"));
257         }
258     }
259 }
260
261
262 void TableOptionsCB(FL_OBJECT * ob, long)
263 {
264 #ifndef NEW_TABULAR
265     LyXTable * table = 0;
266     int s, num = 0;
267     string special, str;
268
269     if (!current_view->available()
270         || !(table = current_view->text->cursor.par()->table)) {
271         MenuLayoutTable(0);
272         return;
273       }
274     int cell = current_view->text->
275         NumberOfCell(current_view->text->cursor.par(), 
276                      current_view->text->cursor.pos());
277     if (ActCell != cell) {
278         MenuLayoutTable(0);
279         fl_set_object_label(fd_form_table_options->text_warning,
280                             _("Warning: Wrong Cursor position, updated window"));
281         fl_show_object(fd_form_table_options->text_warning);
282         extra_col_cursor_x = 0; // would rather place it at the end, but...
283         extra_multicol_cursor_x = 0;
284         return;
285     }
286
287     // No point in processing directives that you can't do anything with
288     // anyhow, so exit now if the buffer is read-only.
289     if (current_view->buffer()->isReadonly()) {
290       MenuLayoutTable(0);
291       return;
292     }
293     
294     if (ob != fd_form_table_options->button_table_delete) {
295         fl_set_object_label(fd_form_table_options->text_warning, "");
296         Confirmed = false;
297     }
298     str = fl_get_input(fd_form_table_options->input_column_width);
299     if (!str.empty() && !isValidLength(str)) {
300         fl_set_object_label(fd_form_table_options->text_warning,
301                             _("Warning: Invalid Length (valid example: 10mm)"));
302         fl_show_object(fd_form_table_options->text_warning);
303         return;
304     }
305     if (((ob == fd_form_table_options->button_delete_row) && (table->rows<= 1)) ||
306         ((ob == fd_form_table_options->button_delete_column) && (table->columns<= 1)))
307         ob = fd_form_table_options->button_table_delete;
308     if (ob == fd_form_table_options->button_append_row)
309         num = LyXTable::APPEND_ROW;
310     else if (ob == fd_form_table_options->button_append_column)
311         num = LyXTable::APPEND_COLUMN;
312     else if (ob == fd_form_table_options->button_delete_row)
313         num = LyXTable::DELETE_ROW;
314     else if (ob == fd_form_table_options->button_delete_column)
315         num = LyXTable::DELETE_COLUMN;
316     else if (ob == fd_form_table_options->button_set_borders)
317         num = LyXTable::SET_ALL_LINES;
318     else if (ob == fd_form_table_options->button_unset_borders)
319         num = LyXTable::UNSET_ALL_LINES;
320     else if (ob == fd_form_table_options->radio_border_top)
321         num = LyXTable::TOGGLE_LINE_TOP;
322     else if (ob == fd_form_table_options->radio_border_bottom)
323         num = LyXTable::TOGGLE_LINE_BOTTOM;
324     else if (ob == fd_form_table_options->radio_border_left)
325         num = LyXTable::TOGGLE_LINE_LEFT;
326     else if (ob == fd_form_table_options->radio_border_right)
327         num = LyXTable::TOGGLE_LINE_RIGHT;
328     else if (ob == fd_form_table_options->radio_align_left)
329         num = LyXTable::ALIGN_LEFT;
330     else if (ob == fd_form_table_options->radio_align_right)
331         num = LyXTable::ALIGN_RIGHT;
332     else if (ob == fd_form_table_options->radio_align_center)
333         num = LyXTable::ALIGN_CENTER;
334     else if ((ob == fd_form_table_options->button_table_delete) && !Confirmed) {
335         fl_set_object_label(fd_form_table_options->text_warning,
336                             _("Confirm: press Delete-Button again"));
337         Confirmed = true;
338         return;
339     } else if ((ob == fd_form_table_options->button_table_delete) 
340                && Confirmed) {
341         num = LyXTable::DELETE_TABLE;
342         Confirmed = false;
343     } else if (ob == fd_form_table_options->radio_multicolumn)
344         num = LyXTable::MULTICOLUMN;
345     else if (ob == fd_form_table_options->radio_longtable) {
346         s = fl_get_button(fd_form_table_options->radio_longtable);
347         if (s) {
348             num = LyXTable::SET_LONGTABLE;
349             fl_activate_object(fd_form_table_options->radio_lt_firsthead);
350             fl_activate_object(fd_form_table_options->radio_lt_head);
351             fl_activate_object(fd_form_table_options->radio_lt_foot);
352             fl_activate_object(fd_form_table_options->radio_lt_lastfoot);
353             fl_activate_object(fd_form_table_options->radio_lt_newpage);
354             fl_set_button(fd_form_table_options->radio_lt_firsthead,
355                           table->RowOfLTFirstHead(cell));
356             fl_set_button(fd_form_table_options->radio_lt_head,
357                           table->RowOfLTHead(cell));
358             fl_set_button(fd_form_table_options->radio_lt_foot,
359                           table->RowOfLTFoot(cell));
360             fl_set_button(fd_form_table_options->radio_lt_lastfoot,
361                           table->RowOfLTLastFoot(cell));
362             fl_set_button(fd_form_table_options->radio_lt_firsthead,
363                           table->LTNewPage(cell));
364         } else {
365             num = LyXTable::UNSET_LONGTABLE;
366             fl_deactivate_object(fd_form_table_options->radio_lt_firsthead);
367             fl_deactivate_object(fd_form_table_options->radio_lt_head);
368             fl_deactivate_object(fd_form_table_options->radio_lt_foot);
369             fl_deactivate_object(fd_form_table_options->radio_lt_lastfoot);
370             fl_deactivate_object(fd_form_table_options->radio_lt_newpage);
371             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
372             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
373             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
374             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
375             fl_set_button(fd_form_table_options->radio_lt_firsthead, 0);
376             fl_set_object_lcol(fd_form_table_options->radio_lt_firsthead,
377                                FL_INACTIVE);
378             fl_set_object_lcol(fd_form_table_options->radio_lt_head,
379                                FL_INACTIVE);
380             fl_set_object_lcol(fd_form_table_options->radio_lt_foot,
381                                FL_INACTIVE);
382             fl_set_object_lcol(fd_form_table_options->radio_lt_lastfoot,
383                                FL_INACTIVE);
384             fl_set_object_lcol(fd_form_table_options->radio_lt_newpage,
385                                FL_INACTIVE);
386         }
387     } else if (ob == fd_form_table_options->radio_rotate_table) {
388         s = fl_get_button(fd_form_table_options->radio_rotate_table);
389         if (s)
390             num = LyXTable::SET_ROTATE_TABLE;
391         else
392             num = LyXTable::UNSET_ROTATE_TABLE;
393     } else if (ob == fd_form_table_options->radio_rotate_cell) {
394         s = fl_get_button(fd_form_table_options->radio_rotate_cell);
395         if (s)
396             num = LyXTable::SET_ROTATE_CELL;
397         else
398             num = LyXTable::UNSET_ROTATE_CELL;
399     } else if (ob == fd_form_table_options->radio_linebreak_cell) {
400         num = LyXTable::SET_LINEBREAKS;
401     } else if (ob == fd_form_table_options->radio_lt_firsthead) {
402         num = LyXTable::SET_LTFIRSTHEAD;
403     } else if (ob == fd_form_table_options->radio_lt_head) {
404         num = LyXTable::SET_LTHEAD;
405     } else if (ob == fd_form_table_options->radio_lt_foot) {
406         num = LyXTable::SET_LTFOOT;
407     } else if (ob == fd_form_table_options->radio_lt_lastfoot) {
408         num = LyXTable::SET_LTLASTFOOT;
409     } else if (ob == fd_form_table_options->radio_lt_newpage) {
410         num = LyXTable::SET_LTNEWPAGE;
411     } else if (ob == fd_form_table_options->button_table_extra) {
412         OpenLayoutTableExtra();
413         return;
414     } else if (ob == fd_form_table_extra->input_special_alignment) {
415         special = fl_get_input(fd_form_table_extra->input_special_alignment);
416         int dummy;
417         fl_get_input_cursorpos(ob, &extra_col_cursor_x, &dummy);
418         num = LyXTable::SET_SPECIAL_COLUMN;
419     } else if (ob == fd_form_table_extra->input_special_multialign) {
420         special = fl_get_input(fd_form_table_extra->input_special_multialign);
421         int dummy;
422         fl_get_input_cursorpos(ob, &extra_multicol_cursor_x, &dummy);
423         num = LyXTable::SET_SPECIAL_MULTI;
424     } else
425         return;
426     if (current_view->available()) {
427         current_view->hideCursor();
428         if (!current_view->text->selection){
429             current_view->beforeChange();
430             current_view->update(BufferView::SELECT|BufferView::FITCUR);
431         }
432         if ((num == LyXTable::SET_SPECIAL_COLUMN) ||
433             (num == LyXTable::SET_SPECIAL_MULTI))
434             current_view->text->TableFeatures(current_view, num, special);
435         else
436             current_view->text->TableFeatures(current_view, num);
437         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
438     }
439     if (num == LyXTable::DELETE_TABLE) {
440         fl_set_focus_object(fd_form_table_options->form_table_options,
441                             fd_form_table_options->button_table_delete);
442         fl_hide_form(fd_form_table_options->form_table_options);
443     } else
444         UpdateLayoutTable(true);
445     return;
446 #endif
447 }
448
449
450 void TableOptCloseCB(FL_OBJECT *, long)
451 {
452     fl_set_focus_object(fd_form_table_options->form_table_options,
453                         fd_form_table_options->button_table_delete);
454     fl_hide_form(fd_form_table_options->form_table_options);
455     return;
456 }
457
458 void TableSpeCloseCB(FL_OBJECT *, long)
459 {
460     fl_set_focus_object(fd_form_table_options->form_table_options,
461                         fd_form_table_options->button_table_delete);
462     fl_hide_form(fd_form_table_extra->form_table_extra);
463     return;
464 }
465
466 void SetPWidthCB(FL_OBJECT * ob, long)
467 {
468 #ifndef NEW_TABULAR
469     fl_set_object_label(fd_form_table_options->text_warning, "");
470     Confirmed = false;
471     if (ob == fd_form_table_options->input_column_width) {
472         string str = fl_get_input(ob);
473         if (!str.empty() && !isValidLength(str)) {
474             fl_set_object_label(fd_form_table_options->text_warning,
475                            _("Warning: Invalid Length (valid example: 10mm)"));
476             fl_show_object(fd_form_table_options->text_warning);
477             return;
478         }
479         if (current_view->available()){
480             current_view->hideCursor();
481             if (!current_view->text->selection) {
482                 current_view->beforeChange(); 
483                 current_view->update(BufferView::SELECT|BufferView::FITCUR);
484             }
485             current_view->text->TableFeatures(current_view, LyXTable::SET_PWIDTH, str);
486             current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
487         }
488         MenuLayoutTable(0); // update for alignment
489     }
490 #endif
491 }