2 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include "RTFTranslator.h"
15 #include "ConfigView.h"
20 #undef B_TRANSLATION_CONTEXT
21 #define B_TRANSLATION_CONTEXT "RTFTranslator"
23 #define READ_BUFFER_SIZE 2048
24 #define DATA_BUFFER_SIZE 64
27 #define TEXT_IN_QUALITY 0.4
28 #define TEXT_IN_CAPABILITY 0.6
30 #define STXT_IN_QUALITY 0.5
31 #define STXT_IN_CAPABILITY 0.5
33 #define RTF_OUT_QUALITY RTF_IN_QUALITY
34 #define RTF_OUT_CAPABILITY RTF_IN_CAPABILITY
36 // The input formats that this translator supports.
37 static const translation_format sInputFormats
[] = {
64 // The output formats that this translator supports.
65 static const translation_format sOutputFormats
[] = {
93 RTFTranslator::RTFTranslator()
96 sprintf(info
, B_TRANSLATE("Rich Text Format translator v%d.%d.%d %s"),
97 static_cast<int>(B_TRANSLATION_MAJOR_VERSION(RTF_TRANSLATOR_VERSION
)),
98 static_cast<int>(B_TRANSLATION_MINOR_VERSION(RTF_TRANSLATOR_VERSION
)),
99 static_cast<int>(B_TRANSLATION_REVISION_VERSION(
100 RTF_TRANSLATOR_VERSION
)),
103 fInfo
= strdup(info
);
107 RTFTranslator::~RTFTranslator()
114 RTFTranslator::TranslatorName() const
116 return B_TRANSLATE("RTF text files");
121 RTFTranslator::TranslatorInfo() const
123 return B_TRANSLATE("Rich Text Format translator");
128 RTFTranslator::TranslatorVersion() const
130 return RTF_TRANSLATOR_VERSION
;
134 const translation_format
*
135 RTFTranslator::InputFormats(int32
*_outCount
) const
137 if (_outCount
== NULL
)
140 *_outCount
= sizeof(sInputFormats
) / sizeof(translation_format
);
141 return sInputFormats
;
145 const translation_format
*
146 RTFTranslator::OutputFormats(int32
*_outCount
) const
148 *_outCount
= sizeof(sOutputFormats
) / sizeof(translation_format
);
149 return sOutputFormats
;
154 RTFTranslator::Identify(BPositionIO
*stream
,
155 const translation_format
*format
, BMessage
*ioExtension
,
156 translator_info
*info
, uint32 outType
)
159 outType
= B_TRANSLATOR_TEXT
;
160 else if (outType
!= B_TRANSLATOR_TEXT
&& outType
!= B_STYLED_TEXT_FORMAT
161 && outType
!= RTF_TEXT_FORMAT
)
162 return B_NO_TRANSLATOR
;
165 RTF::Parser
parser(*stream
);
166 status_t status
= parser
.Identify();
168 if (status
== B_OK
) {
169 // Source data is RTF. We can translate to RTF (no-op), plaintext, or
172 // return information about the data in the stream
173 info
->type
= B_TRANSLATOR_TEXT
; //RTF_TEXT_FORMAT;
174 info
->group
= B_TRANSLATOR_TEXT
;
175 info
->quality
= RTF_IN_QUALITY
;
176 info
->capability
= RTF_IN_CAPABILITY
;
177 strlcpy(info
->name
, B_TRANSLATE("RichTextFormat file"),
179 strcpy(info
->MIME
, "text/rtf");
181 // Not an RTF file. We can only work with it if we are translating to
183 if (outType
!= RTF_TEXT_FORMAT
)
184 return B_NO_TRANSLATOR
;
186 stream
->Seek(0, SEEK_SET
);
187 TranslatorStyledTextStreamHeader header
;
188 stream
->Read(&header
, sizeof(header
));
189 swap_data(B_UINT32_TYPE
, &header
, sizeof(header
),
190 B_SWAP_BENDIAN_TO_HOST
);
191 stream
->Seek(0, SEEK_SET
);
192 if (header
.header
.magic
== B_STYLED_TEXT_FORMAT
193 && header
.header
.header_size
== (int32
)sizeof(header
)
194 && header
.header
.data_size
== 0
195 && header
.version
== 100) {
196 info
->type
= B_STYLED_TEXT_FORMAT
;
197 info
->group
= B_TRANSLATOR_TEXT
;
198 info
->quality
= STXT_IN_QUALITY
;
199 info
->capability
= STXT_IN_CAPABILITY
;
200 strlcpy(info
->name
, B_TRANSLATE("Be style text file"),
202 strcpy(info
->MIME
, "text/x-vnd.Be-stxt");
204 info
->type
= B_TRANSLATOR_TEXT
;
205 info
->group
= B_TRANSLATOR_TEXT
;
206 info
->quality
= TEXT_IN_QUALITY
;
207 info
->capability
= TEXT_IN_CAPABILITY
;
208 strlcpy(info
->name
, B_TRANSLATE("Plain text file"),
210 strcpy(info
->MIME
, "text/plain");
218 RTFTranslator::Translate(BPositionIO
*source
,
219 const translator_info
*inInfo
, BMessage
*ioExtension
,
220 uint32 outType
, BPositionIO
*target
)
222 if (target
== NULL
|| source
== NULL
)
226 outType
= B_TRANSLATOR_TEXT
;
227 if (outType
!= B_TRANSLATOR_TEXT
&& outType
!= B_STYLED_TEXT_FORMAT
228 && outType
!= RTF_TEXT_FORMAT
)
229 return B_NO_TRANSLATOR
;
231 if (strncmp(inInfo
->MIME
, "text/rtf", 8) == 0) {
232 RTF::Parser
parser(*source
);
235 status_t status
= parser
.Parse(header
);
239 if (outType
== B_TRANSLATOR_TEXT
)
240 return convert_to_plain_text(header
, *target
);
242 return convert_to_stxt(header
, *target
);
244 } else if (inInfo
->type
== B_TRANSLATOR_TEXT
) {
245 return convert_plain_text_to_rtf(*source
, *target
);
246 } else if (inInfo
->type
== B_STYLED_TEXT_FORMAT
) {
247 return convert_styled_text_to_rtf(source
, target
);
255 RTFTranslator::MakeConfigurationView(BMessage
*ioExtension
, BView
**_view
,
258 if (_view
== NULL
|| _extent
== NULL
)
261 BView
*view
= new ConfigView(BRect(0, 0, 225, 175));
263 return BTranslator::MakeConfigurationView(ioExtension
, _view
, _extent
);
266 *_extent
= view
->Bounds();
275 make_nth_translator(int32 n
, image_id you
, uint32 flags
, ...)
280 return new RTFTranslator();