Added libdownload from xeD.
This commit is contained in:
parent
30470d4816
commit
082f2ad34e
1
Jamfile
1
Jamfile
|
@ -5,6 +5,7 @@ SubInclude TOP libs ;
|
|||
SubInclude TOP application ;
|
||||
SubInclude TOP protocols ;
|
||||
SubInclude TOP smileys ;
|
||||
SubInclude TOP tests ;
|
||||
|
||||
UninstallTarget $(CAYA_DIRECTORY) ;
|
||||
UninstallTarget $(COMMON_INCLUDE_DIRECTORY)/caya ;
|
||||
|
|
5
Jamrules
5
Jamrules
|
@ -45,7 +45,10 @@ LOCATE on $(HCACHEFILE) $(JCACHEFILE) = $(GENERATED_DIR) ;
|
|||
# Perform configuration checks
|
||||
include [ FDirName $(JAM_DIR) CheckRules ] ;
|
||||
CheckGccPlatform ;
|
||||
CheckOpenSSL ;
|
||||
CheckCurl ;
|
||||
if ! $(HAVE_CURL) {
|
||||
Echo "** Caya needs Curl" ;
|
||||
}
|
||||
|
||||
# Include jam scripts
|
||||
include [ FDirName $(JAM_DIR) HelperRules ] ;
|
||||
|
|
|
@ -83,6 +83,7 @@ StatusView::StatusView(const char* name)
|
|||
void
|
||||
StatusView::AttachedToWindow()
|
||||
{
|
||||
fNickname->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
fNickname->SetTarget(this);
|
||||
fStatusMenu->SetTargetForItems(this);
|
||||
}
|
||||
|
|
|
@ -48,3 +48,30 @@ rule CheckOpenSSL
|
|||
HAVE_OPENSSL = $(haveLibs) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule CheckCurl
|
||||
{
|
||||
# CheckCurl ;
|
||||
# Check for Curl and defined HAVE_CURL according, it also defines
|
||||
# CURL_INCLUDE_DIR and CURL_LIBRARY_DIR with location of respectively
|
||||
# include and library files.
|
||||
|
||||
HAVE_CURL = ;
|
||||
CURL_INCLUDE_DIR = ;
|
||||
CURL_LIBRARY_DIR = ;
|
||||
|
||||
local haveHeaders = [ Glob $(COMMON_INCLUDE_DIRECTORY)/curl : curl.h ] ;
|
||||
if $(haveHeaders) {
|
||||
CURL_INCLUDE_DIR = $(COMMON_INCLUDE_DIRECTORY)/curl ;
|
||||
|
||||
local haveLibs = [ Glob $(COMMON_LIB_DIRECTORY) : libcurl.so ] ;
|
||||
if $(haveLibs) {
|
||||
CURL_LIBRARY_DIR = $(COMMON_LIB_DIRECTORY) ;
|
||||
|
||||
Echo Curl Headers: $(CURL_INCLUDE_DIR) ;
|
||||
Echo Curl Libs: $(CURL_LIBRARY_DIR) ;
|
||||
}
|
||||
|
||||
HAVE_CURL = $(haveLibs) ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
SubDir TOP libs ;
|
||||
|
||||
# Include all the components.
|
||||
SubInclude TOP libs libdownload ;
|
||||
SubInclude TOP libs librunview ;
|
||||
SubInclude TOP libs libsupport ;
|
||||
SubInclude TOP libs libinterface ;
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACTION_H
|
||||
#define _ACTION_H
|
||||
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
|
||||
#define ActionID bigtime_t
|
||||
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
Action() { fActionID = 0; }
|
||||
virtual ~Action() {}
|
||||
|
||||
virtual status_t Perform(BMessage* errors) = 0;
|
||||
virtual BString GetDescription() = 0;
|
||||
|
||||
void SetActionID(const ActionID id) { fActionID = id; }
|
||||
ActionID GetActionID() const { return fActionID; }
|
||||
|
||||
private:
|
||||
ActionID fActionID;
|
||||
};
|
||||
|
||||
#endif //_ACTION_H
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <File.h>
|
||||
#include <Path.h>
|
||||
#include <Mime.h>
|
||||
#include <NodeInfo.h>
|
||||
|
||||
#include "ActionDownload.h"
|
||||
#include "DownloadManager.h"
|
||||
|
||||
|
||||
ActionDownload::ActionDownload(BString URL,
|
||||
entry_ref dest,
|
||||
bool allowResume,
|
||||
BLooper* target,
|
||||
uint32 msg)
|
||||
:
|
||||
Action(),
|
||||
fUrl(URL),
|
||||
fDest(dest),
|
||||
fTarget(target),
|
||||
fMsg(msg),
|
||||
fAllowResume(allowResume)
|
||||
{
|
||||
file = NULL;
|
||||
curl = NULL;
|
||||
resuming = 0.0;
|
||||
SetShouldStop(false);
|
||||
}
|
||||
|
||||
|
||||
ActionDownload::~ActionDownload()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActionDownload::SetDownloadManager(DownloadManager* downloadManager)
|
||||
{
|
||||
fDownloadManager = downloadManager;
|
||||
}
|
||||
|
||||
status_t
|
||||
ActionDownload::openFile(BMessage* errors)
|
||||
{
|
||||
uint32 openMode = 0;
|
||||
|
||||
if (fAllowResume)
|
||||
openMode = B_WRITE_ONLY | B_CREATE_FILE | B_OPEN_AT_END;
|
||||
else
|
||||
openMode = B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE;
|
||||
|
||||
if (file) return B_ERROR;
|
||||
|
||||
file = new BFile(&fDest, openMode);
|
||||
|
||||
if (!file || file->InitCheck() != B_OK) {
|
||||
BString err("Can't open file!");
|
||||
errors->AddInt32("status", ERROR_OPENFILE);
|
||||
errors->AddString("error", err);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActionDownload::Perform(BMessage* errors)
|
||||
{
|
||||
//is it these the right place?
|
||||
fillMessage(this, errors);
|
||||
//
|
||||
|
||||
CURLcode res;
|
||||
status_t status = B_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
BString err("Internal error (CURL can't' init)!");
|
||||
errors->AddInt32("status", ERROR_CURL_INIT);
|
||||
errors->AddString("error", err);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fUrl.String());
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, callback);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this );
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, save_file);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION , 1); //follow the white link!
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , FALSE); //https
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , FALSE); //https
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR , 1);
|
||||
|
||||
if (fDownloadManager)
|
||||
fDownloadManager->FinishCurl(curl);
|
||||
|
||||
//RESUME
|
||||
if (fAllowResume) {
|
||||
BNode stat(&fDest);
|
||||
// file->Seek(SEEK_END,0);
|
||||
// size_t resume = (size_t)file->Position();
|
||||
off_t size = 0;
|
||||
stat.GetSize(&size);
|
||||
|
||||
off_t resume = size;
|
||||
|
||||
|
||||
if ( resume > 0 ) {
|
||||
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, resume);
|
||||
resuming = (double)resume;
|
||||
}
|
||||
}
|
||||
|
||||
BMessage connect(*errors);
|
||||
connect.what = fMsg;
|
||||
connect.AddInt32("status", OK_CONNECTING);
|
||||
fTarget->PostMessage(&connect);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if (res != 0) {
|
||||
BString err("Can't connect!");
|
||||
errors->AddInt32("status", ERROR_PERFORMING);
|
||||
errors->AddString("error", err);
|
||||
errors->AddInt32("curl_error", res);
|
||||
errors->AddBool("should_stop", ShouldStop());
|
||||
status = B_ERROR;
|
||||
} else {
|
||||
errors->AddInt32("status", OK_DOWNLOADED);
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
errors->AddString("path", GetLocalPath());
|
||||
errors->AddRef("entry", &fDest);
|
||||
|
||||
BMimeType mime;
|
||||
|
||||
if (fFileType != "")
|
||||
BNodeInfo(file).SetType(fFileType.String());
|
||||
else {
|
||||
status_t guess = BMimeType::GuessMimeType(&fDest, &mime); // :( return B_ERROR.. why????????????
|
||||
if (guess == B_OK)
|
||||
BNodeInfo(file).SetType(mime.Type());
|
||||
}
|
||||
|
||||
delete file;
|
||||
file = NULL;
|
||||
|
||||
if (res == CURLE_BAD_DOWNLOAD_RESUME || res == CURLE_HTTP_RANGE_ERROR) {
|
||||
// sarebbe bello chiedere.. va be per ora ci riprova e basta!
|
||||
fAllowResume = false;
|
||||
errors->MakeEmpty();
|
||||
Perform(errors);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
BString
|
||||
ActionDownload::GetDescription()
|
||||
{
|
||||
return "HTTP File download";
|
||||
}
|
||||
|
||||
BString
|
||||
ActionDownload::GetLocalPath()
|
||||
{
|
||||
return BPath(&fDest).Path();
|
||||
}
|
||||
|
||||
void
|
||||
ActionDownload::fillMessage(ActionDownload* ad, BMessage* msg)
|
||||
{
|
||||
//fill with common fileds
|
||||
int32 what = msg->what; //preserve original what.
|
||||
*msg = ad->extraInfo;
|
||||
|
||||
msg->AddInt64("sid", ad->GetActionID());
|
||||
msg->AddString("url", ad->fUrl);
|
||||
|
||||
msg->what = what;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ActionDownload::sendProgressX(ActionDownload* ad, double max, double current)
|
||||
{
|
||||
BMessage msg(ad->fMsg);
|
||||
|
||||
fillMessage(ad, &msg);
|
||||
|
||||
msg.AddInt32("status", OK_PROGRESS);
|
||||
msg.AddFloat("max_progress", (float)max);
|
||||
msg.AddFloat("current_progress", (float)current);
|
||||
|
||||
float div = 0.0;
|
||||
if (max > 0.0)
|
||||
div = ((float)current / (float)max ) * 100;
|
||||
|
||||
msg.AddInt32("percentage_progress", (int32)floor(div));
|
||||
|
||||
double speed = 0;
|
||||
if (curl_easy_getinfo(ad->curl, CURLINFO_SPEED_DOWNLOAD, &speed) == CURLE_OK)
|
||||
msg.AddFloat("download_speed", (float)speed);
|
||||
|
||||
|
||||
//TOTALE:
|
||||
if (curl_easy_getinfo(ad->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &speed) == CURLE_OK)
|
||||
msg.AddFloat("total_size", (float)speed);
|
||||
|
||||
// ATTUALE: CURLINFO_SIZE_DOWNLOAD
|
||||
if (curl_easy_getinfo(ad->curl, CURLINFO_SIZE_DOWNLOAD, &speed) == CURLE_OK)
|
||||
msg.AddFloat("actual_size", (float)speed);
|
||||
|
||||
char* array = NULL;
|
||||
|
||||
|
||||
if (curl_easy_getinfo(ad->curl, CURLINFO_EFFECTIVE_URL, &array) == CURLE_OK)
|
||||
msg.AddString("effective_url", BString(array));
|
||||
|
||||
if (ad->fFileType == "" && curl_easy_getinfo(ad->curl, CURLINFO_CONTENT_TYPE, &array) == CURLE_OK) {
|
||||
ad->fFileType.SetTo(array);
|
||||
BNodeInfo(ad->file).SetType(ad->fFileType.String());
|
||||
msg.AddString("filetype", BString(array));
|
||||
}
|
||||
|
||||
ad->fTarget->PostMessage(&msg);
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
ActionDownload::sendError(BLooper* looper,uint32 amsg,Status st,BString descr){
|
||||
BMessage msg(amsg);
|
||||
msg.AddInt32("status",st);
|
||||
msg.AddString("error",descr);
|
||||
looper->PostMessage(&msg);
|
||||
}
|
||||
*/
|
||||
//
|
||||
|
||||
int
|
||||
ActionDownload::callback(void* data,
|
||||
double dltotal,
|
||||
double dlnow,
|
||||
double ,
|
||||
double )
|
||||
{
|
||||
ActionDownload* ad = ((ActionDownload*)data);
|
||||
|
||||
if (ad->fTarget)
|
||||
sendProgressX(ad, ad->resuming + dltotal, ad->resuming + dlnow);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
ActionDownload::save_file( void* ptr, size_t size, size_t nmemb, void* data)
|
||||
{
|
||||
ActionDownload* ad = ((ActionDownload*)data);
|
||||
|
||||
if (!ad->file) {
|
||||
BMessage errors; //FIIX: how to report these errors??
|
||||
if (ad->openFile(&errors) != B_OK) {
|
||||
printf("ERROR: can't create destination file!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
BFile* file = ad->file;
|
||||
if (ad->ShouldStop()) return 0;
|
||||
return file->Write(ptr, size * nmemb);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACTION_DOWNLOAD_H
|
||||
#define _ACTION_DOWNLOAD_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Looper.h>
|
||||
#include <File.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <DownloadManager.h>
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
class ActionDownload : public Action
|
||||
{
|
||||
public:
|
||||
enum Status {
|
||||
ERROR_OPENFILE, // 0
|
||||
ERROR_CURL_INIT, // 1
|
||||
ERROR_PERFORMING, // 2
|
||||
OK_CONNECTING, // 3
|
||||
OK_PROGRESS, // 4
|
||||
OK_DOWNLOADED // 5
|
||||
};
|
||||
|
||||
ActionDownload(BString URL, entry_ref dest,
|
||||
bool allowResume, BLooper* target = NULL, uint32 msg = 0);
|
||||
virtual ~ActionDownload();
|
||||
|
||||
status_t Perform(BMessage* errors);
|
||||
BString GetDescription();
|
||||
BString GetLocalPath();
|
||||
|
||||
void SetLooper(BLooper* loop, uint32 msg) {
|
||||
fTarget = loop;
|
||||
fMsg = msg;
|
||||
};
|
||||
BLooper* Looper() {
|
||||
return fTarget;
|
||||
}
|
||||
uint32 MessageWhat() {
|
||||
return fMsg;
|
||||
}
|
||||
|
||||
// For compatibility:
|
||||
void SetExtraData(BString extra) {
|
||||
extraInfo.AddString("extra", extra);
|
||||
}
|
||||
|
||||
void SetKey(BString key, BString data) {
|
||||
extraInfo.AddString(key.String(), data);
|
||||
}
|
||||
|
||||
void SetRef(BString key, entry_ref* ref) {
|
||||
extraInfo.AddRef(key.String(), ref);
|
||||
}
|
||||
|
||||
status_t GetRef(BString key, entry_ref* ref) {
|
||||
return extraInfo.FindRef(key.String(), ref);
|
||||
}
|
||||
|
||||
BString GetKey(BString key) {
|
||||
BString data;
|
||||
extraInfo.FindString(key.String(), &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void SetShouldStop(bool stop) {
|
||||
fShouldStop = stop;
|
||||
}
|
||||
bool ShouldStop() {
|
||||
return fShouldStop;
|
||||
}
|
||||
|
||||
void SetDownloadManager(DownloadManager* downloadManager);
|
||||
|
||||
private:
|
||||
status_t openFile(BMessage*);
|
||||
|
||||
static void fillMessage(ActionDownload*, BMessage*);
|
||||
static void sendProgressX(ActionDownload*, double max, double current);
|
||||
|
||||
//curl callbacks:
|
||||
static size_t save_file ( void* ptr, size_t size, size_t nmemb, void* stream);
|
||||
static int callback (void* clientp, double dltotal, double dlnow, double , double);
|
||||
|
||||
CURL* curl;
|
||||
BString fUrl;
|
||||
entry_ref fDest;
|
||||
BLooper* fTarget;
|
||||
uint32 fMsg;
|
||||
BMessage extraInfo;
|
||||
bool fShouldStop;
|
||||
BFile* file;
|
||||
double resuming;
|
||||
bool fAllowResume;
|
||||
DownloadManager* fDownloadManager;
|
||||
|
||||
BString fFileType;
|
||||
};
|
||||
|
||||
#endif // _ACTION_DOWNLOAD_H
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <Messenger.h>
|
||||
|
||||
#include "DownloadManager.h"
|
||||
#include "ActionDownload.h"
|
||||
|
||||
#define DEFAULT_ITEMS_DOWNLOAD 1
|
||||
|
||||
DownloadManager::DownloadManager(BLooper* target): fTarget(target)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DownloadManager::Enqueue(QueueType type, ActionDownload* ad)
|
||||
{
|
||||
if (!fQueue[type]) {
|
||||
fQueue[type] = new QueueFileDownload("queue_downloads", DEFAULT_ITEMS_DOWNLOAD, fTarget, DOWNLOAD_INFO);
|
||||
}
|
||||
ad->SetDownloadManager(this);
|
||||
fQueue[type]->AddAction(ad);
|
||||
}
|
||||
|
||||
void
|
||||
DownloadManager::TryStopCurrentAction(QueueType type, BString key, BString value)
|
||||
{
|
||||
|
||||
if (!fQueue[type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fQueue[type]->Lock()) {
|
||||
for (int i = 0; i < fQueue[type]->CountThreads(); i++) {
|
||||
ActionDownload* ad = (ActionDownload*)fQueue[type]->CurrentAction(i);
|
||||
if (ad && ad->GetKey(key).Compare(value.String()) == 0 )
|
||||
ad->SetShouldStop(true);
|
||||
}
|
||||
|
||||
fQueue[type]->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DownloadManager::RemoveFromQueue(QueueType type , BString key, BString value)
|
||||
{
|
||||
|
||||
if (!fQueue[type]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fQueue[type]->Lock()) {
|
||||
|
||||
for (int32 i = 0; i < fQueue[type]->CountActions(); i++) {
|
||||
ActionDownload* ad = (ActionDownload*)fQueue[type]->ActionAt(i);
|
||||
if (ad->GetKey(key).Compare(value.String()) == 0 ) {
|
||||
fQueue[type]->RemoveActionAt(i);
|
||||
fQueue[type]->Unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < fQueue[type]->CountThreads(); i++) {
|
||||
ActionDownload* ad = (ActionDownload*)fQueue[type]->CurrentAction(i);
|
||||
|
||||
if (ad && ad->GetKey(key).Compare(value.String()) == 0 )
|
||||
ad->SetShouldStop(true);
|
||||
}
|
||||
fQueue[type]->Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
DownloadManager::RemoveQueue(QueueType type, BList* removed)
|
||||
{
|
||||
|
||||
if (!fQueue[type]) {
|
||||
return;
|
||||
}
|
||||
fQueue[type]->Lock();
|
||||
|
||||
while (fQueue[type]->CountActions()) {
|
||||
// ActionDownload *ad = (ActionDownload*)fQueue[type]->ActionAt(0);
|
||||
fQueue[type]->RemoveActionAt(0);
|
||||
}
|
||||
|
||||
// ***************************************
|
||||
// we did not unlock
|
||||
// so no one can add new item.
|
||||
// ***************************************
|
||||
|
||||
for (int i = 0; i < fQueue[type]->CountThreads(); i++) {
|
||||
if (fQueue[type]->CurrentAction(i))
|
||||
removed->AddItem( (void*)fQueue[type]->CurrentAction(i));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DownloadManager::LoadProxySetting(BMessage* data)
|
||||
{
|
||||
|
||||
bool value;
|
||||
|
||||
fEnabled = false;
|
||||
fAddress.SetTo("");
|
||||
fUserpwd.SetTo("");
|
||||
fPort = 0;
|
||||
|
||||
if (data->FindBool("enable", &value) == B_OK)
|
||||
fEnabled = value;
|
||||
|
||||
if (!fEnabled)
|
||||
return;
|
||||
|
||||
BString username, password;
|
||||
data->FindString("username", &username);
|
||||
data->FindInt32("port", &fPort);
|
||||
data->FindString("address", &fAddress);
|
||||
data->FindString("password", &password);
|
||||
if (username != "" || password != "")
|
||||
fUserpwd << username << ":" << password;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadManager::LoadDownloadSetting(BMessage* data)
|
||||
{
|
||||
|
||||
//FIXME: fQueue[XXX] can be null.
|
||||
|
||||
//here magic stuff! :=)
|
||||
int32 number = 1;
|
||||
if (data->FindInt32("max_downloads", &number) == B_OK) {
|
||||
fQueue[DOWNLOADS_QUEUE]->SetDownloadCount(number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadManager::FinishCurl(CURL* curl)
|
||||
{
|
||||
if (!fEnabled)
|
||||
return;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, fAddress.String());
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYPORT, fPort);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE , CURLPROXY_HTTP);
|
||||
|
||||
if (fUserpwd != "")
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD , fUserpwd.String() );
|
||||
}
|
||||
|
||||
thread_id
|
||||
DownloadManager::SingleThreadAction(ActionDownload* action)
|
||||
{
|
||||
action->SetDownloadManager(this);
|
||||
if (action->Looper() == NULL) {
|
||||
action->SetLooper(fTarget, DOWNLOAD_INFO);
|
||||
}
|
||||
thread_id id = spawn_thread(DownloadManager::SingleThreadPerform, "single_action_thread", B_NORMAL_PRIORITY, (void*)action);
|
||||
resume_thread(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
int32
|
||||
DownloadManager::SingleThreadPerform(void* a)
|
||||
{
|
||||
|
||||
ActionDownload* ad = (ActionDownload*)a;
|
||||
|
||||
// perform the action
|
||||
BMessage err;
|
||||
//status_t status =
|
||||
ad->Perform(&err);
|
||||
// do post-perform!
|
||||
if (ad->Looper()) {
|
||||
err.what = ad->MessageWhat();
|
||||
BMessenger(ad->Looper()).SendMessage(&err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2006-2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _DOWNLOAD_MANAGER_H
|
||||
#define _DOWNLOAD_MANAGER_H
|
||||
|
||||
#include <Looper.h>
|
||||
#include <List.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "QueueFileDownload.h"
|
||||
|
||||
#define DOWNLOAD_INFO 'dwni'
|
||||
|
||||
class ActionDownload;
|
||||
|
||||
class DownloadManager
|
||||
{
|
||||
public:
|
||||
enum QueueType {
|
||||
DOWNLOADS_QUEUE = 0
|
||||
};
|
||||
|
||||
DownloadManager(BLooper* target);
|
||||
|
||||
void Enqueue(QueueType, ActionDownload*);
|
||||
|
||||
void TryStopCurrentAction(QueueType, BString key, BString value);
|
||||
|
||||
bool RemoveFromQueue(QueueType, BString key, BString value);
|
||||
|
||||
void RemoveQueue(QueueType, BList* removed);
|
||||
|
||||
void LoadProxySetting(BMessage* data);
|
||||
void LoadDownloadSetting(BMessage* data);
|
||||
|
||||
thread_id SingleThreadAction(ActionDownload* action);
|
||||
|
||||
void FinishCurl(CURL* curl);
|
||||
|
||||
private:
|
||||
static int32 SingleThreadPerform(void* a);
|
||||
|
||||
QueueFileDownload* fQueue[3];
|
||||
|
||||
// Proxy
|
||||
int32 fPort;
|
||||
BString fAddress;
|
||||
BString fUserpwd;
|
||||
bool fEnabled;
|
||||
BLooper* fTarget;
|
||||
};
|
||||
|
||||
#endif // _DOWNLOAD_MANAGER_H
|
|
@ -0,0 +1,16 @@
|
|||
SubDir TOP libs libdownload ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(TOP) ] ;
|
||||
SubDirSysHdrs [ FDirName $(CURL_INCLUDE_DIR) ] ;
|
||||
|
||||
StaticLibrary libdownload.a :
|
||||
ActionDownload.cpp
|
||||
DownloadManager.cpp
|
||||
QueueFileDownload.cpp
|
||||
QueueMultiActions.cpp
|
||||
StripeView.cpp
|
||||
PercentageWindow.cpp
|
||||
: be $(TARGET_LIBSTDC++) translation curl
|
||||
;
|
||||
|
||||
LINKFLAGS on libdownload.a += -L$(CURL_LIBRARY_DIR) ;
|
|
@ -0,0 +1,872 @@
|
|||
/*
|
||||
Open Tracker License
|
||||
|
||||
Terms and Conditions
|
||||
|
||||
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice applies to all licensees
|
||||
and shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Be Incorporated shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
this Software without prior written authorization from Be Incorporated.
|
||||
|
||||
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
|
||||
of Be Incorporated in the United States and other countries. Other brand product
|
||||
names are registered trademarks or trademarks of their respective holders.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||
** **
|
||||
** DANGER, WILL ROBINSON! **
|
||||
** **
|
||||
** The interfaces contained here are part of BeOS's **
|
||||
** **
|
||||
** >> PRIVATE NOT FOR PUBLIC USE << **
|
||||
** **
|
||||
** implementation. **
|
||||
** **
|
||||
** These interfaces WILL CHANGE in future releases. **
|
||||
** If you use them, your app WILL BREAK at some future time. **
|
||||
** **
|
||||
** (And yes, this does mean that binaries built from OpenTracker will not **
|
||||
** be compatible with some future releases of the OS. When that happens, **
|
||||
** we will provide an updated version of this file to keep compatibility.) **
|
||||
** **
|
||||
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// ObjectList is a wrapper around BList that adds type safety,
|
||||
// optional object ownership, search, insert operations, etc.
|
||||
//
|
||||
|
||||
#ifndef __OBJECT_LIST__
|
||||
#define __OBJECT_LIST__
|
||||
|
||||
#ifndef _BE_H
|
||||
#include <List.h>
|
||||
#endif
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
template<class T> class BObjectList;
|
||||
|
||||
template<class T>
|
||||
struct UnaryPredicate {
|
||||
|
||||
virtual int operator()(const T*) const
|
||||
// virtual could be avoided here if FindBinaryInsertionIndex,
|
||||
// etc. were member template functions
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static int _unary_predicate_glue(const void* item, void* context);
|
||||
|
||||
friend class BObjectList<T>;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
int
|
||||
UnaryPredicate<T>::_unary_predicate_glue(const void* item, void* context)
|
||||
{
|
||||
return ((UnaryPredicate<T> *)context)->operator()((const T*)item);
|
||||
}
|
||||
|
||||
|
||||
class _PointerList_ : public BList
|
||||
{
|
||||
public:
|
||||
_PointerList_(const _PointerList_ &list);
|
||||
_PointerList_(int32 itemsPerBlock = 20, bool owning = false);
|
||||
~_PointerList_();
|
||||
|
||||
typedef void *(* GenericEachFunction)(void*, void*);
|
||||
typedef int (* GenericCompareFunction)(const void*, const void*);
|
||||
typedef int (* GenericCompareFunctionWithState)(const void*, const void*,
|
||||
void*);
|
||||
typedef int (* UnaryPredicateGlue)(const void*, void*);
|
||||
|
||||
void* EachElement(GenericEachFunction, void*);
|
||||
void SortItems(GenericCompareFunction);
|
||||
void SortItems(GenericCompareFunctionWithState, void* state);
|
||||
void HSortItems(GenericCompareFunction);
|
||||
void HSortItems(GenericCompareFunctionWithState, void* state);
|
||||
|
||||
void* BinarySearch(const void*, GenericCompareFunction) const;
|
||||
void* BinarySearch(const void*, GenericCompareFunctionWithState, void* state) const;
|
||||
|
||||
int32 BinarySearchIndex(const void*, GenericCompareFunction) const;
|
||||
int32 BinarySearchIndex(const void*, GenericCompareFunctionWithState, void* state) const;
|
||||
int32 BinarySearchIndexByPredicate(const void*, UnaryPredicateGlue) const;
|
||||
|
||||
bool Owning() const;
|
||||
bool ReplaceItem(int32, void*);
|
||||
|
||||
protected:
|
||||
bool owning;
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class BObjectList : private _PointerList_
|
||||
{
|
||||
public:
|
||||
|
||||
// iteration and sorting
|
||||
typedef T *(* EachFunction)(T*, void*);
|
||||
typedef const T *(* ConstEachFunction)(const T*, void*);
|
||||
typedef int (* CompareFunction)(const T*, const T*);
|
||||
typedef int (* CompareFunctionWithState)(const T*, const T*, void* state);
|
||||
|
||||
BObjectList(int32 itemsPerBlock = 20, bool owning = false);
|
||||
BObjectList(const BObjectList& list);
|
||||
// clones list; if list is owning, makes copies of all
|
||||
// the items
|
||||
|
||||
virtual ~BObjectList();
|
||||
|
||||
BObjectList& operator=(const BObjectList& list);
|
||||
// clones list; if list is owning, makes copies of all
|
||||
// the items
|
||||
|
||||
// adding and removing
|
||||
// ToDo:
|
||||
// change Add calls to return const item
|
||||
bool AddItem(T*);
|
||||
bool AddItem(T*, int32);
|
||||
bool AddList(BObjectList*);
|
||||
bool AddList(BObjectList*, int32);
|
||||
|
||||
bool RemoveItem(T*, bool deleteIfOwning = true);
|
||||
// if owning, deletes the removed item
|
||||
T* RemoveItemAt(int32);
|
||||
// returns the removed item
|
||||
|
||||
void MakeEmpty(bool deleteIfOwning = true);
|
||||
|
||||
// item access
|
||||
T* ItemAt(int32) const;
|
||||
|
||||
bool ReplaceItem(int32 index, T*);
|
||||
// if list is owning, deletes the item at <index> first
|
||||
T* SwapWithItem(int32 index, T* newItem);
|
||||
// same as ReplaceItem, except does not delete old item at <index>,
|
||||
// returns it instead
|
||||
|
||||
T* FirstItem() const;
|
||||
T* LastItem() const;
|
||||
|
||||
// misc. getters
|
||||
int32 IndexOf(const T*) const;
|
||||
bool HasItem(const T*) const;
|
||||
bool IsEmpty() const;
|
||||
int32 CountItems() const;
|
||||
|
||||
T* EachElement(EachFunction, void*);
|
||||
const T* EachElement(ConstEachFunction, void*) const;
|
||||
|
||||
void SortItems(CompareFunction);
|
||||
void SortItems(CompareFunctionWithState, void* state);
|
||||
void HSortItems(CompareFunction);
|
||||
void HSortItems(CompareFunctionWithState, void* state);
|
||||
|
||||
// linear search, returns first item that matches predicate
|
||||
const T* FindIf(const UnaryPredicate<T> &) const;
|
||||
T* FindIf(const UnaryPredicate<T> &);
|
||||
|
||||
// list must be sorted with CompareFunction for these to work
|
||||
T* BinarySearch(const T&, CompareFunction) const;
|
||||
T* BinarySearch(const T&, CompareFunctionWithState, void* state) const;
|
||||
|
||||
template<typename Key>
|
||||
T* BinarySearchByKey(const Key& key, int (*compare)(const Key*, const T*))
|
||||
const;
|
||||
|
||||
template<typename Key>
|
||||
T* BinarySearchByKey(const Key& key,
|
||||
int (*compare)(const Key*, const T*, void*), void* state) const;
|
||||
|
||||
int32 BinarySearchIndex(const T& item, CompareFunction compare) const;
|
||||
int32 BinarySearchIndex(const T& item, CompareFunctionWithState compare,
|
||||
void* state) const;
|
||||
|
||||
template<typename Key>
|
||||
int32 BinarySearchIndexByKey(const Key& key,
|
||||
int (*compare)(const Key*, const T*)) const;
|
||||
|
||||
// Binary insertion - list must be sorted with CompareFunction for
|
||||
// these to work
|
||||
|
||||
// simple insert
|
||||
bool BinaryInsert(T*, CompareFunction);
|
||||
bool BinaryInsert(T*, CompareFunctionWithState, void* state);
|
||||
bool BinaryInsert(T*, const UnaryPredicate<T> &);
|
||||
|
||||
// unique insert, returns false if item already in list
|
||||
bool BinaryInsertUnique(T*, CompareFunction);
|
||||
bool BinaryInsertUnique(T*, CompareFunctionWithState, void* state);
|
||||
bool BinaryInsertUnique(T*, const UnaryPredicate<T> &);
|
||||
|
||||
// insert a copy of the item, returns new inserted item
|
||||
T* BinaryInsertCopy(const T& copyThis, CompareFunction);
|
||||
T* BinaryInsertCopy(const T& copyThis, CompareFunctionWithState, void* state);
|
||||
|
||||
// insert a copy of the item if not in list already
|
||||
// returns new inserted item or existing item in case of a conflict
|
||||
T* BinaryInsertCopyUnique(const T& copyThis, CompareFunction);
|
||||
T* BinaryInsertCopyUnique(const T& copyThis, CompareFunctionWithState, void* state);
|
||||
|
||||
int32 FindBinaryInsertionIndex(const UnaryPredicate<T> &, bool* alreadyInList = 0) const;
|
||||
// returns either the index into which a new item should be inserted
|
||||
// or index of an existing item that matches the predicate
|
||||
|
||||
// deprecated API, will go away
|
||||
BList* AsBList() {
|
||||
return this;
|
||||
}
|
||||
const BList* AsBList() const {
|
||||
return this;
|
||||
}
|
||||
private:
|
||||
void SetItem(int32, T*);
|
||||
};
|
||||
|
||||
template<class Item, class Result, class Param1>
|
||||
Result
|
||||
WhileEachListItem(BObjectList<Item> *list, Result (Item::*func)(Param1), Param1 p1)
|
||||
{
|
||||
Result result = 0;
|
||||
int32 count = list->CountItems();
|
||||
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if ((result = (list->ItemAt(index)->*func)(p1)) != 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Item, class Result, class Param1>
|
||||
Result
|
||||
WhileEachListItem(BObjectList<Item> *list, Result (*func)(Item*, Param1), Param1 p1)
|
||||
{
|
||||
Result result = 0;
|
||||
int32 count = list->CountItems();
|
||||
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if ((result = (*func)(list->ItemAt(index), p1)) != 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Item, class Result, class Param1, class Param2>
|
||||
Result
|
||||
WhileEachListItem(BObjectList<Item> *list, Result (Item::*func)(Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
Result result = 0;
|
||||
int32 count = list->CountItems();
|
||||
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if ((result = (list->ItemAt(index)->*func)(p1, p2)) != 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Item, class Result, class Param1, class Param2>
|
||||
Result
|
||||
WhileEachListItem(BObjectList<Item> *list, Result (*func)(Item*, Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
Result result = 0;
|
||||
int32 count = list->CountItems();
|
||||
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if ((result = (*func)(list->ItemAt(index), p1, p2)) != 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Item, class Result, class Param1, class Param2, class Param3, class Param4>
|
||||
Result
|
||||
WhileEachListItem(BObjectList<Item> *list, Result (*func)(Item*, Param1, Param2,
|
||||
Param3, Param4), Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||
{
|
||||
Result result = 0;
|
||||
int32 count = list->CountItems();
|
||||
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if ((result = (*func)(list->ItemAt(index), p1, p2, p3, p4)) != 0)
|
||||
break;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Item, class Result>
|
||||
void
|
||||
EachListItemIgnoreResult(BObjectList<Item> *list, Result (Item::*func)())
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(list->ItemAt(index)->*func)();
|
||||
}
|
||||
|
||||
template<class Item, class Param1>
|
||||
void
|
||||
EachListItem(BObjectList<Item> *list, void (*func)(Item*, Param1), Param1 p1)
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(func)(list->ItemAt(index), p1);
|
||||
}
|
||||
|
||||
template<class Item, class Param1, class Param2>
|
||||
void
|
||||
EachListItem(BObjectList<Item> *list, void (Item::*func)(Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(list->ItemAt(index)->*func)(p1, p2);
|
||||
}
|
||||
|
||||
template<class Item, class Param1, class Param2>
|
||||
void
|
||||
EachListItem(BObjectList<Item> *list, void (*func)(Item*, Param1, Param2),
|
||||
Param1 p1, Param2 p2)
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(func)(list->ItemAt(index), p1, p2);
|
||||
}
|
||||
|
||||
template<class Item, class Param1, class Param2, class Param3>
|
||||
void
|
||||
EachListItem(BObjectList<Item> *list, void (*func)(Item*, Param1, Param2,
|
||||
Param3), Param1 p1, Param2 p2, Param3 p3)
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(func)(list->ItemAt(index), p1, p2, p3);
|
||||
}
|
||||
|
||||
|
||||
template<class Item, class Param1, class Param2, class Param3, class Param4>
|
||||
void
|
||||
EachListItem(BObjectList<Item> *list, void (*func)(Item*, Param1, Param2,
|
||||
Param3, Param4), Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||
{
|
||||
int32 count = list->CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
(func)(list->ItemAt(index), p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
// inline code
|
||||
|
||||
inline bool
|
||||
_PointerList_::Owning() const
|
||||
{
|
||||
return owning;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BObjectList<T>::BObjectList(int32 itemsPerBlock, bool owning)
|
||||
: _PointerList_(itemsPerBlock, owning)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BObjectList<T>::BObjectList(const BObjectList<T> &list)
|
||||
: _PointerList_(list)
|
||||
{
|
||||
owning = list.owning;
|
||||
if (owning) {
|
||||
// make our own copies in an owning list
|
||||
int32 count = list.CountItems();
|
||||
for (int32 index = 0; index < count; index++) {
|
||||
T* item = list.ItemAt(index);
|
||||
if (item)
|
||||
item = new T(*item);
|
||||
SetItem(index, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BObjectList<T>::~BObjectList()
|
||||
{
|
||||
if (Owning())
|
||||
// have to nuke elements first
|
||||
MakeEmpty();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BObjectList<T> &
|
||||
BObjectList<T>::operator=(const BObjectList<T> &list)
|
||||
{
|
||||
owning = list.owning;
|
||||
BObjectList<T> &result = (BObjectList<T> &)_PointerList_::operator=(list);
|
||||
if (owning) {
|
||||
// make our own copies in an owning list
|
||||
int32 count = list.CountItems();
|
||||
for (int32 index = 0; index < count; index++) {
|
||||
T* item = list.ItemAt(index);
|
||||
if (item)
|
||||
item = new T(*item);
|
||||
SetItem(index, item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::AddItem(T* item)
|
||||
{
|
||||
// need to cast to void * to make T work for const pointers
|
||||
return _PointerList_::AddItem((void*)item);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::AddItem(T* item, int32 atIndex)
|
||||
{
|
||||
return _PointerList_::AddItem((void*)item, atIndex);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::AddList(BObjectList<T> *newItems)
|
||||
{
|
||||
return _PointerList_::AddList(newItems);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::AddList(BObjectList<T> *newItems, int32 atIndex)
|
||||
{
|
||||
return _PointerList_::AddList(newItems, atIndex);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::RemoveItem(T* item, bool deleteIfOwning)
|
||||
{
|
||||
bool result = _PointerList_::RemoveItem((void*)item);
|
||||
|
||||
if (result && Owning() && deleteIfOwning)
|
||||
delete item;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::RemoveItemAt(int32 index)
|
||||
{
|
||||
return (T*)_PointerList_::RemoveItem(index);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T *
|
||||
BObjectList<T>::ItemAt(int32 index) const
|
||||
{
|
||||
return (T*)_PointerList_::ItemAt(index);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::ReplaceItem(int32 index, T* item)
|
||||
{
|
||||
if (owning)
|
||||
delete ItemAt(index);
|
||||
return _PointerList_::ReplaceItem(index, (void*)item);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::SwapWithItem(int32 index, T* newItem)
|
||||
{
|
||||
T* result = ItemAt(index);
|
||||
_PointerList_::ReplaceItem(index, (void*)newItem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::SetItem(int32 index, T* newItem)
|
||||
{
|
||||
_PointerList_::ReplaceItem(index, (void*)newItem);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int32
|
||||
BObjectList<T>::IndexOf(const T* item) const
|
||||
{
|
||||
return _PointerList_::IndexOf((void*)item);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::FirstItem() const
|
||||
{
|
||||
return (T*)_PointerList_::FirstItem();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::LastItem() const
|
||||
{
|
||||
return (T*)_PointerList_::LastItem();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::HasItem(const T* item) const
|
||||
{
|
||||
return _PointerList_::HasItem((void*)item);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::IsEmpty() const
|
||||
{
|
||||
return _PointerList_::IsEmpty();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int32
|
||||
BObjectList<T>::CountItems() const
|
||||
{
|
||||
return _PointerList_::CountItems();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::MakeEmpty(bool deleteIfOwning)
|
||||
{
|
||||
if (owning && deleteIfOwning) {
|
||||
int32 count = CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
delete ItemAt(index);
|
||||
}
|
||||
_PointerList_::MakeEmpty();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::EachElement(EachFunction func, void* params)
|
||||
{
|
||||
return (T*)_PointerList_::EachElement((GenericEachFunction)func, params);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
const T *
|
||||
BObjectList<T>::EachElement(ConstEachFunction func, void* params) const
|
||||
{
|
||||
return (const T*)
|
||||
const_cast<BObjectList<T> *>(this)->_PointerList_::EachElement(
|
||||
(GenericEachFunction)func, params);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T *
|
||||
BObjectList<T>::FindIf(const UnaryPredicate<T> &predicate) const
|
||||
{
|
||||
int32 count = CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if (predicate.operator()(ItemAt(index)) == 0)
|
||||
return ItemAt(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::FindIf(const UnaryPredicate<T> &predicate)
|
||||
{
|
||||
int32 count = CountItems();
|
||||
for (int32 index = 0; index < count; index++)
|
||||
if (predicate.operator()(ItemAt(index)) == 0)
|
||||
return ItemAt(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::SortItems(CompareFunction function)
|
||||
{
|
||||
_PointerList_::SortItems((GenericCompareFunction)function);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::SortItems(CompareFunctionWithState function, void* state)
|
||||
{
|
||||
_PointerList_::SortItems((GenericCompareFunctionWithState)function, state);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::HSortItems(CompareFunction function)
|
||||
{
|
||||
_PointerList_::HSortItems((GenericCompareFunction)function);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
BObjectList<T>::HSortItems(CompareFunctionWithState function, void* state)
|
||||
{
|
||||
_PointerList_::HSortItems((GenericCompareFunctionWithState)function, state);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinarySearch(const T& key, CompareFunction func) const
|
||||
{
|
||||
return (T*)_PointerList_::BinarySearch(&key,
|
||||
(GenericCompareFunction)func);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinarySearch(const T& key, CompareFunctionWithState func, void* state) const
|
||||
{
|
||||
return (T*)_PointerList_::BinarySearch(&key,
|
||||
(GenericCompareFunctionWithState)func, state);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
template<typename Key>
|
||||
T *
|
||||
BObjectList<T>::BinarySearchByKey(const Key& key,
|
||||
int (*compare)(const Key*, const T*)) const
|
||||
{
|
||||
return (T*)_PointerList_::BinarySearch(&key,
|
||||
(GenericCompareFunction)compare);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
template<typename Key>
|
||||
T *
|
||||
BObjectList<T>::BinarySearchByKey(const Key& key,
|
||||
int (*compare)(const Key*, const T*, void*), void* state) const
|
||||
{
|
||||
return (T*)_PointerList_::BinarySearch(&key,
|
||||
(GenericCompareFunctionWithState)compare, state);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
int32
|
||||
BObjectList<T>::BinarySearchIndex(const T& item, CompareFunction compare) const
|
||||
{
|
||||
return _PointerList_::BinarySearchIndex(&item,
|
||||
(GenericCompareFunction)compare);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
int32
|
||||
BObjectList<T>::BinarySearchIndex(const T& item,
|
||||
CompareFunctionWithState compare, void* state) const
|
||||
{
|
||||
return _PointerList_::BinarySearchIndex(&item,
|
||||
(GenericCompareFunctionWithState)compare, state);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
template<typename Key>
|
||||
int32
|
||||
BObjectList<T>::BinarySearchIndexByKey(const Key& key,
|
||||
int (*compare)(const Key*, const T*)) const
|
||||
{
|
||||
return _PointerList_::BinarySearchIndex(&key,
|
||||
(GenericCompareFunction)compare);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsert(T* item, CompareFunction func)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(item,
|
||||
(GenericCompareFunction)func);
|
||||
if (index >= 0) {
|
||||
// already in list, add after existing
|
||||
return AddItem(item, index + 1);
|
||||
}
|
||||
|
||||
return AddItem(item, -index - 1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsert(T* item, CompareFunctionWithState func, void* state)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(item,
|
||||
(GenericCompareFunctionWithState)func, state);
|
||||
if (index >= 0) {
|
||||
// already in list, add after existing
|
||||
return AddItem(item, index + 1);
|
||||
}
|
||||
|
||||
return AddItem(item, -index - 1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsertUnique(T* item, CompareFunction func)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(item,
|
||||
(GenericCompareFunction)func);
|
||||
if (index >= 0)
|
||||
return false;
|
||||
|
||||
return AddItem(item, -index - 1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsertUnique(T* item, CompareFunctionWithState func, void* state)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(item,
|
||||
(GenericCompareFunctionWithState)func, state);
|
||||
if (index >= 0)
|
||||
return false;
|
||||
|
||||
return AddItem(item, -index - 1);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinaryInsertCopy(const T& copyThis, CompareFunction func)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(©This,
|
||||
(GenericCompareFunction)func);
|
||||
|
||||
if (index >= 0)
|
||||
index++;
|
||||
else
|
||||
index = -index - 1;
|
||||
|
||||
T* newItem = new T(copyThis);
|
||||
AddItem(newItem, index);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinaryInsertCopy(const T& copyThis, CompareFunctionWithState func, void* state)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(©This,
|
||||
(GenericCompareFunctionWithState)func, state);
|
||||
|
||||
if (index >= 0)
|
||||
index++;
|
||||
else
|
||||
index = -index - 1;
|
||||
|
||||
T* newItem = new T(copyThis);
|
||||
AddItem(newItem, index);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinaryInsertCopyUnique(const T& copyThis, CompareFunction func)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(©This,
|
||||
(GenericCompareFunction)func);
|
||||
if (index >= 0)
|
||||
return ItemAt(index);
|
||||
|
||||
index = -index - 1;
|
||||
T* newItem = new T(copyThis);
|
||||
AddItem(newItem, index);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *
|
||||
BObjectList<T>::BinaryInsertCopyUnique(const T& copyThis, CompareFunctionWithState func,
|
||||
void* state)
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndex(©This,
|
||||
(GenericCompareFunctionWithState)func, state);
|
||||
if (index >= 0)
|
||||
return ItemAt(index);
|
||||
|
||||
index = -index - 1;
|
||||
T* newItem = new T(copyThis);
|
||||
AddItem(newItem, index);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int32
|
||||
BObjectList<T>::FindBinaryInsertionIndex(const UnaryPredicate<T> &pred, bool* alreadyInList)
|
||||
const
|
||||
{
|
||||
int32 index = _PointerList_::BinarySearchIndexByPredicate(&pred,
|
||||
(UnaryPredicateGlue)&UnaryPredicate<T>::_unary_predicate_glue);
|
||||
|
||||
if (alreadyInList)
|
||||
*alreadyInList = index >= 0;
|
||||
|
||||
if (index < 0)
|
||||
index = -index - 1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsert(T* item, const UnaryPredicate<T> &pred)
|
||||
{
|
||||
return AddItem(item, FindBinaryInsertionIndex(pred));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
BObjectList<T>::BinaryInsertUnique(T* item, const UnaryPredicate<T> &pred)
|
||||
{
|
||||
bool alreadyInList;
|
||||
int32 index = FindBinaryInsertionIndex(pred, &alreadyInList);
|
||||
if (alreadyInList)
|
||||
return false;
|
||||
|
||||
AddItem(item, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __OBJECT_LIST__ */
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "PercentageWindow.h"
|
||||
|
||||
#include "StripeView.h"
|
||||
#include <Alert.h>
|
||||
|
||||
#include <StringView.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#define DEFAULT_RECT BRect(0, 0, 310, 75)
|
||||
|
||||
static const int kTextIconOffsetSpace = 30;
|
||||
|
||||
PercentageWindow::PercentageWindow(const char* title, const char* text, BBitmap* icon) : BWindow(DEFAULT_RECT, title, B_MODAL_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
|
||||
{
|
||||
|
||||
// Set up the "_master_" view
|
||||
|
||||
StripeView* masterView = new StripeView(Bounds());
|
||||
AddChild(masterView);
|
||||
masterView->SetBitmap(icon);
|
||||
|
||||
kTextIconOffset = 0;
|
||||
|
||||
if (masterView->Bitmap())
|
||||
kTextIconOffset = masterView->Bitmap()->Bounds().right + kTextIconOffsetSpace;
|
||||
|
||||
|
||||
//ok, un String
|
||||
//il percentage (a 0) con testo percentuale
|
||||
float maxW;
|
||||
|
||||
BStringView* text_string = new BStringView(BRect(kTextIconOffset, 6, 0, 0), "_text", text);
|
||||
masterView->AddChild(text_string);
|
||||
text_string->ResizeToPreferred();
|
||||
maxW = text_string->Frame().right + 6;
|
||||
|
||||
BRect rect(text_string->Frame());
|
||||
rect.OffsetBy(0, text_string->Bounds().Height() + 6);
|
||||
|
||||
perc = new BStringView(rect, "_percentage", "100%");
|
||||
masterView->AddChild(perc);
|
||||
perc->ResizeToPreferred();
|
||||
if (perc->Frame().right + 6 > maxW)
|
||||
maxW = perc->Frame().right + 6;
|
||||
|
||||
perc->SetText("0%");
|
||||
|
||||
maxW += kTextIconOffsetSpace;
|
||||
|
||||
ResizeTo(maxW, Bounds().bottom);
|
||||
|
||||
rect = Bounds();
|
||||
|
||||
rect.top = perc->Frame().bottom + 6;
|
||||
rect.left = perc->Frame().left;
|
||||
rect.right -= kTextIconOffsetSpace;
|
||||
|
||||
pw = new BStatusBar(rect, "status_bar", NULL, NULL);
|
||||
pw->SetMaxValue(100.0);
|
||||
masterView->AddChild(pw);
|
||||
// pw->ResizeToPreferred();
|
||||
|
||||
ResizeTo(Bounds().right, pw->Frame().bottom + 5);
|
||||
SetLook(B_FLOATING_WINDOW_LOOK);
|
||||
MoveTo(BAlert::AlertPosition(Frame().Width(), Frame().Height()));
|
||||
}
|
||||
|
||||
void
|
||||
PercentageWindow::SetPercentage(int p)
|
||||
{
|
||||
|
||||
|
||||
BString text;
|
||||
text << p << "%";
|
||||
|
||||
if (Lock()) {
|
||||
perc->SetText(text.String());
|
||||
pw->SetTo((float)p);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
PercentageWindow::GetPercentage()
|
||||
{
|
||||
return (int)pw->CurrentValue();
|
||||
}
|
||||
|
||||
bool
|
||||
PercentageWindow::QuitRequested()
|
||||
{
|
||||
if (fLooper)
|
||||
BMessenger(fLooper).SendMessage(fMsg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PercentageWindow::Go(BLooper* lop, int32 msg)
|
||||
{
|
||||
fLooper = lop;
|
||||
fMsg = msg;
|
||||
Show();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PercentageWindow_H_
|
||||
#define _PercentageWindow_H_
|
||||
|
||||
#include <Window.h>
|
||||
#include <Looper.h>
|
||||
#include <Bitmap.h>
|
||||
#include <String.h>
|
||||
#include <StatusBar.h>
|
||||
|
||||
class ReflowingTextView;
|
||||
class BStringView;
|
||||
|
||||
|
||||
class PercentageWindow : public BWindow
|
||||
{
|
||||
|
||||
public:
|
||||
PercentageWindow(const char* title, const char* text, BBitmap* icon = NULL);
|
||||
void Go(BLooper* lop = NULL, int32 msg = 0);
|
||||
void SetPercentage(int perc);
|
||||
int GetPercentage();
|
||||
bool QuitRequested();
|
||||
|
||||
private:
|
||||
BLooper* fLooper;
|
||||
int32 fMsg;
|
||||
float kTextIconOffset;
|
||||
BStringView* perc;
|
||||
BStatusBar* pw;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "QueueFileDownload.h"
|
||||
#include "ActionDownload.h"
|
||||
#include "Messenger.h"
|
||||
|
||||
void
|
||||
QueueFileDownload::ActionReadyToPerform(Action* action)
|
||||
{
|
||||
ActionDownload* ad = dynamic_cast<ActionDownload*>(action);
|
||||
if (!ad) return;
|
||||
|
||||
ad->SetLooper(fLooper, fMsg);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
QueueFileDownload::ActionPerformed(Action* action, status_t state, BMessage* msg)
|
||||
{
|
||||
|
||||
ActionDownload* ad = dynamic_cast<ActionDownload*>(action);
|
||||
if (!ad) return;
|
||||
|
||||
BMessage notify(*msg);
|
||||
notify.what = fMsg;
|
||||
|
||||
if (fLooper)
|
||||
BMessenger(fLooper).SendMessage(¬ify);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
QueueFileDownload::SuppressAction(Action* action)
|
||||
{
|
||||
ActionDownload* ad = dynamic_cast<ActionDownload*>(action);
|
||||
if (!ad) return;
|
||||
|
||||
ad->SetShouldStop(true);
|
||||
}
|
||||
|
||||
//--
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef QueueFileDownload_H_
|
||||
#define QueueFileDownload_H_
|
||||
|
||||
#include <Looper.h>
|
||||
|
||||
#include "QueueMultiActions.h"
|
||||
|
||||
class QueueFileDownload : public QueueMultiActions
|
||||
{
|
||||
public:
|
||||
QueueFileDownload(const char* name, int howMany, BLooper* target, uint32 msg)
|
||||
:
|
||||
QueueMultiActions(name, howMany)
|
||||
{
|
||||
fMsg = msg;
|
||||
fLooper = target;
|
||||
}
|
||||
|
||||
protected:
|
||||
void ActionPerformed(Action*, status_t, BMessage*);
|
||||
void ActionReadyToPerform(Action*);
|
||||
void SuppressAction(Action*);
|
||||
|
||||
private:
|
||||
BLooper* fLooper;
|
||||
uint32 fMsg;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "QueueMultiActions.h"
|
||||
|
||||
#include <Message.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define CHKLOCK if(!IsLocked()) debugger("\nQueueMultiActions must me locked!\n");
|
||||
|
||||
QueueMultiActions::QueueMultiActions(const char* name, int count)
|
||||
{
|
||||
|
||||
fCount = count;
|
||||
if (count > MAX_MULTI)
|
||||
debugger("wrong number of multi download settings");
|
||||
|
||||
for (int j = 0; j < MAX_MULTI; j++) {
|
||||
fCurrentAction[j] = NULL;
|
||||
fID[j] = 0;
|
||||
}
|
||||
|
||||
fName.SetTo(name);
|
||||
|
||||
for (int i = 0; i < fCount; i++) {
|
||||
BString n(name);
|
||||
n << "'s enemy #" << i;
|
||||
token* tok = new token;
|
||||
tok->qa = this;
|
||||
tok->index = i;
|
||||
fID[i] = spawn_thread(QueueMultiActions::ManageTheQueue, n.String(), B_NORMAL_PRIORITY, tok);
|
||||
//printf("Thread ready [%s] %ld\n",n.String(),fID[i]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fLock = create_sem(1, name);
|
||||
fLocked = false;
|
||||
|
||||
}
|
||||
|
||||
QueueMultiActions::~QueueMultiActions()
|
||||
{
|
||||
if (Lock()) {
|
||||
|
||||
for (int i = 0; i < fCount; i++) {
|
||||
suspend_thread(fID[i]);
|
||||
exit_thread(fID[i]);
|
||||
}
|
||||
delete_sem(fLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
QueueMultiActions::Lock()
|
||||
{
|
||||
status_t value = acquire_sem(fLock) ;
|
||||
if (value == B_NO_ERROR) {
|
||||
fLocked = true;
|
||||
}
|
||||
return (value == B_NO_ERROR);
|
||||
}
|
||||
|
||||
void
|
||||
QueueMultiActions::Unlock()
|
||||
{
|
||||
fLocked = false;
|
||||
release_sem(fLock);
|
||||
}
|
||||
|
||||
void
|
||||
QueueMultiActions::SetDownloadCount(int fProposedCount)
|
||||
{
|
||||
|
||||
if (Lock()) {
|
||||
|
||||
|
||||
if (fProposedCount == fCount || fProposedCount <= 0 || fProposedCount > MAX_MULTI) {
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fProposedCount > fCount) {
|
||||
|
||||
for (int i = fCount; i < fProposedCount; i++) {
|
||||
if ( fID[i] == 0) {
|
||||
BString n = fName;
|
||||
n << "'s enemy #" << i;
|
||||
token* tok = new token;
|
||||
tok->qa = this;
|
||||
tok->index = i;
|
||||
fID[i] = spawn_thread(QueueMultiActions::ManageTheQueue, n.String(), B_NORMAL_PRIORITY, tok);
|
||||
//printf("Thread ready [%s] %ld\n",n.String(),fID[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//uhm what to do?
|
||||
for (int i = fProposedCount; i < fCount; i++) {
|
||||
SuppressAction(fCurrentAction[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fCount = fProposedCount;
|
||||
//NotifyALL
|
||||
|
||||
for (int i = 0; i < fCount; i++)
|
||||
resume_thread(fID[i]);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
QueueMultiActions::AddAction(Action* a)
|
||||
{
|
||||
|
||||
//FIX!
|
||||
//esiste già un azione con lo stesso ID???
|
||||
|
||||
if (Lock()) {
|
||||
//printf("adding %ld - Action name %s\n",fID,a->GetDescription().String());
|
||||
fList.AddItem(a);
|
||||
if (fList.CountItems() <= fCount) { //Auto-start thread
|
||||
for (int i = 0; i < fCount; i++)
|
||||
resume_thread(fID[i]);
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
Action*
|
||||
QueueMultiActions::CurrentAction(int index)
|
||||
{
|
||||
CHKLOCK;
|
||||
return fCurrentAction[index];
|
||||
}
|
||||
|
||||
void
|
||||
QueueMultiActions::SetCurrentAction(Action* action, int index)
|
||||
{
|
||||
CHKLOCK;
|
||||
fCurrentAction[index] = action;
|
||||
}
|
||||
|
||||
int32
|
||||
QueueMultiActions::CountActions()
|
||||
{
|
||||
CHKLOCK;
|
||||
return fList.CountItems();
|
||||
}
|
||||
|
||||
Action*
|
||||
QueueMultiActions::ActionAt(int32 pos)
|
||||
{
|
||||
CHKLOCK;
|
||||
return fList.ItemAt(pos);
|
||||
}
|
||||
|
||||
void
|
||||
QueueMultiActions::RemoveActionAt(int32 pos)
|
||||
{
|
||||
CHKLOCK;
|
||||
fList.RemoveItemAt(pos);
|
||||
}
|
||||
|
||||
bool
|
||||
QueueMultiActions::IsLocked()
|
||||
{
|
||||
return fLocked;
|
||||
}
|
||||
|
||||
void
|
||||
QueueMultiActions::KIllThread(int id)
|
||||
{
|
||||
fID[id] = 0;
|
||||
}
|
||||
|
||||
int32
|
||||
QueueMultiActions::ManageTheQueue(void* data)
|
||||
{
|
||||
|
||||
token* tok = (token*)data;
|
||||
QueueMultiActions* qa = tok->qa;
|
||||
int index = tok->index;
|
||||
|
||||
//printf("Thread started %ld\n",qa->fID[index]);
|
||||
|
||||
while (true) {
|
||||
|
||||
Action* last = NULL;
|
||||
|
||||
if (qa->Lock()) {
|
||||
|
||||
//printf("Thread executing PID %ld Count %ld\n",qa->fID[index],qa->fList.CountItems());
|
||||
if (qa->fList.CountItems() > 0) {
|
||||
// remove and delete the action.
|
||||
last = qa->fList.ItemAt(0);
|
||||
qa->fList.RemoveItemAt(0);
|
||||
qa->SetCurrentAction(last, index);
|
||||
|
||||
} else {
|
||||
|
||||
last = NULL;
|
||||
qa->SetCurrentAction(last, index);
|
||||
}
|
||||
|
||||
qa->Unlock();
|
||||
}
|
||||
|
||||
if (last) {
|
||||
// pop the action
|
||||
qa->ActionReadyToPerform(last);
|
||||
// perform the action
|
||||
BMessage err;
|
||||
status_t status = last->Perform(&err);
|
||||
// do post-perform!
|
||||
|
||||
qa->ActionPerformed(last, status, &err);
|
||||
|
||||
if (qa->Lock()) {
|
||||
qa->SetCurrentAction(NULL, index);
|
||||
delete last;
|
||||
qa->Unlock();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//printf("Thread suspend PID %ld Count %ld\n",qa->fID[index],qa->fList.CountItems());
|
||||
suspend_thread(qa->fID[index]);
|
||||
}
|
||||
|
||||
//Check my life?
|
||||
if (qa->Lock()) {
|
||||
if ( index >= qa->fCount) {
|
||||
qa->KIllThread(index);
|
||||
qa->Unlock();
|
||||
//printf("Thread died PID %ld\n",qa->fID[index]);
|
||||
return 0; //bye-bye world!
|
||||
}
|
||||
qa->Unlock();
|
||||
}
|
||||
|
||||
} //while
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef QueueMultiActions_H_
|
||||
#define QueueMultiActions_H_
|
||||
|
||||
#include <Looper.h>
|
||||
#include <ObjectList.h>
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
#define MAX_MULTI 5
|
||||
|
||||
class QueueMultiActions
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
QueueMultiActions(const char* name, int count);
|
||||
virtual ~QueueMultiActions();
|
||||
|
||||
void AddAction(Action* );
|
||||
|
||||
//BEFORE CALLING CurrentAction, you MUST Lock() the Queue!
|
||||
Action* CurrentAction(int index);
|
||||
|
||||
int32 CountActions();
|
||||
int CountThreads() {
|
||||
return fCount;
|
||||
}
|
||||
|
||||
Action* ActionAt(int32 pos);
|
||||
void RemoveActionAt(int32 pos);
|
||||
|
||||
|
||||
void SetDownloadCount(int count);
|
||||
|
||||
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
bool IsLocked();
|
||||
|
||||
protected:
|
||||
|
||||
static int32 ManageTheQueue(void*);
|
||||
|
||||
virtual void ActionReadyToPerform(Action*) = 0;
|
||||
virtual void ActionPerformed(Action*, status_t, BMessage*) = 0;
|
||||
virtual void SuppressAction(Action*) = 0;
|
||||
|
||||
|
||||
private:
|
||||
struct token {
|
||||
int index;
|
||||
QueueMultiActions* qa;
|
||||
};
|
||||
|
||||
|
||||
void SetCurrentAction(Action*, int index);
|
||||
void KIllThread(int id);
|
||||
|
||||
Action* fCurrentAction[MAX_MULTI];
|
||||
thread_id fID[MAX_MULTI];
|
||||
sem_id fLock;
|
||||
BObjectList<Action> fList;
|
||||
bool fLocked;
|
||||
int fCount;
|
||||
BString fName;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "ReflowingTextView.h"
|
||||
|
||||
const bigtime_t RTV_HIDE_DELAY = 1500000;
|
||||
const bigtime_t RTV_SHOW_DELAY = 750000;
|
||||
|
||||
enum {
|
||||
RTV_SHOW_TOOLTIP = 0x1000,
|
||||
RTV_HIDE_TOOLTIP
|
||||
};
|
||||
|
||||
ReflowingTextView::ReflowingTextView(BRect frame, const char* name, BRect textRect, uint32 resizeMask, uint32 flags) : BTextView(frame, name, textRect, resizeMask, flags), _showTipRunner(NULL), _canShow(false), _urlTip(NULL), _currentLinkStart(-1)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
ReflowingTextView::~ReflowingTextView()
|
||||
{
|
||||
if ((_urlTip) && (_urlTip->Lock())) _urlTip->Quit();
|
||||
delete _showTipRunner;
|
||||
}
|
||||
|
||||
void ReflowingTextView::AttachedToWindow()
|
||||
{
|
||||
BTextView::AttachedToWindow();
|
||||
// FixTextRect();
|
||||
}
|
||||
|
||||
void ReflowingTextView::FrameResized(float w, float h)
|
||||
{
|
||||
BTextView::FrameResized(w, h);
|
||||
// FixTextRect();
|
||||
}
|
||||
|
||||
void ReflowingTextView::MouseMoved(BPoint where, uint32 code, const BMessage* msg)
|
||||
{
|
||||
const URLLink* link = NULL;
|
||||
if (code == B_INSIDE_VIEW) {
|
||||
link = GetURLAt(where);
|
||||
#ifdef B_BEOS_VERSION_5
|
||||
SetViewCursor((link != NULL) ? B_CURSOR_SYSTEM_DEFAULT : B_CURSOR_I_BEAM);
|
||||
#else
|
||||
be_app->SetCursor((link != NULL) ? B_HAND_CURSOR : B_I_BEAM_CURSOR);
|
||||
#endif
|
||||
}
|
||||
|
||||
BString scratch;
|
||||
const BString* urlString = link ? &link->GetURL() : &scratch;
|
||||
if ((link) && (urlString->Length() == 0)) {
|
||||
char* buf = new char[link->GetLength()+1];
|
||||
GetText(link->GetStart(), link->GetLength(), buf);
|
||||
buf[link->GetLength()] = '\0';
|
||||
scratch = buf;
|
||||
delete [] buf;
|
||||
urlString = &scratch;
|
||||
}
|
||||
|
||||
int32 linkStart = link ? (int32)link->GetStart() : -1;
|
||||
if (linkStart != _currentLinkStart) {
|
||||
_currentLinkStart = linkStart;
|
||||
_currentURLString = *urlString;
|
||||
if (linkStart >= 0) {
|
||||
if ((_canShow == false) && ((_showTipRunner == NULL) || (_runnerWillHide))) {
|
||||
// Schedule unsetting the show flag
|
||||
delete _showTipRunner;
|
||||
_runnerWillHide = false;
|
||||
_showTipRunner = new BMessageRunner(this, new BMessage(RTV_SHOW_TOOLTIP), RTV_SHOW_DELAY, 1);
|
||||
}
|
||||
} else {
|
||||
if (_canShow) {
|
||||
// schedule a delayed show
|
||||
delete _showTipRunner;
|
||||
_runnerWillHide = true;
|
||||
_showTipRunner = new BMessageRunner(this, new BMessage(RTV_HIDE_TOOLTIP), RTV_HIDE_DELAY, 1);
|
||||
} else if ((_showTipRunner) && (_runnerWillHide == false)) {
|
||||
delete _showTipRunner; // cancel the pending show!
|
||||
_showTipRunner = NULL;
|
||||
}
|
||||
}
|
||||
UpdateToolTip();
|
||||
}
|
||||
BTextView::MouseMoved(where, code, msg);
|
||||
}
|
||||
|
||||
void ReflowingTextView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case RTV_SHOW_TOOLTIP:
|
||||
delete _showTipRunner;
|
||||
_showTipRunner = NULL;
|
||||
_canShow = true;
|
||||
UpdateToolTip();
|
||||
break;
|
||||
|
||||
case RTV_HIDE_TOOLTIP:
|
||||
delete _showTipRunner;
|
||||
_showTipRunner = NULL;
|
||||
_canShow = false;
|
||||
UpdateToolTip();
|
||||
break;
|
||||
|
||||
default:
|
||||
BTextView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ReflowingTextView::UpdateToolTip()
|
||||
{
|
||||
if ((_canShow) && (_currentLinkStart >= 0)) {
|
||||
if (_urlTip == NULL) {
|
||||
_urlTip = new BWindow(BRect(0, 0, 5, 5), NULL, B_NO_BORDER_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_AVOID_FOCUS);
|
||||
BView* blackBorder = new BView(_urlTip->Bounds(), NULL, B_FOLLOW_ALL_SIDES, 0);
|
||||
const rgb_color black = {0, 0, 0, 255};
|
||||
blackBorder->SetViewColor(black);
|
||||
_urlTip->AddChild(blackBorder);
|
||||
|
||||
const rgb_color hiliteYellow = {255, 255, 200, 255};
|
||||
BRect inset = blackBorder->Bounds();
|
||||
inset.InsetBy(1, 1);
|
||||
BView* yellowInterior = new BView(inset, NULL, B_FOLLOW_ALL_SIDES, 0);
|
||||
yellowInterior->SetLowColor(hiliteYellow);
|
||||
yellowInterior->SetViewColor(hiliteYellow);
|
||||
blackBorder->AddChild(yellowInterior);
|
||||
|
||||
_urlStringView = new BStringView(yellowInterior->Bounds(), NULL, "", B_FOLLOW_ALL_SIDES);
|
||||
_urlStringView->SetLowColor(hiliteYellow);
|
||||
_urlStringView->SetViewColor(hiliteYellow);
|
||||
yellowInterior->AddChild(_urlStringView);
|
||||
}
|
||||
if (_urlTip->Lock()) {
|
||||
font_height ttfh;
|
||||
_urlStringView->GetFontHeight(&ttfh);
|
||||
float urlHeight = 20.0f;
|
||||
BPoint pt = PointAt(_currentLinkStart, &urlHeight);
|
||||
_urlTip->MoveTo(ConvertToScreen(pt) + BPoint(15.0f, -(ttfh.ascent + ttfh.descent + 3.0f)));
|
||||
|
||||
_urlTip->ResizeTo(muscleMin(_urlStringView->StringWidth(_currentURLString.String()) + 4.0f, 400.0f), ttfh.ascent + ttfh.descent + 2.0f);
|
||||
_urlStringView->SetText(_currentURLString.String());
|
||||
_urlTip->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
if (_urlTip->IsHidden()) _urlTip->Show();
|
||||
_urlTip->Unlock();
|
||||
}
|
||||
} else if (_urlTip) {
|
||||
if (_urlTip->Lock()) {
|
||||
if (_urlTip->IsHidden() == false) _urlTip->Hide();
|
||||
_urlTip->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReflowingTextView::MouseDown(BPoint where)
|
||||
{
|
||||
if (IsFocus() == false) MakeFocus();
|
||||
const URLLink* url = GetURLAt(where);
|
||||
if (url) {
|
||||
char* allocBuf = NULL;
|
||||
const char* buf = url->GetURL().String();
|
||||
if (buf[0] == '\0') {
|
||||
buf = allocBuf = new char[url->GetLength()+1];
|
||||
GetText(url->GetStart(), url->GetLength(), allocBuf);
|
||||
allocBuf[url->GetLength()] = '\0';
|
||||
}
|
||||
|
||||
if (strncasecmp(buf, "beshare://", 10) == 0) {
|
||||
char* argv[] = {(char*) &buf[10]};
|
||||
// be_roster->Launch(BESHARE_MIME_TYPE, ARRAYITEMS(argv), argv);
|
||||
} else if (strncasecmp(buf, "beshare:", 8) == 0) {
|
||||
BMessage msg(_queryMessage);
|
||||
msg.AddString("query", &buf[8]);
|
||||
_commandTarget.SendMessage(&msg);
|
||||
} else if (strncasecmp(buf, "share:", 6) == 0) {
|
||||
BMessage msg(_queryMessage);
|
||||
msg.AddString("query", &buf[6]);
|
||||
_commandTarget.SendMessage(&msg);
|
||||
} else if (strncasecmp(buf, "priv:", 5) == 0) {
|
||||
BMessage msg(_privMessage);
|
||||
msg.AddString("users", &buf[5]);
|
||||
_commandTarget.SendMessage(&msg);
|
||||
} else if (strncasecmp(buf, "audio://", 8) == 0) {
|
||||
BMessage msg(B_REFS_RECEIVED);
|
||||
BString temp("http://");
|
||||
temp += &buf[8];
|
||||
msg.AddString("be:url", temp);
|
||||
be_roster->Launch("audio/x-scpls", &msg);
|
||||
} else be_roster->Launch(strncasecmp(buf, "mailto:", 7) ? "text/html" : "text/x-email", 1, const_cast<char**>(&buf));
|
||||
|
||||
delete [] allocBuf;
|
||||
}
|
||||
BTextView::MouseDown(where);
|
||||
}
|
||||
|
||||
void ReflowingTextView::FixTextRect()
|
||||
{
|
||||
BRect t(Frame());
|
||||
SetTextRect(t);
|
||||
}
|
||||
|
||||
void ReflowingTextView::Clear()
|
||||
{
|
||||
Delete(0, TextLength() - 1);
|
||||
_urls.Clear();
|
||||
}
|
||||
|
||||
void ReflowingTextView::AddURLRegion(uint32 start, uint32 len, const BString& optHiddenURL)
|
||||
{
|
||||
_urls.AddTail(URLLink(start, len, optHiddenURL));
|
||||
}
|
||||
|
||||
void ReflowingTextView::SetCommandURLTarget(const BMessenger& target, const BMessage& queryMsg, const BMessage& privMsg)
|
||||
{
|
||||
_commandTarget = target;
|
||||
_queryMessage = queryMsg;
|
||||
_privMessage = privMsg;
|
||||
}
|
||||
|
||||
const ReflowingTextView::URLLink* ReflowingTextView::GetURLAt(BPoint pt) const
|
||||
{
|
||||
uint32 offset = (uint32) OffsetAt(pt);
|
||||
for (int i = _urls.GetNumItems() - 1; i >= 0; i--) {
|
||||
const URLLink& url = _urls[i];
|
||||
if ((offset >= url.GetStart()) && (offset < url.GetStart() + url.GetLength())) return &url;
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef REFLOWING_TEXT_VIEW_H
|
||||
#define REFLOWING_TEXT_VIEW_H
|
||||
|
||||
#include <app/AppDefs.h>
|
||||
#include <app/Application.h>
|
||||
#include <app/Roster.h>
|
||||
#include <app/MessageFilter.h>
|
||||
#include <app/Message.h>
|
||||
#include <app/MessageRunner.h>
|
||||
#include <app/Messenger.h>
|
||||
#include <interface/StringView.h>
|
||||
#include <interface/TextView.h>
|
||||
#include <interface/Window.h>
|
||||
|
||||
#include "Queue.h"
|
||||
#include <String.h>
|
||||
//#include "BeShareNameSpace.h"
|
||||
|
||||
|
||||
/* Subsclass of BTextView that automatically reflows the text when it is resized */
|
||||
class ReflowingTextView : public BTextView
|
||||
{
|
||||
public:
|
||||
ReflowingTextView(BRect frame, const char* name, BRect textRect, uint32 resizeMask, uint32 flags = B_WILL_DRAW | B_PULSE_NEEDED);
|
||||
virtual ~ReflowingTextView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
virtual void FrameResized(float w, float h);
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
virtual void MouseMoved(BPoint where, uint32 code, const BMessage* msg);
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
|
||||
void FixTextRect();
|
||||
|
||||
void Clear();
|
||||
|
||||
void AddURLRegion(uint32 start, uint32 len, const BString& optHiddenURL);
|
||||
|
||||
void SetCommandURLTarget(const BMessenger& target, const BMessage& queryMsg, const BMessage& privMsg);
|
||||
|
||||
private:
|
||||
void UpdateToolTip();
|
||||
|
||||
/* A simple little data class that remembers stuff we need to remember about hyperlinks in the text view */
|
||||
class URLLink
|
||||
{
|
||||
public:
|
||||
URLLink() : _start(0), _len(0) {
|
||||
/* empty */
|
||||
}
|
||||
URLLink(uint32 start, uint32 len, const BString& optURL) : _start(start), _len(len), _url(optURL) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
inline uint32 GetStart() const {
|
||||
return _start;
|
||||
}
|
||||
inline uint32 GetLength() const {
|
||||
return _len;
|
||||
}
|
||||
const BString& GetURL() const {
|
||||
return _url;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _start;
|
||||
uint32 _len;
|
||||
BString _url;
|
||||
};
|
||||
|
||||
const URLLink* GetURLAt(BPoint pt) const;
|
||||
|
||||
Queue<URLLink> _urls;
|
||||
BMessenger _commandTarget;
|
||||
BMessage _queryMessage;
|
||||
BMessage _privMessage;
|
||||
BMessageRunner* _showTipRunner;
|
||||
bool _runnerWillHide; // If true, the runner is a hide-runner.
|
||||
bool _canShow;
|
||||
BWindow* _urlTip;
|
||||
BStringView* _urlStringView;
|
||||
int32 _currentLinkStart;
|
||||
BString _currentURLString;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "StripeView.h"
|
||||
|
||||
static const int kIconStripeWidth = 30;
|
||||
|
||||
StripeView::StripeView(BRect frame)
|
||||
: BView(frame, "StripeView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
|
||||
fIconBitmap(NULL)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
StripeView::StripeView(BMessage* archive)
|
||||
: BView(archive),
|
||||
fIconBitmap(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StripeView::~StripeView() {}
|
||||
|
||||
|
||||
StripeView*
|
||||
StripeView::Instantiate(BMessage* archive)
|
||||
{
|
||||
if (!validate_instantiation(archive, "StripeView"))
|
||||
return NULL;
|
||||
|
||||
return new StripeView(archive);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
StripeView::Archive(BMessage* archive, bool deep)
|
||||
{
|
||||
return BView::Archive(archive, deep);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StripeView::Draw(BRect updateRect)
|
||||
{
|
||||
// Here's the fun stuff
|
||||
if (fIconBitmap) {
|
||||
BRect StripeRect = Bounds();
|
||||
StripeRect.right = kIconStripeWidth;
|
||||
SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
|
||||
FillRect(StripeRect);
|
||||
|
||||
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmapAsync(fIconBitmap, BPoint(18, 6));
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2010, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _StripeView_H_
|
||||
#define _StripeView_H_
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class StripeView : public BView
|
||||
{
|
||||
public:
|
||||
StripeView(BRect frame);
|
||||
StripeView(BMessage* archive);
|
||||
~StripeView();
|
||||
|
||||
static StripeView* Instantiate(BMessage* archive);
|
||||
status_t Archive(BMessage* archive, bool deep = true);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
// These functions (or something analogous) are missing from libbe.so's
|
||||
// dump. I can only assume that the bitmap is a public var in the
|
||||
// original implementation -- or BPAlert is a friend of StripeView.
|
||||
// Neither one is necessary, since I can just add these.
|
||||
void SetBitmap(BBitmap* Icon) {
|
||||
fIconBitmap = Icon;
|
||||
}
|
||||
BBitmap* Bitmap() {
|
||||
return fIconBitmap;
|
||||
}
|
||||
|
||||
private:
|
||||
BBitmap* fIconBitmap;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
SubDir TOP tests ;
|
||||
|
||||
# Include all the components
|
||||
SubInclude TOP tests libdownload ;
|
|
@ -0,0 +1,12 @@
|
|||
SubDir TOP tests libdownload ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs libdownload ] ;
|
||||
|
||||
Application DownloadTest :
|
||||
TheApp.cpp
|
||||
: be $(TARGET_LIBSTDC++) translation libdownload.a curl
|
||||
;
|
||||
|
||||
Depends DownloadTest : libdownload.a ;
|
||||
|
||||
LINKFLAGS on DownloadTest += -L$(CURL_LIBRARY_DIR) ;
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <Application.h>
|
||||
#include "DownloadManager.h"
|
||||
#include "ActionDownload.h"
|
||||
#include <Entry.h>
|
||||
#include "PercentageWindow.h"
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
class TestApp : public BApplication
|
||||
{
|
||||
public:
|
||||
TestApp():BApplication("application/xeD.libdownload.test"){};
|
||||
|
||||
void ReadyToRun()
|
||||
{
|
||||
|
||||
printf("Ready To Run\n");
|
||||
|
||||
entry_ref ref;
|
||||
get_ref_for_path("test.xxx", &ref);
|
||||
ActionDownload* ad = new ActionDownload("http://www.webelin.it/website/wp-content/uploads/pdf/newsletter-webelin.pdf", ref, false);
|
||||
|
||||
BBitmap* icon = BTranslationUtils::GetBitmap("/boot/home/image.bmp");
|
||||
percWindow = new PercentageWindow("Download test","Downloading useless test stuff...", icon);
|
||||
percWindow->Show();
|
||||
|
||||
/*BMessage msg;
|
||||
msg.AddBool("enable", true);
|
||||
msg.AddString("username", "");
|
||||
msg.AddString("address", "");
|
||||
msg.AddString("password", "");
|
||||
msg.AddInt32("port", 8080);
|
||||
*/
|
||||
fDownloadManager = new DownloadManager(this);
|
||||
//fDownloadManager->LoadProxySetting(&msg);
|
||||
fDownloadManager->SingleThreadAction(ad);
|
||||
percWindow->SetPercentage(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MessageReceived(BMessage* msg)
|
||||
{
|
||||
if (msg->what == DOWNLOAD_INFO)
|
||||
{
|
||||
int32 status = msg->FindInt32("status");
|
||||
switch (status)
|
||||
{
|
||||
case ActionDownload::ERROR_OPENFILE:
|
||||
printf("Error openig dest file\n");
|
||||
break;
|
||||
case ActionDownload::ERROR_CURL_INIT:
|
||||
printf("Error while init curl\n");
|
||||
break;
|
||||
case ActionDownload::ERROR_PERFORMING:
|
||||
printf("Error performing download\n");
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
case ActionDownload::OK_CONNECTING:
|
||||
printf("Connecting\n");
|
||||
break;
|
||||
case ActionDownload::OK_PROGRESS:
|
||||
printf("Progress\n");
|
||||
msg->PrintToStream();
|
||||
percWindow->SetPercentage(msg->FindInt32("percentage_progress"));
|
||||
break;
|
||||
case ActionDownload::OK_DOWNLOADED:
|
||||
printf("Downloaded\n");
|
||||
break;
|
||||
default:
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
};
|
||||
}
|
||||
else
|
||||
BApplication::MessageReceived(msg);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
DownloadManager* fDownloadManager;
|
||||
PercentageWindow* percWindow;
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
TestApp tApp;
|
||||
tApp.Run();
|
||||
return 0;
|
||||
}
|
Ŝarĝante…
Reference in New Issue