00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "panel.h"
00022
00023 #include <limits>
00024
00025 #include <QApplication>
00026 #include <QGraphicsLinearLayout>
00027 #include <QPainter>
00028 #include <QBitmap>
00029 #include <QDesktopWidget>
00030 #include <QGridLayout>
00031 #include <QLabel>
00032 #include <QComboBox>
00033 #include <QAction>
00034 #include <QGraphicsLayout>
00035
00036
00037 #include <KDebug>
00038 #include <KIcon>
00039 #include <KDialog>
00040 #include <KIntNumInput>
00041 #include <KMessageBox>
00042
00043 #include <Plasma/Corona>
00044 #include <Plasma/FrameSvg>
00045 #include <Plasma/Theme>
00046 #include <Plasma/View>
00047
00048 using namespace Plasma;
00049
00050 static const int CONTROL_BAR_HEIGHT = 22;
00051
00052 Panel::Panel(QObject *parent, const QVariantList &args)
00053 : Containment(parent, args),
00054 m_configureAction(0)
00055 {
00056 m_background = new Plasma::FrameSvg(this);
00057 m_background->setImagePath("widgets/panel-background");
00058 m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
00059 connect(m_background, SIGNAL(repaintNeeded()), this, SLOT(backgroundChanged()));
00060 setZValue(150);
00061 setContainmentType(Containment::PanelContainment);
00062
00063 QSize size = QSize(args.count() ? args[0].toInt() : 1024, 22);
00064 kDebug() << "**********" << size;
00065 resize(size);
00066 setMinimumSize(size);
00067 setMaximumSize(size);
00068 setDrawWallpaper(false);
00069
00070 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeUpdated()));
00071 connect(this, SIGNAL(appletAdded(Plasma::Applet*,QPointF)),
00072 this, SLOT(layoutApplet(Plasma::Applet*,QPointF)));
00073 connect(this, SIGNAL(appletRemoved(Plasma::Applet*)),
00074 this, SLOT(appletRemoved(Plasma::Applet*)));
00075 }
00076
00077 Panel::~Panel()
00078 {
00079 }
00080
00081 void Panel::init()
00082 {
00083 Containment::init();
00084 }
00085
00086 QList<QAction*> Panel::contextualActions()
00087 {
00088 if (!m_configureAction) {
00089 m_configureAction = new QAction(i18n("Panel Settings"), this);
00090 m_configureAction->setIcon(KIcon("configure"));
00091 connect(m_configureAction, SIGNAL(triggered()), this, SIGNAL(toolBoxToggled()));
00092 }
00093
00094 QList<QAction*> actions;
00095 actions << action("add widgets") << m_configureAction;
00096 return actions;
00097 }
00098
00099 void Panel::backgroundChanged()
00100 {
00101 constraintsEvent(Plasma::LocationConstraint);
00102 }
00103
00104 void Panel::layoutApplet(Plasma::Applet* applet, const QPointF &pos)
00105 {
00106
00107 QGraphicsLinearLayout *lay = dynamic_cast<QGraphicsLinearLayout*>(layout());
00108
00109 if (!lay) {
00110 return;
00111 }
00112
00113 Plasma::FormFactor f = formFactor();
00114 int insertIndex = -1;
00115
00116
00117 if (f == Plasma::Horizontal) {
00118 resize(size().width() + applet->preferredWidth(), size().height());
00119 } else {
00120 resize(size().width(), size().height() + applet->preferredHeight());
00121 }
00122 layout()->setMaximumSize(size());
00123
00124
00125 if (pos != QPoint(-1, -1)) {
00126 for (int i = 0; i < lay->count(); ++i) {
00127 QRectF siblingGeometry = lay->itemAt(i)->geometry();
00128 if (f == Plasma::Horizontal) {
00129 qreal middle = (siblingGeometry.left() + siblingGeometry.right()) / 2.0;
00130 if (pos.x() < middle) {
00131 insertIndex = i;
00132 break;
00133 } else if (pos.x() <= siblingGeometry.right()) {
00134 insertIndex = i + 1;
00135 break;
00136 }
00137 } else {
00138 qreal middle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0;
00139 if (pos.y() < middle) {
00140 insertIndex = i;
00141 break;
00142 } else if (pos.y() <= siblingGeometry.bottom()) {
00143 insertIndex = i + 1;
00144 break;
00145 }
00146 }
00147 }
00148 }
00149
00150 if (insertIndex == -1) {
00151 lay->addItem(applet);
00152 } else {
00153 lay->insertItem(insertIndex, applet);
00154 }
00155
00156 connect(applet, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updateSize()));
00157 }
00158
00159 void Panel::appletRemoved(Plasma::Applet* applet)
00160 {
00161
00162 if (formFactor() == Plasma::Horizontal) {
00163 resize(size().width() - applet->size().width(), size().height());
00164 } else {
00165 resize(size().width(), size().height() - applet->size().height());
00166 }
00167 layout()->setMaximumSize(size());
00168 }
00169
00170 void Panel::updateSize()
00171 {
00172 Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(sender());
00173
00174 if (applet) {
00175 if (formFactor() == Plasma::Horizontal) {
00176 const int delta = applet->preferredWidth() - applet->size().width();
00177
00178
00179 if (delta != 0) {
00180 setPreferredWidth(preferredWidth() + delta);
00181 }
00182 } else if (formFactor() == Plasma::Vertical) {
00183 const int delta = applet->preferredHeight() - applet->size().height();
00184 if (delta != 0) {
00185 setPreferredHeight(preferredHeight() + delta);
00186 }
00187 }
00188
00189 resize(preferredSize());
00190 }
00191 }
00192
00193 void Panel::updateBorders()
00194 {
00195 FrameSvg::EnabledBorders enabledBorders = FrameSvg::AllBorders;
00196
00197 kDebug() << "!!!!!!!!!!!!!!!! location be:" << location();
00198 switch (location()) {
00199 case BottomEdge:
00200 enabledBorders = FrameSvg::TopBorder;
00201 break;
00202 case TopEdge:
00203 enabledBorders = FrameSvg::BottomBorder;
00204 break;
00205 case LeftEdge:
00206 enabledBorders = FrameSvg::RightBorder;
00207 break;
00208 case RightEdge:
00209 enabledBorders = FrameSvg::LeftBorder;
00210 break;
00211 default:
00212 break;
00213 }
00214
00215 qreal topHeight = 0;
00216 qreal bottomHeight = 0;
00217 qreal leftWidth = 0;
00218 qreal rightWidth = 0;
00219
00220
00221 m_background->setEnabledBorders(enabledBorders);
00222 m_background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
00223
00224
00225 if (formFactor() == Vertical) {
00226
00227 if (immutability() == Mutable) {
00228 bottomHeight += 20;
00229 }
00230
00231 } else {
00232
00233 if (immutability() == Mutable) {
00234 if (QApplication::layoutDirection() == Qt::RightToLeft) {
00235 leftWidth += 20;
00236 } else {
00237 rightWidth += 20;
00238 }
00239 }
00240 }
00241
00242
00243
00244 if (layout()) {
00245 layout()->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
00246 layout()->invalidate();
00247 }
00248
00249 update();
00250 }
00251
00252 void Panel::constraintsEvent(Plasma::Constraints constraints)
00253 {
00254 kDebug() << "constraints updated with" << constraints << "!!!!!!";
00255
00256 if (constraints & Plasma::FormFactorConstraint) {
00257 Plasma::FormFactor form = formFactor();
00258 Qt::Orientation layoutDirection = form == Plasma::Vertical ? Qt::Vertical : Qt::Horizontal;
00259
00260
00261 if (layout()) {
00262 QGraphicsLayout *lay = layout();
00263 QGraphicsLinearLayout * linearLay = dynamic_cast<QGraphicsLinearLayout *>(lay);
00264 if (linearLay) {
00265 linearLay->setOrientation(layoutDirection);
00266 }
00267 } else {
00268 QGraphicsLinearLayout *lay = new QGraphicsLinearLayout(this);
00269 lay->setOrientation(layoutDirection);
00270 lay->setContentsMargins(0, 0, 0, 0);
00271 lay->setSpacing(4);
00272 lay->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
00273 setLayout(lay);
00274 updateBorders();
00275
00276 foreach (Applet *applet, applets()) {
00277 lay->addItem(applet);
00278 }
00279 }
00280 }
00281
00282
00283 if (constraints & Plasma::LocationConstraint || constraints & Plasma::SizeConstraint) {
00284 QSize size = geometry().size().toSize();
00285 QRectF screenRect = screen() >= 0 ? QApplication::desktop()->screenGeometry(screen()) : geometry();
00286
00287 if ((formFactor() == Horizontal && size.width() >= screenRect.width()) ||
00288 (formFactor() == Vertical && size.height() >= screenRect.height())) {
00289 m_background->setElementPrefix(location());
00290 } else {
00291 m_background->setElementPrefix(QString());
00292 }
00293
00294 m_background->resizeFrame(size);
00295 updateBorders();
00296 }
00297
00298
00299
00300
00301 if (layout() && (constraints & Plasma::SizeConstraint)) {
00302 layout()->setMaximumSize(size());
00303 }
00304
00305 if (constraints & Plasma::LocationConstraint) {
00306 setFormFactorFromLocation(location());
00307 }
00308
00309 if (constraints & Plasma::ImmutableConstraint) {
00310 bool unlocked = immutability() == Plasma::Mutable;
00311
00312 if (m_configureAction) {
00313 m_configureAction->setEnabled(unlocked);
00314 m_configureAction->setVisible(unlocked);
00315 }
00316
00317 updateBorders();
00318 }
00319 }
00320
00321 void Panel::saveState(KConfigGroup &config) const
00322 {
00323 config.writeEntry("minimumSize", minimumSize());
00324 config.writeEntry("maximumSize", maximumSize());
00325 }
00326
00327 void Panel::themeUpdated()
00328 {
00329
00330
00331
00332 qreal oldLeftWidth;
00333 qreal newLeftWidth;
00334 qreal oldTopHeight;
00335 qreal newTopHeight;
00336 qreal oldRightWidth;
00337 qreal newRightWidth;
00338 qreal oldBottomHeight;
00339 qreal newBottomHeight;
00340
00341 layout()->getContentsMargins(&oldLeftWidth, &oldTopHeight, &oldRightWidth, &oldBottomHeight);
00342 m_background->getMargins(newLeftWidth, newTopHeight, newRightWidth, newBottomHeight);
00343
00344 QSize newSize(size().width()-(oldLeftWidth - newLeftWidth)-(oldRightWidth - newRightWidth),
00345 size().height()-(oldTopHeight - newTopHeight)-(oldBottomHeight - newBottomHeight));
00346
00347 resize(newSize);
00348
00349 if (formFactor() == Plasma::Vertical) {
00350 setMaximumWidth(newSize.width());
00351 setMinimumWidth(newSize.width());
00352 } else {
00353 setMaximumHeight(newSize.height());
00354 setMinimumHeight(newSize.height());
00355 }
00356
00357 updateBorders();
00358 }
00359
00360 void Panel::paintInterface(QPainter *painter,
00361 const QStyleOptionGraphicsItem *option,
00362 const QRect& contentsRect)
00363 {
00364 Q_UNUSED(contentsRect)
00365
00366
00367
00368 painter->save();
00369 painter->resetTransform();
00370
00371 const Containment::StyleOption *containmentOpt = qstyleoption_cast<const Containment::StyleOption *>(option);
00372
00373 QRect viewGeom;
00374 if (containmentOpt) {
00375 viewGeom = containmentOpt->view->geometry();
00376 }
00377
00378
00379 painter->setCompositionMode(QPainter::CompositionMode_Source);
00380 painter->setRenderHint(QPainter::Antialiasing);
00381
00382 m_background->paintFrame(painter, option->exposedRect, option->exposedRect);
00383
00384 if (containmentOpt && containmentOpt->view) {
00385 containmentOpt->view->setMask(m_background->mask());
00386 }
00387
00388
00389 painter->restore();
00390 }
00391
00392 void Panel::setFormFactorFromLocation(Plasma::Location loc) {
00393 switch (loc) {
00394 case BottomEdge:
00395 case TopEdge:
00396
00397 setFormFactor(Plasma::Horizontal);
00398 break;
00399 case RightEdge:
00400 case LeftEdge:
00401
00402 setFormFactor(Plasma::Vertical);
00403 break;
00404 case Floating:
00405
00406 kDebug() << "Floating is unimplemented.";
00407 break;
00408 default:
00409 kDebug() << "invalid location!!";
00410 }
00411 }
00412
00413 K_EXPORT_PLASMA_APPLET(panel, Panel)
00414
00415 #include "panel.moc"
00416