]> git.lyx.org Git - features.git/blob - src/lyx_gui.C
Dekel language/encoding patch + a few fixes
[features.git] / src / lyx_gui.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 #include <cstdlib>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include <fcntl.h>
19 #include "lyx_gui.h"
20 #include FORMS_H_LOCATION
21 #include "support/filetools.h"
22 #include "combox.h"
23 #include "lyx.h"
24 #include "form1.h"
25 #include "layout_forms.h"
26 #include "print_form.h"
27 #include "tex-strings.h"
28 #include "lyx_main.h"
29 #include "log_form.h"
30 #include "debug.h"
31 #include "version.h"
32 #include "LyXView.h"
33 #include "buffer.h"
34 #include "lyxserver.h"
35 #include "lyxrc.h"
36 #include "gettext.h"
37 #include "lyx_gui_misc.h"
38 #include "lyxlookup.h"
39 #include "bufferlist.h"
40 #include "language.h"
41 #include "ColorHandler.h"
42 #include "frontends/GUIRunTime.h"
43
44 using std::endl;
45
46 FD_form_title * fd_form_title;
47 FD_form_character * fd_form_character;
48 FD_form_preamble * fd_form_preamble;
49 FD_form_sendto * fd_form_sendto;
50 FD_form_figure * fd_form_figure;
51 FD_LaTeXLog * fd_latex_log; // from log_form.h
52 Combox * combo_language;
53 Combox * combo_language2;
54
55 extern LyXServer * lyxserver;
56 extern bool finished;   // flag, that we are quitting the program
57 extern BufferList bufferlist;
58 extern GUIRunTime guiruntime;
59
60 FL_CMD_OPT cmdopt[] =
61 {
62         {"-geometry", "*.geometry", XrmoptionSepArg, "690x510"}
63 };
64
65 static int width  = 690;
66 static int height = 510;
67 static int xpos   = -1;
68 static int ypos   = -1;
69 static char geometry[40];
70 bool       cursor_follows_scrollbar;
71
72
73 FL_resource res[] =
74 {
75         {"geometry", "geometryClass", FL_STRING, geometry, "", 40}
76 };
77
78
79 extern "C"
80 int LyX_XErrHandler(Display * display, XErrorEvent * xeev)
81 {
82 //#warning Please see if you can trigger this!
83         // emergency save
84         if (!bufferlist.empty())
85                 bufferlist.emergencyWriteAll();
86
87         // Get the reason for the crash.
88         char etxt[513];
89         XGetErrorText(display, xeev->error_code, etxt, 512);
90         lyxerr << etxt << endl;
91         // By doing an abort we get a nice backtrace. (hopefully)
92         lyx::abort();
93         return 0; // Solaris CC wants us to return something
94 }
95
96
97 LyXGUI::LyXGUI(LyX * owner, int * argc, char * argv[], bool GUI)
98         : _owner(owner), lyxViews(0)
99 {
100         gui = GUI;
101         if (!gui)
102                 return;
103
104         // 
105         setDefaults();
106         
107         static const int num_res = sizeof(res)/sizeof(FL_resource);
108         fl_initialize(argc, argv, "LyX", cmdopt, num_res);
109         fl_get_app_resources(res, num_res);
110
111         static const int geometryBitmask =
112                 XParseGeometry( geometry,
113                                 &xpos,
114                                 &ypos,
115                                 reinterpret_cast<unsigned int *>(&width),
116                                 reinterpret_cast<unsigned int *>(&height));
117
118         Display * display = fl_get_display();
119         if (!display) {
120                 lyxerr << "LyX: unable to access X display, exiting" << endl;
121                 exit(1);
122         }
123         fcntl(ConnectionNumber(display), F_SETFD, FD_CLOEXEC);
124         // X Error handler install goes here
125         XSetErrorHandler(LyX_XErrHandler);
126
127         // A width less than 590 pops up an awkward main window
128         // The minimal values of width/height (590/400) are defined in
129         // src/lyx.C  
130         if (width < 590) width = 590;
131         if (height < 400) height = 400;
132         
133         // If width is not set by geometry, check it against monitor width
134         if ( !(geometryBitmask & 4) ) {
135                 Screen * scr = DefaultScreenOfDisplay(fl_get_display());
136                 if (WidthOfScreen(scr) - 8 < width)
137                         width = WidthOfScreen(scr) - 8;
138         }
139
140         // If height is not set by geometry, check it against monitor height
141         if ( !(geometryBitmask & 8) ) {
142                 Screen * scr = DefaultScreenOfDisplay(fl_get_display());
143                 if (HeightOfScreen(scr) - 24 < height)
144                         height = HeightOfScreen(scr) - 24;
145         }
146
147         // Recalculate xpos if it's negative
148         if (geometryBitmask & 16)
149                 xpos += WidthOfScreen(DefaultScreenOfDisplay(fl_get_display())) - width;
150
151         // Recalculate ypos if it's negative
152         if (geometryBitmask & 32)
153                 ypos += HeightOfScreen(DefaultScreenOfDisplay(fl_get_display())) - height;
154
155         // Initialize the LyXColorHandler
156         lyxColorHandler = new LyXColorHandler;
157 }
158
159
160 // A destructor is always necessary  (asierra-970604)
161 LyXGUI::~LyXGUI()
162 {
163         // Lyxserver was created in this class so should be destroyed
164         // here.  asierra-970604
165         delete lyxserver;
166         lyxserver = 0;
167         delete lyxViews;
168
169         CloseLyXLookup();
170 }
171
172
173 void LyXGUI::setDefaults()
174 {
175         GUIRunTime::setDefaults();
176 }
177
178
179 // This is called after we have parsed lyxrc
180 void LyXGUI::init()
181 {
182         if (!gui)
183                 return;
184
185         create_forms();
186
187         if (lyxrc.font_norm_menu.empty())
188                 lyxrc.font_norm_menu = lyxrc.font_norm;
189         // Set the font name for popups and menus
190         string menufontname = lyxrc.menu_font_name 
191                                + "-*-*-*-?-*-*-*-*-"  
192                                + lyxrc.font_norm_menu;
193                 // "?" means "scale that font"
194         string popupfontname = lyxrc.popup_font_name 
195                                + "-*-*-*-?-*-*-*-*-"  
196                                + lyxrc.font_norm_menu;
197
198         int bold = fl_set_font_name(FL_BOLD_STYLE, menufontname.c_str());
199         int normal = fl_set_font_name(FL_NORMAL_STYLE, popupfontname.c_str());
200         if (bold < 0)
201                 lyxerr << "Could not set menu font to "
202                        << menufontname << endl;
203
204         if (normal < 0)
205                 lyxerr << "Could not set popup font to "
206                        << popupfontname << endl;
207
208         if (bold < 0 && normal < 0) {
209                 lyxerr << "Using 'helvetica' font for menus" << endl;
210                 bold = fl_set_font_name(FL_BOLD_STYLE,
211                                         "-*-helvetica-bold-r-*-*-*-?-*-*-*-*-iso8859-1");
212                 normal = fl_set_font_name(FL_NORMAL_STYLE,
213                                           "-*-helvetica-medium-r-*-*-*-?-*-*-*-*-iso8859-1");
214                 if (bold < 0 && normal < 0) {
215                         lyxerr << "Could not find helvetica font. Using 'fixed'." << endl;
216                         normal = fl_set_font_name(FL_NORMAL_STYLE, "fixed");
217                 }
218         }
219
220         // put here (after fl_initialize) to avoid segfault. Cannot be done
221         // in setDefaults() (Matthias 140496)
222         // Moved from ::LyXGUI to ::init to allow popup font customization 
223         // (petr 120997).
224         fl_setpup_fontstyle(FL_NORMAL_STYLE);
225         fl_setpup_fontsize(FL_NORMAL_SIZE);
226         fl_setpup_color(FL_MCOL, FL_BLACK);
227         fl_set_goodies_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
228
229         // all lyxrc settings has to be done here as lyxrc has not yet
230         // been read when the GUI is created (Jug)
231
232         // the sendto form
233         if (!lyxrc.custom_export_command.empty())
234                 fl_set_input(fd_form_sendto->input_cmd,
235                              lyxrc.custom_export_command.c_str());
236         if (lyxrc.custom_export_format == "lyx")
237                 fl_set_button(fd_form_sendto->radio_ftype_lyx, 1);
238         else if (lyxrc.custom_export_format == "tex")
239                 fl_set_button(fd_form_sendto->radio_ftype_latex, 1);
240         else if (lyxrc.custom_export_format == "dvi")
241                 fl_set_button(fd_form_sendto->radio_ftype_dvi, 1);
242         else if (lyxrc.custom_export_format == "ps")
243                 fl_set_button(fd_form_sendto->radio_ftype_ps, 1);
244         else if (lyxrc.custom_export_format == "ascii")
245                 fl_set_button(fd_form_sendto->radio_ftype_ascii, 1);
246
247         // Update parameters.
248         lyxViews->redraw();
249
250         // Initialize the views.
251         lyxViews->init();
252
253         // in 0.12 the initialisation of the LyXServer must be done here
254         // 0.13 it should be moved again...
255         lyxserver = new LyXServer(lyxViews->getLyXFunc(), lyxrc.lyxpipes);
256 }
257
258
259 void LyXGUI::create_forms()
260 {
261         lyxerr[Debug::INIT] << "Initializing LyXView..." << endl;
262         lyxViews = new LyXView(width, height);
263         lyxerr[Debug::INIT] << "Initializing LyXView...done" << endl;
264
265         // From here down should be done by somebody else. (Lgb)
266
267         //
268         // Create forms
269         //
270
271         // the title form
272         string banner_file = LibFileSearch("images", "banner", "xpm");
273         if (lyxrc.show_banner && !banner_file.empty()) {
274                 fd_form_title = create_form_form_title();
275                 fl_set_form_dblbuffer(fd_form_title->form_title, 1); // use dbl buffer
276                 fl_set_form_atclose(fd_form_title->form_title, CancelCloseBoxCB, 0);
277                 fl_addto_form(fd_form_title->form_title);
278                 FL_OBJECT *obj = fl_add_pixmapbutton(FL_NORMAL_BUTTON, 0, 0, 425, 290, "");
279                 fl_set_pixmapbutton_file(obj, banner_file.c_str());
280                 
281                 fl_set_pixmapbutton_focus_outline(obj, 3);
282                 fl_set_button_shortcut(obj, "^M ^[", 1);
283                 fl_set_object_boxtype(obj, FL_NO_BOX);
284                 fl_set_object_callback(obj, TimerCB, 0);
285                 
286                 obj = fl_add_text(FL_NORMAL_TEXT, 248, 265, 170, 16, LYX_VERSION);
287                 fl_set_object_lsize(obj, FL_NORMAL_SIZE);
288                 fl_mapcolor(FL_FREE_COL2, 0x05, 0x2e, 0x4c);
289                 fl_mapcolor(FL_FREE_COL3, 0xe1, 0xd2, 0x9b);
290                 fl_set_object_color(obj, FL_FREE_COL2, FL_FREE_COL2);
291                 fl_set_object_lcol(obj, FL_FREE_COL3);
292                 fl_set_object_lalign(obj, FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
293                 fl_set_object_lstyle(obj, FL_BOLD_STYLE);
294                 fl_end_form();
295         }
296
297         // the character form
298         fd_form_character = create_form_form_character();
299         fl_set_form_atclose(fd_form_character->form_character,
300                             CancelCloseBoxCB, 0);
301         fl_addto_choice(fd_form_character->choice_family, 
302                         _(" No change %l| Roman | Sans Serif | Typewriter %l| Reset "));
303         fl_addto_choice(fd_form_character->choice_series, 
304                         _(" No change %l| Medium | Bold %l| Reset "));
305         fl_addto_choice(fd_form_character->choice_shape,
306                         _(" No change %l| Upright | Italic | Slanted | Small Caps "
307                         "%l| Reset "));
308         fl_addto_choice(fd_form_character->choice_size, 
309                         _(" No change %l| Tiny | Smallest | Smaller | Small "
310                         "| Normal | Large | Larger | Largest | Huge | Huger "
311                         "%l| Increase | Decrease | Reset "));
312         fl_addto_choice(fd_form_character->choice_bar, 
313                         _(" No change %l| Emph | Underbar | Noun | LaTeX mode %l| Reset "));
314         fl_addto_choice(fd_form_character->choice_color, 
315                         _(" No change %l| No color | Black | White | Red | Green "
316                         "| Blue | Cyan | Magenta | Yellow %l| Reset "));
317         fl_set_form_minsize(fd_form_character->form_character,
318                             fd_form_character->form_character->w,
319                             fd_form_character->form_character->h);
320         lyxerr[Debug::INIT] << "Initializing form_character::combox..." << endl;
321         fl_addto_form(fd_form_character->form_character);
322         combo_language2 = new Combox(FL_COMBOX_DROPLIST);
323         FL_OBJECT * ob = fd_form_character->choice_language;
324         combo_language2->add(ob->x, ob->y, ob->w, ob->h, 250);
325         combo_language2->shortcut("#L", 1);
326         fl_end_form();
327         lyxerr[Debug::INIT] << "Initializing form_character...done" << endl;
328
329         // build up the combox entries
330         combo_language2->addto(_("No change"));
331         combo_language2->addto(_("Reset"));
332         for(Languages::const_iterator cit = languages.begin();
333             cit != languages.end(); ++cit) {
334 #ifdef DO_USE_DEFAULT_LANGUAGE
335             if ((*cit).second.lang() != "default")
336 #endif
337                 combo_language2->addto((*cit).second.lang().c_str());
338         }
339         combo_language2->select_text(_("No change"));
340
341         // the preamble form
342         fd_form_preamble = create_form_form_preamble();
343         fl_set_form_atclose(fd_form_preamble->form_preamble,
344                             CancelCloseBoxCB, 0);
345
346         // the sendto form
347         fd_form_sendto = create_form_form_sendto();
348         fl_set_form_atclose(fd_form_sendto->form_sendto, CancelCloseBoxCB, 0);
349
350         // the figure form
351         fd_form_figure = create_form_form_figure();
352         fl_set_form_atclose(fd_form_figure->form_figure,
353                             CancelCloseBoxCB, 0);
354         fl_set_button(fd_form_figure->radio_postscript, 1);
355
356         // the latex log form
357         fd_latex_log = create_form_LaTeXLog();
358         fl_set_form_atclose(fd_latex_log->LaTeXLog,
359                             CancelCloseBoxCB, 0);
360
361         // Show the main & title form
362         int main_placement = FL_PLACE_CENTER | FL_FREE_SIZE;
363         int title_placement = FL_PLACE_CENTER;
364         // Did we get a valid position?
365         if (xpos >= 0 && ypos >= 0) {
366                 lyxViews->setPosition(xpos, ypos);
367                 if (lyxrc.show_banner) {
368                         // show the title form in the middle of the main form
369                         fl_set_form_position(fd_form_title->form_title,
370                                              abs(xpos + (width/2) - (370 / 2)),
371                                              abs(ypos + (height/2) - (290 / 2)));
372                         title_placement = FL_PLACE_GEOMETRY;
373                         // The use of abs() above is a trick to ensure
374                         // valid positions
375                 }
376                         main_placement = FL_PLACE_POSITION;
377         }
378         lyxViews->show(main_placement, FL_FULLBORDER, "LyX");
379         if (lyxrc.show_banner) {
380                 fl_show_form(fd_form_title->form_title, 
381                              title_placement, FL_NOBORDER, 
382                              _("LyX Banner"));
383                 fl_redraw_form(fd_form_title->form_title);
384                 fl_raise_form(fd_form_title->form_title);
385
386                 // Show the title form at most 7 secs (lowered from 10 secs)
387                 fl_set_timer(fd_form_title->timer_title, 7);
388         }
389 }
390
391
392 void LyXGUI::runTime()
393 {
394         if (!gui) return;
395
396         guiruntime.runTime();
397 }
398
399
400 void LyXGUI::regBuf(Buffer * b)
401 {
402         lyxViews->view()->buffer(b);
403 }
404
405
406 LyXView * LyXGUI::getLyXView() const
407 {
408         return lyxViews;
409 }