~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/widgets/UIPopupBox.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: UIPopupBox.cpp 30904 2010-07-19 09:43:24Z vboxsync $ */
 
2
/** @file
 
3
 *
 
4
 * VBox frontends: Qt GUI ("VirtualBox"):
 
5
 * UIPopupBox class implementation
 
6
 */
 
7
 
 
8
/*
 
9
 * Copyright (C) 2010 Oracle Corporation
 
10
 *
 
11
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
12
 * available from http://www.virtualbox.org. This file is free software;
 
13
 * you can redistribute it and/or modify it under the terms of the GNU
 
14
 * General Public License (GPL) as published by the Free Software
 
15
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
16
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
17
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
18
 */
 
19
 
 
20
/* Local includes */
 
21
#include "UIPopupBox.h"
 
22
#ifdef Q_WS_MAC
 
23
# include "UIImageTools.h"
 
24
#endif /* Q_WS_MAC */
 
25
 
 
26
/* Global includes */
 
27
#include <QApplication>
 
28
#include <QLabel>
 
29
#include <QPaintEvent>
 
30
#include <QPainter>
 
31
#include <QVBoxLayout>
 
32
 
 
33
UIPopupBox::UIPopupBox(QWidget *pParent)
 
34
  : QWidget(pParent)
 
35
  , m_fLinkEnabled(false)
 
36
  , m_pContentWidget(0)
 
37
  , m_fOpen(true)
 
38
  , m_pLabelPath(0)
 
39
  , m_aw(9)
 
40
  , m_fHeaderHover(false)
 
41
{
 
42
    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
 
43
    pMainLayout->setContentsMargins(10, 5, 5, 5);
 
44
    QHBoxLayout *pTitleLayout = new QHBoxLayout();
 
45
    m_pTitleIcon = new QLabel(this);
 
46
    m_pTitleLabel = new QLabel(this);
 
47
    connect(m_pTitleLabel, SIGNAL(linkActivated(const QString)),
 
48
            this, SIGNAL(titleClicked(const QString)));
 
49
    pTitleLayout->addWidget(m_pTitleIcon);
 
50
    pTitleLayout->addWidget(m_pTitleLabel, Qt::AlignLeft);
 
51
    pMainLayout->addLayout(pTitleLayout);
 
52
 
 
53
    m_arrowPath.lineTo(m_aw / 2.0, m_aw / 2.0);
 
54
    m_arrowPath.lineTo(m_aw, 0);
 
55
 
 
56
//    setMouseTracking(true);
 
57
    qApp->installEventFilter(this);
 
58
}
 
59
 
 
60
UIPopupBox::~UIPopupBox()
 
61
{
 
62
    if (m_pLabelPath)
 
63
        delete m_pLabelPath;
 
64
}
 
65
 
 
66
void UIPopupBox::setTitle(const QString& strTitle)
 
67
{
 
68
    m_strTitle = strTitle;
 
69
    updateHover(true);
 
70
    recalc();
 
71
}
 
72
 
 
73
QString UIPopupBox::title() const
 
74
{
 
75
    return m_strTitle;
 
76
}
 
77
 
 
78
void UIPopupBox::setTitleIcon(const QIcon& icon)
 
79
{
 
80
    m_icon = icon;
 
81
    updateHover(true);
 
82
    recalc();
 
83
}
 
84
 
 
85
QIcon UIPopupBox::titleIcon() const
 
86
{
 
87
    return m_icon;
 
88
}
 
89
 
 
90
void UIPopupBox::setTitleLink(const QString& strLink)
 
91
{
 
92
    m_strLink = strLink;
 
93
}
 
94
 
 
95
QString UIPopupBox::titleLink() const
 
96
{
 
97
    return m_strLink;
 
98
}
 
99
 
 
100
void UIPopupBox::setTitleLinkEnabled(bool fEnabled)
 
101
{
 
102
    m_fLinkEnabled = fEnabled;
 
103
}
 
104
 
 
105
bool UIPopupBox::isTitleLinkEnabled() const
 
106
{
 
107
    return m_fLinkEnabled;
 
108
}
 
109
 
 
110
void UIPopupBox::setContentWidget(QWidget *pWidget)
 
111
{
 
112
    if (m_pContentWidget)
 
113
    {
 
114
        layout()->removeWidget(m_pContentWidget);
 
115
//        m_pContentWidget->removeEventFilter(this);
 
116
    }
 
117
    m_pContentWidget = pWidget;
 
118
//    m_pContentWidget->installEventFilter(this);
 
119
//    m_pContentWidget->setMouseTracking(true);
 
120
    layout()->addWidget(pWidget);
 
121
    recalc();
 
122
}
 
123
 
 
124
QWidget* UIPopupBox::contentWidget() const
 
125
{
 
126
    return m_pContentWidget;
 
127
}
 
128
 
 
129
void UIPopupBox::setOpen(bool fOpen)
 
130
{
 
131
    m_fOpen = fOpen;
 
132
    if (m_pContentWidget)
 
133
        m_pContentWidget->setVisible(m_fOpen);
 
134
    else
 
135
        update();
 
136
}
 
137
 
 
138
void UIPopupBox::toggleOpen()
 
139
{
 
140
    setOpen(!m_fOpen);
 
141
}
 
142
 
 
143
bool UIPopupBox::isOpen() const
 
144
{
 
145
    return m_fOpen;
 
146
}
 
147
 
 
148
bool UIPopupBox::eventFilter(QObject * /* pWatched */, QEvent *pEvent)
 
149
{
 
150
    QEvent::Type type = pEvent->type();
 
151
    if (   type == QEvent::MouseMove
 
152
        || type == QEvent::Wheel
 
153
        || type == QEvent::Resize
 
154
        || type == QEvent::Enter
 
155
        || type == QEvent::Leave)
 
156
        updateHover();
 
157
    return false;
 
158
}
 
159
 
 
160
void UIPopupBox::resizeEvent(QResizeEvent *pEvent)
 
161
{
 
162
    updateHover();
 
163
    recalc();
 
164
    QWidget::resizeEvent(pEvent);
 
165
}
 
166
 
 
167
void UIPopupBox::mouseDoubleClickEvent(QMouseEvent * /* pEvent */)
 
168
{
 
169
    toggleOpen();
 
170
}
 
171
 
 
172
void UIPopupBox::mouseMoveEvent(QMouseEvent *pEvent)
 
173
{
 
174
    updateHover();
 
175
    QWidget::mouseMoveEvent(pEvent);
 
176
}
 
177
 
 
178
void UIPopupBox::wheelEvent(QWheelEvent *pEvent)
 
179
{
 
180
    updateHover();
 
181
    QWidget::wheelEvent(pEvent);
 
182
}
 
183
 
 
184
void UIPopupBox::enterEvent(QEvent *pEvent)
 
185
{
 
186
    updateHover();
 
187
    QWidget::enterEvent(pEvent);
 
188
}
 
189
 
 
190
void UIPopupBox::leaveEvent(QEvent *pEvent)
 
191
{
 
192
    updateHover();
 
193
    QWidget::leaveEvent(pEvent);
 
194
}
 
195
 
 
196
void UIPopupBox::paintEvent(QPaintEvent *pEvent)
 
197
{
 
198
    QPainter painter(this);
 
199
    painter.setClipRect(pEvent->rect());
 
200
 
 
201
    QPalette pal = palette();
 
202
    painter.setClipPath(*m_pLabelPath);
 
203
    QColor base = pal.color(QPalette::Active, QPalette::Window);
 
204
    QRect rect = QRect(QPoint(0, 0), size()).adjusted(0, 0, -1, -1);
 
205
    /* Base background */
 
206
    painter.fillRect(QRect(QPoint(0, 0), size()), pal.brush(QPalette::Active, QPalette::Base));
 
207
    /* Top header background */
 
208
    QLinearGradient lg(rect.x(), rect.y(), rect.x(), rect.y() + 2 * 5 + m_pTitleLabel->sizeHint().height());
 
209
    lg.setColorAt(0, base.darker(95));
 
210
    lg.setColorAt(1, base.darker(110));
 
211
    int theight = rect.height();
 
212
    if (m_fOpen)
 
213
        theight = 2 * 5 + m_pTitleLabel->sizeHint().height();
 
214
    painter.fillRect(QRect(rect.x(), rect.y(), rect.width(), theight), lg);
 
215
    /* Outer round rectangle line */
 
216
    painter.setClipping(false);
 
217
    painter.strokePath(*m_pLabelPath, base.darker(110));
 
218
    /* Arrow */
 
219
    if (m_fHeaderHover)
 
220
    {
 
221
        painter.setBrush(base.darker(106));
 
222
        painter.setPen(QPen(base.darker(128), 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
 
223
        QSizeF s = m_arrowPath.boundingRect().size();
 
224
        if (m_fOpen)
 
225
        {
 
226
            painter.translate(rect.x() + rect.width() - s.width() - 10, rect.y() + theight / 2 + s.height() / 2);
 
227
            /* Flip */
 
228
            painter.scale(1, -1);
 
229
        }
 
230
        else
 
231
            painter.translate(rect.x() + rect.width() - s.width() - 10, rect.y() + theight / 2 - s.height() / 2 + 1);
 
232
 
 
233
        painter.setRenderHint(QPainter::Antialiasing);
 
234
        painter.drawPath(m_arrowPath);
 
235
    }
 
236
}
 
237
 
 
238
void UIPopupBox::updateHover(bool fForce /* = false */)
 
239
{
 
240
    bool fOld = m_fHeaderHover;
 
241
    QPoint bl = mapFromGlobal(QCursor::pos());
 
242
//    printf("%d %d\n", bl.x(), bl.y());
 
243
    if (   m_pLabelPath
 
244
        && m_pLabelPath->contains(mapFromGlobal(QCursor::pos())))
 
245
//        if (underMouse())
 
246
        m_fHeaderHover = true;
 
247
    else
 
248
        m_fHeaderHover = false;
 
249
 
 
250
    if (   !m_fLinkEnabled
 
251
        || m_strLink.isEmpty())
 
252
    {
 
253
        m_pTitleLabel->setText(QString("<b>%1</b>").arg(m_strTitle));
 
254
    }
 
255
    if (   fForce
 
256
        || fOld != m_fHeaderHover)
 
257
    {
 
258
        QPalette pal = m_pTitleLabel->palette();
 
259
        m_pTitleLabel->setText(QString("<b><a style=\"text-decoration: none; color: %1\" href=\"%2\">%3</a></b>")
 
260
                               .arg(m_fHeaderHover ? pal.color(QPalette::Link).name() : pal.color(QPalette::WindowText).name())
 
261
                               .arg(m_strLink)
 
262
                               .arg(m_strTitle));
 
263
 
 
264
        QPixmap i = m_icon.pixmap(16, 16);
 
265
#ifdef Q_WS_MAC
 
266
        /* todo: fix this */
 
267
//        if (!m_fHeaderHover)
 
268
//            i = QPixmap::fromImage(toGray(i.toImage()));
 
269
#endif /* Q_WS_MAC */
 
270
        m_pTitleIcon->setPixmap(i);
 
271
        update();
 
272
    }
 
273
}
 
274
 
 
275
void UIPopupBox::recalc()
 
276
{
 
277
    if (m_pLabelPath)
 
278
        delete m_pLabelPath;
 
279
    QRect rect = QRect(QPoint(0, 0), size()).adjusted(0, 0, -1, -1);
 
280
    int d = 18; // 22
 
281
    m_pLabelPath = new QPainterPath(QPointF(rect.x() + rect.width() - d, rect.y()));
 
282
    m_pLabelPath->arcTo(QRectF(rect.x(), rect.y(), d, d), 90, 90);
 
283
    m_pLabelPath->arcTo(QRectF(rect.x(), rect.y() + rect.height() - d, d, d), 180, 90);
 
284
    m_pLabelPath->arcTo(QRectF(rect.x() + rect.width() - d, rect.y() + rect.height() - d, d, d), 270, 90);
 
285
    m_pLabelPath->arcTo(QRectF(rect.x() + rect.width() - d, rect.y(), d, d), 0, 90);
 
286
    m_pLabelPath->closeSubpath();
 
287
    update();
 
288
}
 
289