Skip to content

Commit

Permalink
Merge branch 'devel/apple-xcloc'
Browse files Browse the repository at this point in the history
  • Loading branch information
vslavik committed Feb 6, 2025
2 parents ecebeb5 + bed752d commit a7e9ed2
Show file tree
Hide file tree
Showing 16 changed files with 281 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Poedit.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
<ClCompile Include="src\catalog.cpp" />
<ClCompile Include="src\catalog_json.cpp" />
<ClCompile Include="src\catalog_po.cpp" />
<ClCompile Include="src\catalog_xcloc.cpp" />
<ClCompile Include="src\catalog_xliff.cpp" />
<ClCompile Include="src\cat_sorting.cpp" />
<ClCompile Include="src\cat_update.cpp" />
Expand Down Expand Up @@ -188,6 +189,7 @@
<ClInclude Include="src\catalog.h" />
<ClInclude Include="src\catalog_json.h" />
<ClInclude Include="src\catalog_po.h" />
<ClInclude Include="src\catalog_xcloc.h" />
<ClInclude Include="src\catalog_xliff.h" />
<ClInclude Include="src\cat_sorting.h" />
<ClInclude Include="src\cat_update.h" />
Expand Down
6 changes: 6 additions & 0 deletions Poedit.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@
<ClCompile Include="src\errors.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\catalog_xcloc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\attentionbar.h">
Expand Down Expand Up @@ -428,6 +431,9 @@
<ClInclude Include="src\static_ids.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\catalog_xcloc.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\poedit.rc">
Expand Down
10 changes: 10 additions & 0 deletions Poedit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
23A857D4AE25588C6DDA1CB6 /* utility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28F1CDE16F629D30018AF7E /* utility.cpp */; };
28141065966B0C035B855080 /* unicode_helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2E02A341CB812C500D18F5C /* unicode_helpers.cpp */; };
32DA069EB285429687FE9593 /* libcld2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2083D121A87D17D00150BBF /* libcld2.a */; };
3ED13FB94DB971D259E1FEE0 /* catalog_xcloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BA775F29C57EB5164B2B792 /* catalog_xcloc.cpp */; };
485D22B7D4F845A01E137564 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A60B0E72939BB1B6692FAD8 /* UniformTypeIdentifiers.framework */; };
49C128E5C885E14E7D3748EE /* errors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B273818B2BD5027E005F24DA /* errors.cpp */; };
4C5A07AB3F036AF03E13D7B1 /* QuicklookThumbnails.appex in Copy Gettext bundle and extensions */ = {isa = PBXBuildFile; fileRef = 2E49B156226EE8BCE26F9F19 /* QuicklookThumbnails.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
4CE77399F2643B317B7428BB /* libwx_osx_base_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2B7E8191AD94194007FC4EB /* libwx_osx_base_static.a */; };
5DFE3ACE144F8005096FFA2C /* configuration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B201EBDF1DCF755900FFB541 /* configuration.cpp */; };
6A5AC29259B3BC2A37D22597 /* uilang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2C13766ECFA88FF598316DBA /* uilang.cpp */; };
70FEA36B68430750C1326C6F /* catalog_xcloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BA775F29C57EB5164B2B792 /* catalog_xcloc.cpp */; };
796E87D980AB0659930E8540 /* catalog_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B260089229AE694D00349A0E /* catalog_json.cpp */; };
7EC322151430D2F26AE64498 /* catalog_xcloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BA775F29C57EB5164B2B792 /* catalog_xcloc.cpp */; };
8816DADE560039E7FAD57F46 /* export_html.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28F1CE216F629D30018AF7E /* export_html.cpp */; };
8A905D6EA68B5E7AB51E2ADE /* QuickLookThumbnailing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4C2A4C943959E8220417BD1 /* QuickLookThumbnailing.framework */; };
90E923F206398EFAF8DD5D43 /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B2CAC13A2BBEE95900707D8D /* libicucore.tbd */; };
Expand Down Expand Up @@ -326,6 +329,8 @@
2A58EC80C5A47E2902E5DBC7 /* ThumbnailProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThumbnailProvider.h; sourceTree = "<group>"; };
2C13766ECFA88FF598316DBA /* uilang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uilang.cpp; sourceTree = "<group>"; };
2E49B156226EE8BCE26F9F19 /* QuicklookThumbnails.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = QuicklookThumbnails.appex; sourceTree = BUILT_PRODUCTS_DIR; };
4A11FA9FF60E6EC720F40F25 /* catalog_xcloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catalog_xcloc.h; sourceTree = "<group>"; };
5BA775F29C57EB5164B2B792 /* catalog_xcloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = catalog_xcloc.cpp; sourceTree = "<group>"; };
667D6946D93751EBDFC25FE8 /* InfoThumbnails.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = InfoThumbnails.plist; sourceTree = "<group>"; };
7E3E2780DE9804824D0B5FF4 /* ThumbnailProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThumbnailProvider.m; sourceTree = "<group>"; };
820F3D877353561CFF660576 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -947,6 +952,8 @@
B2E02A351CB812C500D18F5C /* unicode_helpers.h */,
B2E02A341CB812C500D18F5C /* unicode_helpers.cpp */,
B28F1CE016F629D30018AF7E /* version.h */,
4A11FA9FF60E6EC720F40F25 /* catalog_xcloc.h */,
5BA775F29C57EB5164B2B792 /* catalog_xcloc.cpp */,
);
name = "Non-GUI";
path = src;
Expand Down Expand Up @@ -1775,6 +1782,7 @@
B2FE296B1AC85FFF005588E4 /* keytar_mac.cc in Sources */,
B2F25F0D199E327C00127FF9 /* spellchecking.cpp in Sources */,
6A5AC29259B3BC2A37D22597 /* uilang.cpp in Sources */,
7EC322151430D2F26AE64498 /* catalog_xcloc.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1796,6 +1804,7 @@
B228A5F521591D7E0050520D /* catalog_xliff.cpp in Sources */,
B212FEEE20A7366600FAC68F /* pl_evaluate.cpp in Sources */,
B2CE6D231ACFCD95007E6863 /* qlgenerator_main.c in Sources */,
3ED13FB94DB971D259E1FEE0 /* catalog_xcloc.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1816,6 +1825,7 @@
9DA66F94218B662BF94EE503 /* pl_evaluate.cpp in Sources */,
A0AE2A6061C4C9CD31E6D422 /* PreviewProvider.mm in Sources */,
28141065966B0C035B855080 /* unicode_helpers.cpp in Sources */,
70FEA36B68430750C1326C6F /* catalog_xcloc.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
28 changes: 28 additions & 0 deletions macos/Poedit-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@
<string>net.poedit.arb</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>Xcode Localization Catalog</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.apple.xcode.xcloc</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
Expand Down Expand Up @@ -351,6 +361,24 @@
</array>
</dict>
</dict>
<dict>
<key>UTTypeDescription</key>
<string>Xcode Localization Catalog</string>
<key>UTTypeIdentifier</key>
<string>com.apple.xcode.xcloc</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.composite-content</string>
<string>com.apple.package</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xcloc</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ poedit_SOURCES = \
catalog.cpp catalog.h \
catalog_po.cpp catalog_po.h \
catalog_json.cpp catalog_json.h \
catalog_xcloc.cpp catalog_xcloc.h \
catalog_xliff.cpp catalog_xliff.h \
uilang.cpp uilang.h \
cloud_sync.h \
Expand Down
12 changes: 10 additions & 2 deletions src/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "catalog_po.h"
#include "catalog_xliff.h"
#include "catalog_json.h"
#include "catalog_xcloc.h"

#include "configuration.h"
#include "errors.h"
Expand Down Expand Up @@ -589,6 +590,8 @@ wxString MaskForType(Catalog::Type t)
return MaskForType("*.pot", _("POT Translation Templates"));
case Catalog::Type::XLIFF:
return MaskForType("*.xlf;*.xliff", _("XLIFF Translation Files"));
case Catalog::Type::XCLOC:
return MaskForType("*.xcloc", _("Xcode Localization Catalog"));
case Catalog::Type::JSON:
return MaskForType("*.json", _("JSON Translation Files"));
case Catalog::Type::JSON_FLUTTER:
Expand All @@ -602,9 +605,9 @@ wxString MaskForType(Catalog::Type t)

wxString Catalog::GetAllTypesFileMask()
{
return MaskForType("*.po;*.pot;*.xlf;*.xliff;*.json;*.arb", _("All Translation Files"), /*showExt=*/false) +
return MaskForType("*.po;*.pot;*.xlf;*.xliff;*.xcloc;*.json;*.arb", _("All Translation Files"), /*showExt=*/false) +
"|" +
GetTypesFileMask({ Type::PO, Type::POT, Type::XLIFF, Type::JSON, Type::JSON_FLUTTER });
GetTypesFileMask({ Type::PO, Type::POT, Type::XLIFF, Type::JSON, Type::JSON_FLUTTER, Type::XCLOC });
}

wxString Catalog::GetTypesFileMask(std::initializer_list<Type> types)
Expand Down Expand Up @@ -1110,6 +1113,7 @@ CatalogPtr Catalog::Create(Type type)
return CatalogPtr(new POCatalog(type));

case Type::XLIFF:
case Type::XCLOC:
case Type::JSON:
case Type::JSON_FLUTTER:
wxFAIL_MSG("empty XLIFF/JSON creation not implemented");
Expand Down Expand Up @@ -1139,6 +1143,10 @@ CatalogPtr Catalog::Create(const wxString& filename, int flags)
{
cat = JSONCatalog::Open(filename);
}
else if (XCLOCCatalog::CanLoadFile(ext))
{
cat = XCLOCCatalog::Open(filename);
}

if (!cat)
throw Exception(_("The file is in a format not recognized by Poedit."));
Expand Down
1 change: 1 addition & 0 deletions src/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ class Catalog
PO,
POT,
XLIFF,
XCLOC,
JSON,
JSON_FLUTTER
};
Expand Down
107 changes: 107 additions & 0 deletions src/catalog_xcloc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* This file is part of Poedit (https://poedit.net)
*
* Copyright (C) 2025 Vaclav Slavik
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/

#include "catalog_xcloc.h"

#include <wx/dir.h>
#include <wx/filename.h>
#include <wx/translation.h>


bool XCLOCCatalog::CanLoadFile(const wxString& extension)
{
return extension == "xcloc";
}


bool XCLOCCatalog::HasCapability(Cap cap) const
{
// We don't support changing the language yet, as it is more complicated: the .xcloc bundle has
// other files in there and multiple places where it would need to be modified. Poedit takes the
// position that it is an editor for only the l10n part of it.
if (cap == Cap::LanguageSetting)
return false;

return XLIFF1Catalog::HasCapability(cap);
}


void XCLOCCatalog::SetLanguage(Language)
{
wxASSERT_MSG(false, "Setting XCLOC language not supported.");
}


std::shared_ptr<XLIFFCatalog> XCLOCCatalog::Open(const wxString& filename)
{
struct Creator : public InstanceCreatorImpl
{
Creator(const wxString& filename_) : filename(filename_) {}

std::shared_ptr<XLIFFCatalog> CreateFromDoc(pugi::xml_document&& doc, const std::string& xliff_version) override
{
// Apple .xcloc uses XLIFF 1.2 only:
if (xliff_version != "1.2")
return nullptr;

auto c = std::make_shared<XCLOCCatalog>(std::move(doc), /*subversion=*/2);
c->m_originalFilename = filename;
c->m_embeddedXLIFFFilename = embedded_xliff;
return c;
}

wxString filename;
wxString embedded_xliff;
};

Creator c(filename);

// XCLOC bundles contain additional metadata and other localizable resources (images, text files),
// but we only care about l18n content. Find the embedded XLIFF file and open that:
wxDir dir(filename + "/Localized Contents");
if (!dir.IsOpened())
throw Exception(_("Unexpectedly missing content in the XCLOC file."));

if (!dir.GetFirst(&c.embedded_xliff, "*.xliff", wxDIR_FILES))
throw Exception(_("Unexpectedly missing content in the XCLOC file."));

return OpenImpl(dir.GetNameWithSep() + c.embedded_xliff, c);
}


bool XCLOCCatalog::Save(const wxString& filename, bool save_mo,
ValidationResults& validation_results,
CompilationStatus& mo_compilation_status)
{
if (filename != m_originalFilename)
throw Exception(_("Saving in a different location is not supported for XCLOC files."));

// update mtime for the directory to indicate that the file was modified; without this, it wouldn't
// be apparent as we're actually writing a file inside a subdirectory in the bundle:
wxFileName(filename).Touch();

wxString xliff_fn = filename + "/Localized Contents/" + m_embeddedXLIFFFilename;
return XLIFF1Catalog::Save(xliff_fn, save_mo, validation_results, mo_compilation_status);
}
54 changes: 54 additions & 0 deletions src/catalog_xcloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* This file is part of Poedit (https://poedit.net)
*
* Copyright (C) 2025 Vaclav Slavik
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/

#ifndef Poedit_catalog_xcloc_h
#define Poedit_catalog_xcloc_h

#include "catalog_xliff.h"


class XCLOCCatalog : public XLIFF1Catalog
{
public:
using XLIFF1Catalog::XLIFF1Catalog;

bool HasCapability(Cap cap) const override;

static bool CanLoadFile(const wxString& extension);
wxString GetPreferredExtension() const override { return "xcloc"; }

static std::shared_ptr<XLIFFCatalog> Open(const wxString& filename);

bool Save(const wxString& filename, bool save_mo,
ValidationResults& validation_results,
CompilationStatus& mo_compilation_status) override;

void SetLanguage(Language lang) override;

protected:
wxString m_originalFilename, m_embeddedXLIFFFilename;
};

#endif // Poedit_catalog_xcloc_h
Loading

0 comments on commit a7e9ed2

Please sign in to comment.