1 /* 2 ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 ** Distributed under the terms of the OpenBeOS License. 4 */ 5 6 7 #include "AttributeWindow.h" 8 #include "AttributeEditors.h" 9 #include "ProbeView.h" 10 11 #include <MenuBar.h> 12 #include <MenuItem.h> 13 #include <TabView.h> 14 #include <StringView.h> 15 #include <Alert.h> 16 17 18 static const uint32 kMsgRemoveAttribute = 'rmat'; 19 20 21 class EditorTabView : public BTabView { 22 public: 23 EditorTabView(BRect frame, const char *name, button_width width = B_WIDTH_AS_USUAL, 24 uint32 resizingMode = B_FOLLOW_ALL, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS); 25 26 virtual void FrameResized(float width, float height); 27 virtual void Select(int32 tab); 28 29 void AddRawEditorTab(BView *view); 30 void SetTypeEditorTab(BView *view); 31 32 private: 33 BView *fRawEditorView; 34 BView *fTypeEditorView; 35 BStringView *fNoEditorView; 36 int32 fRawTab; 37 }; 38 39 40 //----------------- 41 42 43 EditorTabView::EditorTabView(BRect frame, const char *name, button_width width, 44 uint32 resizingMode, uint32 flags) 45 : BTabView(frame, name, width, resizingMode, flags), 46 fRawEditorView(NULL), 47 fRawTab(-1) 48 { 49 ContainerView()->MoveBy(-ContainerView()->Frame().left, 50 TabHeight() + 1 - ContainerView()->Frame().top); 51 fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor", 52 "No type editor available", B_FOLLOW_NONE); 53 fNoEditorView->ResizeToPreferred(); 54 fNoEditorView->SetAlignment(B_ALIGN_CENTER); 55 fTypeEditorView = fNoEditorView; 56 57 FrameResized(0, 0); 58 59 SetTypeEditorTab(NULL); 60 } 61 62 63 void 64 EditorTabView::FrameResized(float width, float height) 65 { 66 BRect rect = Bounds(); 67 rect.top = ContainerView()->Frame().top; 68 69 ContainerView()->ResizeTo(rect.Width(), rect.Height()); 70 71 BView *view = fTypeEditorView; 72 if (view == NULL) 73 view = fNoEditorView; 74 75 BPoint point = view->Frame().LeftTop(); 76 if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0) 77 point.x = (rect.Width() - view->Bounds().Width()) / 2; 78 if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0) 79 point.y = (rect.Height() - view->Bounds().Height()) / 2; 80 81 view->MoveTo(point); 82 } 83 84 85 void 86 EditorTabView::Select(int32 tab) 87 { 88 if (tab != fRawTab && fRawEditorView != NULL && !fRawEditorView->IsHidden(fRawEditorView)) 89 fRawEditorView->Hide(); 90 91 BTabView::Select(tab); 92 93 BView *view; 94 if (tab == fRawTab && fRawEditorView != NULL) { 95 if (fRawEditorView->IsHidden(fRawEditorView)) 96 fRawEditorView->Show(); 97 view = fRawEditorView; 98 } else 99 view = ViewForTab(Selection()); 100 101 if (view != NULL && (view->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) != 0) { 102 BRect rect = ContainerView()->Bounds(); 103 104 BRect frame = view->Frame(); 105 rect.left = frame.left; 106 rect.top = frame.top; 107 if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0) 108 rect.right = frame.right; 109 if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0) 110 rect.bottom = frame.bottom; 111 112 view->ResizeTo(rect.Width(), rect.Height()); 113 } 114 } 115 116 117 void 118 EditorTabView::AddRawEditorTab(BView *view) 119 { 120 fRawEditorView = view; 121 if (view != NULL) 122 ContainerView()->AddChild(view); 123 124 fRawTab = CountTabs(); 125 126 view = new BView(BRect(0, 0, 5, 5), "Raw Editor", B_FOLLOW_NONE, 0); 127 view->SetViewColor(ViewColor()); 128 AddTab(view); 129 } 130 131 132 void 133 EditorTabView::SetTypeEditorTab(BView *view) 134 { 135 if (fTypeEditorView == view) 136 return; 137 138 BTab *tab = TabAt(0); 139 if (tab != NULL) 140 tab->SetView(NULL); 141 142 fTypeEditorView = view; 143 144 if (view == NULL) 145 view = fNoEditorView; 146 147 if (CountTabs() == 0) 148 AddTab(view); 149 else 150 tab->SetView(view); 151 152 FrameResized(0, 0); 153 154 #ifdef COMPILE_FOR_R5 155 if (Window() != NULL) { 156 // With R5's BTabView, calling select without being 157 // attached to a window crashes... 158 Select(0); 159 } 160 #else 161 Select(0); 162 #endif 163 } 164 165 166 // #pragma mark - 167 168 169 AttributeWindow::AttributeWindow(BRect rect, entry_ref *ref, const char *attribute, 170 const BMessage *settings) 171 : ProbeWindow(rect, ref), 172 fAttribute(strdup(attribute)) 173 { 174 char buffer[256]; 175 snprintf(buffer, sizeof(buffer), "%s: %s", ref->name, attribute); 176 SetTitle(buffer); 177 178 // add the menu 179 180 BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL); 181 AddChild(menuBar); 182 183 BMenu *menu = new BMenu("Attribute"); 184 185 // the ProbeView save menu items will be inserted here 186 menu->AddItem(new BMenuItem("Remove from File", new BMessage(kMsgRemoveAttribute))); 187 menu->AddSeparatorItem(); 188 189 // the ProbeView print menu items will be inserted here 190 menu->AddSeparatorItem(); 191 192 menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY)); 193 menu->SetTargetForItems(this); 194 menuBar->AddItem(menu); 195 196 // add our interface widgets 197 198 BRect rect = Bounds(); 199 rect.top = menuBar->Bounds().Height() + 1; 200 201 BView *view = new BView(rect, "main", B_FOLLOW_ALL, 0); 202 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 203 AddChild(view); 204 205 rect = view->Bounds(); 206 rect.top += 3; 207 208 EditorTabView *tabView = new EditorTabView(rect, "tabView"); 209 210 rect = tabView->ContainerView()->Bounds(); 211 rect.top += 3; 212 fProbeView = new ProbeView(rect, ref, attribute, settings); 213 tabView->AddRawEditorTab(fProbeView); 214 215 view->AddChild(tabView); 216 217 fTypeEditorView = GetTypeEditorFor(rect, fProbeView->Editor()); 218 if (fTypeEditorView != NULL) 219 tabView->SetTypeEditorTab(fTypeEditorView); 220 else { 221 // show the raw editor if we don't have a specialised type editor 222 tabView->Select(1); 223 } 224 225 fProbeView->AddSaveMenuItems(menu, 0); 226 fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 2); 227 228 fProbeView->UpdateSizeLimits(); 229 } 230 231 232 AttributeWindow::~AttributeWindow() 233 { 234 free(fAttribute); 235 } 236 237 238 void 239 AttributeWindow::MessageReceived(BMessage *message) 240 { 241 switch (message->what) { 242 case kMsgRemoveAttribute: 243 { 244 char buffer[1024]; 245 snprintf(buffer, sizeof(buffer), 246 "Do you really want to remove the attribute \"%s\" from the file \"%s\"?\n\n" 247 "You cannot undo this action.", 248 fAttribute, Ref().name); 249 250 int32 chosen = (new BAlert("DiskProbe request", 251 buffer, "Cancel", "Remove", NULL, 252 B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 253 if (chosen == 1) { 254 BNode node(&Ref()); 255 if (node.InitCheck() == B_OK) 256 node.RemoveAttr(fAttribute); 257 258 PostMessage(B_QUIT_REQUESTED); 259 } 260 break; 261 } 262 263 default: 264 ProbeWindow::MessageReceived(message); 265 break; 266 } 267 } 268 269 270 bool 271 AttributeWindow::QuitRequested() 272 { 273 if (fTypeEditorView != NULL) 274 fTypeEditorView->CommitChanges(); 275 276 bool quit = fProbeView->QuitRequested(); 277 if (!quit) 278 return false; 279 280 return ProbeWindow::QuitRequested(); 281 } 282 283 284 bool 285 AttributeWindow::Contains(const entry_ref &ref, const char *attribute) 286 { 287 return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute); 288 } 289 290