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.
287 lines
7.1 KiB
287 lines
7.1 KiB
/* |
|
This file is part of the Konsole Terminal. |
|
|
|
Copyright 2006-2008 Robert Knight <robertknight@gmail.com> |
|
|
|
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; if not, write to the Free Software |
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
02110-1301 USA. |
|
*/ |
|
|
|
// Own |
|
#include "ViewSplitter.h" |
|
|
|
// Qt |
|
#include <QtGui/QKeyEvent> |
|
|
|
// KDE |
|
#include <kdebug.h> |
|
|
|
// Konsole |
|
#include "ViewContainer.h" |
|
|
|
using namespace Konsole; |
|
|
|
ViewSplitter::ViewSplitter(QWidget* parent) |
|
: QSplitter(parent) |
|
, _recursiveSplitting(true) |
|
{ |
|
} |
|
|
|
void ViewSplitter::childEmpty(ViewSplitter* splitter) |
|
{ |
|
delete splitter; |
|
|
|
if ( count() == 0 ) |
|
emit empty(this); |
|
} |
|
|
|
void ViewSplitter::adjustContainerSize(ViewContainer* container , int percentage) |
|
{ |
|
int containerIndex = indexOf(container->containerWidget()); |
|
|
|
Q_ASSERT( containerIndex != -1 ); |
|
|
|
QList<int> containerSizes = sizes(); |
|
|
|
int oldSize = containerSizes[containerIndex]; |
|
int newSize = (int)(oldSize * ( 1.0 + percentage/100.0 )); |
|
|
|
int perContainerDelta = (count() == 1 ) ? 0 : ( (newSize-oldSize) / (count()-1) ) * (-1); |
|
|
|
for ( int i = 0 ; i < containerSizes.count() ; i++ ) |
|
{ |
|
if ( i == containerIndex ) |
|
containerSizes[i] = newSize; |
|
else |
|
containerSizes[i] = containerSizes[i] + perContainerDelta; |
|
} |
|
|
|
setSizes(containerSizes); |
|
} |
|
|
|
ViewSplitter* ViewSplitter::activeSplitter() |
|
{ |
|
QWidget* widget = focusWidget() ? focusWidget() : this; |
|
|
|
ViewSplitter* splitter = 0; |
|
|
|
while ( !splitter && widget ) |
|
{ |
|
splitter = dynamic_cast<ViewSplitter*>(widget); |
|
widget = widget->parentWidget(); |
|
} |
|
|
|
Q_ASSERT( splitter ); |
|
return splitter; |
|
} |
|
|
|
void ViewSplitter::registerContainer( ViewContainer* container ) |
|
{ |
|
_containers << container; |
|
connect( container , SIGNAL(destroyed(ViewContainer*)) , this , SLOT(containerDestroyed(ViewContainer*)) ); |
|
connect( container , SIGNAL(empty(ViewContainer*)) , this , SLOT(containerEmpty(ViewContainer*)) ); |
|
} |
|
|
|
void ViewSplitter::unregisterContainer( ViewContainer* container ) |
|
{ |
|
_containers.removeAll(container); |
|
disconnect( container , 0 , this , 0 ); |
|
} |
|
|
|
void ViewSplitter::updateSizes() |
|
{ |
|
int space; |
|
|
|
if ( orientation() == Qt::Horizontal ) |
|
{ |
|
space = width() / count(); |
|
} |
|
else |
|
{ |
|
space = height() / count(); |
|
} |
|
|
|
QList<int> widgetSizes; |
|
for (int i=0;i<count();i++) |
|
widgetSizes << space; |
|
|
|
setSizes(widgetSizes); |
|
} |
|
|
|
void ViewSplitter::setRecursiveSplitting(bool recursive) |
|
{ |
|
_recursiveSplitting = recursive; |
|
} |
|
bool ViewSplitter::recursiveSplitting() const |
|
{ |
|
return _recursiveSplitting; |
|
} |
|
|
|
void ViewSplitter::removeContainer( ViewContainer* container ) |
|
{ |
|
Q_ASSERT( containers().contains(container) ); |
|
|
|
unregisterContainer(container); |
|
} |
|
|
|
void ViewSplitter::addContainer( ViewContainer* container , |
|
Qt::Orientation containerOrientation ) |
|
{ |
|
ViewSplitter* splitter = activeSplitter(); |
|
|
|
if ( splitter->count() < 2 || |
|
containerOrientation == splitter->orientation() || |
|
!_recursiveSplitting ) |
|
{ |
|
splitter->registerContainer(container); |
|
splitter->addWidget(container->containerWidget()); |
|
|
|
if ( splitter->orientation() != containerOrientation ) |
|
splitter->setOrientation( containerOrientation ); |
|
|
|
splitter->updateSizes(); |
|
} |
|
else |
|
{ |
|
ViewSplitter* newSplitter = new ViewSplitter(this); |
|
connect( newSplitter , SIGNAL(empty(ViewSplitter*)) , splitter , SLOT(childEmpty(ViewSplitter*)) ); |
|
|
|
ViewContainer* oldContainer = splitter->activeContainer(); |
|
int oldContainerIndex = splitter->indexOf(oldContainer->containerWidget()); |
|
|
|
splitter->unregisterContainer(oldContainer); |
|
|
|
newSplitter->registerContainer(oldContainer); |
|
newSplitter->registerContainer(container); |
|
|
|
newSplitter->addWidget(oldContainer->containerWidget()); |
|
newSplitter->addWidget(container->containerWidget()); |
|
newSplitter->setOrientation(containerOrientation); |
|
newSplitter->updateSizes(); |
|
newSplitter->show(); |
|
|
|
splitter->insertWidget(oldContainerIndex,newSplitter); |
|
} |
|
|
|
} |
|
|
|
void ViewSplitter::containerEmpty(ViewContainer* /*object*/) |
|
{ |
|
QListIterator<ViewContainer*> containerIter(_containers); |
|
|
|
int children = 0; |
|
while (containerIter.hasNext()) |
|
{ |
|
children += containerIter.next()->views().count(); |
|
} |
|
|
|
if ( children == 0 ) |
|
emit allContainersEmpty(); |
|
} |
|
|
|
void ViewSplitter::containerDestroyed(ViewContainer* object) |
|
{ |
|
Q_ASSERT( _containers.contains(object) ); |
|
|
|
_containers.removeAll(object); |
|
|
|
if ( count() == 0 ) |
|
{ |
|
emit empty(this); |
|
} |
|
} |
|
|
|
void ViewSplitter::activateNextContainer() |
|
{ |
|
ViewContainer* active = activeContainer(); |
|
|
|
int index = _containers.indexOf(active); |
|
|
|
if ( index == -1 ) |
|
return; |
|
|
|
if ( index == _containers.count() -1 ) |
|
index = 0; |
|
else |
|
index++; |
|
|
|
setActiveContainer( _containers.at(index) ); |
|
} |
|
|
|
void ViewSplitter::activatePreviousContainer() |
|
{ |
|
ViewContainer* active = activeContainer(); |
|
|
|
int index = _containers.indexOf(active); |
|
|
|
if ( index == 0 ) |
|
index = _containers.count() - 1; |
|
else |
|
index--; |
|
|
|
setActiveContainer( _containers.at(index) ); |
|
} |
|
|
|
|
|
void ViewSplitter::setActiveContainer(ViewContainer* container) |
|
{ |
|
QWidget* activeView = container->activeView(); |
|
|
|
if ( activeView ) |
|
activeView->setFocus( Qt::OtherFocusReason ); |
|
} |
|
|
|
ViewContainer* ViewSplitter::activeContainer() const |
|
{ |
|
if ( QWidget* focusW = focusWidget() ) |
|
{ |
|
ViewContainer* focusContainer = 0; |
|
|
|
while ( focusW != 0 ) |
|
{ |
|
QListIterator<ViewContainer*> containerIter(_containers); |
|
while (containerIter.hasNext()) |
|
{ |
|
ViewContainer* nextContainer = containerIter.next(); |
|
|
|
if (nextContainer->containerWidget() == focusW) |
|
{ |
|
focusContainer = nextContainer; |
|
break; |
|
} |
|
} |
|
focusW = focusW->parentWidget(); |
|
} |
|
|
|
if ( focusContainer ) |
|
return focusContainer; |
|
} |
|
|
|
QList<ViewSplitter*> splitters = findChildren<ViewSplitter*>(); |
|
|
|
if (splitters.count() > 0) |
|
{ |
|
return splitters.last()->activeContainer(); |
|
} |
|
else |
|
{ |
|
if ( _containers.count() > 0 ) |
|
return _containers.last(); |
|
else |
|
return 0; |
|
} |
|
} |
|
|
|
#include "ViewSplitter.moc"
|
|
|