| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/gtk/api_permissions_panel_gtk.h" |
| 6 |
| 7 #include <gdk/gdkkeysyms.h> |
| 8 |
| 9 #include <algorithm> |
| 10 #include <vector> |
| 11 |
| 12 #include "app/l10n_util.h" |
| 13 #include "app/resource_bundle.h" |
| 14 #include "base/gfx/gtk_util.h" |
| 15 #include "base/logging.h" |
| 16 #include "chrome/browser/browser_list.h" |
| 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/browser_window.h" |
| 19 #include "chrome/browser/gtk/custom_button.h" |
| 20 #include "chrome/browser/gtk/gtk_chrome_button.h" |
| 21 #include "chrome/browser/gtk/gtk_chrome_link_button.h" |
| 22 #include "chrome/browser/gtk/menu_gtk.h" |
| 23 #include "chrome/browser/tab_contents/tab_contents.h" |
| 24 #include "chrome/common/gtk_util.h" |
| 25 #include "chrome/common/pref_names.h" |
| 26 #include "chrome/common/pref_service.h" |
| 27 #include "grit/chromium_strings.h" |
| 28 #include "grit/generated_resources.h" |
| 29 #include "grit/theme_resources.h" |
| 30 #include "webkit/chaos/GeolocationPowerbox.h" |
| 31 |
| 32 namespace { |
| 33 |
| 34 // The task manager window default size. |
| 35 const int kDefaultWidth = 460; |
| 36 const int kDefaultHeight = 270; |
| 37 |
| 38 // The resource id for the 'End process' button. |
| 39 const gint kApiPermissionsPanelResponseKill = 1; |
| 40 |
| 41 enum ApiPermissionsPanelColumn { |
| 42 kApiPermissionsPanelIcon, |
| 43 kApiPermissionsPanelPage, |
| 44 kApiPermissionsPanelPermissions, |
| 45 kApiPermissionsPanelColumnCount, |
| 46 }; |
| 47 |
| 48 ApiPermissionsPanelColumn ApiPermissionsPanelResourceIDToColumnID(int id) { |
| 49 switch (id) { |
| 50 case IDS_API_PERMISSIONS_PANEL_PAGE_COLUMN: |
| 51 return kApiPermissionsPanelPage; |
| 52 case IDS_API_PERMISSIONS_PANEL_PERMISSIONS_COLUMN: |
| 53 return kApiPermissionsPanelPermissions; |
| 54 default: |
| 55 NOTREACHED(); |
| 56 return static_cast<ApiPermissionsPanelColumn>(-1); |
| 57 } |
| 58 } |
| 59 |
| 60 int ApiPermissionsPanelColumnIDToResourceID(int id) { |
| 61 switch (id) { |
| 62 case kApiPermissionsPanelPage: |
| 63 return IDS_API_PERMISSIONS_PANEL_PAGE_COLUMN; |
| 64 case kApiPermissionsPanelPermissions: |
| 65 return IDS_API_PERMISSIONS_PANEL_PERMISSIONS_COLUMN; |
| 66 default: |
| 67 NOTREACHED(); |
| 68 return -1; |
| 69 } |
| 70 } |
| 71 |
| 72 // Should be used for all gtk_tree_view functions that require a column index on |
| 73 // input. |
| 74 // |
| 75 // We need colid - 1 because the gtk_tree_view function is asking for the |
| 76 // column index, not the column id, and both kApiPermissionsPanelIcon and |
| 77 // kApiPermissionsPanelPage are in the same column index, so all column IDs are
off by |
| 78 // one. |
| 79 int TreeViewColumnIndexFromID(ApiPermissionsPanelColumn colid) { |
| 80 return colid - 1; |
| 81 } |
| 82 |
| 83 // Shows or hides a treeview column. |
| 84 void TreeViewColumnSetVisible(GtkWidget* treeview, ApiPermissionsPanelColumn col
id, |
| 85 bool visible) { |
| 86 GtkTreeViewColumn* column = gtk_tree_view_get_column( |
| 87 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); |
| 88 gtk_tree_view_column_set_visible(column, visible); |
| 89 } |
| 90 |
| 91 bool TreeViewColumnIsVisible(GtkWidget* treeview, ApiPermissionsPanelColumn coli
d) { |
| 92 GtkTreeViewColumn* column = gtk_tree_view_get_column( |
| 93 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); |
| 94 return gtk_tree_view_column_get_visible(column); |
| 95 } |
| 96 |
| 97 void TreeViewInsertColumnWithPixbuf(GtkWidget* treeview, int resid) { |
| 98 int colid = ApiPermissionsPanelResourceIDToColumnID(resid); |
| 99 GtkTreeViewColumn* column = gtk_tree_view_column_new(); |
| 100 gtk_tree_view_column_set_title(column, |
| 101 l10n_util::GetStringUTF8(resid).c_str()); |
| 102 GtkCellRenderer* image_renderer = gtk_cell_renderer_pixbuf_new(); |
| 103 gtk_tree_view_column_pack_start(column, image_renderer, FALSE); |
| 104 gtk_tree_view_column_add_attribute(column, image_renderer, |
| 105 "pixbuf", kApiPermissionsPanelIcon); |
| 106 GtkCellRenderer* text_renderer = gtk_cell_renderer_text_new(); |
| 107 gtk_tree_view_column_pack_start(column, text_renderer, TRUE); |
| 108 gtk_tree_view_column_add_attribute(column, text_renderer, "text", colid); |
| 109 gtk_tree_view_column_set_resizable(column, TRUE); |
| 110 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
| 111 } |
| 112 |
| 113 // Inserts a column with a column id of |colid| and |name|. |
| 114 void TreeViewInsertColumnWithName(GtkWidget* treeview, |
| 115 ApiPermissionsPanelColumn colid, const char* n
ame) { |
| 116 GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); |
| 117 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, |
| 118 name, renderer, |
| 119 "text", colid, |
| 120 NULL); |
| 121 GtkTreeViewColumn* column = gtk_tree_view_get_column( |
| 122 GTK_TREE_VIEW(treeview), TreeViewColumnIndexFromID(colid)); |
| 123 gtk_tree_view_column_set_resizable(column, TRUE); |
| 124 } |
| 125 |
| 126 // Loads the column name from |resid| and uses the corresponding |
| 127 // ApiPermissionsPanelColumn value as the column id to insert into the treeview. |
| 128 void TreeViewInsertColumn(GtkWidget* treeview, int resid) { |
| 129 TreeViewInsertColumnWithName(treeview, |
| 130 ApiPermissionsPanelResourceIDToColumnID(resid), |
| 131 l10n_util::GetStringUTF8(resid).c_str()); |
| 132 } |
| 133 |
| 134 // Get the row number corresponding to |path|. |
| 135 gint GetRowNumForPath(GtkTreePath* path) { |
| 136 gint* indices = gtk_tree_path_get_indices(path); |
| 137 if (!indices) { |
| 138 NOTREACHED(); |
| 139 return -1; |
| 140 } |
| 141 return indices[0]; |
| 142 } |
| 143 |
| 144 } // namespace |
| 145 |
| 146 ApiPermissionsPanelGtk::ApiPermissionsPanelGtk() |
| 147 : //task_manager_(ApiPermissionsPanel::GetInstance()), |
| 148 //model_(ApiPermissionsPanel::GetInstance()->model()), |
| 149 dialog_(NULL), |
| 150 treeview_(NULL), |
| 151 site_list_(NULL), |
| 152 site_count_(0) { |
| 153 Init(); |
| 154 } |
| 155 |
| 156 // static |
| 157 ApiPermissionsPanelGtk* ApiPermissionsPanelGtk::instance_ = NULL; |
| 158 |
| 159 ApiPermissionsPanelGtk::~ApiPermissionsPanelGtk() { |
| 160 //task_manager_->OnWindowClosed(); |
| 161 //model_->RemoveObserver(this); |
| 162 } |
| 163 |
| 164 //////////////////////////////////////////////////////////////////////////////// |
| 165 // ApiPermissionsPanelGtk, ApiPermissionsPanelModelObserver implementation: |
| 166 /* |
| 167 void ApiPermissionsPanelGtk::OnModelChanged() { |
| 168 // Nothing to do. |
| 169 } |
| 170 |
| 171 void ApiPermissionsPanelGtk::OnItemsChanged(int start, int length) { |
| 172 GtkTreeIter iter; |
| 173 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &iter, |
| 174 NULL, start); |
| 175 |
| 176 for (int i = start; i < start + length; i++) { |
| 177 SetRowDataFromModel(i, &iter); |
| 178 gtk_tree_model_iter_next(GTK_TREE_MODEL(process_list_), &iter); |
| 179 } |
| 180 } |
| 181 |
| 182 void ApiPermissionsPanelGtk::OnItemsAdded(int start, int length) { |
| 183 GtkTreeIter iter; |
| 184 if (start == 0) { |
| 185 gtk_list_store_prepend(process_list_, &iter); |
| 186 } else if (start >= process_count_) { |
| 187 gtk_list_store_append(process_list_, &iter); |
| 188 } else { |
| 189 GtkTreeIter sibling; |
| 190 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &sibling, |
| 191 NULL, start); |
| 192 gtk_list_store_insert_before(process_list_, &iter, &sibling); |
| 193 } |
| 194 |
| 195 SetRowDataFromModel(start, &iter); |
| 196 |
| 197 for (int i = start + 1; i < start + length; i++) { |
| 198 gtk_list_store_insert_after(process_list_, &iter, &iter); |
| 199 SetRowDataFromModel(i, &iter); |
| 200 } |
| 201 |
| 202 process_count_ += length; |
| 203 } |
| 204 |
| 205 void ApiPermissionsPanelGtk::OnItemsRemoved(int start, int length) { |
| 206 GtkTreeIter iter; |
| 207 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(process_list_), &iter, |
| 208 NULL, start); |
| 209 |
| 210 for (int i = 0; i < length; i++) { |
| 211 // |iter| is moved to the next valid node when the current node is removed. |
| 212 gtk_list_store_remove(process_list_, &iter); |
| 213 } |
| 214 |
| 215 process_count_ -= length; |
| 216 } |
| 217 */ |
| 218 //////////////////////////////////////////////////////////////////////////////// |
| 219 // ApiPermissionsPanelGtk, public: |
| 220 |
| 221 // static |
| 222 void ApiPermissionsPanelGtk::Show() { |
| 223 if (instance_) { |
| 224 // If there's a Task manager window open already, just activate it. |
| 225 gtk_window_present(GTK_WINDOW(instance_->dialog_)); |
| 226 } else { |
| 227 instance_ = new ApiPermissionsPanelGtk; |
| 228 //instance_->model_->StartUpdating(); |
| 229 } |
| 230 } |
| 231 |
| 232 //////////////////////////////////////////////////////////////////////////////// |
| 233 // ApiPermissionsPanelGtk, private: |
| 234 |
| 235 void ApiPermissionsPanelGtk::Init() { |
| 236 dialog_ = gtk_dialog_new_with_buttons( |
| 237 l10n_util::GetStringUTF8(IDS_API_PERMISSIONS_PANEL_TITLE).c_str(), |
| 238 // Task Manager window is shared between all browsers. |
| 239 NULL, |
| 240 GTK_DIALOG_NO_SEPARATOR, |
| 241 l10n_util::GetStringUTF8(IDS_API_PERMISSIONS_PANEL_KILL).c_str(), |
| 242 kApiPermissionsPanelResponseKill, |
| 243 NULL); |
| 244 |
| 245 /* |
| 246 GtkWidget* link = gtk_chrome_link_button_new( |
| 247 l10n_util::GetStringUTF8(IDS_API_PERMISSIONS_PANEL_ABOUT_MEMORY_LINK).c_st
r()); |
| 248 gtk_dialog_add_action_widget(GTK_DIALOG(dialog_), link, |
| 249 kApiPermissionsPanelAboutMemoryLink); |
| 250 |
| 251 // Setting the link widget to secondary positions the button on the left side |
| 252 // of the action area (vice versa for RTL layout). |
| 253 gtk_button_box_set_child_secondary( |
| 254 GTK_BUTTON_BOX(GTK_DIALOG(dialog_)->action_area), link, TRUE); |
| 255 */ |
| 256 ConnectAccelerators(); |
| 257 |
| 258 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), |
| 259 gtk_util::kContentAreaSpacing); |
| 260 gtk_util::SetWindowIcon(GTK_WINDOW(dialog_)); |
| 261 |
| 262 g_signal_connect(G_OBJECT(dialog_), "response", G_CALLBACK(OnResponse), this); |
| 263 g_signal_connect(G_OBJECT(dialog_), "button-release-event", |
| 264 G_CALLBACK(OnButtonReleaseEvent), this); |
| 265 gtk_widget_add_events(dialog_, |
| 266 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); |
| 267 |
| 268 // Wrap the treeview widget in a scrolled window in order to have a frame. |
| 269 GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL); |
| 270 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), |
| 271 GTK_SHADOW_ETCHED_IN); |
| 272 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), |
| 273 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
| 274 |
| 275 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), scrolled); |
| 276 |
| 277 CreateApiPermissionsPanelTreeview(); |
| 278 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview_), FALSE); |
| 279 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(treeview_), FALSE); |
| 280 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview_), |
| 281 GTK_TREE_VIEW_GRID_LINES_HORIZONTAL); |
| 282 g_signal_connect(G_OBJECT(treeview_), "button-press-event", |
| 283 G_CALLBACK(OnButtonPressEvent), this); |
| 284 gtk_widget_add_events(treeview_, |
| 285 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); |
| 286 |
| 287 // Hide some columns by default |
| 288 /* |
| 289 TreeViewColumnSetVisible(treeview_, kApiPermissionsPanelSharedMem, false); |
| 290 TreeViewColumnSetVisible(treeview_, kApiPermissionsPanelPrivateMem, false); |
| 291 TreeViewColumnSetVisible(treeview_, kApiPermissionsPanelProcessID, false); |
| 292 TreeViewColumnSetVisible(treeview_, kApiPermissionsPanelGoatsTeleported, false
); |
| 293 */ |
| 294 |
| 295 // |selection| is owned by |treeview_|. |
| 296 GtkTreeSelection* selection = gtk_tree_view_get_selection( |
| 297 GTK_TREE_VIEW(treeview_)); |
| 298 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); |
| 299 g_signal_connect(G_OBJECT(selection), "changed", |
| 300 G_CALLBACK(OnSelectionChanged), this); |
| 301 |
| 302 gtk_container_add(GTK_CONTAINER(scrolled), treeview_); |
| 303 |
| 304 GtkTreeIter iter; |
| 305 gtk_list_store_prepend(site_list_, &iter); |
| 306 SetRowDataFromModel(0, &iter); |
| 307 // FIXME(benl) pass this down into SetRowDataFromModel. |
| 308 std::vector<WebCore::GeolocationBrowserPowerbox::DecisionPair> decisions |
| 309 = WebCore::GeolocationBrowserPowerbox::powerbox.decisions(); |
| 310 for (unsigned i = 1; i < decisions.size(); i++) { |
| 311 gtk_list_store_insert_after(site_list_, &iter, &iter); |
| 312 SetRowDataFromModel(i, &iter); |
| 313 } |
| 314 |
| 315 site_count_ += decisions.size(); |
| 316 |
| 317 SetInitialDialogSize(); |
| 318 gtk_widget_show_all(dialog_); |
| 319 |
| 320 //model_->AddObserver(this); |
| 321 } |
| 322 |
| 323 void ApiPermissionsPanelGtk::SetInitialDialogSize() { |
| 324 // If we previously saved the dialog's bounds, use them. |
| 325 if (g_browser_process->local_state()) { |
| 326 /* |
| 327 const DictionaryValue* placement_pref = |
| 328 g_browser_process->local_state()->GetDictionary( |
| 329 prefs::kApiPermissionsPanelWindowPlacement); |
| 330 int top = 0, left = 0, bottom = 1, right = 1; |
| 331 if (placement_pref && |
| 332 placement_pref->GetInteger(L"top", &top) && |
| 333 placement_pref->GetInteger(L"left", &left) && |
| 334 placement_pref->GetInteger(L"bottom", &bottom) && |
| 335 placement_pref->GetInteger(L"right", &right)) { |
| 336 gtk_window_resize(GTK_WINDOW(dialog_), |
| 337 std::max(1, right - left), |
| 338 std::max(1, bottom - top)); |
| 339 return; |
| 340 } |
| 341 */ |
| 342 } |
| 343 |
| 344 // Otherwise, just set a default size (GTK will override this if it's not |
| 345 // large enough to hold the window's contents). |
| 346 gtk_window_set_default_size( |
| 347 GTK_WINDOW(dialog_), kDefaultWidth, kDefaultHeight); |
| 348 } |
| 349 |
| 350 void ApiPermissionsPanelGtk::ConnectAccelerators() { |
| 351 GtkAccelGroup* accel_group = gtk_accel_group_new(); |
| 352 gtk_window_add_accel_group(GTK_WINDOW(dialog_), accel_group); |
| 353 |
| 354 // Drop the initial ref on |accel_group| so |dialog_| will own it. |
| 355 g_object_unref(accel_group); |
| 356 |
| 357 gtk_accel_group_connect(accel_group, |
| 358 GDK_w, GDK_CONTROL_MASK, GtkAccelFlags(0), |
| 359 g_cclosure_new(G_CALLBACK(OnGtkAccelerator), |
| 360 this, NULL)); |
| 361 } |
| 362 |
| 363 void ApiPermissionsPanelGtk::CreateApiPermissionsPanelTreeview() { |
| 364 treeview_ = gtk_tree_view_new(); |
| 365 |
| 366 TreeViewInsertColumnWithPixbuf(treeview_, |
| 367 IDS_API_PERMISSIONS_PANEL_PAGE_COLUMN); |
| 368 TreeViewInsertColumn(treeview_, IDS_API_PERMISSIONS_PANEL_PERMISSIONS_COLUMN); |
| 369 |
| 370 |
| 371 site_list_ = gtk_list_store_new(kApiPermissionsPanelColumnCount, |
| 372 GDK_TYPE_PIXBUF, G_TYPE_STRING, |
| 373 G_TYPE_STRING); |
| 374 // gtk_chrome_link_button_get_type()); |
| 375 |
| 376 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_), |
| 377 GTK_TREE_MODEL(site_list_)); |
| 378 g_object_unref(site_list_); |
| 379 } |
| 380 |
| 381 std::string ApiPermissionsPanelGtk::GetModelText(int row, int col_id) { |
| 382 // FIXME(benl): inefficient |
| 383 std::vector<WebCore::GeolocationBrowserPowerbox::DecisionPair> decisions |
| 384 = WebCore::GeolocationBrowserPowerbox::powerbox.decisions(); |
| 385 switch (col_id) { |
| 386 case IDS_API_PERMISSIONS_PANEL_PAGE_COLUMN: |
| 387 return decisions[row].first.spec(); |
| 388 case IDS_API_PERMISSIONS_PANEL_PERMISSIONS_COLUMN: |
| 389 return WebCore::GeolocationBrowserPowerbox::powerbox.decisionAsString( |
| 390 decisions[row].second); |
| 391 default: |
| 392 return WideToUTF8(std::wstring(L"Hey!")); |
| 393 } |
| 394 } |
| 395 |
| 396 GdkPixbuf* ApiPermissionsPanelGtk::GetModelIcon(int row) { |
| 397 SkBitmap *icon = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 398 IDR_INFOBAR_RESTORE_SESSION); |
| 399 return gfx::GdkPixbufFromSkBitmap(icon); |
| 400 |
| 401 } |
| 402 |
| 403 void ApiPermissionsPanelGtk::SetRowDataFromModel(int row, GtkTreeIter* iter) { |
| 404 GdkPixbuf* icon = GetModelIcon(row); |
| 405 std::string page = GetModelText(row, IDS_API_PERMISSIONS_PANEL_PAGE_COLUMN); |
| 406 std::string permissions = |
| 407 GetModelText(row, IDS_API_PERMISSIONS_PANEL_PERMISSIONS_COLUMN); |
| 408 gtk_list_store_set(site_list_, iter, |
| 409 kApiPermissionsPanelIcon, icon, |
| 410 kApiPermissionsPanelPage, page.c_str(), |
| 411 kApiPermissionsPanelPermissions, permissions.c_str(), |
| 412 -1); |
| 413 g_object_unref(icon); |
| 414 } |
| 415 |
| 416 // FIXME(benl): we should probably only be looking for browsers with |
| 417 // the current profile. |
| 418 static TabContents *FindTabWithURL(const GURL &url) { |
| 419 for (BrowserList::const_iterator b = BrowserList::begin() ; |
| 420 b != BrowserList::end() ; ++b) { |
| 421 Browser *browser = *b; |
| 422 for(int n = 0 ; n < browser->tab_count() ; ++n) { |
| 423 TabContents *tab = browser->GetTabContentsAt(n); |
| 424 if (tab->GetURL() == url) |
| 425 return tab; |
| 426 } |
| 427 } |
| 428 return NULL; |
| 429 } |
| 430 |
| 431 void ApiPermissionsPanelGtk::ActivateFocusedTab() { |
| 432 GtkTreeSelection* selection = gtk_tree_view_get_selection( |
| 433 GTK_TREE_VIEW(treeview_)); |
| 434 |
| 435 // If the user has just double clicked, only one item is selected. |
| 436 GtkTreeModel* model; |
| 437 GList* selected = gtk_tree_selection_get_selected_rows(selection, &model); |
| 438 int row = GetRowNumForPath(reinterpret_cast<GtkTreePath*>(selected->data)); |
| 439 //task_manager_->ActivateProcess(row); |
| 440 LOG(WARNING) << "double clicked on row " << row; |
| 441 // FIXME(benl): we make the bogus assumption that the decision map |
| 442 // hasn't changed. |
| 443 std::vector<WebCore::GeolocationBrowserPowerbox::DecisionPair> decisions |
| 444 = WebCore::GeolocationBrowserPowerbox::powerbox.decisions(); |
| 445 const GURL &url = decisions[row].first; |
| 446 TabContents *tab = FindTabWithURL(url); |
| 447 if (!tab) { |
| 448 LOG(WARNING) << "tab not found for URL " << url; |
| 449 return; |
| 450 } |
| 451 |
| 452 // Delete the decision so the dialog is shown again. Not 100% clear |
| 453 // this is right, we should just perhaps force the dialog in case |
| 454 // the user doesn't complete it. |
| 455 WebCore::GeolocationBrowserPowerbox::powerbox.deleteDecision(url); |
| 456 |
| 457 tab->Activate(); |
| 458 // Ask it to choose the provider again. |
| 459 tab->render_view_host()->ChooseGeolocationProvider(url); |
| 460 } |
| 461 |
| 462 void Clear(gpointer data, gpointer model) { |
| 463 GtkTreePath *path = |
| 464 reinterpret_cast<GtkTreePath*>(data); |
| 465 gtk_tree_path_free(path); |
| 466 } |
| 467 |
| 468 // static |
| 469 void ApiPermissionsPanelGtk::OnResponse(GtkDialog* dialog, gint response_id, |
| 470 ApiPermissionsPanelGtk* task_manager) { |
| 471 if (response_id == GTK_RESPONSE_DELETE_EVENT) { |
| 472 // Store the dialog's size so we can restore it the next time it's opened. |
| 473 /* |
| 474 if (g_browser_process->local_state()) { |
| 475 gint x = 0, y = 0, width = 1, height = 1; |
| 476 gtk_window_get_position(GTK_WINDOW(dialog), &x, &y); |
| 477 gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); |
| 478 |
| 479 DictionaryValue* placement_pref = |
| 480 g_browser_process->local_state()->GetMutableDictionary( |
| 481 prefs::kApiPermissionsPanelWindowPlacement); |
| 482 // Note that we store left/top for consistency with Windows, but that we |
| 483 // *don't* restore them. |
| 484 placement_pref->SetInteger(L"left", x); |
| 485 placement_pref->SetInteger(L"top", y); |
| 486 placement_pref->SetInteger(L"right", x + width); |
| 487 placement_pref->SetInteger(L"bottom", y + height); |
| 488 placement_pref->SetBoolean(L"maximized", false); |
| 489 } |
| 490 */ |
| 491 |
| 492 instance_ = NULL; |
| 493 delete task_manager; |
| 494 } else if (response_id == kApiPermissionsPanelResponseKill) { |
| 495 GtkTreeModel *model = GTK_TREE_MODEL(task_manager->site_list_); |
| 496 GtkTreeSelection *selection = |
| 497 gtk_tree_view_get_selection(GTK_TREE_VIEW(task_manager->treeview_)); |
| 498 GList *selected_items; |
| 499 // This is kludgey, but I was having a problem with removing items and |
| 500 // invalidating the GtkTreePaths. This works for now. |
| 501 while ( (selected_items = gtk_tree_selection_get_selected_rows(selection, |
| 502 &model)) ) { |
| 503 GtkTreePath *path = |
| 504 reinterpret_cast<GtkTreePath*>(selected_items->data); |
| 505 LOG(WARNING) << gtk_tree_path_to_string(path); |
| 506 GtkTreeIter iter; |
| 507 gtk_tree_model_get_iter(GTK_TREE_MODEL(task_manager->site_list_), |
| 508 &iter, |
| 509 path); |
| 510 gtk_list_store_remove(GTK_LIST_STORE(task_manager->site_list_), &iter); |
| 511 g_list_foreach(selected_items, Clear, NULL); |
| 512 g_list_free(selected_items); |
| 513 } |
| 514 } |
| 515 } |
| 516 |
| 517 // static |
| 518 void ApiPermissionsPanelGtk::OnSelectionChanged(GtkTreeSelection* selection, |
| 519 ApiPermissionsPanelGtk* task_manager) { |
| 520 } |
| 521 |
| 522 // static |
| 523 gboolean ApiPermissionsPanelGtk::OnButtonPressEvent(GtkWidget* widget, |
| 524 GdkEventButton* event, |
| 525 ApiPermissionsPanelGtk* task_manager
) { |
| 526 if (event->type == GDK_2BUTTON_PRESS) |
| 527 task_manager->ActivateFocusedTab(); |
| 528 return FALSE; |
| 529 } |
| 530 |
| 531 // static |
| 532 gboolean ApiPermissionsPanelGtk::OnButtonReleaseEvent(GtkWidget* widget, |
| 533 GdkEventButton* event, |
| 534 ApiPermissionsPanelGtk* task_manag
er) { |
| 535 // We don't want to open the context menu in the treeview. |
| 536 if (gtk_util::WidgetContainsCursor(task_manager->treeview_)) |
| 537 return FALSE; |
| 538 |
| 539 return FALSE; |
| 540 } |
| 541 |
| 542 // static |
| 543 gboolean ApiPermissionsPanelGtk::OnGtkAccelerator(GtkAccelGroup* accel_group, |
| 544 GObject* acceleratable, |
| 545 guint keyval, |
| 546 GdkModifierType modifier, |
| 547 ApiPermissionsPanelGtk* task_manager)
{ |
| 548 if (keyval == GDK_w && modifier == GDK_CONTROL_MASK) { |
| 549 // The GTK_RESPONSE_DELETE_EVENT response must be sent before the widget |
| 550 // is destroyed. The deleted object will receive gtk signals otherwise. |
| 551 gtk_dialog_response(GTK_DIALOG(task_manager->dialog_), |
| 552 GTK_RESPONSE_DELETE_EVENT); |
| 553 gtk_widget_destroy(task_manager->dialog_); |
| 554 } |
| 555 |
| 556 return TRUE; |
| 557 } |
| OLD | NEW |