]> Shamusworld >> Repos - architektonas/blob - src/base/fileio.cpp
In the middle of chasing down MDI not activating bug, renaming of Graphic to
[architektonas] / src / base / fileio.cpp
1 // 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 // JLH  09/07/2010  Fixed file detection algorithm.
16 //
17
18 #include "fileio.h"
19
20 #include "filtercxf.h"
21 #include "filterdxf.h"
22 #include "filterdxf1.h"
23 #include "filterinterface.h"
24
25 FileIO * FileIO::uniqueInstance = NULL;
26
27 // Constructor
28 FileIO::FileIO()
29 {
30 }
31
32 /**
33  * @return Instance to the unique import object.
34  */
35 /*static*/ FileIO * FileIO::instance()
36 {
37         if (!uniqueInstance)
38                 uniqueInstance = new FileIO();
39
40         return uniqueInstance;
41 }
42
43 /**
44  * Registers a new import filter.
45  */
46 void FileIO::registerFilter(FilterInterface * f)
47 {
48         filterList.append(f);
49 }
50
51 /**
52  * @return List of registered filters.
53  */
54 QList<FilterInterface *> FileIO::getFilterList()
55 {
56         return filterList;
57 }
58
59 /**
60  * @return Filter which can import the given file type.
61  */
62 FilterInterface * FileIO::getImportFilter(RS2::FormatType t)
63 {
64         for(int i=0; i<filterList.size(); i++)
65         {
66                 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 FilterInterface * FileIO::getExportFilter(RS2::FormatType t)
79 {
80         for(int i=0; i<filterList.size(); i++)
81         {
82                 FilterInterface * f = filterList[i];
83
84                 if (f->canExport(t))
85                         return f;
86         }
87
88         return NULL;
89 }
90
91 /**
92  * Calls the import method of the filter responsible for the format of the
93  * given file.
94  *
95  * @param drawing The container to which we will add entities. Usually that's
96  *        an Drawing entity but it can also be a polyline, text, ...
97  * @param file Path and name of the file to import.
98  */
99 bool FileIO::fileImport(Drawing & drawing, const QString & file, RS2::FormatType type)
100 {
101         DEBUG->print("Trying to import file '%s'...", file.toAscii().data());
102
103         FilterInterface * filter = NULL;
104         RS2::FormatType t = (type == RS2::FormatUnknown ? detectFormat(file) : type);
105         filter = getImportFilter(t);
106
107     if (filter)
108         return filter->fileImport(drawing, file, t);
109         else
110         {
111                 DEBUG->print(Debug::D_WARNING, "FileIO::fileImport: failed to import file: %s",
112                         file.toAscii().data());
113         }
114
115         return false;
116 }
117
118 /**
119  * Calls the export method of the object responsible for the format of the
120  * given file.
121  *
122  * @param file Path and name of the file to import.
123  */
124 bool FileIO::fileExport(Drawing & drawing, const QString & file, RS2::FormatType type)
125 {
126         DEBUG->print("FileIO::fileExport");
127
128         if (type == RS2::FormatUnknown)
129         {
130                 QString extension = QFileInfo(file).suffix().toLower();
131
132                 if (extension == "dxf")
133                         type = RS2::FormatDXF;
134                 else if (extension == "cxf")
135                         type = RS2::FormatCXF;
136         }
137
138         FilterInterface * filter = getExportFilter(type);
139
140         if (filter)
141                 return filter->fileExport(drawing, file, type);
142
143         DEBUG->print("FileIO::fileExport: no filter found");
144
145         return false;
146 }
147
148 /**
149  * Detects and returns the file format of the given file.
150  */
151 RS2::FormatType FileIO::detectFormat(const QString & file)
152 {
153         RS2::FormatType type = RS2::FormatUnknown;
154         QFileInfo info(file);
155         QString ext = info.suffix().toLower();
156
157         if (ext == "cxf")
158         {
159                 type = RS2::FormatCXF;
160         }
161         else if (ext == "dxf")
162         {
163                 type = RS2::FormatDXF1;
164                 QFile f(file);
165
166                 if (!f.open(QIODevice::ReadOnly))
167                 {
168                         // Error opening file:
169                         DEBUG->print(Debug::D_WARNING,
170                                 "FileIO::detectFormat: Cannot open file: %s", file.toAscii().data());
171                         type = RS2::FormatUnknown;
172                 }
173                 else
174                 {
175                         DEBUG->print("FileIO::detectFormat: Successfully opened DXF file: %s",
176                                 file.toAscii().data());
177
178                         QTextStream ts(&f);
179                         int c = 0;
180
181 //I think this is wrong... We're mixing classes here...
182 //AND THAT WAS THE PROBLEM!!!
183 //                      while (!f.atEnd() && ++c < 100)
184                         while (!ts.atEnd() && ++c < 100)
185                         {
186                                 QString line = ts.readLine();
187
188                                 if (line == "$ACADVER")
189                                         type = RS2::FormatDXF;
190
191                                 // very simple reduced DXF:
192                                 if (line == "ENTITIES" && c < 10)
193                                         type = RS2::FormatDXF;
194                         }
195
196                         f.close();
197                 }
198         }
199
200         return type;
201 }