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