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