source: trunk/beos/TRTransfer.cpp @ 5457

Last change on this file since 5457 was 5457, checked in by charles, 14 years ago

remove `TR_STATUS_DONE' from libtransmission's public API. It's useful as an internal state but not for code calling libtransmission.

  • Property svn:keywords set to Date Rev Author Id
File size: 9.0 KB
Line 
1/**
2 * Copyright (C) 2007 Bryan Varner
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * $Id: TRTransfer.cpp 5457 2008-03-31 17:59:16Z charles $
24 */
25
26#include "TRTransfer.h"
27
28#include <Font.h>
29
30#include <malloc.h>
31#include <stdio.h>
32
33/**
34 * BListItem that renders Transfer status.
35 */
36TRTransfer::TRTransfer(const char *fullpath, node_ref node, tr_torrent_t *torrentRef) : BListItem(0, false), cachedNodeRef(node) {
37        fBaselineOffset = 0.0f;
38        fLineSpacing = 0.0f;
39        torrent = torrentRef;
40       
41        cachedPath = new BString(fullpath);
42        fStatusLock = new BLocker("Status Locker", true);
43       
44        fStatus = (tr_stat_t*)calloc(1, sizeof(tr_stat_t));
45        const tr_info_t *info = tr_torrentInfo(torrent);
46        fName = new BString("<unknown name>");
47        fName->SetTo(info->name);
48       
49        fBarColor.red = 50;
50        fBarColor.green = 150;
51        fBarColor.blue = 255;
52        fBarColor.alpha = 255;
53       
54        fTimeStr = (char*)calloc(78, sizeof(char));
55        fTransStr = (char*)calloc(78, sizeof(char));
56}
57
58
59TRTransfer::~TRTransfer() {
60        if (fStatusLock->Lock()) {
61                free(fStatus);
62                fStatusLock->Unlock();
63                delete fStatusLock;
64        }
65        delete cachedPath;
66        delete fName;
67}
68
69
70void TRTransfer::Update(BView *owner, const BFont *font) {
71        BListItem::Update(owner, font);
72        SetHeight(BListItem::Height() * 4);
73       
74        font_height height;
75        font->GetHeight(&height);
76       
77        fBaselineOffset = height.leading + height.ascent;
78        fLineSpacing = height.descent;
79}
80
81
82/**
83 * Sets the transfer information to render.
84 * Returns a bool signaling the view is dirty after the update.
85 *
86 * The view is determined to be dirty if the transfer
87 * status, percentDone, eta or the "shade" (even or odd)
88 * position in the list changes from the previous state.
89 * If the tr_stat_t is in fact different then the new, full
90 * status is memcpy'd overtop the existing code.
91 *
92 * This is a thread-safe function, as all writing to the
93 * local fStatus requires a successful Lock on fStatusLock.
94 */
95bool TRTransfer::UpdateStatus(const tr_stat_t *stat, bool shade) {
96        bool dirty = false;
97        if (fStatusLock->Lock()) {
98                if (fStatus->status != stat->status ||
99                    fStatus->percentDone != stat->percentDone ||
100                    fStatus->eta != stat->eta ||
101                    fShade != shade)
102                {
103                        memcpy(fStatus, stat, sizeof(tr_stat_t));
104                        dirty = true;
105                }
106                fStatusLock->Unlock();
107                fShade = shade;
108        }
109        return dirty;
110}
111
112bool TRTransfer::IsRunning() {
113        return (fStatus != NULL && 
114                        (fStatus->status & (TR_STATUS_CHECK_WAIT | TR_STATUS_CHECK |
115                                            TR_STATUS_DOWNLOAD | TR_STATUS_SEED | TR_STATUS_STOPPING)));
116}
117
118
119/**
120 * Renders (Draws) the current status into the BListView.
121 */
122void TRTransfer::DrawItem(BView *owner, BRect frame, bool) {
123        rgb_color col;
124        col.red = 255;
125        col.green = 255;
126        col.blue = 255;
127       
128        owner->PushState();
129       
130        // Draw the background...
131        if (IsSelected()) {
132                owner->SetLowColor(tint_color(col, B_DARKEN_2_TINT));
133        } else if (fShade) {
134                owner->SetLowColor(tint_color(tint_color(col, B_DARKEN_1_TINT), B_LIGHTEN_2_TINT));
135        } else {
136                owner->SetLowColor(col);
137        }
138        owner->FillRect(frame, B_SOLID_LOW);
139       
140        // Draw the informational text...
141        owner->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
142        BPoint textLoc = frame.LeftTop();
143        textLoc.y += (fBaselineOffset / 2);
144        textLoc += BPoint(2, fBaselineOffset);
145       
146        if (fStatus != NULL && fStatusLock->Lock()) {
147                owner->DrawString(fName->String(), textLoc);
148               
149                if (fStatus->status & TR_STATUS_STOPPED ) {
150                        sprintf(fTimeStr, "Paused (%.2f %%)", 100 * fStatus->percentDone);
151                } else if (fStatus->status & TR_STATUS_CHECK_WAIT ) {
152                        sprintf(fTimeStr, "Waiting To Check Existing Files (%.2f %%)",
153                                100 * fStatus->percentDone);
154                } else if (fStatus->status & TR_STATUS_CHECK ) {
155                        sprintf(fTimeStr, "Checking Existing Files (%.2f %%)",
156                                100 * fStatus->percentDone);
157                } else if (fStatus->status & TR_STATUS_DOWNLOAD) {
158                        if (fStatus->eta < 0 ) {
159                                sprintf(fTimeStr, "--:--:-- Remaining (%.2f %%Complete)",
160                                        100 * fStatus->percentDone);
161                        } else {
162                                sprintf(fTimeStr, "%02d:%02d:%02d Remaining (%.2f %%Complete)",
163                                        fStatus->eta / 3600, (fStatus->eta / 60) % 60,
164                                        fStatus->eta % 60, 100 * fStatus->percentDone);
165                        }
166                } else if (fStatus->status & TR_STATUS_SEED) {
167                        sprintf(fTimeStr, "Seeding");
168                } else if (fStatus->status & TR_STATUS_STOPPING) {
169                        sprintf(fTimeStr, "Stopping...");
170                } else {
171                        fTimeStr[0] = '\0';
172                }
173               
174                textLoc.x = frame.Width() - owner->StringWidth(fTimeStr) - 2;
175                owner->DrawString(fTimeStr, textLoc);
176               
177                if (fStatus->status & (TR_STATUS_DOWNLOAD | TR_STATUS_SEED | TR_STATUS_CHECK | TR_STATUS_CHECK_WAIT )) {
178                        // Move to the left of the bottom line.
179                        textLoc.Set(frame.left + 2, 
180                                    frame.top + fBaselineOffset * 3 + (2 * fLineSpacing) + (fBaselineOffset / 2));
181                        sprintf(fTransStr, "DL: %.2f KB/s (from %i of %i peer%s)",
182                                fStatus->rateDownload, fStatus->peersSendingToUs, fStatus->peersTotal,
183                                (fStatus->peersTotal == 1) ? "" : "s");
184                        owner->DrawString(fTransStr, textLoc);
185                       
186                        sprintf(fTransStr, "UL: %.2f KB/s", fStatus->rateUpload);
187                        textLoc.x = frame.Width() - owner->StringWidth(fTransStr) - 2;
188                        owner->DrawString(fTransStr, textLoc);
189                }
190               
191                /*
192                 * Progress Bar - Mercilessly ripped from the Haiku source code, and
193                 * modified to handle selection tinting, and list item position shading.
194                 */
195                // Custom setup (Transmission Added)
196                BRect rect(frame.left + 2, frame.top + fBaselineOffset + fLineSpacing + (fBaselineOffset / 2),
197                           frame.Width() - 2, frame.top + fBaselineOffset * 2 + fLineSpacing + (fBaselineOffset / 2));
198               
199                // First bevel
200                owner->SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT));
201                if (IsSelected()) {
202                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
203                }
204                owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
205                owner->StrokeLine(BPoint(rect.right, rect.top));
206       
207                owner->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
208                if (IsSelected()) {
209                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
210                }
211                owner->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom));
212                owner->StrokeLine(BPoint(rect.right, rect.top + 1.0f));
213       
214                rect.InsetBy(1.0f, 1.0f);
215               
216                // Second bevel
217                owner->SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT));
218                if (IsSelected()) {
219                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
220                }
221                owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
222                owner->StrokeLine(BPoint(rect.right, rect.top));
223       
224                owner->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
225                if (IsSelected()) {
226                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
227                }
228                owner->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom));
229                owner->StrokeLine(BPoint(rect.right, rect.top + 1.0f));
230       
231                rect.InsetBy(1.0f, 1.0f);
232       
233                // Filling
234                owner->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT));
235                if (IsSelected()) {
236                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
237                }
238                owner->FillRect(rect);
239       
240                if (fStatus->percentDone != 0.0f) {
241                        rect.right = rect.left + (float)ceil(fStatus->percentDone * (rect.Width() - 4)),
242       
243                        // Bevel
244                        owner->SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT));
245                        if (IsSelected()) {
246                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
247                        }
248                        owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
249                        owner->StrokeLine(BPoint(rect.right, rect.top));
250       
251                        owner->SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT));
252                        if (IsSelected()) {
253                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
254                        }
255                        owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.right, rect.bottom));
256                        owner->StrokeLine(BPoint(rect.right, rect.top));
257       
258                        rect.InsetBy(1.0f, 1.0f);
259       
260                        // Filling
261                        owner->SetHighColor(fBarColor);
262                        if (IsSelected()) {
263                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
264                        }
265                        owner->FillRect(rect);
266                }
267               
268                fStatusLock->Unlock();
269        } else {
270                owner->DrawString("loading...", textLoc);
271        }
272       
273        owner->PopState();
274}
Note: See TracBrowser for help on using the repository browser.