Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

layoutmanager.cpp

Go to the documentation of this file.
00001 
00002 // Name:        wxLayoutManager.cpp
00003 // Purpose:     wxLayoutManager implementation.
00004 // Author:      Mark McCormack
00005 // Modified by:
00006 // Created:     23/02/04
00007 // RCS-ID:      $Id: layoutmanager.cpp,v 1.11 2005/05/13 15:02:51 frm Exp $
00008 // Copyright:   (c) 2004 Mark McCormack
00009 // Licence:     wxWindows license
00011 
00012 #include <wx/layoutmanager.h>
00013 #include <wx/dockhost.h>
00014 #include <wx/dockpanel.h>
00015 #include <wx/dockwindow.h>
00016 #include <wx/slidebar.h>
00017 #include <wx/util.h>
00018 #include <wx/mdi.h>
00019 #include <wx/xml/xml.h>
00020 #include <wx/gdicmn.h>
00021 #include <wx/filename.h>
00022 #include <wx/list.h>
00023 #include <wx/listimpl.cpp>
00024 
00025 using namespace wxUtil;
00026 
00027 // ----------------------------------------------------------------------------
00028 // wxOwnerEventHandler implementation
00029 // ----------------------------------------------------------------------------
00030 
00031 IMPLEMENT_DYNAMIC_CLASS( wxOwnerEventHandler, wxEvtHandler )
00032 
00033 BEGIN_EVENT_TABLE( wxOwnerEventHandler, wxEvtHandler )
00034     EVT_SIZE(wxOwnerEventHandler::OnSize)
00035     EVT_MOVE(wxOwnerEventHandler::OnMove)
00036     EVT_SLIDEBAR_UPDATE_LAYOUT(wxOwnerEventHandler::OnUpdateLayout)
00037     EVT_MENU( -1, wxOwnerEventHandler::OnMenu)
00038 END_EVENT_TABLE()
00039 
00040 void wxOwnerEventHandler::OnSize( wxSizeEvent &event ) {
00041     if( pOwner_ ) {
00042         pOwner_->OnSize();
00043     }
00044     event.Skip();
00045 }
00046 
00047 void wxOwnerEventHandler::OnMove( wxMoveEvent &event ) {
00048     if( pOwner_ ) {
00049         pOwner_->OnMove();
00050     }
00051     event.Skip();
00052 }
00053 
00054 void wxOwnerEventHandler::OnUpdateLayout( wxCommandEvent& WXUNUSED(event) ) {
00055     if( pOwner_ ) {
00056         pOwner_->OnUpdateLayout();
00057     }
00058 }
00059 
00060 void wxOwnerEventHandler::OnMenu( wxCommandEvent& event ) {
00061     if( pOwner_ ) {
00062         pOwner_->OnMenuToggle( event.GetId() );
00063     }
00064     event.Skip(true);
00065 }
00066 
00067 // ----------------------------------------------------------------------------
00068 // wxLayoutManager constants & wx-macros
00069 // ----------------------------------------------------------------------------
00070 
00071 IMPLEMENT_CLASS( wxLayoutManager, wxObject )
00072 
00073 DEFINE_EVENT_TYPE( wxEVT_LAYOUT_CHANGED )
00074 
00075 WX_DECLARE_LIST( wxDockPanel, DockPanelList );
00076 WX_DEFINE_LIST( DockPanelList );
00077 
00078 WX_DEFINE_LIST( DockHostList );
00079 
00080 #define STREAM_VERSION wxT("wxDocking-Stream-v1.0")
00081 
00082 
00083 
00084 
00085 // ----------------------------------------------------------------------------
00086 // wxLayoutManager implementation
00087 // ----------------------------------------------------------------------------
00088 
00089 wxLayoutManager::wxLayoutManager( wxWindow * pOwnerFrame )
00090     : pOwnerWindow_( pOwnerFrame ) {
00091     Init();
00092     
00093     // install event handler
00094     frameEventHandler_.SetOwner( this );
00095     pOwnerWindow_->PushEventHandler( &frameEventHandler_ );
00096 }
00097 
00098 wxLayoutManager::~wxLayoutManager() {
00099     // uninstall event handler
00100     pOwnerWindow_->RemoveEventHandler( &frameEventHandler_ );
00101 
00102     // make sure all dockwindows extended Show() handling is turned off
00103     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00104         wxDockWindowBase * pDockWindow = node->GetData();
00105         wxASSERT(pDockWindow);
00106         pDockWindow->DisableShowOverride();
00107     }
00108 }
00109 
00110 void wxLayoutManager::Init() {
00111     dockHosts_.Clear();
00112     dockWindows_.Clear();
00113     flags_ = wxDWF_SPLITTER_BORDERS;
00114     pAutoLayoutClientWindow_ = NULL;
00115     pWindowMenu_ = NULL;
00116 }
00117 
00118 void wxLayoutManager::SetLayout( unsigned int flags, wxWindow * pAutoLayoutClientWindow ) {
00119     flags_ = flags;
00120     pAutoLayoutClientWindow_ = pAutoLayoutClientWindow;
00121 
00122     // generate internal event    
00123     settingsChanged();
00124 }
00125 
00126 void wxLayoutManager::AddDefaultHosts() {
00127     // adds the standard four hosts - in the standard priority order
00128     AddDockHost( wxTOP );
00129     AddDockHost( wxBOTTOM );
00130     AddDockHost( wxLEFT );
00131     AddDockHost( wxRIGHT );
00132 }
00133 
00134 void wxLayoutManager::AddDockHost( wxDirection dir, int initialSize, const wxString& name ) {
00135     // fill in name?
00136     wxString dockName = name;
00137     if( dockName == wxT("guessname") ) {
00138         switch( dir ) {
00139         case wxLEFT:
00140             dockName = wxDEFAULT_LEFT_HOST;
00141         break;
00142         case wxRIGHT:
00143             dockName = wxDEFAULT_RIGHT_HOST;
00144         break;
00145         case wxTOP:
00146             dockName = wxDEFAULT_TOP_HOST;
00147         break;
00148         case wxBOTTOM:
00149             dockName = wxDEFAULT_BOTTOM_HOST;
00150         break;
00151         default:
00152             wxASSERT_MSG( false, wxT("AddDockHost() - direction parameter not recognised") );
00153         break;
00154         }
00155     }
00156 
00157     // check for duplicate
00158     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00159         wxDockHost * pDockHost = node->GetData();
00160         if( dockName == pDockHost->GetName() || dir == pDockHost->GetDirection() ) {
00161             wxASSERT_MSG( false, wxT("AddDockHost() - direction or name already used") );
00162         }
00163     }
00164 
00165     // create host
00166     wxDockHost * pDockHost = new wxDockHost( pOwnerWindow_, 0, dir, dockName );
00167     pDockHost->SetLayoutManager( this );
00168     pDockHost->SetAreaSize( initialSize );
00169     
00170     // add a host
00171     dockHosts_.Append( pDockHost );
00172 }
00173 
00174 wxDockHost * wxLayoutManager::GetDockHost( const wxString& name ) {
00175     // find dock host
00176     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00177         wxDockHost * pDockHost = node->GetData();
00178         if( name == pDockHost->GetName()  ) {
00179             return pDockHost;
00180         }
00181     }
00182     
00183     return NULL;
00184 }
00185 
00186 wxDockHost  *wxLayoutManager :: GetDockHost ( const wxDirection  &_dir )
00187 {
00188     // find dock host
00189     wxDockHost   *pDockHost = 0;
00190 
00191     for ( DockHostList :: Node  *node = dockHosts_.GetFirst(); node; node = node -> GetNext () )
00192     {
00193         pDockHost = node -> GetData ();
00194 
00195         if( pDockHost && ( _dir == pDockHost -> GetDirection () ) )
00196             return ( pDockHost );
00197     }
00198 
00199     return NULL;
00200 }
00201 
00202 void wxLayoutManager::AddDockWindow( wxDockWindowBase * pDockWindow ) {
00203     // check for duplicate
00204     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00205         wxDockWindowBase * pKnownDockWindow = node->GetData();
00206         if( pDockWindow->GetName() == pKnownDockWindow->GetName() ) {
00207             wxASSERT_MSG( false, wxT("AddDockWindow() - name already used") );
00208         }
00209     }
00210     
00211     // add a window
00212     dockWindows_.Append( pDockWindow );
00213     pDockWindow->SetDockingManager( this );
00214 }
00215 
00216 wxHostInfo wxLayoutManager::TestForHost( int sx, int sy ) {
00217     wxHostInfo twxHostInfo;
00218     // test host for screen co-ordinate inside of
00219     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00220         wxDockHost * pDockHost = node->GetData();
00221         if( pDockHost->TestForPanel( sx, sy, twxHostInfo ) ) {
00222             break;
00223         }
00224     }
00225     return twxHostInfo;
00226 }
00227 
00228 wxRect wxLayoutManager::TrimDockArea( wxDockHost * pDockHost, wxRect &dockArea ) {
00229     wxRect tDockArea( dockArea );
00230 
00231     // test host for screen co-ordinate inside of
00232     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00233         wxDockHost * pKnownDockHost = node->GetData();
00234 
00235         if( pKnownDockHost == pDockHost ) {
00236             // ignore all hosts after us
00237             return tDockArea;
00238         }
00239         if( pKnownDockHost->IsEmpty() ) {
00240             // ignore empty dock hosts
00241             continue;
00242         }
00243 
00244         // chew of another bit
00245         wxRect chewArea = pKnownDockHost->GetClientArea();
00246         if( pKnownDockHost->GetDirection() == wxLEFT && pDockHost->GetDirection() != wxRIGHT) {
00247             if( chewArea.width ) {
00248                 tDockArea.x += chewArea.width;
00249                 tDockArea.width -= chewArea.width;
00250             }
00251         }
00252         if( pKnownDockHost->GetDirection() == wxRIGHT && pDockHost->GetDirection() != wxLEFT ) {
00253             if( chewArea.width ) {
00254                 tDockArea.width -= chewArea.width + 1;
00255             }
00256         }
00257         if( pKnownDockHost->GetDirection() == wxTOP && pDockHost->GetDirection() != wxBOTTOM ) {
00258             if( chewArea.height ) {
00259                 tDockArea.y += chewArea.height;
00260                 tDockArea.height -= chewArea.height;
00261             }
00262         }
00263         if( pKnownDockHost->GetDirection() == wxBOTTOM && pDockHost->GetDirection() != wxTOP ) {
00264             if( chewArea.height ) {
00265                 tDockArea.height -= chewArea.height + 1;
00266             }
00267         }
00268     }
00269     return tDockArea;
00270 }
00271 
00272 wxRect wxLayoutManager::RectToScreen( wxRect &rect ) {
00273     // convert owner (frame) rect to screen rect
00274     wxASSERT(pOwnerWindow_);
00275     wxRect tRect( rect );
00276     wxPoint pos = pOwnerWindow_->ClientToScreen( tRect.GetPosition() );
00277     tRect.SetPosition( pos );
00278     return tRect;
00279 }
00280 
00281 wxPoint wxLayoutManager::PointFromScreen( wxPoint &point ) {
00282     wxASSERT(pOwnerWindow_);
00283     return pOwnerWindow_->ScreenToClient( point );
00284 }
00285 
00286 unsigned int wxLayoutManager::GetFlags() {
00287     return flags_;
00288 }
00289 
00290 bool wxLayoutManager::IsPrimaryDockHost( wxDockHost * pDockHost ) {
00291     // are we the first dock host in the list?
00292     if( dockHosts_.IndexOf( pDockHost ) == 0 ) {
00293         return true;
00294     }
00295     else {
00296         return false;
00297     }
00298 }
00299 
00300 void wxLayoutManager::SetDockArea( wxRect &rect ) {
00301     dockArea_ = rect;
00302 }
00303 
00304 wxRect wxLayoutManager::GetDockArea() {
00305     return dockArea_;
00306 }
00307 
00308 void wxLayoutManager::DockWindow( wxDockWindowBase * pDockWindow, wxHostInfo &hi, bool noHideOperation ) {
00309     wxASSERT(hi.valid);
00310     wxASSERT(pDockWindow);
00311     
00312     wxDockPanel * pClient = pDockWindow->GetDockPanel();
00313     wxASSERT(pClient);
00314 
00315     // can't dock back into the same panel
00316     if( hi.pPanel == pClient ) {
00317         return;
00318     }
00319 
00320     // undock first if in a host
00321     if( pClient->GetDockedHost() ) {
00322         UndockWindow( pDockWindow, true );
00323     }
00324     // dock a window into a host
00325     wxDockHost * pDockHost = hi.pHost;
00326     pDockHost->DockPanel( pClient, hi );
00327     if( !noHideOperation ) {
00328         pDockWindow->ActualShow( false );
00329         pDockWindow->SetDocked( true );
00330     }
00331     pDockWindow->SetDockingInfo( hi );
00332     UpdateAllHosts( true );
00333 }
00334 
00335 void wxLayoutManager::UndockWindow( wxDockWindowBase * pDockWindow, bool noShowOperation ) {
00336     wxASSERT(pDockWindow);
00337 
00338     // already undocked?
00339     if( !pDockWindow->IsDocked() ) {
00340         return;
00341     }
00342 
00343     // undock a window
00344     wxDockPanel * pClient = pDockWindow->GetDockPanel();
00345     wxASSERT(pClient);
00346     wxDockHost * pDockHost = pClient->GetDockedHost();
00347     wxASSERT(pDockHost);
00348     pDockHost->UndockPanel( pClient );
00349     pDockWindow->Layout();
00350     if( !noShowOperation ) {
00351         pDockWindow->ActualShow( true );
00352         pDockWindow->SetDocked( false );
00353     }
00354     UpdateAllHosts( true );
00355 }
00356 
00357 void wxLayoutManager::OnSize() {
00358     // callback event generated by the a host size change
00359     UpdateAllHosts( true );
00360 }
00361 
00362 void wxLayoutManager::OnMove() {
00363     // XXX: no longer used
00364 }
00365 
00366 void wxLayoutManager::OnUpdateLayout() {
00367     UpdateAllHosts( false );
00368 }
00369 
00370 void wxLayoutManager::OnMenuToggle( int entryId ) {
00371     if ( entryId == -1 )
00372         return;
00373     if ( !pWindowMenu_ )
00374         return;
00375 
00376     wxMenuItem * mEntry = pWindowMenu_->FindItem(entryId);
00377 
00378     // If we don't own this menu ID then do nothing
00379     if ( mEntry == NULL )
00380         return;
00381 
00382     wxString mTitle = mEntry->GetLabel();
00383     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00384         wxDockWindowBase * pDockWindow = node->GetData();
00385         if (mTitle == pDockWindow->GetTitle()) {
00386             pDockWindow->Show(mEntry->IsChecked());
00387         }
00388     }
00389     UpdateAllHosts( false );
00390 }
00391 
00392 void wxLayoutManager::UpdateAllHosts( bool WXUNUSED(sizeChange), wxDockHost * WXUNUSED(pIgnoreHost) ) {
00393     // generate an event
00394     wxCommandEvent e( wxEVT_LAYOUT_CHANGED );
00395     e.SetEventObject( this );
00396     wxEvtHandler * pFrameEventHandler = pOwnerWindow_->GetEventHandler();
00397     wxASSERT( pFrameEventHandler );
00398     pFrameEventHandler->ProcessEvent( e );
00399 
00400     wxLayoutAlgorithm layout;
00401     wxMDIParentFrame * pMDIFrame = wxDynamicCast( pOwnerWindow_, wxMDIParentFrame );
00402     if( pMDIFrame ) {
00403         // layout within an MDI frame
00404         layout.LayoutMDIFrame( pMDIFrame );
00405     }
00406     else {
00407         // layout within an normal frame/or standard wxWindow
00408         layout.LayoutWindow( pOwnerWindow_, pAutoLayoutClientWindow_ );
00409     }
00410     if ( pWindowMenu_ )    {
00411         wxString mTitle;
00412         wxMenuItem * mEntry;
00413         int mEntryId;
00414         for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00415             wxDockWindowBase * pDockWindow = node->GetData();
00416             mTitle = pDockWindow->GetTitle();
00417             mEntryId = pWindowMenu_->FindItem(mTitle);
00418             if ( mEntryId == wxNOT_FOUND ) {
00419                 mEntry = pWindowMenu_->AppendCheckItem(-1, mTitle);
00420             } 
00421             else {
00422                 mEntry = pWindowMenu_->FindItem(mEntryId);
00423             }
00424             mEntry->Check(pDockWindow->IsVisible());
00425         }
00426     }
00427 
00428 }
00429 
00430 wxDockHost * wxLayoutManager::findDockHost( const wxString& name ) {
00431     // look for a particular host
00432     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00433         wxDockHost * pDockHost = node->GetData();
00434         if( pDockHost->GetName() == name ) {
00435             // found
00436             return pDockHost;
00437         }
00438     }
00439     // not found
00440     return NULL;
00441 }
00442 
00443 wxDockWindowBase * wxLayoutManager::findDockWindow( const wxString& name ) {
00444     // look for a particular window
00445     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00446         wxDockWindowBase * pDockWindow = node->GetData();
00447         if( pDockWindow->GetName() == name ) {
00448             // found
00449             return pDockWindow;
00450         }
00451     }
00452     // not found
00453     return NULL;
00454 }
00455 
00456 void wxLayoutManager::settingsChanged() {
00457     // update size of all hosts
00458     for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
00459         wxDockHost * pDockHost = node->GetData();
00460         pDockHost->SettingsChanged();
00461     }
00462 }
00463 
00464 
00465 
00466 
00467 // -----------------------------------
00468 // wxLAYOUTMANAGER - load/save layout
00469 // -----------------------------------
00470 
00471 bool wxLayoutManager::SaveToStream( wxOutputStream &stream ) {
00472 
00473     // version
00474     WriteString( stream, STREAM_VERSION );
00475 
00476     // windows
00477     WriteString( stream, wxT("<layout>") );
00478 
00479     int winCount = dockWindows_.GetCount();
00480     stream.Write( &winCount, sizeof( winCount ) );
00481     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00482         wxDockWindowBase * pDockWindow = node->GetData();
00483 
00484         // name
00485         WriteString( stream, pDockWindow->GetName() );
00486 
00487         // undocked size
00488         wxRect size = pDockWindow->GetRect();
00489         stream.Write( &size.x, sizeof( size.x ) );
00490         stream.Write( &size.y, sizeof( size.y ) );
00491         stream.Write( &size.width, sizeof( size.width ) );
00492         stream.Write( &size.height, sizeof( size.height ) );
00493 
00494         // attributes
00495         bool isShown = pDockWindow->IsShown();
00496         stream.Write( &isShown, sizeof( isShown ) );
00497         bool isDocked = pDockWindow->IsDocked();
00498         stream.Write( &isDocked, sizeof( isDocked ) );
00499         
00500         // area taken
00501         wxDockPanel * pDockPanel = pDockWindow->GetDockPanel();
00502         wxASSERT(pDockPanel);
00503         int area = pDockPanel->GetArea();
00504         stream.Write( &area, sizeof( area ) );
00505 
00506         // docking info
00507         wxHostInfo &hi = pDockWindow->GetDockingInfo();
00508         if( hi.pHost ) {
00509             WriteString( stream, hi.pHost->GetName() );
00510         }
00511         else {
00512             WriteString( stream, wxT("<nohost>") );
00513         }
00514     }
00515 
00516     // write out hosts
00517     int hostCount = dockHosts_.GetCount();
00518     stream.Write( &hostCount, sizeof( hostCount ) );
00519     for( DockHostList::Node *hnode = dockHosts_.GetFirst(); hnode; hnode = hnode->GetNext() ) {
00520         wxDockHost * pDockHost = hnode->GetData();
00521 
00522         // name
00523         WriteString( stream, pDockHost->GetName() );
00524 
00525         // area size
00526         int areaSize = pDockHost->GetAreaSize();
00527         stream.Write( &areaSize, sizeof( areaSize ) );
00528 
00529         // panel size
00530         int panelArea = pDockHost->GetPanelArea();
00531         stream.Write( &panelArea, sizeof( panelArea ) );
00532 
00533         // docked windows
00534         const DockWindowList & dwl = pDockHost->GetDockWindowList();
00535         int winCount = dwl.GetCount();
00536         stream.Write( &winCount, sizeof( winCount ) );
00537         for( DockWindowList::Node *lnode = dwl.GetFirst(); lnode; lnode = lnode->GetNext() ) {
00538             wxDockWindowBase * pDockWindow = lnode->GetData();
00539 
00540             // name
00541             WriteString( stream, pDockWindow->GetName() );
00542         }
00543     }    
00544 
00545     return true;
00546 }
00547 
00548 bool wxLayoutManager::LoadFromStream( wxInputStream &stream ) {
00549     int i;
00550     // version
00551     wxString version = ReadString( stream );
00552     if( version != STREAM_VERSION ) {
00553         return false;
00554     }
00555 
00556     wxString layoutTag = ReadString( stream );
00557     if( layoutTag == wxT("<layout>") ) {
00558         DockPanelList lockedPanels;
00559         
00560         // undock all windows
00561         for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00562             wxDockWindowBase * pDockWindow = node->GetData();
00563             wxASSERT( pDockWindow );
00564             pDockWindow->Remove();
00565         }
00566 
00567         // read in windows
00568         int winCount = 0;
00569         stream.Read( &winCount, sizeof( winCount ) );
00570         for( i=0; i<winCount; i++ ) {
00571             // name
00572             wxString name = ReadString( stream );
00573 
00574             // undocked size
00575             wxRect size;
00576             stream.Read( &size.x, sizeof( size.x ) );
00577             stream.Read( &size.y, sizeof( size.y ) );
00578             stream.Read( &size.width, sizeof( size.width ) );
00579             stream.Read( &size.height, sizeof( size.height ) );
00580 
00581             // attributes
00582             bool isShown = false;
00583             stream.Read( &isShown, sizeof( isShown ) );
00584             bool isDocked = false;
00585             stream.Read( &isDocked, sizeof( isDocked ) );
00586             
00587             // area taken
00588             int area = 0;
00589             stream.Read( &area, sizeof( area ) );
00590 
00591             // docking info
00592             wxString host = ReadString( stream );
00593 
00594             // find window and apply
00595             wxDockWindowBase * pDockWindow = findDockWindow( name );
00596             if( pDockWindow ) {
00597                 pDockWindow->SetSize( size );
00598                 pDockWindow->SetDocked( isDocked );
00599 
00600                 wxDockPanel * pDockPanel = pDockWindow->GetDockPanel();
00601                 wxASSERT( pDockPanel );
00602 
00603                 // panel area
00604                 pDockPanel->SetArea( area );
00605                 pDockPanel->LockAreaValue( true );
00606                 lockedPanels.Append( pDockPanel );
00607 
00608                 // docking info
00609                 wxDockHost * pDockHost = findDockHost( host );
00610                 if( pDockHost && isDocked ) {
00611                     // was docked
00612                     wxHostInfo hi;
00613                     hi = pDockHost;
00614                     pDockWindow->SetDockingInfo( hi );
00615                 }
00616                 else {
00617                     // was not docked
00618                     if( isShown ) {
00619                         pDockWindow->Appear();
00620                     }
00621                     pDockWindow->ClearDockingInfo();
00622                 }
00623             }
00624             else {
00625                 // could not find window
00626             }
00627         }
00628 
00629         DockHostList lockedHosts;
00630 
00631         // read in hosts
00632         int hostCount = 0;
00633         stream.Read( &hostCount, sizeof( hostCount ) );
00634         for( i=0; i<hostCount; i++ ) {
00635             // name
00636             wxString name = ReadString( stream );
00637 
00638             // area size
00639             int areaSize = 0;
00640             stream.Read( &areaSize, sizeof( areaSize ) );
00641 
00642             // panel area
00643             int panelArea = 0;
00644             stream.Read( &panelArea, sizeof( panelArea ) );
00645 
00646             // find host and apply
00647             wxDockHost * pDockHost = findDockHost( name );
00648             if( pDockHost ) {
00649                 // areas
00650                 pDockHost->SetAreaSize( areaSize );
00651                 pDockHost->SetPanelArea( panelArea );
00652                 pDockHost->LockPanelValue( true );
00653                 lockedHosts.Append( pDockHost );
00654 
00655                 // docked windows
00656                 int winCount = 0;
00657                 stream.Read( &winCount, sizeof( winCount ) );
00658                 for( int i=0; i<winCount; i++ ) {
00659                     // name
00660                     wxString name = ReadString( stream );
00661 
00662                     // find window and dock
00663                     wxDockWindowBase * pDockWindow = findDockWindow( name );
00664                     if( pDockWindow ) {
00665                         wxHostInfo hi;
00666                         hi = pDockHost;
00667                         DockWindow( pDockWindow, hi ); 
00668                     }
00669                     else {
00670                         // could not find window
00671                     }
00672                 }
00673             }
00674             else {
00675                 // could not find host
00676             }
00677         }
00678         UpdateAllHosts( true );
00679 
00680         // unlock all panels
00681         for( DockPanelList::Node *pnode = lockedPanels.GetFirst(); pnode; pnode = pnode->GetNext() ) {
00682             wxDockPanel * pDockPanel = pnode->GetData();
00683             wxASSERT( pDockPanel );
00684             pDockPanel->LockAreaValue( false );
00685         }
00686 
00687         // unlock all hosts
00688         for( DockHostList::Node *hnode = lockedHosts.GetFirst(); hnode; hnode = hnode->GetNext() ) {
00689             wxDockHost * pDockHost = hnode->GetData();
00690             wxASSERT( pDockHost );
00691             pDockHost->LockPanelValue( false );
00692         }
00693 
00694     }   // end <layout>
00695 
00696     return true;
00697 }
00698 
00699 #ifdef wxDI_USE_XMLLOADSAVE
00700 
00715 wxXmlNode *eNode(const wxString &nodename, const wxString &content) {
00716     wxXmlNode *child = new wxXmlNode(wxXML_TEXT_NODE, wxT("value")),
00717         *node = new wxXmlNode(wxXML_ELEMENT_NODE, nodename);
00718     child->SetContent(content);
00719     node->AddChild(child);
00720     return node;
00721 }
00722 
00736 wxXmlNode *changeNode(wxXmlNode *, const wxString &nodePath, const wxString &content) {
00737     return NULL;
00738 }
00739 
00757 wxXmlNode *xmlFindNode(wxXmlNode *root, const wxString &nodePath, bool getText = true) {
00758     wxXmlNode *node = root;
00759     wxString pathPart = nodePath;
00760     wxString findPart;
00761     bool nFound;
00762 
00763     while(pathPart.Length() > 0) {
00764         node = node->GetChildren();
00765         if (pathPart.Find(wxT("/")) == wxNOT_FOUND) {
00766             findPart = pathPart;
00767             pathPart.Empty();
00768         }
00769         else {
00770             findPart = pathPart.Left(pathPart.Find(wxT("/")));
00771             pathPart.Remove(0,pathPart.Find(wxT("/"))+1);
00772         }
00773         nFound = false;
00774         while((!nFound) && (node)) {
00775             if (findPart.Cmp(node->GetName()) == 0) {
00776                 nFound = true;
00777                 continue;
00778             }
00779             node = node->GetNext();
00780         }
00781         if (!node) {
00782             pathPart = wxEmptyString;
00783         }
00784     }
00785     if (!node)
00786         return NULL;
00787     if (getText) {
00788         node = node->GetChildren();
00789     }
00790     return node;
00791 }
00792 
00807 bool wxLayoutManager::SaveToXML( const wxString& filename ) {
00808     wxXmlDocument *xmlDoc = new wxXmlDocument;
00809     wxXmlNode *xnode, *xroot = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("wxDockit"));
00810 
00811     if (::wxFileExists(filename)) {
00812         if (!xmlDoc->Load(filename)) {
00813             // Failed to load the old layout properly
00814             xmlDoc->SetRoot(xroot);
00815         }
00816         else {
00817             delete xroot;
00818             xroot = xmlDoc->GetRoot();
00819             xnode = xroot->GetChildren();
00820             while(xnode) {
00821                 xroot->RemoveChild(xnode);
00822                 xnode = xroot->GetChildren();
00823             }
00824         }
00825     }
00826     else {
00827         xmlDoc->SetRoot(xroot);
00828     }
00829 
00830     xroot->AddChild(eNode(wxT("stream_version"), STREAM_VERSION));
00831 
00832     int winCount = dockWindows_.GetCount();
00833     xroot->AddChild(eNode(wxT("window_count"), wxString::Format(wxT("%d"), winCount)));
00834     int hostCount = dockHosts_.GetCount();
00835     xroot->AddChild(eNode(wxT("host_count"), wxString::Format(wxT("%d"), hostCount)));
00836 
00837     // windows
00838     xnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("windows"));
00839     xroot->AddChild(xnode);
00840 
00841     xroot = xnode;
00842 
00843     wxString wnStr;
00844     int wn = 0;
00845 
00846     for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00847         wxDockWindowBase * pDockWindow = node->GetData();
00848 
00849         wnStr.Printf(wxT("window_%d"),wn++);
00850 
00851         xnode = new wxXmlNode(wxXML_ELEMENT_NODE, wnStr);
00852         xroot->AddChild(xnode);
00853 
00854         // name
00855         xnode->AddChild(eNode(wxT("name"),pDockWindow->GetName()));
00856 
00857         // undocked size
00858         wxRect size = pDockWindow->GetRect();
00859         xnode->AddChild(eNode(wxT("corner_x"), wxString::Format(wxT("%d"), size.x)));
00860         xnode->AddChild(eNode(wxT("corner_y"), wxString::Format(wxT("%d"), size.y)));
00861         xnode->AddChild(eNode(wxT("width"), wxString::Format(wxT("%d"), size.width)));
00862         xnode->AddChild(eNode(wxT("height"), wxString::Format(wxT("%d"), size.height)));
00863 
00864         // attributes
00865         xnode->AddChild(eNode(wxT("shown"), wxString::Format(wxT("%d"), pDockWindow->IsShown())));
00866         xnode->AddChild(eNode(wxT("docked"), wxString::Format(wxT("%d"), pDockWindow->IsDocked())));
00867 
00868         // area taken
00869         wxDockPanel * pDockPanel = pDockWindow->GetDockPanel();
00870         wxASSERT(pDockPanel);
00871         int area = pDockPanel->GetArea();
00872         xnode->AddChild(eNode(wxT("dockarea"), wxString::Format(wxT("%d"), area)));
00873 
00874         // docking info
00875         wxHostInfo &hi = pDockWindow->GetDockingInfo();
00876         if( hi.pHost ) {
00877             xnode->AddChild(eNode(wxT("dockhost"), hi.pHost->GetName()));
00878         }
00879         else {
00880             xnode->AddChild(eNode(wxT("dockhost"), wxT("none")));
00881         }
00882     }
00883 
00884     xroot = xroot->GetParent();
00885 
00886     // write out hosts
00887     xnode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("hosts"));
00888     xroot->AddChild(xnode);
00889 
00890     xroot = xnode;
00891 
00892     wxString hnStr;
00893     int hn = 0;
00894 
00895     for( DockHostList::Node *hnode = dockHosts_.GetFirst(); hnode; hnode = hnode->GetNext() ) {
00896         wxDockHost * pDockHost = hnode->GetData();
00897 
00898         // name
00899         hnStr.Printf(wxT("host_%d"),hn++);
00900         xnode = new wxXmlNode(wxXML_ELEMENT_NODE, hnStr);
00901         xroot->AddChild(xnode);
00902 
00903         xnode->AddChild(eNode(wxT("name"), pDockHost->GetName()));
00904 
00905         // area size
00906         int areaSize = pDockHost->GetAreaSize();
00907         xnode->AddChild(eNode(wxT("host_area"), wxString::Format(wxT("%d"),areaSize)));
00908 
00909         // panel size
00910         int panelArea = pDockHost->GetPanelArea();
00911         xnode->AddChild(eNode(wxT("panel_area"), wxString::Format(wxT("%d"),panelArea)));
00912 
00913         // docked windows
00914         const DockWindowList & dwl = pDockHost->GetDockWindowList();
00915         int winCount = dwl.GetCount();
00916         xnode->AddChild(eNode(wxT("window_count"), wxString::Format(wxT("%d"),winCount)));
00917         wn = 0;
00918         for( DockWindowList::Node *lnode = dwl.GetFirst(); lnode; lnode = lnode->GetNext() ) {
00919             wxDockWindowBase * pDockWindow = lnode->GetData();
00920             wnStr.Printf(wxT("dockwin_%d"),wn++);
00921             xnode->AddChild(eNode(wnStr,pDockWindow->GetName()));
00922             // name
00923         }
00924     }    
00925 
00926     return xmlDoc->Save(filename);
00927 }
00928 
00942 bool wxLayoutManager::LoadFromXML( const wxString& filename ) {
00943     wxXmlDocument *xmlDoc = new wxXmlDocument;
00944 
00945     if (!wxFileName::FileExists(filename) ||
00946         !xmlDoc->Load(filename))
00947         return false;
00948 
00949     wxXmlNode *xroot = xmlDoc->GetRoot();
00950 
00951     int i;
00952     // version
00953     wxString version = xmlFindNode(xroot, wxT("stream_version"))->GetContent();
00954     if( version != STREAM_VERSION ) {
00955         return false;
00956     }
00957 
00958         DockPanelList lockedPanels;
00959         
00960         // undock all windows
00961         for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
00962             wxDockWindowBase * pDockWindow = node->GetData();
00963             wxASSERT( pDockWindow );
00964             pDockWindow->Remove();
00965         }
00966 
00967         // read in windows
00968         wxString wnStr,wPath;
00969         long winCount = 0,longConvert;
00970         wxString strNumber = xmlFindNode(xroot, wxT("window_count"))->GetContent();
00971         strNumber.ToLong(&winCount);
00972         for( i=0; i<(int)winCount; i++ ) {
00973             // name
00974             wxString name = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/name"),i))->GetContent();
00975 
00976             // undocked size
00977             wxRect size;
00978             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/corner_x"),i))->GetContent();
00979             strNumber.ToLong(&longConvert);
00980             size.x = (int)longConvert;
00981             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/corner_y"),i))->GetContent();
00982             strNumber.ToLong(&longConvert);
00983             size.y = (int)longConvert;
00984             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/width"),i))->GetContent();
00985             strNumber.ToLong(&longConvert);
00986             size.width = (int)longConvert;
00987             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/height"),i))->GetContent();
00988             strNumber.ToLong(&longConvert);
00989             size.height = (int)longConvert;
00990 
00991             // attributes
00992             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/shown"),i))->GetContent();
00993             strNumber.ToLong(&longConvert);
00994             bool isShown = (longConvert == 1);
00995             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/docked"),i))->GetContent();
00996             strNumber.ToLong(&longConvert);
00997             bool isDocked = (longConvert == 1);
00998             
00999             // area taken
01000             strNumber = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/dockarea"),i))->GetContent();
01001             strNumber.ToLong(&longConvert);
01002             int area = (int)longConvert;
01003 
01004             // docking info
01005             wxString host = xmlFindNode(xroot,wxString::Format(wxT("windows/window_%d/dockhost"),i))->GetContent();
01006 
01007             // find window and apply
01008             wxDockWindowBase * pDockWindow = findDockWindow( name );
01009             if( pDockWindow ) {
01010                 pDockWindow->SetSize( size );
01011                 pDockWindow->SetDocked( isDocked );
01012 
01013                 wxDockPanel * pDockPanel = pDockWindow->GetDockPanel();
01014                 wxASSERT( pDockPanel );
01015 
01016                 // panel area
01017                 pDockPanel->SetArea( area );
01018                 pDockPanel->LockAreaValue( true );
01019                 lockedPanels.Append( pDockPanel );
01020 
01021                 // docking info
01022                 wxDockHost * pDockHost = findDockHost( host );
01023                 if( pDockHost && isDocked ) {
01024                     // was docked
01025                     wxHostInfo hi;
01026                     hi = pDockHost;
01027                     pDockWindow->SetDockingInfo( hi );
01028                 }
01029                 else {
01030                     // was not docked
01031                     if( isShown ) {
01032                         pDockWindow->Appear();
01033                     }
01034                     pDockWindow->ClearDockingInfo();
01035                 }
01036             }
01037             else {
01038                 // could not find window
01039             }
01040 
01041         DockHostList lockedHosts;
01042 
01043         // read in hosts
01044         long hostCount = 0;
01045         wxString strNumber = xmlFindNode(xroot, wxT("host_count"))->GetContent();
01046         strNumber.ToLong(&hostCount);
01047 
01048         for( i=0; i<hostCount; i++ ) {
01049             // name
01050             wxString name = xmlFindNode(xroot,wxString::Format(wxT("hosts/host_%d/name"),i))->GetContent();
01051 
01052             // area size
01053             strNumber = xmlFindNode(xroot,wxString::Format(wxT("hosts/host_%d/host_area"),i))->GetContent();
01054             strNumber.ToLong(&longConvert);
01055             int areaSize = (int)longConvert;
01056 
01057             // panel area
01058             strNumber = xmlFindNode(xroot,wxString::Format(wxT("hosts/host_%d/panel_area"),i))->GetContent();
01059             strNumber.ToLong(&longConvert);
01060             int panelArea = (int)longConvert;
01061 
01062             // find host and apply
01063             wxDockHost * pDockHost = findDockHost( name );
01064             if( pDockHost ) {
01065                 // areas
01066                 pDockHost->SetAreaSize( areaSize );
01067                 pDockHost->SetPanelArea( panelArea );
01068                 pDockHost->LockPanelValue( true );
01069                 lockedHosts.Append( pDockHost );
01070 
01071                 // docked windows
01072                 strNumber = xmlFindNode(xroot,wxString::Format(wxT("hosts/host_%d/window_count"),i))->GetContent();
01073                 strNumber.ToLong(&longConvert);
01074                 int winCount = (int)longConvert;
01075                 int j;
01076                 for( j=0; j<winCount; j++ ) {
01077                     // name
01078                     wxString name = xmlFindNode(xroot,wxString::Format(wxT("hosts/host_%d/dockwin_%d"),i,j))->GetContent();
01079 
01080                     // find window and dock
01081                     wxDockWindowBase * pDockWindow = findDockWindow( name );
01082                     if( pDockWindow ) {
01083                         wxHostInfo hi;
01084                         hi = pDockHost;
01085                         DockWindow( pDockWindow, hi ); 
01086                     }
01087                     else {
01088                         // could not find window
01089                     }
01090                 }
01091             }
01092             else {
01093                 // could not find host
01094             }
01095         }
01096         UpdateAllHosts( true );
01097 
01098         // unlock all panels
01099         for( DockPanelList::Node *pnode = lockedPanels.GetFirst(); pnode; pnode = pnode->GetNext() ) {
01100             wxDockPanel * pDockPanel = pnode->GetData();
01101             wxASSERT( pDockPanel );
01102             pDockPanel->LockAreaValue( false );
01103         }
01104 
01105         // unlock all hosts
01106         for( DockHostList::Node *hnode = lockedHosts.GetFirst(); hnode; hnode = hnode->GetNext() ) {
01107             wxDockHost * pDockHost = hnode->GetData();
01108             wxASSERT( pDockHost );
01109             pDockHost->LockPanelValue( false );
01110         }
01111 
01112     }   // end <layout>
01113     return true;
01114 }
01115 
01116 #endif  // wxDI_USE_XMLLOADSAVE
01117 
01118 bool wxLayoutManager::SaveToConfig(wxConfigBase *pcfg, const wxString &key) const
01119 {
01120  return FALSE;
01121 }
01122 
01123 bool wxLayoutManager::LoadFromConfig(wxConfigBase *pcfg, const wxString &key)
01124 {
01125  return FALSE;
01126 }
01127 

Generated on Sat May 14 14:54:39 2005 for wxDockIt by  doxygen 1.4.2