]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
mathed31.diff
[lyx.git] / src / lyx_cb.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich,
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include <fstream>
14 #include <algorithm>
15 #include <iostream>
16
17 #include FORMS_H_LOCATION
18 #include "lyx.h"
19 #include "layout_forms.h"
20 #include "lyx_main.h"
21 #include "lyx_cb.h"
22 #include "insets/insetlabel.h"
23 #include "insets/figinset.h"
24 #include "lyxfunc.h"
25 #include "minibuffer.h"
26 #include "combox.h"
27 #include "bufferlist.h"
28 #include "filedlg.h"
29 #include "lyx_gui_misc.h"
30 #include "LyXView.h"
31 #include "lastfiles.h"
32 #include "bufferview_funcs.h"
33 #include "support/FileInfo.h"
34 #include "support/syscall.h"
35 #include "support/filetools.h"
36 #include "support/path.h"
37 #include "lyxrc.h"
38 #include "lyxtext.h"
39
40 using std::ifstream;
41 using std::copy;
42 using std::back_inserter;
43 using std::endl;
44 using std::cout;
45 using std::ios;
46 using std::istream_iterator;
47 using std::pair;
48 using std::vector;
49 using std::sort;
50 using std::equal;
51
52 extern Combox * combo_language;
53 extern Combox * combo_language2;
54 extern BufferList bufferlist;
55 extern void show_symbols_form();
56 extern FD_form_character * fd_form_character;
57 extern FD_form_preamble * fd_form_preamble;
58 extern FD_form_figure * fd_form_figure;
59
60 extern BufferView * current_view; // called too many times in this file...
61
62 extern void DeleteSimpleCutBuffer(); /* for the cleanup when exiting */
63
64 extern void MenuSendto();
65
66 // this should be static, but I need it in buffer.C
67 bool quitting;  // flag, that we are quitting the program
68 extern bool finished; // all cleanup done just let it run through now.
69
70 char ascii_type; /* for selection notify callbacks */
71
72 bool scrolling = false;
73
74 // This is used to make the dreaded font toggle problem hopefully go
75 // away. Definitely not the best solution, but I think it sorta works.
76 bool toggleall = true;
77
78 /* 
79    This is the inset locking stuff needed for mathed --------------------
80
81    an inset can simple call LockInset in it's edit call and *ONLY* in it's
82    edit call.
83    Inset::Edit() can only be called by the main lyx module.
84
85    Then the inset may modify the menu's and/or iconbars. 
86
87    Unlocking is either done by LyX or the inset itself with a UnlockInset-call
88
89    During the lock, all button and keyboard events will be modified
90    and send to the inset through the following inset-features. Note that
91    Inset::InsetUnlock will be called from inside UnlockInset. It is meant
92    to contain the code for restoring the menus and things like this.
93
94    
95    virtual void InsetButtonPress(int x, int y, int button);
96    virtual void InsetButtonRelease(int x, int y, int button);
97    virtual void InsetKeyPress(XKeyEvent *ev);
98    virtual void InsetMotionNotify(int x, int y, int state);
99    virtual void InsetUnlock();
100
101    If a inset wishes any redraw and/or update it just has to call
102    UpdateInset(this).
103    It's is completly irrelevant, where the inset is. UpdateInset will
104    find it in any paragraph in any buffer. 
105    Of course the_locking_inset and the insets in the current paragraph/buffer
106    are checked first, so no performance problem should occur.
107    
108    Hope that's ok for the beginning, Alejandro,
109    sorry that I needed so much time,
110
111                   Matthias
112    */
113
114 //void UpdateInset(BufferView * bv, Inset * inset, bool mark_dirty = true);
115
116 /* these functions return 1 if an error occured, 
117    otherwise 0 */
118 // Now they work only for updatable insets. [Alejandro 080596]
119 //int LockInset(UpdatableInset * inset);
120 void ToggleLockedInsetCursor(int x, int y, int asc, int desc);
121 //void FitLockedInsetCursor(long x, long y, int asc, int desc);
122 //int UnlockInset(UpdatableInset * inset);
123 //void LockedInsetStoreUndo(Undo::undo_kind kind);
124
125 /* this is for asyncron updating. UpdateInsetUpdateList will be called
126    automatically from LyX. Just insert the Inset into the Updatelist */
127 //void UpdateInsetUpdateList();
128 //void PutInsetIntoInsetUpdateList(Inset * inset);
129
130 //InsetUpdateStruct * InsetUpdateList = 0;
131
132
133 /*
134   -----------------------------------------------------------------------
135  */
136
137
138 void ShowMessage(Buffer const * buf,
139                  string const & msg1,
140                  string const & msg2,
141                  string const & msg3, int delay)
142 {
143         if (lyxrc.use_gui)
144                 buf->getUser()->owner()->getMiniBuffer()->Set(msg1, msg2,
145                                                               msg3, delay);
146         else
147                 lyxerr << msg1 << msg2 << msg3 << endl;
148 }
149
150
151 //
152 // Menu callbacks
153 //
154
155 //
156 // File menu
157 //
158
159 // should be moved to lyxfunc.C
160 bool MenuWrite(BufferView * bv, Buffer * buffer)
161 {
162         XFlush(fl_get_display());
163         if (!buffer->save()) {
164                 string const fname = buffer->fileName();
165                 string const s = MakeAbsPath(fname);
166                 if (AskQuestion(_("Save failed. Rename and try again?"),
167                                 MakeDisplayPath(s, 50),
168                                 _("(If not, document is not saved.)"))) {
169                         return MenuWriteAs(bv, buffer);
170                 }
171                 return false;
172         } else {
173                 lastfiles->newFile(buffer->fileName());
174         }
175         return true;
176 }
177
178
179 // should be moved to BufferView.C
180 // Half of this func should be in LyXView, the rest in BufferView.
181 bool MenuWriteAs(BufferView * bv, Buffer * buffer)
182 {
183         // Why do we require BufferView::text to be able to write a
184         // document? I see no point in that. (Lgb)
185         //if (!bv->text) return;
186
187         string fname = buffer->fileName();
188         string oldname = fname;
189         LyXFileDlg fileDlg;
190
191         ProhibitInput(bv);
192         fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
193         fileDlg.SetButton(1, _("Templates"), lyxrc.template_path);
194
195         if (!IsLyXFilename(fname))
196                 fname += ".lyx";
197
198         fname = fileDlg.Select(_("Enter Filename to Save Document as"), 
199                                OnlyPath(fname),
200                                "*.lyx", 
201                                OnlyFilename(fname));
202
203         AllowInput(bv);
204
205         if (fname.empty())
206                 return false;
207
208         // Make sure the absolute filename ends with appropriate suffix
209         string s = MakeAbsPath(fname);
210         if (!IsLyXFilename(s))
211                 s += ".lyx";
212
213         // Same name as we have already?
214         if (!buffer->isUnnamed() && s == oldname) {
215                 if (!AskQuestion(_("Same name as document already has:"),
216                                  MakeDisplayPath(s, 50),
217                                  _("Save anyway?")))
218                         return false;
219                 // Falls through to name change and save
220         } 
221         // No, but do we have another file with this name open?
222         else if (!buffer->isUnnamed() && bufferlist.exists(s)) {
223                 if (AskQuestion(_("Another document with same name open!"),
224                                 MakeDisplayPath(s, 50),
225                                 _("Replace with current document?")))
226                         {
227                                 bufferlist.close(bufferlist.getBuffer(s));
228
229                                 // Ok, change the name of the buffer, but don't save!
230                                 buffer->setFileName(s);
231                                 buffer->markDirty();
232
233                                 ShowMessage(buffer, _("Document renamed to '"),
234                                                 MakeDisplayPath(s), _("', but not saved..."));
235                         }
236                 return false;
237         } // Check whether the file exists
238         else {
239                 FileInfo const myfile(s);
240                 if (myfile.isOK() && !AskQuestion(_("Document already exists:"), 
241                                                   MakeDisplayPath(s, 50),
242                                                   _("Replace file?")))
243                         return false;
244         }
245
246         // Ok, change the name of the buffer
247         buffer->setFileName(s);
248         buffer->markDirty();
249         bool unnamed = buffer->isUnnamed();
250         buffer->setUnnamed(false);
251         // And save
252         // Small bug: If the save fails, we have irreversible changed the name
253         // of the document.
254         // Hope this is fixed this way! (Jug)
255         if (!MenuWrite(bv, buffer)) {
256             buffer->setFileName(oldname);
257             buffer->setUnnamed(unnamed);
258             ShowMessage(buffer, _("Document could not be saved!"),
259                         _("Holding the old name."), MakeDisplayPath(oldname));
260             return false;
261         }
262         // now remove the oldname autosave file if existant!
263         removeAutosaveFile(oldname);
264         return true;
265 }
266
267
268 int MenuRunChktex(Buffer * buffer)
269 {
270         int ret;
271
272         if (buffer->isSGML()) {
273                 WriteAlert(_("Chktex does not work with SGML derived documents."));
274                 return 0;
275         } else 
276                 ret = buffer->runChktex();
277    
278         if (ret >= 0) {
279                 string s;
280                 string t;
281                 if (ret == 0) {
282                         s = _("No warnings found.");
283                 } else if (ret == 1) {
284                         s = _("One warning found.");
285                         t = _("Use 'Edit->Go to Error' to find it.");
286                 } else {
287                         s += tostr(ret);
288                         s += _(" warnings found.");
289                         t = _("Use 'Edit->Go to Error' to find them.");
290                 }
291                 WriteAlert(_("Chktex run successfully"), s, t);
292         } else {
293                 WriteAlert(_("Error!"), _("It seems chktex does not work."));
294         }
295         return ret;
296 }
297
298
299 void QuitLyX()
300 {
301         lyxerr.debug() << "Running QuitLyX." << endl;
302
303         if (lyxrc.use_gui) {
304                 if (!bufferlist.QwriteAll())
305                         return;
306
307                 lastfiles->writeFile(lyxrc.lastfiles);
308         }
309
310         // Set a flag that we do quitting from the program,
311         // so no refreshes are necessary.
312         quitting = true;
313
314         // close buffers first
315         bufferlist.closeAll();
316
317         // do any other cleanup procedures now
318         lyxerr.debug() << "Deleting tmp dir " << system_tempdir << endl;
319
320         DestroyLyXTmpDir(system_tempdir);
321
322         finished = true;
323 }
324
325
326
327 void AutoSave(BufferView * bv)
328         // should probably be moved into BufferList (Lgb)
329         // Perfect target for a thread...
330 {
331         if (!bv->available())
332                 return;
333
334         if (bv->buffer()->isBakClean() || bv->buffer()->isReadonly()) {
335                 // We don't save now, but we'll try again later
336                 bv->owner()->resetAutosaveTimer();
337                 return;
338         }
339
340         bv->owner()->getMiniBuffer()->Set(_("Autosaving current document..."));
341         
342         // create autosave filename
343         string fname =  OnlyPath(bv->buffer()->fileName());
344         fname += "#";
345         fname += OnlyFilename(bv->buffer()->fileName());
346         fname += "#";
347         
348         // tmp_ret will be located (usually) in /tmp
349         // will that be a problem?
350         pid_t const pid = fork(); // If you want to debug the autosave
351         // you should set pid to -1, and comment out the
352         // fork.
353         if (pid == 0 || pid == -1) {
354                 // pid = -1 signifies that lyx was unable
355                 // to fork. But we will do the save
356                 // anyway.
357                 bool failed = false;
358                 
359                 string const tmp_ret = lyx::tempName(string(), "lyxauto");
360                 if (!tmp_ret.empty()) {
361                         bv->buffer()->writeFile(tmp_ret, 1);
362                         // assume successful write of tmp_ret
363                         if (!lyx::rename(tmp_ret, fname)) {
364                                 failed = true;
365                                 // most likely couldn't move between filesystems
366                                 // unless write of tmp_ret failed
367                                 // so remove tmp file (if it exists)
368                                 lyx::unlink(tmp_ret);
369                         }
370                 } else {
371                         failed = true;
372                 }
373                 
374                 if (failed) {
375                         // failed to write/rename tmp_ret so try writing direct
376                         if (!bv->buffer()->writeFile(fname, 1)) {
377                                 // It is dangerous to do this in the child,
378                                 // but safe in the parent, so...
379                                 if (pid == -1)
380                                         bv->owner()->getMiniBuffer()->Set(_("Autosave Failed!"));
381                         }
382                 }
383                 if (pid == 0) { // we are the child so...
384                         _exit(0);
385                 }
386         }
387         
388         bv->buffer()->markBakClean();
389         bv->owner()->resetAutosaveTimer();
390 }
391
392
393 //
394 // Copyright CHT Software Service GmbH
395 // Uwe C. Schroeder
396 //
397 // create new file with template
398 // SERVERCMD !
399 //
400 Buffer * NewLyxFile(string const & filename)
401 {
402         // Split argument by :
403         string name;
404         string tmpname = split(filename, name, ':');
405 #ifdef __EMX__ // Fix me! lyx_cb.C may not be low level enough to allow this.
406         if (name.length() == 1
407             && isalpha(static_cast<unsigned char>(name[0]))
408             && (prefixIs(tmpname, "/") || prefixIs(tmpname, "\\"))) {
409                 name += ':';
410                 name += token(tmpname, ':', 0);
411                 tmpname = split(tmpname, ':');
412         }
413 #endif
414         lyxerr.debug() << "Arg is " << filename
415                        << "\nName is " << name
416                        << "\nTemplate is " << tmpname << endl;
417
418         // find a free buffer 
419         Buffer * tmpbuf = bufferlist.newFile(name, tmpname);
420         if (tmpbuf)
421                 lastfiles->newFile(tmpbuf->fileName());
422         return tmpbuf;
423 }
424
425
426 // Insert ascii file (if filename is empty, prompt for one)
427 void InsertAsciiFile(BufferView * bv, string const & f, bool asParagraph)
428 {
429         string fname = f;
430         LyXFileDlg fileDlg;
431  
432         if (!bv->available()) return;
433      
434         if (fname.empty()) {
435                 ProhibitInput(bv);
436                 fname = fileDlg.Select(_("File to Insert"), 
437                                        bv->owner()->buffer()->filepath,
438                                        "*");
439                 AllowInput(bv);
440                 if (fname.empty()) return;
441         }
442
443         FileInfo fi(fname);
444
445         if (!fi.readable()) {
446                 WriteFSAlert(_("Error! Specified file is unreadable: "),
447                              MakeDisplayPath(fname, 50));
448                 return;
449         }
450
451         ifstream ifs(fname.c_str());
452         if (!ifs) {
453                 WriteFSAlert(_("Error! Cannot open specified file: "),
454                              MakeDisplayPath(fname, 50));
455                 return;
456         }
457
458         ifs.unsetf(ios::skipws);
459         istream_iterator<char> ii(ifs);
460         istream_iterator<char> end;
461 #if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
462         // We use this until the compilers get better...
463         vector<char> tmp;
464         copy(ii, end, back_inserter(tmp));
465         string const tmpstr(tmp.begin(), tmp.end());
466 #else
467         // This is what we want to use and what we will use once the
468         // compilers get good enough. 
469         //string tmpstr(ii, end); // yet a reason for using std::string
470         // alternate approach to get the file into a string:
471         string tmpstr;
472         copy(ii, end, back_inserter(tmpstr));
473 #endif
474         // insert the string
475         bv->hideCursor();
476         
477         // clear the selection
478         bv->beforeChange(bv->text);
479         if (!asParagraph)
480                 bv->text->InsertStringA(bv, tmpstr);
481         else
482                 bv->text->InsertStringB(bv, tmpstr);
483         bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
484 }
485
486
487 void MenuInsertLabel(BufferView * bv, string const & arg)
488 {
489         string label(arg);
490         ProhibitInput(bv);
491         if (label.empty()) {
492 #ifndef NEW_INSETS
493                 LyXParagraph * par =
494                         bv->text->cursor.par()->FirstPhysicalPar();
495 #else
496                 LyXParagraph * par = bv->text->cursor.par();
497 #endif
498                 LyXLayout const * layout =
499                         &textclasslist.Style(bv->buffer()->params.textclass,
500                                              par->GetLayout());
501
502                 if (layout->latextype == LATEX_PARAGRAPH && par->previous) {
503 #ifndef NEW_INSETS
504                         LyXParagraph * par2 = par->previous->FirstPhysicalPar();
505 #else
506                         LyXParagraph * par2 = par->previous;
507 #endif
508                         LyXLayout const * layout2 =
509                                 &textclasslist.Style(bv->buffer()->params.textclass,
510                                                      par2->GetLayout());
511                         if (layout2->latextype != LATEX_PARAGRAPH) {
512                                 par = par2;
513                                 layout = layout2;
514                         }
515                 }
516                 string text = layout->latexname().substr(0, 3);
517                 if (layout->latexname() == "theorem")
518                         text = "thm"; // Create a correct prefix for prettyref
519 #ifndef NEW_INSETS
520                 if (par->footnoteflag==LyXParagraph::OPEN_FOOTNOTE)
521                         switch (par->footnotekind) {
522                         case LyXParagraph::FIG:
523                         case LyXParagraph::WIDE_FIG:
524                                 text = "fig";
525                                 break;
526                         case LyXParagraph::TAB:
527                         case LyXParagraph::WIDE_TAB:
528                                 text = "tab";
529                                 break;
530                         case LyXParagraph::ALGORITHM:
531                                 text = "alg";
532                                 break;
533                         case LyXParagraph::FOOTNOTE:    
534                         case LyXParagraph::MARGIN:
535                                 break;
536                         }
537 #endif
538                 text += ":";
539                 if (layout->latextype == LATEX_PARAGRAPH ||
540                     lyxrc.label_init_length < 0)
541                         text.erase();
542                 string par_text = par->String(bv->buffer(), false);
543                 for (int i = 0; i < lyxrc.label_init_length; ++i) {
544                         if (par_text.empty())
545                                 break;
546                         string head;
547                         par_text = split(par_text, head, ' ');
548                         if (i > 0)
549                                 text += '-'; // Is it legal to use spaces in
550                                              // labels ?
551                         text += head;
552                 }
553
554                 pair<bool, string> result =
555                         askForText(_("Enter new label to insert:"), text);
556                 if (result.first) {
557                         label = frontStrip(strip(result.second));
558                 }
559         }
560         if (!label.empty()) {
561                 InsetCommandParams p( "label", label );
562                 InsetLabel * inset = new InsetLabel( p );
563                 bv->insertInset( inset );
564         }
565         AllowInput(bv);
566 }
567
568
569 // This is _only_ used in Toolbar_pimpl.C, move it there and get rid of
570 // current_view. (Lgb)
571 void LayoutsCB(int sel, void *, Combox *)
572 {
573         string const tmp = tostr(sel);
574         current_view->owner()->getLyXFunc()->Dispatch(LFUN_LAYOUTNO,
575                                                       tmp);
576 }
577
578
579 void MenuLayoutCharacter()
580 {
581         static int ow = -1, oh;
582
583         if (fd_form_character->form_character->visible) {
584                 fl_raise_form(fd_form_character->form_character);
585         } else {
586                 fl_show_form(fd_form_character->form_character,
587                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT,
588                              _("Character Style"));
589                 if (ow < 0) {
590                         ow = fd_form_character->form_character->w;
591                         oh = fd_form_character->form_character->h;
592                 }
593                 fl_set_form_minsize(fd_form_character->form_character, ow, oh);
594         }
595 }
596
597
598 bool UpdateLayoutPreamble(BufferView * bv)
599 {
600         bool update = true;
601         if (!bv->available())
602                 update = false;
603
604         if (update) {
605                 fl_set_input(fd_form_preamble->input_preamble,
606                              bv->buffer()->params.preamble.c_str());
607
608                 if (bv->buffer()->isReadonly()) {
609                         fl_deactivate_object(fd_form_preamble->input_preamble);
610                         fl_deactivate_object(fd_form_preamble->button_ok);
611                         fl_deactivate_object(fd_form_preamble->button_apply);
612                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_INACTIVE);
613                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_INACTIVE);
614                 } else {
615                         fl_activate_object(fd_form_preamble->input_preamble);
616                         fl_activate_object(fd_form_preamble->button_ok);
617                         fl_activate_object(fd_form_preamble->button_apply);
618                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_BLACK);
619                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_BLACK);
620                 }
621         } else if (fd_form_preamble->form_preamble->visible) {
622                 fl_hide_form(fd_form_preamble->form_preamble);
623         }
624         return update;
625 }
626
627
628 void MenuLayoutPreamble()
629 {
630         static int ow = -1, oh;
631
632         if (UpdateLayoutPreamble(current_view)) {
633                 if (fd_form_preamble->form_preamble->visible) {
634                         fl_raise_form(fd_form_preamble->form_preamble);
635                 } else {
636                         fl_show_form(fd_form_preamble->form_preamble,
637                                      FL_PLACE_MOUSE | FL_FREE_SIZE,
638                                      FL_TRANSIENT,
639                                      _("LaTeX Preamble"));
640                         if (ow < 0) {
641                                 ow = fd_form_preamble->form_preamble->w;
642                                 oh = fd_form_preamble->form_preamble->h;
643                         }
644                         fl_set_form_minsize(fd_form_preamble->form_preamble,
645                                             ow, oh);
646                 }
647         }
648 }
649
650
651 void MenuLayoutSave(BufferView * bv)
652 {
653         if (!bv->available())
654                 return;
655
656         if (AskQuestion(_("Do you want to save the current settings"),
657                         _("for Character, Document, Paper and Quotes"),
658                         _("as default for new documents?")))
659                 bv->buffer()->saveParamsAsDefaults();
660 }
661
662
663 // This is both GUI and LyXFont dependent. Don't know where to put it. (Asger)
664 // Well, it's mostly GUI dependent, so I guess it will stay here. (Asger)
665 LyXFont const UserFreeFont(BufferParams const & params)
666 {
667         LyXFont font(LyXFont::ALL_IGNORE);
668
669         int pos = fl_get_choice(fd_form_character->choice_family);
670         switch (pos) {
671         case 1: font.setFamily(LyXFont::IGNORE_FAMILY); break;
672         case 2: font.setFamily(LyXFont::ROMAN_FAMILY); break;
673         case 3: font.setFamily(LyXFont::SANS_FAMILY); break;
674         case 4: font.setFamily(LyXFont::TYPEWRITER_FAMILY); break;
675         case 5: font.setFamily(LyXFont::INHERIT_FAMILY); break;
676         }
677
678         pos = fl_get_choice(fd_form_character->choice_series);
679         switch (pos) {
680         case 1: font.setSeries(LyXFont::IGNORE_SERIES); break;
681         case 2: font.setSeries(LyXFont::MEDIUM_SERIES); break;
682         case 3: font.setSeries(LyXFont::BOLD_SERIES); break;
683         case 4: font.setSeries(LyXFont::INHERIT_SERIES); break;
684         }
685
686         pos = fl_get_choice(fd_form_character->choice_shape);
687         switch (pos) {
688         case 1: font.setShape(LyXFont::IGNORE_SHAPE); break;
689         case 2: font.setShape(LyXFont::UP_SHAPE); break;
690         case 3: font.setShape(LyXFont::ITALIC_SHAPE); break;
691         case 4: font.setShape(LyXFont::SLANTED_SHAPE); break;
692         case 5: font.setShape(LyXFont::SMALLCAPS_SHAPE); break;
693         case 6: font.setShape(LyXFont::INHERIT_SHAPE); break;
694         }
695
696         pos = fl_get_choice(fd_form_character->choice_size);
697         switch (pos) {
698         case 1: font.setSize(LyXFont::IGNORE_SIZE); break;
699         case 2: font.setSize(LyXFont::SIZE_TINY); break;
700         case 3: font.setSize(LyXFont::SIZE_SCRIPT); break;
701         case 4: font.setSize(LyXFont::SIZE_FOOTNOTE); break;
702         case 5: font.setSize(LyXFont::SIZE_SMALL); break;
703         case 6: font.setSize(LyXFont::SIZE_NORMAL); break;
704         case 7: font.setSize(LyXFont::SIZE_LARGE); break;
705         case 8: font.setSize(LyXFont::SIZE_LARGER); break;
706         case 9: font.setSize(LyXFont::SIZE_LARGEST); break;
707         case 10: font.setSize(LyXFont::SIZE_HUGE); break;
708         case 11: font.setSize(LyXFont::SIZE_HUGER); break;
709         case 12: font.setSize(LyXFont::INCREASE_SIZE); break;
710         case 13: font.setSize(LyXFont::DECREASE_SIZE); break;
711         case 14: font.setSize(LyXFont::INHERIT_SIZE); break;
712         }
713
714         pos = fl_get_choice(fd_form_character->choice_bar);
715         switch (pos) {
716         case 1: font.setEmph(LyXFont::IGNORE);
717                 font.setUnderbar(LyXFont::IGNORE);
718                 font.setNoun(LyXFont::IGNORE);
719                 font.setLatex(LyXFont::IGNORE);
720                 break;
721         case 2: font.setEmph(LyXFont::TOGGLE); break;
722         case 3: font.setUnderbar(LyXFont::TOGGLE); break;
723         case 4: font.setNoun(LyXFont::TOGGLE); break;
724         case 5: font.setLatex(LyXFont::TOGGLE); break;
725         case 6: font.setEmph(LyXFont::INHERIT);
726                 font.setUnderbar(LyXFont::INHERIT);
727                 font.setNoun(LyXFont::INHERIT);
728                 font.setLatex(LyXFont::INHERIT);
729                 break;
730         }
731
732         pos = fl_get_choice(fd_form_character->choice_color);
733         switch (pos) {
734         case 1: font.setColor(LColor::ignore); break;
735         case 2: font.setColor(LColor::none); break;
736         case 3: font.setColor(LColor::black); break;
737         case 4: font.setColor(LColor::white); break;
738         case 5: font.setColor(LColor::red); break;
739         case 6: font.setColor(LColor::green); break;
740         case 7: font.setColor(LColor::blue); break;
741         case 8: font.setColor(LColor::cyan); break;
742         case 9: font.setColor(LColor::magenta); break;
743         case 10: font.setColor(LColor::yellow); break;
744         case 11: font.setColor(LColor::inherit); break;
745         }
746
747         int const choice = combo_language2->get();
748         if (choice == 1)
749                 font.setLanguage(ignore_language);
750         else if (choice == 2)
751                 font.setLanguage(params.language);
752         else
753                 font.setLanguage(languages.getLanguage(combo_language2->getline()));
754
755         return font; 
756 }
757
758
759 /* callbacks for form form_character */
760
761 extern "C"
762 void CharacterApplyCB(FL_OBJECT *, long)
763 {
764         // we set toggleall locally here, since it should be true for
765         // all other uses of ToggleAndShow() (JMarc)
766         toggleall = fl_get_button(fd_form_character->check_toggle_all);
767         ToggleAndShow(current_view, UserFreeFont(current_view->buffer()->params));
768         current_view->setState();
769         toggleall = true;
770 }
771
772
773 extern "C"
774 void CharacterCloseCB(FL_OBJECT *, long)
775 {
776         fl_hide_form(fd_form_character->form_character);
777 }
778
779
780 extern "C"
781 void CharacterOKCB(FL_OBJECT * ob, long data)
782 {
783         CharacterApplyCB(ob, data);
784         CharacterCloseCB(ob, data);
785 }
786
787
788 /* callbacks for form form_preamble */
789
790 extern "C"
791 void PreambleCancelCB(FL_OBJECT *, long)
792 {
793         fl_hide_form(fd_form_preamble->form_preamble);
794 }
795
796
797 extern "C"
798 void PreambleApplyCB(FL_OBJECT *, long)
799 {
800         if (!current_view->available())
801                 return;
802         
803         current_view->buffer()->params.preamble = 
804                 fl_get_input(fd_form_preamble->input_preamble);
805         current_view->buffer()->markDirty();
806         current_view->owner()->getMiniBuffer()->Set(_("LaTeX preamble set"));
807 }
808
809    
810 extern "C"
811 void PreambleOKCB(FL_OBJECT * ob, long data)
812 {
813         PreambleApplyCB(ob, data);
814         PreambleCancelCB(ob, data);
815 }
816
817
818 void Figure()
819 {
820         if (fd_form_figure->form_figure->visible) {
821                 fl_raise_form(fd_form_figure->form_figure);
822         } else {
823                 fl_show_form(fd_form_figure->form_figure,
824                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT,
825                              _("Insert Figure"));
826         }
827 }
828
829
830 /* callbacks for form form_figure */
831 extern "C"
832 void FigureApplyCB(FL_OBJECT *, long)
833 {
834         if (!current_view->available())
835                 return;
836
837         Buffer * buffer = current_view->buffer();
838         if (buffer->isReadonly()) // paranoia
839                 return;
840         
841         current_view->owner()->getMiniBuffer()->Set(_("Inserting figure..."));
842         if (fl_get_button(fd_form_figure->radio_inline)) {
843                 InsetFig * new_inset = new InsetFig(100, 20, *buffer);
844                 current_view->insertInset(new_inset);
845                 current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
846                 new_inset->Edit(current_view, 0, 0, 0);
847                 return;
848         }
849         
850         current_view->hideCursor();
851         current_view->update(current_view->text, BufferView::SELECT|BufferView::FITCUR);
852         current_view->beforeChange(current_view->text);
853       
854         current_view->text->SetCursorParUndo(current_view->buffer()); 
855         current_view->text->FreezeUndo();
856
857         current_view->text->BreakParagraph(current_view);
858         current_view->update(current_view->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
859       
860         if (current_view->text->cursor.par()->Last()) {
861                 current_view->text->CursorLeft(current_view);
862          
863                 current_view->text->BreakParagraph(current_view);
864                 current_view->update(current_view->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
865         }
866
867         // The standard layout should always be numer 0;
868         current_view->text->SetLayout(current_view, 0);
869
870 #ifndef NEW_INSETS
871         if (current_view->text->cursor.par()->footnoteflag == 
872             LyXParagraph::NO_FOOTNOTE) {
873 #endif
874                 current_view->text->
875                         SetParagraph(current_view, 0, 0,
876                                      0, 0,
877                                      VSpace (0.3 * buffer->params.spacing.getValue(),
878                                              LyXLength::CM),
879                                      VSpace (0.3 *
880                                              buffer->params.spacing.getValue(),
881                                              LyXLength::CM),
882                                      LYX_ALIGN_CENTER, string(), 0);
883 #ifndef NEW_INSETS
884         } else {
885                 current_view->text->SetParagraph(current_view, 0, 0,
886                                                  0, 0,
887                                                  VSpace(VSpace::NONE),
888                                                  VSpace(VSpace::NONE),
889                                                  LYX_ALIGN_CENTER, 
890                                                  string(),
891                                                  0);
892         }
893 #endif
894         
895         current_view->update(current_view->text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
896       
897         Inset * new_inset = new InsetFig(100, 100, *buffer);
898         current_view->insertInset(new_inset);
899         new_inset->Edit(current_view, 0, 0, 0);
900         current_view->update(current_view->text, BufferView::SELECT|BufferView::FITCUR);
901         current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
902         current_view->text->UnFreezeUndo();
903         current_view->setState();
904 }
905
906
907 extern "C" void FigureCancelCB(FL_OBJECT *, long)
908 {
909         fl_hide_form(fd_form_figure->form_figure);
910 }
911
912
913 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
914 {
915         FigureApplyCB(ob, data);
916         FigureCancelCB(ob, data);
917 }
918
919
920 // This function runs "configure" and then rereads lyx.defaults to
921 // reconfigure the automatic settings.
922 void Reconfigure(BufferView * bv)
923 {
924         bv->owner()->getMiniBuffer()->Set(_("Running configure..."));
925
926         // Run configure in user lyx directory
927         Path p(user_lyxdir);
928         Systemcalls one(Systemcalls::System, 
929                         AddName(system_lyxdir, "configure"));
930         p.pop();
931         bv->owner()->getMiniBuffer()->Set(_("Reloading configuration..."));
932         lyxrc.read(LibFileSearch(string(), "lyxrc.defaults"));
933         WriteAlert(_("The system has been reconfigured."), 
934                    _("You need to restart LyX to make use of any"),
935                    _("updated document class specifications."));
936 }