00001 #include <config.h>
00002
00003 #include <kaction.h>
00004 #include <kapplication.h>
00005 #include <kdebug.h>
00006 #include <kfiledialog.h>
00007 #include <kiconloader.h>
00008 #include <kio/job.h>
00009 #include <klocale.h>
00010 #include <kmessagebox.h>
00011 #include <kprinter.h>
00012 #include <kstdaction.h>
00013 #include <qobject.h>
00014 #include <qlayout.h>
00015 #include <qpaintdevicemetrics.h>
00016 #include <qprogressdialog.h>
00017 #include <qsplitter.h>
00018 #include <qurl.h>
00019 #include <qtoolbox.h>
00020 #include <qvbox.h>
00021
00022 #include "documentWidget.h"
00023 #include "marklist.h"
00024 #include "tableOfContents.h"
00025 #include "kprintDialogPage_pageoptions.h"
00026 #include "kvsprefs.h"
00027 #include "kmultipage.h"
00028 #include "pageNumber.h"
00029 #include "renderedDocumentPagePrinter.h"
00030 #include "searchWidget.h"
00031 #include "textBox.h"
00032 #include "zoomlimits.h"
00033
00034
00035
00036
00037 KMultiPage::KMultiPage(QWidget *parentWidget, const char *widgetName, QObject *parent, const char *name)
00038 : DCOPObject("kmultipage"), KParts::ReadOnlyPart(parent, name)
00039 {
00040
00041
00042
00043
00044 setObjId("kmultipage");
00045
00046 parentWdg = parentWidget;
00047 lastCurrentPage = 0;
00048 timer_id = -1;
00049 searchInProgress = false;
00050
00051 QVBox* verticalBox = new QVBox(parentWidget);
00052 verticalBox->setFocusPolicy(QWidget::StrongFocus);
00053 setWidget(verticalBox);
00054
00055 splitterWidget = new QSplitter(verticalBox, widgetName);
00056 splitterWidget->setOpaqueResize(false);
00057 splitterWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
00058
00059
00060 sideBar = new QToolBox(splitterWidget, "sidebar");
00061
00062
00063 tableOfContents = new TableOfContents(sideBar);
00064 sideBar->addItem(tableOfContents, QIconSet(SmallIcon("contents")), i18n("Contents"));
00065
00066 connect(tableOfContents, SIGNAL(gotoPage(const Anchor&)), this, SLOT(gotoPage(const Anchor&)));
00067
00068
00069 _markList = new MarkList(sideBar, "marklist");
00070 sideBar->addItem(_markList, QIconSet(SmallIcon("thumbnail")), i18n("Thumbnails"));
00071
00072
00073 sideBar->setCurrentItem(sideBar->item(KVSPrefs::sideBarItem()));
00074
00075 splitterWidget->setResizeMode(sideBar, QSplitter::KeepSize);
00076
00077 connect(_markList, SIGNAL(selected(const PageNumber&)), this, SLOT(gotoPage(const PageNumber&)));
00078
00079 _scrollView = new PageView(splitterWidget, widgetName);
00080
00081
00082 searchWidget = new SearchWidget(verticalBox);
00083 searchWidget->hide();
00084 connect(searchWidget, SIGNAL(findNextText()), this, SLOT(findNextText()));
00085 connect(searchWidget, SIGNAL(findPrevText()), this, SLOT(findPrevText()));
00086
00087 sideBar->setMinimumWidth(80);
00088 sideBar->setMaximumWidth(300);
00089
00090 connect(_scrollView, SIGNAL(currentPageChanged(const PageNumber&)), this, SLOT(setCurrentPageNumber(const PageNumber&)));
00091 connect(_scrollView, SIGNAL(viewSizeChanged(const QSize&)), scrollView(), SLOT(calculateCurrentPageNumber()));
00092 connect(_scrollView, SIGNAL(wheelEventReceived(QWheelEvent *)), this, SLOT(wheelEvent(QWheelEvent*)));
00093
00094 connect(this, SIGNAL(enableMoveTool(bool)), _scrollView, SLOT(slotEnableMoveTool(bool)));
00095
00096 splitterWidget->setCollapsible(sideBar, false);
00097 splitterWidget->setSizes(KVSPrefs::guiLayout());
00098
00099 connect(searchWidget, SIGNAL(searchEnabled(bool)), this, SIGNAL(searchEnabled(bool)));
00100 connect(searchWidget, SIGNAL(stopSearch()), this, SLOT(stopSearch()));
00101 }
00102
00103
00104 KMultiPage::~KMultiPage()
00105 {
00106 writeSettings();
00107
00108 if (timer_id != -1)
00109 killTimer(timer_id);
00110
00111 delete pageCache;
00112 }
00113
00114 void KMultiPage::readSettings()
00115 {
00116 }
00117
00118 void KMultiPage::writeSettings()
00119 {
00120
00121 tableOfContents->writeSettings();
00122
00123 KVSPrefs::setGuiLayout(splitterWidget->sizes());
00124
00125 KVSPrefs::setSideBarItem(sideBar->indexOf(sideBar->currentItem()));
00126 KVSPrefs::writeConfig();
00127 }
00128
00129 QString KMultiPage::name_of_current_file()
00130 {
00131 return m_file;
00132 }
00133
00134 bool KMultiPage::is_file_loaded(const QString& filename)
00135 {
00136 return (filename == m_file);
00137 }
00138
00139 void KMultiPage::slotSave_defaultFilename()
00140 {
00141 slotSave();
00142 }
00143
00144 void KMultiPage::slotSave()
00145 {
00146
00147 QString formats;
00148 QString ending;
00149 int rindex = m_file.findRev(".");
00150 if (rindex == -1) {
00151 ending = QString::null;
00152 formats = QString::null;
00153 } else {
00154 ending = m_file.mid(rindex);
00155 formats = fileFormats().grep(ending).join("\n");
00156 }
00157
00158 QString fileName = KFileDialog::getSaveFileName(QString::null, formats, 0, i18n("Save File As"));
00159
00160 if (fileName.isEmpty())
00161 return;
00162
00163
00164
00165 if (!ending.isEmpty() && fileName.find(ending) == -1)
00166 fileName = fileName+ending;
00167
00168 if (QFile(fileName).exists()) {
00169 int r = KMessageBox::warningContinueCancel (0, i18n("The file %1\nexists. Shall I overwrite that file?").arg(fileName),
00170 i18n("Overwrite File"), i18n("Overwrite"));
00171 if (r == KMessageBox::Cancel)
00172 return;
00173 }
00174
00175 KIO::Job *job = KIO::file_copy( KURL( m_file ), KURL( fileName ), 0600, true, false, true );
00176 connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotIOJobFinished ( KIO::Job * ) ) );
00177
00178 return;
00179 }
00180
00181
00182 void KMultiPage::setFile(bool)
00183 {
00184 return;
00185 }
00186
00187
00188 bool KMultiPage::closeURL()
00189 {
00190 #ifdef DEBUG_KMULTIPAGE
00191 kdDebug(1233) << "KMultiPage::closeURL()" << endl;
00192 #endif
00193
00194 if (renderer.isNull())
00195 return false;
00196
00197
00198 document_history.clear();
00199
00200
00201 renderer->setFile(QString::null, KURL());
00202 renderer->clear();
00203
00204
00205 widgetList.setAutoDelete(true);
00206 widgetList.resize(0);
00207 widgetList.setAutoDelete(false);
00208
00209
00210 scrollView()->layoutPages();
00211 enableActions(false);
00212
00213
00214 markList()->clear();
00215
00216
00217 tableOfContents->clear();
00218
00219
00220 emit setStatusBarText(QString::null);
00221
00222 return true;
00223 }
00224
00225 void KMultiPage::slotIOJobFinished ( KIO::Job *job )
00226 {
00227 if ( job->error() )
00228 job->showErrorDialog( 0L );
00229 }
00230
00231 void KMultiPage::slotShowScrollbars(bool status)
00232 {
00233 _scrollView->slotShowScrollbars(status);
00234 }
00235
00236 void KMultiPage::slotShowSidebar(bool show)
00237 {
00238 if (show)
00239 sideBar->show();
00240 else
00241 sideBar->hide();
00242 }
00243
00244 void KMultiPage::slotShowThumbnails(bool show)
00245 {
00246 markList()->slotShowThumbnails(show);
00247 }
00248
00249 void KMultiPage::slotSetFullPage(bool fullpage)
00250 {
00251 _scrollView->setFullScreenMode(fullpage);
00252 if (fullpage)
00253 slotShowSidebar(false);
00254 }
00255
00256 void KMultiPage::preferencesChanged()
00257 {
00258
00259
00260 KVSPrefs::self()->readConfig();
00261
00262 slotShowThumbnails(KVSPrefs::showThumbnails());
00263
00264
00265 if (scrollView()->overviewMode() &&
00266 (scrollView()->getNrColumns() != KVSPrefs::overviewModeColumns() ||
00267 scrollView()->getNrRows() != KVSPrefs::overviewModeRows()))
00268 {
00269 setViewMode(KVSPrefs::EnumViewMode::Overview);
00270 }
00271
00272 if (KVSPrefs::changeColors() && KVSPrefs::renderMode() == KVSPrefs::EnumRenderMode::Paper)
00273 renderer->setAccessibleBackground(true, KVSPrefs::paperColor());
00274 else
00275 renderer->setAccessibleBackground(false);
00276
00277 renderModeChanged();
00278 }
00279
00280 void KMultiPage::setViewMode(int mode)
00281 {
00282 #ifdef DEBUG_KMULTIPAGE
00283 kdDebug(1233) << "KMultiPage::setViewMode(" << mode << ")" << endl;
00284 #endif
00285
00286
00287 PageNumber currentPage = currentPageNumber();
00288
00289
00290 switch (mode)
00291 {
00292 case KVSPrefs::EnumViewMode::SinglePage:
00293 KVSPrefs::setViewMode(KVSPrefs::EnumViewMode::SinglePage);
00294
00295
00296 if ((scrollView()->getNrColumns() == 1) && (scrollView()->getNrRows() == 1) && (scrollView()->isContinuous() == false))
00297 return;
00298
00299 scrollView()->setNrColumns(1);
00300 scrollView()->setNrRows(1);
00301 scrollView()->setContinuousViewMode(false);
00302
00303
00304 scrollView()->scrollTop();
00305 break;
00306 case KVSPrefs::EnumViewMode::ContinuousFacing:
00307 KVSPrefs::setViewMode(KVSPrefs::EnumViewMode::ContinuousFacing);
00308
00309
00310 if ((scrollView()->getNrColumns() == 2) && (scrollView()->getNrRows() == 1) && (scrollView()->isContinuous() == true))
00311 return;
00312
00313 scrollView()->setNrColumns(2);
00314 scrollView()->setNrRows(1);
00315 scrollView()->setContinuousViewMode(true);
00316 break;
00317 case KVSPrefs::EnumViewMode::Overview:
00318 KVSPrefs::setViewMode(KVSPrefs::EnumViewMode::Overview);
00319
00320
00321 if ((scrollView()->getNrColumns() == KVSPrefs::overviewModeColumns()) && (scrollView()->getNrRows() == KVSPrefs::overviewModeRows()) && (scrollView()->isContinuous() == false))
00322 return;
00323
00324 scrollView()->setNrColumns(KVSPrefs::overviewModeColumns());
00325 scrollView()->setNrRows(KVSPrefs::overviewModeRows());
00326 scrollView()->setContinuousViewMode(false);
00327
00328
00329 scrollView()->scrollTop();
00330 break;
00331 default:
00332 KVSPrefs::setViewMode(KVSPrefs::EnumViewMode::Continuous);
00333
00334
00335 if ((scrollView()->getNrColumns() == 1) && (scrollView()->getNrRows() == 1) && (scrollView()->isContinuous() == true))
00336 return;
00337
00338 scrollView()->setNrColumns(1);
00339 scrollView()->setNrRows(1);
00340 scrollView()->setContinuousViewMode(true);
00341 }
00342 generateDocumentWidgets(currentPage);
00343 KVSPrefs::writeConfig();
00344 emit viewModeChanged();
00345 }
00346
00347 void KMultiPage::initializePageCache()
00348 {
00349 pageCache = new DocumentPageCache();
00350 }
00351
00352 DocumentWidget* KMultiPage::createDocumentWidget()
00353 {
00354 DocumentWidget* documentWidget = new DocumentWidget(scrollView()->viewport(), scrollView(), pageCache, "singlePageWidget");
00355 connect(documentWidget, SIGNAL(clearSelection()), this, SLOT(clearSelection()));
00356 connect(this, SIGNAL(enableMoveTool(bool)), documentWidget, SLOT(slotEnableMoveTool(bool)));
00357 return documentWidget;
00358 }
00359
00360
00361 void KMultiPage::generateDocumentWidgets(const PageNumber& _startPage)
00362 {
00363 PageNumber startPage = _startPage;
00364 #ifdef DEBUG_KMULTIPAGE
00365 kdDebug(1233) << "KMultiPage::generateDocumentWidgets(" << startPage << ")" << endl;
00366 #endif
00367
00368
00369 if (getRenderer().isNull() || getRenderer()->isEmpty())
00370 return;
00371
00372
00373
00374 bool reload = !startPage.isValid();
00375
00376 if (reload)
00377 {
00378
00379 startPage = currentPageNumber();
00380 }
00381
00382
00383 if (startPage < 1)
00384 startPage = 1;
00385 if (startPage > numberOfPages())
00386 startPage = numberOfPages();
00387
00388 unsigned int tableauStartPage = startPage;
00389
00390
00391 widgetList.setAutoDelete(true);
00392 Q_UINT16 oldwidgetListSize = widgetList.size();
00393 if (numberOfPages() == 0)
00394 widgetList.resize(0);
00395 else
00396 {
00397 switch (KVSPrefs::viewMode())
00398 {
00399 case KVSPrefs::EnumViewMode::SinglePage:
00400 widgetList.resize(1);
00401 break;
00402 case KVSPrefs::EnumViewMode::Overview:
00403 {
00404
00405 unsigned int visiblePages = KVSPrefs::overviewModeColumns() * KVSPrefs::overviewModeRows();
00406
00407 tableauStartPage = startPage - ((startPage - 1) % visiblePages);
00408
00409 visiblePages = QMIN(visiblePages, numberOfPages() - tableauStartPage + 1);
00410 if (widgetList.size() != visiblePages)
00411 widgetList.resize(visiblePages);
00412 break;
00413 }
00414 default:
00415
00416 widgetList.resize(numberOfPages());
00417 }
00418 }
00419 bool isWidgetListResized = (widgetList.size() != oldwidgetListSize);
00420 widgetList.setAutoDelete(false);
00421
00422
00423 if (widgetList.size() == 0) {
00424 scrollView()->addChild(&widgetList);
00425 return;
00426 }
00427
00428
00429
00430 DocumentWidget *documentWidget;
00431 for(Q_UINT16 i=0; i<widgetList.size(); i++) {
00432 documentWidget = widgetList[i];
00433 if (documentWidget == 0) {
00434 documentWidget = createDocumentWidget();
00435
00436 widgetList.insert(i, documentWidget);
00437 documentWidget->show();
00438
00439 connect(documentWidget, SIGNAL(localLink(const QString &)), this, SLOT(handleLocalLink(const QString &)));
00440 connect(documentWidget, SIGNAL(setStatusBarText(const QString&)), this, SIGNAL(setStatusBarText(const QString&)) );
00441 }
00442 }
00443
00444
00445
00446 if (KVSPrefs::viewMode() == KVSPrefs::EnumViewMode::SinglePage) {
00447
00448
00449
00450 documentWidget = widgetList[0];
00451 if (documentWidget != 0) {
00452 documentWidget->setPageNumber(startPage);
00453 documentWidget->update();
00454 } else
00455 kdError(4300) << "Zero-Pointer in widgetList in KMultiPage::generateDocumentWidgets()" << endl;
00456 } else {
00457
00458
00459 for(Q_UINT16 i=0; i<widgetList.size(); i++) {
00460 documentWidget = widgetList[i];
00461 if (documentWidget != 0)
00462 {
00463 if (KVSPrefs::viewMode() == KVSPrefs::EnumViewMode::Overview)
00464 documentWidget->setPageNumber(i+tableauStartPage);
00465 else
00466 documentWidget->setPageNumber(i+1);
00467 }
00468 else
00469 kdError(4300) << "Zero-Pointer in widgetList in KMultiPage::generateDocumentWidgets()" << endl;
00470 }
00471 }
00472
00473
00474
00475 scrollView()->addChild(&widgetList);
00476
00477
00478
00479 if (isWidgetListResized || !reload)
00480 gotoPage(startPage);
00481 }
00482
00483
00484 bool KMultiPage::gotoPage(const PageNumber& page)
00485 {
00486 return gotoPage(page, 0, true);
00487 }
00488
00489
00490 bool KMultiPage::gotoPage(const PageNumber& page, int y, bool isLink)
00491 {
00492 #ifdef DEBUG_KMULTIPAGE
00493 kdDebug(1233) << "KMultiPage::gotoPage()" << endl;
00494 #endif
00495
00496 if (widgetList.size() == 0) {
00497 kdError(4300) << "KMultiPage::gotoPage(" << page << ", y) called, but widgetList is empty" << endl;
00498 return false;
00499 }
00500
00501 if (!page.isValid())
00502 {
00503 kdDebug(1223) << "KMultiPage::gotoPage(" << page << ") invalid pageNumber." << endl;
00504 return false;
00505 }
00506
00507 if (isLink)
00508 document_history.add(page, y);
00509
00510 DocumentWidget* pageWidget;
00511
00512
00513 if (KVSPrefs::viewMode() == KVSPrefs::EnumViewMode::Overview)
00514 {
00515 unsigned int visiblePages = KVSPrefs::overviewModeColumns() * KVSPrefs::overviewModeRows();
00516
00517 unsigned int firstPage = ((DocumentWidget*)widgetList[0])->getPageNumber();
00518
00519 unsigned int tableauStartPage = page + 1 - (page % visiblePages);
00520
00521 if (firstPage != tableauStartPage)
00522 {
00523 if ((numberOfPages() - tableauStartPage + 1 < visiblePages) || (widgetList.size() < visiblePages))
00524 {
00525
00526
00527 generateDocumentWidgets(tableauStartPage);
00528 }
00529 else
00530 {
00531
00532
00533 for (unsigned int i = 0; i < widgetList.size(); i++)
00534 {
00535 pageWidget = (DocumentWidget*)(widgetList[i]);
00536 if (pageWidget != 0)
00537 pageWidget->setPageNumber(tableauStartPage + i);
00538 }
00539 scrollView()->layoutPages();
00540 }
00541 }
00542
00543
00544
00545
00546 pageWidget = (DocumentWidget*)(widgetList[page % visiblePages]);
00547
00548 scrollView()->moveViewportToWidget(pageWidget, y);
00549
00550
00551 setCurrentPageNumber(page);
00552
00553 return true;
00554 }
00555 else if (widgetList.size() == 1)
00556 {
00557
00558
00559
00560
00561 pageWidget = (DocumentWidget*)(widgetList[0]);
00562
00563
00564 if (pageWidget == 0) {
00565 kdError(4300) << "KMultiPage::goto_Page() called with widgetList.size() == 1, but widgetList[0] == 0" << endl;
00566 return false;
00567 }
00568
00569 if (pageCache->sizeOfPageInPixel(currentPageNumber()) == pageCache->sizeOfPageInPixel(page))
00570 {
00571
00572
00573
00574 pageCache->getPage(page);
00575 }
00576
00577 pageWidget->setPageNumber(page);
00578 scrollView()->layoutPages();
00579 scrollView()->moveViewportToWidget(pageWidget, y);
00580 } else {
00581
00582
00583
00584
00585
00586
00587 if (widgetList.size() < page) {
00588 kdError(4300) << "KMultiPage::goto_Page(page,y ) called with widgetList.size()=" << widgetList.size() << ", and page=" << page << endl;
00589 return false;
00590 }
00591 pageWidget = (DocumentWidget*)(widgetList[page-1]);
00592 if (pageWidget == 0) {
00593 kdError(4300) << "KMultiPage::goto_Page() called with widgetList.size() > 1, but widgetList[page] == 0" << endl;
00594 return false;
00595 }
00596
00597 scrollView()->moveViewportToWidget(pageWidget, y);
00598 }
00599
00600 if (isLink && y != 0)
00601 pageWidget->flash(y);
00602
00603
00604 setCurrentPageNumber(page);
00605 return true;
00606 }
00607
00608
00609 void KMultiPage::handleLocalLink(const QString &linkText)
00610 {
00611 #ifdef DEBUG_SPECIAL
00612 kdDebug(4300) << "hit: local link to " << linkText << endl;
00613 #endif
00614
00615 if (renderer.isNull()) {
00616 kdError(4300) << "KMultiPage::handleLocalLink( " << linkText << " ) called, but renderer==0" << endl;
00617 return;
00618 }
00619
00620 QString locallink;
00621 if (linkText[0] == '#' )
00622 locallink = linkText.mid(1);
00623 else
00624 locallink = linkText;
00625
00626 Anchor anch = renderer->findAnchor(locallink);
00627
00628 if (anch.isValid())
00629 gotoPage(anch);
00630 else {
00631 if (linkText[0] != '#' ) {
00632
00633
00634
00635
00636 QUrl DVI_Url(m_file);
00637 QUrl Link_Url(DVI_Url, linkText, true);
00638
00639 QStringList args;
00640 args << "openURL";
00641 args << Link_Url.toString();
00642 kapp->kdeinitExec("kfmclient", args);
00643 }
00644 }
00645 }
00646
00647 void KMultiPage::setCurrentPageNumber(const PageNumber& page)
00648 {
00649 #ifdef DEBUG_KMULTIPAGE
00650 kdDebug(1233) << "KMultiPage::setCurrentPageNumber()" << endl;
00651 #endif
00652
00653 if (page != currentPageNumber())
00654 {
00655 markList()->setCurrentPageNumber(page);
00656 emit pageInfo(numberOfPages(), currentPageNumber());
00657 }
00658 }
00659
00660 PageNumber KMultiPage::currentPageNumber()
00661 {
00662 return markList()->currentPageNumber();
00663 }
00664
00665 void KMultiPage::doGoBack()
00666 {
00667 HistoryItem *it = document_history.back();
00668 if (it != 0)
00669 gotoPage(it->page, it->ypos, false);
00670 else
00671 kdDebug(4300) << "Faulty return -- bad history buffer" << endl;
00672 return;
00673 }
00674
00675
00676 void KMultiPage::doGoForward()
00677 {
00678 HistoryItem *it = document_history.forward();
00679 if (it != 0)
00680 gotoPage(it->page, it->ypos, false);
00681 else
00682 kdDebug(4300) << "Faulty return -- bad history buffer" << endl;
00683 return;
00684 }
00685
00686
00687 void KMultiPage::renderModeChanged()
00688 {
00689 pageCache->clear();
00690
00691 generateDocumentWidgets();
00692 scrollView()->layoutPages();
00693
00694 for (Q_UINT16 i=0; i < widgetList.size(); i++)
00695 {
00696 DocumentWidget* documentWidget = widgetList[i];
00697 if (documentWidget == 0)
00698 continue;
00699
00700 documentWidget->update();
00701 }
00702
00703 markList()->repaintThumbnails();
00704 }
00705
00706
00707 void KMultiPage::repaintAllVisibleWidgets()
00708 {
00709 #ifdef DEBUG_KMULTIPAGE
00710 kdDebug(1233) << "KMultiPage::repaintAllVisibleWidgets()" << endl;
00711 #endif
00712
00713 bool everResized = false;
00714
00715
00716 for(Q_UINT16 i=0; i<widgetList.size(); i++)
00717 {
00718 DocumentWidget* documentWidget = widgetList[i];
00719 if (documentWidget == 0)
00720 continue;
00721
00722
00723 QSize pageSize = pageCache->sizeOfPageInPixel(documentWidget->getPageNumber());
00724 if (pageSize != documentWidget->pageSize())
00725 {
00726 documentWidget->setPageSize(pageSize);
00727 everResized = true;
00728 }
00729 }
00730
00731
00732
00733
00734 if (everResized == true)
00735 scrollView()->layoutPages(true);
00736 }
00737
00738
00739 double KMultiPage::setZoom(double zoom)
00740 {
00741 #ifdef DEBUG_KMULTIPAGE
00742 kdDebug(1233) << "KMultiPage::setZoom(" << zoom << ")" << endl;
00743 #endif
00744
00745 if (zoom < ZoomLimits::MinZoom/1000.0)
00746 zoom = ZoomLimits::MinZoom/1000.0;
00747 if (zoom > ZoomLimits::MaxZoom/1000.0)
00748 zoom = ZoomLimits::MaxZoom/1000.0;
00749
00750 pageCache->setResolution(QPaintDevice::x11AppDpiX()*zoom);
00751 emit zoomChanged();
00752 return zoom;
00753 }
00754
00755
00756 void KMultiPage::print()
00757 {
00758
00759 if (renderer.isNull())
00760 return;
00761 if (renderer->isEmpty())
00762 return;
00763
00764
00765 KPrinter *printer = getPrinter();
00766 if (printer == 0)
00767 return;
00768
00769
00770 if ( printer->setup(parentWdg, i18n("Print %1").arg(m_file.section('/', -1))) ) {
00771
00772 QValueList<int> pageList = printer->pageList();
00773 if (pageList.isEmpty())
00774 printer->abort();
00775 else {
00776 printer->setCreator("kviewshell");
00777 printer->setDocName(m_file);
00778 RenderedDocumentPagePrinter rdpp(printer);
00779
00780
00781
00782 Length paperWidth, paperHeight;
00783 QPaintDeviceMetrics pdm(printer);
00784 paperWidth.setLength_in_mm(pdm.widthMM());
00785 paperHeight.setLength_in_mm(pdm.heightMM());
00786
00787 QValueList<int>::ConstIterator it = pageList.begin();
00788 while (true) {
00789 SimplePageSize paper_s(paperWidth, paperHeight);
00790
00791
00792
00793 qApp->processEvents();
00794
00795 QPainter *paint = rdpp.getPainter();
00796 if (paint != 0) {
00797
00798
00799
00800 double factual_zoom = 1.0;
00801
00802
00803
00804 SimplePageSize page_s = sizeOfPage(*it);
00805
00806 paint->save();
00807
00808
00809
00810
00811 if ((page_s.isPortrait() != paper_s.isPortrait()) && (printer->option( "kde-kviewshell-rotatepage" ) != "false")) {
00812 paint->rotate(-90);
00813 paint->translate(-printer->resolution()*paperHeight.getLength_in_inch(), 0.0);
00814 paper_s = paper_s.rotate90();
00815 }
00816
00817 double suggested_zoom = page_s.zoomToFitInto(paper_s);
00818
00819
00820
00821 if ((suggested_zoom < 1.0) && (printer->option( "kde-kviewshell-shrinkpage" ) == "true"))
00822 factual_zoom = suggested_zoom;
00823 if ((suggested_zoom > 1.0) && (printer->option( "kde-kviewshell-expandpage" ) == "true"))
00824 factual_zoom = suggested_zoom;
00825
00826 Length delX, delY;
00827
00828
00829 if (printer->option( "kde-kviewshell-centerpage" ) != "false") {
00830 delX = (paper_s.width() - page_s.width()*factual_zoom)/2.0;
00831 delY = (paper_s.height() - page_s.height()*factual_zoom)/2.0;
00832 }
00833
00834
00835 rdpp.setPageNumber(*it);
00836
00837 double resolution = factual_zoom*printer->resolution();
00838
00839 paint->translate(resolution*delX.getLength_in_inch(), resolution*delY.getLength_in_inch());
00840 renderer->drawPage(resolution, &rdpp);
00841 paint->restore();
00842 }
00843 ++it;
00844 if ((it == pageList.end()) || (printer->aborted() == true))
00845 break;
00846
00847 printer->newPage();
00848 }
00849
00850
00851 }
00852 }
00853 delete printer;
00854 }
00855
00856
00857 void KMultiPage::setRenderer(DocumentRenderer* _renderer)
00858 {
00859 renderer = _renderer;
00860
00861
00862 initializePageCache();
00863 pageCache->setRenderer(renderer);
00864
00865 _markList->setPageCache(pageCache);
00866
00867
00868 widgetList.resize(0);
00869
00870
00871 connect(renderer, SIGNAL(setStatusBarText(const QString&)), this, SIGNAL(setStatusBarText(const QString&)));
00872 connect(pageCache, SIGNAL(paperSizeChanged()), this, SLOT(renderModeChanged()));
00873 connect(pageCache, SIGNAL(textSelected(bool)), this, SIGNAL(textSelected(bool)));
00874 connect(renderer, SIGNAL(documentIsChanged()), this, SLOT(renderModeChanged()));
00875 connect(this, SIGNAL(zoomChanged()), this, SLOT(repaintAllVisibleWidgets()));
00876 }
00877
00878
00879 void KMultiPage::updateWidgetSize(const PageNumber& pageNumber)
00880 {
00881 for(Q_UINT16 i=0; i<widgetList.size(); i++)
00882 {
00883 DocumentWidget* documentWidget = widgetList[i];
00884 if (documentWidget == 0)
00885 continue;
00886
00887 if (documentWidget->getPageNumber() == pageNumber)
00888 {
00889
00890 QSize pageSize = pageCache->sizeOfPageInPixel(documentWidget->getPageNumber());
00891 if (pageSize != documentWidget->pageSize())
00892 {
00893 documentWidget->setPageSize(pageSize);
00894 scrollView()->layoutPages();
00895 }
00896
00897 break;
00898 }
00899 }
00900
00901
00902 markList()->updateWidgetSize(pageNumber);
00903 }
00904
00905
00906 PageNumber KMultiPage::widestPage() const
00907 {
00908 Length maxWidth;
00909 PageNumber pageNumber = 1;
00910
00911 for (int i = 1; i <= numberOfPages(); i++)
00912 {
00913 Length width = pageCache->sizeOfPage(i).width();
00914
00915 if (width > maxWidth)
00916 {
00917 maxWidth = width;
00918 pageNumber = i;
00919 }
00920 }
00921
00922 return pageNumber;
00923 }
00924
00925 double KMultiPage::zoomForWidthColumns(unsigned int viewportWidth) const
00926 {
00927 Length maxLeftColumnWidth;
00928 Length maxRightColumnWidth;
00929 Length maxWidth;
00930
00931 PageNumber widestPageLeft;
00932 PageNumber widestPageRight;
00933
00934 for (int i = 1; i <= numberOfPages(); i++)
00935 {
00936 Length width = pageCache->sizeOfPage(i).width();
00937
00938 if ( i % 2 == 0)
00939 {
00940 if (width > maxLeftColumnWidth)
00941 {
00942 maxLeftColumnWidth = width;
00943 widestPageLeft = i;
00944 }
00945 }
00946
00947 if ( i % 2 == 1)
00948 {
00949 if (width > maxRightColumnWidth)
00950 maxRightColumnWidth = width;
00951 widestPageRight = i;
00952 }
00953 }
00954
00955 double ratio = maxLeftColumnWidth / (maxLeftColumnWidth + maxRightColumnWidth);
00956
00957
00958 unsigned int leftTargetWidth = (unsigned int)(ratio * viewportWidth);
00959
00960 return pageCache->sizeOfPage(widestPageLeft).zoomForWidth(leftTargetWidth);
00961 }
00962
00963 double KMultiPage::calculateFitToHeightZoomValue()
00964 {
00965 PageNumber pageNumber = 1;
00966
00967
00968
00969 int columns = scrollView()->getNrColumns();
00970 int rows = scrollView()->getNrRows();
00971 int continuousViewmode = scrollView()->isContinuous();
00972 bool fullScreenMode = scrollView()->fullScreenMode();
00973
00974 if (columns == 1 && rows == 1 && !continuousViewmode)
00975 {
00976 pageNumber = currentPageNumber();
00977 if (!pageNumber.isValid())
00978 pageNumber = 1;
00979 }
00980
00981 int pageDistance = scrollView()->distanceBetweenPages();
00982 if (columns == 1 && rows == 1 && !continuousViewmode && fullScreenMode)
00983 {
00984
00985
00986 pageDistance = 0;
00987 }
00988
00989 int targetViewportHeight = scrollView()->viewportSize(0,0).height();
00990 int targetPageHeight = (targetViewportHeight - rows*pageDistance)/rows;
00991 int targetPageWidth = (int)(targetPageHeight * pageCache->sizeOfPage(pageNumber).aspectRatio() );
00992 int targetViewportWidth = targetPageWidth * columns + (columns+1)*pageDistance;
00993 targetViewportHeight = scrollView()->viewportSize(targetViewportWidth, targetViewportHeight).height();
00994 targetPageHeight = (targetViewportHeight - rows*pageDistance)/rows;
00995
00996 return pageCache->sizeOfPage(pageNumber).zoomForHeight(targetPageHeight);
00997 }
00998
00999
01000 double KMultiPage::calculateFitToWidthZoomValue()
01001 {
01002 PageNumber pageNumber = 1;
01003
01004 int columns = scrollView()->getNrColumns();
01005 int rows = scrollView()->getNrRows();
01006 int continuousViewmode = scrollView()->isContinuous();
01007 bool fullScreenMode = scrollView()->fullScreenMode();
01008
01009 if (columns == 1 && rows == 1 && !continuousViewmode)
01010 {
01011
01012
01013
01014
01015 pageNumber = currentPageNumber();
01016 if (!pageNumber.isValid())
01017 pageNumber = 1;
01018 }
01019
01020 if (columns == 1 && rows == 1 && continuousViewmode)
01021 {
01022 pageNumber = widestPage();
01023 if (!pageNumber.isValid())
01024 pageNumber = 1;
01025 }
01026
01027
01028
01029
01030 if (continuousViewmode)
01031 rows = (int)(ceil(numberOfPages() / (double)columns));
01032
01033 int pageDistance = scrollView()->distanceBetweenPages();
01034 if (columns == 1 && rows == 1 && !continuousViewmode && fullScreenMode)
01035 {
01036
01037
01038 pageDistance = 0;
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 int targetViewportWidth = scrollView()->viewportSize(0,0).width();
01055
01056
01057 int targetPageWidth = (targetViewportWidth - (columns+1) * pageDistance) / columns;
01058
01059
01060 int targetPageHeight = (int)(targetPageWidth/pageCache->sizeOfPage(pageNumber).aspectRatio());
01061
01062 int targetViewportHeight = rows * targetPageHeight + (rows+1) * pageDistance;
01063
01064
01065
01066
01067 targetViewportWidth = scrollView()->viewportSize(targetViewportWidth, targetViewportHeight).width();
01068
01069 if (columns == 2 && continuousViewmode)
01070 {
01071
01072 return zoomForWidthColumns(targetViewportWidth - (columns+1) * pageDistance);
01073 }
01074
01075
01076 targetPageWidth = (targetViewportWidth - (columns+1) * pageDistance) / columns;
01077
01078 return pageCache->sizeOfPage(pageNumber).zoomForWidth(targetPageWidth);
01079 }
01080
01081
01082 void KMultiPage::prevPage()
01083 {
01084 Q_UINT8 cols = scrollView()->getNrColumns();
01085 Q_UINT8 rows = scrollView()->getNrRows();
01086
01087 PageNumber np = 1;
01088 if (cols*rows < currentPageNumber())
01089 {
01090 np = currentPageNumber() - cols*rows;
01091 }
01092
01093 gotoPage(np);
01094 }
01095
01096
01097 void KMultiPage::nextPage()
01098 {
01099 Q_UINT8 cols = scrollView()->getNrColumns();
01100 Q_UINT8 rows = scrollView()->getNrRows();
01101
01102 PageNumber np = QMIN(currentPageNumber() + cols*rows, (Q_UINT16)numberOfPages());
01103
01104 gotoPage(np);
01105 }
01106
01107
01108 void KMultiPage::firstPage()
01109 {
01110 gotoPage(1);
01111 }
01112
01113
01114 void KMultiPage::lastPage()
01115 {
01116 gotoPage(numberOfPages());
01117 }
01118
01119
01120 void KMultiPage::scroll(Q_INT32 deltaInPixel)
01121 {
01122 QScrollBar* scrollBar = scrollView()->verticalScrollBar();
01123 if (scrollBar == 0) {
01124 kdError(4300) << "KMultiPage::scroll called without scrollBar" << endl;
01125 return;
01126 }
01127
01128 if (deltaInPixel < 0) {
01129 if (scrollBar->value() == scrollBar->minValue()) {
01130 if ( (currentPageNumber() == 1) || (changePageDelayTimer.isActive()) )
01131 return;
01132
01133 if (scrollView()->isContinuous())
01134 return;
01135
01136 changePageDelayTimer.stop();
01137 prevPage();
01138
01139 scrollView()->setContentsPos(scrollView()->contentsX(), scrollBar->maxValue());
01140 return;
01141 }
01142 }
01143
01144 if (deltaInPixel > 0) {
01145 if (scrollBar->value() == scrollBar->maxValue()) {
01146 if ( (currentPageNumber() == numberOfPages()) || (changePageDelayTimer.isActive()) )
01147 return;
01148
01149 if (scrollView()->isContinuous())
01150 return;
01151
01152 changePageDelayTimer.stop();
01153 nextPage();
01154
01155 scrollView()->setContentsPos(scrollView()->contentsX(), 0);
01156 return;
01157 }
01158 }
01159
01160 scrollBar->setValue(scrollBar->value() + deltaInPixel);
01161
01162 if ( (scrollBar->value() == scrollBar->maxValue()) || (scrollBar->value() == scrollBar->minValue()) )
01163 changePageDelayTimer.start(200,true);
01164 else
01165 changePageDelayTimer.stop();
01166 }
01167
01168
01169 void KMultiPage::scrollUp()
01170 {
01171 QScrollBar* scrollBar = scrollView()->verticalScrollBar();
01172 if (scrollBar == 0)
01173 return;
01174
01175 scroll(-scrollBar->lineStep());
01176 }
01177
01178
01179 void KMultiPage::scrollDown()
01180 {
01181 QScrollBar* scrollBar = scrollView()->verticalScrollBar();
01182 if (scrollBar == 0)
01183 return;
01184
01185 scroll(scrollBar->lineStep());
01186 }
01187
01188 void KMultiPage::scrollLeft()
01189 {
01190 QScrollBar* scrollBar = scrollView()->horizontalScrollBar();
01191 if (scrollBar)
01192 scrollBar->subtractLine();
01193 }
01194
01195
01196 void KMultiPage::scrollRight()
01197 {
01198 QScrollBar* scrollBar = scrollView()->horizontalScrollBar();
01199 if (scrollBar)
01200 scrollBar->addLine();
01201 }
01202
01203
01204 void KMultiPage::scrollUpPage()
01205 {
01206 QScrollBar* scrollBar = scrollView()->verticalScrollBar();
01207 if (scrollBar)
01208 scrollBar->subtractPage();
01209 }
01210
01211
01212 void KMultiPage::scrollDownPage()
01213 {
01214 QScrollBar* scrollBar = scrollView()->verticalScrollBar();
01215 if (scrollBar)
01216 scrollBar->addPage();
01217 }
01218
01219
01220 void KMultiPage::scrollLeftPage()
01221 {
01222 QScrollBar* scrollBar = scrollView()->horizontalScrollBar();
01223 if (scrollBar)
01224 scrollBar->subtractPage();
01225 }
01226
01227
01228 void KMultiPage::scrollRightPage()
01229 {
01230 QScrollBar* scrollBar = scrollView()->horizontalScrollBar();
01231 if (scrollBar)
01232 scrollBar->addPage();
01233 }
01234
01235
01236 void KMultiPage::readDown()
01237 {
01238 PageView* sv = scrollView();
01239
01240 if (sv->atBottom())
01241 {
01242 if (sv->isContinuous())
01243 return;
01244
01245 if (currentPageNumber() == numberOfPages())
01246 return;
01247
01248 nextPage();
01249 sv->setContentsPos(sv->contentsX(), 0);
01250 }
01251 else
01252 sv->readDown();
01253 }
01254
01255
01256 void KMultiPage::readUp()
01257 {
01258 PageView* sv = scrollView();
01259
01260 if (sv->atTop())
01261 {
01262 if (sv->isContinuous())
01263 return;
01264
01265 if (currentPageNumber() == 1)
01266 return;
01267
01268 prevPage();
01269 sv->setContentsPos(sv->contentsX(), sv->contentsHeight());
01270 }
01271 else
01272 sv->readUp();
01273 }
01274
01275
01276 void KMultiPage::jumpToReference(const QString& reference)
01277 {
01278 if (renderer.isNull())
01279 return;
01280
01281 gotoPage(renderer->parseReference(reference));
01282 }
01283
01284
01285 void KMultiPage::gotoPage(const Anchor &a)
01286 {
01287 if (!a.page.isValid() || (renderer.isNull()))
01288 return;
01289
01290 gotoPage(a.page, (int)(a.distance_from_top.getLength_in_inch()*pageCache->getResolution() + 0.5), true);
01291 }
01292
01293
01294 void KMultiPage::gotoPage(const TextSelection& selection)
01295 {
01296 if (selection.isEmpty())
01297 {
01298 kdError(4300) << "KMultiPage::gotoPage(...) called with empty TextSelection." << endl;
01299 return;
01300 }
01301
01302 RenderedDocumentPage* pageData = pageCache->getPage(selection.getPageNumber());
01303
01304 if (pageData == 0) {
01305 #ifdef DEBUG_DOCUMENTWIDGET
01306 kdDebug(4300) << "DocumentWidget::paintEvent: no documentPage generated" << endl;
01307 #endif
01308 return;
01309 }
01310
01311 switch (widgetList.size())
01312 {
01313 case 0:
01314 kdError(4300) << "KMultiPage::select() while widgetList is empty" << endl;
01315 break;
01316 case 1:
01317 ((DocumentWidget*)widgetList[0])->select(selection);
01318 break;
01319 default:
01320 if (widgetList.size() < currentPageNumber())
01321 kdError(4300) << "KMultiPage::select() while widgetList.size()=" << widgetList.size() << "and currentPageNumber()=" << currentPageNumber() << endl;
01322 else
01323 ((DocumentWidget*)widgetList[selection.getPageNumber() - 1])->select(selection);
01324 }
01325
01326 unsigned int y = pageData->textBoxList[selection.getSelectedTextStart()].box.top();
01327 gotoPage(selection.getPageNumber(), y, false);
01328 }
01329
01330
01331 void KMultiPage::doSelectAll()
01332 {
01333 switch( widgetList.size() ) {
01334 case 0:
01335 kdError(4300) << "KMultiPage::doSelectAll() while widgetList is empty" << endl;
01336 break;
01337 case 1:
01338 ((DocumentWidget *)widgetList[0])->selectAll();
01339 break;
01340 default:
01341 if (widgetList.size() < currentPageNumber())
01342 kdError(4300) << "KMultiPage::doSelectAll() while widgetList.size()=" << widgetList.size() << "and currentPageNumber()=" << currentPageNumber() << endl;
01343 else
01344 ((DocumentWidget *)widgetList[currentPageNumber()-1])->selectAll();
01345 }
01346 }
01347
01348
01349
01350 void KMultiPage::showFindTextDialog()
01351 {
01352 if ((renderer.isNull()) || (renderer->supportsTextSearch() == false))
01353 return;
01354
01355 searchWidget->show();
01356 searchWidget->setFocus();
01357 }
01358
01359 void KMultiPage::stopSearch()
01360 {
01361 if (searchInProgress)
01362 {
01363
01364 searchInProgress = false;
01365 }
01366 else
01367 searchWidget->hide();
01368 }
01369
01370 void KMultiPage::findNextText()
01371 {
01372 #ifdef KDVI_MULTIPAGE_DEBUG
01373 kdDebug(4300) << "KMultiPage::findNextText() called" << endl;
01374 #endif
01375
01376 searchInProgress = true;
01377
01378
01379
01380 bool cachedPage = false;
01381
01382 QString searchText = searchWidget->getText();
01383
01384 if (searchText.isEmpty())
01385 {
01386 kdError(4300) << "KMultiPage::findNextText() called when search text was empty" << endl;
01387 return;
01388 }
01389
01390 bool case_sensitive = searchWidget->caseSensitive();
01391
01392
01393
01394
01395
01396 Q_UINT16 startingPage;
01397 Q_UINT16 startingTextItem;
01398
01399 TextSelection userSelection = pageCache->selectedText();
01400 if (userSelection.isEmpty())
01401 {
01402 startingPage = currentPageNumber();
01403 startingTextItem = 0;
01404 }
01405 else
01406 {
01407 startingPage = userSelection.getPageNumber();
01408 startingTextItem = userSelection.getSelectedTextEnd()+1;
01409 }
01410
01411 TextSelection foundSelection;
01412
01413 RenderedDocumentPagePixmap* searchPage = 0;
01414
01415 for(unsigned int i = 0; i < numberOfPages(); i++)
01416 {
01417 unsigned int pageNumber = (i + startingPage - 1) % numberOfPages() + 1;
01418
01419 if (!searchInProgress)
01420 {
01421
01422 setStatusBarText(i18n("Search interrupted"));
01423 if (!cachedPage)
01424 delete searchPage;
01425 return;
01426 }
01427
01428 if (i != 0)
01429 {
01430 setStatusBarText(i18n("Search page %1 of %2").arg(pageNumber).arg(numberOfPages()));
01431 kapp->processEvents();
01432 }
01433
01434
01435
01436 if (pageCache->isPageCached(pageNumber))
01437 {
01438
01439 if (!cachedPage)
01440 delete searchPage;
01441
01442 searchPage = pageCache->getPage(pageNumber);
01443 cachedPage = true;
01444 }
01445 else
01446 {
01447
01448
01449
01450 if (!searchPage || cachedPage)
01451 searchPage = new RenderedDocumentPagePixmap();
01452
01453 cachedPage = false;
01454
01455 searchPage->resize(1,1);
01456 searchPage->setPageNumber(pageNumber);
01457 renderer->getText(searchPage);
01458 }
01459
01460
01461 if (searchPage->textBoxList.size() == 0)
01462 continue;
01463
01464 foundSelection = searchPage->find(searchText, startingTextItem, case_sensitive);
01465
01466 if (foundSelection.isEmpty())
01467 {
01468
01469 startingTextItem = 0;
01470 clearSelection();
01471
01472 if (pageNumber == numberOfPages())
01473 {
01474 int answ = KMessageBox::questionYesNo(scrollView(),
01475 i18n("<qt>The search string <strong>%1</strong> could not be found by the "
01476 "end of the document. Should the search be restarted from the beginning "
01477 "of the document?</qt>").arg(searchText),
01478 i18n("Text Not Found"), KStdGuiItem::cont(), KStdGuiItem::cancel());
01479
01480 if (answ != KMessageBox::Yes)
01481 {
01482 setStatusBarText(QString::null);
01483 searchInProgress = false;
01484 if (!cachedPage)
01485 delete searchPage;
01486 return;
01487 }
01488 }
01489 }
01490 else
01491 {
01492 pageCache->selectText(foundSelection);
01493 gotoPage(pageCache->selectedText());
01494 setStatusBarText(QString::null);
01495 searchInProgress = false;
01496 if (!cachedPage)
01497 delete searchPage;
01498 return;
01499 }
01500 }
01501
01502 KMessageBox::sorry(scrollView(), i18n("<qt>The search string <strong>%1</strong> could not be found.</qt>").arg(searchText));
01503 setStatusBarText(QString::null);
01504 searchInProgress = false;
01505 if (!cachedPage)
01506 delete searchPage;
01507 }
01508
01509
01510 void KMultiPage::findPrevText()
01511 {
01512 #ifdef KDVI_MULTIPAGE_DEBUG
01513 kdDebug(4300) << "KMultiPage::findPrevText() called" << endl;
01514 #endif
01515
01516 searchInProgress = true;
01517
01518
01519
01520 bool cachedPage = false;
01521
01522 QString searchText = searchWidget->getText();
01523
01524 if (searchText.isEmpty())
01525 {
01526 kdError(4300) << "KMultiPage::findPrevText() called when search text was empty" << endl;
01527 return;
01528 }
01529
01530 bool case_sensitive = searchWidget->caseSensitive();
01531
01532
01533
01534
01535
01536 unsigned int startingPage;
01537 int startingTextItem;
01538
01539 TextSelection userSelection = pageCache->selectedText();
01540 if (userSelection.isEmpty())
01541 {
01542 startingPage = currentPageNumber();
01543 startingTextItem = -1;
01544 }
01545 else
01546 {
01547 startingPage = userSelection.getPageNumber();
01548 startingTextItem = userSelection.getSelectedTextStart()-1;
01549 }
01550
01551 TextSelection foundSelection;
01552
01553 RenderedDocumentPagePixmap* searchPage = 0;
01554
01555 for(unsigned int i = 0; i < numberOfPages(); i++)
01556 {
01557 int pageNumber = startingPage - i;
01558 if (pageNumber <= 0)
01559 pageNumber += numberOfPages();
01560
01561 if (!searchInProgress)
01562 {
01563
01564 setStatusBarText(i18n("Search interrupted"));
01565 if (!cachedPage)
01566 delete searchPage;
01567 return;
01568 }
01569
01570 if (i != 0)
01571 {
01572 setStatusBarText(i18n("Search page %1 of %2").arg(pageNumber).arg(numberOfPages()));
01573 kapp->processEvents();
01574 }
01575
01576
01577
01578 if (pageCache->isPageCached(pageNumber))
01579 {
01580
01581 if (!cachedPage)
01582 delete searchPage;
01583
01584 searchPage = pageCache->getPage(pageNumber);
01585 cachedPage = true;
01586 }
01587 else
01588 {
01589
01590
01591
01592 if (!searchPage || cachedPage)
01593 searchPage = new RenderedDocumentPagePixmap();
01594
01595 cachedPage = false;
01596
01597 searchPage->resize(1,1);
01598 searchPage->setPageNumber(pageNumber);
01599 renderer->getText(searchPage);
01600 }
01601
01602
01603 if (searchPage->textBoxList.size() == 0)
01604 continue;
01605
01606 foundSelection = searchPage->findRev(searchText, startingTextItem, case_sensitive);
01607
01608 if (foundSelection.isEmpty())
01609 {
01610
01611 startingTextItem = -1;
01612 clearSelection();
01613
01614 if (pageNumber == 1)
01615 {
01616 int answ = KMessageBox::questionYesNo(scrollView(),
01617 i18n("<qt>The search string <strong>%1</strong> could not be found by the "
01618 "beginning of the document. Should the search be restarted from the end "
01619 "of the document?</qt>").arg(searchText),
01620 i18n("Text Not Found"), KStdGuiItem::cont(), KStdGuiItem::cancel());
01621
01622 if (answ != KMessageBox::Yes)
01623 {
01624 setStatusBarText(QString::null);
01625 searchInProgress = false;
01626 if (!cachedPage)
01627 delete searchPage;
01628 return;
01629 }
01630 }
01631 }
01632 else
01633 {
01634 pageCache->selectText(foundSelection);
01635 gotoPage(pageCache->selectedText());
01636 setStatusBarText(QString::null);
01637 searchInProgress = false;
01638 if (!cachedPage)
01639 delete searchPage;
01640 return;
01641 }
01642 }
01643
01644 KMessageBox::sorry(scrollView(), i18n("<qt>The search string <strong>%1</strong> could not be found.</qt>").arg(searchText));
01645 setStatusBarText(QString::null);
01646 searchInProgress = false;
01647 if (!cachedPage)
01648 delete searchPage;
01649 }
01650
01651
01652 void KMultiPage::clearSelection()
01653 {
01654 PageNumber page = pageCache->selectedText().getPageNumber();
01655
01656 if (!page.isValid())
01657 return;
01658
01659
01660 pageCache->deselectText();
01661
01662
01663 switch(widgetList.size())
01664 {
01665 case 0:
01666 kdError(4300) << "KMultiPage::clearSelection() while widgetList is empty" << endl;
01667 break;
01668 case 1:
01669 widgetList[0]->update();
01670 break;
01671 default:
01672 for (unsigned int i = 0; i < widgetList.size(); i++)
01673 {
01674 DocumentWidget* pageWidget = (DocumentWidget*)widgetList[i];
01675 if (pageWidget->getPageNumber() == page)
01676 {
01677 pageWidget->update();
01678 break;
01679 }
01680 }
01681 }
01682 }
01683
01684 void KMultiPage::copyText()
01685 {
01686 pageCache->selectedText().copyText();
01687 }
01688
01689 void KMultiPage::timerEvent( QTimerEvent * )
01690 {
01691 #ifdef KMULTIPAGE_DEBUG
01692 kdDebug(4300) << "Timer Event " << endl;
01693 #endif
01694 reload();
01695 }
01696
01697
01698 void KMultiPage::reload()
01699 {
01700 #ifdef KMULTIPAGE_DEBUG
01701 kdDebug(4300) << "Reload file " << m_file << endl;
01702 #endif
01703
01704 if (renderer.isNull()) {
01705 kdError() << "KMultiPage::reload() called, but no renderer was set" << endl;
01706 return;
01707 }
01708
01709 if (renderer->isValidFile(m_file)) {
01710 pageCache->clear();
01711 pageCache->deselectText();
01712 document_history.clear();
01713 emit setStatusBarText(i18n("Reloading file %1").arg(m_file));
01714 Q_INT32 pg = currentPageNumber();
01715
01716 killTimer(timer_id);
01717 timer_id = -1;
01718 bool r = renderer->setFile(m_file, m_url);
01719
01720 generateDocumentWidgets();
01721
01722
01723 tableOfContents->setContents(renderer->getBookmarks());
01724
01725
01726 markList()->clear();
01727 markList()->setNumberOfPages(numberOfPages(), KVSPrefs::showThumbnails());
01728
01729 setCurrentPageNumber(pg);
01730 setFile(r);
01731 emit setStatusBarText(QString::null);
01732 } else {
01733 if (timer_id == -1)
01734 timer_id = startTimer(1000);
01735 }
01736 }
01737
01738
01739 bool KMultiPage::openFile()
01740 {
01741 if (renderer.isNull()) {
01742 kdError(4300) << "KMultiPage::openFile() called when no renderer was set" << endl;
01743 return false;
01744 }
01745
01746 pageCache->deselectText();
01747 document_history.clear();
01748 pageCache->clear();
01749 emit setStatusBarText(i18n("Loading file %1").arg(m_file));
01750
01751 bool r = renderer->setFile(m_file, m_url);
01752
01753 if (r) {
01754 setCurrentPageNumber(1);
01755 generateDocumentWidgets();
01756
01757
01758 markList()->clear();
01759 markList()->setNumberOfPages(numberOfPages(), KVSPrefs::showThumbnails());
01760
01761 QString reference = url().ref();
01762 if (!reference.isEmpty())
01763 gotoPage(renderer->parseReference(reference));
01764
01765
01766 tableOfContents->setContents(renderer->getBookmarks());
01767 } else
01768 m_file = QString::null;
01769
01770
01771 setFile(r);
01772
01773
01774 emit setStatusBarText(QString::null);
01775 return r;
01776 }
01777
01778
01779 bool KMultiPage::openURL(const QString &filename, const KURL &base_url)
01780 {
01781 m_file = filename;
01782 m_url = base_url;
01783
01784 bool success = openFile();
01785 if (success)
01786 setCurrentPageNumber(1);
01787
01788 return success;
01789 }
01790
01791
01792 void KMultiPage::enableActions(bool fileLoaded)
01793 {
01794 Q_UNUSED(fileLoaded);
01795 }
01796
01797 void KMultiPage::wheelEvent(QWheelEvent *e)
01798 {
01799 QScrollBar *sb = scrollView()->verticalScrollBar();
01800 if (sb == 0)
01801 return;
01802
01803
01804 if (e->state() & ControlButton)
01805 {
01806 if (e->delta() < 0)
01807 emit zoomOut();
01808 else
01809 emit zoomIn();
01810 return;
01811 }
01812
01813 Q_INT32 pxl = -(e->delta()*sb->lineStep())/60;
01814 if (pxl == 0)
01815 {
01816 if (e->delta() > 0)
01817 pxl = -1;
01818 else
01819 pxl = 1;
01820 }
01821
01822
01823 if (e->state() & ShiftButton)
01824 pxl *= 10;
01825
01826 scroll(pxl);
01827 }
01828
01829
01830 KPrinter *KMultiPage::getPrinter(bool enablePageSizeFeatures)
01831 {
01832
01833 KPrinter *printer = new KPrinter(true);
01834 if (printer == 0) {
01835 kdError(1223) << "KMultiPage::getPrinter(..): Cannot allocate new KPrinter structure" << endl;
01836 return 0;
01837 }
01838
01839
01840
01841 if (enablePageSizeFeatures == true) {
01842 KPrintDialogPage_PageOptions *pageOptions = new KPrintDialogPage_PageOptions();
01843 if (pageOptions == 0) {
01844 kdError(1223) << "KMultiPage::getPrinter(..): Cannot allocate new KPrintDialogPage_PageOptions structure" << endl;
01845 delete printer;
01846 return 0;
01847 }
01848 printer->addDialogPage( pageOptions );
01849 }
01850
01851
01852 printer->setPageSelection( KPrinter::ApplicationSide );
01853 printer->setCurrentPage( currentPageNumber() );
01854 printer->setMinMax( 1, numberOfPages() );
01855 printer->setFullPage( true );
01856
01857
01858
01859
01860
01861 QValueList<int> selectedPageNo = selectedPages();
01862 if (selectedPageNo.isEmpty() == true)
01863 printer->setOption( "kde-range", "" );
01864 else {
01865 int commaflag = 0;
01866 QString range;
01867 QValueList<int>::ConstIterator it = selectedPageNo.begin();
01868 do{
01869 int val = *it;
01870 if (commaflag == 1)
01871 range += QString(", ");
01872 else
01873 commaflag = 1;
01874 int endval = val;
01875 if (it != selectedPageNo.end()) {
01876 QValueList<int>::ConstIterator jt = it;
01877 jt++;
01878 do{
01879 int val2 = *jt;
01880 if (val2 == endval+1)
01881 endval++;
01882 else
01883 break;
01884 jt++;
01885 } while( jt != selectedPageNo.end() );
01886 it = jt;
01887 } else
01888 it++;
01889 if (endval == val)
01890 range += QString("%1").arg(val);
01891 else
01892 range += QString("%1-%2").arg(val).arg(endval);
01893 } while (it != selectedPageNo.end() );
01894 printer->setOption( "kde-range", range );
01895 }
01896
01897 return printer;
01898 }
01899
01900 void KMultiPage::doExportText()
01901 {
01902
01903 QString suggestedName = url().filename();
01904 suggestedName = suggestedName.left(suggestedName.find(".")) + ".txt";
01905
01906 QString fileName = KFileDialog::getSaveFileName(suggestedName, i18n("*.txt|Plain Text (Latin 1) (*.txt)"), scrollView(), i18n("Export File As"));
01907
01908 if (fileName.isEmpty())
01909 return;
01910
01911 QFileInfo finfo(fileName);
01912 if (finfo.exists())
01913 {
01914 int r = KMessageBox::warningContinueCancel (scrollView(),
01915 i18n("The file %1\nexists. Do you want to overwrite that file?").arg(fileName),
01916 i18n("Overwrite File"), i18n("Overwrite"));
01917
01918 if (r == KMessageBox::Cancel)
01919 return;
01920 }
01921
01922 QFile textFile(fileName);
01923 textFile.open(IO_WriteOnly);
01924 QTextStream stream(&textFile);
01925
01926 QProgressDialog progress(i18n("Exporting to text..."), i18n("Abort"), renderer->totalPages(),
01927 scrollView(), "export_text_progress", true);
01928 progress.setMinimumDuration(300);
01929
01930 RenderedDocumentPagePixmap dummyPage;
01931 dummyPage.resize(1, 1);
01932
01933 for(unsigned int page = 1; page <= renderer->totalPages(); page++)
01934 {
01935 progress.setProgress(page);
01936 qApp->processEvents();
01937
01938 if (progress.wasCancelled())
01939 break;
01940
01941 dummyPage.setPageNumber(page);
01942
01943 renderer->getText(&dummyPage);
01944
01945 for(unsigned int i = 0; i < dummyPage.textBoxList.size(); i++)
01946 {
01947
01948 if (i > 0)
01949 {
01950
01951
01952
01953 if (dummyPage.textBoxList[i].box.top() > dummyPage.textBoxList[i-1].box.bottom() &&
01954 dummyPage.textBoxList[i].box.x() < dummyPage.textBoxList[i-1].box.x())
01955 {
01956 stream << "\n";
01957 }
01958 }
01959 stream << dummyPage.textBoxList[i].text;
01960 }
01961
01962
01963 stream << "\n";
01964 }
01965
01966
01967 progress.setProgress(renderer->totalPages());
01968 return;
01969 }
01970
01971 void KMultiPage::slotEnableMoveTool(bool enable)
01972 {
01973 emit enableMoveTool(enable);
01974 }
01975
01976 #include "kmultipage.moc"