]> git.saurik.com Git - wxWidgets.git/blob - src/common/textbuf.cpp
Added slightly better font dialog for Mac
[wxWidgets.git] / src / common / textbuf.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/common/textbuf.cpp
3 // Purpose:     implementation of wxTextBuffer class
4 // Created:     14.11.01
5 // Author:      Morten Hanssen, Vadim Zeitlin
6 // RCS-ID:      $Id$
7 // Copyright:   (c) 1998-2001 wxWidgets team
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // headers
13 // ============================================================================
14
15 #include  "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18     #pragma hdrstop
19 #endif  //__BORLANDC__
20
21 #ifndef WX_PRECOMP
22     #include  "wx/string.h"
23     #include  "wx/intl.h"
24     #include  "wx/log.h"
25 #endif
26
27 #include "wx/textbuf.h"
28
29 // ============================================================================
30 // wxTextBuffer class implementation
31 // ============================================================================
32
33 // ----------------------------------------------------------------------------
34 // static methods (always compiled in)
35 // ----------------------------------------------------------------------------
36
37 // default type is the native one
38 // the native type under Mac OS X is:
39 //   - Unix when compiling with the Apple Developer Tools (__UNIX__)
40 //   - Mac when compiling with CodeWarrior (__WXMAC__)
41
42 const wxTextFileType wxTextBuffer::typeDefault =
43 #if defined(__WINDOWS__) || defined(__DOS__) || defined(__PALMOS__)
44   wxTextFileType_Dos;
45 #elif defined(__UNIX__)
46   wxTextFileType_Unix;
47 #elif defined(__WXMAC__)
48   wxTextFileType_Mac;
49 #elif defined(__OS2__)
50   wxTextFileType_Os2;
51 #else
52   wxTextFileType_None;
53   #error  "wxTextBuffer: unsupported platform."
54 #endif
55
56 const wxChar *wxTextBuffer::GetEOL(wxTextFileType type)
57 {
58     switch ( type ) {
59         default:
60             wxFAIL_MSG(wxT("bad buffer type in wxTextBuffer::GetEOL."));
61             // fall through nevertheless - we must return something...
62
63         case wxTextFileType_None: return wxEmptyString;
64         case wxTextFileType_Unix: return wxT("\n");
65         case wxTextFileType_Dos:  return wxT("\r\n");
66         case wxTextFileType_Mac:  return wxT("\r");
67     }
68 }
69
70 wxString wxTextBuffer::Translate(const wxString& text, wxTextFileType type)
71 {
72     // don't do anything if there is nothing to do
73     if ( type == wxTextFileType_None )
74         return text;
75
76     // nor if it is empty
77     if ( text.empty() )
78         return text;
79
80     wxString eol = GetEOL(type), result;
81
82     // optimization: we know that the length of the new string will be about
83     // the same as the length of the old one, so prealloc memory to aviod
84     // unnecessary relocations
85     result.Alloc(text.Len());
86
87     wxChar chLast = 0;
88     for ( const wxChar *pc = text.c_str(); *pc; pc++ )
89     {
90         wxChar ch = *pc;
91         switch ( ch ) {
92             case _T('\n'):
93                 // Dos/Unix line termination
94                 result += eol;
95                 chLast = 0;
96                 break;
97
98             case _T('\r'):
99                 if ( chLast == _T('\r') ) {
100                     // Mac empty line
101                     result += eol;
102                 }
103                 else {
104                     // just remember it: we don't know whether it is just "\r"
105                     // or "\r\n" yet
106                     chLast = _T('\r');
107                 }
108                 break;
109
110             default:
111                 if ( chLast == _T('\r') ) {
112                     // Mac line termination
113                     result += eol;
114
115                     // reset chLast to avoid inserting another eol before the
116                     // next character
117                     chLast = 0;
118                 }
119
120                 // add to the current line
121                 result += ch;
122         }
123     }
124
125     if ( chLast ) {
126         // trailing '\r'
127         result += eol;
128     }
129
130     return result;
131 }
132
133 #if wxUSE_TEXTBUFFER
134
135 // ----------------------------------------------------------------------------
136 // ctors & dtor
137 // ----------------------------------------------------------------------------
138
139 wxTextBuffer::wxTextBuffer(const wxString& strBufferName)
140             : m_strBufferName(strBufferName)
141 {
142     m_nCurLine = 0;
143     m_isOpened = false;
144 }
145
146 wxTextBuffer::~wxTextBuffer()
147 {
148     // required here for Darwin
149 }
150
151 // ----------------------------------------------------------------------------
152 // buffer operations
153 // ----------------------------------------------------------------------------
154
155 bool wxTextBuffer::Exists() const
156 {
157     return OnExists();
158 }
159
160 bool wxTextBuffer::Create(const wxString& strBufferName)
161 {
162     m_strBufferName = strBufferName;
163
164     return Create();
165 }
166
167 bool wxTextBuffer::Create()
168 {
169     // buffer name must be either given in ctor or in Create(const wxString&)
170     wxASSERT( !m_strBufferName.empty() );
171
172     // if the buffer already exists do nothing
173     if ( Exists() ) return false;
174
175     if ( !OnOpen(m_strBufferName, WriteAccess) )
176         return false;
177
178     OnClose();
179     return true;
180 }
181
182 bool wxTextBuffer::Open(const wxString& strBufferName, wxMBConv& conv)
183 {
184     m_strBufferName = strBufferName;
185
186     return Open(conv);
187 }
188
189 bool wxTextBuffer::Open(wxMBConv& conv)
190 {
191     // buffer name must be either given in ctor or in Open(const wxString&)
192     wxASSERT( !m_strBufferName.empty() );
193
194     // open buffer in read-only mode
195     if ( !OnOpen(m_strBufferName, ReadAccess) )
196         return false;
197
198     // read buffer into memory
199     m_isOpened = OnRead(conv);
200
201     OnClose();
202
203     return m_isOpened;
204 }
205
206 // analyse some lines of the buffer trying to guess it's type.
207 // if it fails, it assumes the native type for our platform.
208 wxTextFileType wxTextBuffer::GuessType() const
209 {
210     wxASSERT( IsOpened() );
211
212     // scan the buffer lines
213     size_t nUnix = 0,     // number of '\n's alone
214            nDos  = 0,     // number of '\r\n'
215            nMac  = 0;     // number of '\r's
216
217     // we take MAX_LINES_SCAN in the beginning, middle and the end of buffer
218     #define MAX_LINES_SCAN    (10)
219     size_t nCount = m_aLines.Count() / 3,
220         nScan =  nCount > 3*MAX_LINES_SCAN ? MAX_LINES_SCAN : nCount / 3;
221
222     #define   AnalyseLine(n)              \
223         switch ( m_aTypes[n] ) {            \
224             case wxTextFileType_Unix: nUnix++; break;   \
225             case wxTextFileType_Dos:  nDos++;  break;   \
226             case wxTextFileType_Mac:  nMac++;  break;   \
227             default: wxFAIL_MSG(_("unknown line terminator")); \
228         }
229
230     size_t n;
231     for ( n = 0; n < nScan; n++ )     // the beginning
232         AnalyseLine(n);
233     for ( n = (nCount - nScan)/2; n < (nCount + nScan)/2; n++ )
234         AnalyseLine(n);
235     for ( n = nCount - nScan; n < nCount; n++ )
236         AnalyseLine(n);
237
238     #undef   AnalyseLine
239
240     // interpret the results (FIXME far from being even 50% fool proof)
241     if ( nScan > 0 && nDos + nUnix + nMac == 0 ) {
242         // no newlines at all
243         wxLogWarning(_("'%s' is probably a binary buffer."), m_strBufferName.c_str());
244     }
245     else {
246         #define   GREATER_OF(t1, t2) n##t1 == n##t2 ? typeDefault               \
247                                                 : n##t1 > n##t2             \
248                                                     ? wxTextFileType_##t1   \
249                                                     : wxTextFileType_##t2
250
251 #if !defined(__WATCOMC__) || wxCHECK_WATCOM_VERSION(1,4)
252         if ( nDos > nUnix )
253             return GREATER_OF(Dos, Mac);
254         else if ( nDos < nUnix )
255             return GREATER_OF(Unix, Mac);
256         else {
257             // nDos == nUnix
258             return nMac > nDos ? wxTextFileType_Mac : typeDefault;
259         }
260 #endif // __WATCOMC__
261
262         #undef    GREATER_OF
263     }
264
265     return typeDefault;
266 }
267
268
269 bool wxTextBuffer::Close()
270 {
271     m_aTypes.Clear();
272     m_aLines.Clear();
273     m_nCurLine = 0;
274     m_isOpened = false;
275
276     return true;
277 }
278
279 bool wxTextBuffer::Write(wxTextFileType typeNew, wxMBConv& conv)
280 {
281     return OnWrite(typeNew, conv);
282 }
283
284 #endif // wxUSE_TEXTBUFFER