⛏️ index : haiku.git

/*
 * Copyright 2002-2009 Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *		Jerome Duval, jerome.duval@free.fr
 */


#include "ImageFilePanel.h"

#include <Bitmap.h>
#include <Catalog.h>
#include <Locale.h>
#include <NodeInfo.h>
#include <String.h>
#include <StringView.h>
#include <TranslationUtils.h>
#include <Window.h>


#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Image Filepanel"


//	#pragma mark - ImageFilePanel


ImageFilePanel::ImageFilePanel(file_panel_mode mode, BMessenger* target,
	const entry_ref* startDirectory, uint32 nodeFlavors,
	bool allowMultipleSelection, BMessage* message, BRefFilter* filter,
	bool modal, bool hideWhenDone)
	:
	BFilePanel(mode, target, startDirectory, nodeFlavors,
		allowMultipleSelection, message, filter, modal, hideWhenDone),
	fImageView(NULL),
	fResolutionView(NULL),
	fImageTypeView(NULL)
{
}


ImageFilePanel::~ImageFilePanel()
{
	if (RefFilter())
		delete RefFilter();
}


void
ImageFilePanel::Show()
{
	if (fImageView == NULL) {
		Window()->Lock();
		BView* background = Window()->ChildAt(0);
		uint32 poseViewResizingMode
			= background->FindView("PoseView")->ResizingMode();
		uint32 countVwResizingMode
			= background->FindView("CountVw")->ResizingMode();
		uint32 vScrollBarResizingMode
			= background->FindView("VScrollBar")->ResizingMode();
		uint32 hScrollBarResizingMode
			= background->FindView("HScrollBar")->ResizingMode();

		background->FindView("PoseView")
			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
		background->FindView("CountVw")
			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
		background->FindView("VScrollBar")
			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
		background->FindView("HScrollBar")
			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
		Window()->ResizeBy(0, 70);
		background->FindView("PoseView")->SetResizingMode(poseViewResizingMode);
		background->FindView("CountVw")->SetResizingMode(countVwResizingMode);
		background->FindView("VScrollBar")
			->SetResizingMode(vScrollBarResizingMode);
		background->FindView("HScrollBar")
			->SetResizingMode(hScrollBarResizingMode);

		BRect rect(background->Bounds().left + 15,
			background->Bounds().bottom - 94, background->Bounds().left + 122,
			background->Bounds().bottom - 15);
		fImageView = new BView(rect, "ImageView",
			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_SUBPIXEL_PRECISE);
		fImageView->SetViewColor(background->ViewColor());
		background->AddChild(fImageView);

		rect = BRect(background->Bounds().left + 132,
			background->Bounds().bottom - 85, background->Bounds().right,
			background->Bounds().bottom - 65);
		fResolutionView = new BStringView(rect, "ResolutionView", NULL,
			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
		background->AddChild(fResolutionView);

		rect.OffsetBy(0, -16);
		fImageTypeView = new BStringView(rect, "ImageTypeView", NULL,
			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
		background->AddChild(fImageTypeView);

		Window()->Unlock();
	}

	BFilePanel::Show();
}


void
ImageFilePanel::SelectionChanged()
{
	entry_ref ref;
	Rewind();

	if (GetNextSelectedRef(&ref) == B_OK) {
		BEntry entry(&ref);
		BNode node(&ref);
		fImageView->ClearViewBitmap();

		if (node.IsFile()) {
			BBitmap* bitmap = BTranslationUtils::GetBitmap(&ref);

			if (bitmap != NULL) {
				BRect dest(fImageView->Bounds());
				if (bitmap->Bounds().Width() > bitmap->Bounds().Height()) {
					dest.InsetBy(0, (dest.Height() + 1
						- ((bitmap->Bounds().Height() + 1)
						/ (bitmap->Bounds().Width() + 1)
						* (dest.Width() + 1))) / 2);
				} else {
					dest.InsetBy((dest.Width() + 1
						- ((bitmap->Bounds().Width() + 1)
						/ (bitmap->Bounds().Height() + 1)
						* (dest.Height() + 1))) / 2, 0);
				}
				fImageView->SetViewBitmap(bitmap, bitmap->Bounds(), dest,
					B_FOLLOW_LEFT | B_FOLLOW_TOP, 0);

				BString resolution;
				resolution << B_TRANSLATE("Resolution: ")
					<< (int)(bitmap->Bounds().Width() + 1)
					<< "x" << (int)(bitmap->Bounds().Height() + 1);
				fResolutionView->SetText(resolution.String());
				delete bitmap;

				BNodeInfo nodeInfo(&node);
				char type[B_MIME_TYPE_LENGTH];
				if (nodeInfo.GetType(type) == B_OK) {
					BMimeType mimeType(type);
					mimeType.GetShortDescription(type);
					// if this fails, the MIME type will be displayed
					fImageTypeView->SetText(type);
				} else {
					BMimeType refType;
					if (BMimeType::GuessMimeType(&ref, &refType) == B_OK) {
						refType.GetShortDescription(type);
						// if this fails, the MIME type will be displayed
						fImageTypeView->SetText(type);
					} else
						fImageTypeView->SetText("");
				}
			}
		} else {
			fResolutionView->SetText("");
			fImageTypeView->SetText("");
		}
		fImageView->Invalidate();
		fResolutionView->Invalidate();
	}

	BFilePanel::SelectionChanged();
}


//	#pragma mark - ImageFilter


ImageFilter::ImageFilter(bool filtering)
	:
	fImageFiltering(filtering)
{
}


bool
ImageFilter::Filter(const entry_ref* ref, BNode* node,
	struct stat_beos* stat, const char* filetype)
{
	bool isDirectory = node->IsDirectory();
	if (!fImageFiltering || isDirectory)
		return isDirectory;

	BMimeType imageType("image");
	BMimeType refType;
	if (BMimeType::GuessMimeType(ref, &refType) == B_OK)
		return imageType.Contains(&refType);

	return false;
}