#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 #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); // Version auto versionInfo = layout.emplace("Version"); { auto vbox = versionInfo.emplace(); auto version = Version::instance(); auto label = vbox.emplace(version.buildString() + "
" + version.runningString()); label->setOpenExternalLinks(true); label->setTextInteractionFlags(Qt::TextBrowserInteraction); } // 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", "https://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"); addLicense(form.getElement(), "magic_enum", "https://github.com/Neargye/magic_enum", ":/licenses/magic_enum.txt"); addLicense(form.getElement(), "semver", "https://github.com/Neargye/semver", ":/licenses/semver.txt"); addLicense(form.getElement(), "miniaudio", "https://github.com/mackron/miniaudio", ":/licenses/miniaudio.txt"); #ifdef CHATTERINO_HAVE_PLUGINS addLicense(form.getElement(), "lua", "https://lua.org", ":/licenses/lua.txt"); addLicense(form.getElement(), "Fluent icons", "https://github.com/microsoft/fluentui-system-icons", ":/licenses/fluenticons.txt"); #endif #ifdef CHATTERINO_WITH_CRASHPAD addLicense(form.getElement(), "sentry-crashpad", "https://github.com/getsentry/crashpad", ":/licenses/crashpad.txt"); #endif } // 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); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // Default encoding of QTextStream is already UTF-8 #else stream.setCodec("UTF-8"); #endif 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(); } } } 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, BaseWindow::DisableLayoutSave}, 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