xref: /haiku/src/apps/stylededit/StyledEditWindow.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 // Be-defined headers
2 
3 #include <Alert.h>
4 #include <Autolock.h>
5 #include <Debug.h>
6 #include <Clipboard.h>
7 #include <File.h>
8 #include <Menu.h>
9 #include <MenuItem.h>
10 #include <PrintJob.h>
11 #include <Roster.h>
12 #include <ScrollView.h>
13 #include <stdlib.h>
14 #include <String.h>
15 #include <TextControl.h>
16 #include <TranslationUtils.h>
17 #include <Window.h>
18 #include <CharacterSet.h>
19 #include <CharacterSetRoster.h>
20 
21 //****** Application defined header files************/.
22 #include "Constants.h"
23 #include "ColorMenuItem.h"
24 #include "FindWindow.h"
25 #include "ReplaceWindow.h"
26 #include "StyledEditApp.h"
27 #include "StyledEditView.h"
28 #include "StyledEditWindow.h"
29 
30 using namespace BPrivate;
31 
32 StyledEditWindow::StyledEditWindow(BRect frame, int32 id, uint32 encoding)
33 	: BWindow(frame,"untitled",B_DOCUMENT_WINDOW,0)
34 {
35 	InitWindow(encoding);
36 	BString unTitled;
37 	unTitled.SetTo("Untitled ");
38 	unTitled << id;
39 	SetTitle(unTitled.String());
40 	fSaveItem->SetEnabled(true); // allow saving empty files
41 	Show();
42 } /***StyledEditWindow()***/
43 
44 StyledEditWindow::StyledEditWindow(BRect frame, entry_ref *ref, uint32 encoding)
45 	: BWindow(frame,"untitled",B_DOCUMENT_WINDOW,0)
46 {
47 	InitWindow(encoding);
48 	OpenFile(ref);
49 	Show();
50 } /***StyledEditWindow()***/
51 
52 StyledEditWindow::~StyledEditWindow()
53 {
54 	delete fSaveMessage;
55 	delete fPrintSettings;
56 	delete fSavePanel;
57 } /***~StyledEditWindow()***/
58 
59 void
60 StyledEditWindow::InitWindow(uint32 encoding)
61 {
62 	fPrintSettings= NULL;
63 	fSaveMessage= NULL;
64 
65 	// undo modes
66 	fUndoFlag = false;
67 	fCanUndo = false;
68 	fRedoFlag = false;
69 	fCanRedo = false;
70 
71 	// clean modes
72 	fUndoCleans = false;
73 	fRedoCleans = false;
74 	fClean = true;
75 
76 	//search- state
77 	fReplaceString= "";
78 	fStringToFind="";
79 	fCaseSens= false;
80 	fWrapAround= false;
81 	fBackSearch= false;
82 
83 	//add menubar
84 	fMenuBar = new BMenuBar(BRect(0,0,0,0),"menubar");
85 
86 	AddChild(fMenuBar);
87 
88 	//add textview and scrollview
89 	BRect			viewFrame;
90 	BRect			textBounds;
91 
92 	viewFrame= Bounds();
93 
94 	viewFrame.top = fMenuBar->Bounds().Height()+1; //021021
95 	viewFrame.right -=  B_V_SCROLL_BAR_WIDTH;
96 	viewFrame.left = 0; //021021
97 	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
98 
99 
100 	textBounds= viewFrame;
101 	textBounds.OffsetTo(B_ORIGIN);
102 	textBounds.InsetBy(TEXT_INSET, TEXT_INSET);
103 
104 
105 	fTextView= new StyledEditView(viewFrame, textBounds, this);
106 	fTextView->SetDoesUndo(true);
107 	fTextView->SetStylable(true);
108 	fTextView->SetEncoding(encoding);
109 
110 	fScrollView= new BScrollView("scrollview", fTextView, B_FOLLOW_ALL, 0, true, true, B_PLAIN_BORDER);
111 	AddChild(fScrollView);
112 	fTextView->MakeFocus(true);
113 
114 
115 	//Add "File"-menu:
116 	BMenu			*menu;
117 	BMenu			*subMenu;
118 	BMenuItem		*menuItem;
119 
120 	menu= new BMenu("File");
121 	fMenuBar->AddItem(menu);
122 
123 	menu->AddItem(menuItem= new BMenuItem("New", new BMessage(MENU_NEW), 'N'));
124 	menuItem->SetTarget(be_app);
125 
126 	menu->AddItem(menuItem= new BMenuItem(fRecentMenu= new BMenu("Open..."), new BMessage(MENU_OPEN)));
127 	menuItem->SetShortcut('O',0);
128 	menuItem->SetTarget(be_app);
129 	menu->AddSeparatorItem();
130 
131 	menu->AddItem(fSaveItem= new BMenuItem("Save", new BMessage(MENU_SAVE), 'S'));
132 	fSaveItem->SetEnabled(false);
133 	menu->AddItem(menuItem= new BMenuItem("Save As...", new BMessage(MENU_SAVEAS)));
134 	menuItem->SetEnabled(true);
135 
136 	menu->AddItem(fRevertItem= new BMenuItem("Revert to Saved...", new BMessage(MENU_REVERT)));
137 	fRevertItem->SetEnabled(false);
138 	menu->AddItem(menuItem= new BMenuItem("Close", new BMessage(MENU_CLOSE), 'W'));
139 
140 	menu->AddSeparatorItem();
141 	menu->AddItem(menuItem= new BMenuItem("Page Setup...", new BMessage(MENU_PAGESETUP)));
142 	menu->AddItem(menuItem= new BMenuItem("Print...", new BMessage(MENU_PRINT), 'P'));
143 
144 	menu->AddSeparatorItem();
145 	menu->AddItem(menuItem= new BMenuItem("Quit", new BMessage(MENU_QUIT), 'Q'));
146 
147 	//Add the "Edit"-menu:
148 	menu= new BMenu("Edit");
149 	fMenuBar->AddItem(menu);
150 
151 	menu->AddItem(fUndoItem= new BMenuItem("Can't Undo", new BMessage(B_UNDO), 'Z'));
152 	fUndoItem->SetEnabled(false);
153 
154 	menu->AddSeparatorItem();
155 	menu->AddItem(fCutItem= new BMenuItem("Cut", new BMessage(B_CUT), 'X'));
156 	fCutItem->SetEnabled(false);
157 	fCutItem->SetTarget(fTextView);
158 
159 	menu->AddItem(fCopyItem= new BMenuItem("Copy", new BMessage(B_COPY), 'C'));
160 	fCopyItem->SetEnabled(false);
161 	fCopyItem->SetTarget(fTextView);
162 
163 	menu->AddItem(menuItem= new BMenuItem("Paste", new BMessage(B_PASTE), 'V'));
164 	menuItem->SetTarget(fTextView);
165 	menu->AddItem(fClearItem= new BMenuItem("Clear", new BMessage(MENU_CLEAR)));
166 	fClearItem->SetEnabled(false);
167 	fClearItem->SetTarget(fTextView);
168 
169 
170 	menu->AddSeparatorItem();
171 	menu->AddItem(menuItem=new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A'));
172 	menuItem->SetTarget(fTextView);
173 
174 	menu->AddSeparatorItem();
175 	menu->AddItem(menuItem= new BMenuItem("Find...", new BMessage(MENU_FIND),'F'));
176 	menu->AddItem(fFindAgainItem= new BMenuItem("Find Again",new BMessage(MENU_FIND_AGAIN),'G'));
177 	fFindAgainItem->SetEnabled(false);
178 
179 	menu->AddItem(menuItem= new BMenuItem("Find Selection", new BMessage(MENU_FIND_SELECTION),'H'));
180 	menu->AddItem(menuItem= new BMenuItem("Replace...", new BMessage(MENU_REPLACE),'R'));
181 	menu->AddItem(fReplaceSameItem= new BMenuItem("Replace Same", new BMessage(MENU_REPLACE_SAME),'T'));
182 	fReplaceSameItem->SetEnabled(false);
183 
184 	//Add the "Font"-menu:
185 	BMessage		*fontMessage;
186 	fFontMenu = new BMenu("Font");
187 	fMenuBar->AddItem(fFontMenu);
188 
189 	//"Size"-subMenu
190 	fFontSizeMenu=new BMenu("Size");
191 	fFontSizeMenu->SetRadioMode(true);
192 	fFontMenu->AddItem(fFontSizeMenu);
193 
194 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("9", fontMessage= new BMessage(FONT_SIZE)));
195 	fontMessage->AddFloat("size", 9.0);
196 
197 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("10", fontMessage= new BMessage(FONT_SIZE)));
198 	fontMessage->AddFloat("size",10.0);
199 	menuItem->SetMarked(true);
200 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("11", fontMessage= new BMessage(FONT_SIZE)));
201 	fontMessage->AddFloat("size",11.0);
202 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("12", fontMessage= new BMessage(FONT_SIZE)));
203 	fontMessage->AddFloat("size",12.0);
204 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("14", fontMessage= new BMessage(FONT_SIZE)));
205 	fontMessage->AddFloat("size",14.0);
206 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("18", fontMessage= new BMessage(FONT_SIZE)));
207 	fontMessage->AddFloat("size",18.0);
208 
209 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("24", fontMessage= new BMessage(FONT_SIZE)));
210 	fontMessage->AddFloat("size",24.0);
211 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("36", fontMessage= new BMessage(FONT_SIZE)));
212 	fontMessage->AddFloat("size",36.0);
213 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("48", fontMessage= new BMessage(FONT_SIZE)));
214 	fontMessage->AddFloat("size",48.0);
215 	fFontSizeMenu->AddItem(menuItem= new BMenuItem("72", fontMessage= new BMessage(FONT_SIZE)));
216 	fontMessage->AddFloat("size",72.0);
217 
218 	//"Color"-subMenu
219 	fFontColorMenu= new BMenu("Color");
220 	fFontColorMenu->SetRadioMode(true);
221 	fFontMenu->AddItem(fFontColorMenu);
222 
223 	fFontColorMenu->AddItem(fBlackItem= new BMenuItem("Black", new BMessage(FONT_COLOR)));
224 	fBlackItem->SetMarked(true);
225 	fFontColorMenu->AddItem(fRedItem= new ColorMenuItem("Red", RED, new BMessage(FONT_COLOR)));
226 	fFontColorMenu->AddItem(fGreenItem= new ColorMenuItem("Green", GREEN, new BMessage(FONT_COLOR)));
227 	fFontColorMenu->AddItem(fBlueItem= new ColorMenuItem("Blue", BLUE, new BMessage(FONT_COLOR)));
228 	fFontColorMenu->AddItem(fCyanItem= new ColorMenuItem("Cyan", CYAN, new BMessage(FONT_COLOR)));
229 	fFontColorMenu->AddItem(fMagentaItem= new ColorMenuItem("Magenta", MAGENTA, new BMessage(FONT_COLOR)));
230 	fFontColorMenu->AddItem(fYellowItem= new ColorMenuItem("Yellow", YELLOW, new BMessage(FONT_COLOR)));
231 	fFontMenu->AddSeparatorItem();
232 
233 	//Available fonts
234 	font_family plain_family;
235 	font_style plain_style;
236 	be_plain_font->GetFamilyAndStyle(&plain_family,&plain_style);
237 	fCurrentFontItem = 0;
238 
239 	int32 numFamilies = count_font_families();
240 	for ( int32 i = 0; i < numFamilies; i++ ) {
241 		font_family localfamily;
242 		if ( get_font_family ( i, &localfamily ) == B_OK ) {
243 			subMenu=new BMenu(localfamily);
244 			subMenu->SetRadioMode(true);
245 			fFontMenu->AddItem(menuItem = new BMenuItem(subMenu, new BMessage(FONT_FAMILY)));
246 			if (!strcmp(plain_family,localfamily)) {
247 				menuItem->SetMarked(true);
248 				fCurrentFontItem = menuItem;
249 			}
250 			int32 numStyles=count_font_styles(localfamily);
251 			for(int32 j = 0;j<numStyles;j++){
252 				font_style style;
253 				uint32 flags;
254 				if( get_font_style(localfamily,j,&style,&flags)==B_OK){
255 					subMenu->AddItem(menuItem = new BMenuItem(style, new BMessage(FONT_STYLE)));
256 					if (!strcmp(plain_style,style)) {
257 						menuItem->SetMarked(true);
258 					}
259 				}
260 			}
261 		}
262 	}
263 
264 	//Add the "Document"-menu:
265 	menu= new BMenu("Document");
266 	fMenuBar->AddItem(menu);
267 
268 	//"Align"-subMenu:
269 	subMenu= new BMenu("Align");
270 	subMenu->SetRadioMode(true);
271 
272 	subMenu->AddItem(fAlignLeft = new BMenuItem("Left", new BMessage(ALIGN_LEFT)));
273 	menuItem->SetMarked(true);
274 
275 	subMenu->AddItem(fAlignCenter = new BMenuItem("Center", new BMessage(ALIGN_CENTER)));
276 	subMenu->AddItem(fAlignRight = new BMenuItem("Right", new BMessage(ALIGN_RIGHT)));
277 	menu->AddItem(subMenu);
278 	menu->AddItem(fWrapItem = new BMenuItem("Wrap Lines", new BMessage(WRAP_LINES)));
279 	fWrapItem->SetMarked(true);
280 	/***************************MENUS ADDED***********************/
281 
282 	fSavePanel = 0; // build lazily
283 	fSavePanelEncodingMenu = 0; // build lazily
284 }  /***StyledEditWindow::Initwindow()***/
285 
286 void
287 StyledEditWindow::MessageReceived(BMessage *message)
288 {
289 	switch(message->what){
290 /************file menu:***************/
291 		case MENU_SAVE: {
292 			if(!fSaveMessage)
293 				SaveAs();
294 			else
295 				Save(fSaveMessage);
296 		}
297 		break;
298 		case MENU_SAVEAS:
299 			SaveAs();
300 		break;
301 		case B_SAVE_REQUESTED:
302 			Save(message);
303 		break;
304 		case SAVE_THEN_QUIT:
305 			if (Save(message) == B_OK) {
306 				BAutolock lock(this);
307 				Quit();
308 			}
309 		break;
310 		case MENU_REVERT:
311 			RevertToSaved();
312 		break;
313 		case MENU_CLOSE: {
314 			if(this->QuitRequested()) {
315 				BAutolock lock(this);
316 				Quit();
317 			}
318 		}
319 		break;
320 		case MENU_PAGESETUP:
321 			PageSetup(fTextView->Window()->Title());
322 		break;
323 		case MENU_PRINT:
324 			Print(fTextView->Window()->Title());
325 		break;
326 		case MENU_QUIT:
327 			be_app->PostMessage(B_QUIT_REQUESTED);
328 		break;
329 /*********commands from the "Edit"-menu:**************/
330 		case B_UNDO:
331 			ASSERT(fCanUndo || fCanRedo);
332 			ASSERT(!(fCanUndo && fCanRedo));
333 			if (fCanUndo) {
334 				fUndoFlag = true;
335 			}
336 			if (fCanRedo) {
337 				fRedoFlag = true;
338 			}
339 			fTextView->Undo(be_clipboard);
340 		break;
341 		case B_CUT:
342 			fTextView->Cut(be_clipboard);
343 		break;
344 		case B_COPY:
345 			fTextView->Copy(be_clipboard);
346 		break;
347 		case B_PASTE:
348 			fTextView->Paste(be_clipboard);
349 		break;
350 		case MENU_CLEAR:
351 			fTextView->Clear();
352 		break;
353 		case MENU_FIND:
354 			{
355 			BRect findWindowFrame(100,100,400,235);
356 			FindWindow *find;
357 			find= new FindWindow(findWindowFrame, this, &fStringToFind, &fCaseSens,
358 				&fWrapAround, &fBackSearch);
359 			}
360 		break;
361 		case MSG_SEARCH:
362 			{
363 			message->FindString("findtext", &fStringToFind);
364 			fFindAgainItem->SetEnabled(true);
365 			message->FindBool("casesens", &fCaseSens);
366 			message->FindBool("wrap", &fWrapAround);
367 			message->FindBool("backsearch", &fBackSearch);
368 
369 			Search(fStringToFind, fCaseSens, fWrapAround, fBackSearch);
370 			}
371 			break;
372 		case MENU_FIND_AGAIN:
373 			Search(fStringToFind, fCaseSens, fWrapAround, fBackSearch);
374 		break;
375 		case MENU_FIND_SELECTION:
376 			FindSelection();
377 		break;
378 		case MENU_REPLACE:
379 			{
380 			BRect replaceWindowFrame(100,100,400,284);
381 			ReplaceWindow *replace;
382 			replace= new ReplaceWindow(replaceWindowFrame, this, &fStringToFind, &fReplaceString, &fCaseSens,
383 				&fWrapAround, &fBackSearch);
384 			}
385 		break;
386 		case MSG_REPLACE:
387 		{
388 			BString findIt;
389 			BString replaceWith;
390 			bool caseSens, wrap, backSearch;
391 
392 			message->FindBool("casesens", &caseSens);
393 			message->FindBool("wrap", &wrap);
394 			message->FindBool("backsearch", &backSearch);
395 
396 
397 			message->FindString("FindText",&findIt);
398 			message->FindString("ReplaceText",&replaceWith);
399 			fStringToFind= findIt;
400 			fFindAgainItem->SetEnabled(true);
401 			fReplaceString= replaceWith;
402 			fReplaceSameItem->SetEnabled(true);
403 			fCaseSens= caseSens;
404 			fWrapAround= wrap;
405 			fBackSearch= backSearch;
406 
407 			Replace(findIt, replaceWith, caseSens, wrap, backSearch);
408 		}
409 		break;
410 		case MENU_REPLACE_SAME:
411 		{
412 			Replace(fStringToFind,fReplaceString,fCaseSens,fWrapAround,fBackSearch);
413 		}
414 		break;
415 		case MSG_REPLACE_ALL:
416 		{
417 			BString findIt;
418 			BString replaceWith;
419 			bool caseSens, allWindows;
420 
421 			message->FindBool("casesens", &caseSens);
422 			message->FindString("FindText",&findIt);
423 			message->FindString("ReplaceText",&replaceWith);
424 			message->FindBool("allwindows", &allWindows);
425 
426 			fStringToFind= findIt;
427 			fFindAgainItem->SetEnabled(true);
428 			fReplaceString= replaceWith;
429 			fReplaceSameItem->SetEnabled(true);
430 			fCaseSens= caseSens;
431 
432 
433 			if(allWindows)
434 				SearchAllWindows(findIt, replaceWith, caseSens);
435 			else
436 				ReplaceAll(findIt, replaceWith,caseSens);
437 
438 		}
439 		break;
440 /*********"Font"-menu*****************/
441 		case FONT_SIZE:
442 		{
443 			float fontSize;
444 			message->FindFloat("size",&fontSize);
445 			SetFontSize(fontSize);
446 		}
447 		break;
448 		case FONT_FAMILY:
449 			{
450 			const char * fontFamily = 0, * fontStyle = 0;
451 			void * ptr;
452 			if (message->FindPointer("source",&ptr) == B_OK) {
453 				fCurrentFontItem = static_cast<BMenuItem*>(ptr);
454 				fontFamily = fCurrentFontItem->Label();
455 			}
456 			SetFontStyle(fontFamily, fontStyle);
457 			}
458 		break;
459 		case FONT_STYLE:
460 			{
461 			const char * fontFamily = 0, * fontStyle = 0;
462 			void * ptr;
463 			if (message->FindPointer("source",&ptr) == B_OK) {
464 				BMenuItem * item = static_cast<BMenuItem*>(ptr);
465 				fontStyle = item->Label();
466 				BMenu * menu = item->Menu();
467 				if (menu != 0) {
468 					fCurrentFontItem = menu->Superitem();
469 					if (fCurrentFontItem != 0) {
470 						fontFamily = fCurrentFontItem->Label();
471 					}
472 				}
473 			}
474 			SetFontStyle(fontFamily, fontStyle);
475 			}
476 		break;
477 		case FONT_COLOR:
478 		{
479 			void * ptr;
480 			if (message->FindPointer("source",&ptr) == B_OK) {
481 				if (ptr == fBlackItem) {
482 					SetFontColor(&BLACK);
483 				} else if (ptr == fRedItem) {
484 					SetFontColor(&RED);
485 				} else if (ptr == fGreenItem) {
486 					SetFontColor(&GREEN);
487 				} else if (ptr == fBlueItem) {
488 					SetFontColor(&BLUE);
489 				} else if (ptr == fCyanItem) {
490 					SetFontColor(&CYAN);
491 				} else if (ptr == fMagentaItem) {
492 					SetFontColor(&MAGENTA);
493 				} else if (ptr == fYellowItem) {
494 					SetFontColor(&YELLOW);
495 				}
496 			}
497 		}
498 		break;
499 /*********"Document"-menu*************/
500 		case ALIGN_LEFT:
501 			fTextView->SetAlignment(B_ALIGN_LEFT);
502 			fClean = false;
503 			fUndoCleans = false;
504 			fRedoCleans = false;
505 			fRevertItem->SetEnabled(fSaveMessage != NULL);
506 			fSaveItem->SetEnabled(true);
507 			fUndoItem->SetLabel("Can't Undo");
508 			fUndoItem->SetEnabled(false);
509 			fCanUndo = false;
510 			fCanRedo = false;
511 		break;
512 		case ALIGN_CENTER:
513 			fTextView->SetAlignment(B_ALIGN_CENTER);
514 			fClean = false;
515 			fUndoCleans = false;
516 			fRedoCleans = false;
517 			fRevertItem->SetEnabled(fSaveMessage != NULL);
518 			fSaveItem->SetEnabled(true);
519 			fUndoItem->SetLabel("Can't Undo");
520 			fUndoItem->SetEnabled(false);
521 			fCanUndo = false;
522 			fCanRedo = false;
523 		break;
524 		case ALIGN_RIGHT:
525 			fTextView->SetAlignment(B_ALIGN_RIGHT);
526 			fClean = false;
527 			fUndoCleans = false;
528 			fRedoCleans = false;
529 			fRevertItem->SetEnabled(fSaveMessage != NULL);
530 			fSaveItem->SetEnabled(true);
531 			fUndoItem->SetLabel("Can't Undo");
532 			fUndoItem->SetEnabled(false);
533 			fCanUndo = false;
534 			fCanRedo = false;
535 		break;
536 		case WRAP_LINES:
537 			if (fTextView->DoesWordWrap()) {
538 				fTextView->SetWordWrap(false);
539 				fWrapItem->SetMarked(false);
540 				BRect textRect;
541 				textRect = fTextView->Bounds();
542 				textRect.OffsetTo(B_ORIGIN);
543 				textRect.InsetBy(TEXT_INSET,TEXT_INSET);
544 				// the width comes from stylededit R5. TODO: find a better way
545 				textRect.SetRightBottom(BPoint(1500.0,textRect.RightBottom().y));
546 				fTextView->SetTextRect(textRect);
547 			} else {
548 				fTextView->SetWordWrap(true);
549 				fWrapItem->SetMarked(true);
550 				BRect textRect;
551 				textRect = fTextView->Bounds();
552 				textRect.OffsetTo(B_ORIGIN);
553 				textRect.InsetBy(TEXT_INSET,TEXT_INSET);
554 				fTextView->SetTextRect(textRect);
555 			}
556 			fClean = false;
557 			fUndoCleans = false;
558 			fRedoCleans = false;
559 			fRevertItem->SetEnabled(fSaveMessage != NULL);
560 			fSaveItem->SetEnabled(true);
561 			fUndoItem->SetLabel("Can't Undo");
562 			fUndoItem->SetEnabled(false);
563 			fCanUndo = false;
564 			fCanRedo = false;
565 		break;
566 		case ENABLE_ITEMS: {
567 			fCutItem->SetEnabled(true);
568 			fCopyItem->SetEnabled(true);
569 			fClearItem->SetEnabled(true);
570 		}
571 		break;
572 		case DISABLE_ITEMS: {
573 			fCutItem->SetEnabled(false);
574 			fCopyItem->SetEnabled(false);
575 			fClearItem->SetEnabled(false);
576 		}
577 		break;
578 		case TEXT_CHANGED: {
579 			if (fUndoFlag) {
580 				if (fUndoCleans) {
581 					// we cleaned!
582 					fClean = true;
583 					fUndoCleans = false;
584 				} else if (fClean) {
585 				   // if we were clean
586 				   // then a redo will make us clean again
587 				   fRedoCleans = true;
588 				   fClean = false;
589 				}
590 				// set mode
591 				fCanUndo = false;
592 				fCanRedo = true;
593 				fUndoItem->SetLabel("Redo Typing");
594 				fUndoItem->SetEnabled(true);
595 				fUndoFlag = false;
596 			} else {
597 				if (fRedoFlag && fRedoCleans) {
598 					// we cleaned!
599 					fClean = true;
600 					fRedoCleans = false;
601 				} else if (fClean) {
602 					// if we were clean
603 					// then an undo will make us clean again
604 					fUndoCleans = true;
605 					fClean = false;
606 				} else {
607 					// no more cleaning from undo now...
608 					fUndoCleans = false;
609 				}
610 				// set mode
611 				fCanUndo = true;
612 				fCanRedo = false;
613 				fUndoItem->SetLabel("Undo Typing");
614 				fUndoItem->SetEnabled(true);
615 				fRedoFlag = false;
616 			}
617 			if (fClean) {
618 				fRevertItem->SetEnabled(false);
619 			    fSaveItem->SetEnabled(fSaveMessage == NULL);
620 			} else {
621 				fRevertItem->SetEnabled(fSaveMessage != NULL);
622 				fSaveItem->SetEnabled(true);
623 			}
624 			// clear flags
625 		}
626 		break;
627 /*********"Document"-menu*************/
628 		case SAVE_AS_ENCODING:
629 			void * ptr;
630 			if (message->FindPointer("source",&ptr) == B_OK) {
631 				if (fSavePanelEncodingMenu != 0) {
632 					fTextView->SetEncoding((uint32)fSavePanelEncodingMenu->IndexOf((BMenuItem*)ptr));
633 				}
634 			}
635 		break;
636 		default:
637 		BWindow::MessageReceived(message);
638 		break;
639 	}
640 }/***StyledEditWindow::MessageReceived() ***/
641 
642 void
643 StyledEditWindow::MenusBeginning()
644 {
645 	// set up the recent documents menu
646 	BMessage documents;
647 	be_roster->GetRecentDocuments(&documents,9,NULL,APP_SIGNATURE);
648 
649 	// delete old items..
650 	//    shatty: it would be preferable to keep the old
651 	//            menu around instead of continuously thrashing
652 	//            the menu, but unfortunately there does not
653 	//            seem to be a straightforward way to update it
654 	// going backwards may simplify memory management
655 	for (int i = fRecentMenu->CountItems()-1 ; (i >= 0) ; i--) {
656 		delete fRecentMenu->RemoveItem(i);
657 	}
658 	// add new items
659 	int count = 0;
660 	entry_ref ref;
661 	while (documents.FindRef("refs",count++,&ref) == B_OK) {
662 		if ((ref.device != -1) && (ref.directory != -1)) {
663 			// sanity check passed
664 			BMessage * openRecent = new BMessage(B_REFS_RECEIVED);
665 			openRecent->AddRef("refs",&ref);
666 			BMenuItem * item = new BMenuItem(ref.name,openRecent);
667 			item->SetTarget(be_app);
668 			fRecentMenu->AddItem(item);
669 		}
670 	}
671 
672 	// update the font menu be/interface/GraphicsDefs.h
673 	// unselect the old values
674 	if (fCurrentFontItem != 0) {
675 		fCurrentFontItem->SetMarked(false);
676 	}
677 	BMenuItem * oldColorItem = fFontColorMenu->FindMarked();
678 	if (oldColorItem != 0) {
679 		oldColorItem->SetMarked(false);
680 	}
681 	BMenuItem * oldSizeItem = fFontSizeMenu->FindMarked();
682 	if (oldSizeItem != 0) {
683 		oldSizeItem->SetMarked(false);
684 	}
685 	// find the current font, color, size
686 	BFont font;
687 	uint32 sameProperties;
688 	rgb_color color = BLACK;
689 	bool sameColor;
690 	fTextView->GetFontAndColor(&font,&sameProperties,&color,&sameColor);
691 
692 	if (sameColor && (color.alpha == 255)) {
693 		// select the current color
694 		if (color.red == 0) {
695 			if (color.green == 0) {
696 				if (color.blue == 0) {
697 					fBlackItem->SetMarked(true);
698 				} else if (color.blue == 255) {
699 					fBlueItem->SetMarked(true);
700 				}
701 			} else if (color.green == 255) {
702 				if (color.blue == 0) {
703 					fGreenItem->SetMarked(true);
704 				} else if (color.blue == 255) {
705 					fCyanItem->SetMarked(true);
706 				}
707 			}
708 		} else if (color.red == 255) {
709 			if (color.green == 0) {
710 				if (color.blue == 0) {
711 					fRedItem->SetMarked(true);
712 				} else if (color.blue == 255) {
713 					fMagentaItem->SetMarked(true);
714 				}
715 			} else if (color.green == 255) {
716 				if (color.blue == 0) {
717 					fYellowItem->SetMarked(true);
718 				}
719 			}
720 		}
721 	}
722 
723 	if (sameProperties & B_FONT_SIZE) {
724 		if ((int)font.Size() == font.Size()) {
725 			// select the current font size
726 			char fontSizeStr[16];
727 			snprintf(fontSizeStr,15,"%i",(int)font.Size());
728 			BMenuItem * item = fFontSizeMenu->FindItem(fontSizeStr);
729 			if (item != 0) {
730 				item->SetMarked(true);
731 			}
732 		}
733 	}
734 
735 	if (sameProperties & B_FONT_FAMILY_AND_STYLE) {
736 		font_family family;
737 		font_style style;
738 		font.GetFamilyAndStyle(&family,&style);
739 		fCurrentFontItem = fFontMenu->FindItem(family);
740 		if (fCurrentFontItem != 0) {
741 			fCurrentFontItem->SetMarked(true);
742 			BMenu * menu = fCurrentFontItem->Submenu();
743 			if (menu != 0) {
744 				BMenuItem * item = menu->FindItem(style);
745 				if (item != 0) {
746 					item->SetMarked(true);
747 				}
748 			}
749 		}
750 	}
751 
752 	switch (fTextView->Alignment()) {
753 	case B_ALIGN_LEFT:
754 		fAlignLeft->SetMarked(true);
755 	break;
756 	case B_ALIGN_CENTER:
757 		fAlignCenter->SetMarked(true);
758 	break;
759 	case B_ALIGN_RIGHT:
760 		fAlignRight->SetMarked(true);
761 	break;
762 	default:
763 	    // I am so confused.
764 	break;
765 	}
766 }
767 
768 void
769 StyledEditWindow::Quit()
770 {
771 	styled_edit_app->CloseDocument();
772 	BWindow::Quit();
773 }
774 
775 bool
776 StyledEditWindow::QuitRequested()
777 {
778 	int32 buttonIndex= 0;
779 
780 	if (fClean) return true;
781 
782 	BAlert *saveAlert;
783 	BString alertText;
784 	alertText.SetTo("Save changes to the document \"");
785 	alertText<< Title();
786 	alertText<<"\"? ";
787 	saveAlert= new BAlert("savealert",alertText.String(), "Cancel", "Don't Save","Save",
788 		B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT);
789 	saveAlert->SetShortcut(0, B_ESCAPE);
790 	saveAlert->SetShortcut(1,'d');
791 	saveAlert->SetShortcut(2,'s');
792 	buttonIndex= saveAlert->Go();
793 
794 	if (buttonIndex==0) { 		//"cancel": dont save, dont close the window
795 		return false;
796 	} else if(buttonIndex==1) { // "don't save": just close the window
797 		return true;
798 	} else if(!fSaveMessage) { //save as
799 		BMessage * message = new BMessage(SAVE_THEN_QUIT);
800 		SaveAs(message);
801 		return false;
802 	} else {
803 		return (Save() == B_OK);
804 	}
805 
806 }/***QuitRequested()***/
807 
808 status_t
809 StyledEditWindow::Save(BMessage *message)
810 {
811 	status_t err = B_OK;
812 
813 	if(!message){
814 		message=fSaveMessage;
815 		if(!message)
816 			return B_ERROR;
817 	}
818 
819 	entry_ref dirref;
820 	err= message->FindRef("directory", &dirref);
821 	if(err!= B_OK)
822 		return err;
823 
824 	const char *name;
825 	err=message->FindString("name", &name);
826 	if (err!= B_OK)
827 		return err;
828 
829 	BDirectory dir(&dirref);
830 	err= dir.InitCheck();
831 	if(err!= B_OK)
832 		return err;
833 
834 	BEntry entry(&dir, name);
835 	err= entry.InitCheck();
836 	if(err!= B_OK)
837 		return err;
838 
839 	BFile file(&entry, B_READ_WRITE | B_CREATE_FILE);
840 	err= file.InitCheck();
841 	if(err!= B_OK)
842 		return err;
843 
844 	err = fTextView->WriteStyledEditFile(&file);
845 	if(err != B_OK) {
846 		BAlert *saveFailedAlert;
847 		BString alertText;
848 		if (err == B_TRANSLATION_ERROR_BASE) {
849 			alertText.SetTo("Translation error saving \"");
850 		} else {
851 			alertText.SetTo("Unknown error saving \"");
852 		}
853 		alertText<< name;
854 		alertText<<"\".";
855 		saveFailedAlert= new BAlert("saveFailedAlert",alertText.String(), "Bummer", 0, 0,
856 			B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_STOP_ALERT);
857 		saveFailedAlert->SetShortcut(0, B_ESCAPE);
858 		saveFailedAlert->Go();
859 		return err;
860 	}
861 
862 	SetTitle(name);
863 	if(fSaveMessage!= message)
864 	{
865 		delete fSaveMessage;
866 		fSaveMessage= new BMessage(*message);
867 	}
868 
869 	entry_ref ref;
870 	if (entry.GetRef(&ref) == B_OK) {
871 		be_roster->AddToRecentDocuments(&ref,APP_SIGNATURE);
872 	}
873 
874 	// clear clean modes
875 	fSaveItem->SetEnabled(false);
876 	fRevertItem->SetEnabled(false);
877 	fUndoCleans = false;
878 	fRedoCleans = false;
879 	fClean = true;
880 	return err;
881 } /***Save()***/
882 
883 status_t
884 StyledEditWindow::SaveAs(BMessage *message)
885 {
886 	if (fSavePanel == 0) {
887 		entry_ref * directory = 0;
888 		if (fSaveMessage != 0) {
889 			entry_ref dirref;
890 			if (fSaveMessage->FindRef("directory", &dirref)) {
891 				directory = new entry_ref(dirref);
892 			}
893 		}
894 		fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), directory, B_FILE_NODE, false);
895 
896 		fSavePanelTextView =
897 		   dynamic_cast<BTextControl*>(fSavePanel->Window()->FindView("text view"));
898 		BMenuBar * menuBar =
899 		   dynamic_cast<BMenuBar*>(fSavePanel->Window()->FindView("MenuBar"));
900 
901 		fSavePanelEncodingMenu= new BMenu("Encoding");
902 		menuBar->AddItem(fSavePanelEncodingMenu);
903 		fSavePanelEncodingMenu->SetRadioMode(true);
904 
905 		BCharacterSetRoster roster;
906 		BCharacterSet charset;
907 		while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) {
908 			BString name(charset.GetPrintName());
909 			const char * mime = charset.GetMIMEName();
910 			if (mime) {
911 				name.Append(" (");
912 				name.Append(mime);
913 				name.Append(")");
914 			}
915 			BMenuItem * item = new BMenuItem(name.String(),new BMessage(SAVE_AS_ENCODING));
916 			item->SetTarget(this);
917 			fSavePanelEncodingMenu->AddItem(item);
918 			if (charset.GetFontID() == fTextView->GetEncoding()) {
919 				item->SetMarked(true);
920 			}
921 		}
922 	}
923 
924 	// its own scope allows the lock to be released before Show()
925 	{
926 		BAutolock lock(fSavePanel->Window());
927 		if (lock.IsLocked()) {
928 			fSavePanelTextView->SetText(Title());
929 		}
930 	}
931 	if (message != 0) {
932 		fSavePanel->SetMessage(message);
933 	}
934 	fSavePanel->Show();
935 	return B_OK;
936 }
937 
938 void
939 StyledEditWindow::OpenFile(entry_ref *ref)
940 {
941 	BFile file;
942 	status_t fileinit;
943 
944 	fileinit = file.SetTo(ref, B_READ_ONLY);
945 
946 	if (fileinit == B_OK){
947 		status_t result;
948 		result = fTextView->GetStyledText(&file); //he he he :)
949 
950 		if (result != B_OK) {
951 			BEntry entry(ref, true);
952 			char name[B_FILE_NAME_LENGTH];
953 			entry.GetName(name);
954 			BAlert *loadFailedAlert;
955 			BString alertText;
956 			if (result == B_TRANSLATION_ERROR_BASE) {
957 				alertText.SetTo("Translation error loading \"");
958 			} else {
959 				alertText.SetTo("Unknown error loading \"");
960 			}
961 			alertText<< name;
962 			alertText<<"\".";
963 			loadFailedAlert= new BAlert("loadFailedAlert",alertText.String(), "Bummer", 0, 0,
964 				B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_STOP_ALERT);
965 			loadFailedAlert->Go();
966 			return;
967 		}
968 
969 		// update alignment
970 		switch (fTextView->Alignment()) {
971 			case B_ALIGN_LEFT:
972 				fAlignLeft->SetMarked(true);
973 			break;
974 			case B_ALIGN_CENTER:
975 				fAlignCenter->SetMarked(true);
976 			break;
977 			case B_ALIGN_RIGHT:
978 				fAlignRight->SetMarked(true);
979 			break;
980 			default:
981 				// weird
982 			break;
983 		}
984 
985 		// update word wrapping
986 		fWrapItem->SetMarked(fTextView->DoesWordWrap());
987 	} else {
988 		fSaveItem->SetEnabled(true); // allow saving new files
989 	}
990 
991 	be_roster->AddToRecentDocuments(ref,APP_SIGNATURE);
992 	fSaveMessage = new BMessage(B_SAVE_REQUESTED);
993 	if(fSaveMessage){
994 		BEntry entry(ref, true);
995 		BEntry parent;
996 		entry_ref parentRef;
997 		char name[B_FILE_NAME_LENGTH];
998 
999 		entry.GetParent(&parent);
1000 		entry.GetName(name);
1001 		parent.GetRef(&parentRef);
1002 		fSaveMessage->AddRef("directory",&parentRef);
1003 		fSaveMessage->AddString("name", name);
1004 		SetTitle(name);
1005 	}
1006 	fTextView->Select(0,0);
1007 }/*** StyledEditWindow::OpenFile() ***/
1008 
1009 void
1010 StyledEditWindow::RevertToSaved()
1011 {
1012 	entry_ref ref;
1013 	const char *name;
1014 
1015 	fSaveMessage->FindRef("directory", &ref);
1016 	fSaveMessage->FindString("name", &name);
1017 
1018 	BDirectory dir(&ref);
1019 
1020  	BFile file(&dir, name, B_READ_ONLY);
1021 	status_t result;
1022  	result = file.InitCheck();
1023  	if (result != B_OK) {
1024  		BAlert *vanishedAlert;
1025 		BString alertText;
1026 		alertText.SetTo("Cannot revert, file not found: \"");
1027 		alertText<< name;
1028 		alertText<<"\".";
1029 		vanishedAlert = new BAlert("vanishedAlert",alertText.String(), "Bummer", 0, 0,
1030 			B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_STOP_ALERT);
1031 		vanishedAlert->SetShortcut(0, B_ESCAPE);
1032 		vanishedAlert->Go();
1033 		return;
1034  	}
1035 
1036 	int32 buttonIndex= 0;
1037 	BAlert *revertAlert;
1038 	BString alertText;
1039 	alertText.SetTo("Revert to the last version of \"");
1040 	alertText<< Title();
1041 	alertText<<"\"? ";
1042 	revertAlert= new BAlert("revertAlert",alertText.String(), "Cancel", "OK", 0,
1043 		B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
1044 	revertAlert->SetShortcut(0, B_ESCAPE);
1045 	revertAlert->SetShortcut(1, 'o');
1046 	buttonIndex= revertAlert->Go();
1047 
1048 	if (buttonIndex!=1) { 		// some sort of cancel, don't revert
1049 		return;
1050 	}
1051 
1052 	fTextView->Reset();  			    //clear the textview...
1053 	result = fTextView->GetStyledText(&file); //he he he :)
1054 
1055 	if (result != B_OK) {
1056 		BAlert *loadFailedAlert;
1057 		BString alertText;
1058 		if (result == B_TRANSLATION_ERROR_BASE) {
1059 			alertText.SetTo("Translation error loading \"");
1060 		} else {
1061 			alertText.SetTo("Unknown error loading \"");
1062 		}
1063 		alertText<< name;
1064 		alertText<<"\".";
1065 		loadFailedAlert= new BAlert("loadFailedAlert",alertText.String(), "Bummer", 0, 0,
1066 			B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_STOP_ALERT);
1067 		loadFailedAlert->SetShortcut(0, B_ESCAPE);
1068 		loadFailedAlert->Go();
1069 		return;
1070 	}
1071 
1072 	// update alignment
1073 	switch (fTextView->Alignment()) {
1074 		case B_ALIGN_LEFT:
1075 			fAlignLeft->SetMarked(true);
1076 		break;
1077 		case B_ALIGN_CENTER:
1078 			fAlignCenter->SetMarked(true);
1079 		break;
1080 		case B_ALIGN_RIGHT:
1081 			fAlignRight->SetMarked(true);
1082 		break;
1083 		default:
1084 			// weird
1085 		break;
1086 	}
1087 
1088 	// update word wrapping
1089 	fWrapItem->SetMarked(fTextView->DoesWordWrap());
1090 
1091 	// clear undo modes
1092 	fUndoItem->SetLabel("Can't Undo");
1093 	fUndoItem->SetEnabled(false);
1094 	fUndoFlag = false;
1095 	fCanUndo = false;
1096 	fRedoFlag = false;
1097 	fCanRedo = false;
1098 	// clear clean modes
1099 	fSaveItem->SetEnabled(false);
1100 	fRevertItem->SetEnabled(false);
1101 	fUndoCleans = false;
1102 	fRedoCleans = false;
1103 	fClean = true;
1104 }/***StyledEditWindow::RevertToSaved()***/
1105 
1106 status_t
1107 StyledEditWindow::PageSetup(const char *documentname)
1108 {
1109 	status_t result = B_OK;
1110 
1111 	BPrintJob printJob(documentname);
1112 
1113 	if (fPrintSettings != NULL) {
1114 		printJob.SetSettings(new BMessage(*fPrintSettings));
1115 	}
1116 
1117 	result = printJob.ConfigPage();
1118 
1119 	if (result == B_NO_ERROR) {
1120 		delete fPrintSettings;
1121 		fPrintSettings = printJob.Settings();
1122 	}
1123 
1124 	return result;
1125 }/***StyledEditWindow::PageSetup()***/
1126 
1127 void
1128 StyledEditWindow::Print(const char *documentname)
1129 {
1130 	status_t result = B_OK;
1131 
1132 	if (fPrintSettings == NULL) {
1133 		result = PageSetup(documentname);
1134 		if (result != B_OK) {
1135 			return;
1136 		}
1137 	}
1138 
1139 	BPrintJob printJob(documentname);
1140 	printJob.SetSettings(new BMessage(*fPrintSettings));
1141 	result = printJob.ConfigJob();
1142 	if (result != B_OK) {
1143 		return;
1144 	}
1145 	// information from printJob
1146 	BRect printable_rect = printJob.PrintableRect();
1147 	int32 firstPage = printJob.FirstPage();
1148 	int32 lastPage = printJob.LastPage();
1149 
1150 	// lines eventually to be used to compute pages to print
1151 	int32 firstLine = 0;
1152 	int32 lastLine = fTextView->CountLines();
1153 
1154 	// values to be computed
1155 	int32 pagesInDocument = 1;
1156 	int32 linesInDocument = fTextView->CountLines();
1157 
1158 	int32 currentLine = 0;
1159 	while (currentLine < linesInDocument) {
1160 		float currentHeight = 0;
1161 		while ((currentHeight < printable_rect.Height()) && (currentLine < linesInDocument)) {
1162 			currentHeight += fTextView->LineHeight(currentLine);
1163 			if (currentHeight < printable_rect.Height()) {
1164 				currentLine++;
1165 			}
1166 		}
1167 		if (pagesInDocument == lastPage) {
1168 			lastLine = currentLine;
1169 		}
1170 		if (currentHeight >= printable_rect.Height()) {
1171 			pagesInDocument++;
1172 			if (pagesInDocument == firstPage) {
1173 				firstLine = currentLine;
1174 			}
1175 		}
1176 	}
1177 
1178 	if (lastPage > pagesInDocument - 1) {
1179 		lastPage = pagesInDocument - 1;
1180 		lastLine = currentLine - 1;
1181 	}
1182 
1183 	printJob.BeginJob();
1184 	int32 printLine = firstLine;
1185 	while (printLine < lastLine) {
1186 		float currentHeight = 0;
1187 		int32 firstLineOnPage = printLine;
1188 		while ((currentHeight < printable_rect.Height()) && (printLine < lastLine)) {
1189 			currentHeight += fTextView->LineHeight(printLine);
1190 			if (currentHeight < printable_rect.Height()) {
1191 				printLine++;
1192 			}
1193 		}
1194 		float top = 0;
1195 		if (firstLineOnPage != 0) {
1196 			top = fTextView->TextHeight(0,firstLineOnPage-1);
1197 		}
1198 		float bottom = fTextView->TextHeight(0,printLine-1);
1199 		BRect textRect(0.0,top+TEXT_INSET,printable_rect.Width(),bottom+TEXT_INSET);
1200 		printJob.DrawView(fTextView,textRect,BPoint(0.0,0.0));
1201 		printJob.SpoolPage();
1202 	}
1203 	printJob.CommitJob();
1204 }/***StyledEditWindow::Print()***/
1205 
1206 bool
1207 StyledEditWindow::Search(BString string, bool casesens, bool wrap, bool backsearch)
1208 {
1209 	int32	start;
1210 	int32	finish;
1211 	int32	strlen;
1212 
1213 	start = B_ERROR;
1214 
1215 	strlen = string.Length();
1216 	if (strlen== 0)
1217 		return false;
1218 
1219 	BString viewText(fTextView->Text());
1220 	int32 textStart, textFinish;
1221 	fTextView->GetSelection(&textStart, &textFinish);
1222 	if (backsearch == true) {
1223 		if (casesens == true) {
1224 			start = viewText.FindLast(string, textStart);
1225 		} else {
1226 			start = viewText.IFindLast(string, textStart);
1227 		}
1228 	} else {
1229 		if (casesens == true) {
1230 			start = viewText.FindFirst(string, textFinish);
1231 		} else {
1232 			start = viewText.IFindFirst(string, textFinish);
1233 		}
1234 	}
1235 	if ((start == B_ERROR) && (wrap == true)) {
1236 		if (backsearch == true) {
1237 			if (casesens == true) {
1238 				start = viewText.FindLast(string, viewText.Length());
1239 			} else {
1240 				start = viewText.IFindLast(string, viewText.Length());
1241 			}
1242 		} else {
1243 			if (casesens == true) {
1244 				start = viewText.FindFirst(string, 0);
1245 			} else {
1246 				start = viewText.IFindFirst(string, 0);
1247 			}
1248 		}
1249 	}
1250 
1251 	if (start != B_ERROR) {
1252 		finish = start + strlen;
1253 		fTextView->Select(start, finish);
1254 		fTextView->ScrollToSelection();
1255 		return true;
1256 	} else {
1257 		return false;
1258 	}
1259 }/***StyledEditWindow::Search***/
1260 
1261 void
1262 StyledEditWindow::FindSelection()
1263 {
1264 	int32 selectionStart, selectionFinish;
1265 	fTextView->GetSelection(&selectionStart,&selectionFinish);
1266 
1267 	int32 selectionLength;
1268 	selectionLength= selectionFinish- selectionStart;
1269 
1270 	BString viewText;
1271 	viewText= fTextView->Text();
1272 
1273 	viewText.CopyInto(fStringToFind, selectionStart, selectionLength);
1274 	fFindAgainItem->SetEnabled(true);
1275 	Search(fStringToFind, fCaseSens, fWrapAround, fBackSearch);
1276 
1277 }/***StyledEditWindow::FindSelection()***/
1278 
1279 bool
1280 StyledEditWindow::Replace(BString findthis, BString replaceWith,  bool casesens, bool wrap, bool backsearch)
1281 {
1282 	if (Search(findthis, casesens, wrap, backsearch)) {
1283 		int32 start, finish;
1284 		fTextView->GetSelection(&start, &finish);
1285 
1286 		fTextView->Delete(start, start + findthis.Length());
1287 		fTextView->Insert(start, replaceWith.String(), replaceWith.Length());
1288 		fTextView->Select(start, start + replaceWith.Length());
1289 		fTextView->ScrollToSelection();
1290 		return true;
1291 	} else {
1292 		return false;
1293 	}
1294 }/***StyledEditWindow::Replace()***/
1295 
1296 void
1297 StyledEditWindow::ReplaceAll(BString findIt, BString replaceWith, bool caseSens)
1298 {
1299 	BString viewText(fTextView->Text());
1300 	if (caseSens)
1301 		viewText.ReplaceAll(findIt.String(),replaceWith.String());
1302 	else
1303 		viewText.IReplaceAll(findIt.String(),replaceWith.String());
1304 
1305 	if (viewText.Compare(fTextView->Text()) == 0) {
1306 		// they are the same
1307 		return;
1308 	}
1309 
1310 	int32 textStart, textFinish;
1311 	fTextView->GetSelection(&textStart, &textFinish);
1312 
1313 	fTextView->SetText(viewText.String());
1314 
1315 	if (viewText.Length() < textStart)
1316 		textStart = viewText.Length();
1317 	if (viewText.Length() < textFinish)
1318 		textFinish = viewText.Length();
1319 
1320 	fTextView->Select(textStart,textFinish);
1321 	fTextView->ScrollToSelection();
1322 
1323 	fClean = false;
1324 	fUndoCleans = false;
1325 	fRedoCleans = false;
1326 	fRevertItem->SetEnabled(fSaveMessage != NULL);
1327 	fSaveItem->SetEnabled(true);
1328 	fUndoItem->SetLabel("Can't Undo");
1329 	fUndoItem->SetEnabled(false);
1330 	fCanUndo = false;
1331 	fCanRedo = false;
1332 }/***StyledEditWindow::ReplaceAll()***/
1333 
1334 void
1335 StyledEditWindow::SearchAllWindows(BString find, BString replace, bool casesens)
1336 {
1337 	int32 numWindows;
1338 	numWindows= be_app->CountWindows();
1339 
1340 	BMessage *message;
1341 	message= new BMessage(MSG_REPLACE_ALL);
1342 	message->AddString("FindText",find);
1343 	message->AddString("ReplaceText",replace);
1344 	message->AddBool("casesens", casesens);
1345 
1346 	BMessenger *messenger;
1347 
1348 	while(numWindows>=0){
1349 		StyledEditWindow *win= dynamic_cast<StyledEditWindow *>(be_app->WindowAt(numWindows));
1350 		messenger= new BMessenger(win);
1351 		messenger->SendMessage(message);
1352 
1353 		numWindows--;
1354 	}
1355 
1356 }/***StyledEditWindow::SearchAllWindows***/
1357 
1358 
1359 void
1360 StyledEditWindow::SetFontSize(float fontSize)
1361 {
1362 	uint32 sameProperties;
1363 	BFont font;
1364 
1365 	fTextView->GetFontAndColor(&font,&sameProperties);
1366 	font.SetSize(fontSize);
1367 	fTextView->SetFontAndColor(&font,B_FONT_SIZE);
1368 	fClean = false;
1369 	fUndoCleans = false;
1370 	fRedoCleans = false;
1371 	fRevertItem->SetEnabled(fSaveMessage != NULL);
1372 	fSaveItem->SetEnabled(true);
1373 	fUndoItem->SetLabel("Can't Undo");
1374 	fUndoItem->SetEnabled(false);
1375 	fCanUndo = false;
1376 	fCanRedo = false;
1377 }/***StyledEditWindow::SetFontSize()***/
1378 
1379 void
1380 StyledEditWindow::SetFontColor(const rgb_color *color)
1381 {
1382 	uint32 sameProperties;
1383 	BFont font;
1384 
1385 	fTextView->GetFontAndColor(&font,&sameProperties,NULL,NULL);
1386 	fTextView->SetFontAndColor(&font, 0, color);
1387 	fClean = false;
1388 	fUndoCleans = false;
1389 	fRedoCleans = false;
1390 	fRevertItem->SetEnabled(fSaveMessage != NULL);
1391 	fSaveItem->SetEnabled(true);
1392 	fUndoItem->SetLabel("Can't Undo");
1393 	fUndoItem->SetEnabled(false);
1394 	fCanUndo = false;
1395 	fCanRedo = false;
1396 }/***StyledEditWindow::SetFontColor()***/
1397 
1398 void
1399 StyledEditWindow::SetFontStyle(const char *fontFamily, const char *fontStyle)
1400 {
1401 	BFont font;
1402 	uint32 sameProperties;
1403 
1404 	// find out what the old font was
1405 	font_family oldFamily;
1406 	font_style oldStyle;
1407 	fTextView->GetFontAndColor(&font,&sameProperties);
1408 	font.GetFamilyAndStyle(&oldFamily,&oldStyle);
1409 
1410 	// clear that family's bit on the menu, if necessary
1411 	if (strcmp(oldFamily,fontFamily)) {
1412 		BMenuItem * oldItem = fFontMenu->FindItem(oldFamily);
1413 		if (oldItem != 0) {
1414 			oldItem->SetMarked(false);
1415 		}
1416 	}
1417 
1418 	font.SetFamilyAndStyle(fontFamily,fontStyle);
1419 	fTextView->SetFontAndColor(&font);
1420 
1421 	BMenuItem * superItem;
1422 	superItem = fFontMenu->FindItem(fontFamily);
1423 	if (superItem != 0) {
1424 		superItem->SetMarked(true);
1425 	}
1426 
1427 	fClean = false;
1428 	fUndoCleans = false;
1429 	fRedoCleans = false;
1430 	fRevertItem->SetEnabled(fSaveMessage != NULL);
1431 	fSaveItem->SetEnabled(true);
1432 	fUndoItem->SetLabel("Can't Undo");
1433 	fUndoItem->SetEnabled(false);
1434 	fCanUndo = false;
1435 	fCanRedo = false;
1436 }/***StyledEditWindow::SetFontStyle()***/
1437