Author: stippi Date: Wed Mar 24 18:41:38 2010 New Revision: 350 URL: http://mmlr.dyndns.org/changeset/350 Log: Moved DownloadProgressView and related private classes out into their own source file. Added: webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.cpp - copied, changed from r348, webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.h - copied, changed from r348, webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Modified: webkit/trunk/WebKit/Jamfile webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Modified: webkit/trunk/WebKit/Jamfile ============================================================================== --- webkit/trunk/WebKit/Jamfile Wed Mar 24 18:41:05 2010 (r349) +++ webkit/trunk/WebKit/Jamfile Wed Mar 24 18:41:38 2010 (r350) @@ -134,6 +134,7 @@ # WebPositive AuthenticationPanel.cpp BrowsingHistory.cpp + DownloadProgressView.cpp DownloadWindow.cpp BrowserApp.cpp BrowserWindow.cpp Copied and modified: webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.cpp (from r348, webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp) ============================================================================== --- webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Tue Mar 23 15:37:01 2010 (r348, copy source) +++ webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.cpp Wed Mar 24 18:41:38 2010 (r350) @@ -25,7 +25,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "DownloadWindow.h" +#include "DownloadProgressView.h" #include <stdio.h> @@ -36,35 +36,21 @@ #include <Entry.h> #include <FindDirectory.h> #include <GridLayoutBuilder.h> -#include <GroupLayout.h> -#include <GroupLayoutBuilder.h> -#include <MenuBar.h> -#include <MenuItem.h> #include <NodeInfo.h> #include <NodeMonitor.h> -#include <Path.h> #include <Roster.h> -#include <ScrollView.h> -#include <SeparatorView.h> #include <SpaceLayoutItem.h> #include <StatusBar.h> -#include "BrowserApp.h" -#include "SettingsMessage.h" #include "WebDownload.h" #include "WebPage.h" enum { - INIT = 'init', - OPEN_DOWNLOADS_FOLDER = 'odnf', - REMOVE_FINISHED_DOWNLOADS = 'rmfd', - REMOVE_MISSING_DOWNLOADS = 'rmmd', OPEN_DOWNLOAD = 'opdn', RESTART_DOWNLOAD = 'rsdn', CANCEL_DOWNLOAD = 'cndn', REMOVE_DOWNLOAD = 'rmdn', - SAVE_SETTINGS = 'svst' }; @@ -176,697 +162,343 @@ }; -class DownloadProgressView : public BGridView { -public: - DownloadProgressView(BWebDownload* download) - : - BGridView(8, 3), - fDownload(download), - fURL(download->URL()), - fPath(download->Path()), - fExpectedSize(download->ExpectedSize()) - { - } - - DownloadProgressView(const BMessage* archive) - : - BGridView(8, 3), - fDownload(NULL), - fURL(), - fPath(), - fExpectedSize(0) - { - const char* string; - if (archive->FindString("path", &string) == B_OK) - fPath.SetTo(string); - if (archive->FindString("url", &string) == B_OK) - fURL = string; - } - - bool Init(BMessage* archive = NULL) - { - SetViewColor(245, 245, 245); - SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW); - - BGridLayout* layout = GridLayout(); - if (archive) { - fStatusBar = new BStatusBar("download progress", fPath.Leaf()); - float value; - if (archive->FindFloat("value", &value) == B_OK) - fStatusBar->SetTo(value); - } else - fStatusBar = new BStatusBar("download progress", "Download"); - fStatusBar->SetMaxValue(100); - fStatusBar->SetBarHeight(12); - - // fPath is only valid when constructed from archive (fDownload == NULL) - BEntry entry(fPath.Path()); - - if (archive) { - if (!entry.Exists()) - fIconView = new IconView(archive); - else - fIconView = new IconView(entry); - } else - fIconView = new IconView(); - - if (!fDownload && (fStatusBar->CurrentValue() < 100 || !entry.Exists())) - fTopButton = new SmallButton("Restart", new BMessage(RESTART_DOWNLOAD)); - else { - fTopButton = new SmallButton("Open", new BMessage(OPEN_DOWNLOAD)); - fTopButton->SetEnabled(fDownload == NULL); - } - if (fDownload) - fBottomButton = new SmallButton("Cancel", new BMessage(CANCEL_DOWNLOAD)); - else { - fBottomButton = new SmallButton("Remove", new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(fDownload == NULL); - } - - layout->SetInsets(8, 5, 5, 6); - layout->AddView(fIconView, 0, 0, 1, 2); - layout->AddView(fStatusBar, 1, 0, 1, 2); - layout->AddView(fTopButton, 2, 0); - layout->AddView(fBottomButton, 2, 1); - - return true; - } - - status_t SaveSettings(BMessage* archive) - { - if (!archive) - return B_BAD_VALUE; - status_t ret = archive->AddString("path", fPath.Path()); - if (ret == B_OK) - ret = archive->AddString("url", fURL.String()); - if (ret == B_OK) - ret = archive->AddFloat("value", fStatusBar->CurrentValue()); - if (ret == B_OK) - ret = fIconView->SaveSettings(archive); - return ret; - } - - virtual void AttachedToWindow() - { - if (fDownload) - fDownload->SetProgressListener(BMessenger(this)); - fTopButton->SetTarget(this); - fBottomButton->SetTarget(this); - - BEntry entry(fPath.Path()); - if (entry.Exists()) - _StartNodeMonitor(entry); - } - - virtual void DetachedFromWindow() - { - _StopNodeMonitor(); - } - - virtual void AllAttached() - { - SetViewColor(B_TRANSPARENT_COLOR); - SetLowColor(245, 245, 245); - SetHighColor(tint_color(LowColor(), B_DARKEN_1_TINT)); - } - - virtual void Draw(BRect updateRect) - { - BRect bounds(Bounds()); - bounds.bottom--; - FillRect(bounds, B_SOLID_LOW); - bounds.bottom++; - StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); - } - - virtual void MessageReceived(BMessage* message) - { - switch (message->what) { - case B_DOWNLOAD_STARTED: - { - BString path; - if (message->FindString("path", &path) != B_OK) - break; - fPath.SetTo(path); - BEntry entry(fPath.Path()); - fIconView->SetTo(entry); - fStatusBar->Reset(fPath.Leaf()); - _StartNodeMonitor(entry); - break; - }; - case B_DOWNLOAD_PROGRESS: - { - float progress; - if (message->FindFloat("progress", &progress) == B_OK) - fStatusBar->SetTo(progress); - break; - } - case OPEN_DOWNLOAD: - { - // TODO: In case of executable files, ask the user first! - entry_ref ref; - status_t status = get_ref_for_path(fPath.Path(), &ref); - if (status == B_OK) - status = be_roster->Launch(&ref); - if (status != B_OK && status != B_ALREADY_RUNNING) { - BAlert* alert = new BAlert("Open download error", - "The download could not be opened.", "OK"); - alert->Go(NULL); - } - break; - } - case RESTART_DOWNLOAD: - BWebPage::RequestDownload(fURL); - break; - - case CANCEL_DOWNLOAD: - fDownload->Cancel(); - DownloadCanceled(); - break; - - case REMOVE_DOWNLOAD: - { - Window()->PostMessage(SAVE_SETTINGS); - RemoveSelf(); - delete this; - // TOAST! - return; - } - case B_DOWNLOAD_REMOVED: - // TODO: This is a bit asymetric. The removed notification - // arrives here, but it would be nicer if it arrived - // at the window... - Window()->PostMessage(message); - break; - case B_NODE_MONITOR: - { - int32 opCode; - if (message->FindInt32("opcode", &opCode) != B_OK) - break; - switch (opCode) { - case B_ENTRY_REMOVED: - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - case B_ENTRY_MOVED: - { - // Follow the entry to the new location - dev_t device; - ino_t directory; - const char* name; - if (message->FindInt32("device", - reinterpret_cast<int32*>(&device)) != B_OK - || message->FindInt64("to directory", - reinterpret_cast<int64*>(&directory)) != B_OK - || message->FindString("name", &name) != B_OK - || strlen(name) == 0) { - break; - } - // Construct the BEntry and update fPath - entry_ref ref(device, directory, name); - BEntry entry(&ref); - if (entry.GetPath(&fPath) != B_OK) - break; - // Find out if the directory is the Trash for this - // volume - char trashPath[B_PATH_NAME_LENGTH]; - if (find_directory(B_TRASH_DIRECTORY, device, false, - trashPath, B_PATH_NAME_LENGTH) == B_OK) { - BPath trashDirectory(trashPath); - BPath parentDirectory; - fPath.GetParent(&parentDirectory); - if (parentDirectory == trashDirectory) { - // The entry was moved into the Trash. - // If the download is still in progress, - // cancel it. - if (fDownload) - fDownload->Cancel(); - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - } else if (fIconView->IsIconDimmed()) { - // Maybe it was moved out of the trash. - fIconView->SetIconDimmed(false); - } - } - - fStatusBar->SetText(name); - Window()->PostMessage(SAVE_SETTINGS); - break; - } - case B_ATTR_CHANGED: - { - BEntry entry(fPath.Path()); - fIconView->SetIconDimmed(false); - fIconView->SetTo(entry); - break; - } - } - break; - } - default: - BGridView::MessageReceived(message); - } - } - - BWebDownload* Download() const - { - return fDownload; - } - - const BString& URL() const - { - return fURL; - } - - bool IsMissing() const - { - return fIconView->IsIconDimmed(); - } - - bool IsFinished() const - { - return !fDownload && fStatusBar->CurrentValue() == 100; - } - - void DownloadFinished() - { - fDownload = NULL; - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } - - void DownloadCanceled() - { - fDownload = NULL; - fTopButton->SetLabel("Restart"); - fTopButton->SetMessage(new BMessage(RESTART_DOWNLOAD)); - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } - -private: - void _StartNodeMonitor(const BEntry& entry) - { - node_ref nref; - if (entry.GetNodeRef(&nref) == B_OK) - watch_node(&nref, B_WATCH_ALL, this); - } - - void _StopNodeMonitor() - { - stop_watching(this); - } - -private: - IconView* fIconView; - BStatusBar* fStatusBar; - SmallButton* fTopButton; - SmallButton* fBottomButton; - BWebDownload* fDownload; - BString fURL; - BPath fPath; - off_t fExpectedSize; -}; +// #pragma mark - DownloadProgressView -class DownloadsContainerView : public BGroupView { -public: - DownloadsContainerView() - : - BGroupView(B_VERTICAL) - { - SetViewColor(245, 245, 245); - AddChild(BSpaceLayoutItem::CreateGlue()); - } - - virtual BSize MinSize() - { - BSize minSize = BGroupView::MinSize(); - return BSize(minSize.width, 80); - } - -protected: - virtual void DoLayout() - { - BGroupView::DoLayout(); - if (BScrollBar* scrollBar = ScrollBar(B_VERTICAL)) { - BSize minSize = BGroupView::MinSize(); - float height = Bounds().Height(); - float max = minSize.height - height; - scrollBar->SetRange(0, max); - if (minSize.height > 0) - scrollBar->SetProportion(height / minSize.height); - else - scrollBar->SetProportion(1); - } - } -}; - - -class DownloadContainerScrollView : public BScrollView { -public: - DownloadContainerScrollView(BView* target) - : - BScrollView("Downloads scroll view", target, 0, false, true, - B_NO_BORDER) - { - } - -protected: - virtual void DoLayout() - { - BScrollView::DoLayout(); - // Tweak scroll bar layout to hide part of the frame for better looks. - BScrollBar* scrollBar = ScrollBar(B_VERTICAL); - scrollBar->MoveBy(1, -1); - scrollBar->ResizeBy(0, 2); - Target()->ResizeBy(1, 0); - // Set the scroll steps - if (BView* item = Target()->ChildAt(0)) { - scrollBar->SetSteps(item->MinSize().height + 1, - item->MinSize().height + 1); - } - } -}; +DownloadProgressView::DownloadProgressView(BWebDownload* download) + : + BGridView(8, 3), + fDownload(download), + fURL(download->URL()), + fPath(download->Path()), + fExpectedSize(download->ExpectedSize()) +{ +} -// #pragma mark - +DownloadProgressView::DownloadProgressView(const BMessage* archive) + : + BGridView(8, 3), + fDownload(NULL), + fURL(), + fPath(), + fExpectedSize(0) +{ + const char* string; + if (archive->FindString("path", &string) == B_OK) + fPath.SetTo(string); + if (archive->FindString("url", &string) == B_OK) + fURL = string; +} -DownloadWindow::DownloadWindow(BRect frame, bool visible, - SettingsMessage* settings) - : BWindow(frame, "Downloads", - B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, - B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE) +bool +DownloadProgressView::Init(BMessage* archive) { - settings->AddListener(BMessenger(this)); - BPath downloadPath; - if (find_directory(B_DESKTOP_DIRECTORY, &downloadPath) != B_OK) - downloadPath.SetTo("/boot/home/Desktop"); - fDownloadPath = settings->GetValue("download path", downloadPath.Path()); - settings->SetValue("download path", fDownloadPath); + SetViewColor(245, 245, 245); + SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW); - SetLayout(new BGroupLayout(B_VERTICAL)); + BGridLayout* layout = GridLayout(); + if (archive) { + fStatusBar = new BStatusBar("download progress", fPath.Leaf()); + float value; + if (archive->FindFloat("value", &value) == B_OK) + fStatusBar->SetTo(value); + } else + fStatusBar = new BStatusBar("download progress", "Download"); + fStatusBar->SetMaxValue(100); + fStatusBar->SetBarHeight(12); + + // fPath is only valid when constructed from archive (fDownload == NULL) + BEntry entry(fPath.Path()); + + if (archive) { + if (!entry.Exists()) + fIconView = new IconView(archive); + else + fIconView = new IconView(entry); + } else + fIconView = new IconView(); + + if (!fDownload && (fStatusBar->CurrentValue() < 100 || !entry.Exists())) + fTopButton = new SmallButton("Restart", new BMessage(RESTART_DOWNLOAD)); + else { + fTopButton = new SmallButton("Open", new BMessage(OPEN_DOWNLOAD)); + fTopButton->SetEnabled(fDownload == NULL); + } + if (fDownload) + fBottomButton = new SmallButton("Cancel", new BMessage(CANCEL_DOWNLOAD)); + else { + fBottomButton = new SmallButton("Remove", new BMessage(REMOVE_DOWNLOAD)); + fBottomButton->SetEnabled(fDownload == NULL); + } + + layout->SetInsets(8, 5, 5, 6); + layout->AddView(fIconView, 0, 0, 1, 2); + layout->AddView(fStatusBar, 1, 0, 1, 2); + layout->AddView(fTopButton, 2, 0); + layout->AddView(fBottomButton, 2, 1); + + return true; +} - DownloadsContainerView* downloadsGroupView = new DownloadsContainerView(); - fDownloadViewsLayout = downloadsGroupView->GroupLayout(); - BMenuBar* menuBar = new BMenuBar("Menu bar"); - BMenu* menu = new BMenu("Downloads"); - menu->AddItem(new BMenuItem("Open downloads folder", - new BMessage(OPEN_DOWNLOADS_FOLDER))); - menu->AddItem(new BMenuItem("Hide", new BMessage(B_QUIT_REQUESTED), 'H')); - menuBar->AddItem(menu); +status_t +DownloadProgressView::SaveSettings(BMessage* archive) +{ + if (!archive) + return B_BAD_VALUE; + status_t ret = archive->AddString("path", fPath.Path()); + if (ret == B_OK) + ret = archive->AddString("url", fURL.String()); + if (ret == B_OK) + ret = archive->AddFloat("value", fStatusBar->CurrentValue()); + if (ret == B_OK) + ret = fIconView->SaveSettings(archive); + return ret; +} - BScrollView* scrollView = new DownloadContainerScrollView( - downloadsGroupView); - fRemoveFinishedButton = new BButton("Remove finished", - new BMessage(REMOVE_FINISHED_DOWNLOADS)); - fRemoveFinishedButton->SetEnabled(false); +void +DownloadProgressView::AttachedToWindow() +{ + if (fDownload) + fDownload->SetProgressListener(BMessenger(this)); + fTopButton->SetTarget(this); + fBottomButton->SetTarget(this); + + BEntry entry(fPath.Path()); + if (entry.Exists()) + _StartNodeMonitor(entry); +} - fRemoveMissingButton = new BButton("Remove missing", - new BMessage(REMOVE_MISSING_DOWNLOADS)); - fRemoveMissingButton->SetEnabled(false); - AddChild(BGroupLayoutBuilder(B_VERTICAL) - .Add(menuBar) - .Add(scrollView) - .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) - .Add(BGroupLayoutBuilder(B_HORIZONTAL) - .AddGlue() - .Add(fRemoveMissingButton) - .Add(fRemoveFinishedButton) - .SetInsets(5, 5, 5, 5) - ) - ); +void +DownloadProgressView::DetachedFromWindow() +{ + _StopNodeMonitor(); +} - PostMessage(INIT); - if (!visible) - Hide(); - Show(); +void +DownloadProgressView::AllAttached() +{ + SetViewColor(B_TRANSPARENT_COLOR); + SetLowColor(245, 245, 245); + SetHighColor(tint_color(LowColor(), B_DARKEN_1_TINT)); } -DownloadWindow::~DownloadWindow() +void +DownloadProgressView::Draw(BRect updateRect) { - // Only necessary to save the current progress of unfinished downloads: - _SaveSettings(); + BRect bounds(Bounds()); + bounds.bottom--; + FillRect(bounds, B_SOLID_LOW); + bounds.bottom++; + StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); } void -DownloadWindow::MessageReceived(BMessage* message) +DownloadProgressView::MessageReceived(BMessage* message) { switch (message->what) { - case INIT: - { - _LoadSettings(); - // Small trick to get the correct enabled status of the Remove - // finished button - _DownloadFinished(NULL); - break; - } - case B_DOWNLOAD_ADDED: + case B_DOWNLOAD_STARTED: { - BWebDownload* download; - if (message->FindPointer("download", reinterpret_cast<void**>( - &download)) == B_OK) { - _DownloadStarted(download); - } + BString path; + if (message->FindString("path", &path) != B_OK) + break; + fPath.SetTo(path); + BEntry entry(fPath.Path()); + fIconView->SetTo(entry); + fStatusBar->Reset(fPath.Leaf()); + _StartNodeMonitor(entry); break; - } - case B_DOWNLOAD_REMOVED: + }; + case B_DOWNLOAD_PROGRESS: { - BWebDownload* download; - if (message->FindPointer("download", reinterpret_cast<void**>( - &download)) == B_OK) { - _DownloadFinished(download); - } + float progress; + if (message->FindFloat("progress", &progress) == B_OK) + fStatusBar->SetTo(progress); break; } - case OPEN_DOWNLOADS_FOLDER: + case OPEN_DOWNLOAD: { + // TODO: In case of executable files, ask the user first! entry_ref ref; - status_t status = get_ref_for_path(fDownloadPath.String(), &ref); + status_t status = get_ref_for_path(fPath.Path(), &ref); if (status == B_OK) status = be_roster->Launch(&ref); if (status != B_OK && status != B_ALREADY_RUNNING) { - BString errorString("The downloads folder could not be " - "opened.\n\n"); - errorString << "Error: " << strerror(status); - BAlert* alert = new BAlert("Error opening downloads folder", - errorString.String(), "OK"); + BAlert* alert = new BAlert("Open download error", + "The download could not be opened.", "OK"); alert->Go(NULL); } break; } - case REMOVE_FINISHED_DOWNLOADS: - _RemoveFinishedDownloads(); + case RESTART_DOWNLOAD: + BWebPage::RequestDownload(fURL); break; - case REMOVE_MISSING_DOWNLOADS: - _RemoveMissingDownloads(); - break; - case SAVE_SETTINGS: - _SaveSettings(); + + case CANCEL_DOWNLOAD: + fDownload->Cancel(); + DownloadCanceled(); break; - case SETTINGS_VALUE_CHANGED: + case REMOVE_DOWNLOAD: + { + Window()->PostMessage(SAVE_SETTINGS); + RemoveSelf(); + delete this; + // TOAST! + return; + } + case B_DOWNLOAD_REMOVED: + // TODO: This is a bit asymetric. The removed notification + // arrives here, but it would be nicer if it arrived + // at the window... + Window()->PostMessage(message); + break; + case B_NODE_MONITOR: { - BString string; - if (message->FindString("name", &string) == B_OK - && string == "download path" - && message->FindString("value", &string) == B_OK) { - fDownloadPath = string; + int32 opCode; + if (message->FindInt32("opcode", &opCode) != B_OK) + break; + switch (opCode) { + case B_ENTRY_REMOVED: + fIconView->SetIconDimmed(true); + DownloadCanceled(); + break; + case B_ENTRY_MOVED: + { + // Follow the entry to the new location + dev_t device; + ino_t directory; + const char* name; + if (message->FindInt32("device", + reinterpret_cast<int32*>(&device)) != B_OK + || message->FindInt64("to directory", + reinterpret_cast<int64*>(&directory)) != B_OK + || message->FindString("name", &name) != B_OK + || strlen(name) == 0) { + break; + } + // Construct the BEntry and update fPath + entry_ref ref(device, directory, name); + BEntry entry(&ref); + if (entry.GetPath(&fPath) != B_OK) + break; + // Find out if the directory is the Trash for this + // volume + char trashPath[B_PATH_NAME_LENGTH]; + if (find_directory(B_TRASH_DIRECTORY, device, false, + trashPath, B_PATH_NAME_LENGTH) == B_OK) { + BPath trashDirectory(trashPath); + BPath parentDirectory; + fPath.GetParent(&parentDirectory); + if (parentDirectory == trashDirectory) { + // The entry was moved into the Trash. + // If the download is still in progress, + // cancel it. + if (fDownload) + fDownload->Cancel(); + fIconView->SetIconDimmed(true); + DownloadCanceled(); + break; + } else if (fIconView->IsIconDimmed()) { + // Maybe it was moved out of the trash. + fIconView->SetIconDimmed(false); + } + } + + fStatusBar->SetText(name); + Window()->PostMessage(SAVE_SETTINGS); + break; + } + case B_ATTR_CHANGED: + { + BEntry entry(fPath.Path()); + fIconView->SetIconDimmed(false); + fIconView->SetTo(entry); + break; + } } break; } default: - BWindow::MessageReceived(message); - break; + BGridView::MessageReceived(message); } } -bool -DownloadWindow::QuitRequested() +BWebDownload* +DownloadProgressView::Download() const { - if (!IsHidden()) - Hide(); - return false; + return fDownload; } -void -DownloadWindow::_DownloadStarted(BWebDownload* download) +const BString& +DownloadProgressView::URL() const { - download->Start(BPath(fDownloadPath.String())); - - int32 finishedCount = 0; - int32 missingCount = 0; - int32 index = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->URL() == download->URL()) { - index = i; - view->RemoveSelf(); - delete view; - continue; - } - if (view->IsFinished()) - finishedCount++; - if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - fRemoveMissingButton->SetEnabled(missingCount > 0); - DownloadProgressView* view = new DownloadProgressView(download); - if (!view->Init()) - return; - fDownloadViewsLayout->AddView(index, view); - _SaveSettings(); - - SetWorkspaces(B_CURRENT_WORKSPACE); - if (IsHidden()) - Show(); + return fURL; } -void -DownloadWindow::_DownloadFinished(BWebDownload* download) +bool +DownloadProgressView::IsMissing() const { - int32 finishedCount = 0; - int32 missingCount = 0; - for (int32 i = 0; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i++) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (download && view->Download() == download) { - view->DownloadFinished(); - finishedCount++; - continue; - } - if (view->IsFinished()) - finishedCount++; - if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - fRemoveMissingButton->SetEnabled(missingCount > 0); - if (download) - _SaveSettings(); + return fIconView->IsIconDimmed(); } -void -DownloadWindow::_RemoveFinishedDownloads() +bool +DownloadProgressView::IsFinished() const { - int32 missingCount = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->IsFinished()) { - view->RemoveSelf(); - delete view; - } else if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(false); - fRemoveMissingButton->SetEnabled(missingCount > 0); - _SaveSettings(); + return !fDownload && fStatusBar->CurrentValue() == 100; } void -DownloadWindow::_RemoveMissingDownloads() +DownloadProgressView::DownloadFinished() { - int32 finishedCount = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->IsMissing()) { - view->RemoveSelf(); - delete view; - } else if (view->IsFinished()) - finishedCount++; - } - fRemoveMissingButton->SetEnabled(false); - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - _SaveSettings(); + fDownload = NULL; + fTopButton->SetEnabled(true); + fBottomButton->SetLabel("Remove"); + fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); + fBottomButton->SetEnabled(true); } void -DownloadWindow::_SaveSettings() +DownloadProgressView::DownloadCanceled() { - BFile file; - if (!_OpenSettingsFile(file, B_ERASE_FILE | B_CREATE_FILE | B_WRITE_ONLY)) - return; - BMessage message; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - BMessage downloadArchive; - if (view->SaveSettings(&downloadArchive) == B_OK) - message.AddMessage("download", &downloadArchive); - } - message.Flatten(&file); + fDownload = NULL; + fTopButton->SetLabel("Restart"); + fTopButton->SetMessage(new BMessage(RESTART_DOWNLOAD)); + fTopButton->SetEnabled(true); + fBottomButton->SetLabel("Remove"); + fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); + fBottomButton->SetEnabled(true); } +// #pragma mark - private + + void -DownloadWindow::_LoadSettings() +DownloadProgressView::_StartNodeMonitor(const BEntry& entry) { - BFile file; - if (!_OpenSettingsFile(file, B_READ_ONLY)) - return; - BMessage message; - if (message.Unflatten(&file) != B_OK) - return; - BMessage downloadArchive; - for (int32 i = 0; - message.FindMessage("download", i, &downloadArchive) == B_OK; - i++) { - DownloadProgressView* view = new DownloadProgressView( - &downloadArchive); - if (!view->Init(&downloadArchive)) - continue; - fDownloadViewsLayout->AddView(0, view); - } + node_ref nref; + if (entry.GetNodeRef(&nref) == B_OK) + watch_node(&nref, B_WATCH_ALL, this); } -bool -DownloadWindow::_OpenSettingsFile(BFile& file, uint32 mode) +void +DownloadProgressView::_StopNodeMonitor() { - BPath path; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK - || path.Append(kApplicationName) != B_OK - || path.Append("Downloads") != B_OK) { - return false; - } - return file.SetTo(path.Path(), mode) == B_OK; + stop_watching(this); } - Copied and modified: webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.h (from r348, webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp) ============================================================================== --- webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Tue Mar 23 15:37:01 2010 (r348, copy source) +++ webkit/trunk/WebKit/haiku/WebPositive/DownloadProgressView.h Wed Mar 24 18:41:38 2010 (r350) @@ -24,849 +24,63 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef DOWNLOAD_PROGRESS_VIEW_H +#define DOWNLOAD_PROGRESS_VIEW_H -#include "DownloadWindow.h" -#include <stdio.h> - -#include <Alert.h> -#include <Bitmap.h> -#include <Button.h> -#include <Directory.h> -#include <Entry.h> -#include <FindDirectory.h> -#include <GridLayoutBuilder.h> -#include <GroupLayout.h> -#include <GroupLayoutBuilder.h> -#include <MenuBar.h> -#include <MenuItem.h> -#include <NodeInfo.h> -#include <NodeMonitor.h> +#include <GridView.h> #include <Path.h> -#include <Roster.h> -#include <ScrollView.h> -#include <SeparatorView.h> -#include <SpaceLayoutItem.h> -#include <StatusBar.h> - -#include "BrowserApp.h" -#include "SettingsMessage.h" -#include "WebDownload.h" -#include "WebPage.h" +#include <String.h> + +class BEntry; +class BStatusBar; +class BWebDownload; +class IconView; +class SmallButton; enum { - INIT = 'init', - OPEN_DOWNLOADS_FOLDER = 'odnf', - REMOVE_FINISHED_DOWNLOADS = 'rmfd', - REMOVE_MISSING_DOWNLOADS = 'rmmd', - OPEN_DOWNLOAD = 'opdn', - RESTART_DOWNLOAD = 'rsdn', - CANCEL_DOWNLOAD = 'cndn', - REMOVE_DOWNLOAD = 'rmdn', SAVE_SETTINGS = 'svst' }; -class IconView : public BView { +class DownloadProgressView : public BGridView { public: - IconView(const BEntry& entry) - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32), - fDimmedIcon(false) - { - SetDrawingMode(B_OP_OVER); - SetTo(entry); - } - - IconView() - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32), - fDimmedIcon(false) - { - SetDrawingMode(B_OP_OVER); - memset(fIconBitmap.Bits(), 0, fIconBitmap.BitsLength()); - } - - IconView(BMessage* archive) - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(archive), - fDimmedIcon(true) - { - SetDrawingMode(B_OP_OVER); - } - - void SetTo(const BEntry& entry) - { - BNode node(&entry); - BNodeInfo info(&node); - info.GetTrackerIcon(&fIconBitmap, B_LARGE_ICON); - Invalidate(); - } - - void SetIconDimmed(bool iconDimmed) - { - if (fDimmedIcon != iconDimmed) { - fDimmedIcon = iconDimmed; - Invalidate(); - } - } - - bool IsIconDimmed() const - { - return fDimmedIcon; - } - - status_t SaveSettings(BMessage* archive) - { - return fIconBitmap.Archive(archive); - } - - virtual void AttachedToWindow() - { - SetViewColor(Parent()->ViewColor()); - } - - virtual void Draw(BRect updateRect) - { - if (fDimmedIcon) { - SetDrawingMode(B_OP_ALPHA); - SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - SetHighColor(0, 0, 0, 100); - } - DrawBitmapAsync(&fIconBitmap); - } - - virtual BSize MinSize() - { - return BSize(fIconBitmap.Bounds().Width(), fIconBitmap.Bounds().Height()); - } - - virtual BSize PreferredSize() - { - return MinSize(); - } - - virtual BSize MaxSize() - { - return MinSize(); - } + DownloadProgressView(BWebDownload* download); + DownloadProgressView(const BMessage* archive); -private: - BBitmap fIconBitmap; - bool fDimmedIcon; -}; + bool Init(BMessage* archive = NULL); + status_t SaveSettings(BMessage* archive); + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + virtual void AllAttached(); -class SmallButton : public BButton { -public: - SmallButton(const char* label, BMessage* message = NULL) - : - BButton(label, message) - { - BFont font; - GetFont(&font); - float size = ceilf(font.Size() * 0.8); - font.SetSize(max_c(8, size)); - SetFont(&font, B_FONT_SIZE); - } -}; + virtual void Draw(BRect updateRect); + virtual void MessageReceived(BMessage* message); -class DownloadProgressView : public BGridView { -public: - DownloadProgressView(BWebDownload* download) - : - BGridView(8, 3), - fDownload(download), - fURL(download->URL()), - fPath(download->Path()), - fExpectedSize(download->ExpectedSize()) - { - } - - DownloadProgressView(const BMessage* archive) - : - BGridView(8, 3), - fDownload(NULL), - fURL(), - fPath(), - fExpectedSize(0) - { - const char* string; - if (archive->FindString("path", &string) == B_OK) - fPath.SetTo(string); - if (archive->FindString("url", &string) == B_OK) - fURL = string; - } - - bool Init(BMessage* archive = NULL) - { - SetViewColor(245, 245, 245); - SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW); - - BGridLayout* layout = GridLayout(); - if (archive) { - fStatusBar = new BStatusBar("download progress", fPath.Leaf()); - float value; - if (archive->FindFloat("value", &value) == B_OK) - fStatusBar->SetTo(value); - } else - fStatusBar = new BStatusBar("download progress", "Download"); - fStatusBar->SetMaxValue(100); - fStatusBar->SetBarHeight(12); - - // fPath is only valid when constructed from archive (fDownload == NULL) - BEntry entry(fPath.Path()); - - if (archive) { - if (!entry.Exists()) - fIconView = new IconView(archive); - else - fIconView = new IconView(entry); - } else - fIconView = new IconView(); - - if (!fDownload && (fStatusBar->CurrentValue() < 100 || !entry.Exists())) - fTopButton = new SmallButton("Restart", new BMessage(RESTART_DOWNLOAD)); - else { - fTopButton = new SmallButton("Open", new BMessage(OPEN_DOWNLOAD)); - fTopButton->SetEnabled(fDownload == NULL); - } - if (fDownload) - fBottomButton = new SmallButton("Cancel", new BMessage(CANCEL_DOWNLOAD)); - else { - fBottomButton = new SmallButton("Remove", new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(fDownload == NULL); - } - - layout->SetInsets(8, 5, 5, 6); - layout->AddView(fIconView, 0, 0, 1, 2); - layout->AddView(fStatusBar, 1, 0, 1, 2); - layout->AddView(fTopButton, 2, 0); - layout->AddView(fBottomButton, 2, 1); - - return true; - } - - status_t SaveSettings(BMessage* archive) - { - if (!archive) - return B_BAD_VALUE; - status_t ret = archive->AddString("path", fPath.Path()); - if (ret == B_OK) - ret = archive->AddString("url", fURL.String()); - if (ret == B_OK) - ret = archive->AddFloat("value", fStatusBar->CurrentValue()); - if (ret == B_OK) - ret = fIconView->SaveSettings(archive); - return ret; - } - - virtual void AttachedToWindow() - { - if (fDownload) - fDownload->SetProgressListener(BMessenger(this)); - fTopButton->SetTarget(this); - fBottomButton->SetTarget(this); - - BEntry entry(fPath.Path()); - if (entry.Exists()) - _StartNodeMonitor(entry); - } - - virtual void DetachedFromWindow() - { - _StopNodeMonitor(); - } - - virtual void AllAttached() - { - SetViewColor(B_TRANSPARENT_COLOR); - SetLowColor(245, 245, 245); - SetHighColor(tint_color(LowColor(), B_DARKEN_1_TINT)); - } - - virtual void Draw(BRect updateRect) - { - BRect bounds(Bounds()); - bounds.bottom--; - FillRect(bounds, B_SOLID_LOW); - bounds.bottom++; - StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); - } - - virtual void MessageReceived(BMessage* message) - { - switch (message->what) { - case B_DOWNLOAD_STARTED: - { - BString path; - if (message->FindString("path", &path) != B_OK) - break; - fPath.SetTo(path); - BEntry entry(fPath.Path()); - fIconView->SetTo(entry); - fStatusBar->Reset(fPath.Leaf()); - _StartNodeMonitor(entry); - break; - }; - case B_DOWNLOAD_PROGRESS: - { - float progress; - if (message->FindFloat("progress", &progress) == B_OK) - fStatusBar->SetTo(progress); - break; - } - case OPEN_DOWNLOAD: - { - // TODO: In case of executable files, ask the user first! - entry_ref ref; - status_t status = get_ref_for_path(fPath.Path(), &ref); - if (status == B_OK) - status = be_roster->Launch(&ref); - if (status != B_OK && status != B_ALREADY_RUNNING) { - BAlert* alert = new BAlert("Open download error", - "The download could not be opened.", "OK"); - alert->Go(NULL); - } - break; - } - case RESTART_DOWNLOAD: - BWebPage::RequestDownload(fURL); - break; - - case CANCEL_DOWNLOAD: - fDownload->Cancel(); - DownloadCanceled(); - break; - - case REMOVE_DOWNLOAD: - { - Window()->PostMessage(SAVE_SETTINGS); - RemoveSelf(); - delete this; - // TOAST! - return; - } - case B_DOWNLOAD_REMOVED: - // TODO: This is a bit asymetric. The removed notification - // arrives here, but it would be nicer if it arrived - // at the window... - Window()->PostMessage(message); - break; - case B_NODE_MONITOR: - { - int32 opCode; - if (message->FindInt32("opcode", &opCode) != B_OK) - break; - switch (opCode) { - case B_ENTRY_REMOVED: - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - case B_ENTRY_MOVED: - { - // Follow the entry to the new location - dev_t device; - ino_t directory; - const char* name; - if (message->FindInt32("device", - reinterpret_cast<int32*>(&device)) != B_OK - || message->FindInt64("to directory", - reinterpret_cast<int64*>(&directory)) != B_OK - || message->FindString("name", &name) != B_OK - || strlen(name) == 0) { - break; - } - // Construct the BEntry and update fPath - entry_ref ref(device, directory, name); - BEntry entry(&ref); - if (entry.GetPath(&fPath) != B_OK) - break; - // Find out if the directory is the Trash for this - // volume - char trashPath[B_PATH_NAME_LENGTH]; - if (find_directory(B_TRASH_DIRECTORY, device, false, - trashPath, B_PATH_NAME_LENGTH) == B_OK) { - BPath trashDirectory(trashPath); - BPath parentDirectory; - fPath.GetParent(&parentDirectory); - if (parentDirectory == trashDirectory) { - // The entry was moved into the Trash. - // If the download is still in progress, - // cancel it. - if (fDownload) - fDownload->Cancel(); - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - } else if (fIconView->IsIconDimmed()) { - // Maybe it was moved out of the trash. - fIconView->SetIconDimmed(false); - } - } - - fStatusBar->SetText(name); - Window()->PostMessage(SAVE_SETTINGS); - break; - } - case B_ATTR_CHANGED: - { - BEntry entry(fPath.Path()); - fIconView->SetIconDimmed(false); - fIconView->SetTo(entry); - break; - } - } - break; - } - default: - BGridView::MessageReceived(message); - } - } - - BWebDownload* Download() const - { - return fDownload; - } - - const BString& URL() const - { - return fURL; - } - - bool IsMissing() const - { - return fIconView->IsIconDimmed(); - } - - bool IsFinished() const - { - return !fDownload && fStatusBar->CurrentValue() == 100; - } - - void DownloadFinished() - { - fDownload = NULL; - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } - - void DownloadCanceled() - { - fDownload = NULL; - fTopButton->SetLabel("Restart"); - fTopButton->SetMessage(new BMessage(RESTART_DOWNLOAD)); - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } + BWebDownload* Download() const; + const BString& URL() const; + bool IsMissing() const; + bool IsFinished() const; -private: - void _StartNodeMonitor(const BEntry& entry) - { - node_ref nref; - if (entry.GetNodeRef(&nref) == B_OK) - watch_node(&nref, B_WATCH_ALL, this); - } - - void _StopNodeMonitor() - { - stop_watching(this); - } + void DownloadFinished(); + void DownloadCanceled(); private: - IconView* fIconView; - BStatusBar* fStatusBar; - SmallButton* fTopButton; - SmallButton* fBottomButton; - BWebDownload* fDownload; - BString fURL; - BPath fPath; - off_t fExpectedSize; -}; - + void _StartNodeMonitor(const BEntry& entry); + void _StopNodeMonitor(); -class DownloadsContainerView : public BGroupView { -public: - DownloadsContainerView() - : - BGroupView(B_VERTICAL) - { - SetViewColor(245, 245, 245); - AddChild(BSpaceLayoutItem::CreateGlue()); - } - - virtual BSize MinSize() - { - BSize minSize = BGroupView::MinSize(); - return BSize(minSize.width, 80); - } - -protected: - virtual void DoLayout() - { - BGroupView::DoLayout(); - if (BScrollBar* scrollBar = ScrollBar(B_VERTICAL)) { - BSize minSize = BGroupView::MinSize(); - float height = Bounds().Height(); - float max = minSize.height - height; - scrollBar->SetRange(0, max); - if (minSize.height > 0) - scrollBar->SetProportion(height / minSize.height); - else - scrollBar->SetProportion(1); - } - } -}; - - -class DownloadContainerScrollView : public BScrollView { -public: - DownloadContainerScrollView(BView* target) - : - BScrollView("Downloads scroll view", target, 0, false, true, - B_NO_BORDER) - { - } - -protected: - virtual void DoLayout() - { - BScrollView::DoLayout(); - // Tweak scroll bar layout to hide part of the frame for better looks. - BScrollBar* scrollBar = ScrollBar(B_VERTICAL); - scrollBar->MoveBy(1, -1); - scrollBar->ResizeBy(0, 2); - Target()->ResizeBy(1, 0); - // Set the scroll steps - if (BView* item = Target()->ChildAt(0)) { - scrollBar->SetSteps(item->MinSize().height + 1, - item->MinSize().height + 1); - } - } +private: + IconView* fIconView; + BStatusBar* fStatusBar; + SmallButton* fTopButton; + SmallButton* fBottomButton; + BWebDownload* fDownload; + BString fURL; + BPath fPath; + off_t fExpectedSize; }; - -// #pragma mark - - - -DownloadWindow::DownloadWindow(BRect frame, bool visible, - SettingsMessage* settings) - : BWindow(frame, "Downloads", - B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, - B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE) -{ - settings->AddListener(BMessenger(this)); - BPath downloadPath; - if (find_directory(B_DESKTOP_DIRECTORY, &downloadPath) != B_OK) - downloadPath.SetTo("/boot/home/Desktop"); - fDownloadPath = settings->GetValue("download path", downloadPath.Path()); - settings->SetValue("download path", fDownloadPath); - - SetLayout(new BGroupLayout(B_VERTICAL)); - - DownloadsContainerView* downloadsGroupView = new DownloadsContainerView(); - fDownloadViewsLayout = downloadsGroupView->GroupLayout(); - - BMenuBar* menuBar = new BMenuBar("Menu bar"); - BMenu* menu = new BMenu("Downloads"); - menu->AddItem(new BMenuItem("Open downloads folder", - new BMessage(OPEN_DOWNLOADS_FOLDER))); - menu->AddItem(new BMenuItem("Hide", new BMessage(B_QUIT_REQUESTED), 'H')); - menuBar->AddItem(menu); - - BScrollView* scrollView = new DownloadContainerScrollView( - downloadsGroupView); - - fRemoveFinishedButton = new BButton("Remove finished", - new BMessage(REMOVE_FINISHED_DOWNLOADS)); - fRemoveFinishedButton->SetEnabled(false); - - fRemoveMissingButton = new BButton("Remove missing", - new BMessage(REMOVE_MISSING_DOWNLOADS)); - fRemoveMissingButton->SetEnabled(false); - - AddChild(BGroupLayoutBuilder(B_VERTICAL) - .Add(menuBar) - .Add(scrollView) - .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) - .Add(BGroupLayoutBuilder(B_HORIZONTAL) - .AddGlue() - .Add(fRemoveMissingButton) - .Add(fRemoveFinishedButton) - .SetInsets(5, 5, 5, 5) - ) - ); - - PostMessage(INIT); - - if (!visible) - Hide(); - Show(); -} - - -DownloadWindow::~DownloadWindow() -{ - // Only necessary to save the current progress of unfinished downloads: - _SaveSettings(); -} - - -void -DownloadWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - case INIT: - { - _LoadSettings(); - // Small trick to get the correct enabled status of the Remove - // finished button - _DownloadFinished(NULL); - break; - } - case B_DOWNLOAD_ADDED: - { - BWebDownload* download; - if (message->FindPointer("download", reinterpret_cast<void**>( - &download)) == B_OK) { - _DownloadStarted(download); - } - break; - } - case B_DOWNLOAD_REMOVED: - { - BWebDownload* download; - if (message->FindPointer("download", reinterpret_cast<void**>( - &download)) == B_OK) { - _DownloadFinished(download); - } - break; - } - case OPEN_DOWNLOADS_FOLDER: - { - entry_ref ref; - status_t status = get_ref_for_path(fDownloadPath.String(), &ref); - if (status == B_OK) - status = be_roster->Launch(&ref); - if (status != B_OK && status != B_ALREADY_RUNNING) { - BString errorString("The downloads folder could not be " - "opened.\n\n"); - errorString << "Error: " << strerror(status); - BAlert* alert = new BAlert("Error opening downloads folder", - errorString.String(), "OK"); - alert->Go(NULL); - } - break; - } - case REMOVE_FINISHED_DOWNLOADS: - _RemoveFinishedDownloads(); - break; - case REMOVE_MISSING_DOWNLOADS: - _RemoveMissingDownloads(); - break; - case SAVE_SETTINGS: - _SaveSettings(); - break; - - case SETTINGS_VALUE_CHANGED: - { - BString string; - if (message->FindString("name", &string) == B_OK - && string == "download path" - && message->FindString("value", &string) == B_OK) { - fDownloadPath = string; - } - break; - } - default: - BWindow::MessageReceived(message); - break; - } -} - - -bool -DownloadWindow::QuitRequested() -{ - if (!IsHidden()) - Hide(); - return false; -} - - -void -DownloadWindow::_DownloadStarted(BWebDownload* download) -{ - download->Start(BPath(fDownloadPath.String())); - - int32 finishedCount = 0; - int32 missingCount = 0; - int32 index = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->URL() == download->URL()) { - index = i; - view->RemoveSelf(); - delete view; - continue; - } - if (view->IsFinished()) - finishedCount++; - if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - fRemoveMissingButton->SetEnabled(missingCount > 0); - DownloadProgressView* view = new DownloadProgressView(download); - if (!view->Init()) - return; - fDownloadViewsLayout->AddView(index, view); - _SaveSettings(); - - SetWorkspaces(B_CURRENT_WORKSPACE); - if (IsHidden()) - Show(); -} - - -void -DownloadWindow::_DownloadFinished(BWebDownload* download) -{ - int32 finishedCount = 0; - int32 missingCount = 0; - for (int32 i = 0; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i++) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (download && view->Download() == download) { - view->DownloadFinished(); - finishedCount++; - continue; - } - if (view->IsFinished()) - finishedCount++; - if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - fRemoveMissingButton->SetEnabled(missingCount > 0); - if (download) - _SaveSettings(); -} - - -void -DownloadWindow::_RemoveFinishedDownloads() -{ - int32 missingCount = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->IsFinished()) { - view->RemoveSelf(); - delete view; - } else if (view->IsMissing()) - missingCount++; - } - fRemoveFinishedButton->SetEnabled(false); - fRemoveMissingButton->SetEnabled(missingCount > 0); - _SaveSettings(); -} - - -void -DownloadWindow::_RemoveMissingDownloads() -{ - int32 finishedCount = 0; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - if (view->IsMissing()) { - view->RemoveSelf(); - delete view; - } else if (view->IsFinished()) - finishedCount++; - } - fRemoveMissingButton->SetEnabled(false); - fRemoveFinishedButton->SetEnabled(finishedCount > 0); - _SaveSettings(); -} - - -void -DownloadWindow::_SaveSettings() -{ - BFile file; - if (!_OpenSettingsFile(file, B_ERASE_FILE | B_CREATE_FILE | B_WRITE_ONLY)) - return; - BMessage message; - for (int32 i = fDownloadViewsLayout->CountItems() - 1; - BLayoutItem* item = fDownloadViewsLayout->ItemAt(i); i--) { - DownloadProgressView* view = dynamic_cast<DownloadProgressView*>( - item->View()); - if (!view) - continue; - BMessage downloadArchive; - if (view->SaveSettings(&downloadArchive) == B_OK) - message.AddMessage("download", &downloadArchive); - } - message.Flatten(&file); -} - - -void -DownloadWindow::_LoadSettings() -{ - BFile file; - if (!_OpenSettingsFile(file, B_READ_ONLY)) - return; - BMessage message; - if (message.Unflatten(&file) != B_OK) - return; - BMessage downloadArchive; - for (int32 i = 0; - message.FindMessage("download", i, &downloadArchive) == B_OK; - i++) { - DownloadProgressView* view = new DownloadProgressView( - &downloadArchive); - if (!view->Init(&downloadArchive)) - continue; - fDownloadViewsLayout->AddView(0, view); - } -} - - -bool -DownloadWindow::_OpenSettingsFile(BFile& file, uint32 mode) -{ - BPath path; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK - || path.Append(kApplicationName) != B_OK - || path.Append("Downloads") != B_OK) { - return false; - } - return file.SetTo(path.Path(), mode) == B_OK; -} - - +#endif // DOWNLOAD_PROGRESS_VIEW_H Modified: webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp ============================================================================== --- webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Wed Mar 24 18:41:05 2010 (r349) +++ webkit/trunk/WebKit/haiku/WebPositive/DownloadWindow.cpp Wed Mar 24 18:41:38 2010 (r350) @@ -30,26 +30,22 @@ #include <stdio.h> #include <Alert.h> -#include <Bitmap.h> #include <Button.h> -#include <Directory.h> #include <Entry.h> +#include <File.h> #include <FindDirectory.h> -#include <GridLayoutBuilder.h> #include <GroupLayout.h> #include <GroupLayoutBuilder.h> #include <MenuBar.h> #include <MenuItem.h> -#include <NodeInfo.h> -#include <NodeMonitor.h> #include <Path.h> #include <Roster.h> #include <ScrollView.h> #include <SeparatorView.h> #include <SpaceLayoutItem.h> -#include <StatusBar.h> #include "BrowserApp.h" +#include "DownloadProgressView.h" #include "SettingsMessage.h" #include "WebDownload.h" #include "WebPage.h" @@ -59,438 +55,7 @@ INIT = 'init', OPEN_DOWNLOADS_FOLDER = 'odnf', REMOVE_FINISHED_DOWNLOADS = 'rmfd', - REMOVE_MISSING_DOWNLOADS = 'rmmd', - OPEN_DOWNLOAD = 'opdn', - RESTART_DOWNLOAD = 'rsdn', - CANCEL_DOWNLOAD = 'cndn', - REMOVE_DOWNLOAD = 'rmdn', - SAVE_SETTINGS = 'svst' -}; - - -class IconView : public BView { -public: - IconView(const BEntry& entry) - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32), - fDimmedIcon(false) - { - SetDrawingMode(B_OP_OVER); - SetTo(entry); - } - - IconView() - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32), - fDimmedIcon(false) - { - SetDrawingMode(B_OP_OVER); - memset(fIconBitmap.Bits(), 0, fIconBitmap.BitsLength()); - } - - IconView(BMessage* archive) - : - BView("Download icon", B_WILL_DRAW), - fIconBitmap(archive), - fDimmedIcon(true) - { - SetDrawingMode(B_OP_OVER); - } - - void SetTo(const BEntry& entry) - { - BNode node(&entry); - BNodeInfo info(&node); - info.GetTrackerIcon(&fIconBitmap, B_LARGE_ICON); - Invalidate(); - } - - void SetIconDimmed(bool iconDimmed) - { - if (fDimmedIcon != iconDimmed) { - fDimmedIcon = iconDimmed; - Invalidate(); - } - } - - bool IsIconDimmed() const - { - return fDimmedIcon; - } - - status_t SaveSettings(BMessage* archive) - { - return fIconBitmap.Archive(archive); - } - - virtual void AttachedToWindow() - { - SetViewColor(Parent()->ViewColor()); - } - - virtual void Draw(BRect updateRect) - { - if (fDimmedIcon) { - SetDrawingMode(B_OP_ALPHA); - SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - SetHighColor(0, 0, 0, 100); - } - DrawBitmapAsync(&fIconBitmap); - } - - virtual BSize MinSize() - { - return BSize(fIconBitmap.Bounds().Width(), fIconBitmap.Bounds().Height()); - } - - virtual BSize PreferredSize() - { - return MinSize(); - } - - virtual BSize MaxSize() - { - return MinSize(); - } - -private: - BBitmap fIconBitmap; - bool fDimmedIcon; -}; - - -class SmallButton : public BButton { -public: - SmallButton(const char* label, BMessage* message = NULL) - : - BButton(label, message) - { - BFont font; - GetFont(&font); - float size = ceilf(font.Size() * 0.8); - font.SetSize(max_c(8, size)); - SetFont(&font, B_FONT_SIZE); - } -}; - - -class DownloadProgressView : public BGridView { -public: - DownloadProgressView(BWebDownload* download) - : - BGridView(8, 3), - fDownload(download), - fURL(download->URL()), - fPath(download->Path()), - fExpectedSize(download->ExpectedSize()) - { - } - - DownloadProgressView(const BMessage* archive) - : - BGridView(8, 3), - fDownload(NULL), - fURL(), - fPath(), - fExpectedSize(0) - { - const char* string; - if (archive->FindString("path", &string) == B_OK) - fPath.SetTo(string); - if (archive->FindString("url", &string) == B_OK) - fURL = string; - } - - bool Init(BMessage* archive = NULL) - { - SetViewColor(245, 245, 245); - SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW); - - BGridLayout* layout = GridLayout(); - if (archive) { - fStatusBar = new BStatusBar("download progress", fPath.Leaf()); - float value; - if (archive->FindFloat("value", &value) == B_OK) - fStatusBar->SetTo(value); - } else - fStatusBar = new BStatusBar("download progress", "Download"); - fStatusBar->SetMaxValue(100); - fStatusBar->SetBarHeight(12); - - // fPath is only valid when constructed from archive (fDownload == NULL) - BEntry entry(fPath.Path()); - - if (archive) { - if (!entry.Exists()) - fIconView = new IconView(archive); - else - fIconView = new IconView(entry); - } else - fIconView = new IconView(); - - if (!fDownload && (fStatusBar->CurrentValue() < 100 || !entry.Exists())) - fTopButton = new SmallButton("Restart", new BMessage(RESTART_DOWNLOAD)); - else { - fTopButton = new SmallButton("Open", new BMessage(OPEN_DOWNLOAD)); - fTopButton->SetEnabled(fDownload == NULL); - } - if (fDownload) - fBottomButton = new SmallButton("Cancel", new BMessage(CANCEL_DOWNLOAD)); - else { - fBottomButton = new SmallButton("Remove", new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(fDownload == NULL); - } - - layout->SetInsets(8, 5, 5, 6); - layout->AddView(fIconView, 0, 0, 1, 2); - layout->AddView(fStatusBar, 1, 0, 1, 2); - layout->AddView(fTopButton, 2, 0); - layout->AddView(fBottomButton, 2, 1); - - return true; - } - - status_t SaveSettings(BMessage* archive) - { - if (!archive) - return B_BAD_VALUE; - status_t ret = archive->AddString("path", fPath.Path()); - if (ret == B_OK) - ret = archive->AddString("url", fURL.String()); - if (ret == B_OK) - ret = archive->AddFloat("value", fStatusBar->CurrentValue()); - if (ret == B_OK) - ret = fIconView->SaveSettings(archive); - return ret; - } - - virtual void AttachedToWindow() - { - if (fDownload) - fDownload->SetProgressListener(BMessenger(this)); - fTopButton->SetTarget(this); - fBottomButton->SetTarget(this); - - BEntry entry(fPath.Path()); - if (entry.Exists()) - _StartNodeMonitor(entry); - } - - virtual void DetachedFromWindow() - { - _StopNodeMonitor(); - } - - virtual void AllAttached() - { - SetViewColor(B_TRANSPARENT_COLOR); - SetLowColor(245, 245, 245); - SetHighColor(tint_color(LowColor(), B_DARKEN_1_TINT)); - } - - virtual void Draw(BRect updateRect) - { - BRect bounds(Bounds()); - bounds.bottom--; - FillRect(bounds, B_SOLID_LOW); - bounds.bottom++; - StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); - } - - virtual void MessageReceived(BMessage* message) - { - switch (message->what) { - case B_DOWNLOAD_STARTED: - { - BString path; - if (message->FindString("path", &path) != B_OK) - break; - fPath.SetTo(path); - BEntry entry(fPath.Path()); - fIconView->SetTo(entry); - fStatusBar->Reset(fPath.Leaf()); - _StartNodeMonitor(entry); - break; - }; - case B_DOWNLOAD_PROGRESS: - { - float progress; - if (message->FindFloat("progress", &progress) == B_OK) - fStatusBar->SetTo(progress); - break; - } - case OPEN_DOWNLOAD: - { - // TODO: In case of executable files, ask the user first! - entry_ref ref; - status_t status = get_ref_for_path(fPath.Path(), &ref); - if (status == B_OK) - status = be_roster->Launch(&ref); - if (status != B_OK && status != B_ALREADY_RUNNING) { - BAlert* alert = new BAlert("Open download error", - "The download could not be opened.", "OK"); - alert->Go(NULL); - } - break; - } - case RESTART_DOWNLOAD: - BWebPage::RequestDownload(fURL); - break; - - case CANCEL_DOWNLOAD: - fDownload->Cancel(); - DownloadCanceled(); - break; - - case REMOVE_DOWNLOAD: - { - Window()->PostMessage(SAVE_SETTINGS); - RemoveSelf(); - delete this; - // TOAST! - return; - } - case B_DOWNLOAD_REMOVED: - // TODO: This is a bit asymetric. The removed notification - // arrives here, but it would be nicer if it arrived - // at the window... - Window()->PostMessage(message); - break; - case B_NODE_MONITOR: - { - int32 opCode; - if (message->FindInt32("opcode", &opCode) != B_OK) - break; - switch (opCode) { - case B_ENTRY_REMOVED: - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - case B_ENTRY_MOVED: - { - // Follow the entry to the new location - dev_t device; - ino_t directory; - const char* name; - if (message->FindInt32("device", - reinterpret_cast<int32*>(&device)) != B_OK - || message->FindInt64("to directory", - reinterpret_cast<int64*>(&directory)) != B_OK - || message->FindString("name", &name) != B_OK - || strlen(name) == 0) { - break; - } - // Construct the BEntry and update fPath - entry_ref ref(device, directory, name); - BEntry entry(&ref); - if (entry.GetPath(&fPath) != B_OK) - break; - // Find out if the directory is the Trash for this - // volume - char trashPath[B_PATH_NAME_LENGTH]; - if (find_directory(B_TRASH_DIRECTORY, device, false, - trashPath, B_PATH_NAME_LENGTH) == B_OK) { - BPath trashDirectory(trashPath); - BPath parentDirectory; - fPath.GetParent(&parentDirectory); - if (parentDirectory == trashDirectory) { - // The entry was moved into the Trash. - // If the download is still in progress, - // cancel it. - if (fDownload) - fDownload->Cancel(); - fIconView->SetIconDimmed(true); - DownloadCanceled(); - break; - } else if (fIconView->IsIconDimmed()) { - // Maybe it was moved out of the trash. - fIconView->SetIconDimmed(false); - } - } - - fStatusBar->SetText(name); - Window()->PostMessage(SAVE_SETTINGS); - break; - } - case B_ATTR_CHANGED: - { - BEntry entry(fPath.Path()); - fIconView->SetIconDimmed(false); - fIconView->SetTo(entry); - break; - } - } - break; - } - default: - BGridView::MessageReceived(message); - } - } - - BWebDownload* Download() const - { - return fDownload; - } - - const BString& URL() const - { - return fURL; - } - - bool IsMissing() const - { - return fIconView->IsIconDimmed(); - } - - bool IsFinished() const - { - return !fDownload && fStatusBar->CurrentValue() == 100; - } - - void DownloadFinished() - { - fDownload = NULL; - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } - - void DownloadCanceled() - { - fDownload = NULL; - fTopButton->SetLabel("Restart"); - fTopButton->SetMessage(new BMessage(RESTART_DOWNLOAD)); - fTopButton->SetEnabled(true); - fBottomButton->SetLabel("Remove"); - fBottomButton->SetMessage(new BMessage(REMOVE_DOWNLOAD)); - fBottomButton->SetEnabled(true); - } - -private: - void _StartNodeMonitor(const BEntry& entry) - { - node_ref nref; - if (entry.GetNodeRef(&nref) == B_OK) - watch_node(&nref, B_WATCH_ALL, this); - } - - void _StopNodeMonitor() - { - stop_watching(this); - } - -private: - IconView* fIconView; - BStatusBar* fStatusBar; - SmallButton* fTopButton; - SmallButton* fBottomButton; - BWebDownload* fDownload; - BString fURL; - BPath fPath; - off_t fExpectedSize; + REMOVE_MISSING_DOWNLOADS = 'rmmd' };