Extract Collator class.
authorCarl Hetherington <cth@carlh.net>
Wed, 17 Aug 2022 15:45:35 +0000 (17:45 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 18 Oct 2022 22:27:47 +0000 (00:27 +0200)
src/lib/collator.cc [new file with mode: 0644]
src/lib/collator.h [new file with mode: 0644]
src/lib/wscript
src/wx/screens_panel.cc
src/wx/screens_panel.h

diff --git a/src/lib/collator.cc b/src/lib/collator.cc
new file mode 100644 (file)
index 0000000..4f52597
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+    Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "collator.h"
+#include <unicode/putil.h>
+#include <unicode/ucol.h>
+#include <unicode/uiter.h>
+#include <unicode/utypes.h>
+#include <unicode/ustring.h>
+#include <boost/scoped_array.hpp>
+#include <cstring>
+
+
+using std::string;
+
+
+Collator::Collator()
+{
+       UErrorCode status = U_ZERO_ERROR;
+       _collator = ucol_open(nullptr, &status);
+       if (_collator) {
+               ucol_setAttribute(_collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
+               ucol_setAttribute(_collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
+               ucol_setAttribute(_collator, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
+       }
+}
+
+
+Collator::~Collator()
+{
+       if (_collator) {
+               ucol_close (_collator);
+       }
+}
+
+
+int
+Collator::compare (string const& utf8_a, string const& utf8_b)
+{
+       if (_collator) {
+               UErrorCode error = U_ZERO_ERROR;
+               boost::scoped_array<uint16_t> utf16_a(new uint16_t[utf8_a.size() + 1]);
+               u_strFromUTF8(reinterpret_cast<UChar*>(utf16_a.get()), utf8_a.size() + 1, nullptr, utf8_a.c_str(), -1, &error);
+               boost::scoped_array<uint16_t> utf16_b(new uint16_t[utf8_b.size() + 1]);
+               u_strFromUTF8(reinterpret_cast<UChar*>(utf16_b.get()), utf8_b.size() + 1, nullptr, utf8_b.c_str(), -1, &error);
+               return ucol_strcoll(_collator, reinterpret_cast<UChar*>(utf16_a.get()), -1, reinterpret_cast<UChar*>(utf16_b.get()), -1);
+       } else {
+               return strcoll(utf8_a.c_str(), utf8_b.c_str());
+       }
+}
+
diff --git a/src/lib/collator.h b/src/lib/collator.h
new file mode 100644 (file)
index 0000000..3762f24
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+    Copyright (C) 2022 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifndef DCPOMATIC_COLLATOR_H
+#define DCPOMATIC_COLLATOR_H
+
+
+#include <string>
+
+
+struct UCollator;
+
+
+class Collator
+{
+public:
+       Collator();
+       ~Collator();
+
+       Collator(Collator const &) = delete;
+       Collator& operator=(Collator const&) = delete;
+
+       int compare(std::string const& utf8_a, std::string const& utf8_b);
+
+private:
+       UCollator* _collator = nullptr;
+};
+
+
+#endif
+
index 26fcb21e50e24e975795c5272a5ffcdd6a69eb06..d3aec7769bdb129fee2a27fa6bbdc39c484ab0ff 100644 (file)
@@ -51,6 +51,7 @@ sources = """
           check_content_job.cc
           cinema.cc
           cinema_sound_processor.cc
+          collator.cc
           colour_conversion.cc
           config.cc
           content.cc
index 562ea8f3895d0d67423ee135ae8b76bf4ef35900..a726030ade2049e34a3575e9398acde44ee2a2f7 100644 (file)
 #include "lib/scope_guard.h"
 #include "lib/screen.h"
 #include "lib/timer.h"
-#include <unicode/putil.h>
-#include <unicode/ucol.h>
-#include <unicode/uiter.h>
-#include <unicode/utypes.h>
-#include <unicode/ustring.h>
 
 
 using std::cout;
@@ -120,14 +115,6 @@ ScreensPanel::ScreensPanel (wxWindow* parent)
 
        SetSizer (sizer);
 
-       UErrorCode status = U_ZERO_ERROR;
-       _collator = ucol_open(nullptr, &status);
-       if (_collator) {
-               ucol_setAttribute(_collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
-               ucol_setAttribute(_collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
-               ucol_setAttribute(_collator, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
-       }
-
        _config_connection = Config::instance()->Changed.connect(boost::bind(&ScreensPanel::config_changed, this, _1));
 }
 
@@ -136,10 +123,6 @@ ScreensPanel::~ScreensPanel ()
 {
        _targets->Unbind (wxEVT_TREELIST_SELECTION_CHANGED, &ScreensPanel::selection_changed_shim, this);
        _targets->Unbind (wxEVT_TREELIST_ITEM_CHECKED, &ScreensPanel::checkbox_changed, this);
-
-       if (_collator) {
-               ucol_close (_collator);
-       }
 }
 
 
@@ -239,7 +222,7 @@ ScreensPanel::add_cinema_clicked ()
 
                auto cinemas = Config::instance()->cinemas();
                cinemas.sort(
-                       [this](shared_ptr<Cinema> a, shared_ptr<Cinema> b) { return compare(a->name, b->name) < 0; }
+                       [this](shared_ptr<Cinema> a, shared_ptr<Cinema> b) { return _collator.compare(a->name, b->name) < 0; }
                        );
 
                try {
@@ -254,7 +237,7 @@ ScreensPanel::add_cinema_clicked ()
                wxTreeListItem previous = wxTLI_FIRST;
                bool found = false;
                for (auto existing_cinema: cinemas) {
-                       if (compare(dialog->name(), existing_cinema->name) < 0) {
+                       if (_collator.compare(dialog->name(), existing_cinema->name) < 0) {
                                /* existing_cinema should be after the one we're inserting */
                                found = true;
                                break;
@@ -502,7 +485,7 @@ ScreensPanel::add_cinemas ()
 {
        auto cinemas = Config::instance()->cinemas();
        cinemas.sort(
-               [this](shared_ptr<Cinema> a, shared_ptr<Cinema> b) { return compare(a->name, b->name) < 0; }
+               [this](shared_ptr<Cinema> a, shared_ptr<Cinema> b) { return _collator.compare(a->name, b->name) < 0; }
                );
 
        for (auto cinema: cinemas) {
@@ -667,22 +650,6 @@ ScreensPanel::screen_to_item (shared_ptr<Screen> screen) const
 }
 
 
-int
-ScreensPanel::compare (string const& utf8_a, string const& utf8_b)
-{
-       if (_collator) {
-               UErrorCode error = U_ZERO_ERROR;
-               boost::scoped_array<uint16_t> utf16_a(new uint16_t[utf8_a.size() + 1]);
-               u_strFromUTF8(reinterpret_cast<UChar*>(utf16_a.get()), utf8_a.size() + 1, nullptr, utf8_a.c_str(), -1, &error);
-               boost::scoped_array<uint16_t> utf16_b(new uint16_t[utf8_b.size() + 1]);
-               u_strFromUTF8(reinterpret_cast<UChar*>(utf16_b.get()), utf8_b.size() + 1, nullptr, utf8_b.c_str(), -1, &error);
-               return ucol_strcoll(_collator, reinterpret_cast<UChar*>(utf16_a.get()), -1, reinterpret_cast<UChar*>(utf16_b.get()), -1);
-       } else {
-               return strcoll(utf8_a.c_str(), utf8_b.c_str());
-       }
-}
-
-
 bool
 ScreensPanel::notify_cinemas_changed()
 {
@@ -707,5 +674,3 @@ ScreensPanel::config_changed(Config::Property property)
                clear_and_re_add();
        }
 }
-
-
index a91fbc0e055e41a49aa5c6e98dd753f4593e0083..e9cd8454dcd39af0968ba45c69441626f255fb7c 100644 (file)
@@ -19,6 +19,7 @@
 */
 
 
+#include "lib/collator.h"
 #include "lib/config.h"
 #include <dcp/warnings.h>
 LIBDCP_DISABLE_WARNINGS
@@ -38,7 +39,6 @@ namespace dcpomatic {
 
 
 class Cinema;
-struct UCollator;
 
 
 class ScreensPanel : public wxPanel
@@ -69,7 +69,6 @@ private:
        std::shared_ptr<Cinema> cinema_for_operation () const;
        void set_screen_checked (wxTreeListItem item, bool checked);
        void setup_cinema_checked_state (wxTreeListItem screen);
-       int compare (std::string const& utf8_a, std::string const& utf8_b);
        void check_all ();
        void uncheck_all ();
        bool notify_cinemas_changed();
@@ -111,7 +110,7 @@ private:
        bool _ignore_selection_change = false;
        bool _ignore_check_change = false;
 
-       UCollator* _collator = nullptr;
+       Collator _collator;
 
        boost::signals2::scoped_connection _config_connection;
        bool _ignore_cinemas_changed = false;