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