|
|
|
/*
|
|
|
|
* 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"
|