Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / kits / tracker / Navigator.cpp
blob679f58a58dad7ffd3f4a1030415d5b0f81a8aa3e
1 /*
2 Open Tracker License
4 Terms and Conditions
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
36 #include "Navigator.h"
38 #include <TextControl.h>
39 #include <Window.h>
41 #include "Bitmaps.h"
42 #include "Commands.h"
43 #include "FSUtils.h"
44 #include "Tracker.h"
47 namespace BPrivate {
49 static const int32 kMaxHistory = 32;
54 // #pragma mark - BNavigator
57 BNavigator::BNavigator(const Model* model)
59 BToolBar(),
60 fBackHistory(8, true),
61 fForwHistory(8, true)
63 // Get initial path
64 model->GetPath(&fPath);
66 fLocation = new BTextControl("Location", "", "",
67 new BMessage(kNavigatorCommandLocation));
68 fLocation->SetDivider(0);
70 GroupLayout()->SetInsets(0, 0, B_USE_HALF_ITEM_INSETS, 0);
74 BNavigator::~BNavigator()
79 void
80 BNavigator::AttachedToWindow()
82 // Set up toolbar items
83 BBitmap* bmpBack = new BBitmap(BRect(0, 0, 19, 19), B_RGBA32);
84 GetTrackerResources()->GetIconResource(R_ResBackNav, B_MINI_ICON,
85 bmpBack);
86 AddAction(kNavigatorCommandBackward, this, bmpBack);
87 SetActionEnabled(kNavigatorCommandBackward, false);
88 delete bmpBack;
90 BBitmap* bmpForw = new BBitmap(BRect(0, 0, 19, 19), B_RGBA32);
91 GetTrackerResources()->GetIconResource(R_ResForwNav, B_MINI_ICON,
92 bmpForw);
93 AddAction(kNavigatorCommandForward, this, bmpForw);
94 SetActionEnabled(kNavigatorCommandForward, false);
95 delete bmpForw;
97 BBitmap* bmpUp = new BBitmap(BRect(0, 0, 19, 19), B_RGBA32);
98 GetTrackerResources()->GetIconResource(R_ResUpNav, B_MINI_ICON,
99 bmpUp);
100 AddAction(kNavigatorCommandUp, this, bmpUp);
101 SetActionEnabled(kNavigatorCommandUp, false);
102 delete bmpUp;
104 AddView(fLocation);
105 fLocation->SetTarget(this);
109 void
110 BNavigator::AllAttached()
112 // Inital setup of widget states
113 UpdateLocation(0, kActionSet);
117 void
118 BNavigator::MessageReceived(BMessage* message)
120 switch (message->what) {
121 case kNavigatorCommandBackward:
122 GoBackward((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
123 break;
125 case kNavigatorCommandForward:
126 GoForward((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
127 break;
129 case kNavigatorCommandUp:
130 GoUp((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
131 break;
133 case kNavigatorCommandLocation:
134 GoTo();
135 break;
137 case kNavigatorCommandSetFocus:
138 fLocation->MakeFocus();
139 break;
141 default:
143 // Catch any dropped refs and try to switch to this new directory
144 entry_ref ref;
145 if (message->FindRef("refs", &ref) == B_OK) {
146 BMessage message(kSwitchDirectory);
147 BEntry entry(&ref, true);
148 if (!entry.IsDirectory()) {
149 entry.GetRef(&ref);
150 BPath path(&ref);
151 path.GetParent(&path);
152 get_ref_for_path(path.Path(), &ref);
154 message.AddRef("refs", &ref);
155 message.AddInt32("action", kActionSet);
156 Window()->PostMessage(&message);
163 void
164 BNavigator::GoBackward(bool option)
166 int32 itemCount = fBackHistory.CountItems();
167 if (itemCount >= 2 && fBackHistory.ItemAt(itemCount - 2)) {
168 BEntry entry;
169 if (entry.SetTo(fBackHistory.ItemAt(itemCount - 2)->Path()) == B_OK)
170 SendNavigationMessage(kActionBackward, &entry, option);
175 void
176 BNavigator::GoForward(bool option)
178 if (fForwHistory.CountItems() >= 1) {
179 BEntry entry;
180 if (entry.SetTo(fForwHistory.LastItem()->Path()) == B_OK)
181 SendNavigationMessage(kActionForward, &entry, option);
186 void
187 BNavigator::GoUp(bool option)
189 BEntry entry;
190 if (entry.SetTo(fPath.Path()) == B_OK) {
191 BEntry parentEntry;
192 if (entry.GetParent(&parentEntry) == B_OK) {
193 SendNavigationMessage(kActionUp, &parentEntry, option);
199 void
200 BNavigator::SendNavigationMessage(NavigationAction action, BEntry* entry,
201 bool option)
203 entry_ref ref;
205 if (entry->GetRef(&ref) == B_OK) {
206 BMessage message;
207 message.AddRef("refs", &ref);
208 message.AddInt32("action", action);
210 // get the node of this folder for selecting it in the new location
211 const node_ref* nodeRef;
212 if (Window() && Window()->TargetModel())
213 nodeRef = Window()->TargetModel()->NodeRef();
214 else
215 nodeRef = NULL;
217 // if the option key was held down, open in new window (send message
218 // to be_app) otherwise send message to this window. TTracker
219 // (be_app) understands nodeRefToSlection, BContainerWindow doesn't,
220 // so we have to select the item manually
221 if (option) {
222 message.what = B_REFS_RECEIVED;
223 if (nodeRef != NULL) {
224 message.AddData("nodeRefToSelect", B_RAW_TYPE, nodeRef,
225 sizeof(node_ref));
227 be_app->PostMessage(&message);
228 } else {
229 message.what = kSwitchDirectory;
230 Window()->PostMessage(&message);
231 UnlockLooper();
232 // This is to prevent a dead-lock situation.
233 // SelectChildInParentSoon() eventually locks the
234 // TaskLoop::fLock. Later, when StandAloneTaskLoop::Run()
235 // runs, it also locks TaskLoop::fLock and subsequently
236 // locks this window's looper. Therefore we can't call
237 // SelectChildInParentSoon with our Looper locked,
238 // because we would get different orders of locking
239 // (thus the risk of dead-locking).
241 // Todo: Change the locking behaviour of
242 // StandAloneTaskLoop::Run() and subsequently called
243 // functions.
244 if (nodeRef != NULL) {
245 TTracker* tracker = dynamic_cast<TTracker*>(be_app);
246 if (tracker != NULL)
247 tracker->SelectChildInParentSoon(&ref, nodeRef);
250 LockLooper();
256 void
257 BNavigator::GoTo()
259 BString pathname = fLocation->Text();
261 if (pathname.Compare("") == 0)
262 pathname = "/";
264 BEntry entry;
265 entry_ref ref;
267 if (entry.SetTo(pathname.String()) == B_OK
268 && entry.GetRef(&ref) == B_OK) {
269 BMessage message(kSwitchDirectory);
270 message.AddRef("refs", &ref);
271 message.AddInt32("action", kActionLocation);
272 Window()->PostMessage(&message);
273 } else {
274 BPath path;
276 if (Window() && Window()->TargetModel()) {
277 Window()->TargetModel()->GetPath(&path);
278 fLocation->SetText(path.Path());
284 void
285 BNavigator::UpdateLocation(const Model* newmodel, int32 action)
287 if (newmodel)
288 newmodel->GetPath(&fPath);
290 // Modify history according to commands
291 switch (action) {
292 case kActionBackward:
293 fForwHistory.AddItem(fBackHistory.RemoveItemAt(
294 fBackHistory.CountItems() - 1));
295 break;
297 case kActionForward:
298 fBackHistory.AddItem(fForwHistory.RemoveItemAt(
299 fForwHistory.CountItems() - 1));
300 break;
302 case kActionUpdatePath:
303 break;
305 default:
306 fForwHistory.MakeEmpty();
307 fBackHistory.AddItem(new BPath(fPath));
309 while (fBackHistory.CountItems() > kMaxHistory)
310 fBackHistory.RemoveItem(fBackHistory.FirstItem(), true);
311 break;
314 // Enable Up button when there is any parent
315 BEntry entry;
316 if (entry.SetTo(fPath.Path()) == B_OK) {
317 BEntry parentEntry;
318 bool enable = entry.GetParent(&parentEntry) == B_OK;
319 SetActionEnabled(kNavigatorCommandUp, enable);
322 // Enable history buttons if history contains something
323 SetActionEnabled(kNavigatorCommandForward, fForwHistory.CountItems() > 0);
324 SetActionEnabled(kNavigatorCommandBackward, fBackHistory.CountItems() > 1);
326 // Avoid loss of selection and cursor position
327 if (action != kActionLocation)
328 fLocation->SetText(fPath.Path());