00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "screenshot.h"
00016
00017
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
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
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
00158
00159
00160 if (fileName.right(3) != "png")
00161 fileName = fileName + ".png";
00162 lnk.setFile(fileName);
00163 odebug << "saving file " + fileName << oendl;
00164 snapshot.save( fileName, "PNG");
00165 QFileInfo fi( fileName);
00166 lnk.setName( fi.fileName());
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);
00189 odebug << "saving file " + fileName << oendl;
00190 snapshot.save( fileName, "PNG");
00191 QFileInfo fi( fileName);
00192 lnk.setName( fi.fileName());
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") {
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 );
00254
00255 header = "POST /scap/capture.cgi?%1+%2 HTTP/1.1\n"
00256 "Content-length: %3\n"
00257 "Content-Type: image/png\n"
00258 "Host: %4\n"
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
00316
00317
00318
00319 int screenWidth = qApp->desktop()->width();
00320 int windowPosX = curPos. x ( ) - ( sc-> sizeHint ( ). width ( ) - width ( )) / 2 ;
00321 int ZwindowPosX, XwindowPosX;
00322
00323
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