LCOV - code coverage report
Current view: top level - src/engraving/rw/write - connectorinfowriter.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 61 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "connectorinfowriter.h"
      23              : 
      24              : #include "../../dom/engravingitem.h"
      25              : #include "../../dom/spanner.h"
      26              : #include "../../dom/measurebase.h"
      27              : #include "../../dom/measure.h"
      28              : #include "../../dom/score.h"
      29              : 
      30              : #include "../xmlwriter.h"
      31              : 
      32              : #include "twrite.h"
      33              : 
      34              : #include "log.h"
      35              : 
      36              : using namespace mu::engraving;
      37              : using namespace mu::engraving::write;
      38              : 
      39            0 : ConnectorInfoWriter::ConnectorInfoWriter(XmlWriter& xml, WriteContext* ctx, const EngravingItem* current,
      40              :                                          const EngravingItem* connector,
      41              :                                          int track,
      42            0 :                                          Fraction frac)
      43            0 :     : ConnectorInfo(current, track, frac), _connector(connector), m_xml(&xml), m_ctx(ctx)
      44              : {
      45            0 :     IF_ASSERT_FAILED(current) {
      46            0 :         return;
      47              :     }
      48            0 :     m_type = connector->type();
      49            0 :     updateCurrentInfo(m_ctx->clipboardmode());
      50            0 : }
      51              : 
      52            0 : void ConnectorInfoWriter::write()
      53              : {
      54            0 :     XmlWriter& xml = *m_xml;
      55            0 :     WriteContext& ctx = *m_ctx;
      56            0 :     if (!ctx.canWrite(_connector)) {
      57            0 :         return;
      58              :     }
      59            0 :     xml.startElement(tagName(), { { "type", _connector->typeName() } });
      60            0 :     if (isStart()) {
      61            0 :         TWrite::writeItem(_connector, xml, ctx);
      62              :     }
      63            0 :     if (hasPrevious()) {
      64            0 :         xml.startElement("prev");
      65            0 :         m_prevLoc.toRelative(m_currentLoc);
      66            0 :         TWrite::write(&m_prevLoc, xml, ctx);
      67            0 :         xml.endElement();
      68              :     }
      69            0 :     if (hasNext()) {
      70            0 :         xml.startElement("next");
      71            0 :         m_nextLoc.toRelative(m_currentLoc);
      72            0 :         TWrite::write(&m_nextLoc, xml, ctx);
      73            0 :         xml.endElement();
      74              :     }
      75            0 :     xml.endElement();
      76            0 : }
      77              : 
      78              : //---------------------------------------------------------
      79              : //   SpannerWriter::fillSpannerPosition
      80              : //---------------------------------------------------------
      81              : 
      82            0 : void SpannerWriter::fillSpannerPosition(Location& l, const MeasureBase* m, const Fraction& tick, bool clipboardmode)
      83              : {
      84            0 :     if (clipboardmode) {
      85            0 :         l.setMeasure(0);
      86            0 :         l.setFrac(tick);
      87              :     } else {
      88            0 :         if (!m) {
      89            0 :             LOGW("fillSpannerPosition: couldn't find spanner's endpoint's measure");
      90            0 :             l.setMeasure(0);
      91            0 :             l.setFrac(tick);
      92            0 :             return;
      93              :         }
      94            0 :         l.setMeasure(m->measureIndex());
      95            0 :         l.setFrac(tick - m->tick());
      96              :     }
      97              : }
      98              : 
      99              : //---------------------------------------------------------
     100              : //   SpannerWriter::SpannerWriter
     101              : //---------------------------------------------------------
     102              : 
     103            0 : SpannerWriter::SpannerWriter(XmlWriter& xml, WriteContext* ctx, const EngravingItem* current, const Spanner* sp, int track, Fraction frac,
     104            0 :                              bool start)
     105            0 :     : ConnectorInfoWriter(xml, ctx, current, sp, track, frac)
     106              : {
     107            0 :     const bool clipboardmode = ctx->clipboardmode();
     108            0 :     if ((!sp->startElement() || !sp->endElement())
     109            0 :         && (sp->anchor() == Spanner::Anchor::CHORDREST || sp->anchor() == Spanner::Anchor::NOTE)) {
     110            0 :         LOGW("SpannerWriter: spanner (%s) doesn't have an endpoint!", sp->typeName());
     111            0 :         return;
     112              :     }
     113            0 :     if (current->isMeasure() || current->isSegment() || !sp->startElement() || !sp->endElement()
     114            0 :         || (sp->startElement()->type() != current->type())) {
     115              :         // (The latter is the hairpins' case, for example, though they are
     116              :         // covered by the other checks too.)
     117              :         // We cannot determine position of the spanner from its start/end
     118              :         // elements and will try to obtain this info from the spanner itself.
     119            0 :         if (!start) {
     120            0 :             m_prevLoc.setTrack(static_cast<int>(sp->track()));
     121            0 :             Measure* m = sp->score()->tick2measure(sp->tick());
     122            0 :             fillSpannerPosition(m_prevLoc, m, sp->tick(), clipboardmode);
     123              :         } else {
     124            0 :             const track_idx_t track2 = (sp->track2() != muse::nidx) ? sp->track2() : sp->track();
     125            0 :             m_nextLoc.setTrack(static_cast<int>(track2));
     126            0 :             Measure* m = sp->score()->tick2measure(sp->tick2());
     127            0 :             fillSpannerPosition(m_nextLoc, m, sp->tick2(), clipboardmode);
     128              :         }
     129              :     } else {
     130              :         // We can obtain the spanner position info from its start/end
     131              :         // elements and will prefer this source of information.
     132              :         // Reason: some spanners contain no or wrong information (e.g. Ties).
     133            0 :         if (!start) {
     134            0 :             updateLocation(sp->startElement(), m_prevLoc, clipboardmode);
     135              :         } else {
     136            0 :             updateLocation(sp->endElement(), m_nextLoc, clipboardmode);
     137              :         }
     138              :     }
     139            0 : }
        

Generated by: LCOV version 2.0-1