1 /*
2 * This file is part of Licq, an instant messaging client for UNIX.
3 * Copyright (C) 2000-2014 Licq developers <licq-dev@googlegroups.com>
4 *
5 * Licq is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Licq is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Licq; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "selectemoticon.h"
21
22 #include <math.h>
23
24 #include <QGridLayout>
25 #include <QKeyEvent>
26 #include <QMap>
27
28 #include "config/emoticons.h"
29
30 #include "helpers/support.h"
31
32 using namespace LicqQtGui;
33
EmoticonLabel(const QString & file,const QString & value,QWidget * parent)34 EmoticonLabel::EmoticonLabel(const QString& file, const QString& value, QWidget* parent)
35 : QPushButton(parent),
36 myValue(value)
37 {
38 QPixmap icon = QPixmap(file);
39 setIconSize(icon.size());
40 setIcon(icon);
41 setToolTip(value);
42 setFixedSize(icon.size() + QSize(10, 10));
43 setFlat(true);
44 }
45
mouseReleaseEvent(QMouseEvent *)46 void EmoticonLabel::mouseReleaseEvent(QMouseEvent* /* e */)
47 {
48 if (underMouse())
49 emit clicked(myValue);
50 }
51
keyPressEvent(QKeyEvent * e)52 void EmoticonLabel::keyPressEvent(QKeyEvent* e)
53 {
54 if (e->modifiers() != Qt::NoModifier)
55 return;
56
57 switch (e->key())
58 {
59 case Qt::Key_Return: // Fall through
60 case Qt::Key_Enter:
61 case Qt::Key_Space:
62 emit clicked(myValue);
63 break;
64
65 case Qt::Key_Up: // Fall through
66 case Qt::Key_Down:
67 emit move(this, e->key());
68 break;
69
70 default:
71 QPushButton::keyPressEvent(e);
72 break;
73 }
74 }
75
SelectEmoticon(QWidget * parent)76 SelectEmoticon::SelectEmoticon(QWidget* parent)
77 : QFrame(parent, Qt::Popup)
78 {
79 Support::setWidgetProps(this, "SelectEmoticon");
80 setAttribute(Qt::WA_DeleteOnClose, true);
81
82 setFrameShape(StyledPanel);
83
84 QMap<QString, QString> map = Emoticons::self()->emoticonsKeys();
85 QMap<QString, QString>::iterator iter;
86
87 int nCols = static_cast<int>(sqrt(map.size()));
88
89 grid = new QGridLayout(this);
90 grid->setContentsMargins(0, 0, 0, 0);
91 grid->setSpacing(0);
92
93 int x = 0, y = 0;
94 for (iter = map.begin(); iter != map.end(); ++iter)
95 {
96 EmoticonLabel* lbl = new EmoticonLabel(iter.key(), iter.value(), this);
97
98 connect(lbl, SIGNAL(clicked(const QString&)), SLOT(emoticonClicked(const QString&)));
99 connect(lbl, SIGNAL(move(EmoticonLabel*, int)), SLOT(moveFrom(EmoticonLabel*, int)));
100
101 grid->addWidget(lbl, y, x++);
102 grid->setAlignment(lbl, Qt::AlignCenter);
103
104 // Set the focus to the first item so we can use the keyboard to navigate
105 if (y == 0 && x == 1)
106 lbl->setFocus();
107
108 if (x == nCols)
109 {
110 x = 0;
111 y++;
112 }
113 }
114 }
115
emoticonClicked(const QString & value)116 void SelectEmoticon::emoticonClicked(const QString& value)
117 {
118 emit selected(value);
119 close();
120 }
121
moveFrom(EmoticonLabel * item,int key)122 void SelectEmoticon::moveFrom(EmoticonLabel* item, int key)
123 {
124 if (item == 0)
125 return;
126
127 int index = grid->indexOf(item);
128
129 switch (key)
130 {
131 case Qt::Key_Up:
132 index -= grid->columnCount();
133 if (index < 0)
134 index += grid->columnCount() * grid->rowCount();
135 while (grid->itemAt(index) == 0)
136 index -= grid->columnCount();
137 break;
138
139 case Qt::Key_Down:
140 index += grid->columnCount();
141 while (grid->itemAt(index) == 0)
142 if (index >= grid->columnCount() * grid->rowCount())
143 index -= grid->columnCount() * grid->rowCount();
144 else
145 index += grid->columnCount();
146 break;
147
148 default:
149 return;
150 }
151
152 grid->itemAt(index)->widget()->setFocus();
153 }
154