Commit 5b3bb398 authored by Eike Ziller's avatar Eike Ziller
Browse files

Run "New ..." dialog as non-blocking, stay-on-top.



Task-number: QTCREATORBUG-6102
Change-Id: I384c37e5867ce1cbd6127e96c49cb7790298713c
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 8cd6f190
......@@ -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;
}
......
......@@ -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()
......
......@@ -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
......
......@@ -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()
......
......@@ -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();
......
......@@ -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
......@@ -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;
......
......@@ -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));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment