1/*
2 * Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "dialog.h"
21#include "dialogshadows_p.h"
22
23#include <QApplication>
24#include <QDesktopWidget>
25#include <QGraphicsView>
26#include <QGraphicsWidget>
27#include <QGraphicsScene>
28
29#include <KWindowSystem>
30
31#include <Plasma/Applet>
32#include <Plasma/FrameSvg>
33#include <Plasma/WindowEffects>
34
35#ifdef Q_WS_X11
36# include <QX11Info>
37# include <X11/Xlib.h>
38#endif
39
40
41Dialog::Dialog(QWidget *parent)
42 : QWidget(parent, Qt::Popup), m_widget(0)
43{
44 setAttribute(Qt::WA_TranslucentBackground);
45
46#ifdef Q_WS_X11
47 setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu);
48
49 if (KWindowSystem::compositingActive()) {
50 setAttribute(Qt::WA_NoSystemBackground, false);
51 Plasma::WindowEffects::overrideShadow(winId(), true);
52 } else {
53 setAttribute(Qt::WA_NoSystemBackground);
54 }
55#endif
56
57 KWindowSystem::setState(effectiveWinId(), NET::SkipTaskbar | NET::SkipPager);
58
59 QPalette pal = palette();
60 pal.setColor(backgroundRole(), Qt::transparent);
61 setPalette(pal);
62
63 m_background = new Plasma::FrameSvg(this);
64 m_background->setImagePath("dialogs/background");
65
66 m_scene = new QGraphicsScene(this);
67 m_view = new QGraphicsView(m_scene, this);
68 m_view->setFrameShape(QFrame::NoFrame);
69 m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
70 m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
71 m_view->viewport()->setAutoFillBackground(false);
72}
73
74Dialog::~Dialog()
75{
76}
77
78void Dialog::setGraphicsWidget(QGraphicsWidget *widget)
79{
80 m_widget = widget;
81 m_scene->addItem(widget);
82}
83
84void Dialog::show(Plasma::Applet *applet)
85{
86 Plasma::FrameSvg::EnabledBorders borders = Plasma::FrameSvg::AllBorders;
87 m_background->setEnabledBorders(borders);
88
89 int left = m_background->marginSize(Plasma::LeftMargin);
90 int top = m_background->marginSize(Plasma::TopMargin);
91 int right = m_background->marginSize(Plasma::RightMargin);
92 int bottom = m_background->marginSize(Plasma::BottomMargin);
93
94 switch (applet->location())
95 {
96 case Plasma::BottomEdge:
97 borders &= ~Plasma::FrameSvg::BottomBorder;
98 bottom = qMin(bottom, 2);
99 break;
100
101 case Plasma::TopEdge:
102 borders &= ~Plasma::FrameSvg::TopBorder;
103 top = qMin(top, 2);
104 break;
105
106 case Plasma::LeftEdge:
107 borders &= ~Plasma::FrameSvg::LeftBorder;
108 left = qMin(left, 2);
109 break;
110
111 case Plasma::RightEdge:
112 borders &= ~Plasma::FrameSvg::RightBorder;
113 right = qMin(right, 2);
114 break;
115
116 default:
117 break;
118 }
119
120 const QSize margin(left + right, top + bottom);
121 QSize size = m_widget->preferredSize().toSize() + margin;
122 QPoint pos = applet->popupPosition(size);
123 const QRect availableGeometry = QApplication::desktop()->availableGeometry(pos);
124
125 if (pos.y() < 0) {
126 size.rheight() += pos.y();
127 pos.ry() = 0;
128 } else if (applet->location() == Plasma::TopEdge &&
129 pos.y() + size.height() > availableGeometry.bottom()) {
130 size.rheight() -= pos.y() + size.height() - availableGeometry.bottom();
131 }
132
133 if (pos.x() < 0) {
134 size.rwidth() += pos.x();
135 pos.rx() = 0;
136 } else if (applet->location() == Plasma::LeftEdge &&
137 pos.x() + size.width() > availableGeometry.right()) {
138 size.rwidth() -= pos.x() + size.width() - availableGeometry.right();
139 }
140
141 m_background->setEnabledBorders(borders);
142 setContentsMargins(left, top, right, bottom);
143
144 m_widget->resize(size - margin);
145 resize(size);
146 move(pos);
147
148 QWidget::show();
149 DialogShadows::self()->addWindow(this, borders);
150}
151
152void Dialog::resizeEvent(QResizeEvent *event)
153{
154 Q_UNUSED(event)
155
156 m_background->resizeFrame(rect().size());
157 m_view->setGeometry(contentsRect());
158
159 if (KWindowSystem::compositingActive()) {
160 Plasma::WindowEffects::enableBlurBehind(winId(), true, m_background->mask());
161 } else {
162 setMask(m_background->mask());
163 }
164}
165
166void Dialog::paintEvent(QPaintEvent *event)
167{
168 Q_UNUSED(event)
169
170 QPainter p(this);
171 p.setCompositionMode(QPainter::CompositionMode_Source);
172 p.fillRect(rect(), Qt::transparent);
173 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
174 m_background->paintFrame(&p);
175}
176
177void Dialog::mousePressEvent(QMouseEvent *event)
178{
179 if (!rect().contains(event->pos())) {
180 hide();
181 }
182}
183
184