Esempio n. 1
0
void ProjectTreeViewBase::moveItems (OwnedArray <Project::Item>& selectedNodes,
                                     Project::Item destNode, int insertIndex)
{
    for (int i = selectedNodes.size(); --i >= 0;)
    {
        Project::Item* const n = selectedNodes.getUnchecked(i);

        if (destNode == *n || destNode.state.isAChildOf (n->state)) // Check for recursion.
            return;

        if (! destNode.canContain (*n))
            selectedNodes.remove (i);
    }

    // Don't include any nodes that are children of other selected nodes..
    for (int i = selectedNodes.size(); --i >= 0;)
    {
        Project::Item* const n = selectedNodes.getUnchecked(i);

        for (int j = selectedNodes.size(); --j >= 0;)
        {
            if (j != i && n->state.isAChildOf (selectedNodes.getUnchecked(j)->state))
            {
                selectedNodes.remove (i);
                break;
            }
        }
    }

    // Remove and re-insert them one at a time..
    for (int i = 0; i < selectedNodes.size(); ++i)
    {
        Project::Item* selectedNode = selectedNodes.getUnchecked(i);

        if (selectedNode->state.getParent() == destNode.state
              && indexOfNode (destNode.state, selectedNode->state) < insertIndex)
            --insertIndex;

        selectedNode->removeItemFromProject();
        destNode.addChild (*selectedNode, insertIndex++);
    }
}
Esempio n. 2
0
    RowItem* findItem (const int uid) const throw()
    {
        for (int i = items.size(); --i >= 0;)
        {
            RowItem* const ri = items.getUnchecked(i);
            if (ri->uid == uid)
                return ri;
        }

        return 0;
    }
Esempio n. 3
0
//==============================================================================
void DefaultMenuBarItemHandler::setupDefaultItemsIfNecessary()
{
    if (menuBarItems.size() <= 0)
    {
        menuBarItems.add (new FileMenuBarItem());
        menuBarItems.add (new EditMenuBarItem());
        menuBarItems.add (new ViewMenuBarItem());
        menuBarItems.add (new BuildMenuBarItem());
        menuBarItems.add (new ToolsMenuBarItem());
        menuBarItems.add (new HelpMenuBarItem());
    }
}
Esempio n. 4
0
    Trail* getTrail (const MouseInputSource& source)
    {
        for (int i = 0; i < trails.size(); ++i)
        {
            Trail* t = trails.getUnchecked(i);

            if (t->source == source)
                return t;
        }

        return nullptr;
    }
void ComponentLayoutEditor::itemDropped (const SourceDetails& dragSourceDetails)
{
    OwnedArray <Project::Item> selectedNodes;
    ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);

    StringArray filenames;

    for (int i = 0; i < selectedNodes.size(); ++i)
        if (selectedNodes.getUnchecked(i)->getFile().hasFileExtension (".cpp"))
            filenames.add (selectedNodes.getUnchecked(i)->getFile().getFullPathName());

    filesDropped (filenames, dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
}
Esempio n. 6
0
static bool isAnyModuleNewerThanProjucer (const OwnedArray<ModuleDescription>& modules)
{
    for (int i = modules.size(); --i >= 0;)
    {
        const ModuleDescription* m = modules.getUnchecked(i);

        if (m->getID().startsWith ("juce_")
              && getJuceVersion (m->getVersion()) > getBuiltJuceVersion())
            return true;
    }

    return false;
}
Esempio n. 7
0
void ColumnFileBrowserContents::resized()
{
	int width = 0;
	const int height = getHeight();
	
	for (int i = 0; i < columns.size(); i++)
	{
		columns[i]->setBounds (width, 0, columns[i]->getWidth(), height);
		width += columns[i]->getWidth();
	}
	
	setSize (width, height);
}
Esempio n. 8
0
    void buttonClicked (Button* button) override
    {
        if (button == &nativeButton)
        {
            getLookAndFeel().setUsingNativeAlertWindows (nativeButton.getToggleState());

            return;
        }

        for (int i = windowButtons.size(); --i >= 0;)
            if (button == windowButtons.getUnchecked (i))
                return showWindow (*button, static_cast<DialogType> (i));
    }
void Ebu128LoudnessMeter::reset()
{
    // the bins
    for (int k=0; k != bin.size(); ++k)
    {
        OwnedArray<double>* binsForTheKthChannel = bin[k];
        for (int i=0; i != binsForTheKthChannel->size(); ++i)
        {
            double* ithBin = binsForTheKthChannel->getUnchecked(i);
            *ithBin = 0.0;
        }
    }
    
    
    // momentary and short term loudness.
    for (int k = 0; k != momentaryLoudness.size(); ++k)
    {
        momentaryLoudness.set(k, var(minimalReturnValue));
        shortTermLoudness.set(k, minimalReturnValue);
    }
    // To ensure the returned momentary and short term loudness are at its 
    // minimum, even if no audio is processed at the moment.
    for (int k = 0; k < averageOfTheLast400ms.size(); ++k)
    {
        *averageOfTheLast400ms[k] = 0.0;
    }
    for (int k = 0; k < averageOfTheLast3s.size(); ++k)
    {
        *averageOfTheLast3s[k] = 0.0;
    }
    
    // integrated loudness
    numberOfBlocksToCalculateRelativeThreshold = 0;
    sumOfAllBlocksToCalculateRelativeThreshold = 0.0;
    relativeThreshold = absoluteThreshold;
    
    histogramOfBlockLoudness.clear();
    
    integratedLoudness = minimalReturnValue;
    
    
    // Loudness range
    numberOfBlocksToCalculateRelativeThresholdLRA = 0;
    sumOfAllBlocksToCalculateRelativeThresholdLRA = 0.0;
    relativeThresholdLRA = absoluteThreshold;
    
    histogramOfBlockLoudnessLRA.clear();
    
    loudnessRangeStart = minimalReturnValue;
    loudnessRangeEnd = minimalReturnValue;
}
//==============================================================================
//==============================================================================
void NonMember::printSlidersParams(const PluginProcessor& processor,
                        const OwnedArray<Slider>& sliders)
{
    String message;

    for (int i = 0; i < processor.numParams(); ++i) {
        jassert (i < sliders.size());
        jassert (sliders[i]);
        message << "Sliders["<<i<<"] " << sliders[i]->getValue()
                << " params["<<i<<"] " << processor.getParam(i).get() << "\n";
    }

    Logger::outputDebugString (message);
}
Esempio n. 11
0
bool SmugMug::deleteDuplicates(SmugID albumId)
{
	OwnedArray<ImageItem> images;
	if (getImages(images, albumId))
	{
		OwnedArray<SmugID> duplicateIds;
		StringArray fileNames;

		for (int i = 0; i < images.size(); i++)
		{
			if (fileNames.contains(images[i]->filename))
				duplicateIds.add(new SmugID(images[i]->id));
			else
				fileNames.add(images[i]->filename);
		}

		for (int i = 0; i < duplicateIds.size(); i++)
			deleteImage(*duplicateIds[i]);

		return true;
	}
	return false;
}
Esempio n. 12
0
static void initJuceDevicesIfNeeded()
{
    static AudioDeviceManager sDeviceManager;

    if (gDeviceTypes.size() != 0)
        return;

    sDeviceManager.createAudioDeviceTypes(gDeviceTypes);

    CARLA_SAFE_ASSERT_RETURN(gDeviceTypes.size() != 0,);

    new JuceCleanup();

    // remove JACK from device list
    for (int i=0, count=gDeviceTypes.size(); i < count; ++i)
    {
        if (gDeviceTypes[i]->getTypeName() == "JACK")
        {
            gDeviceTypes.remove(i, true);
            break;
        }
    }
}
Esempio n. 13
0
void ColumnFileBrowserContents::selectedFileChanged (const File& file)
{
    // if last column clicked add new column
	if (columns[activeColumn] == columns.getLast())
	{
		addColumn (file);
	}
	else        // otherwise remove uneeded columns and change last
	{
		for (int i = 0; i < columns.size(); i++)
		{
			if (columns[activeColumn] == columns[i])
            {
                const int numColumnsToRemove = columns.size() - i - (file.isDirectory() ? 1 : 0);
				removeColumn (numColumnsToRemove);
				
				if (file.isDirectory())
					columns.getLast()->setRoot (file);
                
                break;
			}
		}
		
		resized();
	}
	
	// stick to edges of viewport
	if (getWidth() < viewport->getWidth())
    {
		viewport->setViewPosition (0, 0);
    }
	else if (file.exists() || (getRight() < viewport->getRight()))
	{
		const int ammountToSubtract = viewport->getRight() - getRight();
		viewport->setViewPosition (viewport->getViewPositionX() - ammountToSubtract, 0);
	}
}
Esempio n. 14
0
    void reorderChildren (const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager)
    {
        jassert (newOrder.size() == children.size());

        for (int i = 0; i < children.size(); ++i)
        {
            SharedObject* const child = newOrder.getUnchecked(i)->object;

            if (children.getObjectPointerUnchecked (i) != child)
            {
                const int oldIndex = children.indexOf (child);
                jassert (oldIndex >= 0);
                moveChild (oldIndex, i, undoManager);
            }
        }
    }
Esempio n. 15
0
void ProjectTreeViewBase::itemDropped (const DragAndDropTarget::SourceDetails& dragSourceDetails, int insertIndex)
{
    OwnedArray <Project::Item> selectedNodes;
    getAllSelectedNodesInTree (dragSourceDetails.sourceComponent, selectedNodes);

    if (selectedNodes.size() > 0)
    {
        TreeView* tree = getOwnerView();
        ScopedPointer <XmlElement> oldOpenness (tree->getOpennessState (false));

        moveSelectedItemsTo (selectedNodes, insertIndex);

        if (oldOpenness != nullptr)
            tree->restoreOpennessState (*oldOpenness, false);
    }
}
Esempio n. 16
0
//==============================================================================
void AudioDeviceManager::createDeviceTypesIfNeeded()
{
    if (availableDeviceTypes.size() == 0)
    {
        OwnedArray <AudioIODeviceType> types;
        createAudioDeviceTypes (types);

        for (int i = 0; i < types.size(); ++i)
            addAudioDeviceType (types.getUnchecked(i));

        types.clear (false);

        if (AudioIODeviceType* first = availableDeviceTypes.getFirst())
            currentDeviceType = first->getTypeName();
    }
}
Esempio n. 17
0
void MixerAudioSource::removeAllInputs()
{
    OwnedArray<AudioSource> toDelete;

    {
        const ScopedLock sl (lock);

        for (int i = inputs.size(); --i >= 0;)
            if (inputsToDelete[i])
                toDelete.add (inputs.getUnchecked(i));

        inputs.clear();
    }

    for (int i = toDelete.size(); --i >= 0;)
        toDelete.getUnchecked(i)->releaseResources();
}
Esempio n. 18
0
	void run()
	{	
		OwnedArray<ImageItem> images;
		bool res = smugmug->getImages(images, ur->getAlbumId());

		smugmug->lock.enter();
		if (res)
		{
			for (int i = ur->getNumImages() - 1; i >= 0; i--)
			{
				for (int j = 0; j < images.size(); j++)
				{
					if (ur->getImageFile(i).getFileName() == images[j]->filename)
					{
						ur->getImageFileInfo(i).status = UploadFile::Duplicate;
					}
				}
			}
		}

		for (int i = 0; i < smugmug->uploadQueue.size(); i++)
		{
			if (smugmug->uploadQueue[i]->getAlbumId().id == ur->getAlbumId().id)
			{
				for (int j = 0; j < smugmug->uploadQueue[i]->getNumImages(); j++)
				{
					for (int k = 0; k < ur->getNumImages(); k++)
					{
						if (ur->getImageFile(k).getFileName() == smugmug->uploadQueue[i]->getImageFile(j).getFileName())
						{
							ur->getImageFileInfo(k).status = UploadFile::Duplicate;
						}
					}
				}
			}
		}
		smugmug->lock.exit();

		smugmug->uploadImages(ur, false);		

		smugmug->lock.enter();
		smugmug->dupeThreads.removeFirstMatchingValue(this);
		smugmug->lock.exit();

        triggerAsyncUpdate();
	}
    const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept
    {
        std::clog << "matchTypeface: " << familyName << " " << style << std::endl;

        for (int i = 0; i < faces.size(); ++i)
        {
            const KnownTypeface* const face = faces.getUnchecked(i);

            std::clog << "  matchTypeface: " << face->family << " " << face->style << std::endl;

            if ((face->family == familyName || familyName.isEmpty())
                  && (face->style.equalsIgnoreCase (style) || style.isEmpty()))
                return face;
        }

        std::cout << "NO MATCHING FONT FOUND" << std::endl;

        return nullptr;
    }
    static void replaceTabsWithSpaces (OwnedArray <SyntaxToken>& tokens, const int spacesPerTab) throw()
    {
        int x = 0;
        for (int i = 0; i < tokens.size(); ++i)
        {
            SyntaxToken* const t = tokens.getUnchecked(i);

            for (;;)
            {
                int tabPos = t->text.indexOfChar (T('\t'));
                if (tabPos < 0)
                    break;

                const int spacesNeeded = spacesPerTab - ((tabPos + x) % spacesPerTab);
                t->text = t->text.replaceSection (tabPos, 1, String::repeatedString (T(" "), spacesNeeded));
            }

            x += t->text.length();
        }
    }
Esempio n. 21
0
static void initJuceDevicesIfNeeded()
{
    static AudioDeviceManager sDeviceManager;
    static bool needsInit = true;

    if (! needsInit)
        return;

    needsInit = false;
    new JuceCleanup();

    sDeviceManager.createAudioDeviceTypes(gDeviceTypes);

    // remove JACK from device list
    for (int i=0, count=gDeviceTypes.size(); i < count; ++i)
    {
        if (gDeviceTypes[i]->getTypeName() == "JACK")
        {
            gDeviceTypes.remove(i, true);
            break;
        }
    }
}
Esempio n. 22
0
void MainHostWindow::filesDropped (const StringArray& files, int x, int y)
{
    GraphDocumentComponent* const graphEditor = getGraphEditor();

    if (graphEditor != nullptr)
    {
        if (files.size() == 1 && File (files[0]).hasFileExtension (filenameSuffix))
        {
            if (graphEditor->graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
                graphEditor->graph.loadFrom (File (files[0]), true);
        }
        else
        {
            OwnedArray <PluginDescription> typesFound;
            knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound);

            Point<int> pos (graphEditor->getLocalPoint (this, Point<int> (x, y)));

            for (int i = 0; i < jmin (5, typesFound.size()); ++i)
                createPlugin (typesFound.getUnchecked(i), pos.getX(), pos.getY());
        }
    }
}
bool BufferingAudioReader::readNextBufferChunk()
{
    const int64 pos = nextReadPosition;
    const int64 startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock;
    const int64 endPos = startPos + numBlocks * samplesPerBlock;

    OwnedArray<BufferedBlock> newBlocks;

    for (int i = blocks.size(); --i >= 0;)
        if (blocks.getUnchecked(i)->range.intersects (Range<int64> (startPos, endPos)))
            newBlocks.add (blocks.getUnchecked(i));

    if (newBlocks.size() == numBlocks)
    {
        newBlocks.clear (false);
        return false;
    }

    for (int64 p = startPos; p < endPos; p += samplesPerBlock)
    {
        if (getBlockContaining (p) == nullptr)
        {
            newBlocks.add (new BufferedBlock (*source, p, samplesPerBlock));
            break; // just do one block
        }
    }

    {
        const ScopedLock sl (lock);
        newBlocks.swapWith (blocks);
    }

    for (int i = blocks.size(); --i >= 0;)
        newBlocks.removeObject (blocks.getUnchecked(i), false);

    return true;
}
Esempio n. 24
0
bool 
EffectDataEntry::EffDatEntryLoad (ShowFile& show,
                                  uint32 version,
                                  const OwnedArray<Device>& devices,
                                  const OwnedArray<EffectPattern>& patterns)

{
    // each effect data has a pointer to a position control. The
    // position control belongs to a device. Therefor we saved the
    // device index and the control index which identifies the
    // position control. We will load both those indices and
    // validate them and find the correlating positon control

    int deviceIndex = 0;
    int controlIndex = 0;

    // load the device index
    if (! show.readInt (deviceIndex))
        return false;

    // load control index
    if (! show.readInt (controlIndex))
        return false;

    // get device count
    int deviceCount = devices.size();

    // validate the device index
    if (( deviceIndex < 0 ) || ( deviceIndex >= deviceCount))
        return false;

    // get the device pointer from the device manager
    Device* pDevice = devices[deviceIndex];

    // get the control count
    int controlCount = pDevice->DeviceGetControlCount();

    // validate the control index
    if (( controlIndex < 0 ) || ( controlIndex >= controlCount))
        return false;

    // get the control pointer from the device and assign it to our member
    m_pControl = pDevice->DeviceGetControl (controlIndex);

    // double check that it is a position control
    if (m_pControl->ControlGetType() != CT_POSITION)
        return false;

    // create empty effect data object
    ScopedPointer<EffectData>pEffectData = new EffectData;
    if (! pEffectData )
        return false;

    // load the effect data
    if (! pEffectData->EffectDataLoad (show, version, patterns))
        return false;

    // assign the new effect data to our member
    m_pEffectData = pEffectData;
    pEffectData.release();

    return true;
}
Esempio n. 25
0
    bool refillCache (const int numSamples, double startTime, const double endTime,
                      const double rate, const int numChans, const int sampsPerThumbSample,
                      LevelDataSource* levelData, const OwnedArray<ThumbData>& chans)
    {
        const double timePerPixel = (endTime - startTime) / numSamples;

        if (numSamples <= 0 || timePerPixel <= 0.0 || rate <= 0)
        {
            invalidate();
            return false;
        }

        if (numSamples == numSamplesCached
             && numChannelsCached == numChans
             && startTime == cachedStart
             && timePerPixel == cachedTimePerPixel
             && ! cacheNeedsRefilling)
        {
            return ! cacheNeedsRefilling;
        }

        numSamplesCached = numSamples;
        numChannelsCached = numChans;
        cachedStart = startTime;
        cachedTimePerPixel = timePerPixel;
        cacheNeedsRefilling = false;

        ensureSize (numSamples);

        if (timePerPixel * rate <= sampsPerThumbSample && levelData != nullptr)
        {
            int sample = roundToInt (startTime * rate);
            Array<float> levels;

            int i;
            for (i = 0; i < numSamples; ++i)
            {
                const int nextSample = roundToInt ((startTime + timePerPixel) * rate);

                if (sample >= 0)
                {
                    if (sample >= levelData->lengthInSamples)
                        break;

                    levelData->getLevels (sample, jmax (1, nextSample - sample), levels);

                    const int totalChans = jmin (levels.size() / 2, numChannelsCached);

                    for (int chan = 0; chan < totalChans; ++chan)
                        getData (chan, i)->setFloat (levels.getUnchecked (chan * 2),
                                                     levels.getUnchecked (chan * 2 + 1));
                }

                startTime += timePerPixel;
                sample = nextSample;
            }

            numSamplesCached = i;
        }
        else
        {
            jassert (chans.size() == numChannelsCached);

            for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum)
            {
                ThumbData* channelData = chans.getUnchecked (channelNum);
                MinMaxValue* cacheData = getData (channelNum, 0);

                const double timeToThumbSampleFactor = rate / (double) sampsPerThumbSample;

                startTime = cachedStart;
                int sample = roundToInt (startTime * timeToThumbSampleFactor);

                for (int i = numSamples; --i >= 0;)
                {
                    const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor);

                    channelData->getMinMax (sample, nextSample, *cacheData);

                    ++cacheData;
                    startTime += timePerPixel;
                    sample = nextSample;
                }
            }
        }

        return true;
    }
Esempio n. 26
0
const String SAMCompiler::compile(ValueTree mdlRoot_)
{
    String dspContent;

    //==========================================================================
    // DSP file header
    //==========================================================================
    dspContent << "// This DSP file has been generated by the Synth-A-Modeler compiler.\n";
    dspContent << "import(\"physicalmodeling.lib\");\n\n";

    //==========================================================================

    ValueTree faustTree = mdlRoot_.getChildWithName(Objects::variables);
    ValueTree massTree = mdlRoot_.getChildWithName(Objects::masses);
    ValueTree linkTree = mdlRoot_.getChildWithName(Objects::links);
    ValueTree wgTree = mdlRoot_.getChildWithName(Objects::waveguides);
    ValueTree jTree = mdlRoot_.getChildWithName(Objects::junctions);
    ValueTree tTree = mdlRoot_.getChildWithName(Objects::terminations);
    ValueTree aoTree = mdlRoot_.getChildWithName(Objects::audioobjects);

    int numMasslike = 0;
    int numPorts = 0;
    int numWaveguides = 0;
    int numJunctions = 0;
    String wgTermString;
    String junctString;
    StringArray wgOutputs;
    StringArray wgInputs;
    StringArray massWithJunct;
    StringArray linkWithJunct;
    StringArray massWithJunctLine;
    StringArray portWithJunctLine;
    StringArray massWithJunctOutputs;
    StringArray junctInputs;
    StringArray junctOutputs;

    //==========================================================================

    //==========================================================================
    // Write all waveguides and terminations
    //==========================================================================
    OwnedArray<WgWithSuffixes> wgWithSuffixes;
    for (int i = 0; i < wgTree.getNumChildren(); ++i)
    {
        ++numWaveguides;
        ValueTree wg = wgTree.getChild(i);
        WgWithSuffixes* wws = new WgWithSuffixes();
        wws->wgId = wg[Ids::identifier].toString();
        ValueTree left = jTree.getChildWithProperty(Ids::identifier,
                                                    wg[Ids::startVertex]);
        ValueTree right;
        if (left.isValid())
        {
            right = tTree.getChildWithProperty(Ids::identifier,
                                               wg[Ids::endVertex]);
        }
        else
        {
            left = tTree.getChildWithProperty(Ids::identifier, wg[Ids::startVertex]);
            right = jTree.getChildWithProperty(Ids::identifier, wg[Ids::endVertex]);
        }
        ValueTree term;
        ValueTree junct;
        StringArray wgSuffixes;
        if (left.getType() == Ids::termination)
        {
            wgSuffixes.add(wgR);
            wgSuffixes.add(wgL);
            wgSuffixes.add(wgRp);
            wgSuffixes.add(wgLp);
            term = left;
            junct = right;
            wws->termRight = false;
        }
        else if (left.getType() == Ids::junction)
        {
            wgSuffixes.add(wgL);
            wgSuffixes.add(wgR);
            wgSuffixes.add(wgLp);
            wgSuffixes.add(wgRp);
            term = right;
            junct = left;
            wws->termRight = true;
        }
        wws->wgSuffixes = wgSuffixes;

        wgInputs.add(wg[Ids::identifier].toString() + wgLp);
        wgInputs.add(wg[Ids::identifier].toString() + wgRp);
        wgOutputs.add(wg[Ids::identifier].toString() + wgL);
        wgOutputs.add(wg[Ids::identifier].toString() + wgR);

        ValueTree paWg = wg.getChildWithName(Ids::parameters);
        StringArray paWgStrings;
        for (int j = 0; j < paWg.getNumChildren(); ++j)
        {
            paWgStrings.add(paWg.getChild(j)[Ids::value].toString());
        }
        wws->wgParams = paWgStrings;
        wgWithSuffixes.add(wws);

        ValueTree paTerm = term.getChildWithName(Ids::parameters);
        StringArray paTermStrings;
        for (int j = 0; j < paTerm.getNumChildren(); ++j)
        {
            paTermStrings.add(paTerm.getChild(j)[Ids::value].toString());
        }

        //======================================================================
        wgTermString << "\t";
        wgTermString << wg[Ids::identifier].toString();
        wgTermString << wgSuffixes[0] << " = " << term[Ids::identifier].toString();

        wgTermString << " : ";
        wgTermString << paWgStrings[1];
        wgTermString << ";\n\t";

        wgTermString << term[Ids::identifier].toString();
        wgTermString << " = ";
        wgTermString << wg[Ids::identifier].toString() << wgSuffixes[3];
        wgTermString << " : ";

        wgTermString << paTermStrings[0] << ";\n\n";
        //======================================================================
    }

    //==========================================================================
    // Write all junctions
    //==========================================================================
    for (int i = 0; i < jTree.getNumChildren(); ++i)
    {
        ++numJunctions;
        ValueTree junct = jTree.getChild(i);

        junctOutputs.add(junct[Ids::identifier].toString());
        junctInputs.add(junct[Ids::identifier].toString()+"p");

        ValueTree wgs = getWgForJunct(wgTree, junct);
        StringArray junctWgOuts;
        StringArray junctWgParams;

        junctString << "\t";
        for (int k = 0; k < wgs.getNumChildren(); ++k)
        {
            ValueTree wg = wgs.getChild(k);
            int wgSuffixesIdx = containsWgRef(wgWithSuffixes, wg[Ids::identifier].toString());
            if (wgSuffixesIdx == -1)
                continue;

            const StringArray& wgSuffixes = wgWithSuffixes[wgSuffixesIdx]->wgSuffixes;
            junctString << wg[Ids::identifier].toString() << wgSuffixes[1];
            junctString << " = ";
            junctString << junct[Ids::identifier].toString() << jTO;
            junctString << wg[Ids::identifier].toString();
            junctString << " : ";
            junctString << wgWithSuffixes[wgSuffixesIdx]->wgParams[1];
            junctString << ";\n\t";

            junctString << junct[Ids::identifier].toString() << jTO;
            junctString << wg[Ids::identifier].toString() << " = ";
            junctString << junct[Ids::identifier].toString() << jOutputs;
            junctString << ":(_,!)-";
            junctString << wg[Ids::identifier].toString() << wgSuffixes[2];
            junctString << ";\n\t";

            String jwo;
            jwo << wg[Ids::identifier].toString() << wgSuffixes[2];
            jwo << "*" << wgWithSuffixes[wgSuffixesIdx]->wgParams[0];
            junctWgOuts.add(jwo);

            junctWgParams.add(wgWithSuffixes[wgSuffixesIdx]->wgParams[0]);
        }


        String junctLinkString;
        String junctMassString;
        // Check if junction has one link and mass connected
        ValueTree junctLink = getJunctionLink(linkTree, junct);
        if (junctLink.isValid())
        {
            String jm;
            if (junctLink[Ids::startVertex] == junct[Ids::identifier])
                jm << junctLink[Ids::endVertex].toString();
            else
                jm << junctLink[Ids::startVertex].toString();
            junctMassString << jm << "p";

            massWithJunct.add(jm);
            massWithJunctOutputs.add(jm + "p");
            linkWithJunct.add(junctLink[Ids::identifier].toString());

            ValueTree junctLinkParams = junctLink.getChildWithName(Ids::parameters);
            StringArray junctLinkParamsStrings;
            for (int k = 0; k < junctLinkParams.getNumChildren(); ++k)
            {
                ValueTree param = junctLinkParams.getChild(k);
                junctLinkParamsStrings.add(param[Ids::value].toString());
            }
            junctLinkString << "junction" << junctLink.getType().toString();
            junctLinkString << "Underneath(0.0,";
            junctLinkString << junctLinkParamsStrings.joinIntoString(",");
            junctLinkString << ")";

            // Get mass-like object connected with junction > link
            ValueTree mwj = massTree.getChildWithProperty(Ids::identifier, jm);
            String mwjl = "\t";
            mwjl << jm;
            mwjl << " = (0.0";

            StringArray otherLinks;
            for (int k = 0; k < linkTree.getNumChildren(); ++k)
            {
                ValueTree li = linkTree.getChild(k);
                if(li[Ids::identifier].toString() == junctLink[Ids::identifier].toString())
                    continue;
                if(li[Ids::startVertex].toString() == jm)
                {
                    otherLinks.add("-"+li[Ids::identifier].toString());
                }
                else if (li[Ids::endVertex].toString() == jm)
                {
                    otherLinks.add("+"+li[Ids::identifier].toString());
                }
            }


            mwjl << otherLinks.joinIntoString(String::empty);
            mwjl << "+(";
            mwjl << junct[Ids::identifier].toString() << jOutputs << ":(!,_)))";
//            mwjl << " : ";
//            ValueTree mwjp = mwj.getChildWithName(Ids::parameters);
//            StringArray mwjpStrings;
//            for (int p = 0; p < mwjp.getNumChildren(); ++p)
//            {
//                ValueTree param = mwjp.getChild(p);
//                mwjpStrings.add(param[Ids::value].toString());
//            }
//            mwjl << mwj.getType().toString();
//            mwjl << "(" << mwjpStrings.joinIntoString(",") << ")";
            mwjl << ";";
            massWithJunctLine.add(mwjl);

        }
        else
        {
            junctMassString << "0.0";
            junctLinkString << "junctionlink(0.0, 0.0, 0.0, 0.0)";
        }
        junctString << junct[Ids::identifier].toString() << jOutputs;
        junctString << " = (";
        junctString << junctMassString << ", 0.0+";

        junctString << junctWgOuts.joinIntoString("+");
        junctString << ", 0.0+";
        junctString << junctWgParams.joinIntoString("+");

        junctString << ") : ";
        junctString << junctLinkString << ";\n\t";

        junctString << junct[Ids::identifier].toString();
        junctString << " = ";
        junctString << junct[Ids::identifier].toString() << jOutputs;
        junctString << ":(_,!);\n\n";

    }

    //==========================================================================
    // Write all faustcode
    //==========================================================================
    for (int i = 0; i < faustTree.getNumChildren(); ++i)
    {
        ValueTree fa = faustTree.getChild(i);
        dspContent << fa[Ids::identifier].toString();
        dspContent << "=";
        dspContent << fa[Ids::faustCode].toString();
        dspContent << ";\n";
    }

    dspContent << "\n";

    //==========================================================================
    // Get all mass names
    //==========================================================================
    OwnedArray<MassLinkRef> massLinkRefs;
    for (int i = 0; i < massTree.getNumChildren(); ++i)
    {
        ValueTree ma = massTree.getChild(i);
        if (massWithJunct.contains(ma[Ids::identifier].toString()))
            continue;
        MassLinkRef* mlf = new MassLinkRef();
        mlf->massId = ma[Ids::identifier].toString();
        StringArray mlfa;
        mlf->linkRefs = mlfa;
        if (ma.getType() == Ids::port)
            mlf->isPort = true;
        else
            mlf->isPort = false;
        massLinkRefs.add(mlf);
    }

    //==========================================================================
    // Write all link-like objects
    //==========================================================================
    StringArray linkobjects;
    for (int i = 0; i < linkTree.getNumChildren(); ++i)
    {
        ValueTree li = linkTree.getChild(i);
        String linkId = li[Ids::identifier].toString();
        if (linkWithJunct.contains(linkId))
            continue;
        String startVertex = li[Ids::startVertex].toString();
        String endVertex = li[Ids::endVertex].toString();
        int sIdx = containsMassLinkRef(massLinkRefs, startVertex);
        if (sIdx >= 0)
            massLinkRefs[sIdx]->linkRefs.add("-" + linkId);

        int eIdx = containsMassLinkRef(massLinkRefs, endVertex);
        if (eIdx >= 0)
            massLinkRefs[eIdx]->linkRefs.add("+" + linkId);

        String tagName = li.getType().toString();
        ValueTree params = li.getChildWithName(Ids::parameters);
        StringArray paramsStr;
        for (int k = 0; k < params.getNumChildren(); ++k)
        {
            ValueTree param = params.getChild(k);
            paramsStr.add(param[Ids::value].toString());
        }

        //======================================================================
        String linkLine;
        linkLine << "\t";
        linkLine << linkId;
        linkLine << " = (";

        linkLine << startVertex << "p - ";
        linkLine << endVertex << "p) : ";
        linkLine << tagName << "(";
        linkLine << paramsStr.joinIntoString(",") << ");";
        linkobjects.add(linkLine);
        //======================================================================
    }

    StringArray massobjects;

    //==========================================================================
    // write all mass-like object except those connected to junctions
    //==========================================================================
    for (int i = 0; i < massTree.getNumChildren(); ++i)
    {
        ValueTree ma = massTree.getChild(i);
        if (massWithJunct.contains(ma[Ids::identifier].toString()))
        {
            if(ma.getType().toString().compare("port") == 0)
                ++numPorts;
            continue;
        }

        ++numMasslike;
        String tagName = ma.getType().toString();
        String massName = ma[Ids::identifier].toString();
        String massLine;
        massLine << "\t";
        massLine << massName << " = (0.0";
        if (tagName.compare("port") == 0)
            ++numPorts;

        int mIdx = containsMassLinkRef(massLinkRefs, massName);
        if (mIdx >= 0)
        {
            if (massLinkRefs[mIdx]->linkRefs.size() > 0)
            {
                massLine << massLinkRefs[mIdx]->linkRefs.joinIntoString(String::empty);
            }
        }

        massLine << ")";
        if (tagName.compare("port") != 0)
        {
            massLine << " : ";
            massLine << tagName << "(";
            ValueTree params = ma.getChildWithName(Ids::parameters);
            StringArray paramsStr;
            for (int k = 0; k < params.getNumChildren(); ++k)
            {
                ValueTree param = params.getChild(k);
                paramsStr.add(param[Ids::value].toString());
            }
            massLine << paramsStr.joinIntoString(",") << ")";
        }
        massLine << ";";
        massobjects.add(massLine);

    }
    //==========================================================================
    // add remaining mass-like object which are connected to junctions
    //==========================================================================
    massobjects.addArray(massWithJunctLine);

    //==========================================================================
    // Write all audio objects
    //==========================================================================
    StringArray audioobjects;
    StringArray audioNames;
    for (int i = 0; i < aoTree.getNumChildren(); ++i)
    {
        ValueTree ao = aoTree.getChild(i);

        String audioLine;
        String audioName = ao[Ids::identifier].toString();
        audioNames.add(audioName);
        audioLine << "\t";
        audioLine << audioName << " = ";
        ValueTree sources = ao.getChildWithName(Ids::sources);
        String paramLine;
        StringArray paramsStr;
        if (sources.getNumChildren() > 0)
        {
            for (int k = 0; k < sources.getNumChildren(); ++k)
            {
                ValueTree src = sources.getChild(k);
                paramsStr.add(src[Ids::value].toString());
            }
            paramLine << paramsStr.joinIntoString("+");
        }

        String optional = ao[Ids::optional].toString();
        if (optional != String::empty)
        {
            if(! paramLine.startsWith("("))
                paramLine = "(" + paramLine;
            if(! paramLine.endsWith(")"))
                paramLine << ")";
            paramLine << optional;
        }
        audioLine << paramLine;
        audioLine << ";";
        audioobjects.add(audioLine);
    }

    //==========================================================================
    // Generate all inputs and outputs
    //==========================================================================
    StringArray inputs;
    StringArray inputsPorts;
    for (int i = 0; i < massLinkRefs.size(); ++i)
    {
        if (massLinkRefs[i]->isPort)
            inputsPorts.add(massLinkRefs[i]->massId);
        else
            inputs.add(massLinkRefs[i]->massId);
    }

    StringArray outputs = inputs;
    outputs.addArray(massWithJunct);
    StringArray outputsPorts = inputsPorts;

    StringArray inputsP;
    StringArray inputsPPorts;
    for (int i = 0; i < inputs.size(); ++i)
    {
        String inputP = inputs[i];
        inputP << "p";
        inputsP.add(inputP);
    }
    for (int i = 0; i < massWithJunctOutputs.size(); ++i)
    {
        ++numMasslike;
        String inputP = massWithJunctOutputs[i];
        inputsP.add(inputP);
    }
    for (int i = 0; i < inputsPorts.size(); ++i)
    {
        String inputPPort = inputsPorts[i];
        inputPPort << "p";
        inputsPPorts.add(inputPPort);
    }

    //==========================================================================
    // bibBlock with all imputs and outputs
    //==========================================================================
    dspContent << "bigBlock(" << inputsP.joinIntoString(",");
    if (wgInputs.size() > 0)
        dspContent << "," << wgInputs.joinIntoString(",");
    if (junctInputs.size() > 0)
        dspContent << "," << junctInputs.joinIntoString(",");
    if (inputsPPorts.size() > 0)
        dspContent << "," << inputsPPorts.joinIntoString(",");
    dspContent << ") = (";
    dspContent << outputs.joinIntoString(",");
    if (wgOutputs.size() > 0)
        dspContent << "," << wgOutputs.joinIntoString(",");
    if (junctOutputs.size() > 0)
        dspContent << "," << junctOutputs.joinIntoString(",");
    if (outputsPorts.size() > 0)
        dspContent << "," << outputsPorts.joinIntoString(",");
    if (audioNames.size() > 0)
        dspContent << "," << audioNames.joinIntoString(",");
    dspContent << ") with {\n";

    //==========================================================================
    // code for model objects
    //==========================================================================
    dspContent << "\n\t//waveguide termination objects\n";
    dspContent << wgTermString;
    dspContent << "\t//junctions\n";
    dspContent << junctString;
    dspContent << "\t//mass-like objects\n";
    dspContent << massobjects.joinIntoString("\n") << "\n";
    dspContent << "\n\t//link-like objects\n";
    dspContent << linkobjects.joinIntoString("\n") << "\n";
    dspContent << "\n\t//audio objects\n";
    dspContent << audioobjects.joinIntoString("\n") << "\n};\n\n";

    //==========================================================================
    // Calculate and write feedback line
    //==========================================================================
    StringArray feedbackArray;
    StringArray outputArray;
    //TODO: needs to be fixed for latest Synth-A-Modeler changes/fiyes
    int numFeedback = numMasslike - numPorts + (2 * numWaveguides) + numJunctions;
    for (int i = 0; i < numFeedback; ++i)
    {
        feedbackArray.add("_");
        outputArray.add("!");
    }
    for (int i = 0; i < numPorts + audioNames.size(); ++i)
    {
        feedbackArray.add("!");
        outputArray.add("_");
    }
    dspContent << "process = (bigBlock)~(";
    dspContent << feedbackArray.joinIntoString(",");
    dspContent << "):(";
    dspContent << outputArray.joinIntoString(",") << ");";

    //==========================================================================
    massLinkRefs.clear();
    wgWithSuffixes.clear();

    return dspContent;
}
Esempio n. 27
0
		virtual void menuItemSelected(int menuItemID, int)
		{
			if (menuItemID == 200)
			{
				WildcardFileFilter wildcardFilter("*.mid", String::empty, "Midi files");
				FileBrowserComponent browser(FileBrowserComponent::canSelectFiles | FileBrowserComponent::openMode, 
					lastOpenedFile.exists() ? lastOpenedFile : File(String("C:\\Users\\GeorgeKrueger\\Documents")), &wildcardFilter, nullptr);
				FileChooserDialogBox dialogBox("Open a midi file",
					"Please choose a midi file to open...",
					browser,
					false,
					Colours::lightgrey);

				if (dialogBox.show())
				{
					File selectedFile = browser.getSelectedFile(0);
					lastOpenedFile = selectedFile;
					FileInputStream fileStream(selectedFile);
					juce::MidiFile midiFile;
					midiFile.readFrom(fileStream);
					int numTracks = midiFile.getNumTracks();
					midiFile.convertTimestampTicksToSeconds();
					String msg;
					msg << "Opened midi file: " << selectedFile.getFileName() << " Tracks: " << numTracks << "\n";
					log(msg);

					for (int i = 0; i < numTracks; ++i)
					{
						const MidiMessageSequence* msgSeq = midiFile.getTrack(i);
						
						OwnedArray<PluginDescription> results;
						String plugFile = "C:\\VST\\FMMF.dll";
						VSTPluginFormat vstFormat;
						vstFormat.findAllTypesForFile(results, plugFile);
						if (results.size() > 0) {
							msg.clear();
							msg << "Found " << results.size() << " plugin(s) matching file " << plugFile << "\n";
							log(msg);

							int secsToRender = 10;
							double sampleRate = 44100;
							int totalSizeInSamples = static_cast<int>(44100 * secsToRender);
							AudioPluginInstance* plugInst = vstFormat.createInstanceFromDescription(*results[0], sampleRate, totalSizeInSamples);
							if (!plugInst) {
								msg.clear();
								msg << "Failed to load plugin " << plugFile << "\n";
								log(msg);
								continue;
							}

							int numInputChannels = plugInst->getTotalNumInputChannels();
							int numOutputChannels = plugInst->getTotalNumOutputChannels();
							msg.clear();
							msg << "Plugin input channels: " << numInputChannels << " output channels: " << numOutputChannels 
								<< " Current program: " << plugInst->getCurrentProgram() << "\n";
							log(msg);

							int maxChannels = std::max(numInputChannels, numOutputChannels);
							AudioBuffer<float> buffer(maxChannels, totalSizeInSamples);
							
							MidiBuffer midiMessages;
							for (int j = 0; j < msgSeq->getNumEvents(); ++j)
							{
								MidiMessageSequence::MidiEventHolder* midiEventHolder = msgSeq->getEventPointer(j);
								MidiMessage midiMsg = midiEventHolder->message;
								int samplePos = static_cast<int>(midiMsg.getTimeStamp() * sampleRate);
								midiMessages.addEvent(midiMsg, samplePos);
							}

							plugInst->prepareToPlay(sampleRate, totalSizeInSamples);
							plugInst->processBlock(buffer, midiMessages);

							/*File txtOutFile("C:\\Users\\GeorgeKrueger\\Documents\\GitHub\\soundserver2\\out.txt");
							FileOutputStream* txtOutStream = txtOutFile.createOutputStream();
							for (int j = 0; j < 44100; ++j)
							{
								float sample = buffer.getSample(0, j);
								txtOutStream->writeFloat(sample);
								txtOutStream->writeText(" ", true, false);
							}*/

							File outputFile("C:\\Users\\GeorgeKrueger\\Documents\\GitHub\\soundserver2\\out.wav");
							if (outputFile.exists()) {
								outputFile.deleteFile();
							}
							FileOutputStream* fileOutputStream = outputFile.createOutputStream();
							WavAudioFormat wavFormat;
							StringPairArray metadataValues;
							juce::AudioFormatWriter* wavFormatWriter = wavFormat.createWriterFor(
								fileOutputStream, sampleRate, 2, 16, metadataValues, 0);
							bool writeAudioDataRet = wavFormatWriter->writeFromAudioSampleBuffer(buffer, 0, buffer.getNumSamples());
							wavFormatWriter->flush();

							msg.clear();
							msg << "Done writing to output file " << outputFile.getFileName() << " . Write return value: " 
								<< (int)writeAudioDataRet << "\n";
							log(msg);

							delete wavFormatWriter;
							delete plugInst;
						}
						else {
							msg.clear();
							msg << "Could not find plugin from file " << plugFile << "\n";
							log(msg);
						}
					}
				}
			}
		}
    bool update (CodeDocument& document, int lineNum,
                 CodeDocument::Iterator& source,
                 CodeTokeniser* analyser, const int spacesPerTab,
                 const CodeDocument::Position& selectionStart,
                 const CodeDocument::Position& selectionEnd)
    {
        OwnedArray <SyntaxToken> newTokens;

        if (analyser == 0)
        {
            newTokens.add (new SyntaxToken (document.getLine (lineNum), -1));
        }
        else if (lineNum < document.getNumLines())
        {
            const CodeDocument::Position pos (&document, lineNum, 0);
            createTokens (pos.getPosition(), pos.getLineText(),
                          source, analyser, newTokens);
        }

        replaceTabsWithSpaces (newTokens, spacesPerTab);

        int newHighlightStart = 0;
        int newHighlightEnd = 0;

        if (selectionStart.getLineNumber() <= lineNum && selectionEnd.getLineNumber() >= lineNum)
        {
            const String line (document.getLine (lineNum));

            CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0);
            newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()),
                                               line, spacesPerTab);
            newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()),
                                             line, spacesPerTab);
        }

        if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd)
        {
            highlightColumnStart = newHighlightStart;
            highlightColumnEnd = newHighlightEnd;
        }
        else
        {
            if (tokens.size() == newTokens.size())
            {
                bool allTheSame = true;

                for (int i = newTokens.size(); --i >= 0;)
                {
                    if (*tokens.getUnchecked(i) != *newTokens.getUnchecked(i))
                    {
                        allTheSame = false;
                        break;
                    }
                }

                if (allTheSame)
                    return false;
            }
        }

        tokens.swapWithArray (newTokens);
        return true;
    }
Esempio n. 29
0
void UploadWindow::filesDropped(const StringArray& filenames, int mouseX, int mouseY)
{
	StringArray extensions;
	extensions.addTokens(".jpg;.jpeg;.jpe;.png;.tif;.tiff;.png;.gif;.mpg;.mpeg;.mpe;.mov;.qt;.avi;.wmv", ";", "");

	UploadRequest* ur = new UploadRequest();
	for (int i = 0; i < filenames.size(); i++)
	{
		File imageFile(File::getCurrentWorkingDirectory().getChildFile (filenames[i]));
        
		if (imageFile.existsAsFile() && extensions.contains(imageFile.getFileExtension(), true))
		{
			ur->addImageFile(imageFile);
		}
		else if (imageFile.isDirectory())
		{
			Array<File> results;			
			imageFile.findChildFiles(results, File::findFiles, true);

			for (int i = 0; i < results.size(); i++)
			{
				if (extensions.contains(results[i].getFileExtension(), true))
					ur->addImageFile(results[i]);
			}
		}
	}

	if (ur->getNumImages() > 0)
	{
		Settings* settings = Settings::getInstance();
		if (settings->password.isEmpty() || settings->email.isEmpty())
			settings->showSettingsDialog();

		if (settings->password.isEmpty() || settings->email.isEmpty())
			return;

		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		if (!smugMug.isLoggedIn())
		{
			AlertWindow::showMessageBox(AlertWindow::WarningIcon, "Komodo Drop", "Error: Unable to connect to Smugmug.");
			return;
		}

		String defaultAlbumName;
		File root(filenames[0]);
		if (filenames.size() == 1 && root.isDirectory())
			defaultAlbumName = root.getFileName();
		else 
			defaultAlbumName = root.getParentDirectory().getFileName();

#ifdef JUCE_DEBUG
		defaultAlbumName = defaultAlbumName.replaceCharacter('_', ' ');
#endif

		SmugID albumId;
		bool open = false;
		if (Settings::getInstance()->silentUpload)
		{
			OwnedArray<Album> albums;
			smugMug.getAlbumList(albums);
			
			for (int i = 0; i < albums.size(); i++)
			{
				if (albums[i]->title == defaultAlbumName)
				{
					albumId = albums[i]->id;
					break;
				}
			}
			if (albumId.id == -1)
			{
				StringPairArray params;
				albumId = smugMug.createAlbum(defaultAlbumName, 0, params);
			}
			ur->setName(defaultAlbumName);
		}
		else
		{
			bool newAlbum;
			int catId;
			String title;
			StringPairArray params;

			UploadDialog* ud = new UploadDialog(&smugMug, defaultAlbumName, newAlbum, title, albumId, catId, params, open);
			if (ud->runModalLoop() == 1)
			{
				ur->setName(title);
				if (newAlbum)
					albumId = smugMug.createAlbum(title, catId, params);
			}
			else
			{
				return;
			}
		}

		if (albumId.id != -1)
		{
			ur->setOpenBrowser(open);
			ur->setAlbumId(albumId);
			smugMug.uploadImages(ur);
			startTimer(333);
			repaint();
		}
		else
		{
			delete ur;
		}
	}
	else
	{
		delete ur;
	}
	return;
}
Esempio n. 30
0
void UploadWindow::handleCommand(int res)
{
	if (res == 1)
	{
		if (!smugMug.isUploading() || AlertWindow::showOkCancelBox(AlertWindow::InfoIcon, "Komodo Drop", 
			"There is an upload in progress, quit anyway?") == 1)
		{
			JUCEApplication::quit();
		}
	}
	else if (res == 2)
	{
		Settings::getInstance()->showSettingsDialog();
	}
	else if (res == 3)
	{
		AlertWindow::showMessageBox(AlertWindow::InfoIcon, "Komodo Drop " + JUCEApplication::getInstance()->getApplicationVersion(), 
			"Created By: Roland Rabien ([email protected])\nBased on JUCE (www.rawmaterialsoftware.com)");
	}
	else if (res == 4)
	{
		setVisible(!isVisible());
	}
	else if (res == 5)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		OwnedArray<Album> albums;
		smugMug.getAlbumList(albums);
		if (albums.size() > 0)
		{
			ComboBox* album = new ComboBox("");
			album->setSize(300, 26);
			album->setVisible(true);

			for (int i = 0; i < albums.size(); i++)
				album->addItem(albums[i]->getDisplayTitle(), i + 1);
			album->setSelectedItemIndex(0);
			
			AlertWindow aw("Komodo Drop", "Delete album:", AlertWindow::InfoIcon);
			aw.addCustomComponent(album);
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1)
			{
				smugMug.deleteAlbum(albums[album->getSelectedId() - 1]->id);
			}
			delete album;
		}
	}
	else if (res == 6)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		OwnedArray<Category> categories;
		smugMug.getCategoryList(categories);
		if (categories.size())
		{
			ComboBox* cats = new ComboBox("");
			cats->setSize(300, 26);
			cats->setVisible(true);

			for (int i = 0; i < categories.size(); i++)
				cats->addItem(categories[i]->title, categories[i]->id + 1);
			cats->setSelectedItemIndex(0);
			
			AlertWindow aw("Komodo Drop", "Delete category:", AlertWindow::InfoIcon);
			aw.addCustomComponent(cats);
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1)
			{
				smugMug.deleteCategory(cats->getSelectedId() - 1);
			}
			delete cats;
		}
	}
	else if (res == 7)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		OwnedArray<Category> categories;
		smugMug.getCategoryList(categories);

		OwnedArray<SubCategory> subCategories;
		smugMug.getSubCategoryList(subCategories);

		if (subCategories.size())
		{
			ComboBox* cats = new ComboBox("");
			cats->setSize(300, 26);
			cats->setVisible(true);

			for (int i = 0; i < subCategories.size(); i++)
			{
				int j;
				for (j = 0; j < categories.size(); j++)
				{
					if (categories[j]->id == subCategories[i]->parentId)
						break;
				}
				cats->addItem(categories[j]->title + " >> " + subCategories[i]->title, subCategories[i]->id + 1);
			}
			cats->setSelectedItemIndex(0);
			
			AlertWindow aw("Komodo Drop", "Delete sub category:", AlertWindow::InfoIcon);
			aw.addCustomComponent(cats);
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1)
			{
				smugMug.deleteSubCategory(cats->getSelectedId() - 1);
			}
			delete cats;
		}
	}
	else if (res == 8)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

			AlertWindow aw("Komodo Drop", "Create category:", AlertWindow::InfoIcon);
			aw.addTextEditor("name", "", "category name:");
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1 && aw.getTextEditorContents("name").isNotEmpty())
			{
				smugMug.createCategory(aw.getTextEditorContents("name"));
			}
	}
	else if (res == 9)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		OwnedArray<Category> categories;
		smugMug.getCategoryList(categories);

		if (categories.size())
		{
			ComboBox* cats = new ComboBox("");
			cats->setSize(300, 26);
			cats->setVisible(true);

			for (int i = 0; i < categories.size(); i++)
				cats->addItem(categories[i]->title, categories[i]->id + 1);
			cats->setSelectedItemIndex(0);
			
			AlertWindow aw("Komodo Drop", "Create sub category:", AlertWindow::InfoIcon);
			aw.addCustomComponent(cats);
			aw.addTextEditor("name", "", "sub category name:");
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1 && aw.getTextEditorContents("name").isNotEmpty())
			{
				smugMug.createSubCategory(cats->getSelectedId() - 1, aw.getTextEditorContents("name"));
			}
			delete cats;
		}
	}
	else if (res == 10)
	{
		smugMug.cancelUploads();
	}
	else if (res == 11)
	{
		FileChooser fc("Komodo Drop", File::getSpecialLocation(File::userDocumentsDirectory));
		if (fc.browseForMultipleFilesToOpen())
		{
			const Array<File>& files = fc.getResults();
			StringArray names;

			for (int i = 0; i < files.size(); i++)
				names.add(files[i].getFullPathName());

			filesDropped(names, 0, 0);
		}
	}
	else if (res == 12)
	{
		FileChooser fc("Komodo Drop", File::getSpecialLocation(File::userDocumentsDirectory));
		if (fc.browseForDirectory())
		{
			File dir = fc.getResult();

			Array<File> files;
			StringArray names;
			dir.findChildFiles(files, File::findFiles, false);

			for (int i = 0; i < files.size(); i++)
				names.add(files[i].getFullPathName());

			if (names.size())
				filesDropped(names, 0, 0);
		}
	}
	else if (res == 13)
	{
		FileChooser fc("Komodo Drop", File::getSpecialLocation(File::userDocumentsDirectory));
		if (fc.browseForDirectory())
		{
			File dir = fc.getResult();

			Array<File> files;
			StringArray names;
			dir.findChildFiles(files, File::findFiles, true);

			for (int i = 0; i < files.size(); i++)
				names.add(files[i].getFullPathName());

			if (names.size())
				filesDropped(names, 0, 0);
		}
	}
	else if (res == 19)
	{
		FileChooser fc("Komodo Drop", File::getSpecialLocation(File::userDocumentsDirectory));
		if (fc.browseForDirectory())
		{
			File dir = fc.getResult();
			
			Array<File> folders;
			dir.findChildFiles(folders, File::findDirectories, false);
			
			for (int i = 0; i < folders.size(); i++)
			{
				Array<File> files;
				folders[i].findChildFiles(files, File::findFiles, true);
				
				StringArray names;
				for (int j = 0; j < files.size(); j++)
					names.add(files[j].getFullPathName());
				
				if (names.size())
					filesDropped(names, 0, 0);
			}
		}		
	}
	else if (res == 14)
	{
		smugMug.showLogFile();
	}
	else if (res == 15)
	{
		smugMug.clearLogFile();
	}
	else if (res == 16)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		OwnedArray<Album> albums;
		smugMug.getAlbumList(albums);
		if (albums.size() > 0)
		{
			ComboBox* album = new ComboBox("");
			album->setSize(300, 26);
			album->setVisible(true);

			for (int i = 0; i < albums.size(); i++)
				album->addItem(albums[i]->getDisplayTitle(), i + 1);
			album->setSelectedItemIndex(0);
			
			AlertWindow aw("Komodo Drop", "Delete duplicate images from album:", AlertWindow::InfoIcon);
			aw.addCustomComponent(album);
			aw.addButton("ok", 1);
			aw.addButton("cancel", 2);

			if (aw.runModalLoop() == 1)
			{
				smugMug.deleteDuplicates(albums[album->getSelectedId() - 1]->id);
			}
			delete album;
		}
	}
	else if (res == 17)
	{
		smugMug.showQueue();
	}
	else if (res == 18)
	{
		if (!smugMug.isLoggedIn())
			smugMug.login(Settings::getInstance()->email, Settings::getInstance()->password);

		smugMug.showTopPhotos();
	}
}