diff --git a/src/apps/resedit/App.cpp b/src/apps/resedit/App.cpp index bcae286f9e..13522e4887 100644 --- a/src/apps/resedit/App.cpp +++ b/src/apps/resedit/App.cpp @@ -17,7 +17,6 @@ main(void) return 0; } - App::App(void) : BApplication("application/x-vnd.Haiku-ResEdit"), fWindowCount(0) @@ -37,10 +36,19 @@ App::~App(void) void App::ReadyToRun(void) { +/* if (fWindowCount < 1) { ResWindow *win = new ResWindow(BRect(50,100,600,400)); win->Show(); } +*/ + if (fWindowCount < 1) { + BEntry entry("/boot/develop/projects/ResEdit/CapitalBe.rsrc"); + entry_ref ref; + entry.GetRef(&ref); + ResWindow *win = new ResWindow(BRect(50,100,600,400),&ref); + win->Show(); + } } diff --git a/src/apps/resedit/Editor.h b/src/apps/resedit/Editor.h index 40b832a048..8019beffaf 100644 --- a/src/apps/resedit/Editor.h +++ b/src/apps/resedit/Editor.h @@ -8,14 +8,25 @@ #ifndef EDITOR_H #define EDITOR_H -class Editor +#include +#include + +class ResourceData; + +#define M_UPDATE_RESOURCE 'uprs' + +class Editor : public BWindow { public: - Editor(void); + Editor(const BRect &frame, ResourceData *data, + BHandler *owner); virtual ~Editor(void); - virtual BView * GetConfigView(void); - virtual void LoadData(unsigned char *data, const size_t &length); - virtual unsigned char * SaveData(size_t *data); + + ResourceData * GetData(void) const { return fResData; } + BHandler * GetOwner(void) const { return fOwner; } +private: + ResourceData *fResData; + BHandler *fOwner; }; #endif diff --git a/src/apps/resedit/Jamfile b/src/apps/resedit/Jamfile index 9498700ea9..4d1b4c183d 100644 --- a/src/apps/resedit/Jamfile +++ b/src/apps/resedit/Jamfile @@ -15,7 +15,13 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits interface ] ; Application ResEdit : $(columnViewSources) App.cpp + BitmapView.cpp + ImageEditor.cpp + InlineEditor.cpp + MiscEditors.cpp + NumberEditors.cpp PreviewColumn.cpp + ResFields.cpp ResourceData.cpp ResourceRoster.cpp ResView.cpp diff --git a/src/apps/resedit/PreviewColumn.cpp b/src/apps/resedit/PreviewColumn.cpp index b0f4ccb8b6..8ef91682cf 100644 --- a/src/apps/resedit/PreviewColumn.cpp +++ b/src/apps/resedit/PreviewColumn.cpp @@ -6,6 +6,7 @@ * DarkWyrm */ #include "PreviewColumn.h" +#include "ResFields.h" #include PreviewColumn::PreviewColumn(const char *title, float width, @@ -17,56 +18,12 @@ PreviewColumn::PreviewColumn(const char *title, float width, void PreviewColumn::DrawField(BField* field, BRect rect, BView* parent) { - BIntegerField *intField = dynamic_cast(field); - BStringField *strField = dynamic_cast(field); - BBitmapField *bmpField = dynamic_cast(field); - - if (intField) { - float width = rect.Width() - 16; - BString string; - string << intField->Value(); - parent->TruncateString(&string, B_TRUNCATE_MIDDLE, width + 2); - DrawString(string.String(), parent, rect); - } else if (strField) { - float width = rect.Width() - 16; - if (width != strField->Width()) { - BString out_string(strField->String()); - - parent->TruncateString(&out_string, B_TRUNCATE_END, width + 2); - strField->SetClippedString(out_string.String()); - strField->SetWidth(width); - } - DrawString(strField->ClippedString(), parent, rect); - } else if (bmpField) { - const BBitmap *bitmap = bmpField->Bitmap(); - - if (bitmap != NULL) { - // Scale the bitmap down to completely fit within the field's height - BRect drawrect(bitmap->Bounds().OffsetToCopy(rect.LeftTop())); - if (drawrect.Height() > rect.Height()) { - drawrect = rect; - drawrect.right = drawrect.left + - (bitmap->Bounds().Width() * - (rect.Height() / bitmap->Bounds().Height())); - } - - parent->SetDrawingMode(B_OP_ALPHA); - parent->DrawBitmap(bitmap, bitmap->Bounds(), drawrect); - parent->SetDrawingMode(B_OP_COPY); - - BString out; - out << bitmap->Bounds().IntegerWidth() << " x " - << bitmap->Bounds().IntegerHeight() << " x " - << (int32(bitmap->BytesPerRow() / bitmap->Bounds().Width()) * 8); - - BRect stringrect = rect; - stringrect.right -= 10; - stringrect.left = stringrect.right - parent->StringWidth(out.String()); - if (stringrect.left < drawrect.right + 5) - stringrect.left = drawrect.right + 5; - - parent->TruncateString(&out, B_TRUNCATE_END, stringrect.Width()); - DrawString(out.String(), parent, stringrect); - } - } + PreviewField *pField = (PreviewField*)field; + pField->DrawField(rect,parent); +} + +bool +PreviewColumn::AcceptsField(const BField* field) const +{ + return dynamic_cast(field); } diff --git a/src/apps/resedit/PreviewColumn.h b/src/apps/resedit/PreviewColumn.h index 6053f39d26..9117f2e3d4 100644 --- a/src/apps/resedit/PreviewColumn.h +++ b/src/apps/resedit/PreviewColumn.h @@ -16,6 +16,7 @@ public: PreviewColumn(const char *title, float width, float minWidth, float maxWidth); void DrawField(BField* field, BRect rect, BView* parent); + bool AcceptsField(const BField* field) const; }; #endif diff --git a/src/apps/resedit/ResView.cpp b/src/apps/resedit/ResView.cpp index 4990c47bb2..379ba31b21 100644 --- a/src/apps/resedit/ResView.cpp +++ b/src/apps/resedit/ResView.cpp @@ -17,8 +17,10 @@ #include "App.h" #include "ResourceData.h" +#include "ResFields.h" #include "ResWindow.h" #include "PreviewColumn.h" +#include "Editor.h" static int32 sUntitled = 1; @@ -29,7 +31,8 @@ enum { M_OPEN_FILE, M_SAVE_FILE, M_SAVE_FILE_AS, - M_QUIT + M_QUIT, + M_EDIT_RESOURCE }; ResView::ResView(const BRect &frame, const char *name, const int32 &resize, @@ -78,6 +81,7 @@ ResView::ResView(const BRect &frame, const char *name, const int32 &resize, fListView->AddColumn(new BStringColumn("Type",width,width,100,B_TRUNCATE_END),1); fListView->AddColumn(new BStringColumn("Name",150,50,300,B_TRUNCATE_END),2); fListView->AddColumn(new PreviewColumn("Data",150,50,300),3); + fListView->SetInvocationMessage(new BMessage(M_EDIT_RESOURCE)); width = be_plain_font->StringWidth("1000 bytes") + 20; fListView->AddColumn(new BSizeColumn("Size",width,10,100),4); @@ -89,6 +93,7 @@ ResView::ResView(const BRect &frame, const char *name, const int32 &resize, ResView::~ResView(void) { + EmptyDataList(); delete fRef; } @@ -98,12 +103,18 @@ ResView::AttachedToWindow(void) { for(int32 i = 0; i < fBar->CountItems(); i++) fBar->SubmenuAt(i)->SetTargetForItems(this); + fListView->SetTarget(this); } void ResView::MessageReceived(BMessage *msg) { + if (msg->WasDropped()) { + be_app->PostMessage(msg); + return; + } + switch (msg->what) { case M_NEW_FILE: { BRect r(100,100,400,400); @@ -121,6 +132,28 @@ ResView::MessageReceived(BMessage *msg) be_app->PostMessage(B_QUIT_REQUESTED); break; } + case M_EDIT_RESOURCE: { + BRow *row = fListView->CurrentSelection(); + TypeCodeField *field = (TypeCodeField*)row->GetField(1); + gResRoster.SpawnEditor(field->GetResourceData(),this); + break; + } + case M_UPDATE_RESOURCE: { + ResourceData *item; + if (msg->FindPointer("item",(void **)&item) != B_OK) + break; + + for (int32 i = 0; i < fListView->CountRows(); i++) { + BRow *row = fListView->RowAt(i); + TypeCodeField *field = (TypeCodeField*)row->GetField(1); + if (!field || field->GetResourceData() != item) + continue; + + UpdateRow(row); + break; + } + break; + } default: BView::MessageReceived(msg); } @@ -133,86 +166,88 @@ ResView::OpenFile(const entry_ref &ref) // Add all the 133t resources and attributes of the file BFile file(&ref, B_READ_ONLY); - if (fResources.SetTo(&file) != B_OK) + BResources resources; + if (resources.SetTo(&file) != B_OK) return; file.Unset(); - fResources.PreloadResourceType(); + resources.PreloadResourceType(); int32 index = 0; - ResourceData data; BRow *row; - while (data.SetFromResource(index, fResources)) { + ResourceData *resData = new ResourceData(); + while (resData->SetFromResource(index, resources)) { row = new BRow(); - row->SetField(new BStringField(data.GetIDString()),0); - row->SetField(new BStringField(data.GetTypeString()),1); - row->SetField(new BStringField(data.GetName()),2); - BField *field = gResRoster.MakeFieldForType(data.GetType(), - data.GetData(), - data.GetLength()); + row->SetField(new BStringField(resData->GetIDString()),0); + row->SetField(new TypeCodeField(resData->GetType(),resData),1); + row->SetField(new BStringField(resData->GetName()),2); + BField *field = gResRoster.MakeFieldForType(resData->GetType(), + resData->GetData(), + resData->GetLength()); if (field) row->SetField(field,3); - row->SetField(new BSizeField(data.GetLength()),4); + row->SetField(new BSizeField(resData->GetLength()),4); fListView->AddRow(row); + fDataList.AddItem(resData); + resData = new ResourceData(); index++; } + delete resData; -//debugger(""); BNode node; if (node.SetTo(&ref) == B_OK) { char attrName[B_ATTR_NAME_LENGTH]; node.RewindAttrs(); + resData = new ResourceData(); while (node.GetNextAttrName(attrName) == B_OK) { - if (data.SetFromAttribute(attrName, node)) { + if (resData->SetFromAttribute(attrName, node)) { row = new BRow(); - row->SetField(new BStringField(data.GetIDString()),0); - row->SetField(new BStringField(data.GetTypeString()),1); - row->SetField(new BStringField(data.GetName()),2); - BField *field = gResRoster.MakeFieldForType(data.GetType(), - data.GetData(), - data.GetLength()); + row->SetField(new BStringField(resData->GetIDString()),0); + row->SetField(new TypeCodeField(resData->GetType(),resData),1); + row->SetField(new BStringField(resData->GetName()),2); + BField *field = gResRoster.MakeFieldForType(resData->GetType(), + resData->GetData(), + resData->GetLength()); if (field) row->SetField(field,3); - row->SetField(new BSizeField(data.GetLength()),4); + row->SetField(new BSizeField(resData->GetLength()),4); fListView->AddRow(row); + fDataList.AddItem(resData); + resData = new ResourceData(); } } + delete resData; } } -const void * -ResView::LoadResource(const type_code &type, const int32 &id, size_t *out_size) +void +ResView::EmptyDataList(void) { - return fResources.LoadResource(type, id, out_size); + for (int32 i = 0; i < fDataList.CountItems(); i++) { + ResourceData *data = (ResourceData*) fDataList.ItemAt(i); + delete data; + } + fDataList.MakeEmpty(); } -const void * -ResView::LoadResource(const type_code &type, const char *name, size_t *out_size) +void +ResView::UpdateRow(BRow *row) { - return fResources.LoadResource(type, name, out_size); + TypeCodeField *typeField = (TypeCodeField*) row->GetField(1); + ResourceData *resData = typeField->GetResourceData(); + BStringField *strField = (BStringField *)row->GetField(0); + + if (strcmp("(attr)", strField->String()) != 0) + strField->SetString(resData->GetIDString()); + + strField = (BStringField *)row->GetField(2); + strField->SetString(resData->GetName()); + + PreviewField *preField = (PreviewField*)row->GetField(3); + preField->SetData(resData->GetData(), resData->GetLength()); + + BSizeField *sizeField = (BSizeField*)row->GetField(4); + sizeField->SetSize(resData->GetLength()); } - - -status_t -ResView::AddResource(const type_code &type, const int32 &id, const void *data, - const size_t &data_size, const char *name) -{ - return fResources.AddResource(type, id, data, data_size, name); -} - - -bool -ResView::HasResource(const type_code &type, const int32 &id) -{ - return fResources.HasResource(type, id); -} - - -bool -ResView::HasResource(const type_code &type, const char *name) -{ - return fResources.HasResource(type, name); -} - diff --git a/src/apps/resedit/ResView.h b/src/apps/resedit/ResView.h index 05cff52d0c..a9bd922e91 100644 --- a/src/apps/resedit/ResView.h +++ b/src/apps/resedit/ResView.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "ResourceRoster.h" @@ -31,25 +32,16 @@ public: void OpenFile(const entry_ref &ref); - // BResources mirror API - const void * LoadResource(const type_code &type, const int32 &id, - size_t *out_size); - const void * LoadResource(const type_code &type, const char *name, - size_t *out_size); - status_t AddResource(const type_code &type, const int32 &id, - const void *data, const size_t &data_size, - const char *name = NULL); - bool HasResource(const type_code &type, const int32 &id); - bool HasResource(const type_code &type, const char *name); - private: + void EmptyDataList(void); + void UpdateRow(BRow *row); + BColumnListView *fListView; entry_ref *fRef; BString fFileName; BMenuBar *fBar; bool fIsDirty; - - BResources fResources; + BList fDataList; }; extern ResourceRoster gResRoster; diff --git a/src/apps/resedit/ResourceData.cpp b/src/apps/resedit/ResourceData.cpp index ef1a2244b5..1d1f0d3703 100644 --- a/src/apps/resedit/ResourceData.cpp +++ b/src/apps/resedit/ResourceData.cpp @@ -6,6 +6,7 @@ * DarkWyrm */ #include "ResourceData.h" +#include "ResFields.h" #include ResourceData::ResourceData(void) @@ -16,7 +17,7 @@ ResourceData::ResourceData(void) fName(""), fData(NULL), fLength(0), - fFree(false) + fAttr(false) { } @@ -29,11 +30,11 @@ ResourceData::ResourceData(const type_code &code, const int32 &id, fName(name), fData(data), fLength(length), - fFree(false) + fAttr(false) { fIDString = ""; fIDString << fID; - MakeTypeString(); + fTypeString = MakeTypeString(code); } @@ -45,8 +46,7 @@ ResourceData::ResourceData(const ResourceData &data) ResourceData::~ResourceData(void) { - if (fFree) - free(fData); + free(fData); } @@ -58,13 +58,9 @@ ResourceData::operator=(const ResourceData &data) fID = data.fID; fIDString = data.fIDString; fName = data.fName; - fLength = data.fLength; - fFree = data.fFree; + fAttr = data.fAttr; + SetData(data.fData, data.fLength); - // This is an attribute, so we need to allocate and free the data - if (fFree) { - fData = data.fData; - } return *this; } @@ -78,11 +74,12 @@ ResourceData::SetFromResource(const int32 &index, BResources &res) return false; } fName = name; - MakeTypeString(); + fTypeString = MakeTypeString(fType); fIDString = ""; fIDString << fID; - fFree = false; - fData = (char *)res.LoadResource(fType,fID,&fLength); + fAttr = false; + char *data = (char *)res.LoadResource(fType,fID,&fLength); + SetData(data,fLength); return true; } @@ -102,9 +99,9 @@ ResourceData::SetFromAttribute(const char *name, BNode &node) fIDString = "(attr)"; fName = name; fLength = info.size; - fFree = true; + fAttr = true; - MakeTypeString(); + fTypeString = MakeTypeString(fType); fData = (char *)malloc(fLength); if (fData) { @@ -125,27 +122,45 @@ ResourceData::SetTo(const type_code &code, const int32 &id, const char *name, char *data, const size_t &length) { fType = code; + fTypeString = MakeTypeString(code); fID = id; + fIDString = ""; + fIDString << fID; fName = name; - fData = data; - fLength = length; + SetData(data,length); - MakeTypeString(); } void -ResourceData::MakeTypeString(void) +ResourceData::SetType(const type_code &code) { - char typestring[7]; - char *typeptr = (char *) &fType; - typestring[0] = '\''; - typestring[1] = typeptr[3]; - typestring[2] = typeptr[2]; - typestring[3] = typeptr[1]; - typestring[4] = typeptr[0]; - typestring[5] = '\''; - typestring[6] = '\0'; - fTypeString = typestring; + fType = code; + fTypeString = MakeTypeString(code); +} + + +void +ResourceData::SetID(const int32 &id) +{ + fID = id; + fIDString = ""; + fIDString << fID; +} + + +void +ResourceData::SetData(const char *data, const size_t &size) +{ + free(fData); + + fLength = size; + + if (size > 0) { + fData = (char *)malloc(size); + memcpy(fData,data,size); + } + else + fData = NULL; } diff --git a/src/apps/resedit/ResourceData.h b/src/apps/resedit/ResourceData.h index f280872d35..bbbb28467f 100644 --- a/src/apps/resedit/ResourceData.h +++ b/src/apps/resedit/ResourceData.h @@ -31,17 +31,23 @@ public: type_code GetType(void) const { return fType; } const char * GetTypeString(void) const { return fTypeString.String(); } + void SetType(const type_code &code); + int32 GetID(void) const { return fID; } const char * GetIDString(void) const { return fIDString.String(); } + void SetID(const int32 &id); + const char * GetName(void) const { return fName.String(); } + void SetName(const char *name) { fName = name; } + char * GetData(void) { return fData; } size_t GetLength(void) const { return fLength; } + void SetData(const char *data, const size_t &size); - bool IsAttribute(void) const { return fFree; } + bool IsAttribute(void) const { return fAttr; } + void SetAttribute(const bool &value) { fAttr = value; } private: - void MakeTypeString(void); - int32 fType; BString fTypeString; int32 fID; @@ -49,7 +55,7 @@ private: BString fName; char *fData; size_t fLength; - bool fFree; + bool fAttr; }; #endif diff --git a/src/apps/resedit/ResourceRoster.cpp b/src/apps/resedit/ResourceRoster.cpp index 9225d80803..55259275f3 100644 --- a/src/apps/resedit/ResourceRoster.cpp +++ b/src/apps/resedit/ResourceRoster.cpp @@ -15,6 +15,10 @@ #include #include +#include "ResourceData.h" +#include "InternalEditors.h" +#include "ResFields.h" + // For the MakeFieldForType temp code #include #include @@ -77,7 +81,7 @@ ResourceRoster::MakeFieldForType(const int32 &type, const char *data, // temporary code until editors are done switch (type) { case B_MIME_STRING_TYPE: - return new BStringField(data); + return new StringPreviewField(data); case B_GIF_FORMAT: case B_PPM_FORMAT: case B_TGA_FORMAT: @@ -88,9 +92,7 @@ ResourceRoster::MakeFieldForType(const int32 &type, const char *data, BMemoryIO memio(data,length); BBitmap *bitmap = BTranslationUtils::GetBitmap(&memio); if (bitmap) { - // XXX WARNING! WARNING! Known memory leak - // This is temp code, so it's OK for the moment - BBitmapField *field = new BBitmapField(bitmap); + BitmapPreviewField *field = new BitmapPreviewField(bitmap); return field; } break; @@ -144,3 +146,31 @@ ResourceRoster::LoadEditors(void) } } +void +ResourceRoster::SpawnEditor(ResourceData *data, BHandler *handler) +{ + // temporary code until editors are done + switch (data->GetType()) { + case B_MIME_STRING_TYPE: { + StringEditor *strEd = new StringEditor(BRect(100,100,300,200), + data, handler); + strEd->Show(); + break; + } + case B_GIF_FORMAT: + case B_PPM_FORMAT: + case B_TGA_FORMAT: + case B_BMP_FORMAT: + case B_TIFF_FORMAT: + case B_PNG_FORMAT: + case B_JPEG_FORMAT: { + ImageEditor *imgEd = new ImageEditor(BRect(100,100,300,200), + data, handler); + imgEd->Show(); + break; + } + default: + break; + } +} + diff --git a/src/apps/resedit/ResourceRoster.h b/src/apps/resedit/ResourceRoster.h index 15ecf2da67..b225a10de7 100644 --- a/src/apps/resedit/ResourceRoster.h +++ b/src/apps/resedit/ResourceRoster.h @@ -13,6 +13,7 @@ #include class Editor; +class ResourceData; class ResourceRoster { @@ -21,9 +22,10 @@ public: ~ResourceRoster(void); BField * MakeFieldForType(const int32 &type, const char *data, const size_t &length); - + void SpawnEditor(ResourceData *data, BHandler *handler); + private: - void LoadEditors(void); + void LoadEditors(void); BList fList; };