2
* Copyright 2007 by Alex Merry <alex.merry@kdemail.net>
3
* Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
4
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Library General Public License version 2,
8
* or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details
15
* You should have received a copy of the GNU Library General Public
16
* License along with this program; if not, write to the
17
* Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
#include "dummytoolbox.h"
23
#include "../common/linearappletoverlay.h"
27
#include <QApplication>
28
#include <QGraphicsLinearLayout>
30
#include <QDesktopWidget>
32
#include <QGraphicsLayout>
39
#include <Plasma/Corona>
40
#include <Plasma/FrameSvg>
41
#include <Plasma/Theme>
42
#include <Plasma/View>
44
using namespace Plasma;
46
Panel::Panel(QObject *parent, const QVariantList &args)
47
: Containment(parent, args),
51
m_background = new Plasma::FrameSvg(this);
52
m_background->setImagePath("widgets/panel-background");
53
m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
54
connect(m_background, SIGNAL(repaintNeeded()), this, SLOT(backgroundChanged()));
56
setContainmentType(Containment::PanelContainment);
58
QSize size = QSize(args.count() ? args[0].toInt() : 1024, 22);
59
kDebug() << "**********" << size;
63
setDrawWallpaper(false);
65
DummyToolBox *toolBox = new DummyToolBox(this);
68
connect(this, SIGNAL(appletRemoved(Plasma::Applet*)),
69
this, SLOT(appletRemoved(Plasma::Applet*)));
70
connect(this, SIGNAL(toolBoxVisibilityChanged(bool)),
71
this, SLOT(updateConfigurationMode(bool)));
82
Plasma::Corona *c = corona();
83
connect(c, SIGNAL(containmentAdded(Plasma::Containment *)),
84
this, SLOT(containmentAdded(Plasma::Containment *)));
86
KAction *lockAction = new KAction(this);
87
addAction("lock panel", lockAction);
88
lockAction->setText(i18n("Lock Panel"));
89
lockAction->setIcon(KIcon("object-locked"));
90
QObject::connect(lockAction, SIGNAL(triggered(bool)), this, SLOT(toggleImmutability()));
91
lockAction->setShortcut(KShortcut("alt+d, l"));
92
lockAction->setShortcutContext(Qt::ApplicationShortcut);
95
void Panel::toggleImmutability()
97
if (immutability() == Plasma::UserImmutable) {
98
setImmutability(Plasma::Mutable);
99
} else if (immutability() == Plasma::Mutable) {
100
setImmutability(Plasma::UserImmutable);
104
void Panel::containmentAdded(Plasma::Containment *containment)
106
connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)),
107
this, SLOT(updateConfigurationMode(bool)));
110
void Panel::backgroundChanged()
112
constraintsEvent(Plasma::LocationConstraint);
115
void Panel::layoutApplet(Plasma::Applet* applet, const QPointF &pos)
117
// this gets called whenever an applet is added, and we add it to our m_layoutout
123
Plasma::FormFactor f = formFactor();
124
int insertIndex = -1;
126
//if pos is (-1,-1) insert at the end of the panel
127
if (pos != QPoint(-1, -1)) {
128
for (int i = 0; i < m_layout->count(); ++i) {
129
QRectF siblingGeometry = m_layout->itemAt(i)->geometry();
130
if (f == Plasma::Horizontal) {
131
qreal middle = (siblingGeometry.left() + siblingGeometry.right()) / 2.0;
132
if (pos.x() < middle) {
135
} else if (pos.x() <= siblingGeometry.right()) {
139
} else { // Plasma::Vertical
140
qreal middle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0;
141
if (pos.y() < middle) {
144
} else if (pos.y() <= siblingGeometry.bottom()) {
152
if (insertIndex == -1) {
153
m_layout->addItem(applet);
155
m_layout->insertItem(insertIndex, applet);
158
connect(applet, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updateSize()));
161
void Panel::appletRemoved(Plasma::Applet* applet)
163
//shrink the panel if possible
164
if (formFactor() == Plasma::Horizontal) {
165
resize(size().width() - applet->size().width(), size().height());
167
resize(size().width(), size().height() - applet->size().height());
169
layout()->setMaximumSize(size());
172
void Panel::updateSize()
174
Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(sender());
177
if (formFactor() == Plasma::Horizontal) {
178
const int delta = applet->preferredWidth() - applet->size().width();
179
//setting the preferred width when delta = 0 and preferredWidth() < minimumWidth()
180
// leads to the same thing as setPreferredWidth(minimumWidth())
182
setPreferredWidth(preferredWidth() + delta);
184
} else if (formFactor() == Plasma::Vertical) {
185
const int delta = applet->preferredHeight() - applet->size().height();
187
setPreferredHeight(preferredHeight() + delta);
191
resize(preferredSize());
195
void Panel::updateBorders()
197
FrameSvg::EnabledBorders enabledBorders = FrameSvg::AllBorders;
199
kDebug() << "!!!!!!!!!!!!!!!! location be:" << location();
200
switch (location()) {
202
enabledBorders = FrameSvg::TopBorder;
205
enabledBorders = FrameSvg::BottomBorder;
208
enabledBorders = FrameSvg::RightBorder;
211
enabledBorders = FrameSvg::LeftBorder;
218
qreal bottomHeight = 0;
220
qreal rightWidth = 0;
222
//activate borders and fetch sizes again
223
m_background->setEnabledBorders(enabledBorders);
224
m_background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
226
//FIXME: this will be probably just killed not kept in this zombie state :)
228
//calculation of extra margins has to be done after getMargins
229
if (formFactor() == Vertical) {
230
//hardcoded extra margin for the toolbox right now
231
if (immutability() == Mutable) {
234
//Default to horizontal for now
236
//hardcoded extra margin for the toolbox for now
237
if (immutability() == Mutable) {
238
if (QApplication::layoutDirection() == Qt::RightToLeft) {
247
switch (location()) {
249
rightWidth = qMin(rightWidth, qMax(qreal(1), size().width() - KIconLoader::SizeMedium));
252
leftWidth = qMin(leftWidth, qMax(qreal(1), size().width() - KIconLoader::SizeMedium));
255
bottomHeight = qMin(bottomHeight, qMax(qreal(1), size().height() - KIconLoader::SizeMedium));
258
topHeight = qMin(topHeight, qMax(qreal(1), size().height() - KIconLoader::SizeMedium));
264
//invalidate the layout and set again
266
layout()->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
267
layout()->invalidate();
273
void Panel::constraintsEvent(Plasma::Constraints constraints)
275
kDebug() << "constraints updated with" << constraints << "!!!!!!";
277
if (constraints & Plasma::FormFactorConstraint) {
278
Plasma::FormFactor form = formFactor();
279
Qt::Orientation layoutDirection = form == Plasma::Vertical ? Qt::Vertical : Qt::Horizontal;
281
// create our layout!
283
QGraphicsLayout *lay = layout();
284
QGraphicsLinearLayout * linearLay = dynamic_cast<QGraphicsLinearLayout *>(lay);
286
linearLay->setOrientation(layoutDirection);
289
m_layout = new QGraphicsLinearLayout(this);
290
m_layout->setOrientation(layoutDirection);
291
m_layout->setContentsMargins(0, 0, 0, 0);
292
m_layout->setSpacing(4);
293
m_layout->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
297
foreach (Applet *applet, applets()) {
298
m_layout->addItem(applet);
303
//we need to know if the width or height is 100%
304
if (constraints & Plasma::LocationConstraint || constraints & Plasma::SizeConstraint) {
305
QSize size = geometry().size().toSize();
306
QRectF screenRect = screen() >= 0 ? QApplication::desktop()->screenGeometry(screen()) : geometry();
308
if (formFactor() == Horizontal ||
309
formFactor() == Vertical) {
310
m_background->setElementPrefix(location());
312
m_background->setElementPrefix(QString());
315
m_background->resizeFrame(size);
319
if (constraints & Plasma::SizeConstraint && m_appletOverlay) {
320
m_appletOverlay->resize(size());
323
//FIXME: this seems the only way to correctly resize the layout the first time when the
324
// saved panel size is less than the default is to setting a maximum size.
325
// this shouldn't happen. maybe even a qgraphicslayout bug?
326
if (layout() && (constraints & Plasma::SizeConstraint)) {
327
layout()->setMaximumSize(size());
330
if (constraints & Plasma::LocationConstraint) {
331
setFormFactorFromLocation(location());
334
if (constraints & Plasma::ImmutableConstraint) {
337
QAction *a = action("lock panel");
339
switch (immutability()) {
340
case Plasma::SystemImmutable:
341
a->setEnabled(false);
342
a->setVisible(false);
345
case Plasma::UserImmutable:
346
a->setText(i18n("Unlock Panel"));
347
a->setIcon(KIcon("object-unlocked"));
352
case Plasma::Mutable:
353
a->setText(i18n("Lock Panel"));
354
a->setIcon(KIcon("object-locked"));
362
if (constraints & Plasma::StartupCompletedConstraint) {
363
connect(this, SIGNAL(appletAdded(Plasma::Applet*,QPointF)),
364
this, SLOT(layoutApplet(Plasma::Applet*,QPointF)));
365
delete action("remove");
369
QList<QAction *> Panel::contextualActions()
371
QList<QAction *> actions;
373
QAction *a = action("lock panel");
381
void Panel::updateConfigurationMode(bool config)
383
if (config && !m_appletOverlay && immutability() == Plasma::Mutable) {
384
m_appletOverlay = new LinearAppletOverlay(this, m_layout);
385
m_appletOverlay->resize(size());
386
connect (m_appletOverlay, SIGNAL(dropRequested(QGraphicsSceneDragDropEvent *)),
387
this, SLOT(overlayRequestedDrop(QGraphicsSceneDragDropEvent *)));
388
} else if (!config) {
389
delete m_appletOverlay;
394
void Panel::overlayRequestedDrop(QGraphicsSceneDragDropEvent *event)
399
//TODO: fold it into saveContents even if it's not strictly contents related?
400
void Panel::saveState(KConfigGroup &config) const
402
config.writeEntry("minimumSize", minimumSize());
403
config.writeEntry("maximumSize", maximumSize());
406
void Panel::paintInterface(QPainter *painter,
407
const QStyleOptionGraphicsItem *option,
408
const QRect& contentsRect)
410
Q_UNUSED(contentsRect)
412
//FIXME: this background drawing is bad and ugly =)
413
// draw the background untransformed (saves lots of per-pixel-math)
415
painter->resetTransform();
417
const Containment::StyleOption *containmentOpt = qstyleoption_cast<const Containment::StyleOption *>(option);
420
if (containmentOpt) {
421
viewGeom = containmentOpt->view->geometry();
424
painter->fillRect(option->exposedRect, Qt::transparent);
425
m_background->paintFrame(painter, option->exposedRect, option->exposedRect);
428
// restore transformation and composition mode
432
void Panel::setFormFactorFromLocation(Plasma::Location loc) {
436
//kDebug() << "setting horizontal form factor";
437
setFormFactor(Plasma::Horizontal);
441
//kDebug() << "setting vertical form factor";
442
setFormFactor(Plasma::Vertical);
445
//TODO: implement a form factor for floating panels
446
kDebug() << "Floating is unimplemented.";
449
kDebug() << "invalid location!!";
453
void Panel::restore(KConfigGroup &group)
455
Containment::restore(group);
457
KConfigGroup appletsConfig(&group, "Applets");
459
QMap<int, Applet *> oderedApplets;
460
QList<Applet *> unoderedApplets;
462
foreach (Applet *applet, applets()) {
463
KConfigGroup appletConfig(&appletsConfig, QString::number(applet->id()));
464
KConfigGroup layoutConfig(&appletConfig, "LayoutInformation");
466
int order = layoutConfig.readEntry("Order", -1);
469
oderedApplets[order] = applet;
470
//if LayoutInformation is not available use the usual way, as a bonus makes it retrocompatible with oler configs
472
unoderedApplets.append(applet);
475
connect(applet, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updateSize()));
478
foreach (Applet *applet, oderedApplets) {
479
m_layout->addItem(applet);
482
foreach (Applet *applet, unoderedApplets) {
483
layoutApplet(applet, applet->pos());
489
void Panel::saveContents(KConfigGroup &group) const
491
Containment::saveContents(group);
497
KConfigGroup appletsConfig(&group, "Applets");
498
for (int order = 0; order < m_layout->count(); ++order) {
499
const Applet *applet = dynamic_cast<Applet *>(m_layout->itemAt(order));
501
KConfigGroup appletConfig(&appletsConfig, QString::number(applet->id()));
502
KConfigGroup layoutConfig(&appletConfig, "LayoutInformation");
504
layoutConfig.writeEntry("Order", order);
509
K_EXPORT_PLASMA_APPLET(netpanel, Panel)