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