diff --git a/toonz/sources/toonz/scenebrowser.cpp b/toonz/sources/toonz/scenebrowser.cpp
new file mode 100644
index 0000000..6cea7fb
--- /dev/null
+++ b/toonz/sources/toonz/scenebrowser.cpp
@@ -0,0 +1,2428 @@
+
+
+#include "filebrowser.h"
+
+// Tnz6 includes
+#include "dvdirtreeview.h"
+#include "filebrowsermodel.h"
+#include "fileselection.h"
+#include "filmstripselection.h"
+#include "castselection.h"
+#include "menubarcommandids.h"
+#include "floatingpanelcommand.h"
+#include "iocommand.h"
+#include "history.h"
+#include "tapp.h"
+
+// TnzQt includes
+#include "toonzqt/dvdialog.h"
+#include "toonzqt/icongenerator.h"
+#include "toonzqt/menubarcommand.h"
+#include "toonzqt/gutil.h"
+#include "toonzqt/trepetitionguard.h"
+
+// TnzLib includes
+#include "toonz/tscenehandle.h"
+#include "toonz/toonzscene.h"
+#include "toonz/txshsimplelevel.h"
+#include "toonz/txshsoundlevel.h"
+#include "toonz/tproject.h"
+#include "toonz/txshlevelhandle.h"
+#include "toonz/namebuilder.h"
+#include "toonz/toonzimageutils.h"
+#include "toonz/preferences.h"
+
+// TnzBase includes
+#include "tenv.h"
+
+// TnzCore includes
+#include "tsystem.h"
+#include "tconvert.h"
+#include "tfiletype.h"
+#include "tlevel_io.h"
+
+// Qt includes
+#include <QDrag>
+#include <QDragEnterEvent>
+#include <QDragMoveEvent>
+#include <QDropEvent>
+#include <QDragLeaveEvent>
+#include <QBoxLayout>
+#include <QLabel>
+#include <QByteArray>
+#include <QMenu>
+#include <QDateTime>
+#include <QInputDialog>
+#include <QDesktopServices>
+#include <QDirModel>
+#include <QDir>
+#include <QPixmap>
+#include <QUrl>
+#include <QRegExp>
+#include <QScrollBar>
+#include <QMap>
+#include <QPushButton>
+#include <QPalette>
+#include <QCheckBox>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QMessageBox>
+#include <QApplication>
+#include <QFormLayout>
+#include <QMainWindow>
+#include <QLineEdit>
+#include <QTreeWidgetItem>
+#include <QSplitter>
+#include <QFileSystemWatcher>
+
+// tcg includes
+#include "tcg/boost/range_utility.h"
+#include "tcg/boost/permuted_range.h"
+
+// boost includes
+#include <boost/bind.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+
+namespace ba = boost::adaptors;
+
+using namespace DVGui;
+
+//=============================================================================
+//      Local declarations
+//=============================================================================
+
+//============================
+//    FrameCountTask class
+//----------------------------
+
+class FrameCountTask final : public TThread::Runnable {
+  bool m_started;
+
+  TFilePath m_path;
+  QDateTime m_modifiedDate;
+
+public:
+  FrameCountTask(const TFilePath &path, const QDateTime &modifiedDate);
+
+  ~FrameCountTask();
+
+  void run() override;
+
+  QThread::Priority runningPriority() override;
+
+public slots:
+
+  void onStarted(TThread::RunnableP thisTask) override;
+  void onCanceled(TThread::RunnableP thisTask) override;
+};
+
+//============================
+//    FCData struct
+//----------------------------
+
+struct FCData {
+  QDateTime m_date;
+  int m_frameCount;
+  bool m_underProgress;
+  int m_retryCount;
+
+  FCData() {}
+  FCData(const QDateTime &date);
+};
+
+//=============================================================================
+//      Local namespace
+//=============================================================================
+
+namespace {
+std::set<FileBrowser *> activeBrowsers;
+std::map<TFilePath, FCData> frameCountMap;
+QMutex frameCountMapMutex;
+QMutex levelFileMutex;
+
+}  // namespace
+
+inline bool isMultipleFrameType(std::string type) {
+  return (type == "tlv" || type == "tzl" || type == "pli" || type == "mov" ||
+          type == "avi" || type == "3gp" || type == "gif" || type == "mp4" ||
+          type == "webm");
+}
+
+//=============================================================================
+// FileBrowser
+//-----------------------------------------------------------------------------
+
+#if QT_VERSION >= 0x050500
+FileBrowser::FileBrowser(QWidget *parent, Qt::WindowFlags flags,
+                         bool noContextMenu, bool multiSelectionEnabled)
+#else
+FileBrowser::FileBrowser(QWidget *parent, Qt::WFlags flags, bool noContextMenu,
+                         bool multiSelectionEnabled)
+#endif
+    : QFrame(parent), m_folderName(0), m_itemViewer(0) {
+  // style sheet
+  setObjectName("FileBrowser");
+  setFrameStyle(QFrame::StyledPanel);
+
+  m_mainSplitter      = new QSplitter(this);
+  m_folderTreeView    = new DvDirTreeView(this);
+  QFrame *box         = new QFrame(this);
+  QLabel *folderLabel = new QLabel(tr("Folder: "), this);
+  m_folderName        = new QLineEdit();
+  m_itemViewer = new DvItemViewer(box, noContextMenu, multiSelectionEnabled,
+                                  DvItemViewer::Browser);
+  DvItemViewerTitleBar *titleBar = new DvItemViewerTitleBar(m_itemViewer, box);
+  DvItemViewerButtonBar *buttonBar =
+      new DvItemViewerButtonBar(m_itemViewer, box);
+  DvItemViewerPanel *viewerPanel = m_itemViewer->getPanel();
+
+  viewerPanel->addColumn(DvItemListModel::FileType, 50);
+  viewerPanel->addColumn(DvItemListModel::FrameCount, 50);
+  viewerPanel->addColumn(DvItemListModel::FileSize, 50);
+  viewerPanel->addColumn(DvItemListModel::CreationDate, 130);
+  viewerPanel->addColumn(DvItemListModel::ModifiedDate, 130);
+  if (Preferences::instance()->isSVNEnabled())
+    viewerPanel->addColumn(DvItemListModel::VersionControlStatus, 120);
+
+  viewerPanel->setSelection(new FileSelection());
+  DVItemViewPlayDelegate *itemViewPlayDelegate =
+      new DVItemViewPlayDelegate(viewerPanel);
+  viewerPanel->setItemViewPlayDelegate(itemViewPlayDelegate);
+
+  m_mainSplitter->setObjectName("FileBrowserSplitter");
+  m_folderTreeView->setObjectName("DirTreeView");
+  box->setObjectName("castFrame");
+  box->setFrameStyle(QFrame::StyledPanel);
+
+  m_itemViewer->setModel(this);
+
+  // layout
+  QVBoxLayout *mainLayout = new QVBoxLayout();
+  mainLayout->setMargin(3);
+  mainLayout->setSpacing(2);
+  {
+    mainLayout->addWidget(buttonBar);
+
+    QHBoxLayout *folderLay = new QHBoxLayout();
+    folderLay->setMargin(0);
+    folderLay->setSpacing(0);
+    {
+      folderLay->addWidget(folderLabel, 0);
+      folderLay->addWidget(m_folderName, 1);
+    }
+    mainLayout->addLayout(folderLay, 0);
+
+    m_mainSplitter->addWidget(m_folderTreeView);
+    QVBoxLayout *boxLayout = new QVBoxLayout(box);
+    boxLayout->setMargin(0);
+    boxLayout->setSpacing(0);
+    {
+      boxLayout->addWidget(titleBar, 0);
+      boxLayout->addWidget(m_itemViewer, 1);
+    }
+    m_mainSplitter->addWidget(box);
+    mainLayout->addWidget(m_mainSplitter, 1);
+  }
+  setLayout(mainLayout);
+
+  m_mainSplitter->setSizes(QList<int>() << 270 << 500);
+
+  // signal-slot connections
+  bool ret = connect(m_folderTreeView, SIGNAL(currentNodeChanged()),
+                     itemViewPlayDelegate, SLOT(resetPlayWidget()));
+  // if the current forder is changed in the folder tree, then update in the
+  // item view
+  ret = ret && connect(m_folderTreeView, SIGNAL(currentNodeChanged()), this,
+                       SLOT(onTreeFolderChanged()));
+
+  ret = ret && connect(m_itemViewer, SIGNAL(clickedItem(int)), this,
+                       SLOT(onClickedItem(int)));
+  ret = ret && connect(m_itemViewer, SIGNAL(doubleClickedItem(int)), this,
+                       SLOT(onDoubleClickedItem(int)));
+  ret =
+      ret && connect(m_itemViewer, SIGNAL(selectedItems(const std::set<int> &)),
+                     this, SLOT(onSelectedItems(const std::set<int> &)));
+  ret = ret && connect(buttonBar, SIGNAL(folderUp()), this, SLOT(folderUp()));
+  ret = ret && connect(buttonBar, SIGNAL(newFolder()), this, SLOT(newFolder()));
+
+  ret = ret && connect(&m_frameCountReader, SIGNAL(calculatedFrameCount()),
+                       m_itemViewer->getPanel(), SLOT(update()));
+
+  QAction *refresh = CommandManager::instance()->getAction(MI_RefreshTree);
+  ret = ret && connect(refresh, SIGNAL(triggered()), this, SLOT(refresh()));
+  addAction(refresh);
+
+  // Version Control instance connection
+  if (Preferences::instance()->isSVNEnabled())
+    ret =
+        ret && connect(VersionControl::instance(),
+                       SIGNAL(commandDone(const QStringList &)), this,
+                       SLOT(onVersionControlCommandDone(const QStringList &)));
+
+  // if the folderName is edited, move the current folder accordingly
+  ret = ret && connect(m_folderName, SIGNAL(editingFinished()), this,
+                       SLOT(onFolderEdited()));
+
+  // folder history
+  ret = ret && connect(m_folderTreeView, SIGNAL(currentNodeChanged()), this,
+                       SLOT(storeFolderHistory()));
+  ret = ret && connect(buttonBar, SIGNAL(folderBack()), this,
+                       SLOT(onBackButtonPushed()));
+  ret = ret && connect(buttonBar, SIGNAL(folderFwd()), this,
+                       SLOT(onFwdButtonPushed()));
+  // when the history changes, enable/disable the history buttons accordingly
+  ret = ret && connect(this, SIGNAL(historyChanged(bool, bool)), buttonBar,
+                       SLOT(onHistoryChanged(bool, bool)));
+
+  // check out the update of the current folder.
+  // Use MyFileSystemWatcher which is shared by all browsers.
+  // Adding and removing paths to the watcher is done in DvDirTreeView.
+  ret = ret && connect(MyFileSystemWatcher::instance(),
+                       SIGNAL(directoryChanged(const QString &)), this,
+                       SLOT(onFileSystemChanged(const QString &)));
+
+  // store the first item("Root") in the history
+  m_indexHistoryList.append(m_folderTreeView->currentIndex());
+  m_currentPosition = 0;
+
+  refreshHistoryButtons();
+
+  assert(ret);
+}
+
+//-----------------------------------------------------------------------------
+
+FileBrowser::~FileBrowser() {}
+
+//-----------------------------------------------------------------------------
+/*! when the m_folderName is edited, move the current folder accordingly
+ */
+void FileBrowser::onFolderEdited() {
+  TFilePath inputPath(m_folderName->text().toStdWString());
+  QModelIndex index = DvDirModel::instance()->getIndexByPath(inputPath);
+
+  // If there is no node matched
+  if (!index.isValid()) {
+    QMessageBox::warning(this, tr("Open folder failed"),
+                         tr("The input folder path was invalid."));
+    return;
+  }
+  m_folderTreeView->collapseAll();
+
+  m_folderTreeView->setCurrentIndex(index);
+
+  // expand the folder tree
+  QModelIndex tmpIndex = index;
+  while (tmpIndex.isValid()) {
+    m_folderTreeView->expand(tmpIndex);
+    tmpIndex = tmpIndex.parent();
+  }
+
+  m_folderTreeView->scrollTo(index);
+  m_folderTreeView->update();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::storeFolderHistory() {
+  QModelIndex currentModelIndex = m_folderTreeView->currentIndex();
+
+  if (!currentModelIndex.isValid()) return;
+
+  if (m_indexHistoryList[m_currentPosition] == currentModelIndex) return;
+
+  // If there is no next history item, then create it
+  if (m_currentPosition == m_indexHistoryList.size() - 1) {
+    m_indexHistoryList << currentModelIndex;
+    m_currentPosition++;
+  }
+  // If the next hitory item is the same as the current one, just move to it
+  else if (m_indexHistoryList[m_currentPosition + 1] == currentModelIndex) {
+    m_currentPosition++;
+  }
+  // If the next history item is different from the current one, then replace
+  // with the new one
+  else {
+    int size = m_indexHistoryList.size();
+    // remove the old history items
+    for (int i = m_currentPosition + 1; i < size; i++)
+      m_indexHistoryList.removeLast();
+    m_indexHistoryList << currentModelIndex;
+    m_currentPosition++;
+  }
+  refreshHistoryButtons();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::refreshHistoryButtons() {
+  emit historyChanged((m_currentPosition != 0),
+                      (m_currentPosition != m_indexHistoryList.size() - 1));
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onBackButtonPushed() {
+  if (m_currentPosition == 0) return;
+  m_currentPosition--;
+  QModelIndex currentIndex = m_indexHistoryList[m_currentPosition];
+  m_folderTreeView->setCurrentIndex(currentIndex);
+  m_folderTreeView->collapseAll();
+  while (currentIndex.isValid()) {
+    currentIndex = currentIndex.parent();
+    m_folderTreeView->expand(currentIndex);
+  }
+  m_folderTreeView->update();
+
+  refreshHistoryButtons();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onFwdButtonPushed() {
+  if (m_currentPosition >= m_indexHistoryList.size() - 1) return;
+  m_currentPosition++;
+  QModelIndex currentIndex = m_indexHistoryList[m_currentPosition];
+  m_folderTreeView->setCurrentIndex(currentIndex);
+  m_folderTreeView->collapseAll();
+  while (currentIndex.isValid()) {
+    currentIndex = currentIndex.parent();
+    m_folderTreeView->expand(currentIndex);
+  }
+  m_folderTreeView->update();
+
+  refreshHistoryButtons();
+}
+
+//-----------------------------------------------------------------------------
+/*! clear the history when the tree date is replaced
+ */
+void FileBrowser::clearHistory() {
+  int size = m_indexHistoryList.size();
+  // leave the last item
+  for (int i = 1; i < size; i++) m_indexHistoryList.removeLast();
+  m_currentPosition = 0;
+  refreshHistoryButtons();
+}
+
+//-----------------------------------------------------------------------------
+/*! update the current folder when changes detected from QFileSystemWatcher
+ */
+void FileBrowser::onFileSystemChanged(const QString &folderPath) {
+  if (folderPath != m_folder.getQString()) return;
+  // changes may create/delete of folder, so update the DvDirModel
+  QModelIndex parentFolderIndex = m_folderTreeView->currentIndex();
+  DvDirModel::instance()->refresh(parentFolderIndex);
+
+  refreshCurrentFolderItems();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::sortByDataModel(DataType dataType, bool isDiscendent) {
+  struct locals {
+    static inline bool itemLess(int aIdx, int bIdx, FileBrowser &fb,
+                                DataType dataType) {
+      return (fb.compareData(dataType, aIdx, bIdx) > 0);
+    }
+
+    static inline bool indexLess(int aIdx, int bIdx,
+                                 const std::vector<int> &vec) {
+      return (vec[aIdx] < vec[bIdx]);
+    }
+
+    static inline int complement(int val, int max) {
+      return (assert(0 <= val && val <= max), max - val);
+    }
+  };  // locals
+
+  if (dataType != getCurrentOrderType()) {
+    // Build the permutation table
+    std::vector<int> new2OldIdx(
+        boost::make_counting_iterator(0),
+        boost::make_counting_iterator(int(m_items.size())));
+
+    std::stable_sort(
+        new2OldIdx.begin(), new2OldIdx.end(),
+        boost::bind(locals::itemLess, _1, _2, boost::ref(*this), dataType));
+
+    // Use the renumbering table to permutate elements
+    std::vector<Item>(
+        boost::make_permutation_iterator(m_items.begin(), new2OldIdx.begin()),
+        boost::make_permutation_iterator(m_items.begin(), new2OldIdx.end()))
+        .swap(m_items);
+
+    // Use the permutation table to update current file selection, if any
+    FileSelection *fs =
+        static_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+
+    if (!fs->isEmpty()) {
+      std::vector<int> old2NewIdx(
+          boost::make_counting_iterator(0),
+          boost::make_counting_iterator(int(m_items.size())));
+
+      std::sort(old2NewIdx.begin(), old2NewIdx.end(),
+                boost::bind(locals::indexLess, _1, _2, boost::ref(new2OldIdx)));
+
+      std::vector<int> newSelectedIndices;
+      tcg::substitute(
+          newSelectedIndices,
+          tcg::permuted_range(old2NewIdx, fs->getSelectedIndices() |
+                                              ba::filtered(boost::bind(
+                                                  std::less<int>(), _1,
+                                                  int(old2NewIdx.size())))));
+
+      fs->select(!newSelectedIndices.empty() ? &newSelectedIndices.front() : 0,
+                 int(newSelectedIndices.size()));
+    }
+
+    setIsDiscendentOrder(true);
+    setOrderType(dataType);
+  }
+
+  // Reverse lists if necessary
+  if (isDiscendentOrder() != isDiscendent) {
+    std::reverse(m_items.begin(), m_items.end());
+
+    // Reverse file selection, if any
+    FileSelection *fs =
+        dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+
+    if (!fs->isEmpty()) {
+      int iCount = int(m_items.size()), lastIdx = iCount - 1;
+
+      std::vector<int> newSelectedIndices;
+      tcg::substitute(
+          newSelectedIndices,
+          fs->getSelectedIndices() |
+              ba::filtered(boost::bind(std::less<int>(), _1, iCount)) |
+              ba::transformed(boost::bind(locals::complement, _1, lastIdx)));
+
+      fs->select(!newSelectedIndices.empty() ? &newSelectedIndices.front() : 0,
+                 int(newSelectedIndices.size()));
+    }
+
+    setIsDiscendentOrder(isDiscendent);
+  }
+
+  m_itemViewer->getPanel()->update();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::setFilterTypes(const QStringList &types) { m_filter = types; }
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::addFilterType(const QString &type) {
+  if (!m_filter.contains(type)) m_filter.push_back(type);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::removeFilterType(const QString &type) {
+  m_filter.removeAll(type);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::refreshCurrentFolderItems() {
+  m_items.clear();
+
+  // put the parent directory item
+  TFilePath parentFp = m_folder.getParentDir();
+  if (parentFp != TFilePath("") && parentFp != m_folder)
+    m_items.push_back(Item(parentFp, true, false));
+
+  // register the all folder items by using the folde tree model
+  DvDirModel *model        = DvDirModel::instance();
+  QModelIndex currentIndex = model->getIndexByPath(m_folder);
+  if (currentIndex.isValid()) {
+    for (int i = 0; i < model->rowCount(currentIndex); i++) {
+      QModelIndex tmpIndex = model->index(i, 0, currentIndex);
+      if (tmpIndex.isValid()) {
+        DvDirModelFileFolderNode *node =
+            dynamic_cast<DvDirModelFileFolderNode *>(model->getNode(tmpIndex));
+        if (node) {
+          TFilePath childFolderPath = node->getPath();
+          if (TFileStatus(childFolderPath).isLink())
+            m_items.push_back(Item(childFolderPath, true, true,
+                                   QString::fromStdWString(node->getName())));
+          else
+            m_items.push_back(Item(childFolderPath, true, false,
+                                   QString::fromStdWString(node->getName())));
+        }
+      }
+    }
+  } else
+    setUnregisteredFolder(m_folder);
+
+  // register the file items
+  if (m_folder != TFilePath()) {
+    TFilePathSet files;
+    TFilePathSet all_files;  // for updating m_multiFileItemMap
+
+    TFileStatus fpStatus(m_folder);
+    // if the item is link, then set the link target of it
+    if (fpStatus.isLink()) {
+      QFileInfo info(toQString(m_folder));
+      setFolder(TFilePath(info.symLinkTarget().toStdWString()));
+      return;
+    }
+    if (fpStatus.doesExist() && fpStatus.isDirectory() &&
+        fpStatus.isReadable()) {
+      try {
+        TSystem::readDirectory(files, all_files, m_folder);
+      } catch (...) {
+      }
+    }
+    TFilePathSet::iterator it;
+    for (it = files.begin(); it != files.end(); ++it) {
+#ifdef _WIN32
+      // include folder shortcut items
+      if (it->getType() == "lnk") {
+        TFileStatus info(*it);
+        if (info.isLink() && info.isDirectory()) {
+          m_items.push_back(
+              Item(*it, true, true, QString::fromStdString((*it).getName())));
+        }
+        continue;
+      }
+#endif
+      // skip the plt file (Palette file for TOONZ 4.6 and earlier)
+      if (it->getType() == "plt") continue;
+
+      // filter the file
+      else if (m_filter.isEmpty()) {
+        if (it->getType() != "tnz" && it->getType() != "scr" &&
+            it->getType() != "tnzbat" && it->getType() != "mpath" &&
+            it->getType() != "curve" && it->getType() != "tpl" &&
+            TFileType::getInfo(*it) == TFileType::UNKNOW_FILE)
+          continue;
+      } else if (!m_filter.contains(QString::fromStdString(it->getType())))
+        continue;
+      // store the filtered file paths
+      m_items.push_back(Item(*it));
+    }
+
+    // update the m_multiFileItemMap
+    m_multiFileItemMap.clear();
+
+    for (it = all_files.begin(); it != all_files.end(); it++) {
+      TFrameId tFrameId;
+      try {
+        tFrameId = it->getFrame();
+      } catch (TMalformedFrameException tmfe) {
+        // Incorrect frame name sequence. Warning to the user in the message
+        // center.
+        DVGui::warning(QString::fromStdWString(
+            tmfe.getMessage() + L": " +
+            QObject::tr("Skipping frame.").toStdWString()));
+        continue;
+      }
+
+      TFilePath levelName(it->getLevelName());
+
+      if (levelName.isLevelName()) {
+        Item &levelItem = m_multiFileItemMap[levelName];
+
+        // TODO:
+        // とりあえず残すが、FileInfoの取得に時間がかかるようならオプション化も検討
+        // 2015/12/28 shun_iwasawa
+        QFileInfo fileInfo(QString::fromStdWString(it->getWideString()));
+        // Update level infos
+        if (levelItem.m_creationDate.isNull() ||
+            (fileInfo.created() < levelItem.m_creationDate))
+          levelItem.m_creationDate = fileInfo.created();
+        if (levelItem.m_modifiedDate.isNull() ||
+            (fileInfo.lastModified() > levelItem.m_modifiedDate))
+          levelItem.m_modifiedDate = fileInfo.lastModified();
+        levelItem.m_fileSize += fileInfo.size();
+
+        // store frameId
+        levelItem.m_frameIds.push_back(tFrameId);
+
+        levelItem.m_frameCount++;
+      }
+    }
+  }
+
+  // Set Missing Version Control Items
+  int missingItemCount          = 0;
+  DvDirVersionControlNode *node = dynamic_cast<DvDirVersionControlNode *>(
+      m_folderTreeView->getCurrentNode());
+  if (node) {
+    QList<TFilePath> list = node->getMissingFiles();
+    missingItemCount      = list.size();
+    for (int i = 0; i < missingItemCount; i++)
+      m_items.push_back(Item(list.at(i)));
+  }
+
+  // Refresh Data (fill Item field)
+  refreshData();
+
+  // If I added some missing items I need to sort items.
+  if (missingItemCount > 0) {
+    DataType currentDataType = getCurrentOrderType();
+    int i;
+    for (i = 1; i < m_items.size(); i++) {
+      int index = i;
+      while (index > 0 && compareData(currentDataType, index - 1, index) > 0) {
+        std::swap(m_items[index - 1], m_items[index]);
+        index = index - 1;
+      }
+    }
+  }
+  // update the ordering rules
+  bool discendentOrder     = isDiscendentOrder();
+  DataType currentDataType = getCurrentOrderType();
+  setOrderType(Name);
+  setIsDiscendentOrder(true);
+  sortByDataModel(currentDataType, discendentOrder);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::setFolder(const TFilePath &fp, bool expandNode,
+                            bool forceUpdate) {
+  if (fp == m_folder && !forceUpdate) return;
+
+  // set the current folder path
+  m_folder        = fp;
+  m_dayDateString = "";
+  // set the folder name
+  if (fp == TFilePath())
+    m_folderName->setText("");
+  else
+    m_folderName->setText(toQString(fp));
+
+  refreshCurrentFolderItems();
+
+  if (!TFileStatus(fp).isLink())
+    m_folderTreeView->setCurrentNode(fp, expandNode);
+}
+
+//-----------------------------------------------------------------------------
+/*! process when inputting the folder which is not regitered in the folder tree
+   (e.g. UNC path in Windows)
+ */
+void FileBrowser::setUnregisteredFolder(const TFilePath &fp) {
+  if (fp != TFilePath()) {
+    TFileStatus fpStatus(fp);
+    // if the item is link, then set the link target of it
+    if (fpStatus.isLink()) {
+      QFileInfo info(toQString(fp));
+      setFolder(TFilePath(info.symLinkTarget().toStdWString()));
+      return;
+    }
+
+    // get both the folder & file list by readDirectory and
+    // readDirectory_Dir_ReadExe
+    TFilePathSet folders;
+    TFilePathSet files;
+    // for updating m_multiFileItemMap
+    TFilePathSet all_files;
+
+    if (fpStatus.doesExist() && fpStatus.isDirectory() &&
+        fpStatus.isReadable()) {
+      try {
+        TSystem::readDirectory(files, all_files, fp);
+        TSystem::readDirectory_Dir_ReadExe(folders, fp);
+      } catch (...) {
+      }
+    }
+
+    TFilePathSet::iterator it;
+
+    // register all folder items
+    for (it = folders.begin(); it != folders.end(); ++it) {
+      if (TFileStatus(*it).isLink())
+        m_items.push_back(Item(*it, true, true));
+      else
+        m_items.push_back(Item(*it, true, false));
+    }
+
+    for (it = files.begin(); it != files.end(); ++it) {
+#ifdef _WIN32
+      // include folder shortcut items
+      if (it->getType() == "lnk") {
+        TFileStatus info(*it);
+        if (info.isLink() && info.isDirectory()) {
+          m_items.push_back(
+              Item(*it, true, true, QString::fromStdString((*it).getName())));
+        }
+        continue;
+      }
+#endif
+      // skip the plt file (Palette file for TOONZ 4.6 and earlier)
+      if (it->getType() == "plt") continue;
+
+      // filtering
+      else if (m_filter.isEmpty()) {
+        if (it->getType() != "tnz" && it->getType() != "scr" &&
+            it->getType() != "tnzbat" && it->getType() != "mpath" &&
+            it->getType() != "curve" && it->getType() != "tpl" &&
+            TFileType::getInfo(*it) == TFileType::UNKNOW_FILE)
+          continue;
+      } else if (!m_filter.contains(QString::fromStdString(it->getType())))
+        continue;
+
+      m_items.push_back(Item(*it));
+    }
+
+    // update the m_multiFileItemMap
+    m_multiFileItemMap.clear();
+    for (it = all_files.begin(); it != all_files.end(); it++) {
+      TFilePath levelName(it->getLevelName());
+      if (levelName.isLevelName()) {
+        Item &levelItem = m_multiFileItemMap[levelName];
+        levelItem.m_frameIds.push_back(it->getFrame());
+        levelItem.m_frameCount++;
+      }
+    }
+  }
+  // for all items in the folder, retrieve the file names(m_name) from the
+  // paths(m_path)
+  refreshData();
+
+  // update the ordering rules
+  bool discendentOrder     = isDiscendentOrder();
+  DataType currentDataType = getCurrentOrderType();
+  setOrderType(Name);
+  setIsDiscendentOrder(true);
+  sortByDataModel(currentDataType, discendentOrder);
+
+  m_itemViewer->repaint();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::setHistoryDay(std::string dayDateString) {
+  m_folder                = TFilePath();
+  m_dayDateString         = dayDateString;
+  const History::Day *day = History::instance()->getDay(dayDateString);
+  m_items.clear();
+  if (day == 0) {
+    m_folderName->setText("");
+  } else {
+    m_folderName->setText(QString::fromStdString(dayDateString));
+    std::vector<TFilePath> files;
+    day->getFiles(files);
+    std::vector<TFilePath>::iterator it;
+    for (it = files.begin(); it != files.end(); ++it)
+      m_items.push_back(Item(*it));
+  }
+  refreshData();
+}
+
+//-----------------------------------------------------------------------------
+/*! for all items in the folder, retrieve the file names(m_name) from the
+ * paths(m_path)
+ */
+void FileBrowser::refreshData() {
+  std::vector<Item>::iterator it;
+  for (it = m_items.begin(); it != m_items.end(); ++it) {
+    if (it->m_name == QString(""))
+      it->m_name = toQString(it->m_path.withoutParentDir());
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+int FileBrowser::getItemCount() const { return m_items.size(); }
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::readInfo(Item &item) {
+  TFilePath fp = item.m_path;
+  QFileInfo info(toQString(fp));
+  if (info.exists()) {
+    item.m_creationDate = info.created();
+    item.m_modifiedDate = info.lastModified();
+    item.m_fileType     = info.suffix();
+    item.m_fileSize     = info.size();
+    if (fp.getType() == "tnz") {
+      ToonzScene scene;
+      try {
+        item.m_frameCount = scene.loadFrameCount(fp);
+      } catch (...) {
+      }
+    } else
+      readFrameCount(item);
+
+    item.m_validInfo = true;
+  } else if (fp.isLevelName())  // for levels johndoe..tif etc.
+  {
+    try {
+      // Find this level's item
+      std::map<TFilePath, Item>::iterator it =
+          m_multiFileItemMap.find(TFilePath(item.m_path.getLevelName()));
+      if (it == m_multiFileItemMap.end()) throw "";
+
+      item.m_creationDate = it->second.m_creationDate;
+      item.m_modifiedDate = it->second.m_modifiedDate;
+      item.m_fileType     = it->second.m_fileType;
+      item.m_fileSize     = it->second.m_fileSize;
+      item.m_frameCount   = it->second.m_frameCount;
+      item.m_validInfo    = true;
+
+      // keep the list of frameIds at the first time and try to reuse it.
+      item.m_frameIds = it->second.m_frameIds;
+
+      // The old way
+      /*TLevelReaderP lr(fp);
+item.m_frameCount = lr->loadInfo()->getFrameCount();
+item.m_creationDate = QDateTime();
+item.m_modifiedDate = QDateTime();
+item.m_fileSize = -1;
+item.m_validInfo = true;*/
+    } catch (...) {
+      item.m_frameCount = 0;
+    }
+  }
+
+  item.m_validInfo = true;
+}
+
+//-----------------------------------------------------------------------------
+
+//! Frame count needs a special access function for viewable types - for they
+//! are
+//! calculated by using a dedicated thread and therefore cannot be simply
+//! classified as *valid* or *invalid* infos...
+void FileBrowser::readFrameCount(Item &item) {
+  if (TFileType::isViewable(TFileType::getInfo(item.m_path))) {
+    if (isMultipleFrameType(item.m_path.getType()))
+      item.m_frameCount = m_frameCountReader.getFrameCount(item.m_path);
+    else
+      item.m_frameCount = 1;
+  } else
+    item.m_frameCount = 0;
+}
+
+//-----------------------------------------------------------------------------
+
+QVariant FileBrowser::getItemData(int index, DataType dataType,
+                                  bool isSelected) {
+  if (index < 0 || index >= (int)m_items.size()) return QVariant();
+  Item &item = m_items[index];
+  if (dataType == Name) {
+    // show two dots( ".." ) for the paret directory item
+    if (item.m_path == m_folder.getParentDir())
+      return QString("..");
+    else
+      return item.m_name;
+  } else if (dataType == Thumbnail) {
+    QSize iconSize = m_itemViewer->getPanel()->getIconSize();
+    // parent folder icons
+    if (item.m_path == m_folder.getParentDir()) {
+      static QPixmap folderUpPixmap(svgToPixmap(":Resources/folderup_icon.svg",
+                                                iconSize, Qt::KeepAspectRatio));
+      return folderUpPixmap;
+    }
+    // folder icons
+    else if (item.m_isFolder) {
+      if (item.m_isLink) {
+        static QPixmap linkIcon(svgToPixmap(":Resources/link_icon.svg",
+                                            iconSize, Qt::KeepAspectRatio));
+        return linkIcon;
+      } else {
+        static QPixmap folderIcon(svgToPixmap(":Resources/folder_icon.svg",
+                                              iconSize, Qt::KeepAspectRatio));
+        return folderIcon;
+      }
+    }
+
+    QPixmap pixmap = IconGenerator::instance()->getIcon(item.m_path);
+    if (pixmap.isNull()) {
+      pixmap = QPixmap(iconSize);
+      pixmap.fill(Qt::white);
+    }
+    return scalePixmapKeepingAspectRatio(pixmap, iconSize, Qt::transparent);
+  } else if (dataType == Icon)
+    return QVariant();
+  else if (dataType == ToolTip || dataType == FullPath)
+    return QString::fromStdWString(item.m_path.getWideString());
+
+  else if (dataType == IsFolder) {
+    return item.m_isFolder;
+  }
+
+  if (!item.m_validInfo) {
+    readInfo(item);
+    if (!item.m_validInfo) return QVariant();
+  }
+
+  if (dataType == CreationDate) return item.m_creationDate;
+  if (dataType == ModifiedDate) return item.m_modifiedDate;
+  if (dataType == FileType) {
+    if (item.m_isLink)
+      return QString("<LINK>");
+    else if (item.m_isFolder)
+      return QString("<DIR>");
+    else
+      return QString::fromStdString(item.m_path.getType()).toUpper();
+  } else if (dataType == FileSize)
+    return (item.m_fileSize == -1) ? QVariant() : item.m_fileSize;
+  else if (dataType == FrameCount) {
+    if (item.m_frameCount == -1) readFrameCount(item);
+    return item.m_frameCount;
+  } else if (dataType == PlayAvailable) {
+    std::string type = item.m_path.getType();
+    if (item.m_frameCount > 1 && type != "tzp" && type != "tzu") return true;
+    return false;
+  } else if (dataType == VersionControlStatus) {
+    return getItemVersionControlStatus(item);
+  } else
+    return QVariant();
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::isSceneItem(int index) const {
+  return 0 <= index && index < (int)m_items.size() &&
+         m_items[index].m_path.getType() == "tnz";
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::canRenameItem(int index) const {
+  // se sto guardando la history non posso rinominare nulla
+  if (getFolder() == TFilePath()) return false;
+  if (index < 0 || index >= (int)m_items.size()) return false;
+  // for now, disable rename for folders
+  if (m_items[index].m_isFolder) return false;
+  TFilePath fp = m_items[index].m_path;
+  return TFileStatus(fp).doesExist();
+}
+
+//-----------------------------------------------------------------------------
+
+int FileBrowser::findIndexWithPath(TFilePath path) {
+  int i;
+  for (i = 0; i < m_items.size(); i++)
+    if (m_items[i].m_path == path) return i;
+  return -1;
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::renameItem(int index, const QString &newName) {
+  if (getFolder() == TFilePath()) return;
+  if (index < 0 || index >= (int)m_items.size()) return;
+
+  TFilePath fp    = m_items[index].m_path;
+  TFilePath newFp = fp;
+  if (renameFile(newFp, newName)) {
+    m_items[index].m_name = QString::fromStdWString(newFp.getLevelNameW());
+    m_items[index].m_path = newFp;
+
+    // ho rinominato anche la palette devo aggiornarla.
+    if (newFp.getType() == "tlv" || newFp.getType() == "tzp" ||
+        newFp.getType() == "tzu") {
+      const char *type = (newFp.getType() == "tlv") ? "tpl" : "plt";
+      int paletteIndex = findIndexWithPath(fp.withNoFrame().withType(type));
+      if (paletteIndex >= 0) {
+        TFilePath palettePath = newFp.withNoFrame().withType(type);
+        m_items[paletteIndex].m_name =
+            QString::fromStdWString(palettePath.getLevelNameW());
+        m_items[paletteIndex].m_path = palettePath;
+      }
+    }
+    m_itemViewer->update();
+
+    if (fp.getType() == "tnz") {
+      // ho cambiato il folder _files. Devo aggiornare il folder che lo contiene
+      // nel tree view
+      QModelIndex index = m_folderTreeView->currentIndex();
+      if (index.isValid()) {
+        DvDirModel::instance()->refresh(index);
+        // m_folderTreeView->getDvDirModel()->refresh(index);
+        m_folderTreeView->update();
+      }
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::renameFile(TFilePath &fp, QString newName) {
+  if (isSpaceString(newName)) return true;
+
+  TFilePath newFp(newName.toStdWString());
+  if (newFp.getType() != "" && newFp.getType() != fp.getType()) {
+    DVGui::error(tr("Can't change file extension"));
+    return false;
+  }
+  if (newFp.getType() == "") newFp = newFp.withType(fp.getType());
+  if (newFp.getFrame() != TFrameId::EMPTY_FRAME &&
+      newFp.getFrame() != TFrameId::NO_FRAME) {
+    DVGui::error(tr("Can't set a drawing number"));
+    return false;
+  }
+  if (newFp.getDots() != fp.getDots()) {
+    if (fp.getDots() == ".")
+      newFp = newFp.withNoFrame();
+    else if (fp.getDots() == "..")
+      newFp = newFp.withFrame(TFrameId::EMPTY_FRAME);
+  }
+  newFp = newFp.withParentDir(fp.getParentDir());
+
+  // se sono uguali non devo rinominare nulla
+  if (newFp == fp) return false;
+
+  if (TSystem::doesExistFileOrLevel(newFp)) {
+    DVGui::error(tr("Can't rename. File already exists: ") + toQString(newFp));
+    return false;
+  }
+
+  try {
+    TSystem::renameFileOrLevel_throw(newFp, fp, true);
+    IconGenerator::instance()->remove(fp);
+    if (fp.getType() == "tnz") {
+      /* TFilePath folder = fp.getParentDir() + (fp.getName() + "_files");
+TFilePath newFolder = newFp.getParentDir() + (newFp.getName() + "_files");
+TSystem::renameFile(newFolder, folder);
+*/
+      TFilePath sceneIconFp    = ToonzScene::getIconPath(fp);
+      TFilePath sceneIconNewFp = ToonzScene::getIconPath(newFp);
+      if (TFileStatus(sceneIconFp).doesExist()) {
+        if (TFileStatus(sceneIconNewFp).doesExist())
+          TSystem::deleteFile(sceneIconNewFp);
+        TSystem::renameFile(sceneIconNewFp, sceneIconFp);
+      }
+    }
+
+  } catch (...) {
+    DVGui::error(tr("Couldn't rename ") + toQString(fp) + " to " +
+                 toQString(newFp));
+    return false;
+  }
+
+  fp = newFp;
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+
+QMenu *FileBrowser::getContextMenu(QWidget *parent, int index) {
+  auto isOldLevelType = [](TFilePath &path) -> bool {
+    return path.getType() == "tzp" || path.getType() == "tzu";
+  };
+
+  bool ret = true;
+
+  // TODO: spostare in questa classe anche la definizione delle azioni?
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return 0;
+  std::vector<TFilePath> files;
+  fs->getSelectedFiles(files);
+
+  QMenu *menu        = new QMenu(parent);
+  CommandManager *cm = CommandManager::instance();
+
+  if (files.empty()) {
+    menu->addAction(cm->getAction(MI_ShowFolderContents));
+    menu->addAction(cm->getAction(MI_SelectAll));
+    if (!Preferences::instance()->isWatchFileSystemEnabled()) {
+      menu->addAction(cm->getAction(MI_RefreshTree));
+    }
+    return menu;
+  }
+
+  if (files.size() == 1 && files[0].getType() == "tnz") {
+    menu->addAction(cm->getAction(MI_LoadScene));
+  }
+
+  bool areResources = true;
+  bool areScenes    = false;
+  int i, j;
+  for (i = 0; i < (int)files.size(); i++) {
+    TFileType::Type type = TFileType::getInfo(files[i]);
+    if (areResources && !TFileType::isResource(type)) areResources = false;
+    if (!areScenes && TFileType::isScene(type)) areScenes = true;
+  }
+
+  bool areFullcolor = true;
+  for (i = 0; i < (int)files.size(); i++) {
+    TFileType::Type type = TFileType::getInfo(files[i]);
+    if (!TFileType::isFullColor(type)) {
+      areFullcolor = false;
+      break;
+    }
+  }
+
+  TFilePath clickedFile;
+  if (0 <= index && index < (int)m_items.size())
+    clickedFile = m_items[index].m_path;
+
+  if (areResources) {
+    QString title;
+    if (clickedFile != TFilePath() && clickedFile.getType() == "tnz")
+      title = tr("Load As Sub-xsheet");
+    else
+      title = tr("Load");
+    QAction *action = new QAction(title, menu);
+    ret             = ret &&
+          connect(action, SIGNAL(triggered()), this, SLOT(loadResources()));
+    menu->addAction(action);
+    menu->addSeparator();
+  }
+
+  menu->addAction(cm->getAction(MI_DuplicateFile));
+  if (!areScenes) {
+    menu->addAction(cm->getAction(MI_Copy));
+    menu->addAction(cm->getAction(MI_Paste));
+  }
+  menu->addAction(cm->getAction(MI_Clear));
+  menu->addAction(cm->getAction(MI_ShowFolderContents));
+  menu->addAction(cm->getAction(MI_SelectAll));
+  menu->addAction(cm->getAction(MI_FileInfo));
+  if (!clickedFile.isEmpty() &&
+      (clickedFile.getType() == "tnz" || clickedFile.getType() == "tab")) {
+    menu->addSeparator();
+    menu->addAction(cm->getAction(MI_AddToBatchRenderList));
+    menu->addAction(cm->getAction(MI_AddToBatchCleanupList));
+  }
+
+  for (i = 0; i < files.size(); i++)
+    if (!TFileType::isViewable(TFileType::getInfo(files[i]))) break;
+  if (i == files.size()) {
+    std::string type = files[0].getType();
+    for (j = 0; j < files.size(); j++)
+      if (isOldLevelType(files[j])) break;
+    if (j == files.size()) menu->addAction(cm->getAction(MI_ViewFile));
+
+    for (j = 0; j < files.size(); j++) {
+      if ((files[0].getType() == "pli" && files[j].getType() != "pli") ||
+          (files[0].getType() != "pli" && files[j].getType() == "pli"))
+        break;
+      else if ((isOldLevelType(files[0]) && !isOldLevelType(files[j])) ||
+               (!isOldLevelType(files[0]) && isOldLevelType(files[j])))
+        break;
+    }
+    if (j == files.size()) {
+      menu->addAction(cm->getAction(MI_ConvertFiles));
+      // iwsw commented out temporarily
+      // menu->addAction(cm->getAction(MI_ToonShadedImageToTLV));
+    }
+    if (areFullcolor) menu->addAction(cm->getAction(MI_SeparateColors));
+
+    if (!areFullcolor) menu->addSeparator();
+  }
+  if (files.size() == 1 && files[0].getType() != "tnz") {
+    QAction *action = new QAction(tr("Rename"), menu);
+    ret             = ret && connect(action, SIGNAL(triggered()), this,
+                         SLOT(renameAsToonzLevel()));
+    menu->addAction(action);
+  }
+#ifdef LEVO
+
+  if (files.size() == 2 &&
+      (files[0].getType() == "tif" || files[0].getType() == "tiff" ||
+       files[0].getType() == "png" || files[0].getType() == "TIF" ||
+       files[0].getType() == "TIFF" || files[0].getType() == "PNG") &&
+      (files[1].getType() == "tif" || files[1].getType() == "tiff" ||
+       files[1].getType() == "png" || files[1].getType() == "TIF" ||
+       files[1].getType() == "TIFF" || files[1].getType() == "PNG")) {
+    QAction *action = new QAction(tr("Convert to Painted TLV"), menu);
+    ret             = ret && connect(action, SIGNAL(triggered()), this,
+                         SLOT(convertToPaintedTlv()));
+    menu->addAction(action);
+  }
+  if (areFullcolor) {
+    QAction *action = new QAction(tr("Convert to Unpainted TLV"), menu);
+    ret             = ret && connect(action, SIGNAL(triggered()), this,
+                         SLOT(convertToUnpaintedTlv()));
+    menu->addAction(action);
+    menu->addSeparator();
+  }
+#endif
+
+  if (!clickedFile.isEmpty() && (clickedFile.getType() == "tnz")) {
+    menu->addSeparator();
+    menu->addAction(cm->getAction(MI_CollectAssets));
+    menu->addAction(cm->getAction(MI_ImportScenes));
+    menu->addAction(cm->getAction(MI_ExportScenes));
+  }
+
+  DvDirVersionControlNode *node = dynamic_cast<DvDirVersionControlNode *>(
+      m_folderTreeView->getCurrentNode());
+  if (node) {
+    // Check Version Control Status
+    DvItemListModel::Status status =
+        (DvItemListModel::Status)m_itemViewer->getModel()
+            ->getItemData(index, DvItemListModel::VersionControlStatus)
+            .toInt();
+
+    // Remove the added actions
+    if (status == DvItemListModel::VC_Missing) menu->clear();
+
+    QMenu *vcMenu = new QMenu(tr("Version Control"), parent);
+    QAction *action;
+
+    if (status == DvItemListModel::VC_ReadOnly ||
+        (status == DvItemListModel::VC_ToUpdate && files.size() == 1)) {
+      if (status == DvItemListModel::VC_ReadOnly) {
+        action = vcMenu->addAction(tr("Edit"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(editVersionControl()));
+
+        TFilePath path       = files.at(0);
+        std::string fileType = path.getType();
+        if (fileType == "tlv" || fileType == "pli" || path.getDots() == "..") {
+          action = vcMenu->addAction(tr("Edit Frame Range..."));
+          ret    = ret && connect(action, SIGNAL(triggered()), this,
+                               SLOT(editFrameRangeVersionControl()));
+        }
+      } else {
+        action = vcMenu->addAction(tr("Edit"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(updateAndEditVersionControl()));
+      }
+    }
+
+    if (status == DvItemListModel::VC_Modified) {
+      action = vcMenu->addAction(tr("Put..."));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(putVersionControl()));
+
+      action = vcMenu->addAction(tr("Revert"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(revertVersionControl()));
+    }
+
+    if (status == DvItemListModel::VC_ReadOnly ||
+        status == DvItemListModel::VC_ToUpdate) {
+      action = vcMenu->addAction(tr("Get"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(getVersionControl()));
+
+      if (status == DvItemListModel::VC_ReadOnly) {
+        action = vcMenu->addAction(tr("Delete"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(deleteVersionControl()));
+      }
+
+      vcMenu->addSeparator();
+
+      if (files.size() == 1) {
+        action         = vcMenu->addAction(tr("Get Revision..."));
+        TFilePath path = files.at(0);
+        if (path.getDots() == "..")
+          ret = ret && connect(action, SIGNAL(triggered()), this,
+                               SLOT(getRevisionVersionControl()));
+        else
+          ret = ret && connect(action, SIGNAL(triggered()), this,
+                               SLOT(getRevisionHistory()));
+      } else if (files.size() > 1) {
+        action = vcMenu->addAction("Get Revision...");
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(getRevisionVersionControl()));
+      }
+    }
+
+    if (status == DvItemListModel::VC_Edited) {
+      action = vcMenu->addAction(tr("Unlock"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(unlockVersionControl()));
+    }
+
+    if (status == DvItemListModel::VC_Unversioned) {
+      action = vcMenu->addAction(tr("Put..."));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(putVersionControl()));
+    }
+
+    if (status == DvItemListModel::VC_Locked && files.size() == 1) {
+      action = vcMenu->addAction(tr("Unlock"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(unlockVersionControl()));
+
+      action = vcMenu->addAction(tr("Edit Info"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(showLockInformation()));
+    }
+
+    if (status == DvItemListModel::VC_Missing) {
+      action = vcMenu->addAction(tr("Get"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(getVersionControl()));
+
+      if (files.size() == 1) {
+        vcMenu->addSeparator();
+        action         = vcMenu->addAction(tr("Revision History..."));
+        TFilePath path = files.at(0);
+        if (path.getDots() == "..")
+          ret = ret && connect(action, SIGNAL(triggered()), this,
+                               SLOT(getRevisionVersionControl()));
+        else
+          ret = ret && connect(action, SIGNAL(triggered()), this,
+                               SLOT(getRevisionHistory()));
+      }
+    }
+
+    if (status == DvItemListModel::VC_PartialLocked) {
+      action = vcMenu->addAction(tr("Get"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(getVersionControl()));
+      if (files.size() == 1) {
+        action = vcMenu->addAction(tr("Edit Frame Range..."));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(editFrameRangeVersionControl()));
+
+        action = vcMenu->addAction(tr("Edit Info"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(showFrameRangeLockInfo()));
+      }
+
+    } else if (status == DvItemListModel::VC_PartialEdited) {
+      action = vcMenu->addAction(tr("Get"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(getVersionControl()));
+
+      if (files.size() == 1) {
+        action = vcMenu->addAction(tr("Unlock Frame Range"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(unlockFrameRangeVersionControl()));
+
+        action = vcMenu->addAction(tr("Edit Info"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(showFrameRangeLockInfo()));
+      }
+    } else if (status == DvItemListModel::VC_PartialModified) {
+      action = vcMenu->addAction(tr("Get"));
+      ret    = ret && connect(action, SIGNAL(triggered()), this,
+                           SLOT(getVersionControl()));
+
+      if (files.size() == 1) {
+        action = vcMenu->addAction(tr("Put..."));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(putFrameRangeVersionControl()));
+
+        action = vcMenu->addAction(tr("Revert"));
+        ret    = ret && connect(action, SIGNAL(triggered()), this,
+                             SLOT(revertFrameRangeVersionControl()));
+      }
+    }
+
+    if (!vcMenu->isEmpty()) {
+      menu->addSeparator();
+      menu->addMenu(vcMenu);
+    }
+  }
+
+  if (!Preferences::instance()->isWatchFileSystemEnabled()) {
+    menu->addSeparator();
+    menu->addAction(cm->getAction(MI_RefreshTree));
+  }
+
+  assert(ret);
+
+  return menu;
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::startDragDrop() {
+  TRepetitionGuard guard;
+  if (!guard.hasLock()) return;
+
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return;
+  std::vector<TFilePath> files;
+  fs->getSelectedFiles(files);
+  if (files.empty()) return;
+
+  QList<QUrl> urls;
+  for (int i = 0; i < (int)files.size(); i++) {
+    if (TSystem::doesExistFileOrLevel(files[i]))
+      urls.append(QUrl::fromLocalFile(
+          QString::fromStdWString(files[i].getWideString())));
+  }
+  if (urls.isEmpty()) return;
+
+  QMimeData *mimeData = new QMimeData;
+  mimeData->setUrls(urls);
+  QDrag *drag    = new QDrag(this);
+  QSize iconSize = m_itemViewer->getPanel()->getIconSize();
+  QPixmap icon   = IconGenerator::instance()->getIcon(files[0]);
+  QPixmap dropThumbnail =
+      scalePixmapKeepingAspectRatio(icon, iconSize, Qt::transparent);
+  if (!dropThumbnail.isNull()) drag->setPixmap(dropThumbnail);
+  drag->setMimeData(mimeData);
+  Qt::DropAction dropAction = drag->exec(Qt::CopyAction);
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::dropMimeData(QTreeWidgetItem *parent, int index,
+                               const QMimeData *data, Qt::DropAction action) {
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onTreeFolderChanged() {
+  DvDirModelNode *node = m_folderTreeView->getCurrentNode();
+  if (node)
+    node->visualizeContent(this);
+  else
+    setFolder(TFilePath());
+  m_itemViewer->resetVerticalScrollBar();
+  m_itemViewer->updateContentSize();
+  m_itemViewer->getPanel()->update();
+  m_frameCountReader.stopReading();
+  IconGenerator::instance()->clearRequests();
+
+  DvDirModelFileFolderNode *fileFolderNode =
+      dynamic_cast<DvDirModelFileFolderNode *>(node);
+  if (fileFolderNode) emit treeFolderChanged(fileFolderNode->getPath());
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::changeFolder(const QModelIndex &index) {}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onDataChanged(const QModelIndex &topLeft,
+                                const QModelIndex &bottomRight) {
+  onTreeFolderChanged();
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::acceptDrop(const QMimeData *data) const {
+  // se il browser non sta visualizzando un folder standard non posso accettare
+  // nessun drop
+  if (getFolder() == TFilePath()) return false;
+
+  if (data->hasFormat("application/vnd.toonz.levels") ||
+      data->hasFormat("application/vnd.toonz.currentscene") ||
+      data->hasFormat("application/vnd.toonz.drawings") ||
+      acceptResourceDrop(data->urls()))
+    return true;
+
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+
+bool FileBrowser::drop(const QMimeData *mimeData) {
+  // se il browser non sta visualizzando un folder standard non posso accettare
+  // nessun drop
+  TFilePath folderPath = getFolder();
+  if (folderPath == TFilePath()) return false;
+
+  if (mimeData->hasFormat(CastItems::getMimeFormat())) {
+    const CastItems *items = dynamic_cast<const CastItems *>(mimeData);
+    if (!items) return false;
+
+    int i;
+    for (i = 0; i < items->getItemCount(); i++) {
+      CastItem *item = items->getItem(i);
+      if (TXshSimpleLevel *sl = item->getSimpleLevel()) {
+        TFilePath levelPath = sl->getPath().withParentDir(getFolder());
+        IoCmd::saveLevel(levelPath, sl, false);
+      } else if (TXshSoundLevel *level = item->getSoundLevel()) {
+        TFilePath soundPath = level->getPath().withParentDir(getFolder());
+        IoCmd::saveSound(soundPath, level, false);
+      }
+    }
+    refreshFolder(getFolder());
+    return true;
+  } else if (mimeData->hasFormat("application/vnd.toonz.currentscene")) {
+    TFilePath scenePath;
+    ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
+    if (scene->isUntitled()) {
+      bool ok;
+      QString sceneName =
+          QInputDialog::getText(this, tr("Save Scene"), tr("Scene name:"),
+                                QLineEdit::Normal, QString(), &ok);
+      if (!ok || sceneName == "") return false;
+      scenePath = folderPath + sceneName.toStdWString();
+    } else
+      scenePath = folderPath + scene->getSceneName();
+    return IoCmd::saveScene(scenePath, false);
+  } else if (mimeData->hasFormat("application/vnd.toonz.drawings")) {
+    TFilmstripSelection *s =
+        dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent());
+    if (!s) return false;
+    TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
+    if (!sl) return false;
+
+    std::wstring levelName = sl->getName();
+    folderPath +=
+        TFilePath(levelName + ::to_wstring(sl->getPath().getDottedType()));
+    if (TSystem::doesExistFileOrLevel(folderPath)) {
+      QString question = "Level " + toQString(folderPath) +
+                         " already exists\nDo you want to duplicate it?";
+      int ret = DVGui::MsgBox(question, QObject::tr("Duplicate"),
+                              QObject::tr("Don't Duplicate"), 0);
+      if (ret == 2 || ret == 0) return false;
+      TFilePath path = folderPath;
+      NameBuilder *nameBuilder =
+          NameBuilder::getBuilder(::to_wstring(path.getName()));
+      do
+        levelName = nameBuilder->getNext();
+      while (TSystem::doesExistFileOrLevel(path.withName(levelName)));
+      folderPath = path.withName(levelName);
+    }
+    assert(!TSystem::doesExistFileOrLevel(folderPath));
+
+    TXshSimpleLevel *newSl = new TXshSimpleLevel();
+    newSl->setType(sl->getType());
+    newSl->clonePropertiesFrom(sl);
+    newSl->setName(levelName);
+    newSl->setPalette(sl->getPalette());
+    newSl->setScene(sl->getScene());
+    std::set<TFrameId> frames = s->getSelectedFids();
+    for (auto const &fid : frames) {
+      newSl->setFrame(fid, sl->getFrame(fid, false));
+    }
+
+    IoCmd::saveLevel(folderPath, newSl, false);
+    refreshFolder(folderPath.getParentDir());
+    return true;
+  } else if (mimeData->hasUrls()) {
+    int count = 0;
+    for (const QUrl &url : mimeData->urls()) {
+      TFilePath srcFp(url.toLocalFile().toStdWString());
+      TFilePath dstFp = srcFp.withParentDir(folderPath);
+      if (dstFp != srcFp) {
+        if (!TSystem::copyFileOrLevel(dstFp, srcFp))
+          DVGui::error(tr("There was an error copying %1 to %2")
+                           .arg(toQString(srcFp))
+                           .arg(toQString(dstFp)));
+      }
+    }
+    refreshFolder(folderPath);
+    return true;
+  } else
+    return false;
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::loadResources() {
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return;
+
+  std::vector<TFilePath> filePaths;
+  fs->getSelectedFiles(filePaths);
+
+  if (filePaths.empty()) return;
+
+  IoCmd::LoadResourceArguments args;
+  args.resourceDatas.assign(filePaths.begin(), filePaths.end());
+
+  IoCmd::loadResources(args);
+}
+
+//-----------------------------------------------------------------------------
+
+void RenameAsToonzPopup::onOk() {
+  if (!isValidFileName(m_name->text())) {
+    DVGui::error(
+        tr("The file name cannot be empty or contain any of the following "
+           "characters:(new line)  \\ / : * ? \"  |"));
+    return;
+  }
+  if (isReservedFileName_message(m_name->text())) return;
+  accept();
+}
+
+RenameAsToonzPopup::RenameAsToonzPopup(const QString name, int frames)
+    : Dialog(TApp::instance()->getMainWindow(), true, true, "RenameAsToonz") {
+  setWindowTitle(QString(tr("Rename")));
+
+  beginHLayout();
+
+  QLabel *lbl;
+  if (frames == -1)
+    lbl = new QLabel(QString(tr("Renaming File ")) + name);
+  else
+    lbl = new QLabel(
+        QString(tr("Creating an animation level of %1 frames").arg(frames)));
+  lbl->setFixedHeight(20);
+  lbl->setObjectName("TitleTxtLabel");
+
+  m_name = new LineEdit(frames == -1 ? "" : name);
+  m_name->setFixedHeight(20);
+  // connect(m_name, SIGNAL(editingFinished()), SLOT(onNameChanged()));
+  // addWidget(tr("Level Name:"),m_name);
+
+  m_overwrite = new QCheckBox(tr("Delete Original Files"));
+  m_overwrite->setFixedHeight(20);
+  // addWidget(m_overwrite, false);
+
+  QFormLayout *formLayout = new QFormLayout;
+
+  QHBoxLayout *labelLayout = new QHBoxLayout;
+  labelLayout->addStretch();
+  labelLayout->addWidget(lbl);
+  labelLayout->addStretch();
+
+  formLayout->addRow(labelLayout);
+  formLayout->addRow(tr("Level Name:"), m_name);
+  formLayout->addRow(m_overwrite);
+
+  addLayout(formLayout);
+
+  endHLayout();
+
+  m_okBtn = new QPushButton(tr("Rename"), this);
+  m_okBtn->setDefault(true);
+  m_cancelBtn = new QPushButton(tr("Cancel"), this);
+  connect(m_okBtn, SIGNAL(clicked()), this, SLOT(onOk()));
+  connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
+  addButtonBarWidget(m_okBtn, m_cancelBtn);
+}
+
+namespace {
+
+bool parsePathName(const QString &fullpath, QString &parentPath, QString &name,
+                   QString &format) {
+  int index = fullpath.lastIndexOf('\\');
+  if (index == -1) index = fullpath.lastIndexOf('/');
+
+  QString filename;
+
+  if (index != -1) {
+    parentPath = fullpath.left(index + 1);
+    filename   = fullpath.right(fullpath.size() - index - 1);
+  } else {
+    parentPath = "";
+    filename   = fullpath;
+  }
+
+  index = filename.lastIndexOf('.');
+
+  if (index <= 0) return false;
+
+  format = filename.right(filename.size() - index - 1);
+  if (format == "") return false;
+
+  index--;
+  if (!filename.at(index).isDigit()) return false;
+
+  while (index >= 0 && filename.at(index).isDigit()) index--;
+
+  if (index < 0) return false;
+
+  name = filename.left(index + 1);
+
+  return true;
+}
+
+//---------------------------------------------------------
+
+void getLevelFiles(const QString &parentPath, const QString &name,
+                   const QString &format, QStringList &pathIn) {
+  QString dummy, dummy1, filter = "*." + format;
+  QDir dir(parentPath, filter);
+  QStringList list = dir.entryList();
+
+  for (int i = 0; i < list.size(); i++) {
+    QString item = list.at(i);
+    QString itemName;
+    if (!parsePathName(item, dummy, itemName, dummy1) || name != itemName)
+      continue;
+
+    pathIn.push_back(item);
+  }
+}
+
+//---------------------------------------------------------
+
+QString getFrame(const QString &filename) {
+  int index = filename.lastIndexOf('.');
+
+  if (index <= 0) return "";
+
+  index--;
+  if (!filename.at(index).isDigit()) return "";
+
+  int to, from;
+  to = from = index;
+  while (from >= 0 && filename.at(from).isDigit()) from--;
+
+  if (from < 0) return "";
+
+  char padStr[5];
+  padStr[4] = '\0';
+
+  int i, frame = 0;
+
+  QString number = filename.mid(from + 1, to - from);
+  for (i = 0; i < 4 - number.size(); i++) padStr[i] = '0';
+  for (i = 0; i < number.size(); i++)
+#if QT_VERSION >= 0x050500
+    padStr[4 - number.size() + i] = number.at(i).toLatin1();
+#else
+    padStr[4 - number.size() + i] = number.at(i).toAscii();
+#endif
+  return QString(padStr);
+}
+
+//------------------------------------------------------------------
+
+//-----------------------------------------------------------
+
+void renameSingleFileOrToonzLevel(const QString &fullpath) {
+  TFilePath fpin(fullpath.toStdString());
+
+  RenameAsToonzPopup popup(
+      QString::fromStdWString(fpin.withoutParentDir().getWideString()));
+  if (popup.exec() != QDialog::Accepted) return;
+
+  std::string name = popup.getName().toStdString();
+
+  if (name == fpin.getName()) {
+    DVGui::error(QString(
+        QObject::tr("The specified name is already assigned to the %1 file.")
+            .arg(fullpath)));
+    return;
+  }
+
+  if (popup.doOverwrite())
+    TSystem::renameFileOrLevel(fpin.withName(name), fpin, true);
+  else
+    TSystem::copyFileOrLevel(fpin.withName(name), fpin);
+}
+
+//----------------------------------------------------------
+
+void doRenameAsToonzLevel(const QString &fullpath) {
+  QString parentPath, name, format;
+
+  if (!parsePathName(fullpath, parentPath, name, format)) {
+    renameSingleFileOrToonzLevel(fullpath);
+    return;
+  }
+
+  QStringList pathIn;
+
+  getLevelFiles(parentPath, name, format, pathIn);
+
+  if (pathIn.empty()) return;
+
+  while (name.endsWith('_') || name.endsWith('.') || name.endsWith(' '))
+    name.chop(1);
+
+  RenameAsToonzPopup popup(name, pathIn.size());
+  if (popup.exec() != QDialog::Accepted) return;
+
+  name = popup.getName();
+
+  QString levelOutStr = parentPath + "/" + name + ".." + format;
+
+  TFilePath levelOut(levelOutStr.toStdWString());
+  if (TSystem::doesExistFileOrLevel(levelOut)) {
+    QApplication::restoreOverrideCursor();
+    int ret = DVGui::MsgBox(
+        QObject::tr("Warning: level %1 already exists; overwrite?")
+            .arg(toQString(levelOut)),
+        QObject::tr("Yes"), QObject::tr("No"), 1);
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+    if (ret == 2 || ret == 0) return;
+    TSystem::removeFileOrLevel(levelOut);
+  }
+
+  int i;
+  for (i = 0; i < pathIn.size(); i++) {
+    QString padStr = getFrame(pathIn[i]);
+    if (padStr == "") continue;
+    QString pathOut = parentPath + "/" + name + "." + padStr + "." + format;
+
+    if (popup.doOverwrite()) {
+      if (!QFile::rename(parentPath + "/" + pathIn[i], pathOut)) {
+        QString tmp(parentPath + "/" + pathIn[i]);
+        DVGui::error(QString(
+            QObject::tr("It is not possible to rename the %1 file.").arg(tmp)));
+        return;
+      }
+    } else if (!QFile::copy(parentPath + "/" + pathIn[i], pathOut)) {
+      QString tmp(parentPath + "/" + pathIn[i]);
+      DVGui::error(QString(
+          QObject::tr("It is not possible to copy the %1 file.").arg(tmp)));
+
+      return;
+    }
+  }
+}
+
+}  // namespace
+
+//-------------------------------------------------------------------------------
+
+void FileBrowser::renameAsToonzLevel() {
+  std::vector<TFilePath> filePaths;
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return;
+  fs->getSelectedFiles(filePaths);
+  if (filePaths.size() != 1) return;
+
+  doRenameAsToonzLevel(QString::fromStdWString(filePaths[0].getWideString()));
+
+  QApplication::restoreOverrideCursor();
+
+  FileBrowser::refreshFolder(filePaths[0].getParentDir());
+}
+
+#ifdef LEVO
+
+void FileBrowser::convertToUnpaintedTlv() {
+  std::vector<TFilePath> filePaths;
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return;
+  fs->getSelectedFiles(filePaths);
+
+  QStringList sl;
+  sl << "Apply Autoclose                        "
+     << "Don't Apply Autoclose                          ";
+  bool ok;
+  QString autoclose = QInputDialog::getItem(
+      this, tr("Convert To Unpainted Tlv"), "", sl, 0, false, &ok);
+  if (!ok) return;
+
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+
+  int i, totFrames = 0;
+  std::vector<Convert2Tlv *> converters;
+  for (i = 0; i < filePaths.size(); i++) {
+    Convert2Tlv *converter =
+        new Convert2Tlv(filePaths[i], TFilePath(), TFilePath(), -1, -1,
+                        autoclose == sl.at(0), TFilePath(), 0, 0, 0);
+
+    if (TSystem::doesExistFileOrLevel(converter->m_levelOut)) {
+      QApplication::restoreOverrideCursor();
+      int ret = DVGui::MsgBox(tr("Warning: level %1 already exists; overwrite?")
+                                  .arg(toQString(converter->m_levelOut)),
+                              tr("Yes"), tr("No"), 1);
+      QApplication::setOverrideCursor(Qt::WaitCursor);
+      if (ret == 2 || ret == 0) {
+        delete converter;
+        continue;
+      }
+      TSystem::removeFileOrLevel(converter->m_levelOut);
+    }
+
+    totFrames += converter->getFramesToConvertCount();
+    converters.push_back(converter);
+  }
+
+  if (converters.empty()) {
+    QApplication::restoreOverrideCursor();
+    return;
+  }
+
+  ProgressDialog pb("", "Cancel", 0, totFrames);
+  int j, l, k = 0;
+  for (i = 0; i < converters.size(); i++) {
+    std::string errorMessage;
+    if (!converters[i]->init(errorMessage)) {
+      converters[i]->abort();
+      DVGui::error(QString::fromStdString(errorMessage));
+      delete converters[i];
+      converters[i] = 0;
+      continue;
+    }
+
+    int count = converters[i]->getFramesToConvertCount();
+
+    pb.setLabelText("Generating level " + toQString(converters[i]->m_levelOut));
+    pb.show();
+
+    for (j = 0; j < count; j++) {
+      std::string errorMessage = "";
+      if (!converters[i]->convertNext(errorMessage) || pb.wasCanceled()) {
+        for (l = i; l < converters.size(); l++) {
+          converters[l]->abort();
+          delete converters[i];
+          converters[i] = 0;
+        }
+        if (errorMessage != "")
+          DVGui::error(QString::fromStdString(errorMessage));
+        QApplication::restoreOverrideCursor();
+        FileBrowser::refreshFolder(filePaths[0].getParentDir());
+        return;
+      }
+      pb.setValue(++k);
+    }
+    TFilePath levelOut(converters[i]->m_levelOut);
+    delete converters[i];
+    IconGenerator::instance()->invalidate(levelOut);
+
+    converters[i] = 0;
+  }
+
+  QApplication::restoreOverrideCursor();
+  pb.hide();
+  DVGui::info(tr("Done: All Levels  converted to TLV Format"));
+
+  FileBrowser::refreshFolder(filePaths[0].getParentDir());
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::convertToPaintedTlv() {
+  std::vector<TFilePath> filePaths;
+  FileSelection *fs =
+      dynamic_cast<FileSelection *>(m_itemViewer->getPanel()->getSelection());
+  if (!fs) return;
+  fs->getSelectedFiles(filePaths);
+
+  if (filePaths.size() != 2) return;
+
+  QStringList sl;
+  sl << "Apply Autoclose                      "
+     << "Don't Apply Autoclose                        ";
+  bool ok;
+  QString autoclose = QInputDialog::getItem(this, tr("Convert To Painted Tlv"),
+                                            "", sl, 0, false, &ok);
+  if (!ok) return;
+
+  QApplication::setOverrideCursor(Qt::WaitCursor);
+
+  Convert2Tlv *converter =
+      new Convert2Tlv(filePaths[0], filePaths[1], TFilePath(), -1, -1,
+                      autoclose == sl.at(0), TFilePath(), 0, 0, 0);
+
+  if (TSystem::doesExistFileOrLevel(converter->m_levelOut)) {
+    QApplication::restoreOverrideCursor();
+    int ret = DVGui::MsgBox(tr("Warning: level %1 already exists; overwrite?")
+                                .arg(toQString(converter->m_levelOut)),
+                            tr("Yes"), tr("No"), 1);
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+    if (ret == 2 || ret == 0) {
+      QApplication::restoreOverrideCursor();
+      return;
+    }
+    TSystem::removeFileOrLevel(converter->m_levelOut);
+  }
+
+  std::string errorMessage;
+  if (!converter->init(errorMessage)) {
+    converter->abort();
+    delete converter;
+    DVGui::error(QString::fromStdString(errorMessage));
+    QApplication::restoreOverrideCursor();
+    return;
+  }
+  int count = converter->getFramesToConvertCount();
+
+  ProgressDialog pb("Generating level " + toQString(converter->m_levelOut),
+                    "Cancel", 0, count);
+  pb.show();
+
+  for (int i = 0; i < count; i++) {
+    errorMessage = "";
+    if (!converter->convertNext(errorMessage) || pb.wasCanceled()) {
+      converter->abort();
+      delete converter;
+      if (errorMessage != "")
+        DVGui::error(QString::fromStdString(errorMessage));
+      QApplication::restoreOverrideCursor();
+      FileBrowser::refreshFolder(filePaths[0].getParentDir());
+      return;
+    }
+
+    pb.setValue(i + 1);
+  }
+
+  TFilePath levelOut(converter->m_levelOut);
+  delete converter;
+  IconGenerator::instance()->invalidate(levelOut);
+
+  QApplication::restoreOverrideCursor();
+  pb.hide();
+  DVGui::info(tr("Done: 2 Levels  converted to TLV Format"));
+
+  fs->selectNone();
+  FileBrowser::refreshFolder(filePaths[0].getParentDir());
+}
+#endif
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onSelectedItems(const std::set<int> &indexes) {
+  std::set<TFilePath> filePaths;
+  std::set<int>::const_iterator it;
+
+  // pass the frameId list for reuse
+  std::list<std::vector<TFrameId>> frameIDs;
+
+  if (indexes.empty()) {  // inform selection is released
+    emit filePathsSelected(filePaths, frameIDs);
+    return;
+  }
+
+  for (it = indexes.begin(); it != indexes.end(); ++it) {
+    filePaths.insert(m_items[*it].m_path);
+    frameIDs.insert(frameIDs.begin(), m_items[*it].m_frameIds);
+  }
+
+  // reuse the list of TFrameId in order to skip loadInfo() when loading the
+  // level with sequencial frames.
+  emit filePathsSelected(filePaths, frameIDs);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onClickedItem(int index) {
+  if (0 <= index && index < (int)m_items.size()) {
+    // if the folder is clicked, then move the current folder
+    TFilePath fp = m_items[index].m_path;
+    if (m_items[index].m_isFolder) {
+      setFolder(fp, true);
+      QModelIndex index = m_folderTreeView->currentIndex();
+      if (index.isValid()) m_folderTreeView->scrollTo(index);
+    } else
+      emit filePathClicked(fp);
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::onDoubleClickedItem(int index) {
+  // TODO: Avoid duplicate code with onClickedItem().
+  if (0 <= index && index < (int)m_items.size()) {
+    // if the folder is clicked, then move the current folder
+    TFilePath fp = m_items[index].m_path;
+    if (m_items[index].m_isFolder) {
+      setFolder(fp, true);
+      QModelIndex index = m_folderTreeView->currentIndex();
+      if (index.isValid()) m_folderTreeView->scrollTo(index);
+    } else
+      emit filePathDoubleClicked(fp);
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::refreshFolder(const TFilePath &folderPath) {
+  std::set<FileBrowser *>::iterator it;
+  for (it = activeBrowsers.begin(); it != activeBrowsers.end(); ++it) {
+    FileBrowser *browser = *it;
+    DvDirModel::instance()->refreshFolder(folderPath);
+    if (browser->getFolder() == folderPath) {
+      browser->setFolder(folderPath, false, true);
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::updateItemViewerPanel() {
+  std::set<FileBrowser *>::iterator it;
+  for (it = activeBrowsers.begin(); it != activeBrowsers.end(); ++it) {
+    FileBrowser *browser = *it;
+    browser->m_itemViewer->getPanel()->update();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::getExpandedFolders(DvDirModelNode *node,
+                                     QList<DvDirModelNode *> &expandedNodes) {
+  if (!node) return;
+  QModelIndex newIndex = DvDirModel::instance()->getIndexByNode(node);
+  if (!m_folderTreeView->isExpanded(newIndex)) return;
+  expandedNodes.push_back(node);
+
+  int i = 0;
+  for (i = 0; i < node->getChildCount(); i++)
+    getExpandedFolders(node->getChild(i), expandedNodes);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::refresh() {
+  TFilePath originalFolder(
+      m_folder);  // setFolder is invoked by Qt throughout the following...
+
+  int dx                   = m_folderTreeView->verticalScrollBar()->value();
+  DvDirModelNode *rootNode = DvDirModel::instance()->getNode(QModelIndex());
+
+  QModelIndex index = DvDirModel::instance()->getIndexByNode(rootNode);
+
+  bool vcEnabled = m_folderTreeView->refreshVersionControlEnabled();
+
+  m_folderTreeView->setRefreshVersionControlEnabled(false);
+  DvDirModel::instance()->refreshFolderChild(index);
+  m_folderTreeView->setRefreshVersionControlEnabled(vcEnabled);
+
+  QList<DvDirModelNode *> expandedNodes;
+  int i;
+  for (i = 0; i < rootNode->getChildCount(); i++)
+    getExpandedFolders(rootNode->getChild(i), expandedNodes);
+
+  for (i = 0; i < expandedNodes.size(); i++) {
+    DvDirModelNode *node = expandedNodes[i];
+    if (!node || !node->hasChildren()) continue;
+    QModelIndex ind = DvDirModel::instance()->getIndexByNode(node);
+    if (!ind.isValid()) continue;
+    m_folderTreeView->expand(ind);
+  }
+  m_folderTreeView->verticalScrollBar()->setValue(dx);
+
+  setFolder(originalFolder, false, true);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::folderUp() {
+  QModelIndex index = m_folderTreeView->currentIndex();
+  if (!index.isValid() || !index.parent().isValid()) {
+    // cannot go up tree view, so try going to parent directory
+    TFilePath parentFp = m_folder.getParentDir();
+    if (parentFp != TFilePath("") && parentFp != m_folder) {
+      setFolder(parentFp, true);
+    }
+    return;
+  }
+  m_folderTreeView->setCurrentIndex(index.parent());
+  m_folderTreeView->scrollTo(index.parent());
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::newFolder() {
+  TFilePath parentFolder = getFolder();
+  if (parentFolder == TFilePath() || !TFileStatus(parentFolder).isDirectory())
+    return;
+  QString tempName(tr("New Folder"));
+  std::wstring folderName = tempName.toStdWString();
+  TFilePath folderPath    = parentFolder + folderName;
+  int i                   = 1;
+  while (TFileStatus(folderPath).doesExist())
+    folderPath = parentFolder + (folderName + L" " + std::to_wstring(++i));
+
+  try {
+    TSystem::mkDir(folderPath);
+
+  } catch (...) {
+    DVGui::error(tr("It is not possible to create the %1 folder.")
+                     .arg(toQString(folderPath)));
+    return;
+  }
+
+  DvDirModel *model = DvDirModel::instance();
+
+  QModelIndex parentFolderIndex = m_folderTreeView->currentIndex();
+  model->refresh(parentFolderIndex);
+  m_folderTreeView->expand(parentFolderIndex);
+
+  std::wstring newFolderName = folderPath.getWideName();
+  QModelIndex newFolderIndex =
+      model->childByName(parentFolderIndex, newFolderName);
+  if (newFolderIndex.isValid()) {
+    m_folderTreeView->setCurrentIndex(newFolderIndex);
+    m_folderTreeView->scrollTo(newFolderIndex);
+    m_folderTreeView->QAbstractItemView::edit(newFolderIndex);
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::showEvent(QShowEvent *) {
+  activeBrowsers.insert(this);
+  // refresh
+  if (getFolder() != TFilePath())
+    setFolder(getFolder(), false, true);
+  else if (getDayDateString() != "")
+    setHistoryDay(getDayDateString());
+  m_folderTreeView->scrollTo(m_folderTreeView->currentIndex());
+
+  // Refresh SVN
+  DvDirVersionControlNode *vcNode = dynamic_cast<DvDirVersionControlNode *>(
+      m_folderTreeView->getCurrentNode());
+  if (vcNode) m_folderTreeView->refreshVersionControl(vcNode);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::hideEvent(QHideEvent *) {
+  activeBrowsers.erase(this);
+  m_itemViewer->getPanel()->getItemViewPlayDelegate()->resetPlayWidget();
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::makeCurrentProjectVisible() {}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::enableGlobalSelection(bool enabled) {
+  m_folderTreeView->enableGlobalSelection(enabled);
+  m_itemViewer->enableGlobalSelection(enabled);
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::selectNone() { m_itemViewer->selectNone(); }
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::enableDoubleClickToOpenScenes() {
+  // perhaps this should disconnect existing signal handlers first
+  connect(this, SIGNAL(filePathDoubleClicked(const TFilePath &)), this,
+          SLOT(tryToOpenScene(const TFilePath &)));
+}
+
+//-----------------------------------------------------------------------------
+
+void FileBrowser::tryToOpenScene(const TFilePath &filePath) {
+  if (filePath.getType() == "tnz") {
+    IoCmd::loadScene(filePath);
+  }
+}
+
+//=============================================================================
+// FCData methods
+//-----------------------------------------------------------------------------
+
+FCData::FCData(const QDateTime &date)
+    : m_date(date), m_frameCount(0), m_underProgress(true), m_retryCount(1) {}
+
+//=============================================================================
+// FrameCountReader methods
+//-----------------------------------------------------------------------------
+
+FrameCountReader::FrameCountReader() : m_executor() {
+  m_executor.setMaxActiveTasks(2);
+}
+
+//-----------------------------------------------------------------------------
+
+FrameCountReader::~FrameCountReader() {}
+
+//-----------------------------------------------------------------------------
+
+int FrameCountReader::getFrameCount(const TFilePath &fp) {
+  QDateTime modifiedDate =
+      QFileInfo(QString::fromStdWString(fp.getWideString())).lastModified();
+  std::map<TFilePath, FCData>::iterator it;
+
+  {
+    // Access the static map to find an occurrence of the path.
+    QMutexLocker locker(&frameCountMapMutex);
+    it = frameCountMap.find(fp);
+
+    if (it != frameCountMap.end()) {
+      if (it->second.m_frameCount > 0 && it->second.m_date == modifiedDate) {
+        // Found an unmodified occurrence with correctly calculated frame count
+        return it->second.m_frameCount;
+      }
+    } else {
+      // First time this frame count is calculated - initialize FC data
+      frameCountMap[fp] = FCData(modifiedDate);
+      goto calculateTask;
+    }
+
+    if ((modifiedDate == it->second.m_date) &&
+        (it->second.m_underProgress || it->second.m_retryCount < 0))
+      return -1;
+  }
+
+calculateTask:
+
+  // Now, we have to calculate the frame count; first, create a frame count
+  // calculation task and submit it.
+  FrameCountTask *task = new FrameCountTask(fp, modifiedDate);
+  connect(task, SIGNAL(finished(TThread::RunnableP)), this,
+          SIGNAL(calculatedFrameCount()));
+  connect(task, SIGNAL(exception(TThread::RunnableP)), this,
+          SIGNAL(calculatedFrameCount()));
+
+  m_executor.addTask(task);
+
+  return -1;  // FrameCount has not yet been calculated
+}
+
+//-----------------------------------------------------------------------------
+
+inline void FrameCountReader::stopReading() { m_executor.cancelAll(); }
+
+//=============================================================================
+// FrameCountTask methods
+//-----------------------------------------------------------------------------
+
+FrameCountTask::FrameCountTask(const TFilePath &path,
+                               const QDateTime &modifiedDate)
+    : m_path(path), m_modifiedDate(modifiedDate), m_started(false) {
+  connect(this, SIGNAL(started(TThread::RunnableP)), this,
+          SLOT(onStarted(TThread::RunnableP)));
+  connect(this, SIGNAL(canceled(TThread::RunnableP)), this,
+          SLOT(onCanceled(TThread::RunnableP)));
+}
+
+//-----------------------------------------------------------------------------
+
+FrameCountTask::~FrameCountTask() {}
+
+//-----------------------------------------------------------------------------
+
+void FrameCountTask::run() {
+  TLevelReaderP lr(m_path);
+  int frameCount = lr->loadInfo()->getFrameCount();
+
+  QMutexLocker fCMapMutex(&frameCountMapMutex);
+
+  std::map<TFilePath, FCData>::iterator it = frameCountMap.find(m_path);
+
+  if (it == frameCountMap.end()) return;
+
+  // Memorize the found frameCount into the frameCountMap
+  if (frameCount > 0) {
+    it->second.m_frameCount = frameCount;
+    it->second.m_date       = m_modifiedDate;
+  } else {
+    // Seems that tlv reads sometimes may fail, returning invalid frame counts
+    // (typically 0).
+    // However, if no exception was thrown, we try to recover it
+    it->second.m_underProgress = false;
+    it->second.m_retryCount--;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+QThread::Priority FrameCountTask::runningPriority() {
+  return QThread::LowPriority;
+}
+
+//-----------------------------------------------------------------------------
+
+// NOTE: onStarted and onCanceled are invoked on the same thread - so m_started
+// operations are serialized, it can be non-thread-guarded.
+void FrameCountTask::onStarted(TThread::RunnableP thisTask) {
+  m_started = true;
+}
+
+//-----------------------------------------------------------------------------
+
+void FrameCountTask::onCanceled(TThread::RunnableP thisTask) {
+  if (!m_started) {
+    QMutexLocker fCMapMutex(&frameCountMapMutex);
+
+    frameCountMap.erase(m_path);
+  }
+}
+
+//=============================================================================
+
+OpenFloatingPanel openBrowserPane(MI_OpenFileBrowser, "Browser",
+                                  QObject::tr("File Browser"));
+
+OpenFloatingPanel openPreproductionBoardPane(MI_OpenPreproductionBoard, "PreproductionBoard",
+                                  QObject::tr("Preproduction Board"));
\ No newline at end of file
diff --git a/toonz/sources/toonz/scenebrowser.h b/toonz/sources/toonz/scenebrowser.h
new file mode 100644
index 0000000..bace081
--- /dev/null
+++ b/toonz/sources/toonz/scenebrowser.h
@@ -0,0 +1,302 @@
+#pragma once
+
+#ifndef FILEBROWSER_INCLUDED
+#define FILEBROWSER_INCLUDED
+
+#include <QFrame>
+#include <QTreeWidget>
+#include <QDateTime>
+#include <QItemDelegate>
+#include <QCheckBox>
+#include <QList>
+#include <QModelIndex>
+#include "dvitemview.h"
+#include "tfilepath.h"
+#include "toonzqt/dvdialog.h"
+#include "versioncontrol.h"
+
+#include "tthread.h"
+
+class QLineEdit;
+class QTreeWidgetItem;
+class QSplitter;
+class DvDirModelNode;
+class DvDirTreeView;
+class QFileSystemWatcher;
+
+//-----------------------------------------------------------------------------
+
+//! FrameCountReader is the class responsible for calculation of levels' frame
+//! counts
+//! in the file browser. Since on many file formats this requires to open the
+//! level file
+//! and scan each frame (MOV-like), and on some machine configurations such a
+//! task
+//! can be time consuming, we dedicate a separate thread for it - just like the
+//! icon
+//! generator does. Calculated frame counts are also stored for quick lookup
+//! once they
+//! have been calculated the first time.
+class FrameCountReader final : public QObject {
+  Q_OBJECT
+
+  TThread::Executor m_executor;
+
+public:
+  FrameCountReader();
+  ~FrameCountReader();
+
+  int getFrameCount(const TFilePath &path);
+  void stopReading();
+
+signals:
+
+  void calculatedFrameCount();
+};
+
+//-----------------------------------------------------------------------------
+
+class FileBrowser final : public QFrame, public DvItemListModel {
+  Q_OBJECT
+
+public:
+#if QT_VERSION >= 0x050500
+  FileBrowser(QWidget *parent, Qt::WindowFlags flags = 0,
+              bool noContextMenu = false, bool multiSelectionEnabled = false);
+#else
+  FileBrowser(QWidget *parent, Qt::WFlags flags = 0, bool noContextMenu = false,
+              bool multiSelectionEnabled = false);
+#endif
+  ~FileBrowser();
+
+  void sortByDataModel(DataType dataType, bool isDiscendent) override;
+  void refreshData() override;
+
+  int getItemCount() const override;
+  QVariant getItemData(int index, DataType dataType,
+                       bool isSelected = false) override;
+
+  bool canRenameItem(int index) const override;
+  void renameItem(int index, const QString &newName) override;
+
+  bool isSceneItem(int index) const override;
+  void startDragDrop() override;
+  QMenu *getContextMenu(QWidget *parent, int index) override;
+
+  /*!
+This functions adds to the types to be filtered a new type;
+if this function is never  called, the default filter is all image
+files and scene files and palette files
+*/
+  void addFilterType(const QString &type);
+
+  /*!
+The setFilterTypes function directly specifies the list of file
+types to be displayed in the file browser.
+*/
+  void setFilterTypes(const QStringList &types);
+  const QStringList &getFilterTypes() const { return m_filter; }
+  void removeFilterType(const QString &type);
+
+  void setFolder(const TFilePath &fp, bool expandNode = false,
+                 bool forceUpdate = false);
+  // process when inputting the folder which is not regitered in the folder tree
+  // (e.g. UNC path in Windows)
+  void setUnregisteredFolder(const TFilePath &fp);
+
+  void setHistoryDay(std::string dayDateString);
+
+  TFilePath getFolder() const { return m_folder; }
+  std::string getDayDateString() const { return m_dayDateString; }
+
+  static void refreshFolder(const TFilePath &folder);
+
+  static void updateItemViewerPanel();
+
+  // ritorna true se il file e' stato rinominato. dopo la chiamata fp contiene
+  // il nuovo path
+  static bool renameFile(TFilePath &fp, QString newName);
+
+  void makeCurrentProjectVisible();
+
+  void enableGlobalSelection(bool enabled);
+  void selectNone();
+
+  QSplitter *getMainSplitter() const { return m_mainSplitter; }
+
+  // Enable double-click to open a scene.
+  // This is not always desirable (e.g. if a user double-clicks on a file in
+  // a "Save As" dialog, they expect the file will be saved to, not opened).
+  // So it is disabled by default.
+  void enableDoubleClickToOpenScenes();
+
+protected:
+  int findIndexWithPath(TFilePath path);
+  void getExpandedFolders(DvDirModelNode *node,
+                          QList<DvDirModelNode *> &expandedNodes);
+
+  bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data,
+                    Qt::DropAction action);
+
+  bool acceptDrop(const QMimeData *data) const override;
+  bool drop(const QMimeData *data) override;
+  void showEvent(QShowEvent *) override;
+  void hideEvent(QHideEvent *) override;
+
+  // Fill the QStringList with files selected in the browser, auxiliary files
+  // (palette for tlv, hooks, sceneIcons)
+  // retrieve also the path, and return also the sceneIconsCount
+  void setupVersionControlCommand(QStringList &files, QString &path,
+                                  int &sceneIconsCount);
+  void setupVersionControlCommand(QString &file, QString &path);
+
+  void refreshHistoryButtons();
+
+public slots:
+
+  void onTreeFolderChanged();
+
+protected slots:
+
+  void refresh();
+
+  void changeFolder(const QModelIndex &index);
+  void onDataChanged(const QModelIndex &topLeft,
+                     const QModelIndex &bottomRight);
+  void loadResources();
+  void onClickedItem(int index);
+  void onDoubleClickedItem(int index);
+  void onSelectedItems(const std::set<int> &indexes);
+  void folderUp();
+  void newFolder();
+
+  void onBackButtonPushed();
+  void onFwdButtonPushed();
+  void onFolderEdited();
+  void storeFolderHistory();
+  void clearHistory();
+
+  void renameAsToonzLevel();
+  void updateAndEditVersionControl();
+  void editVersionControl();
+  void unlockVersionControl();
+
+  void editFrameRangeVersionControl();
+  void unlockFrameRangeVersionControl();
+
+  void putFrameRangeVersionControl();
+  void revertFrameRangeVersionControl();
+
+  void showLockInformation();
+  void showFrameRangeLockInfo();
+
+  void putVersionControl();
+  void revertVersionControl();
+  void deleteVersionControl();
+  void getVersionControl();
+  void getRevisionVersionControl();
+  void getRevisionHistory();
+
+  void onVersionControlCommandDone(const QStringList &files);
+
+  void onFileSystemChanged(const QString &folderPath);
+
+  // If filePath is a valid scene file, open it. Otherwise do nothing.
+  void tryToOpenScene(const TFilePath &filePath);
+
+signals:
+
+  void filePathClicked(const TFilePath &);
+  void filePathDoubleClicked(const TFilePath &);
+  // reuse the list of TFrameId in order to skip loadInfo() when loading the
+  // level with sequencial frames.
+  void filePathsSelected(const std::set<TFilePath> &,
+                         const std::list<std::vector<TFrameId>> &);
+  void treeFolderChanged(const TFilePath &);
+
+  // for activating/deactivating the folder history buttons( back button &
+  // forward button )
+  void historyChanged(bool, bool);
+
+private:
+  struct Item {
+    QString m_name;
+    qlonglong m_fileSize;
+    QDateTime m_creationDate;
+    QDateTime m_modifiedDate;
+    int m_frameCount;
+    QString m_fileType;
+    TFilePath m_path;
+    bool m_validInfo;
+
+    bool m_isFolder;
+    bool m_isLink;
+    // calling loadInfo to the level with sequencial frames is time consuming.
+    // so keep the list of frameIds at the first time and try to reuse it.
+    std::vector<TFrameId> m_frameIds;
+
+    Item() : m_frameCount(0), m_validInfo(false), m_fileSize(0) {}
+    Item(const TFilePath &path, bool folder = false, bool link = false,
+         QString name = QString(""))
+        : m_path(path)
+        , m_frameCount(0)
+        , m_validInfo(false)
+        , m_fileSize(0)
+        , m_isFolder(folder)
+        , m_isLink(link)
+        , m_name(name) {}
+  };
+
+private:
+  DvDirTreeView *m_folderTreeView;
+  QSplitter *m_mainSplitter;
+  QLineEdit *m_folderName;
+  DvItemViewer *m_itemViewer;
+  FrameCountReader m_frameCountReader;
+
+  // folder history
+  QList<QModelIndex> m_indexHistoryList;
+  int m_currentPosition;
+
+  std::vector<Item> m_items;
+  TFilePath m_folder;
+  std::string m_dayDateString;
+  QStringList m_filter;
+  std::map<TFilePath, Item> m_multiFileItemMap;
+
+private:
+  void readFrameCount(Item &item);
+  void readInfo(Item &item);
+
+  void refreshCurrentFolderItems();
+
+  DvItemListModel::Status getItemVersionControlStatus(
+      const FileBrowser::Item &item);
+};
+
+//--------------------------------------------------------------------
+class RenameAsToonzPopup final : public DVGui::Dialog {
+  Q_OBJECT
+  QPushButton *m_okBtn, *m_cancelBtn;
+  DVGui::LineEdit *m_name;
+  QCheckBox *m_overwrite;
+
+public:
+  RenameAsToonzPopup(const QString name = "", int frames = -1);
+
+  bool doOverwrite() { return m_overwrite->isChecked(); }
+  QString getName() { return m_name->text(); }
+
+private:
+  // TPropertyGroup* getFormatProperties(const std::string &ext);
+
+public slots:
+  //! Starts the convertion.
+  // void onConvert();
+  // void onOptionsClicked();
+  void onOk();
+};
+
+//-----------------------------------------------------------
+
+#endif