void LogQueue::PostPluginError(int errorId, int errorSubid, DWORD errorCode, const std::string& errorDescription)
{
  s_criticalSectionQueue.Lock();
  {
    CPluginError pluginError(errorId, errorSubid, errorCode, errorDescription);

    s_pluginErrors.push_back(pluginError);
  }
  s_criticalSectionQueue.Unlock();
}
//*********************************************************
// Name: doIt
// Desc: All of the one-time setup and initialization
//       code for the breakdown command.  doIt is called
//       by Maya when any command is executed in MEL.
//       Any code that changes the state of Maya is
//       handled by the redoIt method.
//*********************************************************
MStatus BreakdownCommand::doIt( const MArgList &args )
{
    parseCommandFlags( args );

	getSelectedObjects();

    if( selectionList.length() == 0 ) {
		MGlobal::displayError( "No Objects Selected" );
        status = MS::kFailure;
    }
    else if( selectedAttrOnly && (populateSelectedAttributeList() == 0) ) {
        MGlobal::displayError( "No Attributes Selected" );
        status = MS::kFailure;
    }
	else
    {
		MStringArray results;
		selectionList.getSelectionStrings( results );

        if( !createBreakdownList()) {
            // Create breakdown will display its own error
        }

        // When in ripple mode, the default behaviour is to verify that
        // all attributes have a key set at the current time or all keys
        // have no keys set at the current time.  The ripple breakdown
        // will fail if this is not the case unless the check is disabled.
        else if( breakdownMode == Breakdown::kRipple && 
                 !ignoreRippleCheck &&
                 !(status = breakdownList.areOriginalKeysUniform()) )
        {
            MGlobal::displayError( "Breakdown Failed. (Ripple Mode)All attributes must have a key set or no keys set at the current time." );
        }
        else {
            if( !redoIt() ) {
                pluginError( "BreakdownCommand", "doIt", "Failed to redoIt" );
            }
            else {
                MString output( "Result: " );

                output += breakdownList.size();

                if( attributesSkipped )
                    output += "   (See Script Editor for skipped attributes)";
                else if( objectsSkipped )
                    output += "   (See Script Editor for skipped objects)";
                MGlobal::displayInfo( output );
            }
        }
	}

	return status;
}
//*********************************************************
// Name: parseCommandFlags
// Desc: Parsed the command flags and stores the values
//       in the appropriate variables
//*********************************************************
void BreakdownCommand::parseCommandFlags( const MArgList &args )
{
    MArgDatabase argData( syntax(), args, &status );
    if( !status ) {
        pluginError( "BreakdownCommand", "parseCommandFlags",
                     "Failed to create MArgDatabase for the breakdown command" );
    }
    else {
        if( argData.isFlagSet( weightFlag ))
            argData.getFlagArgument( weightFlag, 0, breakdownWeight );
        if( argData.isFlagSet( selectedAttrFlag ))
            argData.getFlagArgument( selectedAttrFlag, 0, selectedAttrOnly );
        if( argData.isFlagSet( ignoreRippleCheckFlag ))
            argData.getFlagArgument( ignoreRippleCheckFlag, 0, ignoreRippleCheck );
        if( argData.isFlagSet( tickDrawSpecialFlag ))
            argData.getFlagArgument( tickDrawSpecialFlag, 0, tickDrawSpecial );

        if( argData.isFlagSet( invalidAttrOpFlag )) {
            MString strAttrOp;
            argData.getFlagArgument( invalidAttrOpFlag, 0, strAttrOp );

            if( strAttrOp == "skipAll" )
                invalidAttrOp = kSkipAll;
            else if( strAttrOp == "skipObject" )
                invalidAttrOp = kSkipObject;
            else if( strAttrOp == "skipAttr" )
                invalidAttrOp = kSkipAttr;
            else
                MGlobal::displayWarning( "Invalid arguement for -invalidAttrOp.  Using default value." );
        }

        if( argData.isFlagSet( modeFlag )) {
            MString strMode;
            argData.getFlagArgument( modeFlag, 0, strMode );

            if( strMode == "overwrite" )
                breakdownMode = Breakdown::kOverwrite;
            else if( strMode == "ripple" )
                breakdownMode = Breakdown::kRipple;
        }

        // Ripple mode ignores the selectedAttrOnly flag.
        // All attributes will be affected.
        if( breakdownMode == Breakdown::kRipple ) {
            if( selectedAttrOnly == true ) {
                selectedAttrOnly = false;
                MGlobal::displayWarning( "Key Selected flag is ignored in Ripple Mode" );
            }
        }
    }
}
void CreateAccount::loadPluginAndShowDialog(const QString &pluginName)
{
    KAccountsUiPlugin *ui = KAccounts::UiPluginsManager::pluginForName(pluginName);

    if (!ui) {
        qDebug() << "Plugin could not be loaded";
        pluginError(i18nc("The %1 is for plugin name, eg. Could not load UI plugin", "Could not load %1 plugin, please check your installation", pluginName));
        return;
    }

    connect(ui, &KAccountsUiPlugin::success, this, &CreateAccount::pluginFinished, Qt::UniqueConnection);
    connect(ui, &KAccountsUiPlugin::error, this, &CreateAccount::pluginError, Qt::UniqueConnection);

    ui->setProviderName(m_providerName);
    ui->init(KAccountsUiPlugin::NewAccountDialog);
}
//*********************************************************
// Name: getSelectedObjects
// Desc: 
//*********************************************************
void BreakdownCommand::getSelectedObjects()
{
    status = MS::kFailure;
    MSelectionList characterSetList;

    selectionList.clear();

    // Selected Objects Include:
    //    1) The Active Character Set (if in use) and its subset
    //    2) Character Sets selected by the user (and their subsets)
    //    3) Objects selected by the user

    // Get the character set if active (in Maya) and the associated character set subsets
    MStringArray characterSets;
    MGlobal::executeCommand( MString("cie_atbGetActiveCharacterSets"), characterSets, false, false );

    // Create a selection list with all the character set/subsets
    for( unsigned int i = 0; i < characterSets.length(); i++ ) {
        MGlobal::getSelectionListByName( characterSets[i], characterSetList );
    }

    // Get the character sets selected (by user) and the associated character set subsets 
    MGlobal::executeCommand( MString("cie_atbGetSelectedCharacterSets"), characterSets, false, false);

    // Append to the selection list with all the selected character set/subsets
    for( unsigned int i = 0; i < characterSets.length(); i++ ) {
        MGlobal::getSelectionListByName( characterSets[i], characterSetList );
    }

    // Retrive all of the currently selected objects
    if( !MGlobal::getActiveSelectionList( selectionList )) {
        pluginError( "BreakdownCommand", "getSelectedObjects", "Failed to get active selection list" );
    }
    /*
    // At least one object must be selected for this command
    else if( characterSetList.length() == 0 && selectionList.length() == 0 ) {
            pluginError( "BreakdownCommand", "getSelectedObjects", "No Objects Selected" );
            MGlobal::displayError( "No Objects Selected" );
        }
    }
    */
    else
        status = MS::kSuccess;

    selectionList.merge( characterSetList );
}
//*********************************************************
// Name: undoIt
// Desc: Contains the code to undo the internal state 
//       changes made by the breakdown command (redoIt).
//       It is called by Maya to undo.
//*********************************************************
MStatus BreakdownCommand::undoIt()
{
    // Traverse the breakdown list and call undo on each
    // breakdown object
    if( !breakdownList.empty() ) {
        breakdownList.iterBegin();
        
        for( Breakdown* breakdown = breakdownList.getCurrent();
             breakdown != NULL;
             breakdown = breakdownList.getNext() )
        {
            status = breakdown->undoIt();
            if( !status )
                pluginError( "BreakdownCommand", "undoIt", "Failed to undoIt" );
        }
    }

    return status;
}