Open feed entries as HTML or URL, by preference
This commit is contained in:
parent
afd7ebf2d1
commit
b8c27d9db5
1
TODO.txt
1
TODO.txt
|
@ -1,5 +1,4 @@
|
||||||
Important Features:
|
Important Features:
|
||||||
* Open As support
|
|
||||||
* Show download progress/failures in FeedView's feedlist
|
* Show download progress/failures in FeedView's feedlist
|
||||||
* Update FeedView's feedlist when feeds added/removed
|
* Update FeedView's feedlist when feeds added/removed
|
||||||
* Show in desktray
|
* Show in desktray
|
||||||
|
|
50
src/App.cpp
50
src/App.cpp
|
@ -28,6 +28,7 @@
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
srand(time(0));
|
||||||
installMimeTypes();
|
installMimeTypes();
|
||||||
|
|
||||||
App* app = new App();
|
App* app = new App();
|
||||||
|
@ -113,7 +114,6 @@ App::ArgvReceived(int32 argc, char** argv)
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
BEntry entry(argv[i]);
|
BEntry entry(argv[i]);
|
||||||
std::cout << "ARGV" << std::endl;
|
|
||||||
|
|
||||||
if (entry.Exists() && entry.GetRef(&ref) == B_OK) {
|
if (entry.Exists() && entry.GetRef(&ref) == B_OK) {
|
||||||
refMsg.AddRef("refs", &ref);
|
refMsg.AddRef("refs", &ref);
|
||||||
|
@ -141,7 +141,7 @@ App::RefsReceived(BMessage* message)
|
||||||
char type[B_FILE_NAME_LENGTH];
|
char type[B_FILE_NAME_LENGTH];
|
||||||
|
|
||||||
while (message->HasRef("refs", i)) {
|
while (message->HasRef("refs", i)) {
|
||||||
BMessage msg = BMessage(B_REFS_RECEIVED);
|
BMessage msg(B_REFS_RECEIVED);
|
||||||
message->FindRef("refs", i++, &ref);
|
message->FindRef("refs", i++, &ref);
|
||||||
msg.AddRef("refs", &ref);
|
msg.AddRef("refs", &ref);
|
||||||
|
|
||||||
|
@ -160,14 +160,50 @@ App::RefsReceived(BMessage* message)
|
||||||
void
|
void
|
||||||
App::_OpenEntryFile(BMessage* refMessage)
|
App::_OpenEntryFile(BMessage* refMessage)
|
||||||
{
|
{
|
||||||
const char* openWith = fPreferences->EntryOpenWith();
|
entry_ref entryRef;
|
||||||
entry_ref openRef;
|
refMessage->FindRef("refs", &entryRef);
|
||||||
|
|
||||||
|
if (fPreferences->EntryOpenAsHtml())
|
||||||
|
_OpenEntryFileAsHtml(entryRef);
|
||||||
|
else
|
||||||
|
_OpenEntryFileAsUrl(entryRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
App::_OpenEntryFileAsHtml(entry_ref ref)
|
||||||
|
{
|
||||||
|
const char* openWith = fPreferences->EntryOpenWith();
|
||||||
|
entry_ref openWithRef;
|
||||||
|
BString entryTitle("untitled");
|
||||||
|
BFile(&ref, B_READ_ONLY).ReadAttrString("Feed:name", &entryTitle);
|
||||||
|
|
||||||
|
entry_ref tempRef = tempHtmlFile(&ref, entryTitle.String());
|
||||||
|
BMessage newRefMessage(B_REFS_RECEIVED);
|
||||||
|
newRefMessage.AddRef("refs", &tempRef);
|
||||||
|
|
||||||
if (BMimeType(openWith).IsValid())
|
if (BMimeType(openWith).IsValid())
|
||||||
BRoster().Launch(openWith, refMessage);
|
BRoster().Launch(openWith, &newRefMessage);
|
||||||
else if (BEntry(openWith).GetRef(&openRef) == B_OK)
|
else if (BEntry(openWith).GetRef(&openWithRef) == B_OK)
|
||||||
BRoster().Launch(&openRef, refMessage);
|
BRoster().Launch(&openWithRef, &newRefMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
App::_OpenEntryFileAsUrl(entry_ref ref)
|
||||||
|
{
|
||||||
|
const char* openWith = fPreferences->EntryOpenWith();
|
||||||
|
entry_ref openWithRef;
|
||||||
|
BString entryUrl;
|
||||||
|
if (BFile(&ref, B_READ_ONLY).ReadAttrString("META:url", &entryUrl) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* urlArg = entryUrl.String();
|
||||||
|
|
||||||
|
if (BMimeType(openWith).IsValid())
|
||||||
|
BRoster().Launch(openWith, 1, &urlArg);
|
||||||
|
else if (BEntry(openWith).GetRef(&openWithRef) == B_OK)
|
||||||
|
BRoster().Launch(&openWithRef, 1, &urlArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _OpenEntryFile(BMessage* refMessage);
|
void _OpenEntryFile(BMessage* refMessage);
|
||||||
|
void _OpenEntryFileAsHtml(entry_ref ref);
|
||||||
|
void _OpenEntryFileAsUrl(entry_ref ref);
|
||||||
void _OpenSourceFile(BMessage* refMessage);
|
void _OpenSourceFile(BMessage* refMessage);
|
||||||
|
|
||||||
FeedController* fFeedController;
|
FeedController* fFeedController;
|
||||||
|
|
|
@ -35,7 +35,6 @@ EntriesView::AttachedToWindow()
|
||||||
fEntryFolderText->SetTarget(this);
|
fEntryFolderText->SetTarget(this);
|
||||||
fEntryFolderBrowseButton->SetTarget(this);
|
fEntryFolderBrowseButton->SetTarget(this);
|
||||||
|
|
||||||
fOpenAsAutoRadio->SetTarget(this);
|
|
||||||
fOpenAsHtmlRadio->SetTarget(this);
|
fOpenAsHtmlRadio->SetTarget(this);
|
||||||
fOpenAsUrlRadio->SetTarget(this);
|
fOpenAsUrlRadio->SetTarget(this);
|
||||||
fOpenWithSelectButton->SetTarget(this);
|
fOpenWithSelectButton->SetTarget(this);
|
||||||
|
@ -65,11 +64,6 @@ EntriesView::MessageReceived(BMessage* msg)
|
||||||
((App*)be_app)->fPreferences->fOpenAs = kOpenAsUrl;
|
((App*)be_app)->fPreferences->fOpenAs = kOpenAsUrl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kOpenAutoRadio:
|
|
||||||
{
|
|
||||||
((App*)be_app)->fPreferences->fOpenAs = kOpenAsAuto;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kOpenWithSelect:
|
case kOpenWithSelect:
|
||||||
{
|
{
|
||||||
((App*)be_app)->fPreferences->SetEntryOpenWith(
|
((App*)be_app)->fPreferences->SetEntryOpenWith(
|
||||||
|
@ -124,8 +118,6 @@ EntriesView::_InitInterface()
|
||||||
fOpeningBox->SetLabel("Opening");
|
fOpeningBox->SetLabel("Opening");
|
||||||
|
|
||||||
fOpenAsLabel = new BStringView("openAsLabel", "Open as:");
|
fOpenAsLabel = new BStringView("openAsLabel", "Open as:");
|
||||||
fOpenAsAutoRadio = new BRadioButton("asAuto", "Auto",
|
|
||||||
new BMessage(kOpenAutoRadio));
|
|
||||||
fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML",
|
fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML",
|
||||||
new BMessage(kOpenHtmlRadio));
|
new BMessage(kOpenHtmlRadio));
|
||||||
fOpenAsUrlRadio = new BRadioButton("asUrl", "URL",
|
fOpenAsUrlRadio = new BRadioButton("asUrl", "URL",
|
||||||
|
@ -142,10 +134,8 @@ EntriesView::_InitInterface()
|
||||||
Preferences* prefs = ((App*)be_app)->fPreferences;
|
Preferences* prefs = ((App*)be_app)->fPreferences;
|
||||||
if (prefs->fOpenAs == kOpenAsHtml)
|
if (prefs->fOpenAs == kOpenAsHtml)
|
||||||
fOpenAsHtmlRadio->SetValue(B_CONTROL_ON);
|
fOpenAsHtmlRadio->SetValue(B_CONTROL_ON);
|
||||||
else if (prefs->fOpenAs == kOpenAsUrl)
|
|
||||||
fOpenAsUrlRadio->SetValue(B_CONTROL_ON);
|
|
||||||
else
|
else
|
||||||
fOpenAsAutoRadio->SetValue(B_CONTROL_ON);
|
fOpenAsUrlRadio->SetValue(B_CONTROL_ON);
|
||||||
|
|
||||||
fEntryFolderText->SetText(prefs->EntryDir());
|
fEntryFolderText->SetText(prefs->EntryDir());
|
||||||
|
|
||||||
|
@ -177,7 +167,6 @@ EntriesView::_InitInterface()
|
||||||
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
|
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
|
||||||
.SetInsets(0, 20, B_USE_ITEM_INSETS, 0)
|
.SetInsets(0, 20, B_USE_ITEM_INSETS, 0)
|
||||||
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
|
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
|
||||||
.Add(fOpenAsAutoRadio)
|
|
||||||
.Add(fOpenAsHtmlRadio)
|
.Add(fOpenAsHtmlRadio)
|
||||||
.Add(fOpenAsUrlRadio)
|
.Add(fOpenAsUrlRadio)
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
|
|
|
@ -25,7 +25,6 @@ enum
|
||||||
kEntryFolderBrowse = 'tbef',
|
kEntryFolderBrowse = 'tbef',
|
||||||
kOpenHtmlRadio = 'rdow',
|
kOpenHtmlRadio = 'rdow',
|
||||||
kOpenUrlRadio = 'roow',
|
kOpenUrlRadio = 'roow',
|
||||||
kOpenAutoRadio = 'raow',
|
|
||||||
kOpenWithSelect = 'mnow',
|
kOpenWithSelect = 'mnow',
|
||||||
kOpenWithPath = 'pbow',
|
kOpenWithPath = 'pbow',
|
||||||
kOpenWithBrowse = 'tbow'
|
kOpenWithBrowse = 'tbow'
|
||||||
|
@ -51,7 +50,6 @@ private:
|
||||||
|
|
||||||
BBox* fOpeningBox;
|
BBox* fOpeningBox;
|
||||||
BStringView* fOpenAsLabel;
|
BStringView* fOpenAsLabel;
|
||||||
BRadioButton* fOpenAsAutoRadio;
|
|
||||||
BRadioButton* fOpenAsHtmlRadio;
|
BRadioButton* fOpenAsHtmlRadio;
|
||||||
BRadioButton* fOpenAsUrlRadio;
|
BRadioButton* fOpenAsUrlRadio;
|
||||||
BStringView* fOpenWithLabel;
|
BStringView* fOpenWithLabel;
|
||||||
|
|
|
@ -143,3 +143,21 @@ Preferences::SetEntryOpenWith(const char* binPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Preferences::EntryOpenAsHtml()
|
||||||
|
{
|
||||||
|
return fOpenAs == kOpenAsHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Preferences::SetEntryOpenAsHtml(bool asHtml)
|
||||||
|
{
|
||||||
|
if (asHtml == true)
|
||||||
|
fOpenAs = kOpenAsHtml;
|
||||||
|
else
|
||||||
|
fOpenAs = kOpenAsUrl;
|
||||||
|
return asHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ static const int64 HOUR_IN_MICROSECONDS = 3600000000;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kOpenAsAuto = 0,
|
|
||||||
kOpenAsHtml = 1,
|
kOpenAsHtml = 1,
|
||||||
kOpenAsUrl = 2
|
kOpenAsUrl = 2
|
||||||
};
|
};
|
||||||
|
@ -38,6 +37,9 @@ public:
|
||||||
BString EntryOpenWith();
|
BString EntryOpenWith();
|
||||||
status_t SetEntryOpenWith(const char* binPath);
|
status_t SetEntryOpenWith(const char* binPath);
|
||||||
|
|
||||||
|
bool EntryOpenAsHtml();
|
||||||
|
bool SetEntryOpenAsHtml(bool asHtml);
|
||||||
|
|
||||||
bool fNewNotify;
|
bool fNewNotify;
|
||||||
bool fFailureNotify;
|
bool fFailureNotify;
|
||||||
int8 fOpenAs;
|
int8 fOpenAs;
|
||||||
|
|
44
src/Util.cpp
44
src/Util.cpp
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <File.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <Url.h>
|
#include <Url.h>
|
||||||
#include <UrlProtocolRoster.h>
|
#include <UrlProtocolRoster.h>
|
||||||
|
@ -113,6 +115,17 @@ urlToFilename(BUrl url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
tempFileName(const char* dir, const char* name, const char* suffix)
|
||||||
|
{
|
||||||
|
BString tmpDir("/tmp/");
|
||||||
|
tmpDir << dir;
|
||||||
|
BDirectory().CreateDirectory(tmpDir.String(), NULL);
|
||||||
|
|
||||||
|
tmpDir << "/" << name << "-" << (rand() % 1000) << "." << suffix;
|
||||||
|
return tmpDir.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
fetch(BUrl url, BDataIO* reply, BString* hash, int timeout)
|
fetch(BUrl url, BDataIO* reply, BString* hash, int timeout)
|
||||||
|
@ -146,3 +159,34 @@ userFileError(status_t status, const char* path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
entry_ref
|
||||||
|
tempHtmlFile(entry_ref* ref, const char* title)
|
||||||
|
{
|
||||||
|
entry_ref tempRef;
|
||||||
|
BEntry(tempFileName("Pogger", title, "html")).GetRef(&tempRef);
|
||||||
|
|
||||||
|
BFile ogFile(ref, B_READ_ONLY);
|
||||||
|
BFile htmlFile(&tempRef, B_WRITE_ONLY | B_CREATE_FILE);
|
||||||
|
|
||||||
|
char readBuf[100] = {'\0'};
|
||||||
|
ssize_t readLen = 1;
|
||||||
|
|
||||||
|
BString head("<html>\n<head>\n<title>");
|
||||||
|
head << title << "</title>\n</head>\n<body>\n";
|
||||||
|
BString tail("</body>\n</html>\n");
|
||||||
|
const void* headBuf = head.String();
|
||||||
|
const void* tailBuf = tail.String();
|
||||||
|
|
||||||
|
htmlFile.Write(headBuf, head.Length());
|
||||||
|
|
||||||
|
while (readLen > 0) {
|
||||||
|
readLen = ogFile.Read(readBuf, 100);
|
||||||
|
htmlFile.Write(readBuf, readLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlFile.Write(tailBuf, tail.Length());
|
||||||
|
|
||||||
|
return tempRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,16 @@ bool withinDateRange(BDateTime, BDateTime, BDateTime);
|
||||||
bool isRemotePath(BString);
|
bool isRemotePath(BString);
|
||||||
|
|
||||||
BString urlToFilename(BUrl url);
|
BString urlToFilename(BUrl url);
|
||||||
|
const char* tempFileName(const char* dir, const char* name, const char* suffix);
|
||||||
|
|
||||||
int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout);
|
int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout);
|
||||||
|
|
||||||
void userFileError(status_t status, const char* path);
|
void userFileError(status_t status, const char* path);
|
||||||
|
|
||||||
|
// Takes a (probably invalid) bit of HTML and adds necessary elements in a
|
||||||
|
// temporary copy. Returns an entry_ref to said temporary copy.
|
||||||
|
entry_ref tempHtmlFile(entry_ref* ref, const char* title);
|
||||||
|
|
||||||
|
|
||||||
#endif // UTIL_H
|
#endif // UTIL_H
|
||||||
|
|
||||||
|
|
Ŝarĝante…
Reference in New Issue