/[svn]/gigedit/trunk/src/gigedit/global.h
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/global.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2474 by schoenebeck, Sun Sep 15 18:16:21 2013 UTC revision 3341 by schoenebeck, Mon Jul 31 11:26:56 2017 UTC
# Line 1  Line 1 
1  /*                                                         -*- c++ -*-  /*                                                         -*- c++ -*-
2   * Copyright (C) 2007-2013 Andreas Persson   * Copyright (C) 2007-2017 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 24  Line 24 
24  # include <config.h>  # include <config.h>
25  #endif  #endif
26    
27    #include <cstring>
28    #include <algorithm>
29    
30    #include <glibmmconfig.h>
31    // threads.h must be included first to be able to build with
32    // G_DISABLE_DEPRECATED
33    #if (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION == 31 && GLIBMM_MICRO_VERSION >= 2) || \
34        (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION > 31) || GLIBMM_MAJOR_VERSION > 2
35    #include <glibmm/threads.h>
36    #endif
37    
38    #if !defined(WIN32)
39    # include <unistd.h>
40    # include <errno.h>
41    #endif
42    
43  #include <sstream>  #include <sstream>
44    #include <map>
45    
46    #ifdef LIBGIG_HEADER_FILE
47    # include LIBGIG_HEADER_FILE(gig.h)
48    # include LIBGIG_HEADER_FILE(Serialization.h)
49    #else
50    # include <gig.h>
51    # include <Serialization.h>
52    #endif
53    
54  //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?  //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
55  #if (HAVE_GETTEXT || defined(__APPLE__))  #if (HAVE_GETTEXT || defined(__APPLE__))
# Line 40  Line 65 
65  # define VERSION VER_STRING // VER_STRING defined in libgig_private.h  # define VERSION VER_STRING // VER_STRING defined in libgig_private.h
66  #endif // WIN32  #endif // WIN32
67    
68    #define UNICODE_RIGHT_ARROW     Glib::ustring(1, gunichar(0x2192))
69    #define UNICODE_LEFT_ARROW      Glib::ustring(1, gunichar(0x2190))
70    #define UNICODE_SHIFT_KEY_SYMBOL    Glib::ustring("\xe2\x87\xa7")
71    #if defined(__APPLE__)
72    # define UNICODE_ALT_KEY_SYMBOL     Glib::ustring("\xe2\x8c\xa5")
73    #else
74    # define UNICODE_ALT_KEY_SYMBOL     Glib::ustring("Alt")
75    #endif
76    #define UNICODE_ERASE_KEY_SYMBOL    Glib::ustring("\xe2\x8c\xab")
77    #define UNICODE_CTRL_KEY_SYMBOL     Glib::ustring("Ctrl")
78    #define UNICODE_CMD_KEY_SYMBOL      Glib::ustring(1, gunichar(0x2318))
79    #if defined(__APPLE__)
80    # define UNICODE_PRIMARY_KEY_SYMBOL     UNICODE_CMD_KEY_SYMBOL
81    #else
82    # define UNICODE_PRIMARY_KEY_SYMBOL     UNICODE_CTRL_KEY_SYMBOL
83    #endif
84    
85    // taken from gdk/gdkkeysyms.h
86    // (define on demand, to avoid unnecessary dev lib package build dependency)
87    #ifndef GDK_KEY_Control_L
88    # define GDK_KEY_Control_L 0xffe3
89    #endif
90    #ifndef GDK_KEY_Control_R
91    # define GDK_KEY_Control_R 0xffe4
92    #endif
93    #ifndef GDK_KEY_Left
94    # define GDK_KEY_Left 0xff51
95    #endif
96    #ifndef GDK_KEY_Right
97    # define GDK_KEY_Right 0xff53
98    #endif
99    #ifndef GDK_KEY_Up
100    # define GDK_KEY_Up 0xff52
101    #endif
102    #ifndef GDK_KEY_Down
103    # define GDK_KEY_Down 0xff54
104    #endif
105    
106    #include <glibmm/convert.h>
107    
108    #define GIG_STR_ENCODING "CP1252"
109    
110    static inline
111    Glib::ustring gig_to_utf8(const gig::String& gig_string) {
112        return Glib::convert_with_fallback(gig_string, "UTF-8", GIG_STR_ENCODING, "?");
113    }
114    
115    static inline
116    gig::String gig_from_utf8(const Glib::ustring& utf8_string) {
117        return Glib::convert_with_fallback(utf8_string, GIG_STR_ENCODING, "UTF-8", "?");
118    }
119    
120    inline Glib::ustring ltrim(Glib::ustring s) {
121        s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
122        return s;
123    }
124    
125    inline Glib::ustring rtrim(Glib::ustring s) {
126        s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
127        return s;
128    }
129    
130    inline Glib::ustring trim(Glib::ustring s) {
131        return ltrim(rtrim(s));
132    }
133    
134  template<class T> inline std::string ToString(T o) {  template<class T> inline std::string ToString(T o) {
135      std::stringstream ss;      std::stringstream ss;
136      ss << o;      ss << o;
137      return ss.str();      return ss.str();
138  }  }
139    
140    inline static bool endsWith(const std::string& haystack, const std::string& needle, bool caseSensitive) {
141        if (haystack.size() < needle.size()) return false;
142        const std::string sub = haystack.substr(haystack.size() - needle.size(), needle.size());
143        return (caseSensitive) ? (sub == needle) : (!strcasecmp(sub.c_str(), needle.c_str()));
144    }
145    
146    inline int getDimensionIndex(gig::dimension_t type, gig::Region* rgn) {
147        for (uint i = 0; i < rgn->Dimensions; ++i)
148            if (rgn->pDimensionDefinitions[i].dimension == type)
149                return i;
150        return -1;
151    }
152    
153    inline int getDimensionRegionIndex(gig::DimensionRegion* dr) {
154        if (!dr) return -1;
155        gig::Region* rgn = (gig::Region*)dr->GetParent();
156        for (uint i = 0; i < 256; ++i)
157            if (rgn->pDimensionRegions[i] == dr)
158                return i;
159        return -1;
160    }
161    
162    /// Find the number of bits required to hold the specified amount of zones.
163    inline int zoneCountToBits(int nZones) {
164        if (!nZones) return 0;
165        int iFinalBits = 0;
166        int zoneBits = nZones - 1;
167        for (; zoneBits > 1; iFinalBits += 2, zoneBits >>= 2);
168        iFinalBits += zoneBits;
169        return iFinalBits;
170    }
171    
172    /**
173     * Returns the sum of all bits of all dimensions defined before the given
174     * dimensions (@a type). This allows to access cases of that particular
175     * dimension directly. If the supplied dimension @a type does not exist in the
176     * the supplied @a region, then this function returns -1 instead!
177     *
178     * @param type - dimension that shall be used
179     * @param rgn - parent region of that dimension
180     */
181    inline int baseBits(gig::dimension_t type, gig::Region* rgn) {
182        int previousBits = 0;
183        for (uint i = 0; i < rgn->Dimensions; ++i) {
184            if (rgn->pDimensionDefinitions[i].dimension == type) return previousBits;
185            previousBits += rgn->pDimensionDefinitions[i].bits;
186        }
187        return -1;
188    }
189    
190    // key: dimension type, value: dimension's zone index
191    class DimensionCase : public std::map<gig::dimension_t,int> {
192    public:
193        bool isViolating(const DimensionCase& c) const {
194            for (DimensionCase::const_iterator it = begin(); it != end(); ++it) {
195                if (c.find(it->first) == c.end()) continue;
196                if (c.find(it->first)->second != it->second) return true;
197            }
198            return false;
199        }
200    
201        // prevent passing gig::dimension_none from creating a new pair
202        // (TODO: other invalid gig::dimension_t values should be filtered here as well)
203        int& operator[](const gig::dimension_t& k) {
204            static int unused = 0;
205            if (k == gig::dimension_none) {
206                unused = 0;
207                return unused;
208            }
209            return std::map<gig::dimension_t,int>::operator[](k);
210        }
211    };
212    
213    //TODO: this function and caseOfDimRegion() from dimregionchooser.h are duplicates, eliminate either one of them!
214    inline DimensionCase dimensionCaseOf(gig::DimensionRegion* dr) {
215        DimensionCase dimCase;
216        int idr = getDimensionRegionIndex(dr);
217        if (idr < 0) return dimCase;
218        gig::Region* rgn = (gig::Region*)dr->GetParent();
219        int bitpos = 0;
220        for (int d = 0; d < rgn->Dimensions; ++d) {
221            const gig::dimension_def_t& dimdef = rgn->pDimensionDefinitions[d];
222            const int zone = (idr >> bitpos) & ((1 << dimdef.bits) - 1);
223            dimCase[dimdef.dimension] = zone;
224            bitpos += rgn->pDimensionDefinitions[d].bits;
225        }
226        return dimCase;
227    }
228    
229    /**
230     * Checks whether the passed dimension zones are within the boundaries of the
231     * defined dimensions. This is especially relevant if there are dimensions
232     * defined with an amount not equal to a power of two, in that case there are
233     * unused dimensions regions which should be ignored.
234     */
235    inline bool isUsedCase(const DimensionCase& c, gig::Region* rgn) {
236        for (int d = 0; d < rgn->Dimensions; ++d) {
237            gig::dimension_t type = rgn->pDimensionDefinitions[d].dimension;
238            if (c.find(type) == c.end()) continue;
239            int zone = c.find(type)->second;
240            if (zone < 0 || zone >= rgn->pDimensionDefinitions[d].zones)
241                return false;
242        }
243        return true;
244    }
245    
246    inline std::vector<gig::DimensionRegion*> dimensionRegionsMatching(
247        const DimensionCase& dimCase, gig::Region* rgn, bool skipUnusedZones = false)
248    {
249        std::vector<gig::DimensionRegion*> v;
250        for (int idr = 0; idr < 256; ++idr) {
251            if (!rgn->pDimensionRegions[idr]) continue;
252            DimensionCase c = dimensionCaseOf(rgn->pDimensionRegions[idr]);
253            if (dimCase.isViolating(c)) continue;
254            if (skipUnusedZones && !isUsedCase(c, rgn)) continue;
255            v.push_back(rgn->pDimensionRegions[idr]);
256        }
257        return v;
258    }
259    
260    inline gig::DimensionRegion* dimensionRegionMatching(const DimensionCase& dimCase, gig::Region* rgn) {
261        for (int idr = 0; idr < 256; ++idr) {
262            if (!rgn->pDimensionRegions[idr]) continue;
263            DimensionCase c = dimensionCaseOf(rgn->pDimensionRegions[idr]);
264            if (c == dimCase) return rgn->pDimensionRegions[idr];
265        }
266        return NULL;
267    }
268    
269    template<typename T_Message>
270    class SignalGuard {
271    public:
272        SignalGuard(sigc::signal<void, T_Message>& start, sigc::signal<void, T_Message>& end, T_Message message)
273            : m_end(end), m_message(message)
274        {
275            if (message) start.emit(message);
276        }
277    
278        virtual ~SignalGuard() {
279            if (m_message) m_end.emit(m_message);
280        }
281    protected:
282        sigc::signal<void, T_Message>& m_end;
283        T_Message m_message;
284    };
285    
286  #endif // GIGEDIT_GLOBAL_H  #endif // GIGEDIT_GLOBAL_H

Legend:
Removed from v.2474  
changed lines
  Added in v.3341

  ViewVC Help
Powered by ViewVC