00001 #include <qdict.h>
00002 #include <qcursor.h>
00003 #include <qapplication.h>
00004 #include <qtimer.h>
00005 #include <qpainter.h>
00006 #include <qpixmap.h>
00007 #include <qkeysequence.h>
00008 #include <qpaintdevicemetrics.h>
00009 #include <qdir.h>
00010 #include <qfile.h>
00011 #ifdef QWS
00012 #include <qwindowsystem_qws.h>
00013 #endif
00014 #ifdef Q_WS_MACX
00015 #include <HIToolbox/Menus.h>
00016 #endif
00017
00018 #include <pthread.h>
00019
00020 #include <algorithm>
00021 using namespace std;
00022
00023 #ifdef USE_LIRC
00024 #include "lirc.h"
00025 #include "lircevent.h"
00026 #endif
00027
00028 #ifdef USING_APPLEREMOTE
00029 #include "AppleRemoteListener.h"
00030 #include "lircevent.h"
00031 #endif
00032
00033 #ifdef USE_JOYSTICK_MENU
00034 #include "jsmenu.h"
00035 #include "jsmenuevent.h"
00036 #endif
00037
00038 #include "mythmainwindow.h"
00039 #include "mythscreentype.h"
00040 #include "mythpainter.h"
00041 #ifdef USE_OPENGL_PAINTER
00042 #include "mythpainter_ogl.h"
00043 #endif
00044 #include "mythpainter_qt.h"
00045 #include "mythcontext.h"
00046 #include "mythdbcon.h"
00047 #include "mythgesture.h"
00048
00049
00050 #include "screensaver.h"
00051 #include "mythdialogs.h"
00052 #include "mythmediamonitor.h"
00053
00054 #define GESTURE_TIMEOUT 1000
00055
00056 #ifdef USE_LIRC
00057 static void *SpawnLirc(void *param)
00058 {
00059 QString config_file = MythContext::GetConfDir() + "/lircrc";
00060 if (!QFile::exists(config_file))
00061 config_file = QDir::homeDirPath() + "/.lircrc";
00062
00063 LircClient *cl = new LircClient((MythMainWindow *)param);
00064 if (!cl->Init(config_file, "mythtv"))
00065 cl->Process();
00066
00067 return NULL;
00068 }
00069 #endif
00070
00071 #ifdef USE_JOYSTICK_MENU
00072 static void *SpawnJoystickMenu(void *param)
00073 {
00074 MythMainWindow *main_window = (MythMainWindow *)param;
00075 QString config_file = MythContext::GetConfDir() + "/joystickmenurc";
00076 JoystickMenuClient *js = new JoystickMenuClient(main_window);
00077 if (!js->Init(config_file))
00078 js->Process();
00079
00080 return NULL;
00081 }
00082 #endif
00083
00084 #ifdef USING_APPLEREMOTE
00085 static void* SpawnAppleRemote(void* param)
00086 {
00087 MythMainWindow *main_window = (MythMainWindow *)param;
00088 AppleRemoteListener *arl = new AppleRemoteListener(main_window);
00089 AppleRemote &remote(AppleRemote::instance());
00090
00091 remote.setListener(arl);
00092 remote.startListening();
00093 if (!remote.isListeningToRemote())
00094 return NULL;
00095
00096 remote.runLoop();
00097 return NULL;
00098 }
00099 #endif
00100
00101 class KeyContext
00102 {
00103 public:
00104 void AddMapping(int key, QString action)
00105 {
00106 actionMap[key].append(action);
00107 }
00108
00109 bool GetMapping(int key, QStringList &actions)
00110 {
00111 if (actionMap.count(key) > 0)
00112 {
00113 actions += actionMap[key];
00114 return true;
00115 }
00116 return false;
00117 }
00118
00119 QMap<int, QStringList> actionMap;
00120 };
00121
00122 struct JumpData
00123 {
00124 void (*callback)(void);
00125 QString destination;
00126 QString description;
00127 bool exittomain;
00128 QString localAction;
00129 };
00130
00131 struct MHData
00132 {
00133 void (*callback)(MythMediaDevice *mediadevice);
00134 int MediaType;
00135 QString destination;
00136 QString description;
00137 };
00138
00139 struct MPData {
00140 QString description;
00141 MediaPlayCallback playFn;
00142 };
00143
00144 class MythMainWindowPrivate
00145 {
00146 public:
00147 int TranslateKeyNum(QKeyEvent *e);
00148
00149 float wmult, hmult;
00150 int screenwidth, screenheight;
00151
00152 QRect screenRect;
00153 QRect uiScreenRect;
00154
00155 int xbase, ybase;
00156 bool does_fill_screen;
00157
00158 bool ignore_lirc_keys;
00159 bool ignore_joystick_keys;
00160
00161 bool exitingtomain;
00162 bool popwindows;
00163
00164 bool m_useDB;
00165
00166 QDict<KeyContext> keyContexts;
00167 QMap<int, JumpData*> jumpMap;
00168 QMap<QString, JumpData> destinationMap;
00169 QMap<QString, MHData> mediaHandlerMap;
00170 QMap<QString, MPData> mediaPluginMap;
00171
00172 void (*exitmenucallback)(void);
00173
00174 void (*exitmenumediadevicecallback)(MythMediaDevice* mediadevice);
00175 MythMediaDevice * mediadeviceforcallback;
00176
00177 int escapekey;
00178
00179 QTimer *drawTimer;
00180 QValueVector<MythScreenStack *> stackList;
00181 MythScreenStack *mainStack;
00182
00183 MythPainter *painter;
00184
00185 bool AllowInput;
00186
00187 QRegion repaintRegion;
00188
00189 MythGesture gesture;
00190 QTimer *gestureTimer;
00191
00192
00193 vector<QWidget *> widgetList;
00194 };
00195
00196
00197 int MythMainWindowPrivate::TranslateKeyNum(QKeyEvent* e)
00198 {
00199 int keynum = e->key();
00200
00201 if (keynum != Qt::Key_Escape &&
00202 (keynum < Qt::Key_Shift || keynum > Qt::Key_ScrollLock))
00203 {
00204 Qt::ButtonState modifiers;
00205
00206 if ((modifiers = e->state()) != 0)
00207 {
00208 int modnum = (((modifiers & Qt::ShiftButton) &&
00209 keynum > 0x7f) ? Qt::SHIFT : 0) |
00210 ((modifiers & Qt::ControlButton) ? Qt::CTRL : 0) |
00211 ((modifiers & Qt::MetaButton) ? Qt::META : 0) |
00212 ((modifiers & Qt::AltButton) ? Qt::ALT : 0);
00213 modnum &= ~Qt::UNICODE_ACCEL;
00214 return (keynum |= modnum);
00215 }
00216 }
00217
00218 return keynum;
00219 }
00220
00221 static MythMainWindow *mainWin = NULL;
00222 static QMutex mainLock;
00223
00232 MythMainWindow *MythMainWindow::getMainWindow(const bool useDB)
00233 {
00234 if (mainWin)
00235 return mainWin;
00236
00237 QMutexLocker lock(&mainLock);
00238
00239 if (!mainWin)
00240 mainWin = new MythMainWindow(useDB);
00241
00242 return mainWin;
00243 }
00244
00245 void MythMainWindow::destroyMainWindow(void)
00246 {
00247 if (mainWin)
00248 delete mainWin;
00249 mainWin = NULL;
00250 }
00251
00252 MythMainWindow *GetMythMainWindow(void)
00253 {
00254 return MythMainWindow::getMainWindow();
00255 }
00256
00257 void DestroyMythMainWindow(void)
00258 {
00259 MythMainWindow::destroyMainWindow();
00260 }
00261
00262 MythPainter *GetMythPainter(void)
00263 {
00264 return MythMainWindow::getMainWindow()->GetCurrentPainter();
00265 }
00266
00267 #ifdef USE_OPENGL_PAINTER
00268 #define QWidget QGLWidget
00269 #endif
00270
00271 MythMainWindow::MythMainWindow(const bool useDB)
00272 : QWidget(NULL, "mainWindow")
00273 {
00274
00275 #undef QWidget
00276 d = new MythMainWindowPrivate;
00277
00278 d->AllowInput = false;
00279
00280
00281 d->m_useDB = useDB;
00282
00283
00284 QString painter = gContext->GetSetting("ThemePainter", "qt");
00285 #ifdef USE_OPENGL_PAINTER
00286 if (painter == "opengl")
00287 {
00288 VERBOSE(VB_GENERAL, "Using the OpenGL painter");
00289 d->painter = new MythOpenGLPainter();
00290 }
00291 else
00292 #endif
00293 {
00294 VERBOSE(VB_GENERAL, "Using the Qt painter");
00295 d->painter = new MythQtPainter();
00296 }
00297
00298
00299
00300 d->ignore_lirc_keys = false;
00301 d->ignore_joystick_keys = false;
00302 d->exitingtomain = false;
00303 d->popwindows = true;
00304 d->exitmenucallback = false;
00305 d->exitmenumediadevicecallback = false;
00306 d->mediadeviceforcallback = NULL;
00307 d->escapekey = Key_Escape;
00308 d->mainStack = NULL;
00309
00310 installEventFilter(this);
00311
00312 #ifdef USE_LIRC
00313 pthread_t lirc_tid;
00314 pthread_attr_t attr;
00315 pthread_attr_init(&attr);
00316 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00317 pthread_create(&lirc_tid, &attr, SpawnLirc, this);
00318 pthread_attr_destroy(&attr);
00319 #endif
00320
00321 #ifdef USE_JOYSTICK_MENU
00322 d->ignore_joystick_keys = false;
00323 pthread_t js_tid;
00324
00325 pthread_attr_t attr2;
00326 pthread_attr_init(&attr2);
00327 pthread_attr_setdetachstate(&attr2, PTHREAD_CREATE_DETACHED);
00328 pthread_create(&js_tid, &attr2, SpawnJoystickMenu, this);
00329 pthread_attr_destroy(&attr2);
00330 #endif
00331
00332 #ifdef USING_APPLEREMOTE
00333 pthread_t appleremote_tid;
00334
00335 pthread_attr_t attr3;
00336 pthread_attr_init(&attr3);
00337 pthread_attr_setdetachstate(&attr3, PTHREAD_CREATE_DETACHED);
00338 pthread_create(&appleremote_tid, &attr3, SpawnAppleRemote, this);
00339 pthread_attr_destroy(&attr3);
00340 #endif
00341
00342 d->keyContexts.setAutoDelete(true);
00343
00344 RegisterKey("Global", "UP", "Up Arrow", "Up");
00345 RegisterKey("Global", "DOWN", "Down Arrow", "Down");
00346 RegisterKey("Global", "LEFT", "Left Arrow", "Left");
00347 RegisterKey("Global", "RIGHT", "Right Arrow", "Right");
00348 RegisterKey("Global", "SELECT", "Select", "Return,Enter,Space");
00349 RegisterKey("Global", "ESCAPE", "Escape", "Esc");
00350 RegisterKey("Global", "MENU", "Pop-up menu", "M");
00351 RegisterKey("Global", "INFO", "More information", "I");
00352
00353 RegisterKey("Global", "PAGEUP", "Page Up", "PgUp");
00354 RegisterKey("Global", "PAGEDOWN", "Page Down", "PgDown");
00355
00356 RegisterKey("Global", "PREVVIEW", "Previous View", "Home");
00357 RegisterKey("Global", "NEXTVIEW", "Next View", "End");
00358
00359 RegisterKey("Global", "HELP", "Help", "F1");
00360 RegisterKey("Global", "EJECT", "Eject Removable Media", "");
00361
00362 RegisterKey("Global", "0", "0", "0");
00363 RegisterKey("Global", "1", "1", "1");
00364 RegisterKey("Global", "2", "2", "2");
00365 RegisterKey("Global", "3", "3", "3");
00366 RegisterKey("Global", "4", "4", "4");
00367 RegisterKey("Global", "5", "5", "5");
00368 RegisterKey("Global", "6", "6", "6");
00369 RegisterKey("Global", "7", "7", "7");
00370 RegisterKey("Global", "8", "8", "8");
00371 RegisterKey("Global", "9", "9", "9");
00372
00373 #ifdef USE_OPENGL_PAINTER
00374 setAutoBufferSwap(false);
00375 #endif
00376
00377 d->gestureTimer = new QTimer(this);
00378 connect(d->gestureTimer, SIGNAL(timeout()), this, SLOT(mouseTimeout()));
00379
00380 d->drawTimer = new QTimer(this);
00381 connect(d->drawTimer, SIGNAL(timeout()), this, SLOT(drawTimeout()));
00382 d->drawTimer->start(1000 / 70);
00383
00384 d->AllowInput = true;
00385
00386 d->repaintRegion = QRegion(QRect(0,0,0,0));
00387 }
00388
00389 MythMainWindow::~MythMainWindow()
00390 {
00391 while (!d->stackList.isEmpty())
00392 {
00393 delete d->stackList.back();
00394 d->stackList.pop_back();
00395 }
00396
00397 delete d;
00398 }
00399
00400 MythPainter *MythMainWindow::GetCurrentPainter(void)
00401 {
00402 return d->painter;
00403 }
00404
00405 void MythMainWindow::AddScreenStack(MythScreenStack *stack, bool main)
00406 {
00407 d->stackList.push_back(stack);
00408 if (main)
00409 d->mainStack = stack;
00410 }
00411
00412 MythScreenStack *MythMainWindow::GetMainStack(void)
00413 {
00414 return d->mainStack;
00415 }
00416
00417 void MythMainWindow::drawTimeout(void)
00418 {
00419
00420 if (currentWidget())
00421 return;
00422
00423 bool redraw = false;
00424
00425 if (!d->repaintRegion.isEmpty())
00426 redraw = true;
00427
00428 QValueVector<MythScreenStack *>::Iterator it;
00429 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00430 {
00431 QValueVector<MythScreenType *> drawList;
00432 (*it)->GetDrawOrder(drawList);
00433
00434 QValueVector<MythScreenType *>::Iterator screenit;
00435 for (screenit = drawList.begin(); screenit != drawList.end();
00436 ++screenit)
00437 {
00438 (*screenit)->Pulse();
00439 }
00440
00441
00442 MythScreenType *top = (*it)->GetTopScreen();
00443 if (top && top->NeedsRedraw())
00444 {
00445 QRegion topDirty = top->GetDirtyArea();
00446 d->repaintRegion = d->repaintRegion.unite(topDirty);
00447 redraw = true;
00448 }
00449 }
00450
00451 if (!redraw)
00452 {
00453 return;
00454 }
00455
00456 if (!d->painter->SupportsClipping())
00457 d->repaintRegion = d->repaintRegion.unite(d->uiScreenRect);
00458 else
00459 {
00460
00461
00462 d->repaintRegion = d->repaintRegion.intersect(d->uiScreenRect);
00463 }
00464
00465 d->painter->Begin(this);
00466
00467 QMemArray<QRect> rects = d->repaintRegion.rects();
00468
00469 for (unsigned int i = 0; i < rects.size(); i++)
00470 {
00471 if (rects[i].width() == 0 || rects[i].height() == 0)
00472 continue;
00473
00474 if (rects[i] != d->uiScreenRect)
00475 d->painter->SetClipRect(rects[i]);
00476
00477 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
00478 {
00479 QValueVector<MythScreenType *> redrawList;
00480 (*it)->GetDrawOrder(redrawList);
00481
00482 QValueVector<MythScreenType *>::Iterator screenit;
00483 for (screenit = redrawList.begin(); screenit != redrawList.end();
00484 ++screenit)
00485 {
00486 (*screenit)->Draw(d->painter, 0, 0, 255, rects[i]);
00487 }
00488 }
00489 }
00490
00491 d->painter->End();
00492
00493 d->repaintRegion = QRegion(QRect(0, 0, 0, 0));
00494 }
00495
00496 void MythMainWindow::closeEvent(QCloseEvent *e)
00497 {
00498 (void)e;
00499 qApp->quit();
00500 }
00501
00502 void MythMainWindow::paintEvent(QPaintEvent *pe)
00503 {
00504 d->repaintRegion = d->repaintRegion.unite(pe->region());
00505 }
00506
00507 #ifdef USING_APPLEREMOTE
00508
00509
00510 bool MythMainWindow::event(QEvent* e)
00511 {
00512 switch (e->type())
00513 {
00514 case QEvent::WindowActivate:
00515 {
00516 AppleRemote::instance().startListening();
00517 break;
00518 }
00519 case QEvent::WindowDeactivate:
00520 {
00521
00522 AppleRemote::instance().stopListening();
00523 break;
00524 }
00525 default:
00526 break;
00527 }
00528 return QWidget::event(e);
00529 }
00530 #endif
00531
00532 void MythMainWindow::Init(void)
00533 {
00534 gContext->GetScreenSettings(d->xbase, d->screenwidth, d->wmult,
00535 d->ybase, d->screenheight, d->hmult);
00536
00537 d->screenRect = QRect(d->xbase, d->ybase, d->screenwidth, d->screenheight);
00538 d->uiScreenRect = QRect(0, 0, d->screenwidth, d->screenheight);
00539
00540 setGeometry(d->xbase, d->ybase, d->screenwidth, d->screenheight);
00541 setFixedSize(QSize(d->screenwidth, d->screenheight));
00542
00543 fonTweak = gContext->GetNumSetting("QtFonTweak", 0);
00544
00545 bool hideCursor = gContext->GetNumSetting("HideMouseCursor", 1);
00546 #ifdef QWS
00547 #if QT_VERSION >= 0x030300
00548 QWSServer::setCursorVisible(!hideCursor);
00549 #endif
00550 #endif
00551
00552 if (gContext->GetNumSetting("RunFrontendInWindow", 0))
00553 d->does_fill_screen = false;
00554 else
00555 d->does_fill_screen = true;
00556
00557
00558 Qt::WFlags flags = 0;
00559 if (d->does_fill_screen)
00560 flags = Qt::WStyle_Customize |
00561 Qt::WStyle_NoBorder;
00562 else
00563 flags = Qt::WStyle_Customize | Qt::WStyle_NormalBorder;
00564
00565
00566 #ifdef Q_WS_MACX
00567 if (d->does_fill_screen)
00568 {
00569 #if QT_VERSION >= 0x030303
00570 flags = Qt::WStyle_Customize | Qt::WStyle_Splash;
00571 #else
00572
00573
00574
00575 flags = Qt::WStyle_Customize | Qt::WStyle_DialogBorder;
00576
00577
00578
00579 d->ybase -= GetMBarHeight();
00580 #endif
00581 }
00582 #endif
00583
00584 flags |= WRepaintNoErase;
00585 #ifdef QWS
00586 flags |= WResizeNoErase;
00587 #endif
00588
00589 reparent(parentWidget(), flags, pos());
00590
00591
00592 setFont(gContext->GetMediumFont());
00593 gContext->ThemeWidget(this);
00594
00595 Show();
00596
00597
00598 setCursor((hideCursor) ? (Qt::BlankCursor) : (Qt::ArrowCursor));
00599
00600 move(d->xbase, d->ybase);
00601 }
00602
00603 void MythMainWindow::Show(void)
00604 {
00605 show();
00606 #ifdef Q_WS_MACX
00607 if (d->does_fill_screen)
00608 HideMenuBar();
00609 else
00610 ShowMenuBar();
00611 #endif
00612
00613 setActiveWindow();
00614 raise();
00615 qApp->wakeUpGuiThread();
00616 }
00617
00618
00619 void MythMainWindow::attach(QWidget *child)
00620 {
00621 #ifdef USING_MINGW
00622 #warning TODO FIXME MythMainWindow::attach() does not always work on MS Windows!
00623
00624
00625
00626
00627 VERBOSE(VB_IMPORTANT,
00628 QString("MythMainWindow::attach old: %1, new: %2, thread: %3")
00629 .arg(currentWidget() ? currentWidget()->name() : "none")
00630 .arg(child->name())
00631 .arg(::GetCurrentThreadId()));
00632 #endif
00633 if (currentWidget())
00634 currentWidget()->setEnabled(false);
00635
00636 d->widgetList.push_back(child);
00637 child->raise();
00638 child->setFocus();
00639 }
00640
00641 void MythMainWindow::detach(QWidget *child)
00642 {
00643 vector<QWidget*>::iterator it =
00644 std::find(d->widgetList.begin(), d->widgetList.end(), child);
00645
00646 if (it == d->widgetList.end())
00647 {
00648 VERBOSE(VB_IMPORTANT, "Could not find widget to detach");
00649 return;
00650 }
00651
00652 d->widgetList.erase(it);
00653 QWidget *current = currentWidget();
00654
00655 if (current)
00656 {
00657 current->setEnabled(true);
00658 current->setFocus();
00659 }
00660
00661 if (d->exitingtomain)
00662 QApplication::postEvent(this, new ExitToMainMenuEvent());
00663 }
00664
00665 QWidget *MythMainWindow::currentWidget(void)
00666 {
00667 if (d->widgetList.size() > 0)
00668 return d->widgetList.back();
00669 return NULL;
00670 }
00671
00672
00673 bool MythMainWindow::IsExitingToMain(void) const
00674 {
00675 return d->exitingtomain;
00676 }
00677
00678 void MythMainWindow::ExitToMainMenu(void)
00679 {
00680 bool jumpdone = !(d->popwindows);
00681
00682 d->exitingtomain = true;
00683
00684
00685 QWidget *current = currentWidget();
00686 if (current && d->exitingtomain && d->popwindows)
00687 {
00688 if (current->name() != QString("mainmenu"))
00689 {
00690 if (current->name() == QString("video playback window"))
00691 {
00692 MythEvent *me = new MythEvent("EXIT_TO_MENU");
00693 QApplication::postEvent(current, me);
00694 }
00695 else if (MythDialog *dial = dynamic_cast<MythDialog*>(current))
00696 {
00697 (void)dial;
00698 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, d->escapekey,
00699 0, Qt::NoButton);
00700 QObject *key_target = getTarget(*key);
00701 QApplication::postEvent(key_target, key);
00702 }
00703 return;
00704 }
00705 else
00706 jumpdone = true;
00707 }
00708
00709 MythScreenStack *toplevel = GetMainStack();
00710 if (toplevel && d->popwindows)
00711 {
00712 MythScreenType *screen = toplevel->GetTopScreen();
00713 if (screen && screen->name() != QString("mainmenu"))
00714 {
00715 if (screen->name() == QString("video playback window"))
00716 {
00717 MythEvent *me = new MythEvent("EXIT_TO_MENU");
00718 QApplication::postEvent(screen, me);
00719 }
00720 else
00721 {
00722 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, d->escapekey,
00723 0, Qt::NoButton);
00724 QApplication::postEvent(this, key);
00725 }
00726 return;
00727 }
00728 else
00729 jumpdone = true;
00730 }
00731
00732 if (jumpdone)
00733 {
00734 d->exitingtomain = false;
00735 d->popwindows = true;
00736 if (d->exitmenucallback)
00737 {
00738 void (*callback)(void) = d->exitmenucallback;
00739 d->exitmenucallback = NULL;
00740 callback();
00741 }
00742 else if (d->exitmenumediadevicecallback)
00743 {
00744 void (*callback)(MythMediaDevice*) = d->exitmenumediadevicecallback;
00745 MythMediaDevice * mediadevice = d->mediadeviceforcallback;
00746 d->mediadeviceforcallback = NULL;
00747 callback(mediadevice);
00748 }
00749 }
00750 }
00751
00752 bool MythMainWindow::TranslateKeyPress(const QString &context,
00753 QKeyEvent *e, QStringList &actions,
00754 bool allowJumps)
00755 {
00756 actions.clear();
00757 int keynum = d->TranslateKeyNum(e);
00758
00759 QStringList localActions;
00760 if (allowJumps && (d->jumpMap.count(keynum) > 0) &&
00761 (d->jumpMap[keynum]->localAction != "") &&
00762 (d->keyContexts[context]) &&
00763 (d->keyContexts[context]->GetMapping(keynum, localActions)))
00764 {
00765 if (localActions.contains(d->jumpMap[keynum]->localAction))
00766 allowJumps = false;
00767 }
00768
00769 if (allowJumps && d->jumpMap.count(keynum) > 0 &&
00770 !d->jumpMap[keynum]->exittomain && d->exitmenucallback == NULL)
00771 {
00772 void (*callback)(void) = d->jumpMap[keynum]->callback;
00773 callback();
00774 return false;
00775 }
00776
00777 if (allowJumps &&
00778 d->jumpMap.count(keynum) > 0 && d->exitmenucallback == NULL)
00779 {
00780 d->exitingtomain = true;
00781 d->exitmenucallback = d->jumpMap[keynum]->callback;
00782 QApplication::postEvent(this, new ExitToMainMenuEvent());
00783 return false;
00784 }
00785
00786 bool retval = false;
00787
00788 if (d->keyContexts[context])
00789 {
00790 if (d->keyContexts[context]->GetMapping(keynum, actions))
00791 retval = true;
00792 }
00793
00794 if (context != "Global" &&
00795 d->keyContexts["Global"]->GetMapping(keynum, actions))
00796 {
00797 retval = true;
00798 }
00799
00800 return retval;
00801 }
00802
00803 void MythMainWindow::ClearKey(const QString &context, const QString &action)
00804 {
00805 KeyContext * keycontext = d->keyContexts[context];
00806 if (keycontext == NULL) return;
00807
00808 QMap<int,QStringList>::Iterator it;
00809 for (it = keycontext->actionMap.begin();
00810 it != keycontext->actionMap.end();
00811 it++)
00812 {
00813
00814
00815 QStringList::iterator at = it.data().find(action);
00816
00817
00818 while (at != it.data().end())
00819 {
00820
00821 at = it.data().remove(at);
00822
00823 at = it.data().find(at, action);
00824 }
00825
00826
00827 if (it.data().isEmpty()) keycontext->actionMap.erase(it);
00828 }
00829 }
00830
00831 void MythMainWindow::BindKey(const QString &context, const QString &action,
00832 const QString &key)
00833 {
00834 QKeySequence keyseq(key);
00835
00836 if (!d->keyContexts[context])
00837 d->keyContexts.insert(context, new KeyContext());
00838
00839 for (unsigned int i = 0; i < keyseq.count(); i++)
00840 {
00841 int keynum = keyseq[i];
00842 keynum &= ~Qt::UNICODE_ACCEL;
00843
00844 QStringList dummyaction = "";
00845 if (d->keyContexts[context]->GetMapping(keynum, dummyaction))
00846 {
00847 VERBOSE(VB_GENERAL, QString("Key %1 is bound to multiple actions "
00848 "in context %2.")
00849 .arg(key).arg(context));
00850 }
00851
00852 d->keyContexts[context]->AddMapping(keynum, action);
00853
00854
00855
00856
00857 if (action == "ESCAPE" && context == "Global" && i == 0)
00858 d->escapekey = keynum;
00859 }
00860 }
00861
00862 void MythMainWindow::RegisterKey(const QString &context, const QString &action,
00863 const QString &description, const QString &key)
00864 {
00865 QString keybind = key;
00866
00867 MSqlQuery query(MSqlQuery::InitCon());
00868
00869 if (d->m_useDB && query.isConnected())
00870 {
00871 query.prepare("SELECT keylist, description FROM keybindings WHERE "
00872 "context = :CONTEXT AND action = :ACTION AND "
00873 "hostname = :HOSTNAME ;");
00874 query.bindValue(":CONTEXT", context);
00875 query.bindValue(":ACTION", action);
00876 query.bindValue(":HOSTNAME", gContext->GetHostName());
00877
00878 bool ok = query.exec() && query.isActive();
00879
00880 if (ok && query.next())
00881 {
00882 keybind = query.value(0).toString();
00883 QString db_description = query.value(1).toString();
00884
00885
00886 if (db_description != description)
00887 {
00888 VERBOSE(VB_IMPORTANT, "Updating description...");
00889 query.prepare(
00890 "UPDATE keybindings "
00891 "SET description = :DESCRIPTION "
00892 "WHERE context = :CONTEXT AND "
00893 " action = :ACTION AND "
00894 " hostname = :HOSTNAME");
00895
00896 query.bindValue(":DESCRIPTION", description);
00897 query.bindValue(":CONTEXT", context);
00898 query.bindValue(":ACTION", action);
00899 query.bindValue(":HOSTNAME", gContext->GetHostName());
00900
00901 if (!query.exec())
00902 {
00903 MythContext::DBError("Update Keybinding", query);
00904 }
00905 }
00906 }
00907 else
00908 {
00909 QString inskey = keybind;
00910
00911 query.prepare("INSERT INTO keybindings (context, action, "
00912 "description, keylist, hostname) VALUES "
00913 "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, "
00914 ":HOSTNAME );");
00915 query.bindValue(":CONTEXT", context);
00916 query.bindValue(":ACTION", action);
00917 query.bindValue(":DESCRIPTION", description);
00918 query.bindValue(":KEYLIST", inskey);
00919 query.bindValue(":HOSTNAME", gContext->GetHostName());
00920
00921 if (!query.exec() || !query.isActive())
00922 {
00923 MythContext::DBError("Insert Keybinding", query);
00924 }
00925 }
00926 }
00927
00928 BindKey(context, action, keybind);
00929 }
00930
00931 QString MythMainWindow::GetKey(const QString &context,
00932 const QString &action) const
00933 {
00934 MSqlQuery query(MSqlQuery::InitCon());
00935 if (!query.isConnected())
00936 return "?";
00937
00938 query.prepare("SELECT keylist "
00939 "FROM keybindings "
00940 "WHERE context = :CONTEXT AND "
00941 " action = :ACTION AND "
00942 " hostname = :HOSTNAME");
00943 query.bindValue(":CONTEXT", context);
00944 query.bindValue(":ACTION", action);
00945 query.bindValue(":HOSTNAME", gContext->GetHostName());
00946
00947 if (!query.exec() || !query.isActive() || !query.next())
00948 return "?";
00949
00950 return query.value(0).toString();
00951 }
00952
00953 void MythMainWindow::ClearJump(const QString &destination)
00954 {
00955
00956 if (d->destinationMap.find(destination) == d->destinationMap.end())
00957 {
00958 VERBOSE(VB_GENERAL, "Cannot clear ficticious jump point"+destination);
00959 return;
00960 }
00961
00962 QMap<int, JumpData*>::Iterator it;
00963 for (it = d->jumpMap.begin(); it != d->jumpMap.end(); ++it)
00964 {
00965
00966 JumpData *jd = it.data();
00967 if (jd->destination == destination)
00968 d->jumpMap.remove(it);
00969 }
00970 }
00971
00972
00973 void MythMainWindow::BindJump(const QString &destination, const QString &key)
00974 {
00975
00976 if (d->destinationMap.find(destination) == d->destinationMap.end())
00977 {
00978 VERBOSE(VB_GENERAL,"Cannot bind to ficticious jump point"+destination);
00979 return;
00980 }
00981
00982 QKeySequence keyseq(key);
00983
00984 for (unsigned int i = 0; i < keyseq.count(); i++)
00985 {
00986 int keynum = keyseq[i];
00987 keynum &= ~Qt::UNICODE_ACCEL;
00988
00989 if (d->jumpMap.count(keynum) == 0)
00990 {
00991
00992
00993
00994 d->jumpMap[keynum] = &d->destinationMap[destination];
00995 }
00996 else
00997 {
00998 VERBOSE(VB_GENERAL, QString("Key %1 is already bound to a jump "
00999 "point.").arg(key));
01000 }
01001 }
01002
01003
01004
01005
01006 }
01007
01008 void MythMainWindow::RegisterJump(const QString &destination,
01009 const QString &description,
01010 const QString &key, void (*callback)(void),
01011 bool exittomain, QString localAction)
01012 {
01013 QString keybind = key;
01014
01015 MSqlQuery query(MSqlQuery::InitCon());
01016 if (query.isConnected())
01017 {
01018 query.prepare("SELECT keylist FROM jumppoints WHERE "
01019 "destination = :DEST and hostname = :HOST ;");
01020 query.bindValue(":DEST", destination);
01021 query.bindValue(":HOST", gContext->GetHostName());
01022
01023 if (query.exec() && query.isActive() && query.size() > 0)
01024 {
01025 query.next();
01026 keybind = query.value(0).toString();
01027 }
01028 else
01029 {
01030 QString inskey = keybind;
01031
01032 query.prepare("INSERT INTO jumppoints (destination, description, "
01033 "keylist, hostname) VALUES ( :DEST, :DESC, :KEYLIST, "
01034 ":HOST );");
01035 query.bindValue(":DEST", destination);
01036 query.bindValue(":DESC", description);
01037 query.bindValue(":KEYLIST", inskey);
01038 query.bindValue(":HOST", gContext->GetHostName());
01039
01040 if (!query.exec() || !query.isActive())
01041 {
01042 MythContext::DBError("Insert Jump Point", query);
01043 }
01044 }
01045 }
01046
01047 JumpData jd =
01048 { callback, destination, description, exittomain, localAction };
01049 d->destinationMap[destination] = jd;
01050
01051 BindJump(destination, keybind);
01052 }
01053
01054 void MythMainWindow::JumpTo(const QString& destination, bool pop)
01055 {
01056 if (d->destinationMap.count(destination) > 0 && d->exitmenucallback == NULL)
01057 {
01058 d->exitingtomain = true;
01059 d->popwindows = pop;
01060 d->exitmenucallback = d->destinationMap[destination].callback;
01061 QApplication::postEvent(this, new ExitToMainMenuEvent());
01062 return;
01063 }
01064 }
01065
01066 bool MythMainWindow::DestinationExists(const QString& destination) const
01067 {
01068 return (d->destinationMap.count(destination) > 0) ? true : false;
01069 }
01070
01071 void MythMainWindow::RegisterMediaHandler(const QString &destination,
01072 const QString &description,
01073 const QString &,
01074 void (*callback)(MythMediaDevice*),
01075 int mediaType,
01076 const QString &extensions)
01077 {
01078 #ifndef _WIN32
01079 if (d->mediaHandlerMap.count(destination) == 0)
01080 {
01081 MHData mhd = { callback, mediaType, destination, description };
01082 QString msg = MythMediaDevice::MediaTypeString((MediaType)mediaType);
01083 if (extensions)
01084 msg += QString(", ext(%1)").arg(extensions);
01085
01086 VERBOSE(VB_MEDIA, "Registering " + destination +
01087 " as a media handler for " + msg);
01088
01089 d->mediaHandlerMap[destination] = mhd;
01090
01091 MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
01092 if (mon && !extensions.isEmpty())
01093 mon->MonitorRegisterExtensions(mediaType, extensions);
01094 }
01095 else
01096 {
01097 VERBOSE(VB_GENERAL, QString("%1 is already registered as a media "
01098 "handler.").arg(destination));
01099 }
01100 #endif // !_WIN32
01101 }
01102
01103 void MythMainWindow::RegisterMediaPlugin(const QString &name,
01104 const QString &desc,
01105 MediaPlayCallback fn)
01106 {
01107 if (d->mediaPluginMap.count(name) == 0)
01108 {
01109 VERBOSE(VB_GENERAL, QString("Registering %1 as a media playback "
01110 "plugin.").arg(name));
01111 MPData mpd = {desc, fn};
01112 d->mediaPluginMap[name] = mpd;
01113 }
01114 else
01115 {
01116 VERBOSE(VB_GENERAL, QString("%1 is already registered as a media "
01117 "playback plugin.").arg(name));
01118 }
01119 }
01120
01121 bool MythMainWindow::HandleMedia(QString &handler, const QString &mrl,
01122 const QString &plot, const QString &title,
01123 const QString &director, int lenMins,
01124 const QString &year)
01125 {
01126 if (handler.length() < 1)
01127 handler = "Internal";
01128
01129
01130 if (d->mediaPluginMap.count(handler))
01131 {
01132 d->mediaPluginMap[handler].playFn(mrl, plot, title, director, lenMins, year);
01133 return true;
01134 }
01135
01136 return false;
01137 }
01138
01139 void MythMainWindow::AllowInput(bool allow)
01140 {
01141 d->AllowInput = allow;
01142 }
01143
01144 void MythMainWindow::mouseTimeout(void)
01145 {
01146 MythGestureEvent *e;
01147
01148
01149 if (d->gesture.recording())
01150 {
01151 d->gesture.stop();
01152 }
01153
01154
01155 e = d->gesture.gesture();
01156
01157 if (e->gesture() < MythGestureEvent::Click)
01158 QApplication::postEvent(this, e);
01159 }
01160
01161 bool MythMainWindow::eventFilter(QObject *, QEvent *e)
01162 {
01163 MythGestureEvent *ge;
01164
01165
01166 if (!d->AllowInput)
01167 return true;
01168
01169 switch (e->type())
01170 {
01171 case QEvent::KeyPress:
01172 {
01173 QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e);
01174
01175 if (currentWidget())
01176 {
01177 ke->accept();
01178 QWidget *current = currentWidget();
01179 if (current && current->isEnabled())
01180 qApp->notify(current, ke);
01181
01182
01183
01184 break;
01185 }
01186
01187 QValueVector<MythScreenStack *>::Iterator it;
01188 for (it = d->stackList.begin(); it != d->stackList.end(); ++it)
01189 {
01190 MythScreenType *top = (*it)->GetTopScreen();
01191 if (top)
01192 {
01193 if (top->keyPressEvent(ke))
01194 return true;
01195 }
01196 }
01197 break;
01198 }
01199 case QEvent::MouseButtonPress:
01200 {
01201 if (!d->gesture.recording())
01202 {
01203 d->gesture.start();
01204 d->gesture.record(dynamic_cast<QMouseEvent*>(e)->pos());
01205
01206
01207 d->gestureTimer->start(GESTURE_TIMEOUT);
01208
01209 return true;
01210 }
01211 break;
01212 }
01213 case QEvent::MouseButtonRelease:
01214 {
01215 if (d->gestureTimer->isActive())
01216 d->gestureTimer->stop();
01217
01218 if (currentWidget())
01219 break;
01220
01221 if (d->gesture.recording())
01222 {
01223 d->gesture.stop();
01224 ge = d->gesture.gesture();
01225
01226
01227 if (ge->gesture() == MythGestureEvent::Click)
01228 {
01229 MythUIType *clicked;
01230 QValueVector<MythScreenStack *>::iterator it;
01231 QPoint p = dynamic_cast<QMouseEvent*>(e)->pos();
01232
01233 delete ge;
01234
01235 for (it = d->stackList.begin(); it != d->stackList.end();
01236 it++)
01237 {
01238 MythScreenType *screen = (*it)->GetTopScreen();
01239 if (screen && (clicked = screen->GetChildAt(p)) != NULL)
01240 {
01241 clicked->gestureEvent(clicked, ge);
01242 break;
01243 }
01244 }
01245 }
01246 else
01247 QApplication::postEvent(this, ge);
01248
01249 return true;
01250 }
01251 break;
01252 }
01253 case QEvent::MouseMove:
01254 {
01255 if (d->gesture.recording())
01256 {
01257
01258 d->gestureTimer->stop();
01259 d->gestureTimer->start(GESTURE_TIMEOUT);
01260
01261 d->gesture.record(dynamic_cast<QMouseEvent*>(e)->pos());
01262 return true;
01263 }
01264 break;
01265 }
01266 case QEvent::Wheel:
01267 {
01268 QWheelEvent* qmw = dynamic_cast<QWheelEvent*>(e);
01269 int delta = qmw->delta();
01270 if (delta>0)
01271 {
01272 qmw->accept();
01273 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, 0,
01274 Qt::NoButton);
01275 QObject *key_target = getTarget(*key);
01276 if (!key_target)
01277 QApplication::postEvent(this, key);
01278 else
01279 QApplication::postEvent(key_target, key);
01280 }
01281 if (delta<0)
01282 {
01283 qmw->accept();
01284 QKeyEvent *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down,
01285 0, Qt::NoButton);
01286 QObject *key_target = getTarget(*key);
01287 if (!key_target)
01288 QApplication::postEvent(this, key);
01289 else
01290 QApplication::postEvent(key_target, key);
01291 }
01292 break;
01293 }
01294 default:
01295 break;
01296 }
01297
01298 return false;
01299 }
01300
01301 void MythMainWindow::customEvent(QCustomEvent *ce)
01302 {
01303 if (ce->type() == MythGestureEventType)
01304 {
01305 MythGestureEvent *ge = dynamic_cast<MythGestureEvent*>(ce);
01306 if (ge != NULL)
01307 {
01308 MythScreenStack *toplevel = GetMainStack();
01309 if (toplevel && !currentWidget())
01310 {
01311 MythScreenType *screen = toplevel->GetTopScreen();
01312 if (screen)
01313 screen->gestureEvent(NULL, ge);
01314 }
01315 cout << "Gesture: " << QString(*ge) << endl;
01316 }
01317 }
01318 else if (ce->type() == kExitToMainMenuEventType && d->exitingtomain)
01319 {
01320 ExitToMainMenu();
01321 }
01322 else if (ce->type() == kExternalKeycodeEventType)
01323 {
01324 ExternalKeycodeEvent *eke = (ExternalKeycodeEvent *)ce;
01325 int keycode = eke->getKeycode();
01326
01327 QKeyEvent key(QEvent::KeyPress, keycode, 0, Qt::NoButton);
01328
01329 QObject *key_target = getTarget(key);
01330 if (!key_target)
01331 QApplication::sendEvent(this, &key);
01332 else
01333 QApplication::sendEvent(key_target, &key);
01334 }
01335 #ifndef _WIN32
01336 else if (ce->type() == kMediaEventType)
01337 {
01338 MediaEvent *media_event = (MediaEvent*)ce;
01339
01340
01341
01342
01343 QMap<QString, MHData>::Iterator itr = d->mediaHandlerMap.begin();
01344 MythMediaDevice *pDev = media_event->getDevice();
01345
01346 if (pDev)
01347 {
01348 if (!pDev->isUsable())
01349 {
01350
01351
01352
01353
01354 while (itr != d->mediaHandlerMap.end())
01355 {
01356 if (itr.data().MediaType & (int)pDev->getMediaType())
01357 itr.data().callback(pDev);
01358
01359 itr++;
01360 }
01361
01362 return;
01363 }
01364
01365
01366 QWidget * activewidget = qApp->focusWidget();
01367 MythDialog * activedialog = NULL;
01368 bool iscatched = false;
01369 while (activewidget && !activedialog)
01370 {
01371 activedialog = dynamic_cast<MythDialog*>(activewidget);
01372 if (!activedialog)
01373 activewidget = activewidget->parentWidget();
01374 }
01375 if (activedialog)
01376 iscatched = activedialog->onMediaEvent(pDev);
01377
01378 MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
01379 if (iscatched || !mon->ValidateAndLock(pDev))
01380 mon = NULL;
01381
01382 while (mon && (itr != d->mediaHandlerMap.end()))
01383 {
01384 if ((itr.data().MediaType & (int)pDev->getMediaType()))
01385 {
01386 VERBOSE(VB_IMPORTANT, "Found a handler");
01387 d->exitingtomain = true;
01388 d->exitmenumediadevicecallback = itr.data().callback;
01389 d->mediadeviceforcallback = pDev;
01390 QApplication::postEvent(this, new ExitToMainMenuEvent());
01391 break;
01392 }
01393 itr++;
01394 }
01395 if (mon)
01396 mon->Unlock(pDev);
01397 }
01398 }
01399 #endif // !_WIN32
01400
01401 #if defined(USE_LIRC) || defined(USING_APPLEREMOTE)
01402 else if (ce->type() == kLircKeycodeEventType && !d->ignore_lirc_keys)
01403 {
01404 LircKeycodeEvent *lke = (LircKeycodeEvent *)ce;
01405 int keycode = lke->getKeycode();
01406
01407 if (keycode)
01408 {
01409 gContext->ResetScreensaver();
01410 if (gContext->GetScreenIsAsleep())
01411 return;
01412
01413 int mod = keycode & MODIFIER_MASK;
01414 int k = keycode & ~MODIFIER_MASK;
01415 int ascii = 0;
01416 QString text;
01417
01418 if (k & UNICODE_ACCEL)
01419 {
01420 QChar c(k & ~UNICODE_ACCEL);
01421 ascii = c.latin1();
01422 text = QString(c);
01423 }
01424
01425 mod = ((mod & Qt::CTRL) ? Qt::ControlButton : 0) |
01426 ((mod & Qt::META) ? Qt::MetaButton : 0) |
01427 ((mod & Qt::ALT) ? Qt::AltButton : 0) |
01428 ((mod & Qt::SHIFT) ? Qt::ShiftButton : 0);
01429
01430 QKeyEvent key(lke->isKeyDown() ? QEvent::KeyPress :
01431 QEvent::KeyRelease, k, ascii, mod, text);
01432
01433 QObject *key_target = getTarget(key);
01434 if (!key_target)
01435 QApplication::sendEvent(this, &key);
01436 else
01437 QApplication::sendEvent(key_target, &key);
01438 }
01439 else
01440 {
01441 cerr << "LircClient warning: attempt to convert '"
01442 << lke->getLircText() << "' to a key sequence failed. Fix"
01443 " your key mappings.\n";
01444 }
01445 }
01446 else if (ce->type() == kLircMuteEventType)
01447 {
01448 LircMuteEvent *lme = (LircMuteEvent *)ce;
01449 d->ignore_lirc_keys = lme->eventsMuted();
01450 }
01451 #endif
01452 #ifdef USE_JOYSTICK_MENU
01453 else if (ce->type() == kJoystickKeycodeEventType && !d->ignore_joystick_keys)
01454 {
01455 JoystickKeycodeEvent *jke = (JoystickKeycodeEvent *)ce;
01456 int keycode = jke->getKeycode();
01457
01458 if (keycode)
01459 {
01460 gContext->ResetScreensaver();
01461 if (gContext->GetScreenIsAsleep())
01462 return;
01463
01464 int mod = keycode & MODIFIER_MASK;
01465 int k = keycode & ~MODIFIER_MASK;
01466 int ascii = 0;
01467 QString text;
01468
01469 if (k & UNICODE_ACCEL)
01470 {
01471 QChar c(k & ~UNICODE_ACCEL);
01472 ascii = c.latin1();
01473 text = QString(c);
01474 }
01475
01476 QKeyEvent key(jke->isKeyDown() ? QEvent::KeyPress :
01477 QEvent::KeyRelease, k, ascii, mod, text);
01478
01479 QObject *key_target = getTarget(key);
01480 if (!key_target)
01481 QApplication::sendEvent(this, &key);
01482 else
01483 QApplication::sendEvent(key_target, &key);
01484 }
01485 else
01486 {
01487 cerr << "JoystickMenuClient warning: attempt to convert '"
01488 << jke->getJoystickMenuText() << "' to a key sequence failed. Fix"
01489 " your key mappings.\n";
01490 }
01491 }
01492 else if (ce->type() == kJoystickMuteEventType)
01493 {
01494 JoystickMenuMuteEvent *jme = (JoystickMenuMuteEvent *)ce;
01495 d->ignore_joystick_keys = jme->eventsMuted();
01496 }
01497 #endif
01498 else if (ce->type() == ScreenSaverEvent::kScreenSaverEventType)
01499 {
01500 ScreenSaverEvent *sse = (ScreenSaverEvent *)ce;
01501 switch (sse->getSSEventType())
01502 {
01503 case ScreenSaverEvent::ssetDisable:
01504 {
01505 gContext->DoDisableScreensaver();
01506 break;
01507 }
01508 case ScreenSaverEvent::ssetRestore:
01509 {
01510 gContext->DoRestoreScreensaver();
01511 break;
01512 }
01513 case ScreenSaverEvent::ssetReset:
01514 {
01515 gContext->DoResetScreensaver();
01516 break;
01517 }
01518 default:
01519 {
01520 cerr << "Unknown ScreenSaverEvent type: " <<
01521 sse->getSSEventType() << std::endl;
01522 }
01523 }
01524 }
01525 }
01526
01527 QObject *MythMainWindow::getTarget(QKeyEvent &key)
01528 {
01529 QObject *key_target = NULL;
01530
01531 if (!currentWidget())
01532 return key_target;
01533
01534 key_target = QWidget::keyboardGrabber();
01535
01536 if (!key_target)
01537 {
01538 QWidget *focus_widget = qApp->focusWidget();
01539 if (focus_widget && focus_widget->isEnabled())
01540 {
01541 key_target = focus_widget;
01542
01543
01544
01545 if (key.key() == d->escapekey && focus_widget->topLevelWidget())
01546 key_target = focus_widget->topLevelWidget();
01547 }
01548 }
01549
01550 if (!key_target)
01551 key_target = this;
01552
01553 return key_target;
01554 }
01555
01556 int MythMainWindow::NormalizeFontSize(int pointSize)
01557 {
01558 QPaintDeviceMetrics pdm(this);
01559
01560 float floatSize = pointSize;
01561 float desired = 100.0;
01562
01563 #ifdef USING_MINGW
01564
01565 int logicalDpiY = 100;
01566 HDC hdc = GetDC(NULL);
01567 if (hdc)
01568 {
01569 logicalDpiY = GetDeviceCaps(hdc, LOGPIXELSY);
01570 ReleaseDC(NULL, hdc);
01571 }
01572 #else
01573 int logicalDpiY = pdm.logicalDpiY();
01574 #endif
01575
01576
01577 floatSize = floatSize * desired / logicalDpiY;
01578
01579 floatSize = floatSize * d->hmult;
01580
01581 floatSize = floatSize * ((100.0 + fonTweak) / 100.0);
01582
01583 pointSize = (int)(floatSize + 0.5);
01584
01585 return pointSize;
01586 }
01587
01588 QFont MythMainWindow::CreateQFont(const QString &face, int pointSize,
01589 int weight, bool italic)
01590 {
01591 QFont font = QFont(face);
01592 if (!font.exactMatch())
01593 font = QFont(QApplication::font()).family();
01594 font.setPointSize(NormalizeFontSize(pointSize));
01595 font.setWeight(weight);
01596 font.setItalic(italic);
01597
01598 return font;
01599 }
01600
01601 QRect MythMainWindow::NormRect(const QRect &rect)
01602 {
01603 QRect ret;
01604 ret.setWidth((int)(rect.width() * d->wmult));
01605 ret.setHeight((int)(rect.height() * d->hmult));
01606 ret.moveTopLeft(QPoint((int)(rect.x() * d->wmult),
01607 (int)(rect.y() * d->hmult)));
01608 ret = ret.normalize();
01609
01610 return ret;
01611 }
01612
01613 QPoint MythMainWindow::NormPoint(const QPoint &point)
01614 {
01615 QPoint ret;
01616 ret.setX((int)(point.x() * d->wmult));
01617 ret.setY((int)(point.y() * d->hmult));
01618
01619 return ret;
01620 }
01621
01622 QSize MythMainWindow::NormSize(const QSize &size)
01623 {
01624 QSize ret;
01625 ret.setWidth((int)(size.width() * d->wmult));
01626 ret.setHeight((int)(size.height() * d->hmult));
01627
01628 return ret;
01629 }
01630
01631 int MythMainWindow::NormX(const int x)
01632 {
01633 return (int)(x * d->wmult);
01634 }
01635
01636 int MythMainWindow::NormY(const int y)
01637 {
01638 return (int)(y * d->hmult);
01639 }
01640
01641 QRect MythMainWindow::GetUIScreenRect(void)
01642 {
01643 return d->uiScreenRect;
01644 }
01645
01646