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