diff --git a/src/lib/lib.pro b/src/lib/lib.pro index 2470b59aa..82845f854 100644 --- a/src/lib/lib.pro +++ b/src/lib/lib.pro @@ -89,6 +89,7 @@ SOURCES += \ preferences/sslmanager.cpp \ tools/animatedwidget.cpp \ tools/htmlhighlighter.cpp \ + tools/colors.cpp \ other/sourceviewersearch.cpp \ adblock/adblocksubscription.cpp \ adblock/adblockrule.cpp \ diff --git a/src/lib/navigation/locationbar.cpp b/src/lib/navigation/locationbar.cpp index 549b13f2b..d0be11651 100644 --- a/src/lib/navigation/locationbar.cpp +++ b/src/lib/navigation/locationbar.cpp @@ -38,10 +38,12 @@ #include "globalfunctions.h" #include "iconprovider.h" #include "qzsettings.h" +#include "colors.h" #include #include #include +#include LocationBar::LocationBar(QupZilla* mainClass) : LineEdit(mainClass) @@ -52,7 +54,7 @@ LocationBar::LocationBar(QupZilla* mainClass) , m_clearAction(0) , m_holdingAlt(false) , m_loadProgress(0) - , m_loadFinished(true) + , m_progressVisible(false) { setObjectName("locationbar"); setDragEnabled(true); @@ -87,6 +89,9 @@ LocationBar::LocationBar(QupZilla* mainClass) connect(m_bookmarkIcon, SIGNAL(clicked(QPoint)), this, SLOT(bookmarkIconClicked())); connect(down, SIGNAL(clicked(QPoint)), this, SLOT(showMostVisited())); connect(mApp->searchEnginesManager(), SIGNAL(activeEngineChanged()), this, SLOT(updatePlaceHolderText())); + connect(mApp, SIGNAL(message(Qz::AppMessageType, bool)), SLOT(onMessage(Qz::AppMessageType, bool))); + + loadSettings(); clearIcon(); updatePlaceHolderText(); @@ -96,6 +101,7 @@ void LocationBar::setWebView(TabbedWebView* view) { m_webView = view; + connect(m_webView, SIGNAL(loadStarted()), SLOT(onLoadStarted())); connect(m_webView, SIGNAL(loadProgress(int)), SLOT(onLoadProgress(int))); connect(m_webView, SIGNAL(loadFinished(bool)), SLOT(onLoadFinished())); } @@ -528,34 +534,59 @@ LocationBar::~LocationBar() delete m_bookmarkIcon; } +void LocationBar::onLoadStarted() +{ + m_progressVisible = true; +} + void LocationBar::onLoadProgress(int progress) { if (qzSettings->showLoadingProgress) { - m_loadFinished = false; m_loadProgress = progress; - repaint(); + update(); } } void LocationBar::onLoadFinished() { if (qzSettings->showLoadingProgress) { - m_loadFinished = false; QTimer::singleShot(700, this, SLOT(hideProgress())); } } +void LocationBar::loadSettings() +{ + Settings settings; + settings.beginGroup("AddressBar"); + m_progressStyle = static_cast(settings.value("ProgressStyle", 0).toInt()); + bool customColor = settings.value("UseCustomProgressColor", false).toBool(); + m_progressColor = customColor ? settings.value("CustomProgressColor", palette().color(QPalette::Highlight)).value() : QColor(); + settings.endGroup(); +} + +void LocationBar::onMessage(Qz::AppMessageType msg, bool state) +{ + Q_UNUSED(state) + if (!qzSettings->showLoadingProgress) { + return; + } + + if (msg == Qz::AM_ReloadSettings) { + loadSettings(); + } +} + void LocationBar::hideProgress() { if (qzSettings->showLoadingProgress) { - m_loadFinished = true; - repaint(); + m_progressVisible = false; + update(); } } void LocationBar::paintEvent(QPaintEvent* event) { - if (hasFocus() || !qzSettings->showLoadingProgress || m_loadFinished) { + if (hasFocus() || text().isEmpty()) { LineEdit::paintEvent(event); return; } @@ -580,22 +611,84 @@ void LocationBar::paintEvent(QPaintEvent* event) const int height = fm.height(); QRect textRect(x, y, width, height); - QColor bg = palette().color(QPalette::Base); - if (!bg.isValid() || bg.alpha() == 0) { - bg = p_QupZilla->palette().color(QPalette::Base); - } - bg = bg.darker(110); - p.setBrush(QBrush(bg)); - QPen oldPen = p.pen(); - QPen outlinePen(bg.darker(110), 0.8); - p.setPen(outlinePen); - QRect bar = textRect.adjusted(-3, 0, 6 - (textRect.width() * (100.0 - m_loadProgress) / 100), 0); - const int roundness = bar.height() / 4.0; - p.drawRoundedRect(bar, roundness, roundness); + if (qzSettings->showLoadingProgress && m_progressVisible) { + QColor bg = m_progressColor; + if (!bg.isValid() || bg.alpha() == 0) { + bg = Colors::mid(palette().color(QPalette::Base), + palette().color(QPalette::Text), + 10, 1); + } + p.setBrush(QBrush(bg)); + + QPen outlinePen(bg.darker(110), 0.8); + p.setPen(outlinePen); + + switch (m_progressStyle) { + case ProgressFilled: { + QRect bar = textRect.adjusted(-3, 0, 6 - (textRect.width() * (100.0 - m_loadProgress) / 100), 0); + const int roundness = bar.height() / 4.0; + p.drawRoundedRect(bar, roundness, roundness); + break; + } + case ProgressBottom: { + outlinePen.setWidthF(0.3); + outlinePen.setColor(outlinePen.color().darker(130)); + p.setPen(outlinePen); + QRect bar(contentsRect.x(), contentsRect.bottom() - 2, + contentsRect.width()*m_loadProgress / 100.0, 3); + p.drawRoundedRect(bar, 1, 1); + break; + } + case ProgressTop: { + outlinePen.setWidthF(0.3); + outlinePen.setColor(outlinePen.color().darker(130)); + p.setPen(outlinePen); + QRect bar(contentsRect.x(), contentsRect.top() + 1, + contentsRect.width()*m_loadProgress / 100.0, 3); + p.drawRoundedRect(bar, 1, 1); + break; + } + default: + break; + } + } p.setPen(oldPen); -// Qt::Alignment va = QStyle::visualAlignment(QApplication::layoutDirection(), QFlag(alignment())); - p.drawText(textRect, text()); + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + + const QString hostName = m_webView->url().host(); + QString currentText = text(); + QRect currentRect = textRect; + if (!hostName.isEmpty()) { + const int hostPos = currentText.indexOf(hostName); + if (hostPos > 0) { + QPen lightPen = oldPen; + QColor lightColor = Colors::mid(palette().color(QPalette::Base), + palette().color(QPalette::Text), + 1, 1); + lightPen.setColor(lightColor); + + p.setPen(lightPen); + currentText = text().mid(0, hostPos); + currentRect.setWidth(fm.width(currentText)); + p.drawText(currentRect, currentText, opt); + + p.setPen(oldPen); + currentRect.setX(currentRect.x() + currentRect.width()); + const int hostWidth = fm.width(hostName); + currentRect.setWidth(hostWidth); + p.drawText(currentRect, hostName, opt); + + p.setFont(font()); + currentText = text().mid(hostPos + hostName.length()); + currentRect.setX(currentRect.x() + hostWidth); + currentRect.setWidth(textRect.width() - currentRect.x() + textRect.x()); + p.setPen(lightPen); + } + } + + p.drawText(currentRect, currentText, opt); } diff --git a/src/lib/navigation/locationbar.h b/src/lib/navigation/locationbar.h index c1cd07b73..a6c16b271 100644 --- a/src/lib/navigation/locationbar.h +++ b/src/lib/navigation/locationbar.h @@ -74,11 +74,20 @@ private slots: void updatePlaceHolderText(); void showCompletion(const QString &newText); + void onLoadStarted(); void onLoadProgress(int progress); void onLoadFinished(); void hideProgress(); + void onMessage(Qz::AppMessageType, bool); + private: + enum ProgressStyle { + ProgressFilled, + ProgressBottom, + ProgressTop + }; + void contextMenuEvent(QContextMenuEvent* event); void focusInEvent(QFocusEvent* event); void focusOutEvent(QFocusEvent* event); @@ -94,6 +103,8 @@ private: void showGoButton(); void hideGoButton(); + void loadSettings(); + LocationCompleter m_completer; BookmarkIcon* m_bookmarkIcon; @@ -112,7 +123,9 @@ private: bool m_holdingAlt; int m_loadProgress; - bool m_loadFinished; + bool m_progressVisible; + ProgressStyle m_progressStyle; + QColor m_progressColor; }; #endif // LOCATIONBAR_H diff --git a/src/lib/preferences/preferences.cpp b/src/lib/preferences/preferences.cpp index 18bd71aca..e3524ac83 100644 --- a/src/lib/preferences/preferences.cpp +++ b/src/lib/preferences/preferences.cpp @@ -49,6 +49,7 @@ #include #include #include +#include Preferences::Preferences(QupZilla* mainClass, QWidget* parent) : QDialog(parent) @@ -185,7 +186,17 @@ Preferences::Preferences(QupZilla* mainClass, QWidget* parent) ui->selectAllOnFocus->setChecked(settings.value("SelectAllTextOnDoubleClick", true).toBool()); ui->selectAllOnClick->setChecked(settings.value("SelectAllTextOnClick", false).toBool()); ui->addCountryWithAlt->setChecked(settings.value("AddCountryDomainWithAltKey", true).toBool()); - ui->showLoadingInAddressBar->setChecked(settings.value("ShowLoadingProgress", false).toBool()); + bool showPBinAB = settings.value("ShowLoadingProgress", false).toBool(); + ui->showLoadingInAddressBar->setChecked(showPBinAB); + ui->adressProgressSettings->setEnabled(showPBinAB); + ui->progressStyleSelector->setCurrentIndex(settings.value("ProgressStyle", 0).toInt()); + bool pbInABuseCC = settings.value("UseCustomProgressColor", false).toBool(); + ui->checkBoxCustomProgressColor->setChecked(pbInABuseCC); + ui->progressBarColorSelector->setEnabled(pbInABuseCC); + QColor pbColor = settings.value("CustomProgressColor", p_QupZilla->palette().color(QPalette::Highlight)).value(); + setProgressBarColorIcon(pbColor); + connect(ui->customColorToolButton, SIGNAL(clicked(bool)), SLOT(selectCustomProgressBarColor())); + connect(ui->setProgressBarColorToHighlightButton, SIGNAL(clicked()), SLOT(setProgressBarColorIcon())); settings.endGroup(); //BROWSING @@ -870,6 +881,9 @@ void Preferences::saveSettings() settings.setValue("SelectAllTextOnClick", ui->selectAllOnClick->isChecked()); settings.setValue("AddCountryDomainWithAltKey", ui->addCountryWithAlt->isChecked()); settings.setValue("ShowLoadingProgress", ui->showLoadingInAddressBar->isChecked()); + settings.setValue("ProgressStyle", ui->progressStyleSelector->currentIndex()); + settings.setValue("UseCustomProgressColor", ui->checkBoxCustomProgressColor->isChecked()); + settings.setValue("CustomProgressColor", ui->customColorToolButton->property("ProgressColor").value()); settings.endGroup(); //Languages @@ -936,3 +950,23 @@ Preferences::~Preferences() delete m_pluginsList; delete m_notification.data(); } + +void Preferences::setProgressBarColorIcon(QColor color) +{ + const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); + QPixmap pm(QSize(size, size)); + if (!color.isValid()) { + color = p_QupZilla->palette().color(QPalette::Highlight); + } + pm.fill(color); + ui->customColorToolButton->setIcon(pm); + ui->customColorToolButton->setProperty("ProgressColor", color); +} + +void Preferences::selectCustomProgressBarColor() +{ + QColor newColor = QColorDialog::getColor(ui->customColorToolButton->property("ProgressColor").value(), this, tr("Select Color")); + if (newColor.isValid()) { + setProgressBarColorIcon(newColor); + } +} diff --git a/src/lib/preferences/preferences.h b/src/lib/preferences/preferences.h index 26d3cdcfa..63c567936 100644 --- a/src/lib/preferences/preferences.h +++ b/src/lib/preferences/preferences.h @@ -83,6 +83,9 @@ private slots: void deleteProfile(); void startProfileIndexChanged(QString index); + void setProgressBarColorIcon(QColor col = QColor()); + void selectCustomProgressBarColor(); + void setNotificationPreviewVisible(bool state); private: diff --git a/src/lib/preferences/preferences.ui b/src/lib/preferences/preferences.ui index 178ac7484..e7c2daa55 100644 --- a/src/lib/preferences/preferences.ui +++ b/src/lib/preferences/preferences.ui @@ -793,6 +793,80 @@ + + + + + + + + Fill + + + + + Bottom + + + + + Top + + + + + + + + If unchecked the bar will adapt to the background color. + + + custom color: + + + + + + + + + + Select color + + + ... + + + + + + + Many styles use Highlight color for the progressbar. + + + set to "Highlight" color + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -2383,5 +2457,38 @@ showBookmarksToolbar - + + + showLoadingInAddressBar + toggled(bool) + adressProgressSettings + setEnabled(bool) + + + 513 + 117 + + + 513 + 154 + + + + + checkBoxCustomProgressColor + toggled(bool) + progressBarColorSelector + setEnabled(bool) + + + 405 + 152 + + + 567 + 157 + + + + diff --git a/src/lib/tools/colors.cpp b/src/lib/tools/colors.cpp new file mode 100644 index 000000000..b748405c0 --- /dev/null +++ b/src/lib/tools/colors.cpp @@ -0,0 +1,248 @@ +/* + * Bespin library for Qt style, KWin decoration and everythng else + * Copyright 2007-2012 by Thomas Lübking + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "colors.h" +#define CLAMP(x,l,u) (x) < (l) ? (l) :\ + (x) > (u) ? (u) :\ + (x) +#include +#include + +// using namespace Bespin; + +const QColor & +Colors::bg(const QPalette &pal, const QWidget* w) +{ + QPalette::ColorRole role; + if (!w) { + role = QPalette::Window; + } + else if (w->parentWidget()) { + role = w->parentWidget()->backgroundRole(); + } + else { + role = w->backgroundRole(); + } + +// if (pal.brush(role).style() > 1) + return pal.color(role); +// return QApplication::palette().color(role); +} + +int +Colors::contrast(const QColor &a, const QColor &b) +{ + int ar, ag, ab, br, bg, bb; + a.getRgb(&ar, &ag, &ab); + b.getRgb(&br, &bg, &bb); + + int diff = 299 * (ar - br) + 587 * (ag - bg) + 114 * (ab - bb); + diff = (diff < 0) ? -diff : 90 * diff / 100; + int perc = diff / 2550; + + diff = qMax(ar, br) + qMax(ag, bg) + qMax(ab, bb) + - (qMin(ar, br) + qMin(ag, bg) + qMin(ab, bb)); + + perc += diff / 765; + perc /= 2; + + return perc; +} + +QPalette::ColorRole +Colors::counterRole(QPalette::ColorRole role) +{ + switch (role) { + case QPalette::ButtonText: //8 + return QPalette::Button; + case QPalette::WindowText: //0 + return QPalette::Window; + case QPalette::HighlightedText: //13 + return QPalette::Highlight; + case QPalette::Window: //10 + return QPalette::WindowText; + case QPalette::Base: //9 + return QPalette::Text; + case QPalette::Text: //6 + return QPalette::Base; + case QPalette::Highlight: //12 + return QPalette::HighlightedText; + case QPalette::Button: //1 + return QPalette::ButtonText; + default: + return QPalette::Window; + } +} + +bool +Colors::counterRole(QPalette::ColorRole &from, QPalette::ColorRole &to, QPalette::ColorRole defFrom, + QPalette::ColorRole defTo) +{ + switch (from) { + case QPalette::WindowText: //0 + to = QPalette::Window; + break; + case QPalette::Window: //10 + to = QPalette::WindowText; + break; + case QPalette::Base: //9 + to = QPalette::Text; + break; + case QPalette::Text: //6 + to = QPalette::Base; + break; + case QPalette::Button: //1 + to = QPalette::ButtonText; + break; + case QPalette::ButtonText: //8 + to = QPalette::Button; + break; + case QPalette::Highlight: //12 + to = QPalette::HighlightedText; + break; + case QPalette::HighlightedText: //13 + to = QPalette::Highlight; + break; + default: + from = defFrom; + to = defTo; + return false; + } + return true; +} + +QColor +Colors::emphasize(const QColor &c, int value) +{ + int h, s, v, a; + QColor ret; + c.getHsv(&h, &s, &v, &a); + if (v < 75 + value) { + ret.setHsv(h, s, CLAMP(85 + value, 85, 255), a); + return ret; + } + if (v > 200) { + if (s > 30) { + h -= 5; + if (h < 0) { + h = 360 + h; + } + s = (s << 3) / 9; + v += value; + ret.setHsv(h, CLAMP(s, 30, 255), CLAMP(v, 0, 255), a); + return ret; + } + if (v > 230) { + ret.setHsv(h, s, CLAMP(v - value, 0, 255), a); + return ret; + } + } + if (v > 128) { + ret.setHsv(h, s, CLAMP(v + value, 0, 255), a); + } + else { + ret.setHsv(h, s, CLAMP(v - value, 0, 255), a); + } + return ret; +} + +bool +Colors::haveContrast(const QColor &a, const QColor &b) +{ + int ar, ag, ab, br, bg, bb; + a.getRgb(&ar, &ag, &ab); + b.getRgb(&br, &bg, &bb); + + int diff = (299 * (ar - br) + 587 * (ag - bg) + 114 * (ab - bb)); + + if (qAbs(diff) < 91001) { + return false; + } + + diff = qMax(ar, br) + qMax(ag, bg) + qMax(ab, bb) + - (qMin(ar, br) + qMin(ag, bg) + qMin(ab, bb)); + + return (diff > 300); +} + +QColor +Colors::light(const QColor &c, int value) +{ + int h, s, v, a; + c.getHsv(&h, &s, &v, &a); + QColor ret; + if (v < 255 - value) { + ret.setHsv(h, s, CLAMP(v + value, 0, 255), a); //value could be negative + return ret; + } + // psychovisual uplightning, i.e. shift hue and lower saturation + if (s > 30) { + h -= (value * 5 / 20); + if (h < 0) { + h = 400 + h; + } + s = CLAMP((s << 3) / 9, 30, 255); + ret.setHsv(h, s, 255, a); + return ret; + } + else { // hue shifting has no sense, half saturation (btw, white won't get brighter :) + ret.setHsv(h, s >> 1, 255, a); + } + return ret; +} + +QColor +Colors::mid(const QColor &c1, const QColor &c2, int w1, int w2) +{ + int sum = (w1 + w2); + if (!sum) { + return Qt::black; + } + + int r, g, b, a; +#if 0 + QColor c1 = oc1; + b = value(c1); + if (b < 70) { + c1.getHsv(&r, &g, &b, &a); + c1.setHsv(r, g, 70, a); + } +#endif + r = (w1 * c1.red() + w2 * c2.red()) / sum; + r = CLAMP(r, 0, 255); + g = (w1 * c1.green() + w2 * c2.green()) / sum; + g = CLAMP(g, 0, 255); + b = (w1 * c1.blue() + w2 * c2.blue()) / sum; + b = CLAMP(b, 0, 255); + a = (w1 * c1.alpha() + w2 * c2.alpha()) / sum; + a = CLAMP(a, 0, 255); + return QColor(r, g, b, a); +} + +int +Colors::value(const QColor &c) +{ + int v = c.red(); + if (c.green() > v) { + v = c.green(); + } + if (c.blue() > v) { + v = c.blue(); + } + return v; +} diff --git a/src/lib/tools/colors.h b/src/lib/tools/colors.h new file mode 100644 index 000000000..3c65ac89c --- /dev/null +++ b/src/lib/tools/colors.h @@ -0,0 +1,45 @@ +/* + * Bespin library for Qt style, KWin decoration and everythng else + * Copyright 2007-2012 by Thomas Lübking + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License version 2 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef COLORS_H +#define COLORS_H + +class QWidget; +#include +#include + +// namespace Bespin { +namespace Colors +{ + +const QColor &bg(const QPalette &pal, const QWidget* w); +int contrast(const QColor &a, const QColor &b); +QPalette::ColorRole counterRole(QPalette::ColorRole role); +bool counterRole(QPalette::ColorRole &from, QPalette::ColorRole &to, + QPalette::ColorRole defFrom = QPalette::WindowText, + QPalette::ColorRole defTo = QPalette::Window); +QColor emphasize(const QColor &c, int value = 10); +bool haveContrast(const QColor &a, const QColor &b); +QColor light(const QColor &c, int value); +QColor mid(const QColor &oc1, const QColor &c2, int w1 = 1, int w2 = 1); +int value(const QColor &c); + +} +// } + +#endif //COLORS_H