1 /*
2 * Copyright 2013-2016, 2018 Kai Pastor
3 *
4 * Some parts taken from file_format_oc*d8{.h,_p.h,cpp} which are
5 * Copyright 2012 Pete Curtis
6 *
7 * This file is part of OpenOrienteering.
8 *
9 * OpenOrienteering is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * OpenOrienteering is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "ocd_file_format.h"
24
25 // IWYU pragma: no_include <algorithm>
26 #include <memory>
27
28 #include <QtGlobal>
29 #include <QFlags>
30 #include <QString>
31
32 #include "fileformats/file_import_export.h"
33 #include "fileformats/ocad8_file_format_p.h"
34 #include "fileformats/ocd_file_export.h"
35 #include "fileformats/ocd_file_import.h"
36
37
38 namespace OpenOrienteering {
39
40 namespace {
41
labelForVersion(quint16 version)42 QString labelForVersion(quint16 version)
43 {
44 switch (version)
45 {
46 case OcdFileFormat::autoDeterminedVersion():
47 return ::OpenOrienteering::ImportExport::tr("OCAD");
48 case OcdFileFormat::legacyVersion():
49 return ::OpenOrienteering::ImportExport::tr("OCAD version 8, old implementation");
50 default:
51 return ::OpenOrienteering::ImportExport::tr("OCAD version %1").arg(version);
52 }
53 }
54
featuresForVersion(quint16 version)55 FileFormat::Features featuresForVersion(quint16 version)
56 {
57 switch (version)
58 {
59 case OcdFileFormat::legacyVersion():
60 return FileFormat::Feature::FileOpen | FileFormat::Feature::FileImport | FileFormat::Feature::ReadingLossy |
61 FileFormat::Feature::FileSave | FileFormat::Feature::FileSaveAs | FileFormat::Feature::WritingLossy;
62
63 case OcdFileFormat::autoDeterminedVersion():
64 // Intentionally no FileFormat::ExportSupported. This prevents this
65 // format from being shown in the Save-as dialog. However, it is legal
66 // to create an exporter for the autoDeterminedVersion(). The actual
67 // export version will be determined from the Map's versionProperty()
68 // if possible, or from OcdFileExport::default_version.
69 return FileFormat::Feature::FileOpen | FileFormat::Feature::FileImport | FileFormat::Feature::ReadingLossy |
70 FileFormat::Feature::FileSave | FileFormat::Feature::WritingLossy;
71
72 default:
73 // Intentionally no FileFormat::ImportSupported. Import is handled
74 // by the autoDeterminedVersion().
75 return FileFormat::Feature::FileSave | FileFormat::Feature::FileSaveAs | FileFormat::Feature::WritingLossy;
76 }
77 }
78
79 } // namespace
80
81
82
83 // ### OcdFileFormat ###
84
85 // static
idForVersion(quint16 version)86 const char* OcdFileFormat::idForVersion(quint16 version)
87 {
88 switch (version)
89 {
90 case OcdFileFormat::autoDeterminedVersion():
91 return "OCD";
92 case 8:
93 return "OCD8";
94 case 9:
95 return "OCD9";
96 case 10:
97 return "OCD10";
98 case 11:
99 return "OCD11";
100 case 12:
101 return "OCD12";
102 case OcdFileFormat::legacyVersion():
103 return "OCD-legacy";
104 default:
105 qFatal("Unsupported OCD version");
106 }
107 }
108
109
110 // static
makeAll()111 std::vector<std::unique_ptr<OcdFileFormat>> OcdFileFormat::makeAll()
112 {
113 std::vector<std::unique_ptr<OcdFileFormat>> result;
114 result.reserve(7);
115 result.push_back(std::make_unique<OcdFileFormat>(autoDeterminedVersion()));
116 result.push_back(std::make_unique<OcdFileFormat>(12));
117 result.push_back(std::make_unique<OcdFileFormat>(11));
118 result.push_back(std::make_unique<OcdFileFormat>(10));
119 result.push_back(std::make_unique<OcdFileFormat>(9));
120 result.push_back(std::make_unique<OcdFileFormat>(8));
121 result.push_back(std::make_unique<OcdFileFormat>(legacyVersion()));
122 return result;
123 }
124
125
126
OcdFileFormat(quint16 version)127 OcdFileFormat::OcdFileFormat(quint16 version)
128 : FileFormat { MapFile, idForVersion(version), labelForVersion(version), QStringLiteral("ocd"), featuresForVersion(version) }
129 , version { version }
130 {
131 // Nothing
132 }
133
134
135
understands(const char * buffer,int size) const136 FileFormat::ImportSupportAssumption OcdFileFormat::understands(const char* buffer, int size) const
137 {
138 // The first two bytes of the file must be AD 0C.
139 if (size < 2)
140 return Unknown;
141 else if (quint8(buffer[0]) == 0xAD && buffer[1] == 0x0C)
142 return FullySupported;
143 else
144 return NotSupported;
145 }
146
147
makeImporter(const QString & path,Map * map,MapView * view) const148 std::unique_ptr<Importer> OcdFileFormat::makeImporter(const QString& path, Map *map, MapView *view) const
149 {
150 if (version == legacyVersion())
151 return std::make_unique<OCAD8FileImport>(path, map, view);
152 return std::make_unique<OcdFileImport>(path, map, view);
153 }
154
makeExporter(const QString & path,const Map * map,const MapView * view) const155 std::unique_ptr<Exporter> OcdFileFormat::makeExporter(const QString& path, const Map* map, const MapView* view) const
156 {
157 if (version == legacyVersion())
158 return std::make_unique<OCAD8FileExport>(path, map, view);
159 return std::make_unique<OcdFileExport>(path, map, view, version);
160 }
161
162
163 } // namespace OpenOrienteering
164