/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

  • Committer: Andrew Bennetts
  • Date: 2008-10-27 06:14:45 UTC
  • mfrom: (3793 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3795.
  • Revision ID: andrew.bennetts@canonical.com-20081027061445-eqt9lz6uw1mbvq4g
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
except ImportError:
76
76
    has_win32api = False
77
77
 
 
78
# pulling in win32com.shell is a bit of overhead, and normally we don't need
 
79
# it as ctypes is preferred and common.  lazy_imports and "optional"
 
80
# modules don't work well, so we do our own lazy thing...
 
81
has_win32com_shell = None # Set to True or False once we know for sure...
78
82
 
79
83
# Special Win32 API constants
80
84
# Handles of std streams
84
88
 
85
89
# CSIDL constants (from MSDN 2003)
86
90
CSIDL_APPDATA = 0x001A      # Application Data folder
 
91
CSIDL_LOCAL_APPDATA = 0x001c# <user name>\Local Settings\Application Data (non roaming)
87
92
CSIDL_PERSONAL = 0x0005     # My Documents folder
88
93
 
89
94
# from winapi C headers
119
124
        return (defaultx, defaulty)
120
125
 
121
126
 
 
127
def _get_sh_special_folder_path(csidl):
 
128
    """Call SHGetSpecialFolderPathW if available, or return None.
 
129
    
 
130
    Result is always unicode (or None).
 
131
    """
 
132
    if has_ctypes:
 
133
        try:
 
134
            SHGetSpecialFolderPath = \
 
135
                ctypes.windll.shell32.SHGetSpecialFolderPathW
 
136
        except AttributeError:
 
137
            pass
 
138
        else:
 
139
            buf = ctypes.create_unicode_buffer(MAX_PATH)
 
140
            if SHGetSpecialFolderPath(None,buf,csidl,0):
 
141
                return buf.value
 
142
 
 
143
    global has_win32com_shell
 
144
    if has_win32com_shell is None:
 
145
        try:
 
146
            from win32com.shell import shell
 
147
            has_win32com_shell = True
 
148
        except ImportError:
 
149
            has_win32com_shell = False
 
150
    if has_win32com_shell:
 
151
        # still need to bind the name locally, but this is fast.
 
152
        from win32com.shell import shell
 
153
        try:
 
154
            return shell.SHGetSpecialFolderPath(0, csidl, 0)
 
155
        except shell.error:
 
156
            # possibly E_NOTIMPL meaning we can't load the function pointer,
 
157
            # or E_FAIL meaning the function failed - regardless, just ignore it
 
158
            pass
 
159
    return None
 
160
 
 
161
 
122
162
def get_appdata_location():
123
163
    """Return Application Data location.
124
164
    Return None if we cannot obtain location.
125
165
 
126
 
    Returned value can be unicode or plain sring.
 
166
    Windows defines two 'Application Data' folders per user - a 'roaming'
 
167
    one that moves with the user as they logon to different machines, and
 
168
    a 'local' one that stays local to the machine.  This returns the 'roaming'
 
169
    directory, and thus is suitable for storing user-preferences, etc.
 
170
 
 
171
    Returned value can be unicode or plain string.
127
172
    To convert plain string to unicode use
128
 
    s.decode(bzrlib.user_encoding)
 
173
    s.decode(osutils.get_user_encoding())
 
174
    (XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
129
175
    """
130
 
    if has_ctypes:
131
 
        try:
132
 
            SHGetSpecialFolderPath = \
133
 
                ctypes.windll.shell32.SHGetSpecialFolderPathW
134
 
        except AttributeError:
135
 
            pass
136
 
        else:
137
 
            buf = ctypes.create_unicode_buffer(MAX_PATH)
138
 
            if SHGetSpecialFolderPath(None,buf,CSIDL_APPDATA,0):
139
 
                return buf.value
 
176
    appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
 
177
    if appdata:
 
178
        return appdata
140
179
    # from env variable
141
180
    appdata = os.environ.get('APPDATA')
142
181
    if appdata:
152
191
    return None
153
192
 
154
193
 
 
194
def get_local_appdata_location():
 
195
    """Return Local Application Data location.
 
196
    Return the same as get_appdata_location() if we cannot obtain location.
 
197
 
 
198
    Windows defines two 'Application Data' folders per user - a 'roaming'
 
199
    one that moves with the user as they logon to different machines, and
 
200
    a 'local' one that stays local to the machine.  This returns the 'local'
 
201
    directory, and thus is suitable for caches, temp files and other things
 
202
    which don't need to move with the user.
 
203
 
 
204
    Returned value can be unicode or plain string.
 
205
    To convert plain string to unicode use
 
206
    s.decode(bzrlib.user_encoding)
 
207
    (XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
 
208
    """
 
209
    local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
 
210
    if local:
 
211
        return local
 
212
    # Vista supplies LOCALAPPDATA, but XP and earlier do not.
 
213
    local = os.environ.get('LOCALAPPDATA')
 
214
    if local:
 
215
        return local
 
216
    return get_appdata_location()
 
217
 
 
218
 
155
219
def get_home_location():
156
220
    """Return user's home location.
157
221
    Assume on win32 it's the <My Documents> folder.
160
224
 
161
225
    Returned value can be unicode or plain sring.
162
226
    To convert plain string to unicode use
163
 
    s.decode(bzrlib.user_encoding)
 
227
    s.decode(osutils.get_user_encoding())
164
228
    """
165
 
    if has_ctypes:
166
 
        try:
167
 
            SHGetSpecialFolderPath = \
168
 
                ctypes.windll.shell32.SHGetSpecialFolderPathW
169
 
        except AttributeError:
170
 
            pass
171
 
        else:
172
 
            buf = ctypes.create_unicode_buffer(MAX_PATH)
173
 
            if SHGetSpecialFolderPath(None,buf,CSIDL_PERSONAL,0):
174
 
                return buf.value
 
229
    home = _get_sh_special_folder_path(CSIDL_PERSONAL)
 
230
    if home:
 
231
        return home
175
232
    # try for HOME env variable
176
233
    home = os.path.expanduser('~')
177
234
    if home != '~':
190
247
 
191
248
    Returned value can be unicode or plain sring.
192
249
    To convert plain string to unicode use
193
 
    s.decode(bzrlib.user_encoding)
 
250
    s.decode(osutils.get_user_encoding())
194
251
    """
195
252
    if has_ctypes:
196
253
        try:
263
320
 
264
321
def _ensure_unicode(s):
265
322
    if s and type(s) != unicode:
266
 
        import bzrlib
267
 
        s = s.decode(bzrlib.user_encoding)
 
323
        from bzrlib import osutils
 
324
        s = s.decode(osutils.get_user_encoding())
268
325
    return s
269
326
 
270
327