| 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 "views/controls/table/table_view.h" | 5 #include "views/controls/table/table_view.h" |
| 6 | 6 |
| 7 #include <commctrl.h> | 7 #include <commctrl.h> |
| 8 #include <windowsx.h> | 8 #include <windowsx.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 | 11 |
| 12 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "skia/ext/skia_utils_win.h" | 14 #include "skia/ext/skia_utils_win.h" |
| 15 #include "third_party/skia/include/core/SkBitmap.h" | 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 16 #include "third_party/skia/include/core/SkColorFilter.h" | 16 #include "third_party/skia/include/core/SkColorFilter.h" |
| 17 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
| 18 #include "ui/base/l10n/l10n_util_win.h" | 18 #include "ui/base/l10n/l10n_util_win.h" |
| 19 #include "ui/base/models/table_model.h" | 19 #include "ui/base/models/table_model.h" |
| 20 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/base/win/hwnd_util.h" | 21 #include "ui/base/win/hwnd_util.h" |
| 22 #include "ui/gfx/canvas_skia.h" | 22 #include "ui/gfx/canvas_skia.h" |
| 23 #include "ui/gfx/favicon_size.h" | 23 #include "ui/gfx/favicon_size.h" |
| 24 #include "ui/gfx/font.h" | 24 #include "ui/gfx/font.h" |
| 25 #include "ui/gfx/icon_util.h" | 25 #include "ui/gfx/icon_util.h" |
| 26 #include "views/controls/native/native_view_host.h" | 26 #include "views/controls/native/native_view_host.h" |
| 27 #include "views/controls/table/table_view_observer.h" | 27 #include "views/controls/table/table_view_observer.h" |
| 28 | 28 |
| 29 using ui::TableColumn; | |
| 30 | |
| 31 namespace { | 29 namespace { |
| 32 | 30 |
| 33 int GetViewIndexFromPoint(HWND window, const gfx::Point& p) { | 31 int GetViewIndexFromPoint(HWND window, const gfx::Point& p) { |
| 34 LVHITTESTINFO hit_info = {0}; | 32 LVHITTESTINFO hit_info = {0}; |
| 35 hit_info.pt.x = p.x(); | 33 hit_info.pt.x = p.x(); |
| 36 hit_info.pt.y = p.y(); | 34 hit_info.pt.y = p.y(); |
| 37 return ListView_HitTest(window, &hit_info); | 35 return ListView_HitTest(window, &hit_info); |
| 38 } | 36 } |
| 39 | 37 |
| 40 } // namespace | 38 } // namespace |
| 41 | 39 |
| 42 namespace views { | 40 namespace views { |
| 43 | 41 |
| 44 // Added to column width to prevent truncation. | 42 // Added to column width to prevent truncation. |
| 45 const int kListViewTextPadding = 15; | 43 const int kListViewTextPadding = 15; |
| 46 // Additional column width necessary if column has icons. | 44 // Additional column width necessary if column has icons. |
| 47 const int kListViewIconWidthAndPadding = 18; | 45 const int kListViewIconWidthAndPadding = 18; |
| 48 | 46 |
| 49 // TableView ------------------------------------------------------------------ | 47 // TableView ------------------------------------------------------------------ |
| 50 | 48 |
| 51 // static | 49 // static |
| 52 const int TableView::kImageSize = 18; | 50 const int TableView::kImageSize = 18; |
| 53 | 51 |
| 54 TableView::TableView(TableModel* model, | 52 TableView::TableView(ui::TableModel* model, |
| 55 const std::vector<TableColumn>& columns, | 53 const std::vector<ui::TableColumn>& columns, |
| 56 TableTypes table_type, | 54 TableTypes table_type, |
| 57 bool single_selection, | 55 bool single_selection, |
| 58 bool resizable_columns, | 56 bool resizable_columns, |
| 59 bool autosize_columns) | 57 bool autosize_columns) |
| 60 : model_(model), | 58 : model_(model), |
| 61 table_view_observer_(NULL), | 59 table_view_observer_(NULL), |
| 62 visible_columns_(), | 60 visible_columns_(), |
| 63 all_columns_(), | 61 all_columns_(), |
| 64 column_count_(static_cast<int>(columns.size())), | 62 column_count_(static_cast<int>(columns.size())), |
| 65 table_type_(table_type), | 63 table_type_(table_type), |
| 66 single_selection_(single_selection), | 64 single_selection_(single_selection), |
| 67 ignore_listview_change_(false), | 65 ignore_listview_change_(false), |
| 68 custom_colors_enabled_(false), | 66 custom_colors_enabled_(false), |
| 69 autosize_columns_(autosize_columns), | 67 autosize_columns_(autosize_columns), |
| 70 resizable_columns_(resizable_columns), | 68 resizable_columns_(resizable_columns), |
| 71 list_view_(NULL), | 69 list_view_(NULL), |
| 72 header_original_handler_(NULL), | 70 header_original_handler_(NULL), |
| 73 original_handler_(NULL), | 71 original_handler_(NULL), |
| 74 ALLOW_THIS_IN_INITIALIZER_LIST(table_view_wrapper_(this)), | 72 ALLOW_THIS_IN_INITIALIZER_LIST(table_view_wrapper_(this)), |
| 75 custom_cell_font_(NULL), | 73 custom_cell_font_(NULL), |
| 76 content_offset_(0) { | 74 content_offset_(0) { |
| 77 for (std::vector<TableColumn>::const_iterator i = columns.begin(); | 75 for (std::vector<ui::TableColumn>::const_iterator i = columns.begin(); |
| 78 i != columns.end(); ++i) { | 76 i != columns.end(); ++i) { |
| 79 AddColumn(*i); | 77 AddColumn(*i); |
| 80 visible_columns_.push_back(i->id); | 78 visible_columns_.push_back(i->id); |
| 81 } | 79 } |
| 82 } | 80 } |
| 83 | 81 |
| 84 TableView::~TableView() { | 82 TableView::~TableView() { |
| 85 if (list_view_) { | 83 if (list_view_) { |
| 86 if (model_) | 84 if (model_) |
| 87 model_->SetObserver(NULL); | 85 model_->SetObserver(NULL); |
| 88 } | 86 } |
| 89 if (custom_cell_font_) | 87 if (custom_cell_font_) |
| 90 DeleteObject(custom_cell_font_); | 88 DeleteObject(custom_cell_font_); |
| 91 } | 89 } |
| 92 | 90 |
| 93 void TableView::SetModel(TableModel* model) { | 91 void TableView::SetModel(ui::TableModel* model) { |
| 94 if (model == model_) | 92 if (model == model_) |
| 95 return; | 93 return; |
| 96 | 94 |
| 97 if (list_view_ && model_) | 95 if (list_view_ && model_) |
| 98 model_->SetObserver(NULL); | 96 model_->SetObserver(NULL); |
| 99 model_ = model; | 97 model_ = model; |
| 100 if (list_view_ && model_) | 98 if (list_view_ && model_) |
| 101 model_->SetObserver(this); | 99 model_->SetObserver(this); |
| 102 if (list_view_) | 100 if (list_view_) |
| 103 OnModelChanged(); | 101 OnModelChanged(); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // invoked, so we handle it here. | 349 // invoked, so we handle it here. |
| 352 // | 350 // |
| 353 // When the model is set to NULL all the rows are removed. We don't notify | 351 // When the model is set to NULL all the rows are removed. We don't notify |
| 354 // the delegate in this case as setting the model to NULL is usually done as | 352 // the delegate in this case as setting the model to NULL is usually done as |
| 355 // the last step before being deleted and callers shouldn't have to deal with | 353 // the last step before being deleted and callers shouldn't have to deal with |
| 356 // getting a selection change when the model is being reset. | 354 // getting a selection change when the model is being reset. |
| 357 if (model_ && table_view_observer_ && had_selection && RowCount() == 0) | 355 if (model_ && table_view_observer_ && had_selection && RowCount() == 0) |
| 358 table_view_observer_->OnSelectionChanged(); | 356 table_view_observer_->OnSelectionChanged(); |
| 359 } | 357 } |
| 360 | 358 |
| 361 void TableView::AddColumn(const TableColumn& col) { | 359 void TableView::AddColumn(const ui::TableColumn& col) { |
| 362 DCHECK_EQ(0u, all_columns_.count(col.id)); | 360 DCHECK_EQ(0u, all_columns_.count(col.id)); |
| 363 all_columns_[col.id] = col; | 361 all_columns_[col.id] = col; |
| 364 } | 362 } |
| 365 | 363 |
| 366 void TableView::SetColumns(const std::vector<TableColumn>& columns) { | 364 void TableView::SetColumns(const std::vector<ui::TableColumn>& columns) { |
| 367 // Remove the currently visible columns. | 365 // Remove the currently visible columns. |
| 368 while (!visible_columns_.empty()) | 366 while (!visible_columns_.empty()) |
| 369 SetColumnVisibility(visible_columns_.front(), false); | 367 SetColumnVisibility(visible_columns_.front(), false); |
| 370 | 368 |
| 371 all_columns_.clear(); | 369 all_columns_.clear(); |
| 372 for (std::vector<TableColumn>::const_iterator i = columns.begin(); | 370 for (std::vector<ui::TableColumn>::const_iterator i = columns.begin(); |
| 373 i != columns.end(); ++i) { | 371 i != columns.end(); ++i) { |
| 374 AddColumn(*i); | 372 AddColumn(*i); |
| 375 } | 373 } |
| 376 | 374 |
| 377 // Remove any sort descriptors that are no longer valid. | 375 // Remove any sort descriptors that are no longer valid. |
| 378 SortDescriptors sort = sort_descriptors(); | 376 SortDescriptors sort = sort_descriptors(); |
| 379 for (SortDescriptors::iterator i = sort.begin(); i != sort.end();) { | 377 for (SortDescriptors::iterator i = sort.begin(); i != sort.end();) { |
| 380 if (all_columns_.count(i->column_id) == 0) | 378 if (all_columns_.count(i->column_id) == 0) |
| 381 i = sort.erase(i); | 379 i = sort.erase(i); |
| 382 else | 380 else |
| (...skipping 24 matching lines...) Expand all Loading... |
| 407 if (list_view_) | 405 if (list_view_) |
| 408 SendMessage(list_view_, LVM_DELETECOLUMN, index, 0); | 406 SendMessage(list_view_, LVM_DELETECOLUMN, index, 0); |
| 409 visible_columns_.erase(i); | 407 visible_columns_.erase(i); |
| 410 changed = true; | 408 changed = true; |
| 411 break; | 409 break; |
| 412 } | 410 } |
| 413 } | 411 } |
| 414 } | 412 } |
| 415 if (is_visible) { | 413 if (is_visible) { |
| 416 visible_columns_.push_back(id); | 414 visible_columns_.push_back(id); |
| 417 TableColumn& column = all_columns_[id]; | 415 ui::TableColumn& column = all_columns_[id]; |
| 418 InsertColumn(column, column_count_); | 416 InsertColumn(column, column_count_); |
| 419 if (column.min_visible_width == 0) { | 417 if (column.min_visible_width == 0) { |
| 420 // ListView_GetStringWidth must be padded or else truncation will occur. | 418 // ListView_GetStringWidth must be padded or else truncation will occur. |
| 421 column.min_visible_width = ListView_GetStringWidth(list_view_, | 419 column.min_visible_width = ListView_GetStringWidth(list_view_, |
| 422 column.title.c_str()) + | 420 column.title.c_str()) + |
| 423 kListViewTextPadding; | 421 kListViewTextPadding; |
| 424 } | 422 } |
| 425 changed = true; | 423 changed = true; |
| 426 } | 424 } |
| 427 if (changed) | 425 if (changed) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 453 | 451 |
| 454 bool TableView::IsColumnVisible(int id) const { | 452 bool TableView::IsColumnVisible(int id) const { |
| 455 for (std::vector<int>::const_iterator i = visible_columns_.begin(); | 453 for (std::vector<int>::const_iterator i = visible_columns_.begin(); |
| 456 i != visible_columns_.end(); ++i) | 454 i != visible_columns_.end(); ++i) |
| 457 if (*i == id) { | 455 if (*i == id) { |
| 458 return true; | 456 return true; |
| 459 } | 457 } |
| 460 return false; | 458 return false; |
| 461 } | 459 } |
| 462 | 460 |
| 463 const TableColumn& TableView::GetColumnAtPosition(int pos) { | 461 const ui::TableColumn& TableView::GetColumnAtPosition(int pos) { |
| 464 return all_columns_[visible_columns_[pos]]; | 462 return all_columns_[visible_columns_[pos]]; |
| 465 } | 463 } |
| 466 | 464 |
| 467 bool TableView::HasColumn(int id) { | 465 bool TableView::HasColumn(int id) { |
| 468 return all_columns_.count(id) > 0; | 466 return all_columns_.count(id) > 0; |
| 469 } | 467 } |
| 470 | 468 |
| 471 gfx::Point TableView::GetKeyboardContextMenuLocation() { | 469 gfx::Point TableView::GetKeyboardContextMenuLocation() { |
| 472 int first_selected = FirstSelectedRow(); | 470 int first_selected = FirstSelectedRow(); |
| 473 int y = height() / 2; | 471 int y = height() / 2; |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 window, message, w_param, l_param); | 756 window, message, w_param, l_param); |
| 759 } | 757 } |
| 760 | 758 |
| 761 HWND TableView::CreateNativeControl(HWND parent_container) { | 759 HWND TableView::CreateNativeControl(HWND parent_container) { |
| 762 int style = WS_CHILD | LVS_REPORT | LVS_SHOWSELALWAYS; | 760 int style = WS_CHILD | LVS_REPORT | LVS_SHOWSELALWAYS; |
| 763 if (single_selection_) | 761 if (single_selection_) |
| 764 style |= LVS_SINGLESEL; | 762 style |= LVS_SINGLESEL; |
| 765 // If there's only one column and the title string is empty, don't show a | 763 // If there's only one column and the title string is empty, don't show a |
| 766 // header. | 764 // header. |
| 767 if (all_columns_.size() == 1) { | 765 if (all_columns_.size() == 1) { |
| 768 std::map<int, TableColumn>::const_iterator first = | 766 std::map<int, ui::TableColumn>::const_iterator first = all_columns_.begin(); |
| 769 all_columns_.begin(); | |
| 770 if (first->second.title.empty()) | 767 if (first->second.title.empty()) |
| 771 style |= LVS_NOCOLUMNHEADER; | 768 style |= LVS_NOCOLUMNHEADER; |
| 772 } | 769 } |
| 773 list_view_ = ::CreateWindowEx(WS_EX_CLIENTEDGE | GetAdditionalRTLStyle(), | 770 list_view_ = ::CreateWindowEx(WS_EX_CLIENTEDGE | GetAdditionalRTLStyle(), |
| 774 WC_LISTVIEW, | 771 WC_LISTVIEW, |
| 775 L"", | 772 L"", |
| 776 style, | 773 style, |
| 777 0, 0, width(), height(), | 774 0, 0, width(), height(), |
| 778 parent_container, NULL, NULL, NULL); | 775 parent_container, NULL, NULL, NULL); |
| 779 ui::CheckWindowCreated(list_view_); | 776 ui::CheckWindowCreated(list_view_); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 header_item.mask = HDI_FORMAT; | 965 header_item.mask = HDI_FORMAT; |
| 969 Header_GetItem(header, column_index, &header_item); | 966 Header_GetItem(header, column_index, &header_item); |
| 970 header_item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN); | 967 header_item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN); |
| 971 if (direction == ASCENDING_SORT) | 968 if (direction == ASCENDING_SORT) |
| 972 header_item.fmt |= HDF_SORTUP; | 969 header_item.fmt |= HDF_SORTUP; |
| 973 else if (direction == DESCENDING_SORT) | 970 else if (direction == DESCENDING_SORT) |
| 974 header_item.fmt |= HDF_SORTDOWN; | 971 header_item.fmt |= HDF_SORTDOWN; |
| 975 Header_SetItem(header, column_index, &header_item); | 972 Header_SetItem(header, column_index, &header_item); |
| 976 } | 973 } |
| 977 | 974 |
| 978 void TableView::InsertColumn(const TableColumn& tc, int index) { | 975 void TableView::InsertColumn(const ui::TableColumn& tc, int index) { |
| 979 if (!list_view_) | 976 if (!list_view_) |
| 980 return; | 977 return; |
| 981 | 978 |
| 982 LVCOLUMN column = { 0 }; | 979 LVCOLUMN column = { 0 }; |
| 983 column.mask = LVCF_TEXT|LVCF_FMT; | 980 column.mask = LVCF_TEXT|LVCF_FMT; |
| 984 column.pszText = const_cast<LPWSTR>(tc.title.c_str()); | 981 column.pszText = const_cast<LPWSTR>(tc.title.c_str()); |
| 985 switch (tc.alignment) { | 982 switch (tc.alignment) { |
| 986 case TableColumn::LEFT: | 983 case ui::TableColumn::LEFT: |
| 987 column.fmt = LVCFMT_LEFT; | 984 column.fmt = LVCFMT_LEFT; |
| 988 break; | 985 break; |
| 989 case TableColumn::RIGHT: | 986 case ui::TableColumn::RIGHT: |
| 990 column.fmt = LVCFMT_RIGHT; | 987 column.fmt = LVCFMT_RIGHT; |
| 991 break; | 988 break; |
| 992 case TableColumn::CENTER: | 989 case ui::TableColumn::CENTER: |
| 993 column.fmt = LVCFMT_CENTER; | 990 column.fmt = LVCFMT_CENTER; |
| 994 break; | 991 break; |
| 995 default: | 992 default: |
| 996 NOTREACHED(); | 993 NOTREACHED(); |
| 997 } | 994 } |
| 998 if (tc.width != -1) { | 995 if (tc.width != -1) { |
| 999 column.mask |= LVCF_WIDTH; | 996 column.mask |= LVCF_WIDTH; |
| 1000 column.cx = tc.width; | 997 column.cx = tc.width; |
| 1001 } | 998 } |
| 1002 column.mask |= LVCF_SUBITEM; | 999 column.mask |= LVCF_SUBITEM; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 // Prevent clicks so columns cannot be resized. | 1037 // Prevent clicks so columns cannot be resized. |
| 1041 if (!resizable_columns_) | 1038 if (!resizable_columns_) |
| 1042 return TRUE; | 1039 return TRUE; |
| 1043 break; | 1040 break; |
| 1044 | 1041 |
| 1045 case NM_DBLCLK: | 1042 case NM_DBLCLK: |
| 1046 OnDoubleClick(); | 1043 OnDoubleClick(); |
| 1047 break; | 1044 break; |
| 1048 | 1045 |
| 1049 case LVN_COLUMNCLICK: { | 1046 case LVN_COLUMNCLICK: { |
| 1050 const TableColumn& column = GetColumnAtPosition( | 1047 const ui::TableColumn& column = GetColumnAtPosition( |
| 1051 reinterpret_cast<NMLISTVIEW*>(hdr)->iSubItem); | 1048 reinterpret_cast<NMLISTVIEW*>(hdr)->iSubItem); |
| 1052 if (column.sortable) | 1049 if (column.sortable) |
| 1053 ToggleSortOrder(column.id); | 1050 ToggleSortOrder(column.id); |
| 1054 break; | 1051 break; |
| 1055 } | 1052 } |
| 1056 | 1053 |
| 1057 case LVN_MARQUEEBEGIN: // We don't want the marquee selection. | 1054 case LVN_MARQUEEBEGIN: // We don't want the marquee selection. |
| 1058 return 1; | 1055 return 1; |
| 1059 | 1056 |
| 1060 case LVN_GETINFOTIP: { | 1057 case LVN_GETINFOTIP: { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 column_sizes_valid_ = true; | 1317 column_sizes_valid_ = true; |
| 1321 } | 1318 } |
| 1322 } | 1319 } |
| 1323 | 1320 |
| 1324 float percent = 0; | 1321 float percent = 0; |
| 1325 int fixed_width = 0; | 1322 int fixed_width = 0; |
| 1326 int autosize_width = 0; | 1323 int autosize_width = 0; |
| 1327 | 1324 |
| 1328 for (std::vector<int>::const_iterator i = visible_columns_.begin(); | 1325 for (std::vector<int>::const_iterator i = visible_columns_.begin(); |
| 1329 i != visible_columns_.end(); ++i) { | 1326 i != visible_columns_.end(); ++i) { |
| 1330 TableColumn& col = all_columns_[*i]; | 1327 ui::TableColumn& col = all_columns_[*i]; |
| 1331 int col_index = static_cast<int>(i - visible_columns_.begin()); | 1328 int col_index = static_cast<int>(i - visible_columns_.begin()); |
| 1332 if (col.width == -1) { | 1329 if (col.width == -1) { |
| 1333 if (col.percent > 0) { | 1330 if (col.percent > 0) { |
| 1334 percent += col.percent; | 1331 percent += col.percent; |
| 1335 } else { | 1332 } else { |
| 1336 autosize_width += col.min_visible_width; | 1333 autosize_width += col.min_visible_width; |
| 1337 } | 1334 } |
| 1338 } else { | 1335 } else { |
| 1339 fixed_width += ListView_GetColumnWidth(list_view_, col_index); | 1336 fixed_width += ListView_GetColumnWidth(list_view_, col_index); |
| 1340 } | 1337 } |
| 1341 } | 1338 } |
| 1342 | 1339 |
| 1343 // Now do a pass to set the actual sizes of auto-sized and | 1340 // Now do a pass to set the actual sizes of auto-sized and |
| 1344 // percent-sized columns. | 1341 // percent-sized columns. |
| 1345 int available_width = width - fixed_width - autosize_width; | 1342 int available_width = width - fixed_width - autosize_width; |
| 1346 for (std::vector<int>::const_iterator i = visible_columns_.begin(); | 1343 for (std::vector<int>::const_iterator i = visible_columns_.begin(); |
| 1347 i != visible_columns_.end(); ++i) { | 1344 i != visible_columns_.end(); ++i) { |
| 1348 TableColumn& col = all_columns_[*i]; | 1345 ui::TableColumn& col = all_columns_[*i]; |
| 1349 if (col.width == -1) { | 1346 if (col.width == -1) { |
| 1350 int col_index = static_cast<int>(i - visible_columns_.begin()); | 1347 int col_index = static_cast<int>(i - visible_columns_.begin()); |
| 1351 if (col.percent > 0) { | 1348 if (col.percent > 0) { |
| 1352 if (available_width > 0) { | 1349 if (available_width > 0) { |
| 1353 int col_width = | 1350 int col_width = |
| 1354 static_cast<int>(available_width * (col.percent / percent)); | 1351 static_cast<int>(available_width * (col.percent / percent)); |
| 1355 available_width -= col_width; | 1352 available_width -= col_width; |
| 1356 percent -= col.percent; | 1353 percent -= col.percent; |
| 1357 ListView_SetColumnWidth(list_view_, col_index, col_width); | 1354 ListView_SetColumnWidth(list_view_, col_index, col_width); |
| 1358 } | 1355 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 item.lParam = i; | 1428 item.lParam = i; |
| 1432 ListView_InsertItem(list_view_, &item); | 1429 ListView_InsertItem(list_view_, &item); |
| 1433 } | 1430 } |
| 1434 } | 1431 } |
| 1435 | 1432 |
| 1436 memset(&item, 0, sizeof(LVITEM)); | 1433 memset(&item, 0, sizeof(LVITEM)); |
| 1437 item.mask = | 1434 item.mask = |
| 1438 (table_type_ == ICON_AND_TEXT) ? (LVIF_IMAGE | LVIF_TEXT) : LVIF_TEXT; | 1435 (table_type_ == ICON_AND_TEXT) ? (LVIF_IMAGE | LVIF_TEXT) : LVIF_TEXT; |
| 1439 item.stateMask = 0; | 1436 item.stateMask = 0; |
| 1440 for (int j = 0; j < column_count_; ++j) { | 1437 for (int j = 0; j < column_count_; ++j) { |
| 1441 TableColumn& col = all_columns_[visible_columns_[j]]; | 1438 ui::TableColumn& col = all_columns_[visible_columns_[j]]; |
| 1442 int max_text_width = ListView_GetStringWidth(list_view_, col.title.c_str()); | 1439 int max_text_width = ListView_GetStringWidth(list_view_, col.title.c_str()); |
| 1443 for (int i = start; i < start + length; ++i) { | 1440 for (int i = start; i < start + length; ++i) { |
| 1444 // Set item. | 1441 // Set item. |
| 1445 item.iItem = add ? i : ModelToView(i); | 1442 item.iItem = add ? i : ModelToView(i); |
| 1446 item.iSubItem = j; | 1443 item.iSubItem = j; |
| 1447 std::wstring text = model_->GetText(i, visible_columns_[j]); | 1444 std::wstring text = model_->GetText(i, visible_columns_[j]); |
| 1448 item.pszText = const_cast<LPWSTR>(text.c_str()); | 1445 item.pszText = const_cast<LPWSTR>(text.c_str()); |
| 1449 ListView_SetItem(list_view_, &item); | 1446 ListView_SetItem(list_view_, &item); |
| 1450 | 1447 |
| 1451 // Compute width in px, using current font. | 1448 // Compute width in px, using current font. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 | 1550 |
| 1554 void TableView::UpdateGroups() { | 1551 void TableView::UpdateGroups() { |
| 1555 // Add the groups. | 1552 // Add the groups. |
| 1556 if (model_ && model_->HasGroups()) { | 1553 if (model_ && model_->HasGroups()) { |
| 1557 ListView_RemoveAllGroups(list_view_); | 1554 ListView_RemoveAllGroups(list_view_); |
| 1558 | 1555 |
| 1559 // Windows XP seems to disable groups if we remove them, so we | 1556 // Windows XP seems to disable groups if we remove them, so we |
| 1560 // re-enable them. | 1557 // re-enable them. |
| 1561 ListView_EnableGroupView(list_view_, true); | 1558 ListView_EnableGroupView(list_view_, true); |
| 1562 | 1559 |
| 1563 TableModel::Groups groups = model_->GetGroups(); | 1560 ui::TableModel::Groups groups = model_->GetGroups(); |
| 1564 LVGROUP group = { 0 }; | 1561 LVGROUP group = { 0 }; |
| 1565 group.cbSize = sizeof(LVGROUP); | 1562 group.cbSize = sizeof(LVGROUP); |
| 1566 group.mask = LVGF_HEADER | LVGF_ALIGN | LVGF_GROUPID; | 1563 group.mask = LVGF_HEADER | LVGF_ALIGN | LVGF_GROUPID; |
| 1567 group.uAlign = LVGA_HEADER_LEFT; | 1564 group.uAlign = LVGA_HEADER_LEFT; |
| 1568 for (size_t i = 0; i < groups.size(); ++i) { | 1565 for (size_t i = 0; i < groups.size(); ++i) { |
| 1569 group.pszHeader = const_cast<wchar_t*>(groups[i].title.c_str()); | 1566 group.pszHeader = const_cast<wchar_t*>(groups[i].title.c_str()); |
| 1570 group.iGroupId = groups[i].id; | 1567 group.iGroupId = groups[i].id; |
| 1571 ListView_InsertGroup(list_view_, static_cast<int>(i), &group); | 1568 ListView_InsertGroup(list_view_, static_cast<int>(i), &group); |
| 1572 } | 1569 } |
| 1573 } | 1570 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 } | 1632 } |
| 1636 | 1633 |
| 1637 void TableSelectionIterator::UpdateModelIndexFromViewIndex() { | 1634 void TableSelectionIterator::UpdateModelIndexFromViewIndex() { |
| 1638 if (view_index_ == -1) | 1635 if (view_index_ == -1) |
| 1639 model_index_ = -1; | 1636 model_index_ = -1; |
| 1640 else | 1637 else |
| 1641 model_index_ = table_view_->ViewToModel(view_index_); | 1638 model_index_ = table_view_->ViewToModel(view_index_); |
| 1642 } | 1639 } |
| 1643 | 1640 |
| 1644 } // namespace views | 1641 } // namespace views |
| OLD | NEW |