BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / text_search / Model.cpp
blob4caaf5a3abdad6a2ff29cfaddaedd07f47e2e118
1 /*
2 * Copyright (c) 1998-2007 Matthijs Hollemans
3 * Distributed under the terms of the MIT License.
4 */
7 #include "Model.h"
9 #include <new>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include <Directory.h>
15 #include <Entry.h>
16 #include <File.h>
17 #include <FindDirectory.h>
18 #include <List.h>
19 #include <MenuItem.h>
20 #include <Path.h>
21 #include <Roster.h>
23 #include "GlobalDefs.h"
26 using std::nothrow;
29 Model::Model()
31 fDirectory(),
32 fSelectedFiles((uint32)0),
34 fRecurseDirs(true),
35 fRecurseLinks(false),
36 fSkipDotDirs(true),
37 fCaseSensitive(false),
38 fRegularExpression(false),
39 fTextOnly(true),
40 fInvokePe(false),
42 fFrame(100, 100, 500, 400),
44 fState(STATE_IDLE),
46 fFilePanelPath(""),
48 fShowLines(true),
49 fEncoding(0)
51 BPath path;
52 if (find_directory(B_USER_DIRECTORY, &path) == B_OK)
53 fFilePanelPath = path.Path();
54 else
55 fFilePanelPath = "/boot/home";
57 entry_ref dummy;
58 if (be_roster->FindApp(PE_SIGNATURE, &dummy) == B_OK) {
59 // Pe is installed, change the default settings
60 fInvokePe = true;
65 status_t
66 Model::LoadPrefs()
68 BFile file;
69 status_t status = _OpenFile(&file, PREFS_FILE);
70 if (status != B_OK)
71 return status;
73 status = file.Lock();
74 if (status != B_OK)
75 return status;
77 int32 value;
79 if (file.ReadAttr("RecurseDirs", B_INT32_TYPE, 0, &value,
80 sizeof(int32)) > 0)
81 fRecurseDirs = (value != 0);
83 if (file.ReadAttr("RecurseLinks", B_INT32_TYPE, 0, &value,
84 sizeof(int32)) > 0)
85 fRecurseLinks = (value != 0);
87 if (file.ReadAttr("SkipDotDirs", B_INT32_TYPE, 0, &value,
88 sizeof(int32)) > 0)
89 fSkipDotDirs = (value != 0);
91 if (file.ReadAttr("CaseSensitive", B_INT32_TYPE, 0, &value,
92 sizeof(int32)) > 0)
93 fCaseSensitive = (value != 0);
95 if (file.ReadAttr("RegularExpression", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
96 fRegularExpression = (value != 0);
98 if (file.ReadAttr("TextOnly", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
99 fTextOnly = (value != 0);
101 if (file.ReadAttr("InvokePe", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
102 fInvokePe = (value != 0);
104 char buffer [B_PATH_NAME_LENGTH+1];
105 int32 length = file.ReadAttr("FilePanelPath", B_STRING_TYPE, 0, &buffer,
106 sizeof(buffer));
107 if (length > 0) {
108 buffer[length] = '\0';
109 fFilePanelPath = buffer;
112 file.ReadAttr("WindowFrame", B_RECT_TYPE, 0, &fFrame, sizeof(BRect));
114 if (file.ReadAttr("ShowLines", B_INT32_TYPE, 0, &value,
115 sizeof(int32)) > 0)
116 fShowLines = (value != 0);
118 if (file.ReadAttr("Encoding", B_INT32_TYPE, 0, &value, sizeof(int32)) > 0)
119 fEncoding = value;
121 file.Unlock();
123 return B_OK;
127 status_t
128 Model::SavePrefs()
130 BFile file;
131 status_t status = _OpenFile(&file, PREFS_FILE,
132 B_CREATE_FILE | B_WRITE_ONLY);
133 if (status != B_OK)
134 return status;
136 status = file.Lock();
137 if (status != B_OK)
138 return status;
140 int32 value = 2;
141 file.WriteAttr("Version", B_INT32_TYPE, 0, &value, sizeof(int32));
143 value = fRecurseDirs ? 1 : 0;
144 file.WriteAttr("RecurseDirs", B_INT32_TYPE, 0, &value, sizeof(int32));
146 value = fRecurseLinks ? 1 : 0;
147 file.WriteAttr("RecurseLinks", B_INT32_TYPE, 0, &value, sizeof(int32));
149 value = fSkipDotDirs ? 1 : 0;
150 file.WriteAttr("SkipDotDirs", B_INT32_TYPE, 0, &value, sizeof(int32));
152 value = fCaseSensitive ? 1 : 0;
153 file.WriteAttr("CaseSensitive", B_INT32_TYPE, 0, &value, sizeof(int32));
155 value = fRegularExpression ? 1 : 0;
156 file.WriteAttr("RegularExpression", B_INT32_TYPE, 0, &value, sizeof(int32));
158 value = fTextOnly ? 1 : 0;
159 file.WriteAttr("TextOnly", B_INT32_TYPE, 0, &value, sizeof(int32));
161 value = fInvokePe ? 1 : 0;
162 file.WriteAttr("InvokePe", B_INT32_TYPE, 0, &value, sizeof(int32));
164 file.WriteAttr("WindowFrame", B_RECT_TYPE, 0, &fFrame, sizeof(BRect));
166 file.WriteAttr("FilePanelPath", B_STRING_TYPE, 0, fFilePanelPath.String(),
167 fFilePanelPath.Length() + 1);
169 value = fShowLines ? 1 : 0;
170 file.WriteAttr("ShowLines", B_INT32_TYPE, 0, &value, sizeof(int32));
172 file.WriteAttr("Encoding", B_INT32_TYPE, 0, &fEncoding, sizeof(int32));
174 file.Sync();
175 file.Unlock();
177 return B_OK;
181 void
182 Model::AddToHistory(const char* text)
184 BList items;
185 _LoadHistory(items);
187 BString* string = new (nothrow) BString(text);
188 if (string == NULL || !items.AddItem(string)) {
189 delete string;
190 _FreeHistory(items);
191 return;
194 int32 count = items.CountItems() - 1;
195 // don't check last item, since that's the one we just added
196 for (int32 t = 0; t < count; ++t) {
197 // If the same text is already in the list,
198 // then remove it first. Case-sensitive.
199 BString* string = static_cast<BString*>(items.ItemAt(t));
200 if (*string == text) {
201 delete static_cast<BString*>(items.RemoveItem(t));
202 break;
206 while (items.CountItems() >= HISTORY_LIMIT)
207 delete static_cast<BString*>(items.RemoveItem((int32)0));
209 _SaveHistory(items);
210 _FreeHistory(items);
214 void
215 Model::FillHistoryMenu(BMenu* menu) const
217 BList items;
218 if (!_LoadHistory(items))
219 return;
221 for (int32 t = items.CountItems() - 1; t >= 0; --t) {
222 BString* item = static_cast<BString*>(items.ItemAtFast(t));
223 BMessage* message = new BMessage(MSG_SELECT_HISTORY);
224 message->AddString("text", item->String());
225 menu->AddItem(new BMenuItem(item->String(), message));
228 _FreeHistory(items);
232 // #pragma mark - private
235 bool
236 Model::_LoadHistory(BList& items) const
238 BFile file;
239 status_t status = _OpenFile(&file, PREFS_FILE);
240 if (status != B_OK)
241 return false;
243 status = file.Lock();
244 if (status != B_OK)
245 return false;
247 BMessage message;
248 status = message.Unflatten(&file);
249 if (status != B_OK)
250 return false;
252 file.Unlock();
254 BString string;
255 for (int32 x = 0; message.FindString("string", x, &string) == B_OK; x++) {
256 BString* copy = new (nothrow) BString(string);
257 if (copy == NULL || !items.AddItem(copy)) {
258 delete copy;
259 break;
263 return true;
267 status_t
268 Model::_SaveHistory(const BList& items) const
270 BFile file;
271 status_t status = _OpenFile(&file, PREFS_FILE,
272 B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE,
273 B_USER_SETTINGS_DIRECTORY, NULL);
274 if (status != B_OK)
275 return status;
277 status = file.Lock();
278 if (status != B_OK)
279 return status;
281 BMessage message;
282 int32 count = items.CountItems();
283 for (int32 i = 0; i < count; i++) {
284 BString* string = static_cast<BString*>(items.ItemAtFast(i));
286 if (message.AddString("string", string->String()) != B_OK)
287 break;
290 status = message.Flatten(&file);
291 file.SetSize(message.FlattenedSize());
292 file.Sync();
293 file.Unlock();
295 return status;
299 void
300 Model::_FreeHistory(const BList& items) const
302 for (int32 t = items.CountItems() - 1; t >= 0; --t)
303 delete static_cast<BString*>((items.ItemAtFast(t)));
307 status_t
308 Model::_OpenFile(BFile* file, const char* name, uint32 openMode,
309 directory_which which, BVolume* volume) const
311 if (file == NULL)
312 return B_BAD_VALUE;
314 BPath path;
315 status_t status = find_directory(which, &path, true, volume);
316 if (status != B_OK)
317 return status;
319 status = path.Append(PREFS_FILE);
320 if (status != B_OK)
321 return status;
323 status = file->SetTo(path.Path(), openMode);
324 if (status != B_OK)
325 return status;
327 status = file->InitCheck();
328 if (status != B_OK)
329 return status;
331 return B_OK;