diff --git a/headers/os/translation/TranslationUtils.h b/headers/os/translation/TranslationUtils.h index 42009029f1..86b2fee664 100644 --- a/headers/os/translation/TranslationUtils.h +++ b/headers/os/translation/TranslationUtils.h @@ -46,80 +46,48 @@ class BMenu; // You don't create an instance of it; you just call its various // static member functions for utility-like operations. class BTranslationUtils { - BTranslationUtils(); - ~BTranslationUtils(); - BTranslationUtils(const BTranslationUtils &); - BTranslationUtils & operator=(const BTranslationUtils &); + BTranslationUtils(); + ~BTranslationUtils(); + BTranslationUtils(const BTranslationUtils &); + BTranslationUtils & operator=(const BTranslationUtils &); -public: + public: + // bitmap functions + static BBitmap *GetBitmap(const char *name, BTranslatorRoster *roster = NULL); + static BBitmap *GetBitmap(uint32 type, int32 id, + BTranslatorRoster *roster = NULL); + static BBitmap *GetBitmap(uint32 type, const char *name, + BTranslatorRoster *roster = NULL); + static BBitmap *GetBitmapFile(const char *name, + BTranslatorRoster *roster = NULL); + static BBitmap *GetBitmap(const entry_ref *ref, + BTranslatorRoster *roster = NULL); + static BBitmap *GetBitmap(BPositionIO *stream, + BTranslatorRoster *roster = NULL); -// BITMAP getters - allocate the BBitmap; you call delete on it! + // text functions + static status_t GetStyledText(BPositionIO *fromStream, BTextView *intoView, + BTranslatorRoster *roster = NULL); + static status_t PutStyledText(BTextView *fromView, BPositionIO *intoStream, + BTranslatorRoster *roster = NULL); + static status_t WriteStyledEditFile(BTextView *fromView, BFile *intoFile); + static status_t WriteStyledEditFile(BTextView *fromView, BFile *intoFile, + const char* encoding); -static BBitmap *GetBitmap(const char *kName, BTranslatorRoster *roster = NULL); - // Get bitmap - first try as file name, then as B_TRANSLATOR_BITMAP - // resource type from app file -- can be of any kind for which a - // translator is installed (TGA, etc) - -static BBitmap *GetBitmap(uint32 type, int32 id, - BTranslatorRoster *roster = NULL); - // Get bitmap - from app resource by id - -static BBitmap *GetBitmap(uint32 type, const char *kName, - BTranslatorRoster *roster = NULL); - // Get Bitmap - from app resource by name - -static BBitmap *GetBitmapFile(const char *kName, - BTranslatorRoster *roster = NULL); - // Get bitmap - from file only + // misc. functions + static BMessage *GetDefaultSettings(translator_id forTranslator, + BTranslatorRoster *roster = NULL); + static BMessage *GetDefaultSettings(const char *translatorName, + int32 translatorVersion); -static BBitmap *GetBitmap(const entry_ref *kRef, - BTranslatorRoster *roster = NULL); - // Get bitmap - from open file (or BMemoryIO) - -static BBitmap *GetBitmap(BPositionIO *stream, - BTranslatorRoster *roster = NULL); - // Get bitmap - from open file or IO type object - // This function does the real work for the other GetBitmap functions - -static status_t GetStyledText(BPositionIO *fromStream, BTextView *intoView, - BTranslatorRoster *roster = NULL); - // For styled text, we can translate from a stream - // directly into a BTextView - -static status_t PutStyledText(BTextView *fromView, BPositionIO *intoStream, - BTranslatorRoster *roster = NULL); - // Saving is slightly different -- given the BTextView, a - // B_STYLED_TEXT_FORMAT stream is written to intoStream. You can then call - // Translate() yourself to translate that stream into something else if - // you want, if it is a temp file or a BMallocIO. It's also OK to write - // the B_STYLED_TEXT_FORMAT to a file, although the StyledEdit format - // (TEXT file + style attributes) is preferred. This convenience function - // is only marginally part of the Translation Kit, but what the hey :-) - -static status_t WriteStyledEditFile(BTextView *fromView, BFile *intoFile); - // Writes the styled text data from fromView to intoFile - -static BMessage *GetDefaultSettings(translator_id forTranslator, - BTranslatorRoster *roster = NULL); - // Get default settings for the translator with the id forTranslator - -static BMessage *GetDefaultSettings(const char *kTranslatorName, - int32 translatorVersion); - // Get default settings for the translator with the name kTranslatorName - -// Envious of that "Save As" menu in ShowImage? Well, you can have your own! -// AddTranslationItems will add menu items for all translations from the -// basic format you specify (B_TRANSLATOR_BITMAP, B_TRANSLATOR_TEXT etc). -// The translator ID and format constant chosen will be added to the message -// that is sent to you when the menu item is selected. - enum { - B_TRANSLATION_MENU = 'BTMN' - }; -static status_t AddTranslationItems(BMenu *intoMenu, uint32 fromType, - const BMessage *kModel = NULL, // default B_TRANSLATION_MENU - const char *kTranslatorIdName = NULL, // default "be:translator" - const char *kTranslatorTypeName = NULL, // default "be:type" - BTranslatorRoster *roster = NULL); + enum { + B_TRANSLATION_MENU = 'BTMN' + }; + static status_t AddTranslationItems(BMenu *intoMenu, uint32 fromType, + const BMessage *model = NULL, // default B_TRANSLATION_MENU + const char *translatorIdName = NULL, // default "be:translator" + const char *translatorTypeName = NULL, // default "be:type" + BTranslatorRoster *roster = NULL); }; #endif /* _TRANSLATION_UTILS_H */ diff --git a/src/kits/translation/Jamfile b/src/kits/translation/Jamfile index bd83091c34..9c5526d464 100644 --- a/src/kits/translation/Jamfile +++ b/src/kits/translation/Jamfile @@ -7,7 +7,7 @@ if $(TARGET_PLATFORM) != haiku { UsePublicHeaders translation ; } -UsePrivateHeaders translation ; +UsePrivateHeaders translation textencoding ; SharedLibrary libtranslation.so : BitmapStream.cpp @@ -16,7 +16,7 @@ SharedLibrary libtranslation.so : Translator.cpp TranslatorRoster.cpp - : be $(TARGET_LIBSTDC++) + : be libtextencoding.so $(TARGET_LIBSTDC++) ; Package haiku-translationkit-cvs : diff --git a/src/kits/translation/TranslationUtils.cpp b/src/kits/translation/TranslationUtils.cpp index 112da427ed..67d0d9d29e 100644 --- a/src/kits/translation/TranslationUtils.cpp +++ b/src/kits/translation/TranslationUtils.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -24,12 +26,16 @@ #include #include #include +#include #include #include #include +using namespace BPrivate; + + BTranslationUtils::BTranslationUtils() { } @@ -587,13 +593,14 @@ BTranslationUtils::PutStyledText(BTextView *fromView, BPositionIO *intoStream, \param view the view with the styled text \param file the file where the styled text is written to + \param the encoding to use, defaults to UTF-8 \return B_BAD_VALUE, if either parameter is NULL B_OK, if successful, and any possible file error if writing failed. */ status_t -BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) +BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file, const char *encoding) { if (view == NULL || file == NULL) return B_BAD_VALUE; @@ -607,19 +614,63 @@ BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) return B_ERROR; // move to the start of the file if not already there - status_t result = file->Seek(0, SEEK_SET); - if (result != B_OK) - return result; + status_t status = file->Seek(0, SEEK_SET); + if (status != B_OK) + return status; - // Write plain text data to file - ssize_t bytesWritten = file->Write(text, textLength); - if (bytesWritten != textLength) - return B_ERROR; + const BCharacterSet* characterSet = NULL; + if (encoding != NULL && strcmp(encoding, "")) + characterSet = BCharacterSetRoster::FindCharacterSetByName(encoding); + if (characterSet == NULL) { + // default encoding - UTF-8 + // Write plain text data to file + ssize_t bytesWritten = file->Write(text, textLength); + if (bytesWritten != textLength) { + if (bytesWritten < B_OK) + return bytesWritten; + + return B_ERROR; + } + + // be:encoding, defaults to UTF-8 (65535) + // Note that the B_UNICODE_UTF8 constant is 0 and for some reason + // not appropriate for use here. + int32 value = 65535; + file->WriteAttr("be:encoding", B_INT32_TYPE, 0, &value, sizeof(value)); + } else { + // we need to convert the text + uint32 id = characterSet->GetConversionID(); + const char* outText = view->Text(); + int32 sourceLength = textLength; + int32 state = 0; + + textLength = 0; + + do { + char buffer[32768]; + int32 length = sourceLength; + int32 bufferSize = sizeof(buffer); + status = convert_from_utf8(id, outText, &length, buffer, &bufferSize, &state); + if (status != B_OK) + return status; + + ssize_t bytesWritten = file->Write(buffer, bufferSize); + if (bytesWritten < B_OK) + return bytesWritten; + + sourceLength -= length; + textLength += bytesWritten; + outText += length; + } while (sourceLength > 0); + + file->WriteAttr("be:encoding", B_STRING_TYPE, 0, + encoding, strlen(encoding)); + } // truncate any extra text - result = file->SetSize(textLength); - if (result != B_OK) - return result; + status = file->SetSize(textLength); + if (status != B_OK) + return status; // Write attributes. We don't report an error anymore after this point, // as attributes aren't that crucial - not all volumes support attributes. @@ -630,14 +681,13 @@ BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) char type[B_MIME_TYPE_LENGTH]; if (info.GetType(type) != B_OK) { // This file doesn't have a file type yet, so let's set it - result = info.SetType("text/plain"); - if (result < B_OK) + if (info.SetType("text/plain") < B_OK) return B_OK; } // word wrap setting, turned on by default int32 wordWrap = view->DoesWordWrap() ? 1 : 0; - bytesWritten = file->WriteAttr("wrap", B_INT32_TYPE, 0, + ssize_t bytesWritten = file->WriteAttr("wrap", B_INT32_TYPE, 0, &wordWrap, sizeof(int32)); if (bytesWritten != sizeof(int32)) return B_OK; @@ -649,15 +699,6 @@ BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) if (bytesWritten != sizeof(int32)) return B_OK; - // be:encoding, defaults to UTF-8 (65535) - // Note that the B_UNICODE_UTF8 constant is 0 and for some reason - // not appropriate for use here. - int32 encoding = 65535; - bytesWritten = file->WriteAttr("be:encoding", B_INT32_TYPE, 0, - &encoding, sizeof(int32)); - if (bytesWritten != sizeof(int32)) - return B_OK; - // Write text_run_array, ie. the styles of the text text_run_array *runArray = view->RunArray(0, view->TextLength()); @@ -681,6 +722,13 @@ BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) } +status_t +BTranslationUtils::WriteStyledEditFile(BTextView* view, BFile* file) +{ + return WriteStyledEditFile(view, file, NULL); +} + + /*! Each translator can have default settings, set by the "translations" control panel. You can read these settings to