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