Add deskbar replicant

This commit is contained in:
Jaidyn Ann 2021-03-26 11:06:34 -05:00
parent 36a0d1bf46
commit bbda90725e
8 changed files with 389 additions and 3 deletions

View File

@ -31,6 +31,7 @@ APP_MIME_SIG = application/x-vnd.Pogger
SRCS = \ SRCS = \
src/App.cpp \ src/App.cpp \
src/AtomFeed.cpp \ src/AtomFeed.cpp \
src/DeskbarView.cpp \
src/Entry.cpp \ src/Entry.cpp \
src/EntriesView.cpp \ src/EntriesView.cpp \
src/Feed.cpp \ src/Feed.cpp \

View File

@ -11,6 +11,7 @@
#include <String.h> #include <String.h>
#include "AtomFeed.h" #include "AtomFeed.h"
#include "DeskbarView.h"
#include "Entry.h" #include "Entry.h"
#include "Feed.h" #include "Feed.h"
#include "FeedController.h" #include "FeedController.h"
@ -45,6 +46,7 @@ App::App() : BApplication("application/x-vnd.Pogger")
MessageReceived(&updateMessage); MessageReceived(&updateMessage);
fUpdateRunner = new BMessageRunner(this, updateMessage, interval, count); fUpdateRunner = new BMessageRunner(this, updateMessage, interval, count);
installDeskbar();
} }
@ -106,6 +108,7 @@ App::QuitRequested()
fPreferences->Save(); fPreferences->Save();
delete fPreferences; delete fPreferences;
removeDeskbar();
return true; return true;
} }

288
src/DeskbarView.cpp Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* Copyright 2004-2018, Haiku, Inc. All Rights Reserved.
* Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
* All rights reserved. Distributed under the terms of the MIT license.
*
* Authors:
* Michael Weirauch, dev@m-phasis.de
*/
#include "DeskbarView.h"
#include <Bitmap.h>
#include <Catalog.h>
#include <Deskbar.h>
#include <FindDirectory.h>
#include <IconUtils.h>
#include <MenuItem.h>
#include <NodeInfo.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Resources.h>
#include <Roster.h>
#include "FeedController.h"
#include "Preferences.h"
#include "Util.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "DeskbarView"
DeskbarView::DeskbarView(BRect rect)
: BView(rect, "Pogger", B_FOLLOW_NONE, B_WILL_DRAW)
{
_InitIcon();
}
DeskbarView::DeskbarView(BMessage* message)
: BView(message)
{
_InitIcon();
_GetEntryDir();
}
status_t
DeskbarView::Archive(BMessage* data, bool deep) const {
BView::Archive(data, deep);
data->AddString("add_on", "application/x-vnd.Pogger");
data->AddString("class", "Pogger");
return B_OK;
}
DeskbarView*
DeskbarView::Instantiate(BMessage* data) {
if (!validate_instantiation(data, "Pogger"))
return NULL;
return new DeskbarView(data);
}
void
DeskbarView::AttachedToWindow()
{
BView::AttachedToWindow();
AdoptParentColors();
SetLowColor(ViewColor());
}
void
DeskbarView::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case kEntryFolder:
{
entry_ref ref;
BEntry entry(fEntryDir);
entry.GetRef(&ref);
be_roster->Launch(&ref);
break;
}
case kQueryNew:
{
entry_ref query;
_GetNewEntryQuery(&query);
be_roster->Launch(&query);
break;
}
case kUpdateNow:
{
BMessenger messenger("application/x-vnd.Pogger");
messenger.SendMessage(kUpdateSubscribed);
break;
}
case kOpenSettings:
{
be_roster->Launch("application/x-vnd.Pogger");
break;
}
case kQuitPogger:
{
BMessenger messenger("application/x-vnd.Pogger");
messenger.SendMessage(B_QUIT_REQUESTED);
break;
}
default:
BView::MessageReceived(msg);
}
}
void
DeskbarView::Draw(BRect rect)
{
SetDrawingMode(B_OP_ALPHA);
DrawBitmap(fIcon);
SetDrawingMode(B_OP_COPY);
}
void
DeskbarView::MouseUp(BPoint point)
{
BMessage open(kQueryNew);
MessageReceived(&open);
}
void
DeskbarView::MouseDown(BPoint point)
{
uint32 buttons;
GetMouse(&point, &buttons);
if (!(buttons & B_SECONDARY_MOUSE_BUTTON))
return;
ConvertToScreen(&point);
BPopUpMenu* menu = _BuildMenu();
menu->SetTargetForItems(this);
menu->Go(point, true, false, true, true);
}
BPopUpMenu*
DeskbarView::_BuildMenu()
{
BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
menu->AddItem(new BMenuItem(B_TRANSLATE("Open entry folder" B_UTF8_ELLIPSIS),
new BMessage(kEntryFolder)));
menu->AddItem(new BMenuItem(B_TRANSLATE("Query new entries" B_UTF8_ELLIPSIS),
new BMessage(kQueryNew)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Update now"),
new BMessage(kUpdateNow)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
new BMessage(kOpenSettings)));
menu->AddItem(new BMenuItem(B_TRANSLATE("Quit Pogger"),
new BMessage(kQuitPogger)));
return menu;
}
void
DeskbarView::_GetEntryDir()
{
Preferences pref = Preferences();
pref.Load();
fEntryDir = pref.EntryDir();
}
status_t
DeskbarView::_GetNewEntryQuery(entry_ref* ref)
{
BPath path;
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
path.Append("Pogger/New Entries");
BEntry query(path.Path());
if (query.Exists())
return query.GetRef(ref);
else
return _CreateNewEntryQuery(query);
}
status_t
DeskbarView::_CreateNewEntryQuery(BEntry query)
{
BFile file(&query, B_READ_WRITE | B_CREATE_FILE);
if (file.InitCheck() != B_OK)
return file.InitCheck();
BString string("\"Feed:status\" ==\"New\"");
file.WriteAttrString("_trk/qrystr", &string);
file.WriteAttrString("_trk/qryinitstr", &string);
int32 mode = 'Fbyq';
file.WriteAttr("_trk/qryinitmode", B_INT32_TYPE, 0, &mode, sizeof(int32));
string = "Feed entry";
file.WriteAttrString("_trk/qryinitmime", &string);
BNodeInfo(&file).SetType("application/x-vnd.Be-query");
return B_OK;
}
void
DeskbarView::_InitIcon()
{
image_info info;
if (our_image(info) != B_OK)
return;
BFile file(info.name, B_READ_ONLY);
if (file.InitCheck() < B_OK)
return;
BResources resources(&file);
if (resources.InitCheck() < B_OK)
return;
size_t size;
const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, "feed-type", &size);
if (data != NULL) {
BBitmap* icon = new BBitmap(Bounds(), B_RGBA32);
if (icon->InitCheck() == B_OK
&& BIconUtils::GetVectorIcon((const uint8 *)data, size, icon)
== B_OK) {
fIcon = icon;
}
else
delete icon;
}
}
status_t
our_image(image_info& image)
{
int32 cookie = 0;
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
if ((char *)our_image >= (char *)image.text
&& (char *)our_image <= (char *)image.text + image.text_size)
return B_OK;
}
return B_ERROR;
}
int32
installDeskbar()
{
int32 deskbarId = -1;
removeDeskbar();
BDeskbar deskbar;
deskbar.AddItem(
new DeskbarView(BRect(0,0, deskbar.MaxItemHeight() - 1,
deskbar.MaxItemHeight() - 1)),
&deskbarId);
return deskbarId;
}
void
removeDeskbar()
{
BDeskbar deskbar;
deskbar.RemoveItem("Pogger");
}

68
src/DeskbarView.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* Copyright 2004-2018, Haiku, Inc. All Rights Reserved.
* Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
* All rights reserved. Distributed under the terms of the MIT license.
*
* Authors:
* Michael Weirauch, dev@m-phasis.de
*/
#ifndef DBVIEW_H
#define DBVIEW_H
#include <View.h>
class BPopUpMenu;
enum
{
kOpenSettings = 'dbos',
kQuitPogger = 'dbkp',
kUpdateNow = 'dbup',
kEntryFolder = 'dbef',
kQueryNew = 'dbqn'
};
// This view has a large amount of code from the mail and bluetooth servers
// (src/servers/mail/DeskbarView.cpp src/servers/bluetooth/DeskbarReplicant.cpp)
class DeskbarView : public BView {
public:
DeskbarView(BRect rect);
DeskbarView(BMessage* msg);
status_t Archive(BMessage *data, bool deep = true) const;
static DeskbarView* Instantiate(BMessage *data);
void AttachedToWindow();
void MessageReceived(BMessage* msg);
void Draw(BRect rect);
void MouseUp(BPoint point);
void MouseDown(BPoint point);
BPopUpMenu* _BuildMenu();
void _GetEntryDir();
status_t _GetNewEntryQuery(entry_ref* ref);
status_t _CreateNewEntryQuery(BEntry query);
void _InitIcon();
private:
BBitmap* fIcon;
BString fEntryDir;
};
int32 installDeskbar();
void removeDeskbar();
status_t our_image(image_info& image);
#endif // DBVIEW_H

View File

@ -42,11 +42,11 @@ Entry::Filetize()
} }
outDir.CreateFile(fTitle.String(), &file); outDir.CreateFile(fTitle.String(), &file);
BString betype = BString("text/x-feed-entry"); BString betype = BString("application/x-feed-entry");
file.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, betype.String(), file.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, betype.String(),
betype.CountChars() + 1); betype.CountChars() + 1);
BString readStatus("Unread"); BString readStatus("New");
file.WriteAttrString("Feed:name", &fTitle); file.WriteAttrString("Feed:name", &fTitle);
file.WriteAttrString("Feed:description", &fDescription); file.WriteAttrString("Feed:description", &fDescription);
file.WriteAttrString("Feed:source", &fFeedTitle); file.WriteAttrString("Feed:source", &fFeedTitle);

View File

@ -13,10 +13,15 @@
#include <Message.h> #include <Message.h>
#include <MimeType.h> #include <MimeType.h>
#include <Resources.h> #include <Resources.h>
#include <fs_index.h>
#include <fs_info.h>
#include <VolumeRoster.h>
bool installMimeTypes() bool installMimeTypes()
{ {
addIndices();
return (feedMimeType() && feedEntryMimeType()); return (feedMimeType() && feedEntryMimeType());
} }
@ -82,6 +87,26 @@ feedEntryMimeType()
} }
void
addIndices()
{
int32 cookie = 0;
dev_t device;
while ((device = next_dev(&cookie)) >= B_OK) {
fs_info info;
if (fs_stat_dev(device, &info) < 0
|| (info.flags & B_FS_HAS_QUERY) == 0)
continue;
fs_create_index(device, "Feed:name", B_STRING_TYPE, 0);
fs_create_index(device, "Feed:source", B_STRING_TYPE, 0);
fs_create_index(device, "Feed:status", B_STRING_TYPE, 0);
fs_create_index(device, "Feed:when", B_TIME_TYPE, 0);
}
}
// add the given attribute to a BMessage for use as attr info // add the given attribute to a BMessage for use as attr info
// borrowed from mailserver (thanks!) // borrowed from mailserver (thanks!)
static void static void

View File

@ -15,6 +15,7 @@ class BMessage;
bool installMimeTypes(); bool installMimeTypes();
bool feedMimeType(); bool feedMimeType();
bool feedEntryMimeType(); bool feedEntryMimeType();
void addIndices();
static void addAttribute(BMessage&, const char*, const char*, static void addAttribute(BMessage&, const char*, const char*,
int32 type = B_STRING_TYPE, int32 width = 200); int32 type = B_STRING_TYPE, int32 width = 200);

View File

@ -17,6 +17,6 @@ resource app_version {
}; };
resource file_types message { resource file_types message {
"types" = "text/x-feed-entry", "types" = "application/x-feed-entry",
"types" = "application/x-feed-source" "types" = "application/x-feed-source"
}; };