| Index: chrome/browser/browser.cc
|
| diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
|
| index 0aa1e2b29bd4d201d5c8c50ff11da0658d007d2e..e9f1738d1bac701dffc8c6011bd9c09dc1b7157c 100644
|
| --- a/chrome/browser/browser.cc
|
| +++ b/chrome/browser/browser.cc
|
| @@ -1079,15 +1079,54 @@ void Browser::FocusSearch() {
|
|
|
| void Browser::OpenFile() {
|
| UserMetrics::RecordAction(L"OpenFile", profile_);
|
| - if (!select_file_dialog_.get())
|
| - select_file_dialog_ = SelectFileDialog::Create(this);
|
| +
|
| + TabContents* contents = GetSelectedTabContents();
|
| + if (!contents) { // Avoid crashing in release.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
|
|
| // TODO(beng): figure out how to juggle this.
|
| +#if defined(OS_MACOSX)
|
| + // TODO(viettrungluu@gmail.com): If there's a constrained dialog in the
|
| + // current tab, we should probably just create a new tab and go do the open
|
| + // there. (Why not just close the current dialog, esp. if it's not important?
|
| + // If we did that, then the previous one should come back with its original
|
| + // state on cancel.)
|
| + if (!contents->CanCreateConstrainedDialog()) {
|
| + if (type() == TYPE_NORMAL) {
|
| + contents = AddBlankTab(true);
|
| + if (!contents) { // Avoid crashing in release.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + } else {
|
| + // TODO(viettrungluu@gmail.com): the other cases.
|
| + NOTIMPLEMENTED();
|
| + return;
|
| + }
|
| + }
|
| +
|
| + if (!contents->CanCreateConstrainedDialog()) { // Avoid crashing in release.
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + if (!select_file_dialog_.get())
|
| + select_file_dialog_ = SelectFileDialog::Create(this);
|
| + select_file_dialog_->SelectFileInTab(SelectFileDialog::SELECT_OPEN_FILE,
|
| + string16(), FilePath(),
|
| + NULL, 0, FILE_PATH_LITERAL(""),
|
| + contents, NULL);
|
| +#else
|
| + if (!select_file_dialog_.get())
|
| + select_file_dialog_ = SelectFileDialog::Create(this);
|
| gfx::NativeWindow parent_window = window_->GetNativeHandle();
|
| select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
|
| string16(), FilePath(),
|
| NULL, 0, FILE_PATH_LITERAL(""),
|
| parent_window, NULL);
|
| +#endif
|
| }
|
|
|
| void Browser::OpenCreateShortcutsDialog() {
|
| @@ -1981,6 +2020,11 @@ void Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
|
| }
|
| }
|
|
|
| +void Browser::ChildWindowsChanged(TabContents* source) {
|
| + if (source == GetSelectedTabContents())
|
| + UpdateCommandsForTabState();
|
| +}
|
| +
|
| void Browser::UpdateDownloadShelfVisibility(bool visible) {
|
| if (GetStatusBubble())
|
| GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
|
| @@ -2338,6 +2382,13 @@ void Browser::InitCommandState() {
|
| command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
|
| command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
|
|
|
| +#if defined(OS_MACOSX)
|
| + // On Mac, we do not disable the Encoding menu, but rather the individual menu
|
| + // items (like other Mac apps). The Encoding menu's contents start out
|
| + // disabled by default.
|
| + command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU, true);
|
| +#endif
|
| +
|
| // Clipboard commands
|
| command_updater_.UpdateCommandEnabled(IDC_CUT, true);
|
| command_updater_.UpdateCommandEnabled(IDC_COPY, true);
|
| @@ -2419,6 +2470,123 @@ void Browser::InitCommandState() {
|
| UpdateCommandsForFullscreenMode(false);
|
| }
|
|
|
| +#if defined(OS_MACOSX)
|
| +// TODO(viettrungluu@gmail.com): Merge with non-Mac implementation. The main
|
| +// differences are: (1) on Mac, we have full-tab-modals; (2) on Mac, we have a
|
| +// global application menu.
|
| +void Browser::UpdateCommandsForTabState() {
|
| + struct cmd_disabled_at {
|
| + int cmd_id;
|
| + ConstrainedWindow::ModalityLevel level;
|
| + };
|
| + // Notes:
|
| + // - IDC_GO should be tied to IDC_OPEN_CURRENT_URL (i.e., the latter disables
|
| + // the former)
|
| + // - is IDC_STOP tied to IDC_GO? at least the button should be, right?
|
| + // - unknown: IDC_CLOSE_POPUPS
|
| + // - this is designed to handle additional entries (e.g., for
|
| + // |kModalForWindow|, or a hypothetical |kModalForApp|)
|
| + // TODO(viettrungluu@gmail.com): move the modality stuff to somewhere where we
|
| + // can use it during window modals
|
| + // TODO(viettrungluu@gmail.com): IDC_OPEN_RECENT_MENU_CONTENTS isn't actually
|
| + // picked up by anything (actually, it doesn't do anything either)
|
| + // FIXME(viettrungluu@gmail.com): IDC_PRINT is still really wonky (presumably
|
| + // because it determines whether it's active by sending up the responder
|
| + // chain)
|
| + const cmd_disabled_at k_cmd_levels[] = {
|
| + { IDC_OPEN_FILE, ConstrainedWindow::kModalForTab },
|
| + { IDC_SAVE_PAGE, ConstrainedWindow::kModalForContent },
|
| + { IDC_FOCUS_LOCATION, ConstrainedWindow::kModalForTab },
|
| +// FIXME(viettrungluU@gmail.com): I think page setup will app-modal or modeless
|
| +// { IDC_PRINT_PAGE_SETUP, ConstrainedWindow::kModalForContent },
|
| + { IDC_PRINT, ConstrainedWindow::kModalForContent },
|
| + { IDC_SHOW_BOOKMARK_BAR, ConstrainedWindow::kModalForTab },
|
| + { IDC_STOP, ConstrainedWindow::kModalForTab },
|
| + { IDC_RELOAD, ConstrainedWindow::kModalForTab },
|
| + { IDC_ZOOM_PLUS, ConstrainedWindow::kModalForTab },
|
| + { IDC_ZOOM_NORMAL, ConstrainedWindow::kModalForTab },
|
| + { IDC_ZOOM_MINUS, ConstrainedWindow::kModalForTab },
|
| + { IDC_VIEW_SOURCE, ConstrainedWindow::kModalForTab },
|
| + { IDC_DEV_TOOLS, ConstrainedWindow::kModalForTab },
|
| + { IDC_STAR, ConstrainedWindow::kModalForTab },
|
| + { IDC_BACK, ConstrainedWindow::kModalForTab },
|
| + { IDC_FORWARD, ConstrainedWindow::kModalForTab },
|
| + { IDC_HOME, ConstrainedWindow::kModalForTab },
|
| + { IDC_OPEN_CURRENT_URL, ConstrainedWindow::kModalForTab },
|
| + { IDC_FIND, ConstrainedWindow::kModalForContent },
|
| + { IDC_FIND_NEXT, ConstrainedWindow::kModalForContent },
|
| + { IDC_FIND_PREVIOUS, ConstrainedWindow::kModalForContent },
|
| + { IDC_PAGE_MENU_BUTTON, ConstrainedWindow::kModalForTab },
|
| + { IDC_WRENCH_MENU_BUTTON, ConstrainedWindow::kModalForTab },
|
| + { IDC_OPEN_RECENT_MENU_CONTENTS, ConstrainedWindow::kModalForTab },
|
| + { IDC_HISTORY_MENU_CONTENTS, ConstrainedWindow::kModalForTab },
|
| + { IDC_BOOKMARK_MENU_CONTENTS, ConstrainedWindow::kModalForTab },
|
| + // On Mac, we disable the Encoding menu's contents
|
| + // (IDC_ENCODING_MENU_CONTENTS) rather than the menu (IDC_ENCODING_MENU).
|
| + { IDC_ENCODING_MENU_CONTENTS, ConstrainedWindow::kModalForTab },
|
| + };
|
| + const size_t k_num_cmd_levels = ARRAYSIZE_UNSAFE(k_cmd_levels);
|
| +
|
| + TabContents* current_tab = GetSelectedTabContents();
|
| + if (!current_tab) // May be NULL during tab restore.
|
| + return;
|
| +
|
| + // We make a map out of the above, and "calculate" enable/disable states on
|
| + // the map. We store *disabled* status (i.e., true if disabled), since STL
|
| + // will initialize bool's to false by default (and we want default enabled).
|
| + // See below for how to (possibly) modify the state.
|
| + std::map<int,bool> disable_cmd;
|
| + ConstrainedWindow::ModalityLevel cur_lev = current_tab->GetTabModalityLevel();
|
| + for (size_t i = 0; i < k_num_cmd_levels; ++i)
|
| + disable_cmd[k_cmd_levels[i].cmd_id] = (cur_lev >= k_cmd_levels[i].level);
|
| +
|
| + // === Keep in sync with non-Mac implementation (below)
|
| +
|
| + // Navigation commands
|
| + NavigationController& nc = current_tab->controller();
|
| + disable_cmd[IDC_BACK] |= !nc.CanGoBack();
|
| + disable_cmd[IDC_FORWARD] |= !nc.CanGoForward();
|
| +
|
| + // Window management commands
|
| + disable_cmd[IDC_DUPLICATE_TAB] |= !(!(type() & TYPE_APP) &&
|
| + CanDuplicateContentsAt(selected_index()));
|
| +
|
| + // Current navigation entry, may be NULL.
|
| + NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
|
| + bool is_source_viewable = net::IsSupportedNonImageMimeType(
|
| + current_tab->contents_mime_type().c_str());
|
| +
|
| + // Page-related commands
|
| + window_->SetStarredState(current_tab->is_starred());
|
| + // View-source should not be enabled if already in view-source mode or
|
| + // the source is not viewable.
|
| + disable_cmd[IDC_VIEW_SOURCE] |= !(active_entry &&
|
| + !active_entry->IsViewSourceMode() &&
|
| + is_source_viewable);
|
| + disable_cmd[IDC_SAVE_PAGE] |=
|
| + !(SavePackage::IsSavableURL(current_tab->GetURL()));
|
| +
|
| + // We don't enable/disable the Encoding menu on Mac, but its contents (see
|
| + // note above).
|
| + disable_cmd[IDC_ENCODING_MENU_CONTENTS] |=
|
| + !(SavePackage::IsSavableContents(current_tab->contents_mime_type()) &&
|
| + SavePackage::IsSavableURL(current_tab->GetURL()));
|
| +
|
| + // Show various bits of UI
|
| + disable_cmd[IDC_CREATE_SHORTCUTS] |= current_tab->GetFavIcon().isNull();
|
| +
|
| + // === end sync
|
| +
|
| + // TODO(viettrungluu@gmail.com): not complete; should other implementation
|
| + // have this?
|
| + disable_cmd[IDC_PRINT] |= !active_entry;
|
| +
|
| + // Now we update commands.
|
| + std::map<int,bool>::iterator it, end;
|
| + for (it = disable_cmd.begin(), end = disable_cmd.end(); it != end; ++it)
|
| + command_updater_.UpdateCommandEnabled(it->first, !(it->second));
|
| +}
|
| +#else
|
| void Browser::UpdateCommandsForTabState() {
|
| TabContents* current_tab = GetSelectedTabContents();
|
| if (!current_tab) // May be NULL during tab restore.
|
| @@ -2435,9 +2603,9 @@ void Browser::UpdateCommandsForTabState() {
|
|
|
| // Current navigation entry, may be NULL.
|
| NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
|
| - bool is_source_viewable =
|
| - net::IsSupportedNonImageMimeType(
|
| - current_tab->contents_mime_type().c_str());
|
| + bool is_source_viewable =
|
| + net::IsSupportedNonImageMimeType(
|
| + current_tab->contents_mime_type().c_str());
|
|
|
| // Page-related commands
|
| window_->SetStarredState(current_tab->is_starred());
|
| @@ -2463,6 +2631,7 @@ void Browser::UpdateCommandsForTabState() {
|
| command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
|
| !current_tab->GetFavIcon().isNull());
|
| }
|
| +#endif
|
|
|
| void Browser::UpdateStopGoState(bool is_loading, bool force) {
|
| window_->UpdateStopGoState(is_loading, force);
|
|
|