Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: chrome/browser/views/bookmark_manager_view.cc

Issue 1730015: Windows/Views: delete native bookmark manager code. (Closed)
Patch Set: Patch with fixed file perms. Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/views/bookmark_manager_view.h"
6
7 #include <algorithm>
8
9 #include "app/l10n_util.h"
10 #include "app/resource_bundle.h"
11 #include "base/keyboard_codes.h"
12 #include "base/thread.h"
13 #include "chrome/browser/bookmarks/bookmark_folder_tree_model.h"
14 #include "chrome/browser/bookmarks/bookmark_html_writer.h"
15 #include "chrome/browser/bookmarks/bookmark_manager.h"
16 #include "chrome/browser/bookmarks/bookmark_model.h"
17 #include "chrome/browser/bookmarks/bookmark_table_model.h"
18 #include "chrome/browser/bookmarks/bookmark_utils.h"
19 #include "chrome/browser/browser_list.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/importer/importer.h"
22 #include "chrome/browser/importer/importer_data_types.h"
23 #include "chrome/browser/metrics/user_metrics.h"
24 #include "chrome/browser/pref_service.h"
25 #include "chrome/browser/profile.h"
26 #include "chrome/browser/sync/sync_ui_util.h"
27 #include "chrome/browser/views/bookmark_editor_view.h"
28 #include "chrome/browser/views/bookmark_folder_tree_view.h"
29 #include "chrome/browser/views/bookmark_table_view.h"
30 #include "chrome/common/pref_names.h"
31 #include "gfx/canvas.h"
32 #include "gfx/color_utils.h"
33 #include "gfx/skia_util.h"
34 #include "grit/generated_resources.h"
35 #include "grit/locale_settings.h"
36 #include "grit/theme_resources.h"
37 #include "third_party/skia/include/core/SkShader.h"
38 #include "views/controls/button/menu_button.h"
39 #include "views/controls/label.h"
40 #include "views/controls/menu/menu_item_view.h"
41 #include "views/controls/single_split_view.h"
42 #include "views/grid_layout.h"
43 #include "views/standard_layout.h"
44 #include "views/widget/widget.h"
45 #include "views/window/window.h"
46
47 // If non-null, there is an open editor and this is the window it is contained
48 // in it.
49 static views::Window* open_window = NULL;
50 // And this is the manager contained in it.
51 static BookmarkManagerView* manager = NULL;
52
53 // Delay, in ms, between when the user types and when we run the search.
54 static const int kSearchDelayMS = 200;
55
56 static const int kOrganizeMenuButtonID = 1;
57 static const int kToolsMenuButtonID = 2;
58
59 // Background color.
60 static const SkColor kBackgroundColorTop = SkColorSetRGB(242, 247, 253);
61 static const SkColor kBackgroundColorBottom = SkColorSetRGB(223, 234, 248);
62 static const int kBackgroundGradientHeight = 28;
63
64 namespace {
65
66 // Observer installed on the importer. When done importing the newly created
67 // folder is selected in the bookmark manager.
68 class ImportObserverImpl : public ImportObserver {
69 public:
70 explicit ImportObserverImpl(Profile* profile) : profile_(profile) {
71 BookmarkModel* model = profile->GetBookmarkModel();
72 initial_other_count_ = model->other_node()->GetChildCount();
73 }
74
75 virtual void ImportCanceled() {
76 delete this;
77 }
78
79 virtual void ImportComplete() {
80 // We aren't needed anymore.
81 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
82
83 BookmarkManagerView* manager = BookmarkManagerView::current();
84 if (!manager || manager->profile() != profile_)
85 return;
86
87 BookmarkModel* model = profile_->GetBookmarkModel();
88 int other_count = model->other_node()->GetChildCount();
89 if (other_count == initial_other_count_ + 1) {
90 const BookmarkNode* imported_node =
91 model->other_node()->GetChild(initial_other_count_);
92 manager->SelectInTree(imported_node);
93 manager->ExpandAll(imported_node);
94 }
95 }
96
97 private:
98 Profile* profile_;
99 // Number of children in the other bookmarks folder at the time we were
100 // created.
101 int initial_other_count_;
102
103 DISALLOW_COPY_AND_ASSIGN(ImportObserverImpl);
104 };
105
106 // Converts a virtual keycode into the CutCopyPasteType.
107 BookmarkManagerView::CutCopyPasteType KeyCodeToCutCopyPaste(
108 base::KeyboardCode keycode) {
109 switch (keycode) {
110 case base::VKEY_INSERT:
111 if (GetKeyState(VK_CONTROL) < 0)
112 return BookmarkManagerView::COPY;
113 if (GetKeyState(VK_SHIFT) < 0)
114 return BookmarkManagerView::PASTE;
115 return BookmarkManagerView::NONE;
116
117 case base::VKEY_DELETE:
118 if (GetKeyState(VK_SHIFT) < 0)
119 return BookmarkManagerView::CUT;
120 return BookmarkManagerView::NONE;
121
122 case base::VKEY_C:
123 if (GetKeyState(VK_CONTROL) < 0)
124 return BookmarkManagerView::COPY;
125 return BookmarkManagerView::NONE;
126
127 case base::VKEY_V:
128 if (GetKeyState(VK_CONTROL) < 0)
129 return BookmarkManagerView::PASTE;
130 return BookmarkManagerView::NONE;
131
132 case base::VKEY_X:
133 if (GetKeyState(VK_CONTROL) < 0)
134 return BookmarkManagerView::CUT;
135 return BookmarkManagerView::NONE;
136
137 default:
138 return BookmarkManagerView::NONE;
139 }
140 }
141
142 } // namespace
143
144 namespace browser {
145
146 // Declared in browser_dialogs.h so others don't need to depend on our header.
147 void ShowBookmarkManagerView(Profile* profile) {
148 BookmarkManagerView::Show(profile);
149 }
150
151 } // namespace browser
152
153 // BookmarkManager -------------------------------------------------------------
154
155 void BookmarkManager::SelectInTree(Profile* profile, const BookmarkNode* node) {
156 if (manager && manager->profile() == profile)
157 manager->SelectInTree(node);
158 }
159
160 void BookmarkManager::Show(Profile* profile) {
161 BookmarkManagerView::Show(profile);
162 }
163
164 // -----------------------------------------------------------------------------
165
166 BookmarkManagerView::BookmarkManagerView(Profile* profile)
167 : profile_(profile->GetOriginalProfile()),
168 table_view_(NULL),
169 tree_view_(NULL),
170 sync_status_button_(NULL),
171 sync_service_(NULL),
172 sync_relogin_required_(false),
173 ALLOW_THIS_IN_INITIALIZER_LIST(search_factory_(this)) {
174 views::Label* search_label = new views::Label(
175 l10n_util::GetString(IDS_BOOKMARK_MANAGER_SEARCH_TITLE));
176 search_tf_ = new views::Textfield();
177 search_tf_->set_default_width_in_chars(30);
178 search_tf_->SetAccessibleName(search_label->GetText());
179
180 table_view_ = new BookmarkTableView(profile_, NULL);
181 table_view_->SetObserver(this);
182 table_view_->SetContextMenuController(this);
183
184 tree_view_ = new BookmarkFolderTreeView(profile_, NULL);
185 tree_view_->SetController(this);
186 tree_view_->SetContextMenuController(this);
187
188 views::MenuButton* organize_menu_button = new views::MenuButton(
189 NULL, l10n_util::GetString(IDS_BOOKMARK_MANAGER_ORGANIZE_MENU),
190 this, true);
191 organize_menu_button->SetID(kOrganizeMenuButtonID);
192
193 views::MenuButton* tools_menu_button = new views::MenuButton(
194 NULL, l10n_util::GetString(IDS_BOOKMARK_MANAGER_TOOLS_MENU),
195 this, true);
196 tools_menu_button->SetID(kToolsMenuButtonID);
197
198 split_view_ = new views::SingleSplitView(tree_view_, table_view_,
199 views::SingleSplitView::HORIZONTAL_SPLIT);
200 split_view_->set_resize_leading_on_bounds_change(false);
201 split_view_->set_background(
202 views::Background::CreateSolidBackground(kBackgroundColorBottom));
203
204 views::GridLayout* layout = new views::GridLayout(this);
205 SetLayoutManager(layout);
206 const int top_id = 1;
207 const int split_cs_id = 2;
208 layout->SetInsets(2, 0, 0, 0); // 2px padding above content.
209 views::ColumnSet* column_set = layout->AddColumnSet(top_id);
210 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
211 0, views::GridLayout::USE_PREF, 0, 0);
212 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
213 0, views::GridLayout::USE_PREF, 0, 0);
214 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
215 0, views::GridLayout::USE_PREF, 0, 0);
216 column_set->AddPaddingColumn(1, kUnrelatedControlHorizontalSpacing);
217 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
218 0, views::GridLayout::USE_PREF, 0, 0);
219 column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
220 column_set->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
221 0, views::GridLayout::USE_PREF, 0, 0);
222 column_set->AddPaddingColumn(0, 3); // 3px padding at end of row.
223
224 column_set = layout->AddColumnSet(split_cs_id);
225 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
226 views::GridLayout::USE_PREF, 0, 0);
227
228 layout->StartRow(0, top_id);
229 layout->AddView(organize_menu_button);
230 layout->AddView(tools_menu_button);
231 sync_status_button_ = new views::TextButton(this, std::wstring());
232 layout->AddView(sync_status_button_);
233 layout->AddView(search_label);
234 layout->AddView(search_tf_);
235
236 layout->AddPaddingRow(0, 3); // 3px padding between rows.
237
238 layout->StartRow(1, split_cs_id);
239 layout->AddView(split_view_);
240
241 // Press Ctrl-W to close bookmark manager window.
242 AddAccelerator(views::Accelerator(base::VKEY_W, false, true, false));
243
244 BookmarkModel* bookmark_model = profile_->GetBookmarkModel();
245 if (!bookmark_model->IsLoaded())
246 bookmark_model->AddObserver(this);
247
248 if (profile_->GetProfileSyncService()) {
249 sync_service_ = profile_->GetProfileSyncService();
250 sync_service_->AddObserver(this);
251 UpdateSyncStatus();
252 }
253 }
254
255 BookmarkManagerView::~BookmarkManagerView() {
256 if (select_file_dialog_.get())
257 select_file_dialog_->ListenerDestroyed();
258
259 if (!GetBookmarkModel()->IsLoaded()) {
260 GetBookmarkModel()->RemoveObserver(this);
261 } else {
262 // The models are deleted before the views. Make sure we set the models of
263 // the views to NULL so that they aren't left holding a reference to a
264 // deleted model.
265 table_view_->SetModel(NULL);
266 tree_view_->SetModel(NULL);
267 }
268 manager = NULL;
269 open_window = NULL;
270
271 if (sync_service_)
272 sync_service_->RemoveObserver(this);
273 }
274
275 // static
276 void BookmarkManagerView::Show(Profile* profile) {
277 if (!profile->GetBookmarkModel())
278 return;
279
280 if (open_window != NULL) {
281 open_window->Activate();
282 return;
283 }
284
285 // Both of these will be deleted when the dialog closes.
286 manager = new BookmarkManagerView(profile);
287
288 // Create the window.
289 open_window = views::Window::CreateChromeWindow(NULL, gfx::Rect(), manager);
290 // Let the manager know it's parented.
291 manager->PrepareForShow();
292 // And show it.
293 open_window->Show();
294
295 // Give initial focus to the search field.
296 manager->search_tf_->RequestFocus();
297 }
298
299 // static
300 BookmarkManagerView* BookmarkManagerView::current() {
301 return manager;
302 }
303
304 void BookmarkManagerView::SelectInTree(const BookmarkNode* node) {
305 if (!node)
306 return;
307
308 const BookmarkNode* parent = node->is_url() ? node->GetParent() : node;
309 FolderNode* folder_node = tree_model_->GetFolderNodeForBookmarkNode(parent);
310 if (!folder_node) {
311 NOTREACHED();
312 return;
313 }
314
315 tree_view_->SetSelectedNode(folder_node);
316
317 if (node->is_url()) {
318 int index = table_model_->IndexOfNode(node);
319 if (index != -1)
320 table_view_->Select(index);
321 // TODO(sky): this doesn't work when invoked from add page.
322 table_view_->RequestFocus();
323 }
324 }
325
326 void BookmarkManagerView::ExpandAll(const BookmarkNode* node) {
327 const BookmarkNode* parent = node->is_url() ? node->GetParent() : node;
328 FolderNode* folder_node = tree_model_->GetFolderNodeForBookmarkNode(parent);
329 if (!folder_node) {
330 NOTREACHED();
331 return;
332 }
333 tree_view_->ExpandAll(folder_node);
334 }
335
336 const BookmarkNode* BookmarkManagerView::GetSelectedFolder() {
337 return tree_view_->GetSelectedBookmarkNode();
338 }
339
340 std::vector<const BookmarkNode*> BookmarkManagerView::GetSelectedTableNodes() {
341 std::vector<const BookmarkNode*> nodes;
342 for (views::TableView::iterator i = table_view_->SelectionBegin();
343 i != table_view_->SelectionEnd(); ++i) {
344 nodes.push_back(table_model_->GetNodeForRow(*i));
345 }
346 // TableViews iterator iterates in reverse order. Reverse the nodes so they
347 // are opened in visual order.
348 std::reverse(nodes.begin(), nodes.end());
349 return nodes;
350 }
351
352 void BookmarkManagerView::PaintBackground(gfx::Canvas* canvas) {
353 canvas->drawColor(kBackgroundColorBottom, SkXfermode::kSrc_Mode);
354
355 SkPaint paint;
356 paint.setShader(gfx::CreateGradientShader(0, kBackgroundGradientHeight,
357 kBackgroundColorTop,
358 kBackgroundColorBottom))->safeUnref();
359 canvas->FillRectInt(0, 0, width(), kBackgroundGradientHeight, paint);
360 }
361
362 gfx::Size BookmarkManagerView::GetPreferredSize() {
363 return gfx::Size(views::Window::GetLocalizedContentsSize(
364 IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS,
365 IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES));
366 }
367
368 std::wstring BookmarkManagerView::GetWindowTitle() const {
369 return l10n_util::GetString(IDS_BOOKMARK_MANAGER_TITLE);
370 }
371
372 std::wstring BookmarkManagerView::GetWindowName() const {
373 return prefs::kBookmarkManagerPlacement;
374 }
375
376 void BookmarkManagerView::WindowClosing() {
377 g_browser_process->local_state()->SetInteger(
378 prefs::kBookmarkManagerSplitLocation, split_view_->divider_offset());
379 }
380
381 void BookmarkManagerView::OnStateChanged() {
382 UpdateSyncStatus();
383 }
384
385 bool BookmarkManagerView::AcceleratorPressed(
386 const views::Accelerator& accelerator) {
387 // Ctrl-W to close bookmark manager.
388 DCHECK(accelerator.GetKeyCode() == 'W' && accelerator.IsCtrlDown());
389 window()->Close();
390 return true;
391 }
392
393 void BookmarkManagerView::OnDoubleClick() {
394 std::vector<const BookmarkNode*> nodes = GetSelectedTableNodes();
395 if (nodes.empty())
396 return;
397 if (nodes.size() == 1 && nodes[0]->is_folder()) {
398 // Double click on a folder descends into the folder.
399 SelectInTree(nodes[0]);
400 return;
401 }
402 // TODO(sky): OnDoubleClick needs a handle to the current mouse event so that
403 // we can use
404 // event_utils::DispositionFromEventFlags(sender->mouse_event_flags()) .
405 bookmark_utils::OpenAll(
406 GetWidget()->GetNativeView(), profile_, NULL, nodes, CURRENT_TAB);
407 }
408
409 void BookmarkManagerView::OnMiddleClick() {
410 std::vector<const BookmarkNode*> nodes = GetSelectedTableNodes();
411 if (nodes.empty())
412 return;
413 if (nodes.size() == 1 && nodes[0]->is_folder()) {
414 // Middle clicking on a folder results in no action.
415 return;
416 }
417
418 bookmark_utils::OpenAll(
419 GetWidget()->GetNativeView(), profile_, NULL, nodes, NEW_FOREGROUND_TAB);
420 }
421
422 void BookmarkManagerView::OnTableViewDelete(views::TableView* table) {
423 std::vector<const BookmarkNode*> nodes = GetSelectedTableNodes();
424 if (nodes.empty())
425 return;
426 for (size_t i = 0; i < nodes.size(); ++i) {
427 GetBookmarkModel()->Remove(nodes[i]->GetParent(),
428 nodes[i]->GetParent()->IndexOfChild(nodes[i]));
429 }
430 }
431
432 void BookmarkManagerView::OnKeyDown(base::KeyboardCode keycode) {
433 switch (keycode) {
434 case base::VKEY_RETURN: {
435 std::vector<const BookmarkNode*> selected_nodes = GetSelectedTableNodes();
436 if (selected_nodes.size() == 1 && selected_nodes[0]->is_folder()) {
437 SelectInTree(selected_nodes[0]);
438 } else {
439 bookmark_utils::OpenAll(
440 GetWidget()->GetNativeView(), profile_, NULL, selected_nodes,
441 CURRENT_TAB);
442 }
443 break;
444 }
445
446 case base::VKEY_BACK: {
447 const BookmarkNode* selected_folder = GetSelectedFolder();
448 if (selected_folder != NULL &&
449 selected_folder->GetParent() != GetBookmarkModel()->root_node()) {
450 SelectInTree(selected_folder->GetParent());
451 }
452 break;
453 }
454
455 default:
456 OnCutCopyPaste(KeyCodeToCutCopyPaste(keycode), true);
457 break;
458 }
459 }
460
461 void BookmarkManagerView::OnTreeViewSelectionChanged(
462 views::TreeView* tree_view) {
463 TreeModelNode* node = tree_view_->GetSelectedNode();
464
465 BookmarkTableModel* new_table_model = NULL;
466 const BookmarkNode* table_parent_node = NULL;
467 bool is_search = false;
468
469 if (node) {
470 switch (tree_model_->GetNodeType(node)) {
471 case BookmarkFolderTreeModel::BOOKMARK:
472 table_parent_node = tree_model_->TreeNodeAsBookmarkNode(node);
473 new_table_model =
474 BookmarkTableModel::CreateBookmarkTableModelForFolder(
475 profile_->GetBookmarkModel(),
476 table_parent_node);
477 break;
478
479 case BookmarkFolderTreeModel::RECENTLY_BOOKMARKED:
480 new_table_model = BookmarkTableModel::CreateRecentlyBookmarkedModel(
481 profile_->GetBookmarkModel());
482 break;
483
484 case BookmarkFolderTreeModel::SEARCH:
485 is_search = true;
486 search_factory_.RevokeAll();
487 new_table_model = CreateSearchTableModel();
488 break;
489
490 default:
491 NOTREACHED();
492 break;
493 }
494 }
495
496 SetTableModel(new_table_model, table_parent_node, is_search);
497 }
498
499 void BookmarkManagerView::OnTreeViewKeyDown(base::KeyboardCode keycode) {
500 switch (keycode) {
501 case base::VKEY_DELETE: {
502 const BookmarkNode* node = GetSelectedFolder();
503 if (!node || node->GetParent() == GetBookmarkModel()->root_node())
504 return;
505
506 const BookmarkNode* parent = node->GetParent();
507 GetBookmarkModel()->Remove(parent, parent->IndexOfChild(node));
508 break;
509 }
510
511 default:
512 OnCutCopyPaste(KeyCodeToCutCopyPaste(keycode), false);
513 break;
514 }
515 }
516
517 void BookmarkManagerView::ButtonPressed(views::Button* sender,
518 const views::Event& event) {
519 if (sender == sync_status_button_) {
520 if (sync_relogin_required_) {
521 DCHECK(sync_service_);
522 sync_service_->ShowLoginDialog();
523 } else {
524 UserMetrics::RecordAction(UserMetricsAction("BookmarkManager_Sync"),
525 profile_);
526 sync_ui_util::OpenSyncMyBookmarksDialog(
527 profile_, ProfileSyncService::START_FROM_BOOKMARK_MANAGER);
528 }
529 }
530 }
531
532 void BookmarkManagerView::Loaded(BookmarkModel* model) {
533 model->RemoveObserver(this);
534 LoadedImpl();
535 }
536
537 void BookmarkManagerView::ContentsChanged(views::Textfield* sender,
538 const std::wstring& new_contents) {
539 search_factory_.RevokeAll();
540 MessageLoop::current()->PostDelayedTask(FROM_HERE,
541 search_factory_.NewRunnableMethod(&BookmarkManagerView::PerformSearch),
542 kSearchDelayMS);
543 }
544
545 bool BookmarkManagerView::HandleKeystroke(
546 views::Textfield* sender,
547 const views::Textfield::Keystroke& key) {
548 if (key.GetKeyboardCode() == base::VKEY_RETURN) {
549 PerformSearch();
550 search_tf_->SelectAll();
551 }
552
553 return false;
554 }
555
556 void BookmarkManagerView::ShowContextMenu(views::View* source,
557 const gfx::Point& p,
558 bool is_mouse_gesture) {
559 DCHECK(source == table_view_ || source == tree_view_);
560 bool is_table = (source == table_view_);
561 ShowMenu(p, is_table ?
562 BookmarkContextMenuControllerViews::BOOKMARK_MANAGER_TABLE :
563 BookmarkContextMenuControllerViews::BOOKMARK_MANAGER_TREE);
564 }
565
566 void BookmarkManagerView::RunMenu(views::View* source, const gfx::Point& pt) {
567 // TODO(glen): when you change the buttons around and what not, futz with
568 // this to make it look good. If you end up keeping padding numbers make them
569 // constants.
570 if (!GetBookmarkModel()->IsLoaded())
571 return;
572
573 gfx::Point menu_pt(pt);
574 menu_pt.Offset(UILayoutIsRightToLeft() ?
575 (source->width() - 5) : (-source->width() + 5), 2);
576 if (source->GetID() == kOrganizeMenuButtonID) {
577 ShowMenu(menu_pt,
578 BookmarkContextMenuControllerViews::BOOKMARK_MANAGER_ORGANIZE_MENU);
579 } else if (source->GetID() == kToolsMenuButtonID) {
580 ShowToolsMenu(menu_pt);
581 } else {
582 NOTREACHED();
583 }
584 }
585
586 void BookmarkManagerView::ExecuteCommand(int id) {
587 switch (id) {
588 case IDS_BOOKMARK_MANAGER_IMPORT_MENU:
589 UserMetrics::RecordAction(UserMetricsAction("BookmarkManager_Import"),
590 profile_);
591 ShowImportBookmarksFileChooser();
592 break;
593
594 case IDS_BOOKMARK_MANAGER_EXPORT_MENU:
595 UserMetrics::RecordAction(UserMetricsAction("BookmarkManager_Export"),
596 profile_);
597 ShowExportBookmarksFileChooser();
598 break;
599
600 default:
601 NOTREACHED();
602 break;
603 }
604 }
605
606 void BookmarkManagerView::FileSelected(const FilePath& path,
607 int index,
608 void* params) {
609 int id = reinterpret_cast<int>(params);
610 if (id == IDS_BOOKMARK_MANAGER_IMPORT_MENU) {
611 // ImporterHost is ref counted and will delete itself when done.
612 ImporterHost* host = new ImporterHost();
613 ProfileInfo profile_info;
614 profile_info.browser_type = importer::BOOKMARKS_HTML;
615 profile_info.source_path = path.ToWStringHack();
616 StartImportingWithUI(GetWidget()->GetNativeView(), importer::FAVORITES,
617 host, profile_info, profile_,
618 new ImportObserverImpl(profile()), false);
619 } else if (id == IDS_BOOKMARK_MANAGER_EXPORT_MENU) {
620 bookmark_html_writer::WriteBookmarks(profile(), path, NULL);
621 } else {
622 NOTREACHED();
623 }
624 }
625
626 void BookmarkManagerView::FileSelectionCanceled(void* params) {
627 select_file_dialog_ = NULL;
628 }
629
630 BookmarkTableModel* BookmarkManagerView::CreateSearchTableModel() {
631 std::wstring search_text = search_tf_->text();
632 if (search_text.empty())
633 return NULL;
634 std::wstring languages =
635 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
636 return BookmarkTableModel::CreateSearchTableModel(
637 GetBookmarkModel(), search_text, languages);
638 }
639
640 void BookmarkManagerView::SetTableModel(BookmarkTableModel* new_table_model,
641 const BookmarkNode* parent_node,
642 bool is_search) {
643 // Be sure and reset the model on the view before updating table_model_.
644 // Otherwise the view will attempt to use the deleted model when we set the
645 // new one.
646 table_view_->SetModel(NULL);
647 table_view_->SetShowPathColumn(!parent_node);
648 table_view_->SetModel(new_table_model);
649 table_view_->set_parent_node(parent_node);
650 table_model_.reset(new_table_model);
651 if (!is_search || (new_table_model && new_table_model->RowCount() > 0)) {
652 table_view_->SetAltText(std::wstring());
653 } else if (search_tf_->text().empty()) {
654 table_view_->SetAltText(
655 l10n_util::GetString(IDS_BOOKMARK_MANAGER_NO_SEARCH_TEXT));
656 } else {
657 table_view_->SetAltText(
658 l10n_util::GetStringF(IDS_BOOKMARK_MANAGER_NO_RESULTS,
659 search_tf_->text()));
660 }
661 }
662
663 void BookmarkManagerView::PerformSearch() {
664 search_factory_.RevokeAll();
665 // Reset the controller, otherwise when we change the selection we'll get
666 // notified and update the model twice.
667 tree_view_->SetController(NULL);
668 tree_view_->SetSelectedNode(tree_model_->search_node());
669 tree_view_->SetController(this);
670 SetTableModel(CreateSearchTableModel(), NULL, true);
671 }
672
673 void BookmarkManagerView::PrepareForShow() {
674 // Restore the split location, but don't let it get too small (or big),
675 // otherwise users might inadvertently not see the divider.
676 int split_x = g_browser_process->local_state()->GetInteger(
677 prefs::kBookmarkManagerSplitLocation);
678 if (split_x == -1) {
679 // First time running the bookmark manager, give a third of the width to
680 // the tree.
681 split_x = split_view_->width() / 3;
682 }
683 int min_split_size = split_view_->width() / 8;
684 // Make sure the user can see both the tree/table.
685 split_x = std::min(split_view_->width() - min_split_size,
686 std::max(min_split_size, split_x));
687 split_view_->set_divider_offset(split_x);
688 if (!GetBookmarkModel()->IsLoaded()) {
689 search_tf_->SetReadOnly(true);
690 return;
691 }
692
693 LoadedImpl();
694 }
695
696 void BookmarkManagerView::LoadedImpl() {
697 BookmarkModel* bookmark_model = GetBookmarkModel();
698 const BookmarkNode* bookmark_bar_node = bookmark_model->GetBookmarkBarNode();
699 table_model_.reset(
700 BookmarkTableModel::CreateBookmarkTableModelForFolder(bookmark_model,
701 bookmark_bar_node));
702 table_view_->SetModel(table_model_.get());
703 table_view_->set_parent_node(bookmark_bar_node);
704
705 tree_model_.reset(new BookmarkFolderTreeModel(bookmark_model));
706 tree_view_->SetModel(tree_model_.get());
707
708 tree_view_->ExpandAll();
709
710 tree_view_->SetSelectedNode(
711 tree_model_->GetFolderNodeForBookmarkNode(bookmark_bar_node));
712
713 search_tf_->SetReadOnly(false);
714 search_tf_->SetController(this);
715
716 Layout();
717 SchedulePaint();
718 }
719
720 BookmarkModel* BookmarkManagerView::GetBookmarkModel() const {
721 return profile_->GetBookmarkModel();
722 }
723
724 void BookmarkManagerView::ShowMenu(
725 const gfx::Point& p,
726 BookmarkContextMenuControllerViews::ConfigurationType config) {
727 if (!GetBookmarkModel()->IsLoaded())
728 return;
729
730 const BookmarkNode* parent = GetSelectedFolder();
731 std::vector<const BookmarkNode*> nodes;
732 typedef BookmarkContextMenuControllerViews BCMCV; // Such a long name!
733 if (config == BCMCV::BOOKMARK_MANAGER_TABLE ||
734 (config == BCMCV::BOOKMARK_MANAGER_ORGANIZE_MENU &&
735 table_view_->HasFocus())) {
736 nodes = GetSelectedTableNodes();
737 if (!parent) {
738 config = (config == BCMCV::BOOKMARK_MANAGER_TABLE) ?
739 BCMCV::BOOKMARK_MANAGER_TABLE_OTHER :
740 BCMCV::BOOKMARK_MANAGER_ORGANIZE_MENU_OTHER;
741 }
742 } else {
743 if (parent)
744 nodes.push_back(parent);
745 }
746 BookmarkContextMenu menu(GetWidget()->GetNativeView(), profile_, NULL, parent,
747 nodes, config);
748 menu.RunMenuAt(p);
749 }
750
751 void BookmarkManagerView::OnCutCopyPaste(CutCopyPasteType type,
752 bool from_table) {
753 if (type == CUT || type == COPY) {
754 std::vector<const BookmarkNode*> nodes;
755 if (from_table) {
756 nodes = GetSelectedTableNodes();
757 } else {
758 const BookmarkNode* node = GetSelectedFolder();
759 if (!node || node->GetParent() == GetBookmarkModel()->root_node())
760 return;
761 nodes.push_back(node);
762 }
763 if (nodes.empty())
764 return;
765
766 bookmark_utils::CopyToClipboard(GetBookmarkModel(), nodes, type == CUT);
767 } else if (type == PASTE) {
768 int index = from_table ? table_view_->FirstSelectedRow() : -1;
769 if (index != -1)
770 index++;
771 bookmark_utils::PasteFromClipboard(GetBookmarkModel(), GetSelectedFolder(),
772 index);
773 }
774 }
775
776 void BookmarkManagerView::ShowToolsMenu(const gfx::Point& p) {
777 views::MenuItemView menu(this);
778 menu.AppendMenuItemWithLabel(
779 IDS_BOOKMARK_MANAGER_IMPORT_MENU,
780 l10n_util::GetString(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
781 menu.AppendMenuItemWithLabel(
782 IDS_BOOKMARK_MANAGER_EXPORT_MENU,
783 l10n_util::GetString(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
784 views::MenuItemView::AnchorPosition anchor = UILayoutIsRightToLeft() ?
785 views::MenuItemView::TOPRIGHT : views::MenuItemView::TOPLEFT;
786 menu.RunMenuAt(GetWidget()->GetNativeView(), NULL, gfx::Rect(p, gfx::Size()),
787 anchor, true);
788 }
789
790 void BookmarkManagerView::ShowImportBookmarksFileChooser() {
791 if (select_file_dialog_.get())
792 select_file_dialog_->ListenerDestroyed();
793
794 SelectFileDialog::FileTypeInfo file_type_info;
795 file_type_info.extensions.resize(1);
796 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
797 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm"));
798 file_type_info.include_all_files = true;
799 select_file_dialog_ = SelectFileDialog::Create(this);
800 select_file_dialog_->SelectFile(
801 SelectFileDialog::SELECT_OPEN_FILE, std::wstring(),
802 FilePath(FILE_PATH_LITERAL("bookmarks.html")), &file_type_info, 0,
803 std::wstring(), GetWidget()->GetNativeView(),
804 reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
805 }
806
807 void BookmarkManagerView::ShowExportBookmarksFileChooser() {
808 if (select_file_dialog_.get())
809 select_file_dialog_->ListenerDestroyed();
810
811 SelectFileDialog::FileTypeInfo file_type_info;
812 file_type_info.extensions.resize(1);
813 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
814 file_type_info.include_all_files = true;
815 select_file_dialog_ = SelectFileDialog::Create(this);
816 select_file_dialog_->SelectFile(
817 SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(),
818 FilePath(FILE_PATH_LITERAL("bookmarks.html")), &file_type_info, 0,
819 L"html", GetWidget()->GetNativeView(),
820 reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
821 }
822
823 void BookmarkManagerView::UpdateSyncStatus() {
824 DCHECK(sync_service_);
825 string16 status_label;
826 string16 link_label;
827 sync_relogin_required_ = sync_ui_util::GetStatusLabels(sync_service_,
828 &status_label, &link_label) == sync_ui_util::SYNC_ERROR;
829
830 if (sync_relogin_required_) {
831 sync_status_button_->SetText(
832 l10n_util::GetString(IDS_SYNC_BOOKMARK_BAR_ERROR));
833 // The tooltip is the only way we have to display text explaining the error
834 // to the user.
835 sync_status_button_->SetTooltipText(
836 l10n_util::GetString(IDS_SYNC_BOOKMARK_BAR_ERROR_DESC));
837 sync_status_button_->SetAccessibleName(
838 l10n_util::GetString(IDS_ACCNAME_SYNC_ERROR_BUTTON));
839 sync_status_button_->SetIcon(
840 *ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING));
841 sync_status_button_->GetParent()->Layout();
842 return;
843 }
844
845 if (sync_service_->HasSyncSetupCompleted()) {
846 string16 username = sync_service_->GetAuthenticatedUsername();
847 status_label = l10n_util::GetStringFUTF16(IDS_SYNC_NTP_SYNCED_TO,
848 username);
849 } else if (sync_service_->SetupInProgress()) {
850 status_label = l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS);
851 } else {
852 status_label = l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL);
853 }
854 sync_status_button_->SetText(status_label);
855 sync_status_button_->SetTooltipText(L"");
856 sync_status_button_->SetAccessibleName(L"");
857 sync_status_button_->SetIcon(SkBitmap());
858 sync_status_button_->GetParent()->Layout();
859 }
OLDNEW
« no previous file with comments | « chrome/browser/views/bookmark_manager_view.h ('k') | chrome/browser/views/bookmark_table_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698