diff --git a/Makefile b/Makefile index 3fd0ee0..4833bf7 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,8 @@ SRCS = \ # Specify the resource definition files to use. Full or relative paths can be # used. -RDEFS = # \ - # src/Pogger.rdef \ +RDEFS = \ + src/Pogger.rdef \ # Specify the resource files to use. Full or relative paths can be used. diff --git a/TODO.txt b/TODO.txt index b6907c3..88a08d1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,8 @@ Important Features: -* Open With support * Open As support * File extension support +* Show download progress/failures in FeedView's feedlist +* Update FeedView's feedlist when feeds added/removed * Show in desktray * Make archivable * Get menu working @@ -13,6 +14,7 @@ Important improvements: * Proper queue list (see Multiple downloads at once?) * No hardcoded paths * Remove unnecessary `new`-- make sure to delete everything +* General input sanitization * File error-handling * e.g., Utils.cpp's userFileError * Check if arg is a file or not (treat appropriately) diff --git a/src/App.cpp b/src/App.cpp index 1d604f6..0ed09a3 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -6,6 +6,7 @@ #include "App.h" #include +#include #include #include @@ -107,8 +108,17 @@ App::MessageReceived(BMessage* msg) void App::ArgvReceived(int32 argc, char** argv) { + BMessage refMsg(B_REFS_RECEIVED); + for (int i = 1; i < argc; i++) { - if (BUrl(argv[i]).IsValid()) { + entry_ref ref; + BEntry entry(argv[i]); + std::cout << "ARGV" << std::endl; + + if (entry.Exists() && entry.GetRef(&ref) == B_OK) { + refMsg.AddRef("refs", &ref); + } + else if (BUrl(argv[i]).IsValid()) { Feed* newFeed = new Feed(BUrl(argv[i])); BMessage* enqueue = new BMessage(kEnqueueFeed); @@ -117,8 +127,55 @@ App::ArgvReceived(int32 argc, char** argv) MessageReceived(enqueue); } } + RefsReceived(&refMsg); } - + + +void +App::RefsReceived(BMessage* message) +{ + int i = 0; + entry_ref ref; + BFile file; + BNodeInfo info; + char type[B_FILE_NAME_LENGTH]; + + while (message->HasRef("refs", i)) { + BMessage msg = BMessage(B_REFS_RECEIVED); + message->FindRef("refs", i++, &ref); + msg.AddRef("refs", &ref); + + file.SetTo(&ref, B_READ_ONLY); + info.SetTo(&file); + info.GetType(type); + + if (BString(type) == BString("text/x-feed-entry")) + _OpenEntryFile(&msg); + else if (BString(type) == BString("application/x-feed-source")) + _OpenSourceFile(&msg); + } +} + + +void +App::_OpenEntryFile(BMessage* refMessage) +{ + const char* openWith = fPreferences->EntryOpenWith(); + entry_ref openRef; + + + if (BMimeType(openWith).IsValid()) + BRoster().Launch(openWith, refMessage); + else if (BEntry(openWith).GetRef(&openRef) == B_OK) + BRoster().Launch(&openRef, refMessage); +} + + +void +App::_OpenSourceFile(BMessage* refMessage) +{ +} + const char* configPath = "/boot/home/config/settings/Pogger/"; diff --git a/src/App.h b/src/App.h index e5a2caf..e393bcb 100644 --- a/src/App.h +++ b/src/App.h @@ -23,6 +23,7 @@ public: App(void); void MessageReceived(BMessage* msg); void ArgvReceived(int32 argc, char** argv); + void RefsReceived(BMessage* message); MainWindow* fMainWindow; Preferences* fPreferences; @@ -30,6 +31,9 @@ public: BMessageRunner* fUpdateRunner; private: + void _OpenEntryFile(BMessage* refMessage); + void _OpenSourceFile(BMessage* refMessage); + FeedController* fFeedController; }; diff --git a/src/EntriesView.cpp b/src/EntriesView.cpp index de701d0..8e31610 100644 --- a/src/EntriesView.cpp +++ b/src/EntriesView.cpp @@ -82,6 +82,27 @@ EntriesView::MessageReceived(BMessage* msg) fOpenWithMenuField->MenuItem()->Label()); break; } + case kOpenWithPath: + { + entry_ref ref; + if (msg->HasRef("refs") && msg->FindRef("refs", &ref) == B_OK) { + ((App*)be_app)->fPreferences->SetEntryOpenWith( + BPath(&ref).Path()); + } + + delete fOpenWithPanel; + break; + } + case kOpenWithBrowse: + { + entry_ref appsRef; + BEntry("/boot/system/apps/").GetRef(&appsRef); + + fOpenWithPanel = new BFilePanel(B_OPEN_PANEL, NULL, &appsRef, + B_FILE_NODE, false, new BMessage(kOpenWithPath)); + fOpenWithPanel->Show(); + fOpenWithPanel->SetTarget(this); + } default: { BGroupView::MessageReceived(msg); @@ -199,19 +220,20 @@ EntriesView::_PopulateOpenWithMenu() BStringList signatures; BMessage types; + BMenuItem* prefItem = new BMenuItem(preferred, new BMessage(kOpenWithSelect)); + prefItem->SetMarked(true); + fOpenWithMenu->AddItem(prefItem); + html.GetSupportingApps(&types); if (types.FindStrings("applications", &signatures) != B_OK) return; for (int i = 0; i < signatures.CountStrings(); i++) { BString string = signatures.StringAt(i); + BMenuItem* item = new BMenuItem(string, new BMessage(kOpenWithSelect)); if (string != preferred) - fOpenWithMenu->AddItem( - new BMenuItem(string, new BMessage(kOpenWithSelect))); + fOpenWithMenu->AddItem(item); } - - fOpenWithMenu->AddItem( - new BMenuItem(preferred, new BMessage(kOpenWithSelect)), 0); } diff --git a/src/EntriesView.h b/src/EntriesView.h index a60d720..af9f8bd 100644 --- a/src/EntriesView.h +++ b/src/EntriesView.h @@ -10,6 +10,7 @@ class BBox; class BButton; +class BFilePanel; class BMenuField; class BMessage; class BPopUpMenu; @@ -27,6 +28,7 @@ enum kOpenUrlRadio = 'roow', kOpenAutoRadio = 'raow', kOpenWithSelect = 'mnow', + kOpenWithPath = 'pbow', kOpenWithBrowse = 'tbow' }; @@ -59,6 +61,7 @@ private: BPopUpMenu* fOpenWithMenu; BMenuField* fOpenWithMenuField; BButton* fOpenWithSelectButton; + BFilePanel* fOpenWithPanel; }; diff --git a/src/Pogger.rdef b/src/Pogger.rdef new file mode 100644 index 0000000..b1af86b --- /dev/null +++ b/src/Pogger.rdef @@ -0,0 +1,22 @@ +/* + * Copyight 2021 Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT License. + */ + +resource app_signature "application/x-vnd.Pogger"; + +resource app_flags B_SINGLE_LAUNCH; + +resource app_version { + major = 0, + middle = 0, + minor = 1, + + short_info = "Feed reader", + long_info = "An RSS/Atom feed service" +}; + +resource file_types message { + "types" = "text/x-feed-entry", + "types" = "application/x-feed-source" +};