1 /* 2 * Copyright (c) 2005-2006, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Author: 6 * DarkWyrm <darkwyrm@earthlink.net> 7 */ 8 #include "ResView.h" 9 10 #include <Application.h> 11 #include <ScrollView.h> 12 #include <MenuBar.h> 13 #include <Menu.h> 14 #include <MenuItem.h> 15 #include <stdio.h> 16 #include <ColumnTypes.h> 17 18 #include "App.h" 19 #include "ResourceData.h" 20 #include "ResFields.h" 21 #include "ResWindow.h" 22 #include "PreviewColumn.h" 23 #include "Editor.h" 24 25 static int32 sUntitled = 1; 26 27 ResourceRoster gResRoster; 28 29 enum { 30 M_NEW_FILE = 'nwfl', 31 M_OPEN_FILE, 32 M_SAVE_FILE, 33 M_SAVE_FILE_AS, 34 M_QUIT, 35 M_EDIT_RESOURCE 36 }; 37 38 ResView::ResView(const BRect &frame, const char *name, const int32 &resize, 39 const int32 &flags, const entry_ref *ref) 40 : BView(frame, name, resize, flags), 41 fIsDirty(false) 42 { 43 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 44 if (ref) { 45 fRef = new entry_ref; 46 *fRef = *ref; 47 fFileName = fRef->name; 48 } else { 49 fRef = NULL; 50 fFileName = "Untitled "; 51 fFileName << sUntitled; 52 sUntitled++; 53 } 54 55 BMenu *menu = new BMenu("File"); 56 menu->AddItem(new BMenuItem("New" B_UTF8_ELLIPSIS, new BMessage(M_NEW_FILE), 'N')); 57 menu->AddSeparatorItem(); 58 menu->AddItem(new BMenuItem("Open" B_UTF8_ELLIPSIS, new BMessage(M_OPEN_FILE), 'O')); 59 menu->AddItem(new BMenuItem("Quit", new BMessage(M_QUIT), 'Q')); 60 61 BRect r(Bounds()); 62 r.bottom = 16; 63 fBar = new BMenuBar(r, "bar"); 64 AddChild(fBar); 65 66 fBar->AddItem(menu); 67 68 r = Bounds(); 69 r.top = fBar->Frame().bottom + 4; 70 fListView = new BColumnListView(r, "gridview", B_FOLLOW_ALL, B_WILL_DRAW, 71 B_FANCY_BORDER); 72 AddChild(fListView); 73 74 rgb_color white = { 255,255,255,255 }; 75 fListView->SetColor(B_COLOR_BACKGROUND, white); 76 fListView->SetColor(B_COLOR_SELECTION, ui_color(B_MENU_BACKGROUND_COLOR)); 77 78 float width = be_plain_font->StringWidth("00000") + 20; 79 fListView->AddColumn(new BStringColumn("ID",width,width,100,B_TRUNCATE_END),0); 80 81 fListView->AddColumn(new BStringColumn("Type",width,width,100,B_TRUNCATE_END),1); 82 fListView->AddColumn(new BStringColumn("Name",150,50,300,B_TRUNCATE_END),2); 83 fListView->AddColumn(new PreviewColumn("Data",150,50,300),3); 84 fListView->SetInvocationMessage(new BMessage(M_EDIT_RESOURCE)); 85 86 width = be_plain_font->StringWidth("1000 bytes") + 20; 87 fListView->AddColumn(new BSizeColumn("Size",width,10,100),4); 88 89 if (ref) 90 OpenFile(*ref); 91 } 92 93 94 ResView::~ResView(void) 95 { 96 EmptyDataList(); 97 delete fRef; 98 } 99 100 101 void 102 ResView::AttachedToWindow(void) 103 { 104 for(int32 i = 0; i < fBar->CountItems(); i++) 105 fBar->SubmenuAt(i)->SetTargetForItems(this); 106 fListView->SetTarget(this); 107 } 108 109 110 void 111 ResView::MessageReceived(BMessage *msg) 112 { 113 if (msg->WasDropped()) { 114 be_app->PostMessage(msg); 115 return; 116 } 117 118 switch (msg->what) { 119 case M_NEW_FILE: { 120 BRect r(100,100,400,400); 121 if (Window()) 122 r = Window()->Frame().OffsetByCopy(10,10); 123 ResWindow *win = new ResWindow(r); 124 win->Show(); 125 break; 126 } 127 case M_OPEN_FILE: { 128 be_app->PostMessage(M_SHOW_OPEN_PANEL); 129 break; 130 } 131 case M_QUIT: { 132 be_app->PostMessage(B_QUIT_REQUESTED); 133 break; 134 } 135 case M_EDIT_RESOURCE: { 136 BRow *row = fListView->CurrentSelection(); 137 TypeCodeField *field = (TypeCodeField*)row->GetField(1); 138 gResRoster.SpawnEditor(field->GetResourceData(),this); 139 break; 140 } 141 case M_UPDATE_RESOURCE: { 142 ResourceData *item; 143 if (msg->FindPointer("item",(void **)&item) != B_OK) 144 break; 145 146 for (int32 i = 0; i < fListView->CountRows(); i++) { 147 BRow *row = fListView->RowAt(i); 148 TypeCodeField *field = (TypeCodeField*)row->GetField(1); 149 if (!field || field->GetResourceData() != item) 150 continue; 151 152 UpdateRow(row); 153 break; 154 } 155 break; 156 } 157 default: 158 BView::MessageReceived(msg); 159 } 160 } 161 162 163 void 164 ResView::OpenFile(const entry_ref &ref) 165 { 166 // Add all the 133t resources and attributes of the file 167 168 BFile file(&ref, B_READ_ONLY); 169 BResources resources; 170 if (resources.SetTo(&file) != B_OK) 171 return; 172 file.Unset(); 173 174 resources.PreloadResourceType(); 175 176 int32 index = 0; 177 BRow *row; 178 ResourceData *resData = new ResourceData(); 179 while (resData->SetFromResource(index, resources)) { 180 row = new BRow(); 181 row->SetField(new BStringField(resData->GetIDString()),0); 182 row->SetField(new TypeCodeField(resData->GetType(),resData),1); 183 row->SetField(new BStringField(resData->GetName()),2); 184 BField *field = gResRoster.MakeFieldForType(resData->GetType(), 185 resData->GetData(), 186 resData->GetLength()); 187 if (field) 188 row->SetField(field,3); 189 row->SetField(new BSizeField(resData->GetLength()),4); 190 fListView->AddRow(row); 191 fDataList.AddItem(resData); 192 resData = new ResourceData(); 193 index++; 194 } 195 delete resData; 196 197 BNode node; 198 if (node.SetTo(&ref) == B_OK) { 199 char attrName[B_ATTR_NAME_LENGTH]; 200 node.RewindAttrs(); 201 resData = new ResourceData(); 202 while (node.GetNextAttrName(attrName) == B_OK) { 203 if (resData->SetFromAttribute(attrName, node)) { 204 row = new BRow(); 205 row->SetField(new BStringField(resData->GetIDString()),0); 206 row->SetField(new TypeCodeField(resData->GetType(),resData),1); 207 row->SetField(new BStringField(resData->GetName()),2); 208 BField *field = gResRoster.MakeFieldForType(resData->GetType(), 209 resData->GetData(), 210 resData->GetLength()); 211 if (field) 212 row->SetField(field,3); 213 row->SetField(new BSizeField(resData->GetLength()),4); 214 fListView->AddRow(row); 215 fDataList.AddItem(resData); 216 resData = new ResourceData(); 217 } 218 } 219 delete resData; 220 } 221 } 222 223 224 void 225 ResView::EmptyDataList(void) 226 { 227 for (int32 i = 0; i < fDataList.CountItems(); i++) { 228 ResourceData *data = (ResourceData*) fDataList.ItemAt(i); 229 delete data; 230 } 231 fDataList.MakeEmpty(); 232 } 233 234 235 void 236 ResView::UpdateRow(BRow *row) 237 { 238 TypeCodeField *typeField = (TypeCodeField*) row->GetField(1); 239 ResourceData *resData = typeField->GetResourceData(); 240 BStringField *strField = (BStringField *)row->GetField(0); 241 242 if (strcmp("(attr)", strField->String()) != 0) 243 strField->SetString(resData->GetIDString()); 244 245 strField = (BStringField *)row->GetField(2); 246 strField->SetString(resData->GetName()); 247 248 PreviewField *preField = (PreviewField*)row->GetField(3); 249 preField->SetData(resData->GetData(), resData->GetLength()); 250 251 BSizeField *sizeField = (BSizeField*)row->GetField(4); 252 sizeField->SetSize(resData->GetLength()); 253 } 254