summaryrefslogtreecommitdiffstats
path: root/lib/kofficecore/KoMainWindow.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /lib/kofficecore/KoMainWindow.cpp
downloadkoffice-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.cpp1701
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>