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