xref: /haiku/src/preferences/backgrounds/ImageFilePanel.cpp (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
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_TRANSLATE_CONTEXT
23 #define B_TRANSLATE_CONTEXT "Image Filepanel"
24 
25 
26 ImageFilePanel::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 
39 ImageFilePanel::~ImageFilePanel()
40 {
41 	if (RefFilter())
42 		delete RefFilter();
43 }
44 
45 
46 void
47 ImageFilePanel::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 
104 void
105 ImageFilePanel::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 
173 CustomRefFilter::CustomRefFilter(bool imageFiltering)
174 	:
175 	fImageFiltering(imageFiltering)
176 {
177 }
178 
179 
180 bool
181 CustomRefFilter::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