diff options
author | Eike Ziller <eike.ziller@digia.com> | 2014-06-27 15:15:09 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@digia.com> | 2014-07-02 09:57:11 +0200 |
commit | 5b3bb398ba751265aec0fb8071dacc5784985e91 (patch) | |
tree | c41046eb9aac701a3c322374b938c8099e323ae0 /src/plugins | |
parent | 8cd6f1909579c06940b52b1afef87aef4d8ea0e8 (diff) | |
download | qt-creator-5b3bb398ba751265aec0fb8071dacc5784985e91.tar.gz |
Run "New ..." dialog as non-blocking, stay-on-top.
Task-number: QTCREATORBUG-6102
Change-Id: I384c37e5867ce1cbd6127e96c49cb7790298713c
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/coreplugin/basefilewizardfactory.cpp | 4 | ||||
-rw-r--r-- | src/plugins/coreplugin/dialogs/newdialog.cpp | 98 | ||||
-rw-r--r-- | src/plugins/coreplugin/dialogs/newdialog.h | 13 | ||||
-rw-r--r-- | src/plugins/coreplugin/icore.cpp | 7 | ||||
-rw-r--r-- | src/plugins/coreplugin/icore.h | 2 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.cpp | 61 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.h | 7 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectexplorer.cpp | 10 |
8 files changed, 132 insertions, 70 deletions
diff --git a/src/plugins/coreplugin/basefilewizardfactory.cpp b/src/plugins/coreplugin/basefilewizardfactory.cpp index fe2cffd203..08e3bb2e81 100644 --- a/src/plugins/coreplugin/basefilewizardfactory.cpp +++ b/src/plugins/coreplugin/basefilewizardfactory.cpp @@ -122,7 +122,7 @@ WizardEventLoop::WizardResult WizardEventLoop::execWizardPage(QWizard &wizard) connect(&wizard, SIGNAL(currentIdChanged(int)), eventLoop, SLOT(pageChanged(int))); connect(&wizard, SIGNAL(accepted()), eventLoop, SLOT(accepted())); connect(&wizard, SIGNAL(rejected()), eventLoop, SLOT(rejected())); - wizard.setAttribute(Qt::WA_ShowModal, true); + wizard.setWindowFlags(wizard.windowFlags() | Qt::WindowStaysOnTopHint); wizard.show(); } const WizardResult result = eventLoop->execWizardPageI(); @@ -138,7 +138,7 @@ WizardEventLoop::WizardResult WizardEventLoop::execWizardPage(QWizard &wizard) WizardEventLoop::WizardResult WizardEventLoop::execWizardPageI() { m_result = Rejected; - exec(QEventLoop::DialogExec); + exec(); return m_result; } diff --git a/src/plugins/coreplugin/dialogs/newdialog.cpp b/src/plugins/coreplugin/dialogs/newdialog.cpp index 374c21e205..32704ec31d 100644 --- a/src/plugins/coreplugin/dialogs/newdialog.cpp +++ b/src/plugins/coreplugin/dialogs/newdialog.cpp @@ -31,15 +31,19 @@ #include "ui_newdialog.h" #include <coreplugin/coreconstants.h> +#include <coreplugin/documentmanager.h> +#include <coreplugin/icore.h> +#include <utils/qtcassert.h> -#include <QModelIndex> #include <QAbstractProxyModel> -#include <QSortFilterProxyModel> -#include <QPushButton> -#include <QStandardItem> +#include <QDebug> #include <QItemDelegate> +#include <QKeyEvent> +#include <QModelIndex> #include <QPainter> -#include <QDebug> +#include <QPushButton> +#include <QSortFilterProxyModel> +#include <QStandardItem> Q_DECLARE_METATYPE(Core::IWizardFactory*) @@ -183,12 +187,16 @@ Q_DECLARE_METATYPE(WizardFactoryContainer) using namespace Core; using namespace Core::Internal; +QString NewDialog::m_lastCategory = QString(); + NewDialog::NewDialog(QWidget *parent) : QDialog(parent), m_ui(new Core::Internal::Ui::NewDialog), m_okButton(0) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + setAttribute(Qt::WA_DeleteOnClose); m_ui->setupUi(this); QPalette p = m_ui->frame->palette(); p.setColor(QPalette::Window, p.color(QPalette::Base)); @@ -236,8 +244,12 @@ static bool wizardFactoryLessThan(const IWizardFactory *f1, const IWizardFactory return f1->id().compare(f2->id()) < 0; } -void NewDialog::setWizardFactories(QList<IWizardFactory*> factories) +void NewDialog::setWizardFactories(QList<IWizardFactory *> factories, + const QString &defaultLocation, + const QVariantMap &extraVariables) { + m_defaultLocation = defaultLocation; + m_extraVariables = extraVariables; qStableSort(factories.begin(), factories.end(), wizardFactoryLessThan); m_model->clear(); @@ -287,14 +299,13 @@ void NewDialog::setWizardFactories(QList<IWizardFactory*> factories) parentItem->removeRow(0); } -Core::IWizardFactory *NewDialog::showDialog() +void NewDialog::showDialog() { - static QString lastCategory; QModelIndex idx; - if (!lastCategory.isEmpty()) + if (!m_lastCategory.isEmpty()) foreach (QStandardItem* item, m_categoryItems) { - if (item->data(Qt::UserRole) == lastCategory) + if (item->data(Qt::UserRole) == m_lastCategory) idx = m_twoLevelProxyModel->mapToSource(m_model->indexFromItem(item)); } if (!idx.isValid()) @@ -312,18 +323,7 @@ Core::IWizardFactory *NewDialog::showDialog() currentItemChanged(m_ui->templatesView->rootIndex().child(0,0)); updateOkButton(); - - const int retVal = exec(); - - idx = m_ui->templateCategoryView->currentIndex(); - QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx)); - if (currentItem) - lastCategory = currentItem->data(Qt::UserRole).toString(); - - if (retVal != Accepted) - return 0; - - return currentWizardFactory(); + show(); } QString NewDialog::selectedPlatform() const @@ -333,6 +333,18 @@ QString NewDialog::selectedPlatform() const return m_ui->comboBox->itemData(index).toString(); } +bool NewDialog::event(QEvent *event) +{ + if (event->type() == QEvent::ShortcutOverride) { + QKeyEvent *ke = static_cast<QKeyEvent *>(event); + if (ke->key() == Qt::Key_Escape && !ke->modifiers()) { + ke->accept(); + return true; + } + } + return QDialog::event(event); +} + NewDialog::~NewDialog() { delete m_ui; @@ -422,10 +434,48 @@ void NewDialog::currentItemChanged(const QModelIndex &index) updateOkButton(); } +void NewDialog::saveState() +{ + QModelIndex idx = m_ui->templateCategoryView->currentIndex(); + QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx)); + if (currentItem) + m_lastCategory = currentItem->data(Qt::UserRole).toString(); +} + void NewDialog::okButtonClicked() { - if (m_ui->templatesView->currentIndex().isValid()) - accept(); + if (m_ui->templatesView->currentIndex().isValid()) { + hide(); + saveState(); + + IWizardFactory *wizard = currentWizardFactory(); + QTC_ASSERT(wizard, accept(); return); + QString path = m_defaultLocation; + if (path.isEmpty()) { + switch (wizard->kind()) { + case IWizardFactory::ProjectWizard: + // Project wizards: Check for projects directory or + // use last visited directory of file dialog. Never start + // at current. + path = DocumentManager::useProjectsDirectory() ? + DocumentManager::projectsDirectory() : + DocumentManager::fileDialogLastVisitedDirectory(); + break; + default: + path = DocumentManager::fileDialogInitialDirectory(); + break; + } + } + wizard->runWizard(path, ICore::dialogParent(), selectedPlatform(), m_extraVariables); + + close(); + } +} + +void NewDialog::reject() +{ + saveState(); + QDialog::reject(); } void NewDialog::updateOkButton() diff --git a/src/plugins/coreplugin/dialogs/newdialog.h b/src/plugins/coreplugin/dialogs/newdialog.h index 3dc8fbd9f6..04d434fc01 100644 --- a/src/plugins/coreplugin/dialogs/newdialog.h +++ b/src/plugins/coreplugin/dialogs/newdialog.h @@ -60,21 +60,28 @@ public: explicit NewDialog(QWidget *parent); virtual ~NewDialog(); - void setWizardFactories(QList<IWizardFactory*> factories); + void setWizardFactories(QList<IWizardFactory*> factories, const QString &defaultLocation, const QVariantMap &extraVariables); - Core::IWizardFactory *showDialog(); + void showDialog(); QString selectedPlatform() const; +protected: + bool event(QEvent *); + private slots: void currentCategoryChanged(const QModelIndex &); void currentItemChanged(const QModelIndex &); void okButtonClicked(); + void reject(); void updateOkButton(); void setSelectedPlatform(const QString &platform); private: Core::IWizardFactory *currentWizardFactory() const; void addItem(QStandardItem *topLevelCategoryItem, IWizardFactory *factory); + void saveState(); + + static QString m_lastCategory; Ui::NewDialog *m_ui; QStandardItemModel *m_model; @@ -83,6 +90,8 @@ private: QPushButton *m_okButton; QIcon m_dummyIcon; QList<QStandardItem*> m_categoryItems; + QString m_defaultLocation; + QVariantMap m_extraVariables; }; } // namespace Internal diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index b842d1cce5..5e6cc4613a 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -311,6 +311,11 @@ ICore *ICore::instance() return m_instance; } +bool ICore::isNewItemDialogRunning() +{ + return m_mainwindow->isNewItemDialogRunning(); +} + ICore::ICore(MainWindow *mainwindow) { m_instance = this; @@ -318,6 +323,8 @@ ICore::ICore(MainWindow *mainwindow) // Save settings once after all plugins are initialized: connect(ExtensionSystem::PluginManager::instance(), SIGNAL(initializationDone()), this, SLOT(saveSettings())); + connect(m_mainwindow, SIGNAL(newItemDialogRunningChanged()), + this, SIGNAL(newItemDialogRunningChanged())); } ICore::~ICore() diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index b772b1c965..42f2837312 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -67,6 +67,7 @@ public: // it returns a ICore. static ICore *instance(); + static bool isNewItemDialogRunning(); static void showNewItemDialog(const QString &title, const QList<IWizardFactory *> &factories, const QString &defaultLocation = QString(), @@ -126,6 +127,7 @@ signals: void coreAboutToOpen(); void coreOpened(); void newItemsDialogRequested(); + void newItemDialogRunningChanged(); void saveSettingsRequested(); void optionsDialogRequested(); void coreAboutToClose(); diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 2ef8720bd5..8b8049093a 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -76,6 +76,7 @@ #include <coreplugin/settingsdatabase.h> #include <utils/historycompleter.h> #include <utils/hostosinfo.h> +#include <utils/qtcassert.h> #include <utils/stylehelper.h> #include <utils/stringutils.h> #include <extensionsystem/pluginmanager.h> @@ -248,6 +249,11 @@ void MainWindow::setIsFullScreen(bool fullScreen) m_toggleFullScreenAction->setText(tr("Enter Full Screen")); } +bool MainWindow::isNewItemDialogRunning() const +{ + return !m_newDialog.isNull(); +} + MainWindow::~MainWindow() { ExtensionSystem::PluginManager::removeObject(m_shortcutSettings); @@ -869,46 +875,14 @@ void MainWindow::showNewItemDialog(const QString &title, const QString &defaultLocation, const QVariantMap &extraVariables) { - // Scan for wizards matching the filter and pick one. Don't show - // dialog if there is only one. - IWizardFactory *wizard = 0; - QString selectedPlatform; - switch (factories.size()) { - case 0: - break; - case 1: - wizard = factories.front(); - break; - default: { - NewDialog dlg(this); - dlg.setWizardFactories(factories); - dlg.setWindowTitle(title); - wizard = dlg.showDialog(); - selectedPlatform = dlg.selectedPlatform(); - } - break; - } - - if (!wizard) - return; - - QString path = defaultLocation; - if (path.isEmpty()) { - switch (wizard->kind()) { - case IWizardFactory::ProjectWizard: - // Project wizards: Check for projects directory or - // use last visited directory of file dialog. Never start - // at current. - path = DocumentManager::useProjectsDirectory() ? - DocumentManager::projectsDirectory() : - DocumentManager::fileDialogLastVisitedDirectory(); - break; - default: - path = DocumentManager::fileDialogInitialDirectory(); - break; - } - } - wizard->runWizard(path, this, selectedPlatform, extraVariables); + QTC_ASSERT(!m_newDialog, return); + m_newAction->setEnabled(false); + m_newDialog = new NewDialog(this); + connect(m_newDialog.data(), SIGNAL(destroyed()), this, SLOT(newItemDialogFinished())); + m_newDialog->setWizardFactories(factories, defaultLocation, extraVariables); + m_newDialog->setWindowTitle(title); + m_newDialog->showDialog(); + emit newItemDialogRunningChanged(); } bool MainWindow::showOptionsDialog(Id category, Id page, QWidget *parent) @@ -1263,5 +1237,12 @@ void MainWindow::restoreWindowState() m_statusBarManager->restoreSettings(); } +void MainWindow::newItemDialogFinished() +{ + m_newAction->setEnabled(true); + // fire signal when the dialog is actually destroyed + QTimer::singleShot(0, this, SIGNAL(newItemDialogRunningChanged())); +} + } // namespace Internal } // namespace Core diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 07179c5de9..1540d08247 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -32,6 +32,7 @@ #include "icontext.h" #include "icore.h" +#include "dialogs/newdialog.h" #include <utils/appmainwindow.h> @@ -107,8 +108,12 @@ public: void setOverrideColor(const QColor &color); void setIsFullScreen(bool fullScreen); + + bool isNewItemDialogRunning() const; + signals: void windowActivated(); + void newItemDialogRunningChanged(); public slots: void newFile(); @@ -148,6 +153,7 @@ private slots: void destroyVersionDialog(); void openDelayedFiles(); void restoreWindowState(); + void newItemDialogFinished(); private: void updateContextObject(const QList<IContext *> &context); @@ -179,6 +185,7 @@ private: RightPaneWidget *m_rightPaneWidget; Core::StatusBarWidget *m_outputView; VersionDialog *m_versionDialog; + QPointer<NewDialog> m_newDialog; QList<IContext *> m_activeContext; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 5f8cd008ed..c5f185ab35 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1044,6 +1044,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(ICore::instance(), SIGNAL(coreAboutToOpen()), this, SLOT(determineSessionToRestoreAtStartup())); connect(ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession())); + connect(ICore::instance(), SIGNAL(newItemDialogRunningChanged()), + this, SLOT(updateActions())); updateWelcomePage(); @@ -1933,6 +1935,8 @@ void ProjectExplorerPlugin::updateActions() if (debug) qDebug() << "ProjectExplorerPlugin::updateActions"; + d->m_newAction->setEnabled(!ICore::isNewItemDialogRunning()); + Project *project = SessionManager::startupProject(); QPair<bool, QString> buildActionState = buildSettingsEnabled(project); @@ -2780,9 +2784,11 @@ void ProjectExplorerPlugin::updateContextMenuActions() } if (qobject_cast<FolderNode*>(d->m_currentNode)) { // Also handles ProjectNode - d->m_addNewFileAction->setEnabled(actions.contains(ProjectExplorer::AddNewFile)); + d->m_addNewFileAction->setEnabled(actions.contains(ProjectExplorer::AddNewFile) + && !ICore::isNewItemDialogRunning()); d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType - && actions.contains(ProjectExplorer::AddSubProject)); + && actions.contains(ProjectExplorer::AddSubProject) + && !ICore::isNewItemDialogRunning()); d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectExplorer::AddExistingFile)); d->m_addExistingDirectoryAction->setEnabled(actions.contains(ProjectExplorer::AddExistingDirectory)); d->m_renameFileAction->setEnabled(actions.contains(ProjectExplorer::Rename)); |