xref: /haiku/src/apps/people/PeopleApp.cpp (revision c9ad965c81b08802fed0827fd1dd16f45297928a)
1 /*
2  * Copyright 2005 - 2008, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  *		Robert Polic
7  *		Axel Dörfler, axeld@pinc-software.de
8  *
9  * Copyright 1999, Be Incorporated.   All Rights Reserved.
10  * This file may be used under the terms of the Be Sample Code License.
11  */
12 
13 
14 #include <Bitmap.h>
15 #include <Directory.h>
16 #include <Volume.h>
17 #include <VolumeRoster.h>
18 #include <Path.h>
19 #include <FindDirectory.h>
20 #include <Screen.h>
21 #include <Alert.h>
22 #include <fs_index.h>
23 
24 #include "PeopleApp.h"
25 #include "PeopleWindow.h"
26 #include "PersonIcons.h"
27 
28 #include <string.h>
29 
30 
31 struct people_field gFields[] = {
32 	{ "META:name", 120, "Contact Name" },
33 	{ "META:nickname", 120, "Nickname" },
34 	{ "META:company", 120, "Company" },
35 	{ "META:address", 120, "Address" },
36 	{ "META:city", 90, "City" },
37 	{ "META:state", 50, "State" },
38 	{ "META:zip", 50, "Zip" },
39 	{ "META:country", 120, "Country" },
40 	{ "META:hphone", 90, "Home Phone" },
41 	{ "META:wphone", 90, "Work Phone" },
42 	{ "META:fax", 90, "Fax" },
43 	{ "META:email", 120, "E-mail" },
44 	{ "META:url", 120, "URL" },
45 	{ "META:group", 120, "Group" },
46 	{ NULL, 0, NULL }
47 };
48 
49 
50 TPeopleApp::TPeopleApp(void)
51 	: BApplication(APP_SIG),
52 	fWindowCount(0)
53 {
54 	fPosition.Set(6, TITLE_BAR_HEIGHT, 6 + WIND_WIDTH, TITLE_BAR_HEIGHT + WIND_HEIGHT);
55 	BPoint pos = fPosition.LeftTop();
56 
57 	BPath path;
58 	find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
59 
60 	BDirectory dir(path.Path());
61 	BEntry entry;
62 	if (dir.FindEntry("People_data", &entry) == B_NO_ERROR) {
63 		fPrefs = new BFile(&entry, B_READ_WRITE);
64 		if (fPrefs->InitCheck() == B_NO_ERROR) {
65 			fPrefs->Read(&pos, sizeof(BPoint));
66 			if (BScreen(B_MAIN_SCREEN_ID).Frame().Contains(pos))
67 				fPosition.OffsetTo(pos);
68 		}
69 	} else {
70 		fPrefs = new BFile();
71 		if (dir.CreateFile("People_data", fPrefs) != B_NO_ERROR) {
72 			delete fPrefs;
73 			fPrefs = NULL;
74 		}
75 	}
76 
77 	// create indices on all volumes
78 
79 	BVolumeRoster volumeRoster;
80 	BVolume volume;
81 	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
82 		for (int32 i = 0; gFields[i].attribute; i++) {
83 			fs_create_index(volume.Device(), gFields[i].attribute, B_STRING_TYPE, 0);
84 		}
85 	}
86 
87 	// install person mime type
88 
89 	bool valid = false;
90 	BMimeType mime;
91 	mime.SetType(B_PERSON_MIMETYPE);
92 
93 	if (mime.IsInstalled()) {
94 		BMessage info;
95 		if (mime.GetAttrInfo(&info) == B_NO_ERROR) {
96 			const char *string;
97 			int32 index = 0;
98 			while (info.FindString("attr:name", index++, &string) == B_OK) {
99 				if (!strcmp(string, gFields[0].attribute)) {
100 					valid = true;
101 					break;
102 				}
103 			}
104 			if (!valid)
105 				mime.Delete();
106 		}
107 	}
108 	if (!valid) {
109 		mime.Install();
110 		mime.SetShortDescription("Person");
111 		mime.SetLongDescription("Contact information for a person.");
112 		mime.SetIcon(kPersonIcon, sizeof(kPersonIcon));
113 		mime.SetPreferredApp(APP_SIG);
114 
115 		// add relevant person fields to meta-mime type
116 
117 		BMessage fields;
118 		for (int32 i = 0; gFields[i].attribute; i++) {
119 			fields.AddString("attr:public_name", gFields[i].name);
120 			fields.AddString("attr:name", gFields[i].attribute);
121 			fields.AddInt32("attr:type", B_STRING_TYPE);
122 			fields.AddBool("attr:viewable", true);
123 			fields.AddBool("attr:editable", true);
124 			fields.AddInt32("attr:width", gFields[i].width);
125 			fields.AddInt32("attr:alignment", B_ALIGN_LEFT);
126 			fields.AddBool("attr:extra", false);
127 		}
128 
129 		mime.SetAttrInfo(&fields);
130 	}
131 }
132 
133 
134 TPeopleApp::~TPeopleApp(void)
135 {
136 	delete fPrefs;
137 }
138 
139 
140 void
141 TPeopleApp::AboutRequested(void)
142 {
143 	(new BAlert("", "...by Robert Polic", "Big Deal"))->Go();
144 }
145 
146 
147 void
148 TPeopleApp::ArgvReceived(int32 argc, char **argv)
149 {
150 	TPeopleWindow* window = NULL;
151 
152 	for (int32 loop = 1; loop < argc; loop++) {
153 		char* arg = argv[loop];
154 
155 		int32 index;
156 		for (index = 0; gFields[index].attribute; index++) {
157 			if (!strncmp(gFields[index].attribute, arg, strlen(gFields[index].attribute)))
158 				break;
159 		}
160 
161 		if (gFields[index].attribute != NULL) {
162 			if (!window)
163 				window = NewWindow();
164 
165 			while (arg[0] && arg[0] != ' ' && arg[0] != '=')
166 				arg++;
167 
168 			if (arg[0]) {
169 				arg++;
170 				window->SetField(index, arg);
171 			}
172 		}
173 	}
174 }
175 
176 
177 void
178 TPeopleApp::MessageReceived(BMessage *msg)
179 {
180 	switch (msg->what) {
181 		case M_NEW:
182 		case B_SILENT_RELAUNCH:
183 			NewWindow();
184 			break;
185 
186 		case M_WINDOW_QUITS:
187 			SavePreferences(msg);
188 			fWindowCount--;
189 			if (fWindowCount < 1)
190 				PostMessage(B_QUIT_REQUESTED);
191 			break;
192 
193 		default:
194 			BApplication::MessageReceived(msg);
195 	}
196 }
197 
198 
199 void
200 TPeopleApp::RefsReceived(BMessage *message)
201 {
202 	int32 index = 0;
203 
204 	while (message->HasRef("refs", index)) {
205 		entry_ref ref;
206 		message->FindRef("refs", index++, &ref);
207 
208 		TPeopleWindow* window = FindWindow(ref);
209 		if (window != NULL)
210 			window->Activate(true);
211 		else {
212 			BFile file(&ref, B_READ_ONLY);
213 			if (file.InitCheck() == B_OK)
214 				NewWindow(&ref);
215 		}
216 	}
217 }
218 
219 
220 void
221 TPeopleApp::ReadyToRun(void)
222 {
223 	if (fWindowCount < 1)
224 		NewWindow();
225 }
226 
227 
228 TPeopleWindow*
229 TPeopleApp::NewWindow(entry_ref *ref)
230 {
231 	TPeopleWindow *window;
232 
233 	window = new TPeopleWindow(fPosition, "New Person", ref);
234 	window->Show();
235 	fWindowCount++;
236 	fPosition.OffsetBy(20, 20);
237 
238 	if (fPosition.bottom > BScreen(B_MAIN_SCREEN_ID).Frame().bottom)
239 		fPosition.OffsetTo(fPosition.left, TITLE_BAR_HEIGHT);
240 	if (fPosition.right > BScreen(B_MAIN_SCREEN_ID).Frame().right)
241 		fPosition.OffsetTo(6, fPosition.top);
242 
243 	return window;
244 }
245 
246 
247 TPeopleWindow*
248 TPeopleApp::FindWindow(entry_ref ref)
249 {
250 	TPeopleWindow* window;
251 	int32 index = 0;
252 
253 	while ((window = (TPeopleWindow *)WindowAt(index++))) {
254 		if (window->FindView("PeopleView") != NULL && window->fRef && *window->fRef == ref)
255 			return window;
256 	}
257 	return NULL;
258 }
259 
260 
261 void
262 TPeopleApp::SavePreferences(BMessage* message)
263 {
264 	BRect frame;
265 	if (message->FindRect("frame", &frame) != B_OK)
266 		return;
267 
268 	BPoint leftTop = frame.LeftTop();
269 
270 	if (fPrefs) {
271 		fPrefs->Seek(0, 0);
272 		fPrefs->Write(&leftTop, sizeof(BPoint));
273 	}
274 }
275 
276