Remove libdownload which was preserved in a branch.
This commit is contained in:
parent
f487e366fb
commit
ab1f28bad2
|
@ -1,7 +1,6 @@
|
||||||
SubDir TOP libs ;
|
SubDir TOP libs ;
|
||||||
|
|
||||||
# Include all the components.
|
# Include all the components.
|
||||||
#SubInclude TOP libs libdownload ;
|
|
||||||
SubInclude TOP libs librunview ;
|
SubInclude TOP libs librunview ;
|
||||||
SubInclude TOP libs libsupport ;
|
SubInclude TOP libs libsupport ;
|
||||||
SubInclude TOP libs libinterface ;
|
SubInclude TOP libs libinterface ;
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,290 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,201 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,16 +0,0 @@
|
||||||
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) ;
|
|
|
@ -1,872 +0,0 @@
|
||||||
/*
|
|
||||||
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__ */
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,265 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,272 +0,0 @@
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
Ŝarĝante…
Reference in New Issue