Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: chrome/browser/dom_ui/downloads_ui.cc

Issue 20110: Initial checkin of the HTML downloads UI. It's not yet complete (lacking... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/dom_ui/downloads_ui.h"
6
7 #include "base/gfx/png_encoder.h"
8 #include "base/string_piece.h"
9 #include "base/thread.h"
10 #include "base/time.h"
11 #include "base/time_format.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/dom_ui/fileicon_source.h"
14 #include "chrome/browser/download/download_util.h"
15 #include "chrome/browser/metrics/user_metrics.h"
16 #include "chrome/browser/profile.h"
17 #include "chrome/common/jstemplate_builder.h"
18 #include "chrome/common/l10n_util.h"
19 #include "chrome/common/time_format.h"
20
21 // Generated by GRIT
22 #include "browser_resources.h"
23 #include "generated_resources.h"
24
25 using base::Time;
26
27 // DownloadsUI is accessible from chrome-ui://downloads.
28 static const char kDownloadsHost[] = "downloads";
29
30 ///////////////////////////////////////////////////////////////////////////////
31 //
32 // DownloadsHTMLSource
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 DownloadsUIHTMLSource::DownloadsUIHTMLSource()
37 : DataSource(kDownloadsHost, MessageLoop::current()) {
38 }
39
40 void DownloadsUIHTMLSource::StartDataRequest(const std::string& path,
41 int request_id) {
42 DictionaryValue localized_strings;
43 localized_strings.SetString(L"title",
44 l10n_util::GetString(IDS_DOWNLOAD_TITLE));
45 localized_strings.SetString(L"searchbutton",
46 l10n_util::GetString(IDS_DOWNLOAD_SEARCH_BUTTON));
47 localized_strings.SetString(L"no_results",
48 l10n_util::GetString(IDS_DOWNLOAD_SEARCH_BUTTON));
49 localized_strings.SetString(L"searchresultsfor",
50 l10n_util::GetString(IDS_DOWNLOAD_SEARCHRESULTSFOR));
51 localized_strings.SetString(L"downloads",
52 l10n_util::GetString(IDS_DOWNLOAD_TITLE));
53
54 // Status.
55 localized_strings.SetString(L"status_cancelled",
56 l10n_util::GetString(IDS_DOWNLOAD_TAB_CANCELLED));
57 localized_strings.SetString(L"status_paused",
58 l10n_util::GetString(IDS_DOWNLOAD_PROGRESS_PAUSED));
59
60 // Dangerous file.
61 localized_strings.SetString(L"danger_desc",
62 l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, L"%s"));
63 localized_strings.SetString(L"danger_save",
64 l10n_util::GetString(IDS_SAVE_DOWNLOAD));
65 localized_strings.SetString(L"danger_discard",
66 l10n_util::GetString(IDS_DISCARD_DOWNLOAD));
67
68 // Controls.
69 localized_strings.SetString(L"control_pause",
70 l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE));
71 localized_strings.SetString(L"control_showinfolder",
72 l10n_util::GetString(IDS_DOWNLOAD_LINK_SHOW));
73 localized_strings.SetString(L"control_cancel",
74 l10n_util::GetString(IDS_DOWNLOAD_LINK_CANCEL));
75 localized_strings.SetString(L"control_resume",
76 l10n_util::GetString(IDS_DOWNLOAD_LINK_RESUME));
77
78 static const StringPiece downloads_html(
79 ResourceBundle::GetSharedInstance().GetRawDataResource(
80 IDR_DOWNLOADS_HTML));
81 const std::string full_html = jstemplate_builder::GetTemplateHtml(
82 downloads_html, &localized_strings, "t");
83
84 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
85 html_bytes->data.resize(full_html.size());
86 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
87
88 SendResponse(request_id, html_bytes);
89 }
90
91 ///////////////////////////////////////////////////////////////////////////////
92 //
93 // DownloadsDOMHandler
94 //
95 ///////////////////////////////////////////////////////////////////////////////
96
97 // Sort DownloadItems into descending order by their start time.
98 class DownloadItemSorter : public std::binary_function<DownloadItem*,
99 DownloadItem*,
100 bool> {
101 public:
102 bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) {
103 return lhs->start_time() > rhs->start_time();
104 }
105 };
106
107 DownloadsDOMHandler::DownloadsDOMHandler(DOMUI* dom_ui, DownloadManager* dlm)
108 : DOMMessageHandler(dom_ui),
109 download_manager_(dlm),
110 search_text_() {
111 dom_ui_->RegisterMessageCallback("getDownloads",
112 NewCallback(this, &DownloadsDOMHandler::HandleGetDownloads));
113 dom_ui_->RegisterMessageCallback("openFile",
114 NewCallback(this, &DownloadsDOMHandler::HandleOpenFile));
115
116 dom_ui_->RegisterMessageCallback("drag",
117 NewCallback(this, &DownloadsDOMHandler::HandleDrag));
118
119 dom_ui_->RegisterMessageCallback("saveDangerous",
120 NewCallback(this, &DownloadsDOMHandler::HandleSaveDangerous));
121 dom_ui_->RegisterMessageCallback("discardDangerous",
122 NewCallback(this, &DownloadsDOMHandler::HandleDiscardDangerous));
123 dom_ui_->RegisterMessageCallback("show",
124 NewCallback(this, &DownloadsDOMHandler::HandleShow));
125 dom_ui_->RegisterMessageCallback("pause",
126 NewCallback(this, &DownloadsDOMHandler::HandlePause));
127 dom_ui_->RegisterMessageCallback("cancel",
128 NewCallback(this, &DownloadsDOMHandler::HandleCancel));
129
130 // Create our fileicon data source.
131 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
132 NewRunnableMethod(&chrome_url_data_manager,
133 &ChromeURLDataManager::AddDataSource,
134 new FileIconSource()));
135 }
136
137 DownloadsDOMHandler::~DownloadsDOMHandler() {
138 ClearDownloadItems();
139 download_manager_->RemoveObserver(this);
140 }
141
142 // DownloadsDOMHandler, public: -----------------------------------------------
143
144 void DownloadsDOMHandler::Init() {
145 download_manager_->AddObserver(this);
146 }
147
148 void DownloadsDOMHandler::OnDownloadUpdated(DownloadItem* download) {
149 // Get the id for the download. Our downloads are sorted latest to first,
150 // and the id is the index into that list. We should be careful of sync
151 // errors between the UI and the download_items_ list (we may wish to use
152 // something other than 'id').
153 OrderedDownloads::iterator it = find(download_items_.begin(),
154 download_items_.end(),
155 download);
156 if (it == download_items_.end())
157 return;
158 const int id = static_cast<int>(it - download_items_.begin());
159
160 ListValue results_value;
161 results_value.Append(CreateDownloadItemValue(download, id));
162 dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value);
163 }
164
165 // A download has started or been deleted. Query our DownloadManager for the
166 // current set of downloads, which will call us back in SetDownloads once it
167 // has retrieved them.
168 void DownloadsDOMHandler::ModelChanged() {
169 ClearDownloadItems();
170 download_manager_->GetDownloads(this, search_text_);
171 }
172
173 void DownloadsDOMHandler::SetDownloads(
174 std::vector<DownloadItem*>& downloads) {
175 ClearDownloadItems();
176
177 // Swap new downloads in.
178 download_items_.swap(downloads);
179 sort(download_items_.begin(), download_items_.end(), DownloadItemSorter());
180
181 // Scan for any in progress downloads and add ourself to them as an observer.
182 for (OrderedDownloads::iterator it = download_items_.begin();
183 it != download_items_.end(); ++it) {
184 DownloadItem* download = *it;
185 if (download->state() == DownloadItem::IN_PROGRESS) {
186 // We want to know what happens as the download progresses.
187 download->AddObserver(this);
188 } else if (download->safety_state() == DownloadItem::DANGEROUS) {
189 // We need to be notified when the user validates the dangerous download.
190 download->AddObserver(this);
191 }
192 }
193
194 SendCurrentDownloads();
195 }
196
197 void DownloadsDOMHandler::HandleGetDownloads(const Value* value) {
198 std::wstring new_search = ExtractStringValue(value);
199 if (search_text_.compare(new_search) != 0) {
200 search_text_ = new_search;
201 ClearDownloadItems();
202 download_manager_->GetDownloads(this, search_text_);
203 } else {
204 SendCurrentDownloads();
205 }
206 }
207
208 void DownloadsDOMHandler::HandleOpenFile(const Value* value) {
209 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
210 if (file)
211 download_manager_->OpenDownloadInShell(file, NULL);
212 }
213
214 void DownloadsDOMHandler::HandleDrag(const Value* value) {
215 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
216 if (file) {
217 IconManager* im = g_browser_process->icon_manager();
218 SkBitmap* icon = im->LookupIcon(file->full_path().ToWStringHack(),
219 IconLoader::NORMAL);
220 download_util::DragDownload(file, icon);
221 }
222 }
223
224 void DownloadsDOMHandler::HandleSaveDangerous(const Value* value) {
225 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
226 if (file)
227 download_manager_->DangerousDownloadValidated(file);
228 }
229
230 void DownloadsDOMHandler::HandleDiscardDangerous(const Value* value) {
231 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
232 if (file)
233 file->Remove(true);
234 }
235
236 void DownloadsDOMHandler::HandleShow(const Value* value) {
237 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
238 if (file)
239 download_manager_->ShowDownloadInShell(file);
240 }
241
242 void DownloadsDOMHandler::HandlePause(const Value* value) {
243 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
244 if (file)
245 file->TogglePause();
246 }
247
248 void DownloadsDOMHandler::HandleCancel(const Value* value) {
249 DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
250 if (file)
251 file->Cancel(true);
252 }
253
254 // DownloadsDOMHandler, private: ----------------------------------------------
255
256 void DownloadsDOMHandler::SendCurrentDownloads() {
257 ListValue results_value;
258
259 for (OrderedDownloads::iterator it = download_items_.begin();
260 it != download_items_.end(); ++it) {
261 results_value.Append(CreateDownloadItemValue(*it,
262 static_cast<int>(it - download_items_.begin())));
263 }
264
265 dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
266 }
267
268 DictionaryValue* DownloadsDOMHandler::CreateDownloadItemValue(
269 DownloadItem* download, int id) {
270 DictionaryValue* file_value = new DictionaryValue();
271
272 file_value->SetInteger(L"time",
273 static_cast<int>(download->start_time().ToTimeT()));
274 file_value->SetInteger(L"id", id);
275 file_value->SetString(L"file_path", download->full_path().ToWStringHack());
276 file_value->SetString(L"file_name", download->GetFileName().ToWStringHack());
277 file_value->SetString(L"url", download->url().spec());
278
279 if (download->state() == DownloadItem::IN_PROGRESS) {
280 if (download->safety_state() == DownloadItem::DANGEROUS) {
281 file_value->SetString(L"state", L"DANGEROUS");
282 } else if (download->is_paused()) {
283 file_value->SetString(L"state", L"PAUSED");
284 } else {
285 file_value->SetString(L"state", L"IN_PROGRESS");
286 }
287 file_value->SetInteger(L"speed",
288 static_cast<int>(download->CurrentSpeed()));
289 file_value->SetInteger(L"percent",
290 static_cast<int>(download->PercentComplete()));
291 file_value->SetInteger(L"received",
292 static_cast<int>(download->received_bytes()));
293 } else if (download->state() == DownloadItem::CANCELLED) {
294 file_value->SetString(L"state", L"CANCELLED");
295 } else if (download->state() == DownloadItem::COMPLETE) {
296 if (download->safety_state() == DownloadItem::DANGEROUS) {
297 file_value->SetString(L"state", L"DANGEROUS");
298 } else {
299 file_value->SetString(L"state", L"COMPLETE");
300 }
301 }
302
303 file_value->SetInteger(L"total",
304 static_cast<int>(download->total_bytes()));
305
306 return file_value;
307 }
308
309 void DownloadsDOMHandler::ClearDownloadItems() {
310 // Clear out old state and remove self as observer for each download.
311 for (OrderedDownloads::iterator it = download_items_.begin();
312 it != download_items_.end(); ++it) {
313 (*it)->RemoveObserver(this);
314 }
315 download_items_.clear();
316 }
317
318 DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) {
319 for (OrderedDownloads::iterator it = download_items_.begin();
320 it != download_items_.end(); ++it) {
321 if (static_cast<int>(it - download_items_.begin() == id)) {
322 return (*it);
323 }
324 }
325
326 return NULL;
327 }
328
329 ///////////////////////////////////////////////////////////////////////////////
330 //
331 // DownloadsUI
332 //
333 ///////////////////////////////////////////////////////////////////////////////
334
335 DownloadsUI::DownloadsUI(DOMUIContents* contents) : DOMUI(contents) {
336 }
337
338 void DownloadsUI::Init() {
339 DownloadManager* dlm = get_profile()->GetDownloadManager();
340
341 DownloadsDOMHandler* handler = new DownloadsDOMHandler(this, dlm);
342 AddMessageHandler(handler);
343 handler->Init();
344
345 DownloadsUIHTMLSource* html_source = new DownloadsUIHTMLSource();
346
347 // Set up the chrome-ui://downloads/ source.
348 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
349 NewRunnableMethod(&chrome_url_data_manager,
350 &ChromeURLDataManager::AddDataSource,
351 html_source));
352 }
353
354 // static
355 GURL DownloadsUI::GetBaseURL() {
356 std::string url = DOMUIContents::GetScheme();
357 url += "://";
358 url += kDownloadsHost;
359 return GURL(url);
360 }
361
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698