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