File: | src/kits/tracker/DirMenu.cpp |
Warning: | line 186, column 4 Potential leak of memory pointed to by 'menu' |
1 | /* | |||
2 | Open Tracker License | |||
3 | ||||
4 | Terms and Conditions | |||
5 | ||||
6 | Copyright (c) 1991-2000, Be Incorporated. All rights reserved. | |||
7 | ||||
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: | |||
14 | ||||
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. | |||
17 | ||||
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. | |||
24 | ||||
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. | |||
28 | ||||
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. | |||
33 | */ | |||
34 | ||||
35 | // ToDo: | |||
36 | // get rid of fMenuBar, SetMenuBar and related mess | |||
37 | ||||
38 | ||||
39 | #include <Catalog.h> | |||
40 | #include <Debug.h> | |||
41 | #include <Directory.h> | |||
42 | #include <Locale.h> | |||
43 | #include <MenuBar.h> | |||
44 | #include <Path.h> | |||
45 | #include <Volume.h> | |||
46 | #include <VolumeRoster.h> | |||
47 | ||||
48 | #include "Attributes.h" | |||
49 | #include "ContainerWindow.h" | |||
50 | #include "DirMenu.h" | |||
51 | #include "FSUtils.h" | |||
52 | #include "IconMenuItem.h" | |||
53 | #include "NavMenu.h" | |||
54 | #include "TrackerSettings.h" | |||
55 | #include "Utilities.h" | |||
56 | ||||
57 | ||||
58 | #undef B_TRANSLATION_CONTEXT"DirMenu" | |||
59 | #define B_TRANSLATION_CONTEXT"DirMenu" "DirMenu" | |||
60 | ||||
61 | ||||
62 | // #pragma mark - BDirMenu | |||
63 | ||||
64 | ||||
65 | BDirMenu::BDirMenu(BMenuBar* bar, BMessenger target, uint32 command, | |||
66 | const char* entryName) | |||
67 | : | |||
68 | BPopUpMenu("directories"), | |||
69 | fTarget(target), | |||
70 | fMenuBar(bar), | |||
71 | fCommand(command) | |||
72 | { | |||
73 | SetFont(be_plain_font); | |||
74 | if (entryName) | |||
75 | fEntryName = entryName; | |||
76 | else | |||
77 | fEntryName = "refs"; | |||
78 | } | |||
79 | ||||
80 | ||||
81 | BDirMenu::~BDirMenu() | |||
82 | { | |||
83 | } | |||
84 | ||||
85 | ||||
86 | void | |||
87 | BDirMenu::Populate(const BEntry* startEntry, BWindow* originatingWindow, | |||
88 | bool includeStartEntry, bool select, bool reverse, bool addShortcuts, | |||
89 | bool navMenuEntries) | |||
90 | { | |||
91 | try { | |||
92 | if (!startEntry) | |||
| ||||
93 | throw (status_t)B_ERROR(-1); | |||
94 | ||||
95 | Model model(startEntry); | |||
96 | ThrowOnInitCheckError(&model); | |||
97 | ||||
98 | ModelMenuItem* menu = new ModelMenuItem(&model, this, true, true); | |||
99 | ||||
100 | if (fMenuBar) | |||
101 | fMenuBar->AddItem(menu); | |||
102 | ||||
103 | BEntry entry(*startEntry); | |||
104 | ||||
105 | bool showDesktop, showDisksIcon; | |||
106 | { | |||
107 | TrackerSettings settings; | |||
108 | showDesktop = settings.DesktopFilePanelRoot(); | |||
109 | showDisksIcon = settings.ShowDisksIcon(); | |||
110 | } | |||
111 | ||||
112 | // might start one level above startEntry | |||
113 | if (!includeStartEntry) { | |||
114 | BDirectory parent; | |||
115 | BDirectory dir(&entry); | |||
116 | ||||
117 | if (!showDesktop && dir.InitCheck() == B_OK((int)0) | |||
118 | && dir.IsRootDirectory()) { | |||
119 | // if we're at the root directory skip "mnt" and | |||
120 | // go straight to "/" | |||
121 | parent.SetTo("/"); | |||
122 | parent.GetEntry(&entry); | |||
123 | } else | |||
124 | FSGetParentVirtualDirectoryAware(entry, entry); | |||
125 | } | |||
126 | ||||
127 | BDirectory desktopDir; | |||
128 | FSGetDeskDir(&desktopDir); | |||
129 | BEntry desktopEntry; | |||
130 | desktopDir.GetEntry(&desktopEntry); | |||
131 | ||||
132 | for (;;) { | |||
133 | BNode node(&entry); | |||
134 | ThrowOnInitCheckError(&node); | |||
135 | ||||
136 | PoseInfo info; | |||
137 | ReadAttrResult result = ReadAttr(&node, kAttrPoseInfo"_trk/pinfo_le", | |||
138 | kAttrPoseInfoForeign"_trk/pinfo", B_RAW_TYPE, 0, &info, sizeof(PoseInfo), | |||
139 | &PoseInfo::EndianSwap); | |||
140 | ||||
141 | BEntry parentEntry; | |||
142 | bool hitRoot = false; | |||
143 | ||||
144 | BDirectory dir(&entry); | |||
145 | if (!showDesktop && dir.InitCheck() == B_OK((int)0) | |||
146 | && dir.IsRootDirectory()) { | |||
147 | // if we're at the root directory skip "mnt" and | |||
148 | // go straight to "/" | |||
149 | hitRoot = true; | |||
150 | parentEntry.SetTo("/"); | |||
151 | } else | |||
152 | FSGetParentVirtualDirectoryAware(entry, parentEntry); | |||
153 | ||||
154 | if (showDesktop) { | |||
155 | BEntry root("/"); | |||
156 | // warp from "/" to Desktop properly | |||
157 | if (entry == root) { | |||
158 | if (showDisksIcon) | |||
159 | AddDisksIconToMenu(reverse); | |||
160 | entry = desktopEntry; | |||
161 | } | |||
162 | ||||
163 | if (entry == desktopEntry) | |||
164 | hitRoot = true; | |||
165 | } | |||
166 | ||||
167 | if (result == kReadAttrFailed || !info.fInvisible | |||
168 | || (showDesktop && desktopEntry == entry)) { | |||
169 | AddItemToDirMenu(&entry, originatingWindow, reverse, | |||
170 | addShortcuts, navMenuEntries); | |||
171 | } | |||
172 | ||||
173 | if (hitRoot) { | |||
174 | if (!showDesktop && showDisksIcon && *startEntry != "/") | |||
175 | AddDisksIconToMenu(reverse); | |||
176 | break; | |||
177 | } | |||
178 | ||||
179 | entry = parentEntry; | |||
180 | if (entry.InitCheck() != B_OK((int)0)) | |||
181 | break; | |||
182 | } | |||
183 | ||||
184 | // select last item in menu | |||
185 | if (!select) | |||
186 | return; | |||
| ||||
187 | ||||
188 | ModelMenuItem* item | |||
189 | = dynamic_cast<ModelMenuItem*>(ItemAt(CountItems() - 1)); | |||
190 | if (item != NULL__null) { | |||
191 | item->SetMarked(true); | |||
192 | if (menu) { | |||
193 | entry.SetTo(item->TargetModel()->EntryRef()); | |||
194 | ThrowOnError(menu->SetEntry(&entry))_ThrowOnError(menu->SetEntry(&entry), "/home/haiku/haiku/haiku/src/kits/tracker/DirMenu.cpp" , 194); | |||
195 | } | |||
196 | } | |||
197 | } catch (status_t err) { | |||
198 | PRINT(("BDirMenu::Populate: caught error %s\n", strerror(err)))_debugPrintf ("BDirMenu::Populate: caught error %s\n", strerror (err)); | |||
199 | if (!CountItems()) { | |||
200 | BString error; | |||
201 | error << "Error [" << strerror(err) << "] populating menu"; | |||
202 | AddItem(new BMenuItem(error.String(), 0)); | |||
203 | } | |||
204 | } | |||
205 | } | |||
206 | ||||
207 | ||||
208 | void | |||
209 | BDirMenu::AddItemToDirMenu(const BEntry* entry, BWindow* originatingWindow, | |||
210 | bool atEnd, bool addShortcuts, bool navMenuEntries) | |||
211 | { | |||
212 | Model model(entry); | |||
213 | if (model.InitCheck() != B_OK((int)0)) | |||
214 | return; | |||
215 | ||||
216 | BMessage* message = new BMessage(fCommand); | |||
217 | message->AddRef(fEntryName.String(), model.EntryRef()); | |||
218 | ||||
219 | // add reference to the container windows model so that we can | |||
220 | // close the window if | |||
221 | BContainerWindow* window = originatingWindow ? | |||
222 | dynamic_cast<BContainerWindow*>(originatingWindow) : 0; | |||
223 | if (window != NULL__null) { | |||
224 | message->AddData("nodeRefsToClose", B_RAW_TYPE, | |||
225 | window->TargetModel()->NodeRef(), sizeof (node_ref)); | |||
226 | } | |||
227 | ModelMenuItem* item; | |||
228 | if (navMenuEntries) { | |||
229 | BNavMenu* subMenu = new BNavMenu(model.Name(), B_REFS_RECEIVED, | |||
230 | fTarget, window); | |||
231 | entry_ref ref; | |||
232 | entry->GetRef(&ref); | |||
233 | subMenu->SetNavDir(&ref); | |||
234 | item = new ModelMenuItem(&model, subMenu); | |||
235 | item->SetLabel(model.Name()); | |||
236 | item->SetMessage(message); | |||
237 | } else { | |||
238 | item = new ModelMenuItem(&model, model.Name(), message); | |||
239 | } | |||
240 | ||||
241 | if (addShortcuts) { | |||
242 | if (model.IsDesktop()) | |||
243 | item->SetShortcut('D', B_COMMAND_KEY); | |||
244 | else if (FSIsHomeDir(entry)) | |||
245 | item->SetShortcut('H', B_COMMAND_KEY); | |||
246 | } | |||
247 | ||||
248 | if (atEnd) | |||
249 | AddItem(item); | |||
250 | else | |||
251 | AddItem(item, 0); | |||
252 | ||||
253 | item->SetTarget(fTarget); | |||
254 | ||||
255 | if (fMenuBar != NULL__null) { | |||
256 | ModelMenuItem* menu | |||
257 | = dynamic_cast<ModelMenuItem*>(fMenuBar->ItemAt(0)); | |||
258 | if (menu != NULL__null) { | |||
259 | ThrowOnError(menu->SetEntry(entry))_ThrowOnError(menu->SetEntry(entry), "/home/haiku/haiku/haiku/src/kits/tracker/DirMenu.cpp" , 259); | |||
260 | item->SetMarked(true); | |||
261 | } | |||
262 | } | |||
263 | } | |||
264 | ||||
265 | ||||
266 | void | |||
267 | BDirMenu::AddDisksIconToMenu(bool atEnd) | |||
268 | { | |||
269 | BEntry entry("/"); | |||
270 | Model model(&entry); | |||
271 | if (model.InitCheck() != B_OK((int)0)) | |||
272 | return; | |||
273 | ||||
274 | BMessage* message = new BMessage(fCommand); | |||
275 | message->AddRef(fEntryName.String(), model.EntryRef()); | |||
276 | ||||
277 | ModelMenuItem* item = new ModelMenuItem(&model, | |||
278 | B_TRANSLATE(B_DISKS_DIR_NAME)BLocaleRoster::Default()->GetCatalog()->GetString(("Disks" ), "DirMenu"), message); | |||
279 | if (atEnd) | |||
280 | AddItem(item); | |||
281 | else | |||
282 | AddItem(item, 0); | |||
283 | } |