diff --git a/TODO.txt b/TODO.txt index 2819d51..0239ae1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,8 +2,6 @@ * This way, if the user edits the feed after it is enqueued but before processing, the changes will be applied. * Support for clearing queue -* Revamp configuration - * Fix saving, etc. * Show progress * With progress bar * Ran into a slight problem when trying to set the maxValue and @@ -11,7 +9,8 @@ crash every time, without fail. Even with float constants that work when used in MainWindow::_InitInterface. Weird, idk * With indicator in the feeds list -* Configurations +* File error-handling + * e.g., Utils.cpp's userFileError * Remove unnecessary `new`-- make sure to delete everything * Check if arg is a file or not (treat appropriately) * No hardcoded paths @@ -29,3 +28,6 @@ * Using a proper queue list would give faster results to Notifer about how many feeds are enqueued (so things *feel* faster) +* Open With support +* Open As support +* File extension support diff --git a/src/EntriesView.cpp b/src/EntriesView.cpp index f0857af..de701d0 100644 --- a/src/EntriesView.cpp +++ b/src/EntriesView.cpp @@ -10,10 +10,16 @@ #include #include #include +#include #include #include #include +#include + +#include "App.h" +#include "Util.h" + EntriesView::EntriesView(const char* name) : @@ -30,6 +36,7 @@ EntriesView::AttachedToWindow() fEntryFolderBrowseButton->SetTarget(this); fFileExtText->SetTarget(this); + fOpenAsAutoRadio->SetTarget(this); fOpenAsHtmlRadio->SetTarget(this); fOpenAsUrlRadio->SetTarget(this); fOpenWithSelectButton->SetTarget(this); @@ -41,9 +48,43 @@ EntriesView::MessageReceived(BMessage* msg) { switch (msg->what) { + case kEntryFolderText: + { + status_t result = ((App*)be_app)->fPreferences->SetEntryDir( + fEntryFolderText->Text()); + if (result != B_OK) + userFileError(result, fEntryFolderText->Text()); + break; + } + case kEntryExtText: + { + ((App*)be_app)->fPreferences->fEntryFileExt = fFileExtText->Text(); + break; + } + case kOpenHtmlRadio: + { + ((App*)be_app)->fPreferences->fOpenAs = kOpenAsHtml; + break; + } + case kOpenUrlRadio: + { + ((App*)be_app)->fPreferences->fOpenAs = kOpenAsUrl; + break; + } + case kOpenAutoRadio: + { + ((App*)be_app)->fPreferences->fOpenAs = kOpenAsAuto; + break; + } + case kOpenWithSelect: + { + ((App*)be_app)->fPreferences->SetEntryOpenWith( + fOpenWithMenuField->MenuItem()->Label()); + break; + } default: { -// BWindow::MessageReceived(msg); + BGroupView::MessageReceived(msg); break; } } @@ -58,28 +99,47 @@ EntriesView::_InitInterface() fSavingBox->SetLabel("Saving"); fEntryFolderLabel = new BStringView("entryFolderLabel", "Entry folder:"); - fEntryFolderText = new BTextControl("entryFolder", "", - "/boot/home/feeds/", new BMessage('ssss')); + fEntryFolderText = new BTextControl("entryFolder", "", "", + new BMessage(kEntryFolderText)); fEntryFolderBrowseButton = new BButton("entryFolderBrowse", "Browse…", - new BMessage('mmmm')); + new BMessage(kEntryFolderBrowse)); fFileExtLabel = new BStringView("fileExtLabel", "File extension:"); - fFileExtText = new BTextControl("fileExt", "", "", new BMessage('ffff')); + fFileExtText = new BTextControl("fileExt", "", "", + new BMessage(kEntryExtText)); // Opening fOpeningBox = new BBox("opening"); fOpeningBox->SetLabel("Opening"); fOpenAsLabel = new BStringView("openAsLabel", "Open as:"); - fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML", new BMessage('ii')); - fOpenAsUrlRadio = new BRadioButton("asUrl", "URL", new BMessage('ii')); + fOpenAsAutoRadio = new BRadioButton("asAuto", "Auto", + new BMessage(kOpenAutoRadio)); + fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML", + new BMessage(kOpenHtmlRadio)); + fOpenAsUrlRadio = new BRadioButton("asUrl", "URL", + new BMessage(kOpenUrlRadio)); fOpenWithLabel = new BStringView("openWithLabel", "Open with:"); fOpenWithMenu = new BPopUpMenu("openWith"); fOpenWithMenuField = new BMenuField("openWithMenu", NULL, fOpenWithMenu); - fOpenWithMenu->AddItem(new BMenuItem("WebPositive", new BMessage('wwww'))); fOpenWithSelectButton = new BButton("openWithSelect", "Select…", - new BMessage('mmmm')); + new BMessage(kOpenWithBrowse)); + + + // Display current settings + Preferences* prefs = ((App*)be_app)->fPreferences; + if (prefs->fOpenAs == kOpenAsHtml) + fOpenAsHtmlRadio->SetValue(B_CONTROL_ON); + else if (prefs->fOpenAs == kOpenAsUrl) + fOpenAsUrlRadio->SetValue(B_CONTROL_ON); + else + fOpenAsAutoRadio->SetValue(B_CONTROL_ON); + + fFileExtText->SetText(prefs->fEntryFileExt); + fEntryFolderText->SetText(prefs->EntryDir()); + + _PopulateOpenWithMenu(); BLayoutBuilder::Group<>(fSavingBox, B_HORIZONTAL) @@ -109,6 +169,7 @@ EntriesView::_InitInterface() .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) .SetInsets(0, 20, B_USE_ITEM_INSETS, 0) .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) + .Add(fOpenAsAutoRadio) .Add(fOpenAsHtmlRadio) .Add(fOpenAsUrlRadio) .AddGlue() @@ -130,3 +191,27 @@ EntriesView::_InitInterface() } +void +EntriesView::_PopulateOpenWithMenu() +{ + BString preferred = ((App*)be_app)->fPreferences->EntryOpenWith(); + BMimeType html("text/html"); + BStringList signatures; + BMessage types; + + html.GetSupportingApps(&types); + if (types.FindStrings("applications", &signatures) != B_OK) + return; + + for (int i = 0; i < signatures.CountStrings(); i++) { + BString string = signatures.StringAt(i); + if (string != preferred) + fOpenWithMenu->AddItem( + new BMenuItem(string, new BMessage(kOpenWithSelect))); + } + + fOpenWithMenu->AddItem( + new BMenuItem(preferred, new BMessage(kOpenWithSelect)), 0); +} + + diff --git a/src/EntriesView.h b/src/EntriesView.h index f3ddaf1..a60d720 100644 --- a/src/EntriesView.h +++ b/src/EntriesView.h @@ -18,6 +18,19 @@ class BStringView; class BTextControl; +enum +{ + kEntryFolderText = 'txef', + kEntryFolderBrowse = 'tbef', + kEntryExtText = 'txee', + kOpenHtmlRadio = 'rdow', + kOpenUrlRadio = 'roow', + kOpenAutoRadio = 'raow', + kOpenWithSelect = 'mnow', + kOpenWithBrowse = 'tbow' +}; + + class EntriesView : public BGroupView { public: EntriesView(const char* name); @@ -27,6 +40,7 @@ public: private: void _InitInterface(); + void _PopulateOpenWithMenu(); BBox* fSavingBox; @@ -38,6 +52,7 @@ private: BBox* fOpeningBox; BStringView* fOpenAsLabel; + BRadioButton* fOpenAsAutoRadio; BRadioButton* fOpenAsHtmlRadio; BRadioButton* fOpenAsUrlRadio; BStringView* fOpenWithLabel; diff --git a/src/FeedController.cpp b/src/FeedController.cpp index 02aa593..b7d2c89 100644 --- a/src/FeedController.cpp +++ b/src/FeedController.cpp @@ -150,7 +150,7 @@ FeedController::_ParseLoop(void* ignored) BList entries; BString feedTitle; BUrl feedUrl = feedBuffer->GetXmlUrl(); - BDirectory outDir = BDirectory(((App*)be_app)->fPreferences->fEntryDir); + BDirectory outDir = BDirectory(((App*)be_app)->fPreferences->EntryDir()); if (feedBuffer->IsAtom()) { AtomFeed* feed = (AtomFeed*)malloc(sizeof(AtomFeed)); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 46b9af8..a849168 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -47,6 +47,11 @@ MainWindow::MessageReceived(BMessage *msg) fFeedsView->MessageReceived(msg); break; } + case kOpenWithSelect: + { + fEntriesView->MessageReceived(msg); + break; + } case kProgress: { int32 max = 0; diff --git a/src/Notifier.cpp b/src/Notifier.cpp index 39a107a..b4f1070 100644 --- a/src/Notifier.cpp +++ b/src/Notifier.cpp @@ -73,7 +73,7 @@ Notifier::MessageReceived(BMessage* msg) void Notifier::_NewEntryNotification(BString feedName, int32 entryCount) { - if (((App*)be_app)->fPreferences->NotifyOnNew() == false) + if (((App*)be_app)->fPreferences->fNewNotify == false) return; BNotification notifyNew(B_INFORMATION_NOTIFICATION); @@ -94,7 +94,7 @@ Notifier::_NewEntryNotification(BString feedName, int32 entryCount) void Notifier::_ParseFailNotification(BString feedUrl) { - if (((App*)be_app)->fPreferences->NotifyOnFailure() == false) + if (((App*)be_app)->fPreferences->fFailureNotify == false) return; BNotification notifyError(B_ERROR_NOTIFICATION); @@ -114,7 +114,7 @@ Notifier::_ParseFailNotification(BString feedUrl) void Notifier::_DownloadFailNotification(BString feedUrl) { - if (((App*)be_app)->fPreferences->NotifyOnFailure() == false) + if (((App*)be_app)->fPreferences->fFailureNotify == false) return; BNotification notifyError(B_ERROR_NOTIFICATION); diff --git a/src/Preferences.cpp b/src/Preferences.cpp index 21ec035..4eb05d5 100644 --- a/src/Preferences.cpp +++ b/src/Preferences.cpp @@ -34,8 +34,9 @@ Preferences::Load() fEntryDir = BString(storage.GetString("entryDir", "/boot/home/feeds/")); fEntryFileExt = BString(storage.GetString("entryExt", "")); - fOpenAsHtml = storage.GetBool("openAsHtml", false); - fOpenWith = BString(storage.GetString("openWith", "WebPositive")); + fOpenAs = storage.GetInt8("openAs", kOpenAsUrl); + fOpenWith = BString(storage.GetString("openWith", + "application/x-vnd.Haiku-WebPositive")); fNewNotify = storage.GetBool("notifyNew", true); fFailureNotify = storage.GetBool("notifyFailure", true); @@ -67,8 +68,8 @@ Preferences::Save() storage.AddString("entryDir", fEntryDir.String()); storage.AddString("entryExt", fEntryFileExt.String()); - storage.AddBool("openAsHtml", fOpenAsHtml); storage.AddString("openWith", fOpenWith.String()); + storage.AddInt8("openAs", fOpenAs); storage.AddBool("notifyNew", fNewNotify); storage.AddBool("notifyFailure", fFailureNotify); @@ -109,31 +110,38 @@ Preferences::SetUpdateIntervalIndex(int8 index) } -bool -Preferences::NotifyOnFailure() +BString +Preferences::EntryDir() { - return fFailureNotify; + return fEntryDir; } -bool -Preferences::NotifyOnNew() +status_t +Preferences::SetEntryDir(const char* path) { - return fNewNotify; + status_t testStatus = BEntry(path).InitCheck(); + if (testStatus == B_OK) + fEntryDir = BString(path); + return testStatus; } -void -Preferences::SetNotifyOnFailure(bool value) +BString +Preferences::EntryOpenWith() { - fFailureNotify = value; + return fOpenWith; } -void -Preferences::SetNotifyOnNew(bool value) +status_t +Preferences::SetEntryOpenWith(const char* binPath) { - fNewNotify = value; +// status_t testStatus = BEntry(binPath).InitCheck(); +// if (testStatus == B_OK) + fOpenWith = BString(binPath); + return B_OK; +// return testStatus; } diff --git a/src/Preferences.h b/src/Preferences.h index 1c564f9..1b7111e 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -5,13 +5,19 @@ #ifndef PREFS_H #define PREFS_H - #include #include #include -const int64 HOUR_IN_MICROSECONDS = 3600000000; +static const int64 HOUR_IN_MICROSECONDS = 3600000000; + +enum +{ + kOpenAsAuto = 0, + kOpenAsHtml = 1, + kOpenAsUrl = 2 +}; class Preferences { @@ -26,23 +32,23 @@ public: int UpdateIntervalIndex(); void SetUpdateIntervalIndex(int8 index); - bool NotifyOnFailure(); - bool NotifyOnNew(); - void SetNotifyOnFailure(bool value); - void SetNotifyOnNew(bool value); + BString EntryDir(); + status_t SetEntryDir(const char* path); + + BString EntryOpenWith(); + status_t SetEntryOpenWith(const char* binPath); + - - BString fEntryDir; BString fEntryFileExt; - bool fOpenAsHtml; - BString fOpenWith; - + bool fNewNotify; + bool fFailureNotify; + int8 fOpenAs; private: int8 fUpdateInterval; - bool fNewNotify; - bool fFailureNotify; + BString fEntryDir; + BString fOpenWith; }; diff --git a/src/UpdatesView.cpp b/src/UpdatesView.cpp index 26c82bb..a98d662 100644 --- a/src/UpdatesView.cpp +++ b/src/UpdatesView.cpp @@ -42,17 +42,17 @@ UpdatesView::MessageReceived(BMessage* msg) case kNotifyNewCheckbox: { if (fNotifyNewCheck->Value() == B_CONTROL_ON) - ((App*)be_app)->fPreferences->SetNotifyOnNew(true); + ((App*)be_app)->fPreferences->fNewNotify = true; else - ((App*)be_app)->fPreferences->SetNotifyOnNew(false); + ((App*)be_app)->fPreferences->fNewNotify = false; break; } case kNotifyFailCheckbox: { if (fNotifyFailCheck->Value() == B_CONTROL_ON) - ((App*)be_app)->fPreferences->SetNotifyOnFailure(true); + ((App*)be_app)->fPreferences->fFailureNotify = true; else - ((App*)be_app)->fPreferences->SetNotifyOnFailure(false); + ((App*)be_app)->fPreferences->fFailureNotify = false; break; } case kIntervalChanged: @@ -82,7 +82,6 @@ UpdatesView::_InitInterface() fNotifyFailCheck = new BCheckBox("errorNotify", "Notify about update failures", new BMessage(kNotifyFailCheckbox)); - // Update scheduling fSchedulingBox = new BBox("scheduling"); fSchedulingBox->SetLabel("Scheduling"); @@ -96,13 +95,15 @@ UpdatesView::_InitInterface() fIntervalSlider->SetLimitLabels("Never", "24 hours"); fIntervalSlider->SetModificationMessage(new BMessage('iiii')); + // Display current settings - if (((App*)be_app)->fPreferences->NotifyOnNew() == true) + Preferences* prefs = ((App*)be_app)->fPreferences; + if (prefs->fNewNotify == true) fNotifyNewCheck->SetValue(B_CONTROL_ON); - if (((App*)be_app)->fPreferences->NotifyOnFailure() == true) + if (prefs->fFailureNotify == true) fNotifyFailCheck->SetValue(B_CONTROL_ON); - fIntervalSlider->SetValue(((App*)be_app)->fPreferences->UpdateIntervalIndex()); + fIntervalSlider->SetValue(prefs->UpdateIntervalIndex()); _UpdateIntervalLabel(); diff --git a/src/Util.cpp b/src/Util.cpp index c830bcb..a137da7 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -140,3 +140,9 @@ fetch(BUrl url, BDataIO* reply, BString* hash, int timeout) } +void +userFileError(status_t status, const char* path) +{ +} + + diff --git a/src/Util.h b/src/Util.h index 1fba57b..b2d6347 100644 --- a/src/Util.h +++ b/src/Util.h @@ -27,6 +27,8 @@ BString urlToFilename(BUrl url); int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout); +void userFileError(status_t status, const char* path); -#endif + +#endif // UTIL_H