From fa00547507566a646db2baffea114104b1ffd567 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 5 Feb 2013 00:36:25 -0500 Subject: [PATCH] First version of automatic updates for Mac --- appcast-snapshots.xml.in | 18 ++++ appcast.xml.in | 18 ++++ doc/release-checklist.txt | 3 +- icons/prefsUpdate.png | Bin 0 -> 10909 bytes mjau.gdb | 1 + openscad.pro | 12 ++- openscad.qrc | 1 + scripts/publish-macosx.sh | 41 ++++++--- scripts/release-common.sh | 17 ++-- setenv_mjau.sh | 1 + src/AutoUpdater.cc | 3 + src/AutoUpdater.h | 25 ++++++ src/MainWindow.h | 1 + src/MainWindow.ui | 12 +++ src/Preferences.cc | 33 ++++++++ src/Preferences.h | 3 + src/Preferences.ui | 170 ++++++++++++++++++++++++++++++++++++-- src/SparkleAutoUpdater.h | 32 +++++++ src/SparkleAutoUpdater.mm | 72 ++++++++++++++++ src/mainwin.cc | 18 ++++ src/openscad.cc | 9 ++ 21 files changed, 463 insertions(+), 27 deletions(-) create mode 100644 appcast-snapshots.xml.in create mode 100644 appcast.xml.in create mode 100644 icons/prefsUpdate.png create mode 100644 src/AutoUpdater.cc create mode 100644 src/AutoUpdater.h create mode 100644 src/SparkleAutoUpdater.h create mode 100644 src/SparkleAutoUpdater.mm diff --git a/appcast-snapshots.xml.in b/appcast-snapshots.xml.in new file mode 100644 index 00000000..31035655 --- /dev/null +++ b/appcast-snapshots.xml.in @@ -0,0 +1,18 @@ + + + + OpenSCAD Development Snapshots + http://openscad.org/appcast-snapshots.xml + en + + OpenSCAD @VERSION@ + @VERSIONDATE@ + https://raw.github.com/openscad/openscad/master/RELEASE_NOTES + + + + diff --git a/appcast.xml.in b/appcast.xml.in new file mode 100644 index 00000000..e375fae7 --- /dev/null +++ b/appcast.xml.in @@ -0,0 +1,18 @@ + + + + OpenSCAD Updates + http://openscad.org/appcast.xml + en + + OpenSCAD @VERSION@ + @VERSIONDATE@ + https://raw.github.com/openscad/openscad/openscad-@VERSION@/RELEASE_NOTES + + + + diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt index c51c919c..db5b6965 100644 --- a/doc/release-checklist.txt +++ b/doc/release-checklist.txt @@ -44,7 +44,8 @@ o Notify package managers Build and Upload Release Binaries --------------------------------- -$ export VERSION= +$ export VERSIONDATE= +$ export VERSION= # If development snapshot, you don't need version is the same as VERSIONDATE $ tar xzf openscad-$VERSION.src.tar.gz $ cd openscad-$VERSION diff --git a/icons/prefsUpdate.png b/icons/prefsUpdate.png new file mode 100644 index 0000000000000000000000000000000000000000..a7dc02eeb9cbb522a468dc4b9d5a43bfbc3c998a GIT binary patch literal 10909 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 literal 0 HcmV?d00001 diff --git a/mjau.gdb b/mjau.gdb index 7b8e0296..6d394114 100644 --- a/mjau.gdb +++ b/mjau.gdb @@ -1 +1,2 @@ set environment DYLD_LIBRARY_PATH=/Users/kintel/code/OpenSCAD/libraries/install/lib +set environment DYLD_FRAMEWORK_PATH=/Users/kintel/code/OpenSCAD/libraries/install/lib diff --git a/openscad.pro b/openscad.pro index a7088ecc..c624b2e2 100644 --- a/openscad.pro +++ b/openscad.pro @@ -68,7 +68,7 @@ macx { APP_RESOURCES.path = Contents/Resources APP_RESOURCES.files = OpenSCAD.sdef QMAKE_BUNDLE_DATA += APP_RESOURCES - LIBS += -framework Carbon + LIBS += -framework Cocoa -framework Sparkle } else { TARGET = openscad @@ -320,8 +320,14 @@ SOURCES += src/cgalutils.cc \ macx { HEADERS += src/AppleEvents.h \ - src/EventFilter.h - SOURCES += src/AppleEvents.cc + src/EventFilter.h \ + src/AutoUpdater.h \ + src/SparkleAutoUpdater.h \ + src/CocoaInitializer.h + SOURCES += src/AppleEvents.cc \ + src/AutoUpdater.cc + OBJECTIVE_SOURCES += src/SparkleAutoUpdater.mm \ + src/CocoaInitializer.mm } isEmpty(PREFIX):PREFIX = /usr/local diff --git a/openscad.qrc b/openscad.qrc index 84745e9f..28b6a72d 100644 --- a/openscad.qrc +++ b/openscad.qrc @@ -4,6 +4,7 @@ icons/prefsAdvanced.png icons/prefs3DView.png icons/prefsEditor.png + icons/prefsUpdate.png icons/flattr.png src/AboutDialog.html diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index e22e5bdd..f9c693ba 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -1,10 +1,13 @@ #!/bin/sh -# NB! To build a release build, the VERSION environment variable needs to be set. +# NB! To build a release build, the VERSION and VERSIONDATE environment variables needs to be set. # See doc/release-checklist.txt +if test -z "$VERSIONDATE"; then + VERSIONDATE=`date "+%Y.%m.%d"` +fi if test -z "$VERSION"; then - VERSION=`date "+%Y.%m.%d"` + VERSION=$VERSIONDATE COMMIT=-c SNAPSHOT=true fi @@ -18,21 +21,33 @@ export OPENSCAD_LIBRARIES=$PWD/../libraries/install # Make sure that the correct Qt tools are used export PATH=$OPENSCAD_LIBRARIES/bin:$PATH -`dirname $0`/release-common.sh -v $VERSION $COMMIT -if [[ $? != 0 ]]; then - exit 1 -fi +#`dirname $0`/release-common.sh -v $VERSION $COMMIT +#if [[ $? != 0 ]]; then +# exit 1 +#fi echo "Sanity check of the app bundle..." -`dirname $0`/macosx-sanity-check.py OpenSCAD.app/Contents/MacOS/OpenSCAD -if [[ $? != 0 ]]; then - exit 1 +#`dirname $0`/macosx-sanity-check.py OpenSCAD.app/Contents/MacOS/OpenSCAD +#if [[ $? != 0 ]]; then +# exit 1 +#fi + +if [[ $VERSION == $VERSIONDATE ]]; then + APPCASTFILE=appcast-snapshots.xml +else + APPCASTFILE=appcast.xml +fi +echo "Creating appcast $APPCASTFILE..." +sed -e "s,@VERSION@,$VERSION,g" -e "s,@VERSIONDATE@,$VERSIONDATE,g" -e "s,@FILESIZE@,$(stat -f "%z" OpenSCAD-$VERSION.dmg),g" $APPCASTFILE.in > $APPCASTFILE +cp $APPCASTFILE ../openscad.github.com +if [[ $VERSION == $VERSIONDATE ]]; then + cp $APPCASTFILE ../openscad.github.com/appcast-snapshots.xml fi echo "Uploading..." -LABELS=OpSys-OSX,Type-Executable -if ! $SNAPSHOT; then LABELS=$LABELS,Featured; fi -`dirname $0`/googlecode_upload.py -s 'Mac OS X Snapshot' -p openscad OpenSCAD-$VERSION.dmg -l $LABELS +#LABELS=OpSys-OSX,Type-Executable +#if ! $SNAPSHOT; then LABELS=$LABELS,Featured; fi +#`dirname $0`/googlecode_upload.py -s 'Mac OS X Snapshot' -p openscad OpenSCAD-$VERSION.dmg -l $LABELS # Update snapshot filename on wab page -`dirname $0`/update-web.sh OpenSCAD-$VERSION.dmg +#`dirname $0`/update-web.sh OpenSCAD-$VERSION.dmg diff --git a/scripts/release-common.sh b/scripts/release-common.sh index de14cb17..a30d43a8 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -9,10 +9,12 @@ # # Usage: release-common.sh [-v ] [-c] [-x32] # -v Version string (e.g. -v 2010.01) +# -d Version date (e.g. -d 2010.01.23) # -c Build with commit info # -mingw32 Cross-compile for win32 using MXE # -# If no version string is given, todays date will be used (YYYY-MM-DD) +# If no version string or version date is given, todays date will be used (YYYY-MM-DD) +# If only verion date is given, it will be used also as version string. # If no make target is given, release will be used on Windows, none one Mac OS X # # The commit info will extracted from git and be passed to qmake as OPENSCAD_COMMIT @@ -23,7 +25,7 @@ printUsage() { - echo "Usage: $0 -v -c -mingw32 + echo "Usage: $0 -v -d -c -mingw32 echo echo " Example: $0 -v 2010.01 } @@ -59,16 +61,20 @@ else exit fi -while getopts 'v:c' c +while getopts 'v:d:c' c do case $c in v) VERSION=$OPTARG;; + d) VERSIONDATE=$OPTARG;; c) OPENSCAD_COMMIT=`git log -1 --pretty=format:"%h"` esac done +if test -z "$VERSIONDATE"; then + VERSIONDATE=`date "+%Y.%m.%d"` +fi if test -z "$VERSION"; then - VERSION=`date "+%Y.%m.%d"` + VERSION=$VERSIONDATE fi @@ -102,7 +108,7 @@ if [ -d .git ]; then git submodule update fi -echo "Building openscad-$VERSION $CONFIGURATION..." +echo "Building openscad-$VERSION ($VERSIONDATE) $CONFIGURATION..." case $OS in LINUX|MACOSX) @@ -230,6 +236,7 @@ echo "Creating archive.." case $OS in MACOSX) + /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $VERSIONDATE" OpenSCAD.app/Contents/Info.plist macdeployqt OpenSCAD.app -dmg -no-strip mv OpenSCAD.dmg OpenSCAD-$VERSION.dmg hdiutil internet-enable -yes -quiet OpenSCAD-$VERSION.dmg diff --git a/setenv_mjau.sh b/setenv_mjau.sh index 943ae6b2..7976c609 100644 --- a/setenv_mjau.sh +++ b/setenv_mjau.sh @@ -1,5 +1,6 @@ export OPENSCAD_LIBRARIES=$PWD/../libraries/install export DYLD_LIBRARY_PATH=$OPENSCAD_LIBRARIES/lib +export DYLD_FRAMEWORK_PATH=$OPENSCAD_LIBRARIES/lib export QMAKESPEC=macx-g++ #export OPENCSGDIR=$PWD/../OpenCSG-1.3.0 diff --git a/src/AutoUpdater.cc b/src/AutoUpdater.cc new file mode 100644 index 00000000..b64cc827 --- /dev/null +++ b/src/AutoUpdater.cc @@ -0,0 +1,3 @@ +#include "AutoUpdater.h" + +AutoUpdater *AutoUpdater::updater_instance = NULL; diff --git a/src/AutoUpdater.h b/src/AutoUpdater.h new file mode 100644 index 00000000..18527c8f --- /dev/null +++ b/src/AutoUpdater.h @@ -0,0 +1,25 @@ +#ifndef AUTOUPDATER_H_ +#define AUTOUPDATER_H_ + +#include + +class AutoUpdater +{ +public: + virtual ~AutoUpdater() {} + + virtual void checkForUpdates() = 0; + virtual void setAutomaticallyChecksForUpdates(bool on) = 0; + virtual bool automaticallyChecksForUpdates() = 0; + virtual void setEnableSnapshots(bool on) = 0; + virtual bool enableSnapshots() = 0; + virtual QString lastUpdateCheckDate() = 0; + + static AutoUpdater *updater() { return updater_instance; } + static void setUpdater(AutoUpdater *updater) { updater_instance = updater; } + +protected: + static AutoUpdater *updater_instance; +}; + +#endif diff --git a/src/MainWindow.h b/src/MainWindow.h index a4835c24..033ef498 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -91,6 +91,7 @@ private: class QMessageBox *openglbox; private slots: + void actionUpdateCheck(); void actionNew(); void actionOpen(); void actionOpenRecent(); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index f71ac96c..4b1639bf 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -223,6 +223,7 @@ + @@ -611,6 +612,9 @@ + + true + About @@ -676,6 +680,14 @@ Library info + + + false + + + Check for Update.. + + diff --git a/src/Preferences.cc b/src/Preferences.cc index ec660940..fe7462ad 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -29,7 +29,9 @@ #include #include #include +#include #include "PolySetCache.h" +#include "AutoUpdater.h" #ifdef ENABLE_CGAL #include "CGALCache.h" #endif @@ -88,6 +90,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) QActionGroup *group = new QActionGroup(this); group->addAction(prefsAction3DView); group->addAction(prefsActionEditor); + group->addAction(prefsActionUpdate); group->addAction(prefsActionAdvanced); connect(group, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); @@ -155,6 +158,9 @@ Preferences::actionTriggered(QAction *action) else if (action == this->prefsActionEditor) { this->stackedWidget->setCurrentWidget(this->pageEditor); } + else if (action == this->prefsActionUpdate) { + this->stackedWidget->setCurrentWidget(this->pageUpdate); + } else if (action == this->prefsActionAdvanced) { this->stackedWidget->setCurrentWidget(this->pageAdvanced); } @@ -186,6 +192,27 @@ void Preferences::on_fontSize_editTextChanged(const QString &size) emit fontChanged(getValue("editor/fontfamily").toString(), intsize); } +void Preferences::on_updateCheckBox_toggled(bool on) +{ + if (AutoUpdater *updater =AutoUpdater::updater()) { + updater->setAutomaticallyChecksForUpdates(on); + } +} + +void Preferences::on_snapshotCheckBox_toggled(bool on) +{ + if (AutoUpdater *updater =AutoUpdater::updater()) { + updater->setEnableSnapshots(on); + } +} + +void Preferences::on_checkNowButton_clicked() +{ + if (AutoUpdater *updater =AutoUpdater::updater()) { + updater->checkForUpdates(); + } +} + void Preferences::on_openCSGWarningBox_toggled(bool state) { @@ -289,6 +316,12 @@ void Preferences::updateGUI() this->fontSize->setEditText(fontsize); } + if (AutoUpdater *updater = AutoUpdater::updater()) { + this->updateCheckBox->setChecked(updater->automaticallyChecksForUpdates()); + this->snapshotCheckBox->setChecked(updater->enableSnapshots()); + this->lastCheckedLabel->setText(updater->lastUpdateCheckDate()); + } + this->openCSGWarningBox->setChecked(getValue("advanced/opencsg_show_warning").toBool()); this->enableOpenCSGBox->setChecked(getValue("advanced/enable_opencsg_opengl1x").toBool()); this->cgalCacheSizeEdit->setText(getValue("advanced/cgalCacheSize").toString()); diff --git a/src/Preferences.h b/src/Preferences.h index 48e07b48..46567939 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -30,6 +30,9 @@ public slots: void on_polysetCacheSizeEdit_textChanged(const QString &); void on_opencsgLimitEdit_textChanged(const QString &); void on_forceGoldfeatherBox_toggled(bool); + void on_updateCheckBox_toggled(bool); + void on_snapshotCheckBox_toggled(bool); + void on_checkNowButton_clicked(); signals: void requestRedraw() const; diff --git a/src/Preferences.ui b/src/Preferences.ui index 9b4671a4..d67db6a5 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -6,10 +6,16 @@ 0 0 - 531 - 418 + 473 + 320 + + + 0 + 0 + + Preferences @@ -173,6 +179,150 @@ + + + + + + + + + + Automatically check for updates + + + true + + + + + + + Include development snapshots + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Check Now + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 11 + + + + Last checked: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 89 + + + + + + @@ -227,9 +377,6 @@ - openCSGWarningBox - enableOpenCSGBox - forceGoldfeatherBox @@ -317,6 +464,7 @@ + @@ -355,6 +503,18 @@ Editor + + + true + + + + :/icons/prefsUpdate.png:/icons/prefsUpdate.png + + + Update + + diff --git a/src/SparkleAutoUpdater.h b/src/SparkleAutoUpdater.h new file mode 100644 index 00000000..786a190b --- /dev/null +++ b/src/SparkleAutoUpdater.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 Remko Troncon. BSD license + * Copyright (C) 2013 Marius Kintel. BSD license + */ +#ifndef SPARKLEAUTOUPDATER_H +#define SPARKLEAUTOUPDATER_H + +#include + +#include "AutoUpdater.h" + +class SparkleAutoUpdater : public AutoUpdater +{ +public: + SparkleAutoUpdater(); + ~SparkleAutoUpdater(); + + void checkForUpdates(); + void setAutomaticallyChecksForUpdates(bool on); + bool automaticallyChecksForUpdates(); + void setEnableSnapshots(bool on); + bool enableSnapshots(); + QString lastUpdateCheckDate(); + +private: + void updateFeed(); + + class Private; + Private *d; +}; + +#endif diff --git a/src/SparkleAutoUpdater.mm b/src/SparkleAutoUpdater.mm new file mode 100644 index 00000000..5176e80f --- /dev/null +++ b/src/SparkleAutoUpdater.mm @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 Remko Troncon. BSD license + * Copyright (C) 2013 Marius Kintel. BSD license + */ + +#include "SparkleAutoUpdater.h" + +#include +#include + +NSString *const SUEnableSnapshotsKey = @"SUEnableSnapshots"; + +class SparkleAutoUpdater::Private +{ +public: + SUUpdater* updater; +}; + +SparkleAutoUpdater::SparkleAutoUpdater() +{ + d = new Private; + + d->updater = [SUUpdater sharedUpdater]; + [d->updater retain]; + + updateFeed(); +} + +SparkleAutoUpdater::~SparkleAutoUpdater() +{ + [d->updater release]; + delete d; +} + +void SparkleAutoUpdater::checkForUpdates() +{ + [d->updater checkForUpdatesInBackground]; +} + +void SparkleAutoUpdater::setAutomaticallyChecksForUpdates(bool on) +{ + [d->updater setAutomaticallyChecksForUpdates:on]; +} + +bool SparkleAutoUpdater::automaticallyChecksForUpdates() +{ + return [d->updater automaticallyChecksForUpdates]; +} + +void SparkleAutoUpdater::setEnableSnapshots(bool on) +{ + [[NSUserDefaults standardUserDefaults] setBool:on forKey:SUEnableSnapshotsKey]; + updateFeed(); +} + +bool SparkleAutoUpdater::enableSnapshots() +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:SUEnableSnapshotsKey]; +} + +QString SparkleAutoUpdater::lastUpdateCheckDate() +{ + NSString *datestring = [NSString stringWithFormat:@"Last checked: %@", + [d->updater lastUpdateCheckDate]]; + return QString::fromUtf8([datestring UTF8String]); +} + +void SparkleAutoUpdater::updateFeed() +{ + NSString *urlstring = [NSString stringWithFormat:@"http://openscad.org/appcast%@.xml", enableSnapshots() ? @"-snapshots" : @""]; + [d->updater setFeedURL:[NSURL URLWithString:urlstring]]; +} diff --git a/src/mainwin.cc b/src/mainwin.cc index 17b9ef7a..a05a4d4b 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -48,6 +48,7 @@ #include "ProgressWidget.h" #include "ThrownTogetherRenderer.h" #include "csgtermnormalizer.h" +#include "AutoUpdater.h" #include #include @@ -205,6 +206,16 @@ MainWindow::MainWindow(const QString &filename) animate_panel->hide(); + // Application menu +#ifdef DEBUG + this->appActionUpdateCheck->setEnabled(false); +#else +#ifdef Q_OS_MAC + this->appActionUpdateCheck->setMenuRole(QAction::ApplicationSpecificRole); + this->appActionUpdateCheck->setEnabled(true); + connect(this->appActionUpdateCheck, SIGNAL(triggered()), this, SLOT(actionUpdateCheck())); +#endif +#endif // File menu connect(this->fileActionNew, SIGNAL(triggered()), this, SLOT(actionNew())); connect(this->fileActionOpen, SIGNAL(triggered()), this, SLOT(actionOpen())); @@ -781,6 +792,13 @@ void MainWindow::compileCSG(bool procevents) } } +void MainWindow::actionUpdateCheck() +{ + if (AutoUpdater *updater =AutoUpdater::updater()) { + updater->checkForUpdates(); + } +} + void MainWindow::actionNew() { #ifdef ENABLE_MDI diff --git a/src/openscad.cc b/src/openscad.cc index 880aa0da..e0b4a680 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -54,6 +54,7 @@ #ifdef Q_WS_MAC #include "EventFilter.h" #include "AppleEvents.h" +#include "SparkleAutoUpdater.h" #endif #include @@ -386,6 +387,14 @@ int main(int argc, char **argv) installAppleEventHandlers(); #endif +#ifndef DEBUG +#ifdef Q_WS_MAC + AutoUpdater *updater = new SparkleAutoUpdater; + AutoUpdater::setUpdater(updater); + if (updater->automaticallyChecksForUpdates()) updater->checkForUpdates(); +#endif +#endif + QString qfilename; if (filename) qfilename = QString::fromStdString(boosty::stringy(boosty::absolute(filename)));