Logo Search packages:      
Sourcecode: kmess version File versions  Download package

void SystemTrayWidget::displayCloseMessage ( QString  fileMenu = QString::null  ) 

Display an Hide On Close dialog window with a trayicon screenshot

This method, taken from the Basket Note Pads project (see the related links below), is used when the user closes the main KMess contact list window. Then a custom dialog window is shown to notify that the app will still run in background. This useful method adds to it a screenshot of the system tray area of the users' desktop, highlighting the application's icons. The original code was KDE3, it's been ported to make better use of the new features of Qt4 and KDE4.

See also:
http://basket.kde.org/ - Official site of the Basket Note Pads project

http://basket.kde.org/systemtray-on-close-info.php - Specific tray dialog page

Definition at line 73 of file systemtraywidget.cpp.

{
  // Don't do all the computations if they are unneeded:
  if ( ! KMessageBox::shouldBeShownContinue("hideOnCloseInfo") )
      return;

  const QString& message( i18n( "Closing the main window will keep KMess running in the system tray. "
                                "Use 'Quit' from the 'Connect' menu to quit the application." ) );

  // If the system tray is not visible, just show the text message
  if( ! QSystemTrayIcon::isSystemTrayAvailable() || ! isVisible() )
  {
#ifdef KMESSDEBUG_SYSTEMTRAY
    kDebug() << "Displaying simple dialog with no screenshot.";
#endif

    KMessageBox::information( kapp->activeWindow(), message,
                              i18n( "Docking in System Tray" ),
                              "hideOnCloseInfo" );
    return;
  }

#ifdef KMESSDEBUG_SYSTEMTRAY
  kDebug() << "Displaying dialog with tray icon screenshot: generating image...";
#endif

  // Get initial position of the tray icon and the the screen size
  QRect pictureArea( geometry() );
  QRect pictureGeometry( geometry() );
  QRect desktopArea = kapp->desktop()->screenGeometry( geometry().topLeft() );

  // Compute the final size and position of the pixmap to grab
  const int xRadius = desktopArea.width() / 8;
  const int yRadius = desktopArea.height() / 16;
  pictureArea.adjust( -xRadius, -yRadius, xRadius, yRadius );


  // Crop the picture if it goes out of screen
  pictureArea = pictureArea.intersected( desktopArea );

  // This translates the geometry of the tray icon into the picture area
  pictureGeometry.translate( -pictureArea.x(), -pictureArea.y() );


#ifdef KMESSDEBUG_SYSTEMTRAY
  kDebug() << "Creating screenshot from area" << pictureArea << "using a desktop size of" << desktopArea << "and geometry" << pictureGeometry;
#endif

  // Grab an image of the screen which contains the tray icon
  QPixmap shot;
  if( pictureArea.x() == 0 && pictureArea.y() == 0 )
  {
#ifdef Q_WS_X11
    shot = QPixmap::grabWindow( QX11Info::appRootWindow(), pictureArea.x(), pictureArea.y(), pictureArea.width(), pictureArea.height() );
#else
    #warning Screen capture code not implemented for this platform.
#endif
  }
#ifdef KMESSDEBUG_SYSTEMTRAY
  else
  {
    kDebug() << "Looks like the systray is invisible, not displaying the screenshot in the dialog.";
  }
#endif

  if( ! shot.isNull() )
  {
    // Now we want to draw a circle around the icon
    // Some properties about the circle we'll draw
    const int CIRCLE_WIDTH   = 3;
    const int SHADOW_OFFSET  = 2;
    const int IMAGE_BORDER   = 1;
    const int CIRCLE_MARGINS = 6;

    QRect circleArea = pictureGeometry;
    circleArea.adjust( -CIRCLE_MARGINS, -CIRCLE_MARGINS, CIRCLE_MARGINS, CIRCLE_MARGINS );

#ifdef KMESSDEBUG_SYSTEMTRAY
    kDebug() << "Picture geometry is" << pictureGeometry << "and circle area is" << circleArea;
#endif

    // Draw the circle with a dark shadow
    QPainter painter( &shot );
    painter.setPen( QPen(KApplication::palette().dark(), CIRCLE_WIDTH) );
    painter.drawArc( circleArea.adjusted( SHADOW_OFFSET, SHADOW_OFFSET, 0, 0 ), 0, 16*360 );
    painter.setPen( QPen(Qt::red, CIRCLE_WIDTH) );
    painter.drawArc( circleArea, 0, 16*360);

    // Draw the tray icon over the screenshot again, in case a window is hiding the icon
    icon().paint( &painter, geometry() );
    painter.end();

    // Then, we add a border around the image, to make it more visible
    QPixmap finalShot( pictureArea.size() );
    finalShot.fill( KApplication::palette().color( QPalette::Active, QPalette::Foreground ) );
    painter.begin( &finalShot );
    painter.drawPixmap( QRect( IMAGE_BORDER, IMAGE_BORDER, shot.width() - IMAGE_BORDER*2, shot.height() - IMAGE_BORDER*2 ), shot );
    painter.end();

    // Save the pixmap into a temporary file to allow using it in a dialog
    QTemporaryFile tempFile( QDir::tempPath() + "/kmess_temp_XXXXXX.png" );
    tempFile.open();
    finalShot.save( tempFile.fileName() );

#ifdef KMESSDEBUG_SYSTEMTRAY
    kDebug() << "Temp file info"
             << "- Name:"       << tempFile.fileName()
             << "- Exists?"     << tempFile.exists();
#endif

    // Show the dialog
    KMessageBox::information(kapp->activeWindow(),
        "<qt><p>" + message + "</p><p><center><img src=\"" + tempFile.fileName() + "\" "
        "width=\""  + QString::number( pictureArea.width()  ) + "\" "
        "height=\"" + QString::number( pictureArea.height() ) + "\""
        "></center></p></qt>",
        i18n("Docking in System Tray"), "hideOnCloseInfo");

    // Close the temporary file, it will be deleted when the function returns
    tempFile.close();
  }
  else
  {
    // Dialog without the shot.
    KMessageBox::information(kapp->activeWindow(),
        "<qt><p>" + message + "</p></qt>",
        i18n("Docking in System Tray"), "hideOnCloseInfo");
  }

#ifdef KMESSDEBUG_SYSTEMTRAY
  kDebug() << "Dialog closed.";
#endif
}


Generated by  Doxygen 1.6.0   Back to index