]> git.lyx.org Git - features.git/blob - src/frontends/qt2/QLToolbar.C
* Positionable and dynamically visible toolbars for the XForms frontend.
[features.git] / src / frontends / qt2 / QLToolbar.C
1 /**
2  * \file qt2/QLToolbar.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 Jean-Marc Lasgouttes
9  * \author Angus Leeming
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "debug.h"
19 #include "funcrequest.h"
20 #include "FuncStatus.h"
21 #include "gettext.h"
22 #include "lyxfunc.h"
23
24 #include "QtView.h"
25 #include "QLToolbar.h"
26 #include "qt_helpers.h"
27
28 #include <qcombobox.h>
29 #include <qtoolbar.h>
30 #include <qtoolbutton.h>
31
32 using std::endl;
33 using std::string;
34
35
36 namespace {
37
38 LyXTextClass const & getTextClass(LyXView const & lv)
39 {
40         return lv.buffer()->params().getLyXTextClass();
41 }
42
43 QMainWindow::ToolBarDock getPosition(ToolbarBackend::Flags const & flags)
44 {
45         if (flags & ToolbarBackend::TOP)
46                 return QMainWindow::Top;
47         if (flags & ToolbarBackend::BOTTOM)
48                 return QMainWindow::Bottom;
49         if (flags & ToolbarBackend::LEFT)
50                 return QMainWindow::Left;
51         if (flags & ToolbarBackend::RIGHT)
52                 return QMainWindow::Right;
53         return QMainWindow::Top;
54 }
55
56 } // namespace anon
57
58
59 QLayoutBox::QLayoutBox(QWidget * parent, QtView & owner)
60         : combo_(new QComboBox(parent)),
61           owner_(owner)
62 {
63         QSizePolicy p(QSizePolicy::Minimum, QSizePolicy::Fixed);
64         combo_->setSizePolicy(p);
65         combo_->setFocusPolicy(QWidget::ClickFocus);
66         combo_->setMinimumWidth(combo_->sizeHint().width());
67
68         QObject::connect(combo_, SIGNAL(activated(const QString &)),
69                          this, SLOT(selected(const QString &)));
70 }
71
72
73 void QLayoutBox::set(string const & layout)
74 {
75         LyXTextClass const & tc = getTextClass(owner_);
76
77         QString const & name = qt_(tc[layout]->name());
78
79         int i = 0;
80         for (; i < combo_->count(); ++i) {
81                 if (name == combo_->text(i))
82                         break;
83         }
84
85         if (i == combo_->count()) {
86                 lyxerr << "Trying to select non existent layout type "
87                         << fromqstr(name) << endl;
88                 return;
89         }
90
91         combo_->setCurrentItem(i);
92 }
93
94
95 void QLayoutBox::update()
96 {
97         LyXTextClass const & tc = getTextClass(owner_);
98
99         combo_->setUpdatesEnabled(false);
100
101         combo_->clear();
102
103         LyXTextClass::const_iterator it = tc.begin();
104         LyXTextClass::const_iterator const end = tc.end();
105         for (; it != end; ++it) {
106                 // ignore obsolete entries
107                 if ((*it)->obsoleted_by().empty())
108                         combo_->insertItem(qt_((*it)->name()));
109         }
110
111         // needed to recalculate size hint
112         combo_->hide();
113         combo_->setMinimumWidth(combo_->sizeHint().width());
114         combo_->show();
115
116         combo_->setUpdatesEnabled(true);
117         combo_->update();
118 }
119
120
121 void QLayoutBox::clear()
122 {
123         combo_->clear();
124 }
125
126
127 void QLayoutBox::open()
128 {
129         combo_->popup();
130 }
131
132
133 void QLayoutBox::setEnabled(bool enable)
134 {
135         // Workaround for Qt bug where setEnabled(true) closes
136         // the popup
137         if (enable != combo_->isEnabled())
138                 combo_->setEnabled(enable);
139 }
140
141
142 void QLayoutBox::selected(const QString & str)
143 {
144         string const sel = fromqstr(str);
145
146         owner_.centralWidget()->setFocus();
147
148         LyXTextClass const & tc = getTextClass(owner_);
149
150         LyXTextClass::const_iterator it  = tc.begin();
151         LyXTextClass::const_iterator const end = tc.end();
152         for (; it != end; ++it) {
153                 string const & name = (*it)->name();
154                 // Yes, the _() is correct
155                 if (_(name) == sel) {
156                         owner_.getLyXFunc()
157                                 .dispatch(FuncRequest(LFUN_LAYOUT, name),
158                                           true);
159                         return;
160                 }
161         }
162         lyxerr << "ERROR (QLayoutBox::selected): layout not found!" << endl;
163 }
164
165
166 Toolbars::ToolbarPtr make_toolbar(ToolbarBackend::Toolbar const & tbb,
167                                   LyXView & owner)
168 {
169         return Toolbars::ToolbarPtr(new QLToolbar(tbb, owner));
170 }
171
172
173 QLToolbar::QLToolbar(ToolbarBackend::Toolbar const & tbb, LyXView & owner)
174         : owner_(dynamic_cast<QtView &>(owner)),
175           toolbar_(new QToolBar(qt_(tbb.gui_name), &owner_,
176                                 getPosition(tbb.flags)))
177 {
178         // give visual separation between adjacent toolbars
179         toolbar_->addSeparator();
180
181         ToolbarBackend::item_iterator it = tbb.items.begin();
182         ToolbarBackend::item_iterator end = tbb.items.end();
183         for (; it != end; ++it)
184                 add(it->first, it->second);
185 }
186
187
188 void QLToolbar::add(FuncRequest const & func, string const & tooltip)
189 {
190         switch (func.action) {
191         case ToolbarBackend::SEPARATOR:
192                 toolbar_->addSeparator();
193                 break;
194         case ToolbarBackend::LAYOUTS:
195                 layout_.reset(new QLayoutBox(toolbar_, owner_));
196                 break;
197         case ToolbarBackend::MINIBUFFER:
198                 owner_.addCommandBuffer(toolbar_);
199                 toolbar_->setHorizontalStretchable(true);
200                 break;
201         default: {
202                 if (owner_.getLyXFunc().getStatus(func).unknown())
203                         break;
204                 QPixmap p = QPixmap(toolbarbackend.getIcon(func).c_str());
205                 QToolButton * button =
206                         new QToolButton(p, toqstr(tooltip), "",
207                         this, SLOT(clicked()), toolbar_);
208
209                 map_[button] = func;
210                 break;
211         }
212         }
213 }
214
215
216 void QLToolbar::hide(bool)
217 {
218         toolbar_->hide();
219 }
220
221
222 void QLToolbar::show(bool)
223 {
224         toolbar_->show();
225 }
226
227
228 void QLToolbar::update()
229 {
230         ButtonMap::const_iterator p = map_.begin();
231         ButtonMap::const_iterator end = map_.end();
232
233         for (; p != end; ++p) {
234                 QToolButton * button = p->first;
235                 FuncRequest const & func = p->second;
236
237                 FuncStatus const status =
238                         owner_.getLyXFunc().getStatus(func);
239
240                 button->setToggleButton(true);
241                 button->setOn(status.onoff(true));
242                 button->setEnabled(status.enabled());
243         }
244 }
245
246
247 void QLToolbar::clicked()
248 {
249         QToolButton const * const_button =
250                 static_cast<QToolButton const *>(sender());
251         QToolButton  * button =
252                 const_cast<QToolButton *>(const_button);
253
254         ButtonMap::const_iterator it = map_.find(button);
255
256         if (it != map_.end())
257                 owner_.getLyXFunc().dispatch(it->second, true);
258         else
259                 lyxerr << "non existent tool button selected !" << endl;
260 }