<commit_before>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "backendnode.h"
#include "mediaobject.h"

#include <ocidl.h> // ISpecifyPropertyPages
#include <olectl.h> // OleCreatePropertyFrame

QT_BEGIN_NAMESPACE

namespace Phonon
{
    namespace DS9
    {
        // Displays a property dialog for a filter (experimental but should be put into main
        /*static void showPropertyDialog(const Filter &filter)
        {
            ComPointer<ISpecifyPropertyPages> prop(filter, IID_ISpecifyPropertyPages);
            if (prop != 0) {
                IUnknown *iunk[] = {filter};
                // Show the page.
                CAUUID caGUID;
                prop->GetPages(&caGUID);
                OleCreatePropertyFrame(
                    0, // Parent window
                    0, 0,                   // (Reserved)
                    0,                      // Caption for the dialog box
                    1,                      // Number of objects (just the filter)
                    iunk,                  // Array of object pointers.
                    caGUID.cElems,          // Number of property pages
                    caGUID.pElems,          // Array of property page CLSIDs
                    0,                      // Locale identifier
                    0, 0                    // Reserved
                    );
            }
        }*/

        //for now we have 2 graphs that do the same
        BackendNode::BackendNode(QObject *parent) : QObject(parent), m_mediaObject(0)
        {
        }

        BackendNode::~BackendNode()
        {
            //this will remove the filter from the graph
            mediaObjectDestroyed();
        }

        void BackendNode::setMediaObject(MediaObject *mo)
        {
            if (m_mediaObject) {
                disconnect(m_mediaObject, SIGNAL(destroyed()), this, SLOT(mediaObjectDestroyed()));
            }
            m_mediaObject = mo;
            connect(mo, SIGNAL(destroyed()), SLOT(mediaObjectDestroyed()));
        }

        void BackendNode::mediaObjectDestroyed()
        {
            //remove the filter from its graph
            FILTER_INFO info;
            for(int i = 0; i < FILTER_COUNT; ++i) {
                const Filter &filter = m_filters[i];
                if (!filter)
                    continue; 
                filter->QueryFilterInfo(&info);
                if (info.pGraph) {
                    HRESULT hr = info.pGraph->RemoveFilter(filter);
                    Q_ASSERT(SUCCEEDED(hr));
                    Q_UNUSED(hr);
                    info.pGraph->Release();
                }
            }
            m_mediaObject = 0;
        }

        QList<InputPin> BackendNode::pins(const Filter &filter, PIN_DIRECTION wantedDirection)
        {
            QList<InputPin> ret;
            if (filter) {
                ComPointer<IEnumPins> enumPin;
                HRESULT hr = filter->EnumPins(enumPin.pparam());
                Q_UNUSED(hr);
                Q_ASSERT( SUCCEEDED(hr));
                InputPin pin;
                while (enumPin->Next(1, pin.pparam(), 0) == S_OK) {
                    PIN_DIRECTION dir;
                    hr = pin->QueryDirection(&dir);
                    Q_ASSERT( SUCCEEDED(hr));
                    if (dir == wantedDirection) {
                        ret.append(pin);
                    }
                }
            }
            return ret;
        }
    }
}

QT_END_NAMESPACE

#include "moc_backendnode.cpp"
<commit_msg>Fix assert on windows when deleting phonon nodes from a running graph.<commit_after>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "backendnode.h"
#include "mediaobject.h"

#include <ocidl.h> // ISpecifyPropertyPages
#include <olectl.h> // OleCreatePropertyFrame

QT_BEGIN_NAMESPACE

namespace Phonon
{
    namespace DS9
    {
        // Displays a property dialog for a filter (experimental but should be put into main
        /*static void showPropertyDialog(const Filter &filter)
        {
            ComPointer<ISpecifyPropertyPages> prop(filter, IID_ISpecifyPropertyPages);
            if (prop != 0) {
                IUnknown *iunk[] = {filter};
                // Show the page.
                CAUUID caGUID;
                prop->GetPages(&caGUID);
                OleCreatePropertyFrame(
                    0, // Parent window
                    0, 0,                   // (Reserved)
                    0,                      // Caption for the dialog box
                    1,                      // Number of objects (just the filter)
                    iunk,                  // Array of object pointers.
                    caGUID.cElems,          // Number of property pages
                    caGUID.pElems,          // Array of property page CLSIDs
                    0,                      // Locale identifier
                    0, 0                    // Reserved
                    );
            }
        }*/

        //for now we have 2 graphs that do the same
        BackendNode::BackendNode(QObject *parent) : QObject(parent), m_mediaObject(0)
        {
        }

        BackendNode::~BackendNode()
        {
            //this will remove the filter from the graph
            FILTER_INFO info;
            for(int i = 0; i < FILTER_COUNT; ++i) {
                const Filter &filter = m_filters[i];
                if (!filter)
                    continue;
                filter->QueryFilterInfo(&info);
                if (info.pGraph) {
                    HRESULT hr = info.pGraph->RemoveFilter(filter);

                    if (hr == VFW_E_NOT_STOPPED && m_mediaObject) {
                        m_mediaObject->ensureStopped();

                        hr = info.pGraph->RemoveFilter(filter);
                    }
                    Q_ASSERT(SUCCEEDED(hr));
                    info.pGraph->Release();
                }
            }
        }

        void BackendNode::setMediaObject(MediaObject *mo)
        {
            if (m_mediaObject) {
                disconnect(m_mediaObject, SIGNAL(destroyed()), this, SLOT(mediaObjectDestroyed()));
            }
            m_mediaObject = mo;
            connect(mo, SIGNAL(destroyed()), SLOT(mediaObjectDestroyed()));
        }

        void BackendNode::mediaObjectDestroyed()
        {
            //remove the filter from its graph
            FILTER_INFO info;
            for(int i = 0; i < FILTER_COUNT; ++i) {
                const Filter &filter = m_filters[i];
                if (!filter)
                    continue; 
                filter->QueryFilterInfo(&info);
                if (info.pGraph) {
                    HRESULT hr = info.pGraph->RemoveFilter(filter);
                    Q_ASSERT(SUCCEEDED(hr));
                    Q_UNUSED(hr);
                    info.pGraph->Release();
                }
            }
            m_mediaObject = 0;
        }

        QList<InputPin> BackendNode::pins(const Filter &filter, PIN_DIRECTION wantedDirection)
        {
            QList<InputPin> ret;
            if (filter) {
                ComPointer<IEnumPins> enumPin;
                HRESULT hr = filter->EnumPins(enumPin.pparam());
                Q_UNUSED(hr);
                Q_ASSERT( SUCCEEDED(hr));
                InputPin pin;
                while (enumPin->Next(1, pin.pparam(), 0) == S_OK) {
                    PIN_DIRECTION dir;
                    hr = pin->QueryDirection(&dir);
                    Q_ASSERT( SUCCEEDED(hr));
                    if (dir == wantedDirection) {
                        ret.append(pin);
                    }
                }
            }
            return ret;
        }
    }
}

QT_END_NAMESPACE

#include "moc_backendnode.cpp"

{'fraction_non_alphanumeric': 0.0844650546538589, 'fraction_numerical': 0.005189356298995252, 'mean_word_length': 1.418045915643353, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4809828', 'n_tokens_mistral': 2433, 'n_tokens_neox': 2255, 'n_words': 674}