Ticket #2078: 2078-v1.patch
File 2078-v1.patch, 36.9 KB (added by , 17 years ago) |
---|
-
mythcontrols/actionset.h
58 58 QStringList GetActionStrings(const QString &context_name) const; 59 59 QString GetKeyString(const ActionID &id) const; 60 60 QStringList GetKeys(const ActionID &id) const; 61 QStringList GetContextKeys(const QString &context_name) const; 62 QStringList GetAllKeys(void) const; 61 63 QString GetDescription(const ActionID &id) const; 62 64 const ActionList& GetActions(const QString &key) const; 63 65 /// \brief Returns the appropriate container of modified actions -
mythcontrols/keygrabber.h
94 94 Q_OBJECT 95 95 96 96 public: 97 enum actions { kSave, kC ancel, };97 enum actions { kSave, kChangeView, kCancel, }; 98 98 99 99 /// \brief Create a new action window. Does not pop-up menu. 100 100 OptionsMenu(MythMainWindow *window); … … 103 103 int GetOption(void) { return ExecPopup(this,SLOT(Cancel())); } 104 104 105 105 public slots: 106 void Save(void) { done(OptionsMenu::kSave); } 107 void Cancel(void) { done(OptionsMenu::kCancel); } 106 void Save(void) { done(OptionsMenu::kSave); } 107 void ChangeView(void) { done(OptionsMenu::kChangeView); } 108 void Cancel(void) { done(OptionsMenu::kCancel); } 108 109 }; 109 110 110 111 -
mythcontrols/mythcontrols.cpp
2 2 /** 3 3 * @file mythcontrols.cpp 4 4 * @author Micah F. Galizia <mfgalizi@csd.uwo.ca> 5 * @brief Main header for mythcontrols.5 * @brief Main mythcontrols class. 6 6 * 7 7 * Note that the keybindings are fetched all at once, and cached for 8 8 * this host. This avoids pelting the database everytime the user … … 40 40 #include "mythcontrols.h" 41 41 #include "keygrabber.h" 42 42 43 static QString key_to_display(const QString &key);44 static QString display_to_key(const QString &key);45 46 43 #define LOC QString("MythControls: ") 47 44 #define LOC_ERR QString("MythControls, Error: ") 48 45 … … 53 50 */ 54 51 MythControls::MythControls(MythMainWindow *parent, bool &ok) 55 52 : MythThemedDialog(parent, "controls", "controls-", "controls"), 53 m_currentView(kActionsByContext), 56 54 m_focusedUIElement(NULL), 57 55 m_leftList(NULL), m_rightList(NULL), 58 56 m_description(NULL), … … 71 69 m_rightListType = kActionList; 72 70 73 71 LoadData(gContext->GetHostName()); 74 RefreshKeyInformation();75 72 73 /* start off with the actions by contexts view */ 74 m_currentView = kActionsByContext; 75 SetListContents(m_leftList, m_bindings->GetContexts(), true); 76 UpdateRightList(); 77 76 78 connect(m_leftList, SIGNAL(itemSelected( UIListBtnTypeItem*)), 77 79 this, SLOT( LeftSelected( UIListBtnTypeItem*))); 78 80 connect(m_rightList, SIGNAL(itemSelected( UIListBtnTypeItem*)), … … 221 223 RefreshKeyInformation(); 222 224 } 223 225 226 /// \brief Chagne the view. 227 void MythControls::ChangeView(void) 228 { 229 ViewMenu popup(gContext->GetMainWindow(), m_currentView); 230 QStringList contents; 231 232 switch(popup.GetOption()) 233 { 234 case ViewMenu::kContextAction: 235 m_currentView = kActionsByContext; 236 contents = m_bindings->GetContexts(); 237 break; 238 case ViewMenu::kContextKey: 239 m_currentView = kKeysByContext; 240 contents = m_bindings->GetContexts(); 241 break; 242 case ViewMenu::kKeyContext: 243 m_currentView = kContextsByKey; 244 contents = m_bindings->GetKeys(); 245 break; 246 default: 247 break; 248 } 249 250 SetListContents(m_leftList, contents, true); 251 RefreshKeyInformation(); 252 UpdateRightList(); 253 254 if (m_focusedUIElement != m_leftList) 255 { 256 m_focusedUIElement->looseFocus(); 257 m_focusedUIElement = m_leftList; 258 m_focusedUIElement->takeFocus(); 259 } 260 } 261 224 262 void MythControls::keyPressEvent(QKeyEvent *e) 225 263 { 226 264 bool handled = false; … … 238 276 m_focusedUIElement->looseFocus(); 239 277 240 278 OptionsMenu popup(gContext->GetMainWindow()); 241 if (OptionsMenu::kSave == popup.GetOption())242 Save();243 279 280 switch(popup.GetOption()) 281 { 282 case OptionsMenu::kSave: 283 Save(); 284 break; 285 case OptionsMenu::kChangeView: 286 ChangeView(); 287 break; 288 default: 289 break; 290 } 291 244 292 m_focusedUIElement->takeFocus(); 245 293 } 246 294 else if (action == "SELECT") … … 327 375 else if (m_focusedUIElement == m_rightList) 328 376 m_rightList->MoveDown(UIListBtnType::MovePage); 329 377 } 330 else if (action == "1")331 {332 if ((m_leftListType != kContextList) ||333 (m_rightListType != kActionList))334 {335 m_leftListType = kContextList;336 m_rightListType = kActionList;337 UpdateLists();338 339 if (m_focusedUIElement != m_leftList)340 {341 ChangeListFocus(m_leftList,342 (m_focusedUIElement == m_rightList) ?343 m_rightList : NULL);344 }345 }346 else347 {348 handled = false;349 }350 }351 else if (action == "2")352 {353 if ((m_leftListType != kContextList) ||354 (m_rightListType != kKeyList))355 {356 m_leftListType = kContextList;357 m_rightListType = kKeyList;358 UpdateLists();359 360 if (m_focusedUIElement != m_leftList)361 {362 ChangeListFocus(m_leftList,363 (m_focusedUIElement == m_rightList) ?364 m_rightList : NULL);365 }366 }367 else368 {369 handled = false;370 }371 }372 else if (action == "3")373 {374 if ((m_leftListType != kKeyList) ||375 (m_rightListType != kContextList))376 {377 m_leftListType = kKeyList;378 m_rightListType = kContextList;379 UpdateLists();380 381 if (m_focusedUIElement != m_leftList)382 {383 ChangeListFocus(m_leftList,384 (m_focusedUIElement == m_rightList) ?385 m_rightList : NULL);386 }387 }388 else389 {390 handled = false;391 }392 }393 378 else 394 379 { 395 380 handled = false; … … 397 382 } 398 383 399 384 if (!handled) 400 { 401 handled |= (!escape && JumpTo(e)); 402 if (!handled) 403 MythThemedDialog::keyPressEvent(e); 404 } 385 MythThemedDialog::keyPressEvent(e); 405 386 } 406 387 407 /** \fn MythControls::JumpTo(QKeyEvent*)408 * \brief Jump to a particular key binding409 * \param e key event to use as jump410 */411 bool MythControls::JumpTo(QKeyEvent *e)412 {413 UIListBtnType *list = NULL;414 415 list = ((m_focusedUIElement == m_leftList) &&416 (m_leftListType == kKeyList)) ? m_leftList : list;417 list = ((m_focusedUIElement == m_rightList) &&418 (m_rightListType == kKeyList)) ? m_rightList : list;419 420 if (!list)421 return false;422 423 QString key = e->text();424 if (key.left(6) == "remote")425 {426 key = key_to_display(key);427 }428 else429 {430 key = QString(QKeySequence(e->key()));431 432 if (key.isEmpty())433 return false;434 435 QString modifiers = "";436 437 if (e->state() & Qt::ShiftButton)438 modifiers += "Shift+";439 if (e->state() & Qt::ControlButton)440 modifiers += "Ctrl+";441 if (e->state() & Qt::AltButton)442 modifiers += "Alt+";443 if (e->state() & Qt::MetaButton)444 modifiers += "Meta+";445 446 key = modifiers + key;447 }448 449 uint len = 1024; // infinity450 if (list == m_rightList)451 {452 key = key + " ";453 len = key.length();454 }455 456 UIListBtnTypeItem *b;457 for (b = list->GetItemFirst(); b; b = list->GetItemNext(b))458 {459 if (b->text().left(len) == key)460 break;461 }462 463 if (!b)464 return false;465 466 int curpos = list->GetItemPos(list->GetItemCurrent());467 int newpos = list->GetItemPos(b);468 469 if (newpos > curpos)470 list->MoveDown(newpos - curpos);471 else if (newpos < curpos)472 list->MoveUp(curpos - newpos);473 474 return true;475 }476 477 388 /** \fn MythControls::LeftSelected(UIListBtnTypeItem*) 478 389 * \brief Refreshes the right list when an item in the 479 390 * left list is selected … … 482 393 { 483 394 m_leftList->refresh(); 484 395 m_rightList->blockSignals(true); 485 RefreshRightList();396 UpdateRightList(); 486 397 m_rightList->blockSignals(false); 487 398 m_rightList->refresh(); 488 399 } … … 497 408 RefreshKeyInformation(); 498 409 } 499 410 500 /** \fn MythControls::RefreshRightList(void) 501 * \brief Load the appropriate actions into the action list 411 412 /** \brief Set the contents of a list. 413 * \param list The list being changed. 414 * \param contents The contents of the list. 415 * \param arrows True to draw with arrows, otherwise arrows are not drawn. 502 416 */ 503 void MythControls::RefreshRightList(void) 417 void MythControls::SetListContents( 418 UIListBtnType *uilist, const QStringList &contents, bool arrows) 504 419 { 505 m_rightList->Reset();420 uilist->blockSignals(true); 506 421 507 if (!m_leftList->GetItemCurrent())508 return;422 // remove all strings from the current list 423 uilist->Reset(); 509 424 510 if (m_leftListType == kContextList) 425 // add each new string 426 for (size_t i = 0; i < contents.size(); i++) 511 427 { 512 if (m_rightListType == kActionList) 513 { 514 /* add all of the actions to the context list */ 515 QString context = m_leftList->GetItemCurrent()->text(); 516 QStringList *actions = m_contexts[context]; 517 if (!actions || actions->empty()) 518 { 519 VERBOSE(VB_IMPORTANT, LOC_ERR + 520 QString("Unable to find actions for context %1") 521 .arg(context)); 522 523 return; 524 } 525 526 for (uint i = 0; i < actions->size(); i++) 527 new UIListBtnTypeItem(m_rightList, (*actions)[i]); 528 } 529 else if (m_rightListType == kKeyList) 530 { 531 /* add all of the actions to the context list */ 532 QString context = m_leftList->GetItemCurrent()->text(); 533 const BindingList *list = m_contextToBindingsMap[context]; 534 if (!list) 535 { 536 VERBOSE(VB_IMPORTANT, LOC_ERR+ 537 QString("Unable to find keys for context %1") 538 .arg(context)); 539 540 return; 541 } 542 543 BindingList::const_iterator it = list->begin(); 544 for (; it != list->end(); ++it) 545 { 546 new UIListBtnTypeItem( 547 m_rightList, 548 key_to_display((*it)->key) + " => " + (*it)->action); 549 } 550 } 428 UIListBtnTypeItem *item = new UIListBtnTypeItem(uilist, contents[i]); 429 item->setDrawArrow(arrows); 551 430 } 552 else if ((m_leftListType == kKeyList) && (m_rightListType == kContextList))553 {554 QString key = display_to_key(m_leftList->GetItemCurrent()->text());555 const BindingList *list = m_keyToBindingsMap[key];556 if (!list)557 {558 VERBOSE(VB_IMPORTANT, LOC + QString(559 "Unable to find actions for key %1").arg(key));560 return;561 }562 431 563 BindingList::const_iterator it = list->begin(); 564 const Binding *b = *it; 565 for (uint i = 0; i < m_sortedContexts.size(); i++) 566 { 567 const QString context = m_sortedContexts[i]; 568 QString action = "<none>"; 569 570 if (b && b->context == context) 571 { 572 action = b->action; 573 ++it; 574 b = (it != list->end()) ? *it : NULL; 575 } 576 577 new UIListBtnTypeItem(m_rightList, context + " => " + action); 578 } 579 } 432 uilist->blockSignals(false); 433 uilist->refresh(); 580 434 } 581 435 582 QString MythControls::RefreshKeyInformationKeyList(void) 436 /** \brief Update the right list. */ 437 void MythControls::UpdateRightList(void) 583 438 { 584 if ((m_leftListType != kKeyList) && (m_rightListType != kKeyList))585 return "";439 // get the selected item in the right list. 440 QString rtstr = m_leftList->GetItemCurrent()->text(); 586 441 587 QString action = GetCurrentAction(); 588 QString context = GetCurrentContext(); 589 590 if (action.isEmpty()) 591 return ""; 592 593 QString desc = m_bindings->GetActionDescription(context, action); 594 595 BindingList *list = NULL; 596 if (m_leftListType == kKeyList && m_rightListType == kContextList) 442 switch(m_currentView) 597 443 { 598 list = m_keyToBindingsMap[display_to_key(GetCurrentKey())]; 599 } 600 else if (m_leftListType == kContextList && m_rightListType == kKeyList) 601 { 602 list = m_contextToBindingsMap[context]; 603 } 604 605 if (!list) 606 return desc; 607 608 QString searchKey = QString::null; 609 if (m_rightListType == kContextList) 610 { 611 searchKey = context; 612 } 613 else if (m_rightListType == kActionList) 614 { 615 searchKey = action; 616 } 617 else if (m_rightListType == kKeyList) 618 { 619 searchKey = display_to_key(GetCurrentKey()); 620 } 621 622 const Binding *binding = NULL; 623 for (BindingList::const_iterator it = list->begin(); 624 it != list->end(); ++it) 625 { 626 switch (m_rightListType) 627 { 628 case kContextList: 629 if ((*it)->context == searchKey) 630 binding = *it; 631 break; 632 case kActionList: 633 if ((*it)->action == searchKey) 634 binding = *it; 635 break; 636 case kKeyList: 637 if ((*it)->key == searchKey) 638 binding = *it; 639 break; 640 } 641 642 if (binding) 444 case kActionsByContext: 445 SetListContents(m_rightList, *(m_contexts[rtstr])); 643 446 break; 447 case kKeysByContext: 448 SetListContents(m_rightList, m_bindings->GetContextKeys(rtstr)); 449 break; 450 case kContextsByKey: 451 SetListContents(m_rightList, m_bindings->GetKeyContexts(rtstr)); 452 break; 644 453 } 645 646 if (!binding)647 return desc;648 649 650 if (desc.isEmpty() && (context != binding->contextFrom))651 {652 desc = m_bindings->GetActionDescription(653 binding->contextFrom, action);654 }655 656 desc += "\n" + tr("Binding comes from %1 context")657 .arg(binding->contextFrom);658 659 return desc;660 454 } 661 455 662 456 /** \fn MythControls::RefreshKeyInformation(void) … … 674 468 return; 675 469 } 676 470 677 if ((m_leftListType == kKeyList) || (m_rightListType == kKeyList))678 {679 m_description->SetText(RefreshKeyInformationKeyList());680 return;681 }682 683 471 const QString context = GetCurrentContext(); 684 472 const QString action = GetCurrentAction(); 685 473 … … 690 478 for (uint i = 0; (i < keys.count()) && 691 479 (i < Action::kMaximumNumberOfBindings); i++) 692 480 { 693 m_actionButtons[i]->setText(key _to_display(keys[i]));481 m_actionButtons[i]->setText(keys[i]); 694 482 } 695 483 } 696 484 … … 731 519 QString MythControls::GetCurrentAction(void) const 732 520 { 733 521 if (m_leftListType == kActionList) 734 return m_leftList->GetItemCurrent()->text(); 522 { 523 if (m_leftList && m_leftList->GetItemCurrent()) 524 return QDeepCopy<QString>(m_leftList->GetItemCurrent()->text()); 525 return QString::null; 526 } 735 527 736 528 if (m_focusedUIElement == m_leftList) 737 529 return QString::null; 738 530 531 if (!m_rightList || !m_rightList->GetItemCurrent()) 532 return QString::null; 533 739 534 QString desc = m_rightList->GetItemCurrent()->text(); 740 535 if (m_leftListType == kContextList && m_rightListType == kActionList) 741 return desc;536 return QDeepCopy<QString>(desc); 742 537 743 538 int loc = desc.find(" => "); 744 539 if (loc == -1) … … 794 589 return desc.mid(loc + 4); 795 590 } 796 591 797 /** \fn MythControls::Load All(const QString&)592 /** \fn MythControls::LoadData(const QString&) 798 593 * \brief Load the settings for a particular host. 799 594 * \param hostname The host to load settings for. 800 595 */ … … 804 599 m_bindings = new KeyBindings(hostname); 805 600 m_sortedContexts = m_bindings->GetContexts(); 806 601 807 m_sortedKeys.clear();808 809 602 /* Alphabetic order, but jump and global at the top */ 810 603 m_sortedContexts.sort(); 811 604 m_sortedContexts.remove(ActionSet::kJumpContext); … … 822 615 actions.sort(); 823 616 m_contexts.insert(m_sortedContexts[i], new QStringList(actions)); 824 617 } 825 826 RefreshKeyBindings();827 UpdateLists();828 618 } 829 619 830 620 /** \fn MythControls::DeleteKey(void) … … 846 636 return; 847 637 } 848 638 849 BindingList *list = m_keyToBindingsMap[key]; 850 Binding *binding = NULL; 639 ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this binding?")); 851 640 852 for (BindingList::iterator it = list->begin(); it != list->end(); ++it) 853 { 854 Binding *b = *it; 855 if (b->context == context) 856 binding = b; 857 } 858 859 if (!binding) 860 { 861 InvalidBindingPopup popup(gContext->GetMainWindow()); 862 popup.GetOption(); 641 if (popup.GetOption() != ConfirmMenu::kConfirm) 863 642 return; 864 }865 643 866 if ( binding->contextFrom != context)644 if (!m_bindings->RemoveActionKey(context, action, key)) 867 645 { 868 ConfirmMenu popup(gContext->GetMainWindow(),869 tr("Delete this key binding from context %1?")870 .arg(binding->contextFrom));871 872 if (popup.GetOption() != ConfirmMenu::kConfirm)873 return;874 }875 else876 {877 ConfirmMenu popup(gContext->GetMainWindow(),878 tr("Delete this binding?"));879 880 if (popup.GetOption() != ConfirmMenu::kConfirm)881 return;882 }883 884 if (!m_bindings->RemoveActionKey(binding->contextFrom, action, key))885 {886 646 InvalidBindingPopup popup(gContext->GetMainWindow()); 887 647 popup.GetOption(); 888 648 return; 889 649 } 890 650 891 RefreshKeyBindings();892 651 RefreshKeyInformation(); 893 652 } 894 653 … … 977 736 m_bindings->AddActionKey(context, action, key); 978 737 } 979 738 980 RefreshKeyBindings();981 739 RefreshKeyInformation(); 982 740 } 983 741 984 /** \fn MythControls::AddBindings(QDict<Binding>&, const QString&, 985 const QString&, int) 986 * \brief Add bindings to QDict<Binding> for specified context 987 * \param bindings the QDict to which to add the bindings 988 * \param context the context to grab keybindings from 989 * \param contextParent the context whose keybindings are being calculated 990 * \param bindlevel the bind level associated with this context 742 /** \fn ViewMenu::ViewMenu(MythMainWindow*, ViewType) 743 * \brief Creates a new view dialog box. 744 * \param window The main MythTV window. 745 * \param first The first button's caption 746 * \param second The second button's caption 991 747 */ 992 void MythControls::AddBindings(QDict<Binding> &bindings, 993 const QString &context, 994 const QString &contextParent, 995 int bindlevel) 748 ViewMenu::ViewMenu(MythMainWindow *window, ViewType current) : 749 MythPopupBox(window, "mcviewmenu") 996 750 { 997 QStringList actions = m_bindings->GetActions(context);751 addLabel(tr("Change View"), Large, false); 998 752 999 for (uint i = 0; i < actions.size(); i++)753 switch(current) 1000 754 { 1001 QString action = actions[i]; 1002 QStringList keys = m_bindings->GetActionKeys(context, action); 1003 1004 for (uint j = 0; j < keys.size(); j++) 1005 { 1006 Binding *b = bindings.find(keys[j]); 1007 1008 if (!b) 1009 { 1010 b = new Binding(keys[j], contextParent, 1011 context, action, bindlevel); 1012 1013 bindings.insert(keys[j], b); 1014 } 1015 else if (b->bindlevel == bindlevel) 1016 { 1017 b->action += ", " + action; 1018 } 1019 } 1020 } 1021 } 1022 1023 /** \fn MythControls::GetKeyBindings(const QString&) 1024 * \brief Create a BindingList for the specified context 1025 * \param context the context for which a BindingList should be created 1026 * \return a BindingList with "auto delete" property enabled. 1027 */ 1028 BindingList *MythControls::GetKeyBindings(const QString &context) 1029 { 1030 QDict<Binding> bindings; 1031 for (uint i = 0; i < m_sortedContexts.size(); i++) 1032 AddBindings(bindings, m_sortedContexts[i], context, i); 1033 1034 QStringList keys; 1035 for (QDictIterator<Binding> it(bindings); it.current(); ++it) 1036 keys.append(it.currentKey()); 1037 1038 SortKeyList(keys); 1039 1040 BindingList *blist = new BindingList(); 1041 blist->setAutoDelete(true); 1042 1043 QStringList::const_iterator kit = keys.begin(); 1044 for (; kit != keys.end(); ++kit) 1045 blist->append(bindings[*kit]); 1046 1047 return blist; 1048 } 1049 1050 /** \fn MythControls::RefreshKeyBindings(void) 1051 * \brief Refresh binding information 1052 */ 1053 void MythControls::RefreshKeyBindings(void) 1054 { 1055 m_contextToBindingsMap.clear(); 1056 m_keyToBindingsMap.clear(); 1057 m_contextToBindingsMap.setAutoDelete(true); 1058 m_keyToBindingsMap.setAutoDelete(true); 1059 1060 for (uint i = 0; i < m_sortedContexts.size(); i++) 1061 { 1062 QString context = m_sortedContexts[i]; 1063 BindingList *list = GetKeyBindings(context); 1064 m_contextToBindingsMap.insert(context, list); 1065 1066 BindingList::const_iterator it = list->begin(); 1067 for (; it != list->end(); ++it) 1068 { 1069 BindingList *list = m_keyToBindingsMap.find((*it)->key); 1070 1071 if (!list) 1072 { 1073 list = new BindingList(); 1074 m_keyToBindingsMap.insert((*it)->key, list); 1075 } 1076 1077 m_sortedKeys.append((*it)->key); 1078 list->append(*it); 1079 } 1080 } 1081 1082 SortKeyList(m_sortedKeys); 1083 } 1084 1085 /** \fn MythControls::SortKeyList(QStringList&) 1086 * \brief Sort a list of keys, removing duplicates 1087 * \param keys the list of keys to sort 1088 */ 1089 void MythControls::SortKeyList(QStringList &keys) 1090 { 1091 QStringList tmp; 1092 QStringList::const_iterator it = keys.begin(); 1093 for (; it != keys.end(); ++it) 1094 { 1095 QString key = *it; 1096 QString keydesc = (key.left(6) == "remote") ? "0 " : "3 "; 1097 1098 keydesc = ((key.length() > 1) && !(key.left(6) == "remote") && 1099 (key.find("+", 1) >= 0)) ? "4 " : keydesc; 1100 1101 if (key.length() == 1) 1102 { 1103 QChar::Category cat = key[0].category(); 1104 keydesc = (QChar::Letter_Uppercase == cat) ? "2 " : "5 "; 1105 keydesc = (QChar::Number_DecimalDigit == cat) ? "1 " : keydesc; 1106 } 1107 1108 tmp.push_back(keydesc + key); 1109 } 1110 tmp.sort(); 1111 1112 keys.clear(); 1113 1114 QString prev = QString::null; 1115 for (it = tmp.begin(); it != tmp.end(); ++it) 1116 { 1117 QString cur = (*it).mid(2); 1118 if (cur != prev) 1119 { 1120 keys.append(cur); 1121 prev = cur; 1122 } 1123 } 1124 } 1125 1126 /// NOTE: This can not be a static method because the QObject::tr() 1127 /// translations do not work reliably in static initializers. 1128 QString MythControls::GetTypeDesc(ListType type) const 1129 { 1130 switch (type) 1131 { 1132 case kContextList: 1133 return tr("Contexts"); 755 case kKeysByContext: 756 addButton(tr("Actions By Context"), 757 this, SLOT(ActionsByContext())); 758 addButton(tr("Contexts By Key"), 759 this, SLOT(ContextsByKey())); 1134 760 break; 1135 case kKeyList: 1136 return tr("Keys"); 761 case kContextsByKey: 762 addButton(tr("Actions By Context"), 763 this, SLOT(ActionsByContext())); 764 addButton(tr("Keys By Context"), 765 this, SLOT(KeysByContext())); 1137 766 break; 1138 case kActionList:1139 return tr("Actions");1140 break;1141 767 default: 1142 return ""; 768 addButton(tr("Keys By Context"), 769 this, SLOT(KeysByContext())); 770 addButton(tr("Contexts By Key"), 771 this, SLOT(ContextsByKey())); 772 break; 1143 773 } 1144 }1145 774 1146 /** \fn MythControls::UpdateLists(void) 1147 * \brief Redisplays both the left and right lists and fixes focus issues. 1148 */ 1149 void MythControls::UpdateLists(void) 1150 { 1151 m_rightList->blockSignals(true); 1152 m_leftList->blockSignals(true); 1153 m_leftList->Reset(); 1154 1155 if (m_leftListType == kContextList) 1156 { 1157 for (uint i = 0; i < m_sortedContexts.size(); i++) 1158 { 1159 UIListBtnTypeItem *item = new UIListBtnTypeItem( 1160 m_leftList, m_sortedContexts[i]); 1161 1162 item->setDrawArrow(true); 1163 } 1164 } 1165 else if (m_leftListType == kKeyList) 1166 { 1167 for (uint i = 0; i < m_sortedKeys.size(); i++) 1168 { 1169 UIListBtnTypeItem *item = new UIListBtnTypeItem( 1170 m_leftList, key_to_display(m_sortedKeys[i])); 1171 1172 item->setDrawArrow(true); 1173 } 1174 } 1175 1176 RefreshRightList(); 1177 1178 m_rightList->blockSignals(false); 1179 m_leftList->blockSignals(false); 1180 1181 m_leftList->refresh(); 1182 m_rightList->refresh(); 1183 1184 if (m_leftDescription) 1185 m_leftDescription->SetText(GetTypeDesc(m_leftListType)); 1186 1187 if (m_rightDescription) 1188 m_rightDescription->SetText(GetTypeDesc(m_rightListType)); 775 addButton(tr("Cancel"), this, SLOT(Cancel()))->setFocus(); 1189 776 } 1190 777 1191 static QString key_to_display(const QString &key)1192 {1193 if (key.left(6) == "remote")1194 return "[" + key.mid(6) + "]";1195 1196 return key;1197 }1198 1199 static QString display_to_key(const QString &key)1200 {1201 if (key.left(1) == "[" && key != "[")1202 return "remote" + key.mid(1, key.length() - 2);1203 1204 return key;1205 }1206 1207 778 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythcontrols/keybindings.cpp
49 49 LoadJumppoints(); 50 50 } 51 51 52 /** \brief Returns a list of all keys bound to an action. */ 53 QStringList KeyBindings::GetKeys(void) const 54 { 55 return m_actionSet.GetAllKeys(); 56 } 57 52 58 /** \fn KeyBindings::GetContexts(void) const 53 59 * \brief Returns a list of the context names. 54 60 * \note The returned list is a copy and can be modified without side-effects. 55 61 */ 56 62 QStringList KeyBindings::GetContexts(void) const 57 63 { 58 return QDeepCopy<QStringList>(m_actionSet.GetContextStrings()); 64 QStringList ctxts = 65 QDeepCopy<QStringList>(m_actionSet.GetContextStrings()); 66 ctxts.sort(); 67 return ctxts; 59 68 } 60 69 61 70 /** \fn KeyBindings::GetActions(const QString&) const … … 95 104 (m_actionSet.GetKeys(ActionID(context_name, action_name))); 96 105 } 97 106 107 /** \fn KeyBindings::GetContextKeys(const QString &) const 108 * \brief Get the keys within a context. 109 * \param context The context name. 110 * \return A list of the keys in the context. 111 */ 112 QStringList KeyBindings::GetContextKeys(const QString &context) const 113 { 114 return m_actionSet.GetContextKeys(context); 115 } 116 117 /** \fn KeyBindings::GetKeyContexts(const QString &) const 118 * \brief Get the context names in which a key is bound. 119 * \return A list of context names in which a key is bound. 120 */ 121 QStringList KeyBindings::GetKeyContexts(const QString &key) const 122 { 123 ActionList actions = m_actionSet.GetActions(key); 124 QStringList contexts; 125 126 for (size_t i = 0; i < actions.size(); i++) 127 { 128 QString context = actions[i].GetContext(); 129 if (!contexts.contains(context)) 130 contexts.push_back(context); 131 } 132 133 return contexts; 134 } 135 98 136 /** \fn KeyBindings::GetActionDescription(const QString&,const QString&) const 99 137 * \brief Get an action's description. 100 138 * \param context_name The name of the context. -
mythcontrols/actionset.cpp
62 62 63 63 ActionList &ids = m_keyToActionMap[key]; 64 64 ids.push_back(id); 65 SetModifiedFlag(id, true); 65 SetModifiedFlag(id, true); 66 66 67 67 return true; 68 68 } … … 75 75 * 76 76 * \param id The action identifier to remove from. 77 77 * \param key The key to remove. 78 * 79 * \todo Remove the actionlist from the m_keyToActionMap if the key 80 * is no longer bound to any actions. 78 81 */ 79 82 bool ActionSet::Remove(const ActionID &id, const QString &key) 80 83 { … … 87 90 return false; 88 91 89 92 m_keyToActionMap[key].remove(id); 93 94 // remove the key if there isn't anything bound to it. 95 if (m_keyToActionMap[key].isEmpty()) 96 m_keyToActionMap.remove(key); 97 90 98 SetModifiedFlag(id, true); 91 99 92 return true; 100 return true; 93 101 } 94 102 95 103 /** \fn ActionSet::Replace(const ActionID&,const QString&,const QString&) … … 118 126 m_keyToActionMap[newkey].push_back(id); 119 127 SetModifiedFlag(id, true); 120 128 121 return true; 129 return true; 122 130 } 123 131 124 132 /** \fn ActionSet::SetModifiedFlag(const ActionID&, bool) … … 242 250 return keys; 243 251 } 244 252 253 QStringList ActionSet::GetContextKeys(const QString & context_name) const 254 { 255 QStringList keys; 256 Context *c = m_contexts[context_name]; 257 258 QDictIterator<Action> it(*c); 259 for (;it.current(); ++it) 260 { 261 QStringList akeys = (*it)->GetKeys(); 262 for (size_t i = 0; i < akeys.size(); i++) 263 { 264 keys.append(akeys[i]); 265 } 266 keys.sort(); 267 } 268 269 return keys; 270 } 271 272 /** \brief Get all keys (from every context) to which an action is bound. 273 */ 274 QStringList ActionSet::GetAllKeys(void) const 275 { 276 QStringList keys; 277 278 QMap<QString, ActionList>::ConstIterator it; 279 280 for (it = m_keyToActionMap.begin(); it != m_keyToActionMap.end(); ++it) 281 keys.push_back(it.key()); 282 283 return keys; 284 } 285 245 286 /** \fn ActionSet::GetDescription(const ActionID&) const 246 287 * \brief Returns the description of an action by its identifier. 247 288 * (note: result not thread-safe) -
mythcontrols/mythcontrols.h
29 29 30 30 #include "keybindings.h" 31 31 32 class Binding 32 33 typedef enum { kActionsByContext, kKeysByContext, kContextsByKey, } ViewType; 34 35 /** \class ViewMenu 36 * \brief Prompts the user to change the view. 37 */ 38 class ViewMenu : public MythPopupBox 33 39 { 40 Q_OBJECT 41 34 42 public: 35 Binding(const QString &_key, const QString &_context, 36 const QString &_contextFrom, const QString &_action, 37 int _bindlevel) : 38 key(_key), context(_context), 39 contextFrom(_contextFrom), action(_action), bindlevel(_bindlevel) {} 43 ViewMenu(MythMainWindow *window, ViewType current); 40 44 41 public: 42 QString key; 43 QString context; 44 QString contextFrom; 45 QString action; 46 int bindlevel; 45 /// \brief Execute the option popup. 46 int GetOption(void) { return ExecPopup(this, SLOT(Cancel())); } 47 48 /// \brief The available views 49 enum actions { kContextAction, kContextKey, kKeyContext, kCancel, }; 50 51 public slots: 52 void ActionsByContext(void) { done(ViewMenu::kContextAction); } 53 void KeysByContext(void) { done(ViewMenu::kContextKey); } 54 void ContextsByKey(void) { done(ViewMenu::kKeyContext); } 55 void Cancel(void) { done(ViewMenu::kCancel); } 47 56 }; 48 typedef QPtrList<Binding> BindingList;49 57 50 58 /** \class MythControls 51 59 * \brief The myth controls configuration class. … … 77 85 // Commands 78 86 bool LoadUI(void); 79 87 void RefreshKeyInformation(void); 80 QString RefreshKeyInformationKeyList(void);81 void RefreshRightList(void);82 void UpdateLists(void);83 88 void LoadData(const QString &hostname); 84 89 void ChangeButtonFocus(int direction); 85 90 void ChangeListFocus(UIListBtnType *focus, UIListBtnType *unfocus); 86 void AddBindings(QDict<Binding> &bindings, const QString &context, 87 const QString &contextParent, int bindlevel); 91 void ChangeView(void); 92 void SetListContents(UIListBtnType *uilist, 93 const QStringList & contents, 94 bool arrows = false); 95 void UpdateRightList(void); 88 96 89 97 // Gets 90 BindingList *GetKeyBindings(const QString &context);91 98 uint GetCurrentButton(void) const; 92 99 93 100 // Functions … … 99 106 void DeleteKey(void); 100 107 void LeftSelected(UIListBtnTypeItem *item); 101 108 void RightSelected(UIListBtnTypeItem *item); 102 void SortKeyList(QStringList &keys);103 void RefreshKeyBindings(void);104 109 bool JumpTo(QKeyEvent *e); 105 110 /// \brief Save the bindings to the Database. 106 111 void Save(void) { m_bindings->CommitChanges(); } 107 112 108 113 private: 114 ViewType m_currentView; 109 115 UIType *m_focusedUIElement; 110 116 UIListBtnType *m_leftList; 111 117 UIListBtnType *m_rightList; … … 117 123 KeyBindings *m_bindings; 118 124 LayerSet *m_container; 119 125 QStringList m_sortedContexts; ///< sorted list of contexts 120 QStringList m_sortedKeys; ///< sorted list of keys121 126 QDict<QStringList> m_contexts; ///< actions for a given context 122 QDict<BindingList> m_contextToBindingsMap;123 QDict<BindingList> m_keyToBindingsMap;124 127 ListType m_leftListType; 125 128 ListType m_rightListType; 126 129 }; -
mythcontrols/keybindings.h
59 59 void CommitChanges(void); 60 60 61 61 // Gets 62 QStringList GetKeys(void) const; 62 63 QStringList GetContexts(void) const; 63 64 QStringList GetActions(const QString &context) const; 64 65 void GetKeyActions(const QString &key, ActionList &list) const; 65 66 QStringList GetActionKeys(const QString &context_name, 66 67 const QString &action_name) const; 68 QStringList GetContextKeys(const QString &context) const; 69 QStringList GetKeyContexts(const QString &key) const; 67 70 QString GetActionDescription(const QString &context_name, 68 71 const QString &action_name) const; 69 72 bool HasMandatoryBindings(void) const; -
mythcontrols/controls-ui.xml
46 46 <container name="controls"> 47 47 <area>20,20,780,450</area> 48 48 49 <textarea name="options" draworder="1" align="center">50 <font>options</font>51 <area>0,0,780,30</area>52 <value>(1) Contexts / Actions (2) Contexts / Keys (3) Keys / Contexts</value>53 </textarea>54 55 49 <textarea name="leftdesc" draworder="1" align="center"> 56 50 <font>info</font> 57 <area>0, 40,370,20</area>51 <area>0,0,370,20</area> 58 52 <value>Contexts</value> 59 53 </textarea> 60 54 61 55 <listbtnarea name="leftlist" draworder="0"> 62 <area>0, 60,370,380</area>56 <area>0,30,370,420</area> 63 57 <gradient type="unselected" start="#505050" end="#000000" alpha="100"/> 64 58 <gradient type="selected" start="#52CA38" end="#349838" alpha="255"/> 65 59 <fcnfont name="active" function="active"/> … … 69 63 70 64 <textarea name="rightdesc" draworder="1" align="center"> 71 65 <font>info</font> 72 <area>390, 40,370,20</area>66 <area>390,0,370,20</area> 73 67 <value>Actions</value> 74 68 </textarea> 75 69 76 70 <listbtnarea name="rightlist" draworder="0"> 77 <area>390, 60,370,380</area>71 <area>390,30,370,420</area> 78 72 <gradient type="unselected" start="#505050" end="#000000" alpha="100"/> 79 73 <gradient type="selected" start="#52CA38" end="#349838" alpha="255"/> 80 74 <fcnfont name="active" function="active"/> -
mythcontrols/keygrabber.cpp
126 126 { 127 127 addLabel(tr("Options"), Large, false); 128 128 addButton(QObject::tr("Save"), this, SLOT(Save())); 129 addButton(QObject::tr("Change View"), this, SLOT(ChangeView())); 129 130 addButton(QObject::tr("Cancel"), this, SLOT(Cancel()))->setFocus(); 130 131 } 131 132