/* ************************************************************************** description -------------------- copyright : (C) 2002 by Luis Carvalho email : lpassos@mail.telepac.pt copyright : (C) 2003 by Andreas Zehender email : zehender@kde.org ************************************************************************** ************************************************************************** * * * 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. * * * **************************************************************************/ #include "pmviewlayoutmanager.h" #include "pmdockwidget_private.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pmshell.h" #include "pmdebug.h" #include "pmviewfactory.h" PMViewLayoutManager* PMViewLayoutManager::s_pInstance = 0; KStaticDeleter PMViewLayoutManager::s_staticDeleter; //================ PMViewLayoutEntry ==================== PMViewLayoutEntry::PMViewLayoutEntry( ) { m_viewType = "treeview"; m_dockPosition = PMDockWidget::DockRight; m_columnWidth = 33; m_height = 50; m_floatingWidth = 400; m_floatingHeight = 400; m_floatingPositionX = 200; m_floatingPositionY = 200; m_pCustomOptions = 0; } PMViewLayoutEntry::PMViewLayoutEntry( const PMViewLayoutEntry& e ) { m_viewType = e.m_viewType; m_dockPosition = e.m_dockPosition; m_columnWidth = e.m_columnWidth; m_height = e.m_height; m_floatingWidth = e.m_floatingWidth; m_floatingHeight = e.m_floatingHeight; m_floatingPositionX = e.m_floatingPositionX; m_floatingPositionY = e.m_floatingPositionY; if( e.m_pCustomOptions ) m_pCustomOptions = e.m_pCustomOptions->copy( ); else m_pCustomOptions = 0; } PMViewLayoutEntry::~PMViewLayoutEntry( ) { if( m_pCustomOptions ) delete m_pCustomOptions; } void PMViewLayoutEntry::loadData( TQDomElement& e ) { TQString s; bool ok; // Read the view type s = e.tagName( ); m_viewType = s; // Read dock position s = e.attribute( "position", "Right" ); if( s == "Right" ) m_dockPosition = PMDockWidget::DockRight; else if( s == "Bottom" ) m_dockPosition = PMDockWidget::DockBottom; else if( s == "Center" ) m_dockPosition = PMDockWidget::DockCenter; else if( s == "None" ) m_dockPosition = PMDockWidget::DockNone; // Read the column width s = e.attribute( "columnWidth", "33" ); m_columnWidth = s.toInt( &ok ); if( !ok ) m_columnWidth = 33; // and view height s = e.attribute( "height", "50" ); m_height = s.toInt( &ok ); if( !ok ) m_height = 50; s = e.attribute( "floatingHeight", "400" ); m_floatingHeight = s.toInt( &ok ); if( !ok ) m_floatingHeight = 400; s = e.attribute( "floatingWidth", "400" ); m_floatingWidth = s.toInt( &ok ); if( !ok ) m_floatingWidth = 400; s = e.attribute( "floatingPosX", "200" ); m_floatingPositionX = s.toInt( &ok ); if( !ok ) m_floatingPositionX = 200; s = e.attribute( "floatingPosY", "200" ); m_floatingPositionY = s.toInt( &ok ); if( !ok ) m_floatingPositionY = 200; // Load custom options if( m_pCustomOptions ) delete m_pCustomOptions; m_pCustomOptions = PMViewFactory::theFactory( )->newOptionsInstance( m_viewType ); if( m_pCustomOptions ) m_pCustomOptions->loadData( e ); } void PMViewLayoutEntry::saveData( TQDomElement& e ) const { TQString s; e.setTagName( m_viewType ); switch( m_dockPosition ) { case PMDockWidget::DockRight: e.setAttribute( "position", "Right" ); break; case PMDockWidget::DockBottom: e.setAttribute( "position", "Bottom" ); break; case PMDockWidget::DockCenter: e.setAttribute( "position", "Center" ); break; case PMDockWidget::DockNone: e.setAttribute( "position", "None" ); break; default: kdError( PMArea ) << i18n( "Unknown dock position." ) << endl; break; } s.setNum( m_columnWidth ); e.setAttribute( "columnWidth", s ); s.setNum( m_height ); e.setAttribute( "height", s ); s.setNum( m_floatingHeight ); e.setAttribute( "floatingHeight", s ); s.setNum( m_floatingWidth ); e.setAttribute( "floatingWidth", s ); s.setNum( m_floatingPositionX ); e.setAttribute( "floatingPosX", s ); s.setNum( m_floatingPositionY ); e.setAttribute( "floatingPosY", s ); // save custom options if( m_pCustomOptions ) m_pCustomOptions->saveData( e ); } void PMViewLayoutEntry::setViewType( const TQString& v ) { m_viewType = v; } void PMViewLayoutEntry::setDockPosition( PMDockWidget::DockPosition i ) { m_dockPosition = i; } void PMViewLayoutEntry::setColumnWidth( int i ) { m_columnWidth = i; if( i < 1 ) m_columnWidth = 1; } void PMViewLayoutEntry::setHeight( int i ) { m_height = i; if( i < 1 ) m_height = 1; } const TQString PMViewLayoutEntry::viewTypeAsString( ) { PMViewTypeFactory* f = PMViewFactory::theFactory( )->viewFactory( m_viewType ); if( f ) { if( m_pCustomOptions ) return f->description( m_pCustomOptions ); else return f->description( ); } kdError( PMArea ) << i18n( "Unknown view type." )<< endl; return i18n( "Unknown" ); } const TQString PMViewLayoutEntry::dockPositionAsString( ) { switch( m_dockPosition ) { case PMDockWidget::DockRight: return i18n( "New Column" ); case PMDockWidget::DockBottom: return i18n( "Below" ); case PMDockWidget::DockCenter: return i18n( "Tabbed" ); case PMDockWidget::DockNone: return i18n( "Floating" ); default: kdError( PMArea ) << i18n( "Unknown dock position." ) << endl; return i18n( "unknown" ); } } void PMViewLayoutEntry::setCustomOptions( PMViewOptions* o ) { if( m_pCustomOptions && m_pCustomOptions != o ) delete m_pCustomOptions; m_pCustomOptions = o; } //================== PMViewLayout ====================== PMViewLayout::PMViewLayout( ) { m_entries.clear( ); } PMViewLayout::PMViewLayout( const PMViewLayout& vl ) { m_entries = vl.m_entries; m_name = vl.m_name; } PMViewLayout& PMViewLayout::operator = ( const PMViewLayout& vl ) { m_entries = vl.m_entries; m_name = vl.m_name; return *this; } void PMViewLayout::loadData( TQDomElement& e ) { m_entries.clear( ); m_name = e.attribute( "name", "unnamed" ); TQDomNode m = e.firstChild( ); while( !m.isNull( ) ) { if( m.isElement( ) ) { TQDomElement me = m.toElement( ); PMViewLayoutEntry vle; vle.loadData( me ); m_entries.append( vle ); } m = m.nextSibling( ); } normalize( ); } void PMViewLayout::saveData( TQDomElement& e, TQDomDocument& doc ) const { TQValueList< PMViewLayoutEntry>::const_iterator it; e.setAttribute( "name", m_name ); for( it = m_entries.begin( ); it != m_entries.end( ) ; ++it ) { TQDomElement a; a = doc.createElement( "unknown" ); ( *it ).saveData( a ); e.appendChild( a ); } } void PMViewLayout::setName( const TQString& n ) { m_name = n; } void PMViewLayout::addEntry( const PMViewLayoutEntry& e, int index ) { if( index == -1 ) m_entries.append( e ); else m_entries.insert( m_entries.at( index ), 1, e ); } void PMViewLayout::removeEntry( int index ) { m_entries.remove( m_entries.at( index ) ); } void PMViewLayout::displayLayout( PMShell* shell ) { PMDockWidget* lastWidget = 0; TQValueList< PMViewLayoutEntry>::const_iterator it; bool isViewSet = false; int lastWidth = 0, width = 100; int lastHeight = 0, height = 100; for( it = m_entries.begin( ); it != m_entries.end( ) ; ++it ) { PMDockWidget* dock = shell->createView( ( *it ).viewType( ), ( *it ).customOptions( ), false ); // Dock the widget if( ( *it ).dockPosition( ) == PMDockWidget::DockNone ) { // the specified target is the desktop dock->manualDock( 0, PMDockWidget::DockDesktop, 50, TQPoint( ( *it ).floatingPositionX( ), ( *it ).floatingPositionY( ) ) ); dock->resize( ( *it ).floatingWidth( ), ( *it ).floatingHeight( ) ); dock->show( ); } else { // the first dockwidget is not docked but placed on all the window // through setView( ) if( !isViewSet ) { shell->setView( dock ); isViewSet = true; lastWidget = dock; } else { switch( ( *it ).dockPosition( ) ) { case PMDockWidget::DockRight: dock->manualDock( lastWidget, ( *it ).dockPosition( ), lastWidth * 100 / width ); width -= lastWidth; if( width < 1 ) width = 1; height = 100; lastWidget = dock; break; case PMDockWidget::DockBottom: dock->manualDock( lastWidget, ( *it ).dockPosition( ), lastHeight * 100 / height ); height -= lastHeight; if( height < 1 ) height = 1; lastWidget = dock; break; case PMDockWidget::DockCenter: dock->manualDock( lastWidget, ( *it ).dockPosition( ), 100 ); break; default: dock->manualDock( 0, PMDockWidget::DockDesktop, 100 ); break; } } switch( ( *it ).dockPosition( ) ) { case PMDockWidget::DockRight: lastWidth = ( *it ).columnWidth( ); lastHeight = ( *it ).height( ); break; case PMDockWidget::DockBottom: lastHeight = ( *it ).height( ); break; default: break; } } } } void PMViewLayout::normalize( ) { iterator it; int sumColWidth = 0; it = m_entries.begin( ); // the first entry has to be a new column if( it != m_entries.end( ) ) if( ( *it ).dockPosition( ) != PMDockWidget::DockRight ) ( *it ).setDockPosition( PMDockWidget::DockRight ); // find negative or zero widths and heights for( it = m_entries.begin( ); it != m_entries.end( ); ++it ) { if( ( *it ).columnWidth( ) < 1 ) ( *it ).setColumnWidth( 1 ); if( ( *it ).height( ) < 1 ) ( *it ).setHeight( 1 ); } // normalize the column widths for( it = m_entries.begin( ); it != m_entries.end( ); ++it ) if( ( *it ).dockPosition( ) == PMDockWidget::DockRight ) sumColWidth += ( *it ).columnWidth( ); if( sumColWidth == 0 ) sumColWidth = 1; for( it = m_entries.begin( ); it != m_entries.end( ); ++it ) { if( ( *it ).dockPosition( ) == PMDockWidget::DockRight ) { ( *it ).setColumnWidth( ( int ) ( ( *it ).columnWidth( ) * 100.0 / sumColWidth + 0.5 ) ); // normalize each column iterator it2 = it; int height = ( *it ).height( ); for( it2++; it2 != m_entries.end( ) && ( *it2 ).dockPosition( ) != PMDockWidget::DockRight; ++it2 ) if( ( *it2 ).dockPosition( ) == PMDockWidget::DockBottom ) height += ( *it2 ).height( ); if( height == 0 ) height = 1; ( *it ).setHeight( ( int ) ( ( *it ).height( ) * 100.0 / height + 0.5 ) ); it2 = it; for( it2++; it2 != m_entries.end( ) && ( *it2 ).dockPosition( ) != PMDockWidget::DockRight; ++it2 ) if( ( *it2 ).dockPosition( ) == PMDockWidget::DockBottom ) ( *it2 ).setHeight( ( int ) ( ( *it2 ).height( ) * 100.0 / height + 0.5 ) ); } } } PMViewLayout PMViewLayout::extractViewLayout( PMShell* shell ) { PMViewLayout layout; TQValueList< TQValueList< PMViewLayoutEntry > > cols; cols.append( TQValueList< PMViewLayoutEntry >( ) ); // find docked widgets recursiveExtractColumns( cols, cols.begin( ), 100, shell->centralWidget( ) ); TQValueListIterator< TQValueList< PMViewLayoutEntry > > cit; TQValueListIterator< PMViewLayoutEntry > eit; for( cit = cols.begin( ); cit != cols.end( ); ++cit ) for( eit = ( *cit ).begin( ); eit != ( *cit ).end( ); ++eit ) layout.addEntry( *eit ); // find floating widgets TQPtrList list; shell->manager( )->findFloatingWidgets( list ); TQPtrListIterator it( list ); for( ; it.current( ); ++it ) { kdDebug( PMArea ) << it.current( ) << " " << it.current( )->isVisible( ) << endl; TQWidget* w = it.current( )->getWidget( ); if( w ) { bool invalid = false; PMViewLayoutEntry e; e.setDockPosition( PMDockWidget::DockNone ); TQPoint p = it.current( )->pos( ); e.setFloatingPositionX( p.x( ) ); e.setFloatingPositionY( p.y( ) ); e.setFloatingWidth( it.current( )->width( ) ); e.setFloatingHeight( it.current( )->height( ) ); if( w->inherits( "PMViewBase" ) ) { PMViewBase* v = ( PMViewBase* ) w; e.setViewType( v->viewType( ) ); PMViewOptions* vo = PMViewFactory::theFactory( )->newOptionsInstance( v->viewType( ) ); if( vo ) { v->saveViewConfig( vo ); e.setCustomOptions( vo ); } } else invalid = true; if( !invalid ) layout.addEntry( e ); } } return layout; } void PMViewLayout::recursiveExtractColumns( TQValueList< TQValueList< PMViewLayoutEntry > >& cols, TQValueList< TQValueList< PMViewLayoutEntry > >::iterator cit, int width, TQWidget* widget ) { if( !widget ) return; if( widget->inherits( "PMDockWidget" ) ) { PMDockWidget* dw = ( PMDockWidget* ) widget; TQWidget* w = dw->getWidget( ); if( w ) { bool colStart = true; if( w->inherits( "PMDockSplitter" ) ) { PMDockSplitter* sp = ( PMDockSplitter* ) w; if( sp->splitterOrientation( ) == Qt::Vertical ) { colStart = false; // vertical splitter, split up the current column int w1 = ( int ) ( width * 0.01 * sp->separatorPos( ) + 0.5 ); int w2 = width - w1; if( w1 == 0 ) w1++; if( w2 == 0 ) w2++; TQValueList< TQValueList< PMViewLayoutEntry > >::iterator cit1 = cols.insert( cit, TQValueList< PMViewLayoutEntry >( ) ); recursiveExtractColumns( cols, cit1, w1, sp->getFirst( ) ); recursiveExtractColumns( cols, cit, w2, sp->getLast( ) ); } } if( colStart ) { // widget is a view, a horizontal splitter or a tab widget // a new column starts PMViewLayoutEntry e; e.setColumnWidth( width ); ( *cit ).append( e ); recursiveExtractOneColumn( *cit, ( *cit ).begin( ), 100, dw ); } } } } void PMViewLayout::recursiveExtractOneColumn( TQValueList< PMViewLayoutEntry >& entries, TQValueList< PMViewLayoutEntry >::iterator eit, int height, TQWidget* widget ) { if( !widget ) return; if( widget->inherits( "PMDockWidget" ) ) { PMDockWidget* dw = ( PMDockWidget* ) widget; TQWidget* w = dw->getWidget( ); if( w ) { if( w->inherits( "PMDockSplitter" ) ) { PMDockSplitter* sp = ( PMDockSplitter* ) w; // splitter, split up the current column int h1 = ( int ) ( height * 0.01 * sp->separatorPos( ) + 0.5 ); int h2 = height - h1; if( h1 == 0 ) h1++; if( h2 == 0 ) h2++; ( *eit ).setHeight( h1 ); ( *eit ).setDockPosition( PMDockWidget::DockRight ); PMViewLayoutEntry e; e.setHeight( h2 ); e.setDockPosition( PMDockWidget::DockBottom ); TQValueList< PMViewLayoutEntry >::iterator eit1 = eit; eit1 = entries.insert( ++eit1, e ); recursiveExtractOneColumn( entries, eit, h1, sp->getFirst( ) ); recursiveExtractOneColumn( entries, eit1, h2, sp->getLast( ) ); } else if( w->inherits( "PMDockTabGroup" ) ) { PMDockTabGroup* g = ( PMDockTabGroup* ) w; int num = g->count( ); TQWidget* tw; int i; for( i = 0; i < num; i++ ) { tw = g->page( i ); if( i == 0 ) recursiveExtractOneColumn( entries, eit, height, tw ); else { PMViewLayoutEntry e; e.setHeight( height ); e.setDockPosition( PMDockWidget::DockCenter ); eit++; eit = entries.insert( eit, e ); recursiveExtractOneColumn( entries, eit, height, tw ); } } } else { // a kpovmodeler view??? if( w->inherits( "PMViewBase" ) ) { PMViewBase* v = ( PMViewBase* ) w; ( *eit ).setViewType( v->viewType( ) ); PMViewOptions* vo = PMViewFactory::theFactory( )->newOptionsInstance( v->viewType( ) ); if( vo ) { v->saveViewConfig( vo ); ( *eit ).setCustomOptions( vo ); } } } } } } //=============== PMViewLayoutManager =================== PMViewLayoutManager::PMViewLayoutManager( ) { m_layoutsLoaded = false; m_layoutDisplayed = false; loadData( ); } PMViewLayoutManager::~PMViewLayoutManager( ) { } void PMViewLayoutManager::setDefaultLayout( const TQString& name ) { m_defaultLayout = name; } TQStringList PMViewLayoutManager::availableLayouts( ) { TQStringList result; TQValueListIterator it; for( it = m_layouts.begin( ); it != m_layouts.end( ); ++it ) result.push_back( ( *it ).name( ) ); return result; } void PMViewLayoutManager::loadData( ) { if( m_layoutsLoaded ) m_layouts.clear( ); m_layoutsLoaded = true; TQString fileName = locate( "data", "kpovmodeler/viewlayouts.xml" ); if( fileName.isEmpty( ) ) { // Generate a default layout // I have a feeling this shouldn't be here but hey, it works for now // TODO Must find a way to move this cleanly to PMShell PMViewLayout a; a.setName( i18n( "Default" ) ); PMViewLayoutEntry p; p.setViewType( "treeview" ); p.setDockPosition( PMDockWidget::DockRight ); p.setHeight( 50 ); p.setColumnWidth( 33 ); a.addEntry( p ); p.setViewType( "dialogview" ); p.setDockPosition( PMDockWidget::DockBottom ); p.setHeight( 50 ); a.addEntry( p ); p.setViewType( "glview" ); p.setCustomOptions( new PMGLViewOptions( PMGLView::PMViewPosX ) ); p.setDockPosition( PMDockWidget::DockRight ); p.setHeight( 50 ); p.setColumnWidth( 33 ); a.addEntry( p ); p.setCustomOptions( new PMGLViewOptions( PMGLView::PMViewNegY ) ); p.setDockPosition( PMDockWidget::DockBottom ); p.setHeight( 50 ); a.addEntry( p ); p.setCustomOptions( new PMGLViewOptions( PMGLView::PMViewPosZ ) ); p.setDockPosition( PMDockWidget::DockRight ); p.setHeight( 50 ); p.setColumnWidth( 33 ); a.addEntry( p ); p.setCustomOptions( new PMGLViewOptions( PMGLView::PMViewCamera ) ); p.setDockPosition( PMDockWidget::DockBottom ); p.setHeight( 50 ); a.addEntry( p ); m_layouts.append( a ); m_defaultLayout = a.name( ); return; } TQFile file( fileName ); if( !file.open( IO_ReadOnly ) ) { kdError( PMArea ) << i18n( "Could not open the view layouts file." ) << endl; return; } TQDomDocument doc( "VIEWLAYOUTS" ); doc.setContent( &file ); TQDomElement e = doc.documentElement( ); m_defaultLayout = e.attribute( "default", "empty" ); TQDomNode c = e.firstChild( ); TQString str; while( !c.isNull( ) ) { if( c.isElement( ) ) { TQDomElement ce = c.toElement( ); PMViewLayout v; v.loadData( ce ); m_layouts.append( v ); } c = c.nextSibling( ); } } void PMViewLayoutManager::saveData( ) { TQString fileName = locateLocal( "data", "kpovmodeler/viewlayouts.xml" ); if( fileName.isEmpty( ) ) { kdError( PMArea ) << i18n( "View layouts not found." ) << endl; return; } TQFile file( fileName ); if( !file.open( IO_WriteOnly ) ) { kdError( PMArea ) << i18n( "Could not open the view layouts file." ) << endl; return; } TQDomDocument doc( "VIEWLAYOUTS" ); TQDomElement e = doc.createElement( "viewlist" ); e.setAttribute( "default", m_defaultLayout ); TQValueListIterator it; for( it = m_layouts.begin( ); it != m_layouts.end( ); ++it ) { TQDomElement l; l = doc.createElement( "viewlayout" ); ( *it ).saveData( l, doc ); e.appendChild( l ); } doc.appendChild( e ); TQTextStream str( &file ); str.setEncoding( TQTextStream::UnicodeUTF8 ); str << doc.toString( ); file.close( ); } PMViewLayoutManager* PMViewLayoutManager::theManager( ) { if( !s_pInstance ) s_staticDeleter.setObject( s_pInstance, new PMViewLayoutManager( ) ); return s_pInstance; } void PMViewLayoutManager::displayLayout( const TQString& name, PMShell* shell ) { PMViewLayout* v_layout = findLayout( name ); if( v_layout ) { // Destroy the existing dock widgets if( m_layoutDisplayed ) { TQWidgetList lst; if( shell->centralWidget( ) ) shell->manager( )->findChildDockWidget( shell->centralWidget( ), lst ); while( lst.first( ) ) { ( ( PMDockWidget* )lst.first( ) )->undock( ); ( ( PMDockWidget* )lst.first( ) )->close( ); lst.remove( ); } TQPtrList flist; shell->manager( )->findFloatingWidgets( flist ); while( flist.first( ) ) { flist.first( )->undock( ); flist.first( )->close( ); flist.remove( ); } } // Create the new layout v_layout->displayLayout( shell ); m_layoutDisplayed = true; } } void PMViewLayoutManager::displayDefaultLayout( PMShell* shell ) { displayLayout( m_defaultLayout, shell ); } PMViewLayout* PMViewLayoutManager::findLayout( const TQString& name ) { TQValueListIterator it; for( it = m_layouts.begin( ); it != m_layouts.end( ) && ( *it ).name( ) != name; ++it ); if( it == m_layouts.end( ) ) return 0; return &( *it ); } void PMViewLayoutManager::fillPopupMenu( TDEPopupMenu* pMenu ) { TQStringList lst = availableLayouts( ); TQStringList::ConstIterator it = lst.begin( ); pMenu->clear( ); if( it != lst.end( ) ) { for( ; it != lst.end( ); ++it ) pMenu->insertItem( ( *it ) ); } } void PMViewLayoutManager::addLayout( const TQString& name ) { PMViewLayout a; if( m_layouts.isEmpty( ) ) m_defaultLayout = name; a.setName( name ); m_layouts.append( a ); } void PMViewLayoutManager::removeLayout( const TQString& name ) { TQValueListIterator it; for( it = m_layouts.begin( ); it != m_layouts.end( ) && ( *it ).name( ) != name; ++it ); if( it != m_layouts.end( ) ) m_layouts.remove( it ); } PMSaveViewLayoutDialog::PMSaveViewLayoutDialog( PMShell* parent, const char* name ) : KDialogBase( parent, name, true, i18n( "Save View Layout" ), KDialogBase::Ok | KDialogBase::Cancel ) { m_pShell = parent; setButtonOK( KStdGuiItem::save() ); enableButtonOK( false ); TQWidget* w = new TQWidget( this ); TQVBoxLayout* vl = new TQVBoxLayout( w, 0, KDialog::spacingHint( ) ); TQLabel* l = new TQLabel( i18n( "Enter view layout name:" ), w ); vl->addWidget( l ); m_pLayoutName = new TQLineEdit( w ); vl->addWidget( m_pLayoutName ); connect( m_pLayoutName, TQT_SIGNAL( textChanged( const TQString& ) ), TQT_SLOT( slotNameChanged( const TQString& ) ) ); TQListBox* lb = new TQListBox( w ); vl->addWidget( lb ); connect( lb, TQT_SIGNAL( highlighted( const TQString& ) ), TQT_SLOT( slotNameSelected( const TQString& ) ) ); lb->insertStringList( PMViewLayoutManager::theManager( ) ->availableLayouts( ) ); setMainWidget( w ); setInitialSize( TQSize( 300, 200 ) ); } PMSaveViewLayoutDialog::~PMSaveViewLayoutDialog( ) { } void PMSaveViewLayoutDialog::slotOk( ) { TQString name = m_pLayoutName->text( ); PMViewLayoutManager* m = PMViewLayoutManager::theManager( ); PMViewLayout* layout = m->findLayout( name ); PMViewLayout newLayout = PMViewLayout::extractViewLayout( m_pShell ); newLayout.setName( name ); if( layout ) *layout = newLayout; else m->addLayout( newLayout ); m->saveData( ); KDialogBase::slotOk( ); } void PMSaveViewLayoutDialog::slotNameChanged( const TQString& s ) { enableButtonOK( !s.isEmpty( ) ); } void PMSaveViewLayoutDialog::slotNameSelected( const TQString& s ) { m_pLayoutName->setText( s ); } #include "pmviewlayoutmanager.moc"