1/*
2 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "RTFTranslator.h"
8#include "ConfigView.h"
9#include "RTF.h"
10#include "convert.h"
11
12#include <Catalog.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16
17#undef B_TRANSLATION_CONTEXT
18#define B_TRANSLATION_CONTEXT "RTFTranslator"
19
20#define READ_BUFFER_SIZE 2048
21#define DATA_BUFFER_SIZE 64
22
23
24// The input formats that this translator supports.
25static const translation_format sInputFormats[] = {
26	{
27		RTF_TEXT_FORMAT,
28		B_TRANSLATOR_TEXT,
29		RTF_IN_QUALITY,
30		RTF_IN_CAPABILITY,
31		"text/rtf",
32		"RichTextFormat file"
33	}
34};
35
36// The output formats that this translator supports.
37static const translation_format sOutputFormats[] = {
38	{
39		B_TRANSLATOR_TEXT,
40		B_TRANSLATOR_TEXT,
41		TEXT_OUT_QUALITY,
42		TEXT_OUT_CAPABILITY,
43		"text/plain",
44		"Plain text file"
45	},
46	{
47		B_STYLED_TEXT_FORMAT,
48		B_TRANSLATOR_TEXT,
49		STXT_OUT_QUALITY,
50		STXT_OUT_CAPABILITY,
51		"text/x-vnd.Be-stxt",
52		"Be styled text file"
53	}
54};
55
56
57RTFTranslator::RTFTranslator()
58{
59	char info[256];
60	sprintf(info, B_TRANSLATE("Rich Text Format translator v%d.%d.%d %s"),
61		static_cast<int>(B_TRANSLATION_MAJOR_VERSION(RTF_TRANSLATOR_VERSION)),
62		static_cast<int>(B_TRANSLATION_MINOR_VERSION(RTF_TRANSLATOR_VERSION)),
63		static_cast<int>(B_TRANSLATION_REVISION_VERSION(
64			RTF_TRANSLATOR_VERSION)),
65		__DATE__);
66
67	fInfo = strdup(info);
68}
69
70
71RTFTranslator::~RTFTranslator()
72{
73	free(fInfo);
74}
75
76
77const char *
78RTFTranslator::TranslatorName() const
79{
80	return B_TRANSLATE("RTF text files");
81}
82
83
84const char *
85RTFTranslator::TranslatorInfo() const
86{
87	return B_TRANSLATE("Rich Text Format translator");
88}
89
90
91int32
92RTFTranslator::TranslatorVersion() const
93{
94	return RTF_TRANSLATOR_VERSION;
95}
96
97
98const translation_format *
99RTFTranslator::InputFormats(int32 *_outCount) const
100{
101	if (_outCount == NULL)
102		return NULL;
103
104	*_outCount = sizeof(sInputFormats) / sizeof(translation_format);
105	return sInputFormats;
106}
107
108
109const translation_format *
110RTFTranslator::OutputFormats(int32 *_outCount) const
111{
112	*_outCount = sizeof(sOutputFormats) / sizeof(translation_format);
113	return sOutputFormats;
114}
115
116
117status_t
118RTFTranslator::Identify(BPositionIO *stream,
119	const translation_format *format, BMessage *ioExtension,
120	translator_info *info, uint32 outType)
121{
122	if (!outType)
123		outType = B_TRANSLATOR_TEXT;
124	if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT)
125		return B_NO_TRANSLATOR;
126
127	RTF::Parser parser(*stream);
128
129	status_t status = parser.Identify();
130	if (status != B_OK)
131		return B_NO_TRANSLATOR;
132
133	// return information about the data in the stream
134	info->type = B_TRANSLATOR_TEXT; //RTF_TEXT_FORMAT;
135	info->group = B_TRANSLATOR_TEXT;
136	info->quality = RTF_IN_QUALITY;
137	info->capability = RTF_IN_CAPABILITY;
138	strlcpy(info->name, B_TRANSLATE("RichTextFormat file"),
139		sizeof(info->name));
140	strcpy(info->MIME, "text/rtf");
141
142	return B_OK;
143}
144
145
146status_t
147RTFTranslator::Translate(BPositionIO *source,
148	const translator_info *inInfo, BMessage *ioExtension,
149	uint32 outType, BPositionIO *target)
150{
151	if (target == NULL || source == NULL)
152		return B_BAD_VALUE;
153
154	if (!outType)
155		outType = B_TRANSLATOR_TEXT;
156	if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT)
157		return B_NO_TRANSLATOR;
158
159	RTF::Parser parser(*source);
160
161	RTF::Header header;
162	status_t status = parser.Parse(header);
163	if (status != B_OK)
164		return status;
165
166	// we support two different output formats
167
168	if (outType == B_TRANSLATOR_TEXT)
169		return convert_to_plain_text(header, *target);
170
171	return convert_to_stxt(header, *target);
172}
173
174
175status_t
176RTFTranslator::MakeConfigurationView(BMessage *ioExtension, BView **_view,
177	BRect *_extent)
178{
179	if (_view == NULL || _extent == NULL)
180		return B_BAD_VALUE;
181
182	BView *view = new ConfigView(BRect(0, 0, 225, 175));
183	if (view == NULL)
184		return BTranslator::MakeConfigurationView(ioExtension, _view, _extent);
185
186	*_view = view;
187	*_extent = view->Bounds();
188	return B_OK;
189}
190
191
192//	#pragma mark -
193
194
195BTranslator *
196make_nth_translator(int32 n, image_id you, uint32 flags, ...)
197{
198	if (n != 0)
199		return NULL;
200
201	return new RTFTranslator();
202}
203
204