File indexing completed on 2024-05-19 04:58:50
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "locationbar.h" 0019 #include "browserwindow.h" 0020 #include "tabbedwebview.h" 0021 #include "mainapplication.h" 0022 #include "webpage.h" 0023 #include "tabwidget.h" 0024 #include "bookmarksicon.h" 0025 #include "bookmarks.h" 0026 #include "bookmarkitem.h" 0027 #include "bookmarkstoolbar.h" 0028 #include "siteicon.h" 0029 #include "goicon.h" 0030 #include "downicon.h" 0031 #include "qztools.h" 0032 #include "iconprovider.h" 0033 #include "qzsettings.h" 0034 #include "colors.h" 0035 #include "autofillicon.h" 0036 #include "completer/locationcompleter.h" 0037 #include "zoomlabel.h" 0038 0039 #include <QTimer> 0040 #include <QMimeData> 0041 #include <QCompleter> 0042 #include <QStringListModel> 0043 #include <QContextMenuEvent> 0044 #include <QStyleOptionFrame> 0045 0046 LocationBar::LocationBar(QWidget *parent) 0047 : LineEdit(parent) 0048 , m_window(nullptr) 0049 , m_webView(nullptr) 0050 , m_holdingAlt(false) 0051 , m_oldTextLength(0) 0052 , m_currentTextLength(0) 0053 , m_loadProgress(0) 0054 , m_progressVisible(false) 0055 { 0056 setObjectName("locationbar"); 0057 setDragEnabled(true); 0058 0059 // Disable KDE QLineEdit transitions, it breaks with setText() && home() 0060 setProperty("_kde_no_animations", QVariant(true)); 0061 0062 m_bookmarkIcon = new BookmarksIcon(this); 0063 m_goIcon = new GoIcon(this); 0064 m_siteIcon = new SiteIcon(this); 0065 m_autofillIcon = new AutoFillIcon(this); 0066 auto* down = new DownIcon(this); 0067 m_zoomlabel = new ZoomLabel(this); 0068 0069 addWidget(m_siteIcon, LineEdit::LeftSide); 0070 addWidget(m_zoomlabel, LineEdit::RightSide); 0071 addWidget(m_autofillIcon, LineEdit::RightSide); 0072 addWidget(m_bookmarkIcon, LineEdit::RightSide); 0073 addWidget(m_goIcon, LineEdit::RightSide); 0074 addWidget(down, LineEdit::RightSide); 0075 0076 m_completer = new LocationCompleter(this); 0077 m_completer->setLocationBar(this); 0078 connect(m_completer, &LocationCompleter::showCompletion, this, &LocationBar::showCompletion); 0079 connect(m_completer, &LocationCompleter::showDomainCompletion, this, &LocationBar::showDomainCompletion); 0080 connect(m_completer, &LocationCompleter::clearCompletion, this, &LocationBar::clearCompletion); 0081 connect(m_completer, &LocationCompleter::loadRequested, this, &LocationBar::loadRequest); 0082 connect(m_completer, &LocationCompleter::popupClosed, this, &LocationBar::updateSiteIcon); 0083 0084 m_domainCompleterModel = new QStringListModel(this); 0085 auto* domainCompleter = new QCompleter(this); 0086 domainCompleter->setCompletionMode(QCompleter::InlineCompletion); 0087 domainCompleter->setModel(m_domainCompleterModel); 0088 setCompleter(domainCompleter); 0089 0090 m_progressTimer = new QTimer(this); 0091 m_progressTimer->setInterval(700); 0092 m_progressTimer->setSingleShot(true); 0093 connect(m_progressTimer, &QTimer::timeout, this, &LocationBar::hideProgress); 0094 0095 editAction(PasteAndGo)->setText(tr("Paste And &Go")); 0096 editAction(PasteAndGo)->setIcon(QIcon::fromTheme(QSL("edit-paste"))); 0097 connect(editAction(PasteAndGo), &QAction::triggered, this, &LocationBar::pasteAndGo); 0098 0099 connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdited(QString))); 0100 connect(m_goIcon, &ClickableLabel::clicked, this, &LocationBar::requestLoadUrl); 0101 connect(down, &ClickableLabel::clicked, m_completer, &LocationCompleter::showMostVisited); 0102 connect(mApp->searchEnginesManager(), &SearchEnginesManager::activeEngineChanged, this, &LocationBar::updatePlaceHolderText); 0103 connect(mApp->searchEnginesManager(), &SearchEnginesManager::defaultEngineChanged, this, &LocationBar::updatePlaceHolderText); 0104 connect(mApp, &MainApplication::settingsReloaded, this, &LocationBar::loadSettings); 0105 0106 loadSettings(); 0107 0108 updateSiteIcon(); 0109 0110 // Hide icons by default 0111 m_goIcon->setVisible(qzSettings->alwaysShowGoIcon); 0112 m_autofillIcon->hide(); 0113 0114 QTimer::singleShot(0, this, &LocationBar::updatePlaceHolderText); 0115 } 0116 0117 BrowserWindow *LocationBar::browserWindow() const 0118 { 0119 return m_window; 0120 } 0121 0122 void LocationBar::setBrowserWindow(BrowserWindow *window) 0123 { 0124 m_window = window; 0125 m_completer->setMainWindow(m_window); 0126 m_siteIcon->setBrowserWindow(m_window); 0127 } 0128 0129 TabbedWebView* LocationBar::webView() const 0130 { 0131 return m_webView; 0132 } 0133 0134 void LocationBar::setWebView(TabbedWebView* view) 0135 { 0136 m_webView = view; 0137 0138 m_bookmarkIcon->setWebView(m_webView); 0139 m_siteIcon->setWebView(m_webView); 0140 m_zoomlabel->setWebView(m_webView); 0141 m_autofillIcon->setWebView(m_webView); 0142 0143 connect(m_webView, &QWebEngineView::loadStarted, this, &LocationBar::loadStarted); 0144 connect(m_webView, &QWebEngineView::loadProgress, this, &LocationBar::loadProgress); 0145 connect(m_webView, &QWebEngineView::loadFinished, this, &LocationBar::loadFinished); 0146 connect(m_webView, &QWebEngineView::urlChanged, this, &LocationBar::showUrl); 0147 connect(m_webView, &WebView::privacyChanged, this, &LocationBar::setPrivacyState); 0148 } 0149 0150 void LocationBar::setText(const QString &text) 0151 { 0152 m_oldTextLength = text.length(); 0153 m_currentTextLength = m_oldTextLength; 0154 0155 LineEdit::setText(text); 0156 0157 refreshTextFormat(); 0158 } 0159 0160 void LocationBar::updatePlaceHolderText() 0161 { 0162 if (qzSettings->searchFromAddressBar) { 0163 setPlaceholderText(tr("Enter address or search with %1").arg(searchEngine().name)); 0164 } else 0165 setPlaceholderText(tr("Enter address")); 0166 } 0167 0168 void LocationBar::showCompletion(const QString &completion, bool completeDomain) 0169 { 0170 LineEdit::setText(completion); 0171 0172 // Move cursor to the end 0173 end(false); 0174 0175 if (completeDomain) { 0176 completer()->complete(); 0177 } 0178 0179 updateSiteIcon(); 0180 } 0181 0182 void LocationBar::clearCompletion() 0183 { 0184 m_webView->setFocus(); 0185 showUrl(m_webView->url()); 0186 } 0187 0188 void LocationBar::showDomainCompletion(const QString &completion) 0189 { 0190 m_domainCompleterModel->setStringList(QStringList() << completion); 0191 0192 // We need to manually force the completion because model is updated asynchronously 0193 // But only force completion when the user actually added new text 0194 if (!completion.isEmpty() && m_oldTextLength < m_currentTextLength) 0195 completer()->complete(); 0196 } 0197 0198 QString LocationBar::convertUrlToText(const QUrl &url) 0199 { 0200 // It was most probably entered by user, so don't urlencode it 0201 // Also don't urlencode JavaScript code 0202 if (url.scheme().isEmpty() || url.scheme() == QL1S("javascript")) { 0203 return QUrl::fromPercentEncoding(url.toEncoded()); 0204 } 0205 0206 QString stringUrl = QzTools::urlEncodeQueryString(url); 0207 0208 if (stringUrl == QL1S("falkon:speeddial") || stringUrl == QL1S("about:blank")) { 0209 stringUrl.clear(); 0210 } 0211 0212 return stringUrl; 0213 } 0214 0215 SearchEnginesManager::Engine LocationBar::searchEngine() 0216 { 0217 if (!qzSettings->searchFromAddressBar) { 0218 return {}; 0219 } else if (qzSettings->searchWithDefaultEngine) { 0220 return mApp->searchEnginesManager()->defaultEngine(); 0221 } else { 0222 return mApp->searchEnginesManager()->activeEngine(); 0223 } 0224 } 0225 0226 LocationBar::LoadAction LocationBar::loadAction(const QString &text) 0227 { 0228 LoadAction action; 0229 0230 const QString &t = text.trimmed(); 0231 0232 if (t.isEmpty()) { 0233 return action; 0234 } 0235 0236 // Check for Search Engine shortcut 0237 const int firstSpacePos = t.indexOf(QLatin1Char(' ')); 0238 if (qzSettings->searchFromAddressBar && firstSpacePos != -1) { 0239 const QString shortcut = t.left(firstSpacePos); 0240 const QString searchedString = t.mid(firstSpacePos).trimmed(); 0241 0242 SearchEngine en = mApp->searchEnginesManager()->engineForShortcut(shortcut); 0243 if (en.isValid()) { 0244 action.type = LoadAction::Search; 0245 action.searchEngine = en; 0246 action.loadRequest = mApp->searchEnginesManager()->searchResult(en, searchedString); 0247 return action; 0248 } 0249 } 0250 0251 // Check for Bookmark keyword 0252 const QList<BookmarkItem*> items = mApp->bookmarks()->searchKeyword(t); 0253 if (!items.isEmpty()) { 0254 BookmarkItem* item = items.at(0); 0255 action.type = LoadAction::Bookmark; 0256 action.bookmark = item; 0257 action.loadRequest.setUrl(item->url()); 0258 return action; 0259 } 0260 0261 if (!qzSettings->searchFromAddressBar) { 0262 const QUrl &guessedUrl = QUrl::fromUserInput(t); 0263 if (guessedUrl.isValid()) { 0264 action.type = LoadAction::Url; 0265 action.loadRequest = guessedUrl; 0266 } 0267 return action; 0268 } 0269 0270 // Check for one word search 0271 if (t != QL1S("localhost") 0272 && !QzTools::containsSpace(t) 0273 && !t.contains(QL1C('.')) 0274 && !t.contains(QL1C(':')) 0275 && !t.contains(QL1C('/')) 0276 ) { 0277 action.type = LoadAction::Search; 0278 action.searchEngine = searchEngine(); 0279 action.loadRequest = mApp->searchEnginesManager()->searchResult(searchEngine(), t); 0280 return action; 0281 } 0282 0283 // Otherwise load as url 0284 const QUrl guessedUrl = QUrl::fromUserInput(t); 0285 if (guessedUrl.isValid()) { 0286 // Always allow javascript: to be loaded 0287 const bool forceLoad = guessedUrl.scheme() == QL1S("javascript"); 0288 // Only allow spaces in query 0289 if (forceLoad || !QzTools::containsSpace(t) || !QzTools::containsSpace(guessedUrl.toString(QUrl::RemoveQuery))) { 0290 // Only allow supported schemes 0291 if (forceLoad || WebPage::supportedSchemes().contains(guessedUrl.scheme())) { 0292 action.type = LoadAction::Url; 0293 action.loadRequest = guessedUrl; 0294 return action; 0295 } 0296 } 0297 } 0298 0299 // Search when creating url failed 0300 action.type = LoadAction::Search; 0301 action.searchEngine = searchEngine(); 0302 action.loadRequest = mApp->searchEnginesManager()->searchResult(searchEngine(), t); 0303 return action; 0304 } 0305 0306 void LocationBar::refreshTextFormat() 0307 { 0308 if (!m_webView) { 0309 return; 0310 } 0311 0312 TextFormat textFormat; 0313 const QString hostName = m_webView->url().isEmpty() ? QUrl(text()).host() : m_webView->url().host(); 0314 0315 if (!hostName.isEmpty()) { 0316 const int hostPos = text().indexOf(hostName); 0317 0318 if (hostPos > 0) { 0319 QTextCharFormat format; 0320 format.setForeground(Colors::mid(palette().color(QPalette::Base), palette().color(QPalette::Text), 1, 1)); 0321 0322 QTextLayout::FormatRange schemePart; 0323 schemePart.start = 0; 0324 schemePart.length = hostPos; 0325 schemePart.format = format; 0326 0327 QTextLayout::FormatRange hostPart; 0328 hostPart.start = hostPos; 0329 hostPart.length = hostName.size(); 0330 0331 QTextLayout::FormatRange remainingPart; 0332 remainingPart.start = hostPos + hostName.size(); 0333 remainingPart.length = text().size() - remainingPart.start; 0334 remainingPart.format = format; 0335 0336 textFormat.append(schemePart); 0337 textFormat.append(hostPart); 0338 textFormat.append(remainingPart); 0339 } 0340 } 0341 0342 setTextFormat(textFormat); 0343 } 0344 0345 void LocationBar::requestLoadUrl() 0346 { 0347 loadRequest(loadAction(text()).loadRequest); 0348 updateSiteIcon(); 0349 } 0350 0351 void LocationBar::textEdited(const QString &text) 0352 { 0353 m_oldTextLength = m_currentTextLength; 0354 m_currentTextLength = text.length(); 0355 0356 if (!text.isEmpty()) { 0357 m_completer->complete(text); 0358 m_siteIcon->setIcon(QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg")))); 0359 } 0360 else { 0361 m_completer->closePopup(); 0362 } 0363 0364 setGoIconVisible(true); 0365 } 0366 0367 void LocationBar::setGoIconVisible(bool state) 0368 { 0369 if (state) { 0370 m_bookmarkIcon->hide(); 0371 m_zoomlabel->hide(); 0372 m_goIcon->show(); 0373 } 0374 else { 0375 m_bookmarkIcon->show(); 0376 m_zoomlabel->requestShow(); 0377 0378 if (!qzSettings->alwaysShowGoIcon) { 0379 m_goIcon->hide(); 0380 } 0381 } 0382 0383 updateTextMargins(); 0384 } 0385 0386 void LocationBar::showUrl(const QUrl &url) 0387 { 0388 if (hasFocus() || url.isEmpty()) { 0389 return; 0390 } 0391 0392 const QString stringUrl = convertUrlToText(url); 0393 0394 if (text() == stringUrl) { 0395 home(false); 0396 refreshTextFormat(); 0397 return; 0398 } 0399 0400 // Set converted url as text 0401 setText(stringUrl); 0402 0403 // Move cursor to the start 0404 home(false); 0405 0406 m_bookmarkIcon->checkBookmark(url); 0407 } 0408 0409 void LocationBar::loadRequest(const LoadRequest &request) 0410 { 0411 if (!m_webView->webTab()->isRestored()) { 0412 return; 0413 } 0414 0415 const QString urlString = convertUrlToText(request.url()); 0416 0417 m_completer->closePopup(); 0418 m_webView->setFocus(); 0419 0420 if (urlString != text()) { 0421 setText(urlString); 0422 } 0423 0424 m_webView->userLoadAction(request); 0425 } 0426 0427 void LocationBar::updateSiteIcon() 0428 { 0429 if (m_completer->isVisible()) { 0430 m_siteIcon->setIcon(QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg")))); 0431 } else { 0432 QIcon icon = IconProvider::emptyWebIcon(); 0433 if (property("secured").toBool()) { 0434 icon = QIcon::fromTheme(QSL("document-encrypted"), icon); 0435 } 0436 m_siteIcon->setIcon(QIcon(icon.pixmap(16))); 0437 } 0438 } 0439 0440 void LocationBar::setPrivacyState(bool state) 0441 { 0442 m_siteIcon->setProperty("secured", QVariant(state)); 0443 m_siteIcon->style()->unpolish(m_siteIcon); 0444 m_siteIcon->style()->polish(m_siteIcon); 0445 0446 setProperty("secured", QVariant(state)); 0447 style()->unpolish(this); 0448 style()->polish(this); 0449 0450 updateSiteIcon(); 0451 } 0452 0453 void LocationBar::pasteAndGo() 0454 { 0455 clear(); 0456 paste(); 0457 requestLoadUrl(); 0458 } 0459 0460 void LocationBar::contextMenuEvent(QContextMenuEvent* event) 0461 { 0462 QMenu* menu = createContextMenu(); 0463 menu->setAttribute(Qt::WA_DeleteOnClose); 0464 0465 // Prevent choosing first option with double rightclick 0466 QPoint pos = event->globalPos(); 0467 pos.setY(pos.y() + 1); 0468 menu->popup(pos); 0469 } 0470 0471 void LocationBar::showEvent(QShowEvent* event) 0472 { 0473 LineEdit::showEvent(event); 0474 0475 refreshTextFormat(); 0476 } 0477 0478 void LocationBar::focusInEvent(QFocusEvent* event) 0479 { 0480 if (m_webView) { 0481 const QString stringUrl = convertUrlToText(m_webView->url()); 0482 0483 // Text has been edited, let's show go button 0484 if (stringUrl != text()) { 0485 setGoIconVisible(true); 0486 } 0487 } 0488 0489 clearTextFormat(); 0490 LineEdit::focusInEvent(event); 0491 0492 if (m_window && Settings().value(QSL("Browser-View-Settings/instantBookmarksToolbar")).toBool()) { 0493 m_window->bookmarksToolbar()->show(); 0494 } 0495 } 0496 0497 void LocationBar::focusOutEvent(QFocusEvent* event) 0498 { 0499 // Context menu or completer popup were opened 0500 // Let's block focusOutEvent to trick QLineEdit and paint cursor properly 0501 if (event->reason() == Qt::PopupFocusReason) { 0502 return; 0503 } 0504 0505 LineEdit::focusOutEvent(event); 0506 0507 setGoIconVisible(false); 0508 0509 if (text().trimmed().isEmpty()) { 0510 clear(); 0511 } 0512 0513 refreshTextFormat(); 0514 0515 if (m_window && Settings().value(QSL("Browser-View-Settings/instantBookmarksToolbar")).toBool()) { 0516 m_window->bookmarksToolbar()->hide(); 0517 } 0518 } 0519 0520 void LocationBar::dropEvent(QDropEvent* event) 0521 { 0522 if (event->mimeData()->hasUrls()) { 0523 const QUrl dropUrl = event->mimeData()->urls().at(0); 0524 if (WebView::isUrlValid(dropUrl)) { 0525 setText(dropUrl.toString()); 0526 loadRequest(dropUrl); 0527 0528 QFocusEvent event(QFocusEvent::FocusOut); 0529 LineEdit::focusOutEvent(&event); 0530 return; 0531 } 0532 } 0533 else if (event->mimeData()->hasText()) { 0534 const QString dropText = event->mimeData()->text().trimmed(); 0535 const QUrl dropUrl = QUrl(dropText); 0536 if (WebView::isUrlValid(dropUrl)) { 0537 setText(dropUrl.toString()); 0538 loadRequest(dropUrl); 0539 0540 QFocusEvent event(QFocusEvent::FocusOut); 0541 LineEdit::focusOutEvent(&event); 0542 return; 0543 } else { 0544 setText(dropText); 0545 setFocus(); 0546 return; 0547 } 0548 } 0549 0550 LineEdit::dropEvent(event); 0551 } 0552 0553 void LocationBar::keyPressEvent(QKeyEvent* event) 0554 { 0555 switch (event->key()) { 0556 case Qt::Key_V: 0557 if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { 0558 pasteAndGo(); 0559 event->accept(); 0560 return; 0561 } 0562 break; 0563 0564 case Qt::Key_Down: 0565 m_completer->complete(text()); 0566 break; 0567 0568 case Qt::Key_Left: 0569 m_completer->closePopup(); 0570 break; 0571 0572 case Qt::Key_Escape: 0573 m_webView->setFocus(); 0574 showUrl(m_webView->url()); 0575 event->accept(); 0576 break; 0577 0578 case Qt::Key_Alt: 0579 m_holdingAlt = true; 0580 break; 0581 0582 case Qt::Key_Return: 0583 case Qt::Key_Enter: 0584 switch (event->modifiers()) { 0585 case Qt::ControlModifier: 0586 if (!text().endsWith(QL1S(".com"))) 0587 setText(text().append(QL1S(".com"))); 0588 requestLoadUrl(); 0589 m_holdingAlt = false; 0590 break; 0591 0592 case Qt::AltModifier: 0593 m_completer->closePopup(); 0594 if (m_window) { 0595 m_window->tabWidget()->addView(loadAction(text()).loadRequest); 0596 } 0597 m_holdingAlt = false; 0598 break; 0599 0600 default: 0601 requestLoadUrl(); 0602 m_holdingAlt = false; 0603 } 0604 0605 break; 0606 0607 case Qt::Key_0: 0608 case Qt::Key_1: 0609 case Qt::Key_2: 0610 case Qt::Key_3: 0611 case Qt::Key_4: 0612 case Qt::Key_5: 0613 case Qt::Key_6: 0614 case Qt::Key_7: 0615 case Qt::Key_8: 0616 case Qt::Key_9: 0617 if (event->modifiers() & Qt::AltModifier || event->modifiers() & Qt::ControlModifier) { 0618 event->ignore(); 0619 m_holdingAlt = false; 0620 return; 0621 } 0622 break; 0623 0624 default: 0625 m_holdingAlt = false; 0626 } 0627 0628 LineEdit::keyPressEvent(event); 0629 } 0630 0631 void LocationBar::loadStarted() 0632 { 0633 m_progressVisible = true; 0634 m_progressTimer->stop(); 0635 m_autofillIcon->hide(); 0636 } 0637 0638 void LocationBar::loadProgress(int progress) 0639 { 0640 if (qzSettings->showLoadingProgress) { 0641 m_loadProgress = progress; 0642 update(); 0643 } 0644 } 0645 0646 void LocationBar::loadFinished() 0647 { 0648 if (qzSettings->showLoadingProgress) { 0649 m_progressTimer->start(); 0650 } 0651 0652 auto* page = qobject_cast<WebPage*>(m_webView->page()); 0653 0654 if (page && !page->autoFillUsernames().isEmpty()) { 0655 m_autofillIcon->setUsernames(page->autoFillUsernames()); 0656 m_autofillIcon->show(); 0657 } 0658 } 0659 0660 void LocationBar::loadSettings() 0661 { 0662 Settings settings; 0663 settings.beginGroup(QSL("AddressBar")); 0664 m_progressStyle = static_cast<ProgressStyle>(settings.value(QSL("ProgressStyle"), 0).toInt()); 0665 bool customColor = settings.value(QSL("UseCustomProgressColor"), false).toBool(); 0666 m_progressColor = customColor ? settings.value(QSL("CustomProgressColor"), palette().color(QPalette::Highlight)).value<QColor>() : QColor(); 0667 settings.endGroup(); 0668 } 0669 0670 void LocationBar::hideProgress() 0671 { 0672 if (qzSettings->showLoadingProgress) { 0673 m_progressVisible = false; 0674 update(); 0675 } 0676 } 0677 0678 void LocationBar::paintEvent(QPaintEvent* event) 0679 { 0680 LineEdit::paintEvent(event); 0681 0682 // Show loading progress 0683 if (qzSettings->showLoadingProgress && m_progressVisible) { 0684 QStyleOptionFrame option; 0685 initStyleOption(&option); 0686 0687 QMargins margins = textMargins(); 0688 0689 QRect contentsRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this); 0690 contentsRect.adjust( 0691 margins.left(), margins.top(), -margins.right(), -margins.bottom() 0692 ); 0693 0694 QColor bg = m_progressColor; 0695 if (!bg.isValid() || bg.alpha() == 0) { 0696 bg = Colors::mid(palette().color(QPalette::Base), palette().color(QPalette::Text), m_progressStyle > 0 ? 4 : 8, 1); 0697 } 0698 0699 QPainter p(this); 0700 p.setBrush(QBrush(bg)); 0701 0702 // We are painting over text, make sure the text stays visible 0703 p.setOpacity(0.5); 0704 0705 QPen outlinePen(bg.darker(110), 0.8); 0706 p.setPen(outlinePen); 0707 0708 switch (m_progressStyle) { 0709 case ProgressFilled: { 0710 QRect bar = contentsRect.adjusted(0, 1, 0, -1); 0711 bar.setWidth(bar.width() * m_loadProgress / 100); 0712 const int roundness = bar.height() / 4.0; 0713 p.drawRoundedRect(bar, roundness, roundness); 0714 break; 0715 } 0716 case ProgressBottom: { 0717 outlinePen.setWidthF(0.3); 0718 outlinePen.setColor(outlinePen.color().darker(130)); 0719 p.setPen(outlinePen); 0720 QRect bar(contentsRect.x(), contentsRect.bottom() - 3, 0721 contentsRect.width() * m_loadProgress / 100.0, 3); 0722 p.drawRoundedRect(bar, 1, 1); 0723 break; 0724 } 0725 case ProgressTop: { 0726 outlinePen.setWidthF(0.3); 0727 outlinePen.setColor(outlinePen.color().darker(130)); 0728 p.setPen(outlinePen); 0729 QRect bar(contentsRect.x(), contentsRect.top() + 1, contentsRect.width() * m_loadProgress / 100.0, 3); 0730 p.drawRoundedRect(bar, 1, 1); 0731 break; 0732 } 0733 default: 0734 break; 0735 } 0736 } 0737 }