OutputPanes: Fix various issues with restoring state

- maximize tool button was synced between modes,
  but the size didn't match that
- size was restored to the last visible size, even if that was
  maximized, but maximize state didn't match that

Manage the state (maximize state & non-maximized size) in the output
pane placeholders themselves. The output pane manager is only
responsible for the non maximized size setting that is restored at
restart.

Task-number: QTCREATORBUG-10992
Change-Id: I35b946bbffeef9fbf5301e34018dd0867bd902a6
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Eike Ziller
2016-03-08 14:09:01 +01:00
parent ea29a83095
commit 9aee611520
5 changed files with 90 additions and 58 deletions

View File

@@ -181,7 +181,7 @@ static void setFocusToEditorViewAndUnmaximizePanes(EditorView *view)
if (holder && holder->window() == view->window()) {
// unmaximize output pane if necessary
if (holder->isVisible() && holder->isMaximized())
holder->unmaximize();
holder->setMaximized(false);
}
}

View File

@@ -28,22 +28,26 @@
#include "outputpane.h"
#include "outputpanemanager.h"
#include <QResizeEvent>
#include <QSplitter>
#include <QVBoxLayout>
namespace Core {
struct OutputPanePlaceHolderPrivate {
class OutputPanePlaceHolderPrivate {
public:
explicit OutputPanePlaceHolderPrivate(IMode *mode, QSplitter *parent);
IMode *m_mode;
QSplitter *m_splitter;
int m_lastNonMaxSize;
int m_nonMaximizedSize = 0;
bool m_isMaximized = false;
bool m_initialized = false;
static OutputPanePlaceHolder* m_current;
};
OutputPanePlaceHolderPrivate::OutputPanePlaceHolderPrivate(IMode *mode, QSplitter *parent) :
m_mode(mode), m_splitter(parent), m_lastNonMaxSize(0)
m_mode(mode), m_splitter(parent)
{
}
@@ -82,32 +86,42 @@ void OutputPanePlaceHolder::currentModeChanged(IMode *mode)
{
if (d->m_current == this) {
d->m_current = 0;
if (d->m_initialized)
Internal::OutputPaneManager::setOutputPaneHeightSetting(d->m_nonMaximizedSize);
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
om->setParent(0);
om->hide();
om->setParent(0);
om->updateStatusButtons(false);
}
if (d->m_mode == mode) {
if (d->m_current && d->m_current->d->m_initialized)
Internal::OutputPaneManager::setOutputPaneHeightSetting(d->m_current->d->m_nonMaximizedSize);
d->m_current = this;
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
layout()->addWidget(om);
om->show();
om->updateStatusButtons(isVisible());
Internal::OutputPaneManager::updateMaximizeButton(d->m_isMaximized);
}
}
void OutputPanePlaceHolder::maximizeOrMinimize(bool maximize)
void OutputPanePlaceHolder::setMaximized(bool maximize)
{
if (d->m_isMaximized == maximize)
return;
if (!d->m_splitter)
return;
int idx = d->m_splitter->indexOf(this);
if (idx < 0)
return;
d->m_isMaximized = maximize;
if (d->m_current == this)
Internal::OutputPaneManager::updateMaximizeButton(d->m_isMaximized);
QList<int> sizes = d->m_splitter->sizes();
if (maximize) {
d->m_lastNonMaxSize = sizes[idx];
d->m_nonMaximizedSize = sizes[idx];
int sum = 0;
foreach (int s, sizes)
sum += s;
@@ -116,7 +130,7 @@ void OutputPanePlaceHolder::maximizeOrMinimize(bool maximize)
}
sizes[idx] = sum - (sizes.count()-1) * 32;
} else {
int target = d->m_lastNonMaxSize > 0 ? d->m_lastNonMaxSize : sizeHint().height();
int target = d->m_nonMaximizedSize > 0 ? d->m_nonMaximizedSize : sizeHint().height();
int space = sizes[idx] - target;
if (space > 0) {
for (int i = 0; i < sizes.count(); ++i) {
@@ -127,31 +141,31 @@ void OutputPanePlaceHolder::maximizeOrMinimize(bool maximize)
}
d->m_splitter->setSizes(sizes);
}
bool OutputPanePlaceHolder::isMaximized() const
{
return Internal::OutputPaneManager::instance()->isMaximized();
return d->m_isMaximized;
}
void OutputPanePlaceHolder::setDefaultHeight(int height)
void OutputPanePlaceHolder::setHeight(int height)
{
if (height == 0)
return;
if (!d->m_splitter)
return;
int idx = d->m_splitter->indexOf(this);
const int idx = d->m_splitter->indexOf(this);
if (idx < 0)
return;
d->m_splitter->refresh();
QList<int> sizes = d->m_splitter->sizes();
int difference = height - sizes.at(idx);
if (difference <= 0) // is already larger
const int difference = height - sizes.at(idx);
if (difference == 0)
return;
const int adaption = difference / (sizes.count()-1);
for (int i = 0; i < sizes.count(); ++i) {
sizes[i] += difference / (sizes.count()-1);
sizes[i] -= adaption;
}
sizes[idx] = height;
d->m_splitter->setSizes(sizes);
@@ -162,13 +176,28 @@ void OutputPanePlaceHolder::ensureSizeHintAsMinimum()
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
int minimum = (d->m_splitter->orientation() == Qt::Vertical
? om->sizeHint().height() : om->sizeHint().width());
setDefaultHeight(minimum);
if (height() < minimum)
setHeight(minimum);
}
void OutputPanePlaceHolder::unmaximize()
int OutputPanePlaceHolder::nonMaximizedSize() const
{
if (Internal::OutputPaneManager::instance()->isMaximized())
Internal::OutputPaneManager::instance()->slotMinMax();
return d->m_nonMaximizedSize;
}
void OutputPanePlaceHolder::resizeEvent(QResizeEvent *event)
{
if (d->m_isMaximized || event->size().height() == 0)
return;
d->m_nonMaximizedSize = event->size().height();
}
void OutputPanePlaceHolder::showEvent(QShowEvent *)
{
if (!d->m_initialized) {
d->m_initialized = true;
setHeight(Internal::OutputPaneManager::outputPaneHeightSetting());
}
}
OutputPanePlaceHolder *OutputPanePlaceHolder::getCurrent()
@@ -176,11 +205,6 @@ OutputPanePlaceHolder *OutputPanePlaceHolder::getCurrent()
return OutputPanePlaceHolderPrivate::m_current;
}
bool OutputPanePlaceHolder::canMaximizeOrMinimize() const
{
return d->m_splitter != 0;
}
bool OutputPanePlaceHolder::isCurrentVisible()
{
return OutputPanePlaceHolderPrivate::m_current && OutputPanePlaceHolderPrivate::m_current->isVisible();

View File

@@ -39,12 +39,11 @@ namespace Core {
class IMode;
namespace Internal { class OutputPaneManager; }
struct OutputPanePlaceHolderPrivate;
class OutputPanePlaceHolderPrivate;
class CORE_EXPORT OutputPanePlaceHolder : public QWidget
{
Q_OBJECT
friend class Core::Internal::OutputPaneManager; // needs to set m_visible and thus access m_current
public:
explicit OutputPanePlaceHolder(IMode *mode, QSplitter *parent = 0);
@@ -53,15 +52,18 @@ public:
static OutputPanePlaceHolder *getCurrent();
static bool isCurrentVisible();
void unmaximize();
bool isMaximized() const;
void setDefaultHeight(int height);
void setMaximized(bool maximize);
void ensureSizeHintAsMinimum();
int nonMaximizedSize() const;
protected:
void resizeEvent(QResizeEvent *event);
void showEvent(QShowEvent *);
private:
void setHeight(int height);
void currentModeChanged(IMode *);
bool canMaximizeOrMinimize() const;
void maximizeOrMinimize(bool maximize);
OutputPanePlaceHolderPrivate *d;
};

View File

@@ -103,8 +103,17 @@ void OutputPaneManager::updateStatusButtons(bool visible)
QTC_ASSERT(m_panes.size() == m_buttons.size(), return);
m_buttons.at(idx)->setChecked(visible);
m_panes.at(idx)->visibilityChanged(visible);
OutputPanePlaceHolder *ph = OutputPanePlaceHolder::getCurrent();
m_minMaxAction->setVisible(ph && ph->canMaximizeOrMinimize());
}
void OutputPaneManager::updateMaximizeButton(bool maximized)
{
if (maximized) {
m_instance->m_minMaxAction->setIcon(m_instance->m_minimizeIcon);
m_instance->m_minMaxAction->setText(tr("Minimize Output Pane"));
} else {
m_instance->m_minMaxAction->setIcon(m_instance->m_maximizeIcon);
m_instance->m_minMaxAction->setText(tr("Maximize Output Pane"));
}
}
OutputPaneManager::OutputPaneManager(QWidget *parent) :
@@ -120,8 +129,7 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) :
m_opToolBarWidgets(new QStackedWidget),
m_minimizeIcon(Icons::ARROW_DOWN.icon()),
m_maximizeIcon(Icons::ARROW_UP.icon()),
m_maximised(false),
m_outputPaneHeight(0)
m_outputPaneHeightSetting(0)
{
setWindowTitle(tr("Output"));
@@ -231,7 +239,7 @@ void OutputPaneManager::init()
cmd->setAttribute(Command::CA_UpdateText);
cmd->setAttribute(Command::CA_UpdateIcon);
mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
connect(m_minMaxAction, &QAction::triggered, this, &OutputPaneManager::slotMinMax);
connect(m_minMaxAction, &QAction::triggered, this, &OutputPaneManager::toggleMaximized);
m_minMaxButton->setDefaultAction(cmd->action());
mpanes->addSeparator("Coreplugin.OutputPane.ActionsGroup");
@@ -334,23 +342,24 @@ void OutputPaneManager::shortcutTriggered()
}
}
bool OutputPaneManager::isMaximized()const
int OutputPaneManager::outputPaneHeightSetting()
{
return m_maximised;
return m_instance->m_outputPaneHeightSetting;
}
void OutputPaneManager::slotMinMax()
void OutputPaneManager::setOutputPaneHeightSetting(int value)
{
m_instance->m_outputPaneHeightSetting = value;
}
void OutputPaneManager::toggleMaximized()
{
OutputPanePlaceHolder *ph = OutputPanePlaceHolder::getCurrent();
QTC_ASSERT(ph, return);
if (!ph->isVisible()) // easier than disabling/enabling the action
return;
m_maximised = !m_maximised;
ph->maximizeOrMinimize(m_maximised);
m_minMaxAction->setIcon(m_maximised ? m_minimizeIcon : m_maximizeIcon);
m_minMaxAction->setText(m_maximised ? tr("Minimize Output Pane")
: tr("Maximize Output Pane"));
ph->setMaximized(!ph->isMaximized());
}
void OutputPaneManager::buttonTriggered(int idx)
@@ -380,7 +389,7 @@ void OutputPaneManager::readSettings()
m_buttons.at(i)->setVisible(m_buttonVisibility.value(m_ids.at(i)));
}
m_outputPaneHeight = settings->value(QLatin1String("OutputPanePlaceHolder/Height"), 0).toInt();
m_outputPaneHeightSetting = settings->value(QLatin1String("OutputPanePlaceHolder/Height"), 0).toInt();
}
void OutputPaneManager::slotNext()
@@ -490,7 +499,6 @@ void OutputPaneManager::showPage(int idx, int flags)
ICore::raiseWindow(m_outputWidgetPane);
}
ph->setDefaultHeight(m_outputPaneHeight);
if (flags & IOutputPane::EnsureSizeHint)
ph->ensureSizeHintAsMinimum();
}
@@ -511,13 +519,6 @@ void OutputPaneManager::focusInEvent(QFocusEvent *e)
w->setFocus(e->reason());
}
void OutputPaneManager::resizeEvent(QResizeEvent *e)
{
if (e->size().height() == 0)
return;
m_outputPaneHeight = e->size().height();
}
void OutputPaneManager::setCurrentIndex(int idx)
{
static int lastIndex = -1;
@@ -586,7 +587,11 @@ void OutputPaneManager::saveSettings() const
m_buttonVisibility.value(m_ids.at(i)));
}
settings->endArray();
settings->setValue(QLatin1String("OutputPanePlaceHolder/Height"), m_outputPaneHeight);
int heightSetting = m_outputPaneHeightSetting;
// update if possible
if (OutputPanePlaceHolder *curr = OutputPanePlaceHolder::getCurrent())
heightSetting = curr->nonMaximizedSize();
settings->setValue(QLatin1String("OutputPanePlaceHolder/Height"), heightSetting);
}
void OutputPaneManager::clearPage()

View File

@@ -60,19 +60,20 @@ public:
static OutputPaneManager *instance();
QWidget *buttonsWidget();
void updateStatusButtons(bool visible);
static void updateMaximizeButton(bool maximized);
bool isMaximized()const;
static int outputPaneHeightSetting();
static void setOutputPaneHeightSetting(int value);
public slots:
void slotHide();
void slotNext();
void slotPrev();
void shortcutTriggered();
void slotMinMax();
void toggleMaximized();
protected:
void focusInEvent(QFocusEvent *e);
void resizeEvent(QResizeEvent *e);
private:
// the only class that is allowed to create and destroy
@@ -126,8 +127,8 @@ private:
QWidget *m_buttonsWidget;
QIcon m_minimizeIcon;
QIcon m_maximizeIcon;
bool m_maximised;
int m_outputPaneHeight;
bool m_maximized;
int m_outputPaneHeightSetting;
};
class BadgeLabel