~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/sdk/globals.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
 
3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 
4
 *
 
5
 * $Revision: 4909 $
 
6
 * $Id: globals.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
 
7
 * $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/sdk/globals.cpp $
 
8
 */
 
9
 
 
10
#include "sdk_precomp.h"
 
11
 
 
12
#ifndef CB_PRECOMP
 
13
    #include "globals.h"
 
14
    #include <wx/filename.h>
 
15
    #include <wx/file.h>
 
16
    #include <wx/image.h>
 
17
    #include <wx/listctrl.h>
 
18
    #include <wx/filesys.h>
 
19
    #include "cbexception.h"
 
20
    #include "manager.h"
 
21
    #include "configmanager.h" // ReadBool
 
22
    #include "filemanager.h"
 
23
#endif
 
24
 
 
25
#include "tinyxml/tinyxml.h"
 
26
#include <wx/filefn.h>
 
27
#include <wx/tokenzr.h>
 
28
#include <wx/dirdlg.h>
 
29
#include <wx/msgdlg.h>
 
30
#include <wx/fontmap.h>
 
31
#include <algorithm>
 
32
#include "filefilters.h"
 
33
#include "tinyxml/tinywxuni.h"
 
34
 
 
35
 
 
36
namespace compatibility { typedef TernaryCondTypedef<wxMinimumVersion<2,5>::eval, wxTreeItemIdValue, long int>::eval tree_cookie_t; };
 
37
 
 
38
 
 
39
const wxString DEFAULT_WORKSPACE     = _T("default.workspace");
 
40
const wxString DEFAULT_ARRAY_SEP     = _T(";");
 
41
 
 
42
#ifndef __WXMAC__
 
43
const wxString DEFAULT_CONSOLE_TERM  = _T("xterm -T $TITLE -e");
 
44
#else
 
45
const wxString DEFAULT_CONSOLE_TERM  = _T("osascript -e 'tell app \"Terminal\" to do script \"$SCRIPT\"'");
 
46
#endif
 
47
const wxString DEFAULT_CONSOLE_SHELL = _T("/bin/sh -c");
 
48
 
 
49
int GetPlatformsFromString(const wxString& platforms)
 
50
{
 
51
        bool pW = platforms.Contains(_("Windows"));
 
52
        bool pU = platforms.Contains(_("Unix"));
 
53
        bool pM = platforms.Contains(_("Mac"));
 
54
        bool pA = platforms.Contains(_("All"));
 
55
 
 
56
        if (pA || (pW && pU && pM))
 
57
                return spAll;
 
58
 
 
59
        int p = 0;
 
60
        if (pW)
 
61
                p |= spWindows;
 
62
        if (pU)
 
63
                p |= spUnix;
 
64
        if (pM)
 
65
                p |= spMac;
 
66
        return p;
 
67
}
 
68
 
 
69
wxString GetStringFromPlatforms(int platforms, bool forceSeparate)
 
70
{
 
71
        wxString ret;
 
72
 
 
73
        if (!forceSeparate)
 
74
        {
 
75
                int tmpAll = spWindows | spUnix | spMac;
 
76
                if (((platforms & tmpAll) == tmpAll) || ((platforms & spAll) == spAll))
 
77
                        return _("All");
 
78
        }
 
79
 
 
80
        if (platforms & spWindows)
 
81
                ret << _("Windows;");
 
82
        if (platforms & spUnix)
 
83
                ret << _("Unix;");
 
84
        if (platforms & spMac)
 
85
                ret << _("Mac;");
 
86
        return ret;
 
87
}
 
88
 
 
89
/*
 
90
        Killerbot : 6 Oktober 2007
 
91
        The method has been extended with a bool to specify if the seperator should be appended at the end.
 
92
        Ultimate goal : every client gives as a value : false.
 
93
        Why : well a seperator should separate, there's nothing to separate at the end (like nothing to separate
 
94
        at the begining, we don't put one there ...), but some client code is having problems when the separator is
 
95
        not present at the end. So for compatibility issues we have as default value for the new argument true, so the
 
96
        old code has the same behaviour as before [TODO: make those clients no longer dependent on this stupid final separator behaviour]
 
97
        New code will specify false as the bool value, so hoping rather soon a search on this method will have all hits showing
 
98
        false as the last argument ....
 
99
*/
 
100
 
 
101
wxString GetStringFromArray(const wxArrayString& array, const wxString& separator, bool SeparatorAtEnd)
 
102
{
 
103
    wxString out;
 
104
    for (unsigned int i = 0; i < array.GetCount(); ++i)
 
105
    {
 
106
        out << array[i];
 
107
        if(i < array.GetCount() - 1 || SeparatorAtEnd)
 
108
        {
 
109
            out << separator;
 
110
        }
 
111
    }
 
112
    return out;
 
113
} // end of GetStringFromArray
 
114
 
 
115
wxArrayString GetArrayFromString(const wxString& text, const wxString& separator, bool trimSpaces)
 
116
{
 
117
    wxArrayString out;
 
118
    wxString search = text;
 
119
    int seplen = separator.Length();
 
120
    while (true)
 
121
    {
 
122
        int idx = search.Find(separator);
 
123
        if (idx == -1)
 
124
        {
 
125
            if (trimSpaces)
 
126
            {
 
127
                search.Trim(false);
 
128
                search.Trim(true);
 
129
            }
 
130
            if (!search.IsEmpty())
 
131
                out.Add(search);
 
132
            break;
 
133
        }
 
134
        wxString part = search.Left(idx);
 
135
        search.Remove(0, idx + seplen);
 
136
        if (trimSpaces)
 
137
        {
 
138
            part.Trim(false);
 
139
            part.Trim(true);
 
140
        }
 
141
        if (!part.IsEmpty())
 
142
            out.Add(part);
 
143
    }
 
144
    return out;
 
145
}
 
146
 
 
147
void AppendArray(const wxArrayString& from, wxArrayString& to)
 
148
{
 
149
    for (unsigned int i = 0; i < from.GetCount(); ++i)
 
150
    {
 
151
        to.Add(from[i]);
 
152
    }
 
153
}
 
154
 
 
155
wxString UnixFilename(const wxString& filename)
 
156
{
 
157
    wxString result = filename;
 
158
 
 
159
    if(platform::windows)
 
160
    {
 
161
        bool unc_name = result.StartsWith(_T("\\\\"));
 
162
 
 
163
        while (result.Replace(_T("/"), _T("\\")))
 
164
            ;
 
165
        while (result.Replace(_T("\\\\"), _T("\\")))
 
166
            ;
 
167
 
 
168
        if (unc_name)
 
169
            result = _T("\\") + result;
 
170
    }
 
171
    else
 
172
    {
 
173
        while (result.Replace(_T("\\"), _T("/")))
 
174
            ;
 
175
        while (result.Replace(_T("//"), _T("/")))
 
176
            ;
 
177
    }
 
178
 
 
179
    return result;
 
180
}
 
181
 
 
182
void QuoteStringIfNeeded(wxString& str)
 
183
{
 
184
        bool hasSpace = str.Find(_T(' ')) != -1;
 
185
        bool hasParen = !platform::windows && (str.Find(_T('(')) != -1 || str.Find(_T(')')) != -1);
 
186
    if (!str.IsEmpty() && str.GetChar(0) != _T('"') && (hasSpace || hasParen))
 
187
        str = wxString(_T("\"")) + str + _T("\"");
 
188
}
 
189
 
 
190
wxString EscapeSpaces(const wxString& str)
 
191
{
 
192
        wxString ret = str;
 
193
        if (!ret.IsEmpty() && ret[0] != _T('"') && ret[0] != _T('\''))
 
194
        {
 
195
                // TODO: make it faster
 
196
                ret.Replace(_T(" "), _T("\\ "));
 
197
                ret.Replace(_T("\t"), _T("\\\t"));
 
198
        }
 
199
        return ret;
 
200
}
 
201
 
 
202
FileType FileTypeOf(const wxString& filename)
 
203
{
 
204
    wxString ext = filename.AfterLast(_T('.')).Lower();
 
205
 
 
206
    if (ext.IsSameAs(FileFilters::ASM_EXT) ||
 
207
        ext.IsSameAs(FileFilters::C_EXT) ||
 
208
        ext.IsSameAs(FileFilters::CC_EXT) ||
 
209
        ext.IsSameAs(FileFilters::CPP_EXT) ||
 
210
        ext.IsSameAs(FileFilters::CXX_EXT) ||
 
211
        ext.IsSameAs(FileFilters::S_EXT) ||
 
212
        ext.IsSameAs(FileFilters::SS_EXT) ||
 
213
        ext.IsSameAs(FileFilters::S62_EXT) ||
 
214
        ext.IsSameAs(FileFilters::D_EXT) ||
 
215
        ext.IsSameAs(FileFilters::F_EXT) ||
 
216
        ext.IsSameAs(FileFilters::F77_EXT) ||
 
217
        ext.IsSameAs(FileFilters::F90_EXT) ||
 
218
        ext.IsSameAs(FileFilters::F95_EXT) ||
 
219
        ext.IsSameAs(FileFilters::JAVA_EXT)
 
220
       )
 
221
        return ftSource;
 
222
 
 
223
    else if (ext.IsSameAs(FileFilters::H_EXT) ||
 
224
             ext.IsSameAs(FileFilters::HH_EXT) ||
 
225
             ext.IsSameAs(FileFilters::HPP_EXT) ||
 
226
             ext.IsSameAs(FileFilters::HXX_EXT)
 
227
            )
 
228
        return ftHeader;
 
229
 
 
230
    else if (ext.IsSameAs(FileFilters::CODEBLOCKS_EXT))
 
231
        return ftCodeBlocksProject;
 
232
 
 
233
    else if (ext.IsSameAs(FileFilters::WORKSPACE_EXT))
 
234
        return ftCodeBlocksWorkspace;
 
235
 
 
236
    else if (ext.IsSameAs(FileFilters::DEVCPP_EXT))
 
237
        return ftDevCppProject;
 
238
 
 
239
    else if (ext.IsSameAs(FileFilters::MSVC6_EXT))
 
240
        return ftMSVC6Project;
 
241
 
 
242
    else if (ext.IsSameAs(FileFilters::MSVC7_EXT))
 
243
        return ftMSVC7Project;
 
244
 
 
245
    else if (ext.IsSameAs(FileFilters::MSVC6_WORKSPACE_EXT))
 
246
        return ftMSVC6Workspace;
 
247
 
 
248
    else if (ext.IsSameAs(FileFilters::MSVC7_WORKSPACE_EXT))
 
249
        return ftMSVC7Workspace;
 
250
 
 
251
    else if (ext.IsSameAs(FileFilters::XCODE1_EXT))
 
252
        return ftXcode1Project; // Xcode 1.0+ (Mac OS X 10.3)
 
253
 
 
254
    else if (ext.IsSameAs(FileFilters::XCODE2_EXT))
 
255
        return ftXcode2Project; // Xcode 2.1+ (Mac OS X 10.4)
 
256
 
 
257
    else if (ext.IsSameAs(FileFilters::OBJECT_EXT))
 
258
        return ftObject;
 
259
 
 
260
    else if (ext.IsSameAs(FileFilters::XRCRESOURCE_EXT))
 
261
        return ftXRCResource;
 
262
 
 
263
    else if (ext.IsSameAs(FileFilters::RESOURCE_EXT))
 
264
        return ftResource;
 
265
 
 
266
    else if (ext.IsSameAs(FileFilters::RESOURCEBIN_EXT))
 
267
        return ftResourceBin;
 
268
 
 
269
    else if (ext.IsSameAs(FileFilters::STATICLIB_EXT))
 
270
        return ftStaticLib;
 
271
 
 
272
    else if (ext.IsSameAs(FileFilters::DYNAMICLIB_EXT))
 
273
        return ftDynamicLib;
 
274
 
 
275
    else if (ext.IsSameAs(FileFilters::NATIVE_EXT))
 
276
        return ftNative;
 
277
 
 
278
    else if (ext.IsSameAs(FileFilters::EXECUTABLE_EXT))
 
279
        return ftExecutable;
 
280
 
 
281
    else if (ext.IsSameAs(FileFilters::XML_EXT))
 
282
        return ftXMLDocument;
 
283
 
 
284
    else if (ext.IsSameAs(FileFilters::SCRIPT_EXT))
 
285
        return ftScript;
 
286
 
 
287
    return ftOther;
 
288
}
 
289
 
 
290
bool DoRememberExpandedNodes(wxTreeCtrl* tree, const wxTreeItemId& parent, wxArrayString& nodePaths, wxString& path)
 
291
{
 
292
    // remember expanded tree nodes of this tree
 
293
    if (!tree || !parent.IsOk())
 
294
        return false;
 
295
 
 
296
    wxString originalPath = path;
 
297
    bool found = false;
 
298
 
 
299
    compatibility::tree_cookie_t cookie = 0;
 
300
 
 
301
    wxTreeItemId child = tree->GetFirstChild(parent, cookie);
 
302
    while (child.IsOk())
 
303
    {
 
304
        if (tree->ItemHasChildren(child) && tree->IsExpanded(child))
 
305
        {
 
306
            found = true;
 
307
            path << _T("/") << tree->GetItemText(child);
 
308
            DoRememberExpandedNodes(tree, child, nodePaths, path);
 
309
            nodePaths.Add(path);
 
310
            path = originalPath;
 
311
        }
 
312
        child = tree->GetNextChild(parent, cookie);
 
313
    }
 
314
    return found;
 
315
}
 
316
 
 
317
void DoExpandRememberedNode(wxTreeCtrl* tree, const wxTreeItemId& parent, const wxString& path)
 
318
{
 
319
    if (!path.IsEmpty())
 
320
    {
 
321
        //Manager::Get()->GetLogManager()->Log(mltDevDebug, path);
 
322
        wxString tmpPath;
 
323
        tmpPath = path;
 
324
        wxString folder;
 
325
        int pos = tmpPath.Find(_T('/'));
 
326
        while (pos == 0)
 
327
        {
 
328
            tmpPath = tmpPath.Right(tmpPath.Length() - pos - 1);
 
329
            pos = tmpPath.Find(_T('/'));
 
330
        }
 
331
 
 
332
        if (pos < 0) // no '/'
 
333
        {
 
334
            folder = tmpPath;
 
335
            tmpPath.Clear();
 
336
        }
 
337
        else
 
338
        {
 
339
            folder = tmpPath.Left(pos);
 
340
            tmpPath = tmpPath.Right(tmpPath.Length() - pos - 1);
 
341
        }
 
342
 
 
343
        //Manager::Get()->GetLogManager()->Log(mltDevDebug, "%s, %s", folder.c_str(), tmpPath.c_str());
 
344
 
 
345
        compatibility::tree_cookie_t cookie = 0;
 
346
 
 
347
        wxTreeItemId child = tree->GetFirstChild(parent, cookie);
 
348
        while (child.IsOk())
 
349
        {
 
350
            wxString itemText = tree->GetItemText(child);
 
351
            if (itemText.Matches(folder))
 
352
            {
 
353
                tree->Expand(child);
 
354
                DoExpandRememberedNode(tree, child, tmpPath);
 
355
                break;
 
356
            }
 
357
            child = tree->GetNextChild(parent, cookie);
 
358
        }
 
359
    }
 
360
}
 
361
 
 
362
void SaveTreeState(wxTreeCtrl* tree, const wxTreeItemId& parent, wxArrayString& nodePaths)
 
363
{
 
364
    nodePaths.Clear();
 
365
    if (!parent.IsOk() || !tree || !tree->ItemHasChildren(parent) || !tree->IsExpanded(parent))
 
366
        return;
 
367
    wxString tmp;
 
368
    if (!DoRememberExpandedNodes(tree, parent, nodePaths, tmp))
 
369
        nodePaths.Add(tmp); // just the tree root
 
370
}
 
371
 
 
372
void RestoreTreeState(wxTreeCtrl* tree, const wxTreeItemId& parent, wxArrayString& nodePaths)
 
373
{
 
374
    if (!parent.IsOk() || !tree)
 
375
        return;
 
376
    if (nodePaths.GetCount() == 0)
 
377
    {
 
378
        tree->Collapse(parent);
 
379
        return;
 
380
    }
 
381
    for (unsigned int i = 0; i < nodePaths.GetCount(); ++i)
 
382
        DoExpandRememberedNode(tree, parent, nodePaths[i]);
 
383
    nodePaths.Clear();
 
384
}
 
385
 
 
386
bool CreateDirRecursively(const wxString& full_path, int perms)
 
387
{
 
388
    if(wxDirExists(full_path)) // early out
 
389
        return true;
 
390
 
 
391
    wxArrayString dirs;
 
392
    wxString currdir;
 
393
 
 
394
    {
 
395
        wxFileName tmp(full_path);
 
396
        currdir = tmp.GetVolume() + tmp.GetVolumeSeparator() + wxFILE_SEP_PATH;
 
397
        dirs = tmp.GetDirs();
 
398
    }
 
399
    for (size_t i = 0; i < dirs.GetCount(); ++i)
 
400
    {
 
401
        currdir << dirs[i];
 
402
        if (!wxDirExists(currdir) && !wxMkdir(currdir, perms))
 
403
            return false;
 
404
        currdir << wxFILE_SEP_PATH;
 
405
    }
 
406
    return true;
 
407
}
 
408
 
 
409
bool CreateDir(const wxString& full_path, int perms)
 
410
{
 
411
    if (!wxDirExists(full_path) && !wxMkdir(full_path, perms))
 
412
        return false;
 
413
 
 
414
    return true;
 
415
}
 
416
 
 
417
wxString ChooseDirectory(wxWindow* parent,
 
418
                         const wxString& message,
 
419
                         const wxString& initialPath,
 
420
                         const wxString& basePath,
 
421
                         bool askToMakeRelative, // relative to initialPath
 
422
                         bool showCreateDirButton) // where supported
 
423
{
 
424
    wxDirDialog dlg(parent,
 
425
                    message,
 
426
                    _T(""),
 
427
                    (showCreateDirButton ? wxDD_NEW_DIR_BUTTON : 0) | wxRESIZE_BORDER);
 
428
    dlg.SetPath(initialPath);
 
429
    PlaceWindow(&dlg);
 
430
    if (dlg.ShowModal() != wxID_OK)
 
431
        return wxEmptyString;
 
432
 
 
433
    wxFileName path(dlg.GetPath());
 
434
    if (askToMakeRelative && !basePath.IsEmpty())
 
435
    {
 
436
        // ask the user if he wants it to be kept as relative
 
437
        if (cbMessageBox(_("Keep this as a relative path?"),
 
438
                         _("Question"),
 
439
                         wxICON_QUESTION | wxYES_NO) == wxID_YES)
 
440
        {
 
441
            path.MakeRelativeTo(basePath);
 
442
        }
 
443
    }
 
444
    return path.GetFullPath();
 
445
}
 
446
 
 
447
// Reads a wxString from a file. File must be open. File is closed automatically.
 
448
bool cbRead(wxFile& file, wxString& st, wxFontEncoding encoding)
 
449
{
 
450
    st.Empty();
 
451
    if (!file.IsOpened())
 
452
        return false;
 
453
    int len = file.Length();
 
454
    if(!len)
 
455
    {
 
456
        file.Close();
 
457
        return true;
 
458
    }
 
459
 
 
460
    char* buff = new char[len+1];
 
461
    if (!buff) // remark by killerbot : this is useless, since when out of mem --> exception (this is not malloc you know)
 
462
    {
 
463
        file.Close();
 
464
        return false;
 
465
    }
 
466
    file.Read((void*)buff, len);
 
467
    file.Close();
 
468
    buff[len]='\0';
 
469
 
 
470
        DetectEncodingAndConvert(buff, st, encoding);
 
471
        delete [] buff;
 
472
 
 
473
    return true;
 
474
} // end of cbRead
 
475
 
 
476
wxString cbReadFileContents(wxFile& file, wxFontEncoding encoding)
 
477
{
 
478
    wxString st;
 
479
    cbRead(file, st, encoding);
 
480
    return st;
 
481
}
 
482
 
 
483
// Writes a wxString to a file. File must be open. File is closed automatically.
 
484
bool cbWrite(wxFile& file, const wxString& buff, wxFontEncoding encoding)
 
485
{
 
486
    bool result = false;
 
487
    if (file.IsOpened())
 
488
    {
 
489
        wxCSConv conv(encoding);
 
490
        result = file.Write(buff,conv);
 
491
        if(result)
 
492
            file.Flush();
 
493
        file.Close();
 
494
    }
 
495
    return result;
 
496
}
 
497
 
 
498
// Writes a wxString to a file. Takes care of unicode and uses a temporary file
 
499
// to save first and then it copies it over the original.
 
500
bool cbSaveToFile(const wxString& filename, const wxString& contents, wxFontEncoding encoding, bool bom)
 
501
{
 
502
    return Manager::Get()->GetFileManager()->Save(filename, contents, encoding, bom);
 
503
}
 
504
 
 
505
// Saves a TinyXML document correctly, even if the path contains unicode characters.
 
506
bool cbSaveTinyXMLDocument(TiXmlDocument* doc, const wxString& filename)
 
507
{
 
508
    return TinyXML::SaveDocument(filename, doc);
 
509
}
 
510
 
 
511
// Return @c str as a proper unicode-compatible string
 
512
wxString cbC2U(const char* str)
 
513
{
 
514
#if wxUSE_UNICODE
 
515
    return wxString(str, wxConvUTF8);
 
516
#else
 
517
    return wxString(str);
 
518
#endif
 
519
}
 
520
 
 
521
// Return multibyte (C string) representation of the string
 
522
const wxWX2MBbuf cbU2C(const wxString& str)
 
523
{
 
524
    if(platform::unicode)
 
525
        return str.mb_str(wxConvUTF8);
 
526
    else
 
527
        return str.mb_str();
 
528
}
 
529
 
 
530
// Try converting a C-string from different encodings until a possible match is found.
 
531
// This tries the following encoding converters (in the same order):
 
532
// utf8, system, default and iso8859-1 to iso8859-15
 
533
wxFontEncoding DetectEncodingAndConvert(const char* strIn, wxString& strOut, wxFontEncoding possibleEncoding)
 
534
{
 
535
        wxFontEncoding encoding = possibleEncoding;
 
536
        strOut.Clear();
 
537
 
 
538
    if(platform::unicode)
 
539
    {
 
540
        if (possibleEncoding != wxFONTENCODING_UTF16 &&
 
541
            possibleEncoding != wxFONTENCODING_UTF16LE &&
 
542
            possibleEncoding != wxFONTENCODING_UTF16BE &&
 
543
            possibleEncoding != wxFONTENCODING_UTF32 &&
 
544
            possibleEncoding != wxFONTENCODING_UTF32LE &&
 
545
            possibleEncoding != wxFONTENCODING_UTF32BE)
 
546
        {
 
547
            // crashes deep in the runtime (windows, at least)
 
548
            // if one of the above encodings, hence the guard
 
549
            wxCSConv conv(possibleEncoding);
 
550
            strOut = wxString(strIn, conv);
 
551
 
 
552
            if (strOut.Length() == 0)
 
553
            {
 
554
                // oops! wrong encoding...
 
555
 
 
556
                // try utf8 first, if that was not what was asked for
 
557
                if (possibleEncoding != wxFONTENCODING_UTF8)
 
558
                {
 
559
                    encoding = wxFONTENCODING_UTF8;
 
560
                    strOut = wxString(strIn, wxConvUTF8);
 
561
                }
 
562
 
 
563
                // check again: if still not right, try system encoding, default encoding and then iso8859-1 to iso8859-15
 
564
                if (strOut.Length() == 0)
 
565
                {
 
566
                    for (int i = wxFONTENCODING_SYSTEM; i < wxFONTENCODING_ISO8859_MAX; ++i)
 
567
                    {
 
568
                        encoding = (wxFontEncoding)i;
 
569
                        if (encoding == possibleEncoding)
 
570
                            continue; // skip if same as what was asked
 
571
                        wxCSConv conv(encoding);
 
572
                        strOut = wxString(strIn, conv);
 
573
                        if (strOut.Length() != 0)
 
574
                            break; // got it!
 
575
                    }
 
576
                }
 
577
            }
 
578
        }
 
579
        else
 
580
        {
 
581
            strOut = (const wxChar*) strIn;
 
582
        }
 
583
    }
 
584
    else
 
585
    {
 
586
        strOut = (const wxChar*) strIn;
 
587
    }
 
588
        return encoding;
 
589
}
 
590
 
 
591
wxString URLEncode(const wxString &str) // not sure this is 100% standards compliant, but I hope so
 
592
{
 
593
    wxString ret;
 
594
    wxString t;
 
595
    for(unsigned int i = 0; i < str.length(); ++i)
 
596
    {
 
597
        wxChar c = str[i];
 
598
        if(   (c >= _T('A') && c <= _T('Z'))
 
599
           || (c >= _T('a') && c <= _T('z'))
 
600
           || (c >= _T('0') && c <= _T('9'))
 
601
           ||  c == _T('.') || c == _T('-') || c == _T('_') )
 
602
 
 
603
            ret.Append(c);
 
604
        else if(c == _T(' '))
 
605
            ret.Append(_T('+'));
 
606
        else
 
607
        {
 
608
            t.sprintf(_T("%%%02X"), (unsigned int) c);
 
609
            ret.Append(t);
 
610
        }
 
611
    }
 
612
    return ret;
 
613
}
 
614
 
 
615
bool IsWindowReallyShown(wxWindow* win)
 
616
{
 
617
    while (win && win->IsShown())
 
618
    {
 
619
        win = win->GetParent();
 
620
        if (!win)
 
621
            return true;
 
622
    }
 
623
    return false;
 
624
}
 
625
 
 
626
bool NormalizePath(wxFileName& f,const wxString& base)
 
627
{
 
628
    bool result = true;
 
629
//    if(!f.IsAbsolute())
 
630
    {
 
631
        f.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
 
632
        result = f.IsOk();
 
633
    }
 
634
    return result;
 
635
}
 
636
 
 
637
// function to check the common controls version
 
638
// (should it be moved in sdk globals?)
 
639
#ifdef __WXMSW__
 
640
#include <windows.h>
 
641
#include <shlwapi.h>
 
642
bool UsesCommonControls6()
 
643
{
 
644
    bool result = false;
 
645
    HINSTANCE hinstDll;
 
646
    DWORD dwVersion = 0;
 
647
    hinstDll = LoadLibrary(_T("comctl32.dll"));
 
648
    if(hinstDll)
 
649
    {
 
650
        DLLGETVERSIONPROC pDllGetVersion;
 
651
        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
 
652
 
 
653
        if (pDllGetVersion)
 
654
        {
 
655
            DLLVERSIONINFO dvi;
 
656
            HRESULT hr;
 
657
 
 
658
            ZeroMemory(&dvi, sizeof(dvi));
 
659
            dvi.cbSize = sizeof(dvi);
 
660
 
 
661
            hr = (*pDllGetVersion)(&dvi);
 
662
 
 
663
            if (SUCCEEDED(hr))
 
664
            {
 
665
               dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
 
666
               result = dvi.dwMajorVersion == 6;
 
667
            }
 
668
        }
 
669
 
 
670
        FreeLibrary(hinstDll);
 
671
    }
 
672
    return result;
 
673
}
 
674
#else
 
675
bool UsesCommonControls6()
 
676
{
 
677
        // for non-windows platforms, return true
 
678
        // as this is only used for knowing if bitmaps support transparency or not
 
679
    return true;
 
680
}
 
681
#endif
 
682
 
 
683
wxBitmap cbLoadBitmap(const wxString& filename, int bitmapType)
 
684
{
 
685
    // cache this, can't change while we 're running :)
 
686
    static bool oldCommonControls = !UsesCommonControls6();
 
687
 
 
688
    wxImage im;
 
689
    wxFileSystem* fs = new wxFileSystem;
 
690
    wxFSFile* f = fs->OpenFile(filename);
 
691
    if (f)
 
692
    {
 
693
        wxInputStream* is = f->GetStream();
 
694
        im.LoadFile(*is, bitmapType);
 
695
        delete f;
 
696
    }
 
697
    delete fs;
 
698
    if (oldCommonControls && im.HasAlpha())
 
699
        im.ConvertAlphaToMask();
 
700
 
 
701
    return wxBitmap(im);
 
702
}
 
703
 
 
704
void SetSettingsIconsStyle(wxListCtrl* lc, SettingsIconsStyle style)
 
705
{
 
706
// this doesn't work under wxGTK...
 
707
#ifdef __WXMSW__
 
708
    long flags = lc->GetWindowStyleFlag();
 
709
    switch (style)
 
710
    {
 
711
        case sisNoIcons: flags = (flags & ~wxLC_ICON) | wxLC_SMALL_ICON; break;
 
712
        default: flags = (flags & ~wxLC_SMALL_ICON) | wxLC_ICON; break;
 
713
    }
 
714
    lc->SetWindowStyleFlag(flags);
 
715
#endif
 
716
}
 
717
 
 
718
SettingsIconsStyle GetSettingsIconsStyle(wxListCtrl* lc)
 
719
{
 
720
// this doesn't work under wxGTK...
 
721
#ifdef __WXMSW__
 
722
    long flags = lc->GetWindowStyleFlag();
 
723
    if (flags & wxLC_SMALL_ICON)
 
724
        return sisNoIcons;
 
725
#endif
 
726
    return sisLargeIcons;
 
727
}
 
728
 
 
729
#ifdef __WXMSW__
 
730
 
 
731
typedef APIENTRY HMONITOR (*MonitorFromWindow_t)(HWND, DWORD);
 
732
typedef APIENTRY BOOL (*GetMonitorInfo_t)(HMONITOR, LPMONITORINFO);
 
733
 
 
734
void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode, bool enforce)
 
735
{
 
736
    HMONITOR hMonitor;
 
737
    MONITORINFO mi;
 
738
    RECT        r;
 
739
 
 
740
    int the_mode;
 
741
 
 
742
    if(!w)
 
743
        cbThrow(_T("Passed NULL pointer to PlaceWindow."));
 
744
 
 
745
    wxWindow* referenceWindow = Manager::Get()->GetAppWindow();
 
746
 
 
747
    if(!referenceWindow)    // no application window available, so this is as good as we can get
 
748
        referenceWindow = w;
 
749
 
 
750
    wxRect windowRect = w->GetRect();
 
751
 
 
752
    ConfigManager *cfg = Manager::Get()->GetConfigManager(_T("app"));
 
753
    if(!enforce && cfg->ReadBool(_T("/dialog_placement/do_place")) == false)
 
754
        return;
 
755
 
 
756
    if(mode == pdlBest)
 
757
        the_mode = cfg->ReadInt(_T("/dialog_placement/dialog_position"), (int) pdlCentre);
 
758
    else
 
759
        the_mode = (int) mode;
 
760
 
 
761
 
 
762
    static MonitorFromWindow_t MonitorFromWindowProc = (MonitorFromWindow_t) GetProcAddress(GetModuleHandle(_T("user32.dll")), "MonitorFromWindow");
 
763
    static GetMonitorInfo_t GetMonitorInfoProc = (GetMonitorInfo_t) GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetMonitorInfoA");
 
764
    int monitorWidth;
 
765
    int monitorHeight;
 
766
 
 
767
    if(GetMonitorInfoProc)
 
768
    {
 
769
        hMonitor = MonitorFromWindowProc((HWND) referenceWindow->GetHandle(), MONITOR_DEFAULTTONEAREST);
 
770
 
 
771
        mi.cbSize = sizeof(mi);
 
772
        GetMonitorInfoProc(hMonitor, &mi);
 
773
        r = mi.rcWork;
 
774
 
 
775
        monitorWidth  = r.right - r.left;
 
776
        monitorHeight = r.bottom - r. top;
 
777
    }
 
778
    else // Win95, NT4: support only single monitor
 
779
    {
 
780
        wxDisplaySize(&monitorWidth, &monitorHeight);
 
781
        r.left = r.top = 0;
 
782
    }
 
783
 
 
784
 
 
785
    switch(the_mode)
 
786
    {
 
787
        case pdlCentre:
 
788
        {
 
789
            windowRect.x = r.left + (monitorWidth  - windowRect.width)/2;
 
790
            windowRect.y = r.top  + (monitorHeight - windowRect.height)/2;
 
791
        }
 
792
        break;
 
793
 
 
794
 
 
795
        case pdlHead:
 
796
        {
 
797
            windowRect.x = r.left + (monitorWidth  - windowRect.width)/2;
 
798
            windowRect.y = r.top  + (monitorHeight - windowRect.height)/3;
 
799
        }
 
800
        break;
 
801
 
 
802
 
 
803
        case pdlConstrain:
 
804
        {
 
805
            int x1 = windowRect.x;
 
806
            int x2 = windowRect.x + windowRect.width;
 
807
            int y1 = windowRect.y;
 
808
            int y2 = windowRect.y + windowRect.height;
 
809
 
 
810
            if(windowRect.width > monitorWidth) // cannot place without clipping, so centre it
 
811
            {
 
812
                x1 = r.left + (monitorWidth  - windowRect.width)/2;
 
813
                x2 = x1 + windowRect.width;
 
814
            }
 
815
            else
 
816
            {
 
817
                x2 = std::min((int) r.right, windowRect.GetRight());
 
818
                x1 = std::max(x2 - windowRect.width, (int) r.left);
 
819
                x2 = x1 + windowRect.width;
 
820
            }
 
821
            if(windowRect.height > monitorHeight) // cannot place without clipping, so centre it
 
822
            {
 
823
                y1 = r.top + (monitorHeight  - windowRect.height)/2;
 
824
                y2 = y1 + windowRect.height;
 
825
            }
 
826
            else
 
827
            {
 
828
                y2 = std::min((int) r.bottom, windowRect.GetBottom());
 
829
                y1 = std::max(y2 - windowRect.height, (int) r.top);
 
830
                y2 = y1 + windowRect.height;
 
831
            }
 
832
            windowRect = wxRect(x1, y1, x2-x1, y2-y1);
 
833
        }
 
834
        break;
 
835
 
 
836
 
 
837
        case pdlClip:
 
838
        {
 
839
            int x1 = windowRect.x;
 
840
            int x2 = windowRect.x + windowRect.width;
 
841
            int y1 = windowRect.y;
 
842
            int y2 = windowRect.y + windowRect.height;
 
843
 
 
844
            x1 = std::max(x1, (int) r.left);
 
845
            x2 = std::min(x2, (int) r.right);
 
846
            y1 = std::max(y1, (int) r.top);
 
847
            y2 = std::min(y2, (int) r.bottom);
 
848
 
 
849
            windowRect = wxRect(x1, y1, x2-x1, y2-y1);
 
850
        }
 
851
        break;
 
852
    }
 
853
 
 
854
    w->SetSize(windowRect.x,  windowRect.y, windowRect.width, windowRect.height, wxSIZE_ALLOW_MINUS_ONE);
 
855
}
 
856
 
 
857
 
 
858
#else // ----- non-Windows ----------------------------------------------
 
859
 
 
860
 
 
861
void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode, bool enforce)
 
862
// TODO (thomas#1#): The non-Windows implementation is *pathetic*.
 
863
// However, I don't know how to do it well under GTK / X / Xinerama / whatever.
 
864
// Anyone?
 
865
{
 
866
    int the_mode;
 
867
 
 
868
    wxWindow* referenceWindow = Manager::Get()->GetAppWindow();
 
869
    if(!referenceWindow) // let's not crash on shutdown
 
870
        return;
 
871
 
 
872
    if(!w)
 
873
        cbThrow(_T("Passed NULL pointer to PlaceWindow."));
 
874
 
 
875
 
 
876
    ConfigManager *cfg = Manager::Get()->GetConfigManager(_T("app"));
 
877
    if(!enforce && cfg->ReadBool(_T("/dialog_placement/do_place")) == false)
 
878
        return;
 
879
 
 
880
    if(mode == pdlBest)
 
881
        the_mode = cfg->ReadInt(_T("/dialog_placement/dialog_position"), (int) pdlCentre);
 
882
    else
 
883
        the_mode = (int) mode;
 
884
 
 
885
 
 
886
    if(the_mode == pdlCentre || the_mode == pdlHead)
 
887
    {
 
888
        w->CentreOnScreen();
 
889
        return;
 
890
    }
 
891
    else
 
892
    {
 
893
        wxRect windowRect = w->GetRect();
 
894
        wxRect parentRect = referenceWindow->GetRect();   // poo again!
 
895
 
 
896
        int x1 = windowRect.x;
 
897
        int x2 = windowRect.x + windowRect.width;
 
898
        int y1 = windowRect.y;
 
899
        int y2 = windowRect.y + windowRect.height;
 
900
 
 
901
        x1 = std::max(x1, parentRect.x);
 
902
        x2 = std::min(x2, parentRect.GetRight());
 
903
        y1 = std::max(y1, parentRect.y);
 
904
        y2 = std::min(y2, parentRect.GetBottom());
 
905
 
 
906
        w->SetSize(x1, y1, x2-x1, y2-y1, wxSIZE_ALLOW_MINUS_ONE);
 
907
    }
 
908
}
 
909
 
 
910
#endif //platform-specific placement code
 
911
 
 
912
DirAccessCheck cbDirAccessCheck(const wxString& dir)
 
913
{
 
914
    wxString actualDir = dir;
 
915
    // append ending path separator if needed
 
916
    if (actualDir.Last() != _T('/') && actualDir.Last() != _T('\\'))
 
917
        actualDir << wxFILE_SEP_PATH;
 
918
 
 
919
    if (!wxDirExists(actualDir))
 
920
        return dacInvalidDir;
 
921
 
 
922
    wxString testFile = wxFileName::CreateTempFileName(actualDir);
 
923
    if (!testFile.IsEmpty())
 
924
    {
 
925
        // ok, write-access confirmed
 
926
        // now remove the temporary file and return success
 
927
        wxRemoveFile(testFile);
 
928
        return dacReadWrite;
 
929
    }
 
930
 
 
931
    // if we reached here, the directory is not writable
 
932
    return dacReadOnly;
 
933
}
 
934
 
 
935
 
 
936
namespace platform
 
937
{
 
938
    windows_version_t cb_get_os()
 
939
    {
 
940
        if(!platform::windows)
 
941
        {
 
942
            return winver_NotWindows;
 
943
        }
 
944
        else
 
945
        {
 
946
 
 
947
            int famWin95 = wxOS_WINDOWS_9X;
 
948
            int famWinNT = wxOS_WINDOWS_NT;
 
949
 
 
950
            int Major = 0;
 
951
            int family = wxGetOsVersion(&Major, NULL);
 
952
 
 
953
            if(family == famWin95)
 
954
                 return winver_Windows9598ME;
 
955
 
 
956
            if(family == famWinNT)
 
957
            {
 
958
                if(Major == 5)
 
959
                    return winver_WindowsXP;
 
960
 
 
961
                if(Major == 6) // just guessing here, not sure if this is right
 
962
                    return winver_Vista;
 
963
 
 
964
                return winver_WindowsNT2000;
 
965
            }
 
966
 
 
967
            return winver_UnknownWindows;
 
968
        }
 
969
    };
 
970
 
 
971
    windows_version_t WindowsVersion()
 
972
    {
 
973
        static const windows_version_t theOS = cb_get_os();
 
974
        return theOS;
 
975
    }
 
976
}