]> Shamusworld >> Repos - architektonas/blob - src/base/rs_fileio.cpp
Added missing readme and GPL license file.
[architektonas] / src / base / rs_fileio.cpp
1 // rs_fileio.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/28/2010  Added this text. :-)
13 //
14
15 #include "rs_fileio.h"
16
17 #include "rs_filtercxf.h"
18 #include "rs_filterdxf.h"
19 #include "rs_filterdxf1.h"
20 #include "rs_filterinterface.h"
21
22 RS_FileIO * RS_FileIO::uniqueInstance = NULL;
23
24 // Constructor
25 RS_FileIO::RS_FileIO()
26 {
27 }
28
29 /**
30  * @return Instance to the unique import object.
31  */
32 /*static*/ RS_FileIO * RS_FileIO::instance()
33 {
34         if (uniqueInstance == NULL)
35                 uniqueInstance = new RS_FileIO();
36
37         return uniqueInstance;
38 }
39
40 /**
41  * Registers a new import filter.
42  */
43 void RS_FileIO::registerFilter(RS_FilterInterface * f)
44 {
45         filterList.append(f);
46 }
47
48 /**
49  * @return List of registered filters.
50  */
51 QList<RS_FilterInterface *> RS_FileIO::getFilterList()
52 {
53         return filterList;
54 }
55
56 /**
57  * @return Filter which can import the given file type.
58  */
59 RS_FilterInterface * RS_FileIO::getImportFilter(RS2::FormatType t)
60 {
61 //      for(RS_FilterInterface * f=filterList.first(); f!=NULL; f=filterList.next())
62         for(int i=0; i<filterList.size(); i++)
63         {
64                 RS_FilterInterface * f = filterList[i];
65
66                 if (f->canImport(t))
67                         return f;
68         }
69
70         return NULL;
71 }
72
73 /**
74  * @return Filter which can export the given file type.
75  */
76 RS_FilterInterface * RS_FileIO::getExportFilter(RS2::FormatType t)
77 {
78 //      for(RS_FilterInterface * f=filterList.first(); f!=NULL; f=filterList.next())
79         for(int i=0; i<filterList.size(); i++)
80         {
81                 RS_FilterInterface * f = filterList[i];
82
83                 if (f->canExport(t))
84                         return f;
85         }
86
87         return NULL;
88 }
89
90 /**
91  * Calls the import method of the filter responsible for the format
92  * of the given file.
93  *
94  * @param graphic The container to which we will add
95  *        entities. Usually that's an Drawing entity but
96  *        it can also be a polyline, text, ...
97  * @param file Path and name of the file to import.
98  */
99 bool RS_FileIO::fileImport(Drawing & graphic, const QString & file, RS2::FormatType type)
100 {
101         RS_DEBUG->print("Trying to import file '%s'...", file.toLatin1().data());
102
103         RS_FilterInterface * filter = NULL;
104         RS2::FormatType t;
105
106         if (type == RS2::FormatUnknown)
107                 t = detectFormat(file);
108         else
109                 t = type;
110
111         filter = getImportFilter(t);
112
113         /*
114         switch (t) {
115         case RS2::FormatCXF:
116         filter = new RS_FilterCXF(graphic);
117                 break;
118
119         case RS2::FormatDXF1:
120         filter = new RS_FilterDXF1(graphic);
121                 break;
122
123         case RS2::FormatDXF:
124         filter = new RS_FilterDXF(graphic);
125                 break;
126
127         default:
128                 break;
129     }
130         */
131
132     if (filter != NULL)
133         return filter->fileImport(graphic, file, t);
134         else
135         {
136                 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_FileIO::fileImport: failed to import file: %s",
137                         file.toLatin1().data());
138         }
139
140         return false;
141 }
142
143 /**
144  * Calls the export method of the object responsible for the format
145  * of the given file.
146  *
147  * @param file Path and name of the file to import.
148  */
149 bool RS_FileIO::fileExport(Drawing & graphic, const QString & file, RS2::FormatType type)
150 {
151         RS_DEBUG->print("RS_FileIO::fileExport");
152         //RS_DEBUG->print("Trying to export file '%s'...", file.latin1());
153
154         if (type == RS2::FormatUnknown)
155         {
156                 QString extension;
157 //              extension = QFileInfo(file).extension(false).toLower();
158                 extension = QFileInfo(file).suffix().toLower();
159
160                 if (extension == "dxf")
161                         type = RS2::FormatDXF;
162                 else if (extension == "cxf")
163                         type = RS2::FormatCXF;
164         }
165
166         RS_FilterInterface * filter = getExportFilter(type);
167
168         if (filter != NULL)
169                 return filter->fileExport(graphic, file, type);
170
171         RS_DEBUG->print("RS_FileIO::fileExport: no filter found");
172
173         return false;
174 }
175
176 /**
177  * Detects and returns the file format of the given file.
178  */
179 RS2::FormatType RS_FileIO::detectFormat(const QString & file)
180 {
181         RS2::FormatType type = RS2::FormatUnknown;
182         QFileInfo f(file);
183
184 //      QString ext = f.extension(false).toLower();
185         QString ext = f.suffix().toLower();
186
187         if (ext == "cxf")
188         {
189                 type = RS2::FormatCXF;
190         }
191         else if (ext == "dxf")
192         {
193                 type = RS2::FormatDXF1;
194                 QFile f(file);
195
196                 if (!f.open(QIODevice::ReadOnly))
197                 {
198                         // Error opening file:
199                         RS_DEBUG->print(RS_Debug::D_WARNING,
200                                 "RS_FileIO::detectFormat: Cannot open file: %s", file.toLatin1().data());
201                         type = RS2::FormatUnknown;
202                 }
203                 else
204                 {
205                         RS_DEBUG->print("RS_FileIO::detectFormat: Successfully opened DXF file: %s",
206                                 file.toLatin1().data());
207
208                         QTextStream ts(&f);
209                         QString line;
210                         int c = 0;
211
212                         while (!f.atEnd() && ++c < 100)
213                         {
214                                 line = ts.readLine();
215
216                                 if (line == "$ACADVER")
217                                         type = RS2::FormatDXF;
218
219                                 // very simple reduced DXF:
220                                 if (line == "ENTITIES" && c < 10)
221                                         type = RS2::FormatDXF;
222                         }
223
224                         f.close();
225                 }
226         }
227
228         return type;
229 }