Implemented the document handling foundation for DiskProbe.

Does not yet maintain the window position on disk (nor any other settings).


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6549 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-02-10 04:17:16 +00:00
parent c5cd141413
commit 92ad515183
9 changed files with 594 additions and 7 deletions

View File

@ -25,7 +25,7 @@ class ReplaceChange : public DataChange {
virtual void Apply(off_t offset, uint8 *buffer, size_t size);
virtual void Revert(off_t offset, uint8 *buffer, size_t size);
private:
void Normalize(off_t bufferOffset, size_t bufferSize,
off_t &offset, size_t &dataOffset, size_t &size);

View File

@ -4,10 +4,19 @@
*/
#include "DiskProbe.h"
#include "DataEditor.h"
#include "ProbeWindow.h"
#include "OpenWindow.h"
#include <Application.h>
#include <Autolock.h>
#include <Alert.h>
#include <TextView.h>
#include <FilePanel.h>
#include <Directory.h>
#include <Entry.h>
#include <Path.h>
#include <stdio.h>
#include <string.h>
@ -19,7 +28,24 @@ static const char *kSignature = "application/x-vnd.OpenBeOS-DiskProbe";
class DiskProbe : public BApplication {
public:
DiskProbe();
~DiskProbe();
virtual ~DiskProbe();
virtual void ReadyToRun();
virtual void RefsReceived(BMessage *message);
virtual void ArgvReceived(int32 argc, char **argv);
virtual void MessageReceived(BMessage *message);
virtual void AboutRequested();
virtual bool QuitRequested();
private:
status_t Probe(entry_ref &ref);
BFilePanel *fFilePanel;
BWindow *fOpenWindow;
uint32 fWindowCount;
BRect fWindowPosition;
};
@ -85,8 +111,16 @@ printBlock(DataEditor &editor, const char *text)
DiskProbe::DiskProbe()
: BApplication(kSignature)
: BApplication(kSignature),
fOpenWindow(NULL),
fWindowCount(0),
fWindowPosition(30, 30, 500, 500)
{
fFilePanel = new BFilePanel();
// ToDo: maintain the window position on disk
/*
DataEditor editor;
status_t status = editor.SetTo("/boot/beos/apps/DiskProbe");
if (status < B_OK) {
@ -153,13 +187,174 @@ DiskProbe::DiskProbe()
fprintf(stderr, "Could not undo: %s\n", strerror(status));
if (printBlock(editor, "undo (location 700):") < B_OK)
return;
PostMessage(B_QUIT_REQUESTED);
*/
}
DiskProbe::~DiskProbe()
{
delete fFilePanel;
}
void
DiskProbe::ReadyToRun()
{
// are there already windows open?
if (CountWindows() != 1)
return;
// if not, ask the user to open a file
PostMessage(kMsgOpenOpenWindow);
}
/** Opens a window containing the file pointed to by the entry_ref.
* This function will fail if that file doesn't exist or could not
* be opened.
* It will check if there already is a window that probes the
* file in question and will activate it in that case.
* This function must be called with the application looper locked.
*/
status_t
DiskProbe::Probe(entry_ref &ref)
{
// Do we already have that window open?
for (int32 i = CountWindows(); i-- > 0; ) {
ProbeWindow *window = dynamic_cast<ProbeWindow *>(WindowAt(i));
if (window == NULL)
continue;
if (window->EntryRef() == ref) {
window->Activate(true);
return B_OK;
}
}
// Does the file really exists?
BFile file;
status_t status = file.SetTo(&ref, B_READ_ONLY);
if (status < B_OK)
return status;
// cascade window
BRect rect = fWindowPosition;
rect.OffsetBy(fWindowCount * 15, fWindowCount * 15);
BWindow *window = new ProbeWindow(rect, &ref);
window->Show();
fWindowCount++;
return B_OK;
}
void
DiskProbe::RefsReceived(BMessage *message)
{
int32 index = 0;
entry_ref ref;
while (message->FindRef("refs", index++, &ref) == B_OK) {
Probe(ref);
}
}
void
DiskProbe::ArgvReceived(int32 argc, char **argv)
{
BMessage *message = Looper()->CurrentMessage();
BDirectory currentDirectory;
if (message)
currentDirectory.SetTo(message->FindString("cwd"));
for (int i = 1 ; i < argc ; i++) {
BPath path;
if (argv[i][0] == '/')
path.SetTo(argv[i]);
else
path.SetTo(&currentDirectory, argv[i]);
BEntry entry(path.Path());
entry_ref ref;
status_t status;
if ((status = entry.InitCheck()) != B_OK
|| (status = entry.GetRef(&ref)) != B_OK
|| (status = Probe(ref)) != B_OK) {
char buffer[512];
snprintf(buffer, sizeof(buffer), "Could not open file \"%s\": %s",
argv[i], strerror(status));
(new BAlert("DiskProbe", buffer, "Ok", NULL, NULL,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go();
continue;
}
}
}
void
DiskProbe::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgOpenOpenWindow:
if (fOpenWindow == NULL) {
fOpenWindow = new OpenWindow();
fOpenWindow->Show();
fWindowCount++;
} else
fOpenWindow->Activate(true);
break;
case kMsgOpenWindowClosed:
fOpenWindow = NULL;
// supposed to fall through
case kMsgWindowClosed:
if (--fWindowCount == 0 && !fFilePanel->IsShowing())
PostMessage(B_QUIT_REQUESTED);
break;
case kMsgOpenFilePanel:
fFilePanel->Show();
break;
case B_CANCEL:
if (fWindowCount == 0)
PostMessage(B_QUIT_REQUESTED);
break;
default:
BApplication::MessageReceived(message);
break;
}
}
void
DiskProbe::AboutRequested()
{
BAlert *alert = new BAlert("about", "DiskProbe\n"
"\twritten by Axel Dörfler\n"
"\tCopyright 2004, OpenBeOS.\n\n\n"
"original Be version by Robert Polic\n\n", "Ok");
BTextView *view = alert->TextView();
BFont font;
view->SetStylable(true);
view->GetFont(&font);
font.SetSize(24);
font.SetFace(B_BOLD_FACE);
view->SetFontAndColor(0, 9, &font);
alert->Go();
}
bool
DiskProbe::QuitRequested()
{
return true;
}

View File

@ -0,0 +1,17 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef DISK_PROBE_H
#define DISK_PROBE_H
#include <SupportDefs.h>
static const uint32 kMsgOpenFilePanel = 'opFp';
static const uint32 kMsgOpenOpenWindow = 'opOw';
static const uint32 kMsgOpenWindowClosed = 'clOw';
static const uint32 kMsgWindowClosed = 'WiCl';
#endif /* DISK_PROBE_H */

View File

@ -0,0 +1,81 @@
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.OpenBeOS-DiskProbe";
resource(1, "BEOS:FILE_TYPES") message
{
"types" = "application/octet-stream"
};
resource app_version
{
major = 1,
middle = 0,
minor = 0,
/* 0 = development 1 = alpha 2 = beta
3 = gamma 4 = golden master 5 = final */
variety = 0,
internal = 1,
short_info = "DiskProbe",
long_info = "DiskProbe 1.0.0 ©2004 OpenBeOS"
};
resource(101, "BEOS:L:STD_ICON") #'ICON' array
{
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFF001C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFF001B1818180000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFF001B1818181818180000FFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFF001B1818181818181818180000FFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFF001C1818181818181818181818180000FFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFF001C1818181818181818181818181818180000FFFFFFFFFFFFFF"
$"FFFFFFFFFF001B1818181818181818181818181818181818180000FFFFFFFFFF"
$"FFFFFFFF001C1818181818181818181818181818181818181818180000FFFFFF"
$"FFFFFF001C181818181818181818181818181818181818181818183F0E00FFFF"
$"FFFF001B181818181818181818181818181818181818181818183F0F0F00FFFF"
$"FF001C181818181818181818181818181818181818181818183F0F0F0F00FFFF"
$"000E181818181818181818181818181818181818181818183F0F0F0F0F00FFFF"
$"003F3F18181818181818181818181818181818181818183F0F0F0F0F0F00FFFF"
$"0017173F3F18181818181818181818181818181818183F0F0F0F0F0F0F000FFF"
$"00171718173F3F18181818181818181818181818183F0F0F0F0F0F0F000E0EFF"
$"001717181717183F3F18181818181818181818183F0F0F0F0F0F0F000F0F0FFF"
$"0018170000181717183F3F18181818181818183F0F0F0F0F0F0F000F0F0FFFFF"
$"00181739340000171718173F3F18181818183F0F0F0F0F0F0F000F0F0FFFFFFF"
$"00171835342B2C1718171718173F3F18183F0F0F0F0F0F0F000F0F0FFFFFFFFF"
$"FF00001717181717181718171718173F3F0F0F0F0F0F0F000F0F0FFFFFFFFFFF"
$"FFFFFF0000171718171718171817171C170F0F0F0F0F000F0F0FFFFFFFFFFFFF"
$"FFFFFFFFFF000017171817171817181B180E0F0F0F000F0F0FFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFF00001717181717181B180F0F0E000F0F0FFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFF0000171718171C170F0F000F0F0EFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFF000017171C170F000F0F0FFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFF00001B18000E0F0FFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000E0F0FFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
};
resource(101, "BEOS:M:STD_ICON") #'MICN' array
{
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
$"FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF"
$"FFFFFFFFFF000E180000FFFFFFFFFFFF"
$"FFFFFFFF000E181818180000FFFFFFFF"
$"FFFFFF000E181818181818180000FFFF"
$"FFFF000E181818181818181818180000"
$"FF000E18181818181818181818183F00"
$"000F18181818181818181818183F0F00"
$"003F3F1818181818181818183F0F0F00"
$"0018003F3F1818181818183F0F0F000F"
$"00183900173F3F1818183F0F0F000F0F"
$"FF0000171718173F183F0F0F000F0FFF"
$"FFFFFF00001717183F0F0F000F0FFFFF"
$"FFFFFFFFFF0000171C0E000F0FFFFFFF"
$"FFFFFFFFFFFFFF0000000E0FFFFFFFFF"
};
resource(1, "BEOS:APP_FLAGS") #'APPF' $"00000000";

View File

@ -2,11 +2,13 @@ SubDir OBOS_TOP src apps diskprobe ;
UsePrivateHeaders shared ;
# AddResources DiskProbe : DiskProbe.rsrc ;
AddResources DiskProbe : DiskProbe.rdef ;
App DiskProbe :
DiskProbe.cpp
DataEditor.cpp
ProbeWindow.cpp
OpenWindow.cpp
;
LinkSharedOSLibs DiskProbe : be ;
LinkSharedOSLibs DiskProbe : be tracker ;

View File

@ -0,0 +1,145 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include "OpenWindow.h"
#include "DiskProbe.h"
#include <Application.h>
#include <Screen.h>
#include <MenuField.h>
#include <PopUpMenu.h>
#include <MenuItem.h>
#include <Button.h>
#include <Directory.h>
#include <Entry.h>
#include <Path.h>
static const uint32 kMsgProbeFile = 'prDv';
static const uint32 kMsgProbeDevice = 'prFl';
static const uint32 kMsgCancel = 'Canc';
OpenWindow::OpenWindow()
: BWindow(BRect(0, 0, 350, 100), "DiskProbe", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
{
BView *view = new BView(Bounds(), B_EMPTY_STRING, B_FOLLOW_ALL, B_WILL_DRAW);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(view);
fDevicesMenu = new BPopUpMenu("devices");
CollectDevices(fDevicesMenu);
if (BMenuItem *item = fDevicesMenu->ItemAt(0))
item->SetMarked(true);
BRect rect = Bounds().InsetByCopy(8, 8);
BMenuField *field = new BMenuField(rect, "devices", "Examine Device:", fDevicesMenu);
field->SetDivider(field->StringWidth(field->Label()) + 8);
field->ResizeToPreferred();
view->AddChild(field);
BButton *button = new BButton(BRect(10, 10, 20, 20), "file", "Probe Device", new BMessage(kMsgProbeDevice));
button->ResizeToPreferred();
rect = button->Bounds();
button->MoveTo(Bounds().Width() - 8 - rect.Width(), Bounds().Height() - 8 - rect.Height());
view->AddChild(button);
// MakeDefault() may change the size and location of the button
rect = button->Frame();
button->MakeDefault(true);
button = new BButton(rect, "file", "Probe File" B_UTF8_ELLIPSIS, new BMessage(kMsgProbeFile));
button->ResizeToPreferred();
button->MoveBy(-button->Bounds().Width() - 8, 0);
view->AddChild(button);
button = new BButton(button->Frame(), "cancel", "Cancel", new BMessage(kMsgCancel));
button->ResizeToPreferred();
button->MoveBy(-button->Bounds().Width() - 8, 0);
view->AddChild(button);
BScreen screen;
MoveTo((screen.Frame().Width() - Frame().Width()) / 2,
(screen.Frame().Height() - Frame().Height()) / 2);
}
OpenWindow::~OpenWindow()
{
}
void
OpenWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgProbeDevice:
{
BMenuItem *item = fDevicesMenu->FindMarked();
if (item == NULL)
break;
be_app_messenger.SendMessage(item->Message());
PostMessage(B_QUIT_REQUESTED);
break;
}
case kMsgProbeFile:
be_app_messenger.SendMessage(kMsgOpenFilePanel);
PostMessage(B_QUIT_REQUESTED);
break;
case kMsgCancel:
if (QuitRequested())
Quit();
break;
default:
BWindow::MessageReceived(message);
break;
}
}
bool
OpenWindow::QuitRequested()
{
be_app_messenger.SendMessage(kMsgOpenWindowClosed);
return true;
}
void
OpenWindow::CollectDevices(BMenu *menu, BEntry *startEntry)
{
BDirectory directory;
if (startEntry != NULL)
directory.SetTo(startEntry);
else
directory.SetTo("/dev/disk");
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK) {
if (entry.IsDirectory()) {
CollectDevices(menu, &entry);
continue;
}
entry_ref ref;
if (entry.GetRef(&ref) != B_OK)
continue;
BPath path;
if (entry.GetPath(&path) != B_OK)
continue;
BMessage *message = new BMessage(B_REFS_RECEIVED);
message->AddRef("refs", &ref);
menu->AddItem(new BMenuItem(path.Path(), message));
}
}

View File

@ -0,0 +1,28 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef OPEN_WINDOW_H
#define OPEN_WINDOW_H
#include <Window.h>
class BMenu;
class OpenWindow : public BWindow {
public:
OpenWindow();
virtual ~OpenWindow();
virtual void MessageReceived(BMessage *message);
virtual bool QuitRequested();
static void CollectDevices(BMenu *menu, BEntry *startEntry = NULL);
private:
BMenu *fDevicesMenu;
};
#endif /* OPEN_WINDOW_H */

View File

@ -0,0 +1,92 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include "ProbeWindow.h"
#include "OpenWindow.h"
#include "DiskProbe.h"
#include <Application.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <Entry.h>
#include <Path.h>
#include <string.h>
#include <stdio.h>
ProbeWindow::ProbeWindow(BRect rect, entry_ref *ref, const char *attribute)
: BWindow(rect, ref->name, B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
fRef(*ref)
{
// Set alternative title for certain cases
if (attribute != NULL) {
char buffer[256];
snprintf(buffer, sizeof(buffer), "%s: %s", ref->name, attribute);
SetTitle(buffer);
} else {
BPath path(ref);
if (!strncmp("/dev/", path.Path(), 5))
SetTitle(path.Path());
}
// add the menu
BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL);
AddChild(menuBar);
BMenu *menu = new BMenu("File");
menu->AddItem(new BMenuItem("New" B_UTF8_ELLIPSIS,
new BMessage(kMsgOpenOpenWindow), 'N', B_COMMAND_KEY));
BMenu *devicesMenu = new BMenu("Open Device");
OpenWindow::CollectDevices(devicesMenu);
devicesMenu->SetTargetForItems(be_app);
menu->AddItem(new BMenuItem(devicesMenu));
menu->AddItem(new BMenuItem("Open File" B_UTF8_ELLIPSIS,
new BMessage(kMsgOpenFilePanel), 'O', B_COMMAND_KEY));
menu->AddSeparatorItem();
BMenuItem *item;
menu->AddItem(item = new BMenuItem("Page Setup" B_UTF8_ELLIPSIS, NULL));
item->SetEnabled(false);
menu->AddItem(item = new BMenuItem("Print" B_UTF8_ELLIPSIS, NULL, 'P', B_COMMAND_KEY));
item->SetEnabled(false);
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("About DiskProbe" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q', B_COMMAND_KEY));
menu->SetTargetForItems(be_app);
menuBar->AddItem(menu);
// add our interface widgets
}
ProbeWindow::~ProbeWindow()
{
}
void
ProbeWindow::MessageReceived(BMessage *message)
{
BWindow::MessageReceived(message);
}
bool
ProbeWindow::QuitRequested()
{
be_app_messenger.SendMessage(kMsgWindowClosed);
return true;
}

View File

@ -0,0 +1,27 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef PROBE_WINDOW_H
#define PROBE_WINDOW_H
#include <Window.h>
#include <Entry.h>
class ProbeWindow : public BWindow {
public:
ProbeWindow(BRect rect, entry_ref *ref, const char *attribute = NULL);
virtual ~ProbeWindow();
virtual void MessageReceived(BMessage *message);
virtual bool QuitRequested();
const entry_ref &EntryRef() const { return fRef; }
private:
entry_ref fRef;
};
#endif /* PROBE_WINDOW_H */