Warning, file /graphics/glaxnimate/src/gui/item_models/drag_data.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <iterator>
0010 
0011 #include <QByteArray>
0012 #include <QDataStream>
0013 #include <QSet>
0014 
0015 #include "model/document.hpp"
0016 
0017 namespace glaxnimate::gui::item_models {
0018 
0019 class DragEncoder
0020 {
0021 public:
0022     void add_node(model::DocumentNode* n)
0023     {
0024         if ( !n )
0025             return;
0026 
0027         if ( !uniq.contains(n->uuid.get()) )
0028         {
0029             stream << n->uuid.get();
0030             uniq.insert(n->uuid.get());
0031         }
0032     }
0033 
0034     const QByteArray& data() const
0035     {
0036         return encoded;
0037     }
0038 
0039 private:
0040     QByteArray encoded;
0041     QDataStream stream{&encoded, QIODevice::WriteOnly};
0042     QSet<QUuid> uniq;
0043 };
0044 
0045 
0046 template<class T = model::DocumentNode>
0047 class DragDecoder
0048 {
0049 public:
0050     using value_type = T*;
0051 
0052     class iterator
0053     {
0054     public:
0055         using iterator_category = std::forward_iterator_tag;
0056         using value_type = DragDecoder::value_type;
0057         using pointer = T*;
0058         using difference_type = int;
0059         using reference = T*;
0060 
0061         iterator& operator++()
0062         {
0063             if ( decoder )
0064             {
0065                 if ( decoder->at_end() )
0066                 {
0067                     decoder = nullptr;
0068                     ptr = nullptr;
0069                 }
0070                 else
0071                 {
0072                     do
0073                         ptr = qobject_cast<T*>(decoder->next());
0074                     while ( !ptr );
0075                 }
0076             }
0077             return *this;
0078         }
0079 
0080         value_type operator*() const noexcept
0081         {
0082             return ptr;
0083         }
0084 
0085         bool operator==(const iterator& other) const noexcept
0086         {
0087             return other.decoder == decoder;
0088         }
0089 
0090         bool operator!=(const iterator& other) const noexcept
0091         {
0092             return other.decoder != decoder;
0093         }
0094 
0095     private:
0096         friend DragDecoder;
0097         iterator(DragDecoder* decoder)
0098             : decoder(decoder)
0099         {
0100             if ( decoder )
0101                 ++*this;
0102 
0103         }
0104 
0105         DragDecoder* decoder;
0106         value_type ptr = nullptr;
0107     };
0108 
0109     explicit DragDecoder(QByteArray encoded, model::Document* document)
0110         : encoded(std::move(encoded)),
0111           stream(&this->encoded, QIODevice::ReadOnly),
0112           document(document)
0113     {}
0114 
0115     T* next()
0116     {
0117         QUuid uuid;
0118         stream >> uuid;
0119         return qobject_cast<T*>(document->find_by_uuid(uuid));
0120     }
0121 
0122     bool at_end() const
0123     {
0124         return stream.atEnd();
0125     }
0126 
0127     iterator begin()
0128     {
0129         return iterator(this);
0130     }
0131 
0132     iterator end()
0133     {
0134         return iterator(nullptr);
0135     }
0136 
0137 private:
0138     QByteArray encoded;
0139     QDataStream stream;
0140     model::Document* document;
0141 };
0142 
0143 } // namespace glaxnimate::gui::item_models