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