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