1d11ec082SAxel Dörfler /* 2*527b14e9SAxel Dörfler * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 386daa6f2SAxel Dörfler * Distributed under the terms of the MIT License. 4d11ec082SAxel Dörfler */ 5d11ec082SAxel Dörfler 6d11ec082SAxel Dörfler 7d11ec082SAxel Dörfler #include "AttributeWindow.h" 8d11ec082SAxel Dörfler #include "ProbeView.h" 9*527b14e9SAxel Dörfler #include "TypeEditors.h" 10d11ec082SAxel Dörfler 11d11ec082SAxel Dörfler #include <MenuBar.h> 12d11ec082SAxel Dörfler #include <MenuItem.h> 137d7f16acSAxel Dörfler #include <TabView.h> 147d7f16acSAxel Dörfler #include <StringView.h> 1536a79516SAxel Dörfler #include <Alert.h> 1686daa6f2SAxel Dörfler #include <Directory.h> 1786daa6f2SAxel Dörfler #include <Volume.h> 18d11ec082SAxel Dörfler 19d11ec082SAxel Dörfler 2036a79516SAxel Dörfler static const uint32 kMsgRemoveAttribute = 'rmat'; 217d7f16acSAxel Dörfler 227d7f16acSAxel Dörfler 237d7f16acSAxel Dörfler class EditorTabView : public BTabView { 247d7f16acSAxel Dörfler public: 257d7f16acSAxel Dörfler EditorTabView(BRect frame, const char *name, button_width width = B_WIDTH_AS_USUAL, 267d7f16acSAxel Dörfler uint32 resizingMode = B_FOLLOW_ALL, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS); 277d7f16acSAxel Dörfler 287d7f16acSAxel Dörfler virtual void FrameResized(float width, float height); 297d7f16acSAxel Dörfler virtual void Select(int32 tab); 307d7f16acSAxel Dörfler 317d7f16acSAxel Dörfler void AddRawEditorTab(BView *view); 327d7f16acSAxel Dörfler void SetTypeEditorTab(BView *view); 337d7f16acSAxel Dörfler 347d7f16acSAxel Dörfler private: 357d7f16acSAxel Dörfler BView *fRawEditorView; 367d7f16acSAxel Dörfler BView *fTypeEditorView; 377d7f16acSAxel Dörfler BStringView *fNoEditorView; 387d7f16acSAxel Dörfler int32 fRawTab; 397d7f16acSAxel Dörfler }; 407d7f16acSAxel Dörfler 417d7f16acSAxel Dörfler 427d7f16acSAxel Dörfler //----------------- 437d7f16acSAxel Dörfler 447d7f16acSAxel Dörfler 457d7f16acSAxel Dörfler EditorTabView::EditorTabView(BRect frame, const char *name, button_width width, 467d7f16acSAxel Dörfler uint32 resizingMode, uint32 flags) 477d7f16acSAxel Dörfler : BTabView(frame, name, width, resizingMode, flags), 487d7f16acSAxel Dörfler fRawEditorView(NULL), 497d7f16acSAxel Dörfler fRawTab(-1) 507d7f16acSAxel Dörfler { 517d7f16acSAxel Dörfler ContainerView()->MoveBy(-ContainerView()->Frame().left, 527d7f16acSAxel Dörfler TabHeight() + 1 - ContainerView()->Frame().top); 537d7f16acSAxel Dörfler fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor", 547d7f16acSAxel Dörfler "No type editor available", B_FOLLOW_NONE); 557d7f16acSAxel Dörfler fNoEditorView->ResizeToPreferred(); 567d7f16acSAxel Dörfler fNoEditorView->SetAlignment(B_ALIGN_CENTER); 577d7f16acSAxel Dörfler fTypeEditorView = fNoEditorView; 587d7f16acSAxel Dörfler 597d7f16acSAxel Dörfler FrameResized(0, 0); 607d7f16acSAxel Dörfler 617d7f16acSAxel Dörfler SetTypeEditorTab(NULL); 627d7f16acSAxel Dörfler } 637d7f16acSAxel Dörfler 647d7f16acSAxel Dörfler 657d7f16acSAxel Dörfler void 667d7f16acSAxel Dörfler EditorTabView::FrameResized(float width, float height) 677d7f16acSAxel Dörfler { 687d7f16acSAxel Dörfler BRect rect = Bounds(); 697d7f16acSAxel Dörfler rect.top = ContainerView()->Frame().top; 707d7f16acSAxel Dörfler 717d7f16acSAxel Dörfler ContainerView()->ResizeTo(rect.Width(), rect.Height()); 727d7f16acSAxel Dörfler 737d7f16acSAxel Dörfler BView *view = fTypeEditorView; 747d7f16acSAxel Dörfler if (view == NULL) 757d7f16acSAxel Dörfler view = fNoEditorView; 767d7f16acSAxel Dörfler 777d7f16acSAxel Dörfler BPoint point = view->Frame().LeftTop(); 787d7f16acSAxel Dörfler if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0) 797d7f16acSAxel Dörfler point.x = (rect.Width() - view->Bounds().Width()) / 2; 807d7f16acSAxel Dörfler if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0) 817d7f16acSAxel Dörfler point.y = (rect.Height() - view->Bounds().Height()) / 2; 827d7f16acSAxel Dörfler 837d7f16acSAxel Dörfler view->MoveTo(point); 847d7f16acSAxel Dörfler } 857d7f16acSAxel Dörfler 867d7f16acSAxel Dörfler 877d7f16acSAxel Dörfler void 887d7f16acSAxel Dörfler EditorTabView::Select(int32 tab) 897d7f16acSAxel Dörfler { 907d7f16acSAxel Dörfler if (tab != fRawTab && fRawEditorView != NULL && !fRawEditorView->IsHidden(fRawEditorView)) 917d7f16acSAxel Dörfler fRawEditorView->Hide(); 927d7f16acSAxel Dörfler 937d7f16acSAxel Dörfler BTabView::Select(tab); 947d7f16acSAxel Dörfler 957d7f16acSAxel Dörfler BView *view; 967d7f16acSAxel Dörfler if (tab == fRawTab && fRawEditorView != NULL) { 977d7f16acSAxel Dörfler if (fRawEditorView->IsHidden(fRawEditorView)) 987d7f16acSAxel Dörfler fRawEditorView->Show(); 997d7f16acSAxel Dörfler view = fRawEditorView; 1007d7f16acSAxel Dörfler } else 1017d7f16acSAxel Dörfler view = ViewForTab(Selection()); 1027d7f16acSAxel Dörfler 1037d7f16acSAxel Dörfler if (view != NULL && (view->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) != 0) { 1047d7f16acSAxel Dörfler BRect rect = ContainerView()->Bounds(); 1057d7f16acSAxel Dörfler 1067d7f16acSAxel Dörfler BRect frame = view->Frame(); 1077d7f16acSAxel Dörfler rect.left = frame.left; 1087d7f16acSAxel Dörfler rect.top = frame.top; 1097d7f16acSAxel Dörfler if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0) 1107d7f16acSAxel Dörfler rect.right = frame.right; 1117d7f16acSAxel Dörfler if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0) 1127d7f16acSAxel Dörfler rect.bottom = frame.bottom; 1137d7f16acSAxel Dörfler 1147d7f16acSAxel Dörfler view->ResizeTo(rect.Width(), rect.Height()); 1157d7f16acSAxel Dörfler } 1167d7f16acSAxel Dörfler } 1177d7f16acSAxel Dörfler 1187d7f16acSAxel Dörfler 1197d7f16acSAxel Dörfler void 1207d7f16acSAxel Dörfler EditorTabView::AddRawEditorTab(BView *view) 1217d7f16acSAxel Dörfler { 1227d7f16acSAxel Dörfler fRawEditorView = view; 1237d7f16acSAxel Dörfler if (view != NULL) 1247d7f16acSAxel Dörfler ContainerView()->AddChild(view); 1257d7f16acSAxel Dörfler 1267d7f16acSAxel Dörfler fRawTab = CountTabs(); 1277d7f16acSAxel Dörfler 1287d7f16acSAxel Dörfler view = new BView(BRect(0, 0, 5, 5), "Raw Editor", B_FOLLOW_NONE, 0); 1297d7f16acSAxel Dörfler view->SetViewColor(ViewColor()); 1307d7f16acSAxel Dörfler AddTab(view); 1317d7f16acSAxel Dörfler } 1327d7f16acSAxel Dörfler 1337d7f16acSAxel Dörfler 1347d7f16acSAxel Dörfler void 1357d7f16acSAxel Dörfler EditorTabView::SetTypeEditorTab(BView *view) 1367d7f16acSAxel Dörfler { 1377d7f16acSAxel Dörfler if (fTypeEditorView == view) 1387d7f16acSAxel Dörfler return; 1397d7f16acSAxel Dörfler 1407d7f16acSAxel Dörfler BTab *tab = TabAt(0); 1417d7f16acSAxel Dörfler if (tab != NULL) 1427d7f16acSAxel Dörfler tab->SetView(NULL); 1437d7f16acSAxel Dörfler 1447d7f16acSAxel Dörfler fTypeEditorView = view; 1457d7f16acSAxel Dörfler 1467d7f16acSAxel Dörfler if (view == NULL) 1477d7f16acSAxel Dörfler view = fNoEditorView; 1487d7f16acSAxel Dörfler 1497d7f16acSAxel Dörfler if (CountTabs() == 0) 1507d7f16acSAxel Dörfler AddTab(view); 1517d7f16acSAxel Dörfler else 1527d7f16acSAxel Dörfler tab->SetView(view); 1537d7f16acSAxel Dörfler 1547d7f16acSAxel Dörfler FrameResized(0, 0); 155871fa04fSAxel Dörfler 1566f850dfdSAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 157871fa04fSAxel Dörfler if (Window() != NULL) { 158871fa04fSAxel Dörfler // With R5's BTabView, calling select without being 159871fa04fSAxel Dörfler // attached to a window crashes... 1607d7f16acSAxel Dörfler Select(0); 1617d7f16acSAxel Dörfler } 162871fa04fSAxel Dörfler #else 163871fa04fSAxel Dörfler Select(0); 164871fa04fSAxel Dörfler #endif 165871fa04fSAxel Dörfler } 1667d7f16acSAxel Dörfler 1677d7f16acSAxel Dörfler 1687d7f16acSAxel Dörfler // #pragma mark - 1697d7f16acSAxel Dörfler 1707d7f16acSAxel Dörfler 171758b1d0eSIngo Weinhold AttributeWindow::AttributeWindow(BRect _rect, entry_ref *ref, const char *attribute, 1727fff3ed0SAxel Dörfler const BMessage *settings) 173758b1d0eSIngo Weinhold : ProbeWindow(_rect, ref), 174d11ec082SAxel Dörfler fAttribute(strdup(attribute)) 175d11ec082SAxel Dörfler { 17686daa6f2SAxel Dörfler // Set alternative window title for devices 17786daa6f2SAxel Dörfler 17886daa6f2SAxel Dörfler char name[B_FILE_NAME_LENGTH]; 1796f850dfdSAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 18086daa6f2SAxel Dörfler strncpy(name, ref->name, sizeof(name)); 18186daa6f2SAxel Dörfler name[sizeof(name) - 1] = '\0'; 18286daa6f2SAxel Dörfler #else 18386daa6f2SAxel Dörfler strlcpy(name, ref->name, sizeof(name)); 18486daa6f2SAxel Dörfler #endif 18586daa6f2SAxel Dörfler 18686daa6f2SAxel Dörfler BEntry entry(ref); 18786daa6f2SAxel Dörfler if (entry.IsDirectory()) { 18886daa6f2SAxel Dörfler BDirectory directory(&entry); 18986daa6f2SAxel Dörfler if (directory.InitCheck() == B_OK && directory.IsRootDirectory()) { 19086daa6f2SAxel Dörfler // use the volume name for root directories 19186daa6f2SAxel Dörfler BVolume volume; 19286daa6f2SAxel Dörfler if (directory.GetVolume(&volume) == B_OK) 19386daa6f2SAxel Dörfler volume.GetName(name); 19486daa6f2SAxel Dörfler } 19586daa6f2SAxel Dörfler } 19686daa6f2SAxel Dörfler char buffer[B_PATH_NAME_LENGTH]; 19786daa6f2SAxel Dörfler snprintf(buffer, sizeof(buffer), "%s: %s", name, attribute); 198d11ec082SAxel Dörfler SetTitle(buffer); 199d11ec082SAxel Dörfler 200d11ec082SAxel Dörfler // add the menu 201d11ec082SAxel Dörfler 202d11ec082SAxel Dörfler BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL); 203d11ec082SAxel Dörfler AddChild(menuBar); 204d11ec082SAxel Dörfler 205d11ec082SAxel Dörfler BMenu *menu = new BMenu("Attribute"); 206d11ec082SAxel Dörfler 2076781cbdcSAxel Dörfler // the ProbeView save menu items will be inserted here 20836a79516SAxel Dörfler menu->AddItem(new BMenuItem("Remove from File", new BMessage(kMsgRemoveAttribute))); 20936a79516SAxel Dörfler menu->AddSeparatorItem(); 21036a79516SAxel Dörfler 2116781cbdcSAxel Dörfler // the ProbeView print menu items will be inserted here 212d11ec082SAxel Dörfler menu->AddSeparatorItem(); 213d11ec082SAxel Dörfler 214d11ec082SAxel Dörfler menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY)); 215d11ec082SAxel Dörfler menu->SetTargetForItems(this); 216d11ec082SAxel Dörfler menuBar->AddItem(menu); 217d11ec082SAxel Dörfler 218d11ec082SAxel Dörfler // add our interface widgets 219d11ec082SAxel Dörfler 220d11ec082SAxel Dörfler BRect rect = Bounds(); 221d11ec082SAxel Dörfler rect.top = menuBar->Bounds().Height() + 1; 222d11ec082SAxel Dörfler 2237d7f16acSAxel Dörfler BView *view = new BView(rect, "main", B_FOLLOW_ALL, 0); 2247d7f16acSAxel Dörfler view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 2257d7f16acSAxel Dörfler AddChild(view); 2267d7f16acSAxel Dörfler 2277d7f16acSAxel Dörfler rect = view->Bounds(); 2287d7f16acSAxel Dörfler rect.top += 3; 2297d7f16acSAxel Dörfler 2307d7f16acSAxel Dörfler EditorTabView *tabView = new EditorTabView(rect, "tabView"); 2317d7f16acSAxel Dörfler 2327d7f16acSAxel Dörfler rect = tabView->ContainerView()->Bounds(); 2337d7f16acSAxel Dörfler rect.top += 3; 2347d7f16acSAxel Dörfler fProbeView = new ProbeView(rect, ref, attribute, settings); 2357d7f16acSAxel Dörfler tabView->AddRawEditorTab(fProbeView); 2367d7f16acSAxel Dörfler 2377d7f16acSAxel Dörfler view->AddChild(tabView); 2387d7f16acSAxel Dörfler 239fa78c88eSAxel Dörfler fTypeEditorView = GetTypeEditorFor(rect, fProbeView->Editor()); 240fa78c88eSAxel Dörfler if (fTypeEditorView != NULL) 241fa78c88eSAxel Dörfler tabView->SetTypeEditorTab(fTypeEditorView); 2427d7f16acSAxel Dörfler else { 2437d7f16acSAxel Dörfler // show the raw editor if we don't have a specialised type editor 2447d7f16acSAxel Dörfler tabView->Select(1); 2457d7f16acSAxel Dörfler } 2467d7f16acSAxel Dörfler 247c0ced84aSAxel Dörfler fProbeView->AddSaveMenuItems(menu, 0); 248c0ced84aSAxel Dörfler fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 2); 249c0ced84aSAxel Dörfler 2507d7f16acSAxel Dörfler fProbeView->UpdateSizeLimits(); 251d11ec082SAxel Dörfler } 252d11ec082SAxel Dörfler 253d11ec082SAxel Dörfler 254d11ec082SAxel Dörfler AttributeWindow::~AttributeWindow() 255d11ec082SAxel Dörfler { 256d11ec082SAxel Dörfler free(fAttribute); 257d11ec082SAxel Dörfler } 258d11ec082SAxel Dörfler 259d11ec082SAxel Dörfler 26036a79516SAxel Dörfler void 26136a79516SAxel Dörfler AttributeWindow::MessageReceived(BMessage *message) 26236a79516SAxel Dörfler { 26336a79516SAxel Dörfler switch (message->what) { 26436a79516SAxel Dörfler case kMsgRemoveAttribute: 26536a79516SAxel Dörfler { 26636a79516SAxel Dörfler char buffer[1024]; 26736a79516SAxel Dörfler snprintf(buffer, sizeof(buffer), 26836a79516SAxel Dörfler "Do you really want to remove the attribute \"%s\" from the file \"%s\"?\n\n" 269768673c6SAxel Dörfler "You cannot undo this action.", 27036a79516SAxel Dörfler fAttribute, Ref().name); 27136a79516SAxel Dörfler 27236a79516SAxel Dörfler int32 chosen = (new BAlert("DiskProbe request", 273768673c6SAxel Dörfler buffer, "Cancel", "Remove", NULL, 27436a79516SAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 275768673c6SAxel Dörfler if (chosen == 1) { 27636a79516SAxel Dörfler BNode node(&Ref()); 27736a79516SAxel Dörfler if (node.InitCheck() == B_OK) 27836a79516SAxel Dörfler node.RemoveAttr(fAttribute); 27936a79516SAxel Dörfler 28036a79516SAxel Dörfler PostMessage(B_QUIT_REQUESTED); 28136a79516SAxel Dörfler } 28236a79516SAxel Dörfler break; 28336a79516SAxel Dörfler } 28436a79516SAxel Dörfler 28536a79516SAxel Dörfler default: 28636a79516SAxel Dörfler ProbeWindow::MessageReceived(message); 28736a79516SAxel Dörfler break; 28836a79516SAxel Dörfler } 28936a79516SAxel Dörfler } 29036a79516SAxel Dörfler 29136a79516SAxel Dörfler 292d11ec082SAxel Dörfler bool 2930adaff85SAxel Dörfler AttributeWindow::QuitRequested() 2940adaff85SAxel Dörfler { 295c1381da9SAxel Dörfler if (fTypeEditorView != NULL) 296fa78c88eSAxel Dörfler fTypeEditorView->CommitChanges(); 297fa78c88eSAxel Dörfler 2980adaff85SAxel Dörfler bool quit = fProbeView->QuitRequested(); 2990adaff85SAxel Dörfler if (!quit) 3000adaff85SAxel Dörfler return false; 3010adaff85SAxel Dörfler 3020adaff85SAxel Dörfler return ProbeWindow::QuitRequested(); 3030adaff85SAxel Dörfler } 3040adaff85SAxel Dörfler 3050adaff85SAxel Dörfler 3060adaff85SAxel Dörfler bool 307d11ec082SAxel Dörfler AttributeWindow::Contains(const entry_ref &ref, const char *attribute) 308d11ec082SAxel Dörfler { 309d11ec082SAxel Dörfler return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute); 310d11ec082SAxel Dörfler } 311d11ec082SAxel Dörfler 312