~ubuntu-branches/debian/sid/smplayer/sid

« back to all changes in this revision

Viewing changes to src/winfileassoc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2008-01-31 13:44:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080131134453-nc4dwsn5pkiw5s9h
Tags: 0.6.0~rc1-1
* New upstream release.
* debian/control:
  - Build-depend on CDBS.
  - Updated upstream homepage.
* debian/copyright:
  - Updated download address.
* debian/rules:
  - Migrated to CDBS.
  - Tweaked get-orig-source to work with release candidates.
* debian/docs:
  - Removed Translations.txt, upstream removed it from the tarball.
  - Added Release_notes.txt.
* debian/manpages, debian/smplayer.1:
  - Deleted, manpage merged upstream.
* debian/smplayer.install:
  - Install usr/share/man.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  smplayer, GUI front-end for mplayer.
2
 
    Copyright (C) 2007 Ricardo Villalba <rvm@escomposlinux.org>
3
 
 
4
 
    This program is free software; you can redistribute it and/or modify
5
 
    it under the terms of the GNU General Public License as published by
6
 
    the Free Software Foundation; either version 2 of the License, or
7
 
    (at your option) any later version.
8
 
 
9
 
    This program is distributed in the hope that it will be useful,
10
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
    GNU General Public License for more details.
13
 
 
14
 
    You should have received a copy of the GNU General Public License
15
 
    along with this program; if not, write to the Free Software
16
 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 
18
 
 
19
 
        Winfileassoc.cpp
20
 
        Handles file associations in Windows
21
 
        Author: Florin Braghis (florin@libertv.ro)
22
 
*/
23
 
 
24
 
#include "winfileassoc.h"
25
 
#include <QSettings>
26
 
 
27
 
WinFileAssoc::WinFileAssoc( const QString& ClassId )
28
 
{
29
 
        m_ClassId = ClassId;
30
 
}
31
 
 
32
 
bool WinFileAssoc::CreateFileAssociation(const QString& fileExtension)
33
 
{
34
 
        //Registry keys modified:
35
 
        //HKEY_CLASSES_ROOT\.extension 
36
 
        //HKEY_CLASSES_ROOT\smplayer.exe
37
 
        //Shell 'Open With...' entry:
38
 
        //HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.avi
39
 
 
40
 
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
41
 
        QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat);
42
 
 
43
 
        if (!RegCR.isWritable() || RegCR.status() != QSettings::NoError)
44
 
                return false; 
45
 
 
46
 
        if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError)
47
 
                return false; 
48
 
 
49
 
        QString ExtKeyName = QString("SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension);
50
 
        QString ClassesKeyName = m_ClassId;
51
 
 
52
 
        QString BackupKeyName = ClassesKeyName + "/" + fileExtension; 
53
 
 
54
 
        //Save last ClassId from the extension class
55
 
        QString KeyVal = RegCR.value("." + fileExtension + "/.").toString();
56
 
        if (KeyVal != m_ClassId)
57
 
                RegCR.setValue("." + fileExtension + "/MPlayer_Backup", KeyVal); 
58
 
 
59
 
        //Save last ProgId and Application values from the Exts key
60
 
        KeyVal = RegCU.value(ExtKeyName + "/Progid").toString();
61
 
        if (KeyVal != m_ClassId)
62
 
                RegCU.setValue(ExtKeyName + "/MPlayer_Backup_ProgId", KeyVal);
63
 
 
64
 
        KeyVal = RegCU.value(ExtKeyName + "/Application").toString(); 
65
 
        if (KeyVal != m_ClassId) 
66
 
                RegCU.setValue(ExtKeyName + "/MPlayer_Backup_Application", KeyVal); 
67
 
 
68
 
        //Create the associations
69
 
        RegCR.setValue("." + fileExtension + "/.", m_ClassId);          //Extension class
70
 
        RegCU.setValue(ExtKeyName + "/Progid", m_ClassId);      //Explorer FileExt association
71
 
        return true; 
72
 
}
73
 
 
74
 
bool WinFileAssoc::RestoreFileAssociation(const QString& fileExtension)
75
 
{
76
 
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
77
 
        QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat);
78
 
 
79
 
        if (!RegCR.isWritable() || RegCR.status() != QSettings::NoError)
80
 
                return false; 
81
 
 
82
 
        if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError)
83
 
                return false; 
84
 
 
85
 
 
86
 
        QString ClassesKeyName = m_ClassId; 
87
 
        QString ExtKeyName = QString("SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension);
88
 
 
89
 
        QString BackupKeyName = ClassesKeyName + "/" + fileExtension; 
90
 
        QString OldProgId = RegCR.value("." + fileExtension + "/MPlayer_Backup").toString(); 
91
 
        QString OldApp  = RegCU.value(ExtKeyName + "/MPlayer_Backup_Application").toString(); 
92
 
        QString OldClassId = RegCU.value(ExtKeyName + "/MPlayer_Backup_ProgId").toString(); 
93
 
 
94
 
        //Restore old association
95
 
        if (!OldProgId.isEmpty() && OldProgId != m_ClassId)
96
 
        {
97
 
                RegCU.setValue(ExtKeyName + "/Progid", OldProgId);
98
 
        }
99
 
        else
100
 
        {
101
 
                RegCU.remove(ExtKeyName + "/Progid"); 
102
 
        }
103
 
 
104
 
        if (!OldApp.isEmpty() && OldApp != m_ClassId)
105
 
        {
106
 
                RegCU.setValue(ExtKeyName + "/Application", OldApp); 
107
 
        }
108
 
        else
109
 
        {
110
 
                RegCU.remove(ExtKeyName + "/Application");
111
 
        }
112
 
 
113
 
        if (!OldClassId.isEmpty() && OldClassId != m_ClassId)
114
 
        {
115
 
                RegCR.setValue("." + fileExtension + "/.", OldClassId); 
116
 
        }
117
 
        else
118
 
        {
119
 
                //No old association with this extension, it's better to remove it entirely
120
 
                RegCR.remove("." + fileExtension + "/."); 
121
 
        }
122
 
 
123
 
        //Remove our keys
124
 
        RegCR.remove(BackupKeyName + "/OldProgId"); 
125
 
        RegCR.remove(BackupKeyName + "/OldApplication"); 
126
 
        RegCR.remove(BackupKeyName + "/OldClassId"); 
127
 
        RegCR.remove(BackupKeyName); 
128
 
        return true; 
129
 
}
130
 
 
131
 
bool WinFileAssoc::CreateClassId(const QString& executablePath, const QString& friendlyName)
132
 
{
133
 
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
134
 
        if (!RegCR.isWritable() || RegCR.status() != QSettings::NoError)
135
 
                return false; 
136
 
 
137
 
        QString appPath = executablePath;
138
 
        appPath.replace('/', '\\'); //Explorer gives 'Access Denied' if we write the path with forward slashes to the registry
139
 
 
140
 
        //Add our ProgId to the HKCR classes
141
 
        RegCR.setValue(m_ClassId + "/shell/open/FriendlyAppName", friendlyName);
142
 
        RegCR.setValue(m_ClassId + "/shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath, "%1"));
143
 
        RegCR.setValue(m_ClassId + "/DefaultIcon/.", QString("\"%1\",0").arg(appPath));
144
 
        //Add "Enqueue" command
145
 
        RegCR.setValue(m_ClassId + "/shell/enqueue/.", QObject::tr("Enqueue in SMPlayer"));
146
 
        RegCR.setValue(m_ClassId + "/shell/enqueue/command/.", QString("\"%1\" -add-to-playlist \"%2\"").arg(appPath, "%1"));
147
 
        return true; 
148
 
}
149
 
 
150
 
//Called when no associations exist
151
 
bool WinFileAssoc::RemoveClassId()
152
 
{
153
 
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
154
 
 
155
 
        if (!RegCR.isWritable() || RegCR.status() != QSettings::NoError)
156
 
                return false; 
157
 
 
158
 
        RegCR.remove(m_ClassId + "/shell/open/FriendlyAppName");
159
 
        RegCR.remove(m_ClassId + "/shell/open/command/.");
160
 
        RegCR.remove(m_ClassId + "/shell/enqueue/command/.");
161
 
        RegCR.remove(m_ClassId + "/shell/enqueue/.");
162
 
        RegCR.remove(m_ClassId + "/DefaultIcon/.");
163
 
        RegCR.remove(m_ClassId);
164
 
        return true; 
165
 
}
 
1
/*  smplayer, GUI front-end for mplayer.
 
2
    Copyright (C) 2006-2008 Ricardo Villalba <rvm@escomposlinux.org>
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
 
 
19
        Winfileassoc.cpp
 
20
 
 
21
        Handles file associations in Windows Vista/XP/2000/NT/ME/98/95.
 
22
        We assume that the code is run without administrator privileges, so the associations are done for current user only.
 
23
        System-wide associations require writing to HKEY_CLASSES_ROOT and we don't want to get our hands dirty with that.
 
24
        Each user on the computer can configure his own set of file associations for SMPlayer, which is extremely cool.
 
25
 
 
26
        Optionally, during uninstall, it would be a good idea to call RestoreFileAssociations for all media types so
 
27
        that we can clean up the registry and restore the old associations for current user. 
 
28
 
 
29
        Vista:
 
30
        The code can only register the app as default program for selected extensions and check if it is the default. 
 
31
        It cannot restore 'old' default application, since this doesn't seem to be possible with the current Vista API.
 
32
 
 
33
        Tested on: Win98, Win2000, WinXP, Vista. 
 
34
        NOT tested on: Win95, ME and NT 4.0 (it should work on 95, ME; Not sure about NT 4.0).
 
35
 
 
36
        Author: Florin Braghis (florin@libertv.ro)
 
37
*/
 
38
 
 
39
#include "winfileassoc.h"
 
40
#include <QSettings>
 
41
#include <QApplication>
 
42
#include <QFileInfo>
 
43
 
 
44
/*
 
45
   Note by RVM: Added some #ifdef Q_OS_WIN to allow the file to compile under linux. 
 
46
   It should compile the code for Windows XP.
 
47
   The registry entries are saved on a file named HKEY_CURRENT_USER.
 
48
*/
 
49
 
 
50
WinFileAssoc::WinFileAssoc( const QString ClassId, const QString AppName )
 
51
{
 
52
        m_ClassId = ClassId;
 
53
        m_AppName = AppName; 
 
54
        m_ClassId2 = QFileInfo(QApplication::applicationFilePath()).fileName(); 
 
55
}
 
56
 
 
57
//Associates all extensions in the fileExtensions list with current app.
 
58
//Returns number of extensions processed successfully. 
 
59
int WinFileAssoc::CreateFileAssociations(const QStringList& fileExtensions)
 
60
{
 
61
#ifdef Q_OS_WIN
 
62
        if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
 
63
        {
 
64
                return VistaSetAppsAsDefault(fileExtensions); 
 
65
        }
 
66
#endif
 
67
 
 
68
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat); //Read only on NT+
 
69
        QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat);
 
70
 
 
71
        if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError)
 
72
                return 0; 
 
73
 
 
74
        if (RegCR.status() != QSettings::NoError)
 
75
                return 0; 
 
76
 
 
77
#ifdef Q_OS_WIN
 
78
        if (QSysInfo::WindowsVersion < QSysInfo::WV_NT && !RegCR.isWritable())  //Win98
 
79
                return 0; 
 
80
#endif
 
81
 
 
82
        //Check if classId exists in the registry
 
83
        if (!RegCR.contains(m_ClassId) && !RegCU.contains("Software/Classes/" + m_ClassId))
 
84
        {
 
85
                //If doesn't exist (user didn't run the setup program), try to create the ClassId for current user.
 
86
                if (!CreateClassId(QApplication::applicationFilePath(), "SMPlayer Media Player"))
 
87
                        return 0; 
 
88
        }
 
89
        
 
90
        int count = 0; 
 
91
        foreach(const QString& fileExtension, fileExtensions)
 
92
        {
 
93
                QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension);
 
94
                QString ClassesKeyName = m_ClassId;
 
95
 
 
96
                QString BackupKeyName = ClassesKeyName + "/" + fileExtension; 
 
97
                QString CUKeyName = "Software/Classes/." + fileExtension; 
 
98
 
 
99
                //Save current ClassId for current user
 
100
                QString KeyVal = RegCU.value(CUKeyName + "/.").toString(); 
 
101
 
 
102
                if (KeyVal.length() == 0 || KeyVal == m_ClassId)
 
103
                {
 
104
                        //No registered app for this extension for current user.
 
105
                        //Check the system-wide (HKEY_CLASSES_ROOT) ClassId for this extension 
 
106
                        KeyVal = RegCR.value("." + fileExtension + "/.").toString();
 
107
                }
 
108
 
 
109
                if (KeyVal != m_ClassId)
 
110
                        RegCU.setValue(CUKeyName + "/MPlayer_Backup", KeyVal); 
 
111
 
 
112
                //Save last ProgId and Application values from the Exts key
 
113
                KeyVal = RegCU.value(ExtKeyName + "/Progid").toString();
 
114
                
 
115
                if (KeyVal != m_ClassId && KeyVal != m_ClassId2)
 
116
                        RegCU.setValue(ExtKeyName + "/MPlayer_Backup_ProgId", KeyVal);
 
117
 
 
118
                KeyVal = RegCU.value(ExtKeyName + "/Application").toString(); 
 
119
                if (KeyVal != m_ClassId || KeyVal != m_ClassId2) 
 
120
                        RegCU.setValue(ExtKeyName + "/MPlayer_Backup_Application", KeyVal); 
 
121
 
 
122
                //Create the associations
 
123
#ifdef Q_OS_WIN
 
124
                if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT)
 
125
#endif
 
126
                {
 
127
                        RegCU.setValue(CUKeyName + "/.", m_ClassId);            //Extension class
 
128
                        RegCU.setValue(ExtKeyName + "/Progid", m_ClassId);      //Explorer FileExt association
 
129
 
 
130
                }
 
131
#ifdef Q_OS_WIN
 
132
                else
 
133
                {
 
134
                        //Windows ME/98/95 support
 
135
                        RegCR.setValue("." + fileExtension + "/.", m_ClassId); 
 
136
                }
 
137
#endif
 
138
 
 
139
                if (RegCU.status() == QSettings::NoError && RegCR.status() == QSettings::NoError)
 
140
                        count++; 
 
141
        }
 
142
 
 
143
        return count; 
 
144
}
 
145
 
 
146
//Checks if extensions in extensionsToCheck are registered with this application. Returns a list of registered extensions. 
 
147
//Returns false if there was an error accessing the registry. 
 
148
//Returns true and 0 elements in registeredExtensions if no extension is associated with current app.
 
149
bool WinFileAssoc::GetRegisteredExtensions( const QStringList& extensionsToCheck, QStringList& registeredExtensions)
 
150
{
 
151
        registeredExtensions.clear(); 
 
152
 
 
153
#ifdef Q_OS_WIN
 
154
        if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
 
155
        {
 
156
                return VistaGetDefaultApps(extensionsToCheck, registeredExtensions); 
 
157
        }
 
158
#endif
 
159
 
 
160
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
 
161
        QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat);
 
162
 
 
163
        if (RegCR.status() != QSettings::NoError)
 
164
                return false; 
 
165
 
 
166
        if (RegCU.status() != QSettings::NoError)
 
167
                return false; 
 
168
 
 
169
        foreach(const QString& fileExtension, extensionsToCheck)
 
170
        {
 
171
                bool bRegistered = false; 
 
172
                //Check the explorer extension (Always use this program to open this kind of file...)
 
173
 
 
174
#ifdef Q_OS_WIN
 
175
                if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT)
 
176
#endif
 
177
                {
 
178
                        QString FileExtsKey = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension);
 
179
                        QString CurClassId = RegCU.value(FileExtsKey + "/Progid").toString(); 
 
180
                        QString CurAppId = RegCU.value(FileExtsKey + "/Application").toString();
 
181
 
 
182
                        if (CurClassId.size())  //Registered with Open With... / ProgId ?
 
183
                        {
 
184
                                bRegistered = (CurClassId == m_ClassId) || (0 == CurClassId.compare(m_ClassId2, Qt::CaseInsensitive));
 
185
                        }
 
186
                        else
 
187
                        if (CurAppId.size())
 
188
                        {
 
189
                                //If user uses Open With..., explorer creates it's own ClassId under Application, usually "smplayer.exe"
 
190
                                bRegistered = (CurAppId == m_ClassId) || (0 == CurAppId.compare(m_ClassId2, Qt::CaseInsensitive)); 
 
191
                        }
 
192
                        else
 
193
                        {
 
194
                                //No classId means that no associations exists in Default Programs or Explorer
 
195
                                //Check the default per-user association 
 
196
                                bRegistered = RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId; 
 
197
                        }
 
198
                }
 
199
                
 
200
                //Finally, check the system-wide association
 
201
                if (!bRegistered)
 
202
                        bRegistered = RegCR.value("." + fileExtension + "/.").toString() == m_ClassId;
 
203
 
 
204
 
 
205
                if (bRegistered)
 
206
                        registeredExtensions.append(fileExtension); 
 
207
        }
 
208
        
 
209
        return true; 
 
210
}
 
211
 
 
212
//Restores file associations to old defaults (if any) for all extensions in the fileExtensions list.
 
213
//Cleans up our backup keys from the registry.
 
214
//Returns number of extensions successfully processed (error if fileExtensions.count() != return value && count > 0).
 
215
int WinFileAssoc::RestoreFileAssociations(const QStringList& fileExtensions)
 
216
{
 
217
#ifdef Q_OS_WIN
 
218
        if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
 
219
                return 0; //Not supported by the API
 
220
#endif
 
221
 
 
222
        QSettings RegCR ("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
 
223
        QSettings RegCU ("HKEY_CURRENT_USER", QSettings::NativeFormat);
 
224
 
 
225
        if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError)
 
226
                return 0; 
 
227
 
 
228
        if (RegCR.status() != QSettings::NoError)
 
229
                return 0; 
 
230
 
 
231
#ifdef Q_OS_WIN
 
232
        if (QSysInfo::WindowsVersion < QSysInfo::WV_NT && !RegCR.isWritable())  //Win98
 
233
                return 0; 
 
234
#endif
 
235
 
 
236
        int count = 0; 
 
237
        foreach(const QString& fileExtension, fileExtensions)
 
238
        {
 
239
                QString ExtKeyName = QString("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts/.%1").arg(fileExtension);
 
240
                QString OldProgId = RegCU.value(ExtKeyName + "/MPlayer_Backup_ProgId").toString(); 
 
241
                QString OldApp  = RegCU.value(ExtKeyName + "/MPlayer_Backup_Application").toString(); 
 
242
                QString OldClassId = RegCU.value("Software/Classes/." + fileExtension + "/MPlayer_Backup").toString(); 
 
243
 
 
244
                //Restore old explorer ProgId
 
245
                if (!OldProgId.isEmpty() && OldProgId != m_ClassId)
 
246
                        RegCU.setValue(ExtKeyName + "/Progid", OldProgId);
 
247
                else
 
248
                {
 
249
                        QString CurProgId = RegCU.value(ExtKeyName + "/Progid").toString();
 
250
                        if ((CurProgId == m_ClassId) || (0 == CurProgId.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it
 
251
                                RegCU.remove(ExtKeyName + "/Progid");   
 
252
                }
 
253
 
 
254
                //Restore old explorer Application 
 
255
                if (!OldApp.isEmpty() && OldApp != m_ClassId)
 
256
                        RegCU.setValue(ExtKeyName + "/Application", OldApp); 
 
257
                else
 
258
                {
 
259
                        QString CurApp = RegCU.value(ExtKeyName + "/Application").toString();
 
260
                        if ((CurApp == m_ClassId) || (0 == CurApp.compare(m_ClassId2, Qt::CaseInsensitive))) //Only remove if we own it
 
261
                                RegCU.remove(ExtKeyName + "/Application"); 
 
262
                }
 
263
 
 
264
#ifdef Q_OS_WIN
 
265
                if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT)
 
266
#endif
 
267
                {
 
268
                        //Restore old association for current user
 
269
                        if (!OldClassId.isEmpty() && OldClassId != m_ClassId)
 
270
                                RegCU.setValue("Software/Classes/." + fileExtension + "/.", OldClassId); 
 
271
                        else
 
272
                        {
 
273
                                if (RegCU.value("Software/Classes/." + fileExtension + "/.").toString() == m_ClassId) //Only remove if we own it
 
274
                                        RegCU.remove("Software/Classes/." + fileExtension); 
 
275
                        }
 
276
                }
 
277
#ifdef Q_OS_WIN
 
278
                else
 
279
                {
 
280
                        //Windows 98 ==> Write to HKCR
 
281
                        if (!OldClassId.isEmpty() && OldClassId != m_ClassId)
 
282
                                RegCR.setValue("." + fileExtension + "/.", OldClassId); 
 
283
                        else
 
284
                        {
 
285
                                if (RegCR.value("." + fileExtension + "/.").toString() == m_ClassId)
 
286
                                        RegCR.remove("." + fileExtension); 
 
287
                        }
 
288
                }
 
289
#endif
 
290
                //Remove our keys:
 
291
                //CurrentUserClasses/.ext/MPlayerBackup
 
292
                //Explorer: Backup_Application and Backup_ProgId
 
293
                RegCU.remove("Software/Classes/." + fileExtension + "/MPlayer_Backup"); 
 
294
                RegCU.remove(ExtKeyName + "/MPlayer_Backup_Application"); 
 
295
                RegCU.remove(ExtKeyName + "/MPlayer_Backup_ProgId"); 
 
296
        }
 
297
        return count; 
 
298
}
 
299
 
 
300
//Creates a ClassId for current application. 
 
301
//Note: It's better to create the classId from the installation program.
 
302
bool WinFileAssoc::CreateClassId(const QString& executablePath, const QString& friendlyName)
 
303
{
 
304
        QString RootKeyName;
 
305
        QString classId; 
 
306
 
 
307
#ifdef Q_OS_WIN
 
308
        if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 
 
309
#endif
 
310
        {
 
311
                classId = "Software/Classes/" + m_ClassId; 
 
312
                RootKeyName = "HKEY_CURRENT_USER";
 
313
        }
 
314
#ifdef Q_OS_WIN
 
315
        else 
 
316
        {
 
317
                classId = m_ClassId; 
 
318
                RootKeyName = "HKEY_CLASSES_ROOT";      //Windows 95/98/ME
 
319
        }
 
320
#endif
 
321
 
 
322
        QSettings Reg (RootKeyName, QSettings::NativeFormat);
 
323
        if (!Reg.isWritable() || Reg.status() != QSettings::NoError)
 
324
                return false; 
 
325
 
 
326
        QString appPath = executablePath;
 
327
        appPath.replace('/', '\\'); //Explorer gives 'Access Denied' if we write the path with forward slashes to the registry
 
328
 
 
329
        //Add our ProgId to the HKCR classes
 
330
        Reg.setValue(classId + "/shell/open/FriendlyAppName", friendlyName);
 
331
        Reg.setValue(classId + "/shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath, "%1"));
 
332
        Reg.setValue(classId + "/DefaultIcon/.", QString("\"%1\",1").arg(appPath));
 
333
        //Add "Enqueue" command
 
334
        Reg.setValue(classId + "/shell/enqueue/.", QObject::tr("Enqueue in SMPlayer"));
 
335
        Reg.setValue(classId + "/shell/enqueue/command/.", QString("\"%1\" -add-to-playlist \"%2\"").arg(appPath, "%1"));
 
336
        return true; 
 
337
}
 
338
//Remove ClassId from the registry.
 
339
//Called when no associations exist. Note: It's better to do this in the Setup program.
 
340
bool WinFileAssoc::RemoveClassId()
 
341
{
 
342
        QString RootKeyName;
 
343
        QString classId; 
 
344
 
 
345
#ifdef Q_OS_WIN
 
346
        if (QSysInfo::WindowsVersion >= QSysInfo::WV_NT) 
 
347
#endif
 
348
        {
 
349
                classId = "Software/Classes/" + m_ClassId; 
 
350
                RootKeyName = "HKEY_CURRENT_USER";
 
351
        }
 
352
#ifdef Q_OS_WIN
 
353
        else 
 
354
        {
 
355
                classId = m_ClassId; 
 
356
                RootKeyName = "HKEY_CLASSES_ROOT";      //Windows 95/98/ME
 
357
        }
 
358
#endif
 
359
 
 
360
        QSettings RegCU (RootKeyName, QSettings::NativeFormat);
 
361
 
 
362
        if (!RegCU.isWritable() || RegCU.status() != QSettings::NoError)
 
363
                return false; 
 
364
 
 
365
        RegCU.remove(classId);
 
366
        return true; 
 
367
}
 
368
 
 
369
//Windows Vista specific implementation
 
370
//Add libole32.a library if compiling with mingw.
 
371
//In smplayer.pro, under win32{ :
 
372
//      LIBS += libole32
 
373
#ifdef WIN32
 
374
#include <windows.h>
 
375
 
 
376
#if !defined(IApplicationAssociationRegistration)
 
377
 
 
378
typedef enum tagASSOCIATIONLEVEL
 
379
{
 
380
        AL_MACHINE,
 
381
        AL_EFFECTIVE,
 
382
        AL_USER
 
383
} ASSOCIATIONLEVEL;
 
384
 
 
385
typedef enum tagASSOCIATIONTYPE
 
386
{
 
387
        AT_FILEEXTENSION,
 
388
        AT_URLPROTOCOL,
 
389
        AT_STARTMENUCLIENT,
 
390
        AT_MIMETYPE
 
391
} ASSOCIATIONTYPE;
 
392
 
 
393
MIDL_INTERFACE("4e530b0a-e611-4c77-a3ac-9031d022281b")
 
394
IApplicationAssociationRegistration : public IUnknown
 
395
{
 
396
public:
 
397
        virtual HRESULT STDMETHODCALLTYPE QueryCurrentDefault(LPCWSTR pszQuery,
 
398
                ASSOCIATIONTYPE atQueryType,
 
399
                ASSOCIATIONLEVEL alQueryLevel,
 
400
                LPWSTR *ppszAssociation) = 0;
 
401
        virtual HRESULT STDMETHODCALLTYPE QueryAppIsDefault(LPCWSTR pszQuery,
 
402
                ASSOCIATIONTYPE atQueryType,
 
403
                ASSOCIATIONLEVEL alQueryLevel,
 
404
                LPCWSTR pszAppRegistryName,
 
405
                BOOL *pfDefault) = 0;
 
406
        virtual HRESULT STDMETHODCALLTYPE QueryAppIsDefaultAll(ASSOCIATIONLEVEL alQueryLevel,
 
407
                LPCWSTR pszAppRegistryName,
 
408
                BOOL *pfDefault) = 0;
 
409
        virtual HRESULT STDMETHODCALLTYPE SetAppAsDefault(LPCWSTR pszAppRegistryName,
 
410
                LPCWSTR pszSet,
 
411
                ASSOCIATIONTYPE atSetType) = 0;
 
412
        virtual HRESULT STDMETHODCALLTYPE SetAppAsDefaultAll(LPCWSTR pszAppRegistryName) = 0;
 
413
        virtual HRESULT STDMETHODCALLTYPE ClearUserAssociations( void) = 0;
 
414
};
 
415
#endif
 
416
 
 
417
static const CLSID CLSID_ApplicationAssociationReg = {0x591209C7,0x767B,0x42B2,{0x9F,0xBA,0x44,0xEE,0x46,0x15,0xF2,0xC7}};
 
418
static const IID   IID_IApplicationAssociationReg  = {0x4e530b0a,0xe611,0x4c77,{0xa3,0xac,0x90,0x31,0xd0,0x22,0x28,0x1b}};
 
419
 
 
420
int WinFileAssoc::VistaSetAppsAsDefault(const QStringList& fileExtensions)
 
421
{
 
422
        IApplicationAssociationRegistration* pAAR;
 
423
        HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg,
 
424
                NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg,    (void**)&pAAR);
 
425
 
 
426
        int count = 0; 
 
427
        if (SUCCEEDED(hr) && (pAAR != NULL))
 
428
        {
 
429
                foreach(const QString& fileExtension, fileExtensions)
 
430
                {
 
431
                        hr = pAAR->SetAppAsDefault((const WCHAR*)m_AppName.utf16(),
 
432
                                (const WCHAR*)QString("." + fileExtension).utf16(),
 
433
                                AT_FILEEXTENSION);
 
434
 
 
435
                        if (SUCCEEDED(hr)) 
 
436
                                count++; 
 
437
                }
 
438
                pAAR->Release(); 
 
439
        }
 
440
        return count; 
 
441
}
 
442
 
 
443
bool WinFileAssoc::VistaGetDefaultApps(const QStringList &extensions, QStringList& registeredExt)
 
444
{
 
445
        IApplicationAssociationRegistration* pAAR;
 
446
 
 
447
        HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationReg,
 
448
                NULL, CLSCTX_INPROC, IID_IApplicationAssociationReg,    (void**)&pAAR);
 
449
 
 
450
        if (SUCCEEDED(hr) && (pAAR != NULL))
 
451
        {
 
452
                foreach(const QString& fileExtension, extensions)
 
453
                {
 
454
                        BOOL bIsDefault = FALSE; 
 
455
                        hr = pAAR->QueryAppIsDefault((const WCHAR*)QString("." + fileExtension).utf16(),
 
456
                                AT_FILEEXTENSION,
 
457
                                AL_EFFECTIVE,
 
458
                                (const WCHAR*)m_AppName.utf16(),
 
459
                                &bIsDefault);
 
460
                        if (SUCCEEDED(hr) && bIsDefault)
 
461
                        {
 
462
                                registeredExt.append(fileExtension); 
 
463
                        }
 
464
                }
 
465
 
 
466
                pAAR->Release();
 
467
                return true;
 
468
        }
 
469
        return false;
 
470
}
 
471
#else
 
472
bool WinFileAssoc::VistaGetDefaultApps(const QStringList &extensions, QStringList& registeredExt)
 
473
{
 
474
        return false; 
 
475
}
 
476
 
 
477
int WinFileAssoc::VistaSetAppsAsDefault(const QStringList& extensions)
 
478
{
 
479
        return 0; 
 
480
}
 
481
#endif
 
482