/* This file is part of the KDE project Copyright (C) 1998, 1999 Torben Weis Copyright (C) 2000-2006 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KoMainWindow.h" #include "KoDocument.h" #include "KoView.h" #include "KoFilterManager.h" #include "KoDocumentInfo.h" #include "KoDocumentInfoDlg.h" #include "KoQueryTrader.h" #include "KoMainWindowIface.h" #include "KoFrame.h" #include "KoFileDialog.h" #include "Koversiondialog.h" #include "kkbdaccessextensions.h" #include "KoSpeaker.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KoPartManager : public KParts::PartManager { public: KoPartManager( QWidget * parent, const char * name = 0L ) : KParts::PartManager( parent, name ) { setSelectionPolicy( KParts::PartManager::TriState ); setAllowNestedParts( true ); setIgnoreScrollBars( true ); // Allow right-click on embedded objects (without activating them) // But beware: this means right-click on parent, from embedded object, // doesn't make the parent active first... setActivationButtonMask( Qt::LeftButton | Qt::MidButton ); } virtual bool eventFilter( QObject *obj, QEvent *ev ) { if ( !obj->isWidgetType() || ::qt_cast( obj ) ) return false; return KParts::PartManager::eventFilter( obj, ev ); } }; class KoMainWindowPrivate { public: KoMainWindowPrivate() { m_rootDoc = 0L; m_docToOpen = 0L; m_manager = 0L; bMainWindowGUIBuilt = false; m_forQuit=false; m_splitted=false; m_activePart = 0L; m_activeView = 0L; m_splitter=0L; m_orientation=0L; m_removeView=0L; m_toolbarList.setAutoDelete( true ); m_firstTime=true; m_progress=0L; m_paDocInfo = 0; m_paSave = 0; m_paSaveAs = 0; m_paPrint = 0; m_paPrintPreview = 0; statusBarLabel = 0L; m_dcopObject = 0; m_sendfile = 0; m_paCloseFile = 0L; m_reloadfile = 0L; m_versionsfile = 0L; m_importFile = 0; m_exportFile = 0; m_isImporting = false; m_isExporting = false; m_windowSizeDirty = false; m_lastExportSpecialOutputFlag = 0; // TTS accessibility enhancement (only if KDE 3.4 or later and KTTSD daemon is installed.) if (KoSpeaker::isKttsdInstalled()) { if (kospeaker) m_koSpeaker = kospeaker; else m_koSpeaker = new KoSpeaker(); } else m_koSpeaker = 0; } ~KoMainWindowPrivate() { delete m_dcopObject; } KoDocument *m_rootDoc; KoDocument *m_docToOpen; QPtrList m_rootViews; KParts::PartManager *m_manager; KParts::Part *m_activePart; KoView *m_activeView; QLabel * statusBarLabel; KProgress *m_progress; QPtrList m_splitViewActionList; // This additional list is needed, because we don't plug // the first list, when an embedded view gets activated (Werner) QPtrList m_veryHackyActionList; QSplitter *m_splitter; KSelectAction *m_orientation; KAction *m_removeView; KoMainWindowIface *m_dcopObject; QPtrList m_toolbarList; bool bMainWindowGUIBuilt; bool m_splitted; bool m_forQuit; bool m_firstTime; bool m_windowSizeDirty; KAction *m_paDocInfo; KAction *m_paSave; KAction *m_paSaveAs; KAction *m_paPrint; KAction *m_paPrintPreview; KAction *m_sendfile; KAction *m_paCloseFile; KAction *m_reloadfile; KAction *m_versionsfile; KAction *m_importFile; KAction *m_exportFile; bool m_isImporting; bool m_isExporting; KURL m_lastExportURL; QCString m_lastExportFormat; int m_lastExportSpecialOutputFlag; KSharedPtr m_koSpeaker; }; KoMainWindow::KoMainWindow( KInstance *instance, const char* name ) : KParts::MainWindow( name ) { setStandardToolBarMenuEnabled(true); // should there be a check for >= 3.1 ? Q_ASSERT(instance); d = new KoMainWindowPrivate; d->m_manager = new KoPartManager( this ); connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ), this, SLOT( slotActivePartChanged( KParts::Part * ) ) ); if ( instance ) setInstance( instance, false ); // don't load plugins! we don't want // the part's plugins with this shell, even though we are using the // part's instance! (Simon) QString doc; QStringList allFiles = KGlobal::dirs()->findAllResources( "data", "koffice/koffice_shell.rc" ); setXMLFile( findMostRecentXMLFile( allFiles, doc ) ); setLocalXMLFile( locateLocal( "data", "koffice/koffice_shell.rc" ) ); KStdAction::openNew( this, SLOT( slotFileNew() ), actionCollection(), "file_new" ); KStdAction::open( this, SLOT( slotFileOpen() ), actionCollection(), "file_open" ); m_recent = KStdAction::openRecent( this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection() ); d->m_paSave = KStdAction::save( this, SLOT( slotFileSave() ), actionCollection(), "file_save" ); d->m_paSaveAs = KStdAction::saveAs( this, SLOT( slotFileSaveAs() ), actionCollection(), "file_save_as" ); d->m_paPrint = KStdAction::print( this, SLOT( slotFilePrint() ), actionCollection(), "file_print" ); d->m_paPrintPreview = KStdAction::printPreview( this, SLOT( slotFilePrintPreview() ), actionCollection(), "file_print_preview" ); d->m_sendfile = KStdAction::mail( this, SLOT( slotEmailFile() ), actionCollection(), "file_send_file"); d->m_paCloseFile = KStdAction::close( this, SLOT( slotFileClose() ), actionCollection(), "file_close" ); KStdAction::quit( this, SLOT( slotFileQuit() ), actionCollection(), "file_quit" ); d->m_reloadfile = new KAction( i18n( "Reload"), 0, this, SLOT( slotReloadFile() ), actionCollection(), "file_reload_file"); d->m_versionsfile = new KAction( i18n( "Versions..."), 0, this, SLOT( slotVersionsFile() ), actionCollection(), "file_versions_file"); d->m_importFile = new KAction( i18n( "I&mport..." ), 0, // clashing accel key :( this, SLOT( slotImportFile() ), actionCollection(), "file_import_file"); d->m_exportFile = new KAction( i18n( "E&xport..." ), 0, this, SLOT( slotExportFile() ), actionCollection(), "file_export_file"); /* The following entry opens the document information dialog. Since the action is named so it intends to show data this entry should not have a trailing ellipses (...). */ d->m_paDocInfo = new KAction( i18n( "&Document Information" ), "documentinfo", 0, this, SLOT( slotDocumentInfo() ), actionCollection(), "file_documentinfo" ); KStdAction::keyBindings( this, SLOT( slotConfigureKeys() ), actionCollection() ); KStdAction::configureToolbars( this, SLOT( slotConfigureToolbars() ), actionCollection() ); d->m_paDocInfo->setEnabled( false ); d->m_paSaveAs->setEnabled( false ); d->m_reloadfile->setEnabled( false ); d->m_versionsfile->setEnabled( false ); d->m_importFile->setEnabled( true ); // always enabled like File --> Open d->m_exportFile->setEnabled( false ); d->m_paSave->setEnabled( false ); d->m_paPrint->setEnabled( false ); d->m_paPrintPreview->setEnabled( false ); d->m_sendfile->setEnabled( false); d->m_paCloseFile->setEnabled( false); d->m_splitter=new QSplitter(Qt::Vertical, this, "mw-splitter"); setCentralWidget( d->m_splitter ); // Keyboard accessibility enhancements. new KKbdAccessExtensions(this, "mw-panelSizer"); // set up the action "list" for "Close all Views" (hacky :) (Werner) d->m_veryHackyActionList.append( new KAction(i18n("&Close All Views"), "fileclose", "ctrl+shift+w", this, SLOT(slotCloseAllViews()), actionCollection(), "view_closeallviews") ); // set up the action list for the splitter stuff d->m_splitViewActionList.append(new KAction(i18n("&Split View"), "view_split", 0, this, SLOT(slotSplitView()), actionCollection(), "view_split")); d->m_removeView=new KAction(i18n("&Remove View"), "view_remove", 0, this, SLOT(slotRemoveView()), actionCollection(), "view_rm_splitter"); d->m_splitViewActionList.append(d->m_removeView); d->m_removeView->setEnabled(false); d->m_orientation=new KSelectAction(i18n("Splitter &Orientation"), "view_orientation", 0, this, SLOT(slotSetOrientation()), actionCollection(), "view_splitter_orientation"); QStringList items; items << i18n("&Vertical") << i18n("&Horizontal"); d->m_orientation->setItems(items); d->m_orientation->setCurrentItem(static_cast(d->m_splitter->orientation())); d->m_splitViewActionList.append(d->m_orientation); d->m_splitViewActionList.append(new KActionSeparator(this)); // Load list of recent files KConfig * config = instance ? instance->config() : KGlobal::config(); m_recent->loadEntries( config ); createShellGUI(); d->bMainWindowGUIBuilt = true; if ( !initialGeometrySet() ) { // Default size const int deskWidth = KGlobalSettings::desktopGeometry(this).width(); if (deskWidth > 1100) // very big desktop ? resize( 1000, 800 ); if (deskWidth > 850) // big desktop ? resize( 800, 600 ); else // small (800x600, 640x480) desktop resize( 600, 400 ); } // Saved size config->setGroup( "MainWindow" ); //kdDebug(30003) << "KoMainWindow::restoreWindowSize" << endl; restoreWindowSize( config ); } KoMainWindow::~KoMainWindow() { // The doc and view might still exist (this is the case when closing the window) if (d->m_rootDoc) d->m_rootDoc->removeShell(this); if (d->m_docToOpen) { d->m_docToOpen->removeShell(this); delete d->m_docToOpen; } // safety first ;) d->m_manager->setActivePart(0); if(d->m_rootViews.findRef(d->m_activeView)==-1) { delete d->m_activeView; d->m_activeView=0L; } d->m_rootViews.setAutoDelete( true ); d->m_rootViews.clear(); // We have to check if this was a root document. // -> We aren't allowed to delete the (embedded) document! // This has to be checked from queryClose, too :) if ( d->m_rootDoc && d->m_rootDoc->viewCount() == 0 && !d->m_rootDoc->isEmbedded()) { //kdDebug(30003) << "Destructor. No more views, deleting old doc " << d->m_rootDoc << endl; delete d->m_rootDoc; } delete d->m_manager; delete d; } void KoMainWindow::setRootDocument( KoDocument *doc ) { if ( d->m_rootDoc == doc ) return; if (d->m_docToOpen && d->m_docToOpen != doc) { d->m_docToOpen->removeShell(this); delete d->m_docToOpen; d->m_docToOpen = 0; } else { d->m_docToOpen = 0; } //kdDebug(30003) << "KoMainWindow::setRootDocument this = " << this << " doc = " << doc << endl; QPtrList oldRootViews = d->m_rootViews; d->m_rootViews.clear(); KoDocument *oldRootDoc = d->m_rootDoc; if ( oldRootDoc ) oldRootDoc->removeShell( this ); d->m_rootDoc = doc; if ( doc ) { doc->setSelectable( false ); //d->m_manager->addPart( doc, false ); // done by KoView::setPartManager d->m_rootViews.append( doc->createView( d->m_splitter, "view" /*not unique, but better than unnamed*/ ) ); d->m_rootViews.current()->setPartManager( d->m_manager ); d->m_rootViews.current()->show(); // The addShell has been done already if using openURL if ( !d->m_rootDoc->shells().contains( this ) ) d->m_rootDoc->addShell( this ); d->m_removeView->setEnabled(false); d->m_orientation->setEnabled(false); } bool enable = d->m_rootDoc != 0 ? true : false; d->m_paDocInfo->setEnabled( enable ); d->m_paSave->setEnabled( enable ); d->m_paSaveAs->setEnabled( enable ); d->m_importFile->setEnabled( enable ); d->m_exportFile->setEnabled( enable ); d->m_paPrint->setEnabled( enable ); d->m_paPrintPreview->setEnabled( enable ); d->m_sendfile->setEnabled( enable); d->m_paCloseFile->setEnabled( enable); updateCaption(); d->m_manager->setActivePart( d->m_rootDoc, d->m_rootViews.current() ); oldRootViews.setAutoDelete( true ); oldRootViews.clear(); if ( oldRootDoc && oldRootDoc->viewCount() == 0 ) { //kdDebug(30003) << "No more views, deleting old doc " << oldRootDoc << endl; delete oldRootDoc; } } void KoMainWindow::updateReloadFileAction(KoDocument *doc) { d->m_reloadfile->setEnabled( doc && !doc->url().isEmpty() ); } void KoMainWindow::updateVersionsFileAction(KoDocument *doc) { //TODO activate it just when we save it in oasis file format d->m_versionsfile->setEnabled( doc && !doc->url().isEmpty()&&doc->isModified()); } void KoMainWindow::setRootDocumentDirect( KoDocument *doc, const QPtrList & views ) { d->m_rootDoc = doc; d->m_rootViews = views; bool enable = d->m_rootDoc != 0 ? true : false; d->m_paDocInfo->setEnabled( enable ); d->m_paSave->setEnabled( enable ); d->m_paSaveAs->setEnabled( enable ); d->m_exportFile->setEnabled( enable ); d->m_paPrint->setEnabled( enable ); d->m_paPrintPreview->setEnabled( enable ); d->m_sendfile->setEnabled( enable); d->m_paCloseFile->setEnabled( enable ); } void KoMainWindow::addRecentURL( const KURL& url ) { kdDebug(30003) << "KoMainWindow::addRecentURL url=" << url.prettyURL() << endl; // Add entry to recent documents list // (call coming from KoDocument because it must work with cmd line, template dlg, file/open, etc.) if ( !url.isEmpty() ) { bool ok = true; if ( url.isLocalFile() ) { QString path = url.path( -1 ); QStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" ); for ( QStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it ) if ( path.contains( *it ) ) ok = false; // it's in the tmp resource if ( ok ) KRecentDocument::add(path); } else KRecentDocument::add(url.url(-1), true); if ( ok ) m_recent->addURL( url ); saveRecentFiles(); } } void KoMainWindow::saveRecentFiles() { // Save list of recent files KConfig * config = instance() ? instance()->config() : KGlobal::config(); kdDebug(30003) << this << " Saving recent files list into config. instance()=" << instance() << endl; m_recent->saveEntries( config ); config->sync(); if (KMainWindow::memberList) { // Tell all windows to reload their list, after saving // Doesn't work multi-process, but it's a start KMainWindow *window = KMainWindow::memberList->first(); for (; window; window = KMainWindow::memberList->next()) static_cast(window)->reloadRecentFileList(); } } void KoMainWindow::reloadRecentFileList() { KConfig * config = instance() ? instance()->config() : KGlobal::config(); m_recent->loadEntries( config ); } KoDocument* KoMainWindow::createDoc() const { KoDocumentEntry entry = KoDocumentEntry( KoDocument::readNativeService() ); return entry.createDoc(); } void KoMainWindow::updateCaption() { //kdDebug(30003) << "KoMainWindow::updateCaption()" << endl; if ( !d->m_rootDoc ) setCaption(QString::null); else if ( rootDocument()->isCurrent() ) { QString caption; // Get caption from document info (title(), in about page) if ( rootDocument()->documentInfo() ) { KoDocumentInfoPage * page = rootDocument()->documentInfo()->page( QString::fromLatin1("about") ); if (page) caption = static_cast(page)->title(); } const QString url = rootDocument()->url().prettyURL( 0, KURL::StripFileProtocol ); if ( !caption.isEmpty() && !url.isEmpty() ) caption = QString( "%1 - %2" ).arg( caption ).arg( url ); else if ( caption.isEmpty() ) caption = url; setCaption( caption, rootDocument()->isModified() ); if ( !rootDocument()->url().fileName(false).isEmpty() ) d->m_paSave->setToolTip( i18n("Save as %1").arg(rootDocument()->url().fileName(false)) ); else d->m_paSave->setToolTip( i18n("Save") ); } } void KoMainWindow::updateCaption( QString caption, bool mod ) { //kdDebug(30003)<<"KoMainWindow::updateCaption("<m_rootDoc; } KoView *KoMainWindow::rootView() const { if(d->m_rootViews.find(d->m_activeView)!=-1) return d->m_activeView; return d->m_rootViews.first(); } KParts::PartManager *KoMainWindow::partManager() { return d->m_manager; } bool KoMainWindow::openDocument( const KURL & url ) { if ( !KIO::NetAccess::exists(url,true,0) ) { KMessageBox::error(0L, i18n("The file %1 does not exist.").arg(url.url()) ); m_recent->removeURL(url); //remove the file from the recent-opened-file-list saveRecentFiles(); return false; } return openDocumentInternal( url ); } // (not virtual) bool KoMainWindow::openDocument( KoDocument *newdoc, const KURL & url ) { if (!KIO::NetAccess::exists(url,true,0) ) { if (!newdoc->checkAutoSaveFile()) { newdoc->initEmpty(); //create an emtpy document } setRootDocument( newdoc ); newdoc->setURL(url); QString mime = KMimeType::findByURL(url)->name(); if ( mime.isEmpty() || mime == KMimeType::defaultMimeType() ) mime = newdoc->nativeFormatMimeType(); if ( url.isLocalFile() ) // workaround for kde<=3.3 kparts bug, fixed for 3.4 newdoc->setFile(url.path()); newdoc->setMimeTypeAfterLoading( mime ); updateCaption(); return true; } return openDocumentInternal( url, newdoc ); } // ## If you modify anything here, please check KoShellWindow::openDocumentInternal bool KoMainWindow::openDocumentInternal( const KURL & url, KoDocument *newdoc ) { //kdDebug(30003) << "KoMainWindow::openDocument " << url.url() << endl; if ( !newdoc ) newdoc = createDoc(); if ( !newdoc ) return false; d->m_firstTime=true; connect(newdoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); connect(newdoc, SIGNAL(completed()), this, SLOT(slotLoadCompleted())); connect(newdoc, SIGNAL(canceled( const QString & )), this, SLOT(slotLoadCanceled( const QString & ))); newdoc->addShell( this ); // used by openURL bool openRet = (!isImporting ()) ? newdoc->openURL(url) : newdoc->import(url); if(!openRet) { newdoc->removeShell(this); delete newdoc; return false; } updateReloadFileAction(newdoc); updateVersionsFileAction( newdoc ); return true; } // Separate from openDocument to handle async loading (remote URLs) void KoMainWindow::slotLoadCompleted() { kdDebug(30003) << "KoMainWindow::slotLoadCompleted" << endl; KoDocument* doc = rootDocument(); KoDocument* newdoc = (KoDocument *)(sender()); if ( doc && doc->isEmpty() && !doc->isEmbedded() ) { // Replace current empty document setRootDocument( newdoc ); } else if ( doc && !doc->isEmpty() ) { // Open in a new shell // (Note : could create the shell first and the doc next for this // particular case, that would give a better user feedback...) KoMainWindow *s = new KoMainWindow( newdoc->instance() ); s->show(); newdoc->removeShell( this ); s->setRootDocument( newdoc ); } else { // We had no document, set the new one setRootDocument( newdoc ); } disconnect(newdoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); disconnect(newdoc, SIGNAL(completed()), this, SLOT(slotLoadCompleted())); disconnect(newdoc, SIGNAL(canceled( const QString & )), this, SLOT(slotLoadCanceled( const QString & ))); } void KoMainWindow::slotLoadCanceled( const QString & errMsg ) { kdDebug(30003) << "KoMainWindow::slotLoadCanceled" << endl; if ( !errMsg.isEmpty() ) // empty when canceled by user KMessageBox::error( this, errMsg ); // ... can't delete the document, it's the one who emitted the signal... KoDocument* newdoc = (KoDocument *)(sender()); disconnect(newdoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); disconnect(newdoc, SIGNAL(completed()), this, SLOT(slotLoadCompleted())); disconnect(newdoc, SIGNAL(canceled( const QString & )), this, SLOT(slotLoadCanceled( const QString & ))); newdoc->removeShell(this); delete newdoc; } void KoMainWindow::slotSaveCanceled( const QString &errMsg ) { kdDebug(30003) << "KoMainWindow::slotSaveCanceled" << endl; if ( !errMsg.isEmpty() ) // empty when canceled by user KMessageBox::error( this, errMsg ); slotSaveCompleted(); } void KoMainWindow::slotSaveCompleted() { kdDebug(30003) << "KoMainWindow::slotSaveCompleted" << endl; KoDocument* pDoc = (KoDocument *)(sender()); disconnect(pDoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); disconnect(pDoc, SIGNAL(completed()), this, SLOT(slotSaveCompleted())); disconnect(pDoc, SIGNAL(canceled( const QString & )), this, SLOT(slotSaveCanceled( const QString & ))); } // returns true if we should save, false otherwise. bool KoMainWindow::exportConfirmation( const QCString &outputFormat ) { if (!rootDocument()->wantExportConfirmation()) return true; KMimeType::Ptr mime = KMimeType::mimeType( outputFormat ); const bool neverHeardOfIt = ( mime->name() == KMimeType::defaultMimeType() ); QString comment = neverHeardOfIt ? i18n( "%1 (unknown file type)" ).arg( outputFormat ) : mime->comment(); // Warn the user int ret; if (!isExporting ()) // File --> Save { ret = KMessageBox::warningContinueCancel ( this, i18n( "Saving as a %1 may result in some loss of formatting." "

Do you still want to save in this format?" ) .arg( QString( "%1" ).arg( comment ) ), // in case we want to remove the bold later i18n( "Confirm Save" ), KStdGuiItem::save (), "NonNativeSaveConfirmation", true ); } else // File --> Export { ret = KMessageBox::warningContinueCancel ( this, i18n( "Exporting as a %1 may result in some loss of formatting." "

Do you still want to export to this format?" ) .arg( QString( "%1" ).arg( comment ) ), // in case we want to remove the bold later i18n( "Confirm Export" ), i18n ("Export"), "NonNativeExportConfirmation", // different to the one used for Save (above) true ); } return (ret == KMessageBox::Continue); } bool KoMainWindow::saveDocument( bool saveas, bool silent ) { KoDocument* pDoc = rootDocument(); if(!pDoc) return true; bool reset_url; if ( pDoc->url().isEmpty() ) { emit saveDialogShown(); reset_url = true; saveas = true; } else reset_url = false; connect(pDoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); connect(pDoc, SIGNAL(completed()), this, SLOT(slotSaveCompleted())); connect(pDoc, SIGNAL(canceled( const QString & )), this, SLOT(slotSaveCanceled( const QString & ))); KURL oldURL = pDoc->url(); QString oldFile = pDoc->file(); QCString _native_format = pDoc->nativeFormatMimeType(); QCString oldOutputFormat = pDoc->outputMimeType(); int oldSpecialOutputFlag = pDoc->specialOutputFlag(); KURL suggestedURL = pDoc->url(); QStringList mimeFilter = KoFilterManager::mimeFilter( _native_format, KoFilterManager::Export, pDoc->extraNativeMimeTypes() ); if (mimeFilter.findIndex (oldOutputFormat) < 0 && !isExporting()) { kdDebug(30003) << "KoMainWindow::saveDocument no export filter for '" << oldOutputFormat << "'" << endl; // --- don't setOutputMimeType in case the user cancels the Save As // dialog and then tries to just plain Save --- // suggest a different filename extension (yes, we fortunately don't all live in a world of magic :)) QString suggestedFilename = suggestedURL.fileName (); if ( !suggestedFilename.isEmpty () ) // ".kwd" looks strange for a name { int c = suggestedFilename.findRev ('.'); KMimeType::Ptr mime = KMimeType::mimeType( _native_format ); QString ext = mime->property( "X-KDE-NativeExtension" ).toString(); if (!ext.isEmpty ()) { if (c < 0) suggestedFilename += ext; else suggestedFilename = suggestedFilename.left (c) + ext; } else // current filename extension wrong anyway { if (c > 0) { // this assumes that a . signifies an extension, not just a . suggestedFilename = suggestedFilename.left (c); } } suggestedURL.setFileName (suggestedFilename); } // force the user to choose outputMimeType saveas = true; } bool ret = false; if ( pDoc->url().isEmpty() || saveas ) { // if you're just File/Save As'ing to change filter options you // don't want to be reminded about overwriting files etc. bool justChangingFilterOptions = false; KoFileDialog *dialog = new KoFileDialog( (isExporting() && !d->m_lastExportURL.isEmpty() )? d->m_lastExportURL.url () : suggestedURL.url (), QString::null, this, "file dialog", true); if (!isExporting()) dialog->setCaption( i18n("Save Document As") ); else dialog->setCaption( i18n("Export Document As") ); dialog->setOperationMode( KFileDialog::Saving ); dialog->setSpecialMimeFilter( mimeFilter, isExporting() ? d->m_lastExportFormat : pDoc->mimeType(), isExporting() ? d->m_lastExportSpecialOutputFlag : oldSpecialOutputFlag, _native_format, pDoc->supportedSpecialFormats() ); KURL newURL; QCString outputFormat = _native_format; int specialOutputFlag = 0; bool bOk; do { bOk=true; if(dialog->exec()==QDialog::Accepted) { newURL=dialog->selectedURL(); outputFormat=dialog->currentMimeFilter().latin1(); specialOutputFlag = dialog->specialEntrySelected(); kdDebug(30003) << "KoMainWindow::saveDocument outputFormat = " << outputFormat << endl; if (!isExporting()) justChangingFilterOptions = (newURL == pDoc->url()) && (outputFormat == pDoc->mimeType()) && (specialOutputFlag == oldSpecialOutputFlag); else justChangingFilterOptions = (newURL == d->m_lastExportURL) && (outputFormat == d->m_lastExportFormat) && (specialOutputFlag == d->m_lastExportSpecialOutputFlag); } else { bOk = false; break; } if ( newURL.isEmpty() ) { bOk = false; break; } // adjust URL before doing checks on whether the file exists. if ( specialOutputFlag == KoDocument::SaveAsDirectoryStore ) { QString fileName = newURL.fileName(); if ( fileName != "content.xml" ) { newURL.addPath( "content.xml" ); } } // this file exists and we are not just clicking "Save As" to change filter options // => ask for confirmation if ( KIO::NetAccess::exists( newURL, false /*will write*/, this ) && !justChangingFilterOptions ) { bOk = KMessageBox::questionYesNo( this, i18n("A document with this name already exists.\n"\ "Do you want to overwrite it?"), i18n("Warning") ) == KMessageBox::Yes; } } while ( !bOk ); delete dialog; if (bOk) { bool wantToSave = true; // don't change this line unless you know what you're doing :) if (!justChangingFilterOptions || pDoc->confirmNonNativeSave (isExporting ())) { if ( !pDoc->isNativeFormat( outputFormat ) ) wantToSave = exportConfirmation( outputFormat ); } if (wantToSave) { // // Note: // If the user is stupid enough to Export to the current URL, // we do _not_ change this operation into a Save As. Reasons // follow: // // 1. A check like "isExporting() && oldURL == newURL" // doesn't _always_ work on case-insensitive filesystems // and inconsistent behaviour is bad. // 2. It is probably not a good idea to change pDoc->mimeType // and friends because the next time the user File/Save's, // (not Save As) they won't be expecting that they are // using their File/Export settings // // As a bad side-effect of this, the modified flag will not // be updated and it is possible that what is currently on // their screen is not what is stored on disk (through loss // of formatting). But if you are dumb enough to change // mimetype but not the filename, then arguably, _you_ are // the "bug" :) // // - Clarence // pDoc->setOutputMimeType( outputFormat, specialOutputFlag ); if (!isExporting ()) // Save As { ret = pDoc->saveAs( newURL ); if (ret) { kdDebug(30003) << "Successful Save As!" << endl; addRecentURL( newURL ); } else { kdDebug(30003) << "Failed Save As!" << endl; pDoc->setURL( oldURL ), pDoc->setFile( oldFile ); pDoc->setOutputMimeType( oldOutputFormat, oldSpecialOutputFlag ); } } else // Export { ret = pDoc->exp0rt( newURL ); if (ret) { // a few file dialog convenience things d->m_lastExportURL = newURL; d->m_lastExportFormat = outputFormat; d->m_lastExportSpecialOutputFlag = specialOutputFlag; } // always restore output format pDoc->setOutputMimeType( oldOutputFormat, oldSpecialOutputFlag ); } } // if (wantToSave) else ret = false; } // if (bOk) else ret = false; } else { // saving bool needConfirm = pDoc->confirmNonNativeSave( false ) && !pDoc->isNativeFormat( oldOutputFormat ); if (!needConfirm || (needConfirm && exportConfirmation( oldOutputFormat /* not so old :) */ )) ) { // be sure pDoc has the correct outputMimeType! ret = pDoc->save(); if (!ret) { kdDebug(30003) << "Failed Save!" << endl; pDoc->setURL( oldURL ), pDoc->setFile( oldFile ); } } else ret = false; } // Now that there's a File/Export option, this is no longer necessary. // If you continue to use File/Save to export to a foreign format, // this signals your intention to continue working in a foreign format. // You have already been warned by the DoNotAskAgain exportConfirmation // about losing formatting when you first saved so don't set modified // here or else it will be reported as a bug by some MSOffice user. // You have been warned! Do not click DoNotAskAgain!!! #if 0 if (ret && !isExporting()) { // When exporting to a non-native format, we don't reset modified. // This way the user will be reminded to save it again in the native format, // if he/she doesn't want to lose formatting. if ( wasModified && pDoc->outputMimeType() != _native_format ) pDoc->setModified( true ); } #endif if (!ret && reset_url) pDoc->resetURL(); //clean the suggested filename as the save dialog was rejected else if (! silent) // don't let the document change the window caption pDoc->setTitleModified(); return ret; } void KoMainWindow::closeEvent(QCloseEvent *e) { if(queryClose()) { saveWindowSettings(); setRootDocument(0L); KParts::MainWindow::closeEvent(e); } } void KoMainWindow::saveWindowSettings() { if (d->m_windowSizeDirty && rootDocument()) { // Save window size into the config file of our instance instance()->config()->setGroup( "MainWindow" ); //kdDebug(30003) << "KoMainWindow::saveWindowSettings" << endl; saveWindowSize( instance()->config() ); d->m_windowSizeDirty = false; // Save toolbar position into the config file of the app, under the doc's instance name //kdDebug(30003) << "KoMainWindow::closeEvent -> saveMainWindowSettings rootdoc's instance=" << rootDocument()->instance()->instanceName() << endl; saveMainWindowSettings( KGlobal::config(), rootDocument()->instance()->instanceName() ); KGlobal::config()->sync(); resetAutoSaveSettings(); // Don't let KMainWindow override the good stuff we wrote down } } void KoMainWindow::resizeEvent( QResizeEvent * e ) { d->m_windowSizeDirty = true; KParts::MainWindow::resizeEvent( e ); } bool KoMainWindow::queryClose() { if ( rootDocument() == 0 ) return true; //kdDebug(30003) << "KoMainWindow::queryClose() viewcount=" << rootDocument()->viewCount() // << " shellcount=" << rootDocument()->shellCount() << endl; if ( !d->m_forQuit && rootDocument()->shellCount() > 1 ) // there are more open, and we are closing just one, so no problem for closing return true; // see DTOR for a descr. of the test if ( d->m_rootDoc->isEmbedded() ) return true; // main doc + internally stored child documents if ( d->m_rootDoc->isModified() ) { QString name; if ( rootDocument()->documentInfo() ) { name = rootDocument()->documentInfo()->title(); } if ( name.isEmpty() ) name = rootDocument()->url().fileName(); if ( name.isEmpty() ) name = i18n( "Untitled" ); int res = KMessageBox::warningYesNoCancel( this, i18n( "

The document '%1' has been modified.

Do you want to save it?

" ).arg(name), QString::null, KStdGuiItem::save(), KStdGuiItem::discard()); switch(res) { case KMessageBox::Yes : { d->m_rootDoc->setDoNotSaveExtDoc(); // external docs are saved later bool isNative = ( d->m_rootDoc->outputMimeType() == d->m_rootDoc->nativeFormatMimeType() ); if (! saveDocument( !isNative ) ) return false; break; } case KMessageBox::No : rootDocument()->removeAutoSaveFiles(); rootDocument()->setModified( false ); // Now when queryClose() is called by closeEvent it won't do anything. break; default : // case KMessageBox::Cancel : return false; } } if ( d->m_rootDoc->queryCloseExternalChildren() == KMessageBox::Cancel ) { return false; } return true; } // Helper method for slotFileNew and slotFileClose void KoMainWindow::chooseNewDocument( int /*KoDocument::InitDocFlags*/ initDocFlags ) { KoDocument* doc = rootDocument(); KoDocument *newdoc = createDoc(); if ( !newdoc ) return; //FIXME: This needs to be handled differently connect(newdoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); disconnect(newdoc, SIGNAL(sigProgress(int)), this, SLOT(slotProgress(int))); if ( ( !doc && ( initDocFlags == KoDocument::InitDocFileNew ) ) || ( doc && !doc->isEmpty() ) ) { KoMainWindow *s = new KoMainWindow( newdoc->instance() ); s->show(); newdoc->addShell( s ); newdoc->showStartUpWidget( s, true /*Always show widget*/ ); return; } if( doc ) { setRootDocument( 0 ); delete d->m_rootDoc; d->m_rootDoc = 0; } newdoc->addShell( this ); newdoc->showStartUpWidget( this, true /*Always show widget*/ ); } void KoMainWindow::slotFileNew() { chooseNewDocument( KoDocument::InitDocFileNew ); } void KoMainWindow::slotFileOpen() { KFileDialog *dialog = new KFileDialog(":OpenDialog", QString::null, this, "file dialog", true); if (!isImporting()) dialog->setCaption( i18n("Open Document") ); else dialog->setCaption( i18n("Import Document") ); // The few lines below need to be kept in sync with KoTemplateChooseDia::setupFileDialog const QStringList mimeFilter = KoFilterManager::mimeFilter( KoDocument::readNativeFormatMimeType(), KoFilterManager::Import, KoDocument::readExtraNativeMimeTypes() ); dialog->setMimeFilter( mimeFilter ); if(dialog->exec()!=QDialog::Accepted) { delete dialog; return; } KURL url( dialog->selectedURL() ); delete dialog; if ( url.isEmpty() ) return; (void) openDocument( url ); } void KoMainWindow::slotFileOpenRecent( const KURL & url ) { (void) openDocument( url ); } void KoMainWindow::slotFileSave() { if ( saveDocument() ) emit documentSaved(); } void KoMainWindow::slotFileSaveAs() { if ( saveDocument( true ) ) emit documentSaved(); } void KoMainWindow::slotDocumentInfo() { if ( !rootDocument() ) return; KoDocumentInfo *docInfo = rootDocument()->documentInfo(); if ( !docInfo ) return; KoDocumentInfoDlg *dlg = new KoDocumentInfoDlg( docInfo, this, "documentInfoDlg" ); if ( dlg->exec() ) { dlg->save(); rootDocument()->setModified( true ); rootDocument()->setTitleModified(); } delete dlg; } void KoMainWindow::slotFileClose() { if (queryClose()) { saveWindowSettings(); setRootDocument( 0 ); // don't delete this shell when deleting the document delete d->m_rootDoc; d->m_rootDoc = 0; chooseNewDocument( KoDocument::InitDocFileClose ); } } void KoMainWindow::slotFileQuit() { close(); } void KoMainWindow::print(bool quick) { if ( !rootView() ) { kdDebug(30003) << "KoMainWindow::slotFilePrint : No root view!" << endl; return; } KPrinter printer( true /*, QPrinter::HighResolution*/ ); QString title = rootView()->koDocument()->documentInfo()->title(); QString fileName = rootView()->koDocument()->url().fileName(); // strip off the native extension (I don't want foobar.kwd.ps when printing into a file) KMimeType::Ptr mime = KMimeType::mimeType( rootView()->koDocument()->outputMimeType() ); if ( mime ) { QString extension = mime->property( "X-KDE-NativeExtension" ).toString(); if ( fileName.endsWith( extension ) ) fileName.truncate( fileName.length() - extension.length() ); } if ( title.isEmpty() ) title = fileName; if ( title.isEmpty() ) { // #139905 - breaks message freeze though //const QString programName = instance()->aboutData() ? instance()->aboutData()->programName() : instance()->instanceName(); //title = i18n("%1 unsaved document (%2)").arg(programName).arg(KGlobal::locale()->formatDate(QDate::currentDate(), true/*short*/)); } printer.setDocName( title ); printer.setDocFileName( fileName ); printer.setDocDirectory( rootView()->koDocument()->url().directory() ); // ### TODO: apply global koffice settings here rootView()->setupPrinter( printer ); if ( quick || printer.setup( this ) ) rootView()->print( printer ); } void KoMainWindow::slotFilePrint() { print(false); } void KoMainWindow::slotFilePrintPreview() { if ( !rootView() ) { kdWarning() << "KoMainWindow::slotFilePrint : No root view!" << endl; return; } KPrinter printer( false ); KTempFile tmpFile; // The temp file is deleted by KoPrintPreview // This line has to be before setupPrinter to let the apps decide what to // print and what not (if they want to :) printer.setFromTo( printer.minPage(), printer.maxPage() ); printer.setPreviewOnly( true ); rootView()->setupPrinter( printer ); QString oldFileName = printer.outputFileName(); printer.setOutputFileName( tmpFile.name() ); int oldNumCopies = printer.numCopies(); printer.setNumCopies( 1 ); // Disable kdeprint's own preview, we'd get two. This shows that KPrinter needs // a "don't use the previous settings" mode. The current way is really too much of a hack. QString oldKDEPreview = printer.option( "kde-preview" ); printer.setOption( "kde-preview", "0" ); rootView()->print(printer); //KoPrintPreview::preview(this, "KoPrintPreviewDialog", tmpFile.name()); // Restore previous values printer.setOutputFileName( oldFileName ); printer.setNumCopies( oldNumCopies ); printer.setOption( "kde-preview", oldKDEPreview ); } void KoMainWindow::slotConfigureKeys() { guiFactory()->configureShortcuts(); } void KoMainWindow::slotConfigureToolbars() { if (rootDocument()) saveMainWindowSettings( KGlobal::config(), rootDocument()->instance()->instanceName() ); KEditToolbar edit(factory(), this); connect(&edit,SIGNAL(newToolbarConfig()),this,SLOT(slotNewToolbarConfig())); (void) edit.exec(); } void KoMainWindow::slotNewToolbarConfig() { if (rootDocument()) applyMainWindowSettings( KGlobal::config(), rootDocument()->instance()->instanceName() ); KXMLGUIFactory *factory = guiFactory(); // Check if there's an active view if( !d->m_activeView ) return; // This gets plugged in even for embedded views factory->plugActionList(d->m_activeView, "view_closeallviews", d->m_veryHackyActionList); // This one only for root views if(d->m_rootViews.findRef(d->m_activeView)!=-1) factory->plugActionList(d->m_activeView, "view_split", d->m_splitViewActionList ); plugActionList( "toolbarlist", d->m_toolbarList ); } void KoMainWindow::slotToolbarToggled( bool toggle ) { //kdDebug(30003) << "KoMainWindow::slotToolbarToggled " << sender()->name() << " toggle=" << true << endl; // The action (sender) and the toolbar have the same name KToolBar * bar = toolBar( sender()->name() ); if (bar) { if (toggle) bar->show(); else bar->hide(); if (rootDocument()) saveMainWindowSettings( KGlobal::config(), rootDocument()->instance()->instanceName() ); } else kdWarning(30003) << "slotToolbarToggled : Toolbar " << sender()->name() << " not found!" << endl; } bool KoMainWindow::toolbarIsVisible(const char *tbName) { QWidget *tb = toolBar( tbName); return !tb->isHidden(); } void KoMainWindow::showToolbar( const char * tbName, bool shown ) { QWidget * tb = toolBar( tbName ); if ( !tb ) { kdWarning(30003) << "KoMainWindow: toolbar " << tbName << " not found." << endl; return; } if ( shown ) tb->show(); else tb->hide(); // Update the action appropriately QPtrListIterator it( d->m_toolbarList ); for ( ; it.current() ; ++it ) if ( !strcmp( it.current()->name(), tbName ) ) { //kdDebug(30003) << "KoMainWindow::showToolbar setChecked " << shown << endl; static_cast(it.current())->setChecked( shown ); break; } } void KoMainWindow::slotSplitView() { d->m_splitted=true; d->m_rootViews.append(d->m_rootDoc->createView(d->m_splitter, "splitted-view")); d->m_rootViews.current()->show(); d->m_rootViews.current()->setPartManager( d->m_manager ); d->m_manager->setActivePart( d->m_rootDoc, d->m_rootViews.current() ); d->m_removeView->setEnabled(true); d->m_orientation->setEnabled(true); } void KoMainWindow::slotCloseAllViews() { // Attention: Very touchy code... you know what you're doing? Goooood :) d->m_forQuit=true; if(queryClose()) { // In case the document is embedded we close all open "extra-shells" if(d->m_rootDoc && d->m_rootDoc->isEmbedded()) { hide(); d->m_rootDoc->removeShell(this); QPtrListIterator it(d->m_rootDoc->shells()); while (it.current()) { it.current()->hide(); delete it.current(); // this updates the lists' current pointer and thus // the iterator (the shell dtor calls removeShell) d->m_rootDoc=0; } } // not embedded -> destroy the document and all shells/views ;) else setRootDocument( 0L ); close(); // close this window (and quit the app if necessary) } d->m_forQuit=false; } void KoMainWindow::slotRemoveView() { KoView *view; if(d->m_rootViews.findRef(d->m_activeView)!=-1) view=d->m_rootViews.current(); else view=d->m_rootViews.first(); view->hide(); if ( !d->m_rootViews.removeRef(view) ) kdWarning() << "view not found in d->m_rootViews!" << endl; if(d->m_rootViews.count()==1) { d->m_removeView->setEnabled(false); d->m_orientation->setEnabled(false); } // Prevent the view's destroyed() signal from triggering GUI rebuilding (too early) d->m_manager->setActivePart( 0, 0 ); delete view; view=0L; d->m_rootViews.first()->setPartManager( d->m_manager ); d->m_manager->setActivePart( d->m_rootDoc, d->m_rootViews.first() ); if(d->m_rootViews.count()==1) d->m_splitted=false; } void KoMainWindow::slotSetOrientation() { d->m_splitter->setOrientation(static_cast (d->m_orientation->currentItem())); } void KoMainWindow::slotProgress(int value) { //kdDebug(30003) << "KoMainWindow::slotProgress " << value << endl; if(value==-1) { if ( d->m_progress ) { statusBar()->removeWidget(d->m_progress); delete d->m_progress; d->m_progress=0L; } d->m_firstTime=true; return; } if(d->m_firstTime) { // The statusbar might not even be created yet. // So check for that first, and create it if necessary QObjectList *l = queryList( "QStatusBar" ); if ( !l || !l->first() ) { statusBar()->show(); QApplication::sendPostedEvents( this, QEvent::ChildInserted ); setUpLayout(); } delete l; if ( d->m_progress ) { statusBar()->removeWidget(d->m_progress); delete d->m_progress; d->m_progress=0L; } statusBar()->setMaximumHeight(statusBar()->height()); d->m_progress=new KProgress(statusBar()); //d->m_progress->setMaximumHeight(statusBar()->height()); statusBar()->addWidget( d->m_progress, 0, true ); d->m_progress->show(); d->m_firstTime=false; } d->m_progress->setProgress(value); kapp->processEvents(); } void KoMainWindow::slotActivePartChanged( KParts::Part *newPart ) { // This looks very much like KParts::MainWindow::createGUI, but we have // to reimplement it because it works with an active part, whereas we work // with an active view _and_ an active part, depending for what. // Both are KXMLGUIClients, but e.g. the plugin query needs a QObject. //kdDebug(30003) << "KoMainWindow::slotActivePartChanged( Part * newPart) newPart = " << newPart << endl; //kdDebug(30003) << "current active part is " << d->m_activePart << endl; if ( d->m_activePart && d->m_activePart == newPart && !d->m_splitted ) { //kdDebug(30003) << "no need to change the GUI" << endl; return; } KXMLGUIFactory *factory = guiFactory(); setUpdatesEnabled( false ); if ( d->m_activeView ) { KParts::GUIActivateEvent ev( false ); QApplication::sendEvent( d->m_activePart, &ev ); QApplication::sendEvent( d->m_activeView, &ev ); factory->removeClient( d->m_activeView ); unplugActionList( "toolbarlist" ); d->m_toolbarList.clear(); // deletes the actions } if ( !d->bMainWindowGUIBuilt ) { // Load mainwindow plugins KParts::Plugin::loadPlugins( this, this, instance(), true ); createShellGUI(); } if ( newPart && d->m_manager->activeWidget() && d->m_manager->activeWidget()->inherits( "KoView" ) ) { d->m_activeView = (KoView *)d->m_manager->activeWidget(); d->m_activePart = newPart; //kdDebug(30003) << "new active part is " << d->m_activePart << endl; factory->addClient( d->m_activeView ); // This gets plugged in even for embedded views factory->plugActionList(d->m_activeView, "view_closeallviews", d->m_veryHackyActionList); // This one only for root views if(d->m_rootViews.findRef(d->m_activeView)!=-1) factory->plugActionList(d->m_activeView, "view_split", d->m_splitViewActionList ); // Position and show toolbars according to user's preference setAutoSaveSettings( newPart->instance()->instanceName(), false ); // Create and plug toolbar list for Settings menu //QPtrListIterator it = toolBarIterator(); QPtrList toolBarList = factory->containers( "ToolBar" ); QPtrListIterator it( toolBarList ); for ( ; it.current() ; ++it ) { if ( it.current()->inherits("KToolBar") ) { KToolBar * tb = static_cast(it.current()); KToggleAction * act = new KToggleAction( i18n("Show %1 Toolbar").arg( tb->text() ), 0, actionCollection(), tb->name() ); act->setCheckedState(i18n("Hide %1 Toolbar").arg( tb->text() )); connect( act, SIGNAL( toggled( bool ) ), this, SLOT( slotToolbarToggled( bool ) ) ); act->setChecked ( !tb->isHidden() ); d->m_toolbarList.append( act ); } else kdWarning(30003) << "Toolbar list contains a " << it.current()->className() << " which is not a toolbar!" << endl; } plugActionList( "toolbarlist", d->m_toolbarList ); // Send the GUIActivateEvent only now, since it might show/hide toolbars too // (and this has priority over applyMainWindowSettings) KParts::GUIActivateEvent ev( true ); QApplication::sendEvent( d->m_activePart, &ev ); QApplication::sendEvent( d->m_activeView, &ev ); } else { d->m_activeView = 0L; d->m_activePart = 0L; } setUpdatesEnabled( true ); } QLabel * KoMainWindow::statusBarLabel() { if ( !d->statusBarLabel ) { d->statusBarLabel = new QLabel( statusBar() ); statusBar()->addWidget( d->statusBarLabel, 1, true ); } return d->statusBarLabel; } void KoMainWindow::setMaxRecentItems(uint _number) { m_recent->setMaxItems( _number ); } DCOPObject * KoMainWindow::dcopObject() { if ( !d->m_dcopObject ) { d->m_dcopObject = new KoMainWindowIface( this ); } return d->m_dcopObject; } void KoMainWindow::slotEmailFile() { if (!rootDocument()) return; // Subject = Document file name // Attachment = The current file // Message Body = The current document in HTML export? <-- This may be an option. QString theSubject; QStringList urls; QString fileURL; if (rootDocument()->url ().isEmpty () || rootDocument()->isModified()) { //Save the file as a temporary file bool const tmp_modified = rootDocument()->isModified(); KURL const tmp_url = rootDocument()->url(); QCString const tmp_mimetype = rootDocument()->outputMimeType(); KTempFile tmpfile; //TODO: The temorary file should be deleted when the mail program is closed KURL u; u.setPath(tmpfile.name()); rootDocument()->setURL(u); rootDocument()->setModified(true); rootDocument()->setOutputMimeType(rootDocument()->nativeFormatMimeType()); saveDocument(false, true); fileURL = tmpfile.name(); theSubject = i18n("Document"); urls.append( fileURL ); rootDocument()->setURL(tmp_url); rootDocument()->setModified(tmp_modified); rootDocument()->setOutputMimeType(tmp_mimetype); } else { fileURL = rootDocument()->url().url(); theSubject = i18n("Document - %1").arg(rootDocument()->url().fileName(false)); urls.append( fileURL ); } kdDebug(30003) << "(" << fileURL <<")" << endl; if (!fileURL.isEmpty()) { kapp->invokeMailer(QString::null, QString::null, QString::null, theSubject, QString::null, //body QString::null, urls); // attachments } } void KoMainWindow::slotVersionsFile() { KoVersionDialog *dlg = new KoVersionDialog( this ); dlg->exec(); delete dlg; } void KoMainWindow::slotReloadFile() { KoDocument* pDoc = rootDocument(); if(!pDoc || pDoc->url().isEmpty() || !pDoc->isModified()) return; bool bOk = KMessageBox::questionYesNo( this, i18n("You will lose all your changes!\n" "Do you want to continue?"), i18n("Warning") ) == KMessageBox::Yes; if ( !bOk ) return; KURL url = pDoc->url(); if ( pDoc && !pDoc->isEmpty() ) { setRootDocument( 0L ); // don't delete this shell when deleting the document delete d->m_rootDoc; d->m_rootDoc = 0L; } openDocument( url ); return; } void KoMainWindow::slotImportFile() { kdDebug(30003) << "slotImportFile()" << endl; d->m_isImporting = true; slotFileOpen(); d->m_isImporting = false; } void KoMainWindow::slotExportFile() { kdDebug(30003) << "slotExportFile()" << endl; d->m_isExporting = true; slotFileSaveAs(); d->m_isExporting = false; } bool KoMainWindow::isImporting() const { return d->m_isImporting; } bool KoMainWindow::isExporting() const { return d->m_isExporting; } void KoMainWindow::setDocToOpen( KoDocument *doc ) { d->m_docToOpen = doc; } #include