~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/plugins/contrib/source_exporter/RTFExporter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This code is based in the RTF output generated by Dev-C++
 
3
 *
 
4
 * The tests have shown some missing styles, namely style 11
 
5
 */
 
6
 
 
7
#include "RTFExporter.h"
 
8
#include <configmanager.h>
 
9
#include <wx/fontutil.h>
 
10
#include <cstdlib>
 
11
#include <sstream>
 
12
#include <iomanip>
 
13
#include <algorithm>
 
14
#include <wx/file.h>
 
15
 
 
16
using std::ostringstream;
 
17
using std::hex;
 
18
using std::setw;
 
19
using std::setfill;
 
20
using std::uppercase;
 
21
using std::size_t;
 
22
using std::find;
 
23
using std::for_each;
 
24
 
 
25
namespace
 
26
{
 
27
  // Helper function to convert i to a string
 
28
  inline string to_string(int i)
 
29
  {
 
30
    ostringstream ostr;
 
31
 
 
32
    ostr << i;
 
33
 
 
34
    return ostr.str();
 
35
  }
 
36
 
 
37
  // operator == overloaded for wxColour objects
 
38
  bool operator == (const wxColour &left, const wxColour &right)
 
39
  {
 
40
    return left.Red() == right.Red() && left.Green() == right.Green() && left.Blue() == right.Blue();
 
41
  }
 
42
 
 
43
  // operator != overloaded for wxColour objects
 
44
  bool operator != (const wxColour &left, const wxColour &right)
 
45
  {
 
46
    return left.Red() != right.Red() || left.Green() != right.Green() || left.Blue() != right.Blue();
 
47
  }
 
48
 
 
49
  // Helper class to append colors in RTF colortbl format to a string
 
50
  class wxColourToRTFTbl
 
51
  {
 
52
    private:
 
53
      string *_str;
 
54
 
 
55
    public:
 
56
      wxColourToRTFTbl(string *str)
 
57
      : _str(str)
 
58
      {
 
59
        //
 
60
      }
 
61
 
 
62
      void operator () (const wxColour &color)
 
63
      {
 
64
        (*_str) += string("\\red") + to_string(color.Red());
 
65
        (*_str) += string("\\green") + to_string(color.Green());
 
66
        (*_str) += string("\\blue") + to_string(color.Blue());
 
67
        (*_str) += string(";");
 
68
      }
 
69
  };
 
70
};
 
71
 
 
72
bool RTFExporter::Style::operator == (int aValue)
 
73
{
 
74
  return value == aValue;
 
75
}
 
76
 
 
77
string RTFExporter::RTFFontTable(int &pt)
 
78
{
 
79
  string fonttbl("{\\rtf1\\ansi\\deff0\\deftab720{\\fonttbl{\\f0\\fmodern ");
 
80
  wxString fontstring = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/font"), wxEmptyString);
 
81
  pt = 8;
 
82
 
 
83
  if (!fontstring.IsEmpty())
 
84
  {
 
85
    wxFont tmpFont;
 
86
    wxNativeFontInfo nfi;
 
87
    nfi.FromString(fontstring);
 
88
    tmpFont.SetNativeFontInfo(nfi);
 
89
 
 
90
    pt = tmpFont.GetPointSize();
 
91
    wxString faceName = tmpFont.GetFaceName();
 
92
 
 
93
    if (!faceName.IsEmpty())
 
94
    {
 
95
      fonttbl += string(faceName.mb_str());
 
96
    }
 
97
    else
 
98
    {
 
99
      fonttbl += "Courier New";
 
100
    }
 
101
  }
 
102
  else
 
103
  {
 
104
    fonttbl += "Courier New";
 
105
  }
 
106
 
 
107
  fonttbl += ";}}\n";
 
108
 
 
109
  return fonttbl;
 
110
}
 
111
 
 
112
string RTFExporter::RTFColorTable(const EditorColourSet *c_color_set, HighlightLanguage lang)
 
113
{
 
114
  string colortbl("{\\colortbl");
 
115
  vector<wxColour> color_tbl; // We'll store fore and back colors here
 
116
 
 
117
  m_styles.clear(); // Be sure the styles are cleared
 
118
  defStyleIdx = -1; // No default style
 
119
 
 
120
  if (lang != HL_NONE)
 
121
  {
 
122
    const int count = const_cast<EditorColourSet *>(c_color_set)->GetOptionCount(lang);
 
123
 
 
124
    for (int i = 0; i < count; ++i)
 
125
    {
 
126
      OptionColour *optc = const_cast<EditorColourSet *>(c_color_set)->GetOptionByIndex(lang, i);
 
127
 
 
128
      if (!optc->isStyle)
 
129
      {
 
130
        continue;
 
131
      }
 
132
 
 
133
      vector<wxColour>::iterator foreIter = find(color_tbl.begin(), color_tbl.end(), optc->fore);
 
134
 
 
135
      // Is the fore color already in color_tbl?
 
136
      if (foreIter == color_tbl.end())
 
137
      {
 
138
        // NO? Then push it and make foreIter point to it (it's the last one)
 
139
        color_tbl.push_back(optc->fore);
 
140
        foreIter = color_tbl.end() - 1;
 
141
      }
 
142
 
 
143
      int foreIdx = foreIter - color_tbl.begin();
 
144
 
 
145
      vector<wxColour>::iterator backIter = find(color_tbl.begin(), color_tbl.end(), optc->back);
 
146
 
 
147
      // Is the back color already in color_tbl?
 
148
      if (backIter == color_tbl.end())
 
149
      {
 
150
        // NO? Then push it and make backIter point to it (it's the last one)
 
151
        color_tbl.push_back(optc->back);
 
152
        backIter = color_tbl.end() - 1;
 
153
      }
 
154
      /* TODO (Ceniza#1#): If the background color isn't set don't add it (backIdx = -1) and check for it later */
 
155
      int backIdx = backIter - color_tbl.begin();
 
156
 
 
157
      Style tmpStyle =
 
158
      {
 
159
        optc->value,
 
160
        backIdx,
 
161
        foreIdx,
 
162
        optc->bold,
 
163
        optc->italics,
 
164
        optc->underlined
 
165
      };
 
166
 
 
167
      m_styles.push_back(tmpStyle);
 
168
 
 
169
      // Default Style
 
170
      if (optc->value == 0)
 
171
      {
 
172
        defStyleIdx = m_styles.size() - 1;
 
173
      }
 
174
    }
 
175
 
 
176
    // We've got all the colors and all styles. Write the colors
 
177
    for_each(color_tbl.begin(), color_tbl.end(), wxColourToRTFTbl(&colortbl));
 
178
  }
 
179
 
 
180
  colortbl += "}\n";
 
181
 
 
182
  return colortbl;
 
183
}
 
184
 
 
185
const char *RTFExporter::RTFInfo = "{\\info{\\comment Generated by the Code::Blocks RTF Exporter plugin}\n";
 
186
const char *RTFExporter::RTFTitle = "{\\title Untitled}}\n";
 
187
 
 
188
string RTFExporter::RTFBody(const wxMemoryBuffer &styled_text, int pt)
 
189
{
 
190
  string rtf_body("\n\\deflang1033\\pard\\plain\\f0");
 
191
  const char *buffer = reinterpret_cast<char *>(styled_text.GetData());
 
192
  const size_t buffer_size = styled_text.GetDataLen();
 
193
 
 
194
  rtf_body += string("\\fs") + to_string(pt * 2) + string(" ");
 
195
 
 
196
  if (buffer_size == 0)
 
197
  {
 
198
    return rtf_body;
 
199
  }
 
200
 
 
201
  // Get the current style from the first character
 
202
  char current_style = buffer[1];
 
203
 
 
204
  // If the first style happen to be the body style...
 
205
  if (current_style == 0)
 
206
  {
 
207
    if (defStyleIdx != -1)
 
208
    {
 
209
      vector<Style>::iterator i = m_styles.begin() + defStyleIdx;
 
210
 
 
211
      rtf_body += string("\\cb") + to_string(i->backIdx);
 
212
      rtf_body += string("\\cf") + to_string(i->foreIdx);
 
213
 
 
214
      if (i->bold)
 
215
      {
 
216
        rtf_body += "\\b";
 
217
      }
 
218
 
 
219
      if (i->italics)
 
220
      {
 
221
        rtf_body += "\\i";
 
222
      }
 
223
 
 
224
      if (i->underlined)
 
225
      {
 
226
        rtf_body += "\\ul";
 
227
      }
 
228
 
 
229
      rtf_body += " ";
 
230
    }
 
231
  }
 
232
  else
 
233
  {
 
234
    vector<Style>::iterator i = find(m_styles.begin(), m_styles.end(), current_style);
 
235
 
 
236
    if (i != m_styles.end())
 
237
    {
 
238
      rtf_body += string("\\cb") + to_string(i->backIdx);
 
239
      rtf_body += string("\\cf") + to_string(i->foreIdx);
 
240
 
 
241
      if (i->bold)
 
242
      {
 
243
        rtf_body += "\\b";
 
244
      }
 
245
 
 
246
      if (i->italics)
 
247
      {
 
248
        rtf_body += "\\i";
 
249
      }
 
250
 
 
251
      if (i->underlined)
 
252
      {
 
253
        rtf_body += "\\ul";
 
254
      }
 
255
 
 
256
      rtf_body += " ";
 
257
    }
 
258
  }
 
259
 
 
260
  for (size_t i = 0; i < buffer_size; i += 2)
 
261
  {
 
262
    if (buffer[i + 1] != current_style)
 
263
    {
 
264
      if (!isspace(buffer[i]))
 
265
      {
 
266
        vector<Style>::iterator oldStyle = find(m_styles.begin(), m_styles.end(), current_style);
 
267
 
 
268
        if (oldStyle != m_styles.end())
 
269
        {
 
270
          if (oldStyle->underlined)
 
271
          {
 
272
            rtf_body += "\\ul0";
 
273
          }
 
274
 
 
275
          if (oldStyle->italics)
 
276
          {
 
277
            rtf_body += "\\i0";
 
278
          }
 
279
 
 
280
          if (oldStyle->bold)
 
281
          {
 
282
            rtf_body += "\\b0";
 
283
          }
 
284
        }
 
285
 
 
286
        current_style = buffer[i + 1];
 
287
 
 
288
        vector<Style>::iterator newStyle = find(m_styles.begin(), m_styles.end(), current_style);
 
289
 
 
290
        if (newStyle != m_styles.end())
 
291
        {
 
292
          rtf_body += string("\\cb") + to_string(newStyle->backIdx);
 
293
          rtf_body += string("\\cf") + to_string(newStyle->foreIdx);
 
294
 
 
295
          if (newStyle->bold)
 
296
          {
 
297
            rtf_body += "\\b";
 
298
          }
 
299
 
 
300
          if (newStyle->italics)
 
301
          {
 
302
            rtf_body += "\\i";
 
303
          }
 
304
 
 
305
          if (newStyle->underlined)
 
306
          {
 
307
            rtf_body += "\\ul";
 
308
          }
 
309
        }
 
310
        else if (defStyleIdx != -1)
 
311
        {
 
312
          vector<Style>::iterator i = m_styles.begin() + defStyleIdx;
 
313
 
 
314
          rtf_body += string("\\cb") + to_string(i->backIdx);
 
315
          rtf_body += string("\\cf") + to_string(i->foreIdx);
 
316
 
 
317
          if (i->bold)
 
318
          {
 
319
            rtf_body += "\\b";
 
320
          }
 
321
 
 
322
          if (i->italics)
 
323
          {
 
324
            rtf_body += "\\i";
 
325
          }
 
326
 
 
327
          if (i->underlined)
 
328
          {
 
329
            rtf_body += "\\ul";
 
330
          }
 
331
        }
 
332
 
 
333
        rtf_body += " ";
 
334
      }
 
335
    }
 
336
 
 
337
    switch (buffer[i])
 
338
    {
 
339
      case '{':
 
340
        rtf_body += "\\{";
 
341
        break;
 
342
 
 
343
      case '}':
 
344
        rtf_body += "\\}";
 
345
        break;
 
346
 
 
347
      case '\r':
 
348
        break;
 
349
 
 
350
      case '\n':
 
351
        rtf_body += "\n\\par ";
 
352
        break;
 
353
 
 
354
      default:
 
355
        rtf_body += buffer[i];
 
356
        break;
 
357
    };
 
358
  }
 
359
 
 
360
  return rtf_body;
 
361
}
 
362
 
 
363
const char *RTFExporter::RTFEnd = "\n\\par }";
 
364
 
 
365
void RTFExporter::Export(const wxString &filename, const wxString &title, const wxMemoryBuffer &styled_text, const EditorColourSet *color_set)
 
366
{
 
367
  string rtf_code;
 
368
  HighlightLanguage lang = const_cast<EditorColourSet *>(color_set)->GetLanguageForFilename(title);
 
369
  int pt;
 
370
 
 
371
  rtf_code += RTFFontTable(pt);
 
372
  rtf_code += RTFColorTable(color_set, lang);
 
373
  rtf_code += RTFInfo;
 
374
  rtf_code += RTFTitle;
 
375
  rtf_code += RTFBody(styled_text, pt);
 
376
  rtf_code += RTFEnd;
 
377
 
 
378
  wxFile file(filename, wxFile::write);
 
379
  file.Write(rtf_code.c_str(), rtf_code.size());
 
380
}