-
this allows to handle the part that requires the deleteLater within the MediaLib class, this will allow us to handle the lifecycle of MediaLib like the other singletons
3855b461
mainctx.cpp 28.70 KiB
/*****************************************************************************
* main_interface.cpp : Main interface
****************************************************************************
* Copyright (C) 2006-2011 VideoLAN and AUTHORS
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Baptiste Kempf <jb@videolan.org>
* Ilkka Ollakka <ileoo@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "qt.hpp"
#include "mainctx.hpp"
#include "mainctx_submodels.hpp"
#include "medialibrary/mlhelper.hpp"
#include "compositor.hpp"
#include "util/renderer_manager.hpp"
#include "util/csdbuttonmodel.hpp"
#include "util/workerthreadset.hpp"
#include "widgets/native/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
#include "util/qt_dirs.hpp" // toNativeSeparators
#include "util/color_scheme_model.hpp"
#include "widgets/native/interface_widgets.hpp" // bgWidget, videoWidget
#include "playlist/playlist_controller.hpp"
#include "player/player_controller.hpp"
#include "dialogs/dialogs_provider.hpp"
#include "dialogs/systray/systray.hpp"
#include "videosurface.hpp"
#include "menus/menus.hpp" // Menu creation
#include "dialogs/toolbar/controlbar_profile_model.hpp"
#include "dialogs/help/help.hpp"
#include <QKeyEvent>
#include <QUrl>
#include <QDate>
#include <QMimeData>
#include <QQmlProperty>
#include <QQmlContext>
#include <QWindow>
#include <QScreen>
#include <QOperatingSystemVersion>
#ifdef _WIN32
#include <QFileInfo>
#endif
#include <vlc_interface.h>
#define VLC_REFERENCE_SCALE_FACTOR 96.
using namespace vlc::playlist;
// #define DEBUG_INTF
/* Callback prototypes */
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
vlc_value_t old_val, vlc_value_t new_val, void *param );
static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
vlc_value_t old_val, vlc_value_t new_val, void *param );
static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
vlc_value_t old_val, vlc_value_t new_val, void *param );
static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
vlc_value_t old_val, vlc_value_t new_val,
void *param );
const QEvent::Type MainCtx::ToolbarsNeedRebuild =
(QEvent::Type)QEvent::registerEventType();
namespace
{
template <typename T>
T loadVLCOption(vlc_object_t *obj, const char *name);
template <>
int loadVLCOption<int>(vlc_object_t *obj, const char *name)
{
return var_InheritInteger(obj, name);
}
template <>
float loadVLCOption<float>(vlc_object_t *obj, const char *name)
{
return var_InheritFloat(obj, name);
}
template <>
bool loadVLCOption<bool>(vlc_object_t *obj, const char *name)
{
return var_InheritBool(obj, name);
}
}
MainCtx::MainCtx(qt_intf_t *_p_intf)
: p_intf(_p_intf)
, m_csdButtonModel {std::make_unique<CSDButtonModel>(this, this)}
{
/**
* Configuration and settings
* Pre-building of interface
**/
settings = getSettings();
m_colorScheme = new ColorSchemeModel(this);
m_sort = new SortCtx(this);
m_search = new SearchCtx(this);
// getOSInfo();
QOperatingSystemVersion currentOS = QOperatingSystemVersion::current();
switch (currentOS.type()) {
case QOperatingSystemVersion::OSType::Windows:
m_osName = Windows;
break;
default:
m_osName = Unknown;
break;
}
m_osVersion = (currentOS.majorVersion());
loadPrefs(false);
loadFromSettingsImpl(false);
/* Get the available interfaces */
m_extraInterfaces = new VLCVarChoiceModel(VLC_OBJECT(p_intf->intf), "intf-add", this);
vlc_medialibrary_t* ml = vlc_ml_instance_get( p_intf );
b_hasMedialibrary = (ml != NULL);
if (b_hasMedialibrary) {
m_medialib = new MediaLib(p_intf, p_intf->p_mainPlaylistController);
}
/* Controlbar Profile Model Creation */
m_controlbarProfileModel = new ControlbarProfileModel(p_intf->mainSettings, this);
m_dialogFilepath = getSettings()->value( "filedialog-path", QVLCUserDir( VLC_HOME_DIR ) ).toString();
QString platformName = QGuiApplication::platformName();
b_hasWayland = platformName.startsWith(QLatin1String("wayland"), Qt::CaseInsensitive);
/*********************************
* Create the Systray Management *
*********************************/
//postpone systray initialisation to speedup starting time
QMetaObject::invokeMethod(this, &MainCtx::initSystray, Qt::QueuedConnection);
/*************************************************************
* Connect the input manager to the GUI elements it manages *
* Beware initSystray did some connects on input manager too *
*************************************************************/
/**
* Connects on nameChanged()
* Those connects are different because options can impeach them to trigger.
**/
/* Main Interface statusbar */
/* and title of the Main Interface*/
connect( THEMIM, &PlayerController::inputChanged, this, &MainCtx::onInputChanged );
/* END CONNECTS ON IM */
/* VideoWidget connects for asynchronous calls */
connect( this, &MainCtx::askToQuit, THEDP, &DialogsProvider::quit, Qt::QueuedConnection );
/** END of CONNECTS**/
/************
* Callbacks
************/
libvlc_int_t* libvlc = vlc_object_instance(p_intf);
var_AddCallback( libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
var_AddCallback( libvlc, "intf-boss", IntfBossCB, p_intf );
var_AddCallback( libvlc, "intf-show", IntfRaiseMainCB, p_intf );
/* Register callback for the intf-popupmenu variable */
var_AddCallback( libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
if( config_GetInt("qt-privacy-ask") )
{
//postpone dialog call, as composition might not be ready yet
QMetaObject::invokeMethod(this, [](){
THEDP->firstRunDialog();
}, Qt::QueuedConnection);
}
else if (m_medialib)
{
QMetaObject::invokeMethod(m_medialib, &MediaLib::reload, Qt::QueuedConnection);
}
#ifdef UPDATE_CHECK
/* Checking for VLC updates */
if( var_InheritBool( p_intf, "qt-updates-notif" ) &&
!var_InheritBool( p_intf, "qt-privacy-ask" ) )
{
int interval = var_InheritInteger( p_intf, "qt-updates-days" );
if( QDate::currentDate() >
getSettings()->value( "updatedate" ).toDate().addDays( interval ) )
{
/* check for update at startup */
m_updateModel = std::make_unique<UpdateModel>(p_intf);
connect(m_updateModel.get(), &UpdateModel::updateStatusChanged, this, [this](){
switch (m_updateModel->updateStatus())
{
case UpdateModel::Checking:
case UpdateModel::Unchecked:
break;
case UpdateModel::NeedUpdate:
qWarning() << "Need Udpate";
THEDP->updateDialog();
[[fallthrough]];
case UpdateModel::UpToDate:
case UpdateModel::CheckFailed:
disconnect(m_updateModel.get(), nullptr, this, nullptr);
break;
}
});
m_updateModel->checkUpdate();
getSettings()->setValue( "updatedate", QDate::currentDate() );
}
}
#endif
}
MainCtx::~MainCtx()
{
RendererManager::killInstance();
/* Save states */
settings->beginGroup("MainWindow");
settings->setValue( "pl-dock-status", b_playlistDocked );
settings->setValue( "ShowRemainingTime", m_showRemainingTime );
settings->setValue( "interface-scale", QString::number( m_intfUserScaleFactor ) );
/* Save playlist state */
settings->setValue( "playlist-visible", m_playlistVisible );
settings->setValue( "playlist-width-factor", QString::number( m_playlistWidthFactor ) );
settings->setValue( "player-playlist-width-factor", QString::number( m_playerPlaylistWidthFactor ) );
settings->setValue( "artist-albums-width-factor", QString::number( m_artistAlbumsWidthFactor ) );
settings->setValue( "grid-view", m_gridView );
settings->setValue( "grouping", m_grouping );
settings->setValue( "color-scheme-index", m_colorScheme->currentIndex() );
/* Save the stackCentralW sizes */
settings->endGroup();
if( var_InheritBool( p_intf, "save-recentplay" ) )
getSettings()->setValue( "filedialog-path", m_dialogFilepath );
else
getSettings()->remove( "filedialog-path" );
/* Unregister callbacks */
libvlc_int_t* libvlc = vlc_object_instance(p_intf);
var_DelCallback( libvlc, "intf-boss", IntfBossCB, p_intf );
var_DelCallback( libvlc, "intf-show", IntfRaiseMainCB, p_intf );
var_DelCallback( libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
var_DelCallback( libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
if (m_medialib)
delete m_medialib;
p_intf->p_mi = NULL;
}
bool MainCtx::hasVLM() const {
#ifdef ENABLE_VLM
return true;
#else
return false;
#endif
}
bool MainCtx::useClientSideDecoration() const
{
//don't show CSD when interface is fullscreen
return !m_windowTitlebar;
}
bool MainCtx::hasFirstrun() const {
return config_GetInt( "qt-privacy-ask" );
}
void MainCtx::setUseGlobalShortcuts( bool useShortcuts )
{
if (m_useGlobalShortcuts == useShortcuts)
return;
m_useGlobalShortcuts = useShortcuts;
emit useGlobalShortcutsChanged(m_useGlobalShortcuts);
}
void MainCtx::setWindowSuportExtendedFrame(bool support) {
if (m_windowSuportExtendedFrame == support)
return;
m_windowSuportExtendedFrame = support;
emit windowSuportExtendedFrameChanged();
}
void MainCtx::setWindowExtendedMargin(unsigned int margin) {
if (margin == m_windowExtendedMargin)
return;
m_windowExtendedMargin = margin;
emit windowExtendedMarginChanged(margin);
}
/*****************************
* Main UI handling *
*****************************/
void MainCtx::loadPrefs(const bool callSignals)
{
const auto loadFromVLCOption = [this, callSignals](auto &variable, const char *name
, const std::function<void(MainCtx *)> signal)
{
using variableType = std::remove_reference_t<decltype(variable)>;
const auto value = loadVLCOption<variableType>(VLC_OBJECT(p_intf), name);
if (value == variable)
return;
variable = value;
if (callSignals && signal)
signal(this);
};
/* Are we in the enhanced always-video mode or not ? */
loadFromVLCOption(b_minimalView, "qt-minimal-view", nullptr);
loadFromVLCOption(m_bgCone, "qt-bgcone", &MainCtx::bgConeToggled);
/* Should the UI stays on top of other windows */
loadFromVLCOption(b_interfaceOnTop, "video-on-top", [this](MainCtx *)
{
emit interfaceAlwaysOnTopChanged(b_interfaceOnTop);
});
loadFromVLCOption(m_hasToolbarMenu, "qt-menubar", &MainCtx::hasToolbarMenuChanged);
loadFromVLCOption(m_windowTitlebar, "qt-titlebar" , &MainCtx::useClientSideDecorationChanged);
loadFromVLCOption(m_smoothScroll, "qt-smooth-scrolling", &MainCtx::smoothScrollChanged);
loadFromVLCOption(m_maxVolume, "qt-max-volume", &MainCtx::maxVolumeChanged);
loadFromVLCOption(m_pinVideoControls, "qt-pin-controls", &MainCtx::pinVideoControlsChanged);
loadFromVLCOption(m_pinOpacity, "qt-fs-opacity", &MainCtx::pinOpacityChanged);
loadFromVLCOption(m_safeArea, "qt-safe-area", &MainCtx::safeAreaChanged);
}
void MainCtx::loadFromSettingsImpl(const bool callSignals)
{
const auto loadFromSettings = [this, callSignals](auto &variable, const char *name
, const auto defaultValue, auto signal)
{
using variableType = std::remove_reference_t<decltype(variable)>;
const auto value = getSettings()->value(name, defaultValue).template value<variableType>();
if (value == variable)
return;
variable = value;
if (callSignals && signal)
(this->*signal)(variable);
};
loadFromSettings(b_playlistDocked, "MainWindow/pl-dock-status", true, &MainCtx::playlistDockedChanged);
loadFromSettings(m_playlistVisible, "MainWindow/playlist-visible", false, &MainCtx::playlistVisibleChanged);
loadFromSettings(m_playlistWidthFactor, "MainWindow/playlist-width-factor", 4.0 , &MainCtx::playlistWidthFactorChanged);
loadFromSettings(m_playerPlaylistWidthFactor, "MainWindow/player-playlist-width-factor", 4.0 , &MainCtx::playerPlaylistFactorChanged);
loadFromSettings(m_artistAlbumsWidthFactor, "MainWindow/artist-albums-width-factor"
, 4.0 , &MainCtx::artistAlbumsWidthFactorChanged);
loadFromSettings(m_gridView, "MainWindow/grid-view", true, &MainCtx::gridViewChanged);
loadFromSettings(m_grouping, "MainWindow/grouping", GROUPING_NONE, &MainCtx::groupingChanged);
loadFromSettings(m_showRemainingTime, "MainWindow/ShowRemainingTime", false, &MainCtx::showRemainingTimeChanged);
const auto colorSchemeIndex = getSettings()->value( "MainWindow/color-scheme-index", 0 ).toInt();
m_colorScheme->setCurrentIndex(colorSchemeIndex);
/* user interface scale factor */
auto userIntfScaleFactor = var_InheritFloat(p_intf, "qt-interface-scale");
if (userIntfScaleFactor == -1)
userIntfScaleFactor = getSettings()->value( "MainWindow/interface-scale", 1.0).toDouble();
if (m_intfUserScaleFactor != userIntfScaleFactor)
{
m_intfUserScaleFactor = userIntfScaleFactor;
updateIntfScaleFactor();
}
}
void MainCtx::reloadPrefs()
{
loadPrefs(true);
}
void MainCtx::onInputChanged( bool hasInput )
{
if( hasInput == false )
return;
int autoRaise = var_InheritInteger( p_intf, "qt-auto-raise" );
if ( autoRaise == MainCtx::RAISE_NEVER )
return;
if( THEMIM->hasVideoOutput() == true )
{
if( ( autoRaise & MainCtx::RAISE_VIDEO ) == 0 )
return;
}
else if ( ( autoRaise & MainCtx::RAISE_AUDIO ) == 0 )
return;
emit askRaise();
}
#ifdef KeyPress
#undef KeyPress
#endif
void MainCtx::sendHotkey(Qt::Key key , Qt::KeyboardModifiers modifiers)
{
QKeyEvent event(QEvent::KeyPress, key, modifiers );
int vlckey = qtEventToVLCKey(&event);
var_SetInteger(vlc_object_instance(p_intf), "key-pressed", vlckey);
}
void MainCtx::updateIntfScaleFactor()
{
m_intfScaleFactor = m_intfUserScaleFactor;
if (QWindow* window = p_intf->p_compositor ? p_intf->p_compositor->interfaceMainWindow() : nullptr)
{
QScreen* screen = window->screen();
if (screen)
{
qreal dpi = screen->logicalDotsPerInch();
m_intfScaleFactor = m_intfUserScaleFactor * dpi / VLC_REFERENCE_SCALE_FACTOR;
}
}
emit intfScaleFactorChanged();
}
void MainCtx::onWindowVisibilityChanged(QWindow::Visibility visibility)
{
m_windowVisibility = visibility;
}
void MainCtx::setHasAcrylicSurface(const bool v)
{
if (m_hasAcrylicSurface == v)
return;
m_hasAcrylicSurface = v;
emit hasAcrylicSurfaceChanged();
}
void MainCtx::incrementIntfUserScaleFactor(bool increment)
{
if (increment)
setIntfUserScaleFactor(m_intfUserScaleFactor + 0.1);
else
setIntfUserScaleFactor(m_intfUserScaleFactor - 0.1);
}
void MainCtx::setIntfUserScaleFactor(double newValue)
{
m_intfUserScaleFactor = qBound(getMinIntfUserScaleFactor(), newValue, getMaxIntfUserScaleFactor());
updateIntfScaleFactor();
}
void MainCtx::setHasToolbarMenu( bool hasToolbarMenu )
{
if (m_hasToolbarMenu == hasToolbarMenu)
return;
m_hasToolbarMenu = hasToolbarMenu;
config_PutInt("qt-menubar", (int) hasToolbarMenu);
emit hasToolbarMenuChanged();
}
void MainCtx::setPinVideoControls(bool pinVideoControls)
{
if (m_pinVideoControls == pinVideoControls)
return;
m_pinVideoControls = pinVideoControls;
emit pinVideoControlsChanged();
}
void MainCtx::setPinOpacity(float pinOpacity)
{
if (m_pinOpacity == pinOpacity)
return;
m_pinOpacity = pinOpacity;
emit pinOpacityChanged();
}
inline void MainCtx::initSystray()
{
bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
if( var_InheritBool( p_intf, "qt-start-minimized") )
{
if( b_systrayAvailable )
{
b_systrayWanted = true;
b_hideAfterCreation = true;
}
else
msg_Err( p_intf, "cannot start minimized without system tray bar" );
}
if( b_systrayAvailable && b_systrayWanted )
m_systray = std::make_unique<VLCSystray>(this);
}
WorkerThreadSet* MainCtx::workersThreads() const
{
if (!m_workersThreads)
{
m_workersThreads.reset( new WorkerThreadSet );
}
return m_workersThreads.get();
}
QUrl MainCtx::folderMRL(const QString &fileMRL) const
{
return folderMRL(QUrl::fromUserInput(fileMRL));
}
QUrl MainCtx::folderMRL(const QUrl &fileMRL) const
{
if (fileMRL.isLocalFile())
{
const QString f = fileMRL.toLocalFile();
return QUrl::fromLocalFile(QFileInfo(f).absoluteDir().absolutePath());
}
return {};
}
QString MainCtx::displayMRL(const QUrl &mrl) const
{
return urlToDisplayString(mrl);
}
void MainCtx::setPlaylistDocked( bool docked )
{
b_playlistDocked = docked;
emit playlistDockedChanged(docked);
}
void MainCtx::setPlaylistVisible( bool visible )
{
m_playlistVisible = visible;
emit playlistVisibleChanged(visible);
}
void MainCtx::setPlaylistWidthFactor( double factor )
{
if (factor > 0.0)
{
m_playlistWidthFactor = factor;
emit playlistWidthFactorChanged(factor);
}
}
void MainCtx::setPlayerPlaylistWidthFactor( double factor )
{
if (factor > 0.0)
{
m_playerPlaylistWidthFactor = factor;
emit playerPlaylistFactorChanged(factor);
}
}
void MainCtx::setbgCone(bool bgCone)
{
if (m_bgCone == bgCone)
return;
m_bgCone = bgCone;
emit bgConeToggled();
}
void MainCtx::setShowRemainingTime( bool show )
{
m_showRemainingTime = show;
emit showRemainingTimeChanged(show);
}
void MainCtx::setGridView(bool asGrid)
{
m_gridView = asGrid;
emit gridViewChanged( asGrid );
}
void MainCtx::setGrouping(Grouping grouping)
{
m_grouping = grouping;
emit groupingChanged(grouping);
}
void MainCtx::setInterfaceAlwaysOnTop( bool on_top )
{
b_interfaceOnTop = on_top;
emit interfaceAlwaysOnTopChanged(on_top);
}
bool MainCtx::hasEmbededVideo() const
{
return m_videoSurfaceProvider && m_videoSurfaceProvider->hasVideoEmbed();
}
void MainCtx::setVideoSurfaceProvider(VideoSurfaceProvider* videoSurfaceProvider)
{
if (m_videoSurfaceProvider)
disconnect(m_videoSurfaceProvider, &VideoSurfaceProvider::hasVideoEmbedChanged, this, &MainCtx::hasEmbededVideoChanged);
m_videoSurfaceProvider = videoSurfaceProvider;
if (m_videoSurfaceProvider)
connect(m_videoSurfaceProvider, &VideoSurfaceProvider::hasVideoEmbedChanged,
this, &MainCtx::hasEmbededVideoChanged,
Qt::QueuedConnection);
emit hasEmbededVideoChanged(m_videoSurfaceProvider && m_videoSurfaceProvider->hasVideoEmbed());
}
VideoSurfaceProvider* MainCtx::getVideoSurfaceProvider() const
{
return m_videoSurfaceProvider;
}
/************************************************************************
* Events stuff
************************************************************************/
bool MainCtx::onWindowClose( QWindow* )
{
PlaylistController* playlistController = p_intf->p_mainPlaylistController;
PlayerController* playerController = p_intf->p_mainPlayerController;
if (m_videoSurfaceProvider)
m_videoSurfaceProvider->onWindowClosed();
//We need to make sure that noting is playing anymore otherwise the vout will be closed
//after the main interface, and it requires (at least with OpenGL) that the OpenGL context
//from the main window is still valid.
//vlc_window_ReportClose is currently stubbed
if (playerController && playerController->hasVideoOutput()) {
connect(playerController, &PlayerController::playingStateChanged, [this](PlayerController::PlayingState state){
if (state == PlayerController::PLAYING_STATE_STOPPED) {
emit askToQuit();
}
});
playlistController->stop();
return false;
}
else
{
emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
return true;
}
}
void MainCtx::toggleToolbarMenu()
{
setHasToolbarMenu(!m_hasToolbarMenu);
}
void MainCtx::toggleInterfaceFullScreen()
{
emit setInterfaceFullScreen( m_windowVisibility != QWindow::FullScreen );
}
void MainCtx::emitBoss()
{
emit askBoss();
}
void MainCtx::emitShow()
{
emit askShow();
}
void MainCtx::emitRaise()
{
emit askRaise();
}
VLCVarChoiceModel* MainCtx::getExtraInterfaces()
{
return m_extraInterfaces;
}
/*****************************************************************************
* PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
* We don't show the menu directly here because we don't want the
* caller to block for a too long time.
*****************************************************************************/
static int PopupMenuCB( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t new_val, void *param )
{
qt_intf_t *p_intf = (qt_intf_t *)param;
if( p_intf->pf_show_dialog )
{
p_intf->pf_show_dialog( p_intf->intf, INTF_DIALOG_POPUPMENU,
new_val.b_bool, NULL );
}
return VLC_SUCCESS;
}
/*****************************************************************************
* IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
*****************************************************************************/
static int IntfShowCB( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void *param )
{
qt_intf_t *p_intf = (qt_intf_t *)param;
p_intf->p_mi->emitShow();
return VLC_SUCCESS;
}
/*****************************************************************************
* IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
*****************************************************************************/
static int IntfRaiseMainCB( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void *param )
{
qt_intf_t *p_intf = (qt_intf_t *)param;
p_intf->p_mi->emitRaise();
return VLC_SUCCESS;
}
/*****************************************************************************
* IntfBossCB: callback triggered by the intf-boss libvlc variable.
*****************************************************************************/
static int IntfBossCB( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void *param )
{
qt_intf_t *p_intf = (qt_intf_t *)param;
p_intf->p_mi->emitBoss();
return VLC_SUCCESS;
}
bool MainCtx::acrylicActive() const
{
return m_acrylicActive;
}
void MainCtx::setAcrylicActive(bool newAcrylicActive)
{
if (m_acrylicActive == newAcrylicActive)
return;
m_acrylicActive = newAcrylicActive;
emit acrylicActiveChanged();
}
bool MainCtx::preferHotkeys() const
{
return m_preferHotkeys;
}
void MainCtx::setPreferHotkeys(bool enable)
{
if (m_preferHotkeys == enable)
return;
m_preferHotkeys = enable;
emit preferHotkeysChanged();
}
QWindow *MainCtx::intfMainWindow() const
{
if (p_intf->p_compositor)
return p_intf->p_compositor->interfaceMainWindow();
else
return nullptr;
}
QVariant MainCtx::settingValue(const QString &key, const QVariant &defaultValue) const
{
return settings->value(key, defaultValue);
}
void MainCtx::setSettingValue(const QString &key, const QVariant &value)
{
settings->setValue(key, value);
}
void MainCtx::setAttachedToolTip(QObject *toolTip)
{
// See QQuickToolTipAttachedPrivate::instance(bool create)
assert(toolTip);
// Prevent possible invalid down-casting:
assert(toolTip->inherits("QQuickToolTip"));
QQmlEngine* const engine = qmlEngine(toolTip);
assert(engine);
assert(engine->objectOwnership(toolTip) == QQmlEngine::ObjectOwnership::JavaScriptOwnership);
// Dynamic internal property:
static const char* const name = "_q_QQuickToolTip";
if (const auto obj = engine->property(name).value<QObject *>())
{
if (engine->objectOwnership(obj) == QQmlEngine::ObjectOwnership::CppOwnership)
obj->deleteLater();
}
// setProperty() will return false, so there is no
// need to check the return value:
engine->setProperty(name, QVariant::fromValue(toolTip));
// Check if the attached tooltip is actually the
// one that is set
#ifndef NDEBUG
QQmlComponent component(engine);
component.setData(QByteArrayLiteral("import QtQuick; import QtQuick.Controls; Item { }"), {});
QObject* const obj = component.create();
assert(obj);
// Consider disabling setting of custom attached
// tooltip if the following assertion fails:
if (QQmlProperty::read(obj, QStringLiteral("ToolTip.toolTip"), qmlContext(obj)).value<QObject*>() != toolTip)
qmlWarning(obj) << "Could not set self as custom ToolTip!";
obj->deleteLater();
#endif
}
double MainCtx::dp(const double px, const double scale)
{
return std::round(px * scale);
}
double MainCtx::dp(const double px) const
{
return dp(px, m_intfScaleFactor);
}
bool MainCtx::useXmasCone() const
{
return (QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY)
&& var_InheritBool( p_intf, "qt-icon-change" );
}
bool WindowStateHolder::holdFullscreen(QWindow *window, Source source, bool hold)
{
QVariant prop = window->property("__windowFullScreen");
bool ok = false;
unsigned fullscreenCounter = prop.toUInt(&ok);
if (!ok)
fullscreenCounter = 0;
if (hold)
fullscreenCounter |= source;
else
fullscreenCounter &= ~source;
Qt::WindowStates oldflags = window->windowStates();
Qt::WindowStates newflags;
if( fullscreenCounter != 0 )
newflags = oldflags | Qt::WindowFullScreen;
else
newflags = oldflags & ~Qt::WindowFullScreen;
if( newflags != oldflags )
{
window->setWindowStates( newflags );
}
window->setProperty("__windowFullScreen", QVariant::fromValue(fullscreenCounter));
return fullscreenCounter != 0;
}
bool WindowStateHolder::holdOnTop(QWindow *window, Source source, bool hold)
{
QVariant prop = window->property("__windowOnTop");
bool ok = false;
unsigned onTopCounter = prop.toUInt(&ok);
if (!ok)
onTopCounter = 0;
if (hold)
onTopCounter |= source;
else
onTopCounter &= ~source;
Qt::WindowStates oldStates = window->windowStates();
Qt::WindowFlags oldflags = window->flags();
Qt::WindowFlags newflags;
if( onTopCounter != 0 )
newflags = oldflags | Qt::WindowStaysOnTopHint;
else
newflags = oldflags & ~Qt::WindowStaysOnTopHint;
if( newflags != oldflags )
{
window->setFlags( newflags );
window->show(); /* necessary to apply window flags */
//workaround: removing onTop state might drop fullscreen state
window->setWindowStates(oldStates);
}
window->setProperty("__windowOnTop", QVariant::fromValue(onTopCounter));
return onTopCounter != 0;
}
double MainCtx::artistAlbumsWidthFactor() const
{
return m_artistAlbumsWidthFactor;
}
void MainCtx::setArtistAlbumsWidthFactor(double newArtistAlbumsWidthFactor)
{
if (qFuzzyCompare(m_artistAlbumsWidthFactor, newArtistAlbumsWidthFactor))
return;
m_artistAlbumsWidthFactor = newArtistAlbumsWidthFactor;
emit artistAlbumsWidthFactorChanged( m_artistAlbumsWidthFactor );
}
#ifdef UPDATE_CHECK
UpdateModel* MainCtx::getUpdateModel() const
{
if (!m_updateModel)
m_updateModel = std::make_unique<UpdateModel>(p_intf);
return m_updateModel.get();
}
#endif