MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
virtualkeyboard_qt.cpp
Go to the documentation of this file.
1 #include <QPixmap>
2 #include <QImage>
3 #include <QFrame>
4 #include <QKeyEvent>
5 
6 #include "virtualkeyboard_qt.h"
7 #include "mythdialogs.h"
8 #include "uitypes.h"
9 #include "mythlogging.h"
10 #include "mythcorecontext.h"
11 
12 #include "mythfontproperties.h"
13 #include "mythuihelper.h"
14 
15 #define LOC QString("VirtualKeyboard: ")
16 
18  QWidget *parentEdit,
19  const char *name,
20  bool setsize)
21  : MythThemedDialog(parent, name, setsize)
22 {
23  setFrameStyle(QFrame::Panel | QFrame::Raised);
24  setLineWidth(1);
25  m_parentEdit = parentEdit;
26 
28 }
29 
30 void VirtualKeyboardQt::SwitchLayout(const QString &lang)
31 {
32  if (!m_parentEdit)
33  {
34  LOG(VB_GENERAL, LOG_ERR, LOC + "No edit receiving output");
35  reject();
36  return;
37  }
38 
39  QString language = lang.toLower();
40 
41  QString theme_file = QString("keyboard/%1_").arg(language);
42 
43  if (!loadThemedWindow("keyboard", theme_file))
44  {
45  LOG(VB_GENERAL, LOG_WARNING, LOC +
46  QString("Cannot find layout for '%1'").arg(language));
47 
48  // cannot find layout so fallback to US English layout
49  if (!loadThemedWindow("keyboard", "keyboard/en_us_"))
50  {
51  LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot find layout for US English");
52 
53  reject();
54  return;
55  }
56  }
57 
58  // get dialog size from keyboard_container area
59  LayerSet *container = getContainer("keyboard_container");
60 
61  if (!container)
62  {
63  LOG(VB_GENERAL, LOG_ERR, LOC +
64  "Cannot find the 'keyboard_container' in your theme");
65 
66  reject();
67  return;
68  }
69 
70  m_popupWidth = container->GetAreaRect().width();
71  m_popupHeight = container->GetAreaRect().height();
72  setFixedSize(QSize(m_popupWidth, m_popupHeight));
73 
74  QWidget *pw = m_parentEdit;
75  QWidget *tlw = pw->topLevelWidget();
76  QRect pwg = pw->geometry();
77  QRect tlwg = tlw->frameGeometry();
78 
79  QPoint newpos;
80 
81  PopupPositionQt preferredPos;
82  if (m_parentEdit->inherits("MythLineEdit"))
83  {
85  preferredPos = par->getPopupPosition();
86  }
87  else if (m_parentEdit->inherits("MythRemoteLineEdit"))
88  {
90  preferredPos = par->getPopupPosition();
91  }
92  else if (m_parentEdit->inherits("MythComboBox"))
93  {
95  preferredPos = par->getPopupPosition();
96  }
97  else
98  {
99  preferredPos = VKQT_POSCENTERDIALOG;
100  }
101 
102  if (preferredPos == VKQT_POSBELOWEDIT)
103  {
104  if (pw->mapTo(tlw, QPoint(0,pwg.height() + m_popupHeight + 5)).y()
105  < tlwg.height())
106  {
107  newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, pwg.height() + 5);
108  }
109  else
110  {
111  newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, - 5 - m_popupHeight);
112  }
113  }
114  else if (preferredPos == VKQT_POSABOVEEDIT)
115  {
116  if (pw->mapTo(tlw, QPoint(0, - m_popupHeight - 5)).y()
117  > 0)
118  {
119  newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, - 5 - m_popupHeight);
120  }
121  else
122  {
123  newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, pwg.height() + 5);
124  }
125  }
126  else if (preferredPos == VKQT_POSTOPDIALOG)
127  {
128  newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2, 5);
129  this->move(newpos);
130  }
131  else if (preferredPos == VKQT_POSBOTTOMDIALOG)
132  {
133  newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
134  tlwg.height() - 5 - m_popupHeight);
135  this->move(newpos);
136  }
137  else if (preferredPos == VKQT_POSCENTERDIALOG)
138  {
139  newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
140  tlwg.height() / 2 - m_popupHeight / 2);
141  this->move(newpos);
142  }
143 
144  if (preferredPos == VKQT_POSABOVEEDIT || preferredPos == VKQT_POSBELOWEDIT)
145  {
146  int delx = pw->mapTo(tlw,newpos).x() + m_popupWidth - tlwg.width() + 5;
147  newpos = QPoint(newpos.x() - (delx > 0 ? delx : 0), newpos.y());
148  delx = pw->mapTo(tlw, newpos).x();
149  newpos = QPoint(newpos.x() - (delx < 0 ? delx : 0), newpos.y());
150 
151  int xbase, width, ybase, height;
152  float wmult, hmult;
153  GetMythUI()->GetScreenSettings(xbase, width, wmult, ybase, height, hmult);
154  newpos.setX(newpos.x() - xbase);
155  newpos.setY(newpos.y() - ybase);
156 
157  this->move( pw->mapToGlobal( newpos ) );
158  }
159 
160  // find the UIKeyboardType
161  m_keyboard = getUIKeyboardType("keyboard");
162  if (!m_keyboard)
163  {
164  LOG(VB_GENERAL, LOG_ERR, LOC +
165  "Cannot find the UIKeyboardType in your theme");
166 
167  reject();
168  return;
169  }
170 
171  if (m_parentEdit->inherits("QComboBox"))
172  {
173  QComboBox *combo = (QComboBox *) m_parentEdit;
174  m_keyboard->SetEdit(combo->lineEdit());
175  }
176  else
178 
180 }
181 
183 {
184  Teardown();
185 }
186 
188 {
189  Teardown();
190 }
191 
193 {
194  m_keyboard = NULL;
195  m_parentEdit = NULL;
196 }
197 
199 {
200  grabKeyboard();
201 
203 
204  if (m_parentEdit)
205  m_parentEdit->setFocus();
206 }
207 
209 {
210  releaseKeyboard();
211 
212  if (m_parentEdit)
213  m_parentEdit->setFocus();
214 
216 }
217 
219 {
220  bool handled = false;
221  QStringList actions;
222  handled = GetMythMainWindow()->TranslateKeyPress("qt", e, actions, false);
223 
224  for (int i = 0; i < actions.size() && !handled; i++)
225  {
226  QString action = actions[i];
227  handled = true;
228  if (action == "ESCAPE")
229  accept();
230  else
231  handled = false;
232  }
233 
234  //just pass all unhandled key events for the keyboard to handle
235  if (!handled && m_keyboard)
237 }
238