// Copyright 2010-2021 The Mumble Developers. All rights reserved. // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file at the root of the // Mumble source tree or at . #include "OverlayConfig.h" #include "Channel.h" #include "Database.h" #include "MainWindow.h" #include "Message.h" #include "NetworkConfig.h" #include "Overlay.h" #include "OverlayPositionableItem.h" #include "OverlayText.h" #include "OverlayUserGroup.h" #include "PathListWidget.h" #include "Screen.h" #include "ServerHandler.h" #include "User.h" #include "GlobalShortcut.h" #include "Global.h" #ifdef Q_OS_WIN # include "../../overlay/overlay_blacklist.h" # include "../../overlay/overlay_launchers.h" # include "../../overlay/overlay_whitelist.h" #endif #include #include #include #include #include #include const QString OverlayConfig::name = QLatin1String("OverlayConfig"); static const int OVERLAYCONFIG_PATH_ROLE = Qt::UserRole; static const int OVERLAYCONFIG_BUILTIN_ROLE = Qt::UserRole + 1; // Hide overlay config for Mac OS X universal builds #if !defined(USE_MAC_UNIVERSAL) static ConfigWidget *OverlayConfigDialogNew(Settings &st) { return new OverlayConfig(st); } static ConfigRegistrar registrarOverlayConfig(6000, OverlayConfigDialogNew); #endif void OverlayConfig::initDisplayFps() { // set up FPS preview qgsFpsPreview.clear(); qgsFpsPreview.setBackgroundBrush(qgvFpsPreview->backgroundBrush()); qgpiFpsDemo = new QGraphicsPixmapItem(); refreshFpsDemo(); qgsFpsPreview.addItem(qgpiFpsDemo); qgpiFpsDemo->show(); qgvFpsPreview->setScene(&qgsFpsPreview); qgvFpsPreview->centerOn(qgpiFpsDemo); qgpiFpsLive = new OverlayPositionableItem(&s.os.qrfFps, true); qgpiFpsLive->setZValue(-2.0f); refreshFpsLive(); } void OverlayConfig::initDisplayClock() { qgpiTimeLive = new OverlayPositionableItem(&s.os.qrfTime, true); qgpiTimeLive->setZValue(-2.0f); refreshTimeLive(); } void OverlayConfig::initDisplay() { // set up overlay preview qgpiScreen = new QGraphicsPixmapItem(); qgpiScreen->setPixmap(qpScreen); qgpiScreen->setOpacity(0.5f); qgpiScreen->setZValue(-10.0f); initDisplayFps(); initDisplayClock(); qgtiInstructions = new QGraphicsTextItem(); qgtiInstructions->setHtml(QString::fromLatin1("
  • %1
  • %2
  • %3
") .arg(tr("To move the users, drag the little red dot."), tr("To resize the users, mouse wheel over a user."), tr("For more options, right click a user."))); qgtiInstructions->setOpacity(1.0f); qgtiInstructions->setZValue(-5.0f); qgtiInstructions->setDefaultTextColor(Qt::white); qgs.clear(); qgs.setSceneRect(QRectF(0, 0, qgpiScreen->pixmap().width(), qgpiScreen->pixmap().height())); qgs.setBackgroundBrush(qgvView->backgroundBrush()); qgs.addItem(qgpiScreen); qgpiScreen->show(); qgs.addItem(qgpiFpsLive); qgpiFpsLive->show(); qgs.addItem(qgpiTimeLive); qgpiTimeLive->show(); oug = new OverlayUserGroup(&s.os); oug->bShowExamples = true; qgs.addItem(oug); oug->show(); qgs.addItem(qgtiInstructions); qgtiInstructions->show(); qgvView->setScene(&qgs); qgvView->installEventFilter(this); } void OverlayConfig::refreshFpsDemo() { bpFpsDemo = OverlayTextLine(QString::fromLatin1("%1").arg(42), s.os.qfFps).createPixmap(s.os.qcFps); qgpiFpsDemo->setPixmap(bpFpsDemo); qgvFpsPreview->centerOn(qgpiFpsDemo); } void OverlayConfig::refreshFpsLive() { if (s.os.bFps) { qgpiFpsLive->setPixmap(bpFpsDemo.scaled(bpFpsDemo.size() * fViewScale)); qgpiFpsLive->setOffset((-bpFpsDemo.qpBasePoint + QPoint(0, bpFpsDemo.iAscent)) * fViewScale); } else { qgpiFpsLive->setPixmap(QPixmap()); } qgpiFpsLive->setItemVisible(s.os.bFps); } void OverlayConfig::refreshTimeLive() { if (s.os.bTime) { bpTimeDemo = OverlayTextLine(QString::fromLatin1("%1").arg(QTime::currentTime().toString()), s.os.qfFps) .createPixmap(s.os.qcFps); qgpiTimeLive->setPixmap(bpTimeDemo.scaled(bpTimeDemo.size() * fViewScale)); qgpiTimeLive->setOffset((-bpTimeDemo.qpBasePoint + QPoint(0, bpTimeDemo.iAscent)) * fViewScale); } else { qgpiTimeLive->setPixmap(QPixmap()); } qgpiTimeLive->setItemVisible(s.os.bTime); } OverlayConfig::OverlayConfig(Settings &st) : ConfigWidget(st), qgpiScreen(nullptr), qgs(), qgsFpsPreview(), qgpiFpsDemo(nullptr), oug(nullptr), qgtiInstructions(nullptr), fViewScale(1.0f) { setupUi(this); qlwPaths->setPathType(PathListWidget::FOLDER); qcbOverlayExclusionMode->insertItem(static_cast< int >(OverlaySettings::LauncherFilterExclusionMode), tr("Launcher Filter")); qcbOverlayExclusionMode->insertItem(static_cast< int >(OverlaySettings::WhitelistExclusionMode), tr("Whitelist")); qcbOverlayExclusionMode->insertItem(static_cast< int >(OverlaySettings::BlacklistExclusionMode), tr("Blacklist")); qcbOverlayExclusionMode->setCurrentIndex(static_cast< int >(OverlaySettings::LauncherFilterExclusionMode)); if (!isInstalled()) { qswOverlayPage->setCurrentWidget(qwOverlayInstall); } else if (needsUpgrade()) { qswOverlayPage->setCurrentWidget(qwOverlayUpgrade); } else { qswOverlayPage->setCurrentWidget(qwOverlayConfig); qpbUninstall->setVisible(supportsInstallableOverlay()); } // Grab a desktop screenshot as background QScreen *screen = qApp->primaryScreen(); if (const QWindow *window = windowHandle()) { screen = window->screen(); } // From Qt's documentation (Qt Widgets screenshot example): // "Although this is unlikely to happen, applications should check for null // pointers since there might be situations in which no screen is connected." if (screen) { qpScreen = screen->grabWindow(0); } if (qpScreen.size().isEmpty()) { qWarning() << __FUNCTION__ << "failed to grab screenshot, falling back."; if (screen) { const QRect desktopSize = screen->geometry(); qpScreen = QPixmap(desktopSize.width(), desktopSize.height()); } else { qpScreen = QPixmap(1280, 720); } qpScreen.fill(Qt::darkGreen); } initDisplay(); // Attach the upgrade button to the install click handler. Currently, the // actions they perform are the same. The distinction is only there to inform // users as to what's actually going on. connect(qpbUpgrade, SIGNAL(clicked()), this, SLOT(on_qpbInstall_clicked())); } void OverlayConfig::updateOverlayExclusionModeState() { OverlaySettings::OverlayExclusionMode exclusionMode = static_cast< OverlaySettings::OverlayExclusionMode >(qcbOverlayExclusionMode->currentIndex()); switch (exclusionMode) { case OverlaySettings::LauncherFilterExclusionMode: qwLaunchers->setHidden(false); qwWhitelist->setHidden(false); qwPaths->setHidden(false); qwBlacklist->setHidden(false); // Show all whitelist items (including built-in items) // in launcher filter mode. for (int i = 0; i < qlwWhitelist->count(); i++) { QListWidgetItem *item = qlwWhitelist->item(i); item->setHidden(false); } break; case OverlaySettings::WhitelistExclusionMode: qwLaunchers->setHidden(true); qwWhitelist->setHidden(false); qwPaths->setHidden(true); qwBlacklist->setHidden(true); // Hide the built-in items when in WhitelistExclusionMode. // They are only considered in launcher filter mode. for (int i = 0; i < qlwWhitelist->count(); i++) { QListWidgetItem *item = qlwWhitelist->item(i); bool isBuiltin = item->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool(); if (isBuiltin) { item->setHidden(true); } else { item->setHidden(false); } } break; case OverlaySettings::BlacklistExclusionMode: qwLaunchers->setHidden(true); qwWhitelist->setHidden(true); qwPaths->setHidden(true); qwBlacklist->setHidden(false); break; } } void OverlayConfig::load(const Settings &r) { s.os = r.os; loadCheckBox(qcbEnable, s.os.bEnable); qcbShowFps->setChecked(s.os.bFps); qcbShowTime->setChecked(s.os.bTime); qgpFps->setEnabled(s.os.bEnable); qcbOverlayExclusionMode->setCurrentIndex(static_cast< int >(s.os.oemOverlayExcludeMode)); // Launchers { qlwLaunchers->clear(); QStringList builtinLaunchers; #ifdef Q_OS_WIN int i = 0; while (overlayLaunchers[i]) { QString str = QLatin1String(overlayLaunchers[i]); builtinLaunchers << str; ++i; } #endif foreach (QString str, builtinLaunchers) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwLaunchers); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(true)); // Use italic for 'default' items. QFont font = qlwiApplication->font(); font.setItalic(true); qlwiApplication->setFont(font); qlwiApplication->setFlags(qlwiApplication->flags() | Qt::ItemIsUserCheckable); if (s.os.qslLaunchersExclude.contains(str)) { qlwiApplication->setCheckState(Qt::Unchecked); } else { qlwiApplication->setCheckState(Qt::Checked); } } foreach (QString str, s.os.qslLaunchers) { if (builtinLaunchers.contains(str)) { continue; } OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwLaunchers); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(false)); } } // Whitelist { qlwWhitelist->clear(); QStringList builtinWhitelist; #ifdef Q_OS_WIN int i = 0; while (overlayWhitelist[i]) { QString str = QLatin1String(overlayWhitelist[i]); builtinWhitelist << str; ++i; } #endif foreach (QString str, builtinWhitelist) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwWhitelist); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(true)); // Use italic for 'default' items. QFont font = qlwiApplication->font(); font.setItalic(true); qlwiApplication->setFont(font); qlwiApplication->setFlags(qlwiApplication->flags() | Qt::ItemIsUserCheckable); if (s.os.qslWhitelistExclude.contains(str)) { qlwiApplication->setCheckState(Qt::Unchecked); } else { qlwiApplication->setCheckState(Qt::Checked); } } foreach (QString str, s.os.qslWhitelist) { if (builtinWhitelist.contains(str)) { continue; } OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwWhitelist); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(false)); } } // Paths { qlwPaths->clear(); foreach (QString str, s.os.qslPaths) { QListWidgetItem *qlwiApplication = new QListWidgetItem(QIcon(), str, qlwPaths); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(false)); } } // Blacklist { qlwBlacklist->clear(); QStringList builtinBlacklist; #ifdef Q_OS_WIN int i = 0; while (overlayBlacklist[i]) { QString str = QLatin1String(overlayBlacklist[i]); builtinBlacklist << str; ++i; } #endif foreach (QString str, builtinBlacklist) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwBlacklist); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(true)); // Use italic for 'default' items. QFont font = qlwiApplication->font(); font.setItalic(true); qlwiApplication->setFont(font); qlwiApplication->setFlags(qlwiApplication->flags() | Qt::ItemIsUserCheckable); if (s.os.qslBlacklistExclude.contains(str)) { qlwiApplication->setCheckState(Qt::Unchecked); } else { qlwiApplication->setCheckState(Qt::Checked); } } foreach (QString str, s.os.qslBlacklist) { if (builtinBlacklist.contains(str)) { continue; } OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(str); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwBlacklist); qlwiApplication->setData(OVERLAYCONFIG_PATH_ROLE, QVariant(str)); qlwiApplication->setData(OVERLAYCONFIG_BUILTIN_ROLE, QVariant(false)); } } initDisplay(); resizeScene(true); update(); } QString OverlayConfig::title() const { return tr("Overlay"); } const QString &OverlayConfig::getName() const { return OverlayConfig::name; } QIcon OverlayConfig::icon() const { return QIcon(QLatin1String("skin:config_osd.png")); } void OverlayConfig::save() const { s.os.bEnable = qcbEnable->isChecked(); s.os.bFps = qcbShowFps->isChecked(); s.os.bTime = qcbShowTime->isChecked(); // Directly save overlay config s.os.oemOverlayExcludeMode = static_cast< OverlaySettings::OverlayExclusionMode >(qcbOverlayExclusionMode->currentIndex()); // Launchers { s.os.qslLaunchers.clear(); s.os.qslLaunchersExclude.clear(); for (int i = 0; i < qlwLaunchers->count(); i++) { bool isBuiltin = (qlwLaunchers->item(i)->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool()); bool isChecked = false; if (isBuiltin) { isChecked = qlwLaunchers->item(i)->checkState() == Qt::Checked; } QString str = qlwLaunchers->item(i)->data(OVERLAYCONFIG_PATH_ROLE).toString(); if (isBuiltin) { if (!isChecked) { s.os.qslLaunchersExclude << str; } } else { s.os.qslLaunchers << str; } } } // Whitelist { s.os.qslWhitelist.clear(); s.os.qslWhitelistExclude.clear(); for (int i = 0; i < qlwWhitelist->count(); i++) { bool isBuiltin = (qlwWhitelist->item(i)->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool()); bool isChecked = false; if (isBuiltin) { isChecked = qlwWhitelist->item(i)->checkState() == Qt::Checked; } QString str = qlwWhitelist->item(i)->data(OVERLAYCONFIG_PATH_ROLE).toString(); if (isBuiltin) { if (!isChecked) { s.os.qslWhitelistExclude << str; } } else { s.os.qslWhitelist << str; } } } // Paths { s.os.qslPaths.clear(); s.os.qslPathsExclude.clear(); for (int i = 0; i < qlwPaths->count(); i++) { bool isBuiltin = (qlwPaths->item(i)->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool()); bool isChecked = false; if (isBuiltin) { isChecked = qlwPaths->item(i)->checkState() == Qt::Checked; } QString str = qlwPaths->item(i)->data(OVERLAYCONFIG_PATH_ROLE).toString(); if (isBuiltin) { if (!isChecked) { s.os.qslPathsExclude << str; } } else { s.os.qslPaths << str; } } } // Blacklist { s.os.qslBlacklist.clear(); s.os.qslBlacklistExclude.clear(); for (int i = 0; i < qlwBlacklist->count(); i++) { bool isBuiltin = (qlwBlacklist->item(i)->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool()); bool isChecked = false; if (isBuiltin) { isChecked = qlwBlacklist->item(i)->checkState() == Qt::Checked; } QString str = qlwBlacklist->item(i)->data(OVERLAYCONFIG_PATH_ROLE).toString(); if (isBuiltin) { if (!isChecked) { s.os.qslBlacklistExclude << str; } } else { s.os.qslBlacklist << str; } } } Global::get().qs->beginGroup(QLatin1String("overlay")); s.os.save(); Global::get().qs->endGroup(); #ifdef Q_OS_WIN // On MS windows force sync so the registry is updated. Global::get().qs->sync(); #endif } void OverlayConfig::accept() const { Global::get().o->forceSettings(); Global::get().o->setActive(s.os.bEnable); } bool OverlayConfig::eventFilter(QObject *obj, QEvent *evt) { if (evt->type() == QEvent::Resize) QMetaObject::invokeMethod(this, "resizeScene", Qt::QueuedConnection); return ConfigWidget::eventFilter(obj, evt); } void OverlayConfig::resizeScene(bool force) { QSize sz = qgvView->viewport()->size(); int ph = qgpiScreen->pixmap().height(); int pw = qgpiScreen->pixmap().width(); if (!force && ((ph == sz.height() && pw <= sz.width()) || (ph <= sz.height() && pw == sz.width()))) { return; } qgpiScreen->setPixmap(qpScreen.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation)); qgs.setSceneRect(QRectF(0, 0, qgpiScreen->pixmap().width(), qgpiScreen->pixmap().height())); fViewScale = static_cast< float >(qgpiScreen->pixmap().height()) / static_cast< float >(qpScreen.height()); refreshFpsLive(); refreshTimeLive(); QFont f = qgtiInstructions->font(); f.setPointSizeF(qgs.sceneRect().height() / 20.0f); qgtiInstructions->setFont(f); qgtiInstructions->setPos(qgs.sceneRect().width() / 20.0f, qgs.sceneRect().height() / 10.0f); qgtiInstructions->setTextWidth(qgs.sceneRect().width() * 18.0f / 20.0f); qgvView->fitInView(qgs.sceneRect(), Qt::KeepAspectRatio); oug->updateLayout(); oug->updateUsers(); qgpiFpsLive->updateRender(); qgpiTimeLive->updateRender(); } void OverlayConfig::on_qlwLaunchers_itemSelectionChanged() { QList< QListWidgetItem * > items = qlwLaunchers->selectedItems(); if (items.isEmpty()) { qpbLaunchersRemove->setEnabled(false); return; } QListWidgetItem *item = items.at(0); bool isBuiltin = item->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool(); if (isBuiltin) { qpbLaunchersRemove->setEnabled(false); } else { qpbLaunchersRemove->setEnabled(true); } } void OverlayConfig::on_qcbOverlayExclusionMode_currentIndexChanged(int) { updateOverlayExclusionModeState(); } void OverlayConfig::on_qpbLaunchersAdd_clicked() { #if defined(Q_OS_WIN) QString file = QFileDialog::getOpenFileName(this, tr("Choose executable"), QString(), QLatin1String("*.exe")); #elif defined(Q_OS_MAC) QString file = QFileDialog::getOpenFileName(this, tr("Choose application"), QString(), QLatin1String("*.app")); #else QString file = QString(); #endif if (!file.isEmpty()) { QString qsAppIdentifier = OverlayAppInfo::applicationIdentifierForPath(file); QStringList qslIdentifiers; for (int i = 0; i < qlwLaunchers->count(); i++) qslIdentifiers << qlwLaunchers->item(i)->data(Qt::UserRole).toString(); if (!qslIdentifiers.contains(qsAppIdentifier)) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(qsAppIdentifier); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, qlwLaunchers); qlwiApplication->setData(Qt::UserRole, QVariant(qsAppIdentifier)); qlwLaunchers->setCurrentItem(qlwiApplication); } } } void OverlayConfig::on_qpbLaunchersRemove_clicked() { int row = qlwLaunchers->currentRow(); if (row != -1) delete qlwLaunchers->takeItem(row); } void OverlayConfig::on_qlwWhitelist_itemSelectionChanged() { QList< QListWidgetItem * > items = qlwWhitelist->selectedItems(); if (items.isEmpty()) { qpbWhitelistRemove->setEnabled(false); return; } QListWidgetItem *item = items.at(0); bool isBuiltin = item->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool(); if (isBuiltin) { qpbWhitelistRemove->setEnabled(false); } else { qpbWhitelistRemove->setEnabled(true); } } void OverlayConfig::addWhitelistPath(const QString &path) { QString qsAppIdentifier = OverlayAppInfo::applicationIdentifierForPath(path); QListWidget *sel = qlwWhitelist; QStringList qslIdentifiers; for (int i = 0; i < sel->count(); i++) qslIdentifiers << sel->item(i)->data(Qt::UserRole).toString(); if (!qslIdentifiers.contains(qsAppIdentifier)) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(qsAppIdentifier); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, sel); qlwiApplication->setData(Qt::UserRole, QVariant(qsAppIdentifier)); sel->setCurrentItem(qlwiApplication); } } void OverlayConfig::on_qpbWhitelistAdd_clicked() { #if defined(Q_OS_WIN) QString file = QFileDialog::getOpenFileName(this, tr("Choose executable"), QString(), QLatin1String("*.exe")); #elif defined(Q_OS_MAC) QString file = QFileDialog::getOpenFileName(this, tr("Choose application"), QString(), QLatin1String("*.app")); #else QString file = QString(); #endif if (!file.isEmpty()) { addWhitelistPath(file); } } void OverlayConfig::on_qpbWhitelistRemove_clicked() { QListWidget *sel = qlwWhitelist; int row = sel->currentRow(); if (row != -1) delete sel->takeItem(row); } void OverlayConfig::on_qlwPaths_itemSelectionChanged() { QList< QListWidgetItem * > items = qlwPaths->selectedItems(); if (items.isEmpty()) { qpbPathsRemove->setEnabled(false); return; } QListWidgetItem *item = items.at(0); bool isBuiltin = item->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool(); if (isBuiltin) { qpbPathsRemove->setEnabled(false); } else { qpbPathsRemove->setEnabled(true); } } void OverlayConfig::on_qpbPathsAdd_clicked() { QString existingPath = QFileDialog::getExistingDirectory(this, tr("Choose path")); QString dir = QDir::toNativeSeparators(existingPath); QListWidget *sel = qlwPaths; QStringList qslIdentifiers; for (int i = 0; i < sel->count(); i++) qslIdentifiers << sel->item(i)->data(Qt::UserRole).toString(); if (!dir.isEmpty() && !qslIdentifiers.contains(dir)) { QListWidgetItem *qlwiPath = new QListWidgetItem(QIcon(), dir, sel); qlwiPath->setData(Qt::UserRole, QVariant(dir)); sel->setCurrentItem(qlwiPath); } } void OverlayConfig::on_qpbPathsRemove_clicked() { int row = qlwPaths->currentRow(); if (row != -1) delete qlwPaths->takeItem(row); } void OverlayConfig::on_qlwBlacklist_itemSelectionChanged() { QList< QListWidgetItem * > items = qlwBlacklist->selectedItems(); if (items.isEmpty()) { qpbBlacklistRemove->setEnabled(false); return; } QListWidgetItem *item = items.at(0); bool isBuiltin = item->data(OVERLAYCONFIG_BUILTIN_ROLE).toBool(); if (isBuiltin) { qpbBlacklistRemove->setEnabled(false); } else { qpbBlacklistRemove->setEnabled(true); } } void OverlayConfig::on_qpbBlacklistAdd_clicked() { #if defined(Q_OS_WIN) QString file = QFileDialog::getOpenFileName(this, tr("Choose executable"), QString(), QLatin1String("*.exe")); #elif defined(Q_OS_MAC) QString file = QFileDialog::getOpenFileName(this, tr("Choose application"), QString(), QLatin1String("*.app")); #else QString file = QString(); #endif if (!file.isEmpty()) { QString qsAppIdentifier = OverlayAppInfo::applicationIdentifierForPath(file); QListWidget *sel = qlwBlacklist; QStringList qslIdentifiers; for (int i = 0; i < sel->count(); i++) qslIdentifiers << sel->item(i)->data(Qt::UserRole).toString(); if (!qslIdentifiers.contains(qsAppIdentifier)) { OverlayAppInfo oai = OverlayAppInfo::applicationInfoForId(qsAppIdentifier); QListWidgetItem *qlwiApplication = new QListWidgetItem(oai.qiIcon, oai.qsDisplayName, sel); qlwiApplication->setData(Qt::UserRole, QVariant(qsAppIdentifier)); sel->setCurrentItem(qlwiApplication); } } } void OverlayConfig::on_qpbBlacklistRemove_clicked() { QListWidget *sel = qlwBlacklist; int row = sel->currentRow(); if (row != -1) delete sel->takeItem(row); } void OverlayConfig::on_qcbEnable_stateChanged(int state) { qgpFps->setEnabled(state == Qt::Checked); } void OverlayConfig::on_qpbInstall_clicked() { qpbInstall->setEnabled(false); if (installFiles()) { qswOverlayPage->setCurrentWidget(qwOverlayConfig); } qpbInstall->setEnabled(true); } void OverlayConfig::on_qpbUninstall_clicked() { qpbUninstall->setEnabled(false); if (uninstallFiles()) { qswOverlayPage->setCurrentWidget(qwOverlayInstall); } qpbUninstall->setEnabled(true); } void OverlayConfig::on_qcbShowFps_stateChanged(int state) { Q_UNUSED(state); s.os.bFps = qcbShowFps->isChecked(); refreshFpsLive(); } void OverlayConfig::on_qcbShowTime_stateChanged(int state) { Q_UNUSED(state); s.os.bTime = qcbShowTime->isChecked(); refreshTimeLive(); } void OverlayConfig::on_qpbFpsFont_clicked() { bool ok; QFont new_font = QFontDialog::getFont(&ok, s.os.qfFps); if (ok) { s.os.qfFps = new_font; refreshFpsDemo(); refreshFpsLive(); refreshTimeLive(); } } void OverlayConfig::on_qpbFpsColor_clicked() { QColor color = QColorDialog::getColor(s.os.qcFps); if (color.isValid()) { s.os.qcFps = color; refreshFpsDemo(); refreshFpsLive(); refreshTimeLive(); } } void OverlayConfig::on_qpbLoadPreset_clicked() { QString fn = QFileDialog::getOpenFileName(this, tr("Load Overlay Presets"), QDir::homePath(), tr("Mumble overlay presets (*.mumblelay)")); if (fn.isEmpty()) { return; } QSettings qs(fn, QSettings::IniFormat); OverlaySettings load_preset; qs.beginGroup(QLatin1String("overlay")); load_preset.load(&qs); qs.endGroup(); #ifdef Q_OS_WIN load_preset.qslLaunchers = s.os.qslLaunchers; load_preset.qslLaunchersExclude = s.os.qslLaunchersExclude; load_preset.qslWhitelist = s.os.qslWhitelist; load_preset.qslWhitelistExclude = s.os.qslWhitelistExclude; load_preset.qslPaths = s.os.qslPaths; load_preset.qslPathsExclude = s.os.qslPathsExclude; load_preset.qslBlacklist = s.os.qslBlacklist; load_preset.qslBlacklistExclude = s.os.qslBlacklistExclude; #endif load_preset.bEnable = s.os.bEnable; s.os = load_preset; load(s); } void OverlayConfig::on_qpbSavePreset_clicked() { QString fn = QFileDialog::getSaveFileName(this, tr("Save Overlay Presets"), QDir::homePath(), tr("Mumble overlay presets (*.mumblelay)")); if (fn.isEmpty()) { return; } QSettings qs(fn, QSettings::IniFormat); if (!qs.isWritable()) { qWarning() << __FUNCTION__ << "preset save file" << fn << "is not writable!"; return; } qs.beginGroup(QLatin1String("overlay")); s.os.save(&qs); qs.remove(QLatin1String("enable")); qs.remove(QLatin1String("usewhitelist")); qs.remove(QLatin1String("blacklist")); qs.remove(QLatin1String("whitelist")); qs.remove(QLatin1String("enablelauncherfilter")); qs.remove(QLatin1String("launchers")); qs.endGroup(); }