1 /* 2 * Copyright 2002-2007, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Mattias Sundblad 7 * Andrew Bachmann 8 * Axel Dörfler, axeld@pinc-software.de 9 */ 10 11 12 #include "Constants.h" 13 #include "StyledEditView.h" 14 15 #include <CharacterSet.h> 16 #include <CharacterSetRoster.h> 17 #include <DataIO.h> 18 #include <File.h> 19 #include <Message.h> 20 #include <Messenger.h> 21 #include <Node.h> 22 #include <Rect.h> 23 #include <TranslationUtils.h> 24 #include <UTF8.h> 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 29 30 using namespace BPrivate; 31 32 33 StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds, BHandler *handler) 34 : BTextView(viewFrame, "textview", textBounds, 35 B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW) 36 { 37 fMessenger = new BMessenger(handler); 38 fSuppressChanges = false; 39 } 40 41 42 StyledEditView::~StyledEditView() 43 { 44 delete fMessenger; 45 } 46 47 48 void 49 StyledEditView::Select(int32 start, int32 finish) 50 { 51 fMessenger->SendMessage(start == finish ? DISABLE_ITEMS : ENABLE_ITEMS); 52 fMessenger->SendMessage(UPDATE_LINE); 53 BTextView::Select(start, finish); 54 } 55 56 57 void 58 StyledEditView::Reset() 59 { 60 fSuppressChanges = true; 61 SetText(""); 62 fEncoding = ""; 63 fSuppressChanges = false; 64 } 65 66 67 status_t 68 StyledEditView::GetStyledText(BPositionIO* stream) 69 { 70 fSuppressChanges = true; 71 status_t result = BTranslationUtils::GetStyledText(stream, this, 72 fEncoding.String()); 73 fSuppressChanges = false; 74 75 if (result != B_OK) 76 return result; 77 78 BNode* node = dynamic_cast<BNode*>(stream); 79 if (node != NULL) { 80 // get encoding 81 if (node->ReadAttrString("be:encoding", &fEncoding) != B_OK) { 82 // try to read as "int32" 83 int32 encoding; 84 ssize_t bytesRead = node->ReadAttr("be:encoding", B_INT32_TYPE, 0, 85 &encoding, sizeof(encoding)); 86 if (bytesRead == (ssize_t)sizeof(encoding)) { 87 if (encoding == 65535) { 88 fEncoding = "UTF-8"; 89 } else { 90 const BCharacterSet* characterSet 91 = BCharacterSetRoster::GetCharacterSetByConversionID(encoding); 92 if (characterSet != NULL) 93 fEncoding = characterSet->GetName(); 94 } 95 } 96 } 97 98 // TODO: move those into BTranslationUtils::GetStyledText() as well? 99 100 // restore alignment 101 int32 align; 102 ssize_t bytesRead = node->ReadAttr("alignment", 0, 0, &align, sizeof(align)); 103 if (bytesRead == (ssize_t)sizeof(align)) 104 SetAlignment((alignment)align); 105 106 // restore wrapping 107 bool wrap; 108 bytesRead = node->ReadAttr("wrap", 0, 0, &wrap, sizeof(wrap)); 109 if (bytesRead == (ssize_t)sizeof(wrap)) { 110 SetWordWrap(wrap); 111 if (wrap == false) { 112 BRect textRect; 113 textRect = Bounds(); 114 textRect.OffsetTo(B_ORIGIN); 115 textRect.InsetBy(TEXT_INSET, TEXT_INSET); 116 // the width comes from stylededit R5. TODO: find a better way 117 textRect.SetRightBottom(BPoint(1500.0, textRect.RightBottom().y)); 118 SetTextRect(textRect); 119 } 120 } 121 } 122 123 return result; 124 } 125 126 127 status_t 128 StyledEditView::WriteStyledEditFile(BFile* file) 129 { 130 return BTranslationUtils::WriteStyledEditFile(this, file, 131 fEncoding.String()); 132 } 133 134 135 void 136 StyledEditView::SetEncoding(uint32 encoding) 137 { 138 fEncoding = ""; 139 if (encoding == 0) 140 return; 141 142 const BCharacterSet* set 143 = BCharacterSetRoster::GetCharacterSetByFontID(encoding); 144 145 if (set != NULL) 146 fEncoding = set->GetName(); 147 } 148 149 150 uint32 151 StyledEditView::GetEncoding() const 152 { 153 if (fEncoding == "") 154 return 0; 155 156 const BCharacterSet* set = 157 BCharacterSetRoster::FindCharacterSetByName(fEncoding.String()); 158 if(set != NULL) 159 return set->GetFontID(); 160 161 return 0; 162 } 163 164 165 void 166 StyledEditView::DeleteText(int32 start, int32 finish) 167 { 168 if (!fSuppressChanges) 169 fMessenger-> SendMessage(TEXT_CHANGED); 170 171 BTextView::DeleteText(start, finish); 172 fMessenger->SendMessage(UPDATE_LINE); 173 } 174 175 176 void 177 StyledEditView::InsertText(const char *text, int32 length, int32 offset, 178 const text_run_array *runs) 179 { 180 if (!fSuppressChanges) 181 fMessenger->SendMessage(TEXT_CHANGED); 182 183 BTextView::InsertText(text, length, offset, runs); 184 fMessenger->SendMessage(UPDATE_LINE); 185 } 186 187 188 void 189 StyledEditView::FrameResized(float width, float height) 190 { 191 BTextView::FrameResized(width, height); 192 193 if (DoesWordWrap()) { 194 BRect textRect; 195 textRect = Bounds(); 196 textRect.OffsetTo(B_ORIGIN); 197 textRect.InsetBy(TEXT_INSET, TEXT_INSET); 198 SetTextRect(textRect); 199 } 200 } 201 202