• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kviewshell

kviewpart.cpp

Go to the documentation of this file.
00001 #include <qfileinfo.h>
00002 #include <qhbox.h>
00003 #include <qlayout.h>
00004 #include <qscrollview.h>
00005 #include <qscrollbar.h>
00006 #include <qtimer.h>
00007 #include <qpainter.h>
00008 #include <qprinter.h>
00009 #include <qprintdialog.h>
00010 
00011 #include <kaboutdialog.h>
00012 #include <kaccel.h>
00013 #include <kaction.h>
00014 #include <kapplication.h>
00015 #include <kconfig.h>
00016 #include <kconfigdialog.h>
00017 #include <kdebug.h>
00018 #include <kdirwatch.h>
00019 #include <kfiledialog.h>
00020 #include <kfilterbase.h>
00021 #include <kfilterdev.h>
00022 #include <kglobal.h>
00023 #include <kinstance.h>
00024 #include <kio/job.h>
00025 #include <klocale.h>
00026 #include <kiconloader.h>
00027 #include <kmessagebox.h>
00028 #include <kmimetype.h>
00029 #include <kparts/componentfactory.h>
00030 #include <kparts/genericfactory.h>
00031 #include <kparts/partmanager.h>
00032 #include <kprogress.h>
00033 #include <kstandarddirs.h>
00034 #include <kstdaction.h>
00035 #include <ktempfile.h>
00036 #include <ktrader.h>
00037 #include <kinputdialog.h>
00038 
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <math.h>
00042 
00043 #include "kviewpart.h"
00044 #include "kmultipage.h"
00045 #include "pageSize.h"
00046 #include "pageSizeDialog.h"
00047 #include "zoomlimits.h"
00048 
00049 #include "optionDialogGUIWidget_base.h"
00050 #include "optionDialogAccessibilityWidget.h"
00051 
00052 #include "kvsprefs.h"
00053 
00054 #define MULTIPAGE_VERSION 2
00055 
00056 typedef KParts::GenericFactory<KViewPart> KViewPartFactory;
00057 K_EXPORT_COMPONENT_FACTORY(kviewerpart, KViewPartFactory)
00058 
00059 KViewPart::KViewPart(QWidget *parentWidget, const char *widgetName, QObject *parent,
00060                      const char *name, const QStringList& args)
00061   : KViewPart_Iface(parent, name), showSidebar(0), saveAction(0), partManager(0),
00062     multiPageLibrary(QString::null), aboutDialog(0)
00063 {
00064   KGlobal::locale()->insertCatalogue("kviewshell");
00065 
00066   tmpUnzipped = 0L;
00067   pageChangeIsConnected = false;
00068   setInstance(KViewPartFactory::instance());
00069 
00070   watch = KDirWatch::self();
00071   connect(watch, SIGNAL(dirty(const QString&)), this, SLOT(fileChanged(const QString&)));
00072   watch->startScan();
00073 
00074   mainWidget = new QHBox(parentWidget, widgetName);
00075   mainWidget->setFocusPolicy(QWidget::StrongFocus);
00076   setWidget(mainWidget);
00077 
00078   // Setup part manager
00079   partManager = new KParts::PartManager(parentWidget, "PartManager for kviewpart");
00080   setManager(partManager);
00081   // Don't switch to another part when pressing a mouse button
00082   partManager->setActivationButtonMask(0);
00083   // Without this the GUI-items of the KMultiPages are not merged
00084   partManager->setAllowNestedParts(true);
00085 
00086   connect(partManager, SIGNAL(activePartChanged(KParts::Part*)), this, SIGNAL(pluginChanged(KParts::Part*)));
00087   partManager->addPart(this);
00088 
00089   // create the displaying part
00090 
00091   // Search for service
00092   KTrader::OfferList offers;
00093 
00094   if (!args.isEmpty())
00095   {
00096     // If a default MimeType is specified try to load a MultiPage supporting it.
00097     QString defaultMimeType = args.first();
00098     offers = KTrader::self()->query(
00099         QString::fromLatin1("KViewShell/MultiPage" ),
00100         QString("([X-KDE-MultiPageVersion] == %1) and "
00101                 "([X-KDE-MimeTypes] == '%2')").arg(MULTIPAGE_VERSION).arg(defaultMimeType));
00102   }
00103 
00104   // If no default MimeType is given or no MultiPage has been found, try to load the Empty MultiPage.
00105   if (offers.isEmpty())
00106   {
00107     offers = KTrader::self()->query(
00108         QString::fromLatin1("KViewShell/MultiPage" ),
00109         QString("([X-KDE-MultiPageVersion] == %1) and "
00110                 "([X-KDE-EmptyMultiPage] == 1)").arg(MULTIPAGE_VERSION));
00111   }
00112 
00113   // If still no MultiPage has been found, report an error and abort.
00114   if (offers.isEmpty())
00115   {
00116     KMessageBox::error(parentWidget, i18n("<qt>No MultiPage found.</qt>"));
00117     //    return;
00118   }
00119 
00120   KService::Ptr service = offers.first();
00121   kdDebug(1223) << service->library() << endl;
00122 
00123   // Try to load the multiPage
00124   int error;
00125   multiPage = static_cast<KMultiPage*>(KParts::ComponentFactory::createInstanceFromService<KParts::ReadOnlyPart>(service, mainWidget,
00126                                                          service->name().utf8(), QStringList(), &error ));
00127 
00128   // If the loading of the MultiPage failed report and error and abort.
00129   if (!multiPage) {
00130     QString reason;
00131     switch(error) {
00132     case KParts::ComponentFactory::ErrNoServiceFound:
00133       reason = i18n("<qt>No service implementing the given mimetype and fullfilling the given constraint expression can be found.</qt>");
00134       break;
00135     case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
00136       reason = i18n("<qt>The specified service provides no shared library.</qt>");
00137       break;
00138     case KParts::ComponentFactory::ErrNoLibrary:
00139       reason = i18n("<qt><p>The specified library <b>%1</b> could not be loaded. The error message returned was:</p>"
00140             "<p><b>%2</b></p></qt>").arg(service->library()).arg(KLibLoader::self()->lastErrorMessage());
00141       break;
00142     case KParts::ComponentFactory::ErrNoFactory:
00143       reason = i18n("<qt>The library does not export a factory for creating components.</qt>");
00144       break;
00145     case KParts::ComponentFactory::ErrNoComponent:
00146       reason = i18n("<qt>The factory does not support creating components of the specified type.</qt>");
00147       break;
00148     }
00149 
00150     QString text = i18n("<qt><p><b>Problem:</b> The document <b>%1</b> cannot be shown.</p>"
00151             "<p><b>Reason:</b> The software component <b>%2</b> which is required to "
00152             "display your files could not be initialized. This could point to "
00153             "serious misconfiguration of your KDE system, or to damaged program files.</p>"
00154             "<p><b>What you can do:</b> You could try to re-install the software packages in "
00155             "question. If that does not help, you could file an error report, either to the "
00156             "provider of your software (e.g. the vendor of your Linux distribution), or "
00157             "directly to the authors of the software. The entry <b>Report Bug...</b> in the "
00158             "<b>Help</b> menu helps you to contact the KDE programmers.</p></qt>").arg(m_file).arg(service->library());
00159     QString caption = i18n("Error Initializing Software Component");
00160     KMessageBox::detailedError(mainWidget, text, reason, caption);
00161     emit setStatusBarText(QString::null);
00162     return;
00163   }
00164   // Make the KViewPart the parent of the MultiPage.
00165   // So the Partmanager treats it as a nested KPart.
00166   insertChild(multiPage);
00167 
00168   // Remember the name of the library.
00169   multiPageLibrary = service->library();
00170   // Add the multipage to the GUI.
00171   partManager->addPart(multiPage);
00172 
00173   exportTextAction = new KAction(i18n("Text..."), 0, this, SLOT(mp_exportText()), actionCollection(), "export_text");
00174 
00175   // edit menu
00176   findTextAction = KStdAction::find(this, SLOT(mp_showFindTextDialog()), actionCollection(), "find");
00177   findNextAction = KStdAction::findNext(this, SLOT(mp_findNextText()), actionCollection(), "findnext");
00178   findNextAction->setEnabled(false);
00179   findPrevAction = KStdAction::findPrev(this, SLOT(mp_findPrevText()), actionCollection(), "findprev");
00180   findPrevAction->setEnabled(false);
00181 
00182   selectAllAction = KStdAction::selectAll(this, SLOT(mp_doSelectAll()), actionCollection(), "edit_select_all");
00183 
00184   copyTextAction = KStdAction::copy(this, SLOT(mp_copyText()), actionCollection(), "copy_text");
00185   copyTextAction->setEnabled(false);
00186 
00187   deselectAction = KStdAction::deselect(this, SLOT(mp_clearSelection()), actionCollection(), "edit_deselect_all");
00188   deselectAction->setEnabled(false);
00189 
00190   saveAction = KStdAction::save(this, SLOT(mp_slotSave_defaultFilename()), actionCollection());
00191 
00192   // settings menu
00193   showSidebar = new KToggleAction (i18n("Show &Sidebar"), "show_side_panel", 0, this,
00194                                    SLOT(slotShowSidebar()), actionCollection(), "show_sidebar");
00195   showSidebar->setCheckedState(i18n("Hide &Sidebar"));
00196   watchAct = new KToggleAction(i18n("&Watch File"), 0, 0, 0, actionCollection(), "watch_file");
00197   scrollbarHandling = new KToggleAction (i18n("Show Scrollbars"), 0, 0, 0, actionCollection(), "scrollbarHandling");
00198   scrollbarHandling->setCheckedState(i18n("Hide Scrollbars"));
00199 
00200   // View modes
00201   QStringList viewModes;
00202   viewModes.append(i18n("Single Page"));
00203   viewModes.append(i18n("Continuous"));
00204   viewModes.append(i18n("Continuous - Facing"));
00205   viewModes.append(i18n("Overview"));
00206   viewModeAction = new KSelectAction (i18n("View Mode"), 0, 0, 0, actionCollection(), "viewmode");
00207   viewModeAction->setItems(viewModes);
00208 
00209   // Orientation menu
00210   QStringList orientations;
00211   orientations.append(i18n("Portrait"));
00212   orientations.append(i18n("Landscape"));
00213   orientation = new KSelectAction (i18n("Preferred &Orientation"), 0, 0, 0, actionCollection(), "view_orientation");
00214   orientation->setItems(orientations);
00215   connect(orientation, SIGNAL(activated (int)), &userRequestedPaperSize, SLOT(setOrientation(int)));
00216 
00217   // Zoom Menu
00218   zoom_action = new KSelectAction (i18n("&Zoom"), 0, 0, 0, actionCollection(), "view_zoom");
00219   zoom_action->setEditable(true);
00220   zoom_action->setItems(_zoomVal.zoomNames());
00221 
00222   connect (&_zoomVal, SIGNAL(zoomNamesChanged(const QStringList &)), zoom_action, SLOT(setItems(const QStringList &)));
00223   connect (&_zoomVal, SIGNAL(valNoChanged(int)), zoom_action, SLOT(setCurrentItem(int)));
00224   connect (&_zoomVal, SIGNAL(zoomNameChanged(const QString &)), this, SIGNAL(zoomChanged(const QString &)) );
00225   connect (zoom_action, SIGNAL(activated(const QString &)), this, SLOT(setZoomValue(const QString &)));
00226   _zoomVal.setZoomValue(1.0); // should not be necessary @@@@
00227   emit(zoomChanged("100%"));
00228 
00229   // Paper Size Menu
00230   media = new KSelectAction (i18n("Preferred Paper &Size"), 0, 0, 0, actionCollection(), "view_media");
00231   QStringList items = userRequestedPaperSize.pageSizeNames();
00232   items.prepend(i18n("Custom Size..."));
00233   media->setItems(items);
00234   connect (media, SIGNAL(activated(int)), this, SLOT(slotMedia(int)));
00235 
00236   useDocumentSpecifiedSize = new KToggleAction(i18n("&Use Document Specified Paper Size"), 0, this, SLOT(slotShowSidebar()),
00237                            actionCollection(), "view_use_document_specified_size");
00238 
00239   // Zoom Actions
00240   zoomInAct = KStdAction::zoomIn (this, SLOT(zoomIn()), actionCollection());
00241   zoomOutAct = KStdAction::zoomOut(this, SLOT(zoomOut()), actionCollection());
00242 
00243   fitPageAct = new KToggleAction(i18n("&Fit to Page"), "view_fit_window", Key_P,
00244                                  actionCollection(), "view_fit_to_page");
00245   fitWidthAct = new KToggleAction(i18n("Fit to Page &Width"), "view_fit_width", Key_W,
00246                                   actionCollection(), "view_fit_to_width");
00247   fitHeightAct = new KToggleAction(i18n("Fit to Page &Height"), "view_fit_height", Key_H,
00248                                    actionCollection(), "view_fit_to_height");
00249 
00250   fitPageAct -> setExclusiveGroup("view_fit");
00251   fitWidthAct -> setExclusiveGroup("view_fit");
00252   fitHeightAct -> setExclusiveGroup("view_fit");
00253 
00254   connect(fitPageAct, SIGNAL(toggled(bool)), this, SLOT(enableFitToPage(bool)));
00255   connect(fitWidthAct, SIGNAL(toggled(bool)), this, SLOT(enableFitToWidth(bool)));
00256   connect(fitHeightAct, SIGNAL(toggled(bool)), this, SLOT(enableFitToHeight(bool)));
00257 
00258   // go menu
00259   backAct = KStdAction::prior(this, SLOT(mp_prevPage()), actionCollection());
00260   forwardAct = KStdAction::next(this, SLOT(mp_nextPage()), actionCollection());
00261   startAct = KStdAction::firstPage(this, SLOT(mp_firstPage()), actionCollection());
00262   endAct = KStdAction::lastPage(this, SLOT(mp_lastPage()), actionCollection());
00263   gotoAct = KStdAction::gotoPage(this, SLOT(goToPage()), actionCollection());
00264   gotoAct->setShortcut("CTRL+G");
00265 
00266   readUpAct = new KAction(i18n("Read Up Document"), "up", SHIFT+Key_Space, this, SLOT(mp_readUp()), actionCollection(), "go_read_up");
00267   readDownAct = new KAction(i18n("Read Down Document"), "down", Key_Space, this, SLOT(mp_readDown()), actionCollection(), "go_read_down");
00268 
00269   printAction = KStdAction::print(this, SLOT(slotPrint()), actionCollection());
00270 
00271   saveAsAction = KStdAction::saveAs(this, SLOT(mp_slotSave()), actionCollection());
00272 
00273   // mode action
00274   moveModeAction = new KRadioAction(i18n("&Move Tool"), "movetool", Key_F4, actionCollection(), "move_tool");
00275   selectionModeAction = new KRadioAction(i18n("&Selection Tool"), "selectiontool", Key_F5, actionCollection(), "selection_tool");
00276 
00277   moveModeAction->setExclusiveGroup("tools");
00278   selectionModeAction->setExclusiveGroup("tools");
00279 
00280   moveModeAction->setChecked(true);
00281 
00282   connect(moveModeAction, SIGNAL(toggled(bool)), this, SLOT(slotEnableMoveTool(bool)));
00283   //connect(selectionModeAction, SIGNAL(toggled(bool)), this, SLOT(slotEnableSelectionTool(bool)));
00284 
00285   // history action
00286   backAction = new KAction(i18n("&Back"), "1leftarrow", 0,
00287                    this, SLOT(mp_doGoBack()), actionCollection(), "go_back");
00288   forwardAction = new KAction(i18n("&Forward"), "1rightarrow", 0,
00289                       this, SLOT(mp_doGoForward()), actionCollection(), "go_forward");
00290 
00291   backAction->setEnabled(false);
00292   forwardAction->setEnabled(false);
00293 
00294 
00295   settingsAction = KStdAction::preferences(this, SLOT(doSettings()), actionCollection());
00296 
00297   // We only show this menuitem if no default mimetype is set. This usually means kviewshell
00298   // has been started by itself. Otherwise if KDVI or KFaxView has been started show the
00299   // additional about information.
00300   if (!args.isEmpty())
00301   {
00302     aboutAction = new KAction(i18n("About KViewShell"), "kviewshell", 0, this,
00303                             SLOT(aboutKViewShell()), actionCollection(), "help_about_kviewshell");
00304   }
00305 
00306   // keyboard accelerators
00307   accel = new KAccel(mainWidget);
00308   accel->insert(I18N_NOOP("Scroll Up"), Key_Up, this, SLOT(mp_scrollUp()));
00309   accel->insert(I18N_NOOP("Scroll Down"), Key_Down, this, SLOT(mp_scrollDown()));
00310   accel->insert(I18N_NOOP("Scroll Left"), Key_Left, this, SLOT(mp_scrollLeft()));
00311   accel->insert(I18N_NOOP("Scroll Right"), Key_Right, this, SLOT(mp_scrollRight()));
00312 
00313   accel->insert(I18N_NOOP("Scroll Up Page"), SHIFT+Key_Up, this, SLOT(mp_scrollUpPage()));
00314   accel->insert(I18N_NOOP("Scroll Down Page"), SHIFT+Key_Down, this, SLOT(mp_scrollDownPage()));
00315   accel->insert(I18N_NOOP("Scroll Left Page"), SHIFT+Key_Left, this, SLOT(mp_scrollLeftPage()));
00316   accel->insert(I18N_NOOP("Scroll Right Page"), SHIFT+Key_Right, this, SLOT(mp_scrollRightPage()));
00317 
00318   accel->readSettings();
00319   readSettings();
00320 
00321   m_extension = new KViewPartExtension(this);
00322 
00323   setXMLFile("kviewerpart.rc");
00324 
00325   initializeMultiPage();
00326 
00327   // The page size dialog is constructed on first usage -- saves some
00328   // memory when not used.
00329   _pageSizeDialog = 0;
00330 
00331   checkActions();
00332   viewModeAction->setCurrentItem(KVSPrefs::viewMode());
00333 
00334   // We disconnect because we dont want some FocusEvents to trigger a GUI update, which might mess
00335   // with our menus.
00336   disconnect(partManager, SIGNAL(activePartChanged(KParts::Part*)), this, SIGNAL(pluginChanged(KParts::Part*)));
00337 }
00338 
00339 KViewPart::~KViewPart()
00340 {
00341   writeSettings();
00342 
00343   // Without the next two lines, konqueror crashes when it is quit
00344   // while displaying a DVI file. I don't really understand
00345   // why... --Stefan.
00346   if (manager() != 0)
00347     manager()->removePart(this);
00348 
00349   // Delete the partManager;
00350   setManager(0);
00351   delete partManager;
00352 
00353   delete multiPage;
00354   delete tmpUnzipped;
00355 }
00356 
00357 
00358 void KViewPart::initializeMultiPage()
00359 {
00360   // Paper Size handling
00361   multiPage->setUseDocumentSpecifiedSize(useDocumentSpecifiedSize->isChecked());
00362   multiPage->setUserPreferredSize(userRequestedPaperSize);
00363   connect(&userRequestedPaperSize, SIGNAL(sizeChanged(const SimplePageSize&)), multiPage, SLOT(setUserPreferredSize(const SimplePageSize&)));
00364   connect(useDocumentSpecifiedSize, SIGNAL(toggled(bool)), multiPage, SLOT(setUseDocumentSpecifiedSize(bool)));
00365 
00366 
00367   connect(scrollbarHandling, SIGNAL(toggled(bool)),  multiPage, SLOT(slotShowScrollbars(bool)));
00368 
00369   // connect to the multi page view
00370   connect( this, SIGNAL(scrollbarStatusChanged(bool)), multiPage, SLOT(slotShowScrollbars(bool)));
00371   connect( multiPage, SIGNAL(pageInfo(int, int)), this, SLOT(pageInfo(int, int)) );
00372   connect( multiPage, SIGNAL(askingToCheckActions()), this, SLOT(checkActions()) );
00373   connect( multiPage, SIGNAL( started( KIO::Job * ) ), this, SIGNAL( started( KIO::Job * ) ) );
00374   connect( multiPage, SIGNAL( completed() ), this, SIGNAL( completed() ) );
00375   connect( multiPage, SIGNAL( canceled( const QString & ) ), this, SIGNAL( canceled( const QString & ) ) );
00376   connect( multiPage, SIGNAL( setStatusBarText( const QString& ) ), this, SLOT( setStatusBarTextFromMultiPage( const QString& ) ) );
00377 
00378   connect( multiPage, SIGNAL(zoomIn()), this, SLOT(zoomIn()) );
00379   connect( multiPage, SIGNAL(zoomOut()), this, SLOT(zoomOut()) );
00380 
00381   // change the viewmode
00382   connect(viewModeAction, SIGNAL(activated (int)), multiPage, SLOT(setViewMode(int)));
00383 
00384   // Update zoomlevel on viewmode changes
00385   connect(multiPage, SIGNAL(viewModeChanged()), this, SLOT(updateZoomLevel()));
00386 
00387   // navigation history
00388   connect(multiPage->history(), SIGNAL(backItem(bool)), backAction, SLOT(setEnabled(bool)));
00389   connect(multiPage->history(), SIGNAL(forwardItem(bool)), forwardAction, SLOT(setEnabled(bool)));
00390 
00391   // text selection
00392   connect(multiPage, SIGNAL(textSelected(bool)), copyTextAction, SLOT(setEnabled(bool)));
00393   connect(multiPage, SIGNAL(textSelected(bool)), deselectAction, SLOT(setEnabled(bool)));
00394 
00395   // text search
00396   connect(multiPage, SIGNAL(searchEnabled(bool)), findNextAction, SLOT(setEnabled(bool)));
00397   connect(multiPage, SIGNAL(searchEnabled(bool)), findPrevAction, SLOT(setEnabled(bool)));
00398 
00399   // allow parts to have a GUI, too :-)
00400   // (will be merged automatically)
00401   insertChildClient( multiPage );
00402 }
00403 
00404 void KViewPart::slotStartFitTimer()
00405 {
00406   fitTimer.start(100, true);
00407 }
00408 
00409 
00410 QString KViewPart::pageSizeDescription()
00411 {
00412   PageNumber nr = multiPage->currentPageNumber();
00413   if (!nr.isValid())
00414     return QString::null;
00415   SimplePageSize ss = multiPage->sizeOfPage(nr);
00416   if (!ss.isValid())
00417     return QString::null;
00418   pageSize s(ss);
00419 
00420   QString size = " ";
00421   if (s.formatNumber() == -1) {
00422     if (KGlobal::locale()-> measureSystem() == KLocale::Metric)
00423       size += QString("%1x%2 mm").arg(s.width().getLength_in_mm(), 0, 'f', 0).arg(s.height().getLength_in_mm(), 0, 'f', 0);
00424     else
00425       size += QString("%1x%2 in").arg(s.width().getLength_in_inch(), 0, 'g', 2).arg(s.height().getLength_in_inch(), 0, 'g', 2);
00426   } else {
00427     size += s.formatName() + "/";
00428     if (s.getOrientation() == 0)
00429       size += i18n("portrait");
00430     else
00431       size += i18n("landscape");
00432   }
00433   return size+" ";
00434 }
00435 
00436 
00437 void KViewPart::restoreDocument(const KURL &url, int page)
00438 {
00439   if (openURL(url))
00440     multiPage->gotoPage(page);
00441 }
00442 
00443 
00444 void KViewPart::saveDocumentRestoreInfo(KConfig* config)
00445 {
00446   config->writePathEntry("URL", url().url());
00447   if (multiPage->numberOfPages() > 0)
00448     config->writeEntry("Page", multiPage->currentPageNumber());
00449 }
00450 
00451 
00452 void KViewPart::slotFileOpen()
00453 {
00454   if ((!multiPage.isNull()) && (multiPage->isModified() == true)) {
00455     int ans = KMessageBox::warningContinueCancel( 0,
00456                      i18n("Your document has been modified. Do you really want to open another document?"),
00457                      i18n("Warning - Document Was Modified"),KStdGuiItem::open());
00458     if (ans == KMessageBox::Cancel)
00459       return;
00460   }
00461 
00462   KURL url = KFileDialog::getOpenURL(QString::null, supportedMimeTypes().join(" "));
00463 
00464   if (!url.isEmpty())
00465     openURL(url);
00466 }
00467 
00468 QStringList KViewPart::supportedMimeTypes()
00469 {
00470   QStringList supportedMimeTypes;
00471 
00472   // Search for service
00473   KTrader::OfferList offers = KTrader::self()->query(
00474       QString::fromLatin1("KViewShell/MultiPage"),
00475       QString("([X-KDE-MultiPageVersion] == %1)").arg(MULTIPAGE_VERSION)
00476   );
00477 
00478   if (!offers.isEmpty())
00479   {
00480     KTrader::OfferList::ConstIterator iterator = offers.begin();
00481     KTrader::OfferList::ConstIterator end = offers.end();
00482 
00483     for (; iterator != end; ++iterator)
00484     {
00485       KService::Ptr service = *iterator;
00486       QString mimeType = service->property("X-KDE-MimeTypes").toString();
00487       supportedMimeTypes << mimeType;
00488 
00489     }
00490   }
00491 
00492   // The kviewshell is also able to read compressed files and to
00493   // uncompress them on the fly.
00494 
00495   // Check if this version of KDE supports bzip2
00496   bool bzip2Available = (KFilterBase::findFilterByMimeType( "application/x-bzip2" ) != 0L);
00497 
00498   supportedMimeTypes << "application/x-gzip";
00499 
00500   if (bzip2Available)
00501   {
00502     supportedMimeTypes << "application/x-bzip2";
00503   }
00504 
00505   return supportedMimeTypes;
00506 }
00507 
00508 QStringList KViewPart::fileFormats() const
00509 {
00510   // Compile a list of the supported filename patterns
00511 
00512   // First we build a list of the mimetypes which are supported by the
00513   // currently installed KMultiPage-Plugins.
00514   QStringList supportedMimeTypes;
00515   QStringList supportedPattern;
00516 
00517   // Search for service
00518   KTrader::OfferList offers = KTrader::self()->query(
00519       QString::fromLatin1("KViewShell/MultiPage"),
00520       QString("([X-KDE-MultiPageVersion] == %1)").arg(MULTIPAGE_VERSION)
00521   );
00522 
00523   if (!offers.isEmpty())
00524   {
00525     KTrader::OfferList::ConstIterator iterator = offers.begin();
00526     KTrader::OfferList::ConstIterator end = offers.end();
00527 
00528     for (; iterator != end; ++iterator)
00529     {
00530       KService::Ptr service = *iterator;
00531       QString mimeType = service->property("X-KDE-MimeTypes").toString();
00532       supportedMimeTypes << mimeType;
00533 
00534       QStringList pattern = KMimeType::mimeType(mimeType)->patterns();
00535       while(!pattern.isEmpty())
00536       {
00537         supportedPattern.append(pattern.front().stripWhiteSpace());
00538         pattern.pop_front();
00539       }
00540     }
00541   }
00542 
00543   // The kviewshell is also able to read compressed files and to
00544   // uncompress them on the fly. Thus, we modify the list of supported
00545   // file formats which we obtain from the multipages to include
00546   // compressed files like "*.dvi.gz". We add "*.dvi.bz2" if support
00547   // for bzip2 is compiled into KDE.
00548 
00549   // Check if this version of KDE supports bzip2
00550   bool bzip2Available = (KFilterBase::findFilterByMimeType( "application/x-bzip2" ) != 0L);
00551 
00552   QStringList compressedPattern;
00553 
00554   for(QStringList::Iterator it = supportedPattern.begin(); it != supportedPattern.end(); ++it )
00555   {
00556     if ((*it).find(".gz", -3) == -1) // Paranoia safety check
00557       compressedPattern.append(*it + ".gz");
00558 
00559     if ((bzip2Available) && ((*it).find(".bz2", -4) == -1)) // Paranoia safety check
00560       compressedPattern.append(*it + ".bz2");
00561   }
00562 
00563   while (!compressedPattern.isEmpty())
00564   {
00565     supportedPattern.append(compressedPattern.front());
00566     compressedPattern.pop_front();
00567   }
00568 
00569   kdDebug(1223) << "Supported Pattern: " << supportedPattern << endl;
00570 
00571   return supportedPattern;
00572 }
00573 
00574 
00575 void KViewPart::slotSetFullPage(bool fullpage)
00576 {
00577   if (multiPage)
00578     multiPage->slotSetFullPage(fullpage);
00579   else
00580     kdError(1223) << "KViewPart::slotSetFullPage() called without existing multipage" << endl;
00581 
00582   // Restore normal view
00583   if (fullpage == false)
00584   {
00585     slotShowSidebar();
00586     multiPage->slotShowScrollbars(scrollbarHandling->isChecked());
00587   }
00588 }
00589 
00590 
00591 void KViewPart::slotShowSidebar()
00592 {
00593   bool show = showSidebar->isChecked();
00594   multiPage->slotShowSidebar(show);
00595 }
00596 
00597 
00598 bool KViewPart::openFile()
00599 {
00600   KURL tmpFileURL;
00601 
00602   // We try to be error-tolerant about filenames. If the user calls us
00603   // with something like "test", and we are using the DVI-part, we'll
00604   // also look for "testdvi" and "test.dvi".
00605   QFileInfo fi(m_file);
00606   m_file = fi.absFilePath();
00607 
00608   if (!fi.exists())
00609   {
00610     QStringList supportedPatterns = fileFormats();
00611     QStringList endings;
00612 
00613     for (QStringList::Iterator it = supportedPatterns.begin(); it != supportedPatterns.end(); ++it)
00614     {
00615       // Only consider patterns starting with "*."
00616       if ((*it).find("*.") == 0)
00617       {
00618         // Remove first Letter from string
00619         endings.append((*it).mid(2).stripWhiteSpace());
00620       }
00621     }
00622     kdDebug(1223) << "Supported Endings: " << endings << endl;
00623 
00624     // Now try to append the endings with and without "." to the given filename,
00625     // and see if that gives a existing file.
00626     for (QStringList::Iterator it = endings.begin(); it != endings.end(); ++it)
00627     {
00628       fi.setFile(m_file+(*it));
00629       if (fi.exists())
00630       {
00631         m_file = m_file+(*it);
00632         break;
00633       }
00634       fi.setFile(m_file+"."+(*it));
00635       if (fi.exists())
00636       {
00637         m_file = m_file+"."+(*it);
00638         break;
00639       }
00640     }
00641 
00642     // If we still have not found a file. Show an error message and return.
00643     if (!fi.exists())
00644     {
00645       KMessageBox::error(mainWidget, i18n("<qt>File <nobr><strong>%1</strong></nobr> does not exist.</qt>").arg(m_file));
00646       emit setStatusBarText(QString::null);
00647       return false;
00648     }
00649     m_url.setPath(QFileInfo(m_file).absFilePath());
00650   }
00651 
00652   // Set the window caption now, before we do any uncompression and generation of temporary files.
00653   tmpFileURL.setPath(m_file);
00654   emit setStatusBarText(i18n("Loading '%1'...").arg(tmpFileURL.prettyURL()));
00655   emit setWindowCaption( tmpFileURL.prettyURL() ); // set Window caption WITHOUT the reference part!
00656 
00657   // Check if the file is compressed
00658   KMimeType::Ptr mimetype = KMimeType::findByPath( m_file );
00659 
00660   if (( mimetype->name() == "application/x-gzip" ) || ( mimetype->name() == "application/x-bzip2" ) ||
00661       ( mimetype->parentMimeType() == "application/x-gzip" ) ||
00662       ( mimetype->parentMimeType() == "application/x-bzip2" ))
00663   {
00664     // The file is compressed. Make a temporary file, and store an uncompressed version there...
00665     if (tmpUnzipped != 0L)  // Delete old temporary file
00666       delete tmpUnzipped;
00667 
00668     tmpUnzipped = new KTempFile;
00669     if (tmpUnzipped == 0L)
00670     {
00671       KMessageBox::error(mainWidget, i18n("<qt><strong>File Error!</strong> Could not create "
00672                          "temporary file.</qt>"));
00673       emit setWindowCaption(QString::null);
00674       emit setStatusBarText(QString::null);
00675       return false;
00676     }
00677     tmpUnzipped->setAutoDelete(true);
00678     if(tmpUnzipped->status() != 0)
00679     {
00680       KMessageBox::error(mainWidget, i18n("<qt><strong>File Error!</strong> Could not create temporary file "
00681                          "<nobr><strong>%1</strong></nobr>.</qt>").arg(strerror(tmpUnzipped->status())));
00682       emit setWindowCaption(QString::null);
00683       emit setStatusBarText(QString::null);
00684       return false;
00685     }
00686 
00687     QIODevice* filterDev;
00688     if (( mimetype->parentMimeType() == "application/x-gzip" ) ||
00689         ( mimetype->parentMimeType() == "application/x-bzip2" ))
00690       filterDev = KFilterDev::deviceForFile(m_file, mimetype->parentMimeType());
00691     else
00692       filterDev = KFilterDev::deviceForFile(m_file);
00693     if (filterDev == 0L)
00694     {
00695       emit setWindowCaption(QString::null);
00696       emit setStatusBarText(QString::null);
00697       return false;
00698     }
00699     if(!filterDev->open(IO_ReadOnly))
00700     {
00701       KMessageBox::detailedError(mainWidget, i18n("<qt><strong>File Error!</strong> Could not open the file "
00702           "<nobr><strong>%1</strong></nobr> for uncompression. "
00703           "The file will not be loaded.</qt>").arg(m_file),
00704           i18n("<qt>This error typically occurs if you do not have enough permissions to read the file. "
00705           "You can check ownership and permissions if you right-click on the file in the Konqueror "
00706           "file manager and then choose the 'Properties' menu.</qt>"));
00707       emit setWindowCaption(QString::null);
00708       delete filterDev;
00709       emit setStatusBarText(QString::null);
00710       return false;
00711     }
00712 
00713     KProgressDialog* prog = new KProgressDialog(0L, "uncompress-progress",
00714         i18n("Uncompressing..."),
00715         i18n("<qt>Uncompressing the file <nobr><strong>%1</strong></nobr>. Please wait.</qt>").arg(m_file));
00716 
00717     prog->progressBar()->setTotalSteps((int) fi.size()/1024);
00718     prog->progressBar()->setProgress(0);
00719     prog->setMinimumDuration(250);
00720 
00721     QByteArray buf(1024);
00722     int read = 0, wrtn = 0;
00723 
00724     bool progress_dialog_was_cancelled = false;
00725     while ((read = filterDev->readBlock(buf.data(), buf.size())) > 0)
00726     {
00727       kapp->processEvents();
00728       progress_dialog_was_cancelled = prog->wasCancelled();
00729       if (progress_dialog_was_cancelled)
00730         break;
00731       prog->progressBar()->advance(1);
00732 
00733       wrtn = tmpUnzipped->file()->writeBlock(buf.data(), read);
00734       if(read != wrtn)
00735         break;
00736     }
00737     delete filterDev;
00738     delete prog;
00739     tmpUnzipped->sync();
00740 
00741     if (progress_dialog_was_cancelled) {
00742       emit setStatusBarText(QString::null);
00743       return false;
00744     }
00745 
00746     if ((read != 0) || (tmpUnzipped->file()->size() == 0))
00747     {
00748       KMessageBox::detailedError(mainWidget, i18n("<qt><strong>File Error!</strong> Could not uncompress "
00749           "the file <nobr><strong>%1</strong></nobr>. The file will not be loaded.</qt>").arg( m_file ),
00750           i18n("<qt>This error typically occurs if the file is corrupt. "
00751           "If you want to be sure, try to decompress the file manually using command-line tools.</qt>"));
00752       emit setWindowCaption(QString::null);
00753       emit setStatusBarText(QString::null);
00754       return false;
00755     }
00756     tmpUnzipped->close();
00757 
00758     m_file = tmpUnzipped->name();
00759   }
00760 
00761   // Now call the openURL-method of the multipage and give it an URL
00762   // pointing to the downloaded file.
00763   tmpFileURL.setPath(m_file);
00764   // Pass the reference part of the URL through to the multipage
00765   tmpFileURL.setRef(m_url.ref());
00766 
00767   mimetype = KMimeType::findByURL(tmpFileURL);
00768 
00769   // Search for service
00770   KTrader::OfferList offers = KTrader::self()->query(
00771       QString::fromLatin1("KViewShell/MultiPage" ),
00772   QString("([X-KDE-MultiPageVersion] == %1) and "
00773           "([X-KDE-MimeTypes] == '%2')").arg(MULTIPAGE_VERSION).arg(mimetype->name()));
00774 
00775   if (offers.isEmpty()) {
00776     KMessageBox::detailedError(mainWidget, i18n("<qt>The document <b>%1</b> cannot be shown because "
00777                         "its file type is not supported.</qt>").arg(m_file),
00778                    i18n("<qt>The file has mime type <b>%1</b> which is not supported by "
00779                     "any of the installed KViewShell plugins.</qt>").arg(mimetype->name()));
00780     emit setWindowCaption(QString::null);
00781     emit setStatusBarText(QString::null);
00782     return false;
00783   }
00784 
00785   KService::Ptr service = offers.first();
00786 
00787   // The the new multiPage is different then the currently loaded one.
00788   if (service->library() != multiPageLibrary)
00789   {
00790     // We write the settings before we load the new multipage, so
00791     // that the new multipage gets the same settings than the
00792     // currently loaded one.
00793     writeSettings();
00794 
00795     // Delete old config dialog
00796     KConfigDialog* configDialog = KConfigDialog::exists("kviewshell_config");
00797     delete configDialog;
00798 
00799     KMultiPage* oldMultiPage = multiPage;
00800 
00801     // Try to load the multiPage
00802     int error;
00803     multiPage = static_cast<KMultiPage*>(KParts::ComponentFactory::createInstanceFromService<KParts::ReadOnlyPart>(service, mainWidget,
00804                                                            service->name().utf8(), QStringList(), &error ));
00805 
00806     if (multiPage.isNull()) {
00807       QString reason;
00808       switch(error) {
00809       case KParts::ComponentFactory::ErrNoServiceFound:
00810     reason = i18n("<qt>No service implementing the given mimetype and fullfilling the given constraint expression can be found.</qt>");
00811     break;
00812       case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
00813     reason = i18n("<qt>The specified service provides no shared library.</qt>");
00814     break;
00815       case KParts::ComponentFactory::ErrNoLibrary:
00816     reason = i18n("<qt><p>The specified library <b>%1</b> could not be loaded. The error message returned was:</p> <p><b>%2</b></p></qt>").arg(service->library()).arg(KLibLoader::self()->lastErrorMessage());
00817     break;
00818       case KParts::ComponentFactory::ErrNoFactory:
00819     reason = i18n("<qt>The library does not export a factory for creating components.</qt>");
00820     break;
00821       case KParts::ComponentFactory::ErrNoComponent:
00822     reason = i18n("<qt>The factory does not support creating components of the specified type.</qt>");
00823     break;
00824       }
00825 
00826       QString text = i18n("<qt><p><b>Problem:</b> The document <b>%1</b> cannot be shown.</p>"
00827               "<p><b>Reason:</b> The software "
00828               "component <b>%2</b> which is required to display files of type <b>%3</b> could "
00829               "not be initialized. This could point to serious misconfiguration of your KDE "
00830               "system, or to damaged program files.</p>"
00831               "<p><b>What you can do:</b> You could try to re-install the software packages in "
00832               "question. If that does not help, you could file an error report, either to the "
00833               "provider of your software (e.g. the vendor of your Linux distribution), or "
00834               "directly to the authors of the software. The entry <b>Report Bug...</b> in the "
00835               "<b>Help</b> menu helps you to contact the KDE programmers.</p></qt>").arg(m_file).arg(service->library()).arg(mimetype->name());
00836       QString caption = i18n("Error Initializing Software Component");
00837       if (reason.isEmpty())
00838     KMessageBox::error(mainWidget, text, caption);
00839       else
00840     KMessageBox::detailedError(mainWidget, text, reason, caption);
00841       emit setStatusBarText(QString::null);
00842       return false;
00843     }
00844 
00845     // Remember the name of the part. So only need to switch if really necessary.
00846     multiPageLibrary = service->library();
00847 
00848     connect(partManager, SIGNAL(activePartChanged(KParts::Part*)), this, SIGNAL(pluginChanged(KParts::Part*)));
00849 
00850     // Switch to the new multiPage
00851     partManager->replacePart(oldMultiPage, multiPage);
00852 
00853     delete oldMultiPage;
00854 
00855     // The next line makes the plugin switch much more smooth. Without it the new document
00856     // is at first show at a very small zoomlevel before the zoom switches to the right value.
00857     // This makes the plugin switching actually slower.
00858     // TODO: Get rid of this without causing nasty artifacts.
00859     kapp->processEvents();
00860     initializeMultiPage();
00861     partManager->setActivePart(this);
00862 
00863     // We disconnect because we dont want some FocusEvents to trigger a GUI update, which might mess
00864     // with our menus.
00865     disconnect(partManager, SIGNAL(activePartChanged(KParts::Part*)), this, SIGNAL(pluginChanged(KParts::Part*)));
00866 
00867     readSettings();
00868   }
00869 
00870   // Set the multipage to the current viewmode.
00871   multiPage->setViewMode(viewModeAction->currentItem());
00872 
00873   // Load the URL
00874   bool r = multiPage->openURL(m_file, m_url);
00875   updateZoomLevel(); // @@@@@@@@@@@@@
00876 
00877   // We disable the selection tool for plugins that dont support text.
00878   // Currently this is only the fax plugin.
00879   if (multiPage->supportsTextSearch())
00880   {
00881     selectionModeAction->setEnabled(true);
00882   }
00883   else
00884   {
00885     selectionModeAction->setEnabled(false);
00886     moveModeAction->setChecked(true);
00887   }
00888   // Switch the new multipage to the right tool
00889   slotEnableMoveTool(moveModeAction->isChecked());
00890 
00891   if (r) {
00892     // Add the file to the watchlist
00893     watch->addFile( m_file );
00894 
00895     // Notify the ViewShell about the newly opened file.
00896     emit fileOpened();
00897   } else {
00898     m_url = QString::null;
00899     emit setWindowCaption(QString::null);
00900   }
00901 
00902   checkActions();
00903   emit zoomChanged(QString("%1%").arg((int)(_zoomVal.value()*100.0+0.5)));
00904   emit setStatusBarText(QString::null);
00905   return r;
00906 }
00907 
00908 
00909 void KViewPart::reload()
00910 {
00911   multiPage->reload();
00912 }
00913 
00914 
00915 void KViewPart::fileChanged(const QString &file)
00916 {
00917   if (file == m_file && watchAct->isChecked())
00918     multiPage->reload();
00919 }
00920 
00921 
00922 bool KViewPart::closeURL_ask()
00923 {
00924   if (multiPage.isNull())
00925     return false;
00926 
00927   if (multiPage->isModified() == true) {
00928     int ans = KMessageBox::warningContinueCancel( 0,
00929                      i18n("Your document has been modified. Do you really want to close it?"),
00930                      i18n("Document Was Modified"), KStdGuiItem::close());
00931     if (ans == KMessageBox::Cancel)
00932       return false;
00933   }
00934 
00935   return closeURL();
00936 }
00937 
00938 
00939 bool KViewPart::closeURL()
00940 {
00941   if (multiPage.isNull())
00942     return false;
00943 
00944   if( watch && !m_file.isEmpty() )
00945     watch->removeFile( m_file );
00946 
00947   KParts::ReadOnlyPart::closeURL();
00948   multiPage->closeURL();
00949   m_url = QString::null;
00950   checkActions();
00951   emit setWindowCaption("");
00952 
00953   return true;
00954 }
00955 
00956 
00957 void KViewPart::slotMedia(int id)
00958 {
00959   // If the user has chosen one of the 'known' paper sizes, set the
00960   // user requested paper size to that value. Via signals and slots,
00961   // this will update the menus, and also the GUI, if necessary.
00962   if (id > 1) {
00963     userRequestedPaperSize.setPageSize(media->currentText());
00964     return;
00965   }
00966 
00967   // If the user has chosen "Custom paper size..", show the paper size
00968   // dialog. Construct it, if necessary. The paper size dialog will
00969   // know the address of userRequestedPaperSize and change this
00970   // member, if the user clicks ok/accept. The signal/slot mechanism
00971   // will then make sure that the necessary updates in the GUI are
00972   // done.
00973   if (_pageSizeDialog == 0) {
00974     _pageSizeDialog = new pageSizeDialog(mainWidget, &userRequestedPaperSize);
00975     if (_pageSizeDialog == 0) {
00976       kdError(1223) << "Could not construct the page size dialog!" << endl;
00977       return;
00978     }
00979   }
00980 
00981   // Reset the "preferred paper size" menu. We don't want to have the
00982   // "custom paper size" check if the user aborts the dialog.
00983   checkActions();
00984 
00985   // Set or update the paper size dialog to show the currently
00986   // selected value.
00987   _pageSizeDialog->setPageSize(userRequestedPaperSize.serialize());
00988   _pageSizeDialog->show();
00989 }
00990 
00991 
00992 void KViewPart::pageInfo(int numpages, int currentpage)
00993 {
00994   updateZoomLevel();
00995 
00996   // ATTN: The string here must be the same as in setPage() below
00997   QString pageString = i18n("Page %1 of %2").arg(currentpage).arg(numpages);
00998   if (pageChangeIsConnected) {
00999     emit pageChanged(pageString);
01000     emit sizeChanged(pageSizeDescription());
01001   } else
01002     emit setStatusBarText(pageString);
01003 
01004   checkActions();
01005 }
01006 
01007 
01008 void KViewPart::goToPage()
01009 {
01010   bool ok = false;
01011   int p = KInputDialog::getInteger(i18n("Go to Page"), i18n("Page:"),
01012                                    multiPage->currentPageNumber(), 1, multiPage->numberOfPages(),
01013                                    1 /*step*/, &ok, mainWidget, "gotoDialog");
01014   if (ok)
01015     multiPage->gotoPage(p);
01016 }
01017 
01018 
01019 void KViewPart::disableZoomFit()
01020 {
01021   if (fitPageAct -> isChecked())
01022   {
01023     fitPageAct -> setChecked(false);
01024     enableFitToPage(false);
01025   }
01026   else if(fitWidthAct -> isChecked())
01027   {
01028     fitWidthAct -> setChecked(false);
01029     enableFitToWidth(false);
01030   }
01031   else if (fitHeightAct -> isChecked())
01032   {
01033     fitHeightAct -> setChecked(false);
01034     enableFitToHeight(false);
01035   }
01036 }
01037 
01038 void KViewPart::zoomIn()
01039 {
01040   disableZoomFit();
01041 
01042   float oldVal = _zoomVal.value();
01043   float newVal = _zoomVal.zoomIn();
01044 
01045   if (oldVal != newVal)
01046     _zoomVal.setZoomValue(multiPage->setZoom(_zoomVal.zoomIn()));
01047 }
01048 
01049 
01050 void KViewPart::zoomOut()
01051 {
01052   disableZoomFit();
01053 
01054   float oldVal = _zoomVal.value();
01055   float newVal = _zoomVal.zoomOut();
01056 
01057   if (oldVal != newVal)
01058     _zoomVal.setZoomValue(multiPage->setZoom(_zoomVal.zoomOut()));
01059 }
01060 
01061 void KViewPart::updateZoomLevel()
01062 {
01063   if (fitPageAct->isChecked())
01064   {
01065     fitToPage();
01066   }
01067   else if (fitWidthAct->isChecked())
01068   {
01069     fitToWidth();
01070   }
01071   else if (fitHeightAct->isChecked())
01072   {
01073     fitToHeight();
01074   }
01075   else
01076   {
01077     // Manuell Zoom
01078   }
01079 }
01080 
01081 void KViewPart::enableFitToPage(bool enable)
01082 {
01083   if (enable)
01084   {
01085     fitToPage();
01086     connect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01087             this, SLOT(slotStartFitTimer()));
01088     connect(&fitTimer, SIGNAL(timeout()), SLOT(fitToPage()));
01089   }
01090   else
01091   {
01092     disconnect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01093                this, SLOT(slotStartFitTimer()));
01094     disconnect(&fitTimer, SIGNAL(timeout()), this, SLOT(fitToPage()));
01095   }
01096 }
01097 
01098 void KViewPart::enableFitToWidth(bool enable)
01099 {
01100   if (enable)
01101   {
01102     fitToWidth();
01103     connect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01104             this, SLOT(slotStartFitTimer()));
01105     connect(&fitTimer, SIGNAL(timeout()), SLOT(fitToWidth()));
01106   }
01107   else
01108   {
01109     disconnect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01110                this, SLOT(slotStartFitTimer()));
01111     disconnect(&fitTimer, SIGNAL(timeout()), this, SLOT(fitToWidth()));
01112   }
01113 }
01114 
01115 void KViewPart::enableFitToHeight(bool enable)
01116 {
01117   if (enable)
01118   {
01119     fitToHeight();
01120     connect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01121             this, SLOT(slotStartFitTimer()));
01122     connect(&fitTimer, SIGNAL(timeout()), SLOT(fitToHeight()));
01123   }
01124   else
01125   {
01126     disconnect(multiPage->mainWidget(), SIGNAL(viewSizeChanged(const QSize&)),
01127                this, SLOT(slotStartFitTimer()));
01128     disconnect(&fitTimer, SIGNAL(timeout()), this, SLOT(fitToHeight()));
01129   }
01130 }
01131 
01132 
01133 void KViewPart::fitToPage()
01134 {
01135   double z = QMIN(multiPage->calculateFitToHeightZoomValue(),
01136                   multiPage->calculateFitToWidthZoomValue());
01137 
01138   // Check if the methods returned usable values. Values that are not
01139   // within the limits indicate that fitting to width or height is
01140   // currently not possible (e.g. because no document is
01141   // loaded). In that case, we abort.
01142   if ((z < ZoomLimits::MinZoom/1000.0) || (z > ZoomLimits::MaxZoom/1000.0))
01143     return;
01144 
01145   multiPage->setZoom(z);
01146   _zoomVal.setZoomFitPage(z);
01147 }
01148 
01149 
01150 void KViewPart::fitToHeight()
01151 {
01152   double z = multiPage->calculateFitToHeightZoomValue();
01153 
01154   // Check if the method returned a usable value. Values that are not
01155   // within the limits indicate that fitting to height is currently
01156   // not possible (e.g. because no document is loaded). In that case,
01157   // we abort.
01158   if ((z < ZoomLimits::MinZoom/1000.0) || (z > ZoomLimits::MaxZoom/1000.0))
01159     return;
01160 
01161   multiPage->setZoom(z);
01162   _zoomVal.setZoomFitHeight(z);
01163 }
01164 
01165 
01166 void KViewPart::fitToWidth()
01167 {
01168   double z = multiPage->calculateFitToWidthZoomValue();
01169 
01170   // Check if the method returned a usable value. Values that are not
01171   // within the limits indicate that fitting to width is currently not
01172   // possible (e.g. because no document is loaded). In that case, we
01173   // abort.
01174   if ((z < ZoomLimits::MinZoom/1000.0) || (z > ZoomLimits::MaxZoom/1000.0))
01175     return;
01176 
01177   multiPage->setZoom(z);
01178   _zoomVal.setZoomFitWidth(z);
01179 }
01180 
01181 
01182 void KViewPart::setZoomValue(const QString &sval)
01183 {
01184   if (sval == i18n("Fit to Page Width"))
01185   {
01186     fitWidthAct -> setChecked(true);
01187     fitToWidth();
01188   }
01189   else if (sval == i18n("Fit to Page Height"))
01190   {
01191     fitHeightAct -> setChecked(true);
01192     fitToHeight();
01193   }
01194   else if (sval == i18n("Fit to Page"))
01195   {
01196     fitPageAct -> setChecked(true);
01197     fitToPage();
01198   }
01199   else
01200   {
01201     disableZoomFit();
01202 
01203     float fval = _zoomVal.value();
01204     _zoomVal.setZoomValue(sval);
01205     if (fval != _zoomVal.value())
01206       _zoomVal.setZoomValue(multiPage->setZoom(_zoomVal.value()));
01207   }
01208 
01209   mainWidget->setFocus();
01210 }
01211 
01212 
01213 void KViewPart::checkActions()
01214 {
01215   if (multiPage.isNull())
01216     return;
01217 
01218   int currentPage = multiPage->currentPageNumber();
01219   int numberOfPages = multiPage->numberOfPages();
01220 
01221   bool doc = !url().isEmpty();
01222 
01223   useDocumentSpecifiedSize->setEnabled(multiPage->hasSpecifiedPageSizes() );
01224 
01225   if (multiPage->overviewMode())
01226   {
01227     int visiblePages = multiPage->getNrRows() *
01228                        multiPage->getNrColumns();
01229 
01230     // firstVisiblePage is the smallest currently shown pagenumber.
01231     int firstVisiblePage = currentPage - (currentPage % visiblePages);
01232 
01233     backAct->setEnabled(doc && currentPage >= visiblePages);
01234     forwardAct->setEnabled(doc && firstVisiblePage <= numberOfPages - visiblePages);
01235 
01236     startAct->setEnabled(doc && firstVisiblePage > 1);
01237     endAct->setEnabled(doc && firstVisiblePage + visiblePages < numberOfPages);
01238   }
01239   else
01240   {
01241     backAct->setEnabled(doc && currentPage > 1);
01242     forwardAct->setEnabled(doc && currentPage < numberOfPages);
01243 
01244     startAct->setEnabled(doc && currentPage > 1);
01245     endAct->setEnabled(doc && currentPage < numberOfPages);
01246   }
01247 
01248   gotoAct->setEnabled(doc && numberOfPages > 1);
01249   readDownAct->setEnabled(doc);
01250   readUpAct->setEnabled(doc);
01251 
01252   zoomInAct->setEnabled(doc);
01253   zoomOutAct->setEnabled(doc);
01254 
01255   fitPageAct->setEnabled(doc);
01256   fitHeightAct->setEnabled(doc);
01257   fitWidthAct->setEnabled(doc);
01258 
01259   media->setEnabled(doc);
01260   orientation->setEnabled(doc);
01261 
01262   printAction->setEnabled(doc);
01263 
01264   saveAction->setEnabled(multiPage->isModified());
01265 
01266   saveAsAction->setEnabled(doc);
01267 
01268   if (userRequestedPaperSize.formatNumber() != -1) {
01269     orientation->setCurrentItem(userRequestedPaperSize.getOrientation());
01270     orientation->setEnabled(true);
01271     media->setCurrentItem(userRequestedPaperSize.formatNumber()+1);
01272   } else {
01273     orientation->setEnabled(false);
01274     media->setCurrentItem(userRequestedPaperSize.formatNumber()-1);
01275   }
01276 
01277   bool textSearch = false;
01278   if (doc && multiPage->supportsTextSearch())
01279     textSearch = true;
01280 
01281   exportTextAction->setEnabled(textSearch);
01282   findTextAction->setEnabled(textSearch);
01283   selectAllAction->setEnabled(textSearch);
01284 }
01285 
01286 
01287 void KViewPart::slotPrint()
01288 {
01289   // TODO: REMOVE THIS METHOD
01290   // @@@@@@@@@@@@@@@
01291   multiPage->print();
01292 }
01293 
01294 
01295 void KViewPart::readSettings()
01296 {
01297   showSidebar->setChecked(KVSPrefs::pageMarks());
01298   slotShowSidebar();
01299 
01300   watchAct->setChecked(KVSPrefs::watchFile());
01301 
01302   // Read zoom value. Even if 'fitToPage' has been set above, there is
01303   // no widget available right now, so setting a good default value
01304   // from the configuration file is perhaps not a bad idea.
01305   float _zoom = KVSPrefs::zoom();
01306   if ( (_zoom < ZoomLimits::MinZoom/1000.0) || (_zoom > ZoomLimits::MaxZoom/1000.0)) {
01307     kdWarning(1223) << "Illeagal zoom value of " << _zoom*100.0 << "% found in the preferences file. Setting zoom to 100%." << endl;
01308     _zoom = 1.0;
01309   }
01310   _zoomVal.setZoomValue(multiPage->setZoom(_zoom));
01311 
01312   // The value 'fitToPage' has several meanings: 1 is 'fit to page
01313   // width', 2 is 'fit to page height', 3 is 'fit to page'. Other
01314   // values indicate 'no fit to page'. Note: at the time this code is
01315   // executed, the methods fitToWidth(), etc., do not work well at all
01316   // (perhaps some data is not initialized yet)? For that reason, we
01317   // do not call these methods, and load the last zoom-value from the
01318   // configuration file below. The hope is that this value is not
01319   // terribly wrong. If the user doesn't like it, it suffices to
01320   // resize the window just a bit...
01321   switch(KVSPrefs::fitToPage()) {
01322   case KVSPrefs::EnumFitToPage::FitToPage:
01323     fitPageAct->setChecked(true);
01324     _zoomVal.setZoomFitPage(_zoom);
01325     enableFitToPage(true);
01326     break;
01327   case KVSPrefs::EnumFitToPage::FitToPageWidth:
01328     fitWidthAct->setChecked(true);
01329     _zoomVal.setZoomFitWidth(_zoom);
01330     enableFitToWidth(true);
01331     break;
01332   case KVSPrefs::EnumFitToPage::FitToPageHeight:
01333     fitHeightAct->setChecked(true);
01334     _zoomVal.setZoomFitHeight(_zoom);
01335     enableFitToHeight(true);
01336     break;
01337   }
01338 
01339   // Read Paper Size. and orientation. The GUI is updated
01340   // automatically by the signals/slots mechanism whenever
01341   // userRequestedPaperSize is changed.
01342   userRequestedPaperSize.setPageSize(KVSPrefs::paperFormat());
01343 
01344   // Check if scrollbars should be shown.
01345   bool sbstatus = KVSPrefs::scrollbars();
01346   scrollbarHandling->setChecked(sbstatus);
01347   emit scrollbarStatusChanged(sbstatus);
01348 
01349   // Check if document specified paper sizes should be shown. We do
01350   // not need to take any action here, because this method is called
01351   // only in the constructor of the KViewPart when no document is loaded.
01352   useDocumentSpecifiedSize->setChecked(KVSPrefs::useDocumentSpecifiedSize());
01353 
01354   multiPage->readSettings();
01355 }
01356 
01357 
01358 void KViewPart::writeSettings()
01359 {
01360   KVSPrefs::setPageMarks(showSidebar->isChecked());
01361   KVSPrefs::setWatchFile(watchAct->isChecked());
01362   KVSPrefs::setZoom(_zoomVal.value());
01363   KVSPrefs::setPaperFormat(userRequestedPaperSize.serialize());
01364   KVSPrefs::setScrollbars(scrollbarHandling->isChecked());
01365   KVSPrefs::setUseDocumentSpecifiedSize(useDocumentSpecifiedSize->isChecked());
01366 
01367   if (!multiPage.isNull())
01368     multiPage->writeSettings();
01369 
01370   if (fitPageAct->isChecked())
01371     KVSPrefs::setFitToPage(KVSPrefs::EnumFitToPage::FitToPage);
01372   else if(fitWidthAct->isChecked())
01373     KVSPrefs::setFitToPage(KVSPrefs::EnumFitToPage::FitToPageWidth);
01374   else if (fitHeightAct->isChecked())
01375     KVSPrefs::setFitToPage(KVSPrefs::EnumFitToPage::FitToPageHeight);
01376   else
01377     KVSPrefs::setFitToPage(KVSPrefs::EnumFitToPage::DontFit);
01378 
01379   KVSPrefs::writeConfig();
01380 }
01381 
01382 
01383 void KViewPart::connectNotify ( const char *sig )
01384 {
01385   if (QString(sig).contains("pageChanged"))
01386     pageChangeIsConnected = true;
01387 }
01388 
01389 
01390 void KViewPart::setStatusBarTextFromMultiPage( const QString &msg )
01391 {
01392   if (msg.isEmpty())
01393   {
01394     if (pageChangeIsConnected)
01395       emit setStatusBarText(QString::null);
01396     else
01397     {
01398       int currentPage = multiPage->currentPageNumber();
01399       int numberOfPages = multiPage->numberOfPages();
01400       emit setStatusBarText(i18n("Page %1 of %2").arg(currentPage).arg(numberOfPages));
01401     }
01402   }
01403   else
01404     emit setStatusBarText(msg);
01405 }
01406 
01407 KAboutData* KViewPart::createAboutData()
01408 {
01409   return new KAboutData("kviewerpart", I18N_NOOP("Document Viewer Part"),
01410                         "0.6", I18N_NOOP(""),
01411                         KAboutData::License_GPL,
01412                         I18N_NOOP("Copyright (c) 2005 Wilfried Huss"));
01413 }
01414 
01415 void KViewPart::aboutKViewShell()
01416 {
01417   if (aboutDialog == 0)
01418   {
01419     // Create Dialog
01420     aboutDialog = new KAboutDialog(mainWidget, "about_kviewshell");
01421     aboutDialog->setTitle(I18N_NOOP("KViewShell"));
01422     aboutDialog->setVersion("0.6");
01423     aboutDialog->setAuthor("Matthias Hoelzer-Kluepfel", QString::null, QString::null,
01424                            I18N_NOOP("Original Author"));
01425 
01426     aboutDialog->addContributor("Matthias Hoelzer-Kluepfel", "mhk@caldera.de", QString::null,
01427                                 I18N_NOOP("Framework"));
01428     aboutDialog->addContributor("David Sweet", "dsweet@kde.org", "http://www.chaos.umd.edu/~dsweet",
01429                                 I18N_NOOP("Former KGhostView Maintainer"));
01430     aboutDialog->addContributor("Mark Donohoe", QString::null, QString::null,
01431                                 I18N_NOOP("KGhostView Author"));
01432     aboutDialog->addContributor("Markku Hihnala", QString::null, QString::null,
01433                                 I18N_NOOP("Navigation widgets"));
01434     aboutDialog->addContributor("David Faure", QString::null, QString::null,
01435                                 I18N_NOOP("Basis for shell"));
01436     aboutDialog->addContributor("Daniel Duley", QString::null, QString::null,
01437                                 I18N_NOOP("Port to KParts"));
01438     aboutDialog->addContributor("Espen Sand", QString::null, QString::null,
01439                                 I18N_NOOP("Dialog boxes"));
01440     aboutDialog->addContributor("Stefan Kebekus", "kebekus@kde.org", QString::null,
01441                                 I18N_NOOP("DCOP-Interface, major improvements"));
01442     aboutDialog->addContributor("Wilfried Huss", "Wilfried.Huss@gmx.at", QString::null,
01443                                 I18N_NOOP("Interface enhancements"));
01444   }
01445   aboutDialog->show();
01446 }
01447 
01448 void KViewPart::doSettings()
01449 {
01450   if (KConfigDialog::showDialog("kviewshell_config"))
01451     return;
01452 
01453   KConfigDialog* configDialog = new KConfigDialog(mainWidget, "kviewshell_config", KVSPrefs::self());
01454 
01455   optionDialogGUIWidget_base* guiWidget = new optionDialogGUIWidget_base(mainWidget);
01456   configDialog->addPage(guiWidget, i18n("User Interface"), "view_choose");
01457 
01458   optionDialogAccessibilityWidget* accWidget = new optionDialogAccessibilityWidget(mainWidget);
01459   configDialog->addPage(accWidget, i18n("Accessibility"), "access");
01460 
01461   multiPage->addConfigDialogs(configDialog);
01462 
01463   connect(configDialog, SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
01464   configDialog->show();
01465 }
01466 
01467 void KViewPart::preferencesChanged()
01468 {
01469   multiPage->preferencesChanged();
01470 }
01471 
01472 void KViewPart::partActivateEvent( KParts::PartActivateEvent *ev )
01473 {
01474   QApplication::sendEvent( multiPage, ev );
01475 }
01476 
01477 
01478 void KViewPart::guiActivateEvent( KParts::GUIActivateEvent *ev )
01479 {
01480   QApplication::sendEvent( multiPage, ev );
01481 }
01482 
01483 
01484 void KViewPart::slotEnableMoveTool(bool enable)
01485 {
01486   // Safety Check
01487   if (multiPage.isNull())
01488     return;
01489 
01490   multiPage->slotEnableMoveTool(enable);
01491 }
01492 
01493 
01494 KViewPartExtension::KViewPartExtension(KViewPart *parent)
01495   : KParts::BrowserExtension( parent, "KViewPartExtension")
01496 {
01497 }
01498 
01499 
01500 // KMultiPage Interface
01501 void KViewPart::mp_prevPage()
01502 {
01503   multiPage->prevPage();
01504 }
01505 
01506 void KViewPart::mp_nextPage()
01507 {
01508   multiPage->nextPage();
01509 }
01510 
01511 void KViewPart::mp_firstPage()
01512 {
01513   multiPage->firstPage();
01514 }
01515 
01516 void KViewPart::mp_lastPage()
01517 {
01518   multiPage->lastPage();
01519 }
01520 
01521 
01522 void KViewPart::mp_readUp()
01523 {
01524   multiPage->readUp();
01525 }
01526 
01527 void KViewPart::mp_readDown()
01528 {
01529   multiPage->readDown();
01530 }
01531 
01532 
01533 void KViewPart::mp_scrollUp()
01534 {
01535   multiPage->scrollUp();
01536 }
01537 
01538 void KViewPart::mp_scrollDown()
01539 {
01540   multiPage->scrollDown();
01541 }
01542 
01543 void KViewPart::mp_scrollLeft()
01544 {
01545   multiPage->scrollLeft();
01546 }
01547 
01548 void KViewPart::mp_scrollRight()
01549 {
01550   multiPage->scrollRight();
01551 }
01552 
01553 void KViewPart::mp_scrollUpPage()
01554 {
01555   multiPage->scrollUpPage();
01556 }
01557 
01558 void KViewPart::mp_scrollDownPage()
01559 {
01560   multiPage->scrollDownPage();
01561 }
01562 
01563 void KViewPart::mp_scrollLeftPage()
01564 {
01565   multiPage->scrollLeftPage();
01566 }
01567 
01568 void KViewPart::mp_scrollRightPage()
01569 {
01570   multiPage->scrollRightPage();
01571 }
01572 
01573 
01574 void KViewPart::mp_slotSave()
01575 {
01576   multiPage->slotSave();
01577 }
01578 
01579 void KViewPart::mp_slotSave_defaultFilename()
01580 {
01581   multiPage->slotSave_defaultFilename();
01582 }
01583 
01584 
01585 void KViewPart::mp_doGoBack()
01586 {
01587   multiPage->doGoBack();
01588 }
01589 
01590 void KViewPart::mp_doGoForward()
01591 {
01592   multiPage->doGoForward();
01593 }
01594 
01595 
01596 void KViewPart::mp_showFindTextDialog()
01597 {
01598   multiPage->showFindTextDialog();
01599 }
01600 
01601 void KViewPart::mp_findNextText()
01602 {
01603   multiPage->findNextText();
01604 }
01605 
01606 void KViewPart::mp_findPrevText()
01607 {
01608   multiPage->findPrevText();
01609 }
01610 
01611 void KViewPart::mp_doSelectAll()
01612 {
01613   multiPage->doSelectAll();
01614 }
01615 
01616 void KViewPart::mp_clearSelection()
01617 {
01618   multiPage->clearSelection();
01619 }
01620 
01621 void KViewPart::mp_copyText()
01622 {
01623   multiPage->copyText();
01624 }
01625 
01626 void KViewPart::mp_exportText()
01627 {
01628   multiPage->doExportText();
01629 }
01630 
01631 #include "kviewpart.moc"
01632 

kviewshell

Skip menu "kviewshell"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • kviewshell
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal