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