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.
tdevelop/src/multibuffer.cpp

302 lines
7.8 KiB

/*
* KDevelop Multiple Buffer Support
*
* Copyright (c) 2005 Adam Treat <treat@kde.org>
*
* This program 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 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; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// Ewww... need this to access KParts::Part::setWidget(), so that tdevelop
// doesn't need to be rearchitected for multiple views before the lazy view
// creation can go in
#define protected public
#include <tdeparts/part.h>
#undef protected
#include "multibuffer.h"
#include "api.h"
#include "toplevel.h"
#include "editorproxy.h"
#include "partcontroller.h"
#include "kdevlanguagesupport.h"
#include <kdebug.h>
#include <kmimetype.h>
#include <tdemainwindow.h>
#include <tdeapplication.h>
#include <tdeparts/factory.h>
#include <tdetexteditor/view.h>
#include <tdetexteditor/document.h>
#include <tdetexteditor/viewcursorinterface.h>
MultiBuffer::MultiBuffer( TQWidget *parent )
: TQSplitter( parent, "MultiBuffer" ),
m_editorFactory( 0 ),
m_delayActivate( false ),
m_activated( false ),
m_activeBuffer( 0 )
{
EditorProxy::getInstance() ->registerEditor( this );
if ( KDevLanguageSupport *lang =
API::getInstance() ->languageSupport() )
{
setOrientation( lang->splitOrientation() );
connect( lang, TQ_SIGNAL( splitOrientationChanged( TQt::Orientation ) ),
this, TQ_SLOT( setOrientation( TQt::Orientation ) ) );
}
else
{
setOrientation( TQt::Vertical );
}
}
MultiBuffer::~MultiBuffer()
{
EditorProxy::getInstance() ->deregisterEditor( this );
}
KParts::Part *MultiBuffer::activeBuffer( ) const
{
if ( m_activeBuffer )
return m_activeBuffer;
// The active buffer might just been deleted...
else if ( m_buffers.begin().data() )
return ( m_buffers.begin().data() );
else
return 0;
}
bool MultiBuffer::hasURL( const KURL &url ) const
{
return m_buffers.contains( url );
}
int MultiBuffer::numberOfBuffers() const
{
return m_buffers.count();
}
bool MultiBuffer::isActivated() const
{
if ( m_delayActivate )
return m_activated;
else
return true;
}
void MultiBuffer::setDelayedActivation( bool delayed )
{
m_delayActivate = delayed;
if ( delayed )
m_activated = false;
}
KParts::Part* MultiBuffer::openURL( const KURL &url )
{
KParts::ReadOnlyPart * part =
dynamic_cast<KParts::ReadOnlyPart*>( createPart( url ) );
if ( !part )
return 0;
if ( !part->openURL( url ) )
return 0;
m_buffers.insert( url, part );
return part;
}
bool MultiBuffer::closeURL( const KURL &url )
{
if ( !m_buffers.contains( url ) )
return false;
bool result = false;
KParts::ReadOnlyPart * part =
dynamic_cast<KParts::ReadOnlyPart *>( m_buffers[ url ] );
if ( part )
if (part->closeURL())
{
m_buffers.remove( url );
return true;
}
return false;
}
void MultiBuffer::registerURL( const KURL &url, KParts::Part *part )
{
m_buffers.insert( url, part );
}
void MultiBuffer::registerDelayedActivation( KParts::Part *part,
int line, int col )
{
m_delayedActivation[ part ] = qMakePair( line, col );
}
KParts::Part* MultiBuffer::createPart( const TQString &mimeType,
const TQString &partType,
const TQString &className,
const TQString &preferredName )
{
m_editorFactory = PartController::getInstance() ->findPartFactory(
mimeType, partType, preferredName );
if ( !className.isEmpty() && m_editorFactory )
{
return m_editorFactory->createPart(
this, 0, 0, 0, className.latin1() );
}
return 0;
}
KParts::Part* MultiBuffer::createPart( const KURL &url )
{
if ( !url.isValid() )
return 0;
KMimeType::Ptr mimeType = KMimeType::findByURL( url );
TQString className;
TQString services[] = { "KParts/ReadWritePart", "KParts/ReadOnlyPart" };
TQString classnames[] = { "KParts::ReadWritePart", "KParts::ReadOnlyPart" };
for ( uint i = 0; i < 2; ++i )
{
m_editorFactory = PartController::getInstance() ->findPartFactory(
mimeType->name(), services[ i ] );
if ( m_editorFactory )
{
className = classnames[ i ];
break;
}
}
if ( !className.isEmpty() && m_editorFactory )
{
return m_editorFactory->createPart(
this, 0, 0, 0, className.latin1() );
}
return 0;
}
void MultiBuffer::show()
{
if ( !m_delayedActivation.count() || m_activated )
{
TQSplitter::show();
return ;
}
ActivationMap::Iterator it = m_delayedActivation.begin();
for ( ; it != m_delayedActivation.end(); ++it )
{
KTextEditor::Document *document =
dynamic_cast<KTextEditor::Document*>( it.key() );
if ( !document )
continue;
int line = it.data().first;
int column = it.data().second;
KTextEditor::View *view = document->createView( this );
document->setWidget( view );
// We're managing the view deletion by being its parent,
// don't let the part self-destruct
disconnect( view, TQ_SIGNAL( destroyed() ),
document, TQ_SLOT( slotWidgetDestroyed() ) );
document->insertChildClient( view );
PartController::getInstance() ->integrateTextEditorPart( document );
KTextEditor::ViewCursorInterface *iface =
dynamic_cast<KTextEditor::ViewCursorInterface*>(
static_cast<KTextEditor::View*>( view ) );
if ( iface )
{
iface->setCursorPositionReal( line,
column == -1 ? 0 : column );
}
else
{
// Shouldn't get here
Q_ASSERT( false );
}
view->show();
kdDebug( 9000 ) << "Delayed activation of "
<< document->url().fileName() << " is now complete." << endl;
}
m_activated = true;
TQSplitter::show();
}
void MultiBuffer::setOrientation( TQt::Orientation orientation )
{
TQSplitter::setOrientation( orientation );
}
void MultiBuffer::activePartChanged( const KURL &url )
{
if ( !m_buffers.contains( url ) )
return ;
m_activeBuffer = m_buffers[ url ];
TopLevel::getInstance() ->setCurrentDocumentCaption( url.fileName() );
}
void MultiBuffer::focusInEvent( TQFocusEvent *ev )
{
KParts::Part *active = activeBuffer();
if (active && active->widget())
active->widget()->setFocus();
TQSplitter::focusInEvent(ev);
}
bool MultiBuffer::hasPart( KParts::Part *part )
{
for (BufferMap::iterator it = m_buffers.begin(); it != m_buffers.end(); ++it)
{
if (it.data() == part)
return true;
}
return false;
}
void MultiBuffer::updateUrlForPart(KParts::Part *part, KURL url)
{
if (!url.isValid())
return;
KURL formerURL;
for (BufferMap::iterator it = m_buffers.begin(); it != m_buffers.end(); ++it)
{
if (it.data() == part)
{
formerURL = it.key();
break;
}
}
m_buffers.remove(formerURL);
m_buffers.insert(url, part);
}
#include "multibuffer.moc"