00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "desktopview.h"
00021
00022 #include <QAction>
00023 #include <QDesktopWidget>
00024 #include <QFile>
00025 #include <QWheelEvent>
00026 #include <QCoreApplication>
00027
00028 #include <KAuthorized>
00029 #include <KMenu>
00030 #include <KRun>
00031 #include <KToggleAction>
00032 #include <KWindowSystem>
00033
00034 #include "plasma/applet.h"
00035 #include "plasma/corona.h"
00036 #include "plasma/containment.h"
00037 #include "plasma/svg.h"
00038
00039 #include "dashboardview.h"
00040 #include "plasmaapp.h"
00041
00042 DesktopView::DesktopView(Plasma::Containment *containment, int id, QWidget *parent)
00043 : Plasma::View(containment, id, parent),
00044 m_zoomLevel(Plasma::DesktopZoom),
00045 m_dashboard(0),
00046 m_dashboardFollowsDesktop(true)
00047 {
00048 setFocusPolicy(Qt::NoFocus);
00049
00050 if (containment) {
00051 connectContainment(containment);
00052 containment->enableAction("zoom in", false);
00053 containment->enableAction("add sibling containment", false);
00054 }
00055
00056 QAction *action = new QAction(i18n("Next Activity"), this);
00057 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
00058 action->setShortcut(QKeySequence("ctrl+shift+n"));
00059 connect(action, SIGNAL(triggered()), this, SLOT(nextContainment()));
00060 addAction(action);
00061 action = new QAction(i18n("Previous Activity"), this);
00062 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
00063 action->setShortcut(QKeySequence("ctrl+shift+p"));
00064 connect(action, SIGNAL(triggered()), this, SLOT(previousContainment()));
00065 addAction(action);
00066
00067 const int w = 25;
00068 QPixmap tile(w * 2, w * 2);
00069 tile.fill(palette().base().color());
00070 QPainter pt(&tile);
00071 QColor color = palette().mid().color();
00072 color.setAlphaF(.6);
00073 pt.fillRect(0, 0, w, w, color);
00074 pt.fillRect(w, w, w, w, color);
00075 pt.end();
00076 QBrush b(tile);
00077 setBackgroundBrush(tile);
00078 }
00079
00080 DesktopView::~DesktopView()
00081 {
00082 delete m_dashboard;
00083 }
00084
00085 void DesktopView::connectContainment(Plasma::Containment *containment)
00086 {
00087 if (containment) {
00088 connect(containment, SIGNAL(zoomRequested(Plasma::Containment*,Plasma::ZoomDirection)),
00089 this, SLOT(zoom(Plasma::Containment*,Plasma::ZoomDirection)));
00090 connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showAppletBrowser()));
00091 connect(containment, SIGNAL(addSiblingContainment(Plasma::Containment *)), this, SLOT(addContainment(Plasma::Containment *)));
00092 connect(containment, SIGNAL(focusRequested(Plasma::Containment *)), this, SLOT(setContainment(Plasma::Containment *)));
00093 }
00094 }
00095
00096 void DesktopView::toggleDashboard()
00097 {
00098 if (!m_dashboard) {
00099 if (!containment()) {
00100 return;
00101 }
00102
00103 m_dashboardFollowsDesktop = true;
00104 KConfigGroup cg = config();
00105 Plasma::Containment *dc = containment();
00106 int containmentId = cg.readEntry("DashboardContainment", 0);
00107 if (containmentId > 0) {
00108 foreach (Plasma::Containment *c, containment()->corona()->containments()) {
00109 if (c->id() == containmentId) {
00110 dc = c;
00111 m_dashboardFollowsDesktop = false;
00112 break;
00113 }
00114 }
00115 }
00116 m_dashboard = new DashboardView(dc, 0);
00117 m_dashboard->addActions(actions());
00118 }
00119
00120 m_dashboard->toggleVisibility();
00121 kDebug() << "toggling dashboard for screen" << screen() << m_dashboard->isVisible();
00122 }
00123
00124 void DesktopView::adjustSize()
00125 {
00126
00127 QDesktopWidget *desktop = QApplication::desktop();
00128 QRect geom = desktop->screenGeometry(screen());
00129 setGeometry(geom);
00130 containment()->resize(geom.size());
00131
00132 if (m_dashboard) {
00133 m_dashboard->setGeometry(geom);
00134 }
00135 }
00136
00137 void DesktopView::setIsDesktop(bool isDesktop)
00138 {
00139 if (isDesktop) {
00140 setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
00141
00142 KWindowSystem::setOnAllDesktops(winId(), true);
00143 KWindowSystem::setType(winId(), NET::Desktop);
00144 lower();
00145
00146 adjustSize();
00147 } else {
00148 setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
00149
00150 KWindowSystem::setOnAllDesktops(winId(), false);
00151 KWindowSystem::setType(winId(), NET::Normal);
00152 }
00153 }
00154
00155 bool DesktopView::isDesktop() const
00156 {
00157 return KWindowInfo(winId(), NET::WMWindowType).windowType(NET::Desktop);
00158 }
00159
00160 void DesktopView::setContainment(Plasma::Containment *containment)
00161 {
00162 Plasma::Containment *oldContainment = this->containment();
00163 if (containment == oldContainment) {
00164 return;
00165 }
00166
00167 if (m_zoomLevel == Plasma::DesktopZoom) {
00168
00169
00170 containment->enableAction("zoom in", false);
00171 containment->enableAction("add sibling containment", false);
00172 }
00173
00174 if (m_dashboard && m_dashboardFollowsDesktop) {
00175 m_dashboard->setContainment(containment);
00176 }
00177
00178 if (m_zoomLevel == Plasma::DesktopZoom) {
00179
00180 disconnect(oldContainment, 0, this, 0);
00181 connectContainment(containment);
00182
00183 oldContainment->enableAction("zoom in", true);
00184 oldContainment->enableAction("add sibling containment", true);
00185 }
00186
00187 View::setContainment(containment);
00188 }
00189
00190 void DesktopView::addContainment(Plasma::Containment *fromContainment)
00191 {
00192 if (fromContainment) {
00193 Plasma::Corona *corona = fromContainment->corona();
00194 if (corona) {
00195
00196 Plasma::Containment *c = corona->addContainment(fromContainment->pluginName());
00197 if (m_zoomLevel != Plasma::DesktopZoom) {
00198 connectContainment(c);
00199 }
00200
00201 setContainment(c);
00202 kDebug() << "containment added at" << c->geometry();
00203 }
00204 }
00205 }
00206
00207 void DesktopView::zoom(Plasma::Containment *containment, Plasma::ZoomDirection direction)
00208 {
00209 if (direction == Plasma::ZoomIn) {
00210 zoomIn(containment);
00211 } else if (direction == Plasma::ZoomOut) {
00212 zoomOut(containment);
00213 }
00214 }
00215
00216 void DesktopView::zoomIn(Plasma::Containment *toContainment)
00217 {
00218 if (toContainment && containment() != toContainment) {
00219 setContainment(toContainment);
00220 }
00221
00222 if (m_zoomLevel == Plasma::GroupZoom) {
00223 setDragMode(NoDrag);
00224 m_zoomLevel = Plasma::DesktopZoom;
00225 qreal factor = Plasma::scalingFactor(m_zoomLevel) / matrix().m11();
00226 scale(factor, factor);
00227 if (containment()) {
00228
00229 Plasma::Corona *corona = containment()->corona();
00230 if (corona) {
00231 QList<Plasma::Containment*> containments = corona->containments();
00232 foreach (Plasma::Containment *c, containments) {
00233 if (c == containment() || c->containmentType() == Plasma::Containment::PanelContainment) {
00234 continue;
00235 }
00236 disconnect(c, 0, this, 0);
00237 }
00238 }
00239 setSceneRect(containment()->geometry());
00240 containment()->closeToolBox();
00241 containment()->enableAction("zoom in", false);
00242 containment()->enableAction("add sibling containment", false);
00243 }
00244 } else if (m_zoomLevel == Plasma::OverviewZoom) {
00245 m_zoomLevel = Plasma::GroupZoom;
00246 qreal factor = Plasma::scalingFactor(m_zoomLevel);
00247 factor = factor / matrix().m11();
00248 scale(factor, factor);
00249 setSceneRect(QRectF(0, 0, scene()->sceneRect().right(), scene()->sceneRect().bottom()));
00250
00251 if (containment()) {
00252
00253 Plasma::Corona *corona = containment()->corona();
00254 if (corona) {
00255 QList<Plasma::Containment*> containments = corona->containments();
00256 foreach (Plasma::Containment *c, containments) {
00257 if (c->containmentType() == Plasma::Containment::PanelContainment) {
00258 continue;
00259 }
00260 c->enableAction("zoom out", true);
00261 }
00262 }
00263
00264 ensureVisible(containment()->sceneBoundingRect());
00265 }
00266 } else {
00267 setDragMode(NoDrag);
00268 if (containment()) {
00269 containment()->closeToolBox();
00270 containment()->enableAction("zoom in", false);
00271 containment()->enableAction("add sibling containment", false);
00272 }
00273 }
00274 }
00275
00276 void DesktopView::zoomOut(Plasma::Containment *fromContainment)
00277 {
00278 if (m_zoomLevel == Plasma::DesktopZoom) {
00279 fromContainment->enableAction("zoom in", true);
00280 fromContainment->enableAction("add sibling containment", true);
00281 m_zoomLevel = Plasma::GroupZoom;
00282
00283
00284 Plasma::Corona *corona = containment()->corona();
00285 if (corona) {
00286 QList<Plasma::Containment*> containments = corona->containments();
00287 foreach (Plasma::Containment *c, containments) {
00288 if (c == fromContainment ||
00289 c->containmentType() == Plasma::Containment::PanelContainment) {
00290 continue;
00291 }
00292 connectContainment(c);
00293 }
00294 }
00295 } else if (m_zoomLevel == Plasma::GroupZoom) {
00296
00297 Plasma::Corona *corona = fromContainment->corona();
00298 if (corona) {
00299 QList<Plasma::Containment*> containments = corona->containments();
00300 foreach (Plasma::Containment *c, containments) {
00301 if (c->containmentType() == Plasma::Containment::PanelContainment) {
00302 continue;
00303 }
00304 c->enableAction("zoom out", false);
00305 }
00306 }
00307 m_zoomLevel = Plasma::OverviewZoom;
00308 } else {
00309 fromContainment->enableAction("zoom out", false);
00310 return;
00311 }
00312
00313 setDragMode(ScrollHandDrag);
00314 qreal factor = Plasma::scalingFactor(m_zoomLevel);
00315 qreal s = factor / matrix().m11();
00316 scale(s, s);
00317 setSceneRect(QRectF(0, 0, scene()->sceneRect().right(), scene()->sceneRect().bottom()));
00318
00319 ensureVisible(fromContainment->sceneBoundingRect());
00320 }
00321
00322 void DesktopView::showAppletBrowser()
00323 {
00324 if (m_dashboard && m_dashboard->isVisible()) {
00325 return;
00326 }
00327
00328 PlasmaApp::self()->showAppletBrowser(containment());
00329 }
00330
00331 void DesktopView::wheelEvent(QWheelEvent* event)
00332 {
00333 if (scene() && scene()->itemAt(event->pos())) {
00334 QGraphicsView::wheelEvent(event);
00335 return;
00336 }
00337
00338 if (event->modifiers() & Qt::ControlModifier) {
00339 if (event->delta() < 0) {
00340 zoomOut(containment());
00341 } else {
00342 zoomIn(containment());
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 void DesktopView::drawBackground(QPainter *painter, const QRectF &rect)
00356 {
00357 const QPainter::CompositionMode savedMode = painter->compositionMode();
00358 const QBrush brush = backgroundBrush();
00359
00360 switch (brush.style())
00361 {
00362 case Qt::TexturePattern:
00363 {
00364
00365
00366 const QPixmap texture = brush.texture();
00367 QRect r = rect.toAlignedRect();
00368 r.setLeft(r.left() - (r.left() % texture.width()));
00369 r.setTop(r.top() - (r.top() % texture.height()));
00370 painter->setCompositionMode(QPainter::CompositionMode_Source);
00371 painter->drawTiledPixmap(r, texture);
00372 painter->setCompositionMode(savedMode);
00373 return;
00374 }
00375
00376 case Qt::SolidPattern:
00377 painter->setCompositionMode(QPainter::CompositionMode_Source);
00378 painter->fillRect(rect.toAlignedRect(), brush.color());
00379 painter->setCompositionMode(savedMode);
00380 return;
00381
00382 default:
00383 QGraphicsView::drawBackground(painter, rect);
00384 }
00385 }
00386
00387 void DesktopView::screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* containment)
00388 {
00389 kDebug() << "was, is, containment:" << wasScreen << isScreen << (QObject*)containment;
00390 if (containment->containmentType() == Plasma::Containment::PanelContainment) {
00391
00392 return;
00393 }
00394
00395 if (wasScreen == screen()) {
00396 if (this->containment() == containment) {
00397 setContainment(0);
00398 }
00399 }
00400
00401 if (isScreen == screen()) {
00402 setContainment(containment);
00403 }
00404 }
00405
00406 void DesktopView::nextContainment()
00407 {
00408 QList<Plasma::Containment*> containments = containment()->corona()->containments();
00409 int start = containments.indexOf(containment());
00410 int i = (start + 1) % containments.size();
00411
00412 while (i != start) {
00413 if (containments.at(i)->containmentType() != Plasma::Containment::PanelContainment &&
00414 containments.at(i)->screen() == -1) {
00415 break;
00416 }
00417 i = (i + 1) % containments.size();
00418 }
00419
00420 Plasma::Containment *c = containments.at(i);
00421 setContainment(c);
00422 }
00423
00424 void DesktopView::previousContainment()
00425 {
00426 QList<Plasma::Containment*> containments = containment()->corona()->containments();
00427 int start = containments.indexOf(containment());
00428
00429 int i = start - 1;
00430 if (i < 0) {
00431 i += containments.size();
00432 }
00433
00434 while (i != start) {
00435 if (containments.at(i)->containmentType() != Plasma::Containment::PanelContainment &&
00436 containments.at(i)->screen() == -1) {
00437 break;
00438 }
00439 if (--i < 0) {
00440 i += containments.size();
00441 }
00442 }
00443
00444 Plasma::Containment *c = containments.at(i);
00445 setContainment(c);
00446 }
00447
00448 #include "desktopview.moc"
00449