diff --git a/toonz/sources/common/tapptools/tenv.cpp b/toonz/sources/common/tapptools/tenv.cpp index 62dc75d..07a56d4 100644 --- a/toonz/sources/common/tapptools/tenv.cpp +++ b/toonz/sources/common/tapptools/tenv.cpp @@ -153,15 +153,18 @@ public: m_envFile = profilesDir + "env" + (TSystem::getUserName().toStdString() + ".env"); } - void setApplication(std::string applicationName, std::string applicationVersion) + void setApplication(std::string applicationName, std::string applicationVersion, std::string revision) { m_applicationName = applicationName; m_applicationVersion = applicationVersion; + if (!revision.empty()) { + m_applicationVersion += "." + revision; + } m_applicationFullName = m_applicationName + " " + m_applicationVersion; m_moduleName = m_applicationName; m_rootVarName = toUpper(m_applicationName) + "ROOT"; #ifdef _WIN32 - m_registryRoot = TFilePath("SOFTWARE\\OpenToonz\\") + m_applicationName + m_applicationVersion; + m_registryRoot = TFilePath("SOFTWARE\\OpenToonz\\") + m_applicationName + applicationVersion; #endif m_systemVarPrefix = m_applicationName; updateEnvFile(); @@ -458,9 +461,9 @@ void Variable::assignValue(std::string value) //=================================================================== -void TEnv::setApplication(std::string applicationName, std::string applicationVersion) +void TEnv::setApplication(std::string applicationName, std::string applicationVersion, std::string revision) { - EnvGlobals::instance()->setApplication(applicationName, applicationVersion); + EnvGlobals::instance()->setApplication(applicationName, applicationVersion, revision); #ifdef LEVO_MACOSX TOfflineGL::defineImpGenerator(MacOfflineGenerator1); diff --git a/toonz/sources/common/trop/tresample.cpp b/toonz/sources/common/trop/tresample.cpp index a6ffa1b..c6452ea 100644 --- a/toonz/sources/common/trop/tresample.cpp +++ b/toonz/sources/common/trop/tresample.cpp @@ -2868,12 +2868,6 @@ void do_resample(TRasterPT rout, const TRasterPT &rin, const TAffine &aff, TRop::ResampleFilterType flt_type, double blur) { -/* -TAffine scale; -TAffine rot; -TAffine invrot; -TAffine aff_0, inv_0; -*/ #ifdef ALTRI_TIPI_DI_RASTER double jacob; double s11, s22, s13, s23; @@ -2916,10 +2910,8 @@ TAffine aff_0, inv_0; s13 = aff.a13; s23 = aff.a23; - //rot = aff_place (0.0, 0.0, 0.0, 0.0, TScale(1/s11, 1/s22)*aff);//eventualmente invertire ordine rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0); - //scale = aff_place (0.0, 0.0, s13, s23, TScale(s11, s22)); scale = TScale(s11, s22).place(0.0, 0.0, s13, s23); invrot = rot.inv(); @@ -2947,16 +2939,12 @@ TAffine aff_0, inv_0; minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y, inv_0, negradu_, negradv_, posradu_, posradv_); - //free_nocalc (coln); if (coln) delete (coln); - //free_nocalc (rown); if (rown) delete (rown); free_filter(colf, rout->getLy()); free_filter(rowf, rout->getLx()); -//----NON GESTIAMO ANCORA EXTRA BUFFER -//rop_resample_extra (rin, rout, aff); #endif } diff --git a/toonz/sources/include/tenv.h b/toonz/sources/include/tenv.h index 78eee79..60a3d3b 100644 --- a/toonz/sources/include/tenv.h +++ b/toonz/sources/include/tenv.h @@ -95,7 +95,7 @@ public: // // es.: TEnv::setApplication("Toonz","5.0"); // -DVAPI void setApplication(std::string applicationName, std::string applicationVersion); +DVAPI void setApplication(std::string applicationName, std::string version, std::string revision = std::string()); DVAPI std::string getApplicationName(); DVAPI std::string getApplicationVersion(); diff --git a/toonz/sources/include/toonzqt/updatechecker.h b/toonz/sources/include/toonzqt/updatechecker.h index 08793ca..9258dfc 100644 --- a/toonz/sources/include/toonzqt/updatechecker.h +++ b/toonz/sources/include/toonzqt/updatechecker.h @@ -1,5 +1,3 @@ - - #ifndef UPDATE_CHECKER_H #define UPDATE_CHECKER_H @@ -7,14 +5,9 @@ #include #include "tcommon.h" -#if QT_VERSION >= 0x050000 #include -#else -#include -#endif #include #include -#include #undef DVAPI #undef DVVAR @@ -26,37 +19,24 @@ #define DVVAR DV_IMPORT_VAR #endif -class DVAPI UpdateChecker -#if QT_VERSION < 0x050000 - : public QHttp -#else - : public QObject -#endif +class DVAPI UpdateChecker : public QObject { Q_OBJECT - bool m_httpRequestAborted; - int m_httpGetId; - QDate m_updateDate; - QUrl m_webPageUrl; + QSharedPointer manager_; + + QString m_latestVersion; public: - UpdateChecker(const QString &requestToServer); + UpdateChecker(QUrl const& updateUrl); - QDate getUpdateDate() const { return m_updateDate; } - QUrl getWebPageUrl() const { return m_webPageUrl; } + QString getLatestVersion() const { return m_latestVersion; } protected slots: - void httpRequestStarted(int requestId) {} -#if QT_VERSION >= 0x050000 void httpRequestFinished(QNetworkReply *); -#else - void httpRequestFinished(int requestId, bool error); - void readyReadExec(const QHttpResponseHeader &head) {} - void readResponseHeader(const QHttpResponseHeader &responseHeader); -#endif - void slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator); - void httpStateChanged(int state); + +signals: + void done(bool error); }; #endif // UPDATE_CHECKER_H diff --git a/toonz/sources/toonz/main.cpp b/toonz/sources/toonz/main.cpp index 216228d..83da2db 100644 --- a/toonz/sources/toonz/main.cpp +++ b/toonz/sources/toonz/main.cpp @@ -130,6 +130,7 @@ const char *systemVarPrefix = "XPRESS"; const char *applicationName = "OpenToonz"; const char *applicationVersion = "1.0"; +const char *applicationRevision = "2"; const char *dllRelativePath = "./toonz6.app/Contents/Frameworks"; #ifdef _WIN32 @@ -140,7 +141,7 @@ TEnv::StringVar EnvSoftwareCurrentFont("SoftwareCurrentFont", "Hervetica"); TEnv::IntVar EnvSoftwareCurrentFontSize("SoftwareCurrentFontSize", 12); TEnv::StringVar EnvSoftwareCurrentFontWeight("SoftwareCurrentFontWeightIsBold", "Yes"); -const char *applicationFullName = "OpenToonz 1.0"; +const char *applicationFullName = "OpenToonz 1.0.2"; const char *rootVarName = "TOONZROOT"; const char *systemVarPrefix = "TOONZ"; #endif @@ -252,7 +253,7 @@ void initToonzEnv() #endif - TEnv::setApplication(applicationName, applicationVersion); + TEnv::setApplication(applicationName, applicationVersion, applicationRevision); TEnv::setRootVarName(rootVarName); TEnv::setSystemVarPrefix(systemVarPrefix); TEnv::setDllRelativeDir(TFilePath(dllRelativePath)); diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 4271254..72bc35b 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -215,6 +215,42 @@ void makePrivate(std::vector &rooms) makePrivate(rooms[i]); } + +// major version : 7 bits +// minor version : 8 bits +// revision number: 16 bits +int get_version_code_from(std::string ver) +{ + int version = 0; + + // major version: assume that the major version is less than 127. + std::string::size_type const a = ver.find('.'); + std::string const major + = (a == std::string::npos) + ? ver + : ver.substr(0, a); + version += std::stoi(major) << 24; + if ((a == std::string::npos) || (a + 1 == ver.length())) { + return version; + } + + // minor version: assume that the minor version is less than 255. + std::string::size_type const b = ver.find('.', a + 1); + std::string const minor + = (b == std::string::npos) + ? ver.substr(a + 1) + : ver.substr(a + 1, b - a - 1); + version += std::stoi(minor) << 16; + if ((b == std::string::npos) || (b + 1 == ver.length())) { + return version; + } + + // revision number: assume that the revision number is less than 32767. + version += std::stoi(ver.substr(b + 1)); + + return version; +} + } // namespace //============================================================================= @@ -1029,7 +1065,10 @@ void MainWindow::onAbout() dialog->setWindowTitle(tr("About OpenToonz")); dialog->setTopMargin(0); dialog->addWidget(label); - dialog->addWidget(new QLabel("OpenToonz (built " __DATE__ " " __TIME__ ")")); + + QString name = QString::fromStdString(TEnv::getApplicationFullName()); + name += " (built " __DATE__ " " __TIME__ ")"; + dialog->addWidget(new QLabel(name)); QPushButton *button = new QPushButton(tr("Close"), dialog); button->setDefault(true); @@ -1243,16 +1282,12 @@ extern const char *applicationVersion; //----------------------------------------------------------------------------- void MainWindow::checkForUpdates() { -/* FIXME: とりあえずアップデートチェックしないことにする */ -#if QT_VERSION < 0x050000 - QString requestToServer = "http://www.toonz.com/cgi-shl/update/update.asp"; - requestToServer = requestToServer + QString("?Application_Name=") + applicationName; - requestToServer = requestToServer + QString("&Version=") + applicationVersion; - requestToServer.remove(" "); + // Since there is only a single version of Opentoonz, we can do a simple check against a string + QString updateUrl("http://opentoonz.github.io/opentoonz-version.txt"); - m_updateChecker = new UpdateChecker(requestToServer); - connect(m_updateChecker, SIGNAL(done(bool)), this, SLOT(onUpdateCheckerDone(bool))); -#endif + m_updateChecker = new UpdateChecker(updateUrl); + connect(m_updateChecker, SIGNAL(done(bool)), + this, SLOT(onUpdateCheckerDone(bool))); } //----------------------------------------------------------------------------- #ifdef LINETEST @@ -1272,52 +1307,26 @@ void MainWindow::checkForLicense() void MainWindow::onUpdateCheckerDone(bool error) { - if (!error) { - // Get the last update date - const TFilePath lastUpdateFilePath = TEnv::getConfigDir() + "lastUpdate.dat"; - //QFile data(toQString(lastUpdateFilePath)); - - QFile data(QString::fromStdWString(lastUpdateFilePath.getWideString())); - QString dateString; - if (data.open(QIODevice::ReadOnly)) { - QTextStream in(&data); - in >> dateString; - } - data.close(); - - // Last update Date - QDate lastUpdate = QDate::fromString(dateString, "MM/dd/yyyy"); - // Current Update Date - QDate updateDate = m_updateChecker->getUpdateDate(); - // Update web page - QUrl webPageUrl = m_updateChecker->getWebPageUrl(); - - // If the response 'make sense' - if (!updateDate.toString("MM/dd/yyyy").isEmpty() && !webPageUrl.toString().isEmpty()) { - if (!lastUpdate.isValid() || updateDate > lastUpdate) { - std::vector buttons; - buttons.push_back(QString(tr("Visit Web Site"))); - buttons.push_back(QString(tr("Cancel"))); - int ret = DVGui::MsgBox(DVGui::INFORMATION, QObject::tr("An update is available for this software.\nVisit the Web site for more information."), buttons); - if (ret == 1) - QDesktopServices::openUrl(webPageUrl); - - // Write the new last date to file - QFile data(QString::fromStdWString(lastUpdateFilePath.getWideString())); - if (data.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - QTextStream out(&data); - out << updateDate.toString("MM/dd/yyyy"); - out.flush(); - } - data.close(); - } + if (error) { + // Don't bother doing the update if there was an error + return; + } + + int const software_version = get_version_code_from(TEnv::getApplicationVersion()); + int const latest_version = get_version_code_from(m_updateChecker->getLatestVersion().toStdString()); + if (software_version < latest_version) { + std::vector buttons; + buttons.push_back(QObject::tr("Visit Web Site")); + buttons.push_back(QObject::tr("Cancel")); + int ret = MsgBox(INFORMATION, QObject::tr("An update is available for this software.\nVisit the Web site for more information."), buttons); + if (ret == 1) { + // This URL can be "translated" to give a localised version to non-English users + QDesktopServices::openUrl(QObject::tr("https://opentoonz.github.io/e/")); } } -#if QT_VERSION < 0x050000 disconnect(m_updateChecker); m_updateChecker->deleteLater(); -#endif } //----------------------------------------------------------------------------- #ifdef LINETEST diff --git a/toonz/sources/toonzqt/updatechecker.cpp b/toonz/sources/toonzqt/updatechecker.cpp index 016d0df..e567897 100644 --- a/toonz/sources/toonzqt/updatechecker.cpp +++ b/toonz/sources/toonzqt/updatechecker.cpp @@ -1,227 +1,36 @@ - - #include "./toonzqt/updatechecker.h" -#include #include -#include -//============================================================================= -// UpdateChecker -//----------------------------------------------------------------------------- -UpdateChecker::UpdateChecker(const QString &requestToServer) -#if QT_VERSION >= 0x050000 - : -#else - : QHttp(), -#endif - m_webPageUrl() +UpdateChecker::UpdateChecker(QUrl const& updateUrl) + : manager_(new QNetworkAccessManager(this), &QNetworkAccessManager::deleteLater) { - int i = 0; - QUrl url(requestToServer); -#if QT_VERSION >= 0x050000 - QString urlTemp = requestToServer; - - QStringList urlList = urlTemp.split('?'); - if (urlList.count() <= 1) { - abort(); - return; - } - - QStringList paramList = urlList.at(1).split('&'); - //if (!url.userName().isEmpty()) - // setUser(url.userName(), url.password()); - - m_httpRequestAborted = false; - - QString param; - param = QString("?"); - for (i = 0; i < paramList.size(); i++) { - param += paramList.at(i); - if (i < paramList.size() - 1) - param += QString("&"); - } - - QNetworkAccessManager manager; - QNetworkReply *reply = manager.get(QNetworkRequest(url.path() + param)); - - QEventLoop loop; - - connect(reply, SIGNAL(requestStarted(int)), &loop, SLOT(httpRequestStarted(int))); - connect(reply, SIGNAL(authenticationRequired(const QString &, quint16, QAuthenticator *)), &loop, SLOT(slotAuthenticationRequired(const QString &, quint16, QAuthenticator *))); - connect(reply, SIGNAL(stateChanged(int)), &loop, SLOT(httpStateChanged(int))); - - connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(httpRequestFinished(QNetworkReply *))); - - loop.exec(); - -#else - //connect(this, SIGNAL(readyRead(const QHttpResponseHeader &)), this, - // SLOT(readyReadexec(const QHttpResponseHeader &))); - connect(this, SIGNAL(requestFinished(int, bool)), this, - SLOT(httpRequestFinished(int, bool))); - connect(this, SIGNAL(requestStarted(int)), this, - SLOT(httpRequestStarted(int))); - connect(this, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, - SLOT(readResponseHeader(const QHttpResponseHeader &))); - connect(this, SIGNAL(authenticationRequired(const QString &, quint16, QAuthenticator *)), this, - SLOT(slotAuthenticationRequired(const QString &, quint16, QAuthenticator *))); - connect(this, SIGNAL(stateChanged(int)), this, - SLOT(httpStateChanged(int))); - QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp; - - setHost(url.host(), mode, url.port() == -1 ? 0 : url.port()); - QString urlTemp = requestToServer; - - QStringList urlList = urlTemp.split('?'); - if (urlList.count() <= 1) { - abort(); - return; - } - - QStringList paramList = urlList.at(1).split('&'); - if (!url.userName().isEmpty()) - setUser(url.userName(), url.password()); - - m_httpRequestAborted = false; - - QString param; - param = QString("?"); - for (i = 0; i < paramList.size(); i++) { - param += paramList.at(i); - if (i < paramList.size() - 1) - param += QString("&"); - } - /*param = QString("?")+paramList.at(0)+QString("&") - +paramList.at(1) + QString("&") + paramList.at(2);*/ - m_httpGetId = get(url.path() + param); //, file); -#endif -} - -//----------------------------------------------------------------------------- + connect(manager_.data(), SIGNAL(finished(QNetworkReply*)), + this, SLOT(httpRequestFinished(QNetworkReply*))); -#if QT_VERSION < 0x050000 -void UpdateChecker::readResponseHeader(const QHttpResponseHeader &responseHeader) -{ - int err = responseHeader.statusCode(); - if (err != 200 && err != 502) { - m_httpRequestAborted = true; - abort(); - } + manager_->get(QNetworkRequest(updateUrl)); } -#endif -//----------------------------------------------------------------------------- - -void UpdateChecker::httpStateChanged(int status) +void UpdateChecker::httpRequestFinished(QNetworkReply *pReply) { - std::string stateStr; - switch (status) { - case 1: - stateStr = "A host name lookup is in progress..."; - break; - case 2: - stateStr = "Connecting..."; - break; - case 3: - stateStr = "Sending informations..."; - break; - case 4: - stateStr = "Reading informations..."; - break; - case 5: - stateStr = "Connected."; - break; - case 6: - stateStr = "The connection is closing down, but is not yet closed. (The state will be Unconnected when the connection is closed.)"; - break; - default: - stateStr = "There is no connection to the host."; - } -#if QT_VERSION < 0x050000 - status = state(); - qDebug("Status: %d : %s", status, stateStr.c_str()); -#endif -} - -//----------------------------------------------------------------------------- + QSharedPointer reply(pReply, &QNetworkReply::deleteLater); -#if QT_VERSION >= 0x050000 -void UpdateChecker::httpRequestFinished(QNetworkReply *reply) -#else -void UpdateChecker::httpRequestFinished(int requestId, bool error) -#endif -{ - QByteArray arr; - std::string webPageString; - std::string dateString; - QString qstr; -#if QT_VERSION >= 0x050000 - if (reply->error() != QNetworkReply::NoError) - return; - arr = reply->readAll(); -#else - if (requestId != m_httpGetId) { - return; - } - if (error || m_httpRequestAborted) { - abort(); + // If there was an error, don't bother doing the check + if (reply->error() != QNetworkReply::NoError) { + emit done(true); return; } - arr = readAll(); -#endif - qstr = QString(arr); - int startIndex = qstr.indexOf("Startdate"); - int endIndex = qstr.indexOf("Enddate"); + // Convert the response from a QByteArray into a QString + QString candidateVersion = QString(reply->readAll()).trimmed(); - if ((endIndex - startIndex - 9) <= 0) { - abort(); + // TODO: Verify that the response was valid by ensuring we have a single line in the format x.x[.x]* + if (candidateVersion.indexOf(".") < 0) { + // There was some invalid response, so we'll ignore the check for now + emit done(true); return; } - dateString = qstr.toStdString(); - dateString = dateString.substr(startIndex + 9, endIndex - startIndex - 9); - - QString qDateString = QString::fromStdString(dateString); - qDateString.remove("\""); - - // Make sure that the format is exactly MM/dd/yyyy - if (qDateString.size() != 10) { - QStringList fields = qDateString.split("/"); - if (fields.size() == 3) { - QString month = fields.at(0); - QString day = fields.at(1); - QString year = fields.at(2); - - if (day.size() == 1) - day.prepend("0"); - if (month.size() == 1) - month.prepend("0"); - - qDateString = month + "/" + day + "/" + year; - } - } - - m_updateDate = QDate::fromString(qDateString, "MM/dd/yyyy"); - - startIndex = qstr.indexOf("Starturl"); - endIndex = qstr.indexOf("Endurl"); - - webPageString = qstr.toStdString(); - webPageString = webPageString.substr(startIndex + 9, endIndex - startIndex - 9); - - QString qWebPageString = QString::fromStdString(webPageString); - qWebPageString.remove("\""); - - QUrl webPageUrl(qWebPageString); - - if (webPageUrl.isValid()) - m_webPageUrl = webPageUrl; -} - -//----------------------------------------------------------------------------- - -void UpdateChecker::slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator) -{ - assert(false); + // Completed with no errors + m_latestVersion = candidateVersion; + emit done(false); }