]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiView.C
63aef852fe713d617b5cdcd3ae49519e7bcebc02
[features.git] / src / frontends / qt4 / GuiView.C
1 /**
2  * \file GuiView.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author John Levon
8  * \author Abdelrazak Younes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiView.h"
16
17 #include "GuiImplementation.h"
18 #include "GuiWorkArea.h"
19 #include "QLMenubar.h"
20 #include "QLToolbar.h"
21 #include "QCommandBuffer.h"
22 #include "qt_helpers.h"
23
24 #include "frontends/Application.h"
25 #include "frontends/Gui.h"
26 #include "frontends/WorkArea.h"
27
28 #include "support/filetools.h"
29 #include "support/convert.h"
30 #include "support/lstrings.h"
31
32 #include "BufferView.h"
33 #include "bufferlist.h"
34 #include "debug.h"
35 #include "funcrequest.h"
36 #include "lyx_cb.h"
37 #include "lyxrc.h"
38 #include "lyx_main.h"
39 #include "session.h"
40 #include "lyxfunc.h"
41 #include "MenuBackend.h"
42
43 #include <QAction>
44 #include <QApplication>
45 #include <QCloseEvent>
46 #include <QPixmap>
47 #include <QStatusBar>
48 #include <QToolBar>
49 #include <QDesktopWidget>
50
51 #include <boost/bind.hpp>
52
53 using std::endl;
54 using std::string;
55 using std::vector;
56
57 namespace lyx {
58
59 using support::subst;
60 using support::libFileSearch;
61
62 namespace frontend {
63
64 namespace {
65
66 int const statusbar_timer_value = 3000;
67
68 } // namespace anon
69
70
71 GuiView::GuiView(int id)
72         : QMainWindow(), LyXView(id), commandbuffer_(0)
73 {
74         setAttribute(Qt::WA_DeleteOnClose, true);
75         setAttribute(Qt::WA_QuitOnClose, true);
76
77 //      setToolButtonStyle(Qt::ToolButtonIconOnly);
78 //      setIconSize(QSize(12,12));
79
80 //      bufferview_.reset(new BufferView(this, width, height));
81
82 #ifndef Q_WS_MACX
83         //  assign an icon to main form. We do not do it under Qt/Mac,
84         //  since the icon is provided in the application bundle.
85         string const iconname = libFileSearch("images", "lyx", "xpm");
86         if (!iconname.empty())
87                 setWindowIcon(QPixmap(toqstr(iconname)));
88 #endif
89 }
90
91
92 GuiView::~GuiView()
93 {
94 }
95
96
97 void GuiView::close()
98 {
99         QMainWindow::close();
100 }
101
102
103 void GuiView::init()
104 {
105         menubar_.reset(new QLMenubar(this, menubackend));
106         QObject::connect(menuBar(), SIGNAL(triggered(QAction *)),
107                 this, SLOT(updateMenu(QAction *)));
108
109         getToolbars().init();
110
111         statusBar()->setSizeGripEnabled(false);
112
113         QObject::connect(&statusbar_timer_, SIGNAL(timeout()),
114                 this, SLOT(update_view_state_qt()));
115
116         // make sure the buttons are disabled if needed
117         updateToolbars();
118         updateLayoutChoice();
119         updateMenubar();
120 }
121
122
123 void GuiView::saveGeometry()
124 {
125         // FIXME:
126         // change the ifdef to 'geometry = normalGeometry();' only
127         // when Trolltech has fixed the broken normalGeometry on X11:
128         // http://www.trolltech.com/developer/task-tracker/index_html?id=119684+&method=entry
129         // Then also the moveEvent, resizeEvent, and the
130         // code for floatingGeometry_ can be removed;
131         // adjust GuiView::setGeometry()
132 #ifdef Q_OS_WIN32
133         QRect geometry = normalGeometry();
134 #else
135         updateFloatingGeometry();
136         QRect geometry = floatingGeometry_;
137 #endif
138
139         // save windows size and position
140         Session & session = LyX::ref().session();
141         session.saveSessionInfo("WindowWidth", convert<string>(geometry.width()));
142         session.saveSessionInfo("WindowHeight", convert<string>(geometry.height()));
143         session.saveSessionInfo("WindowIsMaximized", (isMaximized() ? "yes" : "no"));
144         if (lyxrc.geometry_xysaved) {
145                 session.saveSessionInfo("WindowPosX", convert<string>(geometry.x()));
146                 session.saveSessionInfo("WindowPosY", convert<string>(geometry.y()));
147         }
148 }
149                                                   
150 void GuiView::setGeometry(unsigned int width,
151                                                                   unsigned int height,
152                                                                   int posx, int posy,
153                                                                   bool maximize)
154 {
155         // only true when the -geometry option was NOT used
156         if (width != 0 && height != 0) {
157                 if (posx != -1 && posy != -1) {
158                         // if there are ever startup positioning problems 
159                         // on a virtual desktop then check the 6 lines below
160                         // http://doc.trolltech.com/4.2/qdesktopwidget.html 
161                         QDesktopWidget& dw = *qApp->desktop();
162                         QRect desk = dw.availableGeometry(dw.primaryScreen());
163                         if (posx >= desk.width())
164                                    posx = 0.1 * desk.width();
165                         if (posy >= desk.height())
166                                    posy = 0.1 * desk.height();
167 #ifdef Q_WS_WIN
168                         // FIXME: use only setGeoemtry when Trolltech has
169                         // fixed the qt4/X11 bug
170                         QMainWindow::setGeometry(posx, posy,width, height);
171 #else
172                         resize(width, height);
173                         move(posx, posy);
174 #endif
175                 } else {
176                         resize(width, height);
177                 }
178
179                 if (maximize)
180                         setWindowState(Qt::WindowMaximized);
181         }
182         
183         show();
184 }
185
186
187 void GuiView::updateMenu(QAction * /*action*/)
188 {
189         menubar_->update();
190 }
191
192
193 void GuiView::setWindowTitle(docstring const & t, docstring const & it)
194 {
195         QMainWindow::setWindowTitle(toqstr(t));
196         QMainWindow::setWindowIconText(toqstr(it));
197 }
198
199
200 void GuiView::addCommandBuffer(QToolBar * toolbar)
201 {
202         commandbuffer_ = new QCommandBuffer(this, *controlcommand_);
203         focus_command_buffer.connect(boost::bind(&GuiView::focus_command_widget, this));
204         toolbar->addWidget(commandbuffer_);
205 }
206
207
208 void GuiView::message(docstring const & str)
209 {
210         statusBar()->showMessage(toqstr(str));
211         statusbar_timer_.stop();
212         statusbar_timer_.start(statusbar_timer_value);
213 }
214
215
216 void GuiView::clearMessage()
217 {
218         update_view_state_qt();
219 }
220
221
222 void GuiView::focus_command_widget()
223 {
224         if (commandbuffer_)
225                 commandbuffer_->focus_command();
226 }
227
228
229 void GuiView::update_view_state_qt()
230 {
231         statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
232         statusbar_timer_.stop();
233 }
234
235
236 void GuiView::updateStatusBar()
237 {
238         // let the user see the explicit message
239         if (statusbar_timer_.isActive())
240                 return;
241
242         statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
243 }
244
245
246 void GuiView::activated(FuncRequest const & func)
247 {
248         dispatch(func);
249 }
250
251
252 bool GuiView::hasFocus() const
253 {
254         return qApp->activeWindow() == this;
255 }
256
257
258 void  GuiView::updateFloatingGeometry()
259 {
260         if (!isMaximized())
261                 floatingGeometry_ = QRect(x(), y(), width(), height());
262 }
263
264
265 void GuiView::resizeEvent(QResizeEvent *)
266 {
267         updateFloatingGeometry();
268 }
269
270
271 void GuiView::moveEvent(QMoveEvent *)
272 {
273         updateFloatingGeometry();
274 }
275
276
277 void GuiView::closeEvent(QCloseEvent * close_event)
278 {
279         GuiImplementation & gui 
280                 = static_cast<GuiImplementation &>(theApp->gui());
281
282         vector<int> const & view_ids = gui.viewIds();
283
284         if (view_ids.size() == 1 && !theBufferList().quitWriteAll()) {
285                 close_event->ignore();
286                 return;
287         }
288
289         saveGeometry();
290         gui.unregisterView(this);
291 }
292
293
294 void GuiView::show()
295 {
296         QMainWindow::setWindowTitle(qt_("LyX"));
297         QMainWindow::show();
298         updateFloatingGeometry();
299 }
300
301
302 void GuiView::busy(bool yes)
303 {
304         static_cast<GuiWorkArea *>(work_area_)->setUpdatesEnabled(!yes);
305
306         if (yes) {
307                 work_area_->stopBlinkingCursor();
308                 QApplication::setOverrideCursor(Qt::WaitCursor);
309         }
310         else {
311                 work_area_->startBlinkingCursor();
312                 QApplication::restoreOverrideCursor();
313         }
314 }
315
316
317 Toolbars::ToolbarPtr GuiView::makeToolbar(ToolbarBackend::Toolbar const & tbb)
318 {
319         QLToolbar * Tb = new QLToolbar(tbb, *this);
320         static QLToolbar * lastTb = 0;
321
322         if (tbb.flags & ToolbarBackend::TOP) {
323                         addToolBar(Qt::TopToolBarArea, Tb);
324                         addToolBarBreak(Qt::TopToolBarArea);
325         }
326         if (tbb.flags & ToolbarBackend::BOTTOM) {
327                 addToolBar(Qt::BottomToolBarArea, Tb);
328                 if (lastTb)
329                         insertToolBarBreak(lastTb);
330                 lastTb = Tb;
331         }
332         if (tbb.flags & ToolbarBackend::LEFT) {
333                 addToolBar(Qt::LeftToolBarArea, Tb);
334         }
335         if (tbb.flags & ToolbarBackend::RIGHT) {
336                 addToolBar(Qt::RightToolBarArea, Tb);
337         }
338
339         return Toolbars::ToolbarPtr(Tb);
340 }
341
342 } // namespace frontend
343 } // namespace lyx
344
345 #include "GuiView_moc.cpp"