00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "aconf.h"
00010 #include "GString.h"
00011 #include "PDFDoc.h"
00012 #include "TextOutputDev.h"
00013
00014 #include "QPEOutputDev.h"
00015
00016 #include <qpe/qpeapplication.h>
00017 #include <qpe/resource.h>
00018 #include <qpe/applnk.h>
00019 #include <qpe/qcopenvelope_qws.h>
00020
00021
00022 #include <qclipboard.h>
00023 #include <qtoolbar.h>
00024 #include <qtoolbutton.h>
00025 #include <qmenubar.h>
00026 #include <qpopupmenu.h>
00027 #include <qwidgetstack.h>
00028 #include <qtimer.h>
00029 #include <qfileinfo.h>
00030 #include <qstring.h>
00031 #include <qlineedit.h>
00032 #include <qspinbox.h>
00033 #include <qlayout.h>
00034 #include <qdialog.h>
00035 #include <qlabel.h>
00036 #include <qmessagebox.h>
00037
00038 #include "qpdf.h"
00039
00040 #ifdef QPDF_QPE_ONLY
00041 #include <qpe/fileselector.h>
00042 #else
00043 #include <opie/ofileselector.h>
00044 #endif
00045
00046
00047 int main ( int argc, char **argv )
00048 {
00049 QPEApplication app ( argc, argv );
00050
00051
00052 globalParams = new GlobalParams ( "" );
00053 globalParams-> setErrQuiet ( true );
00054
00055 QPdfDlg *dlg = new QPdfDlg ( );
00056 app. showMainDocumentWidget ( dlg );
00057
00058 if (( app. argc ( ) == 3 ) && ( app. argv ( ) [1] == QCString ( "-f" )))
00059 dlg-> openFile ( app. argv ( ) [2] );
00060
00061 return app. exec ( );
00062 }
00063
00064
00065 QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
00066 {
00067 setCaption ( tr( "QPdf" ));
00068 setIcon ( Resource::loadPixmap ( "qpdf_icon" ));
00069
00070 m_busy = false;
00071
00072 m_doc = 0;
00073 m_pages = 0;
00074 m_zoom = 72;
00075 m_currentpage = 0;
00076
00077 m_fullscreen = false;
00078 m_renderok = false;
00079
00080
00081 setToolBarsMovable ( false );
00082
00083 m_stack = new QWidgetStack ( this );
00084 m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ));
00085 setCentralWidget ( m_stack );
00086
00087 m_outdev = new QPEOutputDev ( m_stack );
00088 connect ( m_outdev, SIGNAL( selectionChanged(const QRect&)), this, SLOT( copyToClipboard(const QRect&)));
00089
00090 #ifdef QPDF_QPE_ONLY
00091 m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true );
00092 #else
00093 m_filesel = new OFileSelector ( "application/pdf", m_stack, "fs", false, true );
00094 #endif
00095
00096 connect ( m_filesel, SIGNAL( closeMe()), this, SLOT( closeFileSelector()));
00097 connect ( m_filesel, SIGNAL( fileSelected(const DocLnk&)), this, SLOT( openFile(const DocLnk&)));
00098
00099 m_tb_menu = new QToolBar ( this );
00100 m_tb_menu-> setHorizontalStretchable ( true );
00101
00102 QMenuBar *mb = new QMenuBar ( m_tb_menu );
00103
00104 m_pm_zoom = new QPopupMenu ( mb );
00105 m_pm_zoom-> setCheckable ( true );
00106
00107 mb-> insertItem ( tr( "Zoom" ), m_pm_zoom );
00108
00109 m_pm_zoom-> insertItem ( tr( "Fit to width" ), 1 );
00110 m_pm_zoom-> insertItem ( tr( "Fit to page" ), 2 );
00111 m_pm_zoom-> insertSeparator ( );
00112 m_pm_zoom-> insertItem ( tr( "50%" ), 50 );
00113 m_pm_zoom-> insertItem ( tr( "75%" ), 75 );
00114 m_pm_zoom-> insertItem ( tr( "100%" ), 100 );
00115 m_pm_zoom-> insertItem ( tr( "125%" ), 125 );
00116 m_pm_zoom-> insertItem ( tr( "150%" ), 150 );
00117 m_pm_zoom-> insertItem ( tr( "200%" ), 200 );
00118
00119 connect ( m_pm_zoom, SIGNAL( activated(int)), this, SLOT( setZoom(int)));
00120
00121 m_tb_tool = new QToolBar ( this );
00122
00123 new QToolButton ( Resource::loadIconSet ( "fileopen" ), tr( "Open..." ), QString::null, this, SLOT( openFile()), m_tb_tool, "open" );
00124 m_tb_tool-> addSeparator ( );
00125 m_to_find = new QToolButton ( Resource::loadIconSet ( "find" ), tr( "Find..." ), QString::null, this, SLOT( toggleFindBar()), m_tb_tool, "find" );
00126 m_to_find-> setToggleButton ( true );
00127 m_tb_tool-> addSeparator ( );
00128 m_to_full = new QToolButton ( Resource::loadIconSet ( "fullscreen" ), tr( "Fullscreen" ), QString::null, this, SLOT( toggleFullscreen()), m_tb_tool, "fullscreen" );
00129 m_to_full-> setToggleButton ( true );
00130 m_tb_tool-> addSeparator ( );
00131 new QToolButton ( Resource::loadIconSet ( "fastback" ), tr( "First page" ), QString::null, this, SLOT( firstPage()), m_tb_tool, "first" );
00132 new QToolButton ( Resource::loadIconSet ( "back" ), tr( "Previous page" ), QString::null, this, SLOT( prevPage()), m_tb_tool, "prev" );
00133 new QToolButton ( Resource::loadIconSet ( "down" ), tr( "Goto page..." ), QString::null, this, SLOT( gotoPageDialog()), m_tb_tool, "goto" );
00134 new QToolButton ( Resource::loadIconSet ( "forward" ), tr( "Next page" ), QString::null, this, SLOT( nextPage()), m_tb_tool, "next" );
00135 new QToolButton ( Resource::loadIconSet ( "fastforward" ), tr( "Last page" ), QString::null, this, SLOT( lastPage()), m_tb_tool, "last" );
00136
00137 m_tb_find = new QToolBar ( this );
00138 addToolBar ( m_tb_find, "Search", QMainWindow::Top, true );
00139 m_tb_find-> setHorizontalStretchable ( true );
00140 m_tb_find-> hide ( );
00141
00142 m_findedit = new QLineEdit ( m_tb_find, "findedit" );
00143 m_tb_find-> setStretchableWidget ( m_findedit );
00144 connect ( m_findedit, SIGNAL( textChanged(const QString&)), this, SLOT( findText(const QString&)));
00145
00146 new QToolButton ( Resource::loadIconSet ( "next" ), tr( "Next" ), QString::null, this, SLOT( findText()), m_tb_find, "findnext" );
00147
00148 openFile ( );
00149 }
00150
00151 QPdfDlg::~QPdfDlg ( )
00152 {
00153 delete m_doc;
00154 }
00155
00156
00157
00158 void QPdfDlg::resizeEvent ( QResizeEvent * )
00159 {
00160 if ( m_fullscreen && ( size ( ) != qApp-> desktop ( )-> size ( )))
00161 setFullscreen ( true );
00162 }
00163
00164 void QPdfDlg::focusInEvent ( QFocusEvent * )
00165 {
00166 if ( m_fullscreen )
00167 setFullscreen ( true );
00168 }
00169
00170 void QPdfDlg::toggleFullscreen ( )
00171 {
00172 if ( m_to_full-> isOn ( ) == m_fullscreen )
00173 m_to_full-> setOn ( !m_fullscreen );
00174
00175 m_fullscreen = !m_fullscreen;
00176 setFullscreen ( m_fullscreen );
00177 }
00178
00179 void QPdfDlg::setFullscreen ( bool b )
00180 {
00181 static QSize normalsize;
00182
00183 if ( b ) {
00184 if ( !normalsize. isValid ( ))
00185 normalsize = size ( );
00186
00187 setFixedSize ( qApp-> desktop ( )-> size ( ));
00188 showNormal ( );
00189 reparent ( 0, WStyle_Customize | WStyle_NoBorder, QPoint ( 0, 0 ));
00190 showFullScreen ( );
00191 }
00192 else {
00193 showNormal ( );
00194 reparent ( 0, 0, QPoint ( 0, 0 ));
00195 resize ( normalsize );
00196 showMaximized ( );
00197 normalsize = QSize ( );
00198 }
00199 }
00200
00201
00202
00203 void QPdfDlg::setBusy ( bool b )
00204 {
00205 if ( b != m_busy ) {
00206 m_busy = b;
00207
00208 m_outdev-> setBusy ( m_busy );
00209 setEnabled ( !m_busy );
00210 }
00211 }
00212
00213 bool QPdfDlg::busy ( ) const
00214 {
00215 return m_busy;
00216 }
00217
00218
00219 void QPdfDlg::updateCaption ( )
00220 {
00221 QString cap = "";
00222
00223 if ( !m_currentdoc. isEmpty ( ))
00224 cap = QString ( "%1 - " ). arg ( m_currentdoc );
00225 cap += "QPdf";
00226
00227 setCaption ( cap );
00228 }
00229
00230
00231 void QPdfDlg::setZoom ( int id )
00232 {
00233 int dpi = 0;
00234
00235 switch ( id ) {
00236 case 1:
00237 if ( m_doc && m_doc-> isOk ( ))
00238 dpi = m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage );
00239 break;
00240
00241 case 2:
00242 if ( m_doc && m_doc-> isOk ( ))
00243 dpi = QMIN( m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ), \
00244 m_outdev-> visibleHeight ( ) * 72 / m_doc-> getPageHeight ( m_currentpage ));
00245 break;
00246
00247 default:
00248 dpi = id * 72 / 100;
00249 break;
00250 }
00251
00252 if ( dpi < 18 )
00253 dpi = 18;
00254 if ( dpi > 216 )
00255 dpi = 216;
00256
00257 for ( uint i = 0; i < m_pm_zoom-> count ( ); i++ ) {
00258 int xid = m_pm_zoom-> idAt ( i );
00259 m_pm_zoom-> setItemChecked ( xid, xid == id );
00260 }
00261
00262 if ( dpi != m_zoom ) {
00263 m_zoom = dpi;
00264
00265 renderPage ( );
00266 }
00267 }
00268
00269
00270 void QPdfDlg::gotoPageDialog ( )
00271 {
00272 QDialog *d = new QDialog ( this, "gotodlg", true );
00273 d-> setCaption ( tr( "Goto page" ));
00274
00275 QBoxLayout *lay = new QVBoxLayout ( d, 4, 4 );
00276
00277 QLabel *l = new QLabel ( tr( "Select from 1 .. %1:" ). arg ( m_pages ), d );
00278 lay-> addWidget ( l );
00279
00280 QSpinBox *spin = new QSpinBox ( 1, m_pages, 1, d );
00281 spin-> setValue ( m_currentpage );
00282 spin-> setWrapping ( true );
00283 spin-> setButtonSymbols ( QSpinBox::PlusMinus );
00284 lay-> addWidget ( spin );
00285
00286 if ( d-> exec ( ) == QDialog::Accepted ) {
00287 gotoPage ( spin-> value ( ));
00288 }
00289
00290 delete d;
00291 }
00292
00293 void QPdfDlg::toggleFindBar ( )
00294 {
00295 if ( m_to_find-> isOn ( ) == m_tb_find-> isVisible ( ))
00296 m_to_find-> setOn ( !m_tb_find-> isVisible ( ));
00297
00298 if ( m_tb_find-> isVisible ( )) {
00299 m_tb_find-> hide ( );
00300 m_outdev-> setFocus ( );
00301 }
00302 else {
00303 m_tb_find-> show ( );
00304 m_findedit-> setFocus ( );
00305 }
00306 }
00307
00308 void QPdfDlg::findText ( const QString &str )
00309 {
00310 if ( !m_doc || !m_doc-> isOk ( ) || str. isEmpty ( ))
00311 return;
00312
00313 TextOutputDev *textOut = 0;
00314 int pg = 0;
00315
00316 setBusy ( true );
00317
00318 int len = str. length ( );
00319 Unicode *u = new Unicode [len];
00320 for ( int i = 0; i < len; i++ )
00321 u [i] = str [i]. unicode ( );
00322
00323 int xMin = 0, yMin = 0, xMax = 0, yMax = 0;
00324 QRect selr = m_outdev-> selection ( );
00325 bool fromtop = true;
00326
00327 if ( selr. isValid ( )) {
00328 xMin = selr. right ( );
00329 yMin = selr. top ( ) + selr. height ( ) / 2;
00330 fromtop = false;
00331 }
00332
00333 if ( m_outdev-> findText ( u, len, fromtop, true, &xMin, &yMin, &xMax, &yMax ))
00334 goto found;
00335
00336 qApp-> processEvents ( );
00337
00338
00339 textOut = new TextOutputDev ( 0, gFalse, gFalse );
00340 if ( !textOut-> isOk ( ))
00341 goto done;
00342
00343 qApp-> processEvents ( );
00344
00345 for ( pg = ( m_currentpage % m_pages ) + 1; pg != m_currentpage; pg = ( pg % m_pages ) + 1 ) {
00346 m_doc-> displayPage ( textOut, pg, 72, 0, gFalse );
00347
00348 fp_t xMin1, yMin1, xMax1, yMax1;
00349
00350 qApp-> processEvents ( );
00351
00352 if ( textOut-> findText ( u, len, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1 ))
00353 goto foundPage;
00354
00355 qApp-> processEvents ( );
00356 }
00357
00358
00359 if ( selr. isValid ( )) {
00360 xMax = selr. left ( );
00361 yMax = selr. top ( ) + selr. height ( ) / 2;
00362
00363 if ( m_outdev-> findText ( u, len, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax ))
00364 goto found;
00365 }
00366
00367
00368 QMessageBox::information ( this, tr( "Find..." ), tr( "'%1' could not be found." ). arg ( str ));
00369 goto done;
00370
00371 foundPage:
00372 qApp-> processEvents ( );
00373
00374 gotoPage ( pg );
00375
00376 if ( !m_outdev-> findText ( u, len, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax )) {
00377
00378 goto done;
00379 }
00380
00381 found:
00382 selr. setCoords ( xMin, yMin, xMax, yMax );
00383 m_outdev-> setSelection ( selr, true );
00384
00385 done:
00386
00387 delete [] u;
00388 delete textOut;
00389
00390 setBusy ( false );
00391 }
00392
00393
00394 void QPdfDlg::findText ( )
00395 {
00396 findText ( m_findedit-> text ( ));
00397 }
00398
00399 void QPdfDlg::copyToClipboard ( const QRect &r )
00400 {
00401 if ( m_doc && m_doc-> isOk ( ) && m_doc-> okToCopy ( ))
00402 qApp-> clipboard ( )-> setText ( m_outdev-> getText ( r ));
00403 }
00404
00405 void QPdfDlg::firstPage ( )
00406 {
00407 gotoPage ( 1 );
00408 }
00409
00410 void QPdfDlg::prevPage ( )
00411 {
00412 gotoPage ( m_currentpage - 1 );
00413 }
00414
00415 void QPdfDlg::nextPage ( )
00416 {
00417 gotoPage ( m_currentpage + 1 );
00418 }
00419
00420 void QPdfDlg::lastPage ( )
00421 {
00422 gotoPage ( m_pages );
00423 }
00424
00425 void QPdfDlg::gotoPage ( int n )
00426 {
00427 if ( n < 1 )
00428 n = 1;
00429 if ( n > m_pages )
00430 n = m_pages;
00431
00432 if ( n != m_currentpage ) {
00433 m_currentpage = n;
00434
00435 renderPage ( );
00436 }
00437 }
00438
00439 void QPdfDlg::renderPage ( )
00440 {
00441 if ( m_renderok && m_doc && m_doc-> isOk ( )) {
00442 m_renderok = false;
00443
00444 setBusy ( true );
00445 m_doc-> displayPage ( m_outdev, m_currentpage, m_zoom, 0, true );
00446 setBusy ( false );
00447
00448 m_outdev-> setPageCount ( m_currentpage, m_pages );
00449
00450 m_renderok = true;
00451 }
00452 }
00453
00454 void QPdfDlg::closeFileSelector ( )
00455 {
00456 m_tb_menu-> show ( );
00457 m_tb_tool-> show ( );
00458 m_stack-> raiseWidget ( m_outdev );
00459 }
00460
00461 void QPdfDlg::openFile ( )
00462 {
00463 m_tb_menu-> hide ( );
00464 m_tb_tool-> hide ( );
00465 m_tb_find-> hide ( );
00466 m_stack-> raiseWidget ( m_filesel );
00467 }
00468
00469 void QPdfDlg::openFile ( const QString &f )
00470 {
00471 DocLnk nf;
00472 nf. setType ( "application/pdf" );
00473 nf. setFile ( f );
00474 QFileInfo fi ( f );
00475 nf. setName ( fi. baseName ( ));
00476 openFile ( nf );
00477 }
00478
00479 void QPdfDlg::openFile ( const DocLnk &f )
00480 {
00481 QString fn = f. file ( );
00482 QFileInfo fi ( fn );
00483
00484 if ( fi. exists ( )) {
00485 delete m_doc;
00486
00487 m_doc = new PDFDoc ( new GString ( fn. local8Bit ( )), 0, 0 );
00488
00489 if ( m_doc-> isOk ( )) {
00490 m_currentdoc = f. name ( );
00491 int sep = m_currentdoc. findRev ( '/' );
00492 if ( sep > 0 )
00493 m_currentdoc = m_currentdoc. mid ( sep + 1 );
00494
00495 m_pages = m_doc-> getNumPages ( );
00496 m_currentpage = 0;
00497
00498 QTimer::singleShot ( 0, this, SLOT( delayedInit()));
00499 }
00500 else {
00501 delete m_doc;
00502 m_doc = 0;
00503
00504 m_currentdoc = QString::null;
00505 }
00506
00507 updateCaption ( );
00508 }
00509 else
00510 QMessageBox::warning ( this, tr( "Error" ), tr( "File does not exist!" ));
00511 }
00512
00513 void QPdfDlg::setDocument ( const QString &f )
00514 {
00515 if ( f. find ( ".desktop", 0, true ) == -1 )
00516 openFile ( f );
00517 else
00518 openFile ( DocLnk ( f ));
00519
00520 closeFileSelector ( );
00521 }
00522
00523 void QPdfDlg::delayedInit ( )
00524 {
00525 closeFileSelector ( );
00526
00527 m_currentpage = 0;
00528 m_zoom = 0;
00529 m_renderok = false;
00530
00531 setZoom ( 100 );
00532 gotoPage ( 1 );
00533
00534 m_renderok = true;
00535
00536 renderPage ( );
00537
00538 m_outdev-> setFocus ( );
00539 }
00540