Changeset 38222 in vbox
- Timestamp:
- Jul 28, 2011 2:22:17 PM (13 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp
r37544 r38222 21 21 #else /* !VBOX_WITH_PRECOMPILED_HEADERS */ 22 22 /* Global includes */ 23 #include <QTimer> 23 #include <QNetworkAccessManager> 24 #include <QNetworkReply> 24 25 /* Local includes */ 25 #include " QIHttp.h"26 #include "VBoxUpdateDlg.h" 26 27 #include "VBoxGlobal.h" 27 28 #include "VBoxProblemReporter.h" 28 #include "VBoxUpdateDlg.h"29 29 #include "UIIconPool.h" 30 30 #include "VBoxUtils.h" 31 31 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 32 32 33 /* VBoxVersion stuff */ 33 /** 34 * This class is used to store VBox version data. 35 */ 34 36 class VBoxVersion 35 37 { 36 38 public: 37 39 38 VBoxVersion (const QString &aVersion)39 : x (0), y (0), z(0)40 { 41 QStringList versionStack = aVersion.split('.');40 VBoxVersion(const QString &strVersion) 41 : x(0), y(0), z(0) 42 { 43 QStringList versionStack = strVersion.split('.'); 42 44 if (versionStack.size() > 0) 43 x = versionStack 45 x = versionStack[0].toInt(); 44 46 if (versionStack.size() > 1) 45 y = versionStack 47 y = versionStack[1].toInt(); 46 48 if (versionStack.size() > 2) 47 z = versionStack 48 } 49 50 bool operator< (const VBoxVersion &aOther) const51 { 52 return (x < aOther.x) ||53 (x == aOther.x && y < aOther.y) ||54 (x == aOther.x && y == aOther.y && z < aOther.z);49 z = versionStack[2].toInt(); 50 } 51 52 bool operator<(const VBoxVersion &other) const 53 { 54 return (x < other.x) || 55 (x == other.x && y < other.y) || 56 (x == other.x && y == other.y && z < other.z); 55 57 } 56 58 57 59 QString toString() const 58 60 { 59 return QString ("%1.%2.%3").arg (x).arg (y).arg(z);61 return QString("%1.%2.%3").arg(x).arg(y).arg(z); 60 62 } 61 63 … … 67 69 }; 68 70 69 /* VBoxUpdateData stuff */70 QList <UpdateDay> VBoxUpdateData::mDayList = QList<UpdateDay>();71 /* VBoxUpdateData stuff: */ 72 QList<UpdateDay> VBoxUpdateData::m_dayList = QList<UpdateDay>(); 71 73 72 74 void VBoxUpdateData::populate() 73 75 { 74 m DayList.clear();76 m_dayList.clear(); 75 77 76 78 /* To avoid re-translation complexity all 77 * have to be retranslated separately .*/78 79 /* Separately retranslate each day */80 m DayList << UpdateDay (VBoxUpdateDlg::tr("1 day"), "1 d");81 m DayList << UpdateDay (VBoxUpdateDlg::tr("2 days"), "2 d");82 m DayList << UpdateDay (VBoxUpdateDlg::tr("3 days"), "3 d");83 m DayList << UpdateDay (VBoxUpdateDlg::tr("4 days"), "4 d");84 m DayList << UpdateDay (VBoxUpdateDlg::tr("5 days"), "5 d");85 m DayList << UpdateDay (VBoxUpdateDlg::tr("6 days"), "6 d");79 * have to be retranslated separately: */ 80 81 /* Separately retranslate each day: */ 82 m_dayList << UpdateDay(VBoxUpdateDlg::tr("1 day"), "1 d"); 83 m_dayList << UpdateDay(VBoxUpdateDlg::tr("2 days"), "2 d"); 84 m_dayList << UpdateDay(VBoxUpdateDlg::tr("3 days"), "3 d"); 85 m_dayList << UpdateDay(VBoxUpdateDlg::tr("4 days"), "4 d"); 86 m_dayList << UpdateDay(VBoxUpdateDlg::tr("5 days"), "5 d"); 87 m_dayList << UpdateDay(VBoxUpdateDlg::tr("6 days"), "6 d"); 86 88 87 89 /* Separately retranslate each week */ 88 m DayList << UpdateDay (VBoxUpdateDlg::tr("1 week"), "1 w");89 m DayList << UpdateDay (VBoxUpdateDlg::tr("2 weeks"), "2 w");90 m DayList << UpdateDay (VBoxUpdateDlg::tr("3 weeks"), "3 w");90 m_dayList << UpdateDay(VBoxUpdateDlg::tr("1 week"), "1 w"); 91 m_dayList << UpdateDay(VBoxUpdateDlg::tr("2 weeks"), "2 w"); 92 m_dayList << UpdateDay(VBoxUpdateDlg::tr("3 weeks"), "3 w"); 91 93 92 94 /* Separately retranslate each month */ 93 m DayList << UpdateDay (VBoxUpdateDlg::tr("1 month"), "1 m");95 m_dayList << UpdateDay(VBoxUpdateDlg::tr("1 month"), "1 m"); 94 96 } 95 97 … … 97 99 { 98 100 QStringList result; 99 for (int i = 0; i < m DayList.size(); ++i)100 result << m DayList[i].val;101 for (int i = 0; i < m_dayList.size(); ++i) 102 result << m_dayList[i].val; 101 103 return result; 102 104 } 103 105 104 VBoxUpdateData::VBoxUpdateData (const QString &aData)105 : m Data (aData)106 , m PeriodIndex(Period1Day)107 , m BranchIndex(BranchStable)106 VBoxUpdateData::VBoxUpdateData(const QString &strData) 107 : m_strData(strData) 108 , m_periodIndex(Period1Day) 109 , m_branchIndex(BranchStable) 108 110 { 109 111 decode(); 110 112 } 111 113 112 VBoxUpdateData::VBoxUpdateData (PeriodType aPeriodIndex, BranchType aBranchIndex)113 : m Data (QString::null)114 , m PeriodIndex (aPeriodIndex)115 , m BranchIndex (aBranchIndex)114 VBoxUpdateData::VBoxUpdateData(PeriodType periodIndex, BranchType branchIndex) 115 : m_strData(QString()) 116 , m_periodIndex(periodIndex) 117 , m_branchIndex(branchIndex) 116 118 { 117 119 encode(); … … 120 122 bool VBoxUpdateData::isNecessary() 121 123 { 122 return m PeriodIndex != PeriodNever && QDate::currentDate() >= mDate;124 return m_periodIndex != PeriodNever && QDate::currentDate() >= m_date; 123 125 } 124 126 125 127 bool VBoxUpdateData::isNoNeedToCheck() 126 128 { 127 return m PeriodIndex == PeriodNever;129 return m_periodIndex == PeriodNever; 128 130 } 129 131 130 132 QString VBoxUpdateData::data() const 131 133 { 132 return m Data;134 return m_strData; 133 135 } 134 136 135 137 VBoxUpdateData::PeriodType VBoxUpdateData::periodIndex() const 136 138 { 137 return m PeriodIndex;139 return m_periodIndex; 138 140 } 139 141 140 142 QString VBoxUpdateData::date() const 141 143 { 142 return m PeriodIndex == PeriodNever ? VBoxUpdateDlg::tr ("Never") :143 mDate.toString(Qt::LocaleDate);144 return m_periodIndex == PeriodNever ? VBoxUpdateDlg::tr("Never") 145 : m_date.toString(Qt::LocaleDate); 144 146 } 145 147 146 148 VBoxUpdateData::BranchType VBoxUpdateData::branchIndex() const 147 149 { 148 return m BranchIndex;150 return m_branchIndex; 149 151 } 150 152 151 153 QString VBoxUpdateData::branchName() const 152 154 { 153 switch (m BranchIndex)155 switch (m_branchIndex) 154 156 { 155 157 case BranchStable: … … 160 162 return "withbetas"; 161 163 } 162 return QString ::null;164 return QString(); 163 165 } 164 166 165 167 void VBoxUpdateData::decode() 166 168 { 167 /* Parse standard values */168 if (m Data == "never")169 m PeriodIndex = PeriodNever;170 /* Parse other values */169 /* Parse standard values: */ 170 if (m_strData == "never") 171 m_periodIndex = PeriodNever; 172 /* Parse other values: */ 171 173 else 172 174 { 173 QStringList parser (mData.split(", ", QString::SkipEmptyParts));174 175 /* Parse 'period' value */175 QStringList parser(m_strData.split(", ", QString::SkipEmptyParts)); 176 177 /* Parse 'period' value: */ 176 178 if (parser.size() > 0) 177 179 { 178 if (m DayList.isEmpty())180 if (m_dayList.isEmpty()) 179 181 populate(); 180 PeriodType index = (PeriodType) mDayList.indexOf (UpdateDay (QString::null, parser[0]));181 m PeriodIndex = index == PeriodUndefined ? Period1Day : index;182 } 183 184 /* Parse 'date' value */182 PeriodType index = (PeriodType)m_dayList.indexOf(UpdateDay(QString(), parser[0])); 183 m_periodIndex = index == PeriodUndefined ? Period1Day : index; 184 } 185 186 /* Parse 'date' value: */ 185 187 if (parser.size() > 1) 186 188 { 187 QDate date = QDate::fromString (parser[1], Qt::ISODate);188 m Date = date.isValid() ? date : QDate::currentDate();189 } 190 191 /* Parse 'branch' value */189 QDate date = QDate::fromString(parser[1], Qt::ISODate); 190 m_date = date.isValid() ? date : QDate::currentDate(); 191 } 192 193 /* Parse 'branch' value: */ 192 194 if (parser.size() > 2) 193 195 { 194 QString branch (parser[2]);195 m BranchIndex = branch == "withbetas" ? BranchWithBetas :196 branch == "allrelease" ? BranchAllRelease : BranchStable;196 QString branch(parser[2]); 197 m_branchIndex = branch == "withbetas" ? BranchWithBetas : 198 branch == "allrelease" ? BranchAllRelease : BranchStable; 197 199 } 198 200 } … … 201 203 void VBoxUpdateData::encode() 202 204 { 203 /* Encode standard values */204 if (m PeriodIndex == PeriodNever)205 m Data = "never";206 /* Encode other values */205 /* Encode standard values: */ 206 if (m_periodIndex == PeriodNever) 207 m_strData = "never"; 208 /* Encode other values: */ 207 209 else 208 210 { 209 /* Encode 'period' value */210 if (m DayList.isEmpty())211 /* Encode 'period' value: */ 212 if (m_dayList.isEmpty()) 211 213 populate(); 212 QString remindPeriod = m DayList [mPeriodIndex].key;213 214 /* Encode 'date' value */215 m Date = QDate::currentDate();216 QStringList parser (remindPeriod.split(' '));217 if (parser 218 m Date = mDate.addDays (parser[0].toInt());219 else if (parser 220 m Date = mDate.addDays (parser[0].toInt() * 7);221 else if (parser 222 m Date = mDate.addMonths (parser[0].toInt());223 QString remindDate = m Date.toString(Qt::ISODate);224 225 /* Encode 'branch' value */226 QString branchValue = m BranchIndex == BranchWithBetas ? "withbetas" :227 m BranchIndex == BranchAllRelease ? "allrelease" : "stable";228 229 /* Composite m Data*/230 m Data = QString ("%1, %2, %3").arg(remindPeriod, remindDate, branchValue);231 } 232 } 233 234 /* VBoxUpdateDlg stuff */214 QString remindPeriod = m_dayList[m_periodIndex].key; 215 216 /* Encode 'date' value: */ 217 m_date = QDate::currentDate(); 218 QStringList parser(remindPeriod.split(' ')); 219 if (parser[1] == "d") 220 m_date = m_date.addDays(parser[0].toInt()); 221 else if (parser[1] == "w") 222 m_date = m_date.addDays(parser[0].toInt() * 7); 223 else if (parser[1] == "m") 224 m_date = m_date.addMonths(parser[0].toInt()); 225 QString remindDate = m_date.toString(Qt::ISODate); 226 227 /* Encode 'branch' value: */ 228 QString branchValue = m_branchIndex == BranchWithBetas ? "withbetas" : 229 m_branchIndex == BranchAllRelease ? "allrelease" : "stable"; 230 231 /* Composite m_strData: */ 232 m_strData = QString("%1, %2, %3").arg(remindPeriod, remindDate, branchValue); 233 } 234 } 235 236 /* VBoxUpdateDlg stuff: */ 235 237 bool VBoxUpdateDlg::isNecessary() 236 238 { 237 VBoxUpdateData data (vboxGlobal().virtualBox(). 238 GetExtraData (VBoxDefs::GUI_UpdateDate)); 239 239 VBoxUpdateData data(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateDate)); 240 240 return data.isNecessary(); 241 241 } 242 242 243 VBoxUpdateDlg::VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aParent)244 : QIWithRetranslateUI <QDialog> (aParent)245 , m Self (aSelf)246 , m Url ("http://update.virtualbox.org/query.php")247 , m Http (new QIHttp (this))248 , m ForceRun (aForceRun)249 { 250 /* Store external pointer to this dialog .*/251 *m Self = this;252 253 /* Apply UI decorations */254 Ui::VBoxUpdateDlg::setupUi 255 256 /* Apply window icons */257 setWindowIcon(UIIconPool::iconSetFull(QSize (32, 32), QSize(16, 16),243 VBoxUpdateDlg::VBoxUpdateDlg(VBoxUpdateDlg **ppSelf, bool fForceRun, QWidget *pParent) 244 : QIWithRetranslateUI<QDialog>(pParent) 245 , m_ppSelf(ppSelf) 246 , m_pNetworkManager(new QNetworkAccessManager(this)) 247 , m_url("http://update.virtualbox.org/query.php") 248 , m_fForceRun(fForceRun) 249 { 250 /* Store external pointer to this dialog: */ 251 *m_ppSelf = this; 252 253 /* Apply UI decorations: */ 254 Ui::VBoxUpdateDlg::setupUi(this); 255 256 /* Apply window icons: */ 257 setWindowIcon(UIIconPool::iconSetFull(QSize(32, 32), QSize(16, 16), 258 258 ":/refresh_32px.png", ":/refresh_16px.png")); 259 259 260 /* Setup HTTP proxy: */ 261 UIProxyManager proxyManager(vboxGlobal().settings().proxySettings()); 262 if (proxyManager.proxyEnabled()) 263 { 264 mHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(), 265 proxyManager.authEnabled() ? proxyManager.authLogin() : QString(), 266 proxyManager.authEnabled() ? proxyManager.authPassword() : QString()); 267 } 268 /* Set HTTP host: */ 269 mHttp->setHost(mUrl.host()); 270 271 /* Setup other connections */ 272 connect (mBtnCheck, SIGNAL (clicked()), this, SLOT (search())); 273 274 /* Setup initial condition */ 275 mPbCheck->setMinimumWidth (mLogoUpdate->width() + mLogoUpdate->frameWidth() * 2); 260 /* Setup other connections: */ 261 connect(mBtnCheck, SIGNAL(clicked()), this, SLOT(search())); 262 connect(mBtnFinish, SIGNAL(clicked()), this, SLOT(accept())); 263 connect(this, SIGNAL(sigDelayedAcception()), this, SLOT(accept()), Qt::QueuedConnection); 264 265 /* Setup initial condition: */ 266 mPbCheck->setMinimumWidth(mLogoUpdate->width() + mLogoUpdate->frameWidth() * 2); 276 267 mPbCheck->hide(); 277 268 mTextSuccessInfo->hide(); … … 279 270 mTextNotFoundInfo->hide(); 280 271 281 /* Retranslate string constants */272 /* Retranslate string constants: */ 282 273 retranslateUi(); 283 274 } … … 285 276 VBoxUpdateDlg::~VBoxUpdateDlg() 286 277 { 287 /* Erase dialog handle in config file .*/288 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDlgWinID, QString::null);289 290 /* Erase external pointer to this dialog .*/291 *m Self = 0;278 /* Erase dialog handle in config file: */ 279 vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateDlgWinID, QString()); 280 281 /* Erase external pointer to this dialog: */ 282 *m_ppSelf = 0; 292 283 } 293 284 294 285 void VBoxUpdateDlg::retranslateUi() 295 286 { 296 /* Translate uic generated strings */ 297 Ui::VBoxUpdateDlg::retranslateUi (this); 298 299 #if 0 /* All the text constants */ 300 setWindowTitle (tr ("VirtualBox Update Wizard")); 301 302 mPageUpdateHdr->setText (tr ("Check for Updates")); 303 mBtnCheck->setText (tr ("Chec&k")); 304 mBtnCancel->setText (tr ("Cancel")); 305 306 mPageFinishHdr->setText (tr ("Summary")); 307 mBtnFinish->setText (tr ("&Close")); 308 309 mTextUpdateInfo->setText (tr ("<p>This wizard will connect to the VirtualBox " 310 "web-site and check if a newer version of " 311 "VirtualBox is available.</p><p>Use the " 312 "<b>Check</b> button to check for a new version " 313 "now or the <b>Cancel</b> button if you do not " 314 "want to perform this check.</p><p>You can run " 315 "this wizard at any time by choosing <b>Check " 316 "for Updates...</b> from the <b>Help</b> menu.</p>")); 317 318 mTextSuccessInfo->setText (tr ("<p>A new version of VirtualBox has been released! " 319 "Version <b>%1</b> is available at " 320 "<a href=\"http://www.virtualbox.org/\">virtualbox.org</a>.</p>" 321 "<p>You can download this version using the link:</p>" 322 "<p><a href=%2>%3</a></p>")); 323 324 mTextFailureInfo->setText (tr ("<p>Unable to obtain the new version information " 325 "due to the following network error:</p><p><b>%1</b></p>")); 326 327 mTextNotFoundInfo->setText (tr ("You are already running the most recent version of VirtualBox.")); 328 #endif 287 /* Translate uic generated strings: */ 288 Ui::VBoxUpdateDlg::retranslateUi(this); 289 290 /* For wizard update: */ 291 if (!isHidden()) 292 { 293 setWindowTitle(tr("VirtualBox Update Wizard")); 294 295 mPageUpdateHdr->setText(tr("Check for Updates")); 296 mBtnCheck->setText(tr("Chec&k")); 297 mBtnCancel->setText(tr("Cancel")); 298 299 mPageFinishHdr->setText(tr("Summary")); 300 mBtnFinish->setText(tr("&Close")); 301 302 mTextUpdateInfo->setText(tr("<p>This wizard will connect to the VirtualBox " 303 "web-site and check if a newer version of " 304 "VirtualBox is available.</p><p>Use the " 305 "<b>Check</b> button to check for a new version " 306 "now or the <b>Cancel</b> button if you do not " 307 "want to perform this check.</p><p>You can run " 308 "this wizard at any time by choosing <b>Check " 309 "for Updates...</b> from the <b>Help</b> menu.</p>")); 310 311 mTextSuccessInfo->setText(tr("<p>A new version of VirtualBox has been released! " 312 "Version <b>%1</b> is available at " 313 "<a href=\"http://www.virtualbox.org/\">virtualbox.org</a>.</p>" 314 "<p>You can download this version using the link:</p>" 315 "<p><a href=%2>%3</a></p>")); 316 317 mTextFailureInfo->setText(tr("<p>Unable to obtain the new version information " 318 "due to the following network error:</p><p><b>%1</b></p>")); 319 320 mTextNotFoundInfo->setText(tr("You are already running the most recent version of VirtualBox.")); 321 } 329 322 } 330 323 331 324 void VBoxUpdateDlg::accept() 332 325 { 333 /* Recalculate new update data */ 334 VBoxUpdateData oldData (vboxGlobal().virtualBox(). 335 GetExtraData (VBoxDefs::GUI_UpdateDate)); 336 VBoxUpdateData newData (oldData.periodIndex(), oldData.branchIndex()); 337 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDate, 338 newData.data()); 339 326 /* Recalculate new update data: */ 327 VBoxUpdateData oldData(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateDate)); 328 VBoxUpdateData newData(oldData.periodIndex(), oldData.branchIndex()); 329 vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateDate, newData.data()); 330 /* Call to base-class: */ 340 331 QDialog::accept(); 341 332 } … … 343 334 void VBoxUpdateDlg::search() 344 335 { 345 /* Calculate the count of checks left */346 int c ount = 1;347 QString s c = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateCheckCount);348 if (!s c.isEmpty())336 /* Calculate the count of checks left: */ 337 int cCount = 1; 338 QString strCount = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateCheckCount); 339 if (!strCount.isEmpty()) 349 340 { 350 341 bool ok = false; 351 int c = s c.toLongLong(&ok);352 if (ok) c ount = c;353 } 354 355 /* Compose query */356 QUrl url (mUrl);357 url.addQueryItem 342 int c = strCount.toLongLong(&ok); 343 if (ok) cCount = c; 344 } 345 346 /* Compose query: */ 347 QUrl url(m_url); 348 url.addQueryItem("platform", vboxGlobal().virtualBox().GetPackageType()); 358 349 /* Branding: Check whether we have a local branding file which tells us our version suffix "FOO" 359 350 (e.g. 3.06.54321_FOO) to identify this installation */ 360 351 if (vboxGlobal().brandingIsActive()) 361 352 { 362 url.addQueryItem ("version", QString ("%1_%2_%3").arg(vboxGlobal().virtualBox().GetVersion())363 .arg(vboxGlobal().virtualBox().GetRevision())364 .arg(vboxGlobal().brandingGetKey("VerSuffix")));353 url.addQueryItem("version", QString("%1_%2_%3").arg(vboxGlobal().virtualBox().GetVersion()) 354 .arg(vboxGlobal().virtualBox().GetRevision()) 355 .arg(vboxGlobal().brandingGetKey("VerSuffix"))); 365 356 } 366 357 else 367 358 { 368 /* Use hard coded version set by VBOX_VERSION_STRING */369 url.addQueryItem ("version", QString ("%1_%2").arg(vboxGlobal().virtualBox().GetVersion())370 .arg(vboxGlobal().virtualBox().GetRevision()));371 } 372 url.addQueryItem ("count", QString::number (count));373 url.addQueryItem ("branch", VBoxUpdateData(vboxGlobal().virtualBox().374 GetExtraData(VBoxDefs::GUI_UpdateDate)).branchName());375 QString userAgent (QString("VirtualBox %1 <%2>")376 .arg(vboxGlobal().virtualBox().GetVersion())377 .arg(vboxGlobal().platformInfo()));378 379 /* Show progress bar */359 /* Use hard coded version set by VBOX_VERSION_STRING: */ 360 url.addQueryItem("version", QString("%1_%2").arg(vboxGlobal().virtualBox().GetVersion()) 361 .arg(vboxGlobal().virtualBox().GetRevision())); 362 } 363 url.addQueryItem("count", QString::number(cCount)); 364 url.addQueryItem("branch", VBoxUpdateData(vboxGlobal().virtualBox(). 365 GetExtraData(VBoxDefs::GUI_UpdateDate)).branchName()); 366 QString strUserAgent(QString("VirtualBox %1 <%2>") 367 .arg(vboxGlobal().virtualBox().GetVersion()) 368 .arg(vboxGlobal().platformInfo())); 369 370 /* Show progress bar: */ 380 371 mPbCheck->show(); 381 372 382 /* Send composed information */ 383 QHttpRequestHeader header ("POST", url.toEncoded()); 384 header.setValue ("Host", url.host()); 385 header.setValue ("User-Agent", userAgent); 386 mHttp->disconnect (this); 387 connect (mHttp, SIGNAL (allIsDone (bool)), this, SLOT (searchResponse (bool))); 388 mHttp->request (header); 389 } 390 391 void VBoxUpdateDlg::searchResponse (bool aError) 392 { 393 /* Block all the other incoming signals */ 394 mHttp->disconnect (this); 395 396 /* Process error if present */ 397 if (aError) 398 return abortRequest (mHttp->errorString()); 399 400 /* Hide progress bar */ 373 /* Setup GET request: */ 374 QNetworkRequest request; 375 request.setUrl(url); 376 request.setRawHeader("User-Agent", strUserAgent.toAscii()); 377 QNetworkReply *pReply = m_pNetworkManager->get(request); 378 connect(pReply, SIGNAL(finished()), this, SLOT(sltHandleReply())); 379 connect(pReply, SIGNAL(sslErrors(QList<QSslError>)), pReply, SLOT(ignoreSslErrors())); 380 } 381 382 void VBoxUpdateDlg::sltHandleReply() 383 { 384 /* Get corresponding network reply object: */ 385 QNetworkReply *pReply = qobject_cast<QNetworkReply*>(sender()); 386 /* And ask it for suicide: */ 387 pReply->deleteLater(); 388 389 /* Hide progress bar: */ 401 390 mPbCheck->hide(); 402 391 403 /* Parse incoming data */ 404 QString responseData (mHttp->readAll()); 405 406 if (responseData.indexOf (QRegExp ("^\\d+\\.\\d+\\.\\d+ \\S+$")) == 0) 407 { 408 /* Newer version of necessary package found */ 409 QStringList response = responseData.split (" ", QString::SkipEmptyParts); 410 392 /* Handle normal result: */ 393 if (pReply->error() == QNetworkReply::NoError) 394 { 395 /* Deserialize incoming data: */ 396 QString strResponseData(pReply->readAll()); 397 398 /* Newer version of necessary package found: */ 399 if (strResponseData.indexOf(QRegExp("^\\d+\\.\\d+\\.\\d+ \\S+$")) == 0) 400 { 401 QStringList response = strResponseData.split(" ", QString::SkipEmptyParts); 402 403 /* For background update: */ 404 if (isHidden()) 405 { 406 vboxProblem().showUpdateSuccess(vboxGlobal().mainWindow(), response[0], response[1]); 407 acceptLater(); 408 } 409 /* For wizard update: */ 410 else 411 { 412 mTextSuccessInfo->setText(mTextSuccessInfo->text().arg(response[0], response[1], response[1])); 413 mTextSuccessInfo->show(); 414 mPageStack->setCurrentIndex(1); 415 } 416 } 417 /* No newer version of necessary package found: */ 418 else 419 { 420 /* For background update: */ 421 if (isHidden()) 422 { 423 if (m_fForceRun) 424 vboxProblem().showUpdateNotFound(vboxGlobal().mainWindow()); 425 acceptLater(); 426 } 427 /* For wizard update: */ 428 else 429 { 430 mTextNotFoundInfo->show(); 431 mPageStack->setCurrentIndex(1); 432 } 433 } 434 435 /* Save left count of checks: */ 436 int cCount = 1; 437 QString strCount = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_UpdateCheckCount); 438 if (!strCount.isEmpty()) 439 { 440 bool ok = false; 441 int c = strCount.toLongLong(&ok); 442 if (ok) cCount = c; 443 } 444 vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_UpdateCheckCount, QString("%1").arg((qulonglong)cCount + 1)); 445 } 446 /* Handle errors: */ 447 else 448 { 449 /* For background update: */ 411 450 if (isHidden()) 412 451 { 413 /* For background update */414 vboxProblem().showUpdateSuccess (vboxGlobal().mainWindow(),415 response [0], response [1]);416 QTimer::singleShot (0, this, SLOT (accept()));417 }452 if (m_fForceRun) 453 vboxProblem().showUpdateFailure(vboxGlobal().mainWindow(), pReply->errorString()); 454 acceptLater(); 455 } 456 /* For wizard update: */ 418 457 else 419 458 { 420 /* For wizard update */ 421 mTextSuccessInfo->setText (mTextSuccessInfo->text() 422 .arg (response [0], response [1], response [1])); 423 mTextSuccessInfo->show(); 424 mPageStack->setCurrentIndex (1); 425 } 426 } 427 else /* if (responseData == "UPTODATE") */ 428 { 429 /* No newer version of necessary package found */ 430 if (isHidden()) 431 { 432 /* For background update */ 433 if (mForceRun) 434 vboxProblem().showUpdateNotFound (vboxGlobal().mainWindow()); 435 QTimer::singleShot (0, this, SLOT (accept())); 436 } 437 else 438 { 439 /* For wizard update */ 440 mTextNotFoundInfo->show(); 441 mPageStack->setCurrentIndex (1); 442 } 443 } 444 445 /* Save left count of checks */ 446 int count = 1; 447 bool ok = false; 448 QString sc = vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateCheckCount); 449 if (!sc.isEmpty()) 450 count = sc.toLongLong (&ok); 451 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateCheckCount, 452 QString ("%1").arg ((qulonglong) count + 1)); 453 } 454 455 void VBoxUpdateDlg::abortRequest (const QString &aReason) 456 { 457 /* Hide progress bar */ 458 mPbCheck->hide(); 459 460 if (isHidden()) 461 { 462 /* For background update */ 463 if (mForceRun) 464 vboxProblem().showUpdateFailure (vboxGlobal().mainWindow(), aReason); 465 QTimer::singleShot (0, this, SLOT (accept())); 466 } 467 else 468 { 469 /* For wizard update */ 470 mTextFailureInfo->setText (mTextFailureInfo->text().arg (aReason)); 471 mTextFailureInfo->show(); 472 mPageStack->setCurrentIndex (1); 473 } 474 } 475 459 mTextFailureInfo->setText(mTextFailureInfo->text().arg(pReply->errorString())); 460 mTextFailureInfo->show(); 461 mPageStack->setCurrentIndex(1); 462 } 463 } 464 } 465 -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.h
r28800 r38222 6 6 7 7 /* 8 * Copyright (C) 2006-201 0Oracle Corporation8 * Copyright (C) 2006-2011 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #define __VBoxUpdateDlg_h__ 21 21 22 /* Global includes */ 22 /* Global includes: */ 23 #include <QDate> 23 24 #include <QUrl> 24 #include <QDate>25 25 26 26 /* Local includes */ … … 28 28 #include "VBoxUpdateDlg.gen.h" 29 29 30 /* Global forwards*/31 class Q IHttp;30 /* Forward declarations: */ 31 class QNetworkAccessManager; 32 32 33 33 /** … … 36 36 struct UpdateDay 37 37 { 38 UpdateDay (const QString &aVal, const QString &aKey) 39 : val (aVal), key (aKey) {} 38 UpdateDay(const QString &strVal, const QString &strKey) 39 : val(strVal), key(strKey) {} 40 41 bool operator==(const UpdateDay &other) 42 { 43 return val == other.val || key == other.key; 44 } 40 45 41 46 QString val; 42 47 QString key; 43 44 bool operator== (const UpdateDay &aOther)45 {46 return val == aOther.val || key == aOther.key;47 }48 48 }; 49 49 … … 81 81 static QStringList list(); 82 82 83 VBoxUpdateData (const QString &aData);84 VBoxUpdateData (PeriodType aPeriodIndex, BranchType aBranchIndex);83 VBoxUpdateData(const QString &strData); 84 VBoxUpdateData(PeriodType periodIndex, BranchType branchIndex); 85 85 86 86 bool isNecessary(); … … 100 100 101 101 /* Private variables */ 102 static QList <UpdateDay> m DayList;102 static QList <UpdateDay> m_dayList; 103 103 104 QString m Data;105 PeriodType m PeriodIndex;106 QDate m Date;107 BranchType m BranchIndex;104 QString m_strData; 105 PeriodType m_periodIndex; 106 QDate m_date; 107 BranchType m_branchIndex; 108 108 }; 109 109 110 class VBoxUpdateDlg : public QIWithRetranslateUI <QDialog>, 111 public Ui::VBoxUpdateDlg 110 class VBoxUpdateDlg : public QIWithRetranslateUI<QDialog>, public Ui::VBoxUpdateDlg 112 111 { 113 112 Q_OBJECT; … … 117 116 static bool isNecessary(); 118 117 119 VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aParent = 0); 120 ~VBoxUpdateDlg(); 118 VBoxUpdateDlg(VBoxUpdateDlg **ppSelf, bool fForceRun, QWidget *pParent = 0); 119 ~VBoxUpdateDlg(); 120 121 signals: 122 123 void sigDelayedAcception(); 121 124 122 125 public slots: … … 127 130 128 131 void retranslateUi(); 132 void acceptLater() { emit sigDelayedAcception(); } 129 133 130 134 private slots: 131 135 132 136 void accept(); 133 void s earchResponse (bool aError);137 void sltHandleReply(); 134 138 135 139 private: 136 140 137 void abortRequest (const QString &aReason); 138 139 /* Private variables */ 140 VBoxUpdateDlg **mSelf; 141 QUrl mUrl; 142 QIHttp *mHttp; 143 bool mForceRun; 141 VBoxUpdateDlg **m_ppSelf; 142 QNetworkAccessManager *m_pNetworkManager; 143 QUrl m_url; 144 bool m_fForceRun; 144 145 }; 145 146 -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
r37838 r38222 22 22 #include <VBox/version.h> 23 23 24 #include "VBoxUtils.h" 24 25 #include "VBoxDefs.h" 25 26 #include "VBoxSelectorWnd.h" … … 64 65 #include <QHelpEvent> 65 66 #include <QLocale> 67 #include <QNetworkProxy> 66 68 67 69 #ifdef VBOX_GUI_WITH_PIDFILE … … 2447 2449 } 2448 2450 2451 void VBoxGlobal::reloadProxySettings() 2452 { 2453 UIProxyManager proxyManager(settings().proxySettings()); 2454 if (proxyManager.proxyEnabled()) 2455 { 2456 QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, 2457 proxyManager.proxyHost(), 2458 proxyManager.proxyPort().toInt(), 2459 proxyManager.authEnabled() ? proxyManager.authLogin() : QString(), 2460 proxyManager.authEnabled() ? proxyManager.authPassword() : QString())); 2461 } 2462 else 2463 { 2464 QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); 2465 } 2466 } 2467 2449 2468 VBoxDefs::MediumType VBoxGlobal::mediumTypeToLocal(KDeviceType globalType) 2450 2469 { … … 4653 4672 { 4654 4673 loadLanguage(strLang); 4674 } 4675 4676 void VBoxGlobal::sltProcessGlobalSettingChange() 4677 { 4678 /* Reload proxy settings: */ 4679 reloadProxySettings(); 4655 4680 } 4656 4681 … … 5203 5228 * used by some VBox smart widgets, like VBoxMediaComboBox: */ 5204 5229 vboxGlobal().startEnumeratingMedia(); 5230 5231 /* Prepare global settings change handler: */ 5232 connect(&settings(), SIGNAL(propertyChanged(const char*, const char*)), 5233 this, SLOT(sltProcessGlobalSettingChange())); 5234 /* Handle global settings change for the first time: */ 5235 sltProcessGlobalSettingChange(); 5205 5236 } 5206 5237 -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
r37735 r38222 584 584 void startEnumeratingMedia(); 585 585 586 void reloadProxySettings(); 587 586 588 /** 587 589 * Returns a list of all currently registered media. This list is used to … … 767 769 void perDayNewVersionNotifier(); 768 770 void sltGUILanguageChange(QString strLang); 771 void sltProcessGlobalSettingChange(); 769 772 770 773 protected: -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp
r38168 r38222 1707 1707 } 1708 1708 1709 void VBoxProblemReporter::warnAboutAdditionsCantBeSaved(const QString &strTarget) 1710 { 1711 message(mainWindowShown(), Error, 1712 tr("<p>Failed to save the downloaded file as <nobr><b>%1</b>.</nobr></p>") 1713 .arg(QDir::toNativeSeparators(strTarget))); 1714 } 1715 1709 1716 bool VBoxProblemReporter::askAboutUserManualDownload(const QString &strMissedLocation) 1710 1717 { … … 2800 2807 emit sigDownloaderUserManualCreated(); 2801 2808 /* Start the downloader: */ 2802 pDl->start Download();2809 pDl->start(); 2803 2810 } 2804 2811 #endif /* #ifdef VBOX_OSE */ -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h
r37901 r38222 306 306 bool confirmDownloadAdditions (const QString &aURL, ulong aSize); 307 307 bool confirmMountAdditions (const QString &aURL, const QString &aSrc); 308 void warnAboutAdditionsCantBeSaved(const QString &strTarget); 308 309 309 310 bool askAboutUserManualDownload(const QString &strMissedLocation); -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
r37992 r38222 1460 1460 /* After the download is finished the user may like to install the 1461 1461 * additions.*/ 1462 connect(pDl, SIGNAL( downloadFinished(const QString&)),1462 connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), 1463 1463 uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&))); 1464 1464 /* Some of the modes may show additional info of the download progress: */ 1465 1465 emit sigDownloaderAdditionsCreated(); 1466 1466 /* Start the download: */ 1467 pDl->start Download();1467 pDl->start(); 1468 1468 } 1469 1469 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
r37712 r38222 172 172 /* If there is an additions download running show the process bar: */ 173 173 if (UIDownloaderAdditions *pDl = UIDownloaderAdditions::current()) 174 statusBar()->addWidget(pDl->pro cessWidget(this), 0);174 statusBar()->addWidget(pDl->progressWidget(this), 0); 175 175 } 176 176 … … 179 179 /* If there is an additions download running show the process bar: */ 180 180 if (UIDownloaderUserManual *pDl = UIDownloaderUserManual::current()) 181 statusBar()->addWidget(pDl->pro cessWidget(this), 0);181 statusBar()->addWidget(pDl->progressWidget(this), 0); 182 182 } 183 183 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
r38103 r38222 1663 1663 /* If there is User Manual downloader created => show the process bar: */ 1664 1664 if (UIDownloaderUserManual *pDl = UIDownloaderUserManual::current()) 1665 statusBar()->addWidget(pDl->pro cessWidget(this), 0);1665 statusBar()->addWidget(pDl->progressWidget(this), 0); 1666 1666 } 1667 1667 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp
r37544 r38222 18 18 */ 19 19 20 /* Local includes */ 20 /* Global includes: */ 21 #include <QProgressBar> 22 #include <QNetworkReply> 23 24 /* Local includes: */ 21 25 #include "UIDownloader.h" 22 #include "QIHttp.h"23 26 #include "VBoxGlobal.h" 24 27 #include "VBoxProblemReporter.h" … … 26 29 #include "VBoxUtils.h" 27 30 28 /* Global includes */ 29 #include <QFile> 30 #include <QProgressBar> 31 32 UIMiniProcessWidget::UIMiniProcessWidget(QWidget *pParent /* = 0 */) 31 /* UIMiniProgressWidget stuff: */ 32 UIMiniProgressWidget::UIMiniProgressWidget(QWidget *pParent /* = 0 */) 33 33 : QWidget(pParent) 34 34 , m_pProgressBar(new QProgressBar(this)) 35 35 , m_pCancelButton(new UIMiniCancelButton(this)) 36 36 { 37 /* Progress Bar setup*/37 /* Progress-bar setup: */ 38 38 m_pProgressBar->setFixedWidth(100); 39 39 m_pProgressBar->setFormat("%p%"); 40 40 m_pProgressBar->setValue(0); 41 41 42 /* Cancel Button setup*/42 /* Cancel-button setup: */ 43 43 m_pCancelButton->setFocusPolicy(Qt::NoFocus); 44 44 m_pCancelButton->removeBorder(); 45 connect(m_pCancelButton, SIGNAL(clicked()), 46 this, SIGNAL(sigCancel())); 45 connect(m_pCancelButton, SIGNAL(clicked()), this, SIGNAL(sigCancel())); 47 46 48 47 setContentsMargins(0, 0, 0, 0); 49 48 setFixedHeight(16); 50 49 51 /* Layout setup */50 /* Layout setup: */ 52 51 QHBoxLayout *pMainLayout = new QHBoxLayout(this); 53 52 VBoxGlobal::setLayoutMargin(pMainLayout, 0); … … 66 65 67 66 pMainLayout->addStretch(1); 68 69 } 70 71 void UIMiniProcessWidget::setCancelButtonText(const QString &strText) 72 { 73 m_pCancelButton->setText(strText); 74 } 75 76 QString UIMiniProcessWidget::cancelButtonText() const 77 { 78 return m_pCancelButton->text(); 79 } 80 81 void UIMiniProcessWidget::setCancelButtonToolTip(const QString &strText) 67 } 68 69 void UIMiniProgressWidget::setCancelButtonToolTip(const QString &strText) 82 70 { 83 71 m_pCancelButton->setToolTip(strText); 84 72 } 85 73 86 QString UIMiniPro cessWidget::cancelButtonToolTip() const74 QString UIMiniProgressWidget::cancelButtonToolTip() const 87 75 { 88 76 return m_pCancelButton->toolTip(); 89 77 } 90 78 91 void UIMiniPro cessWidget::setProgressBarToolTip(const QString &strText)79 void UIMiniProgressWidget::setProgressBarToolTip(const QString &strText) 92 80 { 93 81 m_pProgressBar->setToolTip(strText); 94 82 } 95 83 96 QString UIMiniPro cessWidget::progressBarToolTip() const84 QString UIMiniProgressWidget::progressBarToolTip() const 97 85 { 98 86 return m_pProgressBar->toolTip(); 99 87 } 100 88 101 void UIMiniPro cessWidget::setSource(const QString &strSource)89 void UIMiniProgressWidget::sltSetSource(const QString &strSource) 102 90 { 103 91 m_strSource = strSource; 104 92 } 105 93 106 QString UIMiniProcessWidget::source() const 107 { 108 return m_strSource; 109 } 110 111 void UIMiniProcessWidget::sltProcess(int cDone, int cTotal) 94 void UIMiniProgressWidget::sltSetProgress(qint64 cDone, qint64 cTotal) 112 95 { 113 96 m_pProgressBar->setMaximum(cTotal); … … 115 98 } 116 99 100 /* UIDownloader stuff: */ 101 UIMiniProgressWidget* UIDownloader::progressWidget(QWidget *pParent) const 102 { 103 /* Create progress widget: */ 104 UIMiniProgressWidget *pWidget = createProgressWidgetFor(pParent); 105 106 /* Connect the signal to notify about progress canceled: */ 107 connect(pWidget, SIGNAL(sigCancel()), this, SLOT(sltCancel())); 108 /* Connect the signal to notify about source changed: */ 109 connect(this, SIGNAL(sigSourceChanged(const QString&)), pWidget, SLOT(sltSetSource(const QString&))); 110 /* Connect the signal to notify about downloading progress: */ 111 connect(this, SIGNAL(sigDownloadProgress(qint64, qint64)), pWidget, SLOT(sltSetProgress(qint64, qint64))); 112 /* Make sure the widget is destroyed when this class is deleted: */ 113 connect(this, SIGNAL(destroyed(QObject*)), pWidget, SLOT(deleteLater())); 114 115 /* Return widget: */ 116 return pWidget; 117 } 118 119 void UIDownloader::start() 120 { 121 startDelayedAcknowledging(); 122 } 123 117 124 UIDownloader::UIDownloader() 118 : m_pHttp(0) 119 { 120 } 121 122 void UIDownloader::setSource(const QString &strSource) 123 { 124 m_source = strSource; 125 } 126 127 QString UIDownloader::source() const 128 { 129 return m_source.toString(); 130 } 131 132 void UIDownloader::setTarget(const QString &strTarget) 133 { 134 m_strTarget = strTarget; 135 } 136 137 QString UIDownloader::target() const 138 { 139 return m_strTarget; 140 } 141 142 void UIDownloader::startDownload() 143 { 144 /* By default we are not using acknowledging step, so 145 * making downloading immediately */ 146 downloadStart(); 147 } 148 149 /* This function is used to start acknowledging mechanism: 150 * checking file presence & size */ 151 void UIDownloader::acknowledgeStart() 152 { 153 /* Recreate HTTP: */ 154 delete m_pHttp; 155 m_pHttp = new QIHttp(this); 156 /* Setup HTTP proxy: */ 157 UIProxyManager proxyManager(vboxGlobal().settings().proxySettings()); 158 if (proxyManager.proxyEnabled()) 125 : m_pNetworkManager(new QNetworkAccessManager(this)) 126 { 127 connect(this, SIGNAL(sigToStartAcknowledging()), this, SLOT(sltStartAcknowledging()), Qt::QueuedConnection); 128 connect(this, SIGNAL(sigToStartDownloading()), this, SLOT(sltStartDownloading()), Qt::QueuedConnection); 129 } 130 131 /* Start acknowledging: */ 132 void UIDownloader::sltStartAcknowledging() 133 { 134 /* Setup HEAD request: */ 135 QNetworkRequest request; 136 request.setUrl(m_source); 137 QNetworkReply *pReply = m_pNetworkManager->head(request); 138 connect(pReply, SIGNAL(sslErrors(QList<QSslError>)), pReply, SLOT(ignoreSslErrors())); 139 connect(pReply, SIGNAL(finished()), this, SLOT(sltFinishAcknowledging())); 140 } 141 142 /* Finish acknowledging: */ 143 void UIDownloader::sltFinishAcknowledging() 144 { 145 /* Get corresponding network reply object: */ 146 QNetworkReply *pReply = qobject_cast<QNetworkReply*>(sender()); 147 /* And ask it for suicide: */ 148 pReply->deleteLater(); 149 150 /* Handle normal reply: */ 151 if (pReply->error() == QNetworkReply::NoError) 152 handleAcknowledgingResult(pReply); 153 /* Handle errors: */ 154 else 155 handleError(pReply); 156 } 157 158 /* Handle acknowledging result: */ 159 void UIDownloader::handleAcknowledgingResult(QNetworkReply *pReply) 160 { 161 /* Check if redirection required: */ 162 QUrl redirect = pReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); 163 if (redirect.isValid()) 159 164 { 160 m_pHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(), 161 proxyManager.authEnabled() ? proxyManager.authLogin() : QString(), 162 proxyManager.authEnabled() ? proxyManager.authPassword() : QString()); 165 /* Set new source: */ 166 UIDownloader::setSource(redirect.toString()); 167 /* Start redirecting: */ 168 startDelayedAcknowledging(); 169 return; 163 170 } 164 /* Set HTTP host: */ 165 m_pHttp->setHost(m_source.host()); 166 /* Setup connections: */ 167 connect(m_pHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), 168 this, SLOT(acknowledgeProcess(const QHttpResponseHeader &))); 169 connect(m_pHttp, SIGNAL(allIsDone(bool)), 170 this, SLOT(acknowledgeFinished(bool))); 171 /* Make a request: */ 172 m_pHttp->get(m_source.toEncoded()); 173 } 174 175 /* This function is used to store content length */ 176 void UIDownloader::acknowledgeProcess(const QHttpResponseHeader & /* response */) 177 { 178 /* Abort connection as we already got all we need */ 179 m_pHttp->abortAll(); 180 } 181 182 /* This function is used to ask the user about if he really want 183 * to download file of proposed size if no error present or 184 * abort download progress if error is present */ 185 void UIDownloader::acknowledgeFinished(bool /* fError */) 186 { 187 m_pHttp->disconnect(this); 188 189 switch (m_pHttp->errorCode()) 171 172 /* Ask for downloading confirmation: */ 173 if (askForDownloadingConfirmation(pReply)) 190 174 { 191 case QIHttp::NoError: /* full packet comes before aborting */ 192 case QIHttp::Aborted: /* part of packet comes before aborting */ 193 { 194 /* Ask the user if he wish to download it */ 195 if (confirmDownload()) 196 QTimer::singleShot(0, this, SLOT(downloadStart())); 197 else 198 QTimer::singleShot(0, this, SLOT(suicide())); 199 break; 200 } 201 case QIHttp::MovedPermanentlyError: 202 case QIHttp::MovedTemporarilyError: 203 { 204 /* Restart downloading at new location */ 205 m_source = m_pHttp->lastResponse().value("location"); 206 QTimer::singleShot(0, this, SLOT(acknowledgeStart())); 207 break; 208 } 209 default: 210 { 211 /* Show error happens during acknowledging */ 212 abortDownload(m_pHttp->errorString()); 213 break; 214 } 175 /* Start downloading: */ 176 startDelayedDownloading(); 177 return; 215 178 } 216 } 217 218 /* This function is used to start downloading mechanism: 219 * downloading and saving the target */ 220 void UIDownloader::downloadStart() 221 { 222 /* Recreate HTTP: */ 223 delete m_pHttp; 224 m_pHttp = new QIHttp(this); 225 /* Setup HTTP proxy: */ 226 UIProxyManager proxyManager(vboxGlobal().settings().proxySettings()); 227 if (proxyManager.proxyEnabled()) 228 { 229 m_pHttp->setProxy(proxyManager.proxyHost(), proxyManager.proxyPort().toInt(), 230 proxyManager.authEnabled() ? proxyManager.authLogin() : QString(), 231 proxyManager.authEnabled() ? proxyManager.authPassword() : QString()); 232 } 233 /* Set HTTP host: */ 234 m_pHttp->setHost(m_source.host()); 235 /* Setup connections: */ 236 connect(m_pHttp, SIGNAL(dataReadProgress (int, int)), 237 this, SLOT (downloadProcess(int, int))); 238 connect(m_pHttp, SIGNAL(allIsDone(bool)), 239 this, SLOT(downloadFinished(bool))); 240 /* Make a request: */ 241 m_pHttp->get(m_source.toEncoded()); 242 } 243 244 /* this function is used to observe the downloading progress through 245 * changing the corresponding qprogressbar value */ 246 void UIDownloader::downloadProcess(int cDone, int cTotal) 247 { 248 emit sigDownloadProcess(cDone, cTotal); 249 } 250 251 /* This function is used to handle the 'downloading finished' issue 252 * through saving the downloaded into the file if there in no error or 253 * notifying the user about error happens */ 254 void UIDownloader::downloadFinished(bool fError) 255 { 256 m_pHttp->disconnect(this); 257 258 if (fError) 259 { 260 /* Show information about error happens */ 261 if (m_pHttp->errorCode() == QIHttp::Aborted) 262 abortDownload(tr("The download process has been canceled by the user.")); 263 else 264 abortDownload(m_pHttp->errorString()); 265 } 179 180 /* Delete downloader: */ 181 deleteLater(); 182 } 183 184 /* Start downloading: */ 185 void UIDownloader::sltStartDownloading() 186 { 187 /* Setup GET request: */ 188 QNetworkRequest request; 189 request.setUrl(m_source); 190 QNetworkReply *pReply = m_pNetworkManager->get(request); 191 connect(pReply, SIGNAL(sslErrors(QList<QSslError>)), pReply, SLOT(ignoreSslErrors())); 192 connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(sigDownloadProgress(qint64, qint64))); 193 connect(pReply, SIGNAL(finished()), this, SLOT(sltFinishDownloading())); 194 } 195 196 /* Finish downloading: */ 197 void UIDownloader::sltFinishDownloading() 198 { 199 /* Get corresponding network reply object: */ 200 QNetworkReply *pReply = qobject_cast<QNetworkReply*>(sender()); 201 /* And ask it for suicide: */ 202 pReply->deleteLater(); 203 204 /* Handle normal reply: */ 205 if (pReply->error() == QNetworkReply::NoError) 206 handleDownloadingResult(pReply); 207 /* Handle errors: */ 266 208 else 267 { 268 /* Trying to serialize the incoming buffer into the target, this is the 269 * default behavior which have to be reimplemented in sub-class */ 270 QFile file(m_strTarget); 271 if (file.open(QIODevice::WriteOnly)) 272 { 273 file.write(m_pHttp->readAll()); 274 file.close(); 275 } 276 QTimer::singleShot(0, this, SLOT(suicide())); 277 } 278 } 279 280 /* This slot is used to process cancel-button clicking */ 281 void UIDownloader::cancelDownloading() 282 { 283 QTimer::singleShot(0, this, SLOT(suicide())); 284 } 285 286 /* This function is used to abort download by showing aborting reason 287 * and calling the downloader's delete function */ 288 void UIDownloader::abortDownload(const QString &strError) 289 { 290 warnAboutError(strError); 291 QTimer::singleShot(0, this, SLOT(suicide())); 292 } 293 294 /* This function is used to delete the downloader widget itself, 295 * should be reimplemented to enhance necessary functionality in sub-class */ 296 void UIDownloader::suicide() 297 { 298 delete this; 299 } 300 209 handleError(pReply); 210 } 211 212 /* Handle downloading result: */ 213 void UIDownloader::handleDownloadingResult(QNetworkReply *pReply) 214 { 215 /* Handle downloaded object: */ 216 handleDownloadedObject(pReply); 217 218 /* Delete downloader: */ 219 deleteLater(); 220 } 221 222 /* Handle simple errors: */ 223 void UIDownloader::handleError(QNetworkReply *pReply) 224 { 225 /* Show error message: */ 226 warnAboutNetworkError(pReply->errorString()); 227 228 /* Delete downloader: */ 229 deleteLater(); 230 } 231 232 /* Cancel-button stuff: */ 233 void UIDownloader::sltCancel() 234 { 235 /* Delete downloader: */ 236 deleteLater(); 237 } 238 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.h
r30356 r38222 6 6 7 7 /* 8 * Copyright (C) 2006-20 07Oracle Corporation8 * Copyright (C) 2006-2011 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #define __UIDownloader_h__ 21 21 22 /* Global includes */ 22 /* Global includes: */ 23 #include <QWidget> 23 24 #include <QUrl> 24 #include <Q Widget>25 #include <QPointer> 25 26 26 /* Local forward declarations*/27 class Q IHttp;27 /* Forward declarations: */ 28 class QProgressBar; 28 29 class UIMiniCancelButton; 30 class QNetworkAccessManager; 31 class QNetworkReply; 29 32 30 /* Global forward declarations */ 31 class QHttpResponseHeader; 32 class QProgressBar; 33 34 class UIMiniProcessWidget : public QWidget 33 /** 34 * The UIMiniProgressWidget class is QWidget class re-implementation which 35 * embeds into the dialog's status-bar and reflects background http downloading. 36 * This class is not supposed to be used itself and made for sub-classing only. 37 */ 38 class UIMiniProgressWidget : public QWidget 35 39 { 36 40 Q_OBJECT; 37 41 38 public:42 signals: 39 43 40 UIMiniProcessWidget(QWidget *pParent = 0); 44 /* Signal to notify listeners about progress canceling: */ 45 void sigCancel(); 41 46 42 void setCancelButtonText(const QString &strText); 43 QString cancelButtonText() const; 47 protected: 44 48 49 /* Constructor: */ 50 UIMiniProgressWidget(QWidget *pParent = 0); 51 52 /* Source stuff: */ 53 QString source() const { return m_strSource; } 54 55 /* Cancel-button stuff: */ 45 56 void setCancelButtonToolTip(const QString &strText); 46 57 QString cancelButtonToolTip() const; 47 58 59 /* Progress-bar stuff: */ 48 60 void setProgressBarToolTip(const QString &strText); 49 61 QString progressBarToolTip() const; 50 62 51 void setSource(const QString &strSource); 52 QString source() const; 63 protected slots: 53 64 54 signals: 65 /* Slot to set source: */ 66 void sltSetSource(const QString &strSource); 55 67 56 void sigCancel(); 57 58 public slots: 59 60 virtual void sltProcess(int cDone, int cTotal); 68 /* Slot to set progress: */ 69 void sltSetProgress(qint64 cDone, qint64 cTotal); 61 70 62 71 private: 63 72 64 /* Private member vars */73 /* Private member vars: */ 65 74 QProgressBar *m_pProgressBar; 66 75 UIMiniCancelButton *m_pCancelButton; 67 68 76 QString m_strSource; 69 77 }; 70 78 71 79 /** 72 * The UIDownloader class is Q Widget class re-implementation which embeds73 * into the Dialog's status-bar andallows background http downloading.80 * The UIDownloader class is QObject class re-implementation which 81 * allows background http downloading. 74 82 * This class is not supposed to be used itself and made for sub-classing only. 75 83 * … … 86 94 public: 87 95 88 UIDownloader(); 96 /* Parent stuff: */ 97 virtual void setParentWidget(QWidget *pParent) { m_pParent = pParent; } 98 virtual QWidget* parentWidget() const { return m_pParent; } 89 99 90 virtual void setSource(const QString &strSource); 91 virtual QString source() const; 92 virtual void setTarget(const QString &strTarget); 93 virtual QString target() const; 100 /* Source stuff: */ 101 virtual void setSource(const QString &strSource) { m_source = strSource; } 102 virtual QString source() const { return m_source.toString(); } 94 103 95 virtual void startDownload() = 0; 104 /* Target stuff: */ 105 virtual void setTarget(const QString &strTarget) { m_strTarget = strTarget; } 106 virtual QString target() const { return m_strTarget; } 107 108 /* Create UIMiniProgressWidget for particular parent: */ 109 UIMiniProgressWidget* progressWidget(QWidget *pParent = 0) const; 110 111 /* Starting stuff: */ 112 virtual void start(); 96 113 97 114 signals: 98 115 99 void sigDownloadProcess(int cDone, int cTotal);100 void sig Finished();116 /* Signal to notify listeners about source-change: */ 117 void sigSourceChanged(const QString &strNewSource); 101 118 102 protected slots: 119 /* Signal to start acknowledging: */ 120 void sigToStartAcknowledging(); 121 /* Signal to start downloading: */ 122 void sigToStartDownloading(); 103 123 104 /* Acknowledging part */ 105 virtual void acknowledgeStart(); 106 virtual void acknowledgeProcess(const QHttpResponseHeader &response); 107 virtual void acknowledgeFinished(bool fError); 108 109 /* Downloading part */ 110 virtual void downloadStart(); 111 virtual void downloadProcess(int cDone, int cTotal); 112 virtual void downloadFinished(bool fError); 113 114 /* Common slots */ 115 virtual void cancelDownloading(); 116 virtual void abortDownload(const QString &strError); 117 virtual void suicide(); 124 /* Notifies about downloading progress: */ 125 void sigDownloadProgress(qint64 cDone, qint64 cTotal); 118 126 119 127 protected: 120 128 121 /* In sub-class this function will show the user downloading object size 122 * and ask him about downloading confirmation. Returns user response. */ 123 virtual bool confirmDownload() = 0; 129 /* Constructor: */ 130 UIDownloader(); 124 131 125 /* In sub-class this function will show the user which error happens 126 * in context of downloading file and executing his request. */ 127 virtual void warnAboutError(const QString &strError) = 0; 132 /* Start delayed acknowledging: */ 133 void startDelayedAcknowledging() { emit sigToStartAcknowledging(); } 134 /* Start delayed downloading: */ 135 void startDelayedDownloading() { emit sigToStartDownloading(); } 128 136 137 /* Handle acknowledging result: */ 138 virtual void handleAcknowledgingResult(QNetworkReply *pReply); 139 /* Handle downloading result: */ 140 virtual void handleDownloadingResult(QNetworkReply *pReply); 141 /* Handle errors: */ 142 virtual void handleError(QNetworkReply *pReply); 143 144 /* Pure virtual function to create UIMiniProgressWidget sub-class: */ 145 virtual UIMiniProgressWidget* createProgressWidgetFor(QWidget *pParent) const = 0; 146 /* Pure virtual function to ask user about downloading confirmation: */ 147 virtual bool askForDownloadingConfirmation(QNetworkReply *pReply) = 0; 148 /* Pure virtual function to handle downloaded object: */ 149 virtual void handleDownloadedObject(QNetworkReply *pReply) = 0; 150 /* Pure virtual function to warn user about issues: */ 151 virtual void warnAboutNetworkError(const QString &strError) = 0; 152 153 private slots: 154 155 /* Acknowledging part: */ 156 void sltStartAcknowledging(); 157 void sltFinishAcknowledging(); 158 159 /* Downloading part: */ 160 void sltStartDownloading(); 161 void sltFinishDownloading(); 162 163 /* Common slots: */ 164 void sltCancel(); 165 166 private: 167 168 /* Private variables: */ 169 QNetworkAccessManager *m_pNetworkManager; 129 170 QUrl m_source; 130 171 QString m_strTarget; 131 Q IHttp *m_pHttp;172 QPointer<QWidget> m_pParent; 132 173 }; 133 174 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp
r28800 r38222 7 7 8 8 /* 9 * Copyright (C) 2006-201 0Oracle Corporation9 * Copyright (C) 2006-2011 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 18 18 */ 19 19 20 /* Local includes */ 21 #include "UIDownloaderAdditions.h" 22 #include "QIFileDialog.h" 23 #include "QIHttp.h" 24 #include "VBoxProblemReporter.h" 25 26 /* Global includes */ 20 /* Global includes: */ 27 21 #include <QAction> 28 22 #include <QDir> 29 23 #include <QFile> 24 #include <QNetworkReply> 25 26 /* Local includes: */ 27 #include "UIDownloaderAdditions.h" 28 #include "QIFileDialog.h" 29 #include "VBoxProblemReporter.h" 30 30 31 UIDownloaderAdditions *UIDownloaderAdditions::m_pInstance = 0; 31 32 … … 34 35 if (!m_pInstance) 35 36 m_pInstance = new UIDownloaderAdditions; 36 37 37 return m_pInstance; 38 38 } … … 41 41 { 42 42 return m_pInstance; 43 }44 45 void UIDownloaderAdditions::destroy()46 {47 if (m_pInstance)48 delete m_pInstance;49 m_pInstance = 0;50 43 } 51 44 … … 62 55 } 63 56 64 void UIDownloaderAdditions::setParentWidget(QWidget *pParent) 57 UIDownloaderAdditions::UIDownloaderAdditions() 58 : UIDownloader() 65 59 { 66 m_pParent = pParent;67 60 } 68 61 69 QWidget *UIDownloaderAdditions::parentWidget() const 62 UIDownloaderAdditions::~UIDownloaderAdditions() 70 63 { 71 return m_pParent; 64 if (m_pAction) 65 m_pAction->setEnabled(true); 66 if (m_pInstance == this) 67 m_pInstance = 0; 72 68 } 73 69 74 UIMiniPro cessWidgetAdditions* UIDownloaderAdditions::processWidget(QWidget *pParent /* = 0 */) const70 UIMiniProgressWidget* UIDownloaderAdditions::createProgressWidgetFor(QWidget *pParent) const 75 71 { 76 UIMiniProcessWidgetAdditions *pWidget = new UIMiniProcessWidgetAdditions(m_source.toString(), pParent); 77 78 /* Connect the cancel signal. */ 79 connect(pWidget, SIGNAL(sigCancel()), 80 this, SLOT(cancelDownloading())); 81 /* Connect the signal to notify about the download process. */ 82 connect(this, SIGNAL(sigDownloadProcess(int, int)), 83 pWidget, SLOT(sltProcess(int, int))); 84 /* Make sure the widget is destroyed when this class is deleted. */ 85 connect(this, SIGNAL(destroyed(QObject*)), 86 pWidget, SLOT(close())); 87 88 return pWidget; 72 return new UIMiniProgressWidgetAdditions(source(), pParent); 89 73 } 90 74 91 void UIDownloaderAdditions::startDownload()75 bool UIDownloaderAdditions::askForDownloadingConfirmation(QNetworkReply *pReply) 92 76 { 93 acknowledgeStart();77 return vboxProblem().confirmDownloadAdditions(source(), pReply->header(QNetworkRequest::ContentLengthHeader).toInt()); 94 78 } 95 79 96 void UIDownloaderAdditions:: downloadFinished(bool fError)80 void UIDownloaderAdditions::handleDownloadedObject(QNetworkReply *pReply) 97 81 { 98 if (fError) 99 UIDownloader::downloadFinished(fError); 100 else 82 /* Read received data: */ 83 QByteArray receivedData(pReply->readAll()); 84 /* Serialize the incoming buffer into the .iso image: */ 85 while (true) 101 86 { 102 QByteArray receivedData(m_pHttp->readAll());103 /* Serialize the incoming buffer into the .iso image. */104 while (true)87 /* Try to open file to save image: */ 88 QFile file(target()); 89 if (file.open(QIODevice::WriteOnly)) 105 90 { 106 QFile file(m_strTarget); 107 if (file.open(QIODevice::WriteOnly)) 108 { 109 file.write(receivedData); 110 file.close(); 111 if (vboxProblem().confirmMountAdditions(m_source.toString(), 112 QDir::toNativeSeparators(m_strTarget))) 113 emit downloadFinished(m_strTarget); 114 QTimer::singleShot(0, this, SLOT(suicide())); 115 break; 116 } 117 else 118 { 119 vboxProblem().message(m_pParent, VBoxProblemReporter::Error, 120 tr("<p>Failed to save the downloaded file as " 121 "<nobr><b>%1</b>.</nobr></p>") 122 .arg(QDir::toNativeSeparators(m_strTarget))); 123 } 91 /* Write received data into the file: */ 92 file.write(receivedData); 93 file.close(); 94 /* Warn user about additions image loaded and saved, propose to mount it: */ 95 if (vboxProblem().confirmMountAdditions(source(), QDir::toNativeSeparators(target()))) 96 emit sigDownloadFinished(target()); 97 break; 98 } 99 else 100 { 101 /* Warn user about additions image loaded but was not saved: */ 102 vboxProblem().warnAboutAdditionsCantBeSaved(target()); 103 } 124 104 125 QString target = QIFileDialog::getExistingDirectory(QFileInfo(m_strTarget).absolutePath(), m_pParent, 126 tr("Select folder to save Guest Additions image to"), true); 127 if (target.isNull()) 128 QTimer::singleShot(0, this, SLOT(suicide())); 129 else 130 m_strTarget = QDir(target).absoluteFilePath(QFileInfo(m_strTarget).fileName()); 131 } 105 /* Ask the user about additions image file save location: */ 106 QString strTarget = QIFileDialog::getExistingDirectory(QFileInfo(target()).absolutePath(), parentWidget(), 107 tr("Select folder to save Guest Additions image to"), true); 108 109 /* Check if user set new target: */ 110 if (!strTarget.isNull()) 111 setTarget(QDir(strTarget).absoluteFilePath(QFileInfo(target()).fileName())); 112 else 113 break; 132 114 } 133 115 } 134 116 135 void UIDownloaderAdditions:: suicide()117 void UIDownloaderAdditions::warnAboutNetworkError(const QString &strError) 136 118 { 137 if (m_pAction) 138 m_pAction->setEnabled(true); 139 UIDownloaderAdditions::destroy(); 119 return vboxProblem().cannotDownloadGuestAdditions(source(), strError); 140 120 } 141 121 142 UIDownloaderAdditions::UIDownloaderAdditions()143 : UIDownloader()144 , m_pAction(0)145 , m_pParent(0)146 {147 }148 149 bool UIDownloaderAdditions::confirmDownload()150 {151 return vboxProblem().confirmDownloadAdditions(m_source.toString(),152 m_pHttp->lastResponse().contentLength());153 }154 155 void UIDownloaderAdditions::warnAboutError(const QString &strError)156 {157 return vboxProblem().cannotDownloadGuestAdditions(m_source.toString(), strError);158 }159 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.h
r28800 r38222 6 6 7 7 /* 8 * Copyright (C) 2006-201 0Oracle Corporation8 * Copyright (C) 2006-2011 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #define __UIDownloaderAdditions_h__ 21 21 22 /* Local includes */22 /* Local includes: */ 23 23 #include "QIWithRetranslateUI.h" 24 24 #include "UIDownloader.h" 25 25 26 /* Global includes */ 27 #include <QPointer> 28 29 class UIMiniProcessWidgetAdditions : public QIWithRetranslateUI<UIMiniProcessWidget> 26 class UIMiniProgressWidgetAdditions : public QIWithRetranslateUI<UIMiniProgressWidget> 30 27 { 31 28 Q_OBJECT; … … 33 30 public: 34 31 35 UIMiniPro cessWidgetAdditions(const QString &strSource, QWidget *pParent = 0)36 : QIWithRetranslateUI<UIMiniProcessWidget>(pParent)32 UIMiniProgressWidgetAdditions(const QString &strSource, QWidget *pParent = 0) 33 : QIWithRetranslateUI<UIMiniProgressWidget>(pParent) 37 34 { 38 s etSource(strSource);35 sltSetSource(strSource); 39 36 retranslateUi(); 40 37 } … … 44 41 void retranslateUi() 45 42 { 46 setCancelButtonText(tr("Cancel")); 47 setCancelButtonToolTip(tr("Cancel the VirtualBox Guest " 48 "Additions CD image download")); 49 setProgressBarToolTip((tr("Downloading the VirtualBox Guest Additions " 50 "CD image from <nobr><b>%1</b>...</nobr>") 51 .arg(source()))); 43 setCancelButtonToolTip(tr("Cancel the VirtualBox Guest Additions CD image download")); 44 setProgressBarToolTip(tr("Downloading the VirtualBox Guest Additions CD image from <nobr><b>%1</b>...</nobr>") 45 .arg(source())); 52 46 } 53 47 }; … … 58 52 59 53 public: 54 60 55 static UIDownloaderAdditions* create(); 61 56 static UIDownloaderAdditions* current(); 62 static void destroy();63 57 64 58 void setAction(QAction *pAction); 65 59 QAction *action() const; 66 60 67 void setParentWidget(QWidget *pParent); 68 QWidget *parentWidget() const; 61 signals: 69 62 70 UIMiniProcessWidgetAdditions* processWidget(QWidget *pParent = 0) const; 71 void startDownload(); 72 73 signals: 74 void downloadFinished(const QString &strFile); 75 76 private slots: 77 78 void downloadFinished(bool fError); 79 void suicide(); 63 void sigDownloadFinished(const QString &strFile); 80 64 81 65 private: 82 66 83 67 UIDownloaderAdditions(); 68 ~UIDownloaderAdditions(); 84 69 85 bool confirmDownload(); 86 void warnAboutError(const QString &strError); 70 UIMiniProgressWidget* createProgressWidgetFor(QWidget *pParent) const; 71 bool askForDownloadingConfirmation(QNetworkReply *pReply); 72 void handleDownloadedObject(QNetworkReply *pReply); 73 void warnAboutNetworkError(const QString &strError); 87 74 88 /* Private member var s*/75 /* Private member variables: */ 89 76 static UIDownloaderAdditions *m_pInstance; 90 77 91 /* We use QPointer here, cause these items could be deleted in the life of 92 * this object. QPointer guarantees that the ptr itself is zero in that 93 * case. */ 78 /* Action to be blocked: */ 94 79 QPointer<QAction> m_pAction; 95 QPointer<QWidget> m_pParent;96 80 }; 97 81 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.cpp
r33540 r38222 7 7 8 8 /* 9 * Copyright (C) 2006-201 0Oracle Corporation9 * Copyright (C) 2006-2011 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 18 18 */ 19 19 20 /* Global includes */20 /* Global includes: */ 21 21 #include <QAction> 22 22 #include <QDir> 23 23 #include <QFile> 24 #include <QNetworkReply> 24 25 25 /* Local includes */26 /* Local includes: */ 26 27 #include "UIDownloaderUserManual.h" 27 28 #include "QIFileDialog.h" 28 #include "QIHttp.h"29 29 #include "VBoxProblemReporter.h" 30 30 … … 43 43 } 44 44 45 void UIDownloaderUserManual::destroy()46 {47 if (m_pInstance)48 delete m_pInstance;49 m_pInstance = 0;50 }51 52 45 void UIDownloaderUserManual::setSource(const QString &strSource) 53 46 { … … 64 57 } 65 58 66 void UIDownloaderUserManual::setParentWidget(QWidget *pParent) 67 { 68 m_pParent = pParent; 69 } 70 71 QWidget* UIDownloaderUserManual::parentWidget() const 72 { 73 return m_pParent; 74 } 75 76 UIMiniProcessWidgetUserManual* UIDownloaderUserManual::processWidget(QWidget *pParent /* = 0 */) const 77 { 78 UIMiniProcessWidgetUserManual *pWidget = new UIMiniProcessWidgetUserManual(pParent); 79 80 /* Connect the cancel signal: */ 81 connect(pWidget, SIGNAL(sigCancel()), this, SLOT(cancelDownloading())); 82 /* Connect the signal to notify about source changed: */ 83 connect(this, SIGNAL(sigSourceChanged(const QString&)), pWidget, SLOT(sltSetSource(const QString&))); 84 /* Connect the signal to notify about the download process: */ 85 connect(this, SIGNAL(sigDownloadProcess(int, int)), pWidget, SLOT(sltProcess(int, int))); 86 /* Make sure the widget is destroyed when this class is deleted: */ 87 connect(this, SIGNAL(destroyed(QObject*)), pWidget, SLOT(close())); 88 89 return pWidget; 90 } 91 92 void UIDownloaderUserManual::startDownload() 59 void UIDownloaderUserManual::start() 93 60 { 94 61 /* If at least one source to try left: */ … … 100 67 emit sigSourceChanged(source()); 101 68 /* Try to download: */ 102 acknowledgeStart();69 startDelayedAcknowledging(); 103 70 } 104 }105 106 void UIDownloaderUserManual::acknowledgeFinished(bool fError)107 {108 /* If current source was wrong but other is present109 * we will try other source else we should finish: */110 if (m_pHttp->errorCode() != QIHttp::Aborted && m_pHttp->errorCode() != QIHttp::NoError && !m_sourcesList.isEmpty())111 startDownload();112 else113 UIDownloader::acknowledgeFinished(fError);114 }115 116 void UIDownloaderUserManual::downloadFinished(bool fError)117 {118 if (fError)119 UIDownloader::downloadFinished(fError);120 else121 {122 /* Read all received data: */123 QByteArray receivedData(m_pHttp->readAll());124 125 /* Serialize the incoming buffer into the User Manual file: */126 while (true)127 {128 /* Try to open file to save document: */129 QFile file(m_strTarget);130 if (file.open(QIODevice::WriteOnly))131 {132 /* Write received data into file: */133 file.write(receivedData);134 file.close();135 /* Warn user about User Manual document loaded and saved: */136 vboxProblem().warnAboutUserManualDownloaded(m_source.toString(), QDir::toNativeSeparators(m_strTarget));137 /* Warn listener about User Manual was downloaded: */138 emit sigDownloadFinished(m_strTarget);139 /* Close the downloader: */140 QTimer::singleShot(0, this, SLOT(suicide()));141 break;142 }143 else144 {145 /* Warn user about User Manual document loaded but was not saved: */146 vboxProblem().warnAboutUserManualCantBeSaved(m_source.toString(), QDir::toNativeSeparators(m_strTarget));147 }148 149 /* Ask the user about User Manual file save location: */150 QString target = QIFileDialog::getExistingDirectory(QFileInfo(m_strTarget).absolutePath(), m_pParent,151 tr("Select folder to save User Manual to"), true);152 /* If user reject to set save point: */153 if (target.isNull())154 /* Just close the downloader: */155 QTimer::singleShot(0, this, SLOT(suicide()));156 /* If user set correct save point: */157 else158 /* Store it and try to save User Manual document there: */159 m_strTarget = QDir(target).absoluteFilePath(QFileInfo(m_strTarget).fileName());160 }161 }162 }163 164 void UIDownloaderUserManual::suicide()165 {166 UIDownloaderUserManual::destroy();167 71 } 168 72 169 73 UIDownloaderUserManual::UIDownloaderUserManual() 170 74 : UIDownloader() 171 , m_pParent(0)172 75 { 173 76 } 174 77 175 bool UIDownloaderUserManual::confirmDownload()78 UIDownloaderUserManual::~UIDownloaderUserManual() 176 79 { 177 return vboxProblem().confirmUserManualDownload(m_source.toString(), m_pHttp->lastResponse().contentLength()); 80 if (m_pInstance == this) 81 m_pInstance = 0; 178 82 } 179 83 180 void UIDownloaderUserManual:: warnAboutError(const QString &strError)84 void UIDownloaderUserManual::handleError(QNetworkReply *pReply) 181 85 { 182 return vboxProblem().warnAboutUserManualCantBeDownloaded(m_source.toString(), strError); 86 /* Check if other sources present: */ 87 if (!m_sourcesList.isEmpty()) 88 { 89 /* Restart acknowledging: */ 90 start(); 91 } 92 else 93 { 94 /* Call for base-class: */ 95 UIDownloader::handleError(pReply); 96 } 183 97 } 184 98 99 UIMiniProgressWidget* UIDownloaderUserManual::createProgressWidgetFor(QWidget *pParent) const 100 { 101 return new UIMiniProcessWidgetUserManual(pParent); 102 } 103 104 bool UIDownloaderUserManual::askForDownloadingConfirmation(QNetworkReply *pReply) 105 { 106 return vboxProblem().confirmUserManualDownload(source(), pReply->header(QNetworkRequest::ContentLengthHeader).toInt()); 107 } 108 109 void UIDownloaderUserManual::handleDownloadedObject(QNetworkReply *pReply) 110 { 111 /* Read received data: */ 112 QByteArray receivedData(pReply->readAll()); 113 /* Serialize the incoming buffer into the User Manual file: */ 114 while (true) 115 { 116 /* Try to open file to save document: */ 117 QFile file(target()); 118 if (file.open(QIODevice::WriteOnly)) 119 { 120 /* Write received data into file: */ 121 file.write(receivedData); 122 file.close(); 123 /* Warn user about User Manual document loaded and saved: */ 124 vboxProblem().warnAboutUserManualDownloaded(source(), QDir::toNativeSeparators(target())); 125 /* Warn listener about User Manual was downloaded: */ 126 emit sigDownloadFinished(target()); 127 break; 128 } 129 else 130 { 131 /* Warn user about User Manual document loaded but was not saved: */ 132 vboxProblem().warnAboutUserManualCantBeSaved(source(), QDir::toNativeSeparators(target())); 133 } 134 135 /* Ask the user about User Manual file save location: */ 136 QString strTarget = QIFileDialog::getExistingDirectory(QFileInfo(target()).absolutePath(), parentWidget(), 137 tr("Select folder to save User Manual to"), true); 138 139 /* Check if user set new target: */ 140 if (!strTarget.isNull()) 141 setTarget(QDir(strTarget).absoluteFilePath(QFileInfo(target()).fileName())); 142 else 143 break; 144 } 145 } 146 147 void UIDownloaderUserManual::warnAboutNetworkError(const QString &strError) 148 { 149 return vboxProblem().warnAboutUserManualCantBeDownloaded(source(), strError); 150 } 151 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderUserManual.h
r28800 r38222 6 6 7 7 /* 8 * Copyright (C) 2010 Oracle Corporation8 * Copyright (C) 2010-2011 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #define __UIDownloaderUserManual_h__ 21 21 22 /* Global includes */ 23 #include <QPointer> 24 25 /* Local includes */ 22 /* Local includes: */ 26 23 #include "QIWithRetranslateUI.h" 27 24 #include "UIDownloader.h" 28 25 29 class UIMiniProcessWidgetUserManual : public QIWithRetranslateUI<UIMiniPro cessWidget>26 class UIMiniProcessWidgetUserManual : public QIWithRetranslateUI<UIMiniProgressWidget> 30 27 { 31 28 Q_OBJECT; … … 34 31 35 32 UIMiniProcessWidgetUserManual(QWidget *pParent = 0) 36 : QIWithRetranslateUI<UIMiniPro cessWidget>(pParent)33 : QIWithRetranslateUI<UIMiniProgressWidget>(pParent) 37 34 { 38 35 retranslateUi(); 39 36 } 40 37 41 pr otectedslots:38 private slots: 42 39 43 40 void sltSetSource(const QString &strSource) 44 41 { 45 setSource(strSource);42 UIMiniProgressWidget::sltSetSource(strSource); 46 43 retranslateUi(); 47 44 } 48 45 49 pr otected:46 private: 50 47 51 48 void retranslateUi() 52 49 { 53 setCancelButtonText(tr("Cancel"));54 50 setCancelButtonToolTip(tr("Cancel the VirtualBox User Manual download")); 55 QString strProgressBarTip =source().isEmpty() ? tr("Downloading the VirtualBox User Manual") :56 tr("Downloading the VirtualBox User Manual <nobr><b>%1</b>...</nobr>").arg(source());57 setProgressBarToolTip(strProgressBarTip);51 setProgressBarToolTip(source().isEmpty() ? tr("Downloading the VirtualBox User Manual") : 52 tr("Downloading the VirtualBox User Manual <nobr><b>%1</b>...</nobr>") 53 .arg(source())); 58 54 } 59 55 }; … … 67 63 static UIDownloaderUserManual* create(); 68 64 static UIDownloaderUserManual* current(); 69 static void destroy();70 65 71 66 void setSource(const QString &strSource); 72 67 void addSource(const QString &strSource); 73 68 74 void setParentWidget(QWidget *pParent); 75 QWidget *parentWidget() const; 76 77 UIMiniProcessWidgetUserManual* processWidget(QWidget *pParent = 0) const; 78 void startDownload(); 69 void start(); 79 70 80 71 signals: … … 83 74 void sigDownloadFinished(const QString &strFile); 84 75 85 private slots:86 87 void acknowledgeFinished(bool fError);88 void downloadFinished(bool fError);89 void suicide();90 91 76 private: 92 77 93 78 UIDownloaderUserManual(); 79 ~UIDownloaderUserManual(); 94 80 95 bool confirmDownload(); 96 void warnAboutError(const QString &strError); 81 void handleError(QNetworkReply *pReply); 82 83 UIMiniProgressWidget* createProgressWidgetFor(QWidget *pParent) const; 84 bool askForDownloadingConfirmation(QNetworkReply *pReply); 85 void handleDownloadedObject(QNetworkReply *pReply); 86 void warnAboutNetworkError(const QString &strError); 97 87 98 88 /* Private member variables: */ 99 89 static UIDownloaderUserManual *m_pInstance; 100 101 /* We use QPointer here, cause these items could be deleted in the life of this object.102 * QPointer guarantees that the ptr itself is zero in that case. */103 QPointer<QWidget> m_pParent;104 90 105 91 /* List of sources to try to download from: */
Note:
See TracChangeset
for help on using the changeset viewer.