/** * Search for color pattern in given string * contentStr can also be JSON * returns pattern name if successful, or 'nil' if no pattern found * can be in form: * pattern: policecar * pattern: "happy color dance" * { "pattern": "red flashes" } * * @param str string to parse * @return parsed color pattern name or empty string if no match */ QString DataInput::readColorPattern(QString str) { QString patt; QRegularExpression re("\"?pattern\"?:\\s*((\"(.+)\")|((.+)\\s))"); QRegularExpressionMatch match = re.match(str); if( match.hasMatch() ) { patt = match.captured( match.lastCapturedIndex() ); } return patt; }
/** * Read potential color code in string * @param str string to parse * @return valid QColor or invalid QColor if parsing failed */ QColor DataInput::readColorCode(QString str) { QColor c; QRegularExpression re("(#[A-Fa-f0-9]{6})"); // look for "#cccccc" style hex colorcode QRegularExpressionMatch match = re.match(str); if( match.hasMatch() ) { c.setNamedColor( match.captured( match.lastCapturedIndex()) ); } return c; }
QStringList readQmlTypes(const QString &filename) { QRegularExpression re("import QtQuick.tooling 1.2.*Module {\\s*dependencies:\\[([^\\]]*)\\](.*)}", QRegularExpression::DotMatchesEverythingOption); if (!QFileInfo(filename).exists()) { std::cerr << "Non existing file: " << filename.toStdString() << std::endl; return QStringList(); } QFile f(filename); if (!f.open(QFileDevice::ReadOnly)) { std::cerr << "Error in opening file " << filename.toStdString() << " : " << f.errorString().toStdString() << std::endl; return QStringList(); } QByteArray fileData = f.readAll(); QString data(fileData); QRegularExpressionMatch m = re.match(data); if (m.lastCapturedIndex() != 2) { std::cerr << "Malformed file: " << filename.toStdString() << std::endl; return QStringList(); } return m.capturedTexts(); }
QString computeEpisodeName(const QString &article) { const QRegularExpression episodeRegex = AutoDownloader::instance()->smartEpisodeRegex(); const QRegularExpressionMatch match = episodeRegex.match(article); // See if we can extract an season/episode number or date from the title if (!match.hasMatch()) return QString(); QStringList ret; for (int i = 1; i <= match.lastCapturedIndex(); ++i) { QString cap = match.captured(i); if (cap.isEmpty()) continue; bool isInt = false; int x = cap.toInt(&isInt); ret.append(isInt ? QString::number(x) : cap); } return ret.join('x'); }
void ReplaceMatches::doReplaceNextMatch() { if ((!m_manager) || (m_cancelReplace) || (m_tree->topLevelItemCount() != 1)) { m_rootIndex = -1; emit replaceDone(); return; } // NOTE The document managers signal documentWillBeDeleted() must be connected to // cancelReplace(). A closed file could lead to a crash if it is not handled. // Open the file QTreeWidgetItem *rootItem = m_tree->topLevelItem(0)->child(m_rootIndex); if (!rootItem) { m_rootIndex = -1; emit replaceDone(); return; } if (!rootItem->data(0, ColumnRole).toString().isEmpty()) { // this is a search as you type replace rootItem = m_tree->topLevelItem(0); m_cancelReplace = true; // only one document... } if (rootItem->checkState(0) == Qt::Unchecked) { m_rootIndex++; emit replaceNextMatch(); return; } KTextEditor::Document *doc; QString docUrl = rootItem->data(0, FileUrlRole).toString(); QString docName = rootItem->data(0, FileNameRole).toString(); if (docUrl.isEmpty()) { doc = findNamed(rootItem->data(0, FileNameRole).toString()); } else { doc = m_manager->findUrl(QUrl::fromUserInput(docUrl)); if (!doc) { doc = m_manager->openUrl(QUrl::fromUserInput(rootItem->data(0, FileUrlRole).toString())); } } if (!doc) { m_rootIndex++; emit replaceNextMatch(); return; } QVector<KTextEditor::MovingRange*> rVector; QStringList rTexts; KTextEditor::MovingInterface* miface = qobject_cast<KTextEditor::MovingInterface*>(doc); int line; int column; int matchLen; int endLine; int endColumn; QTreeWidgetItem *item; QString matchLines; // lines might be modified so search the document again for (int i=0; i<rootItem->childCount(); i++) { item = rootItem->child(i); if (item->checkState(0) == Qt::Unchecked) continue; line = endLine= item->data(0, LineRole).toInt(); column = item->data(0, ColumnRole).toInt(); matchLen = item->data(0, MatchLenRole).toInt(); matchLines = doc->line(line).mid(column); while (matchLines.size() < matchLen) { if (endLine+1 >= doc->lines()) break; endLine++; matchLines+= QLatin1Char('\n') + doc->line(endLine); } QRegularExpressionMatch match = m_regExp.match(matchLines); if (match.capturedStart() != 0) { qDebug() << matchLines << "Does not match" << m_regExp.pattern(); continue; } QString replaceText = m_replaceText; replaceText.replace(QStringLiteral("\\\\"), QStringLiteral("¤Search&Replace¤")); // allow captures \0 .. \9 for (int j = qMin(9, match.lastCapturedIndex()); j >= 0; --j) { replaceText.replace(QString(QStringLiteral("\\%1")).arg(j), match.captured(j)); } // allow captures \{0} .. \{9999999}... for (int j = match.lastCapturedIndex(); j >= 0; --j) { replaceText.replace(QString(QStringLiteral("\\{%1}")).arg(j), match.captured(j)); } replaceText.replace(QStringLiteral("\\n"), QStringLiteral("\n")); replaceText.replace(QStringLiteral("\\t"), QStringLiteral("\t")); replaceText.replace(QStringLiteral("¤Search&Replace¤"), QStringLiteral("\\")); rTexts << replaceText; replaceText.replace(QLatin1Char('\n'), QStringLiteral("\\n")); replaceText.replace(QLatin1Char('\t'), QStringLiteral("\\t")); QString html = item->data(0, PreMatchRole).toString(); html += QStringLiteral("<i><s>") + item->data(0, MatchRole).toString() + QStringLiteral("</s></i> "); html += QStringLiteral("<b>") + replaceText + QStringLiteral("</b>"); html += item->data(0, PostMatchRole).toString(); item->setData(0, Qt::DisplayRole, i18n("Line: <b>%1</b>: %2",line+1, html)); endLine = line; endColumn = column+matchLen; while ((endLine < doc->lines()) && (endColumn > doc->line(endLine).size())) { endColumn -= doc->line(endLine).size(); endColumn--; // remove one for '\n' endLine++; } KTextEditor::Range range(line, column, endLine, endColumn); KTextEditor::MovingRange* mr = miface->newMovingRange(range); rVector.append(mr); } for (int i=0; i<rVector.size(); i++) { line = rVector[i]->start().line(); column = rVector[i]->start().column(); doc->replaceText(*rVector[i], rTexts[i]); emit matchReplaced(doc, line, column, rTexts[i].length()); } qDeleteAll(rVector); m_rootIndex++; emit replaceNextMatch(); }
int main() { { //! [0] QRegularExpression re("a pattern"); //! [0] } { //! [1] QRegularExpression re; re.setPattern("another pattern"); //! [1] } { //! [2] // matches two digits followed by a space and a word QRegularExpression re("\\d\\d \\w+"); // matches a backslash QRegularExpression re2("\\\\"); //! [2] } { //! [3] QRegularExpression re("a third pattern"); QString pattern = re.pattern(); // pattern == "a third pattern" //! [3] } { //! [4] // matches "Qt rocks", but also "QT rocks", "QT ROCKS", "qT rOcKs", etc. QRegularExpression re("Qt rocks", QRegularExpression::CaseInsensitiveOption); //! [4] } { //! [5] QRegularExpression re("^\\d+$"); re.setPatternOptions(QRegularExpression::MultilineOption); // re matches any line in the subject string that contains only digits (but at least one) //! [5] } { //! [6] QRegularExpression re = QRegularExpression("^two.*words$", QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption); QRegularExpression::PatternOptions options = re.patternOptions(); // options == QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption //! [6] } { //! [7] // match two digits followed by a space and a word QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("abc123 def"); bool hasMatch = match.hasMatch(); // true //! [7] } { //! [8] QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("abc123 def"); if (match.hasMatch()) { QString matched = match.captured(0); // matched == "23 def" // ... } //! [8] } { //! [9] QRegularExpression re("\\d\\d \\w+"); QRegularExpressionMatch match = re.match("12 abc 45 def", 1); if (match.hasMatch()) { QString matched = match.captured(0); // matched == "45 def" // ... } //! [9] } { //! [10] QRegularExpression re("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$"); QRegularExpressionMatch match = re.match("08/12/1985"); if (match.hasMatch()) { QString day = match.captured(1); // day == "08" QString month = match.captured(2); // month == "12" QString year = match.captured(3); // year == "1985" // ... } //! [10] } { //! [11] QRegularExpression re("abc(\\d+)def"); QRegularExpressionMatch match = re.match("XYZabc123defXYZ"); if (match.hasMatch()) { int startOffset = match.capturedStart(1); // startOffset == 6 int endOffset = match.capturedEnd(1); // endOffset == 9 // ... } //! [11] } { //! [12] QRegularExpression re("^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$"); QRegularExpressionMatch match = re.match("08/12/1985"); if (match.hasMatch()) { QString date = match.captured("date"); // date == "08" QString month = match.captured("month"); // month == "12" QString year = match.captured("year"); // year == 1985 } //! [12] } { //! [13] QRegularExpression re("(\\w+)"); QRegularExpressionMatchIterator i = re.globalMatch("the quick fox"); //! [13] //! [14] QStringList words; while (i.hasNext()) { QRegularExpressionMatch match = i.next(); QString word = match.captured(1); words << word; } // words contains "the", "quick", "fox" //! [14] } { //! [15] QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$"); QRegularExpression re(pattern); QString input("Jan 21,"); QRegularExpressionMatch match = re.match(input, 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [15] } { QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$"); QRegularExpression re(pattern); //! [16] QString input("Dec 8, 1985"); QRegularExpressionMatch match = re.match(input, 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // true bool hasPartialMatch = match.hasPartialMatch(); // false //! [16] } { //! [17] QRegularExpression re("abc\\w+X|def"); QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // true bool hasPartialMatch = match.hasPartialMatch(); // false QString captured = match.captured(0); // captured == "def" //! [17] } { //! [18] QRegularExpression re("abc\\w+X|defY"); QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpression::PartialPreferCompleteMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true QString captured = match.captured(0); // captured == "abcdef" //! [18] } { //! [19] QRegularExpression re("abc|ab"); QRegularExpressionMatch match = re.match("ab", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [19] } { //! [20] QRegularExpression re("abc(def)?"); QRegularExpressionMatch match = re.match("abc", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [20] } { //! [21] QRegularExpression re("(abc)*"); QRegularExpressionMatch match = re.match("abc", 0, QRegularExpression::PartialPreferFirstMatch); bool hasMatch = match.hasMatch(); // false bool hasPartialMatch = match.hasPartialMatch(); // true //! [21] } { //! [22] QRegularExpression invalidRe("(unmatched|parenthesis"); bool isValid = invalidRe.isValid(); // false //! [22] } { //! [23] QRegularExpression invalidRe("(unmatched|parenthesis"); if (!invalidRe.isValid()) { QString errorString = invalidRe.errorString(); // errorString == "missing )" int errorOffset = invalidRe.patternErrorOffset(); // errorOffset == 22 // ... } //! [23] } { //! [24] QRegularExpression re("^this pattern must match exactly$"); //! [24] } { //! [25] QString p("a .*|pattern"); QRegularExpression re("\\A(?:" + p + ")\\z"); // re matches exactly the pattern string p //! [25] } { //! [26] QString escaped = QRegularExpression::escape("a(x) = f(x) + g(x)"); // escaped == "a\\(x\\)\\ \\=\\ f\\(x\\)\\ \\+\\ g\\(x\\)" //! [26] } { QString name; QString nickname; //! [27] QString pattern = "(" + QRegularExpression::escape(name) + "|" + QRegularExpression::escape(nickname) + ")"; QRegularExpression re(pattern); //! [27] } { QString string; QRegularExpression re; //! [28] QRegularExpressionMatch match = re.match(string); for (int i = 0; i <= match.lastCapturedIndex(); ++i) { QString captured = match.captured(i); // ... } //! [28] } { //! [29] QRegularExpression re("(\\d\\d) (?<name>\\w+)"); QRegularExpressionMatch match = re.match("23 Jordan"); if (match.hasMatch()) { QString number = match.captured(1); // first == "23" QString name = match.captured("name"); // name == "Jordan" } //! [29] } { //! [30] // extracts the words QRegularExpression re("(\\w+)"); QString subject("the quick fox"); QRegularExpressionMatchIterator i = re.globalMatch(subject); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); // ... } //! [30] } }
void syntax_highlighter::highlightBlock(const QString &text) { m_current_block = text; for (const auto& rule : m_multi_rules) { // Search for all the matching strings QRegularExpressionMatchIterator iter = rule.expression.globalMatch(m_current_block); // Iterate through the matching strings while (iter.hasNext()) { // Apply formats to their respective found groups QRegularExpressionMatch match = iter.next(); for (int i = 0; i <= match.lastCapturedIndex(); i++) { setFormat(match.capturedStart(i), match.capturedLength(i), rule.formats[i]); } } } for (const auto& rule : m_rules) { for (const auto& expression : rule.expressions) { // Search for all the matching strings QRegularExpressionMatchIterator iter = expression.globalMatch(m_current_block); bool contains_group = expression.captureCount() > 0; // Iterate through the matching strings while (iter.hasNext()) { // Apply format to the matching string QRegularExpressionMatch match = iter.next(); if (contains_group) { setFormat(match.capturedStart(1), match.capturedLength(1), rule.format); } else { setFormat(match.capturedStart(), match.capturedLength(), rule.format); } } } } for (const auto& rule : m_comment_rules) { int comment_start = 0; // Current comment's start position in the text block int comment_end = 0; // Current comment's end position in the text block int comment_length = 0; // Current comment length // We assume we end outside a comment until we know better setCurrentBlockState(block_state::ended_outside_comment); // Search for the first comment in this block if we start outside or don't want to search for multiline comments if (!rule.multi_line || previousBlockState() != block_state::ended_inside_comment) { comment_start = m_current_block.indexOf(rule.start_expression); } // Set format for the rest of this block/line if (!rule.multi_line) { comment_length = m_current_block.length() - comment_start; setFormat(comment_start, comment_length, rule.format); break; } // Format all comments in this block (if they exist) while (comment_start >= 0) { // Search for end of comment in the remaining text QRegularExpressionMatch match = rule.end_expression.match(m_current_block, comment_start); comment_end = match.capturedStart(); match.captured(1); if (comment_end == -1) { // We end inside a comment and want to format the entire remaining text setCurrentBlockState(block_state::ended_inside_comment); comment_length = m_current_block.length() - comment_start; } else { // We found the end of the comment so we need to go another round comment_length = comment_end - comment_start + match.capturedLength(); } // Set format for this text segment setFormat(comment_start, comment_length, rule.format); // Search for the next comment comment_start = m_current_block.indexOf(rule.start_expression, comment_start + comment_length); } } }
void playground(QApplication& a) { std::vector<int> l1 = { 0,1,3,6,9,11 }; auto fromItem = std::upper_bound(l1.begin(), l1.end(), 2 , [](const auto &a, const auto &b) { return a > b; }); return; TextColorize::List _coloredTextParts; auto match = [&_coloredTextParts](const QString& text, Part::List& parts) { QRegularExpression::PatternOptions options; /*if (tc.caseSensitive == false) options |= QRegularExpression::PatternOption::CaseInsensitiveOption; */ QString rePattern; foreach(TextColorize ctp, _coloredTextParts) { QString pattern; if (ctp.caseSensitive == false) pattern += "(?i)"; pattern += ctp.text; pattern.prepend("(").append(")"); if(ctp.wordOnly) pattern.prepend("(?:^|[^\\w])").append("(?:[^\\w]|$)"); rePattern += "|" + pattern; } rePattern = rePattern.mid(1); QRegularExpression re(rePattern, options); QRegularExpressionMatchIterator it = re.globalMatch(text); int nonMatchedStart = 0; bool hasMatches = it.hasNext(); while (it.hasNext()) { QRegularExpressionMatch match = it.next(); int matchedGroup = match.lastCapturedIndex(); while (match.capturedTexts().at(matchedGroup).length() && --matchedGroup); qDebug() << match.capturedTexts() << " - " << match.capturedView() << " - " << match.hasPartialMatch() << " - " << matchedGroup; int nonMatechedEnd = match.capturedStart(0); int nonMatchedLength = nonMatechedEnd - nonMatchedStart; //auto& ct = _coloredTextParts[match.lastCapturedIndex() - 1]; auto& ct = _coloredTextParts[0]; if (nonMatchedLength) ;// parts.push_back({ text.mid(nonMatchedStart, nonMatchedLength), nullptr }); parts.push_back({ text.mid(match.capturedStart(0), match.capturedLength(0)), match.lastCapturedIndex() }); nonMatchedStart = match.capturedEnd(0); } if (nonMatchedStart < text.length()) parts.push_back({ text.mid(nonMatchedStart), false }); return hasMatches; };
bool checkSystemInstallation(QString& parVboxDefaultMachineFolder) { QString buttonContinueText = QCoreApplication::translate("'Continue-anyway'-Button of a shown warning", "Continue anyway"); size_t memorySize = getMemorySize( ); qint64 freeMemoryInMb = memorySize / (1024 * 1024); // currently not needed: //ILOG("Total Physical RAM size: " + QString::number(freeMemoryInMb) + " MB"); //qint64 freeSpace = getFreeDiskSpace(parInstallPath); //ILOG("Free space on disk containing '" + parInstallPath + "': " + QString::number(freeSpace) + " Bytes"); int availableRamNeededInMB; if (RunningOnWindows()) availableRamNeededInMB = 1024 * 3; else availableRamNeededInMB = 1024 * 2; if (freeMemoryInMb < availableRamNeededInMB) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); QString message = QCoreApplication::translate("check available resources", "This computer has to low memory(%1 MegaByte) for the PrivacyMachine to work properly (highly recommended: %2 MegaByte)."); message = message.arg(QString::number(freeMemoryInMb), QString::number(availableRamNeededInMB)); msgBox.setStandardButtons(QMessageBox::Abort | QMessageBox::Ignore); msgBox.button(QMessageBox::Ignore)->setText(buttonContinueText); msgBox.setText(message); int ret = msgBox.exec(); if (ret != QMessageBox::Ignore) return false; else ILOG("User pressed Button 'Continue Anyway' while memory check"); } bool hasVirtualization = CpuFeatures::Virtualization(); if (!hasVirtualization) { IERR("Hardware Virtualisation Support is not available"); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Critical); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); msgBox.setTextFormat(Qt::RichText); // this is what makes the links clickable QString message = QCoreApplication::translate("check available resources", "The Hardware Virtualization Support for the CPU is not enabled (or does not exist on very old computers). Please reboot to enter your BIOS and enable an option called like Virtualization, VT-x, AMD-V or AMD-SVM"); message += "<br>"; message += "<div style=\"text-align:center\">"; message += "<a href='http://www.howtogeek.com/213795/how-to-enable-intel-vt-x-in-your-computers-bios-or-uefi-firmware/'>Explanation on howtogeek.com</a>"; message += "</div>"; msgBox.setText(message); msgBox.exec(); return false; } bool vboxInstalled; QString vboxCommand; QString vboxVersion; bool vboxExtensionPackInstalled; determineVirtualBoxInstallation(vboxInstalled, vboxCommand, vboxVersion, parVboxDefaultMachineFolder, vboxExtensionPackInstalled); if (!vboxInstalled) { IERR("VirtualBox is not installed"); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Critical); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); msgBox.setTextFormat(Qt::RichText); // this is what makes the links clickable QString message = QCoreApplication::translate("check of software dependencies", "VirtualBox from Oracle is not installed, please download it directly from:"); message += "<br>"; message += "<div style=\"text-align:center\">"; message += "<a href='https://www.virtualbox.org'>https://www.virtualbox.org</a>"; message += "</div>"; msgBox.setText(message); msgBox.exec(); return false; } if (!vboxExtensionPackInstalled) { IERR("ExtensionPack of VirtualBox is not installed"); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Critical); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); msgBox.setTextFormat(Qt::RichText); // this is what makes the links clickable QString messagePart1 = QCoreApplication::translate("check of software dependencies", "The 'Extension Pack' for VirtualBox is not installed, please download it directly from:"); messagePart1 += "<br>"; messagePart1 += "<div style=\"text-align:center\">"; messagePart1 += "<a href='https://www.virtualbox.org/wiki/Downloads'>https://www.virtualbox.org/wiki/Downloads</a>"; messagePart1 += "</div>"; QString messagePart2 = QCoreApplication::translate("check of software dependencies", "Install the downloaded File 'Oracle_VM_VirtualBox_Extension_Pack-[CurrentVersion].vbox-extpack' with a Double-Click (it will be opened by VirtualBox)"); msgBox.setText(messagePart1 + "<br><br>" + messagePart2); msgBox.exec(); return false; } // We only support the VirtualBox-Versions supported by Oracle: One main and one legacy version // @Debian-Users: Sorry, but VirtualBox is not maintained any more: <https://www.debian.org/security/2016/dsa-3699> // // from <https://www.virtualbox.org/wiki/Download_Old_Builds> // i.e. Actual Version of VirtualBox-Stable : 5.0.28 (<StableMajor>.<StableMinor>.<StableBugfix>) // i.e. Actual Version of VirtualBox-Current: 5.1.8 (<CurrentMajor>.<CurrentMinor>.<CurrentBugfix>) // -> 5.0.28: ok // -> 5.0.29: ok, log warning // -> 5.0.1: show warning: too old // -> 5.1.8: ok // -> 5.1.9: ok, log warning // -> 5.1.1: show warning: too old // -> 5.2.1: show warning: unsupported int StableMajor = 5; int StableMinor = 0; int StableBugfix = 28; int CurrentMajor = 5; int CurrentMinor = 1; int CurrentBugfix = 8; // Supported Versions to show User i.e. "5.0.* + 5.1.*" QString supportedVersions; supportedVersions += QString::number(StableMajor); supportedVersions += "."; supportedVersions += QString::number(StableMinor); supportedVersions += ".* "; supportedVersions += QString::number(CurrentMajor); supportedVersions += "."; supportedVersions += QString::number(CurrentMinor); // the current version contains the subversion revision i.e.: 5.0.28r111378 ILOG("installed VirtualBox version: " + vboxVersion); QRegularExpression regExpVboxVersion("^(\\d+)\\.(\\d+)\\.(\\d+).*$", QRegularExpression::MultilineOption); QRegularExpressionMatch match; bool showVersionUnsupported = false; bool showVersionToOld = false; bool showVersionToNew = false; QString vboxVersionStripped = vboxVersion; match = regExpVboxVersion.match(vboxVersion); if (match.lastCapturedIndex() == 3) { vboxVersionStripped = match.captured(1) + "." + match.captured(2) + "." + match.captured(3); if (match.captured(1).toInt() == StableMajor && match.captured(2).toInt() == StableMinor ) { // VirtualBox-Stable detected if (match.captured(3).toInt() < StableBugfix) { showVersionToOld = true; } if (match.captured(3).toInt() > StableBugfix) { IWARN("Currently installed Bugfix-Version of VirtualBox-Stable is newer than the Verion tested by the PrivacyMachine-Team"); } } else if (match.captured(1).toInt() == CurrentMajor && match.captured(2).toInt() == CurrentMinor ) { // VirtualBox-Current detected if (match.captured(3).toInt() < CurrentBugfix) { showVersionToOld = true; } if (match.captured(3).toInt() > CurrentBugfix) { IWARN("Currently installed Bugfix-Version of VirtualBox-Current is newer than the Verion tested by the PrivacyMachine-Team"); } } else if (match.captured(1).toInt() == CurrentMajor && match.captured(2).toInt() > CurrentMinor ) { // Minor(API?) version is newer IWARN("Currently installed Version of VirtualBox-Current is newer than the Verion tested by the PrivacyMachine-Team"); showVersionToNew = true; } else { IWARN("Unknown version format of virtualbox"); showVersionUnsupported = true; } } else { IWARN("Unknown version format of virtualbox"); showVersionUnsupported = true; } if (showVersionUnsupported) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); QString messageLine1 = QCoreApplication::translate("check of software dependencies", "The currently installed VirtualBox version '%1' is unsupported."); messageLine1 = messageLine1.arg(vboxVersionStripped); QString messageLine2 = QCoreApplication::translate("check of software dependencies", "Currently supported versions are: %1"); messageLine2 = messageLine2.arg(supportedVersions); QString message = messageLine1 + "<br>" + messageLine2; msgBox.setStandardButtons(QMessageBox::Abort | QMessageBox::Ignore); msgBox.button(QMessageBox::Ignore)->setText(buttonContinueText); msgBox.setText(message); int ret = msgBox.exec(); if (ret != QMessageBox::Ignore) return false; else IWARN("User pressed Button 'Continue Anyway' while virtualbox version check"); } if (showVersionToNew) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); QString messageLine1 = QCoreApplication::translate("check of software dependencies", "The currently installed VirtualBox version '%1' is newer than the Verion tested by the PrivacyMachine-Team."); messageLine1 = messageLine1.arg(vboxVersionStripped); QString messageLine2 = QCoreApplication::translate("check of software dependencies", "Currently tested versions are: %1"); messageLine2 = messageLine2.arg(supportedVersions); QString message = messageLine1 + "<br>" + messageLine2; msgBox.setStandardButtons(QMessageBox::Abort | QMessageBox::Ignore); msgBox.button(QMessageBox::Ignore)->setText(buttonContinueText); msgBox.setText(message); int ret = msgBox.exec(); if (ret != QMessageBox::Ignore) return false; else IWARN("User pressed Button 'Continue Anyway' while virtualbox version check"); } if (showVersionToOld) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(QApplication::applicationName()+" "+QApplication::applicationVersion()); QString messageLine1 = QCoreApplication::translate("check of software dependencies", "The currently installed VirtualBox version '%1' is too old. Please update VirtualBox to the current version and start the PrivacyMachine again."); messageLine1 = messageLine1.arg(vboxVersionStripped); QString messageLine2; if (RunningOnWindows()) { messageLine2 = "<br><br>" + QCoreApplication::translate("check of software dependencies", "To update VirtualBox: Start it manually from the windows start menu and navigate to the menu inside VirtualBox: File -> Check for Updates"); } QString message = messageLine1 + messageLine2; msgBox.setStandardButtons(QMessageBox::Abort | QMessageBox::Ignore); msgBox.button(QMessageBox::Ignore)->setText(buttonContinueText); msgBox.setText(message); int ret = msgBox.exec(); if (ret != QMessageBox::Ignore) return false; else IWARN("User pressed Button 'Continue Anyway' while virtualbox version check"); } return true; }