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

Legend:
Removed from v.1396  
changed lines
  Added in v.3364

  ViewVC Help
Powered by ViewVC