xref: /haiku/src/add-ons/translators/rtf/RTFTranslator.cpp (revision d3ff06683af390a4c2e83b69177e0a2eb76679bc)
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_TRANSLATE_CONTEXT
18 #define B_TRANSLATE_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.
25 static 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.
37 static 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 
57 RTFTranslator::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 
71 RTFTranslator::~RTFTranslator()
72 {
73 	free(fInfo);
74 }
75 
76 
77 const char *
78 RTFTranslator::TranslatorName() const
79 {
80 	return B_TRANSLATE("RTF text files");
81 }
82 
83 
84 const char *
85 RTFTranslator::TranslatorInfo() const
86 {
87 	return B_TRANSLATE("Rich Text Format Translator");
88 }
89 
90 
91 int32
92 RTFTranslator::TranslatorVersion() const
93 {
94 	return RTF_TRANSLATOR_VERSION;
95 }
96 
97 
98 const translation_format *
99 RTFTranslator::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 
109 const translation_format *
110 RTFTranslator::OutputFormats(int32 *_outCount) const
111 {
112 	*_outCount = sizeof(sOutputFormats) / sizeof(translation_format);
113 	return sOutputFormats;
114 }
115 
116 
117 status_t
118 RTFTranslator::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 
146 status_t
147 RTFTranslator::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 
175 status_t
176 RTFTranslator::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 
195 BTranslator *
196 make_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