/*
 *   File name:	k4dirstat.cpp
 *   Summary:	The K4DirStat Application
 *   License:	GPL - See file COPYING for details.
 *
 *   Author:	Stefan Hundhammer <kdirstat@gmx.de>
 *		Joshua Hodosh <kdirstat@grumpypenguin.org>
 *		Parts auto-generated by KDevelop
 *
 *   Updated:	2010-03-01
 */

#include "k4dirstat.h"
#include "settings.h"

#include <QtGui/QDropEvent>
#include <QtGui/QPainter>

#include <QStatusBar>
#include <kconfigdialog.h>

#include <kactioncollection.h>
#include <krecentfilesaction.h>
#include <kstandardaction.h>

#include <KLocalizedString>
#include <QFileDialog>
#include <QGuiApplication>
#include <kmessagebox.h>
#include <ktoggleaction.h>
#include <ktoolbar.h>
#include <ktoolinvocation.h>
#include <kurlrequesterdialog.h>
#include <kxmlguifactory.h>

#include "kactivitytracker.h"
#include "kcleanupcollection.h"
#include "kdirstatsettings.h"
#include "kdirtree.h"
#include "kdirtreecache.h"
#include "kdirtreeview.h"
#include "kexcluderules.h"
#include "ktreemaptile.h"
#include "ktreemapview.h"
#include <KIO/ApplicationLauncherJob>
#include <KIO/JobUiDelegate>
#include <KIO/JobUiDelegateFactory>
#include <KHelpClient>
#include <KIconEngine>
#include <KIconLoader>
#include <QClipboard>
#include <QIcon>
#include <QList>
#include <QMenu>
#include <QSplitter>
#include <QStorageInfo>
#include <QLabel>
#include <kwidgetsaddons_version.h>
#include "settings.h"

#define USER_CLEANUPS 10 // Number of user cleanup actions

#define ID_STATUS_MSG 1
#define ID_PACMAN 42
#define PACMAN_WIDTH 350
#define PACMAN_INTERVAL 75 // millisec

using namespace KDirStat;

static QIcon icon(const QString &iconName) {
  return QIcon(new KIconEngine(iconName, KIconLoader::global()));
}

k4dirstat *k4dirstat::instance_ = NULL;

k4dirstat::k4dirstat()
    : KXmlGuiWindow(),
      // m_view(new k4dirstatView(this)),
      m_printer(0) {
  Q_ASSERT(instance_ == NULL);
  instance_ = this;
  // accept dnd
  setAcceptDrops(true);

  // Simple inits

  _activityTracker = 0; // Might or might not be needed

  // Those will be created delayed, only when needed

  _settingsDialog = 0;
  _feedbackDialog = 0;
  _treemapView = 0;
  _pacMan = 0;
  _pacManDelimiter = 0;
  _treemapViewHeight = 0;

  connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this,
          SLOT(triggerSaveConfig()));

  // Set up internal (mainWin -> mainWin) connections

  connect(this, SIGNAL(readConfig(void)), this, SLOT(readMainWinConfig(void)));

  connect(this, SIGNAL(saveConfig(void)), this, SLOT(saveMainWinConfig(void)));

  // Create main window

  _splitter = new QSplitter(Qt::Vertical, this);
  setCentralWidget(_splitter);

  _treeView = new KDirTreeView(_splitter);

  connect(_treeView, SIGNAL(progressInfo(const QString &)), this,
          SLOT(statusMsg(const QString &)));

  connect(_treeView->tree(), SIGNAL(selectionChanged(KDirTree*)), this,
          SLOT(selectionChanged(KDirTree*)));

  connect(_treeView, SIGNAL(contextMenu(const QPoint &)),
          this, SLOT(contextMenu(const QPoint &)));

  connect(this, SIGNAL(readConfig()), _treeView, SLOT(readConfig()));
  connect(this, SIGNAL(saveConfig()), _treeView, SLOT(saveConfig()));

  connect(_treeView, SIGNAL(finished()), this,
          SLOT(createTreemapViewDelayed()));
  connect(_treeView, SIGNAL(aborted()), this, SLOT(createTreemapViewDelayed()));
  connect(_treeView, SIGNAL(startingReading()), this,
          SLOT(deleteTreemapView()));

  connect(_treeView, SIGNAL(startingReading()), this, SLOT(updateActions()));
  connect(_treeView, SIGNAL(finished()), this, SLOT(updateActions()));
  connect(_treeView, SIGNAL(aborted()), this, SLOT(updateActions()));

  // tell the KXmlGuiWindow that this is indeed the main widget
  // setCentralWidget(m_view);

  // set up the elements of the status bar
  initStatusBar();

  // then, setup our actions
  setupActions();

  // setup the cleanup actions
  initCleanups();

  _freeSpaceLabel = new QLabel();
  statusBar()->addPermanentWidget(_freeSpaceLabel);
  // add a status bar
  statusBar()->show();

  // a call to KXmlGuiWindow::setupGUI() populates the GUI
  // with actions, using KXMLGUI.
  // It also applies the saved mainwindow settings, if any, and ask the
  // mainwindow to automatically save settings if changed: window size,
  // toolbar position, icon size, etc.
  setupGUI();

  _treeViewContextMenu =
      static_cast<QMenu *>(factory()->container("treeViewContextMenu", this));
  _treemapContextMenu =
      static_cast<QMenu *>(factory()->container("treemapContextMenu", this));

  readMainWinConfig();

  // Disable certain actions at startup

  _editCopy->setEnabled(false);
  _reportMailToOwner->setEnabled(false);
  _fileRefreshAll->setEnabled(false);
  _fileRefreshSelected->setEnabled(false);
  updateActions();
}

k4dirstat::~k4dirstat() {}

void k4dirstat::setupActions() {

  _fileAskOpenDir =
      KStandardAction::open(this, SLOT(fileAskOpenDir()), actionCollection());

  _fileAskOpenUrl = actionCollection()->addAction("file_open_url", this,
                                                  SLOT(fileAskOpenUrl()));
  _fileAskOpenUrl->setText(i18n("Open &URL..."));
  _fileAskOpenUrl->setIcon(icon("konqueror"));

  _fileOpenRecent = KStandardAction::openRecent(
      this, SLOT(fileOpenRecent(const QUrl &)), actionCollection());
  _fileCloseDir =
      KStandardAction::close(this, SLOT(fileCloseDir()), actionCollection());

  _fileRefreshAll = actionCollection()->addAction("file_refresh_all", this,
                                                  SLOT(refreshAll()));
  _fileRefreshAll->setText(i18n("Refresh &All"));
  _fileRefreshAll->setIcon(icon("document-revert"));

  _fileRefreshSelected = actionCollection()->addAction(
      "file_refresh_selected", this, SLOT(refreshSelected()));
  _fileRefreshSelected->setText(i18n("Refresh &Selected"));

  _fileReadExcludedDir = actionCollection()->addAction(
      "file_read_excluded_dir", this, SLOT(refreshSelected()));
  _fileReadExcludedDir->setText(i18n("Read &Excluded Directory"));

  _fileContinueReadingAtMountPoint = actionCollection()->addAction(
      "file_continue_reading_at_mount_point", this, SLOT(refreshSelected()));
  _fileContinueReadingAtMountPoint->setText(
      i18n("Continue Reading at &Mount Point"));
  _fileContinueReadingAtMountPoint->setIcon(icon("drive-harddisk"));

  _fileStopReading = actionCollection()->addAction("file_stop_reading", this,
                                                   SLOT(stopReading()));
  _fileStopReading->setText(i18n("Stop Rea&ding"));
  _fileStopReading->setIcon(icon("process-stop"));

  _fileAskWriteCache = actionCollection()->addAction(
      "file_ask_write_cache", this, SLOT(askWriteCache()));
  _fileAskWriteCache->setText(i18n("&Write to Cache File..."));
  _fileAskWriteCache->setIcon(icon("document-export"));

  _fileAskReadCache = actionCollection()->addAction("file_ask_read_cache", this,
                                                    SLOT(askReadCache()));
  _fileAskReadCache->setText(i18n("&Read Cache File..."));
  _fileAskReadCache->setIcon(icon("document-import"));

  _fileQuit = KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()),
                                    actionCollection());
  _editCopy = KStandardAction::copy(this, SLOT(editCopy()), actionCollection());

  _cleanupOpenWith = actionCollection()->addAction("cleanup_open_with", this,
                                                   SLOT(cleanupOpenWith()));
  _cleanupOpenWith->setText(i18n("Open With"));

  _treemapZoomIn = actionCollection()->addAction("treemap_zoom_in", this,
                                                 SLOT(treemapZoomIn()));
  _treemapZoomIn->setText(i18n("Zoom in"));
  _treemapZoomIn->setIcon(icon("zoom-in"));
  actionCollection()->setDefaultShortcut(_treemapZoomIn, Qt::Key_Plus);

  _treemapZoomOut = actionCollection()->addAction("treemap_zoom_out", this,
                                                  SLOT(treemapZoomOut()));
  _treemapZoomOut->setText(i18n("Zoom out"));
  _treemapZoomOut->setIcon(icon("zoom-out"));
  actionCollection()->setDefaultShortcut(_treemapZoomOut, Qt::Key_Minus);

  _treemapSelectParent = actionCollection()->addAction(
      "treemap_select_parent", this, SLOT(treemapSelectParent()));
  _treemapSelectParent->setText(i18n("Select Parent"));
  _treemapSelectParent->setIcon(icon("go-up"));
  actionCollection()->setDefaultShortcut(_treemapSelectParent,
                                         Qt::Key_Asterisk);

  _treemapRebuild = actionCollection()->addAction("treemap_rebuild", this,
                                                  SLOT(treemapRebuild()));
  _treemapRebuild->setText(i18n("Rebuild Treemap"));

  _showTreemapView =
      new KToggleAction(i18n("Show Treemap"), actionCollection());
  actionCollection()->addAction("options_show_treemap", _showTreemapView);
  //_showTreemapView->set
  connect(_showTreemapView, SIGNAL(triggered()), this,
          SLOT(toggleTreemapView()));
  actionCollection()->setDefaultShortcut(_showTreemapView, Qt::Key_F9);

  QAction *newAct =
      actionCollection()->addAction("treemap_help", this, SLOT(treemapHelp()));
  newAct->setText(i18n("Help about Treemaps"));
  newAct->setIcon(icon("help-contents"));

  QAction *pref = KStandardAction::preferences(this, SLOT(preferences()),
                                               actionCollection());

  _reportMailToOwner = actionCollection()->addAction(
      "report_mail_to_owner", _treeView, SLOT(sendMailToOwner()));
  _reportMailToOwner->setText(i18n("Send &Mail to Owner"));
  _reportMailToOwner->setIcon(icon("mail-message-new"));

  // _helpSendFeedbackMail =
  // actionCollection()->addAction("help_send_feedback_mail",this,
  // SLOT(sendFeedbackMail())); _helpSendFeedbackMail->setText(i18n("Send
  // &Feedback Mail"));

  _fileAskOpenDir->setStatusTip(i18n("Opens a directory"));
  _fileAskOpenUrl->setStatusTip(i18n("Opens a (possibly remote) directory"));
  _fileOpenRecent->setStatusTip(i18n("Opens a recently used directory"));
  _fileCloseDir->setStatusTip(i18n("Closes the current directory"));
  _fileRefreshAll->setStatusTip(i18n("Re-reads the entire directory tree"));
  _fileRefreshSelected->setStatusTip(i18n("Re-reads the selected subtree"));
  _fileReadExcludedDir->setStatusTip(
      i18n("Scan directory tree that was previously excluded"));
  _fileContinueReadingAtMountPoint->setStatusTip(
      i18n("Scan mounted file systems"));
  _fileStopReading->setStatusTip(i18n("Stops directory reading"));
  _fileAskWriteCache->setStatusTip(
      i18n("Writes the current directory tree to a cache file that can be "
           "loaded much faster"));
  _fileAskReadCache->setStatusTip(
      i18n("Reads a directory tree from a cache file"));
  _fileQuit->setStatusTip(i18n("Quits the application"));
  _editCopy->setStatusTip(
      i18n("Copies the URL of the selected item to the clipboard"));
  _cleanupOpenWith->setStatusTip(
      i18n("Open file or directory with arbitrary application"));
  _showTreemapView->setStatusTip(i18n("Enables/disables the treemap view"));
  _treemapZoomIn->setStatusTip(i18n("Zoom treemap in"));
  _treemapZoomOut->setStatusTip(i18n("Zoom treemap out"));
  _treemapSelectParent->setStatusTip(i18n("Select parent"));
  _treemapRebuild->setStatusTip(
      i18n("Rebuild treemap to fit into available space"));
  pref->setStatusTip(i18n("Opens the preferences dialog"));
  _reportMailToOwner->setStatusTip(
      i18n("Sends a mail to the owner of the selected subtree"));

  // custom menu and menu item - the slot is in the class k4dirstatView
  // KAction *custom = new KAction(KIcon("colorize"), i18n("Swi&tch Colors"),
  // this); actionCollection()->addAction( QLatin1String("switch_action"), custom
  // ); connect(custom, SIGNAL(triggered(bool)), m_view, SLOT(switchColors()));
}

void k4dirstat::initCleanups() {
  _cleanupCollection = new KCleanupCollection(*actionCollection());
  _cleanupCollection->setParent(this);
  Q_CHECK_PTR(_cleanupCollection);
  _cleanupCollection->addStdCleanups();
  _cleanupCollection->addUserCleanups(USER_CLEANUPS);
  _cleanupCollection->readConfig();

  connect(_treeView->tree(), SIGNAL(selectionChanged(KDirTree*)),
          _cleanupCollection, SIGNAL(selectionChanged(KDirTree*)));

  connect(this, SIGNAL(readConfig(void)), _cleanupCollection,
          SLOT(readConfig(void)));

  connect(this, SIGNAL(saveConfig(void)), _cleanupCollection,
          SLOT(saveConfig(void)));
}

void k4dirstat::revertCleanupsToDefaults() {
  _cleanupCollection->revertToDefault(USER_CLEANUPS);
}

void k4dirstat::initStatusBar() { statusBar()->showMessage(i18n("Ready.")); }

void k4dirstat::openURL(const QUrl &url) {
  statusMsg(i18n("Opening directory..."));

  _treeView->openURL(url);
  _fileOpenRecent->addUrl(url);
  _fileRefreshAll->setEnabled(true);
  setCaption(url.fileName(), false);

  statusMsg(i18n("Ready."));
}

void k4dirstat::readMainWinConfig() {
  KConfigGroup config = KSharedConfig::openConfig()->group("General Options");

  // Status settings of the various bars and views

  _showTreemapView->setChecked(config.readEntry("Show Treemap", true));
  toggleTreemapView();

  // Position settings of the various bars

  // KToolBar::BarPosition toolBarPos;
  // toolBarPos = ( KToolBar::BarPosition ) config->readEntry( "ToolBarPos",
  // KToolBar::Top ); toolBar( "mainToolBar" )->setBarPos( toolBarPos );

  _treemapViewHeight = config.readEntry("TreemapViewHeight", 250);

  // initialize the recent file list
  _fileOpenRecent->loadEntries(config);

  QSize size = config.readEntry("Geometry", QSize());

  if (!size.isEmpty())
    resize(size);

  config = KSharedConfig::openConfig()->group("Animation");
  _treeView->enablePacManAnimation(config.readEntry("DirTreePacMan", false));

  config = KSharedConfig::openConfig()->group("Exclude");
  QStringList excludeRules = config.readEntry("ExcludeRules", QStringList());
  KExcludeRules::excludeRules()->clear();

  for (QStringList::Iterator it = excludeRules.begin();
       it != excludeRules.end(); ++it) {
    QString ruleText = *it;
    KExcludeRules::excludeRules()->add(new KExcludeRule(QRegExp(ruleText)));
    qDebug() << "Adding exclude rule: " << ruleText << Qt::endl;
  }

  if (excludeRules.size() == 0)
    qDebug() << "No exclude rules defined" << Qt::endl;
}

void k4dirstat::saveMainWinConfig() {
  KConfigGroup config = KSharedConfig::openConfig()->group("General Options");
  _fileOpenRecent->saveEntries(config);
  config.writeEntry("Show Treemap", _showTreemapView->isChecked());
  if (_treemapView)
    config.writeEntry("TreemapViewHeight", _treemapView->height());
}

//============================================================================
//				     Slots
//============================================================================

void k4dirstat::fileAskOpenDir() {
  statusMsg(i18n("Opening directory..."));
  QUrl url =
      QFileDialog::getExistingDirectoryUrl(this, i18n("Open Directory..."));

  if (!url.isEmpty())
    openURL(url);

  statusMsg(i18n("Ready."));
}

void k4dirstat::fileAskOpenUrl() {
  statusMsg(i18n("Opening URL..."));

  QUrl url = KUrlRequesterDialog::getUrl(QUrl(), // startDir
                                         this, i18n("Open URL..."));

  if (!url.isEmpty())
    openURL(fixedUrl(url.url()));

  statusMsg(i18n("Ready."));
}

void k4dirstat::fileOpenRecent(const QUrl &url) {
  statusMsg(i18n("Opening directory..."));

  if (!url.isEmpty())
    openURL(fixedUrl(url.url()));

  statusMsg(i18n("Ready."));
}

void k4dirstat::fileCloseDir() {
  statusMsg(i18n("Closing directory..."));

  _treeView->clear();
  _fileRefreshAll->setEnabled(false);
  close();

  statusMsg(i18n("Ready."));
}

void k4dirstat::refreshAll() {
  statusMsg(i18n("Refreshing directory tree..."));
  _treeView->refreshAll();
  statusMsg(i18n("Ready."));
}

void k4dirstat::refreshSelected() {
  statusMsg(i18n("Refreshing selected subtree..."));
  auto sel = _treeView->tree()->selection();
  for(auto it = sel.begin(); it != sel.end(); ++it)
    if(!(*it)->isDotEntry())
    _treeView->tree()->refresh(*it);
  statusMsg(i18n("Ready."));
}

void k4dirstat::stopReading() { _treeView->abortReading(); }

void k4dirstat::askWriteCache() {
  QString file_name;

  do {
    file_name = QFileDialog::getSaveFileName(this, i18n("Write to Cache File"),
                                             DEFAULT_CACHE_NAME);

    if (file_name.isEmpty()) // user hit "cancel"
      return;

    if (access(file_name.toLatin1(), F_OK) == 0) // file exists
    {
      auto msg = i18n("File %1 exists. Overwrite?", file_name);
      auto title = i18n("Overwrite?");
#if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
      int button = KMessageBox::questionTwoActionsCancel(this, msg, title,
        KStandardGuiItem::overwrite(), KStandardGuiItem::back());
      if (button == KMessageBox::SecondaryAction)
        file_name = "";
#else
      int button = KMessageBox::questionYesNoCancel(this, msg, title);
      if (button == KMessageBox::No)
        file_name = "";
#endif
      if (button == KMessageBox::Cancel)
        return;
    }
  } while (file_name.isEmpty());

  statusMsg(i18n("Writing cache file..."));

  if (!_treeView || !_treeView->writeCache(file_name)) {
    QString errMsg = i18n("Error writing cache file %1", file_name);
    statusMsg(errMsg);
    KMessageBox::error(this, errMsg,
                       i18n("Write Error")); // caption
  }

  statusMsg(i18n("Wrote cache file %1", file_name));
}

void k4dirstat::askReadCache() {
  QString file_name = QFileDialog::getOpenFileName(
      this, i18n("Read Cache File"), DEFAULT_CACHE_NAME);

  if (!file_name.isNull() && _treeView) {
    statusMsg(i18n("Reading cache file..."));
    _fileRefreshAll->setEnabled(true);
    _treeView->readCache(file_name);
  }
}

void k4dirstat::editCopy() {
  if (_treeView->selection()) {
    QGuiApplication *app =
        dynamic_cast<QGuiApplication *>(QCoreApplication::instance());
    if (app)
      app->clipboard()->setText(_treeView->selection()->url());
  }

#if 0
#warning debug
    if ( _activityTracker )
        _activityTracker->trackActivity( 800 );
#endif
}

void k4dirstat::cleanupOpenWith() {
  if (!_treeView->selection())
    return;

  KFileInfo *sel = _treeView->selection();

  if (sel->isDotEntry())
    return;

  QList<QUrl> urlList;
  urlList.append(QUrl::fromUserInput(sel->url(), QDir::currentPath(),
                                     QUrl::AssumeLocalFile));
  auto *job = new KIO::ApplicationLauncherJob();
  job->setUrls(urlList);
#if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
  job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
#else
  job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
#endif
  job->start();
}

bool atLeastOneNotDotEntry(KDirTree * tree) {
  auto sel = tree->selection();
  for(auto it = sel.begin(); it != sel.end(); ++it) {
    if((*it)->isDotEntry())
      return false;
  }
  return true;
}

void k4dirstat::selectionChanged(KDirTree* tree) {
  _fileRefreshSelected->setEnabled(atLeastOneNotDotEntry(tree));
  if (tree->selection().size() == 1) {
    // TODO: Most action have been written for single selection. We keep
    // that logic until all actions have been ported to multi-selection.
     KFileInfo * selection = tree->selection()[0];
    _editCopy->setEnabled(true);
    _reportMailToOwner->setEnabled(true);
    _cleanupOpenWith->setEnabled(!selection->isDotEntry());
    _fileReadExcludedDir->setEnabled(selection->isExcluded());

    if (selection->isMountPoint() &&
        selection->readState() == KDirOnRequestOnly) {
      _fileContinueReadingAtMountPoint->setEnabled(true);
    } else
      _fileContinueReadingAtMountPoint->setEnabled(false);

    statusMsg(selection->url());
    QStorageInfo i(selection->url());
    if(i.isValid())
      _freeSpaceLabel->setText(formatSize(i.bytesFree()) + " free");
  } else {
    _editCopy->setEnabled(false);
    _reportMailToOwner->setEnabled(false);
    _fileContinueReadingAtMountPoint->setEnabled(false);
    _cleanupOpenWith->setEnabled(false);
    statusMsg("");
  }

  updateActions();
}

void k4dirstat::updateActions() {
  _treemapZoomIn->setEnabled(_treemapView && _treemapView->canZoomIn());
  _treemapZoomOut->setEnabled(_treemapView && _treemapView->canZoomOut());
  _treemapRebuild->setEnabled(_treemapView && _treemapView->rootTile());
  _treemapSelectParent->setEnabled(_treemapView &&
                                   _treemapView->canSelectParent());

  if (_treeView->tree() && _treeView->tree()->isBusy())
    _fileStopReading->setEnabled(true);
  else
    _fileStopReading->setEnabled(false);
}

void k4dirstat::treemapZoomIn() {
  if (_treemapView) {
    _treemapView->zoomIn();
    updateActions();
  }
}

void k4dirstat::treemapZoomOut() {
  if (_treemapView) {
    _treemapView->zoomOut();
    updateActions();
  }
}

void k4dirstat::treemapSelectParent() {
  if (_treemapView) {
    _treemapView->selectParent();
    updateActions();
  }
}

void k4dirstat::treemapRebuild() {
  if (_treemapView) {
    _treemapView->rebuildTreemap();
    updateActions();
  }
}

void k4dirstat::treemapHelp() { KHelpClient::invokeHelp("treemap_intro"); }

void k4dirstat::toggleTreemapView() {
  if (_showTreemapView->isChecked()) {
    if (!_treemapView)
      createTreemapView();
  } else {
    if (_treemapView)
      deleteTreemapView();
  }
}

void k4dirstat::preferences() {
  if (_settingsDialog && _settingsDialog->isVisible())
    return;
  // TODO no longer store the instance as it's always recreated.
  // need to detect closing
  _settingsDialog = new KDirStat::KSettingsDialog(this);
  _settingsDialog->show();
}

void k4dirstat::statusMsg(const QString &text) {
  // Change status message permanently
  statusBar()->showMessage(text);
}

void k4dirstat::contextMenu(const QPoint &pos) {
  if (_treeViewContextMenu)
    _treeViewContextMenu->popup(pos);
}

void k4dirstat::contextMenu(KTreemapTile *tile, const QPoint &pos) {
  NOT_USED(tile);

  if (_treemapContextMenu)
    _treemapContextMenu->popup(pos);
}

void k4dirstat::createTreemapViewDelayed() {
  QTimer::singleShot(0, this, SLOT(createTreemapView()));
}

void k4dirstat::createTreemapView() {
  if (!_showTreemapView->isChecked() || !_treeView->tree())
    return;

  if (_treemapView)
    delete _treemapView;

  // qDebug() << "Creating KTreemapView" << endl;
  _treemapView =
      new KTreemapView(_treeView->tree(), _splitter,
                       QSize(_splitter->width(), _treemapViewHeight));
  Q_CHECK_PTR(_treemapView);

  connect(_treemapView, SIGNAL(contextMenu(KTreemapTile *, const QPoint &)),
          this, SLOT(contextMenu(KTreemapTile *, const QPoint &)));

  connect(_treemapView, SIGNAL(treemapChanged()), this, SLOT(updateActions()));

  if (_activityTracker) {
    connect(_treemapView, SIGNAL(userActivity(int)), _activityTracker,
            SLOT(trackActivity(int)));
  }

  _treemapView->show(); // QSplitter needs explicit show() for new children
  updateActions();
}

void k4dirstat::deleteTreemapView() {
  if (_treemapView) {
    // qDebug() << "Deleting KTreemapView" << endl;
    _treemapViewHeight = _treemapView->height();

    delete _treemapView;
    _treemapView = 0;
  }

  updateActions();
}

void k4dirstat::triggerSaveConfig() { emit saveConfig(); }

/*void k4dirstat::fileNew()
{
    // this slot is called whenever the File->New menu is selected,
    // the New shortcut is pressed (usually CTRL+N) or the New toolbar
    // button is clicked

    // create a new window
    (new k4dirstat)->show();
}

void k4dirstat::optionsPreferences()
{
    // The preference dialog is derived from prefs_base.ui
    //
    // compare the names of the widgets in the .ui file
    // to the names of the variables in the .kcfg file
    //avoid to have 2 dialogs shown
    if ( KConfigDialog::showDialog( "settings" ) )  {
        return;
    }
    KConfigDialog *dialog = new KConfigDialog(this, "settings",
Settings::self()); QWidget *generalSettingsDlg = new QWidget;
    ui_prefs_base.setupUi(generalSettingsDlg);
    dialog->addPage(generalSettingsDlg, i18n("General"), "package_setting");
    connect(dialog, SIGNAL(settingsChanged(QString)), m_view,
SLOT(settingsChanged())); dialog->setAttribute( Qt::WA_DeleteOnClose );
    dialog->show();
}*/
