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.
kxmleditor/kxmleditor/kxmleditorshell.cpp

498 lines
14 KiB

/***************************************************************************
kxmleditorshell.cpp - description
-------------------
begin : Thu Oct 18 2001
copyright : (C) 2001, 2002, 2003 by The KXMLEditor Team
email : lvanek@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/**
@file
*/
#include "kxmleditorshell.h"
#include "kxeshellmanager.h"
#include "../part/kxmleditorpart.h"
#include "../part/kxedocument.h"
#include <klibloader.h>
#include <kstdaction.h>
#include <tdeapplication.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdefiledialog.h>
#include <kkeydialog.h>
#include <kedittoolbar.h>
#include <kstatusbar.h>
#include <tdeparts/browserextension.h>
#include <tdeparts/partmanager.h>
#include <tdemessagebox.h>
#include <tdepopupmenu.h>
#include <tqevent.h>
#include "dcopiface_shell.h"
KXEShellManager *KXMLEditorShell::s_manager=0L;
KXMLEditorShell::KXMLEditorShell( const char * name, WFlags f )
: KParts::MainWindow( name, f ),
m_pPart(0),
m_pKXEShellIface(0)
{
//////////////////////////////
// CREATE ACTIONS
//////////////////////////////
setXMLFile("kxmleditorshell.rc");
KStdAction::openNew( this,SLOT(slotActFileNew()),actionCollection() );
KStdAction::open( this, SLOT(slotFileOpen()), actionCollection() );
m_pActFileOpenRecent = KStdAction::openRecent( this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection() );
m_pActFileOpenRecent->loadEntries( instance()->config() );
m_pActReload = new TDEAction( i18n("Reloa&d"), "reload", Key_F5, this, SLOT(slotFileReload()), actionCollection(), "reload" );
TDEToggleAction * pActToggleMainToolBar = KStdAction::showToolbar( this, SLOT(slotToggleMainToolBar()), actionCollection() );
TDEToggleAction * pActToggleStatusBar = KStdAction::showStatusbar( this, SLOT(slotToggleStatusBar()), actionCollection() );
KStdAction::keyBindings( this, SLOT(slotConfigureKeys()), actionCollection() );
KStdAction::configureToolbars( this, SLOT(slotConfigureToolbars()), actionCollection() );
KStdAction::mail( this, SLOT(mail()), actionCollection() );
KStdAction::close( this, SLOT(slotActClose()), actionCollection() );
KStdAction::quit( this, SLOT(close()), actionCollection());
// L.V. moved to part pActPrint = KStdAction::print( 0, 0, actionCollection(), "print" );
pActCloseW = new TDEAction( i18n("&Close"), 0, 0, this,SLOT(slotActWindowClose()), actionCollection(), "window_close" );
pActCloseAllW = new TDEAction( i18n("Close &all"), 0, 0, this,SLOT(slotActWindowCloseAll()), actionCollection(), "window_close_all" );
pActCloseAllO = new TDEAction( i18n("Close all &others"), 0, 0, this,SLOT(slotActWindowCloseAllOthers()), actionCollection(), "window_close_all_others" );
//////////////////////////////
// CREATE STATUSBAR
//////////////////////////////
statusBar()->message( i18n("Ready.") );
//////////////////////////////
// MISC. INITIALIZATION
//////////////////////////////
manager()->addShell(this);
setAutoSaveSettings();
pActToggleMainToolBar->setChecked( ! toolBar()->isHidden() );
pActToggleStatusBar->setChecked( ! statusBar()->isHidden() );
m_pKXEShellIface = new KXMLEditorShellIface(*this);
statusBar()->setSizeGripEnabled(true);
setPart(0L); // start empty
}
KXMLEditorShell::~KXMLEditorShell()
{
if (m_pKXEShellIface)
delete m_pKXEShellIface;
manager()->removeShell(this);
}
/////////////////////////////////////////////////////////////////////
// ACTION SLOTS
/////////////////////////////////////////////////////////////////////
void KXMLEditorShell::slotFileOpen()
{
statusBar()->message( i18n("Opening file...") );
KURL url = KFileDialog::getOpenURL( TQString::null,
i18n(FILE_DIALOG_FILTER),
this );
openURL(url);
// L.V.: tried to meve save functionality to Part
//m_pActFileSave->setEnabled(true); // TODO: L.V. Why File Save ? Why not Save as... ?
statusBar()->message( i18n("Ready.") );
}
void KXMLEditorShell::slotFileOpenRecent(const KURL & url)
{
statusBar()->message( i18n("Opening file...") );
openURL(url);
statusBar()->message( i18n("Ready.") );
}
void KXMLEditorShell::slotFileReload()
{
statusBar()->message( i18n("Reloading file...") );
// Try to (re)open the file.
// In case the file is modified, a Save/Discard/Cancel message box pops up.
if ( part() && ! part()->url().isEmpty() )
part()->openURL( part()->url() );
statusBar()->message( i18n("Ready.") );
}
void KXMLEditorShell::slotToggleMainToolBar()
{
statusBar()->message( i18n("Toggle the toolbar...") );
if( toolBar()->isHidden() )
toolBar()->show();
else
toolBar()->hide();
statusBar()->message( i18n("Ready.") );
}
void KXMLEditorShell::slotToggleStatusBar()
{
statusBar()->message( i18n("Toggle the statusbar...") );
if( statusBar()->isHidden() )
statusBar()->show();
else
statusBar()->hide();
statusBar()->message( i18n("Ready.") );
}
void KXMLEditorShell::slotConfigureKeys()
{
KKeyDialog dlg;
dlg.insert(part()->actionCollection());
dlg.insert(actionCollection());
dlg.configure();
}
void KXMLEditorShell::slotConfigureToolbars()
{
KEditToolbar dlg( factory() );
if ( dlg.exec() )
createGUI( part() );
}
/////////////////////////////////////////////////////////////////////
// ADDITIONAL FUNCTIONS
/////////////////////////////////////////////////////////////////////
bool KXMLEditorShell::openURL( const KURL & url )
{
if ( url.isEmpty() )
return false;
// About this function, the style guide (
// http://developer.kde.org/documentation/standards/kde/style/basics/index.html )
// says that it should open a new window if the document is _not_
// in its initial state. This is what we do here.
// If there is no part yet created, create new one...
if (!part())
{
setPart(createXMLPart(this));
}
// We have to differenciate, if this shell could
// be used or a new one has to be created.
if ( part()->url().isEmpty() && ! part()->isModified() )
{
// this one can be used - try to open the file in it
if ( ! part()->openURL(url) )
return false;
}
else
{
// a new one has to be created
KXMLEditorShell * pShell = new KXMLEditorShell;
// and a new part too...
pShell->setPart(createXMLPart(pShell));
// try to open the file in the shell
if ( ! pShell->part()->openURL(url) )
return false;
// show the new shell
pShell->show();
}
// on success, the URL could be added to our list of recent files
m_pActFileOpenRecent->addURL(url);
return true;
}
bool KXMLEditorShell::queryClose()
{
if ( part() && ! part()->closeURL() )
return false;
m_pActFileOpenRecent->saveEntries( instance()->config() );
return KParts::MainWindow::queryClose();
}
void KXMLEditorShell::saveProperties( TDEConfig * pConfig )
{
if (part())
{
pConfig->writeEntry( "CurrentURL", part()->url().url() );
}
KParts::MainWindow::saveProperties(pConfig);
}
void KXMLEditorShell::readProperties( TDEConfig * pConfig )
{
KParts::MainWindow::readProperties(pConfig);
/// @todo Check if ths is a deadcode
// TQString strURL = pConfig->readEntry( "CurrentURL", "" );
// if ( strURL.isEmpty())
// part()->openURL( strURL );
}
void KXMLEditorShell::slotEnableBrowserExtActions( const char * pszName, bool bEnabled )
{
TDEAction * pAct = actionCollection()->action( pszName );
if ( pAct )
pAct->setEnabled( bEnabled );
else
kdDebug() << "KXMLEditor " << k_funcinfo << " unknown action (" << pszName << ")" << endl;
}
// Set main window caption (by using the base class functionality),
// Enables/disables Save button (corresponding to the parts modified status)
void KXMLEditorShell::setCaption( const TQString & strCaption )
{
if (part())
{
KParts::MainWindow::setCaption( strCaption, part()->isModified() ); // base class functionality
}
}
//
// Called when creating new file is requested.
//
void KXMLEditorShell::slotActFileNew()
{
// About this function, the style guide (
// http://developer.kde.org/documentation/standards/kde/style/basics/index.html )
// says that it should open a new window if the document is _not_
// in its initial state. This is what we do here..
KXMLEditorShell * pShell;
KParts::ReadWritePart* pPart;
// 1. This shell is empty
if (!part())
{
pPart = createXMLPart(this);
pShell=this;
}
// 2. The shell contains modified part
else if (! part()->url().isEmpty() || part()->isModified() )
{
pShell = new KXMLEditorShell;
pPart = createXMLPart(pShell);
pShell->show();
}
// 3. The shell contains part, and it is empty and not modified
else
{
pPart=part();
pShell=this;
}
pShell->setPart(pPart);
// if there is a way to determine in KXMLEditorPart that it was created "for new file" then
// this part should be changed.
((KXMLEditorPart *)pPart)->document()->newFile();
}
void KXMLEditorShell::mail()
{
// L.V.: tried to meve save functionality to Part
//slotFileSave();
// first - our XML file have to be saved.
part()->save();
if (!part()->url().isEmpty())
{
TQStringList urls(part()->url().url()); // we can prepare then list of attachments (1 element in the list)
TQString theSubject(part()->url().fileName(false)); // and set the mail subject
kapp->invokeMailer(TQString::null, // finally we can compose e-mail (addressed to no-one) out of that
TQString::null,
TQString::null,
theSubject, // subject
TQString::null, // body
TQString::null,
urls); // attachments
}
}
void KXMLEditorShell::setPart(KParts::ReadWritePart* pPart)
{
if (pPart==m_pPart)
return; // nothing to do here...
else
{
if(pPart)
{
connect(static_cast <KXMLEditorPart *> (pPart), SIGNAL(sigAddRecentURL(const KURL &)),
this, SLOT(slotAddRecentURL(const KURL &)) );
}
}
if (m_pPart)
{
factory()->removeClient(m_pPart);
delete m_pPart;
}
m_pPart = pPart;
if (pPart)
{
// get the parts browser extension and connect additional actions to it
KParts::BrowserExtension * pBrowserExt = 0;
if ( (pBrowserExt = KParts::BrowserExtension::childObject(pPart)) ) // if there is one
{
connect( pBrowserExt, SIGNAL(enableAction( const char *, bool )), this, SLOT(slotEnableBrowserExtActions( const char *, bool )) );
// L.V. moved to part. connect(pActPrint,SIGNAL(activated()),pBrowserExt, SLOT(print()));
//pActPrint->setEnabled(pBrowserExt->isActionEnabled("print"));
}
createGUI(pPart);
setCentralWidget(pPart->widget() );
pPart->widget()->show();
stateChanged("part");
}
else
{
createGUI(0L);
setCentralWidget(0L);
stateChanged("empty");
}
// keep pointer to window menu
m_windowMenu = static_cast<TDEPopupMenu*>(factory()->container("window", this));
if(!m_windowMenu)
kdDebug() << "KXMLEditorShell::setPart - m_windowMenu is NULL" << endl;
else
connect(m_windowMenu,SIGNAL(aboutToShow()),this,SLOT(slotBeforeWindowMenuShown()));
}
KParts::ReadWritePart* KXMLEditorShell::createXMLPart(TQObject *parent)
{
return createPart(parent,"libkxmleditorpart", "KParts::ReadWritePart");
}
KParts::ReadWritePart* KXMLEditorShell::createPart(TQObject *parent, const TQString& libName, const TQString& className)
{
KParts::ReadWritePart* newPart = 0L;
KLibFactory * pFactory = KLibLoader::self()->factory(libName.local8Bit());
if (pFactory)
newPart = static_cast <KParts::ReadWritePart*> ( pFactory->create( parent, "KXMLEditor view", className.utf8() ) );
else
kdFatal() << "KXMLEditorShell::KXMLEditorShell no " << libName << " found" << endl;
return newPart;
}
void KXMLEditorShell::slotActClose()
{
if (part() && part()->queryClose())
setPart(0L);
}
void KXMLEditorShell::close()
{
if (queryClose())
{
if (TDEMainWindow::memberList->count()==1)
kapp->deref();
delete this;
}
}
void KXMLEditorShell::slotActWindowCloseAllOthers()
{
TQPtrListIterator<TDEMainWindow> it(*TDEMainWindow::memberList);
for (it.toFirst();it.current();++it)
{
if (it.current()!=this)
it.current()->close();
}
}
void KXMLEditorShell::slotActWindowClose()
{
this->close();
}
void KXMLEditorShell::slotActWindowCloseAll()
{
slotActWindowCloseAllOthers();
slotActWindowClose();
}
KXEShellManager* KXMLEditorShell::manager()
{
if (!s_manager)
{
s_manager = new KXEShellManager();
}
return s_manager;
}
void KXMLEditorShell::slotBeforeWindowMenuShown()
{
// first we have to clean all shell items...
m_windowMenu->clear();
// then we plug-in neccessary actions...
pActCloseW->plug(m_windowMenu);
pActCloseAllW->plug(m_windowMenu);
pActCloseAllO->plug(m_windowMenu);
m_windowMenu->insertSeparator();
// and then we can add entries for all shells
// that are registered in Shell Manager...
TQPtrListIterator<KXMLEditorShell> it (*(manager()->shells()));
for (it.toFirst(); it.current();++it)
{
int id = m_windowMenu->insertItem(it.current()->caption(),it.current(),SLOT(slotActivate()));
m_windowMenu->setItemChecked(id,it.current()==this);
}
}
void KXMLEditorShell::slotActivate()
{
/// @todo windows have to be activated over EWMH
showNormal(); // show it if it's minimized
raise(); // bring that to front
}
// Add URL to recent file list
void KXMLEditorShell::slotAddRecentURL(const KURL &url)
{
m_pActFileOpenRecent->addURL(url);
}
#include "kxmleditorshell.moc"