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 31static const uint32 kMsgRemoveAttribute = 'rmat'; 32 33 34class 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 48EditorTabView::EditorTabView(const char *name, button_width width, uint32 flags) 49 : BTabView(name, width, flags) 50{ 51 SetBorder(B_NO_BORDER); 52} 53 54 55void 56EditorTabView::AddRawEditorTab(BView *view) 57{ 58 BTab* tab = new BTab(view); 59 tab->SetLabel(B_TRANSLATE("Raw editor")); 60 AddTab(view, tab); 61} 62 63 64void 65EditorTabView::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 89AttributeWindow::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 159AttributeWindow::~AttributeWindow() 160{ 161 free(fAttribute); 162} 163 164 165void 166AttributeWindow::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 201bool 202AttributeWindow::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 215bool 216AttributeWindow::Contains(const entry_ref &ref, const char *attribute) 217{ 218 return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute); 219} 220 221