bool VectorizerPopup::apply()
{
	std::set<TXshLevel *> levels;

	ToonzScene *scene = m_sceneHandle->getScene();
	if (!scene) {
		assert(scene);
		return false;
	}

	TSceneProperties *sceneProp = scene->getProperties();
	if (!sceneProp)
		return false;

	VectorizerParameters *vectorizerParameters = sceneProp->getVectorizerParameters();
	if (!vectorizerParameters)
		return false;

	int r0 = 0;
	int c0 = 0;
	int r1 = 0;
	int c1 = 0;
	bool isCellSelection = getSelectedLevels(levels, r0, c0, r1, c1);
	if (levels.empty()) {
		error(tr("The current selection is invalid."));
		return false;
	}

	//Initialize Progress bar
	m_progressDialog = new DVGui::ProgressDialog("", "Cancel", 0, 1);
	m_progressDialog->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint); //Don't show ? and X buttons
	m_progressDialog->setWindowTitle(QString("Convert To Vector..."));
	m_progressDialog->setAttribute(Qt::WA_DeleteOnClose);
	m_progressDialog->setWindowModality(Qt::WindowModal); //No user interaction is allowed during vectorization
	m_progressDialog->setFixedSize(200, 100);

	//Initialize vectorizer
	m_vectorizer = new Vectorizer;

	m_vectorizer->setParameters(*vectorizerParameters);

	connect(m_vectorizer, SIGNAL(frameName(QString)), this, SLOT(onFrameName(QString)), Qt::QueuedConnection);
	connect(m_vectorizer, SIGNAL(frameDone(int)), this, SLOT(onFrameDone(int)), Qt::QueuedConnection);
	connect(m_vectorizer, SIGNAL(partialDone(int, int)), this, SLOT(onPartialDone(int, int)), Qt::QueuedConnection);
	//We DON'T want the progress bar to be hidden at cancel press - since its modal
	//behavior prevents the user to interfere with a possibly still active vectorization.
	disconnect(m_progressDialog, SIGNAL(canceled()), m_progressDialog, SLOT(onCancel()));
	//We first inform the vectorizer of a cancel press;
	bool ret = connect(m_progressDialog, SIGNAL(canceled()), m_vectorizer, SLOT(cancel()));
	//which eventually transmits the command to vectorization core, allowing full-time cancels
	ret = ret && connect(m_progressDialog, SIGNAL(canceled()), m_vectorizer, SIGNAL(transmitCancel()));
	//Only after the vectorizer has terminated its process - or got cancelled, we are allowed
	//to proceed here.
	ret = ret && connect(m_vectorizer, SIGNAL(finished()), this, SLOT(onFinished()), Qt::QueuedConnection);
	assert(ret);

	int newIndexColumn = c1 + 1;
	std::set<TXshLevel *>::iterator it = levels.begin();
	for (it; it != levels.end(); it++) {
		TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(*it);
		if (!sl || !sl->getSimpleLevel() || !isLevelToConvert(sl)) {
			QString levelName = tr(toString(sl->getName()).c_str());
			QString errorMsg = tr("Cannot convert to vector the current selection.") + levelName;
			error(errorMsg);
			continue;
		}

		std::vector<TFrameId> fids;

		if (isCellSelection)
			getSelectedFids(fids, sl, r0, c0, r1, c1);
		else
			sl->getFids(fids);
		assert(fids.size() > 0);

		close();

		// Re-initialize progress Bar
		m_progressDialog->setMaximum(fids.size() * 100);
		m_progressDialog->setValue(0);
		m_currFrame = 0;

		// Re-initialize vectorizer
		m_vectorizer->setLevel(sl);
		m_vectorizer->setFids(fids);

		// Start vectorizing
		m_vectorizer->start();
		m_progressDialog->show();

		// Wait the vectorizer...
		while (!l_quitLoop)
			QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);

		l_quitLoop = false;

		// Assign output X-sheet cells
		TXshSimpleLevel *vl = m_vectorizer->getVectorizedLevel();
		if (isCellSelection && vl) {
			TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet();
			xsheet->insertColumn(newIndexColumn);

			int r, c;
			for (c = c0; c <= c1; c++) {
				for (r = r0; r <= r1; r++) {
					TXshCell cell = xsheet->getCell(r, c);
					TXshSimpleLevel *level = (!cell.isEmpty()) ? cell.getSimpleLevel()
															   : 0;
					if (level != sl)
						continue;
					TFrameId curFid = cell.getFrameId();
					std::vector<TFrameId> newFids;
					vl->getFids(newFids);
					std::vector<TFrameId>::iterator it1 = newFids.begin();
					for (it1; it1 != newFids.end(); it1++) {
						TFrameId id = *it1;
						if (id.getNumber() == curFid.getNumber() ||			   // Hanno stesso numero di frame
							(id.getNumber() == 1 && curFid.getNumber() == -2)) // La vecchia cella non ha numero di frame
							xsheet->setCell(r, newIndexColumn, TXshCell(vl, id));
					}
				}
			}
			newIndexColumn += 1;
		} else if (vl) {
			std::vector<TFrameId> gomi;
			scene->getXsheet()->exposeLevel(0, scene->getXsheet()->getFirstFreeColumnIndex(), vl, gomi);
		}

		if (m_vectorizer->isCanceled())
			break;
	}

	m_progressDialog->close();
	delete m_vectorizer;

	TApp::instance()->getCurrentScene()->notifyCastChange();
	TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();

	return true;
}