| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/intents/intents_model.h" | 5 #include "chrome/browser/ui/intents/web_intents_model.h" |
| 6 #include "base/string_split.h" | 6 #include "base/string_split.h" |
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/intents/web_intents_registry.h" | 10 #include "chrome/browser/intents/web_intents_registry.h" |
| 11 | 11 |
| 12 IntentsTreeNode::IntentsTreeNode() | 12 WebIntentsTreeNode::WebIntentsTreeNode() |
| 13 : ui::TreeNode<IntentsTreeNode>(string16()), | 13 : ui::TreeNode<WebIntentsTreeNode>(string16()), |
| 14 type_(TYPE_ROOT) {} | 14 type_(TYPE_ROOT) {} |
| 15 | 15 |
| 16 IntentsTreeNode::IntentsTreeNode(const string16& title) | 16 WebIntentsTreeNode::WebIntentsTreeNode(const string16& title) |
| 17 : ui::TreeNode<IntentsTreeNode>(title), | 17 : ui::TreeNode<WebIntentsTreeNode>(title), |
| 18 type_(TYPE_ORIGIN) {} | 18 type_(TYPE_ORIGIN) {} |
| 19 | 19 |
| 20 IntentsTreeNode::~IntentsTreeNode() {} | 20 WebIntentsTreeNode::~WebIntentsTreeNode() {} |
| 21 | 21 |
| 22 ServiceTreeNode::ServiceTreeNode(const string16& title) | 22 ServiceTreeNode::ServiceTreeNode(const string16& title) |
| 23 : IntentsTreeNode(title, IntentsTreeNode::TYPE_SERVICE), | 23 : WebIntentsTreeNode(title, WebIntentsTreeNode::TYPE_SERVICE), |
| 24 blocked_(false), | 24 blocked_(false), |
| 25 disabled_(false) {} | 25 disabled_(false) {} |
| 26 | 26 |
| 27 ServiceTreeNode::~ServiceTreeNode() {} | 27 ServiceTreeNode::~ServiceTreeNode() {} |
| 28 | 28 |
| 29 IntentsModel::IntentsModel(WebIntentsRegistry* intents_registry) | 29 WebIntentsModel::WebIntentsModel(WebIntentsRegistry* intents_registry) |
| 30 : ui::TreeNodeModel<IntentsTreeNode>(new IntentsTreeNode()), | 30 : ui::TreeNodeModel<WebIntentsTreeNode>(new WebIntentsTreeNode()), |
| 31 intents_registry_(intents_registry), | 31 intents_registry_(intents_registry), |
| 32 batch_update_(0) { | 32 batch_update_(0) { |
| 33 LoadModel(); | 33 LoadModel(); |
| 34 } | 34 } |
| 35 | 35 |
| 36 IntentsModel::~IntentsModel() {} | 36 WebIntentsModel::~WebIntentsModel() {} |
| 37 | 37 |
| 38 void IntentsModel::AddIntentsTreeObserver(Observer* observer) { | 38 void WebIntentsModel::AddWebIntentsTreeObserver(Observer* observer) { |
| 39 intents_observer_list_.AddObserver(observer); | 39 intents_observer_list_.AddObserver(observer); |
| 40 // Call super so that TreeNodeModel can notify, too. | 40 // Call super so that TreeNodeModel can notify, too. |
| 41 ui::TreeNodeModel<IntentsTreeNode>::AddObserver(observer); | 41 ui::TreeNodeModel<WebIntentsTreeNode>::AddObserver(observer); |
| 42 } | 42 } |
| 43 | 43 |
| 44 void IntentsModel::RemoveIntentsTreeObserver(Observer* observer) { | 44 void WebIntentsModel::RemoveWebIntentsTreeObserver(Observer* observer) { |
| 45 intents_observer_list_.RemoveObserver(observer); | 45 intents_observer_list_.RemoveObserver(observer); |
| 46 // Call super so that TreeNodeModel doesn't have dead pointers. | 46 // Call super so that TreeNodeModel doesn't have dead pointers. |
| 47 ui::TreeNodeModel<IntentsTreeNode>::RemoveObserver(observer); | 47 ui::TreeNodeModel<WebIntentsTreeNode>::RemoveObserver(observer); |
| 48 } | 48 } |
| 49 | 49 |
| 50 string16 IntentsModel::GetTreeNodeId(IntentsTreeNode* node) { | 50 string16 WebIntentsModel::GetTreeNodeId(WebIntentsTreeNode* node) { |
| 51 if (node->Type() == IntentsTreeNode::TYPE_ORIGIN) | 51 if (node->Type() == WebIntentsTreeNode::TYPE_ORIGIN) |
| 52 return node->GetTitle(); | 52 return node->GetTitle(); |
| 53 | 53 |
| 54 // TODO(gbillock): handle TYPE_SERVICE when/if we ever want to do | 54 // TODO(gbillock): handle TYPE_SERVICE when/if we ever want to do |
| 55 // specific managing of them. | 55 // specific managing of them. |
| 56 | 56 |
| 57 return string16(); | 57 return string16(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 IntentsTreeNode* IntentsModel::GetTreeNode(std::string path_id) { | 60 WebIntentsTreeNode* WebIntentsModel::GetTreeNode(std::string path_id) { |
| 61 if (path_id.empty()) | 61 if (path_id.empty()) |
| 62 return GetRoot(); | 62 return GetRoot(); |
| 63 | 63 |
| 64 std::vector<std::string> node_ids; | 64 std::vector<std::string> node_ids; |
| 65 base::SplitString(path_id, ',', &node_ids); | 65 base::SplitString(path_id, ',', &node_ids); |
| 66 | 66 |
| 67 for (int i = 0; i < GetRoot()->child_count(); ++i) { | 67 for (int i = 0; i < GetRoot()->child_count(); ++i) { |
| 68 IntentsTreeNode* node = GetRoot()->GetChild(i); | 68 WebIntentsTreeNode* node = GetRoot()->GetChild(i); |
| 69 if (UTF16ToUTF8(node->GetTitle()) == node_ids[0]) { | 69 if (UTF16ToUTF8(node->GetTitle()) == node_ids[0]) { |
| 70 if (node_ids.size() == 1) | 70 if (node_ids.size() == 1) |
| 71 return node; | 71 return node; |
| 72 } | 72 } |
| 73 } | 73 } |
| 74 | 74 |
| 75 // TODO: support service nodes? | 75 // TODO: support service nodes? |
| 76 return NULL; | 76 return NULL; |
| 77 } | 77 } |
| 78 | 78 |
| 79 void IntentsModel::GetChildNodeList(IntentsTreeNode* parent, | 79 void WebIntentsModel::GetChildNodeList(WebIntentsTreeNode* parent, |
| 80 int start, int count, | 80 int start, int count, |
| 81 base::ListValue* nodes) { | 81 base::ListValue* nodes) { |
| 82 for (int i = 0; i < count; ++i) { | 82 for (int i = 0; i < count; ++i) { |
| 83 base::DictionaryValue* dict = new base::DictionaryValue; | 83 base::DictionaryValue* dict = new base::DictionaryValue; |
| 84 IntentsTreeNode* child = parent->GetChild(start + i); | 84 WebIntentsTreeNode* child = parent->GetChild(start + i); |
| 85 GetIntentsTreeNodeDictionary(*child, dict); | 85 GetWebIntentsTreeNodeDictionary(*child, dict); |
| 86 nodes->Append(dict); | 86 nodes->Append(dict); |
| 87 } | 87 } |
| 88 } | 88 } |
| 89 | 89 |
| 90 void IntentsModel::GetIntentsTreeNodeDictionary(const IntentsTreeNode& node, | 90 void WebIntentsModel::GetWebIntentsTreeNodeDictionary( |
| 91 base::DictionaryValue* dict) { | 91 const WebIntentsTreeNode& node, |
| 92 if (node.Type() == IntentsTreeNode::TYPE_ROOT) { | 92 base::DictionaryValue* dict) { |
| 93 if (node.Type() == WebIntentsTreeNode::TYPE_ROOT) { |
| 93 return; | 94 return; |
| 94 } | 95 } |
| 95 | 96 |
| 96 if (node.Type() == IntentsTreeNode::TYPE_ORIGIN) { | 97 if (node.Type() == WebIntentsTreeNode::TYPE_ORIGIN) { |
| 97 dict->SetString("site", node.GetTitle()); | 98 dict->SetString("site", node.GetTitle()); |
| 98 dict->SetBoolean("hasChildren", !node.empty()); | 99 dict->SetBoolean("hasChildren", !node.empty()); |
| 99 return; | 100 return; |
| 100 } | 101 } |
| 101 | 102 |
| 102 if (node.Type() == IntentsTreeNode::TYPE_SERVICE) { | 103 if (node.Type() == WebIntentsTreeNode::TYPE_SERVICE) { |
| 103 const ServiceTreeNode* snode = static_cast<const ServiceTreeNode*>(&node); | 104 const ServiceTreeNode* snode = static_cast<const ServiceTreeNode*>(&node); |
| 104 dict->SetString("site", snode->GetTitle()); | 105 dict->SetString("site", snode->GetTitle()); |
| 105 dict->SetString("name", snode->ServiceName()); | 106 dict->SetString("name", snode->ServiceName()); |
| 106 dict->SetString("url", snode->ServiceUrl()); | 107 dict->SetString("url", snode->ServiceUrl()); |
| 107 dict->SetString("icon", snode->IconUrl()); | 108 dict->SetString("icon", snode->IconUrl()); |
| 108 dict->SetString("action", snode->Action()); | 109 dict->SetString("action", snode->Action()); |
| 109 dict->Set("types", snode->Types().DeepCopy()); | 110 dict->Set("types", snode->Types().DeepCopy()); |
| 110 dict->SetBoolean("blocked", snode->IsBlocked()); | 111 dict->SetBoolean("blocked", snode->IsBlocked()); |
| 111 dict->SetBoolean("disabled", snode->IsDisabled()); | 112 dict->SetBoolean("disabled", snode->IsDisabled()); |
| 112 return; | 113 return; |
| 113 } | 114 } |
| 114 } | 115 } |
| 115 | 116 |
| 116 void IntentsModel::LoadModel() { | 117 void WebIntentsModel::LoadModel() { |
| 117 NotifyObserverBeginBatch(); | 118 NotifyObserverBeginBatch(); |
| 118 intents_registry_->GetAllIntentProviders(this); | 119 intents_registry_->GetAllIntentProviders(this); |
| 119 } | 120 } |
| 120 | 121 |
| 121 void IntentsModel::OnIntentsQueryDone( | 122 void WebIntentsModel::OnIntentsQueryDone( |
| 122 WebIntentsRegistry::QueryID query_id, | 123 WebIntentsRegistry::QueryID query_id, |
| 123 const std::vector<WebIntentData>& intents) { | 124 const std::vector<WebIntentData>& intents) { |
| 124 for (size_t i = 0; i < intents.size(); ++i) { | 125 for (size_t i = 0; i < intents.size(); ++i) { |
| 125 // Eventually do some awesome sorting, grouping, clustering stuff here. | 126 // Eventually do some awesome sorting, grouping, clustering stuff here. |
| 126 // For now, just stick it in the model flat. | 127 // For now, just stick it in the model flat. |
| 127 IntentsTreeNode* n = new IntentsTreeNode(ASCIIToUTF16( | 128 WebIntentsTreeNode* n = new WebIntentsTreeNode(ASCIIToUTF16( |
| 128 intents[i].service_url.host())); | 129 intents[i].service_url.host())); |
| 129 ServiceTreeNode* ns = new ServiceTreeNode(ASCIIToUTF16( | 130 ServiceTreeNode* ns = new ServiceTreeNode(ASCIIToUTF16( |
| 130 intents[i].service_url.host())); | 131 intents[i].service_url.host())); |
| 131 ns->SetServiceName(intents[i].title); | 132 ns->SetServiceName(intents[i].title); |
| 132 ns->SetServiceUrl(ASCIIToUTF16(intents[i].service_url.spec())); | 133 ns->SetServiceUrl(ASCIIToUTF16(intents[i].service_url.spec())); |
| 133 GURL icon_url = intents[i].service_url.GetOrigin().Resolve("/favicon.ico"); | 134 GURL icon_url = intents[i].service_url.GetOrigin().Resolve("/favicon.ico"); |
| 134 ns->SetIconUrl(ASCIIToUTF16(icon_url.spec())); | 135 ns->SetIconUrl(ASCIIToUTF16(icon_url.spec())); |
| 135 ns->SetAction(intents[i].action); | 136 ns->SetAction(intents[i].action); |
| 136 ns->AddType(intents[i].type); | 137 ns->AddType(intents[i].type); |
| 137 // Won't generate a notification. OK for now as the next line will. | 138 // Won't generate a notification. OK for now as the next line will. |
| 138 n->Add(ns, 0); | 139 n->Add(ns, 0); |
| 139 Add(GetRoot(), n, GetRoot()->child_count()); | 140 Add(GetRoot(), n, GetRoot()->child_count()); |
| 140 } | 141 } |
| 141 | 142 |
| 142 NotifyObserverEndBatch(); | 143 NotifyObserverEndBatch(); |
| 143 } | 144 } |
| 144 | 145 |
| 145 void IntentsModel::NotifyObserverBeginBatch() { | 146 void WebIntentsModel::NotifyObserverBeginBatch() { |
| 146 // Only notify the model once if we're batching in a nested manner. | 147 // Only notify the model once if we're batching in a nested manner. |
| 147 if (batch_update_++ == 0) { | 148 if (batch_update_++ == 0) { |
| 148 FOR_EACH_OBSERVER(Observer, | 149 FOR_EACH_OBSERVER(Observer, |
| 149 intents_observer_list_, | 150 intents_observer_list_, |
| 150 TreeModelBeginBatch(this)); | 151 TreeModelBeginBatch(this)); |
| 151 } | 152 } |
| 152 } | 153 } |
| 153 | 154 |
| 154 void IntentsModel::NotifyObserverEndBatch() { | 155 void WebIntentsModel::NotifyObserverEndBatch() { |
| 155 // Only notify the observers if this is the outermost call to EndBatch() if | 156 // Only notify the observers if this is the outermost call to EndBatch() if |
| 156 // called in a nested manner. | 157 // called in a nested manner. |
| 157 if (--batch_update_ == 0) { | 158 if (--batch_update_ == 0) { |
| 158 FOR_EACH_OBSERVER(Observer, | 159 FOR_EACH_OBSERVER(Observer, |
| 159 intents_observer_list_, | 160 intents_observer_list_, |
| 160 TreeModelEndBatch(this)); | 161 TreeModelEndBatch(this)); |
| 161 } | 162 } |
| 162 } | 163 } |
| OLD | NEW |