xref: /haiku/src/apps/people/PeopleApp.cpp (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 /*
2  * Copyright 2005, 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, NULL }
47 };
48 
49 
50 TPeopleApp::TPeopleApp(void)
51 	: BApplication(APP_SIG),
52 	fHaveWindow(false)
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 		BBitmap largeIcon(BRect(0, 0, B_LARGE_ICON - 1, B_LARGE_ICON - 1), B_CMAP8);
110 		BBitmap miniIcon(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_CMAP8);
111 
112 		mime.Install();
113 		largeIcon.SetBits(kLargePersonIcon, largeIcon.BitsLength(), 0, B_CMAP8);
114 		miniIcon.SetBits(kSmallPersonIcon, miniIcon.BitsLength(), 0, B_CMAP8);
115 		mime.SetShortDescription("Person");
116 		mime.SetLongDescription("Contact information for a person.");
117 		mime.SetIcon(&largeIcon, B_LARGE_ICON);
118 		mime.SetIcon(&miniIcon, B_MINI_ICON);
119 		mime.SetPreferredApp(APP_SIG);
120 
121 		// add relevant person fields to meta-mime type
122 
123 		BMessage fields;
124 		for (int32 i = 0; gFields[i].attribute; i++) {
125 			fields.AddString("attr:public_name", gFields[i].name);
126 			fields.AddString("attr:name", gFields[i].attribute);
127 			fields.AddInt32("attr:type", B_STRING_TYPE);
128 			fields.AddBool("attr:viewable", true);
129 			fields.AddBool("attr:editable", true);
130 			fields.AddInt32("attr:width", gFields[i].width);
131 			fields.AddInt32("attr:alignment", B_ALIGN_LEFT);
132 			fields.AddBool("attr:extra", false);
133 		}
134 
135 		mime.SetAttrInfo(&fields);
136 	}
137 }
138 
139 
140 TPeopleApp::~TPeopleApp(void)
141 {
142 	delete fPrefs;
143 }
144 
145 
146 void
147 TPeopleApp::AboutRequested(void)
148 {
149 	(new BAlert("", "...by Robert Polic", "Big Deal"))->Go();
150 }
151 
152 
153 void
154 TPeopleApp::ArgvReceived(int32 argc, char **argv)
155 {
156 	TPeopleWindow* window = NULL;
157 
158 	for (int32 loop = 1; loop < argc; loop++) {
159 		char* arg = argv[loop];
160 
161 		int32 index;
162 		for (index = 0; gFields[index].attribute; index++) {
163 			if (!strncmp(gFields[index].attribute, arg, strlen(gFields[index].attribute)))
164 				break;
165 		}
166 
167 		if (gFields[index].attribute != NULL) {
168 			if (!window)
169 				window = NewWindow();
170 
171 			while (arg[0] && arg[0] != ' ' && arg[0] != '=')
172 				arg++;
173 
174 			if (arg[0]) {
175 				arg++;
176 				window->SetField(index, arg);
177 			}
178 		}
179 	}
180 }
181 
182 
183 void
184 TPeopleApp::MessageReceived(BMessage *msg)
185 {
186 	switch (msg->what) {
187 		case M_NEW:
188 			NewWindow();
189 			break;
190 
191 		default:
192 			BApplication::MessageReceived(msg);
193 	}
194 }
195 
196 
197 void
198 TPeopleApp::RefsReceived(BMessage *message)
199 {
200 	int32 index = 0;
201 
202 	while (message->HasRef("refs", index)) {
203 		entry_ref ref;
204 		message->FindRef("refs", index++, &ref);
205 
206 		TPeopleWindow* window = FindWindow(ref);
207 		if (window != NULL)
208 			window->Activate(true);
209 		else {
210 			BFile file(&ref, B_READ_ONLY);
211 			if (file.InitCheck() == B_OK)
212 				NewWindow(&ref);
213 		}
214 	}
215 }
216 
217 
218 void
219 TPeopleApp::ReadyToRun(void)
220 {
221 	if (!fHaveWindow)
222 		NewWindow();
223 }
224 
225 
226 TPeopleWindow*
227 TPeopleApp::NewWindow(entry_ref *ref)
228 {
229 	TPeopleWindow *window;
230 
231 	window = new TPeopleWindow(fPosition, "New Person", ref);
232 	window->Show();
233 	fHaveWindow = true;
234 	fPosition.OffsetBy(20, 20);
235 
236 	if (fPosition.bottom > BScreen(B_MAIN_SCREEN_ID).Frame().bottom)
237 		fPosition.OffsetTo(fPosition.left, TITLE_BAR_HEIGHT);
238 	if (fPosition.right > BScreen(B_MAIN_SCREEN_ID).Frame().right)
239 		fPosition.OffsetTo(6, fPosition.top);
240 
241 	return window;
242 }
243 
244 
245 TPeopleWindow*
246 TPeopleApp::FindWindow(entry_ref ref)
247 {
248 	TPeopleWindow* window;
249 	int32 index = 0;
250 
251 	while ((window = (TPeopleWindow *)WindowAt(index++))) {
252 		if (window->FindView("PeopleView") != NULL && window->fRef && *window->fRef == ref)
253 			return window;
254 	}
255 	return NULL;
256 }
257