Diffstat (limited to 'noncore/unsupported/qpdf/qpdf.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/qpdf/qpdf.cpp | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/noncore/unsupported/qpdf/qpdf.cpp b/noncore/unsupported/qpdf/qpdf.cpp new file mode 100644 index 0000000..6c268ec --- a/dev/null +++ b/noncore/unsupported/qpdf/qpdf.cpp | |||
@@ -0,0 +1,529 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // qpdf.cc | ||
4 | // | ||
5 | // Copyright 2001 Robert Griebl | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #include "aconf.h" | ||
10 | #include "GString.h" | ||
11 | #include "PDFDoc.h" | ||
12 | #include "TextOutputDev.h" | ||
13 | |||
14 | #include "QPEOutputDev.h" | ||
15 | |||
16 | #include <qpe/qpeapplication.h> | ||
17 | #include <qpe/resource.h> | ||
18 | #include <qpe/applnk.h> | ||
19 | #include <qpe/fileselector.h> | ||
20 | #include <qpe/qcopenvelope_qws.h> | ||
21 | |||
22 | |||
23 | #include <qclipboard.h> | ||
24 | #include <qtoolbar.h> | ||
25 | #include <qmenubar.h> | ||
26 | #include <qpopupmenu.h> | ||
27 | #include <qwidgetstack.h> | ||
28 | #include <qtimer.h> | ||
29 | #include <qfileinfo.h> | ||
30 | #include <qstring.h> | ||
31 | #include <qlineedit.h> | ||
32 | #include <qspinbox.h> | ||
33 | #include <qlayout.h> | ||
34 | #include <qdialog.h> | ||
35 | #include <qlabel.h> | ||
36 | #include <qmessagebox.h> | ||
37 | |||
38 | #include "qpdf.h" | ||
39 | |||
40 | |||
41 | int main ( int argc, char **argv ) | ||
42 | { | ||
43 | QPEApplication app ( argc, argv ); | ||
44 | |||
45 | // read config file | ||
46 | globalParams = new GlobalParams ( "" ); | ||
47 | globalParams-> setErrQuiet ( true ); | ||
48 | |||
49 | QPdfDlg *dlg = new QPdfDlg ( ); | ||
50 | app. showMainDocumentWidget ( dlg ); | ||
51 | |||
52 | if (( app. argc ( ) == 3 ) && ( app. argv ( ) [1] == QCString ( "-f" ))) | ||
53 | dlg-> openFile ( app. argv ( ) [2] ); | ||
54 | |||
55 | return app. exec ( ); | ||
56 | } | ||
57 | |||
58 | |||
59 | QPdfDlg::QPdfDlg ( ) : QMainWindow ( ) | ||
60 | { | ||
61 | setCaption ( tr( "QPdf" )); | ||
62 | setIcon ( Resource::loadPixmap ( "qpdf_icon" )); | ||
63 | |||
64 | m_busy = false; | ||
65 | |||
66 | m_doc = 0; | ||
67 | m_pages = 0; | ||
68 | m_zoom = 72; | ||
69 | m_currentpage = 0; | ||
70 | |||
71 | m_fullscreen = false; | ||
72 | m_renderok = false; | ||
73 | |||
74 | |||
75 | setToolBarsMovable ( false ); | ||
76 | |||
77 | m_stack = new QWidgetStack ( this ); | ||
78 | m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding )); | ||
79 | setCentralWidget ( m_stack ); | ||
80 | |||
81 | m_outdev = new QPEOutputDev ( m_stack ); | ||
82 | connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & ))); | ||
83 | |||
84 | m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true ); | ||
85 | connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( ))); | ||
86 | connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & ))); | ||
87 | |||
88 | m_tb_menu = new QToolBar ( this ); | ||
89 | m_tb_menu-> setHorizontalStretchable ( true ); | ||
90 | |||
91 | QMenuBar *mb = new QMenuBar ( m_tb_menu ); | ||
92 | |||
93 | m_pm_zoom = new QPopupMenu ( mb ); | ||
94 | m_pm_zoom-> setCheckable ( true ); | ||
95 | |||
96 | mb-> insertItem ( tr( "Zoom" ), m_pm_zoom ); | ||
97 | |||
98 | m_pm_zoom-> insertItem ( tr( "Fit to width" ), 1 ); | ||
99 | m_pm_zoom-> insertItem ( tr( "Fit to page" ), 2 ); | ||
100 | m_pm_zoom-> insertSeparator ( ); | ||
101 | m_pm_zoom-> insertItem ( tr( "50%" ), 50 ); | ||
102 | m_pm_zoom-> insertItem ( tr( "75%" ), 75 ); | ||
103 | m_pm_zoom-> insertItem ( tr( "100%" ), 100 ); | ||
104 | m_pm_zoom-> insertItem ( tr( "125%" ), 125 ); | ||
105 | m_pm_zoom-> insertItem ( tr( "150%" ), 150 ); | ||
106 | m_pm_zoom-> insertItem ( tr( "200%" ), 200 ); | ||
107 | |||
108 | connect ( m_pm_zoom, SIGNAL( activated ( int )), this, SLOT( setZoom ( int ))); | ||
109 | |||
110 | m_tb_tool = new QToolBar ( this ); | ||
111 | |||
112 | new QToolButton ( Resource::loadIconSet ( "fileopen" ), tr( "Open..." ), QString::null, this, SLOT( openFile ( )), m_tb_tool, "open" ); | ||
113 | m_tb_tool-> addSeparator ( ); | ||
114 | m_to_find = new QToolButton ( Resource::loadIconSet ( "find" ), tr( "Find..." ), QString::null, this, SLOT( toggleFindBar ( )), m_tb_tool, "find" ); | ||
115 | m_to_find-> setToggleButton ( true ); | ||
116 | m_tb_tool-> addSeparator ( ); | ||
117 | m_to_full = new QToolButton ( Resource::loadIconSet ( "fullscreen" ), tr( "Fullscreen" ), QString::null, this, SLOT( toggleFullscreen ( )), m_tb_tool, "fullscreen" ); | ||
118 | m_to_full-> setToggleButton ( true ); | ||
119 | m_tb_tool-> addSeparator ( ); | ||
120 | new QToolButton ( Resource::loadIconSet ( "fastback" ), tr( "First page" ), QString::null, this, SLOT( firstPage ( )), m_tb_tool, "first" ); | ||
121 | new QToolButton ( Resource::loadIconSet ( "back" ), tr( "Previous page" ), QString::null, this, SLOT( prevPage ( )), m_tb_tool, "prev" ); | ||
122 | new QToolButton ( Resource::loadIconSet ( "down" ), tr( "Goto page..." ), QString::null, this, SLOT( gotoPageDialog ( )), m_tb_tool, "goto" ); | ||
123 | new QToolButton ( Resource::loadIconSet ( "forward" ), tr( "Next page" ), QString::null, this, SLOT( nextPage ( )), m_tb_tool, "next" ); | ||
124 | new QToolButton ( Resource::loadIconSet ( "fastforward" ), tr( "Last page" ), QString::null, this, SLOT( lastPage ( )), m_tb_tool, "last" ); | ||
125 | |||
126 | m_tb_find = new QToolBar ( this ); | ||
127 | addToolBar ( m_tb_find, "Search", QMainWindow::Top, true ); | ||
128 | m_tb_find-> setHorizontalStretchable ( true ); | ||
129 | m_tb_find-> hide ( ); | ||
130 | |||
131 | m_findedit = new QLineEdit ( m_tb_find, "findedit" ); | ||
132 | m_tb_find-> setStretchableWidget ( m_findedit ); | ||
133 | connect ( m_findedit, SIGNAL( textChanged ( const QString & )), this, SLOT( findText ( const QString & ))); | ||
134 | |||
135 | new QToolButton ( Resource::loadIconSet ( "next" ), tr( "Next" ), QString::null, this, SLOT( findText ( )), m_tb_find, "findnext" ); | ||
136 | |||
137 | openFile ( ); | ||
138 | } | ||
139 | |||
140 | QPdfDlg::~QPdfDlg ( ) | ||
141 | { | ||
142 | delete m_doc; | ||
143 | } | ||
144 | |||
145 | // vv Fullscreen handling (for broken QT-lib) [David Hedbor, www.eongames.com] | ||
146 | |||
147 | void QPdfDlg::resizeEvent ( QResizeEvent * ) | ||
148 | { | ||
149 | if ( m_fullscreen && ( size ( ) != qApp-> desktop ( )-> size ( ))) | ||
150 | setFullscreen ( true ); | ||
151 | } | ||
152 | |||
153 | void QPdfDlg::focusInEvent ( QFocusEvent * ) | ||
154 | { | ||
155 | if ( m_fullscreen ) | ||
156 | setFullscreen ( true ); | ||
157 | } | ||
158 | |||
159 | void QPdfDlg::toggleFullscreen ( ) | ||
160 | { | ||
161 | if ( m_to_full-> isOn ( ) == m_fullscreen ) | ||
162 | m_to_full-> setOn ( !m_fullscreen ); | ||
163 | |||
164 | m_fullscreen = !m_fullscreen; | ||
165 | setFullscreen ( m_fullscreen ); | ||
166 | } | ||
167 | |||
168 | void QPdfDlg::setFullscreen ( bool b ) | ||
169 | { | ||
170 | static QSize normalsize; | ||
171 | |||
172 | if ( b ) { | ||
173 | if ( !normalsize. isValid ( )) | ||
174 | normalsize = size ( ); | ||
175 | |||
176 | setFixedSize ( qApp-> desktop ( )-> size ( )); | ||
177 | showNormal ( ); | ||
178 | reparent ( 0, WStyle_Customize | WStyle_NoBorder, QPoint ( 0, 0 )); | ||
179 | showFullScreen ( ); | ||
180 | } | ||
181 | else { | ||
182 | showNormal ( ); | ||
183 | reparent ( 0, 0, QPoint ( 0, 0 )); | ||
184 | resize ( normalsize ); | ||
185 | showMaximized ( ); | ||
186 | normalsize = QSize ( ); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | // ^^ Fullscreen handling (for broken QT-lib) | ||
191 | |||
192 | void QPdfDlg::setBusy ( bool b ) | ||
193 | { | ||
194 | if ( b != m_busy ) { | ||
195 | m_busy = b; | ||
196 | |||
197 | m_outdev-> setBusy ( m_busy ); | ||
198 | setEnabled ( !m_busy ); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | bool QPdfDlg::busy ( ) const | ||
203 | { | ||
204 | return m_busy; | ||
205 | } | ||
206 | |||
207 | |||
208 | void QPdfDlg::updateCaption ( ) | ||
209 | { | ||
210 | QString cap = ""; | ||
211 | |||
212 | if ( !m_currentdoc. isEmpty ( )) | ||
213 | cap = QString ( "%1 - " ). arg ( m_currentdoc ); | ||
214 | cap += "QPdf"; | ||
215 | |||
216 | setCaption ( cap ); | ||
217 | } | ||
218 | |||
219 | |||
220 | void QPdfDlg::setZoom ( int id ) | ||
221 | { | ||
222 | int dpi = 0; | ||
223 | |||
224 | switch ( id ) { | ||
225 | case 1: | ||
226 | if ( m_doc && m_doc-> isOk ( )) | ||
227 | dpi = m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ); | ||
228 | break; | ||
229 | |||
230 | case 2: | ||
231 | if ( m_doc && m_doc-> isOk ( )) | ||
232 | dpi = QMIN( m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ), \ | ||
233 | m_outdev-> visibleHeight ( ) * 72 / m_doc-> getPageHeight ( m_currentpage )); | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | dpi = id * 72 / 100; | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | if ( dpi < 18 ) | ||
242 | dpi = 18; | ||
243 | if ( dpi > 216 ) | ||
244 | dpi = 216; | ||
245 | |||
246 | for ( uint i = 0; i < m_pm_zoom-> count ( ); i++ ) { | ||
247 | int xid = m_pm_zoom-> idAt ( i ); | ||
248 | m_pm_zoom-> setItemChecked ( xid, xid == id ); | ||
249 | } | ||
250 | |||
251 | if ( dpi != m_zoom ) { | ||
252 | m_zoom = dpi; | ||
253 | |||
254 | renderPage ( ); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | |||
259 | void QPdfDlg::gotoPageDialog ( ) | ||
260 | { | ||
261 | QDialog *d = new QDialog ( this, "gotodlg", true ); | ||
262 | d-> setCaption ( tr( "Goto page" )); | ||
263 | |||
264 | QBoxLayout *lay = new QVBoxLayout ( d, 4, 4 ); | ||
265 | |||
266 | QLabel *l = new QLabel ( tr( "Select from 1 .. %1:" ). arg ( m_pages ), d ); | ||
267 | lay-> addWidget ( l ); | ||
268 | |||
269 | QSpinBox *spin = new QSpinBox ( 1, m_pages, 1, d ); | ||
270 | spin-> setValue ( m_currentpage ); | ||
271 | spin-> setWrapping ( true ); | ||
272 | spin-> setButtonSymbols ( QSpinBox::PlusMinus ); | ||
273 | lay-> addWidget ( spin ); | ||
274 | |||
275 | if ( d-> exec ( ) == QDialog::Accepted ) { | ||
276 | gotoPage ( spin-> value ( )); | ||
277 | } | ||
278 | |||
279 | delete d; | ||
280 | } | ||
281 | |||
282 | void QPdfDlg::toggleFindBar ( ) | ||
283 | { | ||
284 | if ( m_to_find-> isOn ( ) == m_tb_find-> isVisible ( )) | ||
285 | m_to_find-> setOn ( !m_tb_find-> isVisible ( )); | ||
286 | |||
287 | if ( m_tb_find-> isVisible ( )) { | ||
288 | m_tb_find-> hide ( ); | ||
289 | m_outdev-> setFocus ( ); | ||
290 | } | ||
291 | else { | ||
292 | m_tb_find-> show ( ); | ||
293 | m_findedit-> setFocus ( ); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | void QPdfDlg::findText ( const QString &str ) | ||
298 | { | ||
299 | if ( !m_doc || !m_doc-> isOk ( ) || str. isEmpty ( )) | ||
300 | return; | ||
301 | |||
302 | TextOutputDev *textOut = 0; | ||
303 | int pg = 0; | ||
304 | |||
305 | setBusy ( true ); | ||
306 | |||
307 | int len = str. length ( ); | ||
308 | Unicode *u = new Unicode [len]; | ||
309 | for ( int i = 0; i < len; i++ ) | ||
310 | u [i] = str [i]. unicode ( ); | ||
311 | |||
312 | int xMin = 0, yMin = 0, xMax = 0, yMax = 0; | ||
313 | QRect selr = m_outdev-> selection ( ); | ||
314 | bool fromtop = true; | ||
315 | |||
316 | if ( selr. isValid ( )) { | ||
317 | xMin = selr. right ( ); | ||
318 | yMin = selr. top ( ) + selr. height ( ) / 2; | ||
319 | fromtop = false; | ||
320 | } | ||
321 | |||
322 | if ( m_outdev-> findText ( u, len, fromtop, true, &xMin, &yMin, &xMax, &yMax )) | ||
323 | goto found; | ||
324 | |||
325 | qApp-> processEvents ( ); | ||
326 | |||
327 | // search following pages | ||
328 | textOut = new TextOutputDev ( 0, gFalse, gFalse ); | ||
329 | if ( !textOut-> isOk ( )) | ||
330 | goto done; | ||
331 | |||
332 | qApp-> processEvents ( ); | ||
333 | |||
334 | for ( pg = ( m_currentpage % m_pages ) + 1; pg != m_currentpage; pg = ( pg % m_pages ) + 1 ) { | ||
335 | m_doc-> displayPage ( textOut, pg, 72, 0, gFalse ); | ||
336 | |||
337 | fp_t xMin1, yMin1, xMax1, yMax1; | ||
338 | |||
339 | qApp-> processEvents ( ); | ||
340 | |||
341 | if ( textOut-> findText ( u, len, gTrue, gTrue, &xMin1, &yMin1, &xMax1, &yMax1 )) | ||
342 | goto foundPage; | ||
343 | |||
344 | qApp-> processEvents ( ); | ||
345 | } | ||
346 | |||
347 | // search current page ending at current selection | ||
348 | if ( selr. isValid ( )) { | ||
349 | xMax = selr. left ( ); | ||
350 | yMax = selr. top ( ) + selr. height ( ) / 2; | ||
351 | |||
352 | if ( m_outdev-> findText ( u, len, gTrue, gFalse, &xMin, &yMin, &xMax, &yMax )) | ||
353 | goto found; | ||
354 | } | ||
355 | |||
356 | // not found | ||
357 | QMessageBox::information ( this, tr( "Find..." ), tr( "'%1' could not be found." ). arg ( str )); | ||
358 | goto done; | ||
359 | |||
360 | foundPage: | ||
361 | qApp-> processEvents ( ); | ||
362 | |||
363 | gotoPage ( pg ); | ||
364 | |||
365 | if ( !m_outdev-> findText ( u, len, gTrue, gTrue, &xMin, &yMin, &xMax, &yMax )) { | ||
366 | // this can happen if coalescing is bad | ||
367 | goto done; | ||
368 | } | ||
369 | |||
370 | found: | ||
371 | selr. setCoords ( xMin, yMin, xMax, yMax ); | ||
372 | m_outdev-> setSelection ( selr, true ); // this will emit QPEOutputDev::selectionChanged ( ) -> copyToClipboard ( ) | ||
373 | |||
374 | done: | ||
375 | |||
376 | delete [] u; | ||
377 | delete textOut; | ||
378 | |||
379 | setBusy ( false ); | ||
380 | } | ||
381 | |||
382 | |||
383 | void QPdfDlg::findText ( ) | ||
384 | { | ||
385 | findText ( m_findedit-> text ( )); | ||
386 | } | ||
387 | |||
388 | void QPdfDlg::copyToClipboard ( const QRect &r ) | ||
389 | { | ||
390 | if ( m_doc && m_doc-> isOk ( ) && m_doc-> okToCopy ( )) | ||
391 | qApp-> clipboard ( )-> setText ( m_outdev-> getText ( r )); | ||
392 | } | ||
393 | |||
394 | void QPdfDlg::firstPage ( ) | ||
395 | { | ||
396 | gotoPage ( 1 ); | ||
397 | } | ||
398 | |||
399 | void QPdfDlg::prevPage ( ) | ||
400 | { | ||
401 | gotoPage ( m_currentpage - 1 ); | ||
402 | } | ||
403 | |||
404 | void QPdfDlg::nextPage ( ) | ||
405 | { | ||
406 | gotoPage ( m_currentpage + 1 ); | ||
407 | } | ||
408 | |||
409 | void QPdfDlg::lastPage ( ) | ||
410 | { | ||
411 | gotoPage ( m_pages ); | ||
412 | } | ||
413 | |||
414 | void QPdfDlg::gotoPage ( int n ) | ||
415 | { | ||
416 | if ( n < 1 ) | ||
417 | n = 1; | ||
418 | if ( n > m_pages ) | ||
419 | n = m_pages; | ||
420 | |||
421 | if ( n != m_currentpage ) { | ||
422 | m_currentpage = n; | ||
423 | |||
424 | renderPage ( ); | ||
425 | } | ||
426 | } | ||
427 | |||
428 | void QPdfDlg::renderPage ( ) | ||
429 | { | ||
430 | if ( m_renderok && m_doc && m_doc-> isOk ( )) { | ||
431 | m_renderok = false; | ||
432 | |||
433 | setBusy ( true ); | ||
434 | m_doc-> displayPage ( m_outdev, m_currentpage, m_zoom, 0, true ); | ||
435 | setBusy ( false ); | ||
436 | |||
437 | m_outdev-> setPageCount ( m_currentpage, m_pages ); | ||
438 | |||
439 | m_renderok = true; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | void QPdfDlg::closeFileSelector ( ) | ||
444 | { | ||
445 | m_tb_menu-> show ( ); | ||
446 | m_tb_tool-> show ( ); | ||
447 | m_stack-> raiseWidget ( m_outdev ); | ||
448 | } | ||
449 | |||
450 | void QPdfDlg::openFile ( ) | ||
451 | { | ||
452 | m_tb_menu-> hide ( ); | ||
453 | m_tb_tool-> hide ( ); | ||
454 | m_tb_find-> hide ( ); | ||
455 | m_stack-> raiseWidget ( m_filesel ); | ||
456 | } | ||
457 | |||
458 | void QPdfDlg::openFile ( const QString &f ) | ||
459 | { | ||
460 | DocLnk nf; | ||
461 | nf. setType ( "application/pdf" ); | ||
462 | nf. setFile ( f ); | ||
463 | QFileInfo fi ( f ); | ||
464 | nf. setName ( fi. baseName ( )); | ||
465 | openFile ( nf ); | ||
466 | } | ||
467 | |||
468 | void QPdfDlg::openFile ( const DocLnk &f ) | ||
469 | { | ||
470 | QString fn = f. file ( ); | ||
471 | QFileInfo fi ( fn ); | ||
472 | |||
473 | if ( fi. exists ( )) { | ||
474 | delete m_doc; | ||
475 | |||
476 | m_doc = new PDFDoc ( new GString ( fn. local8Bit ( )), 0, 0 ); | ||
477 | |||
478 | if ( m_doc-> isOk ( )) { | ||
479 | m_currentdoc = f. name ( ); | ||
480 | int sep = m_currentdoc. findRev ( '/' ); | ||
481 | if ( sep > 0 ) | ||
482 | m_currentdoc = m_currentdoc. mid ( sep + 1 ); | ||
483 | |||
484 | m_pages = m_doc-> getNumPages ( ); | ||
485 | m_currentpage = 0; | ||
486 | |||
487 | QTimer::singleShot ( 0, this, SLOT( delayedInit ( ))); | ||
488 | } | ||
489 | else { | ||
490 | delete m_doc; | ||
491 | m_doc = 0; | ||
492 | |||
493 | m_currentdoc = QString::null; | ||
494 | } | ||
495 | |||
496 | updateCaption ( ); | ||
497 | } | ||
498 | else | ||
499 | QMessageBox::warning ( this, tr( "Error" ), tr( "File does not exist !" )); | ||
500 | } | ||
501 | |||
502 | void QPdfDlg::setDocument ( const QString &f ) | ||
503 | { | ||
504 | if ( f. find ( ".desktop", 0, true ) == -1 ) | ||
505 | openFile ( f ); | ||
506 | else | ||
507 | openFile ( DocLnk ( f )); | ||
508 | |||
509 | closeFileSelector ( ); | ||
510 | } | ||
511 | |||
512 | void QPdfDlg::delayedInit ( ) | ||
513 | { | ||
514 | closeFileSelector ( ); | ||
515 | |||
516 | m_currentpage = 0; | ||
517 | m_zoom = 0; | ||
518 | m_renderok = false; | ||
519 | |||
520 | setZoom ( 100 ); | ||
521 | gotoPage ( 1 ); | ||
522 | |||
523 | m_renderok = true; | ||
524 | |||
525 | renderPage ( ); | ||
526 | |||
527 | m_outdev-> setFocus ( ); | ||
528 | } | ||
529 | |||