xref: /haiku/src/preferences/backgrounds/ImageFilePanel.cpp (revision 44cceee67e056d8e34cb017d5f5c07b9fac874c0)
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 
29 ImageFilePanel::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 
43 ImageFilePanel::~ImageFilePanel()
44 {
45 	if (RefFilter())
46 		delete RefFilter();
47 }
48 
49 
50 void
51 ImageFilePanel::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 
108 void
109 ImageFilePanel::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 - ImageFilter
175 
176 
177 ImageFilter::ImageFilter(bool filtering)
178 	:
179 	fImageFiltering(filtering)
180 {
181 }
182 
183 
184 bool
185 ImageFilter::Filter(const entry_ref* ref, BNode* node,
186 	struct stat_beos* stat, const char* filetype)
187 {
188 	bool isDirectory = node->IsDirectory();
189 	if (!fImageFiltering || isDirectory)
190 		return isDirectory;
191 
192 	BMimeType imageType("image");
193 	BMimeType refType;
194 	if (BMimeType::GuessMimeType(ref, &refType) == B_OK)
195 		return imageType.Contains(&refType);
196 
197 	return false;
198 }
199