ViewSplitter.h 6.39 KB
Newer Older
1 2 3
/*
    This file is part of the Konsole Terminal.
    
4
    Copyright (C) 2006 Robert Knight <robertknight@gmail.com>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    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.
*/
21 22 23 24

#ifndef VIEWSPLITTER_H
#define VIEWSPLITTER_H

Dirk Mueller's avatar
Dirk Mueller committed
25 26
#include <QtCore/QList>
#include <QtGui/QSplitter>
27

Robert Knight's avatar
 
Robert Knight committed
28
class QFocusEvent;
29 30 31 32

namespace Konsole
{

33 34
class ViewContainer;

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
/**
 * A splitter which holds a number of ViewContainer objects and allows
 * the user to control the size of each view container by dragging a splitter
 * bar between them.
 *
 * Each splitter can also contain child ViewSplitter widgets, allowing
 * for a hierarchy of view splitters and containers.
 *
 * The addContainer() method is used to split the existing view and 
 * insert a new view container.
 * Containers can only be removed from the hierarchy by deleting them.
 */
class ViewSplitter : public QSplitter
{
Q_OBJECT

public:
52
    ViewSplitter(QWidget* parent = 0); 
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
    /**
     * Locates the child ViewSplitter widget which currently has the focus
     * and inserts the container into it.   
     * 
     * @param container The container to insert
     * @param orientation Specifies whether the view should be split
     *                    horizontally or vertically.  If the orientation
     *                    is the same as the ViewSplitter into which the
     *                    container is to be inserted, or if the splitter
     *                    has fewer than two child widgets then the container
     *                    will be added to that splitter.  If the orientation
     *                    is different, then a new child splitter
     *                    will be created, into which the container will
     *                    be inserted.   
     */
    void addContainer( ViewContainer* container , Qt::Orientation orientation );   
    /** Returns the child ViewSplitter widget which currently has the focus */
    ViewSplitter* activeSplitter() ;
 
    /** 
     * Returns the container which currently has the focus or 0 if none
     * of the immediate child containers have the focus.  This does not 
     * search through child splitters.  activeSplitter() can be used
     * to search recursively through child splitters for the splitter
     * which currently has the focus.
     *
     * To find the currently active container, use
     * mySplitter->activeSplitter()->activeContainer() where mySplitter
     * is the ViewSplitter widget at the top of the hierarchy.
     */
    ViewContainer* activeContainer() const; 
Robert Knight's avatar
 
Robert Knight committed
85 86 87 88 89 90

    /**
     * Gives the focus to the active view in the specified container 
     */
    void setActiveContainer(ViewContainer* container);

91 92 93 94
    /**
     * Returns a list of the containers held by this splitter
     */
    QList<ViewContainer*> containers() const {return _containers;}
Robert Knight's avatar
 
Robert Knight committed
95 96 97 98 99 100
   
    /**
     * Gives the focus to the active view in the next container
     */
    void activateNextContainer();

101 102 103 104 105 106 107 108 109 110 111
    /**
     * Changes the size of the specified @p container by a given @p percentage.
     * @p percentage may be positive ( in which case the size of the container 
     * is increased ) or negative ( in which case the size of the container 
     * is decreased ).  
     *
     * The sizes of the remaining containers are increased or decreased
     * uniformly to maintain the width of the splitter.
     */
    void adjustContainerSize(ViewContainer* container , int percentage);

Robert Knight's avatar
 
Robert Knight committed
112 113 114 115 116
   /**
    * Gives the focus to the active view in the previous container
    */
   void activatePreviousContainer();

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
   /**
    * Specifies whether the view may be split recursively.
    * 
    * If this is false, all containers will be placed into the same
    * top-level splitter.  Adding a container with an orientation
    * which is different to that specified when adding the previous
    * containers will change the orientation for all dividers 
    * between containers.
    *
    * If this is true, adding a container to the view splitter with
    * an orientation different to the orientation of the previous
    * area will result in the previously active container being
    * replaced with a new splitter containing the active container
    * and the newly added container.  
    */
   void setRecursiveSplitting(bool recursive);

   /** 
    * Returns whether the view may be split recursively.
    * See setRecursiveSplitting() 
    */
   bool recursiveSplitting() const;

140 141 142 143
signals:
    /** Signal emitted when the last child widget is removed from the splitter */
    void empty(ViewSplitter* splitter);

144 145 146 147 148 149 150 151
    /** 
     * Signal emitted when the containers held by this splitter become empty, this
     * differs from the empty() signal which is only emitted when all of the containers
     * are deleted.  This signal is emitted even if there are still container widgets.
     *
     * TODO: This does not yet work recursively (ie. when splitters inside splitters have empty containers)  
     */
    void allContainersEmpty();
Robert Knight's avatar
 
Robert Knight committed
152 153 154 155

protected:
    //virtual void focusEvent(QFocusEvent* event);

156 157 158 159 160 161 162 163
private:
    // Adds container to splitter's internal list and
    // connects signals and slots
    void registerContainer( ViewContainer* container );
    // Removes container from splitter's internal list and
    // removes signals and slots
    void unregisterContainer( ViewContainer* container );

164 165
    void updateSizes();

166 167 168
private slots:
    // Called to indicate that a child ViewContainer has been deleted
    void containerDestroyed( ViewContainer* object );
169 170 171 172

    // Called to indicate that a child ViewContainer is empty
    void containerEmpty( ViewContainer* object );

173 174 175 176 177 178
    // Called to indicate that a child ViewSplitter is empty
    // (ie. all child widgets have been deleted)
    void childEmpty( ViewSplitter* splitter );

private:
    QList<ViewContainer*> _containers;
179
    bool _recursiveSplitting;
180 181
};

Stephan Binner's avatar
Stephan Binner committed
182
}
183 184
#endif //VIEWSPLITTER_H