Coverage Report

Created: 2026-08-14 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/qt6/src/poppler-outline.cc
Line
Count
Source
1
/* poppler-outline.cc: qt interface to poppler
2
 *
3
 * Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
4
 * Copyright (C) 2019 Oliver Sander <oliver.sander@tu-dresden.de>
5
 * Copyright (C) 2019, 2026 Albert Astals Cid <aacid@kde.org>
6
 * Copyright (C) 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2, or (at your option)
11
 * any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
21
 */
22
23
#include <poppler-qt6.h>
24
#include <poppler-link.h>
25
26
#include "poppler-private.h"
27
#include "poppler-outline-private.h"
28
29
#include "Link.h"
30
#include "Outline.h"
31
32
namespace Poppler {
33
34
0
OutlineItem::OutlineItem() : m_data { new OutlineItemData { nullptr, nullptr } } { }
35
36
493
OutlineItem::OutlineItem(OutlineItemData *data) : m_data { data } { }
37
38
OutlineItem::~OutlineItem()
39
1.47k
{
40
1.47k
    delete m_data;
41
1.47k
    m_data = nullptr;
42
1.47k
}
43
44
0
OutlineItem::OutlineItem(const OutlineItem &other) : m_data { new OutlineItemData { *other.m_data } } { }
45
46
OutlineItem &OutlineItem::operator=(const OutlineItem &other)
47
0
{
48
0
    if (this == &other) {
49
0
        return *this;
50
0
    }
51
52
0
    auto *data = new OutlineItemData { *other.m_data };
53
0
    qSwap(m_data, data);
54
0
    delete data;
55
56
0
    return *this;
57
0
}
58
59
978
OutlineItem::OutlineItem(OutlineItem &&other) noexcept : m_data { other.m_data }
60
978
{
61
978
    other.m_data = nullptr;
62
978
}
63
64
OutlineItem &OutlineItem::operator=(OutlineItem &&other) noexcept
65
0
{
66
0
    qSwap(m_data, other.m_data);
67
68
0
    return *this;
69
0
}
70
71
bool OutlineItem::isNull() const
72
0
{
73
0
    return !m_data->data;
74
0
}
75
76
QString OutlineItem::name() const
77
0
{
78
0
    QString &name = m_data->name;
79
80
0
    if (name.isEmpty()) {
81
0
        if (const ::OutlineItem *data = m_data->data) {
82
0
            name = unicodeToQString(data->getTitle());
83
0
        }
84
0
    }
85
86
0
    return name;
87
0
}
88
89
bool OutlineItem::isOpen() const
90
0
{
91
0
    bool isOpen = false;
92
93
0
    if (const ::OutlineItem *data = m_data->data) {
94
0
        isOpen = data->isOpen();
95
0
    }
96
97
0
    return isOpen;
98
0
}
99
100
QSharedPointer<const LinkDestination> OutlineItem::destination() const
101
0
{
102
0
    QSharedPointer<const LinkDestination> &destination = m_data->destination;
103
104
0
    if (!destination) {
105
0
        if (const ::OutlineItem *data = m_data->data) {
106
0
            if (const ::LinkAction *action = data->getAction()) {
107
0
                if (action->getKind() == actionGoTo) {
108
0
                    const auto *linkGoTo = static_cast<const LinkGoTo *>(action);
109
0
                    destination.reset(new LinkDestination(LinkDestinationData(linkGoTo->getDest(), linkGoTo->getNamedDest(), m_data->documentData, false)));
110
0
                } else if (action->getKind() == actionGoToR) {
111
0
                    const auto *linkGoToR = static_cast<const LinkGoToR *>(action);
112
0
                    const bool external = linkGoToR->getFileName() != nullptr;
113
0
                    destination.reset(new LinkDestination(LinkDestinationData(linkGoToR->getDest(), linkGoToR->getNamedDest(), m_data->documentData, external)));
114
0
                }
115
0
            }
116
0
        }
117
0
    }
118
119
0
    return destination;
120
0
}
121
122
QString OutlineItem::externalFileName() const
123
0
{
124
0
    QString &externalFileName = m_data->externalFileName;
125
126
0
    if (externalFileName.isEmpty()) {
127
0
        if (const ::OutlineItem *data = m_data->data) {
128
0
            if (const ::LinkAction *action = data->getAction()) {
129
0
                if (action->getKind() == actionGoToR) {
130
0
                    if (const GooString *fileName = static_cast<const LinkGoToR *>(action)->getFileName()) {
131
0
                        externalFileName = UnicodeParsedString(fileName);
132
0
                    }
133
0
                }
134
0
            }
135
0
        }
136
0
    }
137
138
0
    return externalFileName;
139
0
}
140
141
QString OutlineItem::uri() const
142
0
{
143
0
    QString &uri = m_data->uri;
144
145
0
    if (uri.isEmpty()) {
146
0
        if (const ::OutlineItem *data = m_data->data) {
147
0
            if (const ::LinkAction *action = data->getAction()) {
148
0
                if (action->getKind() == actionURI) {
149
0
                    uri = UnicodeParsedString(static_cast<const LinkURI *>(action)->getURI());
150
0
                }
151
0
            }
152
0
        }
153
0
    }
154
155
0
    return uri;
156
0
}
157
158
bool OutlineItem::hasChildren() const
159
0
{
160
0
    bool result = false;
161
162
0
    if (::OutlineItem *data = m_data->data) {
163
0
        result = data->hasKids();
164
0
    }
165
166
0
    return result;
167
0
}
168
169
QVector<OutlineItem> OutlineItem::children() const
170
0
{
171
0
    QVector<OutlineItem> result;
172
173
0
    if (::OutlineItem *data = m_data->data) {
174
0
        data->open();
175
0
        if (const std::vector<::OutlineItem *> *kids = data->getKids()) {
176
0
            for (::OutlineItem *kid : *kids) {
177
0
                result.push_back(OutlineItem { new OutlineItemData { kid, m_data->documentData } });
178
0
            }
179
0
        }
180
0
    }
181
182
0
    return result;
183
0
}
184
185
}