00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "panelview.h"
00021
00022 #include <QApplication>
00023 #include <QDesktopWidget>
00024 #include <QGraphicsLinearLayout>
00025 #include <QTimer>
00026
00027 #include <KWindowSystem>
00028 #include <KDebug>
00029
00030 #include <plasma/containment.h>
00031 #include <plasma/corona.h>
00032 #include <plasma/plasma.h>
00033 #include <plasma/svg.h>
00034 #include <plasma/theme.h>
00035
00036 #include "panelappletoverlay.h"
00037 #include "panelcontroller.h"
00038 #include "plasmaapp.h"
00039
00040 PanelView::PanelView(Plasma::Containment *panel, int id, QWidget *parent)
00041 : Plasma::View(panel, id, parent),
00042 m_panelController(0),
00043 m_lastHorizontal(true),
00044 m_editting(false)
00045 {
00046 Q_ASSERT(qobject_cast<Plasma::Corona*>(panel->scene()));
00047
00048 KConfigGroup viewConfig = config();
00049
00050 m_offset = viewConfig.readEntry("Offset", 0);
00051 m_alignment = alignmentFilter((Qt::Alignment)viewConfig.readEntry("Alignment", (int)Qt::AlignLeft));
00052
00053
00054
00055 QRect screenRect = QApplication::desktop()->screenGeometry(containment()->screen());
00056 m_lastHorizontal = isHorizontal();
00057 KConfigGroup sizes = KConfigGroup(&viewConfig, "Sizes");
00058 m_lastSeenSize = sizes.readEntry("lastsize", m_lastHorizontal ? screenRect.width() : screenRect.height());
00059 pinchContainment(screenRect);
00060 m_lastMin = containment()->minimumSize();
00061 m_lastMax = containment()->maximumSize();
00062
00063
00064 if (panel) {
00065 connect(panel, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showAppletBrowser()));
00066 connect(panel, SIGNAL(destroyed(QObject*)), this, SLOT(deleteLater()));
00067 connect(panel, SIGNAL(toolBoxToggled()), this, SLOT(togglePanelController()));
00068 }
00069 connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updatePanelGeometry()));
00070
00071 kDebug() << "Panel geometry is" << panel->geometry();
00072
00073
00074 setFrameStyle(QFrame::NoFrame);
00075
00076
00077
00078 setInteractive(true);
00079 setAcceptDrops(true);
00080 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00081 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00082
00083
00084 KWindowSystem::setType(winId(), NET::Dock);
00085 KWindowSystem::setState(winId(), NET::Sticky);
00086 KWindowSystem::setOnAllDesktops(winId(), true);
00087
00088 updateStruts();
00089 }
00090
00091 PanelView::~PanelView()
00092 {
00093 }
00094
00095 void PanelView::setLocation(Plasma::Location location)
00096 {
00097 Plasma::Containment *c = containment();
00098 QSizeF s = c->size();
00099 QSizeF min = c->minimumSize();
00100 QSizeF max = c->maximumSize();
00101 qreal panelWidth = s.width();
00102 qreal panelHeight = s.height();
00103
00104 Plasma::FormFactor formFactor = c->formFactor();
00105 bool wasHorizontal = formFactor == Plasma::Horizontal;
00106 bool wasFullSize = m_lastSeenSize == (wasHorizontal ? s.width() : s.height());
00107
00108 if (location == Plasma::TopEdge || location == Plasma::BottomEdge) {
00109 if (!wasHorizontal) {
00110
00111 panelHeight = s.width();
00112 if (wasFullSize) {
00113 QRect screenGeom = QApplication::desktop()->screenGeometry(c->screen());
00114 panelWidth = screenGeom.width();
00115 } else {
00116 panelWidth = s.height();
00117 }
00118 min = QSizeF(panelWidth, min.width());
00119 max = QSizeF(panelWidth, max.width());
00120 }
00121
00122 formFactor = Plasma::Horizontal;
00123 } else {
00124 if (wasHorizontal) {
00125
00126
00127 if (wasFullSize) {
00128 QRect screenGeom = QApplication::desktop()->screenGeometry(c->screen());
00129 panelHeight = screenGeom.height();
00130 } else {
00131 panelHeight = s.width();
00132 }
00133
00134 panelWidth = s.height();
00135 min = QSizeF(min.height(), panelHeight);
00136 max = QSizeF(max.height(), panelHeight);
00137 }
00138
00139 formFactor = Plasma::Vertical;
00140 }
00141
00142
00143 disconnect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updatePanelGeometry()));
00144 c->setFormFactor(formFactor);
00145 c->setLocation(location);
00146
00147 c->setMinimumSize(0, 0);
00148 c->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
00149 c->resize(panelWidth, panelHeight);
00150 c->setMinimumSize(min);
00151 c->setMaximumSize(max);
00152
00153 QRect screenRect = QApplication::desktop()->screenGeometry(c->screen());
00154 pinchContainment(screenRect);
00155
00156 connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updatePanelGeometry()));
00157 }
00158
00159 Plasma::Location PanelView::location() const
00160 {
00161 return containment()->location();
00162 }
00163
00164 Plasma::Corona *PanelView::corona() const
00165 {
00166 return qobject_cast<Plasma::Corona*>(scene());
00167 }
00168
00169 void PanelView::updatePanelGeometry()
00170 {
00171 Plasma::Containment *c = containment();
00172
00173
00174 QSize size = c->size().toSize();
00175 QRect geom(QPoint(0,0), size);
00176 int screen = c->screen();
00177
00178 if (screen < 0) {
00179
00180 screen = 0;
00181 }
00182
00183 QRect screenGeom = QApplication::desktop()->screenGeometry(screen);
00184
00185 if (m_alignment != Qt::AlignCenter) {
00186 m_offset = qMax(m_offset, 0);
00187 }
00188
00189
00190 switch (location()) {
00191 case Plasma::TopEdge:
00192 case Plasma::BottomEdge:
00193 if (m_alignment != Qt::AlignCenter) {
00194 m_offset = qMax(m_offset, screenGeom.left());
00195 }
00196
00197 if (geom.width() > screenGeom.width()) {
00198 geom.setWidth(screenGeom.width());
00199 }
00200
00201
00202 if (m_alignment == Qt::AlignLeft) {
00203 if (m_offset + screenGeom.left() + geom.width() > screenGeom.right() + 1) {
00204 m_offset = screenGeom.right() - geom.width();
00205 }
00206 } else if (m_alignment == Qt::AlignRight) {
00207 if (screenGeom.right() - m_offset - geom.width() < -1 ) {
00208 m_offset = screenGeom.right() - geom.width();
00209 }
00210 } else if (m_alignment == Qt::AlignCenter) {
00211 if (screenGeom.center().x() + m_offset + geom.width()/2 > screenGeom.right() + 1) {
00212 m_offset = screenGeom.right() - geom.width()/2 - screenGeom.center().x();
00213 } else if (screenGeom.center().x() + m_offset - geom.width()/2 < -1) {
00214 m_offset = screenGeom.center().x() - geom.width()/2;
00215 }
00216 }
00217 break;
00218
00219 case Plasma::LeftEdge:
00220 case Plasma::RightEdge:
00221 if (m_alignment != Qt::AlignCenter) {
00222 m_offset = qMax(m_offset, screenGeom.top());
00223 }
00224
00225 if (geom.height() > screenGeom.height()) {
00226 geom.setHeight(screenGeom.height());
00227 }
00228
00229
00230
00231 if (m_alignment == Qt::AlignLeft) {
00232 if (m_offset + screenGeom.top() + geom.height() > screenGeom.bottom() + 1) {
00233 m_offset = screenGeom.height() - geom.height();
00234 }
00235 } else if (m_alignment == Qt::AlignRight) {
00236 if (screenGeom.bottom() - m_offset - geom.height() < -1) {
00237 m_offset = screenGeom.bottom() - geom.height();
00238 }
00239 } else if (m_alignment == Qt::AlignCenter) {
00240 if (screenGeom.center().y() + m_offset + geom.height()/2 > screenGeom.bottom() + 1) {
00241 m_offset = screenGeom.bottom() - geom.height()/2 - screenGeom.center().y();
00242 } else if (screenGeom.center().y() + m_offset - geom.width()/2 < -1) {
00243 m_offset = screenGeom.center().y() - geom.width()/2;
00244 }
00245 }
00246 break;
00247
00248
00249 default:
00250 break;
00251 }
00252
00253
00254 switch (location()) {
00255 case Plasma::TopEdge:
00256 if (m_alignment == Qt::AlignLeft) {
00257 geom.moveTopLeft(QPoint(m_offset, screenGeom.top()));
00258 } else if (m_alignment == Qt::AlignRight) {
00259 geom.moveTopRight(QPoint(screenGeom.right() - m_offset, screenGeom.top()));
00260 } else if (m_alignment == Qt::AlignCenter) {
00261 geom.moveCenter(QPoint(screenGeom.center().x() + m_offset, screenGeom.top() + geom.height()/2 - 1));
00262 }
00263
00264
00265
00266 break;
00267
00268 case Plasma::LeftEdge:
00269 if (m_alignment == Qt::AlignLeft) {
00270 geom.moveTopLeft(QPoint(screenGeom.left(), m_offset));
00271 } else if (m_alignment == Qt::AlignRight) {
00272 geom.moveBottomLeft(QPoint(screenGeom.left(), screenGeom.bottom() - m_offset));
00273 } else if (m_alignment == Qt::AlignCenter) {
00274 geom.moveCenter(QPoint(screenGeom.left()+size.width()/2 - 1, screenGeom.center().y() + m_offset -1));
00275 }
00276
00277
00278
00279 break;
00280
00281 case Plasma::RightEdge:
00282 if (m_alignment == Qt::AlignLeft) {
00283 geom.moveTopLeft(QPoint(screenGeom.right() - size.width() + 1, m_offset));
00284 } else if (m_alignment == Qt::AlignRight) {
00285 geom.moveBottomLeft(QPoint(screenGeom.right() - size.width() + 1, screenGeom.bottom() - m_offset));
00286 } else if (m_alignment == Qt::AlignCenter) {
00287 geom.moveCenter(QPoint(screenGeom.right() - size.width()/2, screenGeom.center().y() + m_offset));
00288 }
00289
00290
00291
00292 break;
00293
00294 case Plasma::BottomEdge:
00295 default:
00296 if (m_alignment == Qt::AlignLeft) {
00297 geom.moveTopLeft(QPoint(m_offset, screenGeom.bottom() - size.height() + 1));
00298 } else if (m_alignment == Qt::AlignRight) {
00299 geom.moveTopRight(QPoint(screenGeom.right() - m_offset, screenGeom.bottom() - size.height() + 1));
00300 } else if (m_alignment == Qt::AlignCenter) {
00301 geom.moveCenter(QPoint(screenGeom.center().x() + m_offset, screenGeom.bottom() - size.height()/2));
00302 }
00303
00304
00305
00306 break;
00307 }
00308
00309 kDebug() << (QObject*)this << "thinks its panel is at " << geom;
00310 if (geom == geometry()) {
00311
00312
00313 updateStruts();
00314 } else {
00315 setGeometry(geom);
00316 }
00317
00318 m_lastMin = c->minimumSize();
00319 m_lastMax = c->maximumSize();
00320
00321
00322 if (m_panelController) {
00323 m_panelController->setLocation(c->location());
00324
00325 if (m_panelController->isVisible()) {
00326 m_panelController->resize(m_panelController->sizeHint());
00327 m_panelController->move(m_panelController->positionForPanelGeometry(geometry()));
00328 }
00329
00330 foreach (PanelAppletOverlay *o, m_moveOverlays) {
00331 o->syncOrientation();
00332 }
00333 }
00334 }
00335
00336 bool PanelView::isHorizontal() const
00337 {
00338 return location() == Plasma::BottomEdge ||
00339 location() == Plasma::TopEdge;
00340 }
00341
00342 void PanelView::pinchContainment(const QRect &screenGeom)
00343 {
00344
00345 bool horizontal = isHorizontal();
00346
00347 int sw = screenGeom.width();
00348 int sh = screenGeom.height();
00349
00350 Plasma::Containment *c = containment();
00351 QSizeF min = c->minimumSize();
00352 QSizeF max = c->maximumSize();
00353
00354 KConfigGroup sizes = config();
00355 sizes = KConfigGroup(&sizes, "Sizes");
00356
00357 if (m_lastHorizontal != horizontal ||
00358 m_lastSeenSize != (horizontal ? sw : sh)) {
00359
00360 KConfigGroup lastSize(&sizes, (m_lastHorizontal ? "Horizontal" : "Vertical") +
00361 QString::number(m_lastSeenSize));
00362 lastSize.writeEntry("size", size());
00363 lastSize.writeEntry("offset", m_offset);
00364 lastSize.writeEntry("min", m_lastMin);
00365 lastSize.writeEntry("max", m_lastMax);
00366
00367 QString last = (horizontal ? "Horizontal" : "Vertical") +
00368 QString::number(horizontal ? sw : sh);
00369 if (sizes.hasGroup(last)) {
00370 KConfigGroup thisSize(&sizes, last);
00371
00372
00373
00374
00375
00376
00377
00378
00379 c->setMinimumSize(0, 0);
00380 c->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
00381 c->resize(thisSize.readEntry("size", c->geometry().size()));
00382 c->setMinimumSize(thisSize.readEntry("min", min));
00383 c->setMaximumSize(thisSize.readEntry("max", max));
00384 m_offset = thisSize.readEntry("offset", 0);
00385 } else if (m_lastSeenSize < (horizontal ? sw : sh) &&
00386 c->geometry().width() == m_lastSeenSize) {
00387
00388 if (horizontal) {
00389 c->setMaximumSize(sw, max.height());
00390 c->resize(sw, c->geometry().height());
00391 } else {
00392 c->setMaximumSize(max.width(), sh);
00393 c->resize(c->geometry().width(), sh);
00394 }
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 if (horizontal) {
00406
00407 if (m_offset + min.width() > sw) {
00408
00409 if (min.width() > sw) {
00410 c->setMinimumSize(sw, min.height());
00411 } else {
00412 m_offset = sw - min.width();
00413 }
00414 }
00415
00416 if (m_offset + max.width() > sw) {
00417
00418 if (max.width() > sw) {
00419 c->setMaximumSize(sw, max.height());
00420 } else {
00421 m_offset = sw - max.width();
00422 }
00423 }
00424 } else {
00425 if (m_offset + min.height() > sh) {
00426
00427 if (min.height() > sh) {
00428 c->setMinimumSize(min.width(), sh);
00429 } else {
00430 m_offset = sh - min.height();
00431 }
00432 }
00433
00434 if (m_offset + max.height() > sh) {
00435
00436 if (max.height() > sh) {
00437 c->setMaximumSize(max.width(), sh);
00438 } else {
00439 m_offset = sh - max.height();
00440 }
00441 }
00442 }
00443
00444 if (m_lastHorizontal != horizontal ||
00445 m_lastSeenSize != (horizontal ? sw : sh)) {
00446 m_lastHorizontal = horizontal;
00447 m_lastSeenSize = (horizontal ? sw : sh);
00448 sizes.writeEntry("lastsize", m_lastSeenSize);
00449 }
00450
00451 updatePanelGeometry();
00452
00453 if (m_panelController) {
00454 m_panelController->setContainment(c);
00455
00456 m_panelController->setOffset(m_offset);
00457 }
00458 }
00459
00460 void PanelView::setOffset(int newOffset)
00461 {
00462 m_offset = newOffset;
00463 KConfigGroup viewConfig = config();
00464 viewConfig.writeEntry("Offset", m_offset);
00465
00466 containment()->update();
00467
00468
00469
00470 updatePanelGeometry();
00471 }
00472
00473 int PanelView::offset() const
00474 {
00475 return m_offset;
00476 }
00477
00478 void PanelView::setAlignment(Qt::Alignment align)
00479 {
00480 m_alignment = alignmentFilter(align);
00481 KConfigGroup viewConfig = config();
00482 viewConfig.writeEntry("Alignment", (int)m_alignment);
00483 }
00484
00485 Qt::Alignment PanelView::alignment() const
00486 {
00487 return m_alignment;
00488 }
00489
00490 void PanelView::showAppletBrowser()
00491 {
00492 PlasmaApp::self()->showAppletBrowser(containment());
00493 }
00494
00495 void PanelView::togglePanelController()
00496 {
00497
00498 m_editting = false;
00499 if (containment()->immutability() != Plasma::Mutable) {
00500 delete m_panelController;
00501 m_panelController = 0;
00502 return;
00503 }
00504
00505 if (!m_panelController) {
00506 m_panelController = new PanelController(this);
00507 m_panelController->setContainment(containment());
00508 m_panelController->setLocation(containment()->location());
00509 m_panelController->setAlignment(m_alignment);
00510 m_panelController->setOffset(m_offset);
00511
00512 connect(m_panelController, SIGNAL(destroyed(QObject*)), this, SLOT(edittingComplete()));
00513 connect(m_panelController, SIGNAL(offsetChanged(int)), this, SLOT(setOffset(int)));
00514 connect(m_panelController, SIGNAL(alignmentChanged(Qt::Alignment)), this, SLOT(setAlignment(Qt::Alignment)));
00515 connect(m_panelController, SIGNAL(locationChanged(Plasma::Location)), this, SLOT(setLocation(Plasma::Location)));
00516
00517 if (dynamic_cast<QGraphicsLinearLayout*>(containment()->layout())) {
00518
00519 QColor overlayColor(Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
00520 QBrush overlayBrush(overlayColor);
00521 QPalette p(palette());
00522 p.setBrush(QPalette::Window, overlayBrush);
00523 foreach (Plasma::Applet *applet, containment()->applets()) {
00524 PanelAppletOverlay *moveOverlay = new PanelAppletOverlay(applet, this);
00525 moveOverlay->setPalette(p);
00526 moveOverlay->show();
00527 moveOverlay->raise();
00528 m_moveOverlays << moveOverlay;
00529
00530 }
00531
00532 setTabOrder(0, m_panelController);
00533 QWidget *prior = m_panelController;
00534 foreach (PanelAppletOverlay *w, m_moveOverlays) {
00535 setTabOrder(prior, w);
00536 prior = w;
00537 }
00538 }
00539 }
00540
00541 if (!m_panelController->isVisible()) {
00542 m_editting = true;
00543 m_panelController->resize(m_panelController->sizeHint());
00544 m_panelController->move(m_panelController->positionForPanelGeometry(geometry()));
00545 m_panelController->show();
00546 } else {
00547 m_panelController->close();
00548 }
00549 }
00550
00551 void PanelView::edittingComplete()
00552 {
00553
00554 m_panelController = 0;
00555 m_editting = false;
00556 qDeleteAll(m_moveOverlays);
00557 m_moveOverlays.clear();
00558 containment()->closeToolBox();
00559 }
00560
00561 Qt::Alignment PanelView::alignmentFilter(Qt::Alignment align) const
00562 {
00563
00564 if (align == Qt::AlignLeft || align == Qt::AlignRight || align == Qt::AlignCenter) {
00565 return align;
00566 } else {
00567 return Qt::AlignLeft;
00568 }
00569 }
00570
00571 void PanelView::updateStruts()
00572 {
00573 NETExtendedStrut strut;
00574
00575 QRect thisScreen = QApplication::desktop()->screenGeometry(containment()->screen());
00576 QRect wholeScreen = QApplication::desktop()->geometry();
00577
00578
00579 int leftOffset = wholeScreen.x() - thisScreen.x();
00580 int rightOffset = wholeScreen.right() - thisScreen.right();
00581 int bottomOffset = wholeScreen.bottom() - thisScreen.bottom();
00582 int topOffset = wholeScreen.top() - thisScreen.top();
00583 kDebug() << "screen l/r/b/t offsets are:" << leftOffset << rightOffset << bottomOffset << topOffset;
00584
00585 switch (location())
00586 {
00587 case Plasma::TopEdge:
00588 strut.top_width = height() + topOffset;
00589 strut.top_start = x();
00590 strut.top_end = x() + width() - 1;
00591 break;
00592
00593 case Plasma::BottomEdge:
00594 strut.bottom_width = height() + bottomOffset;
00595 strut.bottom_start = x();
00596 strut.bottom_end = x() + width() - 1;
00597
00598
00599 break;
00600
00601 case Plasma::RightEdge:
00602 strut.right_width = width() + rightOffset;
00603 strut.right_start = y();
00604 strut.right_end = y() + height() - 1;
00605 break;
00606
00607 case Plasma::LeftEdge:
00608 strut.left_width = width() + leftOffset;
00609 strut.left_start = y();
00610 strut.left_end = y() + height() - 1;
00611 break;
00612
00613 default:
00614
00615 break;
00616 }
00617
00618 KWindowSystem::setExtendedStrut(winId(), strut.left_width,
00619 strut.left_start,
00620 strut.left_end,
00621 strut.right_width,
00622 strut.right_start,
00623 strut.right_end,
00624 strut.top_width,
00625 strut.top_start,
00626 strut.top_end,
00627 strut.bottom_width,
00628 strut.bottom_start,
00629 strut.bottom_end);
00630 }
00631
00632 void PanelView::moveEvent(QMoveEvent *event)
00633 {
00634 QWidget::moveEvent(event);
00635 updateStruts();
00636 }
00637
00638 void PanelView::resizeEvent(QResizeEvent *event)
00639 {
00640 QWidget::resizeEvent(event);
00641 updateStruts();
00642 }
00643
00644 #include "panelview.moc"
00645