Ticket #2078: ui_and_logic_again.diff
File ui_and_logic_again.diff, 36.5 KB (added by , 19 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 … … 80 82 static const QString kGlobalContext; 81 83 82 84 private: 83 QMap<QString, ActionList> m_keyToActionMap;84 QDict<Context> m_contexts;85 ActionList m_modified;85 QMap<QString, ActionList> m_keyToActionMap; 86 QDict<Context> m_contexts; 87 ActionList m_modified; 86 88 }; 87 89 88 90 #endif /* ACTIONSET_H */ -
mythcontrols/keygrabber.h
25 25 // MythTV headers 26 26 #include <mythtv/mythdialogs.h> 27 27 28 29 28 /** \class KeyGrabPopupBox 30 29 * \brief Captures a key. 31 30 * … … 94 93 Q_OBJECT 95 94 96 95 public: 97 enum actions { kSave, kC ancel, };96 enum actions { kSave, kChangeView, kCancel, }; 98 97 99 98 /// \brief Create a new action window. Does not pop-up menu. 100 99 OptionsMenu(MythMainWindow *window); … … 103 102 int GetOption(void) { return ExecPopup(this,SLOT(Cancel())); } 104 103 105 104 public slots: 106 void Save(void) { done(OptionsMenu::kSave); } 107 void Cancel(void) { done(OptionsMenu::kCancel); } 105 void Save(void) { done(OptionsMenu::kSave); } 106 void ChangeView(void) { done(OptionsMenu::kChangeView); } 107 void Cancel(void) { done(OptionsMenu::kCancel); } 108 108 }; 109 109 110 110 -
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 … … 37 37 #include <mythtv/mythdialogs.h> 38 38 39 39 // MythControls headers 40 #include "mythcontrols.h"41 40 #include "keygrabber.h" 41 #include "mythcontrols.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"), 56 m_ focusedUIElement(NULL),53 m_currentView(kActionsByContext), m_focusedUIElement(NULL), 57 54 m_leftList(NULL), m_rightList(NULL), 58 55 m_description(NULL), 59 56 m_leftDescription(NULL), m_rightDescription(NULL), 60 m_bindings(NULL), m_container(NULL) 57 m_bindings(NULL), m_container(NULL) 61 58 { 62 59 bzero(m_actionButtons, sizeof(void*) * Action::kMaximumNumberOfBindings); 63 60 m_contexts.setAutoDelete(true); … … 71 68 m_rightListType = kActionList; 72 69 73 70 LoadData(gContext->GetHostName()); 74 RefreshKeyInformation();75 71 72 /* start off with the actions by contexts view */ 73 m_currentView = kActionsByContext; 74 SetListContents(m_leftList, m_bindings->GetContexts(), true); 75 UpdateRightList(); 76 76 77 connect(m_leftList, SIGNAL(itemSelected( UIListBtnTypeItem*)), 77 78 this, SLOT( LeftSelected( UIListBtnTypeItem*))); 78 79 connect(m_rightList, SIGNAL(itemSelected( UIListBtnTypeItem*)), … … 221 222 RefreshKeyInformation(); 222 223 } 223 224 225 /// \brief Chagne the view. 226 void MythControls::ChangeView(void) 227 { 228 ViewMenu popup(gContext->GetMainWindow(), m_currentView); 229 QStringList contents; 230 231 switch(popup.GetOption()) 232 { 233 case ViewMenu::kContextAction: 234 m_currentView = kActionsByContext; 235 contents = m_bindings->GetContexts(); 236 break; 237 case ViewMenu::kContextKey: 238 m_currentView = kKeysByContext; 239 contents = m_bindings->GetContexts(); 240 break; 241 case ViewMenu::kKeyContext: 242 m_currentView = kContextsByKey; 243 contents = m_bindings->GetKeys(); 244 break; 245 default: 246 break; 247 } 248 249 SetListContents(m_leftList, contents, true); 250 RefreshKeyInformation(); 251 UpdateRightList(); 252 253 if (m_focusedUIElement != m_leftList) 254 { 255 m_focusedUIElement->looseFocus(); 256 m_focusedUIElement = m_leftList; 257 m_focusedUIElement->takeFocus(); 258 } 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: Save(); 283 break; 284 case OptionsMenu::kChangeView: 285 ChangeView(); 286 break; 287 default: 288 break; 289 } 290 244 291 m_focusedUIElement->takeFocus(); 245 292 } 246 293 else if (action == "SELECT") … … 327 374 else if (m_focusedUIElement == m_rightList) 328 375 m_rightList->MoveDown(UIListBtnType::MovePage); 329 376 } 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 377 else 394 378 { 395 379 handled = false; … … 397 381 } 398 382 399 383 if (!handled) 400 {401 handled |= (!escape && JumpTo(e));402 if (!handled)403 384 MythThemedDialog::keyPressEvent(e); 404 }405 385 } 406 386 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 387 /** \fn MythControls::LeftSelected(UIListBtnTypeItem*) 478 388 * \brief Refreshes the right list when an item in the 479 389 * left list is selected … … 482 392 { 483 393 m_leftList->refresh(); 484 394 m_rightList->blockSignals(true); 485 RefreshRightList();395 UpdateRightList(); 486 396 m_rightList->blockSignals(false); 487 397 m_rightList->refresh(); 488 398 } … … 497 407 RefreshKeyInformation(); 498 408 } 499 409 500 /** \fn MythControls::RefreshRightList(void) 501 * \brief Load the appropriate actions into the action list 410 411 /** \brief Set the contents of a list. 412 * \param list The list being changed. 413 * \param contents The contents of the list. 414 * \param arrows True to draw with arrows, otherwise arrows are not drawn. 502 415 */ 503 void MythControls::RefreshRightList(void) 416 void MythControls::SetListContents(UIListBtnType *uilist, 417 const QStringList & contents, bool arrows) 504 418 { 505 m_rightList->Reset();419 uilist->blockSignals(true); 506 420 507 if (!m_leftList->GetItemCurrent())508 return;421 // remove all strings from the current list 422 uilist->Reset(); 509 423 510 if (m_leftListType == kContextList) 511 { 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)); 424 // add each new string 425 for (size_t i = 0; i < contents.size(); i++) 426 (new UIListBtnTypeItem(uilist, contents[i]))->setDrawArrow(arrows); 522 427 523 return;524 }428 uilist->blockSignals(false); 429 uilist->refresh(); 525 430 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 }551 }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 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 }580 431 } 581 432 582 QString MythControls::RefreshKeyInformationKeyList(void) 433 /** \brief Update the right list. */ 434 void MythControls::UpdateRightList(void) 583 435 { 584 if ((m_leftListType != kKeyList) && (m_rightListType != kKeyList))585 return "";436 // get the selected item in the right list. 437 QString rtstr = m_leftList->GetItemCurrent()->text(); 586 438 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) 439 switch(m_currentView) 597 440 { 598 list = m_keyToBindingsMap[display_to_key(GetCurrentKey())]; 441 case kActionsByContext: 442 SetListContents(m_rightList, *(m_contexts[rtstr])); 443 break; 444 case kKeysByContext: 445 SetListContents(m_rightList, m_bindings->GetContextKeys(rtstr)); 446 break; 447 case kContextsByKey: 448 SetListContents(m_rightList, m_bindings->GetKeyContexts(rtstr)); 449 break; 599 450 } 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)643 break;644 }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 451 } 661 452 662 453 /** \fn MythControls::RefreshKeyInformation(void) … … 674 465 return; 675 466 } 676 467 677 if ((m_leftListType == kKeyList) || (m_rightListType == kKeyList))678 {679 m_description->SetText(RefreshKeyInformationKeyList());680 return;681 }682 683 468 const QString context = GetCurrentContext(); 684 469 const QString action = GetCurrentAction(); 685 470 … … 690 475 for (uint i = 0; (i < keys.count()) && 691 476 (i < Action::kMaximumNumberOfBindings); i++) 692 477 { 693 m_actionButtons[i]->setText(key _to_display(keys[i]));478 m_actionButtons[i]->setText(keys[i]); 694 479 } 695 480 } 696 481 … … 794 579 return desc.mid(loc + 4); 795 580 } 796 581 797 /** \fn MythControls::Load All(const QString&)582 /** \fn MythControls::Load(const QString&) 798 583 * \brief Load the settings for a particular host. 799 584 * \param hostname The host to load settings for. 800 585 */ … … 804 589 m_bindings = new KeyBindings(hostname); 805 590 m_sortedContexts = m_bindings->GetContexts(); 806 591 807 m_sortedKeys.clear();808 809 592 /* Alphabetic order, but jump and global at the top */ 810 593 m_sortedContexts.sort(); 811 594 m_sortedContexts.remove(ActionSet::kJumpContext); … … 822 605 actions.sort(); 823 606 m_contexts.insert(m_sortedContexts[i], new QStringList(actions)); 824 607 } 825 826 RefreshKeyBindings();827 UpdateLists();828 608 } 829 609 830 610 /** \fn MythControls::DeleteKey(void) … … 846 626 return; 847 627 } 848 628 849 BindingList *list = m_keyToBindingsMap[key]; 850 Binding *binding = NULL; 629 ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this binding?")); 851 630 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(); 631 if (popup.GetOption() != ConfirmMenu::kConfirm) 863 632 return; 864 }865 633 866 if ( binding->contextFrom != context)634 if (!m_bindings->RemoveActionKey(context, action, key)) 867 635 { 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 636 InvalidBindingPopup popup(gContext->GetMainWindow()); 887 637 popup.GetOption(); 888 638 return; 889 639 } 890 640 891 RefreshKeyBindings();892 641 RefreshKeyInformation(); 893 642 } 894 643 … … 977 726 m_bindings->AddActionKey(context, action, key); 978 727 } 979 728 980 RefreshKeyBindings();981 729 RefreshKeyInformation(); 982 730 } 983 731 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 732 /** \brief Create the view menu. 733 * \param window The main window. 734 * \param current The current view type. 991 735 */ 992 void MythControls::AddBindings(QDict<Binding> &bindings, 993 const QString &context, 994 const QString &contextParent, 995 int bindlevel) 736 ViewMenu::ViewMenu(MythMainWindow *window, ViewType current) 737 : MythPopupBox(window, "mcviewmenu") 996 738 { 997 QStringList actions = m_bindings->GetActions(context);739 addLabel(tr("Change View"), Large, false); 998 740 999 for (uint i = 0; i < actions.size(); i++)741 switch(current) 1000 742 { 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 } 743 case kKeysByContext: 744 addButton(tr("Actions By Context"), this, SLOT(ActionsByContext())); 745 addButton(tr("Contexts By Key"), this, SLOT(ContextsByKey())); 746 break; 747 case kContextsByKey: 748 addButton(tr("Actions By Context"), this, SLOT(ActionsByContext())); 749 addButton(tr("Keys By Context"), this, SLOT(KeysByContext())); 750 break; 751 default: 752 addButton(tr("Keys By Context"), this, SLOT(KeysByContext())); 753 addButton(tr("Contexts By Key"), this, SLOT(ContextsByKey())); 754 break; 1020 755 } 1021 }1022 756 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; 757 addButton(tr("Cancel"), this, SLOT(Cancel()))->setFocus(); 1048 758 } 1049 759 1050 /** \fn MythControls::RefreshKeyBindings(void)1051 * \brief Refresh binding information1052 */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 duplicates1087 * \param keys the list of keys to sort1088 */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) const1129 {1130 switch (type)1131 {1132 case kContextList:1133 return tr("Contexts");1134 break;1135 case kKeyList:1136 return tr("Keys");1137 break;1138 case kActionList:1139 return tr("Actions");1140 break;1141 default:1142 return "";1143 }1144 }1145 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));1189 }1190 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 760 /* 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 = QDeepCopy<QStringList>(m_actionSet.GetContextStrings()); 65 ctxts.sort(); 66 return ctxts; 59 67 } 60 68 61 69 /** \fn KeyBindings::GetActions(const QString&) const … … 95 103 (m_actionSet.GetKeys(ActionID(context_name, action_name))); 96 104 } 97 105 106 /** \fn KeyBindings::GetContextKeys(const QString &) const 107 * \brief Get the keys within a context. 108 * \param context The context name. 109 * \return A list of the keys in the context. 110 */ 111 QStringList KeyBindings::GetContextKeys(const QString & context) const 112 { 113 return m_actionSet.GetContextKeys(context); 114 } 115 116 /** \fn KeyBindings::GetKeyContexts(const QString &) const 117 * \brief Get the context names in which a key is bound. 118 * \return A list of context names in which a key is bound. 119 */ 120 QStringList KeyBindings::GetKeyContexts(const QString &key) const 121 { 122 ActionList actions = m_actionSet.GetActions(key); 123 QStringList contexts; 124 125 for (size_t i = 0; i < actions.size(); i++) 126 { 127 QString context = actions[i].GetContext(); 128 if (!contexts.contains(context)) 129 contexts.push_back(context); 130 } 131 132 return contexts; 133 } 134 98 135 /** \fn KeyBindings::GetActionDescription(const QString&,const QString&) const 99 136 * \brief Get an action's description. 100 137 * \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 65 66 SetModifiedFlag(id, true); 66 67 67 68 return true; … … 75 76 * 76 77 * \param id The action identifier to remove from. 77 78 * \param key The key to remove. 79 * 80 * \todo Remove the actionlist from the m_keyToActionMap if the key 81 * is no longer bound to any actions. 78 82 */ 79 83 bool ActionSet::Remove(const ActionID &id, const QString &key) 80 84 { … … 87 91 return false; 88 92 89 93 m_keyToActionMap[key].remove(id); 94 95 // remove the key if there isn't anything bound to it. 96 if (m_keyToActionMap[key].isEmpty()) 97 m_keyToActionMap.remove(key); 98 90 99 SetModifiedFlag(id, true); 91 100 92 101 return true; … … 242 251 return keys; 243 252 } 244 253 254 QStringList ActionSet::GetContextKeys(const QString & context_name) const 255 { 256 QStringList keys; 257 Context *c = m_contexts[context_name]; 258 259 QDictIterator<Action> it(*c); 260 for (;it.current(); ++it) 261 { 262 QStringList akeys = (*it)->GetKeys(); 263 for (size_t i = 0; i < akeys.size(); i++) 264 { 265 keys.append(akeys[i]); 266 } 267 keys.sort(); 268 } 269 270 return keys; 271 } 272 273 /** \brief Get all keys (from every context) to which an action is bound. 274 */ 275 QStringList ActionSet::GetAllKeys(void) const 276 { 277 QStringList keys; 278 279 QMap<QString, ActionList>::ConstIterator it; 280 281 for (it = m_keyToActionMap.begin(); it != m_keyToActionMap.end(); ++it) 282 keys.push_back(it.key()); 283 284 return keys; 285 } 286 287 245 288 /** \fn ActionSet::GetDescription(const ActionID&) const 246 289 * \brief Returns the description of an action by its identifier. 247 290 * (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 { 34 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) {} 40 Q_OBJECT 40 41 41 public: 42 QString key; 43 QString context; 44 QString contextFrom; 45 QString action; 46 int bindlevel; 42 public: 43 44 /// \brief The available views 45 enum actions { kContextAction, kContextKey, kKeyContext, kCancel}; 46 47 /** \brief Creates a new view dialog box. 48 * \param window The main MythTV window. 49 * \param first The first button's caption 50 * \param second The second button's caption 51 */ 52 ViewMenu(MythMainWindow *window, ViewType current); 53 54 /// \brief Execute the option popup. 55 int GetOption(void) { return ExecPopup(this,SLOT(Cancel())); } 56 57 public slots: 58 59 void ActionsByContext(void) { done(ViewMenu::kContextAction); } 60 void KeysByContext(void) { done(ViewMenu::kContextKey); } 61 void ContextsByKey(void) { done(ViewMenu::kKeyContext); } 62 void Cancel(void) { done(ViewMenu::kCancel); } 47 63 }; 48 typedef QPtrList<Binding> BindingList;49 64 50 65 /** \class MythControls 51 66 * \brief The myth controls configuration class. … … 77 92 // Commands 78 93 bool LoadUI(void); 79 94 void RefreshKeyInformation(void); 80 QString RefreshKeyInformationKeyList(void);81 void RefreshRightList(void);82 void UpdateLists(void);83 95 void LoadData(const QString &hostname); 84 96 void ChangeButtonFocus(int direction); 85 97 void ChangeListFocus(UIListBtnType *focus, UIListBtnType *unfocus); 86 void AddBindings(QDict<Binding> &bindings, const QString &context, 87 const QString &contextParent, int bindlevel); 98 void ChangeView(void); 99 void SetListContents(UIListBtnType *uilist, 100 const QStringList & contents, 101 bool arrows = false); 102 void UpdateRightList(void); 88 103 89 104 // Gets 90 BindingList *GetKeyBindings(const QString &context);91 105 uint GetCurrentButton(void) const; 92 106 93 107 // Functions … … 99 113 void DeleteKey(void); 100 114 void LeftSelected(UIListBtnTypeItem *item); 101 115 void RightSelected(UIListBtnTypeItem *item); 102 void SortKeyList(QStringList &keys);103 void RefreshKeyBindings(void);104 116 bool JumpTo(QKeyEvent *e); 105 117 /// \brief Save the bindings to the Database. 106 118 void Save(void) { m_bindings->CommitChanges(); } 107 119 108 120 private: 121 ViewType m_currentView; 109 122 UIType *m_focusedUIElement; 110 123 UIListBtnType *m_leftList; 111 124 UIListBtnType *m_rightList; … … 117 130 KeyBindings *m_bindings; 118 131 LayerSet *m_container; 119 132 QStringList m_sortedContexts; ///< sorted list of contexts 120 QStringList m_sortedKeys; ///< sorted list of keys121 133 QDict<QStringList> m_contexts; ///< actions for a given context 122 QDict<BindingList> m_contextToBindingsMap;123 QDict<BindingList> m_keyToBindingsMap;124 134 ListType m_leftListType; 125 135 ListType m_rightListType; 126 136 }; -
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