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