text: 
  
  #include "palettesscanpopup.h"
  #include "toonzqt/gutil.h"
  #include "tsystem.h"
  
  #include <QPushButton>
  #include <QLabel>
  
  //=============================================================================
  /*! \class PalettesScanPopup
  		\brief The PalettesScanPopup class provides a modal dialog to import
  					 palette in StudioPalette folder.
  
  		Inherits \b Dialog.
  		This object is composed of three sub-object: a \b FileField to choose a
  		folder, a label \b QLabel, generally empty, to show palette folder during
  		them import, and a button bar to start import or cancel command.
  
  		The class provides a method, \b setCurrentFolder(TFilePath path), to set
  		folder wherein import palettes.
  		Protected function allows to manage palette import.
  */
  PalettesScanPopup::PalettesScanPopup()
  	: Dialog(0, true, true, "PalettesScan"), m_folderPath(TFilePath()), m_timerId(0)
  {
  	setWindowTitle(tr("Search for Palettes"));
  	setFixedWidth(250);
  
  	m_field = new DVGui::FileField();
  	addWidget(m_field);
  
  	m_label = new QLabel();
  	m_label->setFixedWidth(200);
  	addWidget(m_label);
  
  	QPushButton *okBtn = new QPushButton(tr("Ok"), this);
  	okBtn->setDefault(true);
  	QPushButton *cancelBtn = new QPushButton(tr("Cancel"), this);
  	connect(okBtn, SIGNAL(clicked()), this, SLOT(onOkBtnClicked()));
  	connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
  	addButtonBarWidget(okBtn, cancelBtn);
  }
  
  //-----------------------------------------------------------------------------
  /*! Set current folder path to \b path.
  */
  void PalettesScanPopup::setCurrentFolder(TFilePath path)
  {
  	m_folderPath = path;
  }
  
  //-----------------------------------------------------------------------------
  /*! Return current folder path.
  */
  TFilePath PalettesScanPopup::getCurrentFolder()
  {
  	return m_folderPath;
  }
  
  //-----------------------------------------------------------------------------
  /*! Start palette import. Add \b FileField path to directories stack and start
  		a timer.
  */
  void PalettesScanPopup::onOkBtnClicked()
  {
  	m_timerId = startTimer(3);
  	TFilePathSet fps;
  	std::wstring s = m_field->getPath().toStdWString();
  	int i = 0, len = s.length();
  	while (i < len) {
  		while (i < len && (s[i] == ' ' || s[i] == '\t'))
  			i++;
  		if (i >= len)
  			break;
  		int j = i;
  		while (j < len && s[j] != ',')
  			j++;
  		int k = j;
  		while (k > i && (s[k - 1] == ' ' || s[k - 1] == '\t'))
  			k--;
  		std::wstring token = s.substr(i, k - i);
  		fps.push_back(TFilePath(token));
  		i = j + 1;
  	}
  	push(fps);
  }
  
  //-----------------------------------------------------------------------------
  /*! Set label text to path \b fp.
  */
  void PalettesScanPopup::setLabel(const TFilePath &fp)
  {
  	QString elideStr = elideText(toQString(fp), m_label->font(), m_label->width());
  	m_label->setText(elideStr);
  }
  
  //-----------------------------------------------------------------------------
  /*! Proceed in palette import recalling \b step(); if step() return false
  		stop timer, clear directories stack, and close popup sending accept event.
  */
  void PalettesScanPopup::timerEvent(QTimerEvent *event)
  {
  	bool ret = step();
  	if (!ret) {
  		killTimer(m_timerId);
  		clearStack();
  		QDialog::accept();
  	}
  }
  
  //-----------------------------------------------------------------------------
  /*! Push TFilePath \b fp to the top of directories stack. Set label text to fp.
  */
  void PalettesScanPopup::push(const TFilePath &fp)
  {
  	setLabel(fp);
  	Directory *dir = new Directory();
  	m_stack.push_back(dir);
  	dir->m_path = fp;
  	dir->m_files = TSystem::readDirectory(fp);
  	dir->m_it = dir->m_files.begin();
  }
  
  //-----------------------------------------------------------------------------
  /*! Push TFilePathSet \b fs to the top of directories stack. Set label text to
  		"<files>".
  */
  void PalettesScanPopup::push(const TFilePathSet &fs)
  {
  	m_label->setText(tr("<files>"));
  	Directory *dir = new Directory();
  	m_stack.push_back(dir);
  	dir->m_path = TFilePath();
  	dir->m_files = fs;
  	dir->m_it = dir->m_files.begin();
  }
  
  //-----------------------------------------------------------------------------
  /*! Removes the top item from the stack. If stack is empty return immediately.
  */
  void PalettesScanPopup::pop()
  {
  	if (m_stack.empty())
  		return;
  	Directory *dir = m_stack.back();
  	delete dir;
  	m_stack.pop_back();
  	if (!m_stack.empty()) {
  		dir = m_stack.back();
  		setLabel(dir->m_path);
  	} else
  		m_label->setText(tr(""));
  }
  
  //-----------------------------------------------------------------------------
  /*! Return true if direcories stack is not empty; otherwise return false.
  \n	If stack is not empty check current directory:
  \li	if all files are checked recall \b pop();
  \li	if its path is a directory recall \b push(const TFilePath &fp);
  \li	if its path is a file check its extension and recall \b onPlt(const TFilePath &fp).
  */
  bool PalettesScanPopup::step()
  {
  	if (m_stack.empty())
  		return false;
  	Directory *dir = m_stack.back();
  	if (dir->m_it == dir->m_files.end())
  		pop();
  	else {
  		TFilePath fp = *(dir->m_it)++;
  		if (TFileStatus(fp).isDirectory())
  			push(fp);
  		else {
  			setLabel(fp);
  			std::string ext = fp.getType();
  			if (ext == "plt" || ext == "tpl" || ext == "pli")
  				onPlt(fp);
  		}
  	}
  	return true;
  }
  
  //-----------------------------------------------------------------------------
  /*! Resets the content of the directories stack and set label text empty.
  */
  void PalettesScanPopup::clearStack()
  {
  	for (int i = 0; i < (int)m_stack.size(); i++)
  		delete m_stack[i];
  	m_stack.clear();
  	m_label->setText(tr(""));
  }
  
  //-----------------------------------------------------------------------------
  /*! Import palette, defined in path \b fp, in current \b StudioPalette folder.
  */
  void PalettesScanPopup::onPlt(const TFilePath &fp)
  {
  	TFilePath root(m_field->getPath().toStdString());
  	assert(root.isAncestorOf(fp));
  	TFilePath q = fp.getParentDir() - root;
  	StudioPalette::instance()->importPalette(m_folderPath + q, fp);
  }
  