#include "AboutPage.hpp" #include "common/Modes.hpp" #include "common/QLogging.hpp" #include "common/Version.hpp" #include "util/LayoutCreator.hpp" #include "util/RemoveScrollAreaBackground.hpp" #include "widgets/BasePopup.hpp" #include "widgets/helper/SignalLabel.hpp" #include #include #include #include #include #include #define PIXMAP_WIDTH 500 #define LINK_CHATTERINO_WIKI "https://wiki.chatterino.com" #define LINK_DONATE "https://streamelements.com/fourtf/tip" #define LINK_CHATTERINO_FEATURES "https://chatterino.com/#features" #define LINK_CHATTERINO_DISCORD "https://discord.gg/7Y5AYhAK4z" namespace chatterino { AboutPage::AboutPage() { LayoutCreator layoutCreator(this); auto scroll = layoutCreator.emplace(); auto widget = scroll.emplaceScrollAreaWidget(); removeScrollAreaBackground(scroll.getElement(), widget.getElement()); auto layout = widget.setLayoutType(); { QPixmap pixmap; pixmap.load(":/settings/aboutlogo.png"); auto logo = layout.emplace().assign(&this->logo_); logo->setPixmap(pixmap); if (pixmap.width() != 0) { logo->setFixedSize(PIXMAP_WIDTH, PIXMAP_WIDTH * pixmap.height() / pixmap.width()); } logo->setScaledContents(true); // this does nothing // QPalette palette; // palette.setColor(QPalette::Text, Qt::white); // palette.setColor(QPalette::Link, "#a5cdff"); // palette.setColor(QPalette::LinkVisited, "#a5cdff"); /*auto xd = layout.emplace("Created by..."); { auto created = xd.emplace(); { created->setText("Created by fourtf
" "with big help from pajlada."); created->setTextFormat(Qt::RichText); created->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByKeyboard); created->setOpenExternalLinks(true); // created->setPalette(palette); } // auto github = xd.emplace(); // { // github->setText( // "Chatterino on // Github"); // github->setTextFormat(Qt::RichText); // github->setTextInteractionFlags(Qt::TextBrowserInteraction | // Qt::LinksAccessibleByKeyboard | // Qt::LinksAccessibleByKeyboard); // github->setOpenExternalLinks(true); // // github->setPalette(palette); // } }*/ // Version auto versionInfo = layout.emplace("Version"); { auto version = Version::instance(); QString osInfo = QSysInfo::prettyProductName() + ", kernel: " + QSysInfo::kernelVersion(); if (version.isFlatpak()) { osInfo += ", running from Flatpak"; } QString commitHashLink = QString("%1") .arg(version.commitHash()); QString nightlyBuildInfo; if (Modes::instance().isNightly) { nightlyBuildInfo = QString(", built on %1").arg(version.dateOfBuild()); } QString supportedOS; if (!version.isSupportedOS()) { supportedOS = "(unsupported OS)"; } QString text = QString("%1 (commit %2%3) running on %4 %5") .arg(version.fullVersion(), commitHashLink, nightlyBuildInfo, osInfo, supportedOS); auto versionLabel = versionInfo.emplace(text); versionLabel->setOpenExternalLinks(true); versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); } // About Chatterino auto aboutChatterino = layout.emplace("About Chatterino..."); { auto l = aboutChatterino.emplace(); // clang-format off l.emplace("Chatterino Wiki can be found here")->setOpenExternalLinks(true); l.emplace("All about Chatterino's features")->setOpenExternalLinks(true); l.emplace("Join the official Chatterino Discord")->setOpenExternalLinks(true); // clang-format on } // Licenses auto licenses = layout.emplace("Open source software used..."); { auto form = licenses.emplace(); addLicense(form.getElement(), "Qt Framework", "https://www.qt.io", ":/licenses/qt_lgpl-3.0.txt"); addLicense(form.getElement(), "Boost", "https://www.boost.org/", ":/licenses/boost_boost.txt"); addLicense(form.getElement(), "LibCommuni", "https://github.com/communi/libcommuni", ":/licenses/libcommuni_BSD3.txt"); addLicense(form.getElement(), "OpenSSL", "https://www.openssl.org/", ":/licenses/openssl.txt"); addLicense(form.getElement(), "RapidJson", "http://rapidjson.org/", ":/licenses/rapidjson.txt"); addLicense(form.getElement(), "Pajlada/Settings", "https://github.com/pajlada/settings", ":/licenses/pajlada_settings.txt"); addLicense(form.getElement(), "Pajlada/Signals", "https://github.com/pajlada/signals", ":/licenses/pajlada_signals.txt"); addLicense(form.getElement(), "Websocketpp", "https://www.zaphoyd.com/websocketpp/", ":/licenses/websocketpp.txt"); #ifndef NO_QTKEYCHAIN addLicense(form.getElement(), "QtKeychain", "https://github.com/frankosterfeld/qtkeychain", ":/licenses/qtkeychain.txt"); #endif addLicense(form.getElement(), "lrucache", "https://github.com/lamerman/cpp-lru-cache", ":/licenses/lrucache.txt"); } // Attributions auto attributions = layout.emplace("Attributions..."); { auto l = attributions.emplace(); // clang-format off l.emplace("Twemoji emojis provided by Twitter's Twemoji")->setOpenExternalLinks(true); l.emplace("Facebook emojis provided by Facebook")->setOpenExternalLinks(true); l.emplace("Apple emojis provided by Apple")->setOpenExternalLinks(true); l.emplace("Google emojis provided by Google")->setOpenExternalLinks(true); l.emplace("Emoji datasource provided by Cal Henderson" "(show license)")->setOpenExternalLinks(true); // clang-format on } // Contributors auto contributors = layout.emplace("Contributors"); { auto l = contributors.emplace(); QFile contributorsFile(":/contributors.txt"); contributorsFile.open(QFile::ReadOnly); QTextStream stream(&contributorsFile); stream.setCodec("UTF-8"); QString line; while (stream.readLineInto(&line)) { if (line.isEmpty() || line.startsWith('#')) { continue; } QStringList contributorParts = line.split("|"); if (contributorParts.size() != 4) { qCDebug(chatterinoWidget) << "Missing parts in line" << line; continue; } QString username = contributorParts[0].trimmed(); QString url = contributorParts[1].trimmed(); QString avatarUrl = contributorParts[2].trimmed(); QString role = contributorParts[3].trimmed(); auto *usernameLabel = new QLabel("" + username + ""); usernameLabel->setOpenExternalLinks(true); auto *roleLabel = new QLabel(role); auto contributorBox2 = l.emplace(); const auto addAvatar = [&avatarUrl, &contributorBox2] { if (!avatarUrl.isEmpty()) { QPixmap avatarPixmap; avatarPixmap.load(avatarUrl); auto avatar = contributorBox2.emplace(); avatar->setPixmap(avatarPixmap); avatar->setFixedSize(64, 64); avatar->setScaledContents(true); } }; const auto addLabels = [&contributorBox2, &usernameLabel, &roleLabel] { auto labelBox = new QVBoxLayout(); contributorBox2->addLayout(labelBox); labelBox->addWidget(usernameLabel); labelBox->addWidget(roleLabel); }; addLabels(); addAvatar(); } } } auto buildInfo = QStringList(); buildInfo += "Qt " QT_VERSION_STR; #ifdef USEWINSDK buildInfo += "Windows SDK"; #endif #ifdef _MSC_FULL_VER buildInfo += "MSVC " + QString::number(_MSC_FULL_VER, 10); #endif auto buildText = QString("Built with " + buildInfo.join(", ")); layout.emplace(buildText); layout->addStretch(1); } void AboutPage::addLicense(QFormLayout *form, const QString &name, const QString &website, const QString &licenseLink) { auto *a = new QLabel("" + name + ""); a->setOpenExternalLinks(true); auto *b = new QLabel("show license"); QObject::connect( b, &QLabel::linkActivated, [parent = this, name, licenseLink] { auto window = new BasePopup(BaseWindow::Flags::EnableCustomFrame, parent); window->setWindowTitle("Chatterino - License for " + name); window->setAttribute(Qt::WA_DeleteOnClose); auto layout = new QVBoxLayout(); auto *edit = new QTextEdit; QFile file(licenseLink); file.open(QIODevice::ReadOnly); edit->setText(file.readAll()); edit->setReadOnly(true); layout->addWidget(edit); window->getLayoutContainer()->setLayout(layout); window->show(); }); form->addRow(a, b); } } // namespace chatterino