xref: /haiku/src/tests/kits/interface/bshelf/ShelfInspector/InfoWindow.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 // InfoWindow.cpp
2 // Generated by Interface Elements (Window v2.3) on Feb 23 2004
3 // This is a user written class and will not be overwritten.
4 
5 #include <Beep.h>
6 #include <File.h>
7 #include <Resources.h>
8 #include <StorageKit.h>
9 #include <SupportKit.h>
10 #include <AppKit.h>
11 #include <iostream.h>
12 
13 #include "InfoWindow.h"
14 
15 // A couple helpers classes and functions.
16 
17 struct IDItem : public BStringItem
18 {
19 				IDItem(const char *name, int32 i);
20 	int32	id;
21 };
22 
23 /*------------------------------------------------------------*/
24 struct match_info
25 {
26 	match_info(image_id i) { id = i; found = false; };
27 	image_id	id;
28 	bool			found;
29 };
30 
31 
32 bool match_id(BListItem *item, void *data)
33 {
34 	match_info *mi = (match_info *) (data);
35 	IDItem *my = dynamic_cast<IDItem*>(item);
36 	if (my->id == (mi)->id)
37 	{
38 		(mi)->found = true;
39 		return true;
40 	}
41 	return false;
42 }
43 
44 
45 IDItem :: IDItem(const char *name, int32 i)
46 	      : BStringItem(name)
47 {
48 	id = i;
49 };
50 
51 
52 
53 InfoWindow :: InfoWindow(void)
54 						: IEWindow("InfoWindow"),
55 							fTickToken( BMessenger(this), new BMessage(CMD_TICK), 500000 ),		// send message periodically
56 							fImportLoc(10,15)																									// position of imported replicant
57 {
58 	Lock();
59 		CreateViews();
60 	Unlock();
61 }
62 
63 
64 InfoWindow::~InfoWindow(void)
65 {
66 	SetPrefs();
67   if (fPrefs != NULL) delete fPrefs;			// now prefs are saved
68 }
69 
70 
71 bool InfoWindow :: QuitRequested()
72 {
73 	long c = be_app->CountWindows();
74 
75 	if (c == 1)
76 	{
77 		be_app->PostMessage(B_QUIT_REQUESTED);
78 	}
79 	return true;
80 }
81 
82 
83 // Handling of user interface and other events
84 void InfoWindow::MessageReceived(BMessage *msg)
85 {
86 
87 	switch(msg->what)
88 	{
89 		case CMD_UPDATE_CONTAINER_ITEM:
90 			{
91 				BMenu *theMenu =(BMenu *)(fMenuField -> Menu());
92 				BMenuItem *theItem = theMenu -> FindItem(IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW);
93 				theItem ->  SetMarked(true);
94 				PostMessage(IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW);
95 			}
96 			break;
97 
98 		case CMD_TICK:
99 		{
100 			UpdateLists(false);
101 			break;
102 		}
103 
104 		case IE_INFOWINDOW_DELETEBUTTON:	// 'DeleteButton' is pressed...
105 			{
106 				int32	sel = fReplicantList->CurrentSelection();
107 				IDItem	*item = dynamic_cast<IDItem*>(fReplicantList->ItemAt(sel));
108 				ASSERT(sel >= 0);
109 				ASSERT(item);
110 				DeleteReplicant(item->id);
111 			}
112 			break;
113 
114 
115 
116 		case IE_INFOWINDOW_COPYBUTTON:	// 'CopyButton' is pressed...
117 			{
118 				BAlert	*alert = new BAlert("",
119 																		"Warning, not all replicants are importable. Importing a "
120 																		"replicant can crash the Container Demo application. Are you "
121 																		"willing to give it a try?", "Cancel", "Import", NULL,
122 																		B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT);
123 				BInvoker *inv = new BInvoker(new BMessage(CMD_IMPORT_REPLICANT),this);
124 				alert->Go(inv);
125 			}
126 			break;
127 
128 
129 		case CMD_IMPORT_REPLICANT:
130 			{
131 				// This message was posted by the Alert above. If 'which' is 1 then
132 				// the user pressed the Import button. Otherwise they pressed Cancel.
133 				int32 r = msg->FindInt32("which");
134 				if (r == 1)
135 				{
136 					int32	sel = fReplicantList->CurrentSelection();
137 					IDItem	*item = dynamic_cast<IDItem*>(fReplicantList->ItemAt(sel));
138 					ASSERT(sel >= 0);
139 					ASSERT(item);
140 					ImportReplicant(item->id);
141 				}
142 			}
143 			break;
144 
145 
146 		case IE_INFOWINDOW_REPLICANTLIST_SELECTION:	// list item is selected in 'ReplicantList'
147 			{
148 				bool	enabled;
149 				enabled = (fReplicantList->CurrentSelection() >= 0);
150 				fDeleteRep->SetEnabled(enabled);
151 				fCopyRep -> SetEnabled(enabled);
152 			}
153 			break;
154 
155 		case IE_INFOWINDOW_REPLICANTLIST_INVOCATION:	// list item is invoked in 'ReplicantList'
156 			break;
157 
158 
159 
160 		case IE_INFOWINDOW_LIBRARYLIST_SELECTION:	// list item is selected in 'LibraryList'
161 			{
162 				bool	enabled;
163 				enabled = (fLibraryList->CurrentSelection() >= 0);
164 				fUnloadLib->SetEnabled(enabled);
165 			}
166 			break;
167 
168 		case IE_INFOWINDOW_LIBRARYLIST_INVOCATION:	// list item is invoked in 'LibraryList'
169 			break;
170 
171 		case IE_INFOWINDOW_UNLOADBUTTON:	// 'UnloadButton' is pressed...
172 			{
173 				BAlert	*alert = new BAlert("",
174 																"Warning, unloading a library that is still in use is pretty bad. "
175 																"Are you sure you want to unload this library?",
176 																"Cancel", "Unload", NULL,
177 																B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT);
178 				BInvoker *inv = new BInvoker(new BMessage(CMD_UNLOAD_LIBRARY),this);
179 				alert->Go(inv);
180 			}
181 			break;
182 
183 		case CMD_UNLOAD_LIBRARY:
184 		{
185 			// This message was posted by the Alert above. If 'which' is 1 then
186 			// the user pressed the Import button. Otherwise they pressed Cancel.
187 			int32 r = msg->FindInt32("which");
188 			if (r == 1)
189 			{
190 				int32	sel = fLibraryList->CurrentSelection();
191 				IDItem	*item = dynamic_cast<IDItem*>(fLibraryList->ItemAt(sel));
192 				ASSERT(sel >= 0);
193 				ASSERT(item);
194 				unload_add_on(item->id);
195 			}
196 			break;
197 		}
198 
199 		case IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW:
200 		case IE_POPUPMENU_TARGETPOPUP_DESKBAR:
201 		case IE_POPUPMENU_TARGETPOPUP_DESKTOP_WINDOW:
202 		{
203 			fTarget = MessengerForTarget(msg->what);
204 			UpdateLists(true);
205 		}
206 		break;
207 
208 		case IE_INFOWINDOW_MAINBAR_FILE_NEW:    // "New" is selected from menu…
209 			break;
210 
211 		case IE_INFOWINDOW_MAINBAR_FILE_OPEN___:    // "Open…" is selected from menu…
212 			break;
213 
214 		case IE_INFOWINDOW_MAINBAR_FILE_SAVE:    // "Save" is selected from menu…
215 			break;
216 
217 		case IE_INFOWINDOW_MAINBAR_FILE_SAVE_AS___:    // "Save As…" is selected from menu…
218 			break;
219 
220 		case IE_INFOWINDOW_MAINBAR_FILE_ABOUT___:    // "About…" is selected from menu…
221 				PostMessage(B_ABOUT_REQUESTED);
222 			break;
223 
224 		case IE_INFOWINDOW_MAINBAR_FILE_QUIT:    // "Quit" is selected from menu…
225 				PostMessage(B_QUIT_REQUESTED);
226 			break;
227 
228 		case IE_INFOWINDOW_MAINBAR_EDIT_UNDO:    // "Undo" is selected from menu…
229 			break;
230 
231 		case IE_INFOWINDOW_MAINBAR_EDIT_CUT:    // "Cut" is selected from menu…
232 			break;
233 
234 		case IE_INFOWINDOW_MAINBAR_EDIT_COPY:    // "Copy" is selected from menu…
235 			break;
236 
237 		case IE_INFOWINDOW_MAINBAR_EDIT_PASTE:    // "Paste" is selected from menu…
238 			break;
239 
240 
241 		case B_ABOUT_REQUESTED:
242 			{
243 				BAlert	*alert = new BAlert("", "XShelfInspector (H.Reh, dr.hartmut.reh@gmx.de) " "\n" "\n"
244 																		"Based upon ShelfInspector from Be Inc." "\n"
245 																		"The GUI was created with InterfaceElements (Attila Mezei)" "\n"
246 																		"Please read the ***Be Sample Code License*** "	"\n"
247 																	 ,"OK");
248 				alert -> Go(NULL);
249 			}
250 			break;
251 
252 
253 		default:
254 			inherited::MessageReceived(msg);
255 			break;
256 	}
257 
258 }
259 
260 
261 void InfoWindow :: EmptyLists()
262 {
263 	fReplicantList	->	MakeEmpty();
264 	fLibraryList		->	MakeEmpty();
265 }
266 
267 
268 void InfoWindow::UpdateLists(bool make_empty)
269 {
270 	bool	deleted_something = false;
271 
272 	if (!fTarget.IsValid())
273 	{
274 		EmptyLists();
275 		PostMessage(IE_INFOWINDOW_REPLICANTLIST_SELECTION);
276 		PostMessage(IE_INFOWINDOW_LIBRARYLIST_SELECTION);
277 		return;
278 	}
279 	if (make_empty)
280 	{
281 		EmptyLists();
282 		deleted_something = true;
283 	}
284 
285 	/*
286 	 I'm not worried about the allgorithms used below to maintain the 2 lists.
287 	 That isn't the point of this sample app.
288 	 */
289 
290 	image_info	info;
291 
292 	if (!make_empty)
293 	{
294 		// walk through the current list of images and remove any that are
295 		// no longer loaded
296 		IDItem	*item;
297 		int32	i = fLibraryList->CountItems();
298 		while ((item = dynamic_cast<IDItem*>(fLibraryList->ItemAt(--i))) != NULL)
299 		{
300 			image_id	id = (image_id) item->id;
301 			if (get_image_info(id, &info) != B_OK)
302 			{
303 				fLibraryList->RemoveItem(item);
304 				delete item;
305 				deleted_something = true;
306 			}
307 		}
308 	}
309 
310 	// get all the images for the 'team' of the target. If the image isn't in the
311 	// list then add
312 	team_id		team = fTarget.Team();
313 	int32		cookie = 0;
314 
315 	while (get_next_image_info(team, &cookie, &info) == B_OK)
316 	{
317 		match_info	mi(info.id);
318 		fLibraryList->DoForEach(match_id, &mi);
319 		if (!mi.found)
320 		{
321 			fLibraryList->AddItem(new IDItem(info.name, info.id));
322 		}
323 	}
324 
325 	// Now it's time to deal with the replicant list
326 
327 	if (!make_empty)
328 	{
329 		// walk through the current list of replicants and remove any that are
330 		// no longer loaded
331 		IDItem	*item;
332 		int32	i = fReplicantList->CountItems();
333 		while ((item = dynamic_cast<IDItem*>(fReplicantList->ItemAt(--i))) != NULL)
334 		{
335 			int32	uid = item->id;
336 			if (IsReplicantLoaded(uid) == false)
337 			{
338 				fReplicantList->RemoveItem(item);
339 				delete item;
340 				deleted_something = true;
341 			}
342 		}
343 	}
344 
345 	// Now get all the replicants from the shelf and make sure that they are in
346 	// the list
347 	int32	index = 0;
348 	int32	uid;
349 	while ((uid = GetReplicantAt(index++)) >= B_OK)
350 	{
351 		// if this uid is already in the list then skip it
352 		match_info	mi(uid);
353 		fReplicantList->DoForEach(match_id, &mi);
354 		if (mi.found)
355 		{
356 			continue;
357 		}
358 
359 		BMessage	rep_info;
360 		if (GetReplicantName(uid, &rep_info) != B_OK)
361 		{
362 			continue;
363 		}
364 
365 		const char *name;
366 		if (rep_info.FindString("result", &name) == B_OK)
367 		{
368 			fReplicantList->AddItem(new IDItem(name, uid));
369 		}
370 	}
371 
372 
373 	if (deleted_something)
374 	{
375 		PostMessage(IE_INFOWINDOW_REPLICANTLIST_SELECTION);
376 		PostMessage(IE_INFOWINDOW_LIBRARYLIST_SELECTION);
377 	}
378 }
379 
380 
381 
382 status_t InfoWindow :: GetReplicantName(int32 uid, BMessage *reply) const
383 {
384 	/*
385 	 We send a message to the target shelf, asking it for the Name of the
386 	 replicant with the given unique id.
387 	 */
388 
389 	BMessage	request(B_GET_PROPERTY);
390 	BMessage	uid_specifier(B_ID_SPECIFIER);	// specifying via ID
391 	status_t	err;
392 	status_t	e;
393 
394 	request.AddSpecifier("Name");		// ask for the Name of the replicant
395 
396 	// IDs are specified using code like the following 3 lines:
397 	uid_specifier.AddInt32("id", uid);
398 	uid_specifier.AddString("property", "Replicant");
399 	request.AddSpecifier(&uid_specifier);
400 
401 	if ((err = fTarget.SendMessage(&request, reply)) != B_OK)
402 		return err;
403 
404 	if (((err = reply->FindInt32("error", &e)) != B_OK) || (e != B_OK))
405 		return err ? err : e;
406 
407 	return B_OK;
408 }
409 
410 bool InfoWindow :: IsReplicantLoaded(int32 uid) const
411 {
412 	/*
413 	 determine if the specified replicant (the unique ID of the replicant)
414 	 still exists in the target container/shelf. If we can get the name then the
415 	 replicant still exists.
416 	 */
417 	BMessage	reply;
418 	status_t	err = GetReplicantName(uid, &reply);
419 	return (err == B_OK);
420 }
421 
422 
423 int32 InfoWindow::GetReplicantAt(int32 index) const
424 {
425 	/*
426 	 So here we want to get the Unique ID of the replicant at the given index
427 	 in the target Shelf.
428 	 */
429 
430 	BMessage	request(B_GET_PROPERTY);		// We're getting the ID property
431 	BMessage	reply;
432 	status_t	err;
433 
434 	request.AddSpecifier("ID");					// want the ID
435 	request.AddSpecifier("Replicant", index);	// of the index'th replicant
436 
437 	if ((err = fTarget.SendMessage(&request, &reply)) != B_OK)
438 		return err;
439 
440 	int32	uid;
441 	if ((err = reply.FindInt32("result", &uid)) != B_OK)
442 		return err;
443 
444 	return uid;
445 }
446 
447 
448 BMessenger InfoWindow :: MessengerForTarget(type_code w) const
449 {
450 	/*
451 	 This function determines the BMessenger to the various Shelf objects
452 	 that this app can talk with.
453 	 */
454 	BMessage	request(B_GET_PROPERTY);
455 	BMessenger	to;
456 	BMessenger	result;
457 
458 	request.AddSpecifier("Messenger");
459 	request.AddSpecifier("Shelf");
460 
461 	switch (w)
462 	{
463 		case IE_POPUPMENU_TARGETPOPUP_DESKBAR:
464 		{
465 			request.AddSpecifier("View", "Status");
466 			request.AddSpecifier("Window", "Deskbar");
467 			to = BMessenger("application/x-vnd.Be-TSKB", -1);
468 			break;
469 		}
470 
471 		case IE_POPUPMENU_TARGETPOPUP_DESKTOP_WINDOW:
472 		{
473 			// The Desktop is owned by Tracker and the Shelf is in the
474 			// View "PoseView" in Window "Desktop"
475 			request.AddSpecifier("View", "PoseView");
476 			request.AddSpecifier("Window", "/boot/home/Desktop");
477 			to = BMessenger("application/x-vnd.Be-TRAK", -1);
478 			break;
479 		}
480 
481 		case IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW:
482 		{
483 			// In the COntainer Demo app the View "MainView" in the only window
484 			// is the Shelf.
485 			request.AddSpecifier("View", "ContainerView");		// Hier werden Replikanten abgelegt
486 			request.AddSpecifier("Window", (int32) 0);
487 			to = BMessenger(XCONTAINER_APP, -1);
488 			// This demo app isn't worried about the Container app going away
489 			// (quitting) unexpectedly.
490 			break;
491 		}
492 	}
493 
494 	BMessage	reply;
495 
496 	if (to.SendMessage(&request, &reply) == B_OK)
497 	{
498 		//reply.PrintToStream();
499 		reply.FindMessenger("result", &result);
500 	}
501 	return result;
502 }
503 
504 
505 status_t InfoWindow :: DeleteReplicant(int32 uid)
506 {
507 	// delete the given replicant from the current target shelf
508 
509 	BMessage	request(B_DELETE_PROPERTY);		// Delete
510 	BMessage	uid_specifier(B_ID_SPECIFIER);	// specifying via ID
511 	BMessage	reply;
512 	status_t	err;
513 	status_t	e;
514 
515 	// IDs are specified using code like the following 3 lines:
516 	uid_specifier.AddInt32("id", uid);
517 	uid_specifier.AddString("property", "Replicant");
518 	request.AddSpecifier(&uid_specifier);
519 
520 	if ((err = fTarget.SendMessage(&request, &reply)) != B_OK)
521 		return err;
522 
523 	if ((err = reply.FindInt32("error", &e)) != B_OK)
524 		return err;
525 
526 	return e;
527 }
528 
529 
530 status_t InfoWindow :: ImportReplicant(int32 uid)
531 {
532 	// Import the given replicant from the current target shelf
533 	// That is get a copy and recreate it in the "Container" window of
534 	// this app.
535 
536 	BMessage	request(B_GET_PROPERTY);		// Get will return the archive msg
537 	BMessage	uid_specifier(B_ID_SPECIFIER);	// specifying via ID
538 	BMessage	reply;
539 	status_t	err;
540 	status_t	e;
541 
542 	// IDs are specified using code like the following 3 lines:
543 	uid_specifier.AddInt32("id", uid);
544 	uid_specifier.AddString("property", "Replicant");
545 	request.AddSpecifier(&uid_specifier);
546 
547 	if ((err = fTarget.SendMessage(&request, &reply)) != B_OK)
548 		return err;
549 
550 	if (((err = reply.FindInt32("error", &e)) != B_OK) || (e != B_OK))
551 		return err;
552 
553 	// OK, let's get the archive message
554 	BMessage	data;
555 	reply.FindMessage("result", &data);
556 
557 	// Now send this to the container window. If someone closed it then the
558 	// Send will fail. Oh well.
559 	BMessenger	mess = MessengerForTarget(IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW);
560 	BMessage	msg(B_CREATE_PROPERTY);
561 
562 	msg.AddMessage("data", &data);
563 
564 	// As this is a Demo I'm not going to worry about some fancy layout
565 	// algorithm. Just keep placing new replicants going down the window
566 	msg.AddPoint("location", fImportLoc);
567 	fImportLoc.y += 40;
568 
569 	return mess.SendMessage(&msg, &reply);
570 }
571 
572 
573 
574 // Update the menu items before they appear on screen
575 void InfoWindow::MenusBeginning()
576 {
577 	// Complete the SetEnabled argument or do anything with the source below...
578 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_NEW)->SetEnabled(false);					// "New"
579 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_OPEN___)->SetEnabled(false);			// "Open…"
580 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_SAVE)->SetEnabled(false);					// "Save"
581 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_SAVE_AS___)->SetEnabled(false);		// "Save As…"
582 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_ABOUT___)->SetEnabled(true);			// "About…"
583 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_FILE_QUIT)->SetEnabled(true);					// "Quit"
584 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_EDIT_UNDO)->SetEnabled(false);					// "Undo"
585 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_EDIT_CUT)->SetEnabled(false);					// "Cut"
586 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_EDIT_COPY)->SetEnabled(false);					// "Copy"
587 	KeyMenuBar()->FindItem(IE_INFOWINDOW_MAINBAR_EDIT_PASTE)->SetEnabled(false);				// "Paste"
588 }
589 
590 
591 
592 
593 BMessage *InfoWindow :: ReadMessageFromResource(const char *resName)
594 {
595 	// Hier wird aus der Resource die Message gelesen
596 	app_info 		ai;
597 	BFile 	 		file;
598 	BResources 	res;
599 	size_t 			res_size;
600 	const void* res_addr;
601 
602 	BMessage* archive = new BMessage;
603 
604 	if( (be_app->GetAppInfo(&ai) != B_OK)
605 	 		||(file.SetTo(&ai.ref,B_READ_ONLY) != B_OK)
606 	 		||(res.SetTo(&file) != B_OK)
607 	 		||((res_addr = res.LoadResource('ARCV',resName,&res_size)) == NULL)
608 	 		||(archive -> Unflatten((const char*)res_addr) != B_OK) )
609 		// Resource muss 'ARCV' - Typ sein -> in IE einstellen
610 		// Resource of type 'ARCV'
611 	 {
612 	 		delete archive;
613 			return NULL;
614 	 }
615 	return archive;
616 }
617 
618 
619 void InfoWindow:: CreateViews()
620 {
621 	BMessage *archive = ReadMessageFromResource("PopUpMenu");				 // Menu Feld from Resource
622 	if (archive)
623 	{
624 		fMenuField = new BMenuField(archive);
625 		delete archive;
626 	}
627 
628 	fMainBox = (BBox *)FindView("MainBox");														// Pointer to MainBox
629 	fMainBox->SetLabel(fMenuField);																		// Replace Label
630 
631 	fReplicantList	 	= (BListView   *) FindView("ReplicantList");
632 	fLibraryList	 		= (BListView   *) FindView("LibraryList");
633 
634 	fDeleteRep	= (BButton *) FindView("DeleteButton");
635 	fCopyRep		= (BButton *) FindView("CopyButton");
636 	fUnloadLib	= (BButton *) FindView("UnloadButton");
637 
638 	BScrollView *libScrollView 		= (BScrollView *)FindView("LibraryScroll");
639 	BScrollBar	*horLibScrollBar = libScrollView -> ScrollBar(B_HORIZONTAL);
640 	horLibScrollBar -> SetRange(0, 400);
641 	horLibScrollBar -> SetProportion(0.4);
642 
643 	BScrollView *repScrollView 	= (BScrollView *)FindView("ReplicantScroll");
644 	BScrollBar	*horRepScrollBar = repScrollView -> ScrollBar(B_HORIZONTAL);
645 	horRepScrollBar -> SetRange(0, 400);
646 	horRepScrollBar -> SetProportion(0.4);
647 }
648 
649 
650 void InfoWindow :: GetPrefs()
651 {
652 	status_t	err;
653 	BRect 		windFrame;
654 	int32			targetShelf;
655 
656 	fPrefs = new TPreferences ("XShelfInspector/preferences");			// Name des Prefs-Files
657 	if (fPrefs -> InitCheck() != B_OK)															// falls keine Prefs -> erzeugen
658 	{
659 		windFrame = Frame();																					// Window Frame aus Resource ermitteln
660 		fPrefs -> SetRect ("WindowFrame", windFrame );
661 
662 		targetShelf = IE_POPUPMENU_TARGETPOPUP_XCONTAINER_WINDOW;			// XContainerWindow
663 		fPrefs -> SetInt32 ("TargetShelf", targetShelf );
664 	}
665 
666 	err = (fPrefs -> FindRect ("WindowFrame", &windFrame) );
667 	if (err == B_OK)
668 	{
669 		ResizeTo(windFrame.Width(), windFrame.Height() );							// Fensterposition und Größe
670 		MoveTo(windFrame.left, windFrame.top);												// aus Preferences
671 	}
672 
673 	err = (fPrefs -> FindInt32 ("TargetShelf", &targetShelf ) );
674 	if (err == B_OK)
675 	{
676 		BMenu *theMenu =(BMenu *)(fMenuField -> Menu());
677 		BMenuItem *theItem = theMenu -> FindItem(targetShelf);
678 		theItem -> SetMarked(true);
679 		PostMessage(targetShelf);																			// TargetShelf
680 	}
681 }
682 
683 
684 void InfoWindow :: SetPrefs()
685 {
686 	fPrefs -> SetRect ("WindowFrame", Frame() );
687 
688 	BMenu *theMenu =(BMenu *)(fMenuField -> Menu());
689 	BMenuItem *theItem = theMenu -> FindMarked();
690 	int32 targetShelf  = theItem -> Command();
691 	fPrefs -> SetInt32("TargetShelf", targetShelf);
692 }
693 
694 
695