⛏️ index : haiku.git

/*
 * Copyright 2009 Ankur Sethi <get.me.ankur@gmail.com>
 * Copyright 2004-2011, Axel DΓΆrfler, axeld@pinc-software.de.
 * All rights reserved. Distributed under the terms of the MIT License.
 */


#include "OpenWindow.h"

#include <Application.h>
#include <Button.h>
#include <Catalog.h>
#include <Directory.h>
#include <Entry.h>
#include <GroupLayout.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Screen.h>

#include "DiskProbe.h"


#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "OpenWindow"

static const uint32 kMsgProbeFile = 'prDv';
static const uint32 kMsgProbeDevice = 'prFl';


OpenWindow::OpenWindow()
	:
	BWindow(BRect(0, 0, 350, 10), B_TRANSLATE_SYSTEM_NAME("DiskProbe"),
		B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
		| B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS)
{
	fDevicesMenu = new BPopUpMenu("devices");
	CollectDevices(fDevicesMenu);
	if (BMenuItem *item = fDevicesMenu->ItemAt(0))
		item->SetMarked(true);

	BMenuField *field = new BMenuField(B_TRANSLATE("Examine device:"),
		fDevicesMenu);

	BButton *probeDeviceButton = new BButton("device",
		B_TRANSLATE("Probe device"), new BMessage(kMsgProbeDevice));
	probeDeviceButton->MakeDefault(true);

	BButton *probeFileButton = new BButton("file",
		B_TRANSLATE("Probe file" B_UTF8_ELLIPSIS),
		new BMessage(kMsgProbeFile));

	BButton *cancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
		new BMessage(B_QUIT_REQUESTED));

	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_WINDOW_SPACING)
		.Add(field)
		.AddGroup(B_HORIZONTAL)
			.Add(cancelButton)
			.Add(probeFileButton)
			.AddGlue()
			.Add(probeDeviceButton);

	CenterOnScreen();
}


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 B_SIMPLE_DATA:
		{
			// if it's a file drop, open it
			entry_ref ref;
			if (message->FindRef("refs", 0, &ref) == B_OK) {
				BMessage openMessage(*message);
				openMessage.what = B_REFS_RECEIVED;

				be_app_messenger.SendMessage(&openMessage);
				PostMessage(B_QUIT_REQUESTED);
			}
			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));
	}
}