diff --git a/Libs/Common/Logging.h b/Libs/Common/Logging.h
index 9d44f4e6af..3b69f80f07 100644
--- a/Libs/Common/Logging.h
+++ b/Libs/Common/Logging.h
@@ -187,4 +187,13 @@ class Logging {
//! Close session macro
#define SW_CLOSE_LOG() shapeworks::Logging::Instance().close_log();
+//! Log once macro, will only log the message once
+#define SW_LOG_ONCE(message, ...) \
+{ \
+ static bool logged = false; \
+ if (!logged) { \
+ SW_LOG(message, ##__VA_ARGS__); \
+ logged = true; \
+ } \
+}
} // namespace shapeworks
diff --git a/Libs/Optimize/Constraints.cpp b/Libs/Optimize/Constraints.cpp
index d7348d910a..a1143523f0 100644
--- a/Libs/Optimize/Constraints.cpp
+++ b/Libs/Optimize/Constraints.cpp
@@ -777,7 +777,6 @@ bool Constraints::hasConstraints() {
return true;
}
- SW_LOG("no constraints");
return false;
}
diff --git a/Libs/Project/ProjectUtils.cpp b/Libs/Project/ProjectUtils.cpp
index 4a672d3295..a6beef55b9 100644
--- a/Libs/Project/ProjectUtils.cpp
+++ b/Libs/Project/ProjectUtils.cpp
@@ -140,7 +140,7 @@ StringList ProjectUtils::get_values(StringList prefixes, StringList domain_names
for (auto& [key, value] : key_map) {
for (const auto& prefix : prefixes) {
if (key == prefix + domain) {
- values.push_back(value);
+ values.push_back(StringUtils::replace_string(value, "\\", "/"));
}
}
}
diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp
index 73b004a686..2cf773093a 100644
--- a/Studio/Analysis/AnalysisTool.cpp
+++ b/Studio/Analysis/AnalysisTool.cpp
@@ -920,17 +920,19 @@ void AnalysisTool::enable_actions(bool newly_enabled) {
update_domain_alignment_box();
}
- auto domain_types = session_->get_groomed_domain_types();
- bool image_domain = domain_types.size() > 0 && domain_types[0] == DomainType::Image;
- ui_->distance_transfom_radio_button->setEnabled(session_->particles_present() && session_->get_groomed_present() &&
- image_domain);
+ if (session_->particles_present()) {
+ auto domain_types = session_->get_groomed_domain_types();
+ bool image_domain = domain_types.size() > 0 && domain_types[0] == DomainType::Image;
+ ui_->distance_transfom_radio_button->setEnabled(session_->particles_present() && session_->get_groomed_present() &&
+ image_domain);
- ui_->mesh_warping_radio_button->setEnabled(session_->particles_present() && session_->get_groomed_present());
+ ui_->mesh_warping_radio_button->setEnabled(session_->particles_present() && session_->get_groomed_present());
- if (!ui_->mesh_warping_radio_button->isEnabled()) {
- ui_->legacy_radio_button->setChecked(true);
+ if (!ui_->mesh_warping_radio_button->isEnabled()) {
+ ui_->legacy_radio_button->setChecked(true);
+ }
+ reconstruction_method_changed();
}
- reconstruction_method_changed();
update_group_boxes();
ui_->sampleSpinBox->setMaximum(session_->get_num_shapes() - 1);
diff --git a/Studio/Analysis/AnalysisTool.ui b/Studio/Analysis/AnalysisTool.ui
index 6976368958..7eaad8b4bd 100644
--- a/Studio/Analysis/AnalysisTool.ui
+++ b/Studio/Analysis/AnalysisTool.ui
@@ -535,7 +535,7 @@ QWidget#particles_panel {
-
- 2
+ 0
@@ -603,7 +603,7 @@ QWidget#particles_panel {
-
-
+
Group slider
@@ -1059,16 +1059,10 @@ QWidget#particles_panel {
-
-
+
false
-
-
- 100
- 0
-
-
Standard deviation slider
@@ -2190,6 +2184,11 @@ Reference Domain
jkqtplotter/jkqtplotter.h
1
+
+ CustomSlider
+ QSlider
+
+
diff --git a/Studio/CMakeLists.txt b/Studio/CMakeLists.txt
index ea09d5e110..56b3c99924 100644
--- a/Studio/CMakeLists.txt
+++ b/Studio/CMakeLists.txt
@@ -169,6 +169,7 @@ SET(STUDIO_UTILS_MOC_HDRS
SET(STUDIO_INTERFACE_SRCS
Interface/CompareWidget.cpp
+ Interface/CustomSlider.cpp
Interface/ExportImageDialog.cpp
Interface/KeyboardShortcuts.cpp
Interface/LogWindow.cpp
@@ -182,6 +183,7 @@ SET(STUDIO_INTERFACE_SRCS
)
SET(STUDIO_INTERFACE_MOC_HDRS
Interface/CompareWidget.h
+ Interface/CustomSlider.h
Interface/ExportImageDialog.h
Interface/KeyboardShortcuts.h
Interface/LogWindow.h
diff --git a/Studio/Data/DataTool.cpp b/Studio/Data/DataTool.cpp
index 020e971c58..ed89cc1550 100644
--- a/Studio/Data/DataTool.cpp
+++ b/Studio/Data/DataTool.cpp
@@ -109,7 +109,7 @@ void DataTool::set_session(QSharedPointer session) {
connect(session.data(), &Session::ffc_changed, this, &DataTool::update_ffc_table);
landmark_table_model_->set_session(session);
- connect(ui_->ffc_brush_size_, &QSlider::valueChanged, session.data(), &Session::set_ffc_paint_size);
+ connect(ui_->ffc_brush_size_, &CustomSlider::valueChanged, session.data(), &Session::set_ffc_paint_size);
connect(ui_->ffc_included_mode_, &QRadioButton::toggled, session.data(), &Session::set_ffc_paint_mode_inclusive);
connect(ui_->ffc_active_, &QCheckBox::toggled, session.data(), &Session::set_ffc_paint_active);
diff --git a/Studio/Data/DataTool.ui b/Studio/Data/DataTool.ui
index 3b20dd691a..eaed9088c7 100644
--- a/Studio/Data/DataTool.ui
+++ b/Studio/Data/DataTool.ui
@@ -381,8 +381,8 @@ QWidget#specificity_panel {
0
0
- 470
- 340
+ 464
+ 330
@@ -848,7 +848,7 @@ QWidget#specificity_panel {
-
-
+
5
@@ -1053,7 +1053,14 @@ QWidget#specificity_panel {
-
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+</style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
@@ -1078,6 +1085,13 @@ QWidget#specificity_panel {
+
+
+ CustomSlider
+ QSlider
+
+
+
diff --git a/Studio/Data/PreferencesWindow.cpp b/Studio/Data/PreferencesWindow.cpp
index 3d49ea4c33..48be5ad709 100644
--- a/Studio/Data/PreferencesWindow.cpp
+++ b/Studio/Data/PreferencesWindow.cpp
@@ -46,7 +46,7 @@ PreferencesWindow::PreferencesWindow(QWidget* parent, Preferences& prefs) : pref
&PreferencesWindow::save_to_preferences);
connect(ui_->orientation_marker_corner, qOverload(&QComboBox::currentIndexChanged), this,
&PreferencesWindow::save_to_preferences);
- connect(ui_->geodesic_cache_multiplier, &QSlider::valueChanged, this, &PreferencesWindow::save_to_preferences);
+ connect(ui_->geodesic_cache_multiplier, &CustomSlider::valueChanged, this, &PreferencesWindow::save_to_preferences);
connect(ui_->color_map, qOverload(&QComboBox::currentIndexChanged), this,
&PreferencesWindow::save_to_preferences);
connect(ui_->particle_colors, qOverload(&QComboBox::currentIndexChanged), this,
diff --git a/Studio/Data/PreferencesWindow.ui b/Studio/Data/PreferencesWindow.ui
index 99781038d7..16259c0e9c 100644
--- a/Studio/Data/PreferencesWindow.ui
+++ b/Studio/Data/PreferencesWindow.ui
@@ -107,7 +107,7 @@
-
-
+
0
@@ -200,7 +200,7 @@
-
-
+
100
@@ -240,7 +240,7 @@
-
-
+
1
@@ -587,6 +587,13 @@
+
+
+ CustomSlider
+ QSlider
+
+
+
pca_range
pca_steps
diff --git a/Studio/Data/Telemetry.cpp b/Studio/Data/Telemetry.cpp
index 21a931a8f6..081c48d83b 100644
--- a/Studio/Data/Telemetry.cpp
+++ b/Studio/Data/Telemetry.cpp
@@ -43,12 +43,12 @@ void Telemetry::record_event(const QString& name, const QVariantMap& params) {
QString api_secret{GA_API_SECRET};
if (measurement_id.isEmpty() || api_secret.isEmpty()) {
- SW_LOG("Telemetry disabled, no measurement id or api secret");
+ SW_LOG_ONCE("Telemetry disabled, no measurement id or api secret");
return;
}
if (!prefs_.get_telemetry_enabled()) {
- SW_LOG("Telemetry disabled by preferences");
+ SW_LOG_ONCE("Telemetry disabled by preferences");
return;
}
diff --git a/Studio/Groom/GroomTool.cpp b/Studio/Groom/GroomTool.cpp
index 411ce09f80..a4b51d8a6c 100644
--- a/Studio/Groom/GroomTool.cpp
+++ b/Studio/Groom/GroomTool.cpp
@@ -73,13 +73,13 @@ GroomTool::GroomTool(Preferences& prefs, Telemetry& telemetry) : preferences_(pr
"Set the adaptivity of remeshing, higher will allocate more triangles around areas of high curvature.");
// connect percent controls
- connect(ui_->remesh_percent_slider, &QSlider::valueChanged, this,
+ connect(ui_->remesh_percent_slider, &CustomSlider::valueChanged, this,
[this](int value) { ui_->remesh_percent_spinbox->setValue(value); });
connect(ui_->remesh_percent_spinbox, qOverload(&QDoubleSpinBox::valueChanged), this,
[=](double value) { ui_->remesh_percent_slider->setValue(static_cast(value)); });
// connect gradation controls
- connect(ui_->remesh_gradation_slider, &QSlider::valueChanged, this,
+ connect(ui_->remesh_gradation_slider, &CustomSlider::valueChanged, this,
[=](int value) { ui_->remesh_gradation_spinbox->setValue(value / 50.0); });
connect(ui_->remesh_gradation_spinbox, qOverload(&QDoubleSpinBox::valueChanged), this,
[=](double value) { ui_->remesh_gradation_slider->setValue(static_cast(value * 50.0)); });
diff --git a/Studio/Groom/GroomTool.ui b/Studio/Groom/GroomTool.ui
index 747718b6f6..30880f04eb 100644
--- a/Studio/Groom/GroomTool.ui
+++ b/Studio/Groom/GroomTool.ui
@@ -1607,7 +1607,7 @@ QWidget#domain_panel {
-
-
+
100
@@ -1620,7 +1620,7 @@ QWidget#domain_panel {
-
-
+
100
@@ -2013,6 +2013,13 @@ QWidget#domain_panel {
+
+
+ CustomSlider
+ QSlider
+
+
+
mesh_fill_holes
mesh_smooth
diff --git a/Studio/Interface/CompareWidget.cpp b/Studio/Interface/CompareWidget.cpp
index a771dde412..f900d03f4c 100644
--- a/Studio/Interface/CompareWidget.cpp
+++ b/Studio/Interface/CompareWidget.cpp
@@ -12,7 +12,7 @@ CompareWidget::CompareWidget(QWidget *parent) : QWidget(parent), ui_(new Ui::Com
connect(ui_->original, &QCheckBox::toggled, this, &CompareWidget::settings_changed);
connect(ui_->groomed, &QCheckBox::toggled, this, &CompareWidget::settings_changed);
connect(ui_->reconstructed, &QCheckBox::toggled, this, &CompareWidget::settings_changed);
- connect(ui_->opacity, &QSlider::valueChanged, this, &CompareWidget::settings_changed);
+ connect(ui_->opacity, &CustomSlider::valueChanged, this, &CompareWidget::settings_changed);
connect(ui_->mean_shape, &QCheckBox::toggled, this, &CompareWidget::settings_changed);
}
diff --git a/Studio/Interface/CompareWidget.ui b/Studio/Interface/CompareWidget.ui
index ad60f1aa2d..e14b272c06 100644
--- a/Studio/Interface/CompareWidget.ui
+++ b/Studio/Interface/CompareWidget.ui
@@ -7,7 +7,7 @@
0
0
470
- 159
+ 172
@@ -15,7 +15,7 @@
-
-
+
100
@@ -74,6 +74,13 @@
+
+
+ CustomSlider
+ QSlider
+
+
+
diff --git a/Studio/Interface/CustomSlider.cpp b/Studio/Interface/CustomSlider.cpp
new file mode 100644
index 0000000000..49a00c0955
--- /dev/null
+++ b/Studio/Interface/CustomSlider.cpp
@@ -0,0 +1,71 @@
+
+
+#include "CustomSlider.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "math.h"
+
+CustomSlider::CustomSlider(QWidget* parent) : QSlider(parent) {
+ this->setStyleSheet(
+ "\
+ QSlider {\
+ min-height: 24px\
+ }\
+ QSlider::groove:horizontal {\
+ border: 1px solid #262626;\
+ height: 3px;\
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);\
+ margin: 0 5px;\
+ }\
+ \
+ QSlider::handle:horizontal {\
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f);\
+ border: 1px solid #5c5c5c;\
+ width: 12px;\
+ margin: -8px -6px;\
+ border-radius: 3px;\
+ }\
+ ");
+};
+
+void CustomSlider::paintEvent(QPaintEvent* ev) {
+ QStylePainter p(this);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ QRect handle = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+
+ // draw tick marks
+ // do this manually because they are very badly behaved with style sheets
+ int interval = tickInterval();
+ if (interval == 0) {
+ interval = pageStep();
+ }
+
+ if (tickPosition() != NoTicks) {
+ for (int i = minimum(); i <= maximum(); i += interval) {
+ int x =
+ std::round((double)((double)((double)(i - this->minimum()) / (double)(this->maximum() - this->minimum())) *
+ (double)(this->width() - handle.width()) +
+ (double)(handle.width() / 2.0))) -
+ 1;
+ int h = 4;
+ p.setPen(QColor("#a5a294"));
+ if (tickPosition() == TicksBothSides || tickPosition() == TicksAbove) {
+ int y = this->rect().top();
+ p.drawLine(x, y, x, y + h);
+ }
+ if (tickPosition() == TicksBothSides || tickPosition() == TicksBelow) {
+ int y = this->rect().bottom();
+ p.drawLine(x, y, x, y - h);
+ }
+ }
+ }
+
+ QSlider::paintEvent(ev);
+}
diff --git a/Studio/Interface/CustomSlider.h b/Studio/Interface/CustomSlider.h
new file mode 100644
index 0000000000..2c76041cbe
--- /dev/null
+++ b/Studio/Interface/CustomSlider.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include
+
+// adapted from:
+// https://stackoverflow.com/questions/69890284/qslider-in-qt-misbehaves-in-new-macos-monterey-v12-0-1-any-workaround/69890285#69890285
+class CustomSlider : public QSlider {
+ public:
+ explicit CustomSlider(Qt::Orientation orientation, QWidget* parent = nullptr) : QSlider(orientation, parent){};
+ explicit CustomSlider(QWidget* parent = nullptr);
+
+ protected:
+ virtual void paintEvent(QPaintEvent* ev);
+};
\ No newline at end of file
diff --git a/Studio/Interface/ShapeWorksStudioApp.cpp b/Studio/Interface/ShapeWorksStudioApp.cpp
index 40a0665b9d..7336b5fb23 100644
--- a/Studio/Interface/ShapeWorksStudioApp.cpp
+++ b/Studio/Interface/ShapeWorksStudioApp.cpp
@@ -729,7 +729,7 @@ void ShapeWorksStudioApp::create_glyph_submenu() {
layout->addWidget(glyph_size_label_, 0, 1, 1, 1);
layout->addWidget(glyph_quality_label_, 1, 1, 1, 1);
- glyph_size_slider_ = new QSlider(widget);
+ glyph_size_slider_ = new CustomSlider(widget);
glyph_size_slider_->setOrientation(Qt::Horizontal);
glyph_size_slider_->setMinimum(1);
glyph_size_slider_->setMaximum(100);
@@ -742,7 +742,7 @@ void ShapeWorksStudioApp::create_glyph_submenu() {
glyph_arrow_scale_ = new QCheckBox("Scale arrows");
- glyph_quality_slider_ = new QSlider(widget);
+ glyph_quality_slider_ = new CustomSlider(widget);
glyph_quality_slider_->setMinimum(1);
glyph_quality_slider_->setMaximum(20);
glyph_quality_slider_->setPageStep(3);
@@ -766,8 +766,8 @@ void ShapeWorksStudioApp::create_glyph_submenu() {
glyph_quality_label_->setText(QString::number(preferences_.get_glyph_quality()));
glyph_size_label_->setText(QString::number(preferences_.get_glyph_size()));
- connect(glyph_size_slider_, &QSlider::valueChanged, this, &ShapeWorksStudioApp::handle_glyph_changed);
- connect(glyph_quality_slider_, &QSlider::valueChanged, this, &ShapeWorksStudioApp::handle_glyph_changed);
+ connect(glyph_size_slider_, &CustomSlider::valueChanged, this, &ShapeWorksStudioApp::handle_glyph_changed);
+ connect(glyph_quality_slider_, &CustomSlider::valueChanged, this, &ShapeWorksStudioApp::handle_glyph_changed);
connect(glyph_auto_size_, &QCheckBox::clicked, this, &ShapeWorksStudioApp::handle_glyph_changed);
connect(glyph_arrow_scale_, &QCheckBox::clicked, this, &ShapeWorksStudioApp::handle_glyph_changed);
@@ -829,7 +829,7 @@ void ShapeWorksStudioApp::create_iso_submenu() {
QLabel* size_label = new QLabel(text);
layout->addWidget(size_label, row, 0, 1, 1);
- QSlider* slider = new QSlider(widget);
+ CustomSlider* slider = new CustomSlider(widget);
slider->setOrientation(Qt::Horizontal);
slider->setMinimum(1);
slider->setMaximum(100);
@@ -838,7 +838,7 @@ void ShapeWorksStudioApp::create_iso_submenu() {
slider->setTickInterval(10);
slider->setValue(100);
slider->setMinimumWidth(200);
- connect(slider, &QSlider::valueChanged, this, &ShapeWorksStudioApp::handle_opacity_changed);
+ connect(slider, &CustomSlider::valueChanged, this, &ShapeWorksStudioApp::handle_opacity_changed);
layout->addWidget(slider, row, 1, 1, 1);
widget->setLayout(layout);
diff --git a/Studio/Interface/ShapeWorksStudioApp.h b/Studio/Interface/ShapeWorksStudioApp.h
index 16ecf0972e..07663bde63 100644
--- a/Studio/Interface/ShapeWorksStudioApp.h
+++ b/Studio/Interface/ShapeWorksStudioApp.h
@@ -20,9 +20,9 @@
#include
#include
#include
-#include
#include
#include
+#include
// Forward Qt class declarations
class Ui_ShapeWorksStudioApp;
@@ -239,8 +239,8 @@ class ShapeWorksStudioApp : public QMainWindow {
QSharedPointer wheel_event_forwarder_;
// programmatic UI elements
- QSlider* glyph_size_slider_;
- QSlider* glyph_quality_slider_;
+ CustomSlider* glyph_size_slider_;
+ CustomSlider* glyph_quality_slider_;
QLabel* glyph_size_label_;
QLabel* glyph_quality_label_;
QCheckBox* glyph_auto_size_;
@@ -250,7 +250,7 @@ class ShapeWorksStudioApp : public QMainWindow {
QPointer status_bar_;
QSharedPointer splash_screen_;
QErrorMessage error_message_dialog_;
- std::vector iso_opacity_sliders_;
+ std::vector iso_opacity_sliders_;
std::vector domain_particle_checkboxes_;
QString current_message_;
diff --git a/Studio/Interface/ShapeWorksStudioApp.ui b/Studio/Interface/ShapeWorksStudioApp.ui
index bb411e0475..4d824ebc34 100644
--- a/Studio/Interface/ShapeWorksStudioApp.ui
+++ b/Studio/Interface/ShapeWorksStudioApp.ui
@@ -368,7 +368,7 @@ QToolBar QToolButton::checked {
-
-
+
100
@@ -1215,6 +1215,11 @@ QToolBar QToolButton::checked {
+
+ CustomSlider
+ QSlider
+
+
QVTKOpenGLNativeWidget
QWidget
diff --git a/Studio/Interface/UpdateChecker.cpp b/Studio/Interface/UpdateChecker.cpp
index 84fc426038..41d4e9008d 100644
--- a/Studio/Interface/UpdateChecker.cpp
+++ b/Studio/Interface/UpdateChecker.cpp
@@ -58,48 +58,53 @@ void UpdateChecker::handleNetworkReply(QNetworkReply* reply) {
std::string response = QString(reply->readAll()).toStdString();
// get the json response
- auto j = json::parse(response);
-
- std::string platform = StudioUtils::get_platform_string().toStdString();
-
- int major = j[platform]["major"].get();
- int minor = j[platform]["minor"].get();
- int patch = j[platform]["patch"].get();
- QString message = QString::fromStdString(j[platform]["message"].get());
-
- bool update_available = false;
- if (major > SHAPEWORKS_MAJOR_VERSION) {
- update_available = true;
- } else if (major == SHAPEWORKS_MAJOR_VERSION && minor > SHAPEWORKS_MINOR_VERSION) {
- update_available = true;
- } else if (major == SHAPEWORKS_MAJOR_VERSION && minor == SHAPEWORKS_MINOR_VERSION &&
- patch > SHAPEWORKS_PATCH_VERSION) {
- update_available = true;
- }
+ try {
+ auto j = json::parse(response);
+ std::string platform = StudioUtils::get_platform_string().toStdString();
+
+ int major = j[platform]["major"].get();
+ int minor = j[platform]["minor"].get();
+ int patch = j[platform]["patch"].get();
+ QString message = QString::fromStdString(j[platform]["message"].get());
+
+ bool update_available = false;
+ if (major > SHAPEWORKS_MAJOR_VERSION) {
+ update_available = true;
+ } else if (major == SHAPEWORKS_MAJOR_VERSION && minor > SHAPEWORKS_MINOR_VERSION) {
+ update_available = true;
+ } else if (major == SHAPEWORKS_MAJOR_VERSION && minor == SHAPEWORKS_MINOR_VERSION &&
+ patch > SHAPEWORKS_PATCH_VERSION) {
+ update_available = true;
+ }
- if (update_available) {
- auto url = QString("https://github.com/SCIInstitute/ShapeWorks/releases/latest");
-
- auto title = QString("New version available");
- setWindowTitle(title);
- ui_->label->setTextFormat(Qt::RichText);
- ui_->label->setOpenExternalLinks(true);
- ui_->label->setTextInteractionFlags(Qt::TextBrowserInteraction);
- ui_->label->setText(QString("A new version of ShapeWorks is available.
"
- "To download the latest version, please visit:
%1
" +
- message)
- .arg(url));
-
- show();
- raise();
-
- } else {
- if (manual_trigger_) {
- // show a messagebox saying there is no update
- auto title = QString("No update available");
- auto info = QString("You are running the latest version of ShapeWorks.");
- QMessageBox::information(nullptr, title, info, QMessageBox::Ok);
+ if (update_available) {
+ auto url = QString("https://github.com/SCIInstitute/ShapeWorks/releases/latest");
+
+ auto title = QString("New version available");
+ setWindowTitle(title);
+ ui_->label->setTextFormat(Qt::RichText);
+ ui_->label->setOpenExternalLinks(true);
+ ui_->label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ ui_->label->setText(QString("A new version of ShapeWorks is available.
"
+ "To download the latest version, please visit:
%1
" +
+ message)
+ .arg(url));
+
+ show();
+ raise();
+
+ } else {
+ if (manual_trigger_) {
+ // show a messagebox saying there is no update
+ auto title = QString("No update available");
+ auto info = QString("You are running the latest version of ShapeWorks.");
+ QMessageBox::information(nullptr, title, info, QMessageBox::Ok);
+ }
}
+
+ } catch (json::exception& e) {
+ SW_LOG("Unable to check for updates: " + std::string(e.what()));
+ return;
}
}
} // namespace shapeworks
\ No newline at end of file
diff --git a/Studio/Interface/UpdateChecker.h b/Studio/Interface/UpdateChecker.h
index 2fd6042411..0393efe353 100644
--- a/Studio/Interface/UpdateChecker.h
+++ b/Studio/Interface/UpdateChecker.h
@@ -1,10 +1,10 @@
#pragma once
+#include
+
#include
#include
-#include
-
namespace Ui {
class UpdateChecker;
}
@@ -25,7 +25,6 @@ class UpdateChecker : public QDialog {
void run_auto_update_check();
void run_manual_update_check();
-
public Q_SLOTS:
void handleNetworkReply(QNetworkReply* reply);
@@ -38,7 +37,6 @@ class UpdateChecker : public QDialog {
Ui::UpdateChecker* ui_;
Preferences& prefs_;
-
};
} // namespace shapeworks
\ No newline at end of file