outputpane.cpp 21.9 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30 31
#include "outputpane.h"
#include "coreconstants.h"
32
#include "icore.h"
con's avatar
con committed
33 34 35 36
#include "ioutputpane.h"
#include "mainwindow.h"
#include "modemanager.h"

37
#include <coreplugin/actionmanager/actionmanager.h>
38
#include <coreplugin/actionmanager/actioncontainer.h>
con's avatar
con committed
39
#include <coreplugin/editormanager/editormanager.h>
con's avatar
con committed
40
#include <coreplugin/findplaceholder.h>
41
#include <coreplugin/editormanager/ieditor.h>
con's avatar
con committed
42

43 44
#include <extensionsystem/pluginmanager.h>

con's avatar
con committed
45
#include <utils/styledbar.h>
46
#include <utils/qtcassert.h>
con's avatar
con committed
47

48 49
#include <QtCore/QDebug>

con's avatar
con committed
50 51 52 53 54
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QComboBox>
#include <QtGui/QFocusEvent>
#include <QtGui/QHBoxLayout>
55
#include <QtGui/QSplitter>
con's avatar
con committed
56 57 58 59 60 61 62 63 64
#include <QtGui/QPainter>
#include <QtGui/QToolButton>
#include <QtGui/QStackedWidget>

using namespace Core;
using namespace Core::Internal;

OutputPanePlaceHolder *OutputPanePlaceHolder::m_current = 0;

65
OutputPanePlaceHolder::OutputPanePlaceHolder(Core::IMode *mode, QSplitter* parent)
66
   : QWidget(parent), m_mode(mode), m_closeable(true)
con's avatar
con committed
67
{
68
    m_splitter = parent;
con's avatar
con committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    setVisible(false);
    setLayout(new QVBoxLayout);
    QSizePolicy sp;
    sp.setHorizontalPolicy(QSizePolicy::Preferred);
    sp.setVerticalPolicy(QSizePolicy::Preferred);
    sp.setHorizontalStretch(0);
    setSizePolicy(sp);
    layout()->setMargin(0);
    connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode *)),
            this, SLOT(currentModeChanged(Core::IMode *)));
}

OutputPanePlaceHolder::~OutputPanePlaceHolder()
{
    if (m_current == this) {
84 85
        OutputPaneManager::instance()->setParent(0);
        OutputPaneManager::instance()->hide();
con's avatar
con committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    }
}

void OutputPanePlaceHolder::setCloseable(bool b)
{
    m_closeable = b;
}

bool OutputPanePlaceHolder::closeable()
{
    return m_closeable;
}

void OutputPanePlaceHolder::currentModeChanged(Core::IMode *mode)
{
    if (m_current == this) {
        m_current = 0;
103 104 105
        OutputPaneManager::instance()->setParent(0);
        OutputPaneManager::instance()->hide();
        OutputPaneManager::instance()->updateStatusButtons(false);
con's avatar
con committed
106 107 108
    }
    if (m_mode == mode) {
        m_current = this;
109 110 111 112
        layout()->addWidget(OutputPaneManager::instance());
        OutputPaneManager::instance()->show();
        OutputPaneManager::instance()->updateStatusButtons(isVisible());
        OutputPaneManager::instance()->setCloseable(m_closeable);
con's avatar
con committed
113 114 115
    }
}

116 117 118 119 120 121 122 123 124 125 126
void OutputPanePlaceHolder::maximizeOrMinimize(bool maximize)
{
    if (!m_splitter)
        return;
    int idx = m_splitter->indexOf(this);
    if (idx < 0)
        return;

    QList<int> sizes = m_splitter->sizes();

    if (maximize) {
Tobias Hunger's avatar
Tobias Hunger committed
127
        int sum = 0;
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        foreach(int s, sizes)
            sum += s;
        for (int i = 0; i < sizes.count(); ++i) {
            sizes[i] = 32;
        }
        sizes[idx] = sum - (sizes.count()-1) * 32;
    } else {
        int target = sizeHint().height();
        int space = sizes[idx] - target;
        if (space > 0) {
            for (int i = 0; i < sizes.count(); ++i) {
                sizes[i] += space / (sizes.count()-1);
            }
            sizes[idx] = target;
        }
    }

    m_splitter->setSizes(sizes);

}

149 150 151 152 153 154 155 156 157 158
bool OutputPanePlaceHolder::isMaximized() const
{
    return OutputPaneManager::instance()->isMaximized();
}

void OutputPanePlaceHolder::unmaximize()
{
    if (OutputPaneManager::instance()->isMaximized())
        OutputPaneManager::instance()->slotMinMax();
}
159

con's avatar
con committed
160
////
161
// OutputPaneManager
con's avatar
con committed
162 163
////

164
static OutputPaneManager *m_instance = 0;
con's avatar
con committed
165

166 167 168 169 170 171 172 173 174 175 176 177
void OutputPaneManager::create()
{
   m_instance = new OutputPaneManager; 
}

void OutputPaneManager::destroy()
{
    delete m_instance;
    m_instance = 0;
}

OutputPaneManager *OutputPaneManager::instance()
con's avatar
con committed
178 179 180 181
{
    return m_instance;
}

182
void OutputPaneManager::updateStatusButtons(bool visible)
con's avatar
con committed
183 184 185 186
{
    int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
    if (m_buttons.value(idx))
        m_buttons.value(idx)->setChecked(visible);
187 188
    m_minMaxButton->setVisible(OutputPanePlaceHolder::m_current
                               && OutputPanePlaceHolder::m_current->canMaximizeOrMinimize());
con's avatar
con committed
189 190
}

191
OutputPaneManager::OutputPaneManager(QWidget *parent) :
con's avatar
con committed
192 193 194 195
    QWidget(parent),
    m_widgetComboBox(new QComboBox),
    m_clearButton(new QToolButton),
    m_closeButton(new QToolButton),
196 197
    m_minMaxAction(0),
    m_minMaxButton(new QToolButton),
198 199
    m_nextAction(0),
    m_prevAction(0),
con's avatar
con committed
200 201 202 203 204 205 206 207 208 209 210
    m_lastIndex(-1),
    m_outputWidgetPane(new QStackedWidget),
    m_opToolBarWidgets(new QStackedWidget)
{
    setWindowTitle(tr("Output"));
    connect(m_widgetComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changePage()));

    m_clearButton->setIcon(QIcon(Constants::ICON_CLEAN_PANE));
    m_clearButton->setToolTip(tr("Clear"));
    connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearPage()));

211 212 213 214 215 216 217 218 219 220
    m_nextAction = new QAction(this);
    m_nextAction->setIcon(QIcon(":/core/images/next.png"));
    m_nextAction->setText(tr("Next Item"));
    connect(m_nextAction, SIGNAL(triggered()), this, SLOT(slotNext()));

    m_prevAction = new QAction(this);
    m_prevAction->setIcon(QIcon(":/core/images/prev.png"));
    m_prevAction->setText(tr("Previous Item"));
    connect(m_prevAction, SIGNAL(triggered()), this, SLOT(slotPrev()));

221 222 223 224
    m_minMaxAction = new QAction(this);
    m_minMaxAction->setText(tr("Minimize/Maximize Output Pane"));
    m_minMaxButton->setArrowType(Qt::UpArrow);

225
    m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
con's avatar
con committed
226 227 228 229 230
    connect(m_closeButton, SIGNAL(clicked()), this, SLOT(slotHide()));

    QVBoxLayout *mainlayout = new QVBoxLayout;
    mainlayout->setSpacing(0);
    mainlayout->setMargin(0);
231
    m_toolBar = new Utils::StyledBar;
con's avatar
con committed
232 233 234 235 236 237 238 239 240 241
    QHBoxLayout *toolLayout = new QHBoxLayout(m_toolBar);
    toolLayout->setMargin(0);
    toolLayout->setSpacing(0);
    toolLayout->addWidget(m_widgetComboBox);
    toolLayout->addWidget(m_clearButton);
    m_prevToolButton = new QToolButton;
    toolLayout->addWidget(m_prevToolButton);
    m_nextToolButton = new QToolButton;
    toolLayout->addWidget(m_nextToolButton);
    toolLayout->addWidget(m_opToolBarWidgets);
242
    toolLayout->addWidget(m_minMaxButton);
con's avatar
con committed
243
    toolLayout->addWidget(m_closeButton);
244
    mainlayout->addWidget(m_toolBar);
con's avatar
con committed
245
    mainlayout->addWidget(m_outputWidgetPane, 10);
con's avatar
con committed
246
    mainlayout->addWidget(new Core::FindToolBarPlaceHolder(this));
con's avatar
con committed
247 248 249 250 251
    setLayout(mainlayout);

    m_buttonsWidget = new QWidget;
    m_buttonsWidget->setLayout(new QHBoxLayout);
    m_buttonsWidget->layout()->setContentsMargins(5,0,0,0);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
252
#ifdef Q_WS_MAC
con's avatar
con committed
253 254 255 256
    m_buttonsWidget->layout()->setSpacing(16);
#else
    m_buttonsWidget->layout()->setSpacing(4);
#endif
257

con's avatar
con committed
258 259
}

260
OutputPaneManager::~OutputPaneManager()
con's avatar
con committed
261 262 263
{
}

264
QWidget *OutputPaneManager::buttonsWidget()
con's avatar
con committed
265 266 267 268
{
    return m_buttonsWidget;
}

Friedemann Kleint's avatar
Friedemann Kleint committed
269
// Return shortcut as Ctrl+<number>
270
static inline int paneShortCut(int number)
Friedemann Kleint's avatar
Friedemann Kleint committed
271
{
272 273 274 275 276
#ifdef Q_WS_MAC
    int modifier = Qt::CTRL;
#else
    int modifier = Qt::ALT;
#endif
Friedemann Kleint's avatar
Friedemann Kleint committed
277 278 279
    return modifier | (Qt::Key_0 + number);
}

280
void OutputPaneManager::init()
con's avatar
con committed
281
{
hjk's avatar
hjk committed
282
    ActionManager *am = Core::ICore::instance()->actionManager();
283
    ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
284 285
    QList<int> globalcontext;
    globalcontext.append(Core::Constants::C_GLOBAL_ID);
con's avatar
con committed
286 287

    // Window->Output Panes
288
    ActionContainer *mpanes = am->createMenu(Constants::M_WINDOW_PANES);
con's avatar
con committed
289 290
    mwindow->addMenu(mpanes, Constants::G_WINDOW_PANES);
    mpanes->menu()->setTitle(tr("Output &Panes"));
291 292 293 294 295 296 297
    mpanes->appendGroup("Coreplugin.OutputPane.ActionsGroup");
    mpanes->appendGroup("Coreplugin.OutputPane.PanesGroup");

    Core::Command *cmd;

    cmd = am->registerAction(m_prevAction, "Coreplugin.OutputPane.previtem", globalcontext);
    cmd->setDefaultKeySequence(QKeySequence("Shift+F6"));
con's avatar
con committed
298
    m_prevToolButton->setDefaultAction(cmd->action());
299 300 301
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");

    cmd = am->registerAction(m_nextAction, "Coreplugin.OutputPane.nextitem", globalcontext);
con's avatar
con committed
302
    m_nextToolButton->setDefaultAction(cmd->action());
303 304 305
    cmd->setDefaultKeySequence(QKeySequence("F6"));
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");

306 307 308 309 310 311
    cmd = am->registerAction(m_minMaxAction, "Coreplugin.OutputPane.minmax", globalcontext);
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+9"));
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
    m_minMaxButton->setDefaultAction(cmd->action());
    connect(m_minMaxAction, SIGNAL(triggered()), this, SLOT(slotMinMax()));

312 313 314 315
    QAction *sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("Coreplugin.OutputPane.Sep"), globalcontext);
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
con's avatar
con committed
316

317 318
    QList<IOutputPane*> panes = ExtensionSystem::PluginManager::instance()
        ->getObjects<IOutputPane>();
con's avatar
con committed
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
    QMultiMap<int, IOutputPane*> sorted;
    foreach (IOutputPane* outPane, panes)
        sorted.insertMulti(outPane->priorityInStatusBar(), outPane);

    QMultiMap<int, IOutputPane*>::const_iterator it, begin;
    begin = sorted.constBegin();
    it = sorted.constEnd();
    int shortcutNumber = 1;
    do {
        --it;
        IOutputPane* outPane = it.value();
        const int idx = m_outputWidgetPane->addWidget(outPane->outputWidget(this));

        m_pageMap.insert(idx, outPane);
        connect(outPane, SIGNAL(showPage(bool)), this, SLOT(showPage(bool)));
        connect(outPane, SIGNAL(hidePage()), this, SLOT(slotHide()));
        connect(outPane, SIGNAL(togglePage(bool)), this, SLOT(togglePage(bool)));
336
        connect(outPane, SIGNAL(navigateStateUpdate()), this, SLOT(updateNavigateState()));
con's avatar
con committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352

        QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets);
        QHBoxLayout *toolButtonsLayout = new QHBoxLayout;
        toolButtonsLayout->setMargin(0);
        toolButtonsLayout->setSpacing(0);
        foreach (QWidget *toolButton, outPane->toolBarWidgets())
            toolButtonsLayout->addWidget(toolButton);
        toolButtonsLayout->addStretch(5);
        toolButtonsContainer->setLayout(toolButtonsLayout);

        m_opToolBarWidgets->addWidget(toolButtonsContainer);

        QString actionId = QString("QtCreator.Pane.%1").arg(outPane->name().simplified());
        actionId.remove(QLatin1Char(' '));
        QAction *action = new QAction(outPane->name(), this);

353
        Command *cmd = am->registerAction(action, actionId, QList<int>() << Constants::C_GLOBAL_ID);
354

355
        mpanes->addAction(cmd, "Coreplugin.OutputPane.PanesGroup");
con's avatar
con committed
356 357
        m_actions.insert(cmd->action(), idx);

358
        if (outPane->priorityInStatusBar() != -1) {
359 360 361
            cmd->setDefaultKeySequence(QKeySequence(paneShortCut(shortcutNumber)));
            QPushButton *button = new OutputPaneToggleButton(shortcutNumber, outPane->name(),
                                                             cmd->action());
con's avatar
con committed
362 363 364 365 366 367 368 369 370 371
            ++shortcutNumber;
            m_buttonsWidget->layout()->addWidget(button);
            connect(button, SIGNAL(clicked()), this, SLOT(buttonTriggered()));
            m_buttons.insert(idx, button);
        }

        // Now add the entry to the combobox, since the first item we add sets the currentIndex, thus we need to be set up for that
        m_widgetComboBox->addItem(outPane->name(), idx);

        connect(cmd->action(), SIGNAL(triggered()), this, SLOT(shortcutTriggered()));
hjk's avatar
hjk committed
372
    } while (it != begin);
con's avatar
con committed
373 374 375 376

    changePage();
}

377
void OutputPaneManager::shortcutTriggered()
con's avatar
con committed
378 379 380 381 382 383 384 385 386 387
{
    QAction *action = qobject_cast<QAction*>(sender());
    if (action && m_actions.contains(action)) {
        int idx = m_actions.value(action);
        Core::IOutputPane *outputPane = m_pageMap.value(idx);
        // Now check the special case, the output window is already visible,
        // we are already on that page
        // but the outputpane doesn't have focus
        // then just give it focus
        // else do the same as clicking on the button does
hjk's avatar
hjk committed
388
        if (OutputPanePlaceHolder::m_current
con's avatar
con committed
389 390 391 392 393 394 395 396 397 398 399 400
           && OutputPanePlaceHolder::m_current->isVisible()
           && m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
            if (!outputPane->hasFocus() && outputPane->canFocus())
                outputPane->setFocus();
            else
                slotHide();
        } else {
            outputPane->popup(true);
        }
    }
}

401 402 403 404
bool OutputPaneManager::isMaximized()const
{
    return m_minMaxButton->arrowType() == Qt::DownArrow;
}
405 406 407 408 409 410 411 412 413 414 415 416

void OutputPaneManager::slotMinMax()
{
    QTC_ASSERT(OutputPanePlaceHolder::m_current, return);

    if (!OutputPanePlaceHolder::m_current->isVisible()) // easier than disabling/enabling the action
        return;
    bool maximize = m_minMaxButton->arrowType() == Qt::UpArrow;
    OutputPanePlaceHolder::m_current->maximizeOrMinimize(maximize);
    m_minMaxButton->setArrowType(maximize ? Qt::DownArrow : Qt::UpArrow);
}

417
void OutputPaneManager::buttonTriggered()
con's avatar
con committed
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
{
    QPushButton *button = qobject_cast<QPushButton *>(sender());
    QMap<int, QPushButton *>::const_iterator it, end;
    end = m_buttons.constEnd();
    for (it = m_buttons.begin(); it != end; ++it) {
        if (it.value() == button)
            break;
    }
    int idx = it.key();

    if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx &&
        OutputPanePlaceHolder::m_current &&
        OutputPanePlaceHolder::m_current->isVisible() &&
        OutputPanePlaceHolder::m_current->closeable()) {
        // we should toggle and the page is already visible and we are actually closeable
        slotHide();
    } else {
        showPage(idx, true);
    }
}

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
void OutputPaneManager::slotNext()
{
    int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
    ensurePageVisible(idx);
    IOutputPane *out = m_pageMap.value(idx);
    if (out->canNext())
        out->goToNext();
}

void OutputPaneManager::slotPrev()
{
    int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
    ensurePageVisible(idx);
    IOutputPane *out = m_pageMap.value(idx);
    if (out->canPrevious())
        out->goToPrev();
}

457
void OutputPaneManager::slotHide()
con's avatar
con committed
458 459 460 461 462 463
{
    if (OutputPanePlaceHolder::m_current) {
        OutputPanePlaceHolder::m_current->setVisible(false);
        int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
        if (m_buttons.value(idx))
            m_buttons.value(idx)->setChecked(false);
464 465
        if (IEditor *editor = Core::EditorManager::instance()->currentEditor())
            editor->widget()->setFocus();
con's avatar
con committed
466 467 468
    }
}

469
int OutputPaneManager::findIndexForPage(IOutputPane *out)
con's avatar
con committed
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
{
    if (!out)
        return -1;

    int stackIndex = -1;
    QMap<int, IOutputPane*>::const_iterator it = m_pageMap.constBegin();
    while (it != m_pageMap.constEnd()) {
        if (it.value() == out) {
            stackIndex = it.key();
            break;
        }
        ++it;
    }
    if (stackIndex > -1)
        return m_widgetComboBox->findData(stackIndex);
    else
        return -1;
}

489
void OutputPaneManager::ensurePageVisible(int idx)
con's avatar
con committed
490 491 492 493 494 495 496 497
{
    if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() != idx) {
        m_widgetComboBox->setCurrentIndex(m_widgetComboBox->findData(idx));
    } else {
        changePage();
    }
}

498 499 500 501 502 503 504 505 506 507
void OutputPaneManager::updateNavigateState()
{
    IOutputPane* pane = qobject_cast<IOutputPane*>(sender());
    int idx = findIndexForPage(pane);
    if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
        m_prevAction->setEnabled(pane->canNavigate() && pane->canPrevious());
        m_nextAction->setEnabled(pane->canNavigate() && pane->canNext());
    }
}

508
// Slot connected to showPage signal of each page
509
void OutputPaneManager::showPage(bool focus)
con's avatar
con committed
510 511 512 513 514
{
    int idx = findIndexForPage(qobject_cast<IOutputPane*>(sender()));
    showPage(idx, focus);
}

515
void OutputPaneManager::showPage(int idx, bool focus)
con's avatar
con committed
516 517 518 519 520 521
{
    IOutputPane *out = m_pageMap.value(idx);
    if (idx > -1) {
        if (!OutputPanePlaceHolder::m_current) {
            // In this mode we don't have a placeholder
            // switch to the output mode and switch the page
con's avatar
con committed
522 523 524 525
            ICore::instance()->modeManager()->activateMode(Constants::MODE_EDIT);
        }
        if (OutputPanePlaceHolder::m_current) {
            // make the page visible
con's avatar
con committed
526 527 528 529 530 531 532 533
            OutputPanePlaceHolder::m_current->setVisible(true);
            ensurePageVisible(idx);
            if (focus && out->canFocus())
                out->setFocus();
        }
    }
}

534
void OutputPaneManager::togglePage(bool focus)
con's avatar
con committed
535 536
{
    int idx = findIndexForPage(qobject_cast<IOutputPane*>(sender()));
537
    if (OutputPanePlaceHolder::m_current
con's avatar
con committed
538 539 540 541 542 543 544 545
       && OutputPanePlaceHolder::m_current->isVisible()
       && m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
         slotHide();
    } else {
         showPage(idx, focus);
    }
}

546
void OutputPaneManager::setCloseable(bool b)
con's avatar
con committed
547
{
con's avatar
con committed
548
    m_closeButton->setVisible(b);
con's avatar
con committed
549 550
}

551
bool OutputPaneManager::closeable()
con's avatar
con committed
552 553 554 555
{
    return m_closeButton->isVisibleTo(m_closeButton->parentWidget());
}

556
void OutputPaneManager::focusInEvent(QFocusEvent *e)
con's avatar
con committed
557 558 559 560 561
{
    if (m_outputWidgetPane->currentWidget())
        m_outputWidgetPane->currentWidget()->setFocus(e->reason());
}

562
void OutputPaneManager::changePage()
con's avatar
con committed
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
{
    if (m_outputWidgetPane->count() <= 0)
        return;

    if (!m_pageMap.contains(m_lastIndex)) {
        int idx = m_outputWidgetPane->currentIndex();
        m_pageMap.value(idx)->visibilityChanged(true);
        if (m_buttons.value(idx)) {
            if (OutputPanePlaceHolder::m_current)
                m_buttons.value(idx)->setChecked(OutputPanePlaceHolder::m_current->isVisible());
            else
                m_buttons.value(idx)->setChecked(false);
        }
        m_lastIndex = idx;
        return;
    }

    int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
581 582 583 584 585 586 587 588 589 590
    if (m_lastIndex != idx) {
        m_outputWidgetPane->setCurrentIndex(idx);
        m_opToolBarWidgets->setCurrentIndex(idx);
        m_pageMap.value(idx)->visibilityChanged(true);
        m_pageMap.value(m_lastIndex)->visibilityChanged(false);

        bool canNavigate = m_pageMap.value(idx)->canNavigate();
        m_prevAction->setEnabled(canNavigate && m_pageMap.value(idx)->canPrevious());
        m_nextAction->setEnabled(canNavigate && m_pageMap.value(idx)->canNext());
    }
591

con's avatar
con committed
592 593 594 595 596 597 598 599 600 601 602 603 604
    if (m_buttons.value(m_lastIndex))
        m_buttons.value(m_lastIndex)->setChecked(false);

    if (m_buttons.value(idx)) {
        if (OutputPanePlaceHolder::m_current)
            m_buttons.value(idx)->setChecked(OutputPanePlaceHolder::m_current->isVisible());
        else
            m_buttons.value(idx)->setChecked(false);
    }

    m_lastIndex = idx;
}

605
void OutputPaneManager::clearPage()
con's avatar
con committed
606 607 608 609 610 611
{
    if (m_pageMap.contains(m_outputWidgetPane->currentIndex()))
        m_pageMap.value(m_outputWidgetPane->currentIndex())->clearContents();
}


612 613
OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text,
                                               QAction *action, QWidget *parent)
con's avatar
con committed
614 615 616
    : QPushButton(parent)
    , m_number(QString::number(number))
    , m_text(text)
617
    , m_action(action)
con's avatar
con committed
618 619 620 621
{
    setFocusPolicy(Qt::NoFocus);
    setCheckable(true);
    setStyleSheet(
622
            "QPushButton { border-image: url(:/core/images/panel_button.png) 2 2 2 19;"
con's avatar
con committed
623
                         " border-width: 2px 2px 2px 19px; padding-left: -17; padding-right: 4 } "
624
            "QPushButton:checked { border-image: url(:/core/images/panel_button_checked.png) 2 2 2 19 } "
625
            "QPushButton::menu-indicator { width:0; height:0 }"
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
626
#ifndef Q_WS_MAC // Mac UIs usually don't hover
627 628 629
            "QPushButton:checked:hover { border-image: url(:/core/images/panel_button_checked_hover.png) 2 2 2 19 } "
            "QPushButton:pressed:hover { border-image: url(:/core/images/panel_button_pressed.png) 2 2 2 19 } "
            "QPushButton:hover { border-image: url(:/core/images/panel_button_hover.png) 2 2 2 19 } "
con's avatar
con committed
630 631
#endif
            );
632 633 634 635 636 637 638 639
    if (m_action)
        connect(m_action, SIGNAL(changed()), this, SLOT(updateToolTip()));
}

void OutputPaneToggleButton::updateToolTip()
{
    Q_ASSERT(m_action);
    setToolTip(m_action->toolTip());
con's avatar
con committed
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
}

QSize OutputPaneToggleButton::sizeHint() const
{
    ensurePolished();

    QSize s = fontMetrics().size(Qt::TextSingleLine, m_text);

    // Expand to account for border image set by stylesheet above
    s.rwidth() += 19 + 5 + 2;
    s.rheight() += 2 + 2;

    return s.expandedTo(QApplication::globalStrut());
}

void OutputPaneToggleButton::paintEvent(QPaintEvent *event)
{
    // For drawing the style sheet stuff
    QPushButton::paintEvent(event);

    const QFontMetrics fm = fontMetrics();
661
    const int baseLine = (height() - fm.height() + 1) / 2 + fm.ascent();
con's avatar
con committed
662 663 664 665 666 667 668 669 670 671 672
    const int numberWidth = fm.width(m_number);

    QPainter p(this);
    p.setFont(font());
    p.setPen(Qt::white);
    p.drawText((20 - numberWidth) / 2, baseLine, m_number);
    if (!isChecked())
        p.setPen(Qt::black);
    int leftPart = 22;
    p.drawText(leftPart, baseLine, fm.elidedText(m_text, Qt::ElideRight, width() - leftPart - 1));
}