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