1 | /* This file is part of the KDE project |
2 | Copyright (C) 2007, 2008 David Faure <faure@kde.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 ( at |
7 | your option ) version 3 or, at the discretion of KDE e.V. ( which shall |
8 | act as a proxy as in section 14 of the GPLv3 ), any later version. |
9 | |
10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU General Public License |
16 | along with this program; see the file COPYING. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #include "mimetypewriter.h" |
22 | #include <kmimetype.h> |
23 | |
24 | #include <kdebug.h> |
25 | #include <kdeversion.h> |
26 | #include <kprocess.h> |
27 | #include <kstandarddirs.h> |
28 | |
29 | #include <QXmlStreamWriter> |
30 | #include <QFile> |
31 | |
32 | /// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes |
33 | |
34 | static bool sharedMimeInfoSupportsIcon() |
35 | { |
36 | return KMimeType::sharedMimeInfoVersion() >= KDE_MAKE_VERSION(0, 40, 0); |
37 | } |
38 | |
39 | class MimeTypeWriterPrivate |
40 | { |
41 | public: |
42 | QString localFilePath() const; |
43 | |
44 | QString m_mimeType; |
45 | QString ; |
46 | QString m_iconName; |
47 | QStringList m_patterns; |
48 | QString m_marker; |
49 | }; |
50 | |
51 | MimeTypeWriter::MimeTypeWriter(const QString& mimeType) |
52 | : d(new MimeTypeWriterPrivate) |
53 | { |
54 | d->m_mimeType = mimeType; |
55 | Q_ASSERT(!mimeType.isEmpty()); |
56 | } |
57 | |
58 | MimeTypeWriter::~MimeTypeWriter() |
59 | { |
60 | delete d; |
61 | } |
62 | |
63 | void MimeTypeWriter::(const QString& ) |
64 | { |
65 | d->m_comment = comment; |
66 | } |
67 | |
68 | void MimeTypeWriter::setPatterns(const QStringList& patterns) |
69 | { |
70 | d->m_patterns = patterns; |
71 | } |
72 | |
73 | void MimeTypeWriter::setIconName(const QString& iconName) |
74 | { |
75 | d->m_iconName = iconName; |
76 | } |
77 | |
78 | void MimeTypeWriter::setMarker(const QString& marker) |
79 | { |
80 | d->m_marker = marker; |
81 | } |
82 | |
83 | bool MimeTypeWriter::write() |
84 | { |
85 | const QString packageFileName = d->localFilePath(); |
86 | kDebug() << "writing" << packageFileName; |
87 | QFile packageFile(packageFileName); |
88 | if (!packageFile.open(QIODevice::WriteOnly)) { |
89 | kError() << "Couldn't open" << packageFileName << "for writing" ; |
90 | return false; |
91 | } |
92 | QXmlStreamWriter writer(&packageFile); |
93 | writer.setAutoFormatting(true); |
94 | writer.writeStartDocument(); |
95 | if (!d->m_marker.isEmpty()) { |
96 | writer.writeComment(d->m_marker); |
97 | } |
98 | const QString nsUri = "http://www.freedesktop.org/standards/shared-mime-info" ; |
99 | writer.writeDefaultNamespace(nsUri); |
100 | writer.writeStartElement("mime-info" ); |
101 | writer.writeStartElement(nsUri, "mime-type" ); |
102 | writer.writeAttribute("type" , d->m_mimeType); |
103 | |
104 | if (!d->m_comment.isEmpty()) { |
105 | writer.writeStartElement(nsUri, "comment" ); |
106 | writer.writeCharacters(d->m_comment); |
107 | writer.writeEndElement(); // comment |
108 | } |
109 | |
110 | if (!d->m_iconName.isEmpty()) { |
111 | // User-specified icon name |
112 | if (sharedMimeInfoSupportsIcon()) { |
113 | writer.writeStartElement(nsUri, "icon" ); |
114 | writer.writeAttribute("name" , d->m_iconName); |
115 | writer.writeEndElement(); // icon |
116 | } |
117 | } |
118 | |
119 | // Allow this local definition to override the global definition |
120 | writer.writeStartElement(nsUri, "glob-deleteall" ); |
121 | writer.writeEndElement(); // glob-deleteall |
122 | |
123 | foreach(const QString& pattern, d->m_patterns) { |
124 | writer.writeStartElement(nsUri, "glob" ); |
125 | writer.writeAttribute("pattern" , pattern); |
126 | writer.writeEndElement(); // glob |
127 | } |
128 | |
129 | writer.writeEndElement(); // mime-info |
130 | writer.writeEndElement(); // mime-type |
131 | writer.writeEndDocument(); |
132 | return true; |
133 | } |
134 | |
135 | void MimeTypeWriter::runUpdateMimeDatabase() |
136 | { |
137 | const QString localPackageDir = KStandardDirs::locateLocal("xdgdata-mime" , QString()); |
138 | Q_ASSERT(!localPackageDir.isEmpty()); |
139 | KProcess proc; |
140 | proc << "update-mime-database" ; |
141 | proc << localPackageDir; |
142 | const int exitCode = proc.execute(); |
143 | if (exitCode) { |
144 | kWarning() << proc.program() << "exited with error code" << exitCode; |
145 | } |
146 | } |
147 | |
148 | QString MimeTypeWriterPrivate::localFilePath() const |
149 | { |
150 | // XDG shared mime: we must write into a <kdehome>/share/mime/packages/ file... |
151 | // To simplify our job, let's use one "input" file per mimetype, in the user's dir. |
152 | // (this writes into $HOME/.local/share/mime by default) |
153 | // |
154 | // We could also use Override.xml, says the spec, but then we'd need to merge with other mimetypes, |
155 | // and in ~/.local we don't really expect other packages to be installed anyway... |
156 | QString baseName = m_mimeType; |
157 | baseName.replace('/', '-'); |
158 | return KStandardDirs::locateLocal( "xdgdata-mime" , "packages/" + baseName + ".xml" ); |
159 | } |
160 | |
161 | static QString existingDefinitionFile(const QString& mimeType) |
162 | { |
163 | QString baseName = mimeType; |
164 | baseName.replace('/', '-'); |
165 | return KGlobal::dirs()->findResource( "xdgdata-mime" , "packages/" + baseName + ".xml" ); |
166 | } |
167 | |
168 | bool MimeTypeWriter::hasDefinitionFile(const QString& mimeType) |
169 | { |
170 | return !existingDefinitionFile(mimeType).isEmpty(); |
171 | } |
172 | |
173 | void MimeTypeWriter::removeOwnMimeType(const QString& mimeType) |
174 | { |
175 | const QString file = existingDefinitionFile(mimeType); |
176 | Q_ASSERT(!file.isEmpty()); |
177 | QFile::remove(file); |
178 | // We must also remove the generated XML file, update-mime-database doesn't do that, for unknown media types |
179 | QString xmlFile = KGlobal::dirs()->findResource( "xdgdata-mime" , mimeType + ".xml" ); |
180 | QFile::remove(xmlFile); |
181 | } |
182 | |
183 | /// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes |
184 | |