⛏️ index : haiku.git

/*
* Copyright 2010, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
*		Ithamar R. Adema <ithamar.adema@team-embedded.nl>
*		Michael Pfeiffer
*/


#include "SelectPrinterDialog.h"

#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>

#include <Button.h>
#include <Debug.h>
#include <Directory.h>
#include <Entry.h>
#include <ListView.h>
#include <Message.h>
#include <Path.h>
#include <ScrollBar.h>
#include <ScrollView.h>
#include <String.h>
#include <StringItem.h>

#include "GPBinding.h"


enum {
	kMsgCancel = 'stop',
	kMsgOK = 'okok',

	kMsgManufacturerSelected = 'msel',
	kMsgPrinterSelected = 'psel',
};


class StringValueItem : public BStringItem {
public:
			StringValueItem(const BString& text, const BString& value)
				:
				BStringItem(text.String()),
				fValue(value)
				{
				}

	BString	fValue;
};


SelectPrinterDialog::SelectPrinterDialog(GPData* data)
	:
	DialogWindow(BRect(100, 100, 500, 500),
		"Select Printer", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
		B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS
			| B_CLOSE_ON_ESCAPE),
	fData(data)
{
	SetResult(B_ERROR);

	BButton* ok;
	BButton* cancel;

	ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK));
	ok->MakeDefault(true);
	ok->SetEnabled(false);
	fOKButton = ok;

	cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel));

	BScrollView* manuScroller, *printerScroller;
	fManufacturersListView = new BListView("olv:manufacturers");
	manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView,
		0, false, true);
	fPrintersListView = new BListView("olv:printers");
	printerScroller = new BScrollView("scr:printers", fPrintersListView, 0,
		false, true);

	fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected));
	fManufacturersListView->SetSelectionMessage(
		new BMessage(kMsgManufacturerSelected));
	PopulateManufacturers();

	// Build the layout
	SetLayout(new BGroupLayout(B_VERTICAL));

	AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
		.AddGroup(B_HORIZONTAL, 5, 1.0f)
			.Add(manuScroller)
			.Add(printerScroller)
		.End()
		.AddGroup(B_HORIZONTAL, 5, 2.0f)
			.AddGlue()
			.Add(cancel)
			.Add(ok)
		.End()
		.SetInsets(10, 10, 10, 10)
	);
}


void
SelectPrinterDialog::PopulateManufacturers()
{
	BMessage manufacturers;
	GPBinding binding;
	binding.GetPrinterManufacturers(manufacturers);

	BString id;
	BString displayName;
	for (int32 index = 0; binding.ExtractManufacturer(manufacturers, index, id,
		displayName); index ++) {
		fManufacturersListView->AddItem(new StringValueItem(id, displayName));
	}
}


void
SelectPrinterDialog::PopulatePrinters()
{
	BString manufacturer = GetSelectedItemValue(fManufacturersListView).String();
	if (manufacturer.Length() == 0)
		return;

	BMessage models;
	GPBinding binding;
	binding.GetPrinterModels(manufacturer, models);

	BString displayName;
	BString driver;
	for (int32 index = 0; binding.ExtractModel(models, index, displayName, driver);
		index ++) {
		StringValueItem* item = new StringValueItem(displayName, driver);
		fPrintersListView->AddItem(item);
	}
}


BString
SelectPrinterDialog::GetSelectedItemValue(BListView* listView)
{
	int32 index = listView->CurrentSelection();

	// Bail out if no manufacturer is selected
	if (index < 0)
		return "";
	BListItem* item = listView->ItemAt(index);
	StringValueItem* valueItem = dynamic_cast<StringValueItem*>(item);
	ASSERT(valueItem != NULL);

	return valueItem->fValue;
}

void
SelectPrinterDialog::PrinterSelected()
{
	int32 index = fPrintersListView->CurrentSelection();
	fOKButton->SetEnabled(index >= 0);
}


void
SelectPrinterDialog::Save()
{
	BString driverName = GetSelectedItemValue(fPrintersListView);
	fData->fGutenprintDriverName = driverName;
	fData->Save();
}


void 
SelectPrinterDialog::MessageReceived(BMessage* msg)
{
	switch (msg->what) {
		case kMsgManufacturerSelected:
			fPrintersListView->MakeEmpty();
			PopulatePrinters();
			PrinterSelected();
			break;
		case kMsgPrinterSelected:
			PrinterSelected();
			break;
		case kMsgOK:
			Save();
			SetResult(B_NO_ERROR);
			PostMessage(B_QUIT_REQUESTED);
			break;
		case kMsgCancel:
			PostMessage(B_QUIT_REQUESTED);
			break;
		default:
			DialogWindow::MessageReceived(msg);
			break;
	}
}