Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/bookmark_table_view.h" | 5 #include "chrome/browser/views/bookmark_table_view.h" |
| 6 | 6 |
| 7 #include "base/base_drag_source.h" | 7 #include "base/base_drag_source.h" |
| 8 #include "chrome/browser/bookmarks/bookmark_utils.h" | 8 #include "chrome/browser/bookmarks/bookmark_utils.h" |
| 9 #include "chrome/browser/bookmarks/bookmark_model.h" | 9 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 10 #include "chrome/browser/bookmarks/bookmark_table_model.h" | 10 #include "chrome/browser/bookmarks/bookmark_table_model.h" |
| 11 #include "chrome/browser/profile.h" | 11 #include "chrome/browser/profile.h" |
| 12 #include "chrome/common/drag_drop_types.h" | 12 #include "chrome/common/drag_drop_types.h" |
| 13 #include "chrome/common/os_exchange_data.h" | 13 #include "chrome/common/os_exchange_data.h" |
| 14 #include "chrome/common/pref_names.h" | 14 #include "chrome/common/pref_names.h" |
| 15 #include "chrome/common/pref_service.h" | 15 #include "chrome/common/pref_service.h" |
| 16 #include "chrome/views/chrome_menu.h" | 16 #include "chrome/views/view_constants.h" |
| 17 | 17 |
| 18 #include "generated_resources.h" | 18 #include "generated_resources.h" |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Height of the drop indicator used when dropping between rows. | 22 // Height of the drop indicator used when dropping between rows. |
| 23 const int kDropHighlightHeight = 2; | 23 const int kDropHighlightHeight = 2; |
| 24 | 24 |
| 25 int GetWidthOfColumn(const std::vector<views::TableColumn>& columns, | 25 int GetWidthOfColumn(const std::vector<views::TableColumn>& columns, |
| 26 const std::vector<int> widths, | 26 const std::vector<int> widths, |
| 27 int column_id) { | 27 int column_id) { |
| 28 for (size_t i = 0; i < columns.size(); ++i) { | 28 for (size_t i = 0; i < columns.size(); ++i) { |
| 29 if (columns[i].id == column_id) | 29 if (columns[i].id == column_id) |
| 30 return widths[i]; | 30 return widths[i]; |
| 31 } | 31 } |
| 32 NOTREACHED(); | 32 NOTREACHED(); |
| 33 return -1; | 33 return -1; |
| 34 } | 34 } |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 void BookmarkTableView::DropInfo::Scrolled() { | |
| 39 view_->UpdateDropInfo(); | |
| 40 } | |
| 41 | |
| 38 BookmarkTableView::BookmarkTableView(Profile* profile, | 42 BookmarkTableView::BookmarkTableView(Profile* profile, |
| 39 BookmarkTableModel* model) | 43 BookmarkTableModel* model) |
| 40 : views::TableView(model, std::vector<views::TableColumn>(), | 44 : views::TableView(model, std::vector<views::TableColumn>(), |
| 41 views::ICON_AND_TEXT, false, true, true), | 45 views::ICON_AND_TEXT, false, true, true), |
| 42 profile_(profile), | 46 profile_(profile), |
| 43 show_path_column_(false) { | 47 show_path_column_(false) { |
| 44 UpdateColumns(); | 48 UpdateColumns(); |
| 45 } | 49 } |
| 46 | 50 |
| 47 // static | 51 // static |
| 48 void BookmarkTableView::RegisterUserPrefs(PrefService* prefs) { | 52 void BookmarkTableView::RegisterUserPrefs(PrefService* prefs) { |
| 49 prefs->RegisterIntegerPref(prefs::kBookmarkTableNameWidth1, -1); | 53 prefs->RegisterIntegerPref(prefs::kBookmarkTableNameWidth1, -1); |
| 50 prefs->RegisterIntegerPref(prefs::kBookmarkTableURLWidth1, -1); | 54 prefs->RegisterIntegerPref(prefs::kBookmarkTableURLWidth1, -1); |
| 51 prefs->RegisterIntegerPref(prefs::kBookmarkTableNameWidth2, -1); | 55 prefs->RegisterIntegerPref(prefs::kBookmarkTableNameWidth2, -1); |
| 52 prefs->RegisterIntegerPref(prefs::kBookmarkTableURLWidth2, -1); | 56 prefs->RegisterIntegerPref(prefs::kBookmarkTableURLWidth2, -1); |
| 53 prefs->RegisterIntegerPref(prefs::kBookmarkTablePathWidth, -1); | 57 prefs->RegisterIntegerPref(prefs::kBookmarkTablePathWidth, -1); |
| 54 } | 58 } |
| 55 | 59 |
| 56 bool BookmarkTableView::CanDrop(const OSExchangeData& data) { | 60 bool BookmarkTableView::CanDrop(const OSExchangeData& data) { |
| 57 if (!parent_node_ || !profile_->GetBookmarkModel()->IsLoaded()) | 61 if (!parent_node_ || !profile_->GetBookmarkModel()->IsLoaded()) |
| 58 return false; | 62 return false; |
| 59 | 63 |
| 60 drop_info_.reset(new DropInfo()); | 64 BookmarkDragData drag_data; |
| 61 if (!drop_info_->drag_data.Read(data)) | 65 if (!drag_data.Read(data)) |
| 62 return false; | 66 return false; |
| 63 | 67 |
| 64 // Don't allow the user to drop an ancestor of the parent node onto the | 68 // Don't allow the user to drop an ancestor of the parent node onto the |
| 65 // parent node. This would create a cycle, which is definitely a no-no. | 69 // parent node. This would create a cycle, which is definitely a no-no. |
| 66 std::vector<BookmarkNode*> nodes = drop_info_->drag_data.GetNodes(profile_); | 70 std::vector<BookmarkNode*> nodes = drag_data.GetNodes(profile_); |
| 67 for (size_t i = 0; i < nodes.size(); ++i) { | 71 for (size_t i = 0; i < nodes.size(); ++i) { |
| 68 if (parent_node_->HasAncestor(nodes[i])) | 72 if (parent_node_->HasAncestor(nodes[i])) |
| 69 return false; | 73 return false; |
| 70 } | 74 } |
| 75 | |
| 76 drop_info_.reset(new DropInfo(this)); | |
| 77 drop_info_->SetData(drag_data); | |
| 71 return true; | 78 return true; |
| 72 } | 79 } |
| 73 | 80 |
| 74 void BookmarkTableView::OnDragEntered(const views::DropTargetEvent& event) { | 81 void BookmarkTableView::OnDragEntered(const views::DropTargetEvent& event) { |
| 75 } | 82 } |
| 76 | 83 |
| 77 int BookmarkTableView::OnDragUpdated(const views::DropTargetEvent& event) { | 84 int BookmarkTableView::OnDragUpdated(const views::DropTargetEvent& event) { |
| 78 if (!parent_node_) | 85 if (!parent_node_ || !drop_info_.get()) { |
| 86 drop_info_.reset(NULL); | |
| 79 return false; | 87 return false; |
| 80 | |
| 81 LVHITTESTINFO hit_info = {0}; | |
| 82 hit_info.pt.x = event.x(); | |
| 83 hit_info.pt.y = event.y(); | |
| 84 // TODO(sky): need to support auto-scroll and all that good stuff. | |
| 85 | |
| 86 int drop_index; | |
| 87 bool drop_on; | |
| 88 drop_index = CalculateDropIndex(event.y(), &drop_on); | |
| 89 | |
| 90 drop_info_->drop_operation = | |
| 91 CalculateDropOperation(event, drop_index, drop_on); | |
| 92 | |
| 93 if (drop_info_->drop_operation == DragDropTypes::DRAG_NONE) { | |
| 94 drop_index = -1; | |
| 95 drop_on = false; | |
| 96 } | 88 } |
| 97 | 89 |
| 98 SetDropIndex(drop_index, drop_on); | 90 drop_info_->Update(event); |
| 99 | 91 return UpdateDropInfo(); |
| 100 return drop_info_->drop_operation; | |
| 101 } | 92 } |
| 102 | 93 |
| 103 void BookmarkTableView::OnDragExited() { | 94 void BookmarkTableView::OnDragExited() { |
| 104 SetDropIndex(-1, false); | 95 SetDropPosition(DropPosition()); |
| 105 drop_info_.reset(); | 96 drop_info_.reset(); |
| 106 } | 97 } |
| 107 | 98 |
| 108 int BookmarkTableView::OnPerformDrop(const views::DropTargetEvent& event) { | 99 int BookmarkTableView::OnPerformDrop(const views::DropTargetEvent& event) { |
| 109 OnPerformDropImpl(); | 100 OnPerformDropImpl(); |
| 110 int drop_operation = drop_info_->drop_operation; | 101 int drop_operation = drop_info_->drop_operation(); |
| 111 SetDropIndex(-1, false); | 102 SetDropPosition(DropPosition()); |
| 112 drop_info_.reset(); | 103 drop_info_.reset(); |
| 113 return drop_operation; | 104 return drop_operation; |
| 114 } | 105 } |
| 115 | 106 |
| 116 BookmarkTableModel* BookmarkTableView::bookmark_table_model() const { | 107 BookmarkTableModel* BookmarkTableView::bookmark_table_model() const { |
| 117 return static_cast<BookmarkTableModel*>(model()); | 108 return static_cast<BookmarkTableModel*>(model()); |
| 118 } | 109 } |
| 119 | 110 |
| 120 void BookmarkTableView::SaveColumnConfiguration() { | 111 void BookmarkTableView::SaveColumnConfiguration() { |
| 121 PrefService* prefs = profile_->GetPrefs(); | 112 PrefService* prefs = profile_->GetPrefs(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 141 if (show_path_column == show_path_column_) | 132 if (show_path_column == show_path_column_) |
| 142 return; | 133 return; |
| 143 | 134 |
| 144 SaveColumnConfiguration(); | 135 SaveColumnConfiguration(); |
| 145 | 136 |
| 146 show_path_column_ = show_path_column; | 137 show_path_column_ = show_path_column; |
| 147 UpdateColumns(); | 138 UpdateColumns(); |
| 148 } | 139 } |
| 149 | 140 |
| 150 void BookmarkTableView::PostPaint() { | 141 void BookmarkTableView::PostPaint() { |
| 151 if (!drop_info_.get() || drop_info_->drop_index == -1 || | 142 if (!drop_info_.get() || drop_info_->position().index == -1 || |
| 152 drop_info_->drop_on) { | 143 drop_info_->position().on) { |
| 153 return; | 144 return; |
| 154 } | 145 } |
| 155 | 146 |
| 156 RECT bounds = GetDropBetweenHighlightRect(drop_info_->drop_index); | 147 RECT bounds = GetDropBetweenHighlightRect(drop_info_->position().index); |
| 157 HDC dc = GetDC(GetNativeControlHWND()); | 148 HDC dc = GetDC(GetNativeControlHWND()); |
| 158 HBRUSH brush = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT)); | 149 HBRUSH brush = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT)); |
| 159 FillRect(dc, &bounds, brush); | 150 FillRect(dc, &bounds, brush); |
| 160 DeleteObject(brush); | 151 DeleteObject(brush); |
| 161 ReleaseDC(GetNativeControlHWND(), dc); | 152 ReleaseDC(GetNativeControlHWND(), dc); |
| 162 } | 153 } |
| 163 | 154 |
| 164 LRESULT BookmarkTableView::OnNotify(int w_param, LPNMHDR l_param) { | 155 LRESULT BookmarkTableView::OnNotify(int w_param, LPNMHDR l_param) { |
| 165 switch(l_param->code) { | 156 switch(l_param->code) { |
| 166 case LVN_BEGINDRAG: | 157 case LVN_BEGINDRAG: |
| 167 BeginDrag(); | 158 BeginDrag(); |
| 168 return 0; // Return value doesn't matter for this message. | 159 return 0; // Return value doesn't matter for this message. |
| 169 } | 160 } |
| 170 | 161 |
| 171 return TableView::OnNotify(w_param, l_param); | 162 return TableView::OnNotify(w_param, l_param); |
| 172 } | 163 } |
| 173 | 164 |
| 165 int BookmarkTableView::UpdateDropInfo() { | |
| 166 DropPosition position = CalculateDropPosition(drop_info_->last_y()); | |
| 167 | |
| 168 drop_info_->set_drop_operation(CalculateDropOperation(position)); | |
| 169 | |
| 170 if (drop_info_->drop_operation() == DragDropTypes::DRAG_NONE) | |
| 171 position = DropPosition(); | |
| 172 | |
| 173 SetDropPosition(position); | |
| 174 | |
| 175 return drop_info_->drop_operation(); | |
| 176 } | |
| 177 | |
| 174 void BookmarkTableView::BeginDrag() { | 178 void BookmarkTableView::BeginDrag() { |
| 175 std::vector<BookmarkNode*> nodes_to_drag; | 179 std::vector<BookmarkNode*> nodes_to_drag; |
| 176 for (TableView::iterator i = SelectionBegin(); i != SelectionEnd(); ++i) | 180 for (TableView::iterator i = SelectionBegin(); i != SelectionEnd(); ++i) |
| 177 nodes_to_drag.push_back(bookmark_table_model()->GetNodeForRow(*i)); | 181 nodes_to_drag.push_back(bookmark_table_model()->GetNodeForRow(*i)); |
| 178 if (nodes_to_drag.empty()) | 182 if (nodes_to_drag.empty()) |
| 179 return; // Nothing to drag. | 183 return; // Nothing to drag. |
| 180 | 184 |
| 181 scoped_refptr<OSExchangeData> data = new OSExchangeData; | 185 scoped_refptr<OSExchangeData> data = new OSExchangeData; |
| 182 BookmarkDragData(nodes_to_drag).Write(profile_, data); | 186 BookmarkDragData(nodes_to_drag).Write(profile_, data); |
| 183 scoped_refptr<BaseDragSource> drag_source(new BaseDragSource); | 187 scoped_refptr<BaseDragSource> drag_source(new BaseDragSource); |
| 184 DWORD effects; | 188 DWORD effects; |
| 185 DoDragDrop(data, drag_source, | 189 DoDragDrop(data, drag_source, |
| 186 DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &effects); | 190 DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &effects); |
| 187 } | 191 } |
| 188 | 192 |
| 189 int BookmarkTableView::CalculateDropOperation( | 193 int BookmarkTableView::CalculateDropOperation(const DropPosition& position) { |
| 190 const views::DropTargetEvent& event, | 194 if (drop_info_->data().IsFromProfile(profile_)) { |
| 191 int drop_index, | |
| 192 bool drop_on) { | |
| 193 if (drop_info_->drag_data.IsFromProfile(profile_)) { | |
| 194 // Data from the same profile. Prefer move, but do copy if the user wants | 195 // Data from the same profile. Prefer move, but do copy if the user wants |
| 195 // that. | 196 // that. |
| 196 if (event.IsControlDown()) | 197 if (drop_info_->is_control_down()) |
| 197 return DragDropTypes::DRAG_COPY; | 198 return DragDropTypes::DRAG_COPY; |
| 198 | 199 |
| 199 int real_drop_index; | 200 int real_drop_index; |
| 200 BookmarkNode* drop_parent = GetDropParentAndIndex(drop_index, drop_on, | 201 BookmarkNode* drop_parent = GetDropParentAndIndex(position, |
| 201 &real_drop_index); | 202 &real_drop_index); |
| 202 if (!bookmark_utils::IsValidDropLocation( | 203 if (!bookmark_utils::IsValidDropLocation( |
| 203 profile_, drop_info_->drag_data, drop_parent, real_drop_index)) { | 204 profile_, drop_info_->data(), drop_parent, real_drop_index)) { |
| 204 return DragDropTypes::DRAG_NONE; | 205 return DragDropTypes::DRAG_NONE; |
| 205 } | 206 } |
| 206 return DragDropTypes::DRAG_MOVE; | 207 return DragDropTypes::DRAG_MOVE; |
| 207 } | 208 } |
| 208 // We're going to copy, but return an operation compatible with the source | 209 // We're going to copy, but return an operation compatible with the source |
| 209 // operations so that the user can drop. | 210 // operations so that the user can drop. |
| 210 return bookmark_utils::PreferredDropOperation( | 211 return bookmark_utils::PreferredDropOperation( |
| 211 event, DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); | 212 drop_info_->source_operations(), |
| 213 DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); | |
| 212 } | 214 } |
| 213 | 215 |
| 214 void BookmarkTableView::OnPerformDropImpl() { | 216 void BookmarkTableView::OnPerformDropImpl() { |
| 215 int drop_index; | 217 int drop_index; |
| 216 BookmarkNode* drop_parent = GetDropParentAndIndex( | 218 BookmarkNode* drop_parent = GetDropParentAndIndex( |
| 217 drop_info_->drop_index, drop_info_->drop_on, &drop_index); | 219 drop_info_->position(), &drop_index); |
| 218 BookmarkModel* model = profile_->GetBookmarkModel(); | 220 BookmarkModel* model = profile_->GetBookmarkModel(); |
| 219 int min_selection; | 221 int min_selection; |
| 220 int max_selection; | 222 int max_selection; |
| 221 // If the data is not from this profile we return an operation compatible | 223 // If the data is not from this profile we return an operation compatible |
| 222 // with the source. As such, we need to need to check the data here too. | 224 // with the source. As such, we need to need to check the data here too. |
| 223 if (!drop_info_->drag_data.IsFromProfile(profile_) || | 225 if (!drop_info_->data().IsFromProfile(profile_) || |
| 224 drop_info_->drop_operation == DragDropTypes::DRAG_COPY) { | 226 drop_info_->drop_operation() == DragDropTypes::DRAG_COPY) { |
| 225 bookmark_utils::CloneDragData(model, drop_info_->drag_data.elements, | 227 bookmark_utils::CloneDragData(model, drop_info_->data().elements, |
| 226 drop_parent, drop_index); | 228 drop_parent, drop_index); |
| 227 min_selection = drop_index; | 229 min_selection = drop_index; |
| 228 max_selection = drop_index + | 230 max_selection = drop_index + |
| 229 static_cast<int>(drop_info_->drag_data.elements.size()); | 231 static_cast<int>(drop_info_->data().elements.size()); |
| 230 } else { | 232 } else { |
| 231 // else, move. | 233 // else, move. |
| 232 std::vector<BookmarkNode*> nodes = drop_info_->drag_data.GetNodes(profile_); | 234 std::vector<BookmarkNode*> nodes = drop_info_->data().GetNodes(profile_); |
| 233 if (nodes.empty()) | 235 if (nodes.empty()) |
| 234 return; | 236 return; |
| 235 | 237 |
| 236 for (size_t i = 0; i < nodes.size(); ++i) { | 238 for (size_t i = 0; i < nodes.size(); ++i) { |
| 237 model->Move(nodes[i], drop_parent, drop_index); | 239 model->Move(nodes[i], drop_parent, drop_index); |
| 238 // Reset the drop_index, just in case the index didn't really change. | 240 // Reset the drop_index, just in case the index didn't really change. |
| 239 drop_index = drop_parent->IndexOfChild(nodes[i]) + 1; | 241 drop_index = drop_parent->IndexOfChild(nodes[i]) + 1; |
| 240 } | 242 } |
| 241 min_selection = drop_parent->IndexOfChild(nodes[0]); | 243 min_selection = drop_parent->IndexOfChild(nodes[0]); |
| 242 max_selection = min_selection + static_cast<int>(nodes.size()); | 244 max_selection = min_selection + static_cast<int>(nodes.size()); |
| 243 } | 245 } |
| 244 if (min_selection < RowCount() && max_selection < RowCount()) { | 246 if (drop_info_->position().on) { |
| 247 // The user dropped on a folder, select it. | |
| 248 int index = parent_node_->IndexOfChild(drop_parent); | |
| 249 if (index != -1) | |
| 250 Select(index); | |
| 251 } else if (min_selection < RowCount() && max_selection <= RowCount()) { | |
| 245 // Select the moved/copied rows. | 252 // Select the moved/copied rows. |
| 246 Select(min_selection); | 253 Select(min_selection); |
| 247 if (min_selection + 1 < max_selection) { | 254 if (min_selection + 1 < max_selection) { |
| 248 // SetSelectedState doesn't send notification, so we manually do it. | 255 // SetSelectedState doesn't send notification, so we manually do it. |
| 249 for (int i = min_selection + 1; i < max_selection; ++i) | 256 for (int i = min_selection + 1; i < max_selection; ++i) |
| 250 SetSelectedState(i, true); | 257 SetSelectedState(i, true); |
| 251 if (observer()) | 258 if (observer()) |
| 252 observer()->OnSelectionChanged(); | 259 observer()->OnSelectionChanged(); |
| 253 } | 260 } |
| 254 } | 261 } |
| 255 } | 262 } |
| 256 | 263 |
| 257 void BookmarkTableView::SetDropIndex(int index, bool drop_on) { | 264 void BookmarkTableView::SetDropPosition(const DropPosition& position) { |
| 258 if (drop_info_->drop_index == index && drop_info_->drop_on == drop_on) | 265 if (drop_info_->position().equals(position)) |
| 259 return; | 266 return; |
| 260 | 267 |
| 261 UpdateDropIndex(drop_info_->drop_index, drop_info_->drop_on, false); | 268 UpdateDropIndicator(drop_info_->position(), false); |
| 262 | 269 |
| 263 drop_info_->drop_index = index; | 270 drop_info_->set_position(position); |
| 264 drop_info_->drop_on = drop_on; | |
| 265 | 271 |
| 266 UpdateDropIndex(drop_info_->drop_index, drop_info_->drop_on, true); | 272 UpdateDropIndicator(drop_info_->position(), true); |
| 267 } | 273 } |
| 268 | 274 |
| 269 void BookmarkTableView::UpdateDropIndex(int index, bool drop_on, bool turn_on) { | 275 void BookmarkTableView::UpdateDropIndicator(const DropPosition& position, |
| 270 if (index == -1) | 276 bool turn_on) { |
| 277 if (position.index == -1) | |
| 271 return; | 278 return; |
| 272 | 279 |
| 273 if (drop_on) { | 280 if (position.on) { |
|
ncarter (slow)
2008/11/04 18:39:47
btw, what confused me about this function in the e
| |
| 274 ListView_SetItemState(GetNativeControlHWND(), index, | 281 ListView_SetItemState(GetNativeControlHWND(), position.index, |
| 275 turn_on ? LVIS_DROPHILITED : 0, LVIS_DROPHILITED); | 282 turn_on ? LVIS_DROPHILITED : 0, LVIS_DROPHILITED); |
| 276 } else { | 283 } else { |
| 277 RECT bounds = GetDropBetweenHighlightRect(index); | 284 RECT bounds = GetDropBetweenHighlightRect(position.index); |
| 278 InvalidateRect(GetNativeControlHWND(), &bounds, FALSE); | 285 InvalidateRect(GetNativeControlHWND(), &bounds, FALSE); |
| 279 } | 286 } |
| 280 } | 287 } |
| 281 | 288 |
| 282 int BookmarkTableView::CalculateDropIndex(int y, bool* drop_on) { | 289 BookmarkTableView::DropPosition |
| 283 *drop_on = false; | 290 BookmarkTableView::CalculateDropPosition(int y) { |
| 284 HWND hwnd = GetNativeControlHWND(); | 291 HWND hwnd = GetNativeControlHWND(); |
| 285 int row_count = RowCount(); | 292 int row_count = RowCount(); |
| 286 int top_index = ListView_GetTopIndex(hwnd); | 293 int top_index = ListView_GetTopIndex(hwnd); |
| 287 if (row_count == 0 || top_index < 0) | 294 if (row_count == 0 || top_index < 0) |
| 288 return 0; | 295 return DropPosition(0, false); |
| 289 | 296 |
| 290 for (int i = top_index; i < row_count; ++i) { | 297 for (int i = top_index; i < row_count; ++i) { |
| 291 RECT bounds; | 298 RECT bounds; |
| 292 ListView_GetItemRect(hwnd, i, &bounds, LVIR_BOUNDS); | 299 ListView_GetItemRect(hwnd, i, &bounds, LVIR_BOUNDS); |
| 293 if (y < bounds.top) | 300 if (y < bounds.top) |
| 294 return i; | 301 return DropPosition(i, false); |
| 295 if (y < bounds.bottom) { | 302 if (y < bounds.bottom) { |
| 296 if (bookmark_table_model()->GetNodeForRow(i)->is_folder()) { | 303 if (bookmark_table_model()->GetNodeForRow(i)->is_folder()) { |
| 297 if (y < bounds.top + views::MenuItemView::kDropBetweenPixels) | 304 if (y < bounds.top + views::kDropBetweenPixels) |
| 298 return i; | 305 return DropPosition(i, false); |
| 299 if (y >= bounds.bottom - views::MenuItemView::kDropBetweenPixels) | 306 if (y >= bounds.bottom - views::kDropBetweenPixels) |
| 300 return i + 1; | 307 return DropPosition(i + 1, false); |
| 301 *drop_on = true; | 308 return DropPosition(i, true); |
| 302 return i; | |
| 303 } | 309 } |
| 304 if (y < (bounds.bottom - bounds.top) / 2 + bounds.top) | 310 if (y < (bounds.bottom - bounds.top) / 2 + bounds.top) |
| 305 return i; | 311 return DropPosition(i, false); |
| 306 return i + 1; | 312 return DropPosition(i + 1, false); |
| 307 } | 313 } |
| 308 } | 314 } |
| 309 return row_count; | 315 return DropPosition(row_count, false); |
| 310 } | 316 } |
| 311 | 317 |
| 312 BookmarkNode* BookmarkTableView::GetDropParentAndIndex(int visual_drop_index, | 318 BookmarkNode* BookmarkTableView::GetDropParentAndIndex( |
| 313 bool drop_on, | 319 const DropPosition& position, |
| 314 int* index) { | 320 int* index) { |
| 315 if (drop_on) { | 321 if (position.on) { |
| 316 BookmarkNode* parent = parent_node_->GetChild(visual_drop_index); | 322 BookmarkNode* parent = parent_node_->GetChild(position.index); |
| 317 *index = parent->GetChildCount(); | 323 *index = parent->GetChildCount(); |
| 318 return parent; | 324 return parent; |
| 319 } | 325 } |
| 320 *index = visual_drop_index; | 326 *index = position.index; |
| 321 return parent_node_; | 327 return parent_node_; |
| 322 } | 328 } |
| 323 | 329 |
| 324 RECT BookmarkTableView::GetDropBetweenHighlightRect(int index) { | 330 RECT BookmarkTableView::GetDropBetweenHighlightRect(int index) { |
| 325 RECT bounds = { 0 }; | 331 RECT bounds = { 0 }; |
| 326 if (RowCount() == 0) { | 332 if (RowCount() == 0) { |
| 327 bounds.top = content_offset(); | 333 bounds.top = content_offset(); |
| 328 bounds.left = 0; | 334 bounds.left = 0; |
| 329 bounds.right = width(); | 335 bounds.right = width(); |
| 330 } else if (index >= RowCount()) { | 336 } else if (index >= RowCount()) { |
| 331 ListView_GetItemRect(GetNativeControlHWND(), index - 1, &bounds, | 337 ListView_GetItemRect(GetNativeControlHWND(), index - 1, &bounds, |
| 332 LVIR_BOUNDS); | 338 LVIR_BOUNDS); |
| 333 bounds.top = bounds.bottom - kDropHighlightHeight / 2; | 339 bounds.top = bounds.bottom - kDropHighlightHeight / 2; |
| 334 } else { | 340 } else { |
| 335 ListView_GetItemRect(GetNativeControlHWND(), index, &bounds, LVIR_BOUNDS); | 341 ListView_GetItemRect(GetNativeControlHWND(), index, &bounds, LVIR_BOUNDS); |
| 336 bounds.top -= kDropHighlightHeight / 2; | 342 bounds.top -= kDropHighlightHeight / 2; |
| 337 } | 343 } |
| 338 bounds.bottom = bounds.top + kDropHighlightHeight; | 344 bounds.bottom = bounds.top + kDropHighlightHeight; |
| 339 return bounds; | 345 return bounds; |
| 340 } | 346 } |
| 347 | |
| 341 void BookmarkTableView::UpdateColumns() { | 348 void BookmarkTableView::UpdateColumns() { |
| 342 PrefService* prefs = profile_->GetPrefs(); | 349 PrefService* prefs = profile_->GetPrefs(); |
| 343 views::TableColumn name_column = | 350 views::TableColumn name_column = |
| 344 views::TableColumn(IDS_BOOKMARK_TABLE_TITLE, views::TableColumn::LEFT, | 351 views::TableColumn(IDS_BOOKMARK_TABLE_TITLE, views::TableColumn::LEFT, |
| 345 -1); | 352 -1); |
| 346 views::TableColumn url_column = | 353 views::TableColumn url_column = |
| 347 views::TableColumn(IDS_BOOKMARK_TABLE_URL, views::TableColumn::LEFT, -1); | 354 views::TableColumn(IDS_BOOKMARK_TABLE_URL, views::TableColumn::LEFT, -1); |
| 348 views::TableColumn path_column = | 355 views::TableColumn path_column = |
| 349 views::TableColumn(IDS_BOOKMARK_TABLE_PATH, views::TableColumn::LEFT, -1); | 356 views::TableColumn(IDS_BOOKMARK_TABLE_PATH, views::TableColumn::LEFT, -1); |
| 350 | 357 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 url_column.percent = .5; | 392 url_column.percent = .5; |
| 386 } | 393 } |
| 387 columns.push_back(name_column); | 394 columns.push_back(name_column); |
| 388 columns.push_back(url_column); | 395 columns.push_back(url_column); |
| 389 } | 396 } |
| 390 SetColumns(columns); | 397 SetColumns(columns); |
| 391 for (size_t i = 0; i < columns.size(); ++i) | 398 for (size_t i = 0; i < columns.size(); ++i) |
| 392 SetColumnVisibility(columns[i].id, true); | 399 SetColumnVisibility(columns[i].id, true); |
| 393 OnModelChanged(); | 400 OnModelChanged(); |
| 394 } | 401 } |
| OLD | NEW |