]> git.lyx.org Git - lyx.git/blob - src/LyXView.C
Patch from John (figinset) and Dekel (RTL and spellchecker)
[lyx.git] / src / LyXView.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 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include <sys/time.h>
18 #include <unistd.h>
19
20 #include "LyXView.h"
21 #include "lyx_main.h"
22 #if FL_REVISION < 89
23 #include "lyxlookup.h"
24 #endif
25 #include "minibuffer.h"
26 #include "lyxfunc.h"
27 #include "debug.h"
28 #include "layout_forms.h"
29 #include "intl.h"
30 #include "lyxrc.h"
31 #include "support/filetools.h"        // OnlyFilename()
32 #include "layout.h"
33 #include "lyxtext.h"
34 #include "buffer.h"
35 #include "frontends/Dialogs.h"
36 #include "frontends/Toolbar.h"
37 #include "frontends/Menubar.h"
38 #include "MenuBackend.h"
39 #include "ToolbarDefaults.h"
40 #include "lyx_gui_misc.h"       // [update,Close,Redraw]AllBufferRelatedDialogs
41 #include "bufferview_funcs.h" // CurrentState()
42
43 using std::endl;
44
45 extern void AutoSave(BufferView *);
46 extern void QuitLyX();
47 LyXTextClass::size_type current_layout = 0;
48
49 // This is very temporary
50 BufferView * current_view;
51
52 extern "C" int C_LyXView_atCloseMainFormCB(FL_FORM *, void *);
53
54 #ifdef SIGC_CXX_NAMESPACES
55 using SigC::Connection;
56 using SigC::slot;
57 #endif
58
59 LyXView::LyXView(int width, int height)
60 {
61         create_form_form_main(width, height);
62         fl_set_form_atclose(form_, C_LyXView_atCloseMainFormCB, 0);
63         lyxerr[Debug::INIT] << "Initializing LyXFunc" << endl;
64         lyxfunc = new LyXFunc(this);
65         intl = new Intl;
66
67         // Make sure the buttons are disabled if needed.
68         toolbar->update();
69         menubar->update();
70
71         dialogs_ = new Dialogs(this);
72         // temporary until all dialogs moved into Dialogs.
73         dialogs_->updateBufferDependent
74                 .connect(slot(&updateAllVisibleBufferRelatedDialogs));
75         dialogs_->hideBufferDependent
76                 .connect(slot(&CloseAllBufferRelatedDialogs));
77         Dialogs::redrawGUI.connect(slot(this, &LyXView::redraw));
78         Dialogs::redrawGUI.connect(slot(&RedrawAllBufferRelatedDialogs));
79 }
80
81
82 LyXView::~LyXView()
83 {
84         delete menubar;
85         delete toolbar;
86         delete bufferview;
87         delete minibuffer;
88         delete lyxfunc;
89         delete intl;
90         delete dialogs_;
91 }
92
93
94 /// Redraw the main form.
95 void LyXView::redraw() {
96         lyxerr[Debug::INFO] << "LyXView::redraw()" << endl;
97         fl_redraw_form(form_);
98         minibuffer->Activate();
99 }
100
101
102 /// returns the buffer currently shown in the main form.
103 Buffer * LyXView::buffer() const
104 {
105         return bufferview->buffer();
106 }
107
108
109 BufferView * LyXView::view() const
110 {
111         return bufferview;
112 }
113
114
115 FL_FORM * LyXView::getForm() const
116 {
117         return form_;
118 }
119
120
121 Toolbar * LyXView::getToolbar() const
122 {
123         return toolbar;
124 }
125
126
127 void LyXView::setLayout(LyXTextClass::size_type layout)
128 {
129         toolbar->setLayout(layout);
130 }
131
132
133 void LyXView::updateToolbar()
134 {
135         toolbar->update();
136         menubar->update();
137 }
138
139
140 LyXFunc * LyXView::getLyXFunc() const
141 {
142         return lyxfunc;
143 }
144
145
146 MiniBuffer * LyXView::getMiniBuffer() const
147 {
148         return minibuffer;
149 }
150
151
152 Menubar * LyXView::getMenubar() const
153 {
154         return menubar;
155 }
156
157
158 void LyXView::updateMenubar() 
159 {
160         if ((!view() || !view()->buffer())
161             && menubackend.hasMenu("main_nobuffer"))
162                 menubar->set("main_nobuffer");
163         else
164                 menubar->set("main");
165 }
166
167
168 Intl * LyXView::getIntl() const
169 {
170         return intl;
171 }
172
173
174 // Callback for autosave timer
175 void LyXView::AutoSave()
176 {
177         lyxerr[Debug::INFO] << "Running AutoSave()" << endl;
178         if (view()->available())
179                 ::AutoSave(view());
180 }
181
182
183 /// Reset autosave timer
184 void LyXView::resetAutosaveTimer()
185 {
186         if (lyxrc.autosave)
187                 autosave_timeout.restart();
188 }
189
190
191 // Callback for close main form from window manager
192 int LyXView::atCloseMainFormCB(FL_FORM *, void *)
193 {
194         QuitLyX();
195         return FL_IGNORE;
196 }
197
198
199 // Wrapper for the above
200 extern "C"
201 int C_LyXView_atCloseMainFormCB(FL_FORM * form, void * p)
202 {
203         return LyXView::atCloseMainFormCB(form, p);
204 }
205
206
207 void LyXView::setPosition(int x, int y)
208 {
209         fl_set_form_position(form_, x, y);
210 }
211
212
213 void LyXView::show(int place, int border, string const & title)
214 {
215         fl_show_form(form_, place, border, title.c_str());
216         minibuffer->Init();
217 #if FL_REVISION < 89
218         InitLyXLookup(fl_get_display(), form_->window);
219 #endif
220 }
221
222
223 void LyXView::create_form_form_main(int width, int height)
224         /* to make this work as it should, .lyxrc should have been
225          * read first; OR maybe this one should be made dynamic.
226          * Hmmmm. Lgb. 
227          * We will probably not have lyxrc before the main form is
228          * initialized, because error messages from lyxrc parsing 
229          * are presented (and rightly so) in GUI popups. Asger. 
230          */
231 {
232         // the main form
233         form_ = fl_bgn_form(FL_NO_BOX, width, height);
234         form_->u_vdata = this;
235         FL_OBJECT * obj = fl_add_box(FL_FLAT_BOX, 0, 0, width, height, "");
236         fl_set_object_color(obj, FL_MCOL, FL_MCOL);
237
238         // Parameters for the appearance of the main form
239         int const air = 2;
240         int const bw = abs(fl_get_border_width());
241         
242         //
243         // THE MENUBAR
244         //
245         menubar = new Menubar(this, menubackend);
246
247         //
248         // TOOLBAR
249         //
250
251         toolbar = new Toolbar(this, air, 30 + air + bw, toolbardefaults);
252
253         // Setup the toolbar
254         toolbar->set(true);
255
256         //
257         // WORKAREA
258         //
259
260         int const ywork = 60 + 2 * air + bw;
261         int const workheight = height - ywork - (25 + 2 * air);
262
263         ::current_view = bufferview = new BufferView(this, air, ywork,
264                                                      width - 3 * air,
265                                                      workheight);
266
267         //
268         // MINIBUFFER
269         //
270
271         minibuffer = new MiniBuffer(this, air, height - (25 + air), 
272                                     width - (2 * air), 25);
273
274         //
275         // TIMERS
276         //
277
278         autosave_timeout.timeout.connect(slot(this, &LyXView::AutoSave));
279         
280         //
281         // Misc
282         //
283
284         //  assign an icon to main form
285         string iconname = LibFileSearch("images", "lyx", "xpm");
286         if (!iconname.empty()) {
287                 unsigned int w, h;
288                 Pixmap lyx_p, lyx_mask;
289                 lyx_p = fl_read_pixmapfile(fl_root,
290                                            iconname.c_str(),
291                                            &w,
292                                            &h,
293                                            &lyx_mask,
294                                            0,
295                                            0,
296                                            0); // this leaks
297                 fl_set_form_icon(form_, lyx_p, lyx_mask);
298         }
299
300         // set min size
301         fl_set_form_minsize(form_, 50, 50);
302         
303         fl_end_form();
304 }
305
306
307 void LyXView::init()
308 {
309         // Set the textclass choice
310         invalidateLayoutChoice();
311         updateLayoutChoice();
312         updateMenubar();
313         
314         // Start autosave timer
315         if (lyxrc.autosave) {
316                 autosave_timeout.setTimeout(lyxrc.autosave * 1000);
317                 autosave_timeout.start();
318         }
319
320         intl->InitKeyMapper(lyxrc.use_kbmap);
321 }
322
323
324 void LyXView::invalidateLayoutChoice()
325 {
326         last_textclass = -1;
327 }
328
329
330 void LyXView::updateLayoutChoice()
331 {
332         // This has a side-effect that the layouts are not showed when no
333         // document is loaded.
334         if (!view() || !view()->buffer()) {
335                 toolbar->clearLayoutList();
336                 return; 
337         }
338
339         // Update the layout display
340         if (last_textclass != int(buffer()->params.textclass)) {
341                 toolbar->updateLayoutList(true);
342                 last_textclass = int(buffer()->params.textclass);
343                 current_layout = 0;
344         } else
345                 toolbar->updateLayoutList(false);
346
347         
348
349         LyXTextClass::size_type layout =
350                 bufferview->text->cursor.par()->GetLayout();
351
352         if (layout != current_layout){
353                 toolbar->setLayout(layout);
354                 current_layout = layout;
355         }
356 }
357
358
359 // Updates the title of the window with the filename of the current document
360 void LyXView::updateWindowTitle()
361 {
362         static string last_title = "LyX";
363         string title = "LyX";
364
365         if (view()->available()) {
366                 string cur_title = buffer()->fileName();
367                 if (!cur_title.empty()){
368                         title += ": " + MakeDisplayPath(cur_title, 30);
369                         if (!buffer()->isLyxClean())
370                                 title += _(" (Changed)");
371                         if (buffer()->isReadonly())
372                                 title += _(" (read only)");
373                 }
374         }
375         // Don't update title if it's the same as last time
376         if (title != last_title) {
377                 fl_set_form_title(form_, title.c_str());
378                 last_title = title;
379         }
380 }
381
382
383 void LyXView::showState()
384 {
385         getMiniBuffer()->Set(CurrentState(view()));
386         getToolbar()->update();
387         menubar->update();
388 }