Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/gtk/bookmark_bar_gtk.h" | 5 #include "chrome/browser/gtk/bookmark_bar_gtk.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "app/gfx/text_elider.h" | 9 #include "app/gfx/text_elider.h" |
| 10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 | 41 |
| 42 // The height of the bar. | 42 // The height of the bar. |
| 43 const int kBookmarkBarHeight = 29; | 43 const int kBookmarkBarHeight = 29; |
| 44 | 44 |
| 45 // Left-padding for the instructional text. | 45 // Left-padding for the instructional text. |
| 46 const int kInstructionsPadding = 6; | 46 const int kInstructionsPadding = 6; |
| 47 | 47 |
| 48 // Color of the instructional text. | 48 // Color of the instructional text. |
| 49 const GdkColor kInstructionsColor = GDK_COLOR_RGB(128, 128, 142); | 49 const GdkColor kInstructionsColor = GDK_COLOR_RGB(128, 128, 142); |
| 50 | 50 |
| 51 const int kDestTargetList[] = { GtkDndUtil::CHROME_BOOKMARK_ITEM, | |
|
tony
2009/07/27 23:33:03
Nit: Comment?
| |
| 52 GtkDndUtil::CHROME_NAMED_URL, | |
| 53 GtkDndUtil::TEXT_URI_LIST, | |
| 54 GtkDndUtil::TEXT_PLAIN, 0 }; | |
| 55 | |
| 51 void SetToolBarStyle() { | 56 void SetToolBarStyle() { |
| 52 static bool style_was_set = false; | 57 static bool style_was_set = false; |
| 53 | 58 |
| 54 if (style_was_set) | 59 if (style_was_set) |
| 55 return; | 60 return; |
| 56 style_was_set = true; | 61 style_was_set = true; |
| 57 | 62 |
| 58 gtk_rc_parse_string( | 63 gtk_rc_parse_string( |
| 59 "style \"chrome-bookmark-toolbar\" {" | 64 "style \"chrome-bookmark-toolbar\" {" |
| 60 " xthickness = 0\n" | 65 " xthickness = 0\n" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 SetToolBarStyle(); | 157 SetToolBarStyle(); |
| 153 gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar"); | 158 gtk_widget_set_name(bookmark_toolbar_.get(), "chrome-bookmark-toolbar"); |
| 154 gtk_widget_set_app_paintable(bookmark_toolbar_.get(), TRUE); | 159 gtk_widget_set_app_paintable(bookmark_toolbar_.get(), TRUE); |
| 155 g_signal_connect(G_OBJECT(bookmark_toolbar_.get()), "expose-event", | 160 g_signal_connect(G_OBJECT(bookmark_toolbar_.get()), "expose-event", |
| 156 G_CALLBACK(&OnToolbarExpose), this); | 161 G_CALLBACK(&OnToolbarExpose), this); |
| 157 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(), | 162 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), bookmark_toolbar_.get(), |
| 158 TRUE, TRUE, 0); | 163 TRUE, TRUE, 0); |
| 159 | 164 |
| 160 gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP, | 165 gtk_drag_dest_set(bookmark_toolbar_.get(), GTK_DEST_DEFAULT_DROP, |
| 161 NULL, 0, GDK_ACTION_MOVE); | 166 NULL, 0, GDK_ACTION_MOVE); |
| 162 GtkDndUtil::SetDestTargetListFromCodeMask(bookmark_toolbar_.get(), | 167 GtkDndUtil::SetDestTargetList(bookmark_toolbar_.get(), kDestTargetList); |
| 163 GtkDndUtil::CHROME_BOOKMARK_ITEM | | |
| 164 GtkDndUtil::CHROME_NAMED_URL); | |
| 165 g_signal_connect(bookmark_toolbar_.get(), "drag-motion", | 168 g_signal_connect(bookmark_toolbar_.get(), "drag-motion", |
| 166 G_CALLBACK(&OnToolbarDragMotion), this); | 169 G_CALLBACK(&OnToolbarDragMotion), this); |
| 167 g_signal_connect(bookmark_toolbar_.get(), "drag-leave", | 170 g_signal_connect(bookmark_toolbar_.get(), "drag-leave", |
| 168 G_CALLBACK(&OnToolbarDragLeave), this); | 171 G_CALLBACK(&OnToolbarDragLeave), this); |
| 169 g_signal_connect(bookmark_toolbar_.get(), "drag-data-received", | 172 g_signal_connect(bookmark_toolbar_.get(), "drag-data-received", |
| 170 G_CALLBACK(&OnToolbarDragReceived), this); | 173 G_CALLBACK(&OnDragReceived), this); |
| 171 g_signal_connect(bookmark_toolbar_.get(), "button-press-event", | 174 g_signal_connect(bookmark_toolbar_.get(), "button-press-event", |
| 172 G_CALLBACK(&OnButtonPressed), this); | 175 G_CALLBACK(&OnButtonPressed), this); |
| 173 | 176 |
| 174 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), gtk_vseparator_new(), | 177 gtk_box_pack_start(GTK_BOX(bookmark_hbox_), gtk_vseparator_new(), |
| 175 FALSE, FALSE, 0); | 178 FALSE, FALSE, 0); |
| 176 | 179 |
| 177 // We pack the button manually (rather than using gtk_button_set_*) so that | 180 // We pack the button manually (rather than using gtk_button_set_*) so that |
| 178 // we can have finer control over its label. | 181 // we can have finer control over its label. |
| 179 other_bookmarks_button_ = theme_provider_->BuildChromeButton(); | 182 other_bookmarks_button_ = theme_provider_->BuildChromeButton(); |
| 180 ConnectFolderButtonEvents(other_bookmarks_button_); | 183 ConnectFolderButtonEvents(other_bookmarks_button_); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 | 445 |
| 443 GtkToolItem* item = gtk_tool_item_new(); | 446 GtkToolItem* item = gtk_tool_item_new(); |
| 444 gtk_container_add(GTK_CONTAINER(item), button); | 447 gtk_container_add(GTK_CONTAINER(item), button); |
| 445 gtk_widget_show_all(GTK_WIDGET(item)); | 448 gtk_widget_show_all(GTK_WIDGET(item)); |
| 446 | 449 |
| 447 return item; | 450 return item; |
| 448 } | 451 } |
| 449 | 452 |
| 450 void BookmarkBarGtk::ConnectFolderButtonEvents(GtkWidget* widget) { | 453 void BookmarkBarGtk::ConnectFolderButtonEvents(GtkWidget* widget) { |
| 451 gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_MOVE); | 454 gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_MOVE); |
| 452 GtkDndUtil::SetDestTargetListFromCodeMask(widget, | 455 GtkDndUtil::SetDestTargetList(widget, kDestTargetList); |
| 453 GtkDndUtil::CHROME_BOOKMARK_ITEM | | |
| 454 GtkDndUtil::CHROME_NAMED_URL); | |
| 455 g_signal_connect(widget, "drag-data-received", | 456 g_signal_connect(widget, "drag-data-received", |
| 456 G_CALLBACK(&OnFolderDragReceived), this); | 457 G_CALLBACK(&OnDragReceived), this); |
| 457 | 458 |
| 458 // Connect to 'button-release-event' instead of 'clicked' because we need | 459 // Connect to 'button-release-event' instead of 'clicked' because we need |
| 459 // access to the modifier keys and we do different things on each | 460 // access to the modifier keys and we do different things on each |
| 460 // button. | 461 // button. |
| 461 g_signal_connect(G_OBJECT(widget), "button-press-event", | 462 g_signal_connect(G_OBJECT(widget), "button-press-event", |
| 462 G_CALLBACK(OnButtonPressed), this); | 463 G_CALLBACK(OnButtonPressed), this); |
| 463 g_signal_connect(G_OBJECT(widget), "button-release-event", | 464 g_signal_connect(G_OBJECT(widget), "button-release-event", |
| 464 G_CALLBACK(OnFolderButtonReleased), this); | 465 G_CALLBACK(OnFolderButtonReleased), this); |
| 465 } | 466 } |
| 466 | 467 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 node, | 660 node, |
| 660 0, | 661 0, |
| 661 false)); | 662 false)); |
| 662 bar->current_menu_->Popup(sender, event->button, event->time); | 663 bar->current_menu_->Popup(sender, event->button, event->time); |
| 663 | 664 |
| 664 // Allow other handlers to run so the button state is updated correctly. | 665 // Allow other handlers to run so the button state is updated correctly. |
| 665 return FALSE; | 666 return FALSE; |
| 666 } | 667 } |
| 667 | 668 |
| 668 // static | 669 // static |
| 669 void BookmarkBarGtk::OnFolderDragReceived(GtkWidget* widget, | |
| 670 GdkDragContext* context, gint x, gint y, GtkSelectionData* selection_data, | |
| 671 guint target_type, guint time, BookmarkBarGtk* bar) { | |
| 672 gboolean dnd_success = FALSE; | |
| 673 gboolean delete_selection_data = FALSE; | |
| 674 | |
| 675 const BookmarkNode* dest_node = bar->GetNodeForToolButton(widget); | |
| 676 DCHECK(dest_node->is_folder()); | |
| 677 | |
| 678 if (target_type == GtkDndUtil::CHROME_BOOKMARK_ITEM) { | |
| 679 std::vector<const BookmarkNode*> nodes = | |
| 680 bookmark_utils::GetNodesFromSelection(context, selection_data, | |
| 681 target_type, | |
| 682 bar->profile_, | |
| 683 &delete_selection_data, | |
| 684 &dnd_success); | |
| 685 DCHECK(!nodes.empty()); | |
| 686 DCHECK(dnd_success); | |
| 687 | |
| 688 for (std::vector<const BookmarkNode*>::iterator it = nodes.begin(); | |
| 689 it != nodes.end(); ++it) { | |
| 690 bar->model_->Move(*it, dest_node, dest_node->GetChildCount()); | |
| 691 } | |
| 692 } else if (target_type == GtkDndUtil::CHROME_NAMED_URL) { | |
| 693 dnd_success = bookmark_utils::CreateNewBookmarkFromNamedUrl( | |
| 694 selection_data, bar->model_, dest_node, dest_node->GetChildCount()); | |
| 695 } else { | |
| 696 NOTREACHED(); | |
| 697 } | |
| 698 | |
| 699 gtk_drag_finish(context, dnd_success, delete_selection_data, time); | |
| 700 } | |
| 701 | |
| 702 // static | |
| 703 gboolean BookmarkBarGtk::OnToolbarExpose(GtkWidget* widget, | 670 gboolean BookmarkBarGtk::OnToolbarExpose(GtkWidget* widget, |
| 704 GdkEventExpose* event, | 671 GdkEventExpose* event, |
| 705 BookmarkBarGtk* bar) { | 672 BookmarkBarGtk* bar) { |
| 706 // A GtkToolbar's expose handler first draws a box. We don't want that so we | 673 // A GtkToolbar's expose handler first draws a box. We don't want that so we |
| 707 // need to propagate the expose event to all the container's children. | 674 // need to propagate the expose event to all the container's children. |
| 708 GList* children = gtk_container_get_children(GTK_CONTAINER(widget)); | 675 GList* children = gtk_container_get_children(GTK_CONTAINER(widget)); |
| 709 for (GList* item = children; item; item = item->next) { | 676 for (GList* item = children; item; item = item->next) { |
| 710 gtk_container_propagate_expose(GTK_CONTAINER(widget), | 677 gtk_container_propagate_expose(GTK_CONTAINER(widget), |
| 711 GTK_WIDGET(item->data), | 678 GTK_WIDGET(item->data), |
| 712 event); | 679 event); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 BookmarkBarGtk* bar) { | 731 BookmarkBarGtk* bar) { |
| 765 if (bar->toolbar_drop_item_) { | 732 if (bar->toolbar_drop_item_) { |
| 766 g_object_unref(bar->toolbar_drop_item_); | 733 g_object_unref(bar->toolbar_drop_item_); |
| 767 bar->toolbar_drop_item_ = NULL; | 734 bar->toolbar_drop_item_ = NULL; |
| 768 } | 735 } |
| 769 | 736 |
| 770 gtk_toolbar_set_drop_highlight_item(toolbar, NULL, 0); | 737 gtk_toolbar_set_drop_highlight_item(toolbar, NULL, 0); |
| 771 } | 738 } |
| 772 | 739 |
| 773 // static | 740 // static |
| 774 void BookmarkBarGtk::OnToolbarDragReceived(GtkWidget* widget, | 741 void BookmarkBarGtk::OnDragReceived(GtkWidget* widget, |
| 775 GdkDragContext* context, | 742 GdkDragContext* context, |
| 776 gint x, gint y, | 743 gint x, gint y, |
| 777 GtkSelectionData* selection_data, | 744 GtkSelectionData* selection_data, |
| 778 guint target_type, guint time, | 745 guint target_type, guint time, |
| 779 BookmarkBarGtk* bar) { | 746 BookmarkBarGtk* bar) { |
| 780 gboolean dnd_success = FALSE; | 747 gboolean dnd_success = FALSE; |
| 781 gboolean delete_selection_data = FALSE; | 748 gboolean delete_selection_data = FALSE; |
| 782 | 749 |
| 783 gint index = gtk_toolbar_get_drop_index( | 750 const BookmarkNode* dest_node; |
| 751 gint index; | |
| 752 if (widget == bar->bookmark_toolbar_.get()) { | |
| 753 dest_node = bar->model_->GetBookmarkBarNode(); | |
| 754 index = gtk_toolbar_get_drop_index( | |
| 784 GTK_TOOLBAR(bar->bookmark_toolbar_.get()), x, y); | 755 GTK_TOOLBAR(bar->bookmark_toolbar_.get()), x, y); |
| 756 } else { | |
| 757 dest_node = bar->GetNodeForToolButton(widget); | |
| 758 index = dest_node->GetChildCount(); | |
| 759 } | |
| 785 | 760 |
| 786 if (target_type == GtkDndUtil::CHROME_BOOKMARK_ITEM) { | 761 switch (target_type) { |
| 787 std::vector<const BookmarkNode*> nodes = | 762 case GtkDndUtil::CHROME_BOOKMARK_ITEM: { |
| 788 bookmark_utils::GetNodesFromSelection(context, selection_data, | 763 std::vector<const BookmarkNode*> nodes = |
| 789 target_type, | 764 bookmark_utils::GetNodesFromSelection(context, selection_data, |
| 790 bar->profile_, | 765 target_type, |
| 791 &delete_selection_data, | 766 bar->profile_, |
| 792 &dnd_success); | 767 &delete_selection_data, |
| 793 DCHECK(!nodes.empty()); | 768 &dnd_success); |
| 794 for (std::vector<const BookmarkNode*>::iterator it = nodes.begin(); | 769 DCHECK(!nodes.empty()); |
| 795 it != nodes.end(); ++it) { | 770 for (std::vector<const BookmarkNode*>::iterator it = nodes.begin(); |
| 796 bar->model_->Move(*it, bar->model_->GetBookmarkBarNode(), index); | 771 it != nodes.end(); ++it) { |
| 797 index = bar->model_->GetBookmarkBarNode()->IndexOfChild(*it) + 1; | 772 bar->model_->Move(*it, dest_node, index); |
| 773 index = dest_node->IndexOfChild(*it) + 1; | |
| 774 } | |
| 775 break; | |
| 798 } | 776 } |
| 799 } else if (target_type == GtkDndUtil::CHROME_NAMED_URL) { | 777 |
| 800 dnd_success = bookmark_utils::CreateNewBookmarkFromNamedUrl( | 778 case GtkDndUtil::CHROME_NAMED_URL: { |
| 801 selection_data, bar->model_, bar->model_->GetBookmarkBarNode(), index); | 779 dnd_success = bookmark_utils::CreateNewBookmarkFromNamedUrl( |
| 802 } else { | 780 selection_data, bar->model_, dest_node, index); |
| 803 NOTREACHED(); | 781 break; |
| 782 } | |
| 783 | |
| 784 case GtkDndUtil::TEXT_URI_LIST: { | |
| 785 dnd_success = bookmark_utils::CreateNewBookmarksFromURIList( | |
| 786 selection_data, bar->model_, dest_node, index); | |
| 787 break; | |
| 788 } | |
| 789 | |
| 790 case GtkDndUtil::TEXT_PLAIN: { | |
| 791 guchar* text = gtk_selection_data_get_text(selection_data); | |
| 792 GURL url(reinterpret_cast<char*>(text)); | |
| 793 g_free(text); | |
| 794 // TODO(estade): It would be nice to head this case off at drag motion, | |
| 795 // so that it doesn't look like we can drag onto the bookmark bar. | |
| 796 if (!url.is_valid()) | |
| 797 break; | |
| 798 std::string title = bookmark_utils::GetNameForURL(url); | |
| 799 bar->model_->AddURL(dest_node, index, UTF8ToWide(title), url); | |
| 800 dnd_success = TRUE; | |
| 801 break; | |
| 802 } | |
| 804 } | 803 } |
| 805 | 804 |
| 806 gtk_drag_finish(context, dnd_success, delete_selection_data, time); | 805 gtk_drag_finish(context, dnd_success, delete_selection_data, time); |
| 807 } | 806 } |
| 808 | 807 |
| 809 // static | 808 // static |
| 810 gboolean BookmarkBarGtk::OnHBoxExpose(GtkWidget* widget, | 809 gboolean BookmarkBarGtk::OnHBoxExpose(GtkWidget* widget, |
| 811 GdkEventExpose* event, | 810 GdkEventExpose* event, |
| 812 BookmarkBarGtk* bar) { | 811 BookmarkBarGtk* bar) { |
| 813 // Paint the background theme image. | 812 // Paint the background theme image. |
| 814 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); | 813 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); |
| 815 cairo_rectangle(cr, event->area.x, event->area.y, | 814 cairo_rectangle(cr, event->area.x, event->area.y, |
| 816 event->area.width, event->area.height); | 815 event->area.width, event->area.height); |
| 817 cairo_clip(cr); | 816 cairo_clip(cr); |
| 818 bar->InitBackground(); | 817 bar->InitBackground(); |
| 819 gfx::Point tabstrip_origin = | 818 gfx::Point tabstrip_origin = |
| 820 bar->window_->tabstrip()->GetTabStripOriginForWidget(widget); | 819 bar->window_->tabstrip()->GetTabStripOriginForWidget(widget); |
| 821 bar->background_ninebox_->RenderTopCenterStrip( | 820 bar->background_ninebox_->RenderTopCenterStrip( |
| 822 cr, tabstrip_origin.x(), tabstrip_origin.y(), | 821 cr, tabstrip_origin.x(), tabstrip_origin.y(), |
| 823 event->area.x + event->area.width - tabstrip_origin.x()); | 822 event->area.x + event->area.width - tabstrip_origin.x()); |
| 824 cairo_destroy(cr); | 823 cairo_destroy(cr); |
| 825 | 824 |
| 826 return FALSE; // Propagate expose to children. | 825 return FALSE; // Propagate expose to children. |
| 827 } | 826 } |
| OLD | NEW |