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