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