9#include "third_party/pdfium/public/fpdf_text.h"
10#include "third_party/pdfium/public/fpdfview.h"
12#include <QtCore/qelapsedtimer.h>
13#include <QtCore/qloggingcategory.h>
14#include <QtCore/QMetaEnum>
62 if (roleName.isEmpty())
64 roleName[0] = QChar::toLower(roleName[0]);
65 m_roleNames.insert(
r, roleName);
95 return d->rowCountSoFar;
107 switch (
Role(role)) {
113 return d->searchResults[pi.page][pi.index].location();
115 return d->searchResults[pi.page][pi.index].contextBefore();
117 return d->searchResults[pi.page][pi.index].contextAfter();
122 const QString ret =
d->searchResults[pi.page][pi.index].contextBefore() +
124 d->searchResults[pi.page][pi.index].contextAfter();
153 return d->searchString;
176 if (
d->searchResults.size() <=
page)
189 if (pi.page < 0 ||
index < 0)
212 [
this]() { d_func()->clearResults(); });
222 if (
event->timerId() !=
d->updateTimerId)
224 if (!
d->document ||
d->nextPageToUpdate >=
d->document->pageCount()) {
226 qCDebug(qLcS) <<
"done updating search results on" <<
d->searchResults.size() <<
"pages";
228 d->updateTimerId = -1;
230 d->doSearch(
d->nextPageToUpdate++);
267 FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage);
270 FPDF_ClosePage(pdfPage);
274 QList<QPdfLink> newSearchResults;
276 while (FPDFText_FindNext(sh)) {
277 int idx = FPDFText_GetSchResultIndex(sh);
278 int count = FPDFText_GetSchCount(sh);
279 int rectCount = FPDFText_CountRects(textPage, idx,
count);
283 for (
int r = 0;
r < rectCount; ++
r) {
291 startIndex = FPDFText_GetCharIndexAtPos(textPage,
left,
top,
294 if (
r == rectCount - 1) {
295 endIndex = FPDFText_GetCharIndexAtPos(textPage,
right,
top,
298 qCDebug(qLcS) << rects.last() <<
"char idx" << startIndex <<
"->" << endIndex
301 QString contextBefore, contextAfter;
302 if (startIndex >= 0 || endIndex >= 0) {
305 int count = endIndex - startIndex + 1;
308 int len = FPDFText_GetText(textPage, startIndex,
count,
buf.data());
311 reinterpret_cast<const char16_t *
>(
buf.constData()),
len - 1);
320 contextBefore =
context.mid(0, si);
324 if (!rects.isEmpty())
325 newSearchResults <<
QPdfLink(
page, rects, contextBefore, contextAfter);
327 FPDFText_FindClose(sh);
328 FPDFText_ClosePage(textPage);
329 FPDF_ClosePage(pdfPage);
331 << newSearchResults.size() <<
"results on page" <<
page;
335 if (newSearchResults.size() > 0) {
337 qCDebug(qLcS) <<
"from row" << rowsBefore <<
"rowCount" <<
rowCountSoFar <<
"increasing by" << newSearchResults.size();
339 q->beginInsertRows(
QModelIndex(), rowsBefore, rowsBefore + newSearchResults.size() - 1);
351 int previousTotalSoFar = 0;
356 if (totalSoFar > resultIndex)
357 return {
page, resultIndex - previousTotalSoFar};
358 previousTotalSoFar = totalSoFar;
373#include "moc_qpdfsearchmodel.cpp"
void endResetModel()
Completes a model reset operation.
void modelReset(QPrivateSignal)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
void beginResetModel()
Begins a model reset operation.
void rowsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been inserted into the model.
void rowsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been removed from the model.
QObject * parent() const
Returns a pointer to the parent object.
qsizetype size() const noexcept
bool isEmpty() const noexcept
void resize(qsizetype size)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void killTimer(int id)
Kills the timer with timer identifier, id.
QPointF mapPageToView(FPDF_PAGE pdfPage, double x, double y) const
The QPdfDocument class loads a PDF document and renders pages from it.
int pageCount
This property holds the number of pages in the loaded document or 0 if no document is loaded.
void pageCountChanged(int pageCount)
The QPdfLink class defines a link between a region on a page (such as a hyperlink or a search result)...
int rowsBeforePage(int page)
QList< bool > pagesSearched
PageAndIndex pageAndIndexForResult(int resultIndex)
QList< QList< QPdfLink > > searchResults
The QPdfSearchModel class searches for a string in a PDF document and holds the results.
QString searchString
the string to search for
int rowCount(const QModelIndex &parent) const override
\reimp
QPdfLink resultAtIndex(int index) const
Returns a result found by index in the \l document, regardless of the page on which it was found.
void setDocument(QPdfDocument *document)
void updatePage(int page)
QHash< int, QByteArray > roleNames() const override
\reimp
int count
the number of search results found
~QPdfSearchModel() override
Destroys the model.
QPdfDocument * document
the document to search
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
void setSearchString(const QString &searchString)
QVariant data(const QModelIndex &index, int role) const override
\reimp
void searchStringChanged()
Role
\value Page The page number where the search result is found (int).
QList< QPdfLink > resultsOnPage(int page) const
Returns the list of all results found on the given page.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
static QString fromUtf16(const char16_t *, qsizetype size=-1)
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
qsizetype size() const noexcept
Returns the number of characters in this string.
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Combined button and popup list for selecting options.
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr const T & qMax(const T &a, const T &b)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLenum GLuint GLenum GLsizei const GLchar * buf
GLdouble GLdouble GLdouble GLdouble q
static const double CharacterHitTolerance
static const int ContextChars
static QT_BEGIN_NAMESPACE const int UpdateTimerInterval
QLatin1StringView QLatin1String
#define QStringLiteral(str)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
obj metaObject() -> className()
myObject disconnect()
[26]
\inmodule QtCore \reentrant