-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
//
-// This library 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
-// Lesser General Public License for more details.
+// This library 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
+// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File: QtxWorkstack.cxx
// Author: Sergey TELKOV
//
#include <QRegExp>
#include <QLayout>
#include <QPainter>
-#include <QSplitter>
+#include <QDataStream>
#include <QFocusEvent>
#include <QMouseEvent>
#include <QRubberBand>
class QtxWorkstackArea::WidgetEvent : public QEvent
{
public:
- WidgetEvent( Type t, QWidget* w = 0 ) : QEvent( t ), myWidget( w ) {};
+ WidgetEvent( Type t, QtxWorkstackChild* w = 0 ) : QEvent( t ), myChild( w ) {};
+
+ QtxWorkstackChild* child() const { return myChild; }
+
+private:
+ QtxWorkstackChild* myChild; // event receiver widget
+};
+
+/*!
+ \class QtxWorkstackArea::RestoreEvent
+ \internal
+ \brief Internal class used to forward restore info events to the workarea
+*/
+
+class QtxWorkstackArea::RestoreEvent : public QtxWorkstackArea::WidgetEvent
+{
+public:
+ RestoreEvent( Type t, int id, int f, QtxWorkstackChild* w )
+ : WidgetEvent( t, w ), myId( id ), myFlags( f ) {};
- QWidget* widget() const { return myWidget; }
+ int id() const { return myId; }
+ int flags() const { return myFlags; }
private:
- QWidget* myWidget; // event receiver widget
+ int myId;
+ int myFlags;
};
/*!
/*!
\brief Called when drop operation is finished.
-
+
Inserts dropped widget to the target workarea.
*/
void QtxWorkstackDrag::dropWidget()
{
if ( myArea )
- myArea->insertWidget( myChild->widget(), myTab );
+ myArea->insertChild( myChild, myTab );
}
/*!
{
ensurePolished();
int dim = 0;
- if( !icon().isNull() )
+ if( !icon().isNull() )
{
const QPixmap pm = icon().pixmap( style()->pixelMetric( QStyle::PM_SmallIconSize ),
QIcon::Normal );
\return minimum size value
*/
QSize CloseButton::minimumSizeHint() const
-{
- return sizeHint();
+{
+ return sizeHint();
}
/*!
QPixmap pm = icon().pixmap( style()->pixelMetric( QStyle::PM_SmallIconSize ), isEnabled() ?
underMouse() ? QIcon::Active : QIcon::Normal
- : QIcon::Disabled,
+ : QIcon::Disabled,
isDown() ? QIcon::On : QIcon::Off );
style()->drawItemPixmap( &p, r, Qt::AlignCenter, pm );
}
+
+/*!
+ \class QtxWorkstackSplitter
+ \internal
+ \brief Workstack splitter.
+*/
+
+/*!
+ \brief Constructor.
+ \param parent parent widget
+*/
+QtxWorkstackSplitter::QtxWorkstackSplitter( QWidget* parent )
+: QSplitter( parent )
+{
+ setChildrenCollapsible( false );
+}
+
+/*!
+ \brief Destructor.
+*/
+QtxWorkstackSplitter::~QtxWorkstackSplitter()
+{
+}
+
+/*!
+ \brief Get parent workstack
+ \return workstack owning this workarea
+*/
+QtxWorkstack* QtxWorkstackSplitter::workstack() const
+{
+ QtxWorkstack* ws = 0;
+ QWidget* wid = parentWidget();
+ while ( wid && !ws )
+ {
+ ws = ::qobject_cast<QtxWorkstack*>( wid );
+ wid = wid->parentWidget();
+ }
+ return ws;
+}
+
+/*!
+ \brief Save the widget area configuration into data stream.
+*/
+void QtxWorkstackSplitter::saveState( QDataStream& stream ) const
+{
+ stream << QtxWorkstack::SplitMarker;
+
+ uchar flags = 0;
+ if ( orientation() == Qt::Horizontal )
+ flags |= QtxWorkstack::Horizontal;
+
+ stream << flags;
+ stream << count();
+
+ QList<int> sz = sizes();
+ for ( QList<int>::const_iterator it = sz.begin(); it != sz.end(); ++it )
+ stream << *it;
+
+ for ( int i = 0; i < count(); i++ )
+ {
+ QWidget* wid = widget( i );
+ QtxWorkstackSplitter* split = ::qobject_cast<QtxWorkstackSplitter*>( wid );
+ if ( split )
+ split->saveState( stream );
+ else
+ {
+ QtxWorkstackArea* area = ::qobject_cast<QtxWorkstackArea*>( wid );
+ if ( area )
+ area->saveState( stream );
+ }
+ }
+}
+
+/*!
+ \brief Restore the widget area configuration from data stream info.
+ \return \c true in successful case.
+*/
+bool QtxWorkstackSplitter::restoreState( QDataStream& stream, QMap<QString, QtxWorkstackChild*>& map )
+{
+ int num = 0;
+ uchar flags = 0;
+
+ stream >> flags;
+ stream >> num;
+
+ setOrientation( flags & QtxWorkstack::Horizontal ? Qt::Horizontal : Qt::Vertical );
+
+ QList<int> sz;
+ for ( int s = 0; s < num; s++ )
+ {
+ int sn = 0;
+ stream >> sn;
+ sz.append( sn );
+ }
+
+ bool ok = true;
+ for ( int i = 0; i < num && ok; i++ )
+ {
+ int marker;
+ stream >> marker;
+
+ if ( stream.status() != QDataStream::Ok )
+ return false;
+
+ if ( marker == QtxWorkstack::SplitMarker )
+ {
+ QtxWorkstackSplitter* split = new QtxWorkstackSplitter( this );
+ addWidget( split );
+ split->setVisible( true );
+
+ ok = split->restoreState( stream, map );
+ }
+ else if ( marker == QtxWorkstack::AreaMarker )
+ {
+ QtxWorkstack* ws = workstack();
+ QtxWorkstackArea* area = ws->createArea( this );
+ addWidget( area );
+ area->setVisible( true );
+
+ ok = area->restoreState( stream, map );
+ }
+ else
+ return false;
+ }
+
+ if ( ok )
+ setSizes( sz );
+
+ return ok;
+}
+
/*!
\class QtxWorkstackArea
\internal
base->setMargin( frameWidth() );
base->setSpacing( 0 );
- QWidget* top = new QWidget( this );
- base->addWidget( top );
+ myTop = new QWidget( this );
+ base->addWidget( myTop );
- QHBoxLayout* tl = new QHBoxLayout( top );
+ QHBoxLayout* tl = new QHBoxLayout( myTop );
tl->setMargin( 0 );
- myBar = new QtxWorkstackTabBar( top );
+ myBar = new QtxWorkstackTabBar( myTop );
tl->addWidget( myBar, 1 );
- CloseButton* close = new CloseButton( top );
+ CloseButton* close = new CloseButton( myTop );
close->setIcon( style()->standardIcon( QStyle::SP_TitleBarCloseButton ) );
myClose = close;
tl->addWidget( myClose );
bool QtxWorkstackArea::isEmpty() const
{
bool res = false;
- for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !res; ++it )
- res = it.value().vis;
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end() && !res; ++it )
+ res = (*it)->visibility();
return !res;
}
\param f widget flags
\return child widget container object (or 0 if index is invalid)
*/
-QWidget* QtxWorkstackArea::insertWidget( QWidget* wid, const int idx, Qt::WindowFlags f )
+QtxWorkstackChild* QtxWorkstackArea::insertWidget( QWidget* wid, const int idx, Qt::WindowFlags f )
{
if ( !wid )
return 0;
- int pos = myList.indexOf( wid );
+ QtxWorkstackChild* c = child( wid );
+ if ( !c )
+ c = new QtxWorkstackChild( wid, myStack, f );
+
+ insertChild( c, idx );
+
+ return c;
+}
+
+void QtxWorkstackArea::insertChild( QtxWorkstackChild* child, const int idx )
+{
+ if ( !child )
+ return;
+
+ QtxWorkstackArea* a = child->area();
+ if ( a && a != this )
+ a->removeChild( child, false );
+
+ int pos = myList.indexOf( child );
if ( pos != -1 && ( pos == idx || ( idx < 0 && pos == (int)myList.count() - 1 ) ) )
- return 0;
+ return;
+
+ bool found = myList.contains( child );
- myList.removeAll( wid );
+ myList.removeAll( child );
pos = idx < 0 ? myList.count() : idx;
- myList.insert( qMin( pos, (int)myList.count() ), wid );
- if ( !myInfo.contains( wid ) )
+ myList.insert( qMin( pos, (int)myList.count() ), child );
+
+ if ( !found )
{
- QtxWorkstackChild* child = new QtxWorkstackChild( wid, myStack, f );
- myChild.insert( wid, child );
- myInfo.insert( wid, WidgetInfo() );
- myInfo[wid].id = generateId();
- myInfo[wid].vis = wid->isVisibleTo( wid->parentWidget() );
+ bool hasId = false;
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end() && !hasId; ++it )
+ hasId = (*it)->id() == child->id();
+
+ if ( hasId || child->id() < 0 )
+ child->setId( generateId() );
connect( child, SIGNAL( destroyed( QObject* ) ), this, SLOT( onChildDestroyed( QObject* ) ) );
- connect( wid, SIGNAL( destroyed() ), this, SLOT( onWidgetDestroyed() ) );
connect( child, SIGNAL( shown( QtxWorkstackChild* ) ), this, SLOT( onChildShown( QtxWorkstackChild* ) ) );
connect( child, SIGNAL( hidden( QtxWorkstackChild* ) ), this, SLOT( onChildHidden( QtxWorkstackChild* ) ) );
connect( child, SIGNAL( activated( QtxWorkstackChild* ) ), this, SLOT( onChildActivated( QtxWorkstackChild* ) ) );
updateState();
- setWidgetActive( wid );
- wid->setFocus();
-
- return myChild[wid];
+ setWidgetActive( child->widget() );
+ child->widget()->setFocus();
}
/*!
}
/*!
- \brief Called when area's child widget is destroyed.
-
- Removes child widget from the area.
+ \brief Remove widget from workarea.
+ \param wid widget to be removed
+ \param del if \c true the widget should be also deleted
*/
-void QtxWorkstackArea::onWidgetDestroyed()
+void QtxWorkstackArea::removeWidget( QWidget* wid, const bool del )
{
- if ( sender() )
- removeWidget( (QWidget*)sender(), false );
+ removeChild( child( wid ), del );
}
/*!
- \brief Remove widget from workarea.
- \param wid widget to be removed
+ \brief Remove child from workarea.
+ \param child child to be removed
\param del if \c true the widget should be also deleted
*/
-void QtxWorkstackArea::removeWidget( QWidget* wid, const bool del )
+void QtxWorkstackArea::removeChild( QtxWorkstackChild* child, const bool del )
{
- if ( !myList.contains( wid ) )
+ if ( !myList.contains( child ) )
return;
- if ( myBar->indexOf( widgetId( wid ) ) != -1 )
- myBar->removeTab( myBar->indexOf( widgetId( wid ) ) );
+ myStack->removeWidget( child );
- myStack->removeWidget( child( wid ) );
+ if ( myBar->indexOf( child->id() ) != -1 )
+ myBar->removeTab( myBar->indexOf( child->id() ) );
- myList.removeAll( wid );
- myInfo.remove( wid );
- myChild.remove( wid );
+ myList.removeAll( child );
if ( del )
- delete child( wid );
+ delete child;
+ else if ( child->widget() )
+ {
+ disconnect( child, SIGNAL( destroyed( QObject* ) ), this, SLOT( onChildDestroyed( QObject* ) ) );
+ disconnect( child, SIGNAL( shown( QtxWorkstackChild* ) ), this, SLOT( onChildShown( QtxWorkstackChild* ) ) );
+ disconnect( child, SIGNAL( hidden( QtxWorkstackChild* ) ), this, SLOT( onChildHidden( QtxWorkstackChild* ) ) );
+ disconnect( child, SIGNAL( activated( QtxWorkstackChild* ) ), this, SLOT( onChildActivated( QtxWorkstackChild* ) ) );
+ disconnect( child, SIGNAL( captionChanged( QtxWorkstackChild* ) ), this, SLOT( onChildCaptionChanged( QtxWorkstackChild* ) ) );
+ }
if ( isNull() )
deleteLater();
updateState();
}
+QList<QtxWorkstackChild*> QtxWorkstackArea::childList() const
+{
+ return myList;
+}
+
/*!
\brief Get all visible child widgets.
\return list of visible child widgets
QWidgetList QtxWorkstackArea::widgetList() const
{
QWidgetList lst;
- for ( QWidgetList::const_iterator it = myList.begin(); it != myList.end(); ++it )
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end(); ++it )
{
- if ( widgetVisibility( *it ) )
- lst.append( *it );
+ QtxWorkstackChild* c = *it;
+ if ( c->visibility() )
+ lst.append( c->widget() );
}
return lst;
}
*/
bool QtxWorkstackArea::contains( QWidget* wid ) const
{
- return myList.contains( wid );
-}
-
-/*!
- \brief Show/hide workarea.
- \param on new visibility state
-*/
-void QtxWorkstackArea::setVisible( bool on )
-{
- QMap<QWidget*, bool> map;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
- {
- map.insert( *it, isBlocked( *it ) );
- setBlocked( *it, true );
- }
-
- QFrame::setVisible( on );
-
- for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
- setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
+ return child( wid );
}
/*!
QWidget* wid = parentWidget();
while ( wid && !ws )
{
- if ( wid->inherits( "QtxWorkstack" ) )
- ws = (QtxWorkstack*)wid;
+ ws = ::qobject_cast<QtxWorkstack*>( wid );
wid = wid->parentWidget();
}
return ws;
return false;
}
+/*!
+ \brief Save the own widgets configuration into data stream.
+*/
+void QtxWorkstackArea::saveState( QDataStream& stream ) const
+{
+ stream << QtxWorkstack::AreaMarker;
+ stream << myList.count();
+ stream << myBar->tabId( myBar->currentIndex() );
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end(); ++it )
+ {
+ QtxWorkstackChild* c = *it;
+
+ stream << QtxWorkstack::WidgetMarker;
+
+ stream << c->widget()->objectName();
+ stream << c->id();
+
+ uchar flags = 0;
+ if ( c->visibility() )
+ flags |= QtxWorkstack::Visible;
+
+ stream << flags;
+ }
+}
+
+/*!
+ \brief Restore the widgets configuration from data stream info.
+ \return \c true in successful case.
+*/
+bool QtxWorkstackArea::restoreState( QDataStream& stream, QMap<QString, QtxWorkstackChild*>& map )
+{
+ int num = 0;
+ int cur = -1;
+
+ stream >> num;
+ stream >> cur;
+
+ QtxWorkstackChild* curChild = 0;
+ for ( int i = 0; i < num; i++ )
+ {
+ int marker;
+ stream >> marker;
+
+ if ( stream.status() != QDataStream::Ok || marker != QtxWorkstack::WidgetMarker )
+ return false;
+
+ QString name;
+ stream >> name;
+
+ int id = -1;
+ stream >> id;
+
+ uchar flags = 0;
+ stream >> flags;
+
+ QtxWorkstackChild* c = map.contains( name ) ? map[name] : 0;
+ if ( !c )
+ {
+ qWarning( "QtxWorkstack: Restored child widget \"%s\" not found.", (const char*)name.toLatin1() );
+ return false;
+ }
+
+ map.remove( name );
+
+ if ( id == cur )
+ curChild = c;
+
+ QApplication::postEvent( this, new RestoreEvent( (QEvent::Type)RestoreWidget, id, flags, c ) );
+ }
+
+ if ( curChild )
+ QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)MakeCurrent, curChild ) );
+
+ return true;
+}
+
+/*!
+ \brief Show/Hide tab bar.
+*/
+void QtxWorkstackArea::showTabBar( bool visible)
+{
+ myTop->setVisible(visible);
+ myBar->setVisible(visible);
+}
+
+
/*!
\brief Get rectangle to be drawn when highlighting drop area.
\return area drop rectangle
{
case ActivateWidget:
myBar->updateActiveState();
+ // IMN 27/03/2015: This workaround caused by the bug INT PAL 0052623: OCC view blinking when
+ // using polyline sketcher which is reproduced on Unix systems with qt-4.8.4.
+ myStack->setUpdatesEnabled( false );
+ updateCurrent();
+ myStack->setUpdatesEnabled( true );
emit activated( activeWidget() );
break;
case FocusWidget:
if ( activeWidget()->focusWidget()->hasFocus() )
{
QFocusEvent in( QEvent::FocusIn );
- QApplication::sendEvent( this, &in );
- }
- else {
+ QApplication::sendEvent( this, &in );
+ }
+ else
+ {
activeWidget()->focusWidget()->setFocus();
- myBar->updateActiveState();
- }
+ myBar->updateActiveState();
+ }
}
}
break;
- case RemoveWidget:
- removeWidget( we->widget() );
+ case MakeCurrent:
+ if ( we->child()->widget() )
+ setActiveWidget( we->child()->widget() );
+ break;
+ case RestoreWidget:
+ if ( we->child() )
+ {
+ QtxWorkstackChild* c = we->child();
+ RestoreEvent* re = (RestoreEvent*)we;
+ if ( c->widget() )
+ c->widget()->setVisible( re->flags() & QtxWorkstack::Visible );
+ c->setId( re->id() );
+ insertChild( c );
+ }
break;
default:
break;
*/
void QtxWorkstackArea::onChildDestroyed( QObject* obj )
{
- QtxWorkstackChild* child = (QtxWorkstackChild*)obj;
- myStack->removeWidget( child );
-
- QWidget* wid = 0;
- for ( ChildMap::ConstIterator it = myChild.begin(); it != myChild.end() && !wid; ++it )
- {
- if ( it.value() == child )
- wid = it.key();
- }
-
- myChild.remove( wid );
-
- QApplication::postEvent( this, new WidgetEvent( (QEvent::Type)RemoveWidget, wid ) );
+ removeChild( (QtxWorkstackChild*)obj, false );
}
/*!
*/
void QtxWorkstackArea::onChildShown( QtxWorkstackChild* c )
{
- setWidgetShown( c->widget(), true );
+ updateState();
}
/*!
*/
void QtxWorkstackArea::onChildHidden( QtxWorkstackChild* c )
{
- setWidgetShown( c->widget(), false );
+ updateState();
}
/*!
*/
void QtxWorkstackArea::updateCurrent()
{
- QMap<QWidget*, bool> map;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
- {
- map.insert( *it, isBlocked( *it ) );
- setBlocked( *it, true );
- }
-
- QWidget* cur = child( widget( myBar->tabId( myBar->currentIndex() ) ) );
+ QWidget* cur = child( myBar->tabId( myBar->currentIndex() ) );
if ( cur )
myStack->setCurrentWidget( cur );
-
- for ( QWidgetList::iterator itr = myList.begin(); itr != myList.end(); ++itr )
- setBlocked( *itr, map.contains( *itr ) ? map[*itr] : false );
}
/*!
*/
QWidget* QtxWorkstackArea::widget( const int id ) const
{
- QWidget* wid = 0;
- for ( WidgetInfoMap::ConstIterator it = myInfo.begin(); it != myInfo.end() && !wid; ++it )
- {
- if ( it.value().id == id )
- wid = it.key();
- }
- return wid;
+ QtxWorkstackChild* c = child( id );
+
+ return c ? c->widget() : 0;
}
/*!
*/
int QtxWorkstackArea::widgetId( QWidget* wid ) const
{
- int id = -1;
- if ( myInfo.contains( wid ) )
- id = myInfo[wid].id;
- return id;
-}
+ QtxWorkstackChild* c = child( wid );
-/*!
- \brief Get child widget's visibility.
- \param wid widget
- \return \c true if widget is visible
-*/
-bool QtxWorkstackArea::widgetVisibility( QWidget* wid ) const
-{
- bool res = false;
- if ( myInfo.contains( wid ) )
- res = myInfo[wid].vis;
- return res;
+ return c ? c->id() : -1;
}
/*!
myBar->setCurrentIndex( myBar->indexOf( id ) );
}
-/*!
- \brief Show/hide child widget.
- \param wid widget
- \param on new visibility state
-*/
-void QtxWorkstackArea::setWidgetShown( QWidget* wid, const bool on )
-{
- if ( isBlocked( wid ) || !myInfo.contains( wid ) || myInfo[wid].vis == on )
- return;
-
- myInfo[wid].vis = on;
- updateState();
-}
-
/*!
\brief Update internal state.
*/
QWidget* prev = activeWidget();
int idx = 0;
- for ( QWidgetList::iterator it = myList.begin(); it != myList.end(); ++it )
+ for ( ChildList::iterator it = myList.begin(); it != myList.end(); ++it )
{
- QWidget* wid = *it;
- int id = widgetId( wid );
+ QtxWorkstackChild* cont = *it;
+ QWidget* wid = cont->widget();;
+ int id = cont->id();
if ( id < 0 )
continue;
- bool vis = widgetVisibility( wid );
+ bool vis = cont->visibility();
int cIdx = myBar->indexOf( id );
if ( cIdx != -1 && ( !vis || myBar->indexOf( id ) != idx ) )
updateTab( wid );
- bool block = isBlocked( wid );
- setBlocked( wid, true );
-
- QtxWorkstackChild* cont = child( wid );
-
if ( !vis )
myStack->removeWidget( cont );
else if ( myStack->indexOf( cont ) < 0 )
if ( vis )
idx++;
-
- setBlocked( wid, block );
}
int curId = widgetId( prev );
if ( myBar->indexOf( curId ) < 0 )
{
- QWidget* wid = 0;
- int pos = myList.indexOf( prev );
- for ( int i = pos - 1; i >= 0 && !wid; i-- )
+ QtxWorkstackChild* c = 0;
+ int pos = myList.indexOf( child( prev ) );
+ for ( int i = pos - 1; i >= 0 && !c; i-- )
{
- if ( widgetVisibility( myList.at( i ) ) )
- wid = myList.at( i );
+ if ( myList.at( i )->visibility() )
+ c = myList.at( i );
}
- for ( int j = pos + 1; j < (int)myList.count() && !wid; j++ )
+ for ( int j = pos + 1; j < (int)myList.count() && !c; j++ )
{
- if ( widgetVisibility( myList.at( j ) ) )
- wid = myList.at( j );
+ if ( myList.at( j )->visibility() )
+ c = myList.at( j );
}
- if ( wid )
- curId = widgetId( wid );
+ if ( c )
+ curId = c->id();
}
myBar->setCurrentIndex( myBar->indexOf( curId ) );
{
QMap<int, int> map;
- for ( WidgetInfoMap::const_iterator it = myInfo.begin(); it != myInfo.end(); ++it )
- map.insert( it.value().id, 0 );
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end(); ++it )
+ map.insert( (*it)->id(), 0 );
int id = 0;
while ( map.contains( id ) )
return id;
}
-/*!
- \brief Check if the child wiget is blocked.
- \param wid widget
- \return \c true if the widget is blocked
-*/
-bool QtxWorkstackArea::isBlocked( QWidget* wid ) const
-{
- return myBlock.contains( wid );
-}
-
-/*!
- \brief Block widget.
- \param wid widget
- \param on new blocked state
-*/
-void QtxWorkstackArea::setBlocked( QWidget* wid, const bool on )
-{
- if ( on )
- myBlock.insert( wid, 0 );
- else
- myBlock.remove( wid );
-}
-
/*!
\brief Get child widget container.
\param wid child widget
QtxWorkstackChild* QtxWorkstackArea::child( QWidget* wid ) const
{
QtxWorkstackChild* res = 0;
- if ( myChild.contains( wid ) )
- res = myChild[wid];
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end() && !res; ++it )
+ {
+ if ( (*it)->widget() == wid )
+ res = *it;
+ }
return res;
}
+QtxWorkstackChild* QtxWorkstackArea::child( const int id ) const
+{
+ QtxWorkstackChild* c = 0;
+ for ( ChildList::const_iterator it = myList.begin(); it != myList.end() && !c; ++it )
+ {
+ if ( (*it)->id() == id )
+ c = *it;
+ }
+ return c;
+}
+
/*!
\fn void QtxWorkstackArea::activated( QWidget* w )
\brief Emitted when child widget is activated.
*/
QtxWorkstackChild::QtxWorkstackChild( QWidget* wid, QWidget* parent, Qt::WindowFlags f )
: QWidget( parent ),
+ myId( 0 ),
myWidget( wid )
{
- myWidget->setParent( this, f );
- myWidget->installEventFilter( this );
- QVBoxLayout* base = new QVBoxLayout( this );
- base->setMargin( 0 );
- base->addWidget( myWidget );
+ if ( myWidget )
+ {
+ myWidget->setParent( this, f );
+ myWidget->installEventFilter( this );
+ if ( myWidget->focusProxy() )
+ myWidget->focusProxy()->installEventFilter( this );
+ myWidget->setVisible( myWidget->isVisibleTo( myWidget->parentWidget() ) );
- connect( myWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ QVBoxLayout* base = new QVBoxLayout( this );
+ base->setMargin( 0 );
+ base->addWidget( myWidget );
+
+ connect( myWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+ }
}
/*!
widget()->hide();
widget()->removeEventFilter( this );
+ if ( widget()->focusProxy() )
+ widget()->focusProxy()->removeEventFilter( this );
widget()->setParent( 0 );
}
return myWidget;
}
+/*!
+ \brief Returns the id.
+*/
+int QtxWorkstackChild::id() const
+{
+ return myId;
+}
+
+/*!
+ \brief Sets the id.
+*/
+void QtxWorkstackChild::setId( const int id )
+{
+ myId = id;
+}
+
+/*!
+ \brief Returns true if this child window should be visible.
+*/
+bool QtxWorkstackChild::visibility()
+{
+ return myWidget ? myWidget->isVisibleTo( this ) : false;
+}
+
+QtxWorkstackArea* QtxWorkstackChild::area() const
+{
+ QtxWorkstackArea* a = 0;
+ QWidget* w = parentWidget();
+ while ( !a && w )
+ {
+ a = ::qobject_cast<QtxWorkstackArea*>( w );
+ w = w->parentWidget();
+ }
+
+ return a;
+}
+
/*!
\brief Custom event filter.
*/
void QtxWorkstackChild::onDestroyed( QObject* obj )
{
- if ( obj != widget() )
- return;
-
- myWidget = 0;
deleteLater();
}
*/
QtxWorkstackTabBar::QtxWorkstackTabBar( QWidget* parent )
: QTabBar( parent ),
- myId( -1 )
+ myId( -1 ),myActive(false)
{
setDrawBase( true );
setElideMode( Qt::ElideNone );
\brief Workstack widget.
Organizes the child widgets in the tabbed space.
- Allows splitting the working area to arrange the child widgets in
+ Allows splitting the working area to arrange the child widgets in
arbitrary way. Any widgets can be moved to another working area with
drag-n-drop operation.
- This widget can be used as workspace of the application main window,
+ This widget can be used as workspace of the application main window,
for example, as kind of implementation of multi-document interface.
*/
QVBoxLayout* base = new QVBoxLayout( this );
base->setMargin( 0 );
- mySplit = new QSplitter( this );
- mySplit->setChildrenCollapsible( false );
+ mySplit = new QtxWorkstackSplitter( this );
base->addWidget( mySplit );
}
}
/*!
- \brief Get list of all widgets in all areas or in specified area which given
+ \brief Get list of all widgets in all areas or in specified area which given
widget belongs to
- \param wid widget specifying area if it is equal to null when widgets of all
+ \param wid widget specifying area if it is equal to null when widgets of all
areas are retuned
\return list of widgets
*/
{
areas( mySplit, lst, true );
}
- else
+ else
{
QtxWorkstackArea* area = wgArea( wid );
if ( area )
return myWin;
}
+/*!
+ \brief Set active widget
+ \param wid widget to activate
+*/
+void QtxWorkstack::setActiveWindow( QWidget* wid )
+{
+ if ( activeArea() )
+ activeArea()->setActiveWidget( wid );
+}
+
/*!
\brief Split workstack.
QList<QtxWorkstackArea*> allAreas;
areas(mySplit, allAreas, true);
-
for ( QList<QtxWorkstackArea*>::iterator it = allAreas.begin(); it != allAreas.end() && !area; ++it )
{
if ( (*it)->contains( wid ) )
if ( !area )
return;
+ QWidget* curWid = area->activeWidget();
+ if ( !curWid )
+ return;
+
QWidgetList wids = area->widgetList();
if ( wids.count() < 2 )
return;
{
area->removeWidget( wid_i );
newArea->insertWidget( wid_i );
+ wid_i->showMaximized();
}
}
break;
{
area->removeWidget( *itr );
newArea->insertWidget( *itr );
+ (*itr)->showMaximized();
}
}
break;
case SplitMove:
area->removeWidget( wid );
newArea->insertWidget( wid );
+ wid->showMaximized();
break;
}
distributeSpace( trg );
+
+ curWid->show();
+ curWid->setFocus();
}
/*!
if ( !area1 || !area2 )
return;
+ QSplitter* s1 = splitter( area1 );
+
QWidget* curWid = area1->activeWidget();
if ( !curWid )
return;
// Set wid1 at first position, wid2 at second
area1->insertWidget( wid1 );
area1->insertWidget( wid2, 1 );
+ wid1->showMaximized();
+ wid2->showMaximized();
}
else
{
QWidgetList wids1 = area1->widgetList();
for ( QWidgetList::iterator itr1 = wids1.begin(); itr1 != wids1.end() && *itr1 != wid1; ++itr1, ++wid1_ind );
area1->insertWidget( wid2, wid1_ind + 1 );
+ wid2->showMaximized();
}
}
else
area1->insertWidget( *itr2, wid1_ind + 1 );
else
area1->insertWidget( *itr2, ind );
+ (*itr2)->showMaximized();
}
}
else
// Set wid2 right after wid1
area2->removeWidget( wid2 );
area1->insertWidget( wid2, wid1_ind + 1 );
+ wid2->showMaximized();
}
}
+ distributeSpace( s1 );
+
area1->setActiveWidget( curWid );
+
+ wid2->show();
+ wid1->setFocus();
+ curWid->show();
+ curWid->setFocus();
}
/*!
{
int res = 0;
if ( myActionsMap.contains( id ) )
- res = myActionsMap[id]->shortcut();
+ res = myActionsMap[id]->shortcut()[0];
return res;
}
/*!
\brief Set actions to be visible in the context popup menu.
-
- Actions, which IDs are set in \a flags parameter, will be shown in the
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
context popup menu. Other actions will not be shown.
\param flags ORed together actions flags
/*!
\brief Set actions to be visible in the context popup menu.
-
- Actions, which IDs are set in \a flags parameter, will be shown in the
+
+ Actions, which IDs are set in \a flags parameter, will be shown in the
context popup menu. Other actions will not be shown.
\param flags ORed together actions flags
QIntList szList = pSplit->sizes();
- QSplitter* wrap = new QSplitter( 0 );
- wrap->setChildrenCollapsible( false );
+ QSplitter* wrap = new QtxWorkstackSplitter( 0 );
pSplit->insertWidget( pSplit->indexOf( area ) + 1, wrap );
wrap->setVisible( true );
wrap->addWidget( area );
for ( QWidgetList::iterator itr = moveList.begin(); itr != moveList.end(); ++itr )
{
(*itr)->setParent( pWid );
- (*itr)->setShown( map.contains( *itr ) ? map[*itr] : false );
+ (*itr)->setVisible( map.contains( *itr ) ? map[*itr] : false );
}
}
if ( lst.count() > 1 )
{
- if ( myActionsMap[SplitVertical]->isEnabled() )
- pm->addAction( myActionsMap[SplitVertical] );
- if ( myActionsMap[SplitHorizontal]->isEnabled() )
- pm->addAction( myActionsMap[SplitHorizontal] );
+ if ( !myActionsMap[SplitVertical]->isEnabled() )
+ myActionsMap[SplitVertical]->setEnabled(true);
+ pm->addAction( myActionsMap[SplitVertical] );
+ if ( !myActionsMap[SplitHorizontal]->isEnabled() )
+ myActionsMap[SplitHorizontal]->setEnabled(true);
+ pm->addAction( myActionsMap[SplitHorizontal] );
pm->addSeparator();
}
connect( area, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
connect( area, SIGNAL( activated( QWidget* ) ), this, SLOT( onWindowActivated( QWidget* ) ) );
connect( area, SIGNAL( contextMenuRequested( QWidget*, QPoint ) ),
- this, SLOT( onContextMenuRequested( QWidget*, QPoint ) ) );
+ this, SLOT( onContextMenuRequested( QWidget*, QPoint ) ) );
connect( area, SIGNAL( deactivated( QtxWorkstackArea* ) ), this, SLOT( onDeactivated( QtxWorkstackArea* ) ) );
return area;
if ( areaList.isEmpty() && splitList.isEmpty() )
delete split;
- else if ( vis )
- split->show();
else
- split->hide();
+ split->setVisible( vis );
}
/*!
- \brief Get splitter info (for debug purposes)
- \param split splitter
- \param info string to be filled with splitter data.
+ \brief Dump workstack configuration to the state description array.
+ \param version number
+ \return state byte array.
*/
-void QtxWorkstack::splitterInfo( QSplitter* split, QString& info ) const
+QByteArray QtxWorkstack::saveState( int version ) const
{
- if ( !split )
- return;
-
- /*const QObjectList& objs = */split->children(); // VSR: is it needed ???
+ QByteArray data;
- QString sizesStr;
- QList<int> sizes = split->sizes();
- for ( QList<int>::iterator sIt = sizes.begin(); sIt != sizes.end(); ++sIt )
- {
- if ( *sIt > 1 ) // size 1 pixel usually means empty Workstack area, which will NOT be re-created,
- sizesStr += QString( ":%1" ).arg( *sIt ); // so we don't need to store its size
- }
+ QDataStream stream( &data, QIODevice::WriteOnly );
+ stream << QtxWorkstack::VersionMarker;
+ stream << version;
+ saveState( stream );
- if ( !sizesStr.isEmpty() ) // cut the first ':'
- sizesStr = sizesStr.right( sizesStr.length() - 1 );
-
- info += QString( "(splitter orientation=%1 sizes=%3 " ).arg( split->orientation() ).arg( sizesStr );
-
- for( int index = 0, count = split->count(); index < count; index++ )
- {
- QObject* obj = split->widget( index );
- if ( obj->inherits( "QSplitter" ) )
- splitterInfo( (QSplitter*)obj, info );
- else if ( obj->inherits( "QtxWorkstackArea" ) )
- {
- QtxWorkstackArea* area = (QtxWorkstackArea*)obj;
- if ( area->isEmpty() )
- continue;
- info += QString( "(views active='%1'" ).arg( area->activeWidget()->objectName() );
- QWidgetList views = area->widgetList();
- for ( QWidgetList::iterator wIt = views.begin(); wIt != views.end(); ++wIt )
- info += QString( " '%1'" ).arg( (*wIt)->objectName() );
- info += ')';
- }
- }
-
- info += ')';
- printf( (const char*)QString( info + '\n' ).toLatin1() );
+ return data;
}
/*!
- \brief Remove round brackets symbols from the string.
- \internal
- \param parameters string to be processed
+ \brief Restore workstack configuration from the state description array.
+ \param version number
+ \return restore performing state
*/
-static void cutBrackets( QString& parameters )
+bool QtxWorkstack::restoreState( const QByteArray& state, int version )
{
- QChar c1 = parameters[0];
- QChar c2 = parameters[int(parameters.length()-1)];
- if ( !parameters.isEmpty() && c1 == '(' && c2 == ')' )
- parameters = parameters.mid( 1, parameters.length()-2 );
-}
+ if ( state.isEmpty() )
+ return false;
-/*!
- \brief Parse string to get some parameter value.
- \internal
+ QByteArray sd = state;
+ QDataStream stream( &sd, QIODevice::ReadOnly );
+ int marker, ver;
+ stream >> marker;
+ stream >> ver;
+ if ( stream.status() != QDataStream::Ok || marker != QtxWorkstack::VersionMarker || ver != version )
+ return false;
- String \a str can contain the parameters description of kind "<param>=<value> ...".
- For example:
- \code
- QString s = "splitter orientation=0 children=2 sizes=332:478";
- QString orient_val = getValue( s, "children" ); // orient_val contains "2"
- QString size_val = getValue( s, "sizes" ); // val contains "332:478"
- \endcode
+ return restoreState( stream );
+}
- \param str string to be processed
- \param valName parameter name
- \return parameter value (or null QStrinhg if parameter is not found)
-*/
-static QString getValue( const QString& str, const QString& valName )
+void QtxWorkstack::saveState( QDataStream& stream ) const
+{
+ mySplit->saveState( stream );
+}
+
+bool QtxWorkstack::restoreState( QDataStream& stream )
{
- int i = str.indexOf( valName );
- if ( i != -1 )
+ QMap<QString, QtxWorkstackChild*> map;
+ QList<QtxWorkstackArea*> areaList;
+ areas( mySplit, areaList, true );
+ for ( QList<QtxWorkstackArea*>::const_iterator it = areaList.begin(); it != areaList.end(); ++it )
{
- int equal_i = str.indexOf( '=', i );
- if ( equal_i != -1 )
+ QtxWorkstackArea* area = *it;
+ QList<QtxWorkstackChild*> childList = area->childList();
+ for ( QList<QtxWorkstackChild*>::iterator itr = childList.begin(); itr != childList.end(); ++itr )
{
- int space_i = str.indexOf( ' ', ++equal_i );
- if ( space_i != -1 )
- return str.mid( equal_i, space_i - equal_i );
+ QtxWorkstackChild* c = *itr;
+ if ( !c->widget() )
+ continue;
+
+ map.insert( c->widget()->objectName(), c );
+
+ qDebug( "QtxWorkstack::restoreState: found widget \"%s\"", (const char*)c->widget()->objectName().toLatin1() );
}
}
- return QString();
-}
-/*!
- \brief Check format of splitter parameters string.
- \internal
- \param parameters splitter parameters description
- \return \c true on success and \c false on error
-*/
-static bool checkFormat( const QString& parameters )
-{
- QString params( parameters );
- // 1. begins and ends with brackets
- QChar c1 = params[0];
- QChar c2 = params[int(params.length()-1)];
- bool ok = ( c1 == '(' && c2 == ')' );
- if ( !ok ) return ok;
- ::cutBrackets( params );
- // 2. has splitter word
- ok = ( params.left( 8 ) == "splitter" );
- if ( !ok ) return ok;
- // 3. has children? = '(' is found
- int i = params.indexOf( '(' );
- ok = i != -1;
- if ( !ok ) return ok;
- params = params.left( i ); // cut all children, they will be checked later
- // 4. has orientation word and correct value
- ::getValue( params, "orientation" ).toInt( &ok );
- if ( !ok ) return ok;
- // 5. has sizes word and values
- ok = ! ::getValue( params, "sizes" ).isEmpty();
- if ( !ok ) return ok;
- // 6. check children -> number of '(' == number of ')' in original string
- ok = ( parameters.contains( '(' ) == parameters.contains( ')' ) );
- return ok;
-}
-
-/*!
- \brief Get splitter's children descriptions from the string.
- \internal
-
- Child widgets descriptions are separated by '(' and ')' symbols.
+ int marker;
+ stream >> marker;
+ if ( stream.status() != QDataStream::Ok || marker != QtxWorkstack::SplitMarker )
+ return false;
- \param str string to be processed
- \return child widgets descriptions
-*/
-static QStringList getChildren( const QString& str )
-{
- QStringList lst;
- if ( !str.startsWith( "(" ) )
- return lst;
+ QtxWorkstackSplitter* split = new QtxWorkstackSplitter( this );
+ if ( layout() )
+ layout()->addWidget( split );
- int i = 1,
- nOpen = 1, // count brackets: '(' increments nOpen, ')' decrements
- start = 0;
- while ( i < (int)str.length() )
+ bool ok = split->restoreState( stream, map );
+ if ( !ok )
+ delete split;
+ else
{
- if ( str[i] == '(' )
- {
- nOpen++;
- if ( nOpen == 1 )
- start = i;
- }
- else if ( str[i] == ')' )
+ mySplit->deleteLater();
+ mySplit = split;
+
+ QList<QtxWorkstackArea*> aList;
+ areas( mySplit, aList, true );
+
+ QtxWorkstackArea* a = !aList.isEmpty() ? aList.first() : 0;
+ for ( QMap<QString, QtxWorkstackChild*>::const_iterator it = map.begin(); it != map.end(); ++it )
{
- nOpen--;
- if ( nOpen == 0 )
- lst.append( str.mid( start, i-start+1 ) );
+ QtxWorkstackChild* c = it.value();
+ if ( c->widget() )
+ c->widget()->setVisible( false );
+ if ( a )
+ a->insertChild( c );
+ else
+ c->setVisible( false );
}
- i++;
}
- return lst;
+ return ok;
}
/*!
- \brief Get view name by index.
- \internal
-
- Example:
- \code
- QString s = "views active='AnotherView' 'GLView' 'AnotherView'";
- QString a0 = getViewName( s, 0 ); // --> a0 contains "GLView"
- QString a1 = getViewName( s, 1 ); // --> a1 contains "AnotherView"
- \endcode
-
- \param str string to be processed
- \param i index
- \return view name
+ \brief Set resize mode of all splitters opaque or transparent.
+ \param opaque opaque mode
*/
-static QString getViewName( const QString& str, int i )
+void QtxWorkstack::setOpaqueResize( bool opaque )
{
- QRegExp exp( "\\s'\\w+'" );
- int start = 0; // start index of view name in the string
- int num = 0 ; // index of found match
- while ( ( start = exp.indexIn( str, start ) ) != -1 && num < i )
- {
- start += exp.matchedLength();
- num ++;
- }
- if ( start != -1 ) // +2 and -3 avoid starting space and starting and ending ' symbols
- return str.mid( start + 2, exp.matchedLength() - 3 );
-
- return QString();
+ QList<QSplitter*> splitList;
+ splitters( mySplit, splitList, true );
+ splitList << mySplit;
+ foreach( QSplitter* split, splitList )
+ split->setOpaqueResize( opaque );
}
/*!
- \brief Get child widget with specified name.
- \internal
- \param parent parent widget
- \param aName child widget name
- \return child widget or 0 if not found
+ \brief Get resize mode of all splitters: opaque (\c true) or transparent (\c false).
+ \return current opaque mode
*/
-static QWidget* getView( const QWidget* parent, const QString& aName )
+bool QtxWorkstack::opaqueResize() const
{
- QWidget* view = 0;
- QList<QWidget*> l = qFindChildren<QWidget*>( parent->topLevelWidget(), aName );
- if ( !l.isEmpty() )
- view = ::qobject_cast<QWidget*>( l.first() );
- return view;
+ return mySplit->opaqueResize();
}
/*!
- \brief Setup splitter according to the specified parameters string.
- \param splitter splitter to be set up
- \param parameters splitter parameters description
- \param sMap map containing resulting child splitters sizes
+ \brief Show/hide splitter state and area.
+ \param wid widget (and parent area) will be shown/hidden
+ \param parent_list parent splitters list
+ \param split splitter will be shown/hidden
+ \param visible splitter
*/
-void QtxWorkstack::setSplitter( QSplitter* splitter, const QString& parameters, QMap<QSplitter*, QList<int> >& sMap )
+void QtxWorkstack::splitterVisible(QWidget* wid, QList<QSplitter*>& parent_list, QSplitter* split, bool visible)
{
- printf( QString( parameters + '\n' ).toLatin1() );
- if ( !::checkFormat( parameters ) ) {
- printf( "\nInvalid format of workstack parameters. Positions of viewers can not be restored.\n" );
- return;
+ QList<QSplitter*> recList;
+ splitters( split, recList, false );
+ for ( QList<QSplitter*>::iterator itr = recList.begin(); itr != recList.end(); ++itr ) {
+ parent_list.prepend( *itr );
+ splitterVisible( wid, parent_list, *itr, visible );
}
- QString params( parameters );
- ::cutBrackets( params );
-
- // get splitter sizes and store it in the map for future setting
- QList<int> sizes;
- QStringList sizesLst = ::getValue( params, "sizes" ).split( ':', QString::SkipEmptyParts );
- QStringList::Iterator it;
- for ( it = sizesLst.begin(); it != sizesLst.end(); ++it )
- sizes.append( (*it).toInt() );
- sMap[ splitter ] = sizes;
-
- // set orientation of splitter
- int orient = ::getValue( params, "orientation" ).toInt();
- splitter->setOrientation( (Qt::Orientation)orient );
-
- // get children
- QString options = params.left( params.indexOf( '(' ) );
- QString childrenStr = params.right( params.length()-options.length() );
- QStringList children = ::getChildren( childrenStr );
-
- // debug output..
- // printf (" splitter orient=%d, sizes_count=%d, children=%d\n", orient, sizes.count(), children.count() );
- // for ( QStringList::Iterator tit = children.begin(); tit != children.end(); ++tit )
- // printf (" |-> child = [%s]\n", (*tit).latin1() );
-
- for ( it = children.begin(); it != children.end(); ++it )
- {
- if ( (*it).startsWith( "(splitter" ) )
- {
- QSplitter* newSplitter = new QSplitter( splitter );
- setSplitter( newSplitter, *it, sMap );
- }
- else if ( (*it).startsWith( "(views" ) )
- {
- QtxWorkstackArea* newArea = createArea( splitter );
- QString activeViewName = ::getValue( *it, "active" );
- QWidget* activeView = 0;
- activeViewName = activeViewName.mid( 1, activeViewName.length()-2 ); // chop off ' symbols
- int i = 0;
- QString viewName = ::getViewName( *it, i );
- while ( !viewName.isEmpty() )
- {
- if ( QWidget* view = ::getView( splitter, viewName ) )
- {
- newArea->insertWidget( view );
- if ( activeViewName == view->objectName() )
- activeView = view;
- }
- viewName = ::getViewName( *it, ++i );
+ QList<QtxWorkstackArea*> areaList;
+ areas( split, areaList, false );
+ for ( QList<QtxWorkstackArea*>::const_iterator it = areaList.begin(); it != areaList.end(); ++it ) {
+ QtxWorkstackArea* area = *it;
+ bool isCurrentWidget = false;
+
+ area->showTabBar(visible);
+
+ // 1. Looking for the selected widget at the lowest level among all splitted areas.
+ QList<QtxWorkstackChild*> childList = area->childList();
+ for ( QList<QtxWorkstackChild*>::iterator itr = childList.begin(); itr != childList.end(); ++itr ) {
+ QWidget* aCurWid = (*itr)->widget();
+ if ( aCurWid == wid ) {
+ isCurrentWidget = true;
+ aCurWid->setVisible( true );
}
- if ( activeView )
- newArea->setActiveWidget( activeView );
+ else
+ aCurWid->setVisible( visible );
}
- }
-}
-/*!
- \brief Restore workstack configuration from the state description string.
- \param parameters workstack state description
- \return reference to this workstack
-*/
-QtxWorkstack& QtxWorkstack::operator<<( const QString& parameters )
-{
- // clear the main splitter - remove all child splitters and empty areas from it
- QList<QSplitter*> splitList;
- QList<QtxWorkstackArea*> areaList;
- splitters( mySplit, splitList, false );
- areas( mySplit, areaList, false );
- for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end(); ++iter )
- delete *iter;
+ // 2. Show/Hide other areas and widgets that don't contain the desired widget
+ if ( !isCurrentWidget || visible )
+ area->setVisible( visible );
- for ( QList<QtxWorkstackArea*>::iterator it = areaList.begin(); it != areaList.end(); ++it )
- {
- if ( (*it)->isEmpty() )
- delete *it;
- }
+ if ( !isCurrentWidget && !visible )
+ continue;
- // restore splitter recursively
- QMap< QSplitter*, QList<int> > sMap;
- setSplitter( mySplit, parameters, sMap );
+ // 3. Show/hide all parent widgets
+ QSplitter* pSplit = splitter( area );
+ int count = pSplit->count();
+ for ( int i = 0; i < count; i++ ) {
+ if ( pSplit->indexOf( area ) == i && !visible )
+ continue;
+ pSplit->widget(i)->setVisible( visible );
+ }
- // now mySplit may contains empty area (where all views were located before restoring)
- // in order setSize to work correctly we have to exclude this area
- areaList.clear();
- areas( mySplit, areaList, false );
- for ( QList<QtxWorkstackArea*>::iterator delIt = areaList.begin(); delIt != areaList.end(); ++delIt )
- {
- if ( (*delIt)->isEmpty() )
- delete *delIt;
+ // 4. Show/hide all parent splitters don't contain the selected widget
+ if ( visible )
+ pSplit->setVisible( true );
+
+ if ( isCurrentWidget && !visible ) {
+ for ( QList<QSplitter*>::iterator itr = parent_list.begin(); itr != parent_list.end() && pSplit != mySplit; ++itr ) {
+ if ( pSplit == *itr )
+ continue;
+ QList<QSplitter*> splitList;
+ splitters( *itr, splitList, false );
+ for ( QList<QSplitter*>::iterator iter = splitList.begin(); iter != splitList.end(); ++iter ) {
+ if ( pSplit == (*iter) ) {
+ pSplit = *itr;
+ continue;
+ }
+ (*iter)->setVisible( false );
+ }
+ }
+ }
}
-
- QApplication::instance()->processEvents();
-
- // restore splitters' sizes (map of sizes is filled in setSplitters)
- for ( QMap< QSplitter*, QList<int> >::iterator itm = sMap.begin(); itm != sMap.end(); ++itm )
- itm.key()->setSizes( itm.value() );
-
- return (*this);
}
/*!
- \brief Dump workstack configuration to the state description string.
- \param parameters resulting workstack state description
- \return reference to this workstack
+ \brief Show/hide splitters state and area.
+ \param wid widget (and parent area) will be shown/hidden
+ \param visible splitters
*/
-QtxWorkstack& QtxWorkstack::operator>>( QString& outParameters )
+void QtxWorkstack::splittersVisible( QWidget* wid, bool visible )
{
- splitterInfo( mySplit, outParameters );
- return (*this);
+ QList<QSplitter*> parent_list;
+ parent_list.append( mySplit );
+ splitterVisible( wid, parent_list, mySplit, visible );
}
/*!
\brief Moves the first widget to the same area which the second widget belongs to
\param wid widget to be moved
\param wid_to widget specified the destination area
- \param before specifies whether the first widget has to be moved before or after
+ \param before specifies whether the first widget has to be moved before or after
the second widget
- \return TRUE if operation is completed successfully, FALSE otherwise
+ \return \c true if operation is completed successfully, \c false otherwise
*/
bool QtxWorkstack::move( QWidget* wid, QWidget* wid_to, const bool before )
{
idx++;
area_src->removeWidget( wid, true );
area_to->insertWidget( wid, idx );
+ wid->showMaximized();
return true;
}
}
/*!
\brief Group all windows in one area
- \return TRUE if operation is completed successfully, FALSE otherwise
+ \return \c true if operation is completed successfully, \c false otherwise
*/
void QtxWorkstack::stack()
{
area_to = wgArea( *it );
area_src = area_to;
}
- else
+ else
area_src = wgArea( *it );
if ( area_src != area_to )
{
area_src->removeWidget( *it, true );
area_to->insertWidget( *it, -1 );
+ (*it)->showMaximized();
}
}
}
+
+QAction* QtxWorkstack::action( const int id ) const
+{
+ return myActionsMap.contains( id ) ? myActionsMap[id] : 0;
+}