Ticket #2078: ui_and_logic.diff
File ui_and_logic.diff, 40.4 KB (added by , 18 years ago) |
---|
-
mythcontrols/actionset.h
122 122 QStringList getKeys(const ActionID &id) const; 123 123 124 124 /** 125 * Get all keys that are in use. 126 * @return A string list containing all of the keys. 127 */ 128 QStringList * getAllKeys(void) const; 129 130 /** 131 * Get the contexts, in which a key is bound. 132 * @return A string list containing the context names. 133 */ 134 QStringList * getKeyContexts(const QString &key) const; 135 136 /** 137 * Get all of the actions that are in use. 138 * @return A string list containing all of the actions. 139 */ 140 QStringList *getAllActions(void) const; 141 142 /** 125 143 * @brief Get the description of an action. 126 144 * @param id The action identifier. 127 145 * @return The action description. … … 209 227 QMap<QString, ActionList> _keymap; 210 228 QDict<Context> _contexts; 211 229 ActionList _modified; 230 231 /* map from action to the contexts it belongs to */ 232 QMap<QString, QStringList> _actions; 233 212 234 }; 213 235 214 236 #endif /* ACTIONSET_H */ -
mythcontrols/mythcontrols.cpp
54 54 return key; 55 55 } 56 56 57 static const QString DisplayToKey(const QString key)58 {59 if (key.left(1) == "[" && key != "[")60 return "remote" + key.mid(1,key.length()-2);61 else62 return key;63 }64 57 65 58 /* comments in header */ 66 59 MythControls::MythControls (MythMainWindow *parent, bool& ui_ok) … … 69 62 /* Nullify keybindings so the deconstructor knows not to delete it */ 70 63 this->key_bindings = NULL; 71 64 72 /* delete the contents when we're done */ 73 m_contexts.setAutoDelete(true); 74 65 this->view = ActionsByContext; 66 75 67 /* load up the ui components */ 76 68 if ((ui_ok = loadUI())) 77 69 { 78 leftType = kContextList;79 rightType = kActionList;80 81 70 /* for starters, load this host */ 82 loadHost(gContext->GetHostName());71 key_bindings = new KeyBindings(gContext->GetHostName()); 83 72 84 73 /* update the information */ 85 refreshKeyInformation(); 74 setView(ActionsByContext, true); 75 refreshInformation(); 86 76 87 77 /* capture the signals we want */ 88 78 connect(LeftList, SIGNAL(itemSelected(UIListBtnTypeItem*)), … … 162 152 } 163 153 164 154 155 void MythControls::showButtons(bool shown) const 156 { 157 for (size_t i = 0; i < Action::MAX_KEYS; i++) 158 { 159 shown ? ActionButtons[i]->show() : ActionButtons[i]->hide(); 160 } 161 } 165 162 163 164 /* method description in mythcontrols.h */ 165 void MythControls::blankButtons(void) const 166 { 167 for (size_t i = 0; i < Action::MAX_KEYS; i++) 168 ActionButtons[i]->setText(""); 169 } 170 171 /* method description in mythcontrols.h */ 172 void MythControls::fillButtons(const QStringList & strings) 173 { 174 size_t i = 0, maxstr = Action::MAX_KEYS; 175 176 if (strings.count() < Action::MAX_KEYS) 177 maxstr = strings.count(); 178 179 /* fill existing keys */ 180 for (; i < maxstr; i++) 181 ActionButtons[i]->setText(KeyToDisplay(strings[i])); 182 183 /* blank the other ones */ 184 for (; i < Action::MAX_KEYS; i++) 185 ActionButtons[i]->setText(""); 186 } 187 166 188 /* comments in header */ 167 189 size_t MythControls::focusedButton(void) const 168 190 { … … 172 194 return Action::MAX_KEYS; 173 195 } 174 196 175 176 197 void MythControls::focusButton(int direction) 177 198 { 178 if (leftType != kContextList || rightType != kActionList)179 return;180 199 if (direction == 0) 181 200 { 182 201 focused = ActionButtons[0]; … … 222 241 focused = focus; 223 242 focus->SetActive(true); 224 243 focus->takeFocus(); 225 refreshKeyInformation(); 244 /*refreshKeyInformation();*/ 245 refreshInformation(); 226 246 } 227 247 248 /* method description in mythcontrols.h */ 249 void MythControls::setView(ViewMode newview, bool force) 250 { 251 QStringList *lstrings = NULL, *rstrings = NULL; 252 253 /* Dont set the view to what is already is */ 254 if ((newview == this->view) && (force == false)) 255 return; 256 257 focused = LeftList; 258 LeftList->takeFocus(); 259 260 this->view = newview; 261 262 switch (newview) { 263 case ActionsByContext: 264 this->showButtons(true); 265 LeftDesc->SetText(tr("Contexts")); 266 RightDesc->SetText(tr("Actions")); 267 lstrings = key_bindings->getContexts(); 268 rstrings = key_bindings->getActions((*lstrings)[0]); 269 break; 270 case ActionsByKey: 271 this->showButtons(false); 272 LeftDesc->SetText(tr("Keys")); 273 RightDesc->SetText(tr("Actions")); 274 lstrings = key_bindings->getAllKeys(); 275 rstrings = key_bindings->getKeyActions((*lstrings)[0]); 276 break; 277 case ContextsByKey: 278 this->showButtons(false); 279 LeftDesc->SetText(tr("Keys")); 280 RightDesc->SetText(tr("Contexts")); 281 lstrings = key_bindings->getAllKeys(); 282 rstrings = key_bindings->getContexts((*lstrings)[0]); 283 break; 284 } 285 286 /* refresh the keys on the left */ 287 if (lstrings != NULL) { 288 refreshLeft(lstrings); 289 delete lstrings; 290 } 291 292 /* refresh the keys on the right */ 293 if (rstrings != NULL) { 294 refreshRight(rstrings); 295 delete rstrings; 296 } 297 } 298 228 299 void MythControls::keyPressEvent(QKeyEvent *e) 229 300 { 230 301 bool handled = false; … … 232 303 QStringList actions; 233 304 gContext->GetMainWindow()->TranslateKeyPress("Controls", e, actions); 234 305 306 307 235 308 for (size_t i = 0; i < actions.size() && !handled; i++) 236 309 { 237 310 QString action = actions[i]; … … 254 327 { 255 328 if (focused == LeftList) 256 329 switchListFocus(RightList, LeftList); 257 else if (focused == RightList) 258 focusButton(0); 259 else { 260 QString key = getCurrentKey(); 261 if (!key.isEmpty()) 262 { 263 ActionMenu popup(gContext->GetMainWindow()); 264 int result = popup.getOption(); 265 if (result == ActionMenu::SET) addKeyToAction(); 266 else if (result == ActionMenu::REMOVE) deleteKey(); 267 } else // for blank keys, no reason to ask what to do 268 addKeyToAction(); 330 else if (this->view == ActionsByContext) { 331 if (focused == RightList) 332 focusButton(0); 333 else { 334 QString key = getCurrentKey(); 335 if (!key.isEmpty()) 336 { 337 ActionMenu popup(gContext->GetMainWindow()); 338 int result = popup.getOption(); 339 if (result == ActionMenu::SET) addKeyToAction(); 340 else if (result == ActionMenu::REMOVE) deleteKey(); 341 } else // for blank keys, no reason to ask what to do 342 addKeyToAction(); 343 } 269 344 } 270 345 } 271 346 else if (action == "ESCAPE") … … 331 406 else if (focused == RightList) 332 407 RightList->MoveDown(UIListBtnType::MovePage); 333 408 } 334 else if (action == "1") 335 { 336 if (leftType != kContextList || rightType != kActionList) 337 { 338 leftType = kContextList; 339 rightType = kActionList; 340 updateLists(); 341 if (focused != LeftList) 342 switchListFocus(LeftList, 343 (focused == RightList) ? RightList : NULL); 344 } else handled = false; 345 } 346 else if (action == "2") 347 { 348 if (leftType != kContextList || rightType != kKeyList) 349 { 350 leftType = kContextList; 351 rightType = kKeyList; 352 updateLists(); 353 if (focused != LeftList) 354 switchListFocus(LeftList, 355 (focused == RightList) ? RightList : NULL); 356 } else handled = false; 357 } 358 else if (action == "3") 359 { 360 if (leftType != kKeyList || rightType != kContextList) 361 { 362 leftType = kKeyList; 363 rightType = kContextList; 364 updateLists(); 365 if (focused != LeftList) 366 switchListFocus(LeftList, 367 (focused == RightList) ? RightList : NULL); 368 } else handled = false; 369 } 409 else if (action == "1") setView(ActionsByContext); 410 else if (action == "2") setView(ActionsByKey); 411 else if (action == "3") setView(ContextsByKey); 370 412 else handled = false; 371 413 } 372 414 … … 381 423 bool MythControls::JumpTo(QKeyEvent *e) 382 424 { 383 425 UIListBtnType *list = NULL; 384 if (focused == LeftList && leftType == kKeyList) list = LeftList; 385 if (focused == RightList && rightType == kKeyList) list = RightList; 426 427 if (view != ActionsByContext) { 428 if (focused == LeftList) list = LeftList; 429 else list = RightList; 430 } 431 386 432 if (!list) return false; 387 433 388 434 QString key = e->text(); … … 429 475 refreshRightList(); 430 476 RightList->blockSignals(false); 431 477 RightList->refresh(); 478 description->SetText(""); 432 479 } 433 480 434 481 void MythControls::rightSelected(UIListBtnTypeItem*) 435 482 { 436 483 RightList->refresh(); 437 refresh KeyInformation();484 refreshInformation(); 438 485 } 439 486 487 void MythControls::refreshRight(QStringList * strings) 488 { 489 RightList->blockSignals(true); 490 RightList->Reset(); 440 491 492 /* sort the strings */ 493 strings->sort(); 441 494 495 for (size_t i = 0; i < strings->size(); i++) { 496 UIListBtnTypeItem *item = new UIListBtnTypeItem(RightList, (*strings)[i]); 497 item->setDrawArrow(false); 498 } 499 500 RightList->blockSignals(false); 501 RightList->refresh(); 502 } 503 442 504 /* method description in header */ 443 void MythControls::refresh RightList()505 void MythControls::refreshLeft(QStringList * strings) 444 506 { 445 RightList->Reset(); 507 LeftList->blockSignals(true); 508 LeftList->Reset(); 446 509 447 if (LeftList->GetItemCurrent() == NULL)448 return;510 /* sort the strings */ 511 strings->sort(); 449 512 450 if (leftType == kContextList) 451 { 452 if (rightType == kActionList) 453 { 454 /* add all of the actions to the context list */ 455 QString context = LeftList->GetItemCurrent()->text(); 456 QStringList *actions = m_contexts[context]; 457 if (actions == NULL) 458 { 459 VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find actions for context %1").arg(context)); 460 return; 461 } 462 UIListBtnTypeItem *item; 463 for (size_t i = 0; i < actions->size(); i++) 464 item = new UIListBtnTypeItem(RightList, (*actions)[i]); 465 } 466 else if (rightType == kKeyList) 467 { 468 /* add all of the actions to the context list */ 469 QString context = LeftList->GetItemCurrent()->text(); 470 BindingList *list = contextKeys[context]; 471 if (list == NULL) 472 { 473 VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find keys for context %1").arg(context)); 474 return; 475 } 476 UIListBtnTypeItem *item; 477 for (BindingList::iterator it = list->begin(); it != list->end(); ++it) 478 { 479 binding_t *b = *it; 480 item = new UIListBtnTypeItem(RightList, KeyToDisplay(b->key) + " => " + b->action); 481 } 482 } 483 } else if (leftType == kKeyList && rightType == kContextList) 484 { 485 QString key = DisplayToKey(LeftList->GetItemCurrent()->text()); 486 BindingList *list = keyActions[key]; 487 if (list == NULL) 488 { 489 VERBOSE(VB_IMPORTANT, QString("MythControls: Unable to find actions for key %1").arg(key)); 490 return; 491 } 492 UIListBtnTypeItem *item; 493 BindingList::iterator it = list->begin(); 494 binding_t *b = *it; 495 for (size_t i = 0; i < contexts.size(); i++) 496 { 497 QString context = contexts[i]; 498 QString action = "<none>"; 499 if (b && b->context == context) 500 { 501 action = b->action; 502 ++it; 503 if (it != list->end()) b = *it; 504 else b = NULL; 505 } 506 item = new UIListBtnTypeItem(RightList, context + " => " + action); 507 } 513 for (size_t i = 0; i < strings->size(); i++) { 514 UIListBtnTypeItem *item = new UIListBtnTypeItem(LeftList, (*strings)[i]); 515 item->setDrawArrow(true); 508 516 } 517 518 LeftList->blockSignals(false); 519 LeftList->refresh(); 509 520 } 510 521 511 522 512 /* comments in header*/513 void MythControls::refresh KeyInformation()523 /* method description in mythcontrols.h */ 524 void MythControls::refreshRightList() 514 525 { 515 /* get the description of the current action */516 QString desc;526 QStringList *rstrings = NULL; 527 QString lstring = LeftList->GetItemCurrent()->text(); 517 528 518 if (focused == LeftList) 519 { 520 /* blank all keys on the context */ 521 for (size_t i = 0; i < Action::MAX_KEYS; i++) 522 ActionButtons[i]->setText(""); 529 /* right list, based on values from the left */ 530 switch (this->view) { 531 case ActionsByContext: 532 this->showButtons(true); 533 rstrings = key_bindings->getActions(lstring); 534 break; 535 case ActionsByKey: 536 this->showButtons(false); 537 rstrings = key_bindings->getKeyActions(lstring); 538 break; 539 case ContextsByKey: 540 this->showButtons(false); 541 rstrings = key_bindings->getContexts(lstring); 542 break; 523 543 } 524 else if (leftType == kKeyList || rightType == kKeyList)525 { // Should show appropriate description526 QString action = getCurrentAction();527 QString context = getCurrentContext();528 /* blank all keys on the context */529 for (size_t i = 0; i < Action::MAX_KEYS; i++)530 ActionButtons[i]->setText("");531 if (!action.isEmpty())532 {533 534 desc = key_bindings->getActionDescription(context, action);535 536 BindingList *list = NULL;537 if (leftType == kKeyList && rightType == kContextList)538 {539 QString key = getCurrentKey();540 list = keyActions[DisplayToKey(key)];541 }542 else if (leftType == kContextList && rightType == kKeyList)543 list = contextKeys[context];544 if (list)545 {546 QString searchKey;547 if (rightType == kContextList)548 searchKey = context;549 else if (rightType == kActionList)550 searchKey = action;551 else if (rightType == kKeyList)552 searchKey = DisplayToKey(getCurrentKey());553 binding_t *binding = NULL;554 for (BindingList::iterator it = list->begin(); it != list->end(); ++it)555 {556 binding_t *b = *it;557 switch (rightType)558 {559 case kContextList:560 if (b->context == searchKey) binding = b;561 break;562 case kActionList:563 if (b->action == searchKey) binding = b;564 break;565 case kKeyList:566 if (b->key == searchKey) binding = b;567 break;568 }569 if (binding) break;570 }571 572 if (binding)573 {574 if (desc.isEmpty() && context != binding->contextFrom)575 desc = key_bindings->getActionDescription(binding->contextFrom, action);576 desc += "\n" + tr("Binding comes from %1 context")577 .arg(binding->contextFrom);578 }579 }580 }581 } else {582 QString context = getCurrentContext();583 QString action = getCurrentAction();584 /* set the description */585 desc = key_bindings->getActionDescription(getCurrentContext(),586 getCurrentAction());587 544 588 /* get the bindings of the current action */589 QStringList keys = key_bindings->getActionKeys(getCurrentContext(),590 getCurrentAction()); 545 refreshRight(rstrings); 546 delete rstrings; 547 } 591 548 592 size_t i;593 549 594 /* fill existing keys */ 595 for (i = 0; i < keys.count(); i++) 596 ActionButtons[i]->setText(KeyToDisplay(keys[i])); 550 void MythControls::refreshBindingInformation() 551 { 552 QString context = LeftList->GetItemCurrent()->text(); 553 QString action = RightList->GetItemCurrent()->text(); 554 QString desc = key_bindings->getActionDescription(getCurrentContext(), 555 getCurrentAction()); 597 556 598 /* blank the other ones */ 599 for (; i < Action::MAX_KEYS; i++) 600 ActionButtons[i]->setText(""); 601 } 557 /* get the bindings of the current action */ 558 QStringList keys = key_bindings->getActionKeys(getCurrentContext(), 559 getCurrentAction()); 602 560 603 /* set the information */ 561 fillButtons(keys); 562 604 563 description->SetText(desc); 605 564 } 606 565 607 566 567 /* method description in mythcontrols.h */ 568 void MythControls::refreshInformation() 569 { 570 switch (this->view) 571 { 572 case ActionsByContext: 573 if (focused == LeftList) { 574 blankButtons(); 575 description->SetText(""); 576 } 577 else refreshBindingInformation(); 578 break; 579 case ActionsByKey: 580 if (focused == LeftList) description->SetText(""); 581 else 582 { 583 QString key = LeftList->GetItemCurrent()->text(); 584 QString action = RightList->GetItemCurrent()->text(); 585 int pos = RightList->GetItemPos(RightList->GetItemCurrent()); 586 QString context = key_bindings->getContext(key, action, pos); 587 QString desc = key_bindings->getActionDescription(context, action); 588 desc += "\n" + tr("Binding comes from %1 context").arg(context); 589 description->SetText(desc); 590 } 591 break; 592 case ContextsByKey: 593 if (focused == LeftList) description->SetText(""); 594 else 595 { 596 QString key = LeftList->GetItemCurrent()->text(); 597 QString context = RightList->GetItemCurrent()->text(); 598 QString action = key_bindings->getAction(key, context); 599 QString desc = action + ": " + key_bindings->getActionDescription(context, 600 action); 601 description->SetText(desc); 602 } 603 break; 604 } 605 } 608 606 609 607 /* comments in header */ 610 608 QString MythControls::getCurrentContext(void) const 611 609 { 612 if (leftType == kContextList) 613 return LeftList->GetItemCurrent()->text(); 614 if (focused == LeftList) return ""; 615 616 QString desc = RightList->GetItemCurrent()->text(); 617 int loc = desc.find(" => "); 618 if (loc == -1) return ""; // Should not happen 619 if (rightType == kContextList) return desc.left(loc); 620 else return desc.mid(loc+4); 610 if (view == ActionsByContext) return LeftList->GetItemCurrent()->text(); 611 else if ((view == ContextsByKey) && (focused == RightList)) 612 return RightList->GetItemCurrent()->text(); 613 else return ""; 621 614 } 622 615 623 616 /* comments in header */ 624 617 QString MythControls::getCurrentAction(void) const 625 618 { 626 if (leftType == kActionList)627 return LeftList->GetItemCurrent()->text();628 if (focused == LeftList) return "";629 619 630 QString desc = RightList->GetItemCurrent()->text(); 631 if (leftType == kContextList && rightType == kActionList) 632 return desc; 633 int loc = desc.find(" => "); 634 if (loc == -1) return ""; // Should not happen 635 if (rightType == kActionList) return desc.left(loc); 636 else 637 { 638 QString rv = desc.mid(loc+4); 639 if (rv == "<none>") return ""; 640 else return rv; 641 } 620 if (((view == ActionsByContext) && (focused != LeftList)) || 621 ((view == ActionsByKey) && (focused == RightList))) 622 return RightList->GetItemCurrent()->text(); 623 else return ""; 642 624 } 643 625 644 626 /* comments in header */ 645 627 QString MythControls::getCurrentKey(void) const 646 628 { 647 if (leftType == kKeyList) 648 return LeftList->GetItemCurrent()->text(); 649 if (focused == LeftList) return ""; 650 651 if (leftType == kContextList && rightType == kActionList) 629 if (view == ActionsByContext) 652 630 { 653 631 QString context = getCurrentContext(); 654 632 QString action = getCurrentAction(); … … 657 635 if (b < keys.count()) return keys[b]; 658 636 else return ""; 659 637 } 660 661 QString desc = RightList->GetItemCurrent()->text(); 662 int loc = desc.find(" => "); 663 if (loc == -1) return ""; // Should not happen 664 if (rightType == kKeyList) return desc.left(loc); 665 else return desc.mid(loc+4); 638 else return LeftList->GetItemCurrent()->text(); 666 639 } 667 640 668 669 641 /* comments in header */ 670 void MythControls::loadHost(const QString & hostname) {671 672 /* create the key bindings and the tree */673 key_bindings = new KeyBindings(hostname);674 contexts = *key_bindings->getContexts();675 676 keys.clear();677 678 /* Alphabetic order, but jump and global at the top */679 contexts.sort();680 contexts.remove(JUMP_CONTEXT);681 contexts.remove(GLOBAL_CONTEXT);682 contexts.insert(contexts.begin(), 1, GLOBAL_CONTEXT);683 contexts.insert(contexts.begin(), 1, JUMP_CONTEXT);684 685 QStringList *actions;686 for (size_t i = 0; i < contexts.size(); i++)687 {688 actions = key_bindings->getActions(contexts[i]);689 actions->sort();690 m_contexts.insert(contexts[i], actions);691 }692 693 refreshKeyBindings();694 updateLists();695 }696 697 698 699 /* comments in header */700 642 void MythControls::deleteKey() 701 643 { 702 644 // This code needs work to support deleteKey in any mode exc. Context/Action 703 645 QString context = getCurrentContext(); 704 646 QString key = getCurrentKey(); 705 647 QString action = getCurrentAction(); 648 706 649 if (context.isEmpty() || key.isEmpty() || action.isEmpty()) 707 650 { 708 651 InvalidBindingPopup popup(gContext->GetMainWindow()); … … 710 653 return; 711 654 } 712 655 713 BindingList *list = keyActions[key]; 714 binding_t *binding = NULL; 715 for (BindingList::iterator it = list->begin(); it != list->end(); ++it) 656 if (view == ActionsByContext) 716 657 { 717 binding_t *b = *it; 718 if (b->context == context) binding = b; 719 } 720 if (!binding) 721 { 722 InvalidBindingPopup popup(gContext->GetMainWindow()); 723 popup.getOption(); 724 return; 725 } 726 727 if (binding->contextFrom != context) 728 { 729 ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this key binding from context %1?").arg(binding->contextFrom)); 658 ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this key binding from context %1?").arg(context)); 730 659 if (popup.getOption() != ConfirmMenu::CONFIRM) return; 731 } else { 732 ConfirmMenu popup(gContext->GetMainWindow(), tr("Delete this binding?")); 733 if (popup.getOption() != ConfirmMenu::CONFIRM) return; 660 else 661 { 662 key_bindings->removeActionKey(context, action, key); 663 } 734 664 } 735 665 736 if (!key_bindings->removeActionKey(binding->contextFrom, action, key)) 737 { 738 InvalidBindingPopup popup(gContext->GetMainWindow()); 739 popup.getOption(); 740 return; 741 } 742 743 // refreshing everything is overkill. I tried incrementally updating, but the 744 // code was ugly. Since this is quick in my experience, overkill away! 745 refreshKeyBindings(); 746 refreshKeyInformation(); 666 refreshInformation(); 747 667 } 748 668 749 669 /* method description in header */ … … 780 700 /* method description in header */ 781 701 void MythControls::addKeyToAction(void) 782 702 { 783 // This code needs work to support deleteKey in any mode exc. Context/Action784 703 /* grab a key from the user */ 785 704 KeyGrabPopupBox *kg = new KeyGrabPopupBox(gContext->GetMainWindow()); 786 705 int result = kg->ExecPopup(kg,SLOT(cancel())); … … 817 736 else 818 737 key_bindings->addActionKey(context, action, key); 819 738 820 refreshKeyBindings(); 821 refreshKeyInformation(); 739 refreshInformation(); 822 740 } 823 741 824 825 826 void MythControls::addBindings(QDict<binding_t> &bindings,827 const QString &context,828 const QString &contextParent, int bindlevel)829 {830 QStringList *actions = key_bindings->getActions(context);831 832 for (size_t i = 0; i < actions->size(); i++)833 {834 QString action = (*actions)[i];835 QStringList keys = key_bindings->getActionKeys(context, action);836 837 for (size_t j = 0; j < keys.size(); j++)838 {839 QString key = keys[j];840 841 binding_t *b = bindings.find(key);842 if (!b)843 {844 b = new(binding_t);845 b->key = key;846 b->action = action;847 b->context = contextParent;848 b->contextFrom = context;849 b->bindlevel = bindlevel;850 bindings.insert(key, b);851 }852 else if (b->bindlevel == bindlevel)853 {854 b->action += ", " + action;855 }856 }857 }858 }859 860 BindingList *MythControls::getKeyBindings(const QString &context)861 {862 QStringList keys;863 QDict<binding_t> bindings;864 bindings.clear();865 866 for (size_t i = 0; i < contexts.size(); i++)867 addBindings(bindings, contexts[i], context, i);868 869 870 for (QDictIterator<binding_t> it(bindings); it.current(); ++it)871 {872 QString key = it.currentKey();873 keys.append(key);874 }875 876 sortKeyList(keys);877 878 BindingList *retval = new BindingList;879 retval->clear();880 881 for (QStringList::Iterator kit = keys.begin(); kit != keys.end(); ++kit)882 {883 QString key = *kit;884 retval->append(bindings[key]);885 }886 retval->setAutoDelete(true);887 return retval;888 }889 890 void MythControls::refreshKeyBindings()891 {892 contextKeys.clear();893 keyActions.clear();894 for (size_t i = 0; i < contexts.size(); i++)895 {896 QString context = contexts[i];897 BindingList *list = getKeyBindings(context);898 contextKeys.insert(context, list);899 for (BindingList::iterator it = list->begin(); it != list->end(); ++it)900 {901 binding_t *b = *it;902 BindingList *list = keyActions.find(b->key);903 if (!list)904 {905 list = new BindingList;906 list->clear();907 keyActions.insert(b->key, list);908 }909 keys.append(b->key);910 list->append(b);911 }912 }913 contextKeys.setAutoDelete(true);914 keyActions.setAutoDelete(true);915 916 sortKeyList(keys);917 }918 919 void MythControls::sortKeyList(QStringList &keys)920 {921 QStringList t;922 t.clear();923 924 for ( QStringList::Iterator it = keys.begin(); it != keys.end(); ++it )925 {926 QString key = *it;927 928 QString keydesc = "3 ";929 if (key.left(6) == "remote")930 {931 keydesc = "0 ";932 }933 else if (key.length() == 1)934 {935 switch (key[0].category())936 {937 case QChar::Letter_Uppercase:938 keydesc = "2 ";939 break;940 case QChar::Number_DecimalDigit:941 keydesc = "1 ";942 break;943 default:944 keydesc = "5 ";945 break;946 }947 }948 else if (key.find("+", 1) != -1)949 keydesc = "4 ";950 951 t.push_back(keydesc + key);952 }953 t.sort();954 955 QString prev = "";956 957 keys.clear();958 for (QStringList::Iterator kit = t.begin(); kit != t.end(); ++kit)959 {960 QString cur = (*kit).mid(2);961 if (cur != prev)962 {963 keys.append(cur);964 prev = cur;965 }966 }967 }968 969 QString MythControls::getTypeDesc(ListType type)970 {971 switch (type)972 {973 case kContextList:974 return tr("Contexts");975 break;976 case kKeyList:977 return tr("Keys");978 break;979 case kActionList:980 return tr("Actions");981 break;982 default:983 return "";984 }985 }986 987 void MythControls::updateLists()988 {989 RightList->blockSignals(true);990 LeftList->blockSignals(true);991 LeftList->Reset();992 if (leftType == kContextList)993 {994 UIListBtnTypeItem *item;995 for (size_t i = 0; i < contexts.size(); i++)996 {997 item = new UIListBtnTypeItem(LeftList, contexts[i]);998 item->setDrawArrow(true);999 }1000 } else if (leftType == kKeyList)1001 {1002 UIListBtnTypeItem *item;1003 for (size_t i = 0; i < keys.size(); i++)1004 {1005 QString key = KeyToDisplay(keys[i]);1006 item = new UIListBtnTypeItem(LeftList, key);1007 item->setDrawArrow(true);1008 }1009 }1010 refreshRightList();1011 RightList->blockSignals(false);1012 LeftList->blockSignals(false);1013 LeftList->refresh();1014 RightList->refresh();1015 1016 if (LeftDesc != NULL)1017 LeftDesc->SetText(getTypeDesc(leftType));1018 if (RightDesc != NULL)1019 RightDesc->SetText(getTypeDesc(rightType));1020 }1021 1022 1023 742 #endif /* MYTHCONTROLS_CPP */ 1024 743 1025 744 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythcontrols/keybindings.cpp
48 48 retrieveJumppoints(); 49 49 } 50 50 51 QStringList * KeyBindings::getKeyActions(const QString &key) const 52 { 53 QStringList *strings; 54 const ActionList & al = actionset.getActions(key); 51 55 56 if (al.size() > 0) strings = new QStringList(); 57 else return NULL; 52 58 59 for (size_t i = 0; i < al.size(); i++) 60 { 61 strings->push_back(al[i].action()); 62 } 63 64 return strings; 65 } 66 67 68 QString KeyBindings::getContext(const QString & key, const QString & action, 69 size_t anum) const 70 { 71 /* The cases where unknown is returned should never happen. If 72 * you see an unknown context, do not approach. Call the police 73 * immediatly. */ 74 const ActionList &al = actionset.getActions(key); 75 int offset = al.size() - anum; 76 77 if (offset < 0) return "UNKNOWN"; 78 else if (al[anum].action() != action) return "UNKNOWN"; 79 if (anum < al.size()) return al[anum].context(); 80 else return "UNKNOWN"; 81 } 82 83 QString KeyBindings::getAction(const QString & key, const QString & context) const 84 { 85 const ActionList &al = actionset.getActions(key); 86 87 for (size_t i = 0; i < al.size(); i++) 88 { 89 if (al[i].context() == context) return al[i].action(); 90 } 91 92 return "UNKNOWN"; 93 } 94 95 53 96 ActionID * KeyBindings::conflicts(const QString & context_name, 54 97 const QString & key, int &level) const 55 98 { -
mythcontrols/actionset.cpp
154 154 } 155 155 } 156 156 157 QStringList * ActionSet::getAllKeys(void) const { 158 return new QStringList(this->_keymap.keys()); 159 } 157 160 158 161 162 QStringList * ActionSet::getAllActions(void) const { 163 return new QStringList(this->_actions.keys()); 164 } 165 166 167 QStringList * ActionSet::getKeyContexts(const QString &key) const 168 { 169 QStringList *strings = NULL; 170 const ActionList &ids = _keymap[key]; 171 172 if (ids.size() == 0) return NULL; 173 174 strings = new QStringList(); 175 176 for (size_t i = 0; i < ids.size(); i++) 177 { 178 if (!strings->contains(ids[i].context())) { 179 strings->push_back(ids[i].context()); 180 } 181 } 182 183 return strings; 184 } 185 186 159 187 /* method description in header */ 160 188 bool ActionSet::addAction(const ActionID &id, const QString &description, 161 189 const QString &keys) … … 173 201 /* add the action into the dict */ 174 202 _contexts[id.context()]->insert(id.action(), a); 175 203 204 /* if the action doesn't already exist, then add it */ 205 QStringList &contexts = _actions[id.action()]; 206 if (!contexts.contains(id.context())) 207 contexts.push_back(id.context()); 208 176 209 /* get the actions keys */ 177 210 const QStringList &keys = a->getKeys(); 178 211 for (size_t i = 0; i < keys.count(); i++) … … 182 215 ActionList &ids = _keymap[keys[i]]; 183 216 184 217 /* add this action id to the list of actions bound to this key */ 185 ids.push_back(id); 218 if (ids.size() == 0) ids.push_back(id); 219 else 220 { 221 bool added = false; 222 ActionList::iterator it; 223 224 /* keep list sorted by action, then by context. You 225 * must sort this stuff because multiple actions from 226 * different contexts can be added. Otherwise, we get 227 * into trouble in keybindings.cpp and 228 * mythcontrols.cpp when trying to delete based on 229 * action (displayed by key) */ 230 for (it = ids.begin(); (it != ids.end()) && (added == false); ++it) 231 { 232 if ((QString::compare(id.action(), (*it).action()) < 0) || 233 ((QString::compare(id.action(), (*it).action()) == 0) && 234 (QString::compare(id.context(), (*it).context()) < 0)) 235 ) 236 { 237 ids.insert(it, id); 238 added = true; 239 } 240 } 241 if (added == false) ids.push_back(id); 242 } 186 243 } 187 244 188 245 return true; … … 225 282 } 226 283 227 284 228 229 285 const QString & ActionSet::getDescription(const ActionID &id) const 230 286 { 231 287 Context *c; -
mythcontrols/mythcontrols.h
93 93 94 94 protected: 95 95 96 97 /** The view mode */ 98 typedef enum { ActionsByContext, ActionsByKey, ContextsByKey } ViewMode; 99 96 100 /** 97 101 * @brief Load up UI. 98 102 * @return true if all UI elements were loaded successfully, … … 105 109 bool loadUI(); 106 110 107 111 /** 112 * Show or hide the buttons at the bottom. 113 * 114 * @param shown Should the buttons be shown? 115 */ 116 void showButtons(bool shown) const; 117 118 /** 119 * Blank the text in the bottom buttons. 120 */ 121 void blankButtons(void) const; 122 123 /** 124 * Fill the buttons with the strings in a string list. 125 * @param strings The string list. 126 */ 127 void fillButtons(const QStringList & strings); 128 129 /** 130 * Set the viewing mode of the plugin. 131 * 132 * @param view The view mode. 133 * @param force Force the view to be set (or reset) 134 */ 135 void setView(ViewMode newview, bool force=false); 136 137 /** 108 138 * @brief The key press handler. 109 139 * @param e The key event. 110 140 */ 111 141 void keyPressEvent(QKeyEvent *e); 112 142 113 143 /** 114 * @brief Redraw the key information 115 * 116 * Updates the list of keys that are shown and the description of 117 * the action. 144 * Refresh the action description and key binding buttons. 118 145 */ 119 void refresh KeyInformation();146 void refreshBindingInformation(); 120 147 121 148 /** 122 * @brief Load the appropriate actions into the action list. 123 * @param context The context, from which actions will be 124 * displayed. 149 * @brief Redraw the information at the bottom. 125 150 */ 126 void refresh RightList(void);151 void refreshInformation(); 127 152 128 153 /** 154 * Refresh the right list. 155 * @param strings The strings to place in the right list. 156 */ 157 void refreshRight(QStringList * strings); 158 159 /** 160 * Refresh the left list. 161 * @param string The strings to place in the left list. 162 */ 163 void refreshLeft(QStringList * strings); 164 165 /** 166 * @brief Load the appropriate information into the right list. 167 * @param strings The strings to load into the right list. 168 */ 169 void refreshRightList(); 170 171 /** 129 172 * @brief Redisplay both the left and right lists and fix focus 130 173 */ 131 174 void updateLists(void); … … 183 226 184 227 private slots: 185 228 186 /**187 * @brief Add a key to the currently selected action.188 */189 void addKeyToAction(void);229 /** 230 * @brief Add a key to the currently selected action. 231 */ 232 void addKeyToAction(void); 190 233 191 234 /** 192 235 * @brief Delete the currently active key. … … 239 282 KeyBindings *key_bindings; 240 283 LayerSet *container; 241 284 242 QStringList contexts; ///< sorted list of contexts243 QStringList keys; ///< sorted list of keys244 285 245 QDict<QStringList> m_contexts; ///< actions for a given context246 286 QDict<BindingList> contextKeys; ///< key bindings for a given context 247 287 QDict<BindingList> keyActions; ///< actions in each context for a given key 248 288 249 289 typedef enum { kContextList, kKeyList, kActionList } ListType; 290 250 291 ListType leftType, rightType; 251 292 293 ViewMode view; 294 252 295 QString getTypeDesc(ListType type); 253 296 254 297 }; -
mythcontrols/keybindings.h
30 30 #include "actionid.h" 31 31 #include "actionset.h" 32 32 33 33 34 /** 34 35 * @class KeyBindings. 35 36 * @brief Information about the current keybindings. … … 63 64 inline const QString & getHostname() const { return this->_hostname; } 64 65 65 66 /** 67 * Determine the context belonging to the key and action 68 * 69 * @param action The action. 70 * @param anum The action number (in the list of all of a keys actions). 71 * 72 * This method falls apart if the actionset class doesn't sort it 73 * the actions lists in the _kemap variable. 74 */ 75 QString getContext(const QString & key, const QString & action, size_t anum) const; 76 77 /** 66 78 * @brief Get a list of the context names. 67 79 * @return A list of the context names. 68 * @note The returned list is a copy and can be modified without69 * side-effects.70 80 */ 71 81 inline QStringList * getContexts() const 72 82 { … … 74 84 } 75 85 76 86 /** 87 * Get the contexts in which a key is bound. 88 * @param key The key. 89 * @return A string list containing the context names. 90 */ 91 inline QStringList * getContexts(const QString & key) const 92 { 93 return actionset.getKeyContexts(key); 94 } 95 96 /** 77 97 * @brief Get a list of the actions in a context. 78 98 * @param context The name of the context. 79 99 * @return A list of action (names) for the target context. … … 86 106 } 87 107 88 108 /** 109 * Get the action bound to a key in a particular context. 110 * 111 * @param key The key. 112 * @param context The context. 113 * @return The action. 114 */ 115 QString getAction(const QString & key, const QString & context) const; 116 117 /** 118 * Get all bound keys. 119 * @return A string list of the bound keys. 120 */ 121 inline QStringList * getAllKeys() const { return actionset.getAllKeys(); } 122 123 /** 89 124 * @brief Get a list of the actions in a context. 90 125 * @param context The name of the context. 91 126 * @return A list of action (names) for the target context. 92 127 * @note Store this instead of calling repeatedly. Every time you 93 128 * do, ActionSet has to iterate over all contexts and actions. 94 129 */ 95 inline void getKeyActions(const QString &key, ActionList &list) const 96 { 97 list = actionset.getActions(key); 98 } 130 QStringList * getKeyActions(const QString &key) const; 99 131 100 132 /** 101 133 * @brief Get an action's keys. … … 187 219 * @param key The key to remove. 188 220 * @return true if the key was removed, or false if it was not. 189 221 * 190 * Unless the action is manditory there is only one key in the222 * Unless the action is manditory and there is only one key in the 191 223 * action, this method should return true. 192 224 */ 193 225 bool removeActionKey(const QString & context_name,