]> git.lyx.org Git - lyx.git/blob - src/frontends/qt3/QBrowseBox.C
Extracted from r14281
[lyx.git] / src / frontends / qt3 / QBrowseBox.C
1 /**
2  * \file QBrowseBox.C
3  *
4  * Original file taken from klyx 0.10 sources:
5  *
6  * \author Kalle Dalheimer
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "QBrowseBox.h"
14
15 #include <qpixmap.h>
16 #include <qpainter.h>
17 #include <qapplication.h>
18 #include <qdrawutil.h>
19 #include <qstyle.h>
20
21 #include <cmath>
22
23
24 QBrowseBox::QBrowseBox(int rows, int cols, QWidget* parent, const char * name, WFlags f)
25         : QGridView(parent,name,f)
26 {
27         setNumRows(rows);
28         setNumCols(cols);
29
30         pixmaps_ = new QPixmap[rows * cols];
31
32         activecell_.setX(-1);
33         activecell_.setY(-1);
34
35         if (style().inherits("QWindowsStyle"))
36                 setFrameStyle(QFrame::WinPanel | QFrame::Raised);
37         else
38                 setFrameStyle(QFrame::Panel | QFrame::Raised);
39
40         setVScrollBarMode(QScrollView::AlwaysOff);
41         setHScrollBarMode(QScrollView::AlwaysOff);
42
43         viewport()->setFocusPolicy(QWidget::StrongFocus);
44         // setMouseTracking must be called after setFocusPolicy
45         viewport()->setMouseTracking(true);
46         inloop=false;
47
48 }
49
50
51 QBrowseBox::~QBrowseBox()
52 {
53         delete [] pixmaps_;
54 }
55
56
57 int QBrowseBox::coordsToIndex(int row, int col)
58 {
59         if (col < 0 || col > numCols() || row < 0 ||  row > numRows())
60                 qDebug("coordsToIndex: invalid coords (%d, %d)\n", row, col);
61         return row + col * numCols();
62 }
63
64
65 void QBrowseBox::insertItem(QPixmap pixmap, int row, int col)
66 {
67         pixmaps_[coordsToIndex(row, col)] = pixmap;
68 }
69
70
71 void QBrowseBox::insertItem(QPixmap pixmap)
72 {
73         int w = pixmap.width() / numCols();
74         int h = pixmap.height() / numRows();
75
76         for (int row = 0; row < numRows(); ++row) {
77                 for (int col = 0; col < numCols(); ++col) {
78                         QPixmap small(w,h);
79                         small.fill(backgroundColor());
80                         bitBlt(&small, 0, 0, &pixmap, col * w, row * h,
81                                 w, h, Qt::CopyROP, false);
82                         insertItem(small, row, col);
83                 }
84         }
85
86         setCellWidth(pixmap.width() / numCols());
87         setCellHeight(pixmap.height() / numRows());
88         setMinimumWidth(pixmap.width() + (numCols() + 1) * 1);
89         setMinimumHeight(pixmap.height() + (numRows() + 1) * 1);
90         resize(minimumSize());
91 }
92
93
94 QPixmap QBrowseBox::pixmap(int row, int col)
95 {
96         if (col < 0 || col >= numCols() || row < 0 || row >= numRows())
97                 return QPixmap();
98         return pixmaps_[coordsToIndex(row, col)];
99 }
100
101
102 int QBrowseBox::exec(const QPoint & pos)
103 {
104         return exec(pos.x(),pos.y());
105 }
106
107
108 int QBrowseBox::exec(const QWidget * trigger)
109 {
110         QPoint globalpos = trigger->parentWidget()->mapToGlobal( trigger->pos());
111         // is there enough space to put the box below the trigger?
112         if ( globalpos.y() + trigger->height()+height()+1<
113              QApplication::desktop()->height()) {
114                 // is there enough space to set the box left-justified with the trigger
115                 if (globalpos.x()+width()<QApplication::desktop()->width())
116                         return exec(globalpos.x(),
117                                     globalpos.y()+trigger->height()+1);
118                 else
119                         return exec(globalpos.x()-width()-1,
120                                     globalpos.y()+trigger->height()+1);
121         } else {
122                 if (globalpos.x()+width()<QApplication::desktop()->width())
123                         return exec(globalpos.x(),
124                                     globalpos.y()-height()-1);
125                 else
126                         return exec(globalpos.x()-width()-1,
127                                     globalpos.y()-height()-1);
128         }
129 }
130
131
132 int QBrowseBox::exec(int x,int y)
133 {
134         firstrelease_ = true;
135         move(x,y);
136         show();
137         repaint();
138         qApp->enter_loop();
139         inloop = true;
140
141         if (activecell_.x()!=-1 && activecell_.y()!=-1 )
142                 return coordsToIndex( activecell_.x(),activecell_.y());
143         else
144                 return -1;
145 }
146
147
148 void QBrowseBox::keyPressEvent(QKeyEvent * e)
149 {
150         switch(e->key()) {
151         case Key_Up:
152                 moveUp();
153                 break;
154         case Key_Down:
155                 moveDown();
156                 break;
157         case Key_Left:
158                 moveLeft();
159                 break;
160         case Key_Right:
161                 moveRight();
162                 break;
163         case Key_Return:
164                 // emit signal
165                 selected(activecell_.x(), activecell_.y());
166                 if ( isVisible() && parentWidget() &&
167                      parentWidget()->inherits("QPopupMenu") )
168                         parentWidget()->close();
169                 else
170                         close();
171                 break;
172         case Key_Escape:
173                 if (inloop)
174                         qApp->exit_loop();
175                 if ( isVisible() && parentWidget() &&
176                      parentWidget()->inherits("QPopupMenu") )
177                         parentWidget()->close();
178         default:
179                 e->ignore();
180         }
181 }
182
183
184 void QBrowseBox::contentsMouseReleaseEvent(QMouseEvent *)
185 {
186
187         if (firstrelease_)
188                 firstrelease_ = false;
189         else {
190                 selected( activecell_.x(), activecell_.y());
191                 if ( isVisible() && parentWidget() &&
192                      parentWidget()->inherits("QPopupMenu") )
193                         parentWidget()->close();
194         }
195 }
196
197
198 void QBrowseBox::closeEvent(QCloseEvent * e)
199 {
200         e->accept();
201         qApp->exit_loop();
202 }
203
204
205 void QBrowseBox::paintCell(QPainter * painter, int row, int col)
206 {
207         painter->setClipRect(cellGeometry(row, col));
208
209         int const index = coordsToIndex(row, col);
210
211         painter->drawPixmap(0, 0, pixmaps_[index]);
212
213         if (activecell_.x() == row && activecell_.y() == col) {
214                 qDrawShadeRect(painter, 0, 0, cellWidth(),
215                                cellHeight(), colorGroup(), false, 1);
216         } else {
217                 qDrawPlainRect(painter, 0, 0, cellWidth(),
218                                cellHeight(), colorGroup().background(), 1);
219         }
220
221         painter->setClipping(false);
222 }
223
224
225 void QBrowseBox::contentsMouseMoveEvent(QMouseEvent * e)
226 {
227         int x = e->pos().x();
228         int y = e->pos().y();
229
230         int cellx;
231         int celly;
232
233         if (x < 0 || y < 0 || x > width() || y > height()) {
234                 // outside the box
235                 cellx = -1;
236                 celly = -1;
237         } else {
238                 celly = (int)floor( ((double)x) / ((double)cellWidth()) );
239                 cellx = (int)floor( ((double)y) / ((double)cellHeight()) );
240         }
241
242         if (activecell_.x() != cellx || activecell_.y() != celly) {
243                 // mouse has been moved to another cell
244                 int oldactivecellx = activecell_.x();
245                 int oldactivecelly = activecell_.y();
246                 activecell_.setX(cellx);
247                 activecell_.setY(celly);
248                 // remove old highlighting
249                 updateCell(oldactivecellx, oldactivecelly);
250                 // set new highlighting
251                 updateCell(activecell_.x(), activecell_.y());
252         }
253 }
254
255
256 void QBrowseBox::moveLeft()
257 {
258         int const y = activecell_.y();
259
260         if (y>0)
261                 activecell_.setY(y - 1);
262         else if (parentWidget())
263                 QWidget::focusNextPrevChild(false);
264
265         updateCell(activecell_.x(), y);
266         updateCell(activecell_.x(), activecell_.y());
267 }
268
269
270 void QBrowseBox::moveRight()
271 {
272         int const y = activecell_.y();
273
274         if (y < numCols() - 1)
275                 activecell_.setY(y+1);
276
277         updateCell(activecell_.x(), y);
278         updateCell(activecell_.x(), activecell_.y());
279 }
280
281
282 void QBrowseBox::moveUp()
283 {
284         int const x = activecell_.x();
285
286         if (x > 0)
287                 activecell_.setX(x - 1);
288         else if (parentWidget())
289                 QWidget::focusNextPrevChild(false);
290
291         updateCell(x, activecell_.y());
292         updateCell(activecell_.x(), activecell_.y());
293 }
294
295
296 void QBrowseBox::moveDown()
297 {
298         int const x = activecell_.x();
299
300         if (x < numRows() - 1)
301                 activecell_.setX(x + 1);
302
303         updateCell(x, activecell_.y());
304         updateCell(activecell_.x(), activecell_.y());
305 }