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