]> git.saurik.com Git - wxWidgets.git/blame - utils/HelpGen/src/ifcontext.cpp
don't blit too much when copying static box border in OnPaint()
[wxWidgets.git] / utils / HelpGen / src / ifcontext.cpp
CommitLineData
cecfc5e7
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: No names yet.
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 27/12/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleskandars Gluchovas
fa1af598 9// Licence: wxWindows licence
cecfc5e7
VZ
10/////////////////////////////////////////////////////////////////////////////
11
cecfc5e7
VZ
12// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20#include "wx/wx.h"
21#endif
22
cecfc5e7
VZ
23#include <stdio.h>
24
25#include "ifcontext.h"
26
27/***** Implementation for class spInterFileContext *****/
28
60ec1c87 29size_t spInterFileContext::GetFileNo( const wxString& fname )
cecfc5e7 30{
60ec1c87 31 for ( size_t i = 0; i != m_Files.size(); ++i )
fa1af598 32 {
60ec1c87 33 if ( fname == m_Files[i] )
3a87625f 34 return i;
fa1af598 35 }
cecfc5e7 36
3a87625f 37 wxFAIL_MSG("File not found in array in function spInterFileContext::GetFileNo()");
fa1af598
WS
38
39 return 0;
cecfc5e7
VZ
40}
41
42size_t spInterFileContext::GetFileNoOfContext( spContext& ctx )
43{
fa1af598 44 spContext* pCtx = ctx.GetEnclosingContext( SP_CTX_FILE );
cecfc5e7 45
fa1af598 46 // DBG:: outer-file context should be present
60ec1c87 47 wxASSERT( pCtx && pCtx->GetType() == SP_CTX_FILE );
cecfc5e7 48
60ec1c87 49 return GetFileNo( ((spFile*)pCtx)->m_FileName );
cecfc5e7
VZ
50}
51
52/*** public interface ***/
53
54spInterFileContext::spInterFileContext()
55{}
56
57spInterFileContext::~spInterFileContext()
58{}
59
60ec1c87 60void spInterFileContext::AddFile( const wxString& fname, const wxString& content )
cecfc5e7 61{
60ec1c87
WS
62 m_Files.push_back( fname );
63 m_Contents.push_back( content );
cecfc5e7
VZ
64}
65
66void spInterFileContext::RemoveContext( spContext& ctx )
67{
fa1af598 68 wxASSERT( ctx.PositionIsKnown() ); // DBG:: should be checked by-user code
cecfc5e7 69
fa1af598 70 size_t fNo = GetFileNoOfContext( ctx );
cecfc5e7 71
fa1af598 72 mDeletionMarks.push_back( spBookmark( ctx.mSrcOffset, ctx.mContextLength, fNo ) );
cecfc5e7
VZ
73}
74
75void spInterFileContext::InsertBookmarkSorted( BookmarkListT& lst, spBookmark& mark )
76{
fa1af598 77 for( size_t i = 0; i != lst.size(); ++i )
cecfc5e7 78
fa1af598
WS
79 if ( lst[i].mFrom > mark.mFrom )
80 {
81 lst.insert( &lst[i], mark );
82 return;
83 }
84
85 lst.push_back( mark );
86}
cecfc5e7 87
7942245d
WS
88void spInterFileContext::DoAppendSourceFragment( wxString& source,
89 wxString& result,
fa1af598 90 size_t pos, size_t len )
cecfc5e7 91{
fa1af598 92 mFiltered.erase( mFiltered.begin(), mFiltered.end() );
cecfc5e7 93
fa1af598
WS
94 size_t i;
95
96 for( i = 0; i != mDeletionMarks.size(); ++i )
97 {
98 spBookmark& mark = mDeletionMarks[i];
cecfc5e7 99
60ec1c87 100 if ( mark.mFileNo == mCurFileNo &&
fa1af598 101 mark.mFrom >= pos && mark.mFrom < pos + len )
cecfc5e7 102
fa1af598
WS
103 InsertBookmarkSorted( mFiltered, mark );
104 }
cecfc5e7 105
fa1af598 106 size_t cur = pos;
cecfc5e7 107
fa1af598
WS
108 for( i = 0; i != mFiltered.size(); ++ i )
109 {
110 spBookmark& mark = mFiltered[i];
cecfc5e7 111
fa1af598 112 result.append( source, cur, ( (size_t)mark.mFrom - cur ) );
cecfc5e7 113
fa1af598 114 cur = size_t( mark.mFrom + mark.mLen );
cecfc5e7 115
fa1af598
WS
116 if ( cur >= pos + len ) // check if we've overstepped the current source-fragment
117 {
118// wxASSERT(0); // DBG:: with current imp. this should not happen
119 wxFAIL_MSG("Overstepped the current source fragment in function\nspInterFileContext::DoAppendSourceFragment()");
120 cur = pos + len; break;
121 }
122 }
123
124 result.append( source, cur, ( pos + len ) - cur );
cecfc5e7
VZ
125}
126
60ec1c87 127void spInterFileContext::GenerateContextBody( spContext& ctx,
7942245d
WS
128 wxString& source,
129 wxString& result,
fa1af598
WS
130 size_t& lastSavedPos,
131 size_t& lastKnownPos )
cecfc5e7 132{
fa1af598
WS
133 if ( ctx.PositionIsKnown() )
134 lastKnownPos = ctx.mSrcOffset;
cecfc5e7 135
fa1af598
WS
136 if ( ctx.IsVirtualContext() )
137 {
138 // add fragment accumulated before this context
cecfc5e7 139
fa1af598 140 DoAppendSourceFragment( source, result,
60ec1c87 141 size_t(lastSavedPos),
fa1af598 142 size_t(lastKnownPos - lastSavedPos) );
cecfc5e7 143
fa1af598 144 // add context body
cecfc5e7 145
fa1af598 146 result += ctx.GetVirtualContextBody();
cecfc5e7 147
fa1af598 148 lastSavedPos = lastKnownPos;
cecfc5e7 149
fa1af598
WS
150 if ( ctx.PositionIsKnown() )
151 {
152 if ( ctx.VitualContextHasChildren() )
153 {
154 lastKnownPos = ctx.mSrcOffset + ctx.mHeaderLength;
cecfc5e7 155
fa1af598
WS
156 lastSavedPos = lastKnownPos;
157 }
158 else
159 {
160 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
cecfc5e7 161
fa1af598 162 lastSavedPos = lastKnownPos;
cecfc5e7 163
fa1af598
WS
164 return; // have not children
165 }
166 }
167 }
cecfc5e7 168
fa1af598 169 MMemberListT& lst = ctx.GetMembers();
cecfc5e7 170
fa1af598
WS
171 for( size_t i = 0; i != lst.size(); ++i )
172 {
173 GenerateContextBody( *lst[i], source, result, lastSavedPos, lastKnownPos );
174 }
cecfc5e7 175
fa1af598
WS
176 if ( ctx.IsVirtualContext() )
177 {
178 if ( ctx.VitualContextHasChildren() && !ctx.GetFooterOfVirtualContextBody().empty() )
179 {
180 // append the reminder space after children of the context
cecfc5e7 181
fa1af598 182 DoAppendSourceFragment( result, source,
60ec1c87 183 size_t(lastSavedPos),
fa1af598 184 size_t(lastKnownPos - lastSavedPos) );
cecfc5e7 185
60ec1c87 186 // add footer
fa1af598 187 result += ctx.GetFooterOfVirtualContextBody();
cecfc5e7 188
fa1af598 189 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
cecfc5e7 190
fa1af598
WS
191 lastSavedPos = lastKnownPos;
192 }
193 }
cecfc5e7 194
fa1af598 195 if ( ctx.PositionIsKnown() )
cecfc5e7 196
fa1af598 197 lastKnownPos = ctx.mSrcOffset + ctx.mContextLength;
cecfc5e7
VZ
198}
199
200void spInterFileContext::GenrateContents()
201{
fa1af598 202 MMemberListT& lst = GetMembers();
cecfc5e7 203
fa1af598
WS
204 for( size_t f = 0; f != lst.size(); ++f )
205 {
60ec1c87 206 wxString& fname = ((spFile*)lst[f])->m_FileName;
cecfc5e7 207
fa1af598 208 size_t fileNo = GetFileNo( fname );
cecfc5e7 209
60ec1c87 210 wxString& source = m_Contents[ fileNo ];
cecfc5e7 211
60ec1c87 212 wxString result;
cecfc5e7 213
fa1af598
WS
214 size_t lastKnownPos = 0, // the begining of the file is always "known"
215 lastSavedPos = 0;
cecfc5e7 216
fa1af598 217 mCurFileNo = fileNo;
cecfc5e7 218
fa1af598 219 GenerateContextBody( *lst[f], source, result, lastSavedPos, lastKnownPos );
cecfc5e7 220
fa1af598 221 // the end of file is always known
cecfc5e7 222
60ec1c87 223 lastKnownPos = m_Contents[ fileNo ].length();
cecfc5e7 224
60ec1c87 225 // append the reminder
cecfc5e7 226
fa1af598 227 DoAppendSourceFragment( source, result,
60ec1c87 228 size_t(lastSavedPos),
fa1af598 229 size_t(lastKnownPos - lastSavedPos) );
cecfc5e7 230
fa1af598 231 // replace original contnet with newly generated one
cecfc5e7 232
60ec1c87 233 m_Contents[ fileNo ] = result;
fa1af598 234 }
cecfc5e7
VZ
235}
236
237void spInterFileContext::ParseContents( SourceParserPlugin* pPlugin )
238{
fa1af598 239 mDeletionMarks.erase( mDeletionMarks.begin(), mDeletionMarks.end() );
cecfc5e7 240
fa1af598 241 RemoveChildren(); // clean up top-level context
cecfc5e7 242
fa1af598 243 mParser.SetPlugin( pPlugin );
cecfc5e7 244
60ec1c87 245 for( size_t i = 0; i != m_Files.size(); ++i )
fa1af598 246 {
98cf46c8 247 wxWritableCharBuffer s(m_Contents[i].char_str());
cecfc5e7 248
60ec1c87 249 spFile* pFCtx = mParser.Parse( s, s + m_Contents[i].length() );
cecfc5e7 250
60ec1c87 251 pFCtx->m_FileName = m_Files[i];
cecfc5e7 252
fa1af598
WS
253 AddMember( pFCtx );
254 }
cecfc5e7
VZ
255}
256
257void spInterFileContext::WriteToFiles()
258{
60ec1c87 259 for( size_t i = 0; i != m_Files.size(); ++i )
fa1af598 260 {
60ec1c87 261 FILE* fp = fopen( m_Files[i].c_str(), "w+t" );
cecfc5e7 262
fa1af598
WS
263 if ( fp != NULL )
264 {
60ec1c87 265 fwrite( m_Contents[i].c_str(), sizeof(char), m_Contents[i].length(), fp );
cecfc5e7 266
fa1af598
WS
267 fclose( fp );
268 }
269 }
cecfc5e7
VZ
270}
271
fa1af598 272wxString spInterFileContext::GetBody( spContext* pCtx )
cecfc5e7 273{
fa1af598 274 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
cecfc5e7 275
60ec1c87 276 wxString& source = m_Contents[ GetFileNoOfContext( *pCtx ) ];
cecfc5e7 277
fa1af598 278 return wxString( source.c_str() + pCtx->mSrcOffset, pCtx->mContextLength );
cecfc5e7
VZ
279}
280
fa1af598 281wxString spInterFileContext::GetHeader( spContext* pCtx )
cecfc5e7 282{
fa1af598 283 wxASSERT( pCtx->PositionIsKnown() ); // DBG:: should be checked by-user code
cecfc5e7 284
fa1af598 285 wxASSERT( pCtx->mHeaderLength != -1 ); // DBG:: -/-
cecfc5e7 286
60ec1c87 287 wxString& source = m_Contents[ GetFileNoOfContext( *pCtx ) ];
cecfc5e7 288
fa1af598 289 return wxString( source.c_str() + pCtx->mSrcOffset, pCtx->mHeaderLength );
cecfc5e7 290}