| 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 // Formats the whole table as a string, like: "[a, b, c], [d, e, f]". Rows |
| 165 // scrolled out of view are included; hidden columns are excluded. |
| 166 std::string GetRowsInViewOrderAsString(TableView* table) { |
| 167 std::string result; |
| 168 for (int i = 0; i < table->RowCount(); ++i) { |
| 169 if (i != 0) |
| 170 result += ", "; // Comma between each row. |
| 171 |
| 172 // Format row |i| like this: "[value1, value2, value3]" |
| 173 result += "["; |
| 174 for (size_t j = 0; j < table->visible_columns().size(); ++j) { |
| 175 const ui::TableColumn& column = table->visible_columns()[j].column; |
| 176 if (j != 0) |
| 177 result += ", "; // Comma between each value in the row. |
| 178 |
| 179 result += base::UTF16ToUTF8( |
| 180 table->model()->GetText(table->ViewToModel(i), column.id)); |
| 181 } |
| 182 result += "]"; |
| 183 } |
| 184 return result; |
| 185 } |
| 186 |
| 164 class TestTableView : public TableView { | 187 class TestTableView : public TableView { |
| 165 public: | 188 public: |
| 166 TestTableView(ui::TableModel* model, | 189 TestTableView(ui::TableModel* model, |
| 167 const std::vector<ui::TableColumn>& columns) | 190 const std::vector<ui::TableColumn>& columns) |
| 168 : TableView(model, columns, TEXT_ONLY, false) { | 191 : TableView(model, columns, TEXT_ONLY, false) { |
| 169 } | 192 } |
| 170 | 193 |
| 171 // View overrides: | 194 // View overrides: |
| 172 bool HasFocus() const override { | 195 bool HasFocus() const override { |
| 173 // Overriden so key processing works. | 196 // 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)); | 351 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); |
| 329 helper_->header()->OnGestureEvent(&scroll_update); | 352 helper_->header()->OnGestureEvent(&scroll_update); |
| 330 | 353 |
| 331 // This should shrink the first column and pull the second column in. | 354 // This should shrink the first column and pull the second column in. |
| 332 EXPECT_EQ(x - 1, table_->visible_columns()[0].width); | 355 EXPECT_EQ(x - 1, table_->visible_columns()[0].width); |
| 333 EXPECT_EQ(x - 1, table_->visible_columns()[1].x); | 356 EXPECT_EQ(x - 1, table_->visible_columns()[1].x); |
| 334 } | 357 } |
| 335 | 358 |
| 336 // Assertions for table sorting. | 359 // Assertions for table sorting. |
| 337 TEST_F(TableViewTest, Sort) { | 360 TEST_F(TableViewTest, Sort) { |
| 361 // Initial ordering. |
| 362 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 363 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 364 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 365 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [3, 0]", |
| 366 GetRowsInViewOrderAsString(table_)); |
| 367 |
| 338 // Toggle the sort order of the first column, shouldn't change anything. | 368 // Toggle the sort order of the first column, shouldn't change anything. |
| 339 table_->ToggleSortOrder(0); | 369 table_->ToggleSortOrder(0); |
| 340 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 370 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 341 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 371 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 342 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 372 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 343 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | 373 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 344 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | 374 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 375 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [3, 0]", |
| 376 GetRowsInViewOrderAsString(table_)); |
| 345 | 377 |
| 346 // Invert the sort (first column descending). | 378 // Toggle the sort (first column descending). |
| 347 table_->ToggleSortOrder(0); | 379 table_->ToggleSortOrder(0); |
| 348 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 380 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 349 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 381 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 350 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 382 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 351 EXPECT_EQ("3 2 1 0", GetViewToModelAsString(table_)); | 383 EXPECT_EQ("3 2 1 0", GetViewToModelAsString(table_)); |
| 352 EXPECT_EQ("3 2 1 0", GetModelToViewAsString(table_)); | 384 EXPECT_EQ("3 2 1 0", GetModelToViewAsString(table_)); |
| 385 EXPECT_EQ("[3, 0], [2, 2], [1, 1], [0, 1]", |
| 386 GetRowsInViewOrderAsString(table_)); |
| 353 | 387 |
| 354 // Change cell 0x3 to -1, meaning we have 0, 1, 2, -1 (in the first column). | 388 // Change the [3, 0] cell to [-1, 0]. This should move it to the back of |
| 389 // the current sort order. |
| 355 model_->ChangeRow(3, -1, 0); | 390 model_->ChangeRow(3, -1, 0); |
| 356 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 391 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 357 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 392 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 358 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 393 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 359 EXPECT_EQ("2 1 0 3", GetViewToModelAsString(table_)); | 394 EXPECT_EQ("2 1 0 3", GetViewToModelAsString(table_)); |
| 360 EXPECT_EQ("2 1 0 3", GetModelToViewAsString(table_)); | 395 EXPECT_EQ("2 1 0 3", GetModelToViewAsString(table_)); |
| 396 EXPECT_EQ("[2, 2], [1, 1], [0, 1], [-1, 0]", |
| 397 GetRowsInViewOrderAsString(table_)); |
| 361 | 398 |
| 362 // Invert sort again (first column ascending). | 399 // Toggle the sort again, to clear the sort and restore the model ordering. |
| 400 table_->ToggleSortOrder(0); |
| 401 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 402 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 403 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 404 EXPECT_EQ("[0, 1], [1, 1], [2, 2], [-1, 0]", |
| 405 GetRowsInViewOrderAsString(table_)); |
| 406 |
| 407 // Toggle the sort again (first column ascending). |
| 363 table_->ToggleSortOrder(0); | 408 table_->ToggleSortOrder(0); |
| 364 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 409 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 365 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 410 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 366 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 411 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 367 EXPECT_EQ("3 0 1 2", GetViewToModelAsString(table_)); | 412 EXPECT_EQ("3 0 1 2", GetViewToModelAsString(table_)); |
| 368 EXPECT_EQ("1 2 3 0", GetModelToViewAsString(table_)); | 413 EXPECT_EQ("1 2 3 0", GetModelToViewAsString(table_)); |
| 414 EXPECT_EQ("[-1, 0], [0, 1], [1, 1], [2, 2]", |
| 415 GetRowsInViewOrderAsString(table_)); |
| 369 | 416 |
| 370 // Add a row so that model has 0, 3, 1, 2, -1. | 417 // Add a row that's second in the model order, but last in the active sort |
| 418 // order. |
| 371 model_->AddRow(1, 3, 4); | 419 model_->AddRow(1, 3, 4); |
| 372 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 420 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 373 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 421 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 374 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 422 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 375 EXPECT_EQ("4 0 2 3 1", GetViewToModelAsString(table_)); | 423 EXPECT_EQ("4 0 2 3 1", GetViewToModelAsString(table_)); |
| 376 EXPECT_EQ("1 4 2 3 0", GetModelToViewAsString(table_)); | 424 EXPECT_EQ("1 4 2 3 0", GetModelToViewAsString(table_)); |
| 425 EXPECT_EQ("[-1, 0], [0, 1], [1, 1], [2, 2], [3, 4]", |
| 426 GetRowsInViewOrderAsString(table_)); |
| 377 | 427 |
| 378 // Delete the first row, ending up with 3, 1, 2, -1. | 428 // Add a row that's last in the model order but second in the the active sort |
| 379 model_->RemoveRow(0); | 429 // order. |
| 430 model_->AddRow(5, -1, 20); |
| 380 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 431 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 381 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 432 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 382 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 433 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 383 EXPECT_EQ("3 1 2 0", GetViewToModelAsString(table_)); | 434 EXPECT_EQ("4 5 0 2 3 1", GetViewToModelAsString(table_)); |
| 384 EXPECT_EQ("3 1 2 0", GetModelToViewAsString(table_)); | 435 EXPECT_EQ("2 5 3 4 0 1", GetModelToViewAsString(table_)); |
| 436 EXPECT_EQ("[-1, 0], [-1, 20], [0, 1], [1, 1], [2, 2], [3, 4]", |
| 437 GetRowsInViewOrderAsString(table_)); |
| 438 |
| 439 // Click the first column again, then click the second column. This should |
| 440 // yield an ordering of second column ascending, with the first column |
| 441 // descending as a tiebreaker. |
| 442 table_->ToggleSortOrder(0); |
| 443 table_->ToggleSortOrder(1); |
| 444 ASSERT_EQ(2u, table_->sort_descriptors().size()); |
| 445 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); |
| 446 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 447 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); |
| 448 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); |
| 449 EXPECT_EQ("4 2 0 3 1 5", GetViewToModelAsString(table_)); |
| 450 EXPECT_EQ("2 4 1 3 0 5", GetModelToViewAsString(table_)); |
| 451 EXPECT_EQ("[-1, 0], [1, 1], [0, 1], [2, 2], [3, 4], [-1, 20]", |
| 452 GetRowsInViewOrderAsString(table_)); |
| 453 |
| 454 // Toggle the current column to change from ascending to descending. This |
| 455 // should result in an almost-reversal of the previous order, except for the |
| 456 // two rows with the same value for the second column. |
| 457 table_->ToggleSortOrder(1); |
| 458 ASSERT_EQ(2u, table_->sort_descriptors().size()); |
| 459 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); |
| 460 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 461 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); |
| 462 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); |
| 463 EXPECT_EQ("5 1 3 2 0 4", GetViewToModelAsString(table_)); |
| 464 EXPECT_EQ("4 1 3 2 5 0", GetModelToViewAsString(table_)); |
| 465 EXPECT_EQ("[-1, 20], [3, 4], [2, 2], [1, 1], [0, 1], [-1, 0]", |
| 466 GetRowsInViewOrderAsString(table_)); |
| 467 |
| 468 // Delete the [0, 1] row from the model. It's at model index zero. |
| 469 model_->RemoveRow(0); |
| 470 ASSERT_EQ(2u, table_->sort_descriptors().size()); |
| 471 EXPECT_EQ(1, table_->sort_descriptors()[0].column_id); |
| 472 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 473 EXPECT_EQ(0, table_->sort_descriptors()[1].column_id); |
| 474 EXPECT_FALSE(table_->sort_descriptors()[1].ascending); |
| 475 EXPECT_EQ("4 0 2 1 3", GetViewToModelAsString(table_)); |
| 476 EXPECT_EQ("1 3 2 4 0", GetModelToViewAsString(table_)); |
| 477 EXPECT_EQ("[-1, 20], [3, 4], [2, 2], [1, 1], [-1, 0]", |
| 478 GetRowsInViewOrderAsString(table_)); |
| 479 |
| 480 // Toggle the current sort column again. This should clear both the primary |
| 481 // and secondary sort descriptor. |
| 482 table_->ToggleSortOrder(1); |
| 483 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 484 EXPECT_EQ("0 1 2 3 4", GetViewToModelAsString(table_)); |
| 485 EXPECT_EQ("0 1 2 3 4", GetModelToViewAsString(table_)); |
| 486 EXPECT_EQ("[3, 4], [1, 1], [2, 2], [-1, 0], [-1, 20]", |
| 487 GetRowsInViewOrderAsString(table_)); |
| 385 } | 488 } |
| 386 | 489 |
| 387 // Verfies clicking on the header sorts. | 490 // Verfies clicking on the header sorts. |
| 388 TEST_F(TableViewTest, SortOnMouse) { | 491 TEST_F(TableViewTest, SortOnMouse) { |
| 389 EXPECT_TRUE(table_->sort_descriptors().empty()); | 492 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 390 | 493 |
| 391 const int x = table_->visible_columns()[0].width / 2; | 494 const int x = table_->visible_columns()[0].width / 2; |
| 392 EXPECT_NE(0, x); | 495 EXPECT_NE(0, x); |
| 393 // Press and release the mouse. | 496 // Press and release the mouse. |
| 394 const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(x, 0), | 497 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 | 597 // 1 |
| 495 // B -1 | 598 // B -1 |
| 496 // -1 | 599 // -1 |
| 497 model_->ChangeRow(2, -1, 0); | 600 model_->ChangeRow(2, -1, 0); |
| 498 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 601 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 499 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 602 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 500 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); | 603 EXPECT_FALSE(table_->sort_descriptors()[0].ascending); |
| 501 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); | 604 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 502 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); | 605 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 503 | 606 |
| 504 // Toggle to ascending sort. | 607 // Toggle to clear the sort. |
| 608 table_->ToggleSortOrder(0); |
| 609 EXPECT_TRUE(table_->sort_descriptors().empty()); |
| 610 EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_)); |
| 611 EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_)); |
| 612 |
| 613 // Toggle again to effect an ascending sort. |
| 505 table_->ToggleSortOrder(0); | 614 table_->ToggleSortOrder(0); |
| 506 ASSERT_EQ(1u, table_->sort_descriptors().size()); | 615 ASSERT_EQ(1u, table_->sort_descriptors().size()); |
| 507 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); | 616 EXPECT_EQ(0, table_->sort_descriptors()[0].column_id); |
| 508 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); | 617 EXPECT_TRUE(table_->sort_descriptors()[0].ascending); |
| 509 EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_)); | 618 EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_)); |
| 510 EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_)); | 619 EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_)); |
| 511 } | 620 } |
| 512 | 621 |
| 513 namespace { | 622 namespace { |
| 514 | 623 |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 new_selection.AddIndexToSelection(0); | 1017 new_selection.AddIndexToSelection(0); |
| 909 new_selection.AddIndexToSelection(1); | 1018 new_selection.AddIndexToSelection(1); |
| 910 new_selection.set_active(0); | 1019 new_selection.set_active(0); |
| 911 new_selection.set_anchor(0); | 1020 new_selection.set_anchor(0); |
| 912 helper_->SetSelectionModel(new_selection); | 1021 helper_->SetSelectionModel(new_selection); |
| 913 model_->RemoveRow(0); | 1022 model_->RemoveRow(0); |
| 914 helper_->OnFocus(); | 1023 helper_->OnFocus(); |
| 915 } | 1024 } |
| 916 | 1025 |
| 917 } // namespace views | 1026 } // namespace views |
| OLD | NEW |