|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
|
|
|
|
Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
|
|
|
|
Copyright (C) 2000-2005 David Faure <faure@kde.org>
|
|
|
|
Copyright (C) 2005, 2006 Sven Lüppken <sven@kde.org>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program 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
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; see the file COPYING. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqsplitter.h>
|
|
|
|
#include <tqiconview.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqvbox.h>
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "koshell_shell.h"
|
|
|
|
#include "koshellsettings.h"
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <tdetempfile.h>
|
|
|
|
#include <tdefiledialog.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kkeydialog.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <klibloader.h>
|
|
|
|
#include <tdepopupmenu.h>
|
|
|
|
#include <kservice.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <tderecentdocument.h>
|
|
|
|
#include <tdeparts/partmanager.h>
|
|
|
|
#include <tdeaction.h>
|
|
|
|
#include <tdeversion.h>
|
|
|
|
#include <tdeaboutdata.h>
|
|
|
|
|
|
|
|
#include <KoQueryTrader.h>
|
|
|
|
#include <KoDocumentInfo.h>
|
|
|
|
#include <KoDocument.h>
|
|
|
|
#include <KoView.h>
|
|
|
|
#include <KoPartSelectDia.h>
|
|
|
|
#include <KoFilterManager.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
|
|
|
|
KoShellWindow::KoShellWindow()
|
|
|
|
: KoMainWindow( TDEGlobal::instance() )
|
|
|
|
{
|
|
|
|
m_activePage = m_lstPages.end();
|
|
|
|
|
|
|
|
m_pLayout = new TQSplitter( centralWidget() );
|
|
|
|
|
|
|
|
// Setup the sidebar
|
|
|
|
m_pSidebar = new IconSidePane( m_pLayout );
|
|
|
|
m_pSidebar->setSizePolicy( TQSizePolicy( TQSizePolicy::Maximum,
|
|
|
|
TQSizePolicy::Preferred ) );
|
|
|
|
m_pSidebar->setActionCollection( actionCollection() );
|
|
|
|
m_grpFile = m_pSidebar->insertGroup(i18n("Components"), false, TQT_TQOBJECT(this), TQT_SLOT( slotSidebar_Part(int )));
|
|
|
|
m_grpDocuments = m_pSidebar->insertGroup(i18n("Documents"), true, TQT_TQOBJECT(this), TQT_SLOT(slotSidebar_Document(int)));
|
|
|
|
m_pLayout->setResizeMode(m_pSidebar,TQSplitter::FollowSizeHint);
|
|
|
|
|
|
|
|
// Setup the tabbar
|
|
|
|
m_pFrame = new KTabWidget( m_pLayout );
|
|
|
|
m_pFrame->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum,
|
|
|
|
TQSizePolicy::Preferred ) );
|
|
|
|
m_pFrame->setTabPosition( KTabWidget::Bottom );
|
|
|
|
|
|
|
|
m_tabCloseButton = new TQToolButton( m_pFrame );
|
|
|
|
connect( m_tabCloseButton, TQT_SIGNAL( clicked() ),
|
|
|
|
this, TQT_SLOT( slotFileClose() ) );
|
|
|
|
m_tabCloseButton->setIconSet( SmallIconSet( "tab_remove" ) );
|
|
|
|
m_tabCloseButton->adjustSize();
|
|
|
|
TQToolTip::add(m_tabCloseButton, i18n("Close"));
|
|
|
|
m_pFrame->setCornerWidget( m_tabCloseButton, BottomRight );
|
|
|
|
m_tabCloseButton->hide();
|
|
|
|
|
|
|
|
TQValueList<KoDocumentEntry> lstComponents = KoDocumentEntry::query(false,TQString());
|
|
|
|
TQValueList<KoDocumentEntry>::Iterator it = lstComponents.begin();
|
|
|
|
int id = 0;
|
|
|
|
// Get all available components
|
|
|
|
for( ; it != lstComponents.end(); ++it )
|
|
|
|
{
|
|
|
|
KService* service = (*it).service();
|
|
|
|
if ( !service->genericName().isEmpty() )
|
|
|
|
{
|
|
|
|
id = m_pSidebar->insertItem(m_grpFile, service->icon(), service->genericName());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_mapComponents[ id++ ] = *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQValueList<int> list;
|
|
|
|
list.append( KoShellSettings::sidebarWidth() );
|
|
|
|
list.append( this->width() - KoShellSettings::sidebarWidth() );
|
|
|
|
m_pLayout->setSizes( list );
|
|
|
|
|
|
|
|
connect( this, TQT_SIGNAL( documentSaved() ),
|
|
|
|
this, TQT_SLOT( slotNewDocumentName() ) );
|
|
|
|
|
|
|
|
connect( m_pFrame, TQT_SIGNAL( currentChanged( TQWidget* ) ),
|
|
|
|
this, TQT_SLOT( slotUpdatePart( TQWidget* ) ) );
|
|
|
|
connect( m_pFrame, TQT_SIGNAL( contextMenu(TQWidget * ,const TQPoint &)), this, TQT_SLOT( tab_contextMenu(TQWidget * ,const TQPoint &)) );
|
|
|
|
|
|
|
|
m_client = new KoShellGUIClient( this );
|
|
|
|
createShellGUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
KoShellWindow::~KoShellWindow()
|
|
|
|
{
|
|
|
|
//kdDebug() << "KoShellWindow::~KoShellWindow()" << endl;
|
|
|
|
|
|
|
|
// Set the active part to 0 (as we do in ~KoMainWindow, but this is too
|
|
|
|
// late for KoShell, it gets activePartChanged signals delivered to a dead
|
|
|
|
// KoShellWindow object).
|
|
|
|
partManager()->setActivePart(0);
|
|
|
|
|
|
|
|
// Destroy all documents - queryClose has made sure we saved them first
|
|
|
|
TQValueList<Page>::ConstIterator it = m_lstPages.begin();
|
|
|
|
for (; it != m_lstPages.end(); ++it )
|
|
|
|
{
|
|
|
|
(*it).m_pDoc->removeShell( this );
|
|
|
|
delete (*it).m_pView;
|
|
|
|
if ( (*it).m_pDoc->viewCount() == 0 )
|
|
|
|
delete (*it).m_pDoc;
|
|
|
|
}
|
|
|
|
m_lstPages.clear();
|
|
|
|
|
|
|
|
setRootDocumentDirect( 0L, TQPtrList<KoView>() ); // prevent our parent destructor from doing stupid things
|
|
|
|
saveSettings(); // Now save our settings before exiting
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoShellWindow::openDocumentInternal( const KURL &url, KoDocument* )
|
|
|
|
{
|
|
|
|
// Here we have to distinguish two cases: The passed URL has a native
|
|
|
|
// KOffice mimetype. Then we query the trader and create the document.
|
|
|
|
// The file is loaded and everyone's happy.
|
|
|
|
// The second case is a non-native file. Here we have to create a
|
|
|
|
// filter manager, ask it to convert the file to the "closest" available
|
|
|
|
// KOffice part and open the temporary file.
|
|
|
|
|
|
|
|
/*if (!TDEIO::NetAccess::exists(url,true,0) )
|
|
|
|
{
|
|
|
|
KMessageBox::error(0L, i18n("The file %1 doesn't exist.").arg(url.url()) );
|
|
|
|
recentAction()->removeURL(url); //remove the file from the recent-opened-file-list
|
|
|
|
saveRecentFiles();
|
|
|
|
return false;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
KMimeType::Ptr mimeType = KMimeType::findByURL( url );
|
|
|
|
m_documentEntry = KoDocumentEntry::queryByMimeType( mimeType->name().latin1() );
|
|
|
|
|
|
|
|
KTempFile* tmpFile = 0;
|
|
|
|
KURL tmpUrl( url ); // we might have to load a converted temp. file
|
|
|
|
|
|
|
|
if ( m_documentEntry.isEmpty() ) { // non-native
|
|
|
|
tmpFile = new KTempFile;
|
|
|
|
|
|
|
|
KoFilterManager *manager = new KoFilterManager( url.path() );
|
|
|
|
TQCString mimetype; // an empty mimetype means, that the "nearest"
|
|
|
|
KoFilter::ConversionStatus status = manager->exp0rt( tmpFile->name(), mimetype ); // KOffice part will be chosen
|
|
|
|
delete manager;
|
|
|
|
|
|
|
|
if ( status != KoFilter::OK || mimetype.isEmpty() ) {
|
|
|
|
tmpFile->unlink();
|
|
|
|
delete tmpFile;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the conversion was successful we get the mimetype of the
|
|
|
|
// chosen KOffice part back.
|
|
|
|
m_documentEntry = KoDocumentEntry::queryByMimeType( mimetype );
|
|
|
|
if ( m_documentEntry.isEmpty() ) {
|
|
|
|
tmpFile->unlink();
|
|
|
|
delete tmpFile;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open the temporary file
|
|
|
|
tmpUrl.setPath( tmpFile->name() );
|
|
|
|
}
|
|
|
|
|
|
|
|
recentAction()->addURL( url );
|
|
|
|
|
|
|
|
KoDocument* newdoc = m_documentEntry.createDoc();
|
|
|
|
if ( !newdoc ) {
|
|
|
|
if ( tmpFile ) {
|
|
|
|
tmpFile->unlink();
|
|
|
|
delete tmpFile;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
connect(newdoc, TQT_SIGNAL(sigProgress(int)), this, TQT_SLOT(slotProgress(int)));
|
|
|
|
connect(newdoc, TQT_SIGNAL(completed()), this, TQT_SLOT(slotKSLoadCompleted()));
|
|
|
|
connect(newdoc, TQT_SIGNAL(canceled( const TQString & )), this, TQT_SLOT(slotKSLoadCanceled( const TQString & )));
|
|
|
|
newdoc->addShell( this ); // used by openURL
|
|
|
|
bool openRet = (!isImporting ()) ? newdoc->openURL(tmpUrl) : newdoc->import(tmpUrl);
|
|
|
|
if ( !openRet )
|
|
|
|
{
|
|
|
|
newdoc->removeShell(this);
|
|
|
|
delete newdoc;
|
|
|
|
if ( tmpFile ) {
|
|
|
|
tmpFile->unlink();
|
|
|
|
delete tmpFile;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( tmpFile ) {
|
|
|
|
//if the loaded file has been a temporary file
|
|
|
|
//we need to correct a few document settings
|
|
|
|
//see description of bug #77574 for additional information
|
|
|
|
|
|
|
|
//correct (output) mime type: we need to set it to the non-native format
|
|
|
|
//to make sure the user knows about saving to a non-native mime type
|
|
|
|
//setConfirmNonNativeSave is set to true below
|
|
|
|
newdoc->setMimeType( mimeType->name().latin1() );
|
|
|
|
newdoc->setOutputMimeType( mimeType->name().latin1() );
|
|
|
|
|
|
|
|
//the next time the user saves the document he should be warned
|
|
|
|
//because of mime type settings done above;
|
|
|
|
newdoc->setConfirmNonNativeSave(true,true); //exporting,warn_on
|
|
|
|
newdoc->setConfirmNonNativeSave(false,true); //save/save as,warn_on
|
|
|
|
|
|
|
|
//correct document file (should point to URL)
|
|
|
|
newdoc->setFile( url.path() );
|
|
|
|
|
|
|
|
//correct document URL
|
|
|
|
newdoc->setURL( url );
|
|
|
|
|
|
|
|
//update caption to represent the correct URL in the window titlebar
|
|
|
|
updateCaption();
|
|
|
|
|
|
|
|
tmpFile->unlink();
|
|
|
|
delete tmpFile;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotSidebarItemClicked( TQIconViewItem *item )
|
|
|
|
{
|
|
|
|
//kdDebug() << "slotSidebarItemClicked called!" << endl;
|
|
|
|
if( item != 0 )
|
|
|
|
{
|
|
|
|
int index = item->index();
|
|
|
|
|
|
|
|
// Create new document from a KoDocumentEntry
|
|
|
|
m_documentEntry = m_mapComponents[ index ];
|
|
|
|
KoDocument *doc = m_documentEntry.createDoc();
|
|
|
|
if (doc)
|
|
|
|
{
|
|
|
|
// koshell isn't starting, but this is like starting a new app:
|
|
|
|
// offer both "open existing file" and "open new file".
|
|
|
|
if ( doc->showEmbedInitDialog( this ) )
|
|
|
|
{
|
|
|
|
partManager()->addPart( doc, false );
|
|
|
|
setRootDocument( doc );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
delete doc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Separate from openDocument to handle async loading (remote URLs)
|
|
|
|
void KoShellWindow::slotKSLoadCompleted()
|
|
|
|
{
|
|
|
|
KoDocument* newdoc = (KoDocument *)(sender());
|
|
|
|
|
|
|
|
// KoDocument::import() calls resetURL() too late...
|
|
|
|
// ...setRootDocument will show the URL...
|
|
|
|
// So let's stop this from happening and the user will never know :)
|
|
|
|
if (isImporting()) newdoc->resetURL ();
|
|
|
|
|
|
|
|
partManager()->addPart( newdoc, false );
|
|
|
|
setRootDocument( newdoc );
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(sigProgress(int)), this, TQT_SLOT(slotProgress(int)));
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(completed()), this, TQT_SLOT(slotKSLoadCompleted()));
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(canceled( const TQString & )), this, TQT_SLOT(slotKSLoadCanceled( const TQString & )));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotKSLoadCanceled( const TQString & errMsg )
|
|
|
|
{
|
|
|
|
KMessageBox::error( this, errMsg );
|
|
|
|
// ... can't delete the document, it's the one who emitted the signal...
|
|
|
|
// ###### FIXME: This can be done in 3.0 with deleteLater, I assume (Werner)
|
|
|
|
|
|
|
|
KoDocument* newdoc = (KoDocument *)(sender());
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(sigProgress(int)), this, TQT_SLOT(slotProgress(int)));
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(completed()), this, TQT_SLOT(slotKSLoadCompleted()));
|
|
|
|
disconnect(newdoc, TQT_SIGNAL(canceled( const TQString & )), this, TQT_SLOT(slotKSLoadCanceled( const TQString & )));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::saveAll()
|
|
|
|
{
|
|
|
|
KoView *currentView = (*m_activePage).m_pView;
|
|
|
|
for (TQValueList<Page>::iterator it=m_lstPages.begin(); it != m_lstPages.end(); ++it)
|
|
|
|
{
|
|
|
|
if ( (*it).m_pDoc->isModified() )
|
|
|
|
{
|
|
|
|
m_pFrame->showPage( (*it).m_pView );
|
|
|
|
(*it).m_pView->shell()->slotFileSave();
|
|
|
|
if ( (*it).m_pDoc->isModified() )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_pFrame->showPage( currentView );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::setRootDocument( KoDocument * doc )
|
|
|
|
{
|
|
|
|
kdDebug() << "KoShellWindow::setRootDocument this=" << this << " doc=" << doc << endl;
|
|
|
|
// We do things quite differently from KoMainWindow::setRootDocument
|
|
|
|
// This one is called with doc != 0 when a new doc is created
|
|
|
|
// and with 0L after they have all been removed.
|
|
|
|
// We use setRootDocumentDirect to switch the 'root doc' known by KoMainWindow.
|
|
|
|
|
|
|
|
if ( doc )
|
|
|
|
{
|
|
|
|
if ( !doc->shells().contains( this ) )
|
|
|
|
doc->addShell( this );
|
|
|
|
|
|
|
|
KoView *v = doc->createView(this);
|
|
|
|
TQPtrList<KoView> views;
|
|
|
|
views.append(v);
|
|
|
|
setRootDocumentDirect( doc, views );
|
|
|
|
|
|
|
|
v->setGeometry( 0, 0, m_pFrame->width(), m_pFrame->height() );
|
|
|
|
v->setPartManager( partManager() );
|
|
|
|
m_pFrame->addTab( v, TDEGlobal::iconLoader()->loadIcon( m_documentEntry.service()->icon(), TDEIcon::Small ), i18n("Untitled") );
|
|
|
|
|
|
|
|
// Create a new page for this doc
|
|
|
|
Page page;
|
|
|
|
page.m_pDoc = doc;
|
|
|
|
page.m_pView = v;
|
|
|
|
// insert the new document in the sidebar
|
|
|
|
page.m_id = m_pSidebar->insertItem( m_grpDocuments,
|
|
|
|
m_documentEntry.service()->icon(),
|
|
|
|
i18n("Untitled"));
|
|
|
|
m_lstPages.append( page );
|
|
|
|
v->show();
|
|
|
|
|
|
|
|
switchToPage( m_lstPages.fromLast() );
|
|
|
|
mnuSaveAll->setEnabled(true);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
setRootDocumentDirect( 0L, TQPtrList<KoView>() );
|
|
|
|
m_activePage = m_lstPages.end();
|
|
|
|
KoMainWindow::updateCaption();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotNewDocumentName()
|
|
|
|
{
|
|
|
|
updateCaption();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::updateCaption()
|
|
|
|
{
|
|
|
|
//kdDebug() << "KoShellWindow::updateCaption() rootDoc=" << rootDocument() << endl;
|
|
|
|
KoMainWindow::updateCaption();
|
|
|
|
// Let's take this opportunity for setting a correct name for the icon
|
|
|
|
// in koolbar
|
|
|
|
TQValueList<Page>::Iterator it = m_lstPages.begin();
|
|
|
|
for( ; it != m_lstPages.end() ; ++it )
|
|
|
|
{
|
|
|
|
if ( (*it).m_pDoc == rootDocument() )
|
|
|
|
{
|
|
|
|
//kdDebug() << "updateCaption called for " << rootDocument() << endl;
|
|
|
|
// Get caption from document info (title(), in about page)
|
|
|
|
TQString name;
|
|
|
|
if ( rootDocument()->documentInfo() )
|
|
|
|
{
|
|
|
|
name = rootDocument()->documentInfo()->title();
|
|
|
|
}
|
|
|
|
if ( name.isEmpty() )
|
|
|
|
// Fall back to document URL
|
|
|
|
name = rootDocument()->url().fileName();
|
|
|
|
|
|
|
|
if ( !name.isEmpty() ) // else keep Untitled
|
|
|
|
{
|
|
|
|
if ( name.length() > 20 )
|
|
|
|
{
|
|
|
|
name.truncate( 17 );
|
|
|
|
name += "...";
|
|
|
|
}
|
|
|
|
m_pFrame->changeTab( m_pFrame->currentPage(), name );
|
|
|
|
m_pSidebar->renameItem(m_grpDocuments, (*m_activePage).m_id, name); //remove the document from the sidebar
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KoShellWindow::slotSidebar_Part(int _item)
|
|
|
|
{
|
|
|
|
//kdDebug() << "Component part choosed:" << _item << endl;
|
|
|
|
kapp->setOverrideCursor( TQCursor(TQt::WaitCursor) );
|
|
|
|
m_documentEntry = m_mapComponents[ _item ];
|
|
|
|
kdDebug() << m_documentEntry.service() << endl;
|
|
|
|
kdDebug() << m_documentEntry.name() << endl;
|
|
|
|
KoDocument *doc = m_documentEntry.createDoc();
|
|
|
|
kapp->restoreOverrideCursor();
|
|
|
|
if (doc)
|
|
|
|
{
|
|
|
|
if ( doc->showEmbedInitDialog( this ) )
|
|
|
|
{
|
|
|
|
partManager()->addPart( doc, false );
|
|
|
|
setRootDocument( doc );
|
|
|
|
m_tabCloseButton->show();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
delete doc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotSidebar_Document(int _item)
|
|
|
|
{
|
|
|
|
// Switch to an existing document
|
|
|
|
if ( m_activePage != m_lstPages.end() &&
|
|
|
|
(*m_activePage).m_id == _item )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQValueList<Page>::Iterator it = m_lstPages.begin();
|
|
|
|
while( it != m_lstPages.end() )
|
|
|
|
{
|
|
|
|
if ( (*it).m_id == _item )
|
|
|
|
{
|
|
|
|
switchToPage( it );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotShowSidebar()
|
|
|
|
{
|
|
|
|
if( m_pSidebar->isShown() )
|
|
|
|
{
|
|
|
|
m_pSidebar->hide();
|
|
|
|
m_pComponentsLabel->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pSidebar->show();
|
|
|
|
m_pComponentsLabel->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotUpdatePart( TQWidget* widget )
|
|
|
|
{
|
|
|
|
KoView* v = dynamic_cast<KoView*>(widget);
|
|
|
|
if ( v != 0 )
|
|
|
|
{
|
|
|
|
TQValueList<Page>::Iterator it = m_lstPages.begin();
|
|
|
|
for( ; it != m_lstPages.end(); ++it )
|
|
|
|
{
|
|
|
|
if( (*it).m_pView == v )
|
|
|
|
switchToPage(it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::switchToPage( TQValueList<Page>::Iterator it )
|
|
|
|
{
|
|
|
|
// Select new active page (view)
|
|
|
|
m_activePage = it;
|
|
|
|
KoView *v = (*m_activePage).m_pView;
|
|
|
|
|
|
|
|
kdDebug() << " setting active part to " << (*m_activePage).m_pDoc << endl;
|
|
|
|
// Make it active (GUI etc.)
|
|
|
|
partManager()->setActivePart( (*m_activePage).m_pDoc, v );
|
|
|
|
// Change current document
|
|
|
|
TQPtrList<KoView> views;
|
|
|
|
views.append(v);
|
|
|
|
setRootDocumentDirect( (*m_activePage).m_pDoc, views );
|
|
|
|
// Select the item in the sidebar
|
|
|
|
m_pSidebar->group(m_grpDocuments)->setSelected((*m_activePage).m_id,true);
|
|
|
|
// Raise the new page
|
|
|
|
m_pFrame->showPage( v );
|
|
|
|
// Fix caption and set focus to the new view
|
|
|
|
updateCaption();
|
|
|
|
v->setFocus();
|
|
|
|
|
|
|
|
partSpecificHelpAction->setEnabled(true);
|
|
|
|
partSpecificHelpAction->setText(i18n("%1 Handbook").arg((*m_activePage).m_pDoc->instance()->aboutData()->programName()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotFileNew()
|
|
|
|
{
|
|
|
|
m_documentEntry = KoPartSelectDia::selectPart( this );
|
|
|
|
if ( m_documentEntry.isEmpty() )
|
|
|
|
return;
|
|
|
|
KoDocument* newdoc = m_documentEntry.createDoc();
|
|
|
|
if ( !newdoc )
|
|
|
|
return;
|
|
|
|
if ( !newdoc->showEmbedInitDialog( this ) )
|
|
|
|
{
|
|
|
|
delete newdoc;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
partManager()->addPart( newdoc, false );
|
|
|
|
setRootDocument( newdoc );
|
|
|
|
m_tabCloseButton->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotFileOpen()
|
|
|
|
{
|
|
|
|
KFileDialog *dialog=new KFileDialog(TQString(), TQString(), 0L, "file dialog", true);
|
|
|
|
if (!isImporting())
|
|
|
|
dialog->setCaption( i18n("Open Document") );
|
|
|
|
else
|
|
|
|
dialog->setCaption( i18n("Import Document") );
|
|
|
|
dialog->setMimeFilter( KoFilterManager::mimeFilter() );
|
|
|
|
|
|
|
|
KURL url;
|
|
|
|
if(dialog->exec()==TQDialog::Accepted) {
|
|
|
|
url=dialog->selectedURL();
|
|
|
|
recentAction()->addURL( url );
|
|
|
|
if ( url.isLocalFile() )
|
|
|
|
TDERecentDocument::add(url.path(-1));
|
|
|
|
else
|
|
|
|
TDERecentDocument::add(url.url(-1), true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete dialog;
|
|
|
|
if ( url.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
(void) openDocumentInternal( url );
|
|
|
|
m_tabCloseButton->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotFileClose()
|
|
|
|
{
|
|
|
|
// reimplemented to avoid closing the window when we have docs opened
|
|
|
|
|
|
|
|
// No docs at all ?
|
|
|
|
if ( m_lstPages.count() == 0 )
|
|
|
|
close(); // close window
|
|
|
|
else
|
|
|
|
closeDocument(); // close only doc
|
|
|
|
|
|
|
|
if ( m_pFrame->count() == 0 )
|
|
|
|
m_tabCloseButton->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::closeDocument()
|
|
|
|
{
|
|
|
|
// Set the root document to the current one - so that queryClose acts on it
|
|
|
|
assert( m_activePage != m_lstPages.end() );
|
|
|
|
assert( rootDocument() == (*m_activePage).m_pDoc );
|
|
|
|
|
|
|
|
// First do the standard queryClose
|
|
|
|
kdDebug() << "KoShellWindow::closeDocument calling standard queryClose" << endl;
|
|
|
|
if ( KoMainWindow::queryClose() )
|
|
|
|
{
|
|
|
|
kdDebug() << "Ok for closing document" << endl;
|
|
|
|
m_pSidebar->removeItem(m_grpDocuments, (*m_activePage).m_id ); //remove the document from the sidebar
|
|
|
|
(*m_activePage).m_pDoc->removeShell(this);
|
|
|
|
Page oldPage = (*m_activePage); // make a copy of the struct
|
|
|
|
m_lstPages.remove( m_activePage );
|
|
|
|
m_activePage = m_lstPages.end(); // no active page right now
|
|
|
|
m_pSidebar->group(m_grpDocuments)->setSelected((*m_activePage).m_id, true); //select the new document in the sidebar
|
|
|
|
|
|
|
|
kdDebug() << "m_lstPages has " << m_lstPages.count() << " documents" << endl;
|
|
|
|
if ( m_lstPages.count() > 0 )
|
|
|
|
{
|
|
|
|
kdDebug() << "Activate the document behind" << endl;
|
|
|
|
switchToPage( m_lstPages.fromLast() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdDebug() << "Revert to initial state (no docs)" << endl;
|
|
|
|
setRootDocument( 0L );
|
|
|
|
partManager()->setActivePart( 0L, 0L );
|
|
|
|
mnuSaveAll->setEnabled(false);
|
|
|
|
partSpecificHelpAction->setEnabled(false);
|
|
|
|
partSpecificHelpAction->setText(i18n("Part Handbook"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now delete the old view and page
|
|
|
|
// Don't do it before, because setActivePart will call slotActivePartChanged,
|
|
|
|
// which needs the old view (to unplug it and its plugins)
|
|
|
|
delete oldPage.m_pView;
|
|
|
|
if ( oldPage.m_pDoc->viewCount() <= 1 )
|
|
|
|
delete oldPage.m_pDoc;
|
|
|
|
|
|
|
|
}
|
|
|
|
kdDebug() << "m_lstPages has " << m_lstPages.count() << " documents" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoShellWindow::queryClose()
|
|
|
|
{
|
|
|
|
// Save current doc and views
|
|
|
|
TQPtrList<KoView> currentViews;
|
|
|
|
KoDocument * currentDoc = 0L;
|
|
|
|
bool ok = true;
|
|
|
|
if (m_activePage != m_lstPages.end())
|
|
|
|
{
|
|
|
|
currentDoc = (*m_activePage).m_pDoc;
|
|
|
|
currentViews.append((*m_activePage).m_pView);
|
|
|
|
|
|
|
|
// This one is called by slotFileQuit and by the X button.
|
|
|
|
// We have to check for unsaved docs...
|
|
|
|
TQValueList<Page>::Iterator it = m_lstPages.begin();
|
|
|
|
for( ; it != m_lstPages.end(); ++it )
|
|
|
|
{
|
|
|
|
// This is quite a HACK
|
|
|
|
// We should ask ourselves, to get a better dialog box
|
|
|
|
setRootDocumentDirect( (*it).m_pDoc, TQPtrList<KoView>() );
|
|
|
|
// Test if we can close this doc
|
|
|
|
if ( !KoMainWindow::queryClose() )
|
|
|
|
{
|
|
|
|
ok = false; // No
|
|
|
|
break; // abort
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Restore current doc and views
|
|
|
|
setRootDocumentDirect( currentDoc, currentViews );
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Should this be an additional action in the File menu ?
|
|
|
|
bool KoShellWindow::saveAllPages()
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
void KoShellWindow::saveSettings()
|
|
|
|
{
|
|
|
|
KoShellSettings::setSidebarWidth( m_pLayout->sizes().first() );
|
|
|
|
KoShellSettings::writeConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KoShellWindow::configFile() const
|
|
|
|
{
|
|
|
|
//return readConfigFile( locate( "data", "koshell/koshell_shell.rc" ) );
|
|
|
|
return TQString(); // use UI standards only for now
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::tab_contextMenu(TQWidget * w,const TQPoint &p)
|
|
|
|
{
|
|
|
|
TDEPopupMenu menu;
|
|
|
|
TDEIconLoader il;
|
Bring filenew, fileopen, fileprint, filequickprint, filesave, filesaveas, fileclose, editclear, editcopy, editcut, editdelete, editpaste, folder_new, and gohome icons into XDG compliance
10 years ago
|
|
|
int const mnuSave = menu.insertItem( il.loadIconSet( "document-save", TDEIcon::Small ), i18n("Save") );
|
|
|
|
int const mnuClose = menu.insertItem( il.loadIcon( "window-close", TDEIcon::Small ), i18n("Close") );
|
|
|
|
|
|
|
|
int tabnr = m_pFrame->indexOf( w );
|
|
|
|
Page page = m_lstPages[tabnr];
|
|
|
|
// disable save if there's nothing to save
|
|
|
|
if ( !page.m_pDoc->isModified() )
|
|
|
|
menu.setItemEnabled( mnuSave, false );
|
|
|
|
|
|
|
|
// show menu
|
|
|
|
int const choice = menu.exec(p);
|
|
|
|
|
|
|
|
if( choice == mnuClose )
|
|
|
|
{
|
|
|
|
const int index = m_pFrame->currentPageIndex();
|
|
|
|
m_pFrame->setCurrentPage( tabnr );
|
|
|
|
slotFileClose();
|
|
|
|
if ( index > m_pFrame->currentPageIndex() )
|
|
|
|
m_pFrame->setCurrentPage(index-1);
|
|
|
|
else
|
|
|
|
m_pFrame->setCurrentPage(index);
|
|
|
|
}
|
|
|
|
else if ( choice == mnuSave )
|
|
|
|
{
|
|
|
|
page.m_pView->shell()->slotFileSave();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::slotConfigureKeys()
|
|
|
|
{
|
|
|
|
KoView *view = rootView();
|
|
|
|
KKeyDialog dlg( this );
|
|
|
|
dlg.insert( actionCollection() );
|
|
|
|
if ( view )
|
|
|
|
dlg.insert( view->actionCollection() );
|
|
|
|
if ( rootDocument() )
|
|
|
|
dlg.insert( rootDocument()->actionCollection() );
|
|
|
|
dlg.configure();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::createShellGUI( bool )
|
|
|
|
{
|
|
|
|
guiFactory()->addClient( m_client );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoShellWindow::showPartSpecificHelp()
|
|
|
|
{
|
|
|
|
if((m_activePage == m_lstPages.end()) || ((*m_activePage).m_pDoc == 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
kapp->invokeHelp("", (*m_activePage).m_pDoc->instance()->aboutData()->appName(), "");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////
|
|
|
|
KoShellGUIClient::KoShellGUIClient( KoShellWindow *window ) : KXMLGUIClient()
|
|
|
|
{
|
|
|
|
setXMLFile( "koshellui.rc", true, true );
|
|
|
|
window->mnuSaveAll = new TDEAction( i18n("Save All"), 0, TQT_TQOBJECT(window), TQT_SLOT( saveAll() ), actionCollection(), "save_all" );
|
|
|
|
window->mnuSaveAll->setEnabled(false);
|
|
|
|
window->partSpecificHelpAction = new TDEAction(i18n("Part Handbook"), "contents", 0, TQT_TQOBJECT(window), TQT_SLOT(showPartSpecificHelp()),
|
|
|
|
actionCollection(), "partSpecificHelp");
|
|
|
|
window->partSpecificHelpAction->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "koshell_shell.moc"
|