From a90a577ee11cb2b30dee21ec5f527e0c124fec56 Mon Sep 17 00:00:00 2001 From: Kyle Kneitinger Date: Sat, 24 Nov 2018 14:30:55 -0800 Subject: [PATCH] Add favicon fetch button next to entry's url edit textbox (#2439) When WITH_XC_NETWORKING is defined, create a QToolButton beside the Edit Entry -> Entry -> URL, which when pressed, acts as though the Edit Entry -> Icon -> Download Favicon button is pressed. This button is disabled (grayed-out) when the URL text is empty, and enabled when the text is present. Fixes #936 * Add favicon download button * Remove the progress dialog that appears when downloading an entry's URL's favicon since (when working correctly) it disappears before it can be read. When downloading icons from the button located next to the URL text box, display a message panel that confirms the download was a success. * Do not show successful icon download msg if icon alread exists --- COPYING | 6 ++++ .../16x16/actions/favicon-download.png | Bin 0 -> 755 bytes .../22x22/actions/favicon-download.png | Bin 0 -> 1054 bytes .../32x32/actions/favicon-download.png | Bin 0 -> 1618 bytes src/gui/EditWidgetIcons.cpp | 34 ++---------------- src/gui/EditWidgetIcons.h | 12 ------- src/gui/entry/EditEntryWidget.cpp | 21 +++++++++++ src/gui/entry/EditEntryWidget.h | 3 ++ src/gui/entry/EditEntryWidgetMain.ui | 14 ++++++-- 9 files changed, 44 insertions(+), 46 deletions(-) create mode 100644 share/icons/application/16x16/actions/favicon-download.png create mode 100644 share/icons/application/22x22/actions/favicon-download.png create mode 100644 share/icons/application/32x32/actions/favicon-download.png diff --git a/COPYING b/COPYING index b91037658..b3eddd766 100644 --- a/COPYING +++ b/COPYING @@ -151,6 +151,12 @@ Copyright: 2003-2004, David Vignoni License: LGPL-2.1 Comment: based on Nuvola icon theme +Files: share/icons/application/*/actions/favicon-download.png +Copyright: 2003-2004, David Vignoni + 2018, Kyle Kneitinger +License: LGPL-2.1 +Comment: based on Nuvola icon theme + Files: share/icons/application/*/actions/application-exit.png share/icons/application/*/actions/chronometer.png share/icons/application/*/actions/configure.png diff --git a/share/icons/application/16x16/actions/favicon-download.png b/share/icons/application/16x16/actions/favicon-download.png new file mode 100644 index 0000000000000000000000000000000000000000..80bc4a65dcc7178850d20dcd9b3575b873aec980 GIT binary patch literal 755 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7Sc;uILpV4%IBGajIv5xj zI14-?iy0W0H-a$Z*XFmL3=9mCC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2 zNHH)l6?nQhhFJ90PV)Ac5-4-D{(JSgCB{D-lwCIqY;3h~>YKJYhD z?h+bi{rRL`oATM&e3L$gvc=mkE8o(7TQ_&h-Mt6rXczdoEL31Spk;8HYeKx+`Adpz z%H<7_%m)h9DlZoH{`tFePL9R-FDI;>KJ#6BXw$Os^0sWwiA>qXhn^o~oU>BkTnNX# z`pDf=-znY|dGXB8;f}zPZPO~AUUJ>VoccOC+qc(U=2uVRnOKH(YTKr9gdS98(OwTbV3jbyIR?iMhS%>q^M4S+Dq=9_VwMr ze*H?%%*Sc;uILpV4%IBGajIv5xj zI14-?iy0VLg+Z7x%KDT)0|SF(iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$ zQVa~tvproLLo9liPL0lpag{k%Z~Xj?uBY%MRl{2uxxQzmSdZG>XkYOoY3)_JCkGu| zbVMeyh#WbsWv3Ovn~{6aDJS!{fbJ0qlcT4dHEy+UTgesXJRj`|-GY-x2hpU=+uFL*JdL`kS~OV-+->o@6m^YZiWH#0N)CTKoIveV_= zt5>g%72a9o%eB-bsyRsNg7)W7QM2EFgZTLP-ZAkp=W$9L*i`go&%NV|WDglQN-!~M z@SeK5qwm;O)3S964dLJJo}Rp0o>`zF=DCCe$Jr%!eNL~F%QEwHvJ+sE;lC8=n-w^5 zZn5W?Djgqdl}B>*{`GBfTjQ3UIi#>+)zqB4Nms(1FR*AH_@*#b_zXMG62?=^>g!KL zN@-r7sq= zKRy)nW;a-JBy_?#=Urh!YbLU+Rt@Uvm2Ey?qVS^mn$^*}TcwT%W?WY?tDD-|bNa%< zzY@J~pXj)r3z`!%C#|GriuTWJegRJYhbuSxsMtk_w>l)GU;eW9BNOvq^$$ON_We)m zcr3rKbx%Ee@o&*9$FIr6vgsLfR_En9yrE3C)k8FHS{$F&e}B!+`i^IaYtS6NpJC+A*{#mRZd&K?}m5H zJ*OR>lZ>VI-wZMg_UD>YH2wSUpN2N-{)gIJj1J3BUVcriQ>^p;iW5i8So|)QZ(_P; zl6$Xf>c+57dLGPC&c{T4oGsdsbbM*C@PSg%{eMdsHNG@Hs#~!2S!afM@v$1$4aJ8) z8#CJYKisv7<=10w9DCuqa;Hm}|eMtEAbP znxv=G_xJ5T{^ro`W!Gk{T6G}mzV5kiAKT>KH+dELKTRX+tKE68w8b(mcL?B~w> zDz)#gL-bdk;aITX!z!Kym8p9wS()rM=brAoyWZ}~#e0R)48r1%=hXfGBWi87wLjAxcre*b5j7WR6ZM){U6%-iqeoV35*_ol2O{LFj? P1_lOCS3j3^P6hf)mEyUSZEm7_BDOB8{65;9^y73l&ZQxQb zSEtacQMyhhT1{cP6Bm5(tzEc+WvQ3SJ(i}BpH3`X8loaoJqit$g{TOvSn6AlWc}5$ zPxkqnA93a7X}=QRpMBOhNBNffthu*u-u(Ih`G1?wcQz+wWW2cW>+9?NYAp;0qIR#5 zOqS}4UzNGmbNOX=K6$%8t_o308ZBR6Tl@RfVgC24n3*-a@9%lfi;l}~ z=eO$n{L_G^-$Yem>5(XJz3?R=T+?-<{2v89{`$bnbJs2vFU>VurDruVTTFG;k2~}E z^nDu_HR&b>MMsC9Oc5Ix)R>IK)@+Pmb_)(wzpDB3D6_Ra&*x?qh9x3Beik)vPV)=q zPp{x?e9SeaOF|--v!*+KgGh1PpGk__Gft%OcuStWwC9+9l-0kF)pe?_!3Wg1T%t=K zH=WCK-4r{iJyliNH!>5#2M*Q$87q7A#!Ndrd__vUvxy*EK!!tIC`eFG^%Puda-&NreEB&=ztc7g9!7wt^?OACX^fuEoJd3dB5UTt>%=_1pUMU z;igH#JCAL9)_6;ELXbf50$s62^`r}z*WHxS7tA<)a?bHJ@*jD5e^?c{+bI@4Zi|Q! zD&}nznJ&!Cz@&Ph+toT&eml<+rxJ||w>HFzTI{;fx2K|-#wc|Y&}sXM>_I}@#Z`$N9pp#*ntBjyQLo9un~8LJyk zigLL)&X_s#$%S{-8luc;=jJ@Cu=1{7z_Il~XKjCB;wzr?bW`cg+#RN?N(&mwT0{Mq zUaV6O=qu#rXu89b>^}d=lZ}GM{H9m@`zZf;?fbg^iv3n#w%-5WMj+eD+d&Lv|G>ht*DYEl#yHwA1Pt@!_wETgu^3h{i z({iphvAtaQib*ly(Oq-Hg->gKi9Bc2V3b@Dce+gVNUE;-mKW zxNkR^<>xXnB(C6OiVgqivfx^i;Vj|FkAE!WKk(&_&MN7o)hY@tQ_7N8^=n^~N|^X~ z`LR`o8}__e)!X=VqxiSaCszAED!D3Py}mH~ZIjFV*&F7+`6t|9zxLwnpz`qK1(G|q z79`*QYN4+cbic$i?yX7Wzf0R*vcF}}+4s`;cfS4M)|k4P9lZzEZmoH?OSPoBhes1KQ{FUfn-;kbVAvJy(wXIc?XM66%{d z<6d~myVj-OEiAt}e_EQ}u!dQn+p?tO$aGP`)3HJ~m#=@D{NyEb&0qKON$2J~6u$pa zV5-HB3H$#Wq)XOs@%UEpjaTj5pPmWV8F>}j+S>g1d3e5r?Bkzy{r|Ry5i3m3@B7B} z+$`lr)%B=3E}tI<%;2sp|K4==|La5AK1<{o?yX#|{p*LMG0*SC6C zeeLbP=9b}kFW2zRuXwGa|M%ltCj+~$8k@z-7>%cIt@AGPJ)e8;?CnqY>p#ZrPS5J! z`}L#s+8qyfRa#k>GiCoTKk)V1?cb55kH3DtU0!o|)7Rk1DwDS}pZw2XarBp2{uF4`E>tE6A|r_>B=??3=9mOu6{1-oD!M 0) { - setValue(static_cast(bytesRead / totalBytes)); - } else { - setValue(0); - } -} - EditWidgetIcons::EditWidgetIcons(QWidget* parent) : QWidget(parent) , m_ui(new Ui::EditWidgetIcons()) @@ -268,14 +249,14 @@ void EditWidgetIcons::fetchFinished() // No redirect, and we theoretically have some icon data now. image.loadFromData(m_bytesReceived); } - } else { - UrlFetchProgressDialog *progress = findChild(url.toString()); - progress->close(); } if (!image.isNull()) { if (!addCustomIcon(image)) { emit messageEditEntry(tr("Custom icon already exists"), MessageWidget::Information); + } else if (!this->isVisible()) { + // Show confirmation message if triggered from Entry tab download button + emit messageEditEntry(tr("Custom icon successfully downloaded"), MessageWidget::Positive); } } else if (!m_urlsToTry.empty()) { m_redirects = 0; @@ -316,15 +297,6 @@ void EditWidgetIcons::startFetchFavicon(const QUrl& url) m_reply = m_netMgr.get(request); connect(m_reply, &QNetworkReply::finished, this, &EditWidgetIcons::fetchFinished); connect(m_reply, &QIODevice::readyRead, this, &EditWidgetIcons::fetchReadyRead); - - UrlFetchProgressDialog *progress = new UrlFetchProgressDialog(url, this); - progress->setObjectName(url.toString()); - progress->setAttribute(Qt::WA_DeleteOnClose); - connect(m_reply, &QNetworkReply::finished, progress, &QProgressDialog::hide); - connect(m_reply, &QNetworkReply::downloadProgress, progress, &UrlFetchProgressDialog::networkReplyProgress); - connect(progress, &QProgressDialog::canceled, this, &EditWidgetIcons::fetchCanceled); - - progress->show(); #else Q_UNUSED(url); #endif diff --git a/src/gui/EditWidgetIcons.h b/src/gui/EditWidgetIcons.h index d00e064af..677cbebef 100644 --- a/src/gui/EditWidgetIcons.h +++ b/src/gui/EditWidgetIcons.h @@ -20,7 +20,6 @@ #define KEEPASSX_EDITWIDGETICONS_H #include -#include #include #include #include @@ -50,17 +49,6 @@ struct IconStruct int number; }; -class UrlFetchProgressDialog : public QProgressDialog -{ - Q_OBJECT - -public: - explicit UrlFetchProgressDialog(const QUrl &url, QWidget *parent = nullptr); - -public slots: - void networkReplyProgress(qint64 bytesRead, qint64 totalBytes); -}; - class EditWidgetIcons : public QWidget { Q_OBJECT diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index a19a89332..72d09c9ff 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -121,8 +121,19 @@ void EditEntryWidget::setupMain() m_mainUi->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show")); m_mainUi->togglePasswordGeneratorButton->setIcon(filePath()->icon("actions", "password-generator")); +#ifdef WITH_XC_NETWORKING + m_mainUi->fetchFaviconButton->setIcon(filePath()->icon("actions", "favicon-download")); + m_mainUi->fetchFaviconButton->setDisabled(true); +#else + m_mainUi->fetchFaviconButton->setVisible(false); +#endif + + connect(m_mainUi->togglePasswordButton, SIGNAL(toggled(bool)), m_mainUi->passwordEdit, SLOT(setShowPassword(bool))); connect(m_mainUi->togglePasswordGeneratorButton, SIGNAL(toggled(bool)), SLOT(togglePasswordGeneratorButton(bool))); +#ifdef WITH_XC_NETWORKING + connect(m_mainUi->fetchFaviconButton, SIGNAL(clicked()), m_iconsWidget, SLOT(downloadFavicon())); +#endif connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool))); connect(m_mainUi->notesEnabled, SIGNAL(toggled(bool)), this, SLOT(toggleHideNotes(bool))); m_mainUi->passwordRepeatEdit->enableVerifyMode(m_mainUi->passwordEdit); @@ -241,6 +252,9 @@ void EditEntryWidget::setupEntryUpdate() connect(m_mainUi->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); +#ifdef WITH_XC_NETWORKING + connect(m_mainUi->urlEdit, SIGNAL(textChanged(const QString&)), this, SLOT(updateFaviconButtonEnable(const QString&))); +#endif connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setUnsavedChanges())); @@ -995,6 +1009,13 @@ void EditEntryWidget::setGeneratedPassword(const QString& password) m_mainUi->togglePasswordGeneratorButton->setChecked(false); } +#ifdef WITH_XC_NETWORKING +void EditEntryWidget::updateFaviconButtonEnable(const QString& url) +{ + m_mainUi->fetchFaviconButton->setDisabled(url.isEmpty()); +} +#endif + void EditEntryWidget::insertAttribute() { Q_ASSERT(!m_history); diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index d45b29726..b0f5d8c94 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -79,6 +79,9 @@ private slots: void cancel(); void togglePasswordGeneratorButton(bool checked); void setGeneratedPassword(const QString& password); +#ifdef WITH_XC_NETWORKING + void updateFaviconButtonEnable(const QString& url); +#endif void insertAttribute(); void editCurrentAttribute(); void removeCurrentAttribute(); diff --git a/src/gui/entry/EditEntryWidgetMain.ui b/src/gui/entry/EditEntryWidgetMain.ui index dc07603aa..3e759fec7 100644 --- a/src/gui/entry/EditEntryWidgetMain.ui +++ b/src/gui/entry/EditEntryWidgetMain.ui @@ -19,6 +19,17 @@ + + + + + + + + + + + @@ -155,9 +166,6 @@ - - -