xref: /haiku/src/apps/expander/ExpanderSettings.cpp (revision 0c93c0a807b27096abbfad677436afb7d1712d4a)
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 ExpanderSettings::ExpanderSettings()
57 	:
58 	fMessage(kMsgExpanderSettings),
59 	fUpdated(false)
60 {
61 	fMessage.AddBool("automatically_expand_files", false);
62 	fMessage.AddBool("close_when_done", false);
63 	fMessage.AddInt8("destination_folder", 0x63);
64 	entry_ref ref;
65 	fMessage.AddRef("destination_folder_use", &ref);
66 	fMessage.AddBool("open_destination_folder", true);
67 	fMessage.AddBool("show_contents_listing", false);
68 	fMessage.AddPoint("window_position", BPoint(50, 50));
69 
70 	BFile file;
71 	if (Open(&file, B_READ_ONLY) != B_OK)
72 		return;
73 
74 	// ToDo: load/save settings as flattened BMessage - but not yet,
75 	//		since that will break compatibility with R5's Expander
76 
77 	bool unknown;
78 	bool automatically_expand_files;
79 	bool close_when_done;
80 	int8 destination_folder;
81 	bool open_destination_folder;
82 	bool show_contents_listing;
83 	BPoint position;
84 	int32 name_size;
85 	if (
86 		(file.Read(&unknown, sizeof(unknown)) == sizeof(unknown))
87 		&& (file.Read(&automatically_expand_files, sizeof(automatically_expand_files)) == sizeof(automatically_expand_files))
88 		&& (file.Read(&close_when_done, sizeof(close_when_done)) == sizeof(close_when_done))
89 		&& (file.Read(&destination_folder, sizeof(destination_folder)) == sizeof(destination_folder))
90 		&& (file.Read(&unknown, sizeof(unknown)) == sizeof(unknown))
91 		&& (file.Read(&ref.device, sizeof(ref.device)) == sizeof(ref.device))
92 		&& (file.Read(&ref.directory, sizeof(ref.directory)) == sizeof(ref.directory))
93 		&& (file.Read(&name_size, sizeof(name_size)) == sizeof(name_size))
94 		&& ((name_size <= 0) || (ref.name = (char*)malloc(name_size + 1)))
95 		&& (file.Read(ref.name, name_size) == name_size)
96 		&& (file.Read(&open_destination_folder, sizeof(open_destination_folder)) == sizeof(open_destination_folder))
97 		&& (file.Read(&show_contents_listing, sizeof(show_contents_listing)) == sizeof(show_contents_listing))
98 		&& (file.Read(&position, sizeof(position)) == sizeof(position))
99 	   ) {
100 
101 		// check if the window position is on screen at all
102 		BScreen screen;
103 		if (screen.Frame().Contains(position))
104 			fMessage.ReplacePoint("window_position", position);
105 
106 		fMessage.ReplaceBool("automatically_expand_files", automatically_expand_files);
107 		fMessage.ReplaceBool("close_when_done", close_when_done);
108 		if (destination_folder == 0x66 || destination_folder == 0x63 || destination_folder == 0x65)
109 			fMessage.ReplaceInt8("destination_folder", destination_folder);
110 		if (name_size > 0)
111 			ref.name[name_size] = '\0';
112 		BEntry entry(&ref);
113 		if (entry.Exists())
114 			fMessage.ReplaceRef("destination_folder_use", &ref);
115 		fMessage.ReplaceBool("open_destination_folder", open_destination_folder);
116 		fMessage.ReplaceBool("show_contents_listing", show_contents_listing);
117 	}
118 }
119 
120 
121 ExpanderSettings::~ExpanderSettings()
122 {
123 	// only save the settings if something has changed
124 	if (!fUpdated)
125 		return;
126 
127 	BFile file;
128 	if (Open(&file, B_CREATE_FILE | B_WRITE_ONLY) != B_OK)
129 		return;
130 
131 	bool automatically_expand_files;
132 	bool close_when_done;
133 	int8 destination_folder;
134 	entry_ref ref;
135 	bool open_destination_folder;
136 	bool show_contents_listing;
137 	BPoint position;
138 	bool unknown = 1;
139 
140 	if ((fMessage.FindPoint("window_position", &position) == B_OK)
141 		&& (fMessage.FindBool("automatically_expand_files", &automatically_expand_files) == B_OK)
142 		&& (fMessage.FindBool("close_when_done", &close_when_done) == B_OK)
143 		&& (fMessage.FindInt8("destination_folder", &destination_folder) == B_OK)
144 		&& (fMessage.FindRef("destination_folder_use", &ref) == B_OK)
145 		&& (fMessage.FindBool("open_destination_folder", &open_destination_folder) == B_OK)
146 		&& (fMessage.FindBool("show_contents_listing", &show_contents_listing) == B_OK)) {
147 
148 		file.Write(&unknown, sizeof(unknown));
149 		file.Write(&automatically_expand_files, sizeof(automatically_expand_files));
150 		file.Write(&close_when_done, sizeof(close_when_done));
151 		file.Write(&destination_folder, sizeof(destination_folder));
152 		unknown = 0;
153 		file.Write(&unknown, sizeof(unknown));
154 		file.Write(&ref.device, sizeof(ref.device));
155 		file.Write(&ref.directory, sizeof(ref.directory));
156 		int32 name_size = 0;
157 		if (ref.name)
158 			name_size = strlen(ref.name);
159 		file.Write(&name_size, sizeof(name_size));
160 		file.Write(ref.name, name_size);
161 		file.Write(&open_destination_folder, sizeof(open_destination_folder));
162 		file.Write(&show_contents_listing, sizeof(show_contents_listing));
163 		file.Write(&position, sizeof(position));
164 	}
165 
166 }
167 
168 
169 status_t
170 ExpanderSettings::Open(BFile *file, int32 mode)
171 {
172 	BPath path;
173 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
174 		return B_ERROR;
175 
176 	path.Append("Expander_Settings");
177 
178 	return file->SetTo(path.Path(), mode);
179 }
180 
181 
182 void
183 ExpanderSettings::UpdateFrom(BMessage *message)
184 {
185 	bool automatically_expand_files;
186 	bool close_when_done;
187 	int8 destination_folder;
188 	entry_ref ref;
189 	bool open_destination_folder;
190 	bool show_contents_listing;
191 	BPoint position;
192 
193 	if (message->FindPoint("window_position", &position) == B_OK)
194 		fMessage.ReplacePoint("window_position", position);
195 
196 	if (message->FindBool("automatically_expand_files", &automatically_expand_files) == B_OK)
197 		fMessage.ReplaceBool("automatically_expand_files", automatically_expand_files);
198 
199 	if (message->FindBool("close_when_done", &close_when_done) == B_OK)
200 		fMessage.ReplaceBool("close_when_done", close_when_done);
201 
202 	if (message->FindInt8("destination_folder", &destination_folder) == B_OK)
203 		fMessage.ReplaceInt8("destination_folder", destination_folder);
204 
205 	if (message->FindRef("destination_folder_use", &ref) == B_OK)
206 		fMessage.ReplaceRef("destination_folder_use", &ref);
207 
208 	if (message->FindBool("open_destination_folder", &open_destination_folder) == B_OK)
209 		fMessage.ReplaceBool("open_destination_folder", open_destination_folder);
210 
211 	if (message->FindBool("show_contents_listing", &show_contents_listing) == B_OK)
212 		fMessage.ReplaceBool("show_contents_listing", show_contents_listing);
213 
214 	fUpdated = true;
215 }
216