1 #include <Message.h> 2 #include <Messenger.h> 3 #include <Rect.h> 4 #include <Region.h> 5 #include <TranslationUtils.h> 6 #include <Node.h> 7 #include <stdio.h> 8 #include <CharacterSet.h> 9 #include <CharacterSetRoster.h> 10 #include <UTF8.h> 11 12 #include <StyledEditView.h> 13 #include <Constants.h> 14 15 using namespace BPrivate; 16 17 StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds, BHandler *handler) 18 : BTextView(viewFrame, "textview", textBounds, 19 B_FOLLOW_ALL, B_FRAME_EVENTS|B_WILL_DRAW) 20 { 21 fHandler= handler; 22 fMessenger= new BMessenger(handler); 23 fSuppressChanges = false; 24 fEncoding = 0; 25 } 26 27 StyledEditView::~StyledEditView() 28 { 29 delete fMessenger; 30 } 31 32 void 33 StyledEditView::FrameResized(float width, float height) 34 { 35 BTextView::FrameResized(width, height); 36 37 if (DoesWordWrap()) { 38 BRect textRect; 39 textRect = Bounds(); 40 textRect.OffsetTo(B_ORIGIN); 41 textRect.InsetBy(TEXT_INSET,TEXT_INSET); 42 SetTextRect(textRect); 43 } 44 /* // I tried to do some sort of intelligent resize thing but it just doesn't work 45 // so we revert to the R5 stylededit yucky practice of setting the text rect to 46 // some crazy large number when word wrap is turned off :-( 47 else if (textRect.Width() > TextRect().Width()) { 48 SetTextRect(textRect); 49 } 50 51 BRegion region; 52 GetTextRegion(0,TextLength(),®ion); 53 float textWidth = region.Frame().Width(); 54 if (textWidth < textRect.Width()) { 55 BRect textRect(B_ORIGIN,BPoint(textWidth+TEXT_INSET*2,Bounds().Height())); 56 textRect.InsetBy(TEXT_INSET,TEXT_INSET); 57 SetTextRect(textRect); 58 } 59 */ 60 } 61 62 status_t 63 StyledEditView::GetStyledText(BPositionIO * stream) 64 { 65 status_t result = B_OK; 66 67 fSuppressChanges = true; 68 result = BTranslationUtils::GetStyledText(stream, this, NULL); 69 fSuppressChanges = false; 70 if (result != B_OK) { 71 return result; 72 } 73 74 BNode * node = dynamic_cast<BNode*>(stream); 75 if (node != 0) { 76 ssize_t bytesRead; 77 // decode encoding 78 int32 encoding; 79 bytesRead = node->ReadAttr("be:encoding",0,0,&encoding,sizeof(encoding)); 80 if (bytesRead > 0) { 81 if (encoding == 65535) { 82 fEncoding = 0; 83 } else { 84 const BCharacterSet * cs = BCharacterSetRoster::GetCharacterSetByConversionID(encoding); 85 if (cs != 0) { 86 fEncoding = cs->GetFontID(); 87 } 88 } 89 } 90 91 // restore alignment 92 alignment align; 93 bytesRead = node->ReadAttr("alignment",0,0,&align,sizeof(align)); 94 if (bytesRead > 0) { 95 SetAlignment(align); 96 } 97 // restore wrapping 98 bool wrap; 99 bytesRead = node->ReadAttr("wrap",0,0,&wrap,sizeof(wrap)); 100 if (bytesRead > 0) { 101 SetWordWrap(wrap); 102 if (wrap == false) { 103 BRect textRect; 104 textRect = Bounds(); 105 textRect.OffsetTo(B_ORIGIN); 106 textRect.InsetBy(TEXT_INSET,TEXT_INSET); 107 // the width comes from stylededit R5. TODO: find a better way 108 textRect.SetRightBottom(BPoint(1500.0,textRect.RightBottom().y)); 109 SetTextRect(textRect); 110 } 111 } 112 } 113 if (fEncoding != 0) { 114 int32 length = stream->Seek(0,SEEK_END); 115 text_run_array * run_array = RunArray(0,length); 116 uint32 id = BCharacterSetRoster::GetCharacterSetByFontID(fEncoding)->GetConversionID(); 117 fSuppressChanges = true; 118 SetText(""); 119 fSuppressChanges = false; 120 char inBuffer[32768]; 121 off_t location = 0; 122 int32 textOffset = 0; 123 int32 state = 0; 124 int32 bytesRead; 125 while ((bytesRead = stream->ReadAt(location,inBuffer,32768)) > 0) { 126 char * inPtr = inBuffer; 127 char textBuffer[32768]; 128 int32 textLength = 32768; 129 int32 bytes = bytesRead; 130 while ((textLength > 0) && (bytes > 0)) { 131 result = convert_to_utf8(id,inPtr,&bytes,textBuffer,&textLength,&state); 132 if (result != B_OK) { 133 return result; 134 } 135 fSuppressChanges = true; 136 InsertText(textBuffer,textLength,textOffset); 137 fSuppressChanges = false; 138 textOffset += textLength; 139 inPtr += bytes; 140 location += bytes; 141 bytesRead -= bytes; 142 bytes = bytesRead; 143 if (textLength > 0) { 144 textLength = 32768; 145 } 146 } 147 } 148 SetRunArray(0,length,run_array); 149 } 150 return result; 151 } 152 153 status_t 154 StyledEditView::WriteStyledEditFile(BFile * file) 155 { 156 status_t result = B_OK; 157 result = BTranslationUtils::WriteStyledEditFile(this,file); 158 if (result != B_OK) { 159 return result; 160 } 161 if (fEncoding == 0) { 162 int32 encoding = 65535; 163 file->WriteAttr("be:encoding",B_INT32_TYPE,0,&encoding,sizeof(encoding)); 164 } else { 165 result = file->SetSize(0); 166 if (result != B_OK) { 167 return result; 168 } 169 result = file->Seek(0,SEEK_SET); 170 if (result != B_OK) { 171 return result; 172 } 173 const BCharacterSet * cs = BCharacterSetRoster::GetCharacterSetByFontID(fEncoding); 174 if (cs != 0) { 175 uint32 id = cs->GetConversionID(); 176 const char * outText = Text(); 177 int32 sourceLength = TextLength(); 178 int32 state = 0; 179 char buffer[32768]; 180 while (sourceLength > 0) { 181 int32 length = sourceLength; 182 int32 written = 32768; 183 result = convert_from_utf8(id,outText,&length,buffer,&written,&state); 184 if (result != B_OK) { 185 return result; 186 } 187 file->Write(buffer,written); 188 sourceLength -= length; 189 outText += length; 190 } 191 file->WriteAttr("be:encoding",B_INT32_TYPE,0,&id,sizeof(id)); 192 } 193 } 194 195 alignment align = Alignment(); 196 file->WriteAttr("alignment",B_INT32_TYPE,0,&align,sizeof(align)); 197 bool wrap = DoesWordWrap(); 198 file->WriteAttr("wrap",B_BOOL_TYPE,0,&wrap,sizeof(wrap)); 199 return result; 200 } 201 202 void 203 StyledEditView::Reset() 204 { 205 fSuppressChanges = true; 206 SetText(""); 207 fSuppressChanges = false; 208 } 209 210 void 211 StyledEditView::Select(int32 start, int32 finish) 212 { 213 if(start==finish) 214 fChangeMessage= new BMessage(DISABLE_ITEMS); 215 else 216 fChangeMessage= new BMessage(ENABLE_ITEMS); 217 218 fMessenger->SendMessage(fChangeMessage); 219 220 BTextView::Select(start, finish); 221 } 222 223 void 224 StyledEditView::SetEncoding(uint32 encoding) 225 { 226 fEncoding = encoding; 227 } 228 229 uint32 230 StyledEditView::GetEncoding() const 231 { 232 return fEncoding; 233 } 234 235 void 236 StyledEditView::InsertText(const char *text, int32 length, int32 offset, const text_run_array *runs) 237 { 238 if (!fSuppressChanges) 239 fMessenger-> SendMessage(new BMessage(TEXT_CHANGED)); 240 241 BTextView::InsertText(text, length, offset, runs); 242 243 }/****StyledEditView::InsertText()***/ 244 245 void 246 StyledEditView::DeleteText(int32 start, int32 finish) 247 { 248 if (!fSuppressChanges) 249 fMessenger-> SendMessage(new BMessage(TEXT_CHANGED)); 250 251 BTextView::DeleteText(start, finish); 252 253 }/***StyledEditView::DeleteText***/ 254