1 /*
2 # PostgreSQL Database Modeler (pgModeler)
3 #
4 # Copyright 2006-2020 - Raphael Araújo e Silva <raphael@pgmodeler.io>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation version 3.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # The complete text of GPLv3 is at LICENSE file on source code root directory.
16 # Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
17 */
18
19 #include "updatenotifierwidget.h"
20 #include "pgmodeleruins.h"
21
UpdateNotifierWidget(QWidget * parent)22 UpdateNotifierWidget::UpdateNotifierWidget(QWidget *parent) : QWidget(parent)
23 {
24 setupUi(this);
25 setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);
26
27 show_no_upd_msg=false;
28 update_chk_reply=nullptr;
29 old_pos=QPoint(-1,-1);
30 frame->installEventFilter(this);
31
32 QGraphicsDropShadowEffect * drop_shadow=new QGraphicsDropShadowEffect(this);
33 drop_shadow->setOffset(5,5);
34 drop_shadow->setBlurRadius(30);
35 this->setGraphicsEffect(drop_shadow);
36
37 connect(&update_chk_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleUpdateChecked(QNetworkReply*)));
38
39 //C++11 lambda slots
40 connect(get_source_tb, &QToolButton::clicked, this, [&](){ activateLink(GlobalAttributes::PgModelerSourceURL); });
41 connect(get_binary_tb, &QToolButton::clicked, this, [&](){ activateLink(GlobalAttributes::PgModelerDownloadURL); });
42
43
44 connect(hide_tb, &QToolButton::clicked, this,
45 [&](){
46 this->close();
47 emit s_visibilityChanged(false);
48 });
49
50 PgModelerUiNs::configureWidgetFont(changelog_txt, PgModelerUiNs::MediumFontFactor);
51 PgModelerUiNs::configureWidgetFont(ver_num_lbl, PgModelerUiNs::BigFontFactor);
52 PgModelerUiNs::configureWidgetFont(title_lbl, PgModelerUiNs::BigFontFactor);
53 this->adjustSize();
54 }
55
eventFilter(QObject * obj,QEvent * event)56 bool UpdateNotifierWidget::eventFilter(QObject *obj, QEvent *event)
57 {
58 if(obj==frame && (event->type()==QEvent::MouseMove || event->type()==QEvent::MouseButtonPress))
59 {
60 QMouseEvent *m_event=dynamic_cast<QMouseEvent *>(event);
61
62 if(event->type()==QEvent::MouseButtonPress)
63 old_pos=QPoint(-1,-1);
64 else
65 {
66 //Resizing the widget
67 if(m_event->buttons()==Qt::LeftButton)
68 {
69 if(m_event->pos().x() >= this->minimumWidth() - 20 ||
70 m_event->pos().y() >= this->minimumHeight()- 20)
71 {
72 int w, h;
73
74 if(old_pos.x() >= 0)
75 {
76 //Calculates the width and height based upon the delta between the points
77 w=this->width() + (m_event->pos().x() - old_pos.x());
78 h=this->height() + (m_event->pos().y() - old_pos.y());
79 this->setGeometry(this->pos().x(), this->pos().y(), w, h);
80 }
81 }
82
83 old_pos=m_event->pos();
84 }
85 }
86 }
87
88 return QWidget::eventFilter(obj, event);
89 }
90
activateLink(const QString & link)91 void UpdateNotifierWidget::activateLink(const QString &link)
92 {
93 QDesktopServices::openUrl(QUrl(link));
94 this->close();
95 emit s_visibilityChanged(false);
96 }
97
checkForUpdate()98 void UpdateNotifierWidget::checkForUpdate()
99 {
100 QUrl url(GlobalAttributes::PgModelerUpdateCheckURL + GlobalAttributes::PgModelerVersion);
101 QNetworkRequest req(url);
102
103 req.setRawHeader("User-Agent", "pgModelerUpdateCheck");
104 show_no_upd_msg=(dynamic_cast<QAction *>(sender())!=nullptr);
105 update_chk_reply=update_chk_manager.get(req);
106 }
107
handleUpdateChecked(QNetworkReply * reply)108 void UpdateNotifierWidget::handleUpdateChecked(QNetworkReply *reply)
109 {
110 Messagebox msg_box;
111 unsigned http_status=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt();
112
113 if(reply->error()!=QNetworkReply::NoError)
114 {
115 msg_box.show(tr("Failed to check updates"),
116 tr("The update notifier failed to check for new versions! Please, verify your internet connectivity and try again! Connection error returned: <em>%1</em> - <strong>%2</strong>.").arg(http_status).arg(reply->errorString()),
117 Messagebox::ErrorIcon, Messagebox::OkButton);
118 }
119 else
120 {
121 /* In case of [301 - Move permanently] there is the need to make a new request to
122 reach the final destination */
123 if(http_status==301 || http_status==302)
124 {
125 QString url=reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
126
127 if(http_status==302 && !url.startsWith(GlobalAttributes::PgModelerSite))
128 url.prepend(GlobalAttributes::PgModelerSite);
129
130 QNetworkRequest req(url);
131 update_chk_reply=update_chk_manager.get(req);
132 }
133 else
134 {
135 //In case of [200 - OK] updates the contents with the retrieved json
136 if(http_status==200)
137 {
138 QJsonDocument json_doc=QJsonDocument::fromJson(reply->readAll());
139 QJsonObject json_obj=json_doc.object();
140 QString version=json_obj.value(Attributes::NewVersion).toString(),
141 changelog=json_obj.value(Attributes::Changelog).toString(),
142 date=json_obj.value(Attributes::Date).toString();
143 bool upd_found=(!version.isEmpty() && version!=Attributes::False);
144
145 if(upd_found)
146 {
147 ver_num_lbl->setText(version);
148 changelog_txt->setText(changelog);
149 ver_date_lbl->setText(date);
150 }
151 else if(show_no_upd_msg)
152 {
153 msg_box.show(tr("No updates found"),
154 tr("You are running the most recent pgModeler version! No update needed."),
155 Messagebox::InfoIcon, Messagebox::OkButton);
156 }
157
158 emit s_updateAvailable(upd_found);
159 }
160 else
161 {
162 msg_box.show(tr("Failed to check updates"),
163 tr("The update notifier failed to check for new versions! A HTTP status code was returned: <strong>%1</strong>").arg(http_status),
164 Messagebox::ErrorIcon, Messagebox::OkButton);
165 }
166
167 update_chk_reply->deleteLater();
168 update_chk_reply=nullptr;
169 }
170 }
171 }
172
173
174