From eb28188661262eef8aad4b530a3f16532aceffd4 Mon Sep 17 00:00:00 2001 From: Adrien Destugues - PulkoMandy Date: Thu, 15 Nov 2012 22:34:42 +0100 Subject: Update the BeOS/Haiku port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Toolbar use HVIF icons on Haiku * Download window * Some tweaks to the event loop to let network traffic happen Signed-off-by: François Revol --- beos/download.cpp | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 beos/download.cpp (limited to 'beos/download.cpp') diff --git a/beos/download.cpp b/beos/download.cpp new file mode 100644 index 000000000..e1a0c8c0f --- /dev/null +++ b/beos/download.cpp @@ -0,0 +1,246 @@ +/* + * Copyright 2012 Adrien Destugues + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +extern "C" { +#include "desktop/gui.h" +} +#include "beos/download.h" + +#include +#include +#include +#include +#include +#include + +class NSDownloadWindow: public BWindow +{ + public: + NSDownloadWindow(download_context* ctx); + ~NSDownloadWindow(); + + void MessageReceived(BMessage* message); + + void Progress(int size); + void Failure(const char* error); + void Success(); + private: + download_context* ctx; + BStatusBar* bar; + unsigned long progress; + bool success; +}; + + +struct gui_download_window { + download_context* ctx; + NSDownloadWindow* window; + + BLocker* storageLock; + BDataIO* storage; +}; + + +NSDownloadWindow::NSDownloadWindow(download_context* ctx) + : BWindow(BRect(30, 30, 400, 200), "Downloads", B_TITLED_WINDOW, + B_NOT_RESIZABLE) + , ctx(ctx) + , progress(0) + , success(false) +{ + unsigned long dlsize = download_context_get_total_length(ctx); + char* buffer = human_friendly_bytesize(dlsize); + + // Create the status bar + BRect rect = Bounds(); + rect.InsetBy(3, 3); + bar = new BStatusBar(rect, "progress", + download_context_get_filename(ctx), buffer); + bar->SetMaxValue(dlsize); + + // Create the backgroundview (just so that the area around the progress bar + // is B_PANEL_BACKGROUND_COLOR instead of white) + BView* back = new BView(Bounds(), "back", B_FOLLOW_ALL_SIDES, B_WILL_DRAW); + back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + // Add the views to the window + back->AddChild(bar); + AddChild(back); + + // Resize the window to leave a margin around the progress bar + BRect size = bar->Bounds(); + ResizeTo(size.Width() + 6, size.Height() + 6); + Show(); +} + + +NSDownloadWindow::~NSDownloadWindow() +{ + download_context_abort(ctx); + download_context_destroy(ctx); +} + + +void +NSDownloadWindow::MessageReceived(BMessage* message) +{ + switch(message->what) + { + case B_SAVE_REQUESTED: + { + entry_ref directory; + const char* name; + struct gui_download_window* dw; + BFilePanel* source; + + message->FindRef("directory", &directory); + message->FindString("name", &name); + message->FindPointer("dw", (void**)&dw); + + BDirectory dir(&directory); + BFile* storage = new BFile(&dir, name, + B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + dw->storageLock->Lock(); + + BMallocIO* tempstore = dynamic_cast(dw->storage); + + storage->Write(tempstore->Buffer(), tempstore->BufferLength()); + delete dw->storage; + + if (success) + delete storage; // File is already finished downloading ! + else + dw->storage = storage; + dw->storageLock->Unlock(); + + message->FindPointer("source", (void**)&source); + delete source; + + break; + } + default: + BWindow::MessageReceived(message); + } +} + + +void +NSDownloadWindow::Progress(int size) +{ + progress += size; + + char* buffer = human_friendly_bytesize(progress); + strcat(buffer, "/"); + + bar->LockLooper(); + bar->Update(size, NULL, buffer); + bar->Invalidate(); + bar->UnlockLooper(); +} + + +void +NSDownloadWindow::Success() +{ + bar->LockLooper(); + bar->SetBarColor(ui_color(B_SUCCESS_COLOR)); + bar->UnlockLooper(); + + success = true; +} + + +void +NSDownloadWindow::Failure(const char* error) +{ + bar->LockLooper(); + bar->Update(0, NULL, error); + bar->SetBarColor(ui_color(B_FAILURE_COLOR)); + bar->UnlockLooper(); +} + + +struct gui_download_window *gui_download_window_create(download_context *ctx, + struct gui_window *parent) +{ + struct gui_download_window *download = (struct gui_download_window*)malloc(sizeof *download); + if (download == NULL) + return NULL; + + download->storageLock = new BLocker("storage_lock"); + download->storage = new BMallocIO(); + download->ctx = ctx; + + download->window = new NSDownloadWindow(ctx); + + // Also ask the user where to save the file + // TODO inject the suggested name somehow + BMessage* msg = new BMessage(B_SAVE_REQUESTED); + + BFilePanel* panel = new BFilePanel(B_SAVE_PANEL, + new BMessenger(download->window), NULL, 0, false); + + msg->AddPointer("source", panel); + msg->AddPointer("dw", download); + panel->SetMessage(msg); + + panel->Show(); + + return download; +} + + +nserror gui_download_window_data(struct gui_download_window *dw, + const char *data, unsigned int size) +{ + dw->window->Progress(size); + + dw->storageLock->Lock(); + dw->storage->Write(data, size); + dw->storageLock->Unlock(); + + return NSERROR_OK; +} + + +void gui_download_window_error(struct gui_download_window *dw, + const char *error_msg) +{ + dw->window->Failure(error_msg); + + delete dw->storageLock; + delete dw->storage; +} + + +void gui_download_window_done(struct gui_download_window *dw) +{ + dw->window->Success(); + + dw->storageLock->Lock(); + + // Only delete if the storage is already a file. Else, we must wait for the + // user to select something in the BFilePanel! + BFile* file = dynamic_cast(dw->storage); + delete file; + if (file) + delete dw->storageLock; + else + dw->storageLock->Unlock(); +} + -- cgit v1.2.3