Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/controls/table/table_view.h" | 5 #include "ui/views/controls/table/table_view.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 std::string GetModelToViewAsString(TableView* table) { | 154 std::string GetModelToViewAsString(TableView* table) { |
| 155 std::string result; | 155 std::string result; |
| 156 for (int i = 0; i < table->RowCount(); ++i) { | 156 for (int i = 0; i < table->RowCount(); ++i) { |
| 157 if (i != 0) | 157 if (i != 0) |
| 158 result += " "; | 158 result += " "; |
| 159 result += base::IntToString(table->ModelToView(i)); | 159 result += base::IntToString(table->ModelToView(i)); |
| 160 } | 160 } |
| 161 return result; | 161 return result; |
| 162 } | 162 } |
| 163 | 163 |
| 164 std::string GetRowsInViewOrderAsString(TableView* table) { | |
|
sky
2016/07/18 16:18:58
add a description of the format of the returned st
ncarter (slow)
2016/07/25 20:04:02
Done.
| |
| 165 std::string result; | |
| 166 | |
| 167 std::string separator = ""; | |
|
sky
2016/07/18 16:18:58
nit: no = "", just std::string separator;
ncarter (slow)
2016/07/25 20:04:02
Done (switched to index checking).
| |
| 168 for (int row = 0; row < table->RowCount(); ++row) { | |
| 169 result += separator; | |
| 170 separator = "["; | |
| 171 for (auto column : table->visible_columns()) { | |
| 172 result += separator; | |
| 173 result += base::UTF16ToUTF8( | |
| 174 table->model()->GetText(table->ViewToModel(row), column.column.id)); | |
| 175 separator = ", "; | |
|
sky
2016/07/18 16:18:58
nit: reusing separator for the inner loop makes th
ncarter (slow)
2016/07/25 20:04:01
You're right, this was confusing. I switched to us
| |
| 176 } | |
| 177 result += "]"; | |
| 178 separator = ", "; | |
| 179 } | |
| 180 return result; | |
| 181 } | |
| 182 | |
| 164 class TestTableView : public TableView { | 183 class TestTableView : public TableView { |
| 165 public: | 184 public: |
| 166 TestTableView(ui::TableModel* model, | 185 TestTableView(ui::TableModel* model, |
| 167 const std::vector<ui::TableColumn>& columns) | 186 const std::vector<ui::TableColumn>& columns) |
| 168 : TableView(model, columns, TEXT_ONLY, false) { | 187 : TableView(model, columns, TEXT_ONLY, false) { |
| 169 } | 188 } |
| 170 | 189 |
| 171 // View overrides: | 190 // View overrides: |
| 172 bool HasFocus() const override { | 191 bool HasFocus() const override { |
| 173 // Overriden so key processing works. | 192 // Overriden so key processing works. |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); | 347 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); |
| 329 helper_->header()->OnGestureEvent(&scroll_update); | 348 helper_->header()->OnGestureEvent(&scroll_update); |
| 330 | 349 |
| 331 // This should shrink the first column and pull the second column in. | 350 // This should shrink the first column and pull the second column in. |
| 332 EXPECT_EQ(x - 1, table_->visible_columns()[0].width); | 351 EXPECT_EQ(x - 1, table_->visible_columns()[0].width); |
| 333 EXPECT_EQ(x - 1, table_->visible_columns()[1].x); | 352 EXPECT_EQ(x - 1, table_->visible_columns()[1].x); |
| 334 } | 353 } |
| 335 | 354 |
| 336 // Assertions for table sorting. | 355 // Assertions for table sorting. |
| 337 TEST_F(TableViewTest, Sort) { | 356 TEST_F(TableViewTest, Sort) { |
| 357 // Initial ordering. | |
| 358 ASSERT_EQ(0u, table_->sort_descriptors().size()); | |
|
sky
2016/07/18 16:18:58
nit: use empty
ncarter (slow)
2016/07/25 20:04:02
Done.
| |
| 359 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | |
| 360 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | |
| 361 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [3, 0]", | |
| 362 GetRowsInViewOrderAsString(table_)); | |
| 363 | |
| 338 // Toggle the sort order of the first column, shouldn't change anything. | 364 // Toggle the sort order of the first column, shouldn't change anything. |
| 339 table_->ToggleSortOrder(0); | 365 table_->ToggleSortOrder(0); |
| 340 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 366 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 341 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 367 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 342 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 368 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 343 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | 369 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 344 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | 370 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 371 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [3, 0]", | |
| 372 GetRowsInViewOrderAsString(table_)); | |
| 345 | 373 |
| 346 // Invert the sort (first column descending). | 374 // Toggle the sort (first column descending). |
| 347 table_->ToggleSortOrder(0); | 375 table_->ToggleSortOrder(0); |
| 348 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 376 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 349 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 377 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 350 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 378 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 351 EXPECT_EQ("3 2 1 0", GetViewToModelAsString(table_)); | 379 EXPECT_EQ("3 2 1 0", GetViewToModelAsString(table_)); |
| 352 EXPECT_EQ("3 2 1 0", GetModelToViewAsString(table_)); | 380 EXPECT_EQ("3 2 1 0", GetModelToViewAsString(table_)); |
| 381 EXPECT_EQ("[3, 0], [2, 2], [1, 1], [0, 1]", | |
| 382 GetRowsInViewOrderAsString(table_)); | |
| 353 | 383 |
| 354 // Change cell 0x3 to -1, meaning we have 0, 1, 2, -1 (in the first column). | 384 // Change the [3, 0] cell to [-1, 0]. This should move it to the back of |
| 385 // the current sort order. | |
| 355 model_->ChangeRow(3, -1, 0); | 386 model_->ChangeRow(3, -1, 0); |
| 356 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 387 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 357 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 388 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 358 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 389 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 359 EXPECT_EQ("2 1 0 3", GetViewToModelAsString(table_)); | 390 EXPECT_EQ("2 1 0 3", GetViewToModelAsString(table_)); |
| 360 EXPECT_EQ("2 1 0 3", GetModelToViewAsString(table_)); | 391 EXPECT_EQ("2 1 0 3", GetModelToViewAsString(table_)); |
| 392 EXPECT_EQ("[2, 2], [1, 1], [0, 1], [-1, 0]", | |
| 393 GetRowsInViewOrderAsString(table_)); | |
| 361 | 394 |
| 362 // Invert sort again (first column ascending). | 395 // Toggle the sort again, to clear the sort and restore the model ordering. |
| 396 table_->ToggleSortOrder(0); | |
| 397 ASSERT_EQ(0u, table_->sort_descriptors().size()); | |
| 398 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | |
| 399 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | |
| 400 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [-1, 0]", | |
| 401 GetRowsInViewOrderAsString(table_)); | |
| 402 | |
| 403 // Toggle the sort again (first column ascending). | |
| 363 table_->ToggleSortOrder(0); | 404 table_->ToggleSortOrder(0); |
| 364 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 405 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 365 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 406 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 366 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 407 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 367 EXPECT_EQ("3 0 1 2", GetViewToModelAsString(table_)); | 408 EXPECT_EQ("3 0 1 2", GetViewToModelAsString(table_)); |
| 368 EXPECT_EQ("1 2 3 0", GetModelToViewAsString(table_)); | 409 EXPECT_EQ("1 2 3 0", GetModelToViewAsString(table_)); |
| 410 EXPECT_EQ("[-1, 0], [0, 1], [1, 1], [2, 2]", | |
| 411 GetRowsInViewOrderAsString(table_)); | |
| 369 | 412 |
| 370 // Add a row so that model has 0, 3, 1, 2, -1. | 413 // Add a row that's second in the model order, but last in the active sort |
| 414 // order. | |
| 371 model_->AddRow(1, 3, 4); | 415 model_->AddRow(1, 3, 4); |
| 372 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 416 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 373 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 417 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 374 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 418 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 375 EXPECT_EQ("4 0 2 3 1", GetViewToModelAsString(table_)); | 419 EXPECT_EQ("4 0 2 3 1", GetViewToModelAsString(table_)); |
| 376 EXPECT_EQ("1 4 2 3 0", GetModelToViewAsString(table_)); | 420 EXPECT_EQ("1 4 2 3 0", GetModelToViewAsString(table_)); |
| 421 EXPECT_EQ("[-1, 0], [0, 1], [1, 1], [2, 2], [3, 4]", | |
| 422 GetRowsInViewOrderAsString(table_)); | |
| 377 | 423 |
| 378 // Delete the first row, ending up with 3, 1, 2, -1. | 424 // Add a row that's last in the model order but second in the the active sort |
| 379 model_->RemoveRow(0); | 425 // order. |
| 426 model_->AddRow(5, -1, 20); | |
| 380 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 427 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 381 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 428 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 382 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 429 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 383 EXPECT_EQ("3 1 2 0", GetViewToModelAsString(table_)); | 430 EXPECT_EQ("4 5 0 2 3 1", GetViewToModelAsString(table_)); |
| 384 EXPECT_EQ("3 1 2 0", GetModelToViewAsString(table_)); | 431 EXPECT_EQ("2 5 3 4 0 1", GetModelToViewAsString(table_)); |
| 432 EXPECT_EQ("[-1, 0], [-1, 20], [0, 1], [1, 1], [2, 2], [3, 4]", | |
| 433 GetRowsInViewOrderAsString(table_)); | |
| 434 | |
| 435 // Click the first column again, then click the second column. This should | |
| 436 // yield an ordering of second column ascending, with the first column | |
| 437 // descending as a tiebreaker. | |
| 438 table_->ToggleSortOrder(0); | |
| 439 table_->ToggleSortOrder(1); | |
| 440 ASSERT_EQ(2u, table_->sort_descriptors().size()); | |
| 441 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); | |
| 442 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | |
| 443 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); | |
| 444 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); | |
| 445 EXPECT_EQ("4 2 0 3 1 5", GetViewToModelAsString(table_)); | |
| 446 EXPECT_EQ("2 4 1 3 0 5", GetModelToViewAsString(table_)); | |
| 447 EXPECT_EQ("[-1, 0], [1, 1], [0, 1], [2, 2], [3, 4], [-1, 20]", | |
| 448 GetRowsInViewOrderAsString(table_)); | |
| 449 | |
| 450 // Toggle the current column to change from ascending to descending. This | |
| 451 // should result in an almost-reversal of the previous order, except for the | |
| 452 // two rows with the same value for the second column. | |
| 453 table_->ToggleSortOrder(1); | |
| 454 ASSERT_EQ(2u, table_->sort_descriptors().size()); | |
| 455 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); | |
| 456 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | |
| 457 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); | |
| 458 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); | |
| 459 EXPECT_EQ("5 1 3 2 0 4", GetViewToModelAsString(table_)); | |
| 460 EXPECT_EQ("4 1 3 2 5 0", GetModelToViewAsString(table_)); | |
| 461 EXPECT_EQ("[-1, 20], [3, 4], [2, 2], [1, 1], [0, 1], [-1, 0]", | |
| 462 GetRowsInViewOrderAsString(table_)); | |
| 463 | |
| 464 // Delete the [0, 1] row from the model. It's at model index zero. | |
| 465 model_->RemoveRow(0); | |
| 466 ASSERT_EQ(2u, table_->sort_descriptors().size()); | |
| 467 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); | |
| 468 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | |
| 469 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); | |
| 470 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); | |
| 471 EXPECT_EQ("4 0 2 1 3", GetViewToModelAsString(table_)); | |
| 472 EXPECT_EQ("1 3 2 4 0", GetModelToViewAsString(table_)); | |
| 473 EXPECT_EQ("[-1, 20], [3, 4], [2, 2], [1, 1], [-1, 0]", | |
| 474 GetRowsInViewOrderAsString(table_)); | |
| 475 | |
| 476 // Toggle the current sort column again. This should clear both the primary | |
| 477 // and secondary sort descriptor. | |
| 478 table_->ToggleSortOrder(1); | |
| 479 ASSERT_EQ(0u, table_->sort_descriptors().size()); | |
| 480 EXPECT_EQ("0 1 2 3 4", GetViewToModelAsString(table_)); | |
| 481 EXPECT_EQ("0 1 2 3 4", GetModelToViewAsString(table_)); | |
| 482 EXPECT_EQ("[3, 4], [1, 1], [2, 2], [-1, 0], [-1, 20]", | |
| 483 GetRowsInViewOrderAsString(table_)); | |
| 385 } | 484 } |
| 386 | 485 |
| 387 // Verfies clicking on the header sorts. | 486 // Verfies clicking on the header sorts. |
| 388 TEST_F(TableViewTest, SortOnMouse) { | 487 TEST_F(TableViewTest, SortOnMouse) { |
| 389 EXPECT_TRUE(table_->sort_descriptors().empty()); | 488 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 390 | 489 |
| 391 const int x = table_->visible_columns()[0].width / 2; | 490 const int x = table_->visible_columns()[0].width / 2; |
| 392 EXPECT_NE(0, x); | 491 EXPECT_NE(0, x); |
| 393 // Press and release the mouse. | 492 // Press and release the mouse. |
| 394 const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(x, 0), | 493 const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(x, 0), |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 // 1 | 593 // 1 |
| 495 // B -1 | 594 // B -1 |
| 496 // -1 | 595 // -1 |
| 497 model_->ChangeRow(2, -1, 0); | 596 model_->ChangeRow(2, -1, 0); |
| 498 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 597 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 499 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 598 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 500 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 599 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 501 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | 600 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 502 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | 601 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 503 | 602 |
| 504 // Toggle to ascending sort. | 603 // Toggle to clear the sort. |
| 604 table_->ToggleSortOrder(0); | |
| 605 ASSERT_EQ(0u, table_->sort_descriptors().size()); | |
| 606 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | |
| 607 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | |
| 608 | |
| 609 // Toggle again to effect an ascending sort. | |
| 505 table_->ToggleSortOrder(0); | 610 table_->ToggleSortOrder(0); |
| 506 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 611 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 507 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 612 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 508 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 613 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 509 EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_)); | 614 EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_)); |
| 510 EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_)); | 615 EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_)); |
| 511 } | 616 } |
| 512 | 617 |
| 513 namespace { | 618 namespace { |
| 514 | 619 |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 new_selection.AddIndexToSelection(0); | 1013 new_selection.AddIndexToSelection(0); |
| 909 new_selection.AddIndexToSelection(1); | 1014 new_selection.AddIndexToSelection(1); |
| 910 new_selection.set_active(0); | 1015 new_selection.set_active(0); |
| 911 new_selection.set_anchor(0); | 1016 new_selection.set_anchor(0); |
| 912 helper_->SetSelectionModel(new_selection); | 1017 helper_->SetSelectionModel(new_selection); |
| 913 model_->RemoveRow(0); | 1018 model_->RemoveRow(0); |
| 914 helper_->OnFocus(); | 1019 helper_->OnFocus(); |
| 915 } | 1020 } |
| 916 | 1021 |
| 917 } // namespace views | 1022 } // namespace views |
| OLD | NEW |