1 /* 2 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "AttributeWindow.h" 8 #include "ProbeView.h" 9 #include "TypeEditors.h" 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <Alert.h> 15 #include <Catalog.h> 16 #include <Directory.h> 17 #include <GroupView.h> 18 #include <LayoutBuilder.h> 19 #include <Locale.h> 20 #include <MenuBar.h> 21 #include <MenuItem.h> 22 #include <StringView.h> 23 #include <TabView.h> 24 #include <Volume.h> 25 26 27 #undef B_TRANSLATION_CONTEXT 28 #define B_TRANSLATION_CONTEXT "AttributeWindow" 29 30 31 static const uint32 kMsgRemoveAttribute = 'rmat'; 32 33 34 class EditorTabView : public BTabView { 35 public: 36 EditorTabView(const char *name, 37 button_width width = B_WIDTH_FROM_WIDEST, 38 uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS); 39 40 void AddRawEditorTab(BView *view); 41 void SetTypeEditorTab(BView *view); 42 }; 43 44 45 // ----------------- 46 47 48 EditorTabView::EditorTabView(const char *name, button_width width, uint32 flags) 49 : BTabView(name, width, flags) 50 { 51 SetBorder(B_NO_BORDER); 52 } 53 54 55 void 56 EditorTabView::AddRawEditorTab(BView *view) 57 { 58 BTab* tab = new BTab(view); 59 tab->SetLabel(B_TRANSLATE("Raw editor")); 60 AddTab(view, tab); 61 } 62 63 64 void 65 EditorTabView::SetTypeEditorTab(BView *view) 66 { 67 if (view == NULL) { 68 view = new BStringView(B_TRANSLATE("Type editor"), 69 B_TRANSLATE("No type editor available")); 70 ((BStringView*)view)->SetAlignment(B_ALIGN_CENTER); 71 } 72 73 BGroupView* group = new BGroupView(B_VERTICAL); 74 BLayoutBuilder::Group<>(group, B_VERTICAL) 75 .SetInsets(B_USE_WINDOW_SPACING, 0, B_USE_WINDOW_SPACING, 0) 76 .Add(view) 77 .AddGlue(25.0f); 78 79 group->SetName(view->Name()); 80 81 AddTab(group); 82 Select(0); 83 } 84 85 86 // #pragma mark - 87 88 89 AttributeWindow::AttributeWindow(BRect _rect, entry_ref *ref, 90 const char *attribute, const BMessage *settings) 91 : ProbeWindow(_rect, ref), 92 fAttribute(strdup(attribute)) 93 { 94 // Set alternative window title for devices 95 char name[B_FILE_NAME_LENGTH]; 96 strlcpy(name, ref->name, sizeof(name)); 97 98 BEntry entry(ref); 99 if (entry.IsDirectory()) { 100 BDirectory directory(&entry); 101 if (directory.InitCheck() == B_OK && directory.IsRootDirectory()) { 102 // use the volume name for root directories 103 BVolume volume; 104 if (directory.GetVolume(&volume) == B_OK) 105 volume.GetName(name); 106 } 107 } 108 char buffer[B_PATH_NAME_LENGTH]; 109 snprintf(buffer, sizeof(buffer), "%s: %s", name, attribute); 110 SetTitle(buffer); 111 112 BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 0); 113 SetLayout(layout); 114 115 // add the menu 116 117 BMenuBar *menuBar = new BMenuBar(""); 118 layout->AddView(menuBar, 0); 119 120 BMenu *menu = new BMenu(B_TRANSLATE("Attribute")); 121 122 // the ProbeView save menu items will be inserted here 123 menu->AddItem(new BMenuItem(B_TRANSLATE("Remove from file"), 124 new BMessage(kMsgRemoveAttribute))); 125 menu->AddSeparatorItem(); 126 127 // the ProbeView print menu items will be inserted here 128 menu->AddSeparatorItem(); 129 130 menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), 131 new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY)); 132 menu->SetTargetForItems(this); 133 menuBar->AddItem(menu); 134 135 // add our interface widgets 136 137 EditorTabView *tabView = new EditorTabView("tabView"); 138 layout->AddView(tabView, 999); 139 140 BRect rect = tabView->ContainerView()->Bounds(); 141 rect.top += 3; 142 143 fProbeView = new ProbeView(ref, attribute, settings); 144 fProbeView->AddSaveMenuItems(menu, 0); 145 fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 2); 146 147 fTypeEditorView = GetTypeEditorFor(rect, fProbeView->Editor()); 148 149 tabView->SetTypeEditorTab(fTypeEditorView); 150 tabView->AddRawEditorTab(fProbeView); 151 152 if (fTypeEditorView == NULL) { 153 // show the raw editor if we don't have a specialised type editor 154 tabView->Select(1); 155 } 156 } 157 158 159 AttributeWindow::~AttributeWindow() 160 { 161 free(fAttribute); 162 } 163 164 165 void 166 AttributeWindow::MessageReceived(BMessage *message) 167 { 168 switch (message->what) { 169 case kMsgRemoveAttribute: 170 { 171 char buffer[1024]; 172 173 snprintf(buffer, sizeof(buffer), 174 B_TRANSLATE("Do you really want to remove the attribute \"%s\" " 175 "from the file \"%s\"?\n\nYou cannot undo this action."), 176 fAttribute, Ref().name); 177 178 BAlert* alert = new BAlert(B_TRANSLATE("DiskProbe request"), 179 buffer, B_TRANSLATE("Cancel"), B_TRANSLATE("Remove"), NULL, 180 B_WIDTH_AS_USUAL, B_WARNING_ALERT); 181 alert->SetShortcut(0, B_ESCAPE); 182 int32 chosen = alert->Go(); 183 184 if (chosen == 1) { 185 BNode node(&Ref()); 186 if (node.InitCheck() == B_OK) 187 node.RemoveAttr(fAttribute); 188 189 PostMessage(B_QUIT_REQUESTED); 190 } 191 break; 192 } 193 194 default: 195 ProbeWindow::MessageReceived(message); 196 break; 197 } 198 } 199 200 201 bool 202 AttributeWindow::QuitRequested() 203 { 204 if (fTypeEditorView != NULL) 205 fTypeEditorView->CommitChanges(); 206 207 bool quit = fProbeView->QuitRequested(); 208 if (!quit) 209 return false; 210 211 return ProbeWindow::QuitRequested(); 212 } 213 214 215 bool 216 AttributeWindow::Contains(const entry_ref &ref, const char *attribute) 217 { 218 return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute); 219 } 220 221