diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /lib/kofficecore/KoMainWindow.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/kofficecore/KoMainWindow.cpp')
-rw-r--r-- | lib/kofficecore/KoMainWindow.cpp | 1701 |
1 files changed, 1701 insertions, 0 deletions
diff --git a/lib/kofficecore/KoMainWindow.cpp b/lib/kofficecore/KoMainWindow.cpp new file mode 100644 index 00000000..bdcfaa6a --- /dev/null +++ b/lib/kofficecore/KoMainWindow.cpp @@ -0,0 +1,1701 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + Copyright (C) 2000-2006 David Faure <[email protected]> + + 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 <kaboutdata.h> +#include <kprinter.h> +#include <kdeversion.h> +#include <kstdaction.h> +#include <kapplication.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kio/netaccess.h> +#include <kkeydialog.h> +#include <kedittoolbar.h> +#include <kprogress.h> +#include <kpushbutton.h> +#include <kdebug.h> +#include <ktempfile.h> +#include <krecentdocument.h> +#include <kparts/partmanager.h> +#include <kparts/plugin.h> +#include <kparts/event.h> +#include <klocale.h> +#include <kstatusbar.h> +#include <kglobalsettings.h> +#include <ksharedptr.h> + +#include <qobjectlist.h> + +#include <unistd.h> +#include <stdlib.h> + +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<KoFrame *>( 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<KoView> m_rootViews; + KParts::PartManager *m_manager; + + KParts::Part *m_activePart; + KoView *m_activeView; + + QLabel * statusBarLabel; + KProgress *m_progress; + + QPtrList<KAction> m_splitViewActionList; + // This additional list is needed, because we don't plug + // the first list, when an embedded view gets activated (Werner) + QPtrList<KAction> m_veryHackyActionList; + QSplitter *m_splitter; + KSelectAction *m_orientation; + KAction *m_removeView; + KoMainWindowIface *m_dcopObject; + + QPtrList <KAction> 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<KoSpeaker> 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<int>(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<KoView> 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<KoView> & 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<KoMainWindow *>(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<KoDocumentInfoAbout *>(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("<<caption<<","<<mod<<")"<<endl; + setCaption( caption, mod ); +} + +KoDocument *KoMainWindow::rootDocument() const +{ + return d->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( "<qt>Saving as a %1 may result in some loss of formatting." + "<p>Do you still want to save in this format?</qt>" ) + .arg( QString( "<b>%1</b>" ).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( "<qt>Exporting as a %1 may result in some loss of formatting." + "<p>Do you still want to export to this format?</qt>" ) + .arg( QString( "<b>%1</b>" ).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( "<p>The document <b>'%1'</b> has been modified.</p><p>Do you want to save it?</p>" ).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<KAction> it( d->m_toolbarList ); + for ( ; it.current() ; ++it ) + if ( !strcmp( it.current()->name(), tbName ) ) + { + //kdDebug(30003) << "KoMainWindow::showToolbar setChecked " << shown << endl; + static_cast<KToggleAction *>(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<KoMainWindow> 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<Qt::Orientation> + (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<KToolBar> it = toolBarIterator(); + QPtrList<QWidget> toolBarList = factory->containers( "ToolBar" ); + QPtrListIterator<QWidget> it( toolBarList ); + for ( ; it.current() ; ++it ) + { + if ( it.current()->inherits("KToolBar") ) + { + KToolBar * tb = static_cast<KToolBar *>(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 <KoMainWindow.moc> |