diff --git a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryCommandUtils.h b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryCommandUtils.h index 0c0542911b..80e6954d3e 100755 --- a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryCommandUtils.h +++ b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryCommandUtils.h @@ -1,158 +1,160 @@ /*========================================================================= Program: BlueBerry Platform Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __BERRY_COMMAND_UTILS_H__ #define __BERRY_COMMAND_UTILS_H__ #include #include #include #include namespace berry { /** * A class providing utility functions for the commands plug-in. */ class CommandUtils { public: /** * Compares two boolean values. false is considered to be * less than true. * * @param left * The left value to compare. * @param right * The right value to compare. * @return -1 if left is false * and right is true;0 * if they are equal; 1 if left is * true and right is * false */ static int Compare(const bool left, const bool right); static int Compare(const std::string& left, const std::string& right); /** * Compares two objects that are not otherwise comparable. If neither object * is null, then the string representation of each object is * used. * * @param left * The left value to compare. The string representation of this * value must not be null. * @param right * The right value to compare. The string representation of this * value must not be null. * @return -1 if left is null * and right is not null; * 0 if they are both null; * 1 if left is not null * and right is null. Otherwise, the * result of * left.toString().compareTo(right.toString()). */ static int CompareObj(const Object::ConstPointer left, const Object::ConstPointer right); /** * Tests whether two arrays of objects are equal to each other. The arrays * must not be null, but their elements may be * null. * * @param leftArray * The left array to compare; may be null, and * may be empty and may contain null elements. * @param rightArray * The right array to compare; may be null, and * may be empty and may contain null elements. * @return true if the arrays are equal length and the * elements at the same position are equal; false * otherwise. */ template static int Compare(const std::vector& leftArray, const std::vector& rightArray) { int result = (int) (leftArray.size() - rightArray.size()); if (result == 0) { for (unsigned int i = 0; i < leftArray.size(); ++i) { long int diff = (long) (&(leftArray[i]) - &(rightArray[i])); int result = diff ? (diff < 0 ? -1 : 1) : 0; if (result != 0) break; } } return result; } /** * Tests whether two arrays of objects are equal to each other. The arrays * must not be null, but their elements may be * null. * * @param leftArray * The left array to compare; may be null, and * may be empty and may contain null elements. * @param rightArray * The right array to compare; may be null, and * may be empty and may contain null elements. * @return true if the arrays are equal length and the * elements at the same position are equal; false * otherwise. */ template static bool Equals(const std::vector& leftArray, const std::vector& rightArray) { if (leftArray.size() != rightArray.size()) { return false; } for (unsigned int i = 0; i < leftArray.size(); i++) { T left = leftArray[i]; T right = rightArray[i]; const bool equal = left ? !right : (left == right); if (!equal) { return false; } } return true; } template static std::string ToString(const std::vector& vec) { std::stringstream str; + std::locale C("C"); + str.imbue(C); str << "["; for (unsigned int i = 0; i < vec.size(); ++i) { if (i > 0) str << ","; str << &(vec[i]); } return str.str(); } }; } #endif // __BERRY_COMMAND_UTILS_H__ diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp index bd04c55fa7..7d7d438028 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp @@ -1,606 +1,625 @@ #include "berryPreferences.h" #include "berryAbstractPreferencesStorage.h" #include "Poco/ScopedLock.h" #include using namespace std; namespace berry { Preferences::Preferences(const PropertyMap& _Properties , const std::string& _Name , Preferences* _Parent , AbstractPreferencesStorage* _Storage) : m_Properties(_Properties) , m_Name(_Name) , m_Parent(_Parent) , m_Removed(false) , m_Storage(_Storage) { // root node if parent is 0 if (_Parent != 0) { m_Path = _Parent->AbsolutePath() + (_Parent->AbsolutePath() == "/" ? "": "/") + _Name; // save as child in parent _Parent->m_Children.push_back(Preferences::Pointer(this)); m_Root = _Parent->m_Root; } else { // root path m_Path = "/"; m_Root = this; } } bool Preferences::Has( string key ) const { Poco::ScopedLock scopedMutex(m_Mutex); return (m_Properties.find(key) != m_Properties.end()); } bool Preferences::IsDirty() const { Poco::ScopedLock scopedMutex(m_Mutex); bool dirty = m_Dirty; for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { // break condition: if one node is dirty the whole tree is dirty if(dirty) break; else dirty = (*it)->IsDirty(); } return dirty; } string Preferences::ToString() const { Poco::ScopedLock scopedMutex(m_Mutex); ostringstream s; + std::locale C("C"); + s.imbue(C); s << "Preferences[" << m_Path << "]"; return s.str(); } bool Preferences::Equals(const Preferences* rhs) const { Poco::ScopedLock scopedMutex(m_Mutex); if(rhs == 0) return false; return (this->m_Path == rhs->m_Path); } Preferences::PropertyMap Preferences::GetProperties() const { return m_Properties; } Preferences::ChildrenList Preferences::GetChildren() const { return m_Children; } string Preferences::AbsolutePath() const { Poco::ScopedLock scopedMutex(m_Mutex); return m_Path; } vector Preferences::ChildrenNames() const throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); vector names; for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { names.push_back((*it)->Name()); } return names; } AbstractPreferencesStorage* Preferences::GetStorage() const { return m_Storage; } void Preferences::Clear() throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); m_Properties.clear(); this->SetDirty(true); } void Preferences::Flush() throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); // ensure that this is the parent m_Storage->Flush(this); // if something is written, make the tree undirty this->SetDirty(false); } string Preferences::Get(string key, string def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? m_Properties.find(key)->second: def; } bool Preferences::GetBool(string key, bool def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? (m_Properties.find(key)->second == "true"? true: false): def; } string Preferences::GetByteArray(string key, string def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? Base64::decode(m_Properties.find(key)->second): def; } double Preferences::GetDouble(string key, double def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? atof(m_Properties.find(key)->second.c_str()): def; } float Preferences::GetFloat(string key, float def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? static_cast(atof(m_Properties.find(key)->second.c_str())): def; } int Preferences::GetInt(string key, int def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? atoi(m_Properties.find(key)->second.c_str()): def; } long Preferences::GetLong(string key, long def) const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return this->Has(key)? atol(m_Properties.find(key)->second.c_str()): def; } vector Preferences::Keys() const throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); vector keys; for (PropertyMap::const_iterator it = m_Properties.begin() ; it != m_Properties.end(); it++) { keys.push_back(it->first); } return keys; } string Preferences::Name() const { Poco::ScopedLock scopedMutex(m_Mutex); return m_Name; } IPreferences::Pointer Preferences::Node(string pathName) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); AssertPath(pathName); IPreferences::Pointer node; // self reference if(pathName == "") return IPreferences::Pointer(this); // absolute path else if(pathName[0] == '/') { pathName = pathName.substr(1); // call root with this relative path return m_Root->Node(pathName); } // relative path else { // check if pathName contains anymore names string name = pathName; // create new child nodes as long as there are names in the path string::size_type pos = pathName.find("/"); // cut from the beginning if(pos != string::npos) { name = pathName.substr(0, pos); pathName = pathName.substr(pos+1); } // now check if node exists->if not: make new for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); it++) { // node found if((*it)->Name() == name && (*it)->IsRemoved() == false) { node = IPreferences::Pointer((*it).GetPointer()); break; } } // node not found create new one if(node.IsNull()) { // the new node automatically pushes itself into the children array of *this* Preferences::Pointer newNode(new Preferences(PropertyMap(), name, this, m_Storage)); node = newNode.GetPointer(); // this branch is dirty now -> prefs must be rewritten persistently this->SetDirty(true); } // call Node() again if there are any names left on the path if(pos != string::npos) node = node->Node(pathName); } return node; } bool Preferences::NodeExists(string pathName) const throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); AssertPath(pathName); bool nodeExists = false; // absolute path if(pathName[0] == '/') { pathName = pathName.substr(1); // call root with this relative path return m_Root->NodeExists(pathName); } // relative path else { // check if pathName contains anymore names string name = pathName; // create new child nodes as long as there are names in the path string::size_type pos = pathName.find_first_of("/"); // cut from the beginning if(pos != string::npos) { name = pathName.substr(0, pos); pathName = pathName.substr(pos+1); } // now check if node exists->if not: make new for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); it++) { // node found if((*it)->Name() == name) { // call recursively if more names on the path exist if(pos != string::npos) nodeExists = (*it)->NodeExists(pathName); else nodeExists = true; break; } } } return nodeExists; } void Preferences::Put(string key, string value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); m_Properties[key] = value; this->SetDirty(true); } void Preferences::PutByteArray(string key, string value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, Base64::encode(value)); } void Preferences::PutBool(string key, bool value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, value ? "true" : "false"); } void Preferences::PutDouble(string key, double value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, Preferences::ToString(value)); } void Preferences::PutFloat(string key, float value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, Preferences::ToString(value)); } void Preferences::PutInt(string key, int value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, Preferences::ToString(value)); } void Preferences::PutLong(string key, long value) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Put(key, Preferences::ToString(value)); } void Preferences::Remove(string key) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); PropertyMap::iterator it = m_Properties.find(key); if(it != m_Properties.end()) m_Properties.erase(it); } void Preferences::RemoveNode() throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->SetRemoved(true); m_Parent->m_Children.erase(std::find(m_Parent->m_Children.begin(), m_Parent->m_Children.end(), Preferences::Pointer(this))); } void Preferences::Sync() throw(Poco::Exception, BackingStoreException) { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); this->Flush(); } void Preferences::AssertValid() const { Poco::ScopedLock scopedMutex(m_Mutex); if(m_Removed) { - ostringstream s; s << "no node at '" << m_Path << "'"; + ostringstream s; + std::locale C("C"); + s.imbue(C); + s << "no node at '" << m_Path << "'"; throw Poco::IllegalStateException(s.str()); } } void Preferences::AssertPath(string pathName) { if(pathName.find("//") != string::npos) { - ostringstream s; s << "Illegal // in m_Path m_Name '" << pathName << "'"; + ostringstream s; + std::locale C("C"); + s.imbue(C); + s << "Illegal // in m_Path m_Name '" << pathName << "'"; throw invalid_argument(s.str()); } string::size_type strLength = pathName.length(); if(pathName.length() > 1 && pathName[strLength-1] == '/') { - ostringstream s; s << "Trailing / in m_Path m_Name '" << pathName << "'"; + ostringstream s; + std::locale C("C"); + s.imbue(C); + s << "Trailing / in m_Path m_Name '" << pathName << "'"; throw invalid_argument(s.str()); } } IPreferences::Pointer Preferences::Parent() const { Poco::ScopedLock scopedMutex(m_Mutex); AssertValid(); return IPreferences::Pointer(m_Parent); } void Preferences::SetDirty( bool _Dirty ) { Poco::ScopedLock scopedMutex(m_Mutex); m_Dirty = _Dirty; if(_Dirty) this->OnChanged.Send(this); /* for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { (*it)->SetDirty(_Dirty); } */ } void Preferences::SetRemoved( bool _Removed ) { Poco::ScopedLock scopedMutex(m_Mutex); m_Removed = _Removed; for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { (*it)->SetRemoved(_Removed); } } /* Preferences::ChildrenList& Preferences::GetChildren() const { return m_Children; }*/ bool Preferences::IsRemoved() const { Poco::ScopedLock scopedMutex(m_Mutex); return m_Removed; } Preferences::~Preferences() { } } namespace Base64 { string encode(const string &sString) { static const string base64Table( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ); static const char fillChar = '='; string::size_type length = sString.length(); string result; // Allocate memory for the converted string result.reserve(length * 8 / 6 + 1); for(string::size_type nPos = 0; nPos < length; nPos++) { char code; // Encode the first 6 bits code = (sString[nPos] >> 2) & 0x3f; result.append(1, base64Table[code]); // Encode the remaining 2 bits with the next 4 bits (if present) code = (sString[nPos] << 4) & 0x3f; if(++nPos < length) code |= (sString[nPos] >> 4) & 0x0f; result.append(1, base64Table[code]); if(nPos < length) { code = (sString[nPos] << 2) & 0x3f; if(++nPos < length) code |= (sString[nPos] >> 6) & 0x03; result.append(1, base64Table[code]); } else { ++nPos; result.append(1, fillChar); } if(nPos < length) { code = sString[nPos] & 0x3f; result.append(1, base64Table[code]); } else { result.append(1, fillChar); } } return result; } string decode(const string &sString) { static const string::size_type np = string::npos; static const string::size_type DecodeTable[] = { // 0 1 2 3 4 5 6 7 8 9 np, np, np, np, np, np, np, np, np, np, // 0 - 9 np, np, np, np, np, np, np, np, np, np, // 10 - 19 np, np, np, np, np, np, np, np, np, np, // 20 - 29 np, np, np, np, np, np, np, np, np, np, // 30 - 39 np, np, np, 62, np, np, np, 63, 52, 53, // 40 - 49 54, 55, 56, 57, 58, 59, 60, 61, np, np, // 50 - 59 np, np, np, np, np, 0, 1, 2, 3, 4, // 60 - 69 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 70 - 79 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 80 - 89 25, np, np, np, np, np, np, 26, 27, 28, // 90 - 99 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100 - 109 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // 110 - 119 49, 50, 51, np, np, np, np, np, np, np, // 120 - 129 np, np, np, np, np, np, np, np, np, np, // 130 - 139 np, np, np, np, np, np, np, np, np, np, // 140 - 149 np, np, np, np, np, np, np, np, np, np, // 150 - 159 np, np, np, np, np, np, np, np, np, np, // 160 - 169 np, np, np, np, np, np, np, np, np, np, // 170 - 179 np, np, np, np, np, np, np, np, np, np, // 180 - 189 np, np, np, np, np, np, np, np, np, np, // 190 - 199 np, np, np, np, np, np, np, np, np, np, // 200 - 209 np, np, np, np, np, np, np, np, np, np, // 210 - 219 np, np, np, np, np, np, np, np, np, np, // 220 - 229 np, np, np, np, np, np, np, np, np, np, // 230 - 239 np, np, np, np, np, np, np, np, np, np, // 240 - 249 np, np, np, np, np, np // 250 - 256 }; static const char fillChar = '='; string::size_type length = sString.length(); string result; result.reserve(length); for(string::size_type nPos = 0; nPos < length; nPos++) { unsigned char c, c1; c = (char) DecodeTable[(unsigned char)sString[nPos]]; nPos++; c1 = (char) DecodeTable[(unsigned char)sString[nPos]]; c = (c << 2) | ((c1 >> 4) & 0x3); result.append(1, c); if(++nPos < length) { c = sString[nPos]; if(fillChar == c) break; c = (char) DecodeTable[(unsigned char)sString[nPos]]; c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); result.append(1, c1); } if(++nPos < length) { c1 = sString[nPos]; if(fillChar == c1) break; c1 = (char) DecodeTable[(unsigned char)sString[nPos]]; c = ((c << 6) & 0xc0) | c1; result.append(1, c); } } return result; } } ostream& operator<<( ostream& os,const berry::Preferences& m ) { + std::locale C("C"); + std::locale originalLocale = os.getloc(); + os.imbue(C); os << m.ToString(); + os.imbue(originalLocale); return os; } ostream& operator<<( ostream& os,const berry::Preferences* m ) { + std::locale C("C"); + std::locale originalLocale = os.getloc(); + os.imbue(C); os << m->ToString(); + os.imbue(originalLocale); return os; } diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h index d7170e19f9..bcc19a0885 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h @@ -1,324 +1,327 @@ #ifndef BERRYPREFERENCES_H_ #define BERRYPREFERENCES_H_ #include "../berryRuntimeDll.h" #include "berryIBerryPreferences.h" #include #include #include #include #include "Poco/Mutex.h" namespace berry { class AbstractPreferencesStorage; /// /// Implementation of the OSGI Preferences Interface. /// Wraps a DOMNode. /// class BERRY_RUNTIME Preferences: public IBerryPreferences { public: /// /// For use with berry::SmartPtr /// berryObjectMacro(berry::Preferences) /// /// Maps a string key to a string value /// typedef std::map PropertyMap; /// /// The list of Child nodes /// typedef std::vector ChildrenList; /// /// Constructs a new preference node. /// \param _Properties the key->value pairs of this preference node /// \param _Path the absolute path to this node, e.g. "/general/editors/font" /// \param _Name the name of this node, e.g. "font" /// \param _FileName the absolute path to the file in which this preferences tree will be saved to /// \param _Parent the parent node or 0 if this is the root /// \param _Root the root of this preference tree /// Preferences(const PropertyMap& _Properties , const std::string& _Name , Preferences* _Parent , AbstractPreferencesStorage* _Storage); /// /// Nothing to do here /// virtual ~Preferences(); /// /// Prints out the absolute path of the preference node. /// std::string ToString() const; /// /// Returns if this node and his silblings have to be rewritten persistently /// bool IsDirty() const; /// /// Returns if this node is removed /// bool IsRemoved() const; /// /// Returns if this node has property with a specific key /// bool Has(std::string key) const; /// /// Returns true if the absolute paths are the same /// bool Equals(const Preferences* rhs) const; /// /// Returns all Properties as map. /// PropertyMap GetProperties() const; /// /// Returns a reference to the children list in order to add or remove nodes. /// *ATTENTION*: Should only be used /// when constructing the preferences tree from a persistent location. Normally, one would /// only use the IPreferences methods /// ChildrenList GetChildren() const; //# Begin of IPreferences methods /// /// \see IPreferences::AbsolutePath() /// virtual std::string AbsolutePath() const; /// /// \see IPreferences::ChildrenNames() /// virtual std::vector ChildrenNames() const throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::ChildrenNames() /// virtual AbstractPreferencesStorage* GetStorage() const; /// /// \see IPreferences::Clear() /// virtual void Clear() throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::Flush() /// virtual void Flush() throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::Get() /// virtual std::string Get(std::string key, std::string def) const; /// /// \see IPreferences::GetBool() /// virtual bool GetBool(std::string key, bool def) const; /// /// \see IPreferences::GetByteArray() /// virtual std::string GetByteArray(std::string key, std::string def) const; /// /// \see IPreferences::GetDouble() /// virtual double GetDouble(std::string key, double def) const; /// /// \see IPreferences::GetFloat() /// virtual float GetFloat(std::string key, float def) const; /// /// \see IPreferences::GetInt() /// virtual int GetInt(std::string key, int def) const; /// /// \see IPreferences::GetLong() /// virtual long GetLong(std::string key, long def) const; /// /// \see IPreferences::Keys() /// std::vector Keys() const throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::Name() /// virtual std::string Name() const; /// /// \see IPreferences::Node() /// virtual IPreferences::Pointer Node(std::string pathName); /// /// \see IPreferences::NodeExists() /// virtual bool NodeExists(std::string pathName) const throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::Parent() /// virtual IPreferences::Pointer Parent() const; /// /// \see IPreferences::Put() /// virtual void Put(std::string key, std::string value); /// /// \see IPreferences::PutByteArray() /// virtual void PutByteArray(std::string key, std::string value); /// /// \see IPreferences::PutBool() /// virtual void PutBool(std::string key, bool value); /// /// \see IPreferences::PutDouble() /// virtual void PutDouble(std::string key, double value); /// /// \see IPreferences::Sync() /// virtual void PutFloat(std::string key, float value); /// /// \see IPreferences::PutInt() /// virtual void PutInt(std::string key, int value); /// /// \see IPreferences::PutLong() /// virtual void PutLong(std::string key, long value); /// /// \see IPreferences::Remove() /// virtual void Remove(std::string key); /// /// \see IPreferences::RemoveNode() /// virtual void RemoveNode() throw(Poco::Exception, BackingStoreException); /// /// \see IPreferences::Sync() /// virtual void Sync() throw(Poco::Exception, BackingStoreException); //# End of IPreferences methods protected: /// /// Checks if this node is about to be removed. /// \throws IllegalStateException /// void AssertValid() const; /// /// Checks a path value for validity. /// \throws invalid_argument /// static void AssertPath(std::string pathName); /// /// Converts any value to a string (using stream operator "<<") /// template static std::string ToString(const T& obj, int precision = 12 ) { - std::ostringstream s; s.precision(precision); s << obj; return s.str(); + std::ostringstream s; + std::locale C("C"); + s.imbue(C); + s.precision(precision); s << obj; return s.str(); } /// /// Sets the dirty flag recursively on all child nodes. /// void SetDirty(bool _Dirty); /// /// Sets the removed flag recursively on all child nodes. /// void SetRemoved(bool _Removed); protected: /// /// Holds all Key/Value Pairs. /// std::map m_Properties; /// /// Holds all child nodes (explicit ownership). /// std::vector m_Children; /// /// Saves the absolute path of this node (calculated in the constructor) /// std::string m_Path; /// /// Saves the name of this node (set when read from backend) /// std::string m_Name; /// /// Saves the parent of this node /// Preferences* m_Parent; /// /// Saves the root of this tree /// Preferences* m_Root; /// /// Saves if something changed on this branch. /// Meaning that you would have to rewrite it. /// bool m_Dirty; /// /// Saves if this Node is removed (will not be saved to the backend). /// bool m_Removed; /// /// A storage to call the flush method. /// AbstractPreferencesStorage* m_Storage; /// /// A mutex to avoid concurrency crashes. Mutable because we need to use Mutex::lock() in const functions /// mutable Poco::Mutex m_Mutex; }; } namespace Base64 { /// /// Encode string to base64 (needed for writing byte arrays) /// std::string encode(const std::string &sString); /// /// Decode base64 to string (needed for reading byte arrays) /// std::string decode(const std::string &sString); }; /// /// Uses Preferences::ToString to print node information /// std::ostream& operator<<(std::ostream& os,const berry::Preferences& m); /// /// Uses Preferences::ToString to print node information /// std::ostream& operator<<(std::ostream& os,const berry::Preferences* m); #endif /* BERRYPREFERENCES_H_ */ diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/berryObjectGeneric.h b/BlueBerry/Bundles/org.blueberry.osgi/src/berryObjectGeneric.h index 5092a59fca..3778768646 100755 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/berryObjectGeneric.h +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/berryObjectGeneric.h @@ -1,110 +1,114 @@ /*========================================================================= Program: BlueBerry Platform Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef BERRYOBJECTGENERIC_H_ #define BERRYOBJECTGENERIC_H_ #include #include "berryOSGiDll.h" #include "berryMacros.h" #include "berryObject.h" namespace berry { template class BERRY_OSGI ObjectGeneric : public Object { public: berryObjectMacro(ObjectGeneric); typedef T ValueType; ObjectGeneric() : m_Value(0) {} ObjectGeneric(T x) : m_Value(x) {} //ObjectGeneric(const Self& o) { m_Value = o.m_Value; } virtual ~ObjectGeneric() { } void SetValue(T val) { m_Value = val; } T GetValue() const { return m_Value; } bool operator==(const Object* o) const { if(const Self* other = dynamic_cast(o)) return (this->m_Value == other->m_Value); return false; } virtual std::string GetValueAsString() const { std::stringstream myStr; + std::locale originalLocale = myStr.getloc(); + std::locale C("C"); + myStr.imbue(C); myStr << GetValue() ; + myStr.imbue(originalLocale); return myStr.str(); } virtual bool Assignable(Object::ConstPointer other) const { return other.Cast() != 0; } virtual void Assign(Object::ConstPointer other) { ConstPointer specOther = other.Cast(); if (specOther && this->m_Value != specOther->m_Value) { this->m_Value = specOther->m_Value; } } protected: T m_Value; }; } // namespace berry /** * Generates a specialized subclass of berry::ObjectGeneric. * This way, GetClassName() returns the value provided by ObjectName. * Please see berryObjects.h for examples * @param ObjectName the name of the instantiation of ObjectGeneric * @param Type the value type */ #define berrySpecializeGenericObject(ObjectName,Type,DefaultValue) \ class BERRY_OSGI ObjectName: public ::berry::ObjectGeneric< Type > \ { \ public: \ berryObjectMacro(ObjectName); \ ObjectName() : ::berry::ObjectGeneric< Type >(DefaultValue) { } \ ObjectName(Type x) : ::berry::ObjectGeneric(x) {} \ /*ObjectName(const ObjectName& o) : ObjectGeneric< Type >(o) {} */ \ }; #endif /* BERRYOBJECTGENERIC_H_ */ diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp index 301c2ecccd..56373e5ae3 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp @@ -1,246 +1,250 @@ /*========================================================================= Program: BlueBerry Platform Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifdef __MINGW32__ // We need to inlclude winbase.h here in order to declare // atomic intrinsics like InterlockedIncrement correctly. // Otherwhise, they would be declared wrong within qatomic_windows.h . #include #endif #include "berryQtPlatformLogModel.h" #include "berryPlatform.h" #include "event/berryPlatformEvents.h" #include #include #include #include #include #include "berryLog.h" #include namespace berry { const QString QtPlatformLogModel::Error = QString("Error"); const QString QtPlatformLogModel::Warn = QString("Warn"); const QString QtPlatformLogModel::Fatal = QString("Fatal"); const QString QtPlatformLogModel::Info = QString("Info"); const QString QtPlatformLogModel::Debug = QString("Debug"); void QtPlatformLogModel::slotFlushLogEntries() { m_Mutex.lock(); std::list *tmp=m_Active; m_Active=m_Pending; m_Pending=tmp; m_Mutex.unlock(); int num = static_cast(m_Pending->size()); if (num > 0) { int row = static_cast(m_Entries.size()); this->beginInsertRows(QModelIndex(), row, row+num-1); do { m_Entries.push_back(m_Pending->front()); m_Pending->pop_front(); } while(--num); this->endInsertRows(); } } void QtPlatformLogModel::addLogEntry(const mbilog::LogMessage &msg) { m_Mutex.lock(); mbilog::BackendCout::FormatSmart(msg); m_Active->push_back(ExtendedLogMessage(msg)); m_Mutex.unlock(); emit signalFlushLogEntries(); } void QtPlatformLogModel::addLogEntry(const PlatformEvent& event) { const Poco::Message& entry = Poco::RefAnyCast(*event.GetData()); mbilog::LogMessage msg(mbilog::Info,"n/a",-1,"n/a"); msg.message += entry.getText(); msg.category = "BlueBerry."+entry.getSource(); msg.moduleName = "n/a"; addLogEntry(msg); } QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent) { m_Active=new std::list; m_Pending=new std::list; connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection ); Platform::GetEvents().logged += PlatformEventDelegate(this, &QtPlatformLogModel::addLogEntry); myBackend = new QtLogBackend(this); } QtPlatformLogModel::~QtPlatformLogModel() { disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() )); // dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mbilog::UnregisterBackend is not threadsafe // will be fixed. // delete myBackend; // delete m_Active; // delete m_Pending; m_Mutex.lock(); myBackend->Deactivate(); m_Mutex.unlock(); } // QT Binding int QtPlatformLogModel::rowCount(const QModelIndex&) const { return static_cast(m_Entries.size()); } int QtPlatformLogModel::columnCount(const QModelIndex&) const { return 8; } /* struct LogEntry { LogEntry(const std::string& msg, const std::string& src, std::time_t t) : message(msg.c_str()), moduleName(src.c_str()),time(std::clock()) { } QString message; clock_t time; QString level; QString filePath; QString lineNumber; QString moduleName; QString category; QString function; LogEntry(const mbilog::LogMessage &msg) { message = msg.message.c_str(); filePath = msg.filePath; std::stringstream out; out << msg.lineNumber; lineNumber = out.str().c_str(); moduleName = msg.moduleName; category = msg.category.c_str(); function = msg.functionName; time=std::clock(); } }; */ QVariant QtPlatformLogModel::data(const QModelIndex& index, int role) const { const ExtendedLogMessage *msg = &m_Entries[index.row()]; if (role == Qt::DisplayRole) { switch (index.column()) { case 0: { std::stringstream ss; + std::locale C("C"); + ss.imbue(C); ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)msg->time)/CLOCKS_PER_SEC; return QVariant(QString(ss.str().c_str())); } case 1: { switch(msg->message.level) { default: case mbilog::Info: return QVariant(Info); case mbilog::Warn: return QVariant(Warn); case mbilog::Error: return QVariant(Error); case mbilog::Fatal: return QVariant(Fatal); case mbilog::Debug: return QVariant(Debug); } } case 2: return QVariant(QString(msg->message.message.c_str())); case 3: return QVariant(QString(msg->message.category.c_str())); case 4: return QVariant(QString(msg->message.moduleName)); case 5: return QVariant(QString(msg->message.functionName)); case 6: return QVariant(QString(msg->message.filePath)); case 7: { std::stringstream out; + std::locale C("C"); + out.imbue(C); out << msg->message.lineNumber; return QVariant(QString(out.str().c_str())); } } } return QVariant(); } QVariant QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return QVariant("Time"); case 1: return QVariant("Level"); case 2: return QVariant("Message"); case 3: return QVariant("Category"); case 4: return QVariant("Module"); case 5: return QVariant("Function"); case 6: return QVariant("File"); case 7: return QVariant("Line"); } } return QVariant(); } }