00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 const int _SBARHEIGHT = 3;
00012
00013 #include <qpainter.h>
00014
00015 #include <qimage.h>
00016 #include <qtimer.h>
00017 #include "config.h"
00018 #include "QTReader.h"
00019
00020 #include "CDrawBuffer.h"
00021 #ifdef USEQPE
00022 #include <qpe/qpeapplication.h>
00023 #endif
00024 #include <math.h>
00025 #include <ctype.h>
00026 #include <stdio.h>
00027 #ifdef USEQPE
00028 #include <qpe/config.h>
00029 #include <qpe/applnk.h>
00030 #include <qpe/global.h>
00031 #include <qpe/qcopenvelope_qws.h>
00032 #endif
00033 #include <qfileinfo.h>
00034 #include <qdir.h>
00035 #include "TableDialog.h"
00036 #include "outputcodec.h"
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 tchar QTReader::pluckernextpart[] = { 'C','l','i','c','k',' ','h','e','r','e',' ','f','o','r',' ','t','h','e',' ','n','e','x','t',' ','p','a','r','t',0 };
00053 tchar QTReader::jplucknextpart[] = { 'N','e','x','t',' ','P','a','r','t',' ','>','>',0 };
00054
00055
00056 QTReader::QTReader( QWidget *parent, const char *name, WFlags f) :
00057 QWidget(parent, name, f | WRepaintNoErase | WResizeNoErase),
00058 m_outofdate(true),
00059 m_default_fg(0,0,0),
00060 m_default_bg(255,255,255),
00061 m_bg(255,255,255),
00062 m_delay(100),
00063 m_scrolldy1(0),
00064 m_scrolldy2(0),
00065 m_totalscroll(0),
00066 m_autoScroll(false),
00067
00068
00069 numlines(0),
00070 m_fontname("unifont"),
00071 m_fm(NULL),
00072 mouseUpOn(true),
00073 m_twotouch(true),
00074 m_touchone(true),
00075 bDoUpdates(false),
00076 #ifdef _SCROLLPIPE
00077 m_pipeout(NULL),
00078 #endif
00079 m_left_border(2),
00080 m_right_border(2),
00081 m_rotated(true),
00082 pBkmklist(NULL),
00083 m_scrollpos(0),
00084
00085 bInverse(false),
00086 m_highlightfilter(NULL),
00087 m_bgIsScaled(false),
00088 m_scrollstep(2),
00089 m_topmargin(5),
00090 m_bottommargin(5),
00091 m_reparastring("{\\n[\\n ]}"),
00092 m_currentlinkstyle(NULL),
00093 m_currentlinkoffset(-1),
00094 m_currentlink(-1)
00095 {
00096 m_output = NULL;
00097 m_overlap = 1;
00098 setKeyCompression ( true );
00099
00100 dbuff = NULL;
00101 dbp = NULL;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 long QTReader::real_delay()
00135 {
00136 return m_scrollstep*( 8976 + m_delay ) / ( m_linespacing * m_linespacing );
00137 }
00138
00139 void QTReader::mousePressEvent( QMouseEvent* _e )
00140 {
00141 m_drageligible = false;
00142 qDebug("Mouse pressed at (%u, %u)", _e->x(), _e->y());
00143 int x, y, ht, wh;
00144 if (m_rotated)
00145 {
00146 x = _e->y();
00147 y = width()-_e->x();
00148 ht = width();
00149 wh = height();
00150 }
00151 else
00152 {
00153 x = _e->x();
00154 y = _e->y();
00155 ht = height();
00156 wh = width();
00157 }
00158 if (x >= m_left_border && x <= wh - m_right_border && y >= m_topmargin && y <= ht-m_bottommargin)
00159 {
00160 if (_e->button() == RightButton)
00161 {
00162
00163 mouseUpOn = false;
00164 if (m_swapmouse)
00165 {
00166 int lineno = 0;
00167
00168
00169
00170
00171
00172
00173
00174 size_t startpos, startoffset, tgt, tgtoffset, pictgt, tabtgt;
00175 QImage* img;
00176 getcurrentpos(x, y, wh, ht, lineno, startpos, startoffset, tgt, tgtoffset, pictgt, img, tabtgt);
00177 processmousewordevent(startpos, startoffset, _e, lineno);
00178 }
00179 else
00180 {
00181 processmousepositionevent(_e);
00182 }
00183 }
00184 }
00185 else
00186 {
00187 int ln = -1;
00188 int mp;
00189 int sectionsize = (buffdoc.endSection()-buffdoc.startSection());
00190 switch (m_scrollpos)
00191 {
00192 case 1:
00193 {
00194 if (m_rotated)
00195 {
00196 if (_e->x() < m_bottommargin)
00197 {
00198 ln = height();
00199 mp = _e->y();
00200 }
00201 }
00202 else
00203 {
00204 if (_e->y() > height()-m_bottommargin)
00205 {
00206 ln = width();
00207 mp = _e->x();
00208 }
00209 }
00210 }
00211 break;
00212 case 2:
00213 {
00214 if (m_rotated)
00215 {
00216 if (_e->y() > height() - m_right_border)
00217 {
00218 ln = width();
00219 mp = width()-_e->x();
00220 }
00221 }
00222 else
00223 {
00224 if (_e->x() > width() - m_right_border)
00225 {
00226 ln = height();
00227 mp = _e->y();
00228 }
00229 }
00230 }
00231 break;
00232 case 3:
00233 {
00234 if (m_rotated)
00235 {
00236 if (_e->y() < m_left_border)
00237 {
00238 ln = width();
00239 mp = width()-_e->x();
00240 }
00241 }
00242 else
00243 {
00244 if (_e->x() < m_left_border)
00245 {
00246 ln = height();
00247 mp = _e->y();
00248 }
00249 }
00250 }
00251 break;
00252 case 0:
00253 default:
00254 ln = -1;
00255 break;
00256 }
00257 if (ln >= 0)
00258 {
00259 int dp = (sectionsize*mp+ln/2)/ln + buffdoc.startSection();
00260 int winsize = locnarray[numlines]-locnarray[0];
00261 int slidersize = 10*(sectionsize+ln/2)/ln;
00262 if (slidersize > winsize)
00263 {
00264 int mid = (locnarray[0] + locnarray[numlines])/2;
00265 slidersize /= 2;
00266 if (dp < mid-slidersize)
00267 {
00268 dopageup();
00269 }
00270 else if (dp > mid+slidersize)
00271 {
00272 dopagedn();
00273 }
00274
00275 else
00276 {
00277 m_drageligible = true;
00278 }
00279 }
00280 else
00281 {
00282 if (dp < locnarray[0])
00283 {
00284 dopageup();
00285 }
00286 else if (dp > locnarray[numlines])
00287 {
00288 dopagedn();
00289 }
00290
00291 else
00292 {
00293 m_drageligible = true;
00294 }
00295 }
00296 qDebug("Drag eligible:%s", (m_drageligible) ? "true" : "false");
00297 }
00298 else
00299 {
00300 if (m_scrollpos == 1)
00301 {
00302 if (x < m_left_border)
00303 {
00304 lineUp();
00305 }
00306 if (y > ht - m_bottommargin)
00307 {
00308 lineDown();
00309 }
00310 }
00311 else if (m_scrollpos != 0)
00312 {
00313 if (y < m_topmargin)
00314 {
00315 lineUp();
00316 }
00317 if (y > ht - m_bottommargin)
00318 {
00319 lineDown();
00320 }
00321 }
00322 }
00323 }
00324 }
00325
00326 void QTReader::processmousepositionevent( QMouseEvent* _e )
00327 {
00328 int x, y, ht, wh;
00329 if (m_rotated)
00330 {
00331 x = _e->y();
00332 y = width()-_e->x();
00333 ht = width();
00334 wh = height();
00335 }
00336 else
00337 {
00338 x = _e->x();
00339 y = _e->y();
00340 ht = height();
00341 wh = width();
00342 }
00343 if (buffdoc.hasnavigation())
00344 {
00345 if (y > (2*ht)/3)
00346 {
00347 goDown();
00348 }
00349 else if (y < ht/3)
00350 {
00351 goUp();
00352 }
00353 else
00354 {
00355 if (x < wh/3)
00356 {
00357 goBack();
00358 }
00359 else if (x > (2*wh)/3)
00360 {
00361 goForward();
00362 }
00363 else
00364 {
00365 goHome();
00366 }
00367 }
00368 }
00369 else
00370 {
00371 if (y > ht/2)
00372 {
00373 goDown();
00374 }
00375 else
00376 {
00377 goUp();
00378 }
00379 }
00380 }
00381
00382 void QTReader::goHome()
00383 {
00384 if (buffdoc.hasnavigation())
00385 {
00386 size_t current=pagelocate();
00387 size_t home=buffdoc.getHome();
00388 if (current!=home)
00389 {
00390 buffdoc.saveposn(m_lastfile, current);
00391 locate(home);
00392 }
00393 }
00394 else
00395 locate(0);
00396 }
00397
00398 void QTReader::goBack()
00399 {
00400 if (buffdoc.hasnavigation())
00401 {
00402 size_t target = pagelocate();
00403 QString nxt = m_lastfile;
00404 buffdoc.writeposn(m_lastfile, target);
00405 linkType lt = buffdoc.back(nxt, target);
00406 if ((lt & eFile) != 0)
00407 {
00408 if (nxt != m_lastfile)
00409 {
00410 emit NewFileRequest(nxt);
00411 }
00412 locate(target);
00413 }
00414 else if ((lt & eLink) != 0)
00415 {
00416 locate(target);
00417 }
00418 }
00419 }
00420
00421 void QTReader::goForward()
00422 {
00423 if (buffdoc.hasnavigation())
00424 {
00425 size_t target = pagelocate();
00426 QString nxt = m_lastfile;
00427 linkType lt = buffdoc.forward(nxt, target);
00428 if ((lt & eFile) != 0)
00429 {
00430 if (nxt != m_lastfile)
00431 {
00432 emit NewFileRequest(nxt);
00433 }
00434 locate(target);
00435 }
00436 else if ((lt & eLink) != 0)
00437 {
00438 locate(target);
00439 }
00440 }
00441 }
00442
00443 linkType QTReader::getcurrentpos(int x, int y, int w, int h, int& lineno, size_t& start, size_t& offset, size_t& tgt, size_t& tgtoffset, size_t& pictgt, QImage*& img, size_t& tabtgt)
00444 {
00445 int ht;
00446 if (m_scrolldy == m_topmargin)
00447 {
00448 lineno = 0;
00449 ht = textarray[0]->lineSpacing()-m_scrolldy1 + m_topmargin;
00450 }
00451 else
00452 {
00453 if (y >= m_scrolldy)
00454 {
00455 lineno = 0;
00456 ht = textarray[0]->lineSpacing()-m_scrolldy1+m_scrolldy + m_topmargin;
00457 }
00458 else
00459 {
00460 lineno = 0;
00461 ht = textarray[0]->lineSpacing()-m_scrolldy1+m_scrolldy+m_topmargin;
00462 while ((ht < h) && (lineno < numlines-1))
00463 {
00464 ht += textarray[++lineno]->lineSpacing();
00465 }
00466 ht = textarray[lineno]->lineSpacing();
00467 }
00468 }
00469 while ((ht < y) && (lineno < numlines-1))
00470 {
00471 ht += textarray[++lineno]->lineSpacing();
00472 }
00473 if (ht < y && textarray[numlines]->showPartial()) lineno = numlines;
00474 start = locnarray[lineno];
00475 int availht = ((m_rotated) ? width() : height()) - m_topmargin - m_bottommargin;
00476 if (m_bMonoSpaced)
00477 {
00478 offset = (x - textarray[lineno]->offset(w, m_left_border, m_right_border, availht))/m_charWidth;
00479 }
00480 else
00481 {
00482 int i;
00483 CDrawBuffer* t = textarray[lineno];
00484 x = x - t->offset(width(), m_left_border, m_right_border, availht);
00485 for (i = t->length(); i > 0 && t->width(availht, i, true, w, m_left_border, m_right_border) > x; i--);
00486 offset = i;
00487 }
00488 return textarray[lineno]->getLinkType(offset, tgt, tgtoffset, pictgt, img, tabtgt);
00489 }
00490
00491 void QTReader::suspend()
00492 {
00493 buffdoc.suspend();
00494
00495
00496
00497
00498
00499
00500 }
00501
00502 void QTReader::setDoubleBuffer(bool _b)
00503 {
00504 m_doubleBuffered = _b;
00505 if (_b || m_rotated)
00506 {
00507 if (dbuff == NULL)
00508 {
00509 dbuff = new QPixmap();
00510 dbp = new QPainter();
00511 }
00512 if (m_rotated)
00513 {
00514 dbuff->resize(height(), width());
00515 }
00516 else
00517 {
00518 dbuff->resize(width(), height());
00519 }
00520 m_outofdate = true;
00521 }
00522 else
00523 {
00524 if (dbuff != NULL)
00525 {
00526 delete dbuff;
00527 delete dbp;
00528 }
00529 dbuff = NULL;
00530 dbp = NULL;
00531 }
00532 }
00533
00534 void QTReader::setTwoTouch(bool _b)
00535 {
00536 setBackgroundColor( m_bg );
00537 m_twotouch = m_touchone = _b;
00538 }
00539
00540 void QTReader::setContinuous(bool _b)
00541 {
00542 buffdoc.setContinuous(m_continuousDocument = _b);
00543 }
00544
00545 void QTReader::processmousewordevent(size_t startpos, size_t startoffset, QMouseEvent* _e, int lineno)
00546 {
00547 unsigned long wrdstart, wrdend;
00548 QString wrd;
00549 int availht = ((m_rotated) ? width() : height()) - m_topmargin - m_bottommargin;
00550 if (m_twotouch)
00551 {
00552 if (m_touchone)
00553 {
00554 m_touchone = false;
00555 m_startpos = startpos;
00556 m_startoffset = startoffset;
00557 setBackgroundColor( lightGray );
00558 }
00559 else
00560 {
00561 m_touchone = true;
00562 setBackgroundColor( m_bg );
00563 size_t endpos, endoffset;
00564 endpos = startpos;
00565 endoffset = startoffset;
00566 size_t currentpos = locate();
00567 if (endpos >= m_startpos)
00568 {
00569 jumpto(m_startpos);
00570 for (int i = 0; i < m_startoffset; i++)
00571 {
00572 getch();
00573 }
00574 wrdstart = buffdoc.explocate();
00575 if (m_startpos == endpos)
00576 {
00577 for (int i = m_startoffset; i <= endoffset; i++)
00578 {
00579 wrd += QChar(getch());
00580 }
00581 }
00582 else
00583 {
00584 while (buffdoc.explocate() <= endpos)
00585 {
00586 wrd += QChar(getch());
00587 }
00588 for (int i = 0; i < endoffset; i++)
00589 {
00590 wrd += QChar(getch());
00591 }
00592 }
00593 wrdend = buffdoc.explocate();
00594 jumpto(currentpos);
00595 }
00596 }
00597 }
00598 else if (m_bMonoSpaced)
00599 {
00600 int chno = (m_rotated) ?
00601 (_e->y()-textarray[lineno]->offset(height(), m_left_border, m_right_border, availht))/m_charWidth
00602 :
00603 (_e->x()-textarray[lineno]->offset(width(), m_left_border, m_right_border, availht))/m_charWidth;
00604 if (chno < ustrlen(textarray[lineno]->data()))
00605 {
00606 wrd[0] = textarray[lineno]->data()[chno];
00607 }
00608 }
00609 else
00610 {
00611 CDrawBuffer* t = textarray[lineno];
00612 int first = 0;
00613 int tgt = (m_rotated) ?
00614 _e->y() - t->offset(height(), m_left_border, m_right_border, availht) :
00615 _e->x() - t->offset(width(), m_left_border, m_right_border, availht);
00616 while (1)
00617 {
00618 int i = first+1;
00619 int availht = ((m_rotated) ? width() : height()) - m_topmargin - m_bottommargin;
00620 while (QChar((*t)[i]).isLetter() && (*t)[i] != 0) i++;
00621 if (t->width(availht, i, true, (m_rotated) ? height() : width(), m_left_border, m_right_border) > tgt)
00622 {
00623 wrd = toQString(t->data()+first, i - first);
00624
00625 break;
00626 }
00627 while (!QChar((*t)[i]).isLetter() && (*t)[i] != 0) i++;
00628 if ((*t)[i] == 0) break;
00629 first = i;
00630 }
00631 }
00632 if (!wrd.isEmpty())
00633 {
00634 qDebug("Selected:%s", (const char*)wrd);
00635 if (m_twotouch)
00636 {
00637 emit OnWordSelected(wrd, wrdstart, wrdend, wrd);
00638 }
00639 else
00640 {
00641 QString line = toQString(textarray[lineno]->data());
00642 emit OnWordSelected(wrd, locnarray[lineno], locnarray[lineno]+line.length(), line);
00643 }
00644 }
00645 }
00646
00647 #ifdef USETIMER
00648 void QTReader::actionDrag()
00649 {
00650 if (m_drageligible)
00651 {
00652 int fivepages = 5*((2*width()+m_textsize/2)/m_textsize)*((height()+m_textsize/2)/m_textsize);
00653 if (m_dragtarget > fivepages && locnarray[numlines] < m_dragtarget - fivepages)
00654 {
00655 int tgt = m_dragtarget - fivepages/2;
00656
00657 if (tgt < buffdoc.startSection())
00658 {
00659 tgt = buffdoc.startSection();
00660 }
00661 locate(tgt);
00662 drawFonts();
00663 }
00664 else if (locnarray[0] > m_dragtarget+fivepages)
00665 {
00666 int tgt = m_dragtarget + fivepages/2;
00667
00668 if (tgt > buffdoc.endSection())
00669 {
00670 dopageup();
00671 }
00672 else
00673 {
00674 locate(tgt);
00675 drawFonts();
00676 }
00677 }
00678 else if (locnarray[numlines] <= m_dragtarget)
00679 {
00680 dopagedn();
00681 }
00682 else if (locnarray[0] > m_dragtarget)
00683 {
00684 dopageup();
00685 }
00686 }
00687 else
00688 {
00689 m_dragtimer->stop();
00690 }
00691 }
00692 #endif
00693
00694 void QTReader::mouseMoveEvent( QMouseEvent* _e )
00695 {
00696 if (m_drageligible)
00697 {
00698 int ht;
00699 int mp;
00700 int sectionsize = (buffdoc.endSection()-buffdoc.startSection());
00701
00702 switch (m_scrollpos)
00703 {
00704 case 1:
00705 {
00706 if (m_rotated)
00707 {
00708 ht = height();
00709 mp = _e->y();
00710 }
00711 else
00712 {
00713 ht = width();
00714 mp = _e->x();
00715 }
00716 }
00717 break;
00718 case 2:
00719 case 3:
00720 {
00721 if (m_rotated)
00722 {
00723 ht = width();
00724 mp = width()-_e->x();
00725 }
00726 else
00727 {
00728 ht = height();
00729 mp = _e->y();
00730 }
00731 }
00732 break;
00733 case 0:
00734 default:
00735 ht = -1;
00736 break;
00737 }
00738 if (ht >= 0)
00739 {
00740 #ifdef USETIMER
00741 m_dragtarget = (sectionsize*mp+ht/2)/ht + buffdoc.startSection();
00742 if (!m_dragtimer->isActive())
00743 {
00744 m_dragtimer->start(0, false);
00745 }
00746 #else
00747 int dp = (sectionsize*mp+ht/2)/ht + buffdoc.startSection();
00748 locate(dp);
00749 #endif
00750 }
00751 }
00752 }
00753
00754 void QTReader::mouseReleaseEvent( QMouseEvent* _e )
00755 {
00756 qDebug("Mouse released at (%u, %u)", _e->x(), _e->y());
00757 if (m_drageligible)
00758 {
00759 m_drageligible = false;
00760 }
00761 else
00762 {
00763 int x, y, ht, wh;
00764 if (m_rotated)
00765 {
00766 x = _e->y();
00767 y = width()-_e->x();
00768 ht = width();
00769 wh = height();
00770 }
00771 else
00772 {
00773 x = _e->x();
00774 y = _e->y();
00775 ht = height();
00776 wh = width();
00777 }
00778 if (_e->button() == LeftButton)
00779 {
00780 if (mouseUpOn)
00781 {
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 if (textarray[0] != NULL)
00813 {
00814 QString line;
00815
00816 int lineno = 0;
00817
00818
00819
00820
00821
00822
00823
00824 size_t startpos, startoffset, tgt, tgtoffset, pictgt, tabtgt;
00825 QImage* img;
00826 if (m_currentlinkstyle != NULL)
00827 {
00828 textarray[m_currentlink]->invertLink(m_currentlinkoffset);
00829 m_currentlinkstyle = NULL;
00830 m_currentlink = -1;
00831 m_currentlinkoffset = -1;
00832 }
00833 linkType glt = getcurrentpos(x, y, wh, ht, lineno, startpos, startoffset, tgt, tgtoffset, pictgt, img, tabtgt);
00834 if (bNoInlineTables && ((glt & eTable) != 0))
00835 {
00836 size_t currentpos = locate();
00837 QString tabtext = buffdoc.getTableAsHtml(tabtgt);
00838 qDebug("TABLE:%u:%u:%s", currentpos, tabtgt, (const char*)tabtext);
00839 QFont f(m_fontname, m_fontControl.currentsize());
00840 #ifdef USEQPE
00841 CTableDialog td(f, tabtext, true, this);
00842 #else
00843 CTableDialog td(f, tabtext, false, this);
00844 #endif
00845 td.exec();
00846 jumpto(currentpos);
00847 }
00848 if ((glt & eLink) != 0)
00849 {
00850 if ((glt & ePicture) != 0)
00851 {
00852 qDebug("Big Picture:%x", pictgt);
00853 if (QMessageBox::warning(this, PROGNAME, "Show picture or goto link?", "Show", "Goto Link") == 0)
00854 {
00855 QImage* pm = buffdoc.getPicture(pictgt);
00856 if (pm != NULL)
00857 {
00858 emit OnShowPicture(*pm);
00859 delete pm;
00860 return;
00861 }
00862 }
00863 }
00864 else if (img != NULL)
00865 {
00866 if (QMessageBox::warning(this, PROGNAME, "Show picture or goto link?", "Show", "Goto Link") == 0)
00867 {
00868 emit OnShowPicture(*img);
00869 return;
00870 }
00871 }
00872 size_t saveposn = pagelocate();
00873 QString href, nm;
00874 linkType lt = buffdoc.hyperlink(tgt, tgtoffset, href, nm);
00875 qDebug("URL(1):%s", (const char*)href);
00876 if ((lt & eFile) != 0)
00877 {
00878 buffdoc.saveposn(m_lastfile, saveposn);
00879 #ifdef USEQPE
00880 {
00881 QCopEnvelope e("QPE/System", "busy()");
00882 }
00883 #endif
00884 ResetScroll();
00885 if (!href.isEmpty())
00886 {
00887 if (!buffdoc.getFile(href, nm))
00888 {
00889 emit NewFileRequest(href);
00890 }
00891 else
00892 {
00893 qDebug("BEFORE:%u", pagelocate());
00894 buffdoc.resetPos();
00895 ResetScroll();
00896 fillbuffer();
00897 qDebug("AFTER:%u", pagelocate());
00898 m_outofdate = true;
00899 update();
00900 }
00901 }
00902 if (!nm.isEmpty())
00903 {
00904 qDebug("QTReader:Finding %s", (const char*)nm);
00905 if (buffdoc.findanchor(nm))
00906 {
00907 buffdoc.resetPos();
00908 fillbuffer();
00909 m_outofdate = true;
00910 update();
00911 }
00912 }
00913
00914
00915 #ifdef USEQPE
00916 {
00917 QCopEnvelope e("QPE/System", "notBusy()");
00918 }
00919 #endif
00920 }
00921 else if ((lt & eLink) != 0)
00922 {
00923 buffdoc.saveposn(m_lastfile, saveposn);
00924 ResetScroll();
00925 fillbuffer();
00926 m_outofdate = true;
00927 update();
00928 }
00929 else
00930 {
00931 if ((lt & ePicture) != 0)
00932 {
00933 QImage* pm = buffdoc.getPicture(tgt);
00934 if (pm != NULL)
00935 {
00936 emit OnShowPicture(*pm);
00937 delete pm;
00938 }
00939 }
00940 else
00941 {
00942
00943 if (!href.isEmpty())
00944 {
00945 emit OnURLSelected(href, tgt);
00946 }
00947 }
00948 }
00949 return;
00950 }
00951 else if ((glt & ePicture) != 0)
00952 {
00953 qDebug("Big Picture:%x", pictgt);
00954 QImage* pm = buffdoc.getPicture(pictgt);
00955 if (pm != NULL)
00956 {
00957 emit OnShowPicture(*pm);
00958 delete pm;
00959 }
00960 else
00961 {
00962 update();
00963 }
00964 return;
00965 }
00966 else if (img != NULL)
00967 {
00968 emit OnShowPicture(*img);
00969 return;
00970 }
00971 if (m_swapmouse)
00972 processmousepositionevent(_e);
00973 else
00974 processmousewordevent(startpos, startoffset, _e, lineno);
00975 }
00976 }
00977 else
00978 {
00979 mouseUpOn = true;
00980 }
00981 }
00982 }
00983 }
00984
00985 void QTReader::focusInEvent(QFocusEvent* e)
00986 {
00987 if (m_autoScroll && (m_scrolltype != 4)) timer->start(real_delay(), false);
00988 update();
00989 }
00990
00991 void QTReader::focusOutEvent(QFocusEvent* e)
00992 {
00993 if (m_autoScroll)
00994 {
00995 if (m_scrolltype != 4)
00996 {
00997 timer->stop();
00998 }
00999 else
01000 {
01001 m_autoScroll = false;
01002 }
01003
01004 }
01005 }
01006
01007 #include <qapplication.h>
01008 #include <qdrawutil.h>
01009 #ifndef _WINDOWS
01010 #include <unistd.h>
01011 #endif
01012
01013 void QTReader::goDown()
01014 {
01015 if (m_bpagemode)
01016 {
01017 dopagedn();
01018 }
01019 else
01020 {
01021 lineDown();
01022 }
01023 }
01024
01025 void QTReader::goUp()
01026 {
01027 if (m_bpagemode)
01028 {
01029 dopageup();
01030 }
01031 else
01032 {
01033 lineUp();
01034 }
01035 }
01036
01037 void QTReader::NavUp()
01038 {
01039 if (buffdoc.hasnavigation())
01040 {
01041
01042
01043
01044
01045
01046
01047
01048 locate(buffdoc.startSection());
01049 }
01050 else
01051 {
01052 goUp();
01053 }
01054 }
01055
01056 void QTReader::NavDown()
01057 {
01058 if (buffdoc.hasnavigation())
01059 {
01060
01061
01062
01063
01064
01065
01066
01067 dopageup(buffdoc.endSection());
01068 }
01069 else
01070 {
01071 goDown();
01072 }
01073 }
01074
01075 void QTReader::zoomin()
01076 {
01077 if (m_fontControl.increasesize())
01078 {
01079 bool sc = m_autoScroll;
01080 setautoscroll(false);
01081 setfont();
01082 refresh();
01083 setautoscroll(sc);
01084 }
01085 }
01086
01087 void QTReader::zoomout()
01088 {
01089 if (m_fontControl.decreasesize())
01090 {
01091 bool sc = m_autoScroll;
01092 setautoscroll(false);
01093 setfont();
01094 refresh();
01095 setautoscroll(sc);
01096 }
01097 }
01098
01099 void QTReader::reduceScroll()
01100 {
01101 if (m_delay < 59049)
01102 {
01103 m_delay = (3*m_delay)/2;
01104 timer->changeInterval(real_delay());
01105 }
01106 else
01107 {
01108 m_delay = 59049;
01109 }
01110 }
01111
01112 void QTReader::increaseScroll()
01113 {
01114 if (m_delay > 454)
01115 {
01116 m_delay = (2*m_delay)/3;
01117 timer->changeInterval(real_delay());
01118 }
01119 else
01120 {
01121 m_delay = 454;
01122 }
01123 }
01124
01125 void QTReader::keyPressEvent(QKeyEvent* e)
01126 {
01127
01128
01129 emit HandleKeyRequest(e);
01130
01131 return;
01132 #ifdef _SCROLLPIPE
01133 if (m_isPaused)
01134 {
01135 m_isPaused = false;
01136 if (e->key() != Key_Space)
01137 {
01138 m_autoScroll = false;
01139 if (m_pipeout != NULL)
01140 {
01141 pclose(m_pipeout);
01142 m_pipeout = NULL;
01143 }
01144
01145 emit SetScrollState(m_autoScroll);
01146 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
01147 }
01148 else
01149 {
01150 timer->start(real_delay(), false);
01151 }
01152 e->accept();
01153 return;
01154 }
01155 #endif
01156 }
01157
01158 void QTReader::CalculateScrollParameters()
01159 {
01160 int bmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
01161 if (bmargin < m_bottommargin) bmargin = m_bottommargin;
01162 switch (m_scrolltype)
01163 {
01164 case 0:
01165 {
01166 if (m_scrolldy == m_topmargin)
01167 {
01168 m_scrolldy1 = 0;
01169 m_scrolldy2 = 0;
01170 m_totalscroll = 0;
01171 return;
01172 }
01173 if (m_scrolldy < textarray[0]->lineSpacing())
01174 {
01175 m_scrolldy2 = m_scrolldy;
01176 return;
01177 }
01178 int ht = m_scrolldy - m_scrolldy1;
01179 int i;
01180 for (i = 0; (ht < ((m_rotated) ? width() : height())-bmargin) && (i < numlines); i++)
01181 {
01182 ht += textarray[i]->lineSpacing();
01183 }
01184 ht = 0;
01185 int j;
01186 i--;
01187 for (j = i; j < numlines; j++)
01188 {
01189 ht += textarray[j]->lineSpacing();
01190 }
01191 ht -= (
01192 textarray[i]->lineExtraSpacing()
01193 +
01194 (i != 0) ? textarray[numlines-1]->lineExtraSpacing() : 0
01195 )/2-2;
01196
01197 m_scrolldy2 = m_scrolldy-ht;
01198 }
01199 break;
01200 case 1:
01201 case 2:
01202 case 3:
01203 {
01204 int ypos = m_topmargin;
01205 for (int i = 0; i < numlines; i++)
01206 {
01207 ypos += textarray[i]->lineSpacing();
01208 }
01209 ypos -= (
01210 textarray[0]->lineExtraSpacing()
01211 +
01212 ((numlines > 1) ? textarray[numlines-1]->lineExtraSpacing() : 0)
01213 )/2 +
01214 m_scrolldy1 - 2;
01215 m_scrolldy2 = ((m_rotated) ? width() : height()) - ypos - bmargin;
01216 }
01217 break;
01218 }
01219 }
01220
01221 void QTReader::setautoscroll(bool _sc)
01222 {
01223 m_outofdate = true;
01224 if (_sc == m_autoScroll) return;
01225 if (m_autoScroll)
01226 {
01227 m_autoScroll = false;
01228 #ifdef USEQPE
01229 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
01230 #endif
01231 #ifdef _SCROLLPIPE
01232 if (m_pipeout != NULL)
01233 {
01234 pclose(m_pipeout);
01235 m_pipeout = NULL;
01236 }
01237 #endif
01238
01239
01240 }
01241 else
01242 {
01243 CDrawBuffer* reusebuffer = textarray[numlines];
01244 if (reusebuffer == NULL || reusebuffer->eof()) return;
01245 #ifndef __STATIC
01246 if ((m_scrolltype == 4) && !checkoutput()) return;
01247 #endif
01248 m_autoScroll = true;
01249 CalculateScrollParameters();
01250
01251 #ifdef _SCROLLPIPE
01252 if (!m_pipetarget.isEmpty())
01253 {
01254
01255 m_pipeout = popen((const char*)m_pipetarget, "w");
01256 m_isPaused = false;
01257 }
01258 #endif
01259 autoscroll();
01260 #ifdef USEQPE
01261 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Disable;
01262 #endif
01263 }
01264 }
01265
01266 bool QTReader::getline(CDrawBuffer *buff)
01267 {
01268 bool bRet;
01269 int availht = ((m_rotated) ? width() : height()) - m_topmargin - m_bottommargin;
01270 if (m_bMonoSpaced)
01271 {
01272 bRet = buffdoc.getline(buff ,(m_rotated) ? height() : width(), m_charWidth, m_left_border, m_right_border, availht);
01273 }
01274 else
01275 {
01276 bRet = buffdoc.getline(buff, (m_rotated) ? height() : width(), m_left_border, m_right_border, hyphenate, availht);
01277 }
01278 buff->resize(availht);
01279 return bRet;
01280 }
01281
01282 void QTReader::doscroll()
01283 {
01284 if (!m_autoScroll)
01285 {
01286 timer->stop();
01287 return;
01288 }
01289 switch (m_scrolltype)
01290 {
01291 case 0:
01292 doinplacescroll();
01293 break;
01294 case 1:
01295 dorollingscroll(false);
01296 break;
01297 case 2:
01298 dorollingscroll(true);
01299 break;
01300 case 3:
01301 dostaticscroll();
01302 break;
01303 }
01304 }
01305
01306 void QTReader::doinplacescroll()
01307 {
01308 QPainter p( this );
01309
01310 int wh, ht;
01311 int bmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
01312 if (bmargin < m_bottommargin) bmargin = m_bottommargin;
01313 if (m_rotated)
01314 {
01315 ht = width()-bmargin;
01316 wh = height();
01317 }
01318 else
01319 {
01320 ht = height()-bmargin;
01321 wh = width();
01322 }
01323 int lastdy = m_scrolldy;
01324 m_scrolldy += m_scrollstep;
01325 if ((m_scrolldy1 = m_scrolldy1+m_scrollstep) >= textarray[0]->lineSpacing())
01326 {
01327 int ht = textarray[0]->lineSpacing();
01328 #ifdef _SCROLLPIPE
01329 if (m_pipeout != NULL)
01330 {
01331 QString outstr = toQString(textarray[0]->data());
01332 if (!outstr.isEmpty())
01333 {
01334 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01335 fflush(m_pipeout);
01336 }
01337 else if (m_pauseAfterEachPara)
01338 {
01339 m_isPaused = true;
01340 timer->stop();
01341 }
01342 }
01343 #endif
01344 CDrawBuffer* buff = textarray[0];
01345 for (int i = 1; i <= numlines; i++)
01346 {
01347 textarray[i-1] = textarray[i];
01348 locnarray[i-1] = locnarray[i];
01349 }
01350 textarray[numlines] = buff;
01351 --numlines;
01352 m_scrolldy1 -= ht;
01353 }
01354 if ((m_scrolldy2 = m_scrolldy2+m_scrollstep) >= textarray[numlines]->lineSpacing())
01355 {
01356 m_scrolldy2 -= textarray[numlines]->lineSpacing();
01357 numlines++;
01358
01359 if (textarray[numlines] == NULL)
01360 {
01361 textarray[numlines] = new CDrawBuffer(&m_fontControl);
01362 }
01363 locnarray[numlines] = locate();
01364 int ch = getline(textarray[numlines]);
01365 if (m_rotated)
01366 {
01367 blitRot(width()-m_scrolldy, 0, height(), -1, textarray[numlines-1]);
01368 }
01369 else
01370 {
01371 if (m_bgpm.isNull())
01372 {
01373 p.fillRect(m_left_border,m_scrolldy-textarray[numlines-1]->lineSpacing(),width()-(m_left_border+m_right_border),textarray[numlines-1]->lineSpacing(),m_bg);
01374 }
01375 else
01376 {
01377 int h_tmp = textarray[numlines-1]->lineSpacing();
01378 bitBlt(this, m_left_border, m_scrolldy-h_tmp, dbuff, m_left_border, m_scrolldy-h_tmp, width()-(m_left_border+m_right_border), h_tmp);
01379 }
01380 textarray[numlines-1]->render(&p, m_scrolldy -textarray[numlines-1]->lineSpacing()+ textarray[numlines-1]->ascent(), m_bMonoSpaced, m_charWidth, width(), m_left_border, m_right_border, m_bg, height()-m_topmargin-m_bottommargin);
01381 }
01382 mylastpos = locate();
01383 if (!ch)
01384 {
01385 m_scrolldy = m_topmargin;
01386 m_autoScroll = false;
01387 #ifdef _SCROLLPIPE
01388 for (int i = 0; i < numlines; i++)
01389 {
01390 if (m_pipeout != NULL)
01391 {
01392 QString outstr = toQString(textarray[i]->data());
01393 if (!outstr.isEmpty())
01394 {
01395 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01396 fflush(m_pipeout);
01397 }
01398 }
01399 }
01400 #endif
01401 emit SetScrollState(m_autoScroll);
01402 #ifdef USEQPE
01403 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
01404 #endif
01405 }
01406 if (m_scrolldy > ht-textarray[numlines]->lineSpacing())
01407 {
01408 if (m_rotated)
01409 {
01410 if (m_bgpm.isNull())
01411 {
01412 p.fillRect(bmargin, m_left_border, ht-m_scrolldy, wh-(m_left_border+m_right_border), m_bg);
01413 }
01414 else
01415 {
01416 blitRot(bmargin, 0,height(), ht-m_scrolldy, NULL);
01417 }
01418 }
01419 else
01420 if (m_bgpm.isNull())
01421 {
01422 p.fillRect(m_left_border,m_scrolldy,width()-(m_left_border+m_right_border),height()-m_scrolldy,m_bg);
01423 }
01424 else
01425 {
01426 bitBlt(this,m_left_border,m_scrolldy,dbuff,m_left_border,m_scrolldy,width()-(m_left_border+m_right_border), height()-m_scrolldy);
01427 }
01428 m_scrolldy = m_topmargin;
01429 m_scrolldy2 = 0;
01430 }
01431 redrawScroll(&p);
01432 emitRedraw();
01433 lastdy = -1;
01434 }
01435
01436 {
01437 if (m_rotated)
01438 {
01439 if (lastdy >= 0)
01440 {
01441 if (m_bgpm.isNull())
01442 {
01443 p.fillRect(width()-lastdy, m_left_border, m_scrollstep, wh-(m_left_border+m_right_border),m_bg);
01444 }
01445 else
01446 {
01447 blitRot(width()-lastdy,m_left_border,wh-(m_left_border+m_right_border), m_scrollstep, NULL);
01448 }
01449 }
01450 p.fillRect(width()-m_scrolldy, m_left_border, 1,wh-(m_left_border+m_right_border),m_scrollcolor);
01451 }
01452 else
01453 {
01454 if (lastdy >= 0)
01455 {
01456 if (m_bgpm.isNull())
01457 {
01458 p.fillRect(m_left_border,lastdy,width()-(m_left_border+m_right_border),m_scrollstep,m_bg);
01459 }
01460 else
01461 {
01462 bitBlt(this, m_left_border, lastdy, dbuff, m_left_border, lastdy, width()-(m_left_border+m_right_border), m_scrollstep);
01463 }
01464 }
01465 p.fillRect(m_left_border,m_scrolldy,width()-(m_left_border+m_right_border),1,m_scrollcolor);
01466 }
01467 }
01468 }
01469
01470 void QTReader::dorollingscroll(bool _statbord)
01471 {
01472 bool bredrawscroll = false;
01473 QPainter p( this );
01474
01475 int tmargin = (_statbord) ? m_topmargin : 0;
01476 int lmargin = (m_scrollpos == 3 || _statbord) ? m_left_border : 0;
01477 int rmargin = (m_scrollpos == 2 || _statbord) ? m_right_border : 0;
01478 int hmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
01479 if (hmargin < m_bottommargin) hmargin = m_bottommargin;
01480 if (m_rotated)
01481 {
01482 m_totalscroll = (m_totalscroll+m_scrollstep) % width();
01483 bitBlt(this, m_scrollstep+hmargin, lmargin, this, hmargin, lmargin, width()-tmargin-hmargin, height()-(lmargin+rmargin));
01484 if (!m_bgpm.isNull())
01485 {
01486 blitRot(hmargin, tmargin, height(), m_scrollstep, NULL);
01487 }
01488 else
01489 {
01490 p.fillRect(hmargin, rmargin, m_scrollstep, height()-lmargin-rmargin, m_bg);
01491 }
01492 }
01493 else
01494 {
01495 m_totalscroll = (m_totalscroll+m_scrollstep) % height();
01496 bitBlt(this,lmargin,tmargin,this,lmargin,tmargin+m_scrollstep,width()-(lmargin+rmargin),height() - tmargin - hmargin - m_scrollstep);
01497 if (m_bgpm.isNull())
01498 {
01499 p.fillRect(0, height() - (m_scrollstep+1) - hmargin, width(), (m_scrollstep+1), m_bg);
01500 }
01501 else
01502 {
01503 int loff = (_statbord) ? 0 : m_totalscroll;
01504 bitBlt(this,0,height() - (m_scrollstep+1) - hmargin, dbuff, 0, (loff+height() - (m_scrollstep+1) - hmargin) % height(), width(), (m_scrollstep+1));
01505 }
01506 }
01507
01508 if ((m_scrolldy1 = m_scrolldy1+m_scrollstep) >= textarray[0]->lineSpacing())
01509 {
01510 int ht = textarray[0]->lineSpacing();
01511 bredrawscroll = true;
01512 #ifdef _SCROLLPIPE
01513 if (m_pipeout != NULL)
01514 {
01515 QString outstr = toQString(textarray[0]->data());
01516 if (!outstr.isEmpty())
01517 {
01518 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01519 fflush(m_pipeout);
01520 }
01521 else if (m_pauseAfterEachPara)
01522 {
01523 m_isPaused = true;
01524 timer->stop();
01525 }
01526 }
01527 #endif
01528 CDrawBuffer* buff = textarray[0];
01529 for (int i = 1; i <= numlines; i++)
01530 {
01531 textarray[i-1] = textarray[i];
01532 locnarray[i-1] = locnarray[i];
01533 }
01534 textarray[numlines] = buff;
01535 --numlines;
01536 m_scrolldy1 -= ht;
01537 }
01538 if ((m_scrolldy2 = m_scrolldy2+m_scrollstep) >= textarray[numlines]->lineSpacing())
01539 {
01540 bredrawscroll = true;
01541 m_scrolldy2 -= textarray[numlines]->lineSpacing();
01542 numlines++;
01543
01544 if (textarray[numlines] == NULL)
01545 {
01546 textarray[numlines] = new CDrawBuffer(&m_fontControl);
01547 }
01548 locnarray[numlines] = locate();
01549 int ch = getline(textarray[numlines]);
01550 if (m_rotated)
01551 {
01552 blitRot(hmargin, 0, height(), -1, textarray[numlines-1]);
01553 }
01554 else
01555 {
01556
01557 textarray[numlines-1]->render(&p, height() - textarray[numlines-1]->descent() - textarray[numlines-1]->lineExtraSpacing() - 1 - hmargin, m_bMonoSpaced, m_charWidth, width(), m_left_border, m_right_border, m_bg, height()-m_topmargin-m_bottommargin);
01558
01559 }
01560 mylastpos = locate();
01561 if (!ch)
01562 {
01563 redrawScroll(&p);
01564 emitRedraw();
01565 m_autoScroll = false;
01566 #ifdef _SCROLLPIPE
01567 for (int i = 0; i < numlines; i++)
01568 {
01569 if (m_pipeout != NULL)
01570 {
01571 QString outstr = toQString(textarray[i]->data());
01572 if (!outstr.isEmpty())
01573 {
01574 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01575 fflush(m_pipeout);
01576 }
01577 }
01578 }
01579 #endif
01580 emit SetScrollState(m_autoScroll);
01581 #ifdef USEQPE
01582 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
01583 #endif
01584 return;
01585 }
01586 }
01587 if (!bredrawscroll && ((m_scrolldy2/m_scrollstep) % 10 == 5) && textarray[numlines]->showPartial())
01588 {
01589 if (m_rotated)
01590 {
01591 blitRot(hmargin + m_scrolldy2 - textarray[numlines]->lineSpacing(), 0, height(), -1, textarray[numlines]);
01592 }
01593 else
01594 {
01595 textarray[numlines]->render( &p, height() + textarray[numlines]->lineSpacing() - textarray[numlines]->descent() - 2 - hmargin-m_scrolldy2, m_bMonoSpaced, m_charWidth, width(), m_left_border, m_right_border, m_bg, height()-m_topmargin-m_bottommargin);
01596 }
01597 }
01598 if (m_scrollpos != 0)
01599 {
01600 redrawScroll(&p);
01601 }
01602 if (bredrawscroll) emitRedraw();
01603 }
01604
01605 void QTReader::dostaticscroll()
01606 {
01607 redrawall();
01608 bool bredraw = false;
01609 if ((m_scrolldy1 = m_scrolldy1+m_scrollstep) >= textarray[0]->lineSpacing())
01610 {
01611 int ht = textarray[0]->lineSpacing();
01612 bredraw = true;
01613 #ifdef _SCROLLPIPE
01614 if (m_pipeout != NULL)
01615 {
01616 QString outstr = toQString(textarray[0]->data());
01617 if (!outstr.isEmpty())
01618 {
01619 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01620 fflush(m_pipeout);
01621 }
01622 else if (m_pauseAfterEachPara)
01623 {
01624 m_isPaused = true;
01625 timer->stop();
01626 }
01627 }
01628 #endif
01629 CDrawBuffer* buff = textarray[0];
01630 for (int i = 1; i <= numlines; i++)
01631 {
01632 textarray[i-1] = textarray[i];
01633 locnarray[i-1] = locnarray[i];
01634 }
01635 textarray[numlines] = buff;
01636 --numlines;
01637 m_scrolldy1 -= ht;
01638 }
01639 if ((m_scrolldy2 = m_scrolldy2 + m_scrollstep) >= textarray[numlines]->lineSpacing())
01640 {
01641 bredraw = true;
01642 m_scrolldy2 -= textarray[numlines]->lineSpacing();
01643 numlines++;
01644
01645 if (textarray[numlines] == NULL)
01646 {
01647 textarray[numlines] = new CDrawBuffer(&m_fontControl);
01648 }
01649 locnarray[numlines] = locate();
01650 int ch = getline(textarray[numlines]);
01651 mylastpos = locate();
01652 if (!ch)
01653 {
01654 redrawall();
01655 emitRedraw();
01656 m_autoScroll = false;
01657 #ifdef _SCROLLPIPE
01658 for (int i = 0; i < numlines; i++)
01659 {
01660 if (m_pipeout != NULL)
01661 {
01662 QString outstr = toQString(textarray[i]->data());
01663 if (!outstr.isEmpty())
01664 {
01665 fprintf(m_pipeout, "%s\n", (const char*)outstr);
01666 fflush(m_pipeout);
01667 }
01668 }
01669 }
01670 #endif
01671 emit SetScrollState(m_autoScroll);
01672 #ifdef USEQPE
01673 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
01674 #endif
01675 return;
01676 }
01677 }
01678 if (bredraw) emitRedraw();
01679 }
01680
01681 void QTReader::redrawScroll(QPainter* p)
01682 {
01683 int offset = (m_scrolltype == 1) ? m_totalscroll : 0;
01684 switch (m_scrollpos)
01685 {
01686 case 1:
01687 {
01688 int hmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
01689 if (hmargin < m_bottommargin) hmargin = m_bottommargin;
01690 if (m_rotated)
01691 {
01692 if (m_bgpm.isNull())
01693 {
01694 p->fillRect(0,0,hmargin,height(),m_bg);
01695 }
01696 else
01697 {
01698 blitRot(0,0, height(), hmargin, NULL);
01699 }
01700 }
01701 else
01702 {
01703 if (m_bgpm.isNull())
01704 {
01705 p->fillRect(0,height() - hmargin,width(),hmargin,m_bg);
01706 }
01707 else
01708 {
01709 int toffset = (offset+height()-hmargin) % height();
01710 if (toffset+hmargin > height())
01711 {
01712 int fp = height()-toffset;
01713 bitBlt(this,
01714 0,height() - hmargin,
01715 dbuff,
01716 0, toffset, width(), fp);
01717 bitBlt(this,
01718 0,height()-hmargin+fp,
01719 dbuff,
01720 0, 0, width(), hmargin-fp);
01721 }
01722 else
01723 {
01724 bitBlt(this,
01725 0,height() - hmargin,
01726 dbuff,
01727 0, toffset, width(), hmargin);
01728 }
01729 }
01730 }
01731 }
01732 break;
01733 case 2:
01734 if (m_rotated)
01735 {
01736 if (m_bgpm.isNull())
01737 {
01738 p->fillRect(0,height()-m_right_border,width(),m_right_border,m_bg);
01739 }
01740 else
01741 {
01742 blitRot(0,height()-m_right_border, m_right_border, width(), NULL);
01743 }
01744 }
01745 else
01746 {
01747 if (m_bgpm.isNull())
01748 {
01749 p->fillRect(width()-m_right_border,0,m_right_border,height(),m_bg);
01750 }
01751 else
01752 {
01753 int x = width() - m_right_border;
01754 int fp = height()-offset;
01755 bitBlt(this, x, 0, dbuff, x, offset, m_right_border, fp);
01756 bitBlt(this, x, fp, dbuff, x, 0, m_right_border, height()-fp);
01757 }
01758 }
01759 break;
01760 case 3:
01761 if (m_rotated)
01762 {
01763 if (m_bgpm.isNull())
01764 {
01765 p->fillRect(0,0,width(),m_left_border,m_bg);
01766 }
01767 else
01768 {
01769 blitRot(0,0, m_left_border, width(), NULL);
01770 }
01771 }
01772 else
01773 {
01774 if (m_bgpm.isNull())
01775 {
01776 p->fillRect(0,0,m_left_border,height(),m_bg);
01777 }
01778 else
01779 {
01780 int fp = height()-offset;
01781 bitBlt(this, 0, 0, dbuff, 0, offset, m_left_border, fp);
01782 bitBlt(this, 0, fp, dbuff, 0, 0, m_left_border, height()-fp);
01783 }
01784 }
01785 break;
01786 case 0:
01787 default:
01788 break;
01789 }
01790 if (m_scrollpos != 0) DrawScroll(p, width(), height());
01791 }
01792
01793 void QTReader::autoscroll()
01794 {
01795 if (m_scrolltype == 4)
01796 {
01797 readAloud();
01798 }
01799 else
01800 {
01801 if (dbuff != NULL)
01802 {
01803 dbp->begin(dbuff);
01804 drawBackground(dbp);
01805 dbp->end();
01806 }
01807 timer->start(real_delay(), false);
01808 }
01809 }
01810
01811 void QTReader::setfont()
01812 {
01813
01814 m_charWidth = (m_charpc*m_fontControl.currentsize())/100;
01815 if (m_charWidth <= 0) m_charWidth = 1;
01816 m_ascent = m_fontControl.ascent();
01817 m_descent = m_fontControl.descent();
01818 m_linespacing = m_fontControl.lineSpacing();
01819 }
01820
01821 void QTReader::DrawStraight(QPainter* p, int w, int h)
01822 {
01823 if (m_scrolldy == m_topmargin)
01824 {
01825 int ypos = textarray[0]->ascent()-m_scrolldy1+m_topmargin;
01826 textarray[0]->render( p, ypos, m_bMonoSpaced, m_charWidth, w, m_left_border, m_right_border, m_bg, h-m_topmargin-m_bottommargin);
01827 int i;
01828 for (i = 1; i < numlines; i++)
01829 {
01830 ypos += (textarray[i-1]->descent() + textarray[i]->ascent())+
01831 (textarray[i-1]->lineExtraSpacing() + textarray[i]->lineExtraSpacing())/2;
01832 textarray[i]->render( p, ypos, m_bMonoSpaced, m_charWidth, w, m_left_border, m_right_border, m_bg, h-m_topmargin-m_bottommargin);
01833 }
01834 if (textarray[i]->showPartial())
01835 {
01836 ypos += (textarray[i-1]->descent() + textarray[i]->ascent())+
01837 (textarray[i-1]->lineExtraSpacing() + textarray[i]->lineExtraSpacing())/2;
01838 textarray[i]->render( p, ypos, m_bMonoSpaced, m_charWidth, w, m_left_border, m_right_border, m_bg, h-m_topmargin-m_bottommargin);
01839 }
01840 }
01841 else
01842 {
01843 int ypos = textarray[0]->ascent()-m_scrolldy1+m_scrolldy+m_topmargin;
01844 textarray[0]->render( p, ypos, m_bMonoSpaced, m_charWidth, w, m_left_border, m_right_border, m_bg, h-m_topmargin-m_bottommargin);
01845
01846 for (int i = 1; i < numlines; i++)
01847 {
01848 ypos += (textarray[i-1]->descent() + textarray[i]->ascent())+
01849 (textarray[i-1]->lineExtraSpacing() + textarray[i]->lineExtraSpacing())/2;
01850 if (ypos+textarray[i]->descent() > h)
01851 {
01852 ypos = textarray[i]->ascent();
01853 }
01854 textarray[i]->render( p, ypos, m_bMonoSpaced, m_charWidth, w, m_left_border, m_right_border, m_bg, h-m_topmargin-m_bottommargin);
01855 }
01856 p->fillRect(m_left_border,m_scrolldy,w-(m_left_border+m_right_border),1,m_scrollcolor);
01857 }
01858 bool wasrotated = m_rotated;
01859 m_rotated = false;
01860 DrawScroll(p, w, h);
01861 m_rotated = wasrotated;
01862
01863 }
01864
01865 void QTReader::redrawall()
01866 {
01867 if (m_rotated)
01868 {
01869 if (dbuff != NULL)
01870 {
01871 dbp->begin(dbuff);
01872 drawBackground(dbp);
01873 DrawStraight(dbp, height(), width());
01874 dbp->end();
01875
01876 QWMatrix m;
01877 m.rotate(90);
01878 QPixmap rp = dbuff->xForm(m);
01879 bitBlt(this, 0,0,&rp,0,0,-1,-1);
01880 }
01881 else
01882 {
01883 qDebug("This shouldn't happen but it doesn't matter if it does (rotated == double buffered)");
01884 QPixmap dbuff(height(), width());
01885 QPainter dbp(&dbuff);
01886
01887 drawBackground(&dbp);
01888 DrawStraight(&dbp, height(), width());
01889
01890 QWMatrix m;
01891 m.rotate(90);
01892 QPixmap rp = dbuff.xForm(m);
01893 bitBlt(this, 0,0,&rp,0,0,-1,-1);
01894 }
01895 }
01896 else
01897 {
01898 if (dbuff != NULL)
01899 {
01900 dbp->begin(dbuff);
01901 drawBackground(dbp);
01902 DrawStraight(dbp, width(), height());
01903 dbp->end();
01904 bitBlt(this, 0,0,dbuff,0,0,-1,-1);
01905 }
01906 else
01907 {
01908 QPainter p(this);
01909 drawBackground(&p);
01910 DrawStraight(&p, width(), height());
01911 }
01912 }
01913 }
01914
01915 void QTReader::drawFonts()
01916 {
01917 if (bDoUpdates)
01918 {
01919 int hmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
01920 if (hmargin < m_bottommargin) hmargin = m_bottommargin;
01921
01922 if (buffdoc.empty())
01923 {
01924 if (dbuff != NULL)
01925 {
01926 dbp->begin(dbuff);
01927 drawBackground(dbp);
01928 dbp->end();
01929 }
01930 else
01931 {
01932 QPainter p(this);
01933 drawBackground(&p);
01934 }
01935 return;
01936 }
01937 setfont();
01938
01939 if (dbuff != NULL && (dbuff->width() != width() || dbuff->height() != height()))
01940 {
01941 qDebug("Oh no! A resize event was missed...");
01942 if (m_rotated)
01943 {
01944 dbuff->resize(height(), width());
01945 }
01946 else
01947 {
01948 dbuff->resize(width(), height());
01949 }
01950 m_lastwidth = 0;
01951 }
01952 if (m_lastwidth != ((m_rotated) ? height() : width()))
01953 {
01954 m_scrolldy = m_topmargin;
01955
01956 m_lastwidth = ((m_rotated) ? height() : width());
01957 m_lastheight = ((m_rotated) ? width() : height());
01958 buffdoc.setwidth(m_lastwidth-(m_left_border+m_right_border));
01959 buffdoc.locate(pagelocate());
01960 fillbuffer();
01961 redrawall();
01962
01963 }
01964 else
01965 {
01966 int newht = ((m_rotated) ? width() : height());
01967 if (m_lastheight > newht)
01968 {
01969
01970 m_scrolldy = m_topmargin;
01971 int ypos = m_scrolldy1+m_topmargin;
01972 for (int i = 0; i < numlines; i++)
01973 {
01974 if ((ypos += textarray[i]->lineSpacing()) > newht - hmargin)
01975 {
01976 numlines = i;
01977 jumpto(mylastpos = locnarray[i+1]);
01978 break;
01979 }
01980 }
01981
01982 m_lastheight = newht;
01983 }
01984 else if (m_lastheight < newht)
01985 {
01986 m_scrolldy = m_topmargin;
01987
01988 int ypos = m_scrolldy1+m_topmargin;
01989 for (int i = 0; i <= numlines; i++)
01990 {
01991 ypos += textarray[i]->lineSpacing();
01992 }
01993 fillbuffer(numlines+1, ypos, newht);
01994
01995 }
01996 if (numlines > 0)
01997 {
01998 redrawall();
01999 }
02000 }
02001 emitRedraw();
02002 }
02003
02004
02005
02006
02007
02008
02009 }
02010
02011 void QTReader::DrawScroll( QPainter *p, int _w, int _h )
02012 {
02013 if (!buffdoc.empty())
02014 {
02015 QBrush checkered = QBrush( Dense4Pattern );
02016 checkered.setColor(m_scrollbarcolor);
02017 switch (m_scrollpos)
02018 {
02019 case 1:
02020 if (m_rotated)
02021 {
02022 p->fillRect(0, 0, 2, _h, checkered);
02023 }
02024 else
02025 {
02026 p->fillRect(0, _h-2, _w, 2, checkered);
02027 }
02028 break;
02029 case 2:
02030 if (m_rotated)
02031 {
02032 p->fillRect(0, _h-2, _w, 2, checkered);
02033 }
02034 else
02035 {
02036 p->fillRect(_w-2, 0, 2, _h, checkered);
02037 }
02038 break;
02039 case 3:
02040 if (m_rotated)
02041 {
02042 p->fillRect(0, 0, _w, 2, checkered);
02043 }
02044 else
02045 {
02046 p->fillRect(0, 0, 2, _h, checkered);
02047 }
02048 break;
02049 case 0:
02050 default:
02051 break;
02052 }
02053 switch (m_scrollpos)
02054 {
02055 case 1:
02056 {
02057 int ht;
02058 if (m_rotated)
02059 {
02060 ht = _h;
02061 }
02062 else
02063 {
02064 ht = _w;
02065 }
02066 int sectionsize = (buffdoc.endSection()-buffdoc.startSection());
02067 int mid = (ht*(locnarray[numlines]+locnarray[0]-2*buffdoc.startSection())+sectionsize)/(2*sectionsize);
02068 int sliderheight = ((locnarray[numlines]-locnarray[0])*ht+sectionsize/2)/sectionsize;
02069 int sliderpos;
02070 if (sliderheight < 10)
02071 {
02072 sliderheight = 10;
02073 sliderpos = mid-5;
02074 }
02075 else
02076 {
02077 sliderpos = (ht*(locnarray[0]-buffdoc.startSection())+sectionsize/2)/sectionsize;
02078 }
02079 if (m_rotated)
02080 {
02081 p->fillRect(0, sliderpos, 3, sliderheight, m_scrollbarcolor);
02082 }
02083 else
02084 {
02085 p->fillRect(sliderpos, _h-3, sliderheight, 3, m_scrollbarcolor);
02086 }
02087 }
02088 break;
02089 case 2:
02090 case 3:
02091 {
02092 int ht;
02093 if (m_rotated)
02094 {
02095 ht = _w;
02096 }
02097 else
02098 {
02099 ht = _h;
02100 }
02101 int sectionsize = (buffdoc.endSection()-buffdoc.startSection());
02102 int mid = (ht*(locnarray[numlines]+locnarray[0]-2*buffdoc.startSection())+sectionsize)/(2*sectionsize);
02103 int sliderheight = ((locnarray[numlines]-locnarray[0])*ht+sectionsize/2)/sectionsize;
02104 int sliderpos;
02105 if (sliderheight < 10)
02106 {
02107 sliderheight = 10;
02108 sliderpos = mid-5;
02109 }
02110 else
02111 {
02112 sliderpos = (ht*(locnarray[0]-buffdoc.startSection())+sectionsize/2)/sectionsize;
02113 }
02114 if (m_rotated)
02115 {
02116 int hoff;
02117 if (m_scrollpos == 2)
02118 {
02119 hoff = _h-3;
02120 }
02121 else
02122 {
02123 hoff = 0;
02124 }
02125 p->fillRect(ht-sliderpos-sliderheight, hoff, sliderheight, 3, m_scrollbarcolor);
02126 }
02127 else
02128 {
02129 int hoff;
02130 if (m_scrollpos == 2)
02131 {
02132 hoff = _w-3;
02133 }
02134 else
02135 {
02136 hoff = 0;
02137 }
02138 p->fillRect(hoff, sliderpos, 3, sliderheight, m_scrollbarcolor);
02139 }
02140 }
02141 break;
02142 case 0:
02143 default:
02144 break;
02145 }
02146 }
02147 }
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 QString QTReader::firstword()
02183 {
02184 if (m_bMonoSpaced)
02185 {
02186 return toQString(textarray[0]->data());
02187 }
02188 else
02189 {
02190 int start, end, len, j;
02191 for (j = 0; j < numlines; j++)
02192 {
02193 len = textarray[j]->length();
02194 for (start = 0; start < len && !isalpha((*textarray[j])[start]); start++);
02195 if (start < len) break;
02196 }
02197 if (j < numlines)
02198 {
02199 QString ret = "";
02200 for (end = start; end < len && isalpha((*textarray[j])[end]); end++)
02201 ret += (*textarray[j])[end];
02202 if (ret.isEmpty()) ret = "Current position";
02203 return ret;
02204 }
02205 else
02206 return "Current position";
02207 }
02208 }
02209
02210
02211
02212
02213
02214 bool QTReader::ChangeFont(int tgt)
02215 {
02216 return m_fontControl.ChangeFont(m_fontname, tgt);
02217 }
02218
02219 void QTReader::init()
02220 {
02221 setBackgroundColor( m_bg );
02222 buffdoc.setfilter(getfilter());
02223 ChangeFont(m_textsize);
02224 setFocusPolicy(QWidget::StrongFocus);
02225 timer = new QTimer(this);
02226 connect(timer, SIGNAL(timeout()), this, SLOT(doscroll()));
02227 #ifdef USETIMER
02228 m_dragtimer = new QTimer(this);
02229 connect(m_dragtimer, SIGNAL(timeout()), this, SLOT(actionDrag()));
02230 #endif
02231
02232 setfont();
02233 }
02234
02235
02236
02237
02238 QTReader::~QTReader()
02239 {
02240 if (m_output != NULL)
02241 {
02242 delete m_output;
02243 }
02244 if (dbuff != NULL)
02245 {
02246 delete dbuff;
02247 delete dbp;
02248 }
02249 #ifdef USEQPE
02250 if (m_autoScroll)
02251 {
02252 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
02253 }
02254 #endif
02255 #ifdef _SCROLLPIPE
02256 if (m_pipeout != NULL)
02257 {
02258 fclose(m_pipeout);
02259 }
02260 #endif
02261 }
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 void QTReader::paintEvent( QPaintEvent * p )
02284 {
02285 if ((dbuff != NULL) && !m_outofdate)
02286 {
02287 if (m_rotated)
02288 {
02289 if ((p->rect().width() != width()) || (p->rect().height() != height()))
02290 {
02291 qDebug("Partial paint");
02292 QRect r;
02293 r.setTop(width()-p->rect().right()-1);
02294 r.setLeft(p->rect().top());
02295 r.setHeight(p->rect().width());
02296 r.setWidth(p->rect().height());
02297 QPixmap p1(r.width(), r.height());
02298 bitBlt(&p1, QPoint(0, 0), dbuff, r);
02299 QWMatrix m;
02300 m.rotate(90);
02301 QPixmap p2 = p1.xForm(m);
02302 bitBlt(this, p->rect().left(), p->rect().top(), &p2, 0, 0, -1, -1);
02303 }
02304 else
02305 {
02306 qDebug("Full paint");
02307 QWMatrix m;
02308 m.rotate(90);
02309 QPixmap rp = dbuff->xForm(m);
02310 bitBlt(this, 0,0,&rp,0,0,-1,-1);
02311 }
02312 }
02313 else
02314 {
02315
02316 bitBlt(this,p->rect().topLeft(),dbuff,p->rect());
02317 }
02318 }
02319 else
02320 {
02321 drawFonts();
02322 }
02323 m_outofdate = false;
02324 }
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355 bool QTReader::locate(unsigned long n)
02356 {
02357 m_outofdate = true;
02358 m_lastwidth = 0;
02359 locnarray[0] = n;
02360 ResetScroll();
02361 update();
02362 return true;
02363 }
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379 unsigned int QTReader::screenlines()
02380 {
02381
02382
02383 return (height()-2)/(m_linespacing);
02384 };
02385
02386 bool QTReader::fillbuffer(int reuse, int ht, int newht)
02387 {
02388 int hmargin = ((m_scrollpos == 1) ? _SBARHEIGHT : 0);
02389 if (hmargin < m_bottommargin) hmargin = m_bottommargin;
02390 if (ht < 0) ht = m_topmargin;
02391 if (buffdoc.empty()) return false;
02392 if (newht < 0)
02393 m_lastheight = (m_rotated) ? width() : height();
02394 else
02395 m_lastheight = newht;
02396 int ch;
02397 bool ret = false;
02398 unsigned int oldpagepos = locnarray[reuse];
02399 int lastypos = ht, ypos = ht;
02400 numlines = reuse;
02401 while (ypos < m_lastheight - hmargin || numlines < 2)
02402 {
02403 lastypos = ypos;
02404 if (textarray[numlines] == NULL)
02405 {
02406 textarray[numlines] = new CDrawBuffer(&m_fontControl);
02407 }
02408 locnarray[numlines] = locate();
02409 int ch = getline(textarray[numlines]);
02410 ypos += textarray[numlines]->lineSpacing();
02411
02412
02413
02414
02415
02416
02417 numlines++;
02418 if (!ch)
02419 {
02420 if (numlines - reuse == 1 )
02421 {
02422 qDebug("FALSE");
02423 if (oldpagepos < buffdoc.endSection())
02424 locate(oldpagepos);
02425 else
02426 dopageup(buffdoc.endSection());
02427 return false;
02428 }
02429 else
02430 {
02431 qDebug("TRUE");
02432 --numlines;
02433 mylastpos = locate();
02434 return true;
02435 }
02436 }
02437 if (numlines > 1 && textarray[numlines-2]->isBop())
02438 {
02439 --numlines;
02440 mylastpos = locate();
02441 return true;
02442 }
02443 }
02444
02445 --numlines;
02446 mylastpos = locate();
02447 m_scrollpart = m_lastheight - lastypos - hmargin;
02448 if (m_autoScroll)
02449 {
02450 CalculateScrollParameters();
02451 }
02452 return true;
02453 }
02454
02455 void QTReader::dopagedn()
02456 {
02457
02458 ResetScroll();
02459 int skip = 0, ypos = m_topmargin;
02460 if (locate() != mylastpos)
02461 {
02462 jumpto(mylastpos);
02463 }
02464 CDrawBuffer* reusebuffer = textarray[numlines];
02465 if (reusebuffer != NULL)
02466 {
02467 if (reusebuffer->eof()) return;
02468 for (int i = 0; i <= m_overlap; i++)
02469 {
02470 int offset = numlines - m_overlap + i;
02471 reusebuffer = textarray[offset];
02472 size_t reuselocn = locnarray[offset];
02473 textarray[offset] = textarray[i];
02474 textarray[i] = reusebuffer;
02475
02476 locnarray[offset] = locnarray[i];
02477 locnarray[i] = reuselocn;
02478 ypos += textarray[i]->lineSpacing();
02479 skip++;
02480 }
02481 }
02482 if (numlines <= 1)
02483 {
02484 skip = 0;
02485 ypos = 0;
02486 qDebug("Doing extra skip");
02487 }
02488 if (fillbuffer(skip, ypos))
02489 {
02490 drawFonts();
02491 }
02492 }
02493
02494 void QTReader::dopageup()
02495 {
02496 dopageup(locnarray[(m_overlap < numlines) ? m_overlap : numlines/2]);
02497 }
02498
02499 bool QTReader::synch(size_t start, size_t end)
02500 {
02501 jumpto(start);
02502 while (start++ < end)
02503 {
02504 tchar ch = getch();
02505 if (ch == 10) return true;
02506 if ((ch == UEOF) || (ch == 6))
02507 {
02508 return false;
02509 }
02510 }
02511 return false;
02512 }
02513
02514 void QTReader::dopageup(unsigned int target)
02515 {
02516 ResetScroll();
02517 CBufferFace<CDrawBuffer*> buff;
02518 CBufferFace<size_t> loc;
02519 size_t delta, guess = 2*(locate()-pagelocate()), lastdelta = 0;
02520 qDebug("dopageup:: locate():%u pagelocate():%u guess:%u", locate(), pagelocate(), guess);
02521 bool ch = true;
02522 int nbfl, ypos = m_topmargin;
02523 if (guess < 128) guess = 128;
02524 while (1)
02525 {
02526
02527
02528 ch = true;
02529 if (target < guess)
02530 {
02531 delta = 0;
02532 jumpto( (m_continuousDocument) ? 0 : buffdoc.startSection() );
02533 }
02534 else if (!m_continuousDocument && (target - guess < buffdoc.startSection()))
02535 {
02536 delta = 0;
02537 qDebug("Jumping to startsection:%d", buffdoc.startSection());
02538 jumpto(buffdoc.startSection());
02539 }
02540 else
02541 {
02542 delta = guess;
02543 if (!synch(target-delta, target-lastdelta))
02544 {
02545 lastdelta = delta;
02546 if (guess < 4000)
02547 {
02548 guess <<= 1;
02549 continue;
02550 }
02551 else
02552 {
02553 jumpto(target-delta);
02554 }
02555 }
02556 }
02557
02558 nbfl = 0;
02559 ypos = m_topmargin;
02560
02561 while (locate() < target)
02562 {
02563 if (buff[nbfl] == NULL) buff[nbfl] = new CDrawBuffer(&m_fontControl);
02564 loc[nbfl] = locate();
02565 ch = getline(buff[nbfl]);
02566 ypos += buff[nbfl]->lineSpacing();
02567 nbfl++;
02568 if (!ch) break;
02569 }
02570 if (guess < 4000 && ypos < ((m_rotated) ? width() : height())-(m_bottommargin) && (delta != 0))
02571 {
02572 for (int i = 0; i < nbfl; i++)
02573 {
02574 delete buff[i];
02575 buff[i] = NULL;
02576 }
02577 guess <<= 1;
02578 continue;
02579 }
02580 break;
02581 }
02582 if (ch)
02583 {
02584 if (buff[nbfl] == NULL) buff[nbfl] = new CDrawBuffer(&m_fontControl);
02585 loc[nbfl] = locate();
02586 int ch = getline(buff[nbfl]);
02587 nbfl++;
02588 }
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 ypos = m_topmargin;
02601 numlines = 0;
02602 while (ypos < ((m_rotated) ? width() : height())-m_bottommargin && numlines+2 <= nbfl)
02603 {
02604 ypos += buff[nbfl - numlines - 2]->lineSpacing();
02605 numlines++;
02606 }
02607 if (numlines > 0) --numlines;
02608 if (numlines == 0 && nbfl > 1) numlines = 1;
02609
02610 int offset = nbfl-1;
02611 offset -= numlines;
02612 ypos = m_topmargin;
02613 for (int i = 0; i <= numlines; i++)
02614 {
02615 delete textarray[i];
02616 textarray[i] = buff[offset+i];
02617 locnarray[i] = loc[offset + i];
02618 ypos += textarray[i]->lineSpacing();
02619 }
02620 #ifdef _WINDOWS
02621 for (i = 0; i < nbfl - numlines - 1; i++)
02622 #else
02623 for (int i = 0; i < nbfl - numlines - 1; i++)
02624 #endif
02625 {
02626 delete buff[i];
02627 }
02628
02629 while (ypos < ((m_rotated) ? width() : height())-m_bottommargin)
02630 {
02631 numlines++;
02632 locnarray[numlines] = locate();
02633 if (textarray[numlines] == NULL) textarray[numlines] = new CDrawBuffer(&m_fontControl);
02634 if (!getline(textarray[numlines])) break;
02635 ypos += textarray[numlines]->lineSpacing();
02636 }
02637
02638 mylastpos = locate();
02639 CalculateScrollParameters();
02640 drawFonts();
02641
02642 }
02643
02644 bool QTReader::load_file(const char *newfile, unsigned int _lcn)
02645 {
02646
02647
02648 int prog = 0;
02649 bool bRC = false;
02650 unsigned int lcn = _lcn;
02651 bDoUpdates = false;
02652 ResetScroll();
02653 if (m_lastfile == newfile && lcn == 0)
02654 {
02655 lcn = m_lastposn;
02656 }
02657
02658 if (m_rotated)
02659 {
02660 m_lastwidth = height();
02661 m_lastheight = width();
02662 }
02663 else
02664 {
02665 m_lastwidth = width();
02666 m_lastheight = height();
02667 }
02668 if (buffdoc.openfile(this,newfile) == 0)
02669 {
02670 m_lastfile = newfile;
02671 buffdoc.setwidth(m_lastwidth-(m_left_border+m_right_border));
02672 bRC = true;
02673 buffdoc.setContinuous(m_continuousDocument);
02674 qDebug("buffdoc.openfile done");
02675 }
02676 setfilter(getfilter());
02677 qDebug("Updated");
02678 bDoUpdates = true;
02679 locate(lcn);
02680 return bRC;
02681 }
02682
02683 void QTReader::lineDown()
02684 {
02685 int ypos = m_topmargin;
02686 ResetScroll();
02687 int offset = numlines;
02688
02689 for (int i = 0; i <= numlines; i++)
02690 {
02691 if ((ypos += textarray[numlines-i]->lineSpacing()) > ((m_rotated) ? width() : height()))
02692 {
02693 offset = i-1;
02694 break;
02695 }
02696 }
02697 offset = numlines - offset;
02698 #ifdef _WINDOWS
02699 for (i = offset; i <= numlines; i++)
02700 #else
02701 for (int i = offset; i <= numlines; i++)
02702 #endif
02703 {
02704 CDrawBuffer* buff = textarray[i-offset];
02705 textarray[i-offset] = textarray[i];
02706 locnarray[i-offset] = locnarray[i];
02707 textarray[i] = buff;
02708 }
02709 numlines = numlines - offset + 1;
02710 locnarray[numlines] = locate();
02711 if (textarray[numlines] == NULL)
02712 {
02713 textarray[numlines] = new CDrawBuffer(&m_fontControl);
02714 }
02715 getline(textarray[numlines]);
02716 mylastpos = locate();
02717 m_outofdate = true;
02718 update();
02719 }
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804 void QTReader::ResetScroll()
02805 {
02806 m_totalscroll = 0;
02807 m_scrolldy1 = 0;
02808 m_scrolldy = m_topmargin;
02809 if (m_autoScroll && ((m_scrolltype == 0) || !m_bgpm.isNull()))
02810 {
02811 setautoscroll(false);
02812 }
02813 }
02814
02815 void QTReader::lineUp()
02816 {
02817 dopageup(locnarray[numlines-1]);
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908 }
02909
02910 bool QTReader::empty()
02911 {
02912 return buffdoc.empty();
02913 }
02914
02915 MarkupType QTReader::PreferredMarkup()
02916 {
02917 MarkupType m = buffdoc.PreferredMarkup();
02918 if (m == cTEXT)
02919 {
02920 int ext = m_lastfile.findRev('.');
02921 if (ext >= 0)
02922 {
02923 QString ft = m_lastfile.right(m_lastfile.length()-ext-1).upper();
02924 if (ft.left(3) == "HTM")
02925 {
02926 m = cHTML;
02927 }
02928 }
02929 }
02930 return m;
02931 }
02932
02933 void QTReader::resizeEvent( QResizeEvent * p )
02934 {
02935 qDebug("Resizing");
02936 m_outofdate = true;
02937 if (dbuff != NULL)
02938 {
02939 if (m_rotated)
02940 {
02941 dbuff->resize(p->size().height(),p->size().width());
02942 }
02943 else
02944 {
02945 dbuff->resize(p->size());
02946 }
02947 }
02948 m_bgIsScaled = false;
02949 if (m_bgtype == bgStretched)
02950 {
02951 emit RefreshBitmap();
02952 }
02953
02954 {
02955 int h, w;
02956 if (m_rotated)
02957 {
02958 h = p->size().width();
02959 w = p->size().height();
02960 }
02961 else
02962 {
02963 w = p->size().width();
02964 h = p->size().height();
02965 }
02966 m_topmargin = (h*m_abstopmargin+500)/1000;
02967 m_bottommargin = (h*m_absbottommargin+500)/1000;
02968 m_left_border = (w*m_absleft_border+500)/1000;
02969 m_right_border = (w*m_absright_border+500)/1000;
02970 }
02971 if (dbuff != NULL && buffdoc.empty())
02972 {
02973 dbp->begin(dbuff);
02974 drawBackground(dbp);
02975 dbp->end();
02976 }
02977 }
02978
02979 void QTReader::setrotated(bool sfs)
02980 {
02981 qDebug("Rotating");
02982 m_rotated = sfs;
02983 setDoubleBuffer(m_doubleBuffered);
02984 m_bgIsScaled = false;
02985 m_outofdate = true;
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008 }
03009
03010 void QTReader::drawBackground(QPainter *p)
03011 {
03012
03013 p->setBackgroundColor(m_bg);
03014 if (dbuff != NULL)
03015 {
03016 p->eraseRect(dbuff->rect());
03017 }
03018 else
03019 {
03020 if (m_rotated)
03021 {
03022 p->eraseRect(0,0,height(),width());
03023 }
03024 else
03025 {
03026 p->eraseRect(rect());
03027 }
03028 }
03029 if (!m_bgpm.isNull())
03030 {
03031
03032 switch (m_bgtype)
03033 {
03034 case bgCentred:
03035 {
03036 if (dbuff == NULL)
03037 {
03038 p->drawPixmap(width(),height(),m_bgpm);
03039 }
03040 else
03041 {
03042 int w = (dbuff->rect().width()-m_bgpm.width())/2;
03043 int h = (dbuff->rect().height()-m_bgpm.height())/2;
03044 p->drawPixmap(w,h,m_bgpm);
03045 }
03046 }
03047 break;
03048 case bgTiled:
03049 {
03050 if (dbuff == NULL)
03051 {
03052 p->drawTiledPixmap(0,0,width(),height(),m_bgpm);
03053 }
03054 else
03055 {
03056 p->drawTiledPixmap(0,0,dbuff->rect().width(),dbuff->rect().height(),m_bgpm);
03057 }
03058 }
03059 break;
03060 case bgStretched:
03061 {
03062 if (!m_bgIsScaled)
03063 {
03064 m_bgIsScaled = true;
03065 QImage im = m_bgpm.convertToImage();
03066 if (dbuff == NULL)
03067 {
03068 m_bgpm.convertFromImage(im.smoothScale(width(),height()));
03069 }
03070 else
03071 {
03072 m_bgpm.convertFromImage(im.smoothScale(dbuff->rect().width(), dbuff->rect().height()));
03073 }
03074 }
03075 p->drawPixmap(0,0,m_bgpm);
03076 }
03077 break;
03078 default:
03079 qDebug("Unknown background type");
03080 }
03081
03082 }
03083 }
03084
03085 void QTReader::blitRot(int dx, int dy, int sw, int sh, CDrawBuffer* txt)
03086 {
03087 if (txt != NULL)
03088 {
03089 sh = txt->lineSpacing();
03090 }
03091 int sy = width()-dx-sh;
03092 if (m_autoScroll && !(m_scrolltype == 0))
03093 {
03094 sy = (sy+m_totalscroll+1)%width();
03095 }
03096
03097 QPixmap pm(sw, sh);
03098
03099 QPainter pd(&pm, this);
03100 if (m_bgpm.isNull())
03101 {
03102 pd.eraseRect(pm.rect());
03103 }
03104 else
03105 {
03106 if (sy+pm.height() > dbuff->height())
03107 {
03108
03109 int fh = dbuff->height() - sy;
03110 if (sy+fh > dbuff->height())
03111 {
03112 qDebug("Oh no!");
03113 }
03114
03115 if (fh > pm.height())
03116 {
03117 qDebug("Oh no! - 2");
03118 }
03119
03120 bitBlt(&pm,0,0,dbuff,dy,sy,pm.width(),fh);
03121 bitBlt(&pm,0,fh,dbuff,dy,0,pm.width(),pm.height()-fh);
03122 }
03123 else
03124 {
03125 bitBlt(&pm,0,0,dbuff,dy,sy,pm.width(),pm.height());
03126 }
03127 }
03128 if (txt != NULL)
03129 {
03130
03131 txt->render(&pd, txt->lineSpacing() - txt->descent() - txt->lineExtraSpacing(), m_bMonoSpaced, m_charWidth, sw, m_left_border, m_right_border, m_bg, width()-m_topmargin-m_bottommargin);
03132 }
03133 QWMatrix m;
03134 m.rotate(90);
03135 QPixmap rp = pm.xForm(m);
03136
03137
03138
03139 bitBlt(this, dx, dy, &rp, 0, 0, -1, -1, CopyROP);
03140 }
03141
03142 QString QTReader::about()
03143 {
03144 QString ab = QString("QTReader widget (c) Tim Wentford\n")+buffdoc.about() + "\nMini-scrollbar by Markus Gritsch\nNavigation History fixes by Frantisek Dufka";
03145 if (m_output != NULL)
03146 {
03147 ab += QString("\n") + m_output->about();
03148 }
03149 return ab;
03150 }
03151
03152 void QTReader::getNextLink()
03153 {
03154 if (m_scrolldy != 0)
03155 {
03156 setautoscroll(false);
03157 ResetScroll();
03158 redrawall();
03159 }
03160 bool redraw = false;
03161 bool found = false;
03162 if (m_currentlink >= 0)
03163 {
03164 m_currentlinkoffset = textarray[m_currentlink]->invertLink(m_currentlinkoffset);
03165 if ((m_currentlinkstyle = textarray[m_currentlink]->getNextLink(m_currentlinkoffset)) != NULL)
03166 {
03167 qDebug("Found a link at %u", m_currentlinkoffset);
03168 int offset = textarray[m_currentlink]->invertLink(m_currentlinkoffset);
03169 qDebug("Finishes at %u", offset);
03170 found = true;
03171 }
03172 redraw = true;
03173 drawSingleLine(m_currentlink);
03174
03175 }
03176 if (!found)
03177 {
03178 m_currentlinkoffset = -1;
03179 for (int i = m_currentlink+1; i < numlines; ++i)
03180 {
03181 if ((m_currentlinkstyle = textarray[i]->getNextLink(m_currentlinkoffset)) != NULL)
03182 {
03183 m_currentlink = i;
03184 qDebug("Found a link at %u", m_currentlinkoffset);
03185 int offset = textarray[m_currentlink]->invertLink(m_currentlinkoffset);
03186 qDebug("Finishes at %u", offset);
03187
03188 redraw = true;
03189 found = true;
03190 drawSingleLine(m_currentlink);
03191 break;
03192 }
03193 }
03194 }
03195 if (redraw)
03196 {
03197
03198 }
03199 if (!found)
03200 {
03201 m_currentlink = -1;
03202 m_currentlinkstyle = NULL;
03203 m_currentlinkoffset = -1;
03204 dopagedn();
03205 }
03206 }
03207
03208 void QTReader::emitRedraw()
03209 {
03210 m_currentlinkstyle = NULL;
03211 m_currentlink = -1;
03212 m_currentlinkoffset = -1;
03213 emit OnRedraw();
03214 };
03215
03216 void QTReader::drawSingleLine(int lineno)
03217 {
03218 QPainter p( this );
03219 int ypos = textarray[0]->ascent()+m_topmargin;
03220 if (lineno == 0)
03221 {
03222 if (m_rotated)
03223 {
03224 blitRot(width()-(ypos+textarray[lineno]->descent()+textarray[lineno]->lineExtraSpacing()), 0, height(), -1, textarray[lineno]);
03225 }
03226 else
03227 {
03228 if (m_bgpm.isNull())
03229 {
03230 p.fillRect(m_left_border,ypos-textarray[lineno]->ascent(),width()-(m_left_border+m_right_border),textarray[lineno]->lineSpacing(),m_bg);
03231 }
03232 else
03233 {
03234 bitBlt(this, m_left_border, ypos-textarray[lineno]->ascent(), dbuff, m_left_border, ypos-textarray[lineno]->ascent(), width()-(m_left_border+m_right_border), textarray[lineno]->lineSpacing());
03235 }
03236 textarray[lineno]->render( &p, ypos, m_bMonoSpaced, m_charWidth, width(), m_left_border, m_right_border, m_bg, height()-m_topmargin-m_bottommargin);
03237 }
03238 }
03239 for (int i = 1; i < numlines; i++)
03240 {
03241 ypos += (textarray[i-1]->descent() + textarray[i]->ascent())+
03242 (textarray[i-1]->lineExtraSpacing() + textarray[i]->lineExtraSpacing())/2;
03243 if (i == lineno)
03244 {
03245 if (m_rotated)
03246 {
03247 blitRot(width()-(ypos+textarray[i]->descent()+textarray[i]->lineExtraSpacing()), 0, height(), -1, textarray[i]);
03248 }
03249 else
03250 {
03251 if (m_bgpm.isNull())
03252 {
03253 p.fillRect(m_left_border,ypos-textarray[lineno]->ascent(),width()-(m_left_border+m_right_border),textarray[lineno]->lineSpacing(),m_bg);
03254 }
03255 else
03256 {
03257 bitBlt(this, m_left_border, ypos-textarray[lineno]->ascent(), dbuff, m_left_border, ypos-textarray[lineno]->ascent(), width()-(m_left_border+m_right_border), textarray[lineno]->lineSpacing());
03258 }
03259 textarray[i]->render( &p, ypos, m_bMonoSpaced, m_charWidth, width(), m_left_border, m_right_border, m_bg, height()-m_topmargin-m_bottommargin);
03260 }
03261 }
03262 }
03263 }
03264
03265
03266 void QTReader::gotoLink()
03267 {
03268 if (m_currentlinkstyle == NULL) return;
03269 textarray[m_currentlink]->invertLink(m_currentlinkoffset);
03270 size_t saveposn = pagelocate();
03271 QString href, nm;
03272 unsigned long tgt = m_currentlinkstyle->getData();
03273 unsigned long tgtoffset = m_currentlinkstyle->getOffset();
03274 linkType lt = buffdoc.hyperlink(tgt, tgtoffset, href, nm);
03275 qDebug("URL(1):%s", (const char*)href);
03276 if ((lt & eFile) != 0)
03277 {
03278 buffdoc.saveposn(m_lastfile, saveposn);
03279 #ifdef USEQPE
03280 {
03281 QCopEnvelope e("QPE/System", "busy()");
03282 }
03283 #endif
03284 ResetScroll();
03285 if (!href.isEmpty())
03286 {
03287 if (!buffdoc.getFile(href, nm))
03288 {
03289 emit NewFileRequest(href);
03290 }
03291 else
03292 {
03293 ResetScroll();
03294 fillbuffer();
03295 m_outofdate = true;
03296 update();
03297 }
03298 }
03299 if (!nm.isEmpty())
03300 {
03301 qDebug("QTReader:Finding %s", (const char*)nm);
03302 if (buffdoc.findanchor(nm))
03303 {
03304 buffdoc.resetPos();
03305 fillbuffer();
03306 m_outofdate = true;
03307 update();
03308 }
03309 }
03310
03311
03312 #ifdef USEQPE
03313 {
03314 QCopEnvelope e("QPE/System", "notBusy()");
03315 }
03316 #endif
03317 }
03318 else if ((lt & eLink) != 0)
03319 {
03320 buffdoc.saveposn(m_lastfile, saveposn);
03321 ResetScroll();
03322 fillbuffer();
03323 m_outofdate = true;
03324 update();
03325 }
03326 else
03327 {
03328 if ((lt & ePicture) != 0)
03329 {
03330 QImage* pm = buffdoc.getPicture(tgt);
03331 if (pm != NULL)
03332 {
03333 emit OnShowPicture(*pm);
03334 delete pm;
03335 }
03336 }
03337 else
03338 {
03339
03340 if (!href.isEmpty())
03341 {
03342 emit OnURLSelected(href, tgt);
03343 refresh();
03344 }
03345 }
03346 }
03347 m_currentlinkstyle = NULL;
03348 m_currentlink = -1;
03349 m_currentlinkoffset = -1;
03350 }
03351
03352 void QTReader::refresh(bool full)
03353 {
03354 qDebug("Refreshing");
03355 int h, w;
03356 if (m_rotated)
03357 {
03358 h = width();
03359 w = height();
03360 }
03361 else
03362 {
03363 w = width();
03364 h = height();
03365 }
03366 m_topmargin = (h*m_abstopmargin+500)/1000;
03367 m_bottommargin = (h*m_absbottommargin+500)/1000;
03368 m_left_border = (w*m_absleft_border+500)/1000;
03369 m_right_border = (w*m_absright_border+500)/1000;
03370
03371 qDebug("Top margin:%u", m_topmargin );
03372 qDebug("Bottom margin:%u", m_bottommargin );
03373 qDebug("Left margin:%u", m_left_border );
03374 qDebug("Right margin:%u", m_right_border );
03375 if (full && m_highlightfilter) m_highlightfilter->refresh(pagelocate());
03376 m_outofdate = true;
03377 locate(pagelocate());
03378 }
03379
03380 #include "striphtml.h"
03381
03382 CFilterChain* QTReader::getfilter()
03383 {
03384 CFilterChain * filt = new CFilterChain(getencoding());
03385 if (bstripcr) filt->addfilter(new stripcr);
03386
03387 if (btextfmt || (bautofmt && (PreferredMarkup() == cTEXT))) filt->addfilter(new textfmt);
03388 if (bpeanut || (bautofmt && (PreferredMarkup() == cPML))) filt->addfilter(new PeanutFormatter);
03389
03390
03391 #ifdef __STATIC
03392 if (bstriphtml || (bautofmt && (PreferredMarkup() == cHTML))) filt->addfilter(new striphtml(m_lastfile));
03393 if (bautofmt && (PreferredMarkup() == cCHM))
03394 {
03395 striphtml* f = new striphtml(m_lastfile);
03396 f->setchm(true);
03397 filt->addfilter(f);
03398 }
03399 #else
03400 if (bstriphtml || (bautofmt && (PreferredMarkup() == cHTML))) filt->addfilter(new ExternFilter("HTMLfilter", m_lastfile));
03401 if (bautofmt && (PreferredMarkup() == cCHM))
03402 {
03403 ExternFilter* f = new ExternFilter("HTMLfilter",m_lastfile);
03404 ((striphtml*)f->filter())->setchm(true);
03405 filt->addfilter(f);
03406 }
03407 #endif
03408 m_highlightfilter = new HighlightFilter(this);
03409 filt->addfilter(m_highlightfilter);
03410
03411 if (bdehyphen) filt->addfilter(new dehyphen);
03412 if (bunindent) filt->addfilter(new unindent);
03413 if (brepara) filt->addfilter(new repara(m_reparastring));
03414 if (bonespace) filt->addfilter(new OnePara);
03415 if (bindenter) filt->addfilter(new indenter(bindenter));
03416 if (bdblspce) filt->addfilter(new dblspce);
03417 if (bdepluck) filt->addfilter(new DePluck(pluckernextpart));
03418 if (bdejpluck) filt->addfilter(new DePluck(jplucknextpart));
03419 if (brepalm) filt->addfilter(new repalm);
03420 if (bunderlineLink) filt->addfilter(new underlineLink);
03421 if (bkern) filt->addfilter(new kern);
03422 if (bremap) filt->addfilter(new remap);
03423 if (bmakebold) filt->addfilter(new embolden);
03424 if (bfulljust) filt->addfilter(new FullJust);
03425 int r,g,b;
03426 m_default_bg.rgb(&r, &g, &b);
03427 if (r != 255 || g != 255 || b != 255)
03428 filt->addfilter(new setbg(r,g,b));
03429 m_default_fg.rgb(&r, &g, &b);
03430 if (r != 0 || g != 0 || b != 0)
03431 filt->addfilter(new setfg(r,g,b));
03432
03433 if (bInverse) filt->addfilter(new makeInverse);
03434 if (bNoInlineTables) filt->addfilter(new tableLink);
03435 return filt;
03436 }
03437
03438 void QTReader::readAloud()
03439 {
03440 #ifdef __STATIC
03441 return;
03442 #else
03443 CBuffer para;
03444 jumpto(pagelocate());
03445 while (m_autoScroll && (buffdoc.getpara(para) != -1))
03446 {
03447 if (para.length() > 0)
03448 {
03449 unsigned long lastpos = buffdoc.explocate();
03450 while (lastpos > mylastpos)
03451 {
03452 dopagedn();
03453 qApp->processEvents();
03454 }
03455 jumpto(lastpos);
03456 QString txt = toQString(para.data());
03457
03458 doOutput(txt);
03459 }
03460 qApp->processEvents();
03461 }
03462 #endif
03463 }
03464
03465 bool QTReader::doOutput(const QString& wrd)
03466 {
03467 if (m_output != NULL)
03468 {
03469 m_output->output(wrd);
03470 return true;
03471 }
03472 else
03473 {
03474 return false;
03475 }
03476 }
03477
03478 bool QTReader::checkoutput()
03479 {
03480 if (m_output == NULL)
03481 {
03482 m_output = new outputcodec(m_outputName);
03483 if (reinterpret_cast<outputcodec*>(m_output)->getStatus() != 0)
03484 {
03485 delete m_output;
03486 m_output = NULL;
03487 QMessageBox::warning(this, PROGNAME, QString("Couldn't find output codec\n")+m_outputName);
03488 return false;
03489 }
03490 }
03491 return true;
03492 }