1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/base/accelerators/accelerator_manager.h"
9 #include "base/logging.h"
13 AcceleratorManager::AcceleratorManager() {
16 AcceleratorManager::~AcceleratorManager() {
19 void AcceleratorManager::Register(const Accelerator
& accelerator
,
20 HandlerPriority priority
,
21 AcceleratorTarget
* target
) {
22 AcceleratorTargetList
& targets
= accelerators_
[accelerator
].second
;
23 DCHECK(std::find(targets
.begin(), targets
.end(), target
) == targets
.end())
24 << "Registering the same target multiple times";
26 // All priority accelerators go to the front of the line.
28 DCHECK(!accelerators_
[accelerator
].first
)
29 << "Only one _priority_ handler can be registered";
30 targets
.push_front(target
);
31 // Mark that we have a priority accelerator at the front.
32 accelerators_
[accelerator
].first
= true;
36 // We are registering a normal priority handler. If no priority accelerator
37 // handler has been registered before us, just add the new handler to the
38 // front. Otherwise, register it after the first (only) priority handler.
39 if (!accelerators_
[accelerator
].first
)
40 targets
.push_front(target
);
42 targets
.insert(++targets
.begin(), target
);
45 void AcceleratorManager::Unregister(const Accelerator
& accelerator
,
46 AcceleratorTarget
* target
) {
47 AcceleratorMap::iterator map_iter
= accelerators_
.find(accelerator
);
48 if (map_iter
== accelerators_
.end()) {
49 NOTREACHED() << "Unregistering non-existing accelerator";
53 AcceleratorTargetList
* targets
= &map_iter
->second
.second
;
54 AcceleratorTargetList::iterator target_iter
=
55 std::find(targets
->begin(), targets
->end(), target
);
56 if (target_iter
== targets
->end()) {
57 NOTREACHED() << "Unregistering accelerator for wrong target";
61 // Check to see if we have a priority handler and whether we are removing it.
62 if (accelerators_
[accelerator
].first
&& target_iter
== targets
->begin()) {
63 // We've are taking the priority accelerator away, flip the priority flag.
64 accelerators_
[accelerator
].first
= false;
67 targets
->erase(target_iter
);
70 void AcceleratorManager::UnregisterAll(AcceleratorTarget
* target
) {
71 for (AcceleratorMap::iterator map_iter
= accelerators_
.begin();
72 map_iter
!= accelerators_
.end(); ++map_iter
) {
73 AcceleratorTargetList
* targets
= &map_iter
->second
.second
;
74 targets
->remove(target
);
78 bool AcceleratorManager::Process(const Accelerator
& accelerator
) {
80 AcceleratorMap::iterator map_iter
= accelerators_
.find(accelerator
);
81 if (map_iter
!= accelerators_
.end()) {
82 // We have to copy the target list here, because an AcceleratorPressed
83 // event handler may modify the list.
84 AcceleratorTargetList
targets(map_iter
->second
.second
);
85 for (AcceleratorTargetList::iterator iter
= targets
.begin();
86 iter
!= targets
.end(); ++iter
) {
87 if ((*iter
)->CanHandleAccelerators() &&
88 (*iter
)->AcceleratorPressed(accelerator
)) {
97 AcceleratorTarget
* AcceleratorManager::GetCurrentTarget(
98 const Accelerator
& accelerator
) const {
99 AcceleratorMap::const_iterator map_iter
= accelerators_
.find(accelerator
);
100 if (map_iter
== accelerators_
.end() || map_iter
->second
.second
.empty())
102 return map_iter
->second
.second
.front();
105 bool AcceleratorManager::HasPriorityHandler(
106 const Accelerator
& accelerator
) const {
107 AcceleratorMap::const_iterator map_iter
= accelerators_
.find(accelerator
);
108 if (map_iter
== accelerators_
.end() || map_iter
->second
.second
.empty())
111 // Check if we have a priority handler. If not, there's no more work needed.
112 if (!map_iter
->second
.first
)
115 // If the priority handler says it cannot handle the accelerator, we must not
117 return map_iter
->second
.second
.front()->CanHandleAccelerators();