1 /* 2 * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "OpenWindow.h" 8 #include "DiskProbe.h" 9 10 #include <Application.h> 11 #include <Screen.h> 12 #include <MenuField.h> 13 #include <PopUpMenu.h> 14 #include <MenuItem.h> 15 #include <Button.h> 16 #include <Directory.h> 17 #include <Entry.h> 18 #include <Path.h> 19 20 21 static const uint32 kMsgProbeFile = 'prDv'; 22 static const uint32 kMsgProbeDevice = 'prFl'; 23 24 25 OpenWindow::OpenWindow() 26 : BWindow(BRect(0, 0, 35, 10), "DiskProbe", B_TITLED_WINDOW, 27 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS) 28 { 29 BView *view = new BView(Bounds(), B_EMPTY_STRING, B_FOLLOW_ALL, B_WILL_DRAW); 30 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 31 AddChild(view); 32 33 fDevicesMenu = new BPopUpMenu("devices"); 34 CollectDevices(fDevicesMenu); 35 if (BMenuItem *item = fDevicesMenu->ItemAt(0)) 36 item->SetMarked(true); 37 38 BRect rect = Bounds().InsetByCopy(8, 8); 39 BMenuField *field = new BMenuField(rect, "devices", "Examine Device:", fDevicesMenu); 40 field->ResizeToPreferred(); 41 field->SetDivider(field->StringWidth(field->Label()) + 8); 42 view->AddChild(field); 43 44 BButton *probeDeviceButton = new BButton(BRect(10, 10, 20, 20), "file", "Probe Device", 45 new BMessage(kMsgProbeDevice), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 46 probeDeviceButton->ResizeToPreferred(); 47 rect = probeDeviceButton->Bounds(); 48 probeDeviceButton->MoveTo(Bounds().Width() - 8 - rect.Width(), 49 Bounds().Height() - 8 - rect.Height()); 50 view->AddChild(probeDeviceButton); 51 52 // MakeDefault() may change the size and location of the button 53 rect = probeDeviceButton->Frame(); 54 float width = rect.Width() + 58.0f; 55 probeDeviceButton->MakeDefault(true); 56 57 BButton *button = new BButton(rect, "file", "Probe File" B_UTF8_ELLIPSIS, 58 new BMessage(kMsgProbeFile), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 59 button->ResizeToPreferred(); 60 button->MoveBy(-button->Bounds().Width() - 8, 0); 61 view->AddChild(button); 62 width += button->Bounds().Width(); 63 64 button = new BButton(button->Frame(), "cancel", "Cancel", 65 new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 66 button->ResizeToPreferred(); 67 button->MoveBy(-button->Bounds().Width() - 8, 0); 68 view->AddChild(button); 69 width += button->Bounds().Width(); 70 71 // make sure the window is large enough 72 73 if (width < Bounds().Width()) 74 width = Bounds().Width(); 75 float height = button->Bounds().Height() + 24.0f + field->Frame().bottom; 76 if (height < Bounds().Height()) 77 height = Bounds().Height(); 78 79 ResizeTo(width, height); 80 81 BScreen screen(this); 82 MoveTo(screen.Frame().left + (screen.Frame().Width() - Frame().Width()) / 2, 83 screen.Frame().top + (screen.Frame().Height() - Frame().Height()) / 2); 84 } 85 86 87 OpenWindow::~OpenWindow() 88 { 89 } 90 91 92 void 93 OpenWindow::MessageReceived(BMessage *message) 94 { 95 switch (message->what) { 96 case kMsgProbeDevice: { 97 BMenuItem *item = fDevicesMenu->FindMarked(); 98 if (item == NULL) 99 break; 100 101 be_app_messenger.SendMessage(item->Message()); 102 PostMessage(B_QUIT_REQUESTED); 103 break; 104 } 105 106 case kMsgProbeFile: 107 be_app_messenger.SendMessage(kMsgOpenFilePanel); 108 PostMessage(B_QUIT_REQUESTED); 109 break; 110 111 case B_SIMPLE_DATA: { 112 // if it's a file drop, open it 113 entry_ref ref; 114 if (message->FindRef("refs", 0, &ref) == B_OK) { 115 BMessage openMessage(*message); 116 openMessage.what = B_REFS_RECEIVED; 117 118 be_app_messenger.SendMessage(&openMessage); 119 PostMessage(B_QUIT_REQUESTED); 120 } 121 break; 122 } 123 124 default: 125 BWindow::MessageReceived(message); 126 break; 127 } 128 } 129 130 131 bool 132 OpenWindow::QuitRequested() 133 { 134 be_app_messenger.SendMessage(kMsgOpenWindowClosed); 135 return true; 136 } 137 138 139 void 140 OpenWindow::CollectDevices(BMenu *menu, BEntry *startEntry) 141 { 142 BDirectory directory; 143 if (startEntry != NULL) 144 directory.SetTo(startEntry); 145 else 146 directory.SetTo("/dev/disk"); 147 148 BEntry entry; 149 while (directory.GetNextEntry(&entry) == B_OK) { 150 if (entry.IsDirectory()) { 151 CollectDevices(menu, &entry); 152 continue; 153 } 154 155 entry_ref ref; 156 if (entry.GetRef(&ref) != B_OK) 157 continue; 158 159 BPath path; 160 if (entry.GetPath(&path) != B_OK) 161 continue; 162 163 BMessage *message = new BMessage(B_REFS_RECEIVED); 164 message->AddRef("refs", &ref); 165 166 menu->AddItem(new BMenuItem(path.Path(), message)); 167 } 168 } 169 170