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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3341 - (hide annotations) (download) (as text)
Mon Jul 31 11:26:56 2017 UTC (6 years, 8 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 9539 byte(s)
- Fixed compilation error.

1 schoenebeck 1396 /* -*- c++ -*-
2 schoenebeck 3089 * Copyright (C) 2007-2017 Andreas Persson
3 schoenebeck 1396 *
4     * This program is free software; you can redistribute it and/or
5     * modify it under the terms of the GNU General Public License as
6     * published by the Free Software Foundation; either version 2, or (at
7     * your option) any later version.
8     *
9     * This program is distributed in the hope that it will be useful, but
10     * WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12     * General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with program; see the file COPYING. If not, write to the Free
16     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17     * 02110-1301 USA.
18     */
19    
20     #ifndef GIGEDIT_GLOBAL_H
21     #define GIGEDIT_GLOBAL_H
22    
23     #if HAVE_CONFIG_H
24     # include <config.h>
25     #endif
26    
27 schoenebeck 3151 #include <cstring>
28 schoenebeck 3341 #include <algorithm>
29 schoenebeck 3151
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 schoenebeck 2967 #if !defined(WIN32)
39     # include <unistd.h>
40     # include <errno.h>
41     #endif
42    
43 persson 2442 #include <sstream>
44 schoenebeck 3089 #include <map>
45 persson 2442
46 schoenebeck 3089 #ifdef LIBGIG_HEADER_FILE
47     # include LIBGIG_HEADER_FILE(gig.h)
48 schoenebeck 3157 # include LIBGIG_HEADER_FILE(Serialization.h)
49 schoenebeck 3089 #else
50     # include <gig.h>
51 schoenebeck 3157 # include <Serialization.h>
52 schoenebeck 3089 #endif
53    
54 schoenebeck 2474 //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
55     #if (HAVE_GETTEXT || defined(__APPLE__))
56 schoenebeck 1396 # include <libintl.h>
57     # define _(String) gettext(String)
58     #else
59     # define _(String) String
60     #endif
61    
62     #if defined(WIN32) && !HAVE_CONFIG_H
63     # include "../../win32/libgigedit_private.h" // like config.h, automatically generated by Dev-C++
64     # define PACKAGE "gigedit"
65     # define VERSION VER_STRING // VER_STRING defined in libgig_private.h
66     #endif // WIN32
67    
68 schoenebeck 2692 #define UNICODE_RIGHT_ARROW Glib::ustring(1, gunichar(0x2192))
69     #define UNICODE_LEFT_ARROW Glib::ustring(1, gunichar(0x2190))
70 schoenebeck 3155 #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 schoenebeck 2692
85 schoenebeck 3123 // 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 schoenebeck 3151 #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 schoenebeck 3340 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 persson 2442 template<class T> inline std::string ToString(T o) {
135     std::stringstream ss;
136     ss << o;
137     return ss.str();
138     }
139    
140 schoenebeck 3176 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 schoenebeck 3089 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 schoenebeck 2548 /// Find the number of bits required to hold the specified amount of zones.
163     inline int zoneCountToBits(int nZones) {
164 schoenebeck 2604 if (!nZones) return 0;
165 schoenebeck 2548 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 schoenebeck 3089 /**
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 schoenebeck 3123
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 schoenebeck 3089 };
212    
213 schoenebeck 3123 //TODO: this function and caseOfDimRegion() from dimregionchooser.h are duplicates, eliminate either one of them!
214 schoenebeck 3089 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 schoenebeck 3307 /**
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 schoenebeck 3089 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 schoenebeck 3307 if (dimCase.isViolating(c)) continue;
254     if (skipUnusedZones && !isUsedCase(c, rgn)) continue;
255     v.push_back(rgn->pDimensionRegions[idr]);
256 schoenebeck 3089 }
257     return v;
258     }
259    
260 schoenebeck 3123 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 schoenebeck 3177 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 schoenebeck 1396 #endif // GIGEDIT_GLOBAL_H

  ViewVC Help
Powered by ViewVC