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