Info about JavaScript tool

This commit is contained in:
Jakub Melka
2020-10-05 19:50:04 +02:00
parent 2acbcd68b2
commit 9a85ba458f
8 changed files with 283 additions and 0 deletions

View File

@@ -63,6 +63,8 @@ public:
ScanNamed = 0x0008, ///< Scan named javascript in catalog
ScanForm = 0x0010, ///< Scan javascript in form actions
ScanPage = 0x0020, ///< Scan javascript in page annotations
ScanMask = ScanDocument | ScanNamed | ScanForm | ScanPage
};
Q_DECLARE_FLAGS(Options, Option)

View File

@@ -308,6 +308,94 @@ QString PDFClosedIntervalSet::toText() const
return intervals.join(", ");
}
std::vector<PDFInteger> PDFClosedIntervalSet::unfold() const
{
std::vector<PDFInteger> result(getTotalLength(), 0);
auto it = result.begin();
for (auto [first, last] : m_intervals)
{
PDFInteger rangeSize = last - first + 1;
std::iota(it, std::next(it, rangeSize), first);
std::advance(it, rangeSize);
}
Q_ASSERT(it == result.end());
return result;
}
PDFClosedIntervalSet PDFClosedIntervalSet::parse(PDFInteger first, PDFInteger last, const QString& text, QString* errorMessage)
{
PDFClosedIntervalSet result;
*errorMessage = QString();
QStringList parts = text.split(",", Qt::SkipEmptyParts, Qt::CaseSensitive);
for (QString part : parts)
{
part = part.trimmed();
int separatorPos = part.indexOf(QChar('-'));
const bool isRange = separatorPos != -1;
if (isRange)
{
const bool isLowerBoundDefined = part.front() != QChar('-');
const bool isUpperBoundDefined = part.back() != QChar('-');
QString lowerString = part.left(separatorPos);
QString upperString = part.mid(separatorPos + 1);
bool ok1 = true;
bool ok2 = true;
PDFInteger lower = isLowerBoundDefined ? lowerString.toLongLong(&ok1) : first;
PDFInteger upper = isUpperBoundDefined ? upperString.toLongLong(&ok2) : last;
if (!ok1)
{
*errorMessage = PDFTranslationContext::tr("Can't convert '%1' to a number.").arg(lowerString);
break;
}
if (!ok2)
{
*errorMessage = PDFTranslationContext::tr("Can't convert '%1' to a number.").arg(upperString);
break;
}
if (lower > upper)
{
*errorMessage = PDFTranslationContext::tr("Closed interval [%1, %2] is invalid.").arg(lower).arg(upper);
break;
}
result.addInterval(lower, upper);
}
else
{
bool ok = true;
PDFInteger value = part.toLongLong(&ok);
if (!ok)
{
*errorMessage = PDFTranslationContext::tr("Can't convert '%1' to a number.").arg(part);
break;
}
result.addValue(value);
}
}
if (!errorMessage->isEmpty())
{
// Clear the result, error occured
result = PDFClosedIntervalSet();
}
result.normalize();
return result;
}
void PDFClosedIntervalSet::normalize()
{
// Algorithm:

View File

@@ -614,6 +614,24 @@ public:
/// Transforms interval set to readable text
QString toText() const;
/// Returns all integers from the range
std::vector<PDFInteger> unfold() const;
/// Returns true, if interval set is empty
bool isEmpty() const { return m_intervals.empty(); }
/// Parses text into closed interval set, text should be in form "1,3,4,7,-11,12-,52-53,-",
/// where 1,3,4,7 means single pages, -11 means range from \p first to 11, 12- means range
/// from 12 to \p last, and 52-53 means closed interval [52, 53]. If text is not in this form,
/// then empty interval set is returned and if \p errorMessage is specified, then error message
/// is stored here. Parsed numbers must be equal or greater than \p first and lower or equal
/// to \p last, if overflow occurs, then error message is returned.
/// \param[in] first Lower bound of work range
/// \param[in] last Upper bound of work range
/// \param[in] text Text
/// \param[out] errorMessage Error message
static PDFClosedIntervalSet parse(PDFInteger first, PDFInteger last, const QString& text, QString* errorMessage);
private:
/// Normalizes interval ranges - merges adjacent intervals
void normalize();