1 /*****************************************************************************/ 2 // Expander 3 // Written by Jérôme Duval 4 // 5 // ExpanderSettings.cpp 6 // 7 // Code from Diskprobe by Axel Dörfler 8 // 9 // Copyright (c) 2004 OpenBeOS Project 10 // 11 // Permission is hereby granted, free of charge, to any person obtaining a 12 // copy of this software and associated documentation files (the "Software"), 13 // to deal in the Software without restriction, including without limitation 14 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 // and/or sell copies of the Software, and to permit persons to whom the 16 // Software is furnished to do so, subject to the following conditions: 17 // 18 // The above copyright notice and this permission notice shall be included 19 // in all copies or substantial portions of the Software. 20 // 21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 // DEALINGS IN THE SOFTWARE. 28 /*****************************************************************************/ 29 #include "ExpanderSettings.h" 30 31 #include <ByteOrder.h> 32 #include <Screen.h> 33 #include <FindDirectory.h> 34 #include <Entry.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <Path.h> 38 39 // Format of Expander_Settings 40 // 1st byte : unknown (0x1) 41 // 2nd byte : Automatically expand files (default : 0x0) 42 // 3rd byte : Close when done (default : 0x0) 43 // 4th byte : 0x66 44 // 0x63 (default) 45 // 0x65 46 // 5th byte : unknown (0x0) 47 // 4 bytes : dev_t (default : 0xffff) 48 // 8 bytes : ino_t (default : 0xfffffffff) 49 // 4 bytes : name length (big endian) (default : 0x0) 50 // n bytes : name (default : "") 51 // 1 byte : Open destination folder (default : 0x1) 52 // 1 byte : Show content listing (default : 0x0) 53 // 4 bytes : window position topleft x (default : 0x4842) 54 // 4 bytes : window position topleft y (default : 0x4842) 55 56 57 template<typename T> bool 58 read_data(BFile& file, T& value) 59 { 60 return file.Read(&value, sizeof(T)) == (ssize_t)sizeof(T); 61 } 62 63 64 // #pragma mark - 65 66 67 ExpanderSettings::ExpanderSettings() 68 : 69 fMessage(kMsgExpanderSettings), 70 fUpdated(false) 71 { 72 fMessage.AddBool("automatically_expand_files", false); 73 fMessage.AddBool("close_when_done", true); 74 fMessage.AddInt8("destination_folder", 0x63); 75 entry_ref ref; 76 fMessage.AddRef("destination_folder_use", &ref); 77 fMessage.AddBool("open_destination_folder", true); 78 fMessage.AddBool("show_contents_listing", false); 79 fMessage.AddPoint("window_position", BPoint(50, 50)); 80 81 BFile file; 82 if (Open(&file, B_READ_ONLY) != B_OK) 83 return; 84 85 // TODO: load/save settings as flattened BMessage - but not yet, 86 // since that will break compatibility with R5's Expander 87 88 bool unknown; 89 bool automaticallyExpandFiles; 90 bool closeWhenDone; 91 int8 destinationFolder; 92 bool openDestinationFolder; 93 bool showContentsListing; 94 BPoint position; 95 char name[B_FILE_NAME_LENGTH] = {'\0'}; 96 int32 nameSize; 97 if (read_data(file, unknown) 98 && read_data(file, automaticallyExpandFiles) 99 && read_data(file, closeWhenDone) 100 && read_data(file, destinationFolder) 101 && read_data(file, unknown) 102 && read_data(file, ref.device) 103 && read_data(file, ref.directory) 104 && read_data(file, nameSize) 105 && (nameSize <= 0 || file.Read(name, nameSize) == nameSize) 106 && read_data(file, openDestinationFolder) 107 && read_data(file, showContentsListing) 108 && read_data(file, position)) { 109 if (nameSize > 0 && nameSize < B_FILE_NAME_LENGTH) { 110 name[nameSize] = '\0'; 111 ref.set_name(name); 112 } 113 114 // check if the window position is on screen at all 115 BScreen screen; 116 if (screen.Frame().Contains(position)) 117 fMessage.ReplacePoint("window_position", position); 118 119 fMessage.ReplaceBool("automatically_expand_files", 120 automaticallyExpandFiles); 121 fMessage.ReplaceBool("close_when_done", closeWhenDone); 122 if (destinationFolder == 0x66 123 || destinationFolder == 0x63 124 || destinationFolder == 0x65) 125 fMessage.ReplaceInt8("destination_folder", destinationFolder); 126 BEntry entry(&ref); 127 if (entry.Exists()) 128 fMessage.ReplaceRef("destination_folder_use", &ref); 129 fMessage.ReplaceBool("open_destination_folder", openDestinationFolder); 130 fMessage.ReplaceBool("show_contents_listing", showContentsListing); 131 } 132 } 133 134 135 ExpanderSettings::~ExpanderSettings() 136 { 137 // only save the settings if something has changed 138 if (!fUpdated) 139 return; 140 141 BFile file; 142 if (Open(&file, B_CREATE_FILE | B_WRITE_ONLY) != B_OK) 143 return; 144 145 bool automaticallyExpandFiles; 146 bool closeWhenDone; 147 int8 destinationFolder; 148 entry_ref ref; 149 bool openDestinationFolder; 150 bool showContentsListing; 151 BPoint position; 152 bool unknown = 1; 153 154 if (fMessage.FindPoint("window_position", &position) == B_OK 155 && fMessage.FindBool("automatically_expand_files", 156 &automaticallyExpandFiles) == B_OK 157 && fMessage.FindBool("close_when_done", &closeWhenDone) == B_OK 158 && fMessage.FindInt8("destination_folder", &destinationFolder) == B_OK 159 && fMessage.FindRef("destination_folder_use", &ref) == B_OK 160 && fMessage.FindBool("open_destination_folder", 161 &openDestinationFolder) == B_OK 162 && fMessage.FindBool("show_contents_listing", 163 &showContentsListing) == B_OK) { 164 file.Write(&unknown, sizeof(unknown)); 165 file.Write(&automaticallyExpandFiles, sizeof(automaticallyExpandFiles)); 166 file.Write(&closeWhenDone, sizeof(closeWhenDone)); 167 file.Write(&destinationFolder, sizeof(destinationFolder)); 168 unknown = 0; 169 file.Write(&unknown, sizeof(unknown)); 170 file.Write(&ref.device, sizeof(ref.device)); 171 file.Write(&ref.directory, sizeof(ref.directory)); 172 int32 nameSize = 0; 173 if (ref.name) 174 nameSize = strlen(ref.name); 175 file.Write(&nameSize, sizeof(nameSize)); 176 file.Write(ref.name, nameSize); 177 file.Write(&openDestinationFolder, sizeof(openDestinationFolder)); 178 file.Write(&showContentsListing, sizeof(showContentsListing)); 179 file.Write(&position, sizeof(position)); 180 } 181 } 182 183 184 status_t 185 ExpanderSettings::Open(BFile *file, int32 mode) 186 { 187 BPath path; 188 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 189 return B_ERROR; 190 191 path.Append("Expander_Settings"); 192 193 return file->SetTo(path.Path(), mode); 194 } 195 196 197 void 198 ExpanderSettings::UpdateFrom(BMessage *message) 199 { 200 bool automaticallyExpandFiles; 201 bool closeWhenDone; 202 int8 destinationFolder; 203 entry_ref ref; 204 bool openDestinationFolder; 205 bool showContentsListing; 206 BPoint position; 207 208 if (message->FindPoint("window_position", &position) == B_OK) 209 fMessage.ReplacePoint("window_position", position); 210 211 if (message->FindBool("automatically_expand_files", 212 &automaticallyExpandFiles) == B_OK) { 213 fMessage.ReplaceBool("automatically_expand_files", 214 automaticallyExpandFiles); 215 } 216 217 if (message->FindBool("close_when_done", &closeWhenDone) == B_OK) 218 fMessage.ReplaceBool("close_when_done", closeWhenDone); 219 220 if (message->FindInt8("destination_folder", &destinationFolder) == B_OK) 221 fMessage.ReplaceInt8("destination_folder", destinationFolder); 222 223 if (message->FindRef("destination_folder_use", &ref) == B_OK) 224 fMessage.ReplaceRef("destination_folder_use", &ref); 225 226 if (message->FindBool("open_destination_folder", 227 &openDestinationFolder) == B_OK) 228 fMessage.ReplaceBool("open_destination_folder", openDestinationFolder); 229 230 if (message->FindBool("show_contents_listing", 231 &showContentsListing) == B_OK) 232 fMessage.ReplaceBool("show_contents_listing", showContentsListing); 233 234 fUpdated = true; 235 } 236