Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

screenshot.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2002 L.J. Potter ljp@llornkcor.com
00003 **  All rights reserved.
00004 **
00005 ** This file may be distributed and/or modified under the terms of the
00006 ** GNU General Public License version 2 as published by the Free Software
00007 ** Foundation and appearing in the file LICENSE.GPL included in the
00008 ** packaging of this file.
00009 **
00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 **
00013 **********************************************************************/
00014 
00015 #include "screenshot.h"
00016 
00017 /* OPIE */
00018 #include <opie2/odebug.h>
00019 #include <opie2/ofiledialog.h>
00020 #include <opie2/oresource.h>
00021 #include <opie2/otaskbarapplet.h>
00022 
00023 #include <qpe/qpeapplication.h>
00024 #include <qpe/applnk.h>
00025 #include <qpe/qcopenvelope_qws.h>
00026 
00027 /* QT */
00028 #include <qlineedit.h>
00029 #include <qdir.h>
00030 #include <qlabel.h>
00031 #include <qpushbutton.h>
00032 #include <qpainter.h>
00033 #include <qspinbox.h>
00034 #include <qlayout.h>
00035 #include <qcheckbox.h>
00036 #include <qmessagebox.h>
00037 
00038 /* STD */
00039 #include <stdlib.h>
00040 #include <sys/socket.h>
00041 #include <netinet/in.h>
00042 #include <netdb.h>
00043 #include <unistd.h>
00044 
00045 using namespace Opie::Core;
00046 using namespace Opie::Ui;
00047 
00048 static const char *SCAP_hostname = "www.handhelds.org";
00049 static const int SCAP_port = 80;
00050 
00051 
00052 ScreenshotControl::ScreenshotControl( QWidget *parent, const char *name )
00053     : QFrame( parent, name, WDestructiveClose | WStyle_StaysOnTop | WType_Popup )
00054 {
00055   setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
00056   QVBoxLayout *vbox = new QVBoxLayout ( this, 5, 3 );
00057   QHBoxLayout *hbox;
00058 
00059   hbox = new QHBoxLayout ( vbox );
00060 
00061   QLabel *l = new QLabel ( tr( "Delay" ), this );
00062   hbox-> addWidget ( l );
00063 
00064   delaySpin = new QSpinBox( 0, 60, 1, this, "Spinner" );
00065   delaySpin-> setButtonSymbols ( QSpinBox::PlusMinus );
00066   delaySpin-> setSuffix ( tr( "sec" ));
00067   delaySpin-> setFocusPolicy( QWidget::NoFocus );
00068   delaySpin-> setValue ( 1 );
00069   hbox-> addWidget ( delaySpin );
00070 
00071   saveNamedCheck = new QCheckBox ( tr( "Save named" ), this);
00072   saveNamedCheck-> setFocusPolicy ( QWidget::NoFocus );
00073   vbox->addWidget( saveNamedCheck);
00074 
00075   vbox-> addSpacing ( 3 );
00076 
00077   l = new QLabel ( tr( "Save screenshot as..." ), this );
00078   vbox-> addWidget ( l, AlignCenter );
00079 
00080   hbox = new QHBoxLayout ( vbox );
00081 
00082   grabItButton = new QPushButton( tr( "File" ), this, "GrabButton" );
00083   grabItButton ->setFocusPolicy( QWidget::TabFocus );
00084   hbox-> addWidget ( grabItButton );
00085 
00086   QPushButton* drawPadButton = new QPushButton( tr("Opie drawpad"), this, "DrawPadButton" );
00087   drawPadButton->setFocusPolicy( QWidget::TabFocus );
00088   hbox->addWidget( drawPadButton );
00089 
00090   scapButton = new QPushButton( tr( "Scap" ), this, "ScapButton" );
00091   scapButton ->setFocusPolicy( QWidget::TabFocus );
00092   hbox-> addWidget ( scapButton );
00093 
00094   setFixedSize ( sizeHint ( ));
00095   setFocusPolicy ( QWidget::NoFocus );
00096 
00097 
00098   grabTimer = new QTimer ( this, "grab timer");
00099 
00100   connect ( grabTimer, SIGNAL( timeout()), this, SLOT( performGrab()));
00101   connect ( grabItButton, SIGNAL( clicked()), SLOT( slotGrab()));
00102   connect ( scapButton, SIGNAL( clicked()), SLOT( slotScap()));
00103   connect ( drawPadButton, SIGNAL(clicked()), SLOT(slotDrawpad()) );
00104 }
00105 
00106 void ScreenshotControl::slotGrab()
00107 {
00108   buttonPushed = 1;
00109   hide();
00110 
00111   setFileName = FALSE;
00112   if ( saveNamedCheck->isChecked()) {
00113     setFileName = TRUE;
00114 
00115     MimeTypes types;
00116     QStringList list;
00117     list << "image/*";
00118     types. insert ( "Images", list );
00119 
00120     FileNamePath = Opie::Ui::OFileDialog::getSaveFileName( 1,"/","", types, 0 );
00121   }
00122 
00123   if ( delaySpin->value() )
00124     grabTimer->start( delaySpin->value() * 1000, true );
00125   else
00126     show();
00127 }
00128 
00129 void ScreenshotControl::slotScap()
00130 {
00131   buttonPushed = 2;
00132   hide();
00133 
00134   if ( delaySpin->value() )
00135     grabTimer->start( delaySpin->value() * 1000, true );
00136   else
00137     show();
00138 }
00139 
00140 void ScreenshotControl::slotDrawpad()
00141 {
00142     buttonPushed = 3;
00143     hide();
00144     if ( delaySpin->value() )
00145         grabTimer->start( delaySpin->value()*1000, true );
00146     else
00147         show();
00148 }
00149 
00150 void ScreenshotControl::savePixmap()
00151 {
00152   DocLnk lnk;
00153   QString fileName;
00154 
00155   if ( setFileName) {
00156     fileName = FileNamePath;
00157     //not sure why this is needed here, but it forgets fileName
00158     // if this is below the braces
00159 
00160     if (fileName.right(3) != "png")
00161       fileName = fileName + ".png";
00162     lnk.setFile(fileName); //sets File property
00163     odebug << "saving file " + fileName << oendl;
00164     snapshot.save( fileName, "PNG");
00165     QFileInfo fi( fileName);
00166     lnk.setName( fi.fileName()); //sets file name
00167 
00168     if (!lnk.writeLink())
00169       odebug << "Writing doclink did not work" << oendl;
00170   }
00171   else {
00172 
00173     fileName = "sc_" + QDateTime::currentDateTime().toString();
00174     fileName.replace(QRegExp("'"), "");
00175     fileName.replace(QRegExp(" "), "_");
00176     fileName.replace(QRegExp(":"), ".");
00177     fileName.replace(QRegExp(","), "");
00178     QString dirName = QDir::homeDirPath() + "/Documents/image/png/";
00179 
00180     if ( !QDir( dirName).exists() ) {
00181       odebug << "making dir " + dirName << oendl;
00182       QString msg = "mkdir -p " + dirName;
00183       system(msg.latin1());
00184     }
00185     fileName = dirName + fileName;
00186     if (fileName.right(3) != "png")
00187       fileName = fileName + ".png";
00188     lnk.setFile(fileName); //sets File property
00189     odebug << "saving file " + fileName << oendl;
00190     snapshot.save( fileName, "PNG");
00191     QFileInfo fi( fileName);
00192     lnk.setName( fi.fileName()); //sets file name
00193 
00194     if (!lnk.writeLink())
00195       odebug << "Writing doclink did not work" << oendl;
00196 
00197   }
00198 
00199   QPEApplication::beep();
00200 }
00201 
00202 void ScreenshotControl::performGrab()
00203 {
00204         snapshot = QPixmap::grabWindow( QPEApplication::desktop()->winId(), 0, 0, QApplication::desktop()->width(),  QApplication::desktop()->height() );
00205 
00206         if (buttonPushed == 1) {
00207                 odebug << "grabbing screen" << oendl;
00208                 grabTimer->stop();
00209                 show();
00210                 qApp->processEvents();
00211                 savePixmap();
00212         }else if ( buttonPushed == 3 ) {
00213             grabTimer->stop();
00214             show();
00215             QCopEnvelope env("QPE/Application/drawpad", "importPixmap(QPixmap)" );
00216             env << snapshot;
00217         } else {
00218                 grabTimer->stop();
00219 
00220                 struct sockaddr_in raddr;
00221                 struct hostent *rhost_info;
00222                 int sock = -1;
00223                 bool ok = false;
00224 
00225                 QString displayEnv = getenv("QWS_DISPLAY");
00226                 odebug << displayEnv << oendl;
00227 
00228                 if(( displayEnv.left(2) != ":0" ) && (!displayEnv.isEmpty())) {
00229 
00230                         if (( rhost_info = (struct hostent *) ::gethostbyname ((char *) SCAP_hostname )) != 0 ) {
00231                         ::memset ( &raddr, 0, sizeof (struct sockaddr_in));
00232                         ::memcpy ( &raddr. sin_addr, rhost_info-> h_addr, rhost_info-> h_length );
00233                         raddr. sin_family = rhost_info-> h_addrtype;
00234                         raddr. sin_port = htons ( SCAP_port );
00235 
00236                         if (( sock = ::socket ( AF_INET, SOCK_STREAM, 0 )) >= 0 ) {
00237                                 if ( ::connect ( sock, (struct sockaddr *) & raddr, sizeof (struct sockaddr)) >= 0 ) {
00238 
00239                                         QString header;
00240 
00241                                         QPixmap pix;
00242 
00243                                         QString SCAP_model="";
00244 #warning FIXME: model string should be filled with actual device model
00245                                                 if( snapshot.width() > 320)
00246                                                         SCAP_model ="Corgi";
00247 
00248                                         if(displayEnv == "QVFb:0")  {//set this if you plan on using this app in qvfb!!
00249                                                  pix = snapshot.xForm(QWMatrix().rotate(90));
00250                                         } else
00251                                                 pix = ( snapshot.width() > snapshot.height() ) ? snapshot : snapshot.xForm( QWMatrix().rotate(90) );
00252 
00253                                         QImage img = pix.convertToImage().convertDepth( 16 ); // could make that also depth independent, if hh.org/scap can handle it
00254 
00255                                         header = "POST /scap/capture.cgi?%1+%2 HTTP/1.1\n"  // 1: model / 2: user
00256                                                 "Content-length: %3\n"                     // 3: content length
00257                                                 "Content-Type: image/png\n"
00258                                                 "Host: %4\n"                               // 4: scap host
00259                                                 "\n";
00260 
00261 
00262                                         header = header.arg( SCAP_model).arg( ::getenv( "USER" ) ).arg( img.numBytes() ).arg( SCAP_hostname );
00263                                         odebug << header << oendl;
00264 
00265                                         if ( !pix.isNull() )  {
00266                                                 const char *ascii = header.latin1( );
00267                                                 uint ascii_len = ::strlen( ascii );
00268                                                  ::write ( sock, ascii, ascii_len );
00269                                                  ::write ( sock, img.bits(), img.numBytes() );
00270 
00271                                                 ok = true;
00272                                         }
00273                                 }
00274                                 ::close ( sock );
00275                         }
00276                 }
00277                 if ( ok ) {
00278                         QMessageBox::information( 0, tr( "Success" ), QString( "<p>%1</p>" ).arg ( tr( "Screenshot was uploaded to %1" )).arg( SCAP_hostname ));
00279                 } else {
00280                         QMessageBox::warning( 0, tr( "Error" ), QString( "<p>%1</p>" ).arg( tr( "Connection to %1 failed." )).arg( SCAP_hostname ));
00281                 }
00282         } else {
00283                 QMessageBox::warning( 0, tr( "Error" ),tr("Please set <b>QWS_DISPLAY</b> environmental variable."));
00284             }
00285         }
00286 
00287 }
00288 
00289 
00290 
00291 //===========================================================================
00292 
00293 ScreenshotApplet::ScreenshotApplet( QWidget *parent, const char *name )
00294     : QWidget( parent, name )
00295 {
00296     setFixedHeight( AppLnk::smallIconSize() );
00297     setFixedWidth( AppLnk::smallIconSize() );
00298     m_icon = Opie::Core::OResource::loadPixmap( "screenshotapplet/screenshot", Opie::Core::OResource::SmallIcon );
00299 }
00300 
00301 ScreenshotApplet::~ScreenshotApplet()
00302 {
00303 }
00304 
00305 int ScreenshotApplet::position()
00306 {
00307     return 6;
00308 }
00309 
00310 void ScreenshotApplet::mousePressEvent( QMouseEvent *)
00311 {
00312   ScreenshotControl *sc = new ScreenshotControl ( );
00313   QPoint curPos = mapToGlobal ( QPoint ( 0, 0 ));
00314 
00315   // windowPosX is the windows position centered above the applets icon.
00316   // If the icon is near the edge of the screen, the window would leave the visible area
00317   // so we check the position against the screen width and correct the difference if needed
00318 
00319   int screenWidth = qApp->desktop()->width();
00320   int windowPosX = curPos. x ( ) - ( sc-> sizeHint ( ). width ( ) - width ( )) / 2 ;
00321   int ZwindowPosX, XwindowPosX;
00322 
00323   // the window would be placed beyond the screen wich doesn't look tooo good
00324   if ( (windowPosX + sc-> sizeHint ( ). width ( )) > screenWidth ) {
00325       XwindowPosX = windowPosX + sc-> sizeHint ( ). width ( ) - screenWidth;
00326     ZwindowPosX = windowPosX - XwindowPosX - 1;
00327   } else {
00328       ZwindowPosX = windowPosX;
00329   }
00330 
00331    sc-> move ( ZwindowPosX, curPos. y ( ) - sc-> sizeHint ( ). height ( ) );
00332    sc-> show ( );
00333 }
00334 
00335 void ScreenshotApplet::paintEvent( QPaintEvent* )
00336 {
00337   QPainter p ( this );
00338   p.drawPixmap( 0, 2, m_icon );
00339 }
00340 
00341 
00342 EXPORT_OPIE_APPLET_v1( ScreenshotApplet )
00343 

Generated on Sat Nov 5 16:15:24 2005 for OPIE by  doxygen 1.4.2