00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #include <qfileinfo.h>
00012 #include <qtimer.h>
00013 #include <qregexp.h>
00014 
00015 #include <kiconloader.h>
00016 #include <kstandarddirs.h>
00017 #include <kapplication.h>
00018 #include <kaction.h>
00019 #include <kconfig.h>
00020 #include <kdebug.h>
00021 #include <klocale.h>
00022 #include <kmessagebox.h>
00023 #include <kmenubar.h>
00024 #include <klibloader.h>
00025 #include <kstdaction.h>
00026 #include <kedittoolbar.h>
00027 #include <kurldrag.h>
00028 #include <kparts/partmanager.h>
00029 #include <kmimetype.h>
00030 
00031 #include <kprogress.h>
00032 #include <qlabel.h>
00033 
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036 
00037 #include "kviewpart_iface.h"
00038 #include <kstatusbar.h>
00039 #include <kkeydialog.h>
00040 #include "kviewshell.moc"
00041 
00042 
00043 #define StatusBar_ID_PageNr 1
00044 #define StatusBar_ID_PageSize 2
00045 #define StatusBar_ID_Zoom 3
00046 
00047 
00048 KViewShell::KViewShell(const QString& defaultMimeType)
00049   : KParts::MainWindow()
00050 {
00051   
00052 
00053   
00054   KLibFactory *factory = KLibLoader::self()->factory("kviewerpart");
00055   if (factory) {
00056     if (defaultMimeType == QString::null)
00057     {
00058       view = (KViewPart_Iface*) factory->create(this, "kviewerpart", "KViewPart");
00059     }
00060     else
00061     {
00062       QStringList args;
00063       args << defaultMimeType;
00064       view = (KViewPart_Iface*) factory->create(this, "kviewerpart", "KViewPart", args);
00065     }
00066     if (!view)
00067       ::exit(-1);
00068   } else {
00069     KMessageBox::error(this, i18n("No viewing component found"));
00070     ::exit(-1);
00071   }
00072 
00073   setCentralWidget(view->widget());
00074 
00075   
00076   KStdAction::open(view, SLOT(slotFileOpen()), actionCollection());
00077   recent = KStdAction::openRecent (this, SLOT(openURL(const KURL &)), actionCollection());
00078   reloadAction = new KAction(i18n("Reload"), "reload", CTRL + Key_R, view, SLOT(reload()), actionCollection(), "reload");
00079   closeAction = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
00080   KStdAction::quit (this, SLOT(slotQuit()), actionCollection());
00081 
00082   connect(view, SIGNAL(fileOpened()), this, SLOT(addRecentFile()));
00083 
00084   
00085   fullScreenAction = KStdAction::fullScreen(this, SLOT(slotFullScreen()), actionCollection(), this, "fullscreen" );
00086 
00087   
00088   createStandardStatusBarAction();
00089 
00090   setStandardToolBarMenuEnabled(true);
00091 
00092   KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
00093   KStdAction::configureToolbars(this, SLOT(slotEditToolbar()), actionCollection());
00094 
00095   
00096   connect( view, SIGNAL( zoomChanged(const QString &) ), this,SLOT( slotChangeZoomText(const QString &) ) );
00097   connect( view, SIGNAL( pageChanged(const QString &) ), this,SLOT( slotChangePageText(const QString &) ) );
00098   connect( view, SIGNAL( sizeChanged(const QString &) ), this,SLOT( slotChangeSizeText(const QString &) ) );
00099 
00100   
00101   connect( this, SIGNAL( restoreDocument(const KURL &, int) ), view, SLOT( restoreDocument(const KURL &, int)));
00102   connect( this, SIGNAL( saveDocumentRestoreInfo(KConfig*) ), view, SLOT( saveDocumentRestoreInfo(KConfig*)));
00103 
00104   setXMLFile( "kviewshell.rc" );
00105   createGUI(view);
00106   readSettings();
00107   checkActions();
00108   setAcceptDrops(true);
00109 
00110   
00111   
00112   
00113   
00114   
00115   menuBar()->show();
00116 
00117   
00118   statusBar()->insertItem("", StatusBar_ID_PageNr, 0, true);
00119   statusBar()->insertFixedItem("XXXX%", StatusBar_ID_Zoom, true);
00120   statusBar()->changeItem("", StatusBar_ID_Zoom);
00121   statusBar()->insertItem(view->pageSizeDescription(), StatusBar_ID_PageSize, 0, true);
00122 
00123   connect( view, SIGNAL(pluginChanged(KParts::Part*)), this, SLOT(createGUI(KParts::Part*)));
00124 }
00125 
00126 
00127 void KViewShell::checkActions()
00128 {
00129   bool doc = !view->url().isEmpty();
00130 
00131   closeAction->setEnabled(doc);
00132   reloadAction->setEnabled(doc);
00133   fullScreenAction->setEnabled(doc);
00134 }
00135 
00136 
00137 KViewShell::~KViewShell()
00138 {
00139   writeSettings();
00140   delete view;
00141 }
00142 
00143 
00144 void KViewShell::slotQuit()
00145 {
00146   
00147   
00148   
00149   
00150   
00151   if (fullScreenAction->isChecked()) {
00152     kdDebug() << "Switching off fullscreen mode before quitting the application" << endl;
00153     showNormal();
00154     if (isStatusBarShownInNormalMode)
00155       statusBar()->show();
00156     if (isToolBarShownInNormalMode)
00157       toolBar()->show();
00158     menuBar()->show();
00159     view->slotSetFullPage(false); 
00160   }
00161   kapp->closeAllWindows();
00162   kapp->quit();
00163 }
00164 
00165 
00166 void KViewShell::readSettings()
00167 {
00168   resize(600, 300); 
00169   setAutoSaveSettings( "General" ); 
00170 
00171   KConfig *config = kapp->config();
00172   config->setGroup("General");
00173 
00174   recent->loadEntries(config, "Recent Files");
00175 
00176   
00177   
00178   
00179   QStringList items = recent->items();
00180   for ( QStringList::Iterator it = items.begin(); it != items.end(); ++it ) {
00181     KURL url(*it);
00182     if (url.isLocalFile()) {
00183       QFileInfo info(url.path());
00184       if (!info.exists())
00185         recent->removeURL(url);
00186     }
00187   }
00188 
00189 }
00190 
00191 
00192 void KViewShell::writeSettings()
00193 {
00194   KConfig *config = kapp->config();
00195   config->setGroup( "General" );
00196   recent->saveEntries(config, "Recent Files");
00197 
00198   config->sync();
00199 }
00200 
00201 
00202 void KViewShell::saveProperties(KConfig* config)
00203 {
00204   
00205   
00206   
00207   emit saveDocumentRestoreInfo(config);
00208 }
00209 
00210 
00211 void KViewShell::readProperties(KConfig* config)
00212 {
00213   
00214   
00215   
00216   
00217   if (view)
00218   {
00219     KURL url (config->readPathEntry("URL"));
00220     if (url.isValid())
00221       emit restoreDocument(url, config->readNumEntry("Page", 1));
00222   }
00223 }
00224 
00225 
00226 void KViewShell::addRecentFile()
00227 {
00228   
00229   KURL actualURL = view->url();
00230   
00231   
00232   actualURL.setRef(QString::null);
00233   recent->addURL(actualURL);
00234   checkActions();
00235 }
00236 
00237 void KViewShell::openURL(const KURL& url)
00238 {
00239   view->openURL(url);
00240 }
00241 
00242 void KViewShell::slotFullScreen()
00243 {
00244   if (fullScreenAction->isChecked()) {
00245     
00246     
00247     
00248     
00249     isStatusBarShownInNormalMode = statusBar()->isShown();
00250     statusBar()->hide();
00251     isToolBarShownInNormalMode = toolBar()->isShown();
00252     toolBar()->hide();
00253     menuBar()->hide();
00254     view->slotSetFullPage(true); 
00255 
00256     
00257     showFullScreen();
00258 
00259     KMessageBox::information(this, i18n("Use the Escape key to leave the fullscreen mode."), i18n("Entering Fullscreen Mode"), "leavingFullScreen");
00260   } else {
00261     showNormal();
00262     if (isStatusBarShownInNormalMode)
00263       statusBar()->show();
00264     if (isToolBarShownInNormalMode)
00265       toolBar()->show();
00266     menuBar()->show();
00267     view->slotSetFullPage(false); 
00268   }
00269 }
00270 
00271 
00272 void KViewShell::slotFileClose()
00273 {
00274   view->closeURL_ask();
00275 
00276   checkActions();
00277 }
00278 
00279 void KViewShell::slotConfigureKeys()
00280 {
00281   KKeyDialog dlg( true, this );
00282 
00283   dlg.insert( actionCollection() );
00284   dlg.insert( view->actionCollection() );
00285 
00286   dlg.configure();
00287 }
00288 
00289 void KViewShell::slotEditToolbar()
00290 {
00291   saveMainWindowSettings( KGlobal::config(), autoSaveGroup() );
00292   KEditToolbar dlg(factory());
00293   connect( &dlg, SIGNAL( newToolbarConfig() ), SLOT( slotNewToolbarConfig() ) );
00294   dlg.exec();
00295 }
00296 
00297 
00298 void KViewShell::slotNewToolbarConfig()
00299 {
00300   applyMainWindowSettings( KGlobal::config(), autoSaveGroup() );
00301 }
00302 
00303 void KViewShell::dragEnterEvent(QDragEnterEvent *event)
00304 {
00305   if (KURLDrag::canDecode(event))
00306   {
00307     KURL::List urls;
00308     KURLDrag::decode(event, urls);
00309     if (!urls.isEmpty())
00310     {
00311       KURL url = urls.first();
00312 
00313       
00314       if (!url.isLocalFile())
00315       {
00316         event->accept();
00317         return;
00318       }
00319 
00320       
00321       
00322       KMimeType::Ptr mimetype = KMimeType::findByURL(url);
00323       kdDebug() << "[dragEnterEvent] Dragged URL is of type " << mimetype->comment() << endl;
00324 
00325       
00326       if (view)
00327       {
00328         QStringList mimetypeList = view->supportedMimeTypes();
00329         kdDebug() << "[dragEnterEvent] Supported mime types: " << mimetypeList << endl;
00330 
00331         for (QStringList::Iterator it = mimetypeList.begin(); it != mimetypeList.end(); ++it)
00332         {
00333           if (mimetype->is(*it))
00334           {
00335             kdDebug() << "[dragEnterEvent] Found matching mimetype: " << *it << endl;
00336             event->accept();
00337             return;
00338           }
00339         }
00340         kdDebug() << "[dragEnterEvent] no matching mimetype found" << endl;
00341       }
00342     }
00343     event->ignore();
00344   }
00345 }
00346 
00347 
00348 void KViewShell::dropEvent(QDropEvent *event)
00349 {
00350   KURL::List urls;
00351   if (KURLDrag::decode(event, urls) && !urls.isEmpty())
00352     view->openURL(urls.first());
00353 }
00354 
00355 
00356 void KViewShell::keyPressEvent(QKeyEvent *event)
00357 {
00358   
00359   
00360   if ((event->key() == Qt::Key_Escape) && (fullScreenAction->isChecked())) {
00361     showNormal();
00362     return;
00363   }
00364   
00365   event->ignore();
00366 }
00367 
00368 
00369 void KViewShell::slotChangePageText(const QString &message)
00370 {
00371   statusBar()->changeItem(" "+message+" ",StatusBar_ID_PageNr);
00372 }
00373 
00374 
00375 void KViewShell::slotChangeSizeText(const QString &message)
00376 {
00377   statusBar()->changeItem(" "+message+" ",StatusBar_ID_PageSize);
00378 }
00379 
00380 
00381 void KViewShell::slotChangeZoomText(const QString &message)
00382 {
00383   statusBar()->changeItem(" "+message+" ",StatusBar_ID_Zoom);
00384 }