BPicture: Fix archive constructor.
[haiku.git] / src / kits / mail / MailSettings.cpp
blob98984203ad121252aee831a89a458bb7dc5b9cb4
1 /*
2 * Copyright 2004-2015, Haiku Inc. All rights reserved.
3 * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
5 * Distributed under the terms of the MIT License.
6 */
9 //! The mail daemon's settings
12 #include <MailSettings.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
18 #include <Directory.h>
19 #include <Entry.h>
20 #include <File.h>
21 #include <FindDirectory.h>
22 #include <MailDaemon.h>
23 #include <Message.h>
24 #include <Messenger.h>
25 #include <Path.h>
26 #include <String.h>
27 #include <Window.h>
29 #include <MailPrivate.h>
32 // #pragma mark - BMailSettings
35 BMailSettings::BMailSettings()
37 Reload();
41 BMailSettings::~BMailSettings()
46 status_t
47 BMailSettings::InitCheck() const
49 return B_OK;
53 status_t
54 BMailSettings::Save()
56 BPath path;
57 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
58 if (status != B_OK) {
59 fprintf(stderr, "Couldn't find user settings directory: %s\n",
60 strerror(status));
61 return status;
64 path.Append("Mail");
66 status = BPrivate::WriteMessageFile(fData, path, "new_mail_daemon");
67 if (status != B_OK)
68 return status;
70 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(
71 BPrivate::kMsgSettingsUpdated);
72 return B_OK;
76 status_t
77 BMailSettings::Reload()
79 // Try directories from most specific to least
80 directory_which which[] = {
81 B_USER_SETTINGS_DIRECTORY,
82 B_SYSTEM_SETTINGS_DIRECTORY};
83 status_t status = B_ENTRY_NOT_FOUND;
85 for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
86 BPath path;
87 status = find_directory(which[i], &path);
88 if (status != B_OK)
89 continue;
91 path.Append("Mail/new_mail_daemon");
92 BFile file;
93 status = file.SetTo(path.Path(), B_READ_ONLY);
94 if (status != B_OK)
95 continue;
97 // read settings
98 BMessage settings;
99 status = settings.Unflatten(&file);
100 if (status != B_OK) {
101 fprintf(stderr, "Couldn't read settings from '%s': %s\n",
102 path.Path(), strerror(status));
103 continue;
106 // clobber old settings
107 fData = settings;
108 return B_OK;
111 return status;
115 // # pragma mark - Global settings
118 int32
119 BMailSettings::WindowFollowsCorner()
121 return fData.FindInt32("WindowFollowsCorner");
125 void
126 BMailSettings::SetWindowFollowsCorner(int32 whichCorner)
128 if (fData.ReplaceInt32("WindowFollowsCorner", whichCorner) != B_OK)
129 fData.AddInt32("WindowFollowsCorner", whichCorner);
133 uint32
134 BMailSettings::ShowStatusWindow()
136 int32 showStatusWindow;
137 if (fData.FindInt32("ShowStatusWindow", &showStatusWindow) != B_OK) {
138 // show during send and receive
139 return 2;
142 return showStatusWindow;
146 void
147 BMailSettings::SetShowStatusWindow(uint32 mode)
149 if (fData.ReplaceInt32("ShowStatusWindow", mode) != B_OK)
150 fData.AddInt32("ShowStatusWindow", mode);
154 bool
155 BMailSettings::DaemonAutoStarts()
157 return fData.FindBool("DaemonAutoStarts");
161 void
162 BMailSettings::SetDaemonAutoStarts(bool startIt)
164 if (fData.ReplaceBool("DaemonAutoStarts", startIt) != B_OK)
165 fData.AddBool("DaemonAutoStarts", startIt);
169 BRect
170 BMailSettings::ConfigWindowFrame()
172 return fData.FindRect("ConfigWindowFrame");
176 void
177 BMailSettings::SetConfigWindowFrame(BRect frame)
179 if (fData.ReplaceRect("ConfigWindowFrame", frame) != B_OK)
180 fData.AddRect("ConfigWindowFrame", frame);
184 BRect
185 BMailSettings::StatusWindowFrame()
187 BRect frame;
188 if (fData.FindRect("StatusWindowFrame", &frame) != B_OK)
189 return BRect(100, 100, 200, 120);
191 return frame;
195 void
196 BMailSettings::SetStatusWindowFrame(BRect frame)
198 if (fData.ReplaceRect("StatusWindowFrame", frame) != B_OK)
199 fData.AddRect("StatusWindowFrame", frame);
203 int32
204 BMailSettings::StatusWindowWorkspaces()
206 uint32 workspaces;
207 if (fData.FindInt32("StatusWindowWorkSpace", (int32*)&workspaces) != B_OK)
208 return B_ALL_WORKSPACES;
210 return workspaces;
214 void
215 BMailSettings::SetStatusWindowWorkspaces(int32 workspace)
217 if (fData.ReplaceInt32("StatusWindowWorkSpace", workspace) != B_OK)
218 fData.AddInt32("StatusWindowWorkSpace", workspace);
220 BMessage msg('wsch');
221 msg.AddInt32("StatusWindowWorkSpace",workspace);
222 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(&msg);
226 int32
227 BMailSettings::StatusWindowLook()
229 return fData.FindInt32("StatusWindowLook");
233 void
234 BMailSettings::SetStatusWindowLook(int32 look)
236 if (fData.ReplaceInt32("StatusWindowLook", look) != B_OK)
237 fData.AddInt32("StatusWindowLook", look);
239 BMessage msg('lkch');
240 msg.AddInt32("StatusWindowLook", look);
241 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(&msg);
245 bigtime_t
246 BMailSettings::AutoCheckInterval()
248 bigtime_t value;
249 if (fData.FindInt64("AutoCheckInterval", &value) != B_OK) {
250 // every 5 min
251 return 5 * 60 * 1000 * 1000;
253 return value;
257 void
258 BMailSettings::SetAutoCheckInterval(bigtime_t interval)
260 if (fData.ReplaceInt64("AutoCheckInterval", interval) != B_OK)
261 fData.AddInt64("AutoCheckInterval", interval);
265 bool
266 BMailSettings::CheckOnlyIfPPPUp()
268 return fData.FindBool("CheckOnlyIfPPPUp");
272 void
273 BMailSettings::SetCheckOnlyIfPPPUp(bool yes)
275 if (fData.ReplaceBool("CheckOnlyIfPPPUp", yes))
276 fData.AddBool("CheckOnlyIfPPPUp", yes);
280 bool
281 BMailSettings::SendOnlyIfPPPUp()
283 return fData.FindBool("SendOnlyIfPPPUp");
287 void
288 BMailSettings::SetSendOnlyIfPPPUp(bool yes)
290 if (fData.ReplaceBool("SendOnlyIfPPPUp", yes))
291 fData.AddBool("SendOnlyIfPPPUp", yes);
295 int32
296 BMailSettings::DefaultOutboundAccount()
298 return fData.FindInt32("DefaultOutboundAccount");
302 void
303 BMailSettings::SetDefaultOutboundAccount(int32 to)
305 if (fData.ReplaceInt32("DefaultOutboundAccount", to) != B_OK)
306 fData.AddInt32("DefaultOutboundAccount", to);
310 // #pragma mark -
313 BMailAccounts::BMailAccounts()
315 BPath path;
316 status_t status = AccountsPath(path);
317 if (status != B_OK)
318 return;
320 BDirectory dir(path.Path());
321 if (dir.InitCheck() != B_OK)
322 return;
324 std::vector<time_t> creationTimeList;
325 BEntry entry;
326 while (dir.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
327 BNode node(&entry);
328 time_t creationTime;
329 if (node.GetCreationTime(&creationTime) != B_OK)
330 continue;
332 BMailAccountSettings* account = new BMailAccountSettings(entry);
333 if (account->InitCheck() != B_OK) {
334 delete account;
335 continue;
338 // sort by creation time
339 int insertIndex = -1;
340 for (unsigned int i = 0; i < creationTimeList.size(); i++) {
341 if (creationTimeList[i] > creationTime) {
342 insertIndex = i;
343 break;
346 if (insertIndex < 0) {
347 fAccounts.AddItem(account);
348 creationTimeList.push_back(creationTime);
349 } else {
350 fAccounts.AddItem(account, insertIndex);
351 creationTimeList.insert(creationTimeList.begin() + insertIndex,
352 creationTime);
358 status_t
359 BMailAccounts::AccountsPath(BPath& path)
361 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
362 if (status != B_OK)
363 return status;
364 return path.Append("Mail/accounts");
368 BMailAccounts::~BMailAccounts()
370 for (int i = 0; i < fAccounts.CountItems(); i++)
371 delete fAccounts.ItemAt(i);
375 int32
376 BMailAccounts::CountAccounts()
378 return fAccounts.CountItems();
382 BMailAccountSettings*
383 BMailAccounts::AccountAt(int32 index)
385 return fAccounts.ItemAt(index);
389 BMailAccountSettings*
390 BMailAccounts::AccountByID(int32 id)
392 for (int i = 0; i < fAccounts.CountItems(); i++) {
393 BMailAccountSettings* account = fAccounts.ItemAt(i);
394 if (account->AccountID() == id)
395 return account;
397 return NULL;
401 BMailAccountSettings*
402 BMailAccounts::AccountByName(const char* name)
404 for (int i = 0; i < fAccounts.CountItems(); i++) {
405 BMailAccountSettings* account = fAccounts.ItemAt(i);
406 if (strcmp(account->Name(), name) == 0)
407 return account;
409 return NULL;
413 // #pragma mark -
416 BMailAddOnSettings::BMailAddOnSettings()
421 BMailAddOnSettings::~BMailAddOnSettings()
426 status_t
427 BMailAddOnSettings::Load(const BMessage& message)
429 const char* pathString = NULL;
430 if (message.FindString("add-on path", &pathString) != B_OK)
431 return B_BAD_VALUE;
433 BPath path(pathString);
434 if (!path.IsAbsolute()) {
435 directory_which which[] = {
436 B_USER_ADDONS_DIRECTORY,
437 B_SYSTEM_ADDONS_DIRECTORY
440 for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
441 status_t status = find_directory(which[i], &path);
442 if (status != B_OK)
443 continue;
445 path.Append("mail_daemon");
446 path.Append(pathString);
448 if (BEntry(path.Path()).Exists())
449 break;
453 status_t status = get_ref_for_path(path.Path(), &fRef);
454 if (status != B_OK)
455 return status;
457 BMessage settings;
458 message.FindMessage("settings", &settings);
460 MakeEmpty();
461 Append(settings);
463 fOriginalSettings = *this;
464 fOriginalRef = fRef;
465 return B_OK;
469 status_t
470 BMailAddOnSettings::Save(BMessage& message)
472 BPath path(&fRef);
473 status_t status = message.AddString("add-on path", _RelativizePath(path));
474 if (status == B_OK)
475 status = message.AddMessage("settings", this);
476 if (status != B_OK)
477 return status;
479 fOriginalSettings = *this;
480 fOriginalRef = fRef;
481 return B_OK;
485 void
486 BMailAddOnSettings::SetAddOnRef(const entry_ref& ref)
488 fRef = ref;
492 const entry_ref&
493 BMailAddOnSettings::AddOnRef() const
495 return fRef;
499 bool
500 BMailAddOnSettings::HasBeenModified() const
502 return fRef != fOriginalRef
503 || !fOriginalSettings.HasSameData(*this, true, true);
507 /*! Cuts off the ".../add-ons/mail_daemon" part of the provided \a path
508 in case it exists. Otherwise, the complete path will be returned.
510 const char*
511 BMailAddOnSettings::_RelativizePath(const BPath& path) const
513 const char* string = path.Path();
514 const char* parentDirectory = "/mail_daemon/";
515 const char* at = strstr(string, parentDirectory);
516 if (at == NULL)
517 return string;
519 return at + strlen(parentDirectory);
523 // #pragma mark -
526 BMailProtocolSettings::BMailProtocolSettings()
528 fFiltersSettings(5, true)
533 BMailProtocolSettings::~BMailProtocolSettings()
538 status_t
539 BMailProtocolSettings::Load(const BMessage& message)
541 status_t status = BMailAddOnSettings::Load(message);
542 if (status != B_OK)
543 return status;
545 type_code typeFound;
546 int32 countFound;
547 message.GetInfo("filters", &typeFound, &countFound);
548 if (typeFound != B_MESSAGE_TYPE)
549 return B_BAD_VALUE;
551 for (int i = 0; i < countFound; i++) {
552 int32 index = AddFilterSettings();
553 if (index < 0)
554 return B_NO_MEMORY;
556 BMailAddOnSettings* filterSettings = fFiltersSettings.ItemAt(index);
558 BMessage filterMessage;
559 message.FindMessage("filters", i, &filterMessage);
560 if (filterSettings->Load(filterMessage) != B_OK)
561 RemoveFilterSettings(index);
563 return B_OK;
567 status_t
568 BMailProtocolSettings::Save(BMessage& message)
570 status_t status = BMailAddOnSettings::Save(message);
571 if (status != B_OK)
572 return status;
574 for (int i = 0; i < CountFilterSettings(); i++) {
575 BMessage filter;
576 BMailAddOnSettings* filterSettings = fFiltersSettings.ItemAt(i);
577 filterSettings->Save(filter);
578 message.AddMessage("filters", &filter);
580 return B_OK;
584 int32
585 BMailProtocolSettings::CountFilterSettings() const
587 return fFiltersSettings.CountItems();
591 int32
592 BMailProtocolSettings::AddFilterSettings(const entry_ref* ref)
594 BMailAddOnSettings* filterSettings = new BMailAddOnSettings();
595 if (ref != NULL)
596 filterSettings->SetAddOnRef(*ref);
598 if (fFiltersSettings.AddItem(filterSettings))
599 return fFiltersSettings.CountItems() - 1;
601 delete filterSettings;
602 return -1;
606 void
607 BMailProtocolSettings::RemoveFilterSettings(int32 index)
609 fFiltersSettings.RemoveItemAt(index);
613 bool
614 BMailProtocolSettings::MoveFilterSettings(int32 from, int32 to)
616 if (from < 0 || from >= (int32)CountFilterSettings() || to < 0
617 || to >= (int32)CountFilterSettings())
618 return false;
619 if (from == to)
620 return true;
622 BMailAddOnSettings* settings = fFiltersSettings.RemoveItemAt(from);
623 fFiltersSettings.AddItem(settings, to);
624 return true;
628 BMailAddOnSettings*
629 BMailProtocolSettings::FilterSettingsAt(int32 index) const
631 return fFiltersSettings.ItemAt(index);
635 bool
636 BMailProtocolSettings::HasBeenModified() const
638 if (BMailAddOnSettings::HasBeenModified())
639 return true;
640 for (int32 i = 0; i < CountFilterSettings(); i++) {
641 if (FilterSettingsAt(i)->HasBeenModified())
642 return true;
644 return false;
648 // #pragma mark -
651 BMailAccountSettings::BMailAccountSettings()
653 fStatus(B_OK),
654 fInboundEnabled(true),
655 fOutboundEnabled(true),
656 fModified(true)
658 fAccountID = real_time_clock();
662 BMailAccountSettings::BMailAccountSettings(BEntry account)
664 fAccountFile(account),
665 fModified(false)
667 fStatus = Reload();
671 BMailAccountSettings::~BMailAccountSettings()
677 void
678 BMailAccountSettings::SetAccountID(int32 id)
680 fModified = true;
681 fAccountID = id;
685 int32
686 BMailAccountSettings::AccountID() const
688 return fAccountID;
692 void
693 BMailAccountSettings::SetName(const char* name)
695 fModified = true;
696 fAccountName = name;
700 const char*
701 BMailAccountSettings::Name() const
703 return fAccountName;
707 void
708 BMailAccountSettings::SetRealName(const char* realName)
710 fModified = true;
711 fRealName = realName;
715 const char*
716 BMailAccountSettings::RealName() const
718 return fRealName;
722 void
723 BMailAccountSettings::SetReturnAddress(const char* returnAddress)
725 fModified = true;
726 fReturnAdress = returnAddress;
730 const char*
731 BMailAccountSettings::ReturnAddress() const
733 return fReturnAdress;
737 bool
738 BMailAccountSettings::SetInboundAddOn(const char* name)
740 BPath path;
741 status_t status = find_directory(B_BEOS_ADDONS_DIRECTORY, &path);
742 if (status != B_OK)
743 return false;
744 path.Append("mail_daemon");
745 path.Append("inbound_protocols");
746 path.Append(name);
747 entry_ref ref;
748 get_ref_for_path(path.Path(), &ref);
749 fInboundSettings.SetAddOnRef(ref);
751 return true;
755 bool
756 BMailAccountSettings::SetOutboundAddOn(const char* name)
758 BPath path;
759 status_t status = find_directory(B_BEOS_ADDONS_DIRECTORY, &path);
760 if (status != B_OK)
761 return false;
762 path.Append("mail_daemon");
763 path.Append("outbound_protocols");
764 path.Append(name);
765 entry_ref ref;
766 get_ref_for_path(path.Path(), &ref);
767 fOutboundSettings.SetAddOnRef(ref);
769 return true;
773 const entry_ref&
774 BMailAccountSettings::InboundAddOnRef() const
776 return fInboundSettings.AddOnRef();
780 const entry_ref&
781 BMailAccountSettings::OutboundAddOnRef() const
783 return fOutboundSettings.AddOnRef();
787 BMailProtocolSettings&
788 BMailAccountSettings::InboundSettings()
790 return fInboundSettings;
794 const BMailProtocolSettings&
795 BMailAccountSettings::InboundSettings() const
797 return fInboundSettings;
801 BMailProtocolSettings&
802 BMailAccountSettings::OutboundSettings()
804 return fOutboundSettings;
808 const BMailProtocolSettings&
809 BMailAccountSettings::OutboundSettings() const
811 return fOutboundSettings;
815 bool
816 BMailAccountSettings::HasInbound()
818 return BEntry(&fInboundSettings.AddOnRef()).Exists();
822 bool
823 BMailAccountSettings::HasOutbound()
825 return BEntry(&fOutboundSettings.AddOnRef()).Exists();
829 void
830 BMailAccountSettings::SetInboundEnabled(bool enabled)
832 fInboundEnabled = enabled;
833 fModified = true;
837 bool
838 BMailAccountSettings::IsInboundEnabled() const
840 return fInboundEnabled;
844 void
845 BMailAccountSettings::SetOutboundEnabled(bool enabled)
847 fOutboundEnabled = enabled;
848 fModified = true;
852 bool
853 BMailAccountSettings::IsOutboundEnabled() const
855 return fOutboundEnabled;
859 status_t
860 BMailAccountSettings::Reload()
862 BFile file(&fAccountFile, B_READ_ONLY);
863 status_t status = file.InitCheck();
864 if (status != B_OK)
865 return status;
866 BMessage settings;
867 settings.Unflatten(&file);
869 int32 id;
870 if (settings.FindInt32("id", &id) == B_OK)
871 fAccountID = id;
872 settings.FindString("name", &fAccountName);
873 settings.FindString("real_name", &fRealName);
874 settings.FindString("return_address", &fReturnAdress);
876 BMessage inboundSettings;
877 settings.FindMessage("inbound", &inboundSettings);
878 fInboundSettings.Load(inboundSettings);
879 BMessage outboundSettings;
880 settings.FindMessage("outbound", &outboundSettings);
881 fOutboundSettings.Load(outboundSettings);
883 if (settings.FindBool("inbound_enabled", &fInboundEnabled) != B_OK)
884 fInboundEnabled = true;
885 if (settings.FindBool("outbound_enabled", &fOutboundEnabled) != B_OK)
886 fOutboundEnabled = true;
888 fModified = false;
889 return B_OK;
893 status_t
894 BMailAccountSettings::Save()
896 fModified = false;
898 BMessage settings;
899 settings.AddInt32("id", fAccountID);
900 settings.AddString("name", fAccountName);
901 settings.AddString("real_name", fRealName);
902 settings.AddString("return_address", fReturnAdress);
904 BMessage inboundSettings;
905 fInboundSettings.Save(inboundSettings);
906 settings.AddMessage("inbound", &inboundSettings);
907 BMessage outboundSettings;
908 fOutboundSettings.Save(outboundSettings);
909 settings.AddMessage("outbound", &outboundSettings);
911 settings.AddBool("inbound_enabled", fInboundEnabled);
912 settings.AddBool("outbound_enabled", fOutboundEnabled);
914 status_t status = _CreateAccountFilePath();
915 if (status != B_OK)
916 return status;
918 BFile file(&fAccountFile, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
919 status = file.InitCheck();
920 if (status != B_OK)
921 return status;
922 return settings.Flatten(&file);
926 status_t
927 BMailAccountSettings::Delete()
929 return fAccountFile.Remove();
933 bool
934 BMailAccountSettings::HasBeenModified() const
936 return fModified
937 || fInboundSettings.HasBeenModified()
938 || fOutboundSettings.HasBeenModified();
942 const BEntry&
943 BMailAccountSettings::AccountFile() const
945 return fAccountFile;
949 status_t
950 BMailAccountSettings::_CreateAccountFilePath()
952 BPath path;
953 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
954 if (status != B_OK)
955 return status;
956 path.Append("Mail/accounts");
957 create_directory(path.Path(), 777);
959 if (fAccountFile.InitCheck() == B_OK)
960 return B_OK;
962 BString fileName = fAccountName;
963 if (fileName == "")
964 fileName << fAccountID;
965 for (int i = 0; ; i++) {
966 BString testFileName = fileName;
967 if (i != 0) {
968 testFileName += "_";
969 testFileName << i;
971 BPath testPath(path);
972 testPath.Append(testFileName);
973 BEntry testEntry(testPath.Path());
974 if (!testEntry.Exists()) {
975 fileName = testFileName;
976 break;
980 path.Append(fileName);
981 return fAccountFile.SetTo(path.Path());