00001 #include <QPixmap>
00002 #include <QImage>
00003 #include <QFrame>
00004 #include <QKeyEvent>
00005
00006 #include "virtualkeyboard_qt.h"
00007 #include "mythdialogs.h"
00008 #include "uitypes.h"
00009 #include "mythlogging.h"
00010 #include "mythcorecontext.h"
00011
00012 #include "mythfontproperties.h"
00013 #include "mythuihelper.h"
00014
00015 #define LOC QString("VirtualKeyboard: ")
00016
00017 VirtualKeyboardQt::VirtualKeyboardQt(MythMainWindow *parent,
00018 QWidget *parentEdit,
00019 const char *name,
00020 bool setsize)
00021 : MythThemedDialog(parent, name, setsize)
00022 {
00023 setFrameStyle(QFrame::Panel | QFrame::Raised);
00024 setLineWidth(1);
00025 m_parentEdit = parentEdit;
00026
00027 SwitchLayout(gCoreContext->GetLanguage());
00028 }
00029
00030 void VirtualKeyboardQt::SwitchLayout(const QString &lang)
00031 {
00032 if (!m_parentEdit)
00033 {
00034 LOG(VB_GENERAL, LOG_ERR, LOC + "No edit receiving output");
00035 reject();
00036 return;
00037 }
00038
00039 QString language = lang.toLower();
00040
00041 QString theme_file = QString("keyboard/%1_").arg(language);
00042
00043 if (!loadThemedWindow("keyboard", theme_file))
00044 {
00045 LOG(VB_GENERAL, LOG_WARNING, LOC +
00046 QString("Cannot find layout for '%1'").arg(language));
00047
00048
00049 if (!loadThemedWindow("keyboard", "keyboard/en_us_"))
00050 {
00051 LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot find layout for US English");
00052
00053 reject();
00054 return;
00055 }
00056 }
00057
00058
00059 LayerSet *container = getContainer("keyboard_container");
00060
00061 if (!container)
00062 {
00063 LOG(VB_GENERAL, LOG_ERR, LOC +
00064 "Cannot find the 'keyboard_container' in your theme");
00065
00066 reject();
00067 return;
00068 }
00069
00070 m_popupWidth = container->GetAreaRect().width();
00071 m_popupHeight = container->GetAreaRect().height();
00072 setFixedSize(QSize(m_popupWidth, m_popupHeight));
00073
00074 QWidget *pw = m_parentEdit;
00075 QWidget *tlw = pw->topLevelWidget();
00076 QRect pwg = pw->geometry();
00077 QRect tlwg = tlw->frameGeometry();
00078
00079 QPoint newpos;
00080
00081 PopupPositionQt preferredPos;
00082 if (m_parentEdit->inherits("MythLineEdit"))
00083 {
00084 MythLineEdit *par = (MythLineEdit *)m_parentEdit;
00085 preferredPos = par->getPopupPosition();
00086 }
00087 else if (m_parentEdit->inherits("MythRemoteLineEdit"))
00088 {
00089 MythRemoteLineEdit *par = (MythRemoteLineEdit *)m_parentEdit;
00090 preferredPos = par->getPopupPosition();
00091 }
00092 else if (m_parentEdit->inherits("MythComboBox"))
00093 {
00094 MythComboBox *par = (MythComboBox *)m_parentEdit;
00095 preferredPos = par->getPopupPosition();
00096 }
00097 else
00098 {
00099 preferredPos = VKQT_POSCENTERDIALOG;
00100 }
00101
00102 if (preferredPos == VKQT_POSBELOWEDIT)
00103 {
00104 if (pw->mapTo(tlw, QPoint(0,pwg.height() + m_popupHeight + 5)).y()
00105 < tlwg.height())
00106 {
00107 newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, pwg.height() + 5);
00108 }
00109 else
00110 {
00111 newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, - 5 - m_popupHeight);
00112 }
00113 }
00114 else if (preferredPos == VKQT_POSABOVEEDIT)
00115 {
00116 if (pw->mapTo(tlw, QPoint(0, - m_popupHeight - 5)).y()
00117 > 0)
00118 {
00119 newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, - 5 - m_popupHeight);
00120 }
00121 else
00122 {
00123 newpos = QPoint(pwg.width() / 2 - m_popupWidth / 2, pwg.height() + 5);
00124 }
00125 }
00126 else if (preferredPos == VKQT_POSTOPDIALOG)
00127 {
00128 newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2, 5);
00129 this->move(newpos);
00130 }
00131 else if (preferredPos == VKQT_POSBOTTOMDIALOG)
00132 {
00133 newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
00134 tlwg.height() - 5 - m_popupHeight);
00135 this->move(newpos);
00136 }
00137 else if (preferredPos == VKQT_POSCENTERDIALOG)
00138 {
00139 newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
00140 tlwg.height() / 2 - m_popupHeight / 2);
00141 this->move(newpos);
00142 }
00143
00144 if (preferredPos == VKQT_POSABOVEEDIT || preferredPos == VKQT_POSBELOWEDIT)
00145 {
00146 int delx = pw->mapTo(tlw,newpos).x() + m_popupWidth - tlwg.width() + 5;
00147 newpos = QPoint(newpos.x() - (delx > 0 ? delx : 0), newpos.y());
00148 delx = pw->mapTo(tlw, newpos).x();
00149 newpos = QPoint(newpos.x() - (delx < 0 ? delx : 0), newpos.y());
00150
00151 int xbase, width, ybase, height;
00152 float wmult, hmult;
00153 GetMythUI()->GetScreenSettings(xbase, width, wmult, ybase, height, hmult);
00154 newpos.setX(newpos.x() - xbase);
00155 newpos.setY(newpos.y() - ybase);
00156
00157 this->move( pw->mapToGlobal( newpos ) );
00158 }
00159
00160
00161 m_keyboard = getUIKeyboardType("keyboard");
00162 if (!m_keyboard)
00163 {
00164 LOG(VB_GENERAL, LOG_ERR, LOC +
00165 "Cannot find the UIKeyboardType in your theme");
00166
00167 reject();
00168 return;
00169 }
00170
00171 if (m_parentEdit->inherits("QComboBox"))
00172 {
00173 QComboBox *combo = (QComboBox *) m_parentEdit;
00174 m_keyboard->SetEdit(combo->lineEdit());
00175 }
00176 else
00177 m_keyboard->SetEdit(m_parentEdit);
00178
00179 m_keyboard->SetParentDialog(this);
00180 }
00181
00182 VirtualKeyboardQt::~VirtualKeyboardQt(void)
00183 {
00184 Teardown();
00185 }
00186
00187 void VirtualKeyboardQt::deleteLater(void)
00188 {
00189 Teardown();
00190 }
00191
00192 void VirtualKeyboardQt::Teardown(void)
00193 {
00194 m_keyboard = NULL;
00195 m_parentEdit = NULL;
00196 }
00197
00198 void VirtualKeyboardQt::Show(void)
00199 {
00200 grabKeyboard();
00201
00202 MythDialog::Show();
00203
00204 if (m_parentEdit)
00205 m_parentEdit->setFocus();
00206 }
00207
00208 void VirtualKeyboardQt::hide()
00209 {
00210 releaseKeyboard();
00211
00212 if (m_parentEdit)
00213 m_parentEdit->setFocus();
00214
00215 MythDialog::hide();
00216 }
00217
00218 void VirtualKeyboardQt::keyPressEvent(QKeyEvent *e)
00219 {
00220 bool handled = false;
00221 QStringList actions;
00222 handled = GetMythMainWindow()->TranslateKeyPress("qt", e, actions, false);
00223
00224 for (int i = 0; i < actions.size() && !handled; i++)
00225 {
00226 QString action = actions[i];
00227 handled = true;
00228 if (action == "ESCAPE")
00229 accept();
00230 else
00231 handled = false;
00232 }
00233
00234
00235 if (!handled && m_keyboard)
00236 m_keyboard->keyPressEvent(e);
00237 }
00238