summaryrefslogtreecommitdiffstats
path: root/src/multibuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multibuffer.cpp')
-rw-r--r--src/multibuffer.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/multibuffer.cpp b/src/multibuffer.cpp
new file mode 100644
index 00000000..cdbffe85
--- /dev/null
+++ b/src/multibuffer.cpp
@@ -0,0 +1,303 @@
+/*
+ * 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 kdevelop
+// doesn't need to be rearchitected for multiple views before the lazy view
+// creation can go in
+#define protected public
+#include <kparts/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 <kmainwindow.h>
+#include <kapplication.h>
+
+#include <kparts/factory.h>
+
+#include <ktexteditor/view.h>
+#include <ktexteditor/document.h>
+#include <ktexteditor/viewcursorinterface.h>
+
+MultiBuffer::MultiBuffer( QWidget *parent )
+ : QSplitter( 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, SIGNAL( splitOrientationChanged( Qt::Orientation ) ),
+ this, SLOT( setOrientation( Qt::Orientation ) ) );
+ }
+ else
+ {
+ setOrientation( Qt::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 QString &mimeType,
+ const QString &partType,
+ const QString &className,
+ const QString &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 );
+
+ QString className;
+ QString services[] = { "KParts/ReadWritePart", "KParts/ReadOnlyPart" };
+ QString 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 )
+ {
+ QSplitter::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, SIGNAL( destroyed() ),
+ document, 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;
+ QSplitter::show();
+}
+
+void MultiBuffer::setOrientation( Qt::Orientation orientation )
+{
+ QSplitter::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( QFocusEvent *ev )
+{
+ KParts::Part *active = activeBuffer();
+ if (active && active->widget())
+ active->widget()->setFocus();
+ QSplitter::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"
+
+// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on