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

Side by Side Diff: chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc

Issue 10915069: Add Copy URL option to Omnibox context menu when URL is replaced by Instant Extended. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
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 "chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h" 5 #include "chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 13 matching lines...) Expand all
24 #include "chrome/browser/ui/browser.h" 24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_tabstrip.h" 25 #include "chrome/browser/ui/browser_tabstrip.h"
26 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 26 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
27 #include "chrome/browser/ui/gtk/gtk_util.h" 27 #include "chrome/browser/ui/gtk/gtk_util.h"
28 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" 28 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
29 #include "chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.h" 29 #include "chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.h"
30 #include "chrome/browser/ui/gtk/view_id_util.h" 30 #include "chrome/browser/ui/gtk/view_id_util.h"
31 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h" 31 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
32 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" 32 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
33 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 33 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
34 #include "chrome/browser/ui/search/search.h"
34 #include "chrome/browser/ui/toolbar/toolbar_model.h" 35 #include "chrome/browser/ui/toolbar/toolbar_model.h"
35 #include "chrome/common/chrome_notification_types.h" 36 #include "chrome/common/chrome_notification_types.h"
36 #include "content/public/browser/notification_source.h" 37 #include "content/public/browser/notification_source.h"
37 #include "content/public/browser/web_contents.h" 38 #include "content/public/browser/web_contents.h"
38 #include "googleurl/src/gurl.h" 39 #include "googleurl/src/gurl.h"
39 #include "grit/generated_resources.h" 40 #include "grit/generated_resources.h"
40 #include "net/base/escape.h" 41 #include "net/base/escape.h"
41 #include "third_party/undoview/undo_view.h" 42 #include "third_party/undoview/undo_view.h"
42 #include "ui/base/animation/multi_animation.h" 43 #include "ui/base/animation/multi_animation.h"
43 #include "ui/base/dragdrop/drag_drop_types.h" 44 #include "ui/base/dragdrop/drag_drop_types.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound, 140 gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound,
140 gtk_text_buffer_get_selection_bound(buffer)); 141 gtk_text_buffer_get_selection_bound(buffer));
141 142
142 if (!gtk_text_iter_equal(&insert, &selection_bound)) { 143 if (!gtk_text_iter_equal(&insert, &selection_bound)) {
143 gtk_text_buffer_move_mark(buffer, 144 gtk_text_buffer_move_mark(buffer,
144 gtk_text_buffer_get_selection_bound(buffer), 145 gtk_text_buffer_get_selection_bound(buffer),
145 &insert); 146 &insert);
146 } 147 }
147 } 148 }
148 149
150 // Returns the |menu| item whose label matches |label|.
151 guint GetPopupMenuIndexForStockLabel(const char* label, GtkMenu* menu) {
152 GList* list = gtk_container_get_children(GTK_CONTAINER(menu));
153 guint index = 1;
154 for (GList* item = list; item != NULL; item = item->next, ++index) {
155 if (GTK_IS_IMAGE_MENU_ITEM(item->data)) {
156 gboolean is_stock = gtk_image_menu_item_get_use_stock(
157 GTK_IMAGE_MENU_ITEM(item->data));
158 if (is_stock) {
159 std::string menu_item_label =
160 gtk_menu_item_get_label(GTK_MENU_ITEM(item->data));
161 if (menu_item_label == label)
162 break;
163 }
164 }
165 }
166 g_list_free(list);
167 return index;
168 }
169
170 // Writes the |url| and |text| to the primary clipboard.
171 void DoWriteToClipboard(const GURL& url, const string16& text) {
172 BookmarkNodeData data;
173 data.ReadFromTuple(url, text);
174 data.WriteToClipboard(NULL);
175 }
176
149 } // namespace 177 } // namespace
150 178
151 OmniboxViewGtk::OmniboxViewGtk(OmniboxEditController* controller, 179 OmniboxViewGtk::OmniboxViewGtk(OmniboxEditController* controller,
152 ToolbarModel* toolbar_model, 180 ToolbarModel* toolbar_model,
153 Browser* browser, 181 Browser* browser,
154 CommandUpdater* command_updater, 182 CommandUpdater* command_updater,
155 bool popup_window_mode, 183 bool popup_window_mode,
156 GtkWidget* location_bar) 184 GtkWidget* location_bar)
157 : OmniboxView(browser->profile(), controller, toolbar_model, 185 : OmniboxView(browser->profile(), controller, toolbar_model,
158 command_updater), 186 command_updater),
(...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 GtkWidget* search_engine_menuitem = gtk_menu_item_new_with_mnemonic( 1278 GtkWidget* search_engine_menuitem = gtk_menu_item_new_with_mnemonic(
1251 ui::ConvertAcceleratorsFromWindowsStyle( 1279 ui::ConvertAcceleratorsFromWindowsStyle(
1252 l10n_util::GetStringUTF8(IDS_EDIT_SEARCH_ENGINES)).c_str()); 1280 l10n_util::GetStringUTF8(IDS_EDIT_SEARCH_ENGINES)).c_str());
1253 gtk_menu_shell_append(GTK_MENU_SHELL(menu), search_engine_menuitem); 1281 gtk_menu_shell_append(GTK_MENU_SHELL(menu), search_engine_menuitem);
1254 g_signal_connect(search_engine_menuitem, "activate", 1282 g_signal_connect(search_engine_menuitem, "activate",
1255 G_CALLBACK(HandleEditSearchEnginesThunk), this); 1283 G_CALLBACK(HandleEditSearchEnginesThunk), this);
1256 gtk_widget_set_sensitive(search_engine_menuitem, 1284 gtk_widget_set_sensitive(search_engine_menuitem,
1257 command_updater()->IsCommandEnabled(IDC_EDIT_SEARCH_ENGINES)); 1285 command_updater()->IsCommandEnabled(IDC_EDIT_SEARCH_ENGINES));
1258 gtk_widget_show(search_engine_menuitem); 1286 gtk_widget_show(search_engine_menuitem);
1259 1287
1260 // Detect the Paste menu item by searching for the one that
1261 // uses the stock Paste label (i.e. gtk-paste).
1262 string16 stock_paste_label(UTF8ToUTF16(GTK_STOCK_PASTE));
1263 GList* list = gtk_container_get_children(GTK_CONTAINER(menu));
1264 guint index = 1;
1265 for (GList* item = list; item != NULL; item = item->next, ++index) {
1266 if (GTK_IS_IMAGE_MENU_ITEM(item->data)) {
1267 gboolean is_stock = gtk_image_menu_item_get_use_stock(
1268 GTK_IMAGE_MENU_ITEM(item->data));
1269 if (is_stock) {
1270 string16 menu_item_label
1271 (UTF8ToUTF16(gtk_menu_item_get_label(GTK_MENU_ITEM(item->data))));
1272 if (menu_item_label == stock_paste_label) {
1273 break;
1274 }
1275 }
1276 }
1277 }
1278 g_list_free(list);
1279
1280 // If we don't find the stock Paste menu item,
1281 // the Paste and Go item will be appended at the end of the popup menu.
1282 GtkClipboard* x_clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 1288 GtkClipboard* x_clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
1283 gchar* text = gtk_clipboard_wait_for_text(x_clipboard); 1289 gchar* text = gtk_clipboard_wait_for_text(x_clipboard);
1284 sanitized_text_for_paste_and_go_ = text ? 1290 sanitized_text_for_paste_and_go_ = text ?
1285 StripJavascriptSchemas(CollapseWhitespace(UTF8ToUTF16(text), true)) : 1291 StripJavascriptSchemas(CollapseWhitespace(UTF8ToUTF16(text), true)) :
1286 string16(); 1292 string16();
1287 g_free(text); 1293 g_free(text);
1294
1295 // Copy URL menu item.
1296 if (chrome::search::IsInstantExtendedAPIEnabled(browser_->profile())) {
1297 GtkWidget* copy_url_menuitem = gtk_menu_item_new_with_mnemonic(
1298 ui::ConvertAcceleratorsFromWindowsStyle(
1299 l10n_util::GetStringUTF8(IDS_COPY_URL)).c_str());
1300
1301 // Detect the Paste and Copy menu items by searching for the ones that use
1302 // the stock labels (i.e. GTK_STOCK_PASTE and GTK_STOCK_COPY).
1303
1304 // If we don't find the stock Copy menu item, the Copy URL item will be
1305 // appended at the end of the popup menu.
1306 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), copy_url_menuitem,
1307 GetPopupMenuIndexForStockLabel(GTK_STOCK_COPY, menu));
1308 g_signal_connect(copy_url_menuitem, "activate",
1309 G_CALLBACK(HandleCopyURLClipboardThunk), this);
1310 gtk_widget_set_sensitive(
1311 copy_url_menuitem,
1312 toolbar_model()->WouldReplaceSearchURLWithSearchTerms() &&
1313 !model()->user_input_in_progress());
1314 gtk_widget_show(copy_url_menuitem);
1315 }
1316
1317 // Paste and Go menu item.
1288 GtkWidget* paste_go_menuitem = gtk_menu_item_new_with_mnemonic( 1318 GtkWidget* paste_go_menuitem = gtk_menu_item_new_with_mnemonic(
1289 ui::ConvertAcceleratorsFromWindowsStyle(l10n_util::GetStringUTF8( 1319 ui::ConvertAcceleratorsFromWindowsStyle(l10n_util::GetStringUTF8(
1290 model()->IsPasteAndSearch(sanitized_text_for_paste_and_go_) ? 1320 model()->IsPasteAndSearch(sanitized_text_for_paste_and_go_) ?
1291 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO)).c_str()); 1321 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO)).c_str());
1292 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), paste_go_menuitem, index); 1322
1323 // If we don't find the stock Paste menu item, the Paste and Go item will be
1324 // appended at the end of the popup menu.
1325 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), paste_go_menuitem,
1326 GetPopupMenuIndexForStockLabel(GTK_STOCK_PASTE, menu));
1327
1293 g_signal_connect(paste_go_menuitem, "activate", 1328 g_signal_connect(paste_go_menuitem, "activate",
1294 G_CALLBACK(HandlePasteAndGoThunk), this); 1329 G_CALLBACK(HandlePasteAndGoThunk), this);
1295 gtk_widget_set_sensitive(paste_go_menuitem, 1330 gtk_widget_set_sensitive(paste_go_menuitem,
1296 model()->CanPasteAndGo(sanitized_text_for_paste_and_go_)); 1331 model()->CanPasteAndGo(sanitized_text_for_paste_and_go_));
1297 gtk_widget_show(paste_go_menuitem); 1332 gtk_widget_show(paste_go_menuitem);
1298 1333
1299 g_signal_connect(menu, "deactivate", 1334 g_signal_connect(menu, "deactivate",
1300 G_CALLBACK(HandlePopupMenuDeactivateThunk), this); 1335 G_CALLBACK(HandlePopupMenuDeactivateThunk), this);
1301 } 1336 }
1302 1337
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 if (handled) { 1605 if (handled) {
1571 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); 1606 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
1572 g_signal_stop_emission(widget, signal_id, 0); 1607 g_signal_stop_emission(widget, signal_id, 0);
1573 } 1608 }
1574 } 1609 }
1575 1610
1576 void OmniboxViewGtk::HandleCopyClipboard(GtkWidget* sender) { 1611 void OmniboxViewGtk::HandleCopyClipboard(GtkWidget* sender) {
1577 HandleCopyOrCutClipboard(true); 1612 HandleCopyOrCutClipboard(true);
1578 } 1613 }
1579 1614
1615 void OmniboxViewGtk::HandleCopyURLClipboard(GtkWidget* sender) {
1616 DoWriteToClipboard(toolbar_model()->GetURL(),
1617 toolbar_model()->GetText(false));
1618 }
1619
1580 void OmniboxViewGtk::HandleCutClipboard(GtkWidget* sender) { 1620 void OmniboxViewGtk::HandleCutClipboard(GtkWidget* sender) {
1581 HandleCopyOrCutClipboard(false); 1621 HandleCopyOrCutClipboard(false);
1582 } 1622 }
1583 1623
1584 void OmniboxViewGtk::HandleCopyOrCutClipboard(bool copy) { 1624 void OmniboxViewGtk::HandleCopyOrCutClipboard(bool copy) {
1585 DCHECK(text_view_); 1625 DCHECK(text_view_);
1586 1626
1587 // On copy or cut, we manually update the PRIMARY selection to contain the 1627 // On copy or cut, we manually update the PRIMARY selection to contain the
1588 // highlighted text. This matches Firefox -- we highlight the URL but don't 1628 // highlighted text. This matches Firefox -- we highlight the URL but don't
1589 // update PRIMARY on Ctrl-L, so Ctrl-L, Ctrl-C and then middle-click is a 1629 // update PRIMARY on Ctrl-L, so Ctrl-L, Ctrl-C and then middle-click is a
1590 // convenient way to paste the current URL somewhere. 1630 // convenient way to paste the current URL somewhere.
1591 if (!gtk_text_buffer_get_has_selection(text_buffer_)) 1631 if (!gtk_text_buffer_get_has_selection(text_buffer_))
1592 return; 1632 return;
1593 1633
1594 GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 1634 GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
1595 DCHECK(clipboard); 1635 DCHECK(clipboard);
1596 if (!clipboard)
1597 return;
1598 1636
1599 CharRange selection = GetSelection(); 1637 CharRange selection = GetSelection();
1600 GURL url; 1638 GURL url;
1601 string16 text(UTF8ToUTF16(GetSelectedText())); 1639 string16 text(UTF8ToUTF16(GetSelectedText()));
1602 bool write_url; 1640 bool write_url;
1603 model()->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, 1641 model()->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text,
1604 &url, &write_url); 1642 &url, &write_url);
1605 1643
1644 // TODO(dominich): On other platforms we write |text| to the clipboard
1645 // irregardless of |write_url|. Is this correct?
1606 if (write_url) { 1646 if (write_url) {
1607 BookmarkNodeData data; 1647 DoWriteToClipboard(url, text);
1608 data.ReadFromTuple(url, text);
1609 data.WriteToClipboard(NULL);
1610 1648
1611 // Stop propagating the signal. 1649 // Stop propagating the signal.
1612 static guint copy_signal_id = 1650 static guint copy_signal_id =
1613 g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW); 1651 g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW);
1614 static guint cut_signal_id = 1652 static guint cut_signal_id =
1615 g_signal_lookup("cut-clipboard", GTK_TYPE_TEXT_VIEW); 1653 g_signal_lookup("cut-clipboard", GTK_TYPE_TEXT_VIEW);
1616 g_signal_stop_emission(text_view_, 1654 g_signal_stop_emission(text_view_,
1617 copy ? copy_signal_id : cut_signal_id, 1655 copy ? copy_signal_id : cut_signal_id,
1618 0); 1656 0);
1619 1657
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 void OmniboxViewGtk::AdjustVerticalAlignmentOfInstantView() { 2206 void OmniboxViewGtk::AdjustVerticalAlignmentOfInstantView() {
2169 // By default, GtkTextView layouts an anchored child widget just above the 2207 // By default, GtkTextView layouts an anchored child widget just above the
2170 // baseline, so we need to move the |instant_view_| down to make sure it 2208 // baseline, so we need to move the |instant_view_| down to make sure it
2171 // has the same baseline as the |text_view_|. 2209 // has the same baseline as the |text_view_|.
2172 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); 2210 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_));
2173 int height; 2211 int height;
2174 pango_layout_get_size(layout, NULL, &height); 2212 pango_layout_get_size(layout, NULL, &height);
2175 int baseline = pango_layout_get_baseline(layout); 2213 int baseline = pango_layout_get_baseline(layout);
2176 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); 2214 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL);
2177 } 2215 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h ('k') | chrome/browser/ui/omnibox/omnibox_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698