You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/lib/kofficecore/KoMainWindow.cpp

1702 lines
58 KiB

/* This file is part of the KDE project
Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
Copyright (C) 2000-2006 David Faure <faure@kde.org>
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 <tdeversion.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 <tqobjectlist.h>
#include <unistd.h>
#include <stdlib.h>
class KoPartManager : public KParts::PartManager
{
public:
KoPartManager( TQWidget * 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( TQObject *obj, TQEvent *ev )
{
if ( !obj->isWidgetType() || ::tqqt_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;
TQPtrList<KoView> m_rootViews;
KParts::PartManager *m_manager;
KParts::Part *m_activePart;
KoView *m_activeView;
TQLabel * statusBarLabel;
KProgress *m_progress;
TQPtrList<KAction> m_splitViewActionList;
// This additional list is needed, because we don't plug
// the first list, when an embedded view gets activated (Werner)
TQPtrList<KAction> m_veryHackyActionList;
TQSplitter *m_splitter;
KSelectAction *m_orientation;
KAction *m_removeView;
KoMainWindowIface *m_dcopObject;
TQPtrList <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;
TQCString m_lastExportFormat;
int m_lastExportSpecialOutputFlag;
KSharedPtr<KoSpeaker> m_koSpeaker;
};
KoMainWindow::KoMainWindow( TDEInstance *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, TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
TQT_TQOBJECT(this), TQT_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)
TQString doc;
TQStringList allFiles = KGlobal::dirs()->findAllResources( "data", "koffice/koffice_shell.rc" );
setXMLFile( findMostRecentXMLFile( allFiles, doc ) );
setLocalXMLFile( locateLocal( "data", "koffice/koffice_shell.rc" ) );
KStdAction::openNew( TQT_TQOBJECT(this), TQT_SLOT( slotFileNew() ), actionCollection(), "file_new" );
KStdAction::open( TQT_TQOBJECT(this), TQT_SLOT( slotFileOpen() ), actionCollection(), "file_open" );
m_recent = KStdAction::openRecent( TQT_TQOBJECT(this), TQT_SLOT(slotFileOpenRecent(const KURL&)), actionCollection() );
d->m_paSave = KStdAction::save( TQT_TQOBJECT(this), TQT_SLOT( slotFileSave() ), actionCollection(), "file_save" );
d->m_paSaveAs = KStdAction::saveAs( TQT_TQOBJECT(this), TQT_SLOT( slotFileSaveAs() ), actionCollection(), "file_save_as" );
d->m_paPrint = KStdAction::print( TQT_TQOBJECT(this), TQT_SLOT( slotFilePrint() ), actionCollection(), "file_print" );
d->m_paPrintPreview = KStdAction::printPreview( TQT_TQOBJECT(this), TQT_SLOT( slotFilePrintPreview() ), actionCollection(), "file_print_preview" );
d->m_sendfile = KStdAction::mail( TQT_TQOBJECT(this), TQT_SLOT( slotEmailFile() ), actionCollection(), "file_send_file");
d->m_paCloseFile = KStdAction::close( TQT_TQOBJECT(this), TQT_SLOT( slotFileClose() ), actionCollection(), "file_close" );
KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT( slotFileQuit() ), actionCollection(), "file_quit" );
d->m_reloadfile = new KAction( i18n( "Reload"), 0,
TQT_TQOBJECT(this), TQT_SLOT( slotReloadFile() ),
actionCollection(), "file_reload_file");
d->m_versionsfile = new KAction( i18n( "Versions..."), 0,
TQT_TQOBJECT(this), TQT_SLOT( slotVersionsFile() ),
actionCollection(), "file_versions_file");
d->m_importFile = new KAction( i18n( "I&mport..." ), 0, // clashing accel key :(
TQT_TQOBJECT(this), TQT_SLOT( slotImportFile() ),
actionCollection(), "file_import_file");
d->m_exportFile = new KAction( i18n( "E&xport..." ), 0,
TQT_TQOBJECT(this), TQT_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,
TQT_TQOBJECT(this), TQT_SLOT( slotDocumentInfo() ),
actionCollection(), "file_documentinfo" );
KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( slotConfigureKeys() ), actionCollection() );
KStdAction::configureToolbars( TQT_TQOBJECT(this), TQT_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 TQSplitter(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", TQT_TQOBJECT(this), TQT_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,
TQT_TQOBJECT(this), TQT_SLOT(slotSplitView()),
actionCollection(), "view_split"));
d->m_removeView=new KAction(i18n("&Remove View"), "view_remove", 0,
TQT_TQOBJECT(this), TQT_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,
TQT_TQOBJECT(this), TQT_SLOT(slotSetOrientation()),
actionCollection(), "view_splitter_orientation");
TQStringList 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(TQT_TQOBJECT(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;
TQPtrList<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 TQPtrList<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() )
{
TQString path = url.path( -1 );
TQStringList tmpDirs = KGlobal::dirs()->resourceDirs( "tmp" );
for ( TQStringList::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(TQString());
else if ( rootDocument()->isCurrent() )
{
TQString caption;
// Get caption from document info (title(), in about page)
if ( rootDocument()->documentInfo() )
{
KoDocumentInfoPage * page = rootDocument()->documentInfo()->page( TQString::fromLatin1("about") );
if (page)
caption = static_cast<KoDocumentInfoAbout *>(page)->title();
}
const TQString url = rootDocument()->url().prettyURL( 0, KURL::StripFileProtocol );
if ( !caption.isEmpty() && !url.isEmpty() )
caption = TQString( "%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( TQString 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);
TQString 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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
connect(newdoc, TQT_SIGNAL(completed()), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCompleted()));
connect(newdoc, TQT_SIGNAL(canceled( const TQString & )), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCanceled( const TQString & )));
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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
disconnect(newdoc, TQT_SIGNAL(completed()), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCompleted()));
disconnect(newdoc, TQT_SIGNAL(canceled( const TQString & )), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCanceled( const TQString & )));
}
void KoMainWindow::slotLoadCanceled( const TQString & 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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
disconnect(newdoc, TQT_SIGNAL(completed()), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCompleted()));
disconnect(newdoc, TQT_SIGNAL(canceled( const TQString & )), TQT_TQOBJECT(this), TQT_SLOT(slotLoadCanceled( const TQString & )));
newdoc->removeShell(this);
delete newdoc;
}
void KoMainWindow::slotSaveCanceled( const TQString &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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
disconnect(pDoc, TQT_SIGNAL(completed()), TQT_TQOBJECT(this), TQT_SLOT(slotSaveCompleted()));
disconnect(pDoc, TQT_SIGNAL(canceled( const TQString & )),
TQT_TQOBJECT(this), TQT_SLOT(slotSaveCanceled( const TQString & )));
}
// returns true if we should save, false otherwise.
bool KoMainWindow::exportConfirmation( const TQCString &outputFormat )
{
if (!rootDocument()->wantExportConfirmation()) return true;
KMimeType::Ptr mime = KMimeType::mimeType( outputFormat );
const bool neverHeardOfIt = ( mime->name() == KMimeType::defaultMimeType() );
TQString comment = neverHeardOfIt ?
i18n( "%1 (unknown file type)" ).arg( outputFormat.data() )
: 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( TQString( "<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( TQString( "<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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
connect(pDoc, TQT_SIGNAL(completed()), TQT_TQOBJECT(this), TQT_SLOT(slotSaveCompleted()));
connect(pDoc, TQT_SIGNAL(canceled( const TQString & )),
TQT_TQOBJECT(this), TQT_SLOT(slotSaveCanceled( const TQString & )));
KURL oldURL = pDoc->url();
TQString oldFile = pDoc->file();
TQCString _native_format = pDoc->nativeFormatMimeType();
TQCString oldOutputFormat = pDoc->outputMimeType();
int oldSpecialOutputFlag = pDoc->specialOutputFlag();
KURL suggestedURL = pDoc->url();
TQStringList 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 :))
TQString suggestedFilename = suggestedURL.fileName ();
if ( !suggestedFilename.isEmpty () ) // ".kwd" looks strange for a name
{
int c = suggestedFilename.findRev ('.');
KMimeType::Ptr mime = KMimeType::mimeType( _native_format );
TQString ext = mime->property( "X-TDE-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 (),
TQString(), 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;
TQCString outputFormat = _native_format;
int specialOutputFlag = 0;
bool bOk;
do {
bOk=true;
if(dialog->exec()==TQDialog::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 ) {
TQString 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 TQT_TQOBJECT(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(TQCloseEvent *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( TQResizeEvent * 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() )
{
TQString 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),
TQString(),
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, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_SLOT(slotProgress(int)));
disconnect(newdoc, TQT_SIGNAL(sigProgress(int)), TQT_TQOBJECT(this), TQT_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", TQString(), 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 TQStringList mimeFilter = KoFilterManager::mimeFilter( KoDocument::readNativeFormatMimeType(),
KoFilterManager::Import,
KoDocument::readExtraNativeMimeTypes() );
dialog->setMimeFilter( mimeFilter );
if(dialog->exec()!=TQDialog::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 /*, TQPrinter::HighResolution*/ );
TQString title = rootView()->koDocument()->documentInfo()->title();
TQString 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 ) {
TQString extension = mime->property( "X-TDE-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 TQString programName = instance()->aboutData() ? instance()->aboutData()->programName() : instance()->instanceName();
//title = i18n("%1 unsaved document (%2)").arg(programName).arg(KGlobal::locale()->formatDate(TQDate::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 );
TQString oldFileName = printer.outputFileName();
printer.setOutputFileName( tmpFile.name() );
int oldNumCopies = printer.numCopies();
printer.setNumCopies( 1 );
// Disable tdeprint'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.
TQString 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,TQT_SIGNAL(newToolbarConfig()),this,TQT_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( TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name() );
if (bar)
{
if (toggle)
bar->show();
else
bar->hide();
if (rootDocument())
saveMainWindowSettings( KGlobal::config(), rootDocument()->instance()->instanceName() );
}
else
kdWarning(30003) << "slotToolbarToggled : Toolbar " << TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name() << " not found!" << endl;
}
bool KoMainWindow::toolbarIsVisible(const char *tbName)
{
TQWidget *tb = toolBar( tbName);
return !tb->isHidden();
}
void KoMainWindow::showToolbar( const char * tbName, bool shown )
{
TQWidget * 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
TQPtrListIterator<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);
TQPtrListIterator<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
TQObjectList *l = queryList( "TQStatusBar" );
if ( !l || !l->first() ) {
statusBar()->show();
TQApplication::sendPostedEvents( TQT_TQOBJECT(this), TQEvent::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 TQObject.
//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 );
TQApplication::sendEvent( d->m_activePart, &ev );
TQApplication::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( TQT_TQOBJECT(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
//TQPtrListIterator<KToolBar> it = toolBarIterator();
TQPtrList<TQWidget> toolBarList = factory->containers( "ToolBar" );
TQPtrListIterator<TQWidget> 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, TQT_SIGNAL( toggled( bool ) ), TQT_TQOBJECT(this), TQT_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 );
TQApplication::sendEvent( d->m_activePart, &ev );
TQApplication::sendEvent( d->m_activeView, &ev );
}
else
{
d->m_activeView = 0L;
d->m_activePart = 0L;
}
setUpdatesEnabled( true );
}
TQLabel * KoMainWindow::statusBarLabel()
{
if ( !d->statusBarLabel )
{
d->statusBarLabel = new TQLabel( 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.
TQString theSubject;
TQStringList urls;
TQString 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();
TQCString 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(TQString(), TQString(), TQString(), theSubject,
TQString(), //body
TQString(),
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>