1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2019 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception,  that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: mimetype.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23 
24 #include "mimetype.h"
25 
26 #include <QFile>
27 #include <QXmlStreamReader>
28 #include <QCoreApplication>
29 #include <QDebug>
30 //lite_memory_check_begin
31 #if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
32      #define _CRTDBG_MAP_ALLOC
33      #include <stdlib.h>
34      #include <crtdbg.h>
35      #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
36      #define new DEBUG_NEW
37 #endif
38 //lite_memory_check_end
39 
40 
package() const41 QString MimeType::package() const
42 {
43     return m_package;
44 }
45 
type() const46 QString MimeType::type() const
47 {
48     return m_type;
49 }
50 
scheme() const51 QString MimeType::scheme() const
52 {
53     return m_scheme;
54 }
55 
comment() const56 QString MimeType::comment() const
57 {
58     return m_comment.join("/");
59 }
60 
codec() const61 QString MimeType::codec() const
62 {
63     return m_codec;
64 }
65 
tabToSpace() const66 bool MimeType::tabToSpace() const
67 {
68     return m_tabToSpace;
69 }
70 
tabWidth() const71 int MimeType::tabWidth() const
72 {
73     return m_tabWidth;
74 }
75 
globPatterns() const76 QStringList MimeType::globPatterns() const
77 {
78     return m_globPatterns;
79 }
subClassesOf() const80 QStringList MimeType::subClassesOf() const
81 {
82     return m_subClassesOf;
83 }
84 
merge(const IMimeType * mimeType)85 void MimeType::merge(const IMimeType *mimeType)
86 {
87     if (m_type != mimeType->type()) {
88         return;
89     }
90     m_subClassesOf.append(mimeType->subClassesOf());
91     m_globPatterns.append(mimeType->globPatterns());
92     m_customPatterns.append(mimeType->customPatterns());
93     m_comment.append(mimeType->comment());
94 
95     if (!mimeType->codec().isEmpty()) {
96         m_codec = mimeType->codec();
97     }
98     if (!mimeType->scheme().isEmpty()) {
99         m_scheme = mimeType->scheme();
100     }
101     if (!mimeType->package().isEmpty()) {
102         m_package = mimeType->package();
103     }
104     if (mimeType->tabToSpace()) {
105         m_tabToSpace = mimeType->tabToSpace();
106     }
107     if (mimeType->tabWidth() != -1) {
108         m_tabWidth = mimeType->tabWidth();
109     }
110     m_subClassesOf.removeDuplicates();
111     m_globPatterns.removeDuplicates();
112     m_customPatterns.removeDuplicates();
113     m_comment.removeDuplicates();
114 }
115 
setCustomPatterns(const QStringList & custom)116 void MimeType::setCustomPatterns(const QStringList &custom)
117 {
118     m_customPatterns = custom;
119 }
120 
customPatterns() const121 QStringList MimeType::customPatterns() const
122 {
123     return m_customPatterns;
124 }
125 
allPatterns() const126 QStringList MimeType::allPatterns() const
127 {
128     QStringList all;
129     all << m_globPatterns;
130     all << m_customPatterns;
131     all.removeDuplicates();
132     return all;
133 }
134 
setPackage(const QString & package)135 void MimeType::setPackage(const QString &package)
136 {
137     m_package = package;
138 }
139 
setType(const QString & type)140 void MimeType::setType(const QString &type)
141 {
142     m_type = type;
143 }
144 
setScheme(const QString & scheme)145 void MimeType::setScheme(const QString &scheme)
146 {
147     m_scheme = scheme;
148 }
149 
setCodec(const QString & codec)150 void MimeType::setCodec(const QString &codec)
151 {
152     m_codec = codec;
153 }
154 
setTabToSpace(const QString & s)155 void MimeType::setTabToSpace(const QString &s)
156 {
157     if (s == "true" || s == "1") {
158         m_tabToSpace = true;
159     }
160 }
161 
setTabWidth(const QString & s)162 void MimeType::setTabWidth(const QString &s)
163 {
164     bool ok = false;
165     int n = s.toInt(&ok);
166     if (ok) {
167         m_tabWidth = n;
168     }
169 }
170 
setComment(const QString & comment)171 void MimeType::setComment(const QString &comment)
172 {
173     m_comment.append(comment);
174 }
175 
appendLocalComment(const QString & local,const QString & comment)176 void MimeType::appendLocalComment(const QString &local, const QString &comment)
177 {
178     if (!local.isEmpty() && !comment.isEmpty()) {
179         m_localCommentMap.insert(local,comment);
180     }
181 }
182 
appendGlobPatterns(const QString & globPattern)183 void MimeType::appendGlobPatterns(const QString &globPattern)
184 {
185     if (globPattern.isEmpty()) {
186         return;
187     }
188     m_globPatterns.append(globPattern);
189 }
190 
appendSubClassesOf(const QString & subClassOf)191 void MimeType::appendSubClassesOf(const QString &subClassOf)
192 {
193     if (subClassOf.isEmpty()) {
194         return;
195     }
196     m_subClassesOf.append(subClassOf);
197 }
198 
isEmpty() const199 bool MimeType::isEmpty() const
200 {
201     return m_type.isEmpty();
202 }
203 
loadMimeTypes(LiteApi::IMimeTypeManager * manager,const QString & fileName)204 bool MimeType::loadMimeTypes(LiteApi::IMimeTypeManager *manager, const QString &fileName)
205 {
206     QFile file(fileName);
207     if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
208         return false;
209     }
210 
211     return MimeType::loadMimeTypes(manager,&file,fileName);
212 }
213 
loadMimeTypes(LiteApi::IMimeTypeManager * manager,QIODevice * dev,const QString &)214 bool MimeType::loadMimeTypes(LiteApi::IMimeTypeManager *manager, QIODevice *dev, const QString &/*fileName*/)
215 {
216     QXmlStreamReader reader(dev);
217     QXmlStreamAttributes attrs;
218     MimeType *mimeType = 0;
219     while (!reader.atEnd()) {
220         switch (reader.readNext()) {
221         case QXmlStreamReader::StartElement:
222             attrs = reader.attributes();
223             if (reader.name() == "mime-type" && mimeType == 0) {
224                 mimeType = new MimeType;
225                 mimeType->setType(attrs.value("type").toString());
226                 mimeType->setPackage(attrs.value("package").toString());
227                 mimeType->setCodec(attrs.value("codec").toString());
228                 mimeType->setScheme(attrs.value("scheme").toString());
229                 mimeType->setTabToSpace(attrs.value("tabtospace").toString());
230                 mimeType->setTabWidth(attrs.value("tabwidth").toString());
231             } else if (reader.name() == "sub-class-of" && mimeType) {
232                 mimeType->appendSubClassesOf(attrs.value("type").toString());
233             } else if (reader.name() == "comment" && mimeType) {
234                 QString locale = attrs.value("xml:lang").toString();
235                 const QString comment = QCoreApplication::translate("MimeType", reader.readElementText().toLatin1());
236                 if (locale.isEmpty()) {
237                     mimeType->setComment(comment);
238                 } else {
239                     mimeType->appendLocalComment(locale,comment);
240                 }
241             } else if (reader.name() == "glob" && mimeType) {
242                 mimeType->appendGlobPatterns(attrs.value("pattern").toString());
243             }
244             break;
245         case QXmlStreamReader::EndElement:
246             if (reader.name() == "mime-type") {
247                 bool b = false;
248                 if (mimeType && !mimeType->isEmpty()) {
249                     if (manager->addMimeType(mimeType)) {
250                         b = true;
251                     }
252                 }
253                 if (!b) {
254                     delete mimeType;
255                 }
256                 mimeType = 0;
257             }
258             break;
259         default:
260             break;
261         }
262     }
263     return true;
264 }
265