Added ResourceEdit and modified BColumnListView, BRow and BMenu.

Signed-off-by: Matt Madia <mattmadia@gmail.com>
This commit is contained in:
Tri-Edge AI 2013-01-03 18:02:21 +02:00 committed by Matt Madia
parent 9e3038ae8e
commit 49126a0e9b
22 changed files with 1638 additions and 3 deletions

Binary file not shown.

View File

@ -122,6 +122,7 @@ public:
float MaxContentWidth() const;
BMenuItem* FindMarked();
int32 FindMarkedIndex();
BMenu* Supermenu() const;
BMenuItem* Superitem() const;

View File

@ -133,6 +133,7 @@ public:
float Height() const;
bool IsExpanded() const;
bool IsSelected() const;
private:
// Blows up into the debugger if the validation fails.
@ -326,8 +327,9 @@ public:
// Does not delete row or children at this time.
// todo: Make delete row and children
void RemoveRow(BRow* row);
void UpdateRow(BRow* row);
bool SwapRows(int32 index1, int32 index2, BRow*
parentRow1 = NULL, BRow* parentRow2 = NULL);
void Clear();
// Appearance (DEPRECATED)

View File

@ -48,7 +48,7 @@ HaikuSubInclude powerstatus ;
HaikuSubInclude processcontroller ;
HaikuSubInclude pulse ;
HaikuSubInclude remotedesktop ;
HaikuSubInclude resedit ;
HaikuSubInclude resourceedit ;
HaikuSubInclude screenshot ;
HaikuSubInclude serialconnect ;
HaikuSubInclude showimage ;

View File

@ -0,0 +1,42 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define MSG_NEW 'm000'
#define MSG_OPEN 'm001'
#define MSG_OPEN_DONE 'm002'
#define MSG_CLOSE 'm003'
#define MSG_SAVE 'm004'
#define MSG_SAVEAS 'm005'
#define MSG_SAVEAS_DONE 'm006'
#define MSG_SAVEALL 'm007'
#define MSG_MERGEWITH 'm008'
#define MSG_QUIT 'm009'
#define MSG_UNDO 'm010'
#define MSG_REDO 'm011'
#define MSG_CUT 'm012'
#define MSG_COPY 'm013'
#define MSG_PASTE 'm014'
#define MSG_CLEAR 'm015'
#define MSG_SELECTALL 'm016'
#define MSG_ADD 'm020'
#define MSG_REMOVE 'm021'
#define MSG_MOVEUP 'm022'
#define MSG_MOVEDOWN 'm023'
#define MSG_SELECTION 'm030'
// TODO: Remove prior to release.
#define DEBUG 1
#include <Debug.h>
// --- ---
#endif

View File

@ -0,0 +1,101 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "DefaultTypes.h"
#include <ByteOrder.h>
BString
toStringBOOL(const void* data)
{
if (*(bool*)data)
return "✔ true";
else
return "✖ false";
}
BString
toStringBYTE(const void* data)
{
return (BString() << *(int8*)data);
}
BString
toStringSHRT(const void* data)
{
return (BString() << *(int16*)data);
}
BString
toStringLONG(const void* data)
{
return (BString() << *(int32*)data);
}
BString
toStringLLNG(const void* data)
{
return (BString() << *(int64*)data);
}
BString
toStringUBYT(const void* data)
{
return (BString() << *(uint8*)data);
}
BString
toStringUSHT(const void* data)
{
return (BString() << *(uint16*)data);
}
BString
toStringULNG(const void* data)
{
return (BString() << *(uint32*)data);
}
BString
toStringULLG(const void* data)
{
return (BString() << *(uint64*)data);
}
BString
toStringRAWT(const void* data)
{
return "[Raw Data]";
}
int32
FindTypeCodeIndex(type_code code)
{
for (int32 i = 0; kDefaultTypes[i].type != NULL; i++)
if (kDefaultTypes[i].typeCode == code)
return i;
return -1;
}
void
TypeCodeToString(type_code code, char* str)
{
*(type_code*)str = B_HOST_TO_BENDIAN_INT32(code);
str[4] = '\0';
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef DEFAULT_TYPES_H
#define DEFAULT_TYPES_H
#include <String.h>
struct ResourceDataType {
const char* type;
type_code typeCode;
uint32 size;
BString (*toString)(const void*);
};
// TODO: Rework design of this. This one sucks.
BString toStringBOOL(const void* data);
BString toStringBYTE(const void* data);
BString toStringSHRT(const void* data);
BString toStringLONG(const void* data);
BString toStringLLNG(const void* data);
BString toStringUBYT(const void* data);
BString toStringUSHT(const void* data);
BString toStringULNG(const void* data);
BString toStringULLG(const void* data);
BString toStringRAWT(const void* data);
char * const kDefaultData[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
#define LINE "", 0, ~0
#define END NULL, 0, 0
const ResourceDataType kDefaultTypes[] = {
{ "bool", 'BOOL', 1, toStringBOOL },
{ LINE },
{ "int8", 'BYTE', 1, toStringBYTE },
{ "int16", 'SHRT', 2, toStringSHRT },
{ "int32", 'LONG', 4, toStringLONG },
{ "int64", 'LLNG', 8, toStringLLNG },
{ LINE },
{ "uint8", 'UBYT', 1, toStringUBYT },
{ "uint16", 'USHT', 2, toStringUSHT },
{ "uint32", 'ULNG', 4, toStringULNG },
{ "uint64", 'ULLG', 8, toStringULLG },
{ LINE },
{ "raw", 'RAWT', 0, toStringRAWT },
{ END }
};
const int32 kDefaultTypeSelected = 4;
// int32
#undef LINE
#undef END
int32 FindTypeCodeIndex(type_code code);
void TypeCodeToString(type_code code, char* str);
#endif

View File

@ -0,0 +1,67 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ImageButton.h"
#include <Bitmap.h>
ImageButton::ImageButton(BRect frame, const char* name, BBitmap* image,
BMessage* message, uint32 resizingMode = B_FOLLOW_NONE)
:
BButton(frame, name, "", message, resizingMode)
{
fImage = image;
fDrawPoint.x = ((frame.RightTop().x - frame.LeftTop().x)
- (image->Bounds().RightBottom().x + 1)) / 2;
fDrawPoint.y = ((frame.LeftBottom().y - frame.LeftTop().y)
- (image->Bounds().RightBottom().y + 1)) / 2;
fInnerBounds = Bounds();
fInnerBounds.InsetBy(3, 3);
SetDrawingMode(B_OP_ALPHA);
}
ImageButton::~ImageButton()
{
}
void
ImageButton::Draw(BRect updateRect)
{
BButton::Draw(updateRect);
DrawBitmap(fImage, fDrawPoint);
if (!IsEnabled()) {
rgb_color tempColor = HighColor();
SetHighColor(255, 255, 255, 155);
FillRect(fInnerBounds, B_SOLID_HIGH);
SetHighColor(tempColor);
}
}
void
ImageButton::ResizeTo(float width, float height)
{
BButton::ResizeTo(width, height);
fInnerBounds = Bounds();
fInnerBounds.InsetBy(3, 3);
}
void
ImageButton::SetBitmap(BBitmap* image)
{
fImage = image;
Invalidate();
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef IMAGE_BUTTON_H
#define IMAGE_BUTTON_H
#include <Button.h>
class ImageButton : public BButton
{
public:
ImageButton(BRect frame, const char* name, BBitmap* image,
BMessage* message, uint32 resizingMode);
~ImageButton();
void Draw(BRect updateRect);
void ResizeTo(float width, float height);
void SetBitmap(BBitmap* image);
private:
BBitmap* fImage;
BPoint fDrawPoint;
BRect fInnerBounds;
};
#endif

View File

@ -0,0 +1,23 @@
SubDir HAIKU_TOP src apps resourceedit ;
UsePrivateHeaders interface shared ;
Application ResourceEdit
:
DefaultTypes.cpp
ImageButton.cpp
MainWindow.cpp
ResourceEdit.cpp
ResourceListView.cpp
ResourceRow.cpp
main.cpp
:
be
tracker
translation
libcolumnlistview.a
$(TARGET_LIBSTDC++)
:
ResourceEdit.rdef
;

View File

@ -0,0 +1,562 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "MainWindow.h"
#include "Constants.h"
#include "ImageButton.h"
#include "ResourceListView.h"
#include "ResourceRow.h"
#include <Application.h>
#include <ColumnListView.h>
#include <ColumnTypes.h>
#include <Entry.h>
#include <FilePanel.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Resources.h>
#include <StatusBar.h>
#include <String.h>
#include <TextControl.h>
#include <TranslationUtils.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fstream>
using namespace std;
MainWindow::MainWindow(BRect frame, BEntry* assocEntry)
:
BWindow(frame, NULL, B_DOCUMENT_WINDOW, 0)
{
fAssocEntry = assocEntry;
fSavePanel = NULL;
fMenuBar = new BMenuBar(BRect(0, 0, 600, 1), "fMenuBar");
fFileMenu = new BMenu("File", B_ITEMS_IN_COLUMN);
fNewItem = new BMenuItem("New", new BMessage(MSG_NEW), 'N');
fOpenItem = new BMenuItem("Open", new BMessage(MSG_OPEN), 'O');
fCloseItem = new BMenuItem("Close", new BMessage(MSG_CLOSE), 'W');
fSaveItem = new BMenuItem("Save", new BMessage(MSG_SAVE), 'S');
fSaveAsItem = new BMenuItem("Save As" B_UTF8_ELLIPSIS, new
BMessage(MSG_SAVEAS));
fSaveAllItem = new BMenuItem("Save All", new BMessage(MSG_SAVEALL), 'S',
B_SHIFT_KEY);
fMergeWithItem = new BMenuItem("Merge With" B_UTF8_ELLIPSIS,
new BMessage(MSG_MERGEWITH), 'M');
fQuitItem = new BMenuItem("Quit", new BMessage(MSG_QUIT), 'Q');
fEditMenu = new BMenu("Edit", B_ITEMS_IN_COLUMN);
fUndoItem = new BMenuItem("Undo", new BMessage(MSG_UNDO), 'Z');
fRedoItem = new BMenuItem("Redo", new BMessage(MSG_REDO), 'Y');
fCutItem = new BMenuItem("Cut", new BMessage(MSG_CUT), 'X');
fCopyItem = new BMenuItem("Copy", new BMessage(MSG_COPY), 'C');
fPasteItem = new BMenuItem("Paste", new BMessage(MSG_PASTE), 'V');
fClearItem = new BMenuItem("Clear", new BMessage(MSG_CLEAR));
fSelectAllItem = new BMenuItem("Select All",
new BMessage(MSG_SELECTALL), 'A');
fHelpMenu = new BMenu("Help", B_ITEMS_IN_COLUMN);
fResourceIDText = new BTextControl(BRect(0, 0, 47, 23).OffsetBySelf(8, 24),
"fResourceIDText", NULL, "0", NULL);
fResourceTypePopUp = new BPopUpMenu("(Type)");
fResourceTypeMenu = new BMenuField(BRect(0, 0, 1, 1).OffsetBySelf(60, 24),
"fResourceTypeMenu", NULL, fResourceTypePopUp);
for (int32 i = 0; kDefaultTypes[i].type != NULL; i++) {
if (kDefaultTypes[i].size == ~(uint32)0)
fResourceTypePopUp->AddSeparatorItem();
else
fResourceTypePopUp->AddItem(
new BMenuItem(kDefaultTypes[i].type, NULL));
}
fResourceTypePopUp->ItemAt(kDefaultTypeSelected)->SetMarked(true);
fToolbarView = new BView(BRect(0, 0, 600, 51), "fToolbarView",
B_FOLLOW_LEFT_RIGHT, 0);
fToolbarView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BRect toolRect = BRect(0, 0, 23, 23).OffsetBySelf(8, 24);
fAddButton = new ImageButton(toolRect.OffsetBySelf(200, 0),
"fAddButton", BTranslationUtils::GetBitmap('PNG ', "add.png"),
new BMessage(MSG_ADD), B_FOLLOW_NONE);
fAddButton->ResizeTo(23, 23);
fRemoveButton = new ImageButton(toolRect.OffsetBySelf(30, 0),
"fRemoveButton", BTranslationUtils::GetBitmap('PNG ', "remove.png"),
new BMessage(MSG_REMOVE), B_FOLLOW_NONE);
fRemoveButton->ResizeTo(23, 23);
fRemoveButton->SetEnabled(false);
fMoveUpButton = new ImageButton(toolRect.OffsetBySelf(30, 0),
"fMoveUpButton", BTranslationUtils::GetBitmap('PNG ', "moveup.png"),
new BMessage(MSG_MOVEUP), B_FOLLOW_NONE);
fMoveUpButton->ResizeTo(23, 23);
fMoveUpButton->SetEnabled(false);
fMoveDownButton = new ImageButton(toolRect.OffsetBySelf(30, 0),
"fMoveDownButton", BTranslationUtils::GetBitmap('PNG ', "movedown.png"),
new BMessage(MSG_MOVEDOWN), B_FOLLOW_NONE);
fMoveDownButton->ResizeTo(23, 23);
fMoveDownButton->SetEnabled(false);
BRect listRect = Bounds();
listRect.SetLeftTop(BPoint(0, 52));
listRect.InsetBy(-1, -1);
fResourceList = new ResourceListView(listRect, "fResourceList",
B_FOLLOW_ALL, 0);
fResourceList->AddColumn(new BIntegerColumn("ID", 48, 1, 999,
B_ALIGN_RIGHT), 0);
fResourceList->AddColumn(new BStringColumn("Name", 156, 1, 999,
B_TRUNCATE_END, B_ALIGN_LEFT), 1);
fResourceList->AddColumn(new BStringColumn("Type", 56, 1, 999,
B_TRUNCATE_END, B_ALIGN_CENTER), 2);
fResourceList->AddColumn(new BStringColumn("Code", 56, 1, 999,
B_TRUNCATE_END, B_ALIGN_CENTER), 3);
fResourceList->AddColumn(new BStringColumn("Data", 156, 1, 999,
B_TRUNCATE_END, B_ALIGN_LEFT), 4);
fResourceList->AddColumn(new BSizeColumn("Size", 74, 1, 999,
B_ALIGN_RIGHT), 5);
fResourceList->SetLatchWidth(0);
fResourceList->SetTarget(this);
fResourceList->SetSelectionMessage(new BMessage(MSG_SELECTION));
AddChild(fMenuBar);
fMenuBar->AddItem(fFileMenu);
fFileMenu->AddItem(fNewItem);
fFileMenu->AddItem(fOpenItem);
fFileMenu->AddItem(fCloseItem);
fFileMenu->AddSeparatorItem();
fFileMenu->AddItem(fSaveItem);
fFileMenu->AddItem(fSaveAsItem);
fFileMenu->AddItem(fSaveAllItem);
fFileMenu->AddItem(fMergeWithItem);
fFileMenu->AddSeparatorItem();
fFileMenu->AddItem(fQuitItem);
fMenuBar->AddItem(fEditMenu);
fEditMenu->AddItem(fUndoItem);
fEditMenu->AddItem(fRedoItem);
fEditMenu->AddSeparatorItem();
fEditMenu->AddItem(fCutItem);
fEditMenu->AddItem(fCopyItem);
fEditMenu->AddItem(fPasteItem);
fEditMenu->AddItem(fClearItem);
fEditMenu->AddSeparatorItem();
fEditMenu->AddItem(fSelectAllItem);
fMenuBar->AddItem(fHelpMenu);
fToolbarView->AddChild(fResourceIDText);
fToolbarView->AddChild(fResourceTypeMenu);
fToolbarView->AddChild(fAddButton);
fToolbarView->AddChild(fRemoveButton);
fToolbarView->AddChild(fMoveUpButton);
fToolbarView->AddChild(fMoveDownButton);
AddChild(fToolbarView);
AddChild(fResourceList);
if (assocEntry != NULL) {
_SetTitleFromEntry();
_Load();
} else {
SetTitle("ResourceEdit | " B_UTF8_ELLIPSIS);
}
}
MainWindow::~MainWindow()
{
}
bool
MainWindow::QuitRequested()
{
// TODO: Check if file is saved.
BMessage* msg = new BMessage(MSG_CLOSE);
msg->AddPointer("window", (void*)this);
be_app->PostMessage(msg);
return true;
}
void
MainWindow::SelectionChanged()
{
if (fResourceList->CurrentSelection(NULL) == NULL) {
fMoveUpButton->SetEnabled(false);
fMoveDownButton->SetEnabled(false);
fRemoveButton->SetEnabled(false);
} else {
fRemoveButton->SetEnabled(true);
fMoveUpButton->SetEnabled(!fResourceList->RowAt(0)->IsSelected());
fMoveDownButton->SetEnabled(!fResourceList->RowAt(
fResourceList->CountRows() - 1)->IsSelected());
}
}
void
MainWindow::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case MSG_NEW:
be_app->PostMessage(MSG_NEW);
break;
case MSG_OPEN:
be_app->PostMessage(MSG_OPEN);
break;
case MSG_CLOSE:
PostMessage(B_QUIT_REQUESTED);
break;
case MSG_SAVE:
_Save();
break;
case MSG_SAVEAS:
_SaveAs();
break;
case MSG_SAVEAS_DONE:
{
entry_ref ref;
const char* leaf;
if (msg->FindRef("directory", &ref) != B_OK)
break;
if (msg->FindString("name", &leaf) != B_OK)
break;
BDirectory dir(&ref);
_Save(new BEntry(&dir, leaf));
break;
}
case MSG_SAVEALL:
be_app->PostMessage(MSG_SAVEALL);
break;
case MSG_MERGEWITH:
PRINT(("[MSG_MERGEWITH]: Not yet implemented."));
// TODO: Implement.
// "Merge from..." might be a better idea actually.
break;
case MSG_QUIT:
be_app->PostMessage(B_QUIT_REQUESTED);
break;
case MSG_UNDO:
// TODO: Implement.
PRINT(("[MSG_UNDO]: Not yet implemented."));
break;
case MSG_REDO:
// TODO: Implement.
PRINT(("[MSG_REDO]: Not yet implemented."));
break;
case MSG_CUT:
// TODO: Implement.
PRINT(("[MSG_CUT]: Not yet implemented."));
break;
case MSG_COPY:
// TODO: Implement.
PRINT(("[MSG_COPY]: Not yet implemented."));
break;
case MSG_PASTE:
// TODO: Implement.
PRINT(("[MSG_PASTE]: Not yet implemented."));
break;
case MSG_CLEAR:
fResourceList->Clear();
SelectionChanged();
break;
case MSG_SELECTALL:
{
for (int32 i = 0; i < fResourceList->CountRows(); i++)
fResourceList->AddToSelection(fResourceList->RowAt(i));
SelectionChanged();
break;
}
case MSG_ADD:
{
// Thank you, François Claus :D Merry Christmas!
int32 ix = fResourceTypePopUp->FindMarkedIndex();
if (ix != -1) {
ResourceRow* row = new ResourceRow();
row->SetResourceID(_NextResourceID());
row->SetResourceType(kDefaultTypes[ix].type);
row->SetResourceTypeCode(kDefaultTypes[ix].typeCode);
row->SetResourceRawData(kDefaultData);
row->SetResourceSize(kDefaultTypes[ix].size);
fResourceList->AddRow(row);
}
break;
}
case MSG_REMOVE:
{
for (int i = 0; i < fResourceList->CountRows(); i++) {
BRow* row = fResourceList->RowAt(i);
if (row->IsSelected()) {
fResourceList->RemoveRow(row);
i--;
}
}
break;
}
case MSG_MOVEUP:
{
for (int i = 1; i < fResourceList->CountRows(); i++) {
BRow* row = fResourceList->RowAt(i);
if (row->IsSelected())
fResourceList->SwapRows(i, i - 1);
}
fResourceList->ClearSortColumns();
SelectionChanged();
break;
}
case MSG_MOVEDOWN:
{
for (int i = fResourceList->CountRows() - 1 - 1; i >= 0; i--) {
BRow* row = fResourceList->RowAt(i);
if (row->IsSelected())
fResourceList->SwapRows(i, i + 1);
}
fResourceList->ClearSortColumns();
SelectionChanged();
break;
}
case MSG_SELECTION:
SelectionChanged();
break;
default:
BWindow::MessageReceived(msg);
}
}
void
MainWindow::_SetTitleFromEntry()
{
char nameBuffer[B_FILE_NAME_LENGTH];
fAssocEntry->GetName(nameBuffer);
BString title;
title << "ResourceEdit | ";
title << nameBuffer;
SetTitle(title);
}
void
MainWindow::_SaveAs()
{
if (fSavePanel == NULL)
fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), NULL,
B_FILE_NODE, false, new BMessage(MSG_SAVEAS_DONE));
fSavePanel->Rewind();
fSavePanel->Show();
}
void
MainWindow::_Save(BEntry* entry)
{
if (entry == NULL) {
if (fAssocEntry == NULL) {
_SaveAs();
return;
} else
entry = fAssocEntry;
} else {
if (fAssocEntry == NULL) {
fAssocEntry = entry;
_SetTitleFromEntry();
}
}
/*BPath path;
entry->GetPath(&path);
// I wouldn't use std:: if BFile had cooler stuff.
// Not very comfortable here.
fstream out(path.Path(), ios::out);
time_t timeNow = time(0);
out << "/-" << endl;
out << " - This file is auto-generated by Haiku ResourceEdit." << endl;
out << " - Time: " << ctime((const time_t*)&timeNow);
out << " -\" << endl;
for (int32 i = 0; i < fResourceList->CountRows(); i++) {
ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
out << endl;
out << "resource";
if (true) {
// TODO: Implement no-ID cases.
out << "(" << row->ResourceID();
if (row->ResourceName()[0] != '\0') {
out << ", \"" << row->ResourceName() << "\"" << endl;
}
out << ") ";
}
if (row->ResourceTypeCode()[0] != '\0')
out << "#\'" << row->ResourceTypeCode() << "\' ";
if (strcmp(row->ResourceType(), "raw") != 0)
out << row->ResourceType() << ' ' << row->ResourceData();
else {
// TODO: Implement hexdump and import.
out << "array {" << endl;
out << "\t\"Not yet implemented.\"" << endl;
out << "}";
}
out << endl;
}
out.close();*/
// Commented out whole output section. Switching to .rsrc files to
// close Part 1 of GCI task.
// TODO: Implement exporting to .rdef and/or other formats.
BFile* file = new BFile(entry, B_READ_WRITE | B_CREATE_FILE);
BResources output(file, true);
delete file;
for (int32 i = 0; i < fResourceList->CountRows(); i++) {
ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
output.AddResource(row->ResourceTypeCode(), row->ResourceID(),
row->ResourceRawData(), row->ResourceSize(), row->ResourceName());
}
output.Sync();
}
void
MainWindow::_Load()
{
/*BPath path;
struct stat st;
fAssocEntry->GetPath(&path);
fAssocEntry->GetStat(&st);
int fd = open(path.Path(), 0);
const char* in = (const char*)mmap(NULL, st.st_size, PROT_READ,
MAP_SHARED, fd, 0);
// TODO: Fix stucking bug.
// TODO: Parse data.
for (int32 i = 0; i < st.st_size - 1; i++) {
//...
}*/
// Commented out input section. Same reason as above.
// TODO: Implement importing from .rdef and/or other formats.
BFile* file = new BFile(fAssocEntry, B_READ_ONLY);
BResources input(file);
delete file;
type_code code;
int32 id;
const char* name;
size_t size;
for (int32 i = 0; input.GetResourceInfo(i, &code, &id, &name, &size); i++) {
ResourceRow* row = new ResourceRow();
row->SetResourceID(id);
row->SetResourceName(name);
row->SetResourceSize(size);
row->SetResourceTypeCode(code);
row->SetResourceRawData(input.LoadResource(code, id, &size));
fResourceList->AddRow(row);
}
}
int32
MainWindow::_NextResourceID()
{
int32 currentID = atoi(fResourceIDText->Text());
int32 nextID = currentID + 1;
BString text;
// Should I check if the ID is already present in the list?
// Hmmm...
text << nextID;
fResourceIDText->SetText(text);
return currentID;
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include <Window.h>
class ImageButton;
class BColumnListView;
class BEntry;
class BFilePanel;
class BMenu;
class BMenuBar;
class BMenuField;
class BMenuItem;
class BMessage;
class BPopUpMenu;
class BTextControl;
class MainWindow : public BWindow {
public:
MainWindow(BRect frame, BEntry* entry);
~MainWindow();
bool QuitRequested();
void MessageReceived(BMessage* msg);
void SelectionChanged();
private:
BEntry* fAssocEntry;
BMenuBar* fMenuBar;
BMenu* fFileMenu;
BMenuItem* fNewItem;
BMenuItem* fOpenItem;
BMenuItem* fCloseItem;
BMenuItem* fSaveItem;
BMenuItem* fSaveAsItem;
BMenuItem* fSaveAllItem;
BMenuItem* fMergeWithItem;
BMenuItem* fQuitItem;
BMenu* fEditMenu;
BMenuItem* fUndoItem;
BMenuItem* fRedoItem;
BMenuItem* fCutItem;
BMenuItem* fCopyItem;
BMenuItem* fPasteItem;
BMenuItem* fClearItem;
BMenuItem* fSelectAllItem;
BMenu* fHelpMenu;
BTextControl* fResourceIDText;
BPopUpMenu* fResourceTypePopUp;
BMenuField* fResourceTypeMenu;
BView* fToolbarView;
ImageButton* fAddButton;
ImageButton* fRemoveButton;
ImageButton* fMoveUpButton;
ImageButton* fMoveDownButton;
BColumnListView* fResourceList;
BFilePanel* fSavePanel;
void _SetTitleFromEntry();
void _SaveAs();
void _Save(BEntry* entry = NULL);
void _Load();
int32 _NextResourceID();
};
#endif

View File

@ -0,0 +1,121 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ResourceEdit.h"
#include "AboutWindow.h"
#include "Constants.h"
#include "MainWindow.h"
#include <Entry.h>
#include <FilePanel.h>
ResourceEdit::ResourceEdit()
:
BApplication("application/x-vnd.Haiku-ResourceEdit")
{
fCascade = BRect(100, 100, 700, 400);
fCascadeCount = 0;
fOpenPanel = new BFilePanel(B_OPEN_PANEL, &be_app_messenger, NULL, 0, true,
new BMessage(MSG_OPEN_DONE));
}
ResourceEdit::~ResourceEdit()
{
}
void
ResourceEdit::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case MSG_NEW:
_CreateWindow(NULL);
break;
case MSG_OPEN:
fOpenPanel->Show();
break;
case MSG_OPEN_DONE:
{
entry_ref ref;
while (fOpenPanel->GetNextSelectedRef(&ref) == B_OK)
_CreateWindow(new BEntry(&ref));
fOpenPanel->Rewind();
break;
}
case MSG_CLOSE:
{
MainWindow* window;
msg->FindPointer("window", (void**)&window);
fWindowList.RemoveItem(window);
if (fWindowList.CountItems() == 0)
Quit();
break;
}
case MSG_SAVEALL:
{
for (int32 i = 0; i < fWindowList.CountItems(); i++)
((MainWindow*)fWindowList.ItemAt(i))->PostMessage(MSG_SAVE);
break;
}
default:
BApplication::MessageReceived(msg);
}
}
void
ResourceEdit::ArgvReceived(int32 argc, char* argv[])
{
for (int32 i = 1; i < argc; i++)
_CreateWindow(new BEntry(argv[i]));
}
void
ResourceEdit::ReadyToRun()
{
if (fWindowList.CountItems() <= 0)
_CreateWindow(NULL);
}
void
ResourceEdit::_CreateWindow(BEntry* assocEntry)
{
MainWindow* window = new MainWindow(_Cascade(), assocEntry);
fWindowList.AddItem(window);
window->Show();
}
BRect
ResourceEdit::_Cascade()
{
if (fCascadeCount == 8) {
fCascade.OffsetBy(-20 * 8, -20 * 8);
fCascadeCount = 0;
} else {
fCascade.OffsetBy(20, 20);
fCascadeCount++;
}
return fCascade;
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef RESOURCE_EDIT_H
#define RESOURCE_EDIT_H
#include <Application.h>
class MainWindow;
class BEntry;
class BFilePanel;
class BMessage;
class ResourceEdit : public BApplication {
public:
ResourceEdit();
~ResourceEdit();
void MessageReceived(BMessage* msg);
private:
BRect fCascade;
uint32 fCascadeCount;
BList fWindowList;
BFilePanel* fOpenPanel;
void ArgvReceived(int32 argc, char* argv[]);
void ReadyToRun();
void _CreateWindow(BEntry* assocEntry);
BRect _Cascade();
};
#endif

View File

@ -0,0 +1,136 @@
resource app_signature "application/x-vnd.Haiku-ResourceEdit";
resource app_name_catalog_entry "x-vnd.Haiku-ResourceEdit:System name:ResourceEdit";
resource app_version {
major = 0,
middle = 1,
minor = 0,
variety = B_APPV_ALPHA,
internal = 0,
short_info = "ResourceEdit",
long_info = "ResourceEdit © 2012-2013 Haiku, Inc."
};
resource app_flags B_SINGLE_LAUNCH;
resource(1, "BEOS:FILE_TYPES") message {
"types" = "text/x-vnd.Be.ResourceDef"
};
resource vector_icon {
$"6E6369660E050102000603399E0F3D9C0ABF82B23B84A94B88504870C900A5FF"
$"F5BCEAFFF2FFB3FFE3020106023E49240000000000003CAAAA4940004A3000FF"
$"C0FFDD7C6DFFBC040192020006023A4BAE3411A9B629883C6629495368484715"
$"00FFF9BAFFFFC104020006023A6A0E3670BCB6D8C13AD0F64A21BC4A0DF300BA"
$"DCFFFF2A20F10200060239AAD5343BA5B6E7993C629D4ABB354803A500E99797"
$"FFCE323202000602AAB1FB3A081FBE8A26AF5E794C4014448D43FFFDDCAB00DB"
$"AB5F02000602B507E13A82E2BAD599B56BB44A7652479FE400116201FE69A403"
$"020006023C08200000000000004000004A4000000000FD6AD839004AB9270200"
$"06023D4D340000000000004000004A5000000000009CFA80FFF8FAFF02000603"
$"B2F679BA14D43A7FB6B38E9E460F5547105A00FFEED58DDBAB5FCFFFEED50401"
$"95020012023B8E380000000000004000004A5400C100000001FFFF0199120606"
$"AE0BB40BBF4D33C3AFB75DC173BDEFC607C13EC804CA28BD82C118B920C51BBB"
$"40BF07B8083AB6BC0605AE02B57D3EB9B9C3EFB7BB44BBB751BD75C936CA8EC1"
$"B1402F0A093B593D5BBFCDC93E455BC516C5F160465B435D4544510A045A425E"
$"3F5A3D57400A063236323D3A41403E403739330A063A433A4A404D464A464341"
$"400A064237423E48424E3F4E3948350604EE532755295528552A532B5229522A"
$"52280604EE532456295625562D532E5029502D50250A04B969B771332E502E4E"
$"2B0A04B969B5BAB969B7714E2B4E270A043324B969B5BA4E2750240A063124B8"
$"BAB5B2B8BAB779312EB677B6ECB67CB63C0606B20831245356295625562D532E"
$"3126290804BA28B4D33027302BBA28B8580003C6E8B4D3C6E8B4D3C690B51750"
$"2950B59E50B78DC6E8B858C690B814C6E8B8580A04C6F0C5C24E4F514BC9BBC4"
$"280A06C4E04F41C507374B394A45C33CC6D1C36F120A030202032020250A0001"
$"0130202501178400040A0201012020250A00010030202501178400040A010100"
$"2020250A000304050630202501178400040A0401042020250A0501052020250A"
$"0601062020250A0C0110000A0D0111000A00030D0E0F123ED413BED4133ED413"
$"3ED41347F4A24A588901178400040A0B010C023ED413BED4133ED4133ED41347"
$"F4A24A58890A0A010B023ED413BED4133ED4133ED41347F4A24A58890A09010A"
$"023ED413BED4133ED4133ED41347F4A24A58890A080109023ED413BED4133ED4"
$"133ED41347F4A24A58890A070108023ED413BED4133ED4133ED41347F4A24A58"
$"890A0001070A3ED413BED4133ED4133ED41347F4A24A588915FF"
};
resource(1, "add.png") #'PNG ' array {
$"89504E470D0A1A0A0000000D4948445200000018000000180806000000E0773D"
$"F80000017B494441544889ED95B14EC25014863F6AAB4864C40768D84C184908"
$"3E002B899B71742171C7677024716572C207707124260C0E460709A94C86844D"
$"144BEF6D716841CA2D5083C6857FBB7FFE73BF7B4F7B5AD8E8BF9588952A5231"
$"0B660D1D0D008967DD59559A5CAC2AD56301D2E473A739CDD8330010EF42B31E"
$"AD32D000BAEB03005BDA48210190524EEC9D5575B1011FCE07C676700347C42D"
$"8B0F1042E0391E00AE70D70014A990261FF2521C0EE5105DF8712925A4C852A2"
$"0EB4A7B9012D9A5CCE96AA6FD119AE79646AF3B6B16B7CA7C7203ED53659D796"
$"478D1CF0B4F8060934477714DB11735E54731368C0FE72C018466214511D4363"
$"D5520112AFFFD6575A4492508BB02300126F35E0812A2F94435E8A2CC7644806"
$"6B1BB8A2CF904E2837A00B61880AF0C7BFC1EC1095A8E3929996BAC0900E379C"
$"03BDB91D5E97037C75E7D66DA01091EB01CF0BF60040EDF52FEBCF01F13E1503"
$"5ADC72C2567020172F78A02B15EF7FE0EB007F8826F2807B60F0833D3652F505"
$"AA6A764F51A11AA20000000049454E44AE426082"
};
resource(2, "remove.png") #'PNG ' array {
$"89504E470D0A1A0A0000000D4948445200000018000000180806000000E0773D"
$"F800000275494441544889ED94C14B93611CC73F7B7D6DF80EDA72BEAFCE2D82"
$"57F022099AE065902884791C41052BD7FE804DA48378AF4E49978E199845273D"
$"CC90C0759B78085C66186387053A9C4B3417CB4DD6D3C136F5F5DDC04E1DFCC2"
$"0F5E9EDFFB7EBEBFEFFB3CEF0BE7FA6FA5C3C551557D1780A78064728B148027"
$"A3AAFA5E07C799E1E31ECFC7642824627EBF08C282C1440AC2B398DF2F92A190"
$"18F778523A38CD587566F03BAAFA617868E85A8BA2D06CB3E172B974CBDA9A77"
$"19A6014B10261EF87CE14EB71B9B24D1E6763B4AEBEBB737F2F9573BF0ABA6C1"
$"B0AACE04FBFBAF373734208A4544B188A628B8344D9792496F17740D0F0E86AF"
$"B6B454FA3649A2ADB5D5F1736BEBE6523EFF02289579B2D160379BFDBA99C90C"
$"A986F50EBB9D7B7D7D03C04087DD4E696FEF447F339361379BDD00BA81A5AA09"
$"E2B050974A793545D1554942140A9552651955964FAC894281CFE934D38B8BD1"
$"97F01A5804F6AB1A006219A6E574DAAB59AD7A932C230E0EAAD66A26C39B783C"
$"3A09534004D8A9B907C74DEAB359AF2ACB7A9310A7A61685025FB6B7799B4854"
$"8583C91E18B42A72B9815295A6C8E5CA977366F05A09A4204CDC8270BBCD5639"
$"2DC67202CDF9BC6E859EBF47581841966A701F84DB6BA7AB2801CC4074126E00"
$"BF6B2608C0631F3C348327806D4E7FB24E4003DD0ABDF1C3937434AD11E280EE"
$"C62AF05988CE423461D26F3C7CD60D74D64CB00573F570F7323814037C12A696"
$"E15103F468A097937C0722F06D069EEFC027E087C90C47D2C13906A918880894"
$"7F76F7814BE5E44158888088811883940E21A0AD26D86832022B019837C0CB92"
$"02303F022B67861FD305A0D7045E9685C3777EE55FE0E702E00F037E0BAE5DFC"
$"3C830000000049454E44AE426082"
};
resource(3, "moveup.png") #'PNG ' array {
$"89504E470D0A1A0A0000000D4948445200000018000000180806000000E0773D"
$"F8000001C8494441544889ED933B485B6118861F93D8788F510E27DAE00D259D"
$"0485823108723843296E22850E0EBA140AA543C4A18A9442A920EA62068582E2"
$"E0AA83E2050415A18B882028ED927AE8693C31510721A8F93B5841E9C9498A2E"
$"822FBCC3CFF7F3BCDFF75FE0510F465EC81E57F93AAE32ED85EC7B854B609F50"
$"98D4D755A1AFAB6242615302C77DC16D2185316D392044AC4D88589BD0960222"
$"A4B02A81FDCEF0D116BE84E7EA8530945B0ECFD58B911616D2312C3B1808F0A1"
$"FD9DAFBFB2D90DE2F2965D4F9DC8725E6D997ED4B072C0CC7F077C6AE27DC79B"
$"9AC19AD6221017A676573CC1539CFB4CFA1DAF5CD598CD38A0EF39DDAFBBA550"
$"9D5A00E2DCD22555763C85B686E2C8996BED178B6903828DBCEAEC94A67C2F9C"
$"64610DBF7669B5038FD3E9CF3B3C4B6EEAACDDE4FDF3D4FCE5F4D8EC063F96AE"
$"D6451512B2CFFC1823FB70FAD3B8EAD401FE72BAD8620A08A70CF8F80DD5BB4D"
$"179053E6C2DDFBD608CAB5E601A761181C63483F210EA02530807CCB09760C8E"
$"776018E025549324C8A5790049D04F88CF6B7C4EB12383DF28FE3A552D8D6CE9"
$"B7DC4D0F3FC0F20EB404D1EF1B44627BC866F5A328112D41D48A919541138540"
$"23A9A73D047633E03CCA5C7F00288AC08FE23A7EB30000000049454E44AE4260"
$"82"
};
resource(4, "movedown.png") #'PNG ' array {
$"89504E470D0A1A0A0000000D4948445200000018000000180806000000E0773D"
$"F8000001E6494441544889ED92DD4B53611CC73F6ED5BC680D978F6B792AC45C"
$"E164577A9710E7A6B0BAEAAE0B41F09F08BAEAC66E4421F042AF6A228A2F28BA"
$"A42226859B48DD0C247A811C8E1DE2D0081793A9674F174B523BCF966F78515F"
$"F8C173CEF7F7FB7E785EE0BF8E5B15A5CC90C0DD7543BC3DEB7707ECFC6F46D6"
$"B8FFDC6C4A98645419274A013417D50D37EB030D772ED8FA9FA657FCDA9CD991"
$"80EE7D010028AC83B5A6F6C0556AFC2F0079B0726AAF8CCA03E426588A20B979"
$"08006B437D44D6C6DE0121C169CD8500F07BD09059B04EDA4FCB2C7E0F556D50"
$"0790CA63264C7E6C6FF9E3998EDF6631D8265A1CCEE2F7994BE0BB627F8F5F3F"
$"E4594D16D7050B969E99CB7767080159E50EE2691E5FCD9B4F03B704158E5F3F"
$"1577E0BB5C2C5980F71193789A97401058D8EA71EE1E8A1924BC192A6BDDB96B"
$"D5753990E5EBE38B1C4383841FBD631A7803584A00C0EB34AF6A329CABF5D0EC"
$"BD0848757D9E83E130230F17990422C08EEDDA0200A22922DA771ACF0B82559A"
$"7DCF9705187BC2D48338A3C00CA0786E0A0970F4B6329B0C23E5D2CE4A86913D"
$"ADCC02F700F79E827743FA74A2A991DFE1A96164DF75A202DA01CFBEC3B7419C"
$"033A316302698C23077462023A00EF81C3B7A4C1A97E9DF97E9D790D3A8BDCC3"
$"970368067C4711FE8FEA273678C1FAFB9AC8FD0000000049454E44AE426082"
};

View File

@ -0,0 +1,52 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ResourceListView.h"
#include "Constants.h"
#include <ColumnListView.h>
#include <Entry.h>
ResourceListView::ResourceListView(BRect rect, const char* name,
uint32 resizingMode, uint32 drawFlags, border_style border,
bool showHorizontalScrollbar)
:
BColumnListView(rect, name, resizingMode, drawFlags, border,
showHorizontalScrollbar)
{
}
ResourceListView::~ResourceListView()
{
}
void
ResourceListView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_SIMPLE_DATA: {
entry_ref ref;
int32 n = 0;
// TODO: Implement D&D adding of files.
while (msg->FindRef("refs", n++, &ref) == B_OK) {
PRINT(("%s\n", ref.name));
// ...
}
break;
}
default:
BColumnListView::MessageReceived(msg);
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef RESOURCE_LIST_VIEW_H
#define RESOURCE_LIST_VIEW_H
#include <ColumnListView.h>
class ResourceListView : public BColumnListView {
public:
ResourceListView(BRect rect, const char* name, uint32 resizingMode,
uint32 drawFlags, border_style border = B_NO_BORDER,
bool showHorizontalScrollbar = true);
~ResourceListView();
void MessageReceived(BMessage* msg);
private:
};
#endif

View File

@ -0,0 +1,141 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ResourceRow.h"
#include <ColumnListView.h>
#include <ColumnTypes.h>
ResourceRow::ResourceRow()
:
BRow()
{
fRawData = NULL;
SetField(new BIntegerField(0), 0);
SetField(new BStringField(""), 1);
SetField(new BStringField(""), 2);
SetField(new BStringField(""), 3);
SetField(new BStringField(""), 4);
SetField(new BSizeField(0), 5);
}
ResourceRow::~ResourceRow()
{
// ...
}
void
ResourceRow::SetResourceID(int32 id)
{
((BIntegerField*)GetField(0))->SetValue(id);
}
void
ResourceRow::SetResourceName(const char* name)
{
((BStringField*)GetField(1))->SetString(name);
}
void
ResourceRow::SetResourceType(const char* type)
{
((BStringField*)GetField(2))->SetString(type);
}
void
ResourceRow::SetResourceTypeCode(type_code code)
{
fTypeCode = code;
TypeCodeToString(code, fTypeString);
((BStringField*)GetField(3))->SetString(fTypeString);
}
void
ResourceRow::SetResourceData(const char* data)
{
((BStringField*)GetField(4))->SetString(data);
}
void
ResourceRow::SetResourceRawData(const void* data)
{
if (data == NULL)
data = kDefaultData;
fRawData = data;
int32 ix = FindTypeCodeIndex(ResourceTypeCode());
if (ix == -1)
SetResourceData("[Unknown Data]");
else
SetResourceData(kDefaultTypes[ix].toString(fRawData));
}
void
ResourceRow::SetResourceSize(off_t size)
{
((BSizeField*)GetField(5))->SetSize(size);
}
int32
ResourceRow::ResourceID()
{
return ((BIntegerField*)GetField(0))->Value();
}
const char*
ResourceRow::ResourceName()
{
return ((BStringField*)GetField(1))->String();
}
const char*
ResourceRow::ResourceType()
{
return ((BStringField*)GetField(2))->String();
}
type_code
ResourceRow::ResourceTypeCode()
{
return fTypeCode;
}
const char*
ResourceRow::ResourceData()
{
return ((BStringField*)GetField(4))->String();
}
const void*
ResourceRow::ResourceRawData()
{
return fRawData;
}
off_t
ResourceRow::ResourceSize()
{
return ((BSizeField*)GetField(5))->Size();
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef RESOURCE_ROW_H
#define RESOURCE_ROW_H
#include "DefaultTypes.h"
#include <ColumnListView.h>
class ResourceRow : public BRow {
public:
ResourceRow();
~ResourceRow();
void SetResourceID(int32 id);
void SetResourceName(const char* name);
void SetResourceType(const char* type);
void SetResourceTypeCode(type_code code);
void SetResourceData(const char* data);
void SetResourceRawData(const void*);
void SetResourceSize(off_t size);
int32 ResourceID();
const char* ResourceName();
const char* ResourceType();
type_code ResourceTypeCode();
const char* ResourceData();
const void* ResourceRawData();
off_t ResourceSize();
private:
const void* fRawData;
type_code fTypeCode;
char fTypeString[8];
};
#endif

View File

@ -0,0 +1,17 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ResourceEdit.h"
int
main()
{
ResourceEdit* app = new ResourceEdit();
app->Run();
delete app;
return 0;
}

View File

@ -523,6 +523,13 @@ BRow::IsExpanded() const
}
bool
BRow::IsSelected() const
{
return fPrevSelected != NULL;
}
void
BRow::ValidateFields() const
{
@ -1258,6 +1265,60 @@ BColumnListView::UpdateRow(BRow* row)
}
bool
BColumnListView::SwapRows(int32 index1, int32 index2, BRow* parentRow1,
BRow* parentRow2)
{
BRow* row1 = NULL;
BRow* row2 = NULL;
BRowContainer* container1 = NULL;
BRowContainer* container2 = NULL;
if (parentRow1 == NULL)
container1 = fOutlineView->RowList();
else
container1 = parentRow1->fChildList;
if (container1 == NULL)
return false;
if (parentRow2 == NULL)
container2 = fOutlineView->RowList();
else
container2 = parentRow1->fChildList;
if (container2 == NULL)
return false;
row1 = container1->ItemAt(index1);
if (row1 == NULL)
return false;
row2 = container2->ItemAt(index2);
if (row2 == NULL)
return false;
container1->ReplaceItem(index2, row1);
container2->ReplaceItem(index1, row2);
BRect rect1;
BRect rect2;
BRect rect;
fOutlineView->FindRect(row1, &rect1);
fOutlineView->FindRect(row2, &rect2);
rect = rect1 | rect2;
fOutlineView->Invalidate(rect);
return true;
}
void
BColumnListView::ScrollTo(const BRow* row)
{
@ -4195,7 +4256,7 @@ OutlineView::AddRow(BRow* row, int32 Index, BRow* parentRow)
row->fParent = parentRow;
if (fMasterView->SortingEnabled()) {
if (fMasterView->SortingEnabled() && !fSortColumns->IsEmpty()) {
// Ignore index here.
if (parentRow) {
if (parentRow->fChildList == NULL)

View File

@ -1107,6 +1107,7 @@ BMenu::FindMarked()
{
for (int32 i = 0; i < fItems.CountItems(); i++) {
BMenuItem* item = ItemAt(i);
if (item->IsMarked())
return item;
}
@ -1115,6 +1116,20 @@ BMenu::FindMarked()
}
int32
BMenu::FindMarkedIndex()
{
for (int32 i = 0; i < fItems.CountItems(); i++) {
BMenuItem* item = ItemAt(i);
if (item->IsMarked())
return i;
}
return -1;
}
BMenu*
BMenu::Supermenu() const
{