Index: macosx/CelestiaAppCore.mm =================================================================== --- macosx/CelestiaAppCore.mm (revision 4157) +++ macosx/CelestiaAppCore.mm (working copy) @@ -595,10 +595,13 @@ case Selection::Type_Star: { - char name[32]; - sprintf(name, "HIP%d", sel.star()->getCatalogNumber() & ~0xf0000000); - - url = string("http://simbad.u-strasbg.fr/sim-id.pl?protocol=html&Ident=") + name; + url = sel.star()->getInfoURL(); + if (url.empty()) + { + char name[32]; + sprintf(name, "HIP%d", sel.star()->getCatalogNumber() & ~0xf0000000); + url = string("http://simbad.u-strasbg.fr/sim-id.pl?protocol=html&Ident=") + name; + } } break; Index: src/celengine/star.h =================================================================== --- src/celengine/star.h (revision 4159) +++ src/celengine/star.h (working copy) @@ -51,6 +51,7 @@ inline bool getVisibility() const; inline const RotationModel* getRotationModel() const; inline Vec3f getEllipsoidSemiAxes() const; + const std::string& getInfoURL() const; void setRadius(float); void setTemperature(float); @@ -65,6 +66,7 @@ void setVisibility(bool); void setRotationModel(const RotationModel*); void setEllipsoidSemiAxes(const Vec3f&); + void setInfoURL(const std::string& _infoURL); bool shared() const; @@ -101,6 +103,8 @@ Vec3f semiAxes; + std::string* infoURL; + std::vector* orbitingStars; bool isShared; @@ -219,6 +223,7 @@ } + class Star { public: @@ -267,6 +272,7 @@ inline uint32 getKnowledge() const; inline const RotationModel* getRotationModel() const; inline Vec3f getEllipsoidSemiAxes() const; + const std::string& getInfoURL() const; enum { MaxTychoCatalogNumber = 0xf0000000, Index: src/celengine/star.cpp =================================================================== --- src/celengine/star.cpp (revision 4159) +++ src/celengine/star.cpp (working copy) @@ -43,6 +43,8 @@ static StarDetails* blackHoleDetails = NULL; static StarDetails* barycenterDetails = NULL; +static string DEFAULT_INFO_URL(""); + StarDetails::StarTextureSet StarDetails::starTextures; // Star temperature data from Lang's _Astrophysical Data: Planets and Stars_ @@ -748,6 +750,7 @@ barycenter(NULL), rotationModel(NULL), semiAxes(1.0f, 1.0f, 1.0f), + infoURL(NULL), orbitingStars(NULL), isShared(true) { @@ -768,20 +771,37 @@ barycenter(sd.barycenter), rotationModel(sd.rotationModel), semiAxes(sd.semiAxes), + infoURL(NULL), orbitingStars(NULL), isShared(false) { assert(sd.isShared); memcpy(spectralType, sd.spectralType, sizeof(spectralType)); + if (sd.infoURL != NULL) + infoURL = new string(*sd.infoURL); } StarDetails::~StarDetails() { delete orbitingStars; + delete infoURL; } +/*! Return the InfoURL. If the InfoURL has not been set, this method + * returns an empty string. + */ +const std::string& +StarDetails::getInfoURL() const +{ + if (infoURL != NULL) + return *infoURL; + else + return DEFAULT_INFO_URL; +} + + void StarDetails::setRadius(float _radius) { @@ -893,7 +913,30 @@ } +/*! Set the InfoURL for this star. +*/ +void +StarDetails::setInfoURL(const string& _infoURL) +{ + if (_infoURL.empty()) + { + // Save space in the common case--no InfoURL--by not + // allocating a string. + delete infoURL; + infoURL = NULL; + } + else + { + // Allocate the new string before freeing the old one, so we don't crash + // in the event the caller does something like: + // star->setInfoURL(star->getInfoURL()); + string* oldURL = infoURL; + infoURL = new string(_infoURL); + delete oldURL; + } +} + Star::~Star() { // TODO: Implement reference counting for StarDetails objects so that @@ -1056,6 +1099,16 @@ } +/*! Return the InfoURL. If the InfoURL has not been set, this method +* returns an empty string. +*/ +const string& +Star::getInfoURL() const +{ + return details->getInfoURL(); +} + + void Star::setCatalogNumber(uint32 n) { catalogNumber = n; Index: src/celengine/stardb.cpp =================================================================== --- src/celengine/stardb.cpp (revision 4159) +++ src/celengine/stardb.cpp (working copy) @@ -925,6 +925,9 @@ double radius; bool hasRadius = starData->getNumber("Radius", radius); + + string infoURL; + bool hasInfoURL = starData->getString("InfoURL", infoURL); Orbit* orbit = CreateOrbit(NULL, starData, path, true); @@ -933,7 +936,8 @@ orbit != NULL || hasSemiAxes || hasRadius || - hasRotationModel) + hasRotationModel || + hasInfoURL) { // If the star definition has extended information, clone the // star details so we can customize it without affecting other @@ -961,6 +965,11 @@ details->setRadius((float) radius); details->addKnowledge(StarDetails::KnowRadius); } + + if (hasInfoURL) + { + details->setInfoURL(infoURL); + } if (orbit != NULL) { Index: src/celestia/winmain.cpp =================================================================== --- src/celestia/winmain.cpp (revision 4157) +++ src/celestia/winmain.cpp (working copy) @@ -1731,10 +1731,13 @@ case Selection::Type_Star: { - char name[32]; - sprintf(name, "HIP%d", sel.star()->getCatalogNumber() & ~0xf0000000); - - url = string("http://simbad.u-strasbg.fr/sim-id.pl?protocol=html&Ident=") + name; + url = sel.star()->getInfoURL(); + if (url.empty()) + { + char name[32]; + sprintf(name, "HIP%d", sel.star()->getCatalogNumber() & ~0xf0000000); + url = string("http://simbad.u-strasbg.fr/sim-id.pl?protocol=html&Ident=") + name; + } } break;