1/*
2 * Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Jerome Duval (jerome.duval@free.fr)
7 */
8
9
10#include "ImageFilePanel.h"
11
12#include <Bitmap.h>
13#include <Catalog.h>
14#include <Locale.h>
15#include <NodeInfo.h>
16#include <String.h>
17#include <StringView.h>
18#include <TranslationUtils.h>
19#include <Window.h>
20
21
22#undef B_TRANSLATION_CONTEXT
23#define B_TRANSLATION_CONTEXT "Image Filepanel"
24
25
26ImageFilePanel::ImageFilePanel(file_panel_mode mode, BMessenger* target,
27	const entry_ref* startDirectory, uint32 nodeFlavors,
28	bool allowMultipleSelection, BMessage* message, BRefFilter* filter,
29	bool modal, bool hideWhenDone)
30	: BFilePanel(mode, target, startDirectory, nodeFlavors,
31		allowMultipleSelection, message, filter, modal, hideWhenDone),
32	fImageView(NULL),
33	fResolutionView(NULL),
34	fImageTypeView(NULL)
35{
36}
37
38
39ImageFilePanel::~ImageFilePanel()
40{
41	if (RefFilter())
42		delete RefFilter();
43}
44
45
46void
47ImageFilePanel::Show()
48{
49	if (fImageView == NULL) {
50		Window()->Lock();
51		BView* background = Window()->ChildAt(0);
52		uint32 poseViewResizingMode
53			= background->FindView("PoseView")->ResizingMode();
54		uint32 countVwResizingMode
55			= background->FindView("CountVw")->ResizingMode();
56		uint32 vScrollBarResizingMode
57			= background->FindView("VScrollBar")->ResizingMode();
58		uint32 hScrollBarResizingMode
59			= background->FindView("HScrollBar")->ResizingMode();
60
61		background->FindView("PoseView")
62			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
63		background->FindView("CountVw")
64			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
65		background->FindView("VScrollBar")
66			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
67		background->FindView("HScrollBar")
68			->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
69		Window()->ResizeBy(0, 70);
70		background->FindView("PoseView")->SetResizingMode(poseViewResizingMode);
71		background->FindView("CountVw")->SetResizingMode(countVwResizingMode);
72		background->FindView("VScrollBar")
73			->SetResizingMode(vScrollBarResizingMode);
74		background->FindView("HScrollBar")
75			->SetResizingMode(hScrollBarResizingMode);
76
77		BRect rect(background->Bounds().left + 15,
78			background->Bounds().bottom - 94, background->Bounds().left + 122,
79			background->Bounds().bottom - 15);
80		fImageView = new BView(rect, "ImageView",
81			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_SUBPIXEL_PRECISE);
82		fImageView->SetViewColor(background->ViewColor());
83		background->AddChild(fImageView);
84
85		rect = BRect(background->Bounds().left + 132,
86			background->Bounds().bottom - 85, background->Bounds().right,
87			background->Bounds().bottom - 65);
88		fResolutionView = new BStringView(rect, "ResolutionView", NULL,
89			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
90		background->AddChild(fResolutionView);
91
92		rect.OffsetBy(0, -16);
93		fImageTypeView = new BStringView(rect, "ImageTypeView", NULL,
94			B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
95		background->AddChild(fImageTypeView);
96
97		Window()->Unlock();
98	}
99
100	BFilePanel::Show();
101}
102
103
104void
105ImageFilePanel::SelectionChanged()
106{
107	entry_ref ref;
108	Rewind();
109
110	if (GetNextSelectedRef(&ref) == B_OK) {
111		BEntry entry(&ref);
112		BNode node(&ref);
113		fImageView->ClearViewBitmap();
114
115		if (node.IsFile()) {
116			BBitmap* bitmap = BTranslationUtils::GetBitmap(&ref);
117
118			if (bitmap != NULL) {
119				BRect dest(fImageView->Bounds());
120				if (bitmap->Bounds().Width() > bitmap->Bounds().Height()) {
121					dest.InsetBy(0, (dest.Height() + 1
122						- ((bitmap->Bounds().Height() + 1)
123						/ (bitmap->Bounds().Width() + 1)
124						* (dest.Width() + 1))) / 2);
125				} else {
126					dest.InsetBy((dest.Width() + 1
127						- ((bitmap->Bounds().Width() + 1)
128						/ (bitmap->Bounds().Height() + 1)
129						* (dest.Height() + 1))) / 2, 0);
130				}
131				fImageView->SetViewBitmap(bitmap, bitmap->Bounds(), dest,
132					B_FOLLOW_LEFT | B_FOLLOW_TOP, 0);
133
134				BString resolution;
135				resolution << B_TRANSLATE("Resolution: ")
136					<< (int)(bitmap->Bounds().Width() + 1)
137					<< "x" << (int)(bitmap->Bounds().Height() + 1);
138				fResolutionView->SetText(resolution.String());
139				delete bitmap;
140
141				BNodeInfo nodeInfo(&node);
142				char type[B_MIME_TYPE_LENGTH];
143				if (nodeInfo.GetType(type) == B_OK) {
144					BMimeType mimeType(type);
145					mimeType.GetShortDescription(type);
146					// if this fails, the MIME type will be displayed
147					fImageTypeView->SetText(type);
148				} else {
149					BMimeType refType;
150					if (BMimeType::GuessMimeType(&ref, &refType) == B_OK) {
151						refType.GetShortDescription(type);
152						// if this fails, the MIME type will be displayed
153						fImageTypeView->SetText(type);
154					} else
155						fImageTypeView->SetText("");
156				}
157			}
158		} else {
159			fResolutionView->SetText("");
160			fImageTypeView->SetText("");
161		}
162		fImageView->Invalidate();
163		fResolutionView->Invalidate();
164	}
165
166	BFilePanel::SelectionChanged();
167}
168
169
170//	#pragma mark -
171
172
173CustomRefFilter::CustomRefFilter(bool imageFiltering)
174	:
175	fImageFiltering(imageFiltering)
176{
177}
178
179
180bool
181CustomRefFilter::Filter(const entry_ref* ref, BNode* node,
182	struct stat_beos* stat, const char* filetype)
183{
184	if (!fImageFiltering)
185		return node->IsDirectory();
186
187	if (node->IsDirectory())
188		return true;
189
190	BMimeType imageType("image"), refType;
191	BMimeType::GuessMimeType(ref, &refType);
192	if (imageType.Contains(&refType))
193		return true;
194
195	return false;
196}
197
198