Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konsole / src / ViewSplitter.cpp
blobcb2f19e1609a693e9037b651efd138a61e8d6797
1 /*
2 This file is part of the Konsole Terminal.
4 Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
22 // Own
23 #include "ViewSplitter.h"
25 // Qt
26 #include <QtGui/QKeyEvent>
28 // KDE
29 #include "kdebug.h"
31 // Konsole
32 #include "ViewContainer.h"
34 using namespace Konsole;
36 ViewSplitter::ViewSplitter(QWidget* parent)
37 : QSplitter(parent)
38 , _recursiveSplitting(true)
42 void ViewSplitter::childEmpty(ViewSplitter* splitter)
44 delete splitter;
46 if ( count() == 0 )
47 emit empty(this);
50 void ViewSplitter::adjustContainerSize(ViewContainer* container , int percentage)
52 int containerIndex = indexOf(container->containerWidget());
54 Q_ASSERT( containerIndex != -1 );
56 QList<int> containerSizes = sizes();
58 int oldSize = containerSizes[containerIndex];
59 int newSize = (int)(oldSize * ( 1.0 + percentage/100.0 ));
61 int perContainerDelta = (count() == 1 ) ? 0 : ( (newSize-oldSize) / (count()-1) ) * (-1);
63 for ( int i = 0 ; i < containerSizes.count() ; i++ )
65 if ( i == containerIndex )
66 containerSizes[i] = newSize;
67 else
68 containerSizes[i] = containerSizes[i] + perContainerDelta;
71 setSizes(containerSizes);
74 ViewSplitter* ViewSplitter::activeSplitter()
76 QWidget* widget = focusWidget() ? focusWidget() : this;
78 ViewSplitter* splitter = 0;
80 while ( !splitter && widget )
82 splitter = dynamic_cast<ViewSplitter*>(widget);
83 widget = widget->parentWidget();
86 Q_ASSERT( splitter );
87 return splitter;
90 void ViewSplitter::registerContainer( ViewContainer* container )
92 _containers << container;
93 connect( container , SIGNAL(destroyed(ViewContainer*)) , this , SLOT( containerDestroyed(ViewContainer*) ) );
94 connect( container , SIGNAL(empty(ViewContainer*)) , this , SLOT( containerEmpty(ViewContainer*) ) );
97 void ViewSplitter::unregisterContainer( ViewContainer* container )
99 _containers.removeAll(container);
100 disconnect( container , 0 , this , 0 );
103 void ViewSplitter::updateSizes()
105 int space;
107 if ( orientation() == Qt::Horizontal )
109 space = width() / count();
111 else
113 space = height() / count();
116 QList<int> widgetSizes;
117 for (int i=0;i<count();i++)
118 widgetSizes << space;
120 setSizes(widgetSizes);
123 void ViewSplitter::setRecursiveSplitting(bool recursive)
125 _recursiveSplitting = recursive;
127 bool ViewSplitter::recursiveSplitting() const
129 return _recursiveSplitting;
132 void ViewSplitter::removeContainer( ViewContainer* container )
134 Q_ASSERT( containers().contains(container) );
136 unregisterContainer(container);
139 void ViewSplitter::addContainer( ViewContainer* container ,
140 Qt::Orientation containerOrientation )
142 ViewSplitter* splitter = activeSplitter();
144 if ( splitter->count() < 2 ||
145 containerOrientation == splitter->orientation() ||
146 !_recursiveSplitting )
148 splitter->registerContainer(container);
149 splitter->addWidget(container->containerWidget());
151 if ( splitter->orientation() != containerOrientation )
152 splitter->setOrientation( containerOrientation );
154 splitter->updateSizes();
156 else
158 ViewSplitter* newSplitter = new ViewSplitter(this);
159 connect( newSplitter , SIGNAL(empty(ViewSplitter*)) , splitter , SLOT(childEmpty(ViewSplitter*)) );
161 ViewContainer* oldContainer = splitter->activeContainer();
162 int oldContainerIndex = splitter->indexOf(oldContainer->containerWidget());
164 splitter->unregisterContainer(oldContainer);
166 newSplitter->registerContainer(oldContainer);
167 newSplitter->registerContainer(container);
169 newSplitter->addWidget(oldContainer->containerWidget());
170 newSplitter->addWidget(container->containerWidget());
171 newSplitter->setOrientation(containerOrientation);
172 newSplitter->updateSizes();
173 newSplitter->show();
175 splitter->insertWidget(oldContainerIndex,newSplitter);
180 void ViewSplitter::containerEmpty(ViewContainer* /*object*/)
182 QListIterator<ViewContainer*> containerIter(_containers);
184 int children = 0;
185 while (containerIter.hasNext())
187 children += containerIter.next()->views().count();
190 if ( children == 0 )
191 emit allContainersEmpty();
194 void ViewSplitter::containerDestroyed(ViewContainer* object)
196 Q_ASSERT( _containers.contains(object) );
198 _containers.removeAll(object);
200 if ( count() == 0 )
202 emit empty(this);
206 void ViewSplitter::activateNextContainer()
208 ViewContainer* active = activeContainer();
210 int index = _containers.indexOf(active);
212 if ( index == -1 )
213 return;
215 if ( index == _containers.count() -1 )
216 index = 0;
217 else
218 index++;
220 setActiveContainer( _containers.at(index) );
223 void ViewSplitter::activatePreviousContainer()
225 ViewContainer* active = activeContainer();
227 int index = _containers.indexOf(active);
229 if ( index == 0 )
230 index = _containers.count() - 1;
231 else
232 index--;
234 setActiveContainer( _containers.at(index) );
238 void ViewSplitter::setActiveContainer(ViewContainer* container)
240 QWidget* activeView = container->activeView();
242 if ( activeView )
243 activeView->setFocus( Qt::OtherFocusReason );
246 ViewContainer* ViewSplitter::activeContainer() const
248 if ( QWidget* focusW = focusWidget() )
250 ViewContainer* focusContainer = 0;
252 while ( focusW != 0 )
254 QListIterator<ViewContainer*> containerIter(_containers);
255 while (containerIter.hasNext())
257 ViewContainer* nextContainer = containerIter.next();
259 if (nextContainer->containerWidget() == focusW)
261 focusContainer = nextContainer;
262 break;
265 focusW = focusW->parentWidget();
268 if ( focusContainer )
269 return focusContainer;
272 QList<ViewSplitter*> splitters = findChildren<ViewSplitter*>();
274 if (splitters.count() > 0)
276 return splitters.last()->activeContainer();
278 else
280 if ( _containers.count() > 0 )
281 return _containers.last();
282 else
283 return 0;
287 #include "ViewSplitter.moc"