]> git.lyx.org Git - features.git/blob - src/frontends/qt2/QCommandBuffer.C
update ignore, and make sure to dist the lyx2lyx_version.py.in template file
[features.git] / src / frontends / qt2 / QCommandBuffer.C
1 /**
2  * \file QCommandBuffer.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 // Qt defines a macro 'signals' that clashes with a boost namespace.
14 // All is well if the namespace is visible first.
15 #include "QtView.h"
16
17 #include "QCommandBuffer.h"
18 #include "QCommandEdit.h"
19 #include "qt_helpers.h"
20
21 #include "controllers/ControlCommandBuffer.h"
22
23 #include "support/filetools.h"
24
25 #include <qlistbox.h>
26 #include <qlayout.h>
27 #include <qtooltip.h>
28 #include <qpushbutton.h>
29
30 using lyx::support::libFileSearch;
31
32 using std::vector;
33 using std::string;
34
35 namespace lyx {
36 namespace frontend {
37
38 namespace {
39
40 class QTempListBox : public QListBox {
41 public:
42         QTempListBox()
43                 : QListBox(0, 0,
44                            WType_Modal | WType_Popup | WDestructiveClose) {
45                 setHScrollBarMode(AlwaysOff);
46         }
47 protected:
48         void mouseReleaseEvent(QMouseEvent * e) {
49                 if (e->x() < 0 || e->y() < 0
50                     || e->x() > width() || e->y() > height()) {
51                         hide();
52                 } else {
53                         emit selected(currentText());
54                 }
55         }
56
57         void keyPressEvent(QKeyEvent * e) {
58                 if (e->key() == Key_Escape) {
59                         hide();
60                         return;
61                 }
62                 QListBox::keyPressEvent(e);
63         }
64 };
65
66 } // end of anon
67
68
69 QCommandBuffer::QCommandBuffer(QtView * view, QWidget * parent, ControlCommandBuffer & control)
70         : QWidget(parent), view_(view), controller_(control)
71 {
72         QPixmap qpup(toqstr(libFileSearch("images", "up", "xpm")));
73         QPixmap qpdown(toqstr(libFileSearch("images", "down", "xpm")));
74
75         QVBoxLayout * top = new QVBoxLayout(this);
76         QHBoxLayout * layout = new QHBoxLayout(0);
77
78         QPushButton * up = new QPushButton(qpup, "", this);
79         QToolTip::add(up, qt_("Previous command"));
80         connect(up, SIGNAL(clicked()), this, SLOT(up()));
81         QPushButton * down = new QPushButton(qpdown, "", this);
82         QToolTip::add(down, qt_("Next command"));
83         connect(down, SIGNAL(clicked()), this, SLOT(down()));
84
85         edit_ = new QCommandEdit(this);
86         edit_->setMinimumSize(edit_->sizeHint());
87         edit_->setFocusPolicy(ClickFocus);
88
89         connect(edit_, SIGNAL(escapePressed()), this, SLOT(cancel()));
90         connect(edit_, SIGNAL(returnPressed()), this, SLOT(dispatch()));
91         connect(edit_, SIGNAL(tabPressed()), this, SLOT(complete()));
92         connect(edit_, SIGNAL(upPressed()), this, SLOT(up()));
93         connect(edit_, SIGNAL(downPressed()), this, SLOT(down()));
94
95         layout->addWidget(up, 0);
96         layout->addWidget(down, 0);
97         layout->addWidget(edit_, 10);
98         top->addLayout(layout);
99 }
100
101
102
103 void QCommandBuffer::focus_command()
104 {
105         edit_->setFocus();
106 }
107
108
109 void QCommandBuffer::cancel()
110 {
111         view_->centralWidget()->setFocus();
112         edit_->setText("");
113 }
114
115
116 void QCommandBuffer::dispatch()
117 {
118         controller_.dispatch(fromqstr(edit_->text()));
119         view_->centralWidget()->setFocus();
120         edit_->setText("");
121         edit_->clearFocus();
122 }
123
124
125 void QCommandBuffer::complete()
126 {
127         string const input = fromqstr(edit_->text());
128         string new_input;
129         vector<string> comp = controller_.completions(input, new_input);
130
131         if (comp.empty() && new_input == input) {
132         //      show_info_suffix(qt_("[no match]"), input);
133                 return;
134         }
135
136         if (comp.empty()) {
137                 edit_->setText(toqstr(new_input));
138         //      show_info_suffix(("[only completion]"), new_input + ' ');
139                 return;
140         }
141
142         edit_->setText(toqstr(new_input));
143
144         QTempListBox * list = new QTempListBox;
145
146         // For some reason the scrollview's contents are larger
147         // than the number of actual items...
148         vector<string>::const_iterator cit = comp.begin();
149         vector<string>::const_iterator end = comp.end();
150         for (; cit != end; ++cit) {
151                 list->insertItem(toqstr(*cit));
152         }
153
154         // width() is not big enough by a few pixels. Qt Sucks.
155         list->setMinimumWidth(list->sizeHint().width() + 10);
156
157         list->resize(list->sizeHint());
158         QPoint pos(edit_->mapToGlobal(QPoint(0, 0)));
159
160         int y = std::max(0, pos.y() - list->height());
161
162         list->move(pos.x(), y);
163
164         connect(list, SIGNAL(selected(const QString &)),
165                 this, SLOT(complete_selected(const QString &)));
166
167         list->show();
168         list->setFocus();
169 }
170
171
172 void QCommandBuffer::complete_selected(QString const & str)
173 {
174         QWidget const * widget = static_cast<QWidget const *>(sender());
175         const_cast<QWidget *>(widget)->hide();
176         edit_->setText(str + ' ');
177         edit_->setFocus();
178 }
179
180
181 void QCommandBuffer::up()
182 {
183         string const input(fromqstr(edit_->text()));
184         string const h(controller_.historyUp());
185
186         if (h.empty()) {
187         //      show_info_suffix(qt_("[Beginning of history]"), input);
188         } else {
189                 edit_->setText(toqstr(h));
190         }
191 }
192
193
194 void QCommandBuffer::down()
195 {
196         string const input(fromqstr(edit_->text()));
197         string const h(controller_.historyDown());
198
199         if (h.empty()) {
200         //      show_info_suffix(qt_("[End of history]"), input);
201         } else {
202                 edit_->setText(toqstr(h));
203         }
204 }
205
206
207 #if 0
208 void XMiniBuffer::show_info_suffix(string const & suffix, string const & input)
209 {
210         stored_input_ = input;
211         info_suffix_shown_ = true;
212         set_input(input + ' ' + suffix);
213         suffix_timer_->start();
214 }
215
216
217 void XMiniBuffer::suffix_timeout()
218 {
219         info_suffix_shown_ = false;
220         set_input(stored_input_);
221 }
222
223 #endif
224
225 } // namespace frontend
226 } // namespace lyx