00001 #include <qstyle.h>
00002 #include <qpainter.h>
00003 #include <qcursor.h>
00004 #include <qapplication.h>
00005 #include <qvbox.h>
00006 #include <qlayout.h>
00007
00008 #include <iostream>
00009
00010 using namespace std;
00011
00012 #include "mythwidgets.h"
00013 #include "mythcontext.h"
00014 #include "util.h"
00015 #include "mythdialogs.h"
00016 #include "virtualkeyboard.h"
00017 #include "libmythui/mythmainwindow.h"
00018
00019 typedef VirtualKeyboard* QWidgetP;
00020 static void qt_delete(QWidgetP &widget)
00021 {
00022 if (widget)
00023 {
00024 widget->disconnect();
00025 widget->hide();
00026 widget->deleteLater();
00027 widget = NULL;
00028 }
00029 }
00030
00031 MythComboBox::MythComboBox(bool rw, QWidget *parent, const char *name) :
00032 QComboBox(rw, parent, name),
00033 popup(NULL), helptext(QString::null), AcceptOnSelect(false),
00034 useVirtualKeyboard(true), allowVirtualKeyboard(rw),
00035 popupPosition(VK_POSBELOWEDIT), step(1)
00036 {
00037 useVirtualKeyboard = gContext->GetNumSetting("UseVirtualKeyboard", 1);
00038 }
00039
00040 MythComboBox::~MythComboBox()
00041 {
00042 Teardown();
00043 }
00044
00045 void MythComboBox::deleteLater(void)
00046 {
00047 Teardown();
00048 QComboBox::deleteLater();
00049 }
00050
00051 void MythComboBox::Teardown(void)
00052 {
00053 qt_delete(popup);
00054 }
00055
00056 void MythComboBox::setHelpText(const QString &help)
00057 {
00058 bool changed = helptext != help;
00059 helptext = QDeepCopy<QString>(help);
00060 if (hasFocus() && changed)
00061 emit changeHelpText(QDeepCopy<QString>(help));
00062 }
00063
00064 void MythComboBox::popupVirtualKeyboard(void)
00065 {
00066 qt_delete(popup);
00067
00068 popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
00069 gContext->GetMainWindow()->detach(popup);
00070 popup->exec();
00071
00072 qt_delete(popup);
00073 }
00074
00075
00076 void MythComboBox::keyPressEvent(QKeyEvent *e)
00077 {
00078 bool handled = false;
00079 QStringList actions;
00080 if ((!popup || !popup->isShown()) &&
00081 (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, !allowVirtualKeyboard)))
00082 {
00083 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00084 {
00085 QString action = actions[i];
00086 handled = true;
00087
00088 if (action == "UP")
00089 focusNextPrevChild(false);
00090 else if (action == "DOWN")
00091 focusNextPrevChild(true);
00092 else if (action == "LEFT")
00093 {
00094 if (currentItem() == 0)
00095 setCurrentItem(count()-1);
00096 else if (count() > 0)
00097 setCurrentItem((currentItem() - 1) % count());
00098 }
00099 else if (action == "RIGHT")
00100 {
00101 if (count() > 0)
00102 setCurrentItem((currentItem() + 1) % count());
00103 }
00104 else if (action == "PAGEDOWN")
00105 {
00106 if (currentItem() == 0)
00107 setCurrentItem(count() - (step % count()));
00108 else if (count() > 0)
00109 setCurrentItem(
00110 (currentItem() + count() - (step % count())) % count());
00111 }
00112 else if (action == "PAGEUP")
00113 {
00114 if (count() > 0)
00115 setCurrentItem(
00116 (currentItem() + (step % count())) % count());
00117 }
00118 else if (action == "SELECT" && AcceptOnSelect)
00119 emit accepted(currentItem());
00120 else if (action == "SELECT" &&
00121 (e->text().isEmpty() ||
00122 (e->key() == Qt::Key_Enter) ||
00123 (e->key() == Qt::Key_Return) ||
00124 (e->key() == Qt::Key_Space)))
00125 {
00126 if (useVirtualKeyboard && allowVirtualKeyboard)
00127 popupVirtualKeyboard();
00128 else
00129 handled = true;
00130 }
00131
00132 else
00133 handled = false;
00134 }
00135 }
00136
00137 if (!handled)
00138 {
00139 if (editable())
00140 QComboBox::keyPressEvent(e);
00141 else
00142 e->ignore();
00143 }
00144 }
00145
00146 void MythComboBox::focusInEvent(QFocusEvent *e)
00147 {
00148 emit changeHelpText(helptext);
00149 emit gotFocus();
00150
00151 QColor highlight = colorGroup().highlight();
00152
00153 this->setPaletteBackgroundColor(highlight);
00154
00155 if (lineEdit())
00156 lineEdit()->setPaletteBackgroundColor(highlight);
00157
00158 QComboBox::focusInEvent(e);
00159 }
00160
00161 void MythComboBox::focusOutEvent(QFocusEvent *e)
00162 {
00163 this->unsetPalette();
00164
00165 if (lineEdit())
00166 {
00167 lineEdit()->unsetPalette();
00168
00169
00170 QString curText = currentText();
00171 int i;
00172 bool foundItem = false;
00173
00174 for(i = 0; i < count(); i++)
00175 if (curText == text(i))
00176 foundItem = true;
00177
00178 if ( !foundItem )
00179 {
00180 insertItem(curText);
00181 setCurrentItem(count()-1);
00182 }
00183 }
00184
00185 QComboBox::focusOutEvent(e);
00186 }
00187
00188 void MythCheckBox::keyPressEvent(QKeyEvent* e)
00189 {
00190 bool handled = false;
00191 QStringList actions;
00192 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00193 {
00194 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00195 {
00196 QString action = actions[i];
00197 handled = true;
00198
00199 if (action == "UP")
00200 focusNextPrevChild(false);
00201 else if (action == "DOWN")
00202 focusNextPrevChild(true);
00203 else if (action == "LEFT" || action == "RIGHT" || action == "SELECT")
00204 toggle();
00205 else
00206 handled = false;
00207 }
00208 }
00209
00210 if (!handled)
00211 e->ignore();
00212 }
00213
00214 void MythCheckBox::setHelpText(const QString &help)
00215 {
00216 bool changed = helptext != help;
00217 helptext = QDeepCopy<QString>(help);
00218 if (hasFocus() && changed)
00219 emit changeHelpText(QDeepCopy<QString>(help));
00220 }
00221
00222 void MythCheckBox::focusInEvent(QFocusEvent *e)
00223 {
00224 emit changeHelpText(helptext);
00225
00226 QColor highlight = colorGroup().highlight();
00227
00228 this->setPaletteBackgroundColor(highlight);
00229 QCheckBox::focusInEvent(e);
00230 }
00231
00232 void MythCheckBox::focusOutEvent(QFocusEvent *e)
00233 {
00234 this->unsetPalette();
00235 QCheckBox::focusOutEvent(e);
00236 }
00237
00238 void MythRadioButton::keyPressEvent(QKeyEvent* e)
00239 {
00240 bool handled = false;
00241 QStringList actions;
00242 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00243 {
00244 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00245 {
00246 QString action = actions[i];
00247 handled = true;
00248
00249 if (action == "UP")
00250 focusNextPrevChild(false);
00251 else if (action == "DOWN")
00252 focusNextPrevChild(true);
00253 else if (action == "LEFT" || action == "RIGHT")
00254 toggle();
00255 else
00256 handled = false;
00257 }
00258 }
00259
00260 if (!handled)
00261 e->ignore();
00262 }
00263
00264 void MythRadioButton::setHelpText(const QString &help)
00265 {
00266 bool changed = helptext != help;
00267 helptext = QDeepCopy<QString>(help);
00268 if (hasFocus() && changed)
00269 emit changeHelpText(QDeepCopy<QString>(help));
00270 }
00271
00272 void MythRadioButton::focusInEvent(QFocusEvent *e)
00273 {
00274 emit changeHelpText(helptext);
00275
00276 QColor highlight = colorGroup().highlight();
00277
00278 this->setPaletteBackgroundColor(highlight);
00279 QRadioButton::focusInEvent(e);
00280 }
00281
00282 void MythRadioButton::focusOutEvent(QFocusEvent *e)
00283 {
00284 this->unsetPalette();
00285 QRadioButton::focusOutEvent(e);
00286 }
00287
00288 bool MythSpinBox::eventFilter(QObject* o, QEvent* e)
00289 {
00290 (void)o;
00291
00292 if (e->type() == QEvent::FocusIn)
00293 {
00294 QColor highlight = colorGroup().highlight();
00295 editor()->setPaletteBackgroundColor(highlight);
00296 emit(changeHelpText(helptext));
00297 }
00298 else if (e->type() == QEvent::FocusOut)
00299 {
00300 editor()->unsetPalette();
00301 }
00302
00303 if (e->type() != QEvent::KeyPress)
00304 return FALSE;
00305
00306 bool handled = false;
00307 QStringList actions;
00308 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
00309 actions))
00310 {
00311 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00312 {
00313 QString action = actions[i];
00314 handled = true;
00315
00316 if (action == "UP")
00317 focusNextPrevChild(false);
00318 else if (action == "DOWN")
00319 focusNextPrevChild(true);
00320 else if (action == "LEFT")
00321 {
00322 if (singlestep)
00323 setValue(value() - 1);
00324 else
00325 stepDown();
00326 }
00327 else if (action == "RIGHT")
00328 {
00329 if (singlestep)
00330 setValue(value() + 1);
00331 else
00332 stepUp();
00333 }
00334 else if (action == "PAGEUP")
00335 stepDown();
00336 else if (action == "PAGEDOWN")
00337 stepUp();
00338 else if (action == "SELECT")
00339 handled = true;
00340 else if (action == "ESCAPE")
00341 return FALSE;
00342 else
00343 handled = false;
00344 }
00345 }
00346
00347 return TRUE;
00348 }
00349
00350 void MythSpinBox::setHelpText(const QString &help)
00351 {
00352 bool changed = helptext != help;
00353 helptext = QDeepCopy<QString>(help);
00354 if (hasFocus() && changed)
00355 emit changeHelpText(QDeepCopy<QString>(help));
00356 }
00357
00358 void MythSpinBox::focusInEvent(QFocusEvent *e)
00359 {
00360 emit changeHelpText(helptext);
00361
00362 QColor highlight = colorGroup().highlight();
00363
00364 this->setPaletteBackgroundColor(highlight);
00365 QSpinBox::focusInEvent(e);
00366 }
00367
00368 void MythSpinBox::focusOutEvent(QFocusEvent *e)
00369 {
00370 this->unsetPalette();
00371 QSpinBox::focusOutEvent(e);
00372 }
00373
00374 void MythSlider::keyPressEvent(QKeyEvent* e)
00375 {
00376 bool handled = false;
00377 QStringList actions;
00378 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00379 {
00380 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00381 {
00382 QString action = actions[i];
00383 handled = true;
00384
00385 if (action == "UP")
00386 focusNextPrevChild(false);
00387 else if (action == "DOWN")
00388 focusNextPrevChild(true);
00389 else if (action == "LEFT")
00390 setValue(value() - lineStep());
00391 else if (action == "RIGHT")
00392 setValue(value() + lineStep());
00393 else if (action == "SELECT")
00394 handled = true;
00395 else
00396 handled = false;
00397 }
00398 }
00399
00400 if (!handled)
00401 QSlider::keyPressEvent(e);
00402 }
00403
00404 void MythSlider::setHelpText(const QString &help)
00405 {
00406 bool changed = helptext != help;
00407 helptext = QDeepCopy<QString>(help);
00408 if (hasFocus() && changed)
00409 emit changeHelpText(QDeepCopy<QString>(help));
00410 }
00411
00412 void MythSlider::focusInEvent(QFocusEvent *e)
00413 {
00414 emit changeHelpText(helptext);
00415
00416 QColor highlight = colorGroup().highlight();
00417
00418 this->setPaletteBackgroundColor(highlight);
00419 QSlider::focusInEvent(e);
00420 }
00421
00422 void MythSlider::focusOutEvent(QFocusEvent *e)
00423 {
00424 this->unsetPalette();
00425 QSlider::focusOutEvent(e);
00426 }
00427
00428 MythLineEdit::MythLineEdit(QWidget *parent, const char* widgetName) :
00429 QLineEdit(parent, widgetName),
00430 popup(NULL), helptext(QString::null), rw(true),
00431 useVirtualKeyboard(true),
00432 allowVirtualKeyboard(true),
00433 popupPosition(VK_POSBELOWEDIT)
00434 {
00435 useVirtualKeyboard = gContext->GetNumSetting("UseVirtualKeyboard", 1);
00436 }
00437
00438 MythLineEdit::MythLineEdit(
00439 const QString &contents, QWidget *parent, const char* widgetName) :
00440 QLineEdit(contents, parent, widgetName),
00441 popup(NULL), helptext(QString::null), rw(true),
00442 useVirtualKeyboard(true),
00443 allowVirtualKeyboard(true),
00444 popupPosition(VK_POSBELOWEDIT)
00445 {
00446 useVirtualKeyboard = gContext->GetNumSetting("UseVirtualKeyboard", 1);
00447 }
00448
00449 MythLineEdit::~MythLineEdit()
00450 {
00451 Teardown();
00452 }
00453
00454 void MythLineEdit::deleteLater(void)
00455 {
00456 Teardown();
00457 QLineEdit::deleteLater();
00458 }
00459
00460 void MythLineEdit::Teardown(void)
00461 {
00462 qt_delete(popup);
00463 }
00464
00465 void MythLineEdit::popupVirtualKeyboard(void)
00466 {
00467 qt_delete(popup);
00468
00469 popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
00470 gContext->GetMainWindow()->detach(popup);
00471 popup->exec();
00472
00473 qt_delete(popup);
00474 }
00475
00476 void MythLineEdit::keyPressEvent(QKeyEvent *e)
00477 {
00478 bool handled = false;
00479 QStringList actions;
00480 if ((!popup || !popup->isShown()) &&
00481 gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
00482 {
00483 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00484 {
00485 QString action = actions[i];
00486 handled = true;
00487
00488 if (action == "UP")
00489 focusNextPrevChild(false);
00490 else if (action == "DOWN")
00491 focusNextPrevChild(true);
00492 else if (action == "SELECT" &&
00493 (e->text().isEmpty() ||
00494 (e->key() == Qt::Key_Enter) ||
00495 (e->key() == Qt::Key_Return)))
00496 {
00497 if (useVirtualKeyboard && allowVirtualKeyboard && rw)
00498 popupVirtualKeyboard();
00499 else
00500 handled = false;
00501 }
00502 else if (action == "SELECT" && e->text().isEmpty() )
00503 e->ignore();
00504 else
00505 handled = false;
00506 }
00507 }
00508
00509 if (!handled)
00510 if (rw || e->key() == Key_Escape || e->key() == Key_Left
00511 || e->key() == Key_Return || e->key() == Key_Right)
00512 QLineEdit::keyPressEvent(e);
00513 }
00514
00515 void MythLineEdit::setText(const QString &text)
00516 {
00517
00518
00519
00520
00521 int pos = cursorPosition();
00522 QLineEdit::setText(QDeepCopy<QString>(text));
00523 setCursorPosition(pos);
00524 }
00525
00526 QString MythLineEdit::text(void)
00527 {
00528 return QDeepCopy<QString>(QLineEdit::text());
00529 }
00530
00531 void MythLineEdit::setHelpText(const QString &help)
00532 {
00533 bool changed = helptext != help;
00534 helptext = QDeepCopy<QString>(help);
00535 if (hasFocus() && changed)
00536 emit changeHelpText(QDeepCopy<QString>(help));
00537 }
00538
00539 void MythLineEdit::focusInEvent(QFocusEvent *e)
00540 {
00541 emit changeHelpText(helptext);
00542
00543 QColor highlight = colorGroup().highlight();
00544
00545 this->setPaletteBackgroundColor(highlight);
00546 QLineEdit::focusInEvent(e);
00547 }
00548
00549 void MythLineEdit::focusOutEvent(QFocusEvent *e)
00550 {
00551 this->unsetPalette();
00552 if (popup && popup->isShown() && !popup->hasFocus())
00553 popup->hide();
00554 QLineEdit::focusOutEvent(e);
00555 }
00556
00557 void MythLineEdit::hideEvent(QHideEvent *e)
00558 {
00559 if (popup && popup->isShown())
00560 popup->hide();
00561 QLineEdit::hideEvent(e);
00562 }
00563
00564 void MythLineEdit::mouseDoubleClickEvent(QMouseEvent *e)
00565 {
00566 QLineEdit::mouseDoubleClickEvent(e);
00567 }
00568
00569 MythRemoteLineEdit::MythRemoteLineEdit(QWidget * parent, const char * name)
00570 : QTextEdit(parent, name)
00571 {
00572 my_font = NULL;
00573 m_lines = 1;
00574 this->Init();
00575 }
00576
00577 MythRemoteLineEdit::MythRemoteLineEdit(const QString & contents,
00578 QWidget * parent, const char * name)
00579 : QTextEdit(parent, name)
00580 {
00581 my_font = NULL;
00582 m_lines = 1;
00583 this->Init();
00584 setText(contents);
00585 }
00586
00587 MythRemoteLineEdit::MythRemoteLineEdit(QFont *a_font, QWidget * parent,
00588 const char * name)
00589 : QTextEdit(parent, name)
00590 {
00591 my_font = a_font;
00592 m_lines = 1;
00593 this->Init();
00594 }
00595
00596 MythRemoteLineEdit::MythRemoteLineEdit(int lines, QWidget * parent,
00597 const char * name)
00598 : QTextEdit(parent, name)
00599 {
00600 my_font = NULL;
00601 m_lines = lines;
00602 this->Init();
00603 }
00604
00605 void MythRemoteLineEdit::Init()
00606 {
00607
00608 cycle_timer = new QTimer();
00609 shift = false;
00610 active_cycle = false;
00611 current_choice = "";
00612 current_set = "";
00613
00614
00615
00616
00617
00618
00619 setTextFormat(Qt::PlainText);
00620
00621 cycle_time = 3000;
00622
00623 pre_cycle_text_upto = "";
00624 pre_cycle_text_from = "";
00625 pre_cycle_para = 0;
00626 pre_cycle_pos = 0;
00627
00628 col_unselected.setRgb(100, 100, 100);
00629 col_selected.setRgb(0, 255, 255);
00630 col_special.setRgb(255, 0, 0);
00631
00632 assignHexColors();
00633
00634
00635 setWordWrap(QTextEdit::NoWrap);
00636 QScrollView::setVScrollBarMode(QScrollView::AlwaysOff);
00637 QScrollView::setHScrollBarMode(QScrollView::AlwaysOff);
00638
00639 if (my_font)
00640 setFont(*my_font);
00641
00642 QFontMetrics fontsize(font());
00643
00644 setMinimumHeight(fontsize.height() * 5 / 4);
00645 setMaximumHeight(fontsize.height() * m_lines * 5 / 4);
00646
00647 connect(cycle_timer, SIGNAL(timeout()), this, SLOT(endCycle()));
00648
00649 popup = NULL;
00650 useVirtualKeyboard = gContext->GetNumSetting("UseVirtualKeyboard", 1);
00651 popupPosition = VK_POSBELOWEDIT;
00652 }
00653
00654 void MythRemoteLineEdit::startCycle(QString current_choice, QString set)
00655 {
00656 int end_paragraph;
00657 int end_position;
00658 int dummy;
00659 int dummy_two;
00660
00661 if (active_cycle)
00662 {
00663 cerr << "libmyth: MythRemoteLineEdit was asked to start a cycle when a cycle was already active." << endl;
00664 }
00665 else
00666 {
00667 cycle_timer->start(cycle_time, true);
00668 active_cycle = true;
00669
00670
00671
00672 getCursorPosition(&pre_cycle_para, &pre_cycle_pos);
00673 selectAll(true);
00674 getSelection(&dummy, &dummy_two, &end_paragraph, &end_position);
00675 setSelection(pre_cycle_para, pre_cycle_pos, end_paragraph, end_position, 0);
00676 pre_cycle_text_from = selectedText();
00677 setSelection(0, 0, pre_cycle_para, pre_cycle_pos, 0);
00678 pre_cycle_text_upto = selectedText();
00679 selectAll(false);
00680 setCursorPosition(pre_cycle_para, pre_cycle_pos);
00681 updateCycle(current_choice, set);
00682 }
00683 }
00684
00685 void MythRemoteLineEdit::setCharacterColors(QColor unselected, QColor selected,
00686 QColor special)
00687 {
00688 col_unselected = unselected;
00689 col_selected = selected;
00690 col_special = special;
00691 assignHexColors();
00692 }
00693
00694 void MythRemoteLineEdit::updateCycle(QString current_choice, QString set)
00695 {
00696 int index;
00697 QString aString, bString;
00698
00699
00700
00701
00702
00703
00704
00705 if (shift)
00706 {
00707 set = set.upper();
00708 current_choice = current_choice.upper();
00709 }
00710
00711 bString = "<B>";
00712 if (current_choice == "_" || current_choice == "X")
00713 {
00714 bString += "<FONT COLOR=\"#";
00715 bString += hex_special;
00716 bString += "\">";
00717 bString += current_choice;
00718 bString += "</FONT>";
00719 }
00720 else
00721 {
00722 bString += "<FONT COLOR=\"#";
00723 bString += hex_selected;
00724 bString += "\">";
00725 bString += current_choice;
00726 bString += "</FONT>";
00727 }
00728 bString += "</B>";
00729
00730 index = set.find(current_choice);
00731 int length = set.length();
00732 if (index < 0 || index > length)
00733 {
00734 cerr << "libmyth: MythRemoteLineEdit passed a choice of \"" << current_choice << "\" which is not in set \"" << set << "\"" << endl;
00735 setText("????");
00736 return;
00737 }
00738 else
00739 {
00740 set.replace(index, current_choice.length(), bString);
00741 }
00742
00743 QString esc_upto = pre_cycle_text_upto;
00744 QString esc_from = pre_cycle_text_from;
00745
00746 esc_upto.replace("<", "<").replace(">", ">").replace("\n", "<br>");
00747 esc_from.replace("<", "<").replace(">", ">").replace("\n", "<br>");
00748
00749 aString = esc_upto;
00750 aString += "<FONT COLOR=\"#";
00751 aString += hex_unselected;
00752 aString += "\">[";
00753 aString += set;
00754 aString += "]</FONT>";
00755 aString += esc_from;
00756 setTextFormat(Qt::RichText);
00757 setText(aString);
00758 setCursorPosition(pre_cycle_para, pre_cycle_pos + set.length());
00759 update();
00760 setCursorPosition(pre_cycle_para, pre_cycle_pos);
00761
00762
00763
00764
00765
00766 if (current_choice == "X" && pre_cycle_pos > 0)
00767 {
00768 setSelection(pre_cycle_para, pre_cycle_pos - 1, pre_cycle_para, pre_cycle_pos, 0);
00769 }
00770 }
00771
00772 void MythRemoteLineEdit::assignHexColors()
00773 {
00774 char text[1024];
00775
00776 sprintf(text, "%.2X%.2X%.2X", col_unselected.red(), col_unselected.green(), col_unselected.blue());
00777 hex_unselected = text;
00778
00779 sprintf(text, "%.2X%.2X%.2X", col_selected.red(), col_selected.green(), col_selected.blue());
00780 hex_selected = text;
00781
00782 sprintf(text, "%.2X%.2X%.2X", col_special.red(), col_special.green(), col_special.blue());
00783 hex_special = text;
00784 }
00785
00786 void MythRemoteLineEdit::endCycle()
00787 {
00788 QString aString;
00789
00790 if (active_cycle)
00791 {
00792
00793
00794 if (current_choice == "_")
00795 {
00796 aString = pre_cycle_text_upto;
00797 aString += " ";
00798 aString += pre_cycle_text_from;
00799 }
00800 else if (current_choice == "X")
00801 {
00802
00803
00804
00805
00806 if (pre_cycle_text_upto.length() > 0)
00807 {
00808 aString = pre_cycle_text_upto.left(pre_cycle_text_upto.length() - 1);
00809 }
00810 else
00811 {
00812 aString = "";
00813 }
00814 aString += pre_cycle_text_from;
00815 pre_cycle_pos--;
00816 }
00817 else if (shift)
00818 {
00819 aString = pre_cycle_text_upto;
00820 aString += current_choice.upper();
00821 aString += pre_cycle_text_from;
00822 }
00823 else
00824 {
00825 aString = pre_cycle_text_upto;
00826 aString += current_choice;
00827 aString += pre_cycle_text_from;
00828 }
00829
00830 setTextFormat(Qt::PlainText);
00831 setText(aString);
00832 setCursorPosition(pre_cycle_para, pre_cycle_pos + 1);
00833 active_cycle = false;
00834 current_choice = "";
00835 current_set = "";
00836 }
00837 emit(textChanged(this->text()));
00838 }
00839
00840 void MythRemoteLineEdit::setText(const QString& text)
00841 {
00842 int para, pos;
00843
00844
00845
00846
00847 getCursorPosition(¶, &pos);
00848 QTextEdit::setText(QDeepCopy<QString>(text));
00849 setCursorPosition(para, pos);
00850 }
00851
00852 QString MythRemoteLineEdit::text(void)
00853 {
00854 return QDeepCopy<QString>(QTextEdit::text());
00855 }
00856
00857 void MythRemoteLineEdit::keyPressEvent(QKeyEvent *e)
00858 {
00859 bool handled = false;
00860 QStringList actions;
00861
00862 if ((!popup || !popup->isShown()) &&
00863 gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
00864 {
00865 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00866 {
00867 QString action = actions[i];
00868 handled = true;
00869
00870 if (action == "UP")
00871 {
00872 endCycle();
00873
00874
00875
00876
00877 QWidget::focusNextPrevChild(false);
00878 emit tryingToLooseFocus(false);
00879 }
00880 else if (action == "DOWN")
00881 {
00882 endCycle();
00883 QWidget::focusNextPrevChild(true);
00884 emit tryingToLooseFocus(true);
00885 }
00886 else if ((action == "SELECT") &&
00887 (!active_cycle) &&
00888 ((e->text().isEmpty()) ||
00889 (e->key() == Qt::Key_Enter) ||
00890 (e->key() == Qt::Key_Return)))
00891 {
00892 if (useVirtualKeyboard)
00893 popupVirtualKeyboard();
00894 }
00895 else
00896 handled = false;
00897 }
00898 }
00899
00900 if (handled)
00901 return;
00902
00903 if (popup && popup->isShown())
00904 {
00905 endCycle();
00906 QTextEdit::keyPressEvent(e);
00907 emit textChanged(this->text());
00908 return;
00909 }
00910
00911 switch (e->key())
00912 {
00913 case Key_Enter:
00914 case Key_Return:
00915 handled = true;
00916 endCycle();
00917 e->ignore();
00918 break;
00919
00920
00921
00922 case Key_Space:
00923 if (active_cycle)
00924 {
00925 handled = true;
00926 endCycle();
00927 e->ignore();
00928 }
00929 break;
00930
00931
00932
00933
00934 case Key_1:
00935 cycleKeys("_X%-/.?()1");
00936 handled = true;
00937 break;
00938
00939 case Key_2:
00940 cycleKeys("abc2");
00941 handled = true;
00942 break;
00943
00944 case Key_3:
00945 cycleKeys("def3");
00946 handled = true;
00947 break;
00948
00949 case Key_4:
00950 cycleKeys("ghi4");
00951 handled = true;
00952 break;
00953
00954 case Key_5:
00955 cycleKeys("jkl5");
00956 handled = true;
00957 break;
00958
00959 case Key_6:
00960 cycleKeys("mno6");
00961 handled = true;
00962 break;
00963
00964 case Key_7:
00965 cycleKeys("pqrs7");
00966 handled = true;
00967 break;
00968
00969 case Key_8:
00970 cycleKeys("tuv8");
00971 handled = true;
00972 break;
00973
00974 case Key_9:
00975 cycleKeys("wxyz90");
00976 handled = true;
00977 break;
00978
00979 case Key_0:
00980 toggleShift();
00981 handled = true;
00982 break;
00983 }
00984
00985 if (!handled)
00986 {
00987 endCycle();
00988 QTextEdit::keyPressEvent(e);
00989 emit textChanged(this->text());
00990 }
00991 }
00992
00993 void MythRemoteLineEdit::setCycleTime(float desired_interval)
00994 {
00995 if (desired_interval < 0.5 || desired_interval > 10.0)
00996 {
00997 cerr << "libmyth: Did not accept key cycle interval of " << desired_interval << " seconds" << endl;
00998 }
00999 else
01000 {
01001 cycle_time = (int) (desired_interval * 1000.0);
01002 }
01003 }
01004
01005 void MythRemoteLineEdit::cycleKeys(QString cycle_list)
01006 {
01007 int index;
01008
01009 if (active_cycle)
01010 {
01011 if (cycle_list == current_set)
01012 {
01013
01014 cycle_timer->changeInterval(cycle_time);
01015 index = current_set.find(current_choice);
01016 int length = current_set.length();
01017 if (index + 1 >= length)
01018 {
01019 index = -1;
01020 }
01021 current_choice = current_set.mid(index + 1, 1);
01022 updateCycle(current_choice, current_set);
01023 }
01024 else
01025 {
01026
01027
01028 endCycle();
01029 current_choice = cycle_list.left(1);
01030 current_set = cycle_list;
01031 cycle_timer->changeInterval(cycle_time);
01032 startCycle(current_choice, current_set);
01033 }
01034 }
01035 else
01036 {
01037
01038 current_choice = cycle_list.left(1);
01039 current_set = cycle_list;
01040 startCycle(current_choice, current_set);
01041 }
01042 }
01043
01044 void MythRemoteLineEdit::toggleShift()
01045 {
01046
01047
01048
01049 QString temp_choice = current_choice;
01050 QString temp_set = current_set;
01051
01052 if (shift)
01053 {
01054 shift = false;
01055 }
01056 else
01057 {
01058 shift = true;
01059 temp_choice = current_choice.upper();
01060 temp_set = current_set.upper();
01061 }
01062 if (active_cycle)
01063 {
01064 updateCycle(temp_choice, temp_set);
01065 }
01066 }
01067
01068 void MythRemoteLineEdit::setHelpText(const QString &help)
01069 {
01070 bool changed = helptext != help;
01071 helptext = QDeepCopy<QString>(help);
01072 if (hasFocus() && changed)
01073 emit changeHelpText(QDeepCopy<QString>(help));
01074 }
01075
01076 void MythRemoteLineEdit::focusInEvent(QFocusEvent *e)
01077 {
01078 emit changeHelpText(helptext);
01079 emit gotFocus();
01080
01081 QColor highlight = colorGroup().highlight();
01082
01083 this->setPaletteBackgroundColor(highlight);
01084
01085 QTextEdit::focusInEvent(e);
01086 }
01087
01088 void MythRemoteLineEdit::focusOutEvent(QFocusEvent *e)
01089 {
01090 this->unsetPalette();
01091
01092 if (popup && popup->isShown() && !popup->hasFocus())
01093 popup->hide();
01094
01095 emit lostFocus();
01096 QTextEdit::focusOutEvent(e);
01097 }
01098
01099 MythRemoteLineEdit::~MythRemoteLineEdit()
01100 {
01101 Teardown();
01102 }
01103
01104 void MythRemoteLineEdit::deleteLater(void)
01105 {
01106 Teardown();
01107 QTextEdit::deleteLater();
01108 }
01109
01110 void MythRemoteLineEdit::Teardown(void)
01111 {
01112 if (cycle_timer)
01113 {
01114 cycle_timer->disconnect();
01115 cycle_timer->deleteLater();
01116 cycle_timer = NULL;
01117 }
01118
01119 qt_delete(popup);
01120 }
01121
01122 void MythRemoteLineEdit::popupVirtualKeyboard(void)
01123 {
01124 qt_delete(popup);
01125
01126 popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
01127 gContext->GetMainWindow()->detach(popup);
01128 popup->exec();
01129
01130 qt_delete(popup);
01131 }
01132
01133 void MythRemoteLineEdit::insert(QString text)
01134 {
01135 QTextEdit::insert(text);
01136 emit textChanged(this->text());
01137 }
01138
01139 void MythRemoteLineEdit::del()
01140 {
01141 doKeyboardAction(QTextEdit::ActionDelete);
01142 emit textChanged(this->text());
01143 }
01144
01145 void MythRemoteLineEdit::backspace()
01146 {
01147 doKeyboardAction(QTextEdit::ActionBackspace);
01148 emit textChanged(this->text());
01149 }
01150
01151 void MythTable::keyPressEvent(QKeyEvent *e)
01152 {
01153 if (isEditing() && item(currEditRow(), currEditCol()) &&
01154 item(currEditRow(), currEditCol())->editType() == QTableItem::OnTyping)
01155 return;
01156
01157 int tmpRow = currentRow();
01158 bool handled = false;
01159 QStringList actions;
01160 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
01161 actions))
01162 {
01163 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01164 {
01165 QString action = actions[i];
01166
01167 if (action == "UP")
01168 {
01169 if (tmpRow == 0)
01170 {
01171 focusNextPrevChild(false);
01172 handled = true;
01173 }
01174 }
01175 else if (action == "DOWN")
01176 {
01177 if (tmpRow == numRows() - 1)
01178 {
01179 focusNextPrevChild(true);
01180 handled = true;
01181 }
01182 }
01183 else if (action == "LEFT" || action == "RIGHT")
01184 handled = true;
01185 else if (action == "SELECT")
01186 handled = true;
01187 }
01188 }
01189
01190 if (!handled)
01191 QTable::keyPressEvent(e);
01192 }
01193
01194 void MythButtonGroup::moveFocus(int key)
01195 {
01196 QButton *currentSel = selected();
01197
01198 QButtonGroup::moveFocus(key);
01199
01200 if (selected() == currentSel)
01201 {
01202 switch (key)
01203 {
01204 case Key_Up: focusNextPrevChild(FALSE); break;
01205 case Key_Down: focusNextPrevChild(TRUE); break;
01206 default: break;
01207 }
01208 }
01209 }
01210
01211 MythPushButton::MythPushButton(const QString &ontext, const QString &offtext,
01212 QWidget *parent, bool isOn, bool aa)
01213 : QPushButton(ontext, parent)
01214 {
01215 setBackgroundOrigin(WindowOrigin);
01216 arrowAccel = aa;
01217
01218 onText = ontext;
01219 offText = offtext;
01220
01221 setToggleButton(true);
01222
01223 if (isOn)
01224 setText(onText);
01225 else
01226 setText(offText);
01227
01228 setOn(isOn);
01229 }
01230
01231 void MythPushButton::setHelpText(const QString &help)
01232 {
01233 bool changed = helptext != help;
01234 helptext = QDeepCopy<QString>(help);
01235 if (hasFocus() && changed)
01236 emit changeHelpText(QDeepCopy<QString>(help));
01237 }
01238
01239 void MythPushButton::keyPressEvent(QKeyEvent *e)
01240 {
01241 bool handled = false;
01242 QStringList actions;
01243 keyPressActions.clear();
01244
01245 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
01246 actions))
01247 {
01248 keyPressActions = actions;
01249
01250 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01251 {
01252 QString action = actions[i];
01253 if (action == "SELECT")
01254 {
01255 if (isToggleButton())
01256 toggleText();
01257 setDown(true);
01258 emit pressed();
01259 handled = true;
01260 }
01261 else if (arrowAccel)
01262 {
01263 if (action == "LEFT")
01264 {
01265 parent()->event(e);
01266 handled = true;
01267 }
01268 else if (action == "RIGHT")
01269 {
01270 if (isToggleButton())
01271 toggleText();
01272 setDown(true);
01273 emit pressed();
01274 handled = true;
01275 }
01276 }
01277 }
01278 }
01279
01280 if (!handled)
01281 QPushButton::keyPressEvent(e);
01282 }
01283
01284 void MythPushButton::keyReleaseEvent(QKeyEvent *e)
01285 {
01286 bool handled = false;
01287 QStringList actions = keyPressActions;
01288 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01289 {
01290 QString action = actions[i];
01291 if (action == "SELECT")
01292 {
01293 QKeyEvent tempe(QEvent::KeyRelease, Key_Space, ' ', 0, " ");
01294 QPushButton::keyReleaseEvent(&tempe);
01295 handled = true;
01296 }
01297 }
01298
01299 if (!handled)
01300 QPushButton::keyReleaseEvent(e);
01301 }
01302
01303 void MythPushButton::toggleText(void)
01304 {
01305 if (!isToggleButton())
01306 return;
01307
01308 if (isOn())
01309 setText(offText);
01310 else
01311 setText(onText);
01312 }
01313
01314 void MythPushButton::focusInEvent(QFocusEvent *e)
01315 {
01316 emit changeHelpText(helptext);
01317
01318 QColor highlight = colorGroup().highlight();
01319
01320 this->setPaletteBackgroundColor(highlight);
01321 QPushButton::focusInEvent(e);
01322 }
01323
01324 void MythPushButton::focusOutEvent(QFocusEvent *e)
01325 {
01326 this->unsetPalette();
01327 QPushButton::focusOutEvent(e);
01328 }
01329
01330 MythListView::MythListView(QWidget *parent)
01331 : QListView(parent)
01332 {
01333 viewport()->setPalette(palette());
01334 horizontalScrollBar()->setPalette(palette());
01335 verticalScrollBar()->setPalette(palette());
01336 header()->setPalette(palette());
01337 header()->setFont(font());
01338
01339 setAllColumnsShowFocus(TRUE);
01340 }
01341
01342 void MythListView::ensureItemVCentered ( const QListViewItem * i )
01343 {
01344 if (!i)
01345 return;
01346
01347 int y = itemPos(i);
01348 int h = i->height();
01349
01350 if (y - h / 2 < visibleHeight() / 2 ||
01351 y - h / 2 > contentsHeight() - visibleHeight() / 2)
01352 {
01353 ensureItemVisible(i);
01354 }
01355 else
01356 {
01357 ensureVisible(contentsX(), y, 0, visibleHeight() / 2);
01358 }
01359 }
01360
01361 void MythListView::keyPressEvent(QKeyEvent *e)
01362 {
01363 if (currentItem() && !currentItem()->isEnabled())
01364 {
01365 QListView::keyPressEvent(e);
01366 return;
01367
01368 }
01369
01370 bool handled = false;
01371 QStringList actions;
01372 gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions);
01373
01374 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01375 {
01376 QString action = actions[i];
01377 handled = true;
01378
01379 if (action == "UP" && currentItem() == firstChild())
01380 {
01381
01382 clearSelection();
01383 if (!focusNextPrevChild(false))
01384 {
01385
01386 setSelected(currentItem(), true);
01387 }
01388 }
01389 else if (action == "DOWN" && currentItem() == lastItem())
01390 {
01391
01392 clearSelection();
01393 if (!focusNextPrevChild(true))
01394 setSelected(currentItem(), true);
01395 }
01396 else if (action == "SELECT")
01397 {
01398 emit spacePressed(currentItem());
01399 return;
01400 }
01401 else
01402 handled = false;
01403 }
01404
01405 QListView::keyPressEvent(e);
01406 }
01407
01408 void MythListView::focusInEvent(QFocusEvent *e)
01409 {
01410
01411
01412
01413
01414
01415 QListView::focusInEvent(e);
01416
01417
01418
01419
01420
01421
01422
01423 setSelected(currentItem(), true);
01424 }
01425
01426 MythListBox::MythListBox(QWidget* parent): QListBox(parent)
01427 {
01428 }
01429
01430 void MythListBox::polish(void)
01431 {
01432 QListBox::polish();
01433
01434 QPalette pal = palette();
01435 QColorGroup::ColorRole role = QColorGroup::Highlight;
01436 pal.setColor(QPalette::Active, role, pal.active().button());
01437 pal.setColor(QPalette::Inactive, role, pal.active().button());
01438 pal.setColor(QPalette::Disabled, role, pal.active().button());
01439
01440 setPalette(pal);
01441 }
01442
01443 void MythListBox::setCurrentItem(const QString& matchText, bool caseSensitive,
01444 bool partialMatch)
01445 {
01446 for (unsigned i = 0 ; i < count() ; ++i)
01447 {
01448 if (partialMatch)
01449 {
01450 if (caseSensitive)
01451 {
01452 if (text(i).startsWith(matchText))
01453 {
01454 setCurrentItem(i);
01455 break;
01456 }
01457 }
01458 else
01459 {
01460 if (text(i).lower().startsWith(matchText.lower()))
01461 {
01462 setCurrentItem(i);
01463 break;
01464 }
01465 }
01466 }
01467 else
01468 {
01469 if (caseSensitive)
01470 {
01471 if (text(i) == matchText)
01472 {
01473 setCurrentItem(i);
01474 break;
01475 }
01476 }
01477 else
01478 {
01479 if (text(i).lower() == matchText.lower())
01480 {
01481 setCurrentItem(i);
01482 break;
01483 }
01484 }
01485 }
01486 }
01487 }
01488
01489 void MythListBox::keyPressEvent(QKeyEvent* e)
01490 {
01491 bool handled = false;
01492 QStringList actions;
01493 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
01494 {
01495 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01496 {
01497 QString action = actions[i];
01498 if (action == "UP" || action == "DOWN" || action == "PAGEUP" ||
01499 action == "PAGEDOWN" || action == "LEFT" || action == "RIGHT")
01500 {
01501 int key;
01502 if (action == "UP")
01503 {
01504
01505 if (currentItem() == 0)
01506 {
01507 focusNextPrevChild(false);
01508 handled = true;
01509 continue;
01510 }
01511
01512 key = Key_Up;
01513 }
01514 else if (action == "DOWN")
01515 {
01516
01517 if (currentItem() == (int) count() - 1)
01518 {
01519 focusNextPrevChild(true);
01520 handled = true;
01521 continue;
01522 }
01523
01524 key = Key_Down;
01525 }
01526 else if (action == "LEFT")
01527 {
01528 focusNextPrevChild(false);
01529 handled = true;
01530 continue;
01531 }
01532 else if (action == "RIGHT")
01533 {
01534 focusNextPrevChild(true);
01535 handled = true;
01536 continue;
01537 }
01538 else if (action == "PAGEUP")
01539 key = Key_Prior;
01540 else if (action == "PAGEDOWN")
01541 key = Key_Next;
01542 else
01543 key = Key_unknown;
01544
01545 QKeyEvent ev(QEvent::KeyPress, key, 0, Qt::NoButton);
01546 QListBox::keyPressEvent(&ev);
01547 handled = true;
01548 }
01549 else if (action == "0" || action == "1" || action == "2" ||
01550 action == "3" || action == "4" || action == "5" ||
01551 action == "6" || action == "7" || action == "8" ||
01552 action == "9")
01553 {
01554 int percent = action.toInt() * 10;
01555 int nextItem = percent * count() / 100;
01556 if (!itemVisible(nextItem))
01557 setTopItem(nextItem);
01558 setCurrentItem(nextItem);
01559 handled = true;
01560 }
01561 else if (action == "PREVVIEW")
01562 {
01563 int nextItem = currentItem();
01564 if (nextItem > 0)
01565 nextItem--;
01566 while (nextItem > 0 && text(nextItem)[0] == ' ')
01567 nextItem--;
01568 if (!itemVisible(nextItem))
01569 setTopItem(nextItem);
01570 setCurrentItem(nextItem);
01571 handled = true;
01572 }
01573 else if (action == "NEXTVIEW")
01574 {
01575 int nextItem = currentItem();
01576 if (nextItem < (int)count() - 1)
01577 nextItem++;
01578 while (nextItem < (int)count() - 1 && text(nextItem)[0] == ' ')
01579 nextItem++;
01580 if (!itemVisible(nextItem))
01581 setTopItem(nextItem);
01582 setCurrentItem(nextItem);
01583 handled = true;
01584 }
01585 else if (action == "MENU")
01586 emit menuButtonPressed(currentItem());
01587 else if (action == "EDIT")
01588 emit editButtonPressed(currentItem());
01589 else if (action == "DELETE")
01590 emit deleteButtonPressed(currentItem());
01591 else if (action == "SELECT")
01592 emit accepted(currentItem());
01593 }
01594 }
01595
01596 if (!handled)
01597 e->ignore();
01598 }
01599
01600 void MythListBox::setHelpText(const QString &help)
01601 {
01602 bool changed = helptext != help;
01603 helptext = QDeepCopy<QString>(help);
01604 if (hasFocus() && changed)
01605 emit changeHelpText(QDeepCopy<QString>(help));
01606 }
01607
01608 void MythListBox::focusOutEvent(QFocusEvent *e)
01609 {
01610 QPalette pal = palette();
01611 QColorGroup::ColorRole role = QColorGroup::Highlight;
01612 pal.setColor(QPalette::Active, role, pal.active().button());
01613 pal.setColor(QPalette::Inactive, role, pal.active().button());
01614 pal.setColor(QPalette::Disabled, role, pal.active().button());
01615
01616 setPalette(pal);
01617 QListBox::focusOutEvent(e);
01618 }
01619
01620 void MythListBox::focusInEvent(QFocusEvent *e)
01621 {
01622 this->unsetPalette();
01623
01624 emit changeHelpText(helptext);
01625 QListBox::focusInEvent(e);
01626 }
01627
01628