First step to reactivate version control plugin functionality

- Add a DolphinFileItemListWidget that provides icon-overlays
  and colored text for the version state (implementation is
  missing yet)
- Allow KFileItemListWidget to have custom text colors
- Update interface of VersionControlObserver to work with
  KFileItemModel instead of the old model-interface.
This commit is contained in:
Peter Penz 2011-09-06 23:42:42 +02:00
parent 7a91492cff
commit b8c718a6fd
13 changed files with 237 additions and 89 deletions

View file

@ -43,6 +43,7 @@ set(dolphinprivate_LIB_SRCS
settings/viewpropsprogressinfo.cpp
views/additionalinfoaccessor.cpp
views/dolphindirlister.cpp
views/dolphinfileitemlistwidget.cpp
views/dolphinview.cpp
views/dolphinitemlistcontainer.cpp
views/dolphinnewfilemenuobserver.cpp

View file

@ -27,6 +27,15 @@
class KFileItemModelRolesUpdater;
class QTimer;
/**
* @brief View that allows to show the content of file-items.
*
* The corresponding model set by the controller must be an instance
* of KFileItemModel. Per default KFileItemListWidget is set as widget creator
* value and KItemListGroupHeader as group-header creator value. Use
* KItemListView::setWidgetCreator() and KItemListView::setGroupHeaderCreator()
* to apply customized generators.
*/
class LIBDOLPHINPRIVATE_EXPORT KFileItemListView : public KItemListView
{
Q_OBJECT

View file

@ -56,6 +56,7 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
m_textBoundingRect(),
m_sortedVisibleRoles(),
m_expansionArea(),
m_customTextColor(0),
m_additionalInfoTextColor()
{
for (int i = 0; i < TextIdCount; ++i) {
@ -66,6 +67,8 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
KFileItemListWidget::~KFileItemListWidget()
{
delete m_customTextColor;
m_customTextColor = 0;
}
void KFileItemListWidget::setLayout(Layout layout)
@ -114,7 +117,11 @@ void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsIte
}
painter->setFont(itemListStyleOption.font);
painter->setPen(itemListStyleOption.palette.text().color());
if (m_customTextColor) {
painter->setPen(*m_customTextColor);
} else {
painter->setPen(itemListStyleOption.palette.text().color());
}
painter->drawStaticText(m_textPos[Name], m_text[Name]);
painter->setPen(m_additionalInfoTextColor);
@ -153,6 +160,27 @@ QRectF KFileItemListWidget::expansionToggleRect() const
return m_isDir ? m_expansionArea : QRectF();
}
void KFileItemListWidget::setTextColor(const QColor& color)
{
if (color.isValid()) {
if (!m_customTextColor) {
m_customTextColor = new QColor(color);
} else {
*m_customTextColor = color;
}
} else {
delete m_customTextColor;
m_customTextColor = 0;
}
updateAdditionalInfoTextColor();
update();
}
QColor KFileItemListWidget::textColor() const
{
return m_customTextColor ? *m_customTextColor : styleOption().palette.text().color();
}
void KFileItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& current,
const QSet<QByteArray>& roles)
{
@ -215,18 +243,7 @@ void KFileItemListWidget::styleOptionChanged(const KItemListStyleOption& current
const KItemListStyleOption& previous)
{
KItemListWidget::styleOptionChanged(current, previous);
// For the color of the additional info the inactive text color
// is not used as this might lead to unreadable text for some color schemes. Instead
// the text color is slightly mixed with the background color.
const QColor c1 = current.palette.text().color();
const QColor c2 = current.palette.background().color();
const int p1 = 70;
const int p2 = 100 - p1;
m_additionalInfoTextColor = QColor((c1.red() * p1 + c2.red() * p2) / 100,
(c1.green() * p1 + c2.green() * p2) / 100,
(c1.blue() * p1 + c2.blue() * p2) / 100);
updateAdditionalInfoTextColor();
m_dirtyLayout = true;
}
@ -602,6 +619,20 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
}
}
void KFileItemListWidget::updateAdditionalInfoTextColor()
{
// For the color of the additional info the inactive text color
// is not used as this might lead to unreadable text for some color schemes. Instead
// the text color is slightly mixed with the background color.
const QColor c1 = m_customTextColor ? *m_customTextColor : styleOption().palette.text().color();
const QColor c2 = styleOption().palette.background().color();
const int p1 = 70;
const int p2 = 100 - p1;
m_additionalInfoTextColor = QColor((c1.red() * p1 + c2.red() * p2) / 100,
(c1.green() * p1 + c2.green() * p2) / 100,
(c1.blue() * p1 + c2.blue() * p2) / 100);
}
QString KFileItemListWidget::roleText(TextId textId, const QVariant& roleValue) const
{
QString text;

View file

@ -53,6 +53,9 @@ public:
virtual QRectF expansionToggleRect() const;
protected:
void setTextColor(const QColor& color);
QColor textColor() const;
virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>());
virtual void visibleRolesChanged(const QHash<QByteArray, int>& current, const QHash<QByteArray, int>& previous);
virtual void visibleRolesSizesChanged(const QHash<QByteArray, QSizeF>& current, const QHash<QByteArray, QSizeF>& previous);
@ -82,6 +85,8 @@ private:
void updateIconsLayoutTextCache();
void updateCompactLayoutTextCache();
void updateDetailsLayoutTextCache();
void updateAdditionalInfoTextColor();
QString roleText(TextId textId, const QVariant& roleValue) const;
@ -111,6 +116,7 @@ private:
QList<QByteArray> m_sortedVisibleRoles;
QRectF m_expansionArea;
QColor* m_customTextColor;
QColor m_additionalInfoTextColor;
};

View file

@ -213,6 +213,15 @@ int KFileItemModel::index(const KFileItem& item) const
return m_items.value(item, -1);
}
KUrl KFileItemModel::rootDirectory() const
{
const KDirLister* dirLister = m_dirLister.data();
if (dirLister) {
return dirLister->url();
}
return KUrl();
}
void KFileItemModel::clear()
{
slotClear();

View file

@ -89,6 +89,11 @@ public:
*/
int index(const KFileItem& item) const;
/**
* @return Root directory of all items.
*/
KUrl rootDirectory() const;
/**
* Clears all items of the model.
*/

View file

@ -0,0 +1,31 @@
/***************************************************************************
* Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "dolphinfileitemlistwidget.h"
DolphinFileItemListWidget::DolphinFileItemListWidget(QGraphicsItem* parent) :
KFileItemListWidget(parent)
{
}
DolphinFileItemListWidget::~DolphinFileItemListWidget()
{
}
#include "dolphinfileitemlistwidget.moc"

View file

@ -0,0 +1,38 @@
/***************************************************************************
* Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef DOLPHINFILEITEMLISTWIDGET_H
#define DOLPHINFILEITEMLISTWIDGET_H
#include <libdolphin_export.h>
#include <kitemviews/kfileitemlistwidget.h>
class LIBDOLPHINPRIVATE_EXPORT DolphinFileItemListWidget : public KFileItemListWidget
{
Q_OBJECT
public:
DolphinFileItemListWidget(QGraphicsItem* parent);
virtual ~DolphinFileItemListWidget();
};
#endif

View file

@ -23,6 +23,8 @@
#include "dolphin_detailsmodesettings.h"
#include "dolphin_compactmodesettings.h"
#include "dolphinfileitemlistwidget.h"
#include <kitemviews/kfileitemlistview.h>
#include <kitemviews/kfileitemmodel.h>
#include <kitemviews/kitemlistcontroller.h>
@ -45,6 +47,7 @@ DolphinItemListContainer::DolphinItemListContainer(KDirLister* dirLister,
controller()->setModel(new KFileItemModel(dirLister, this));
m_fileItemListView = new KFileItemListView();
m_fileItemListView->setWidgetCreator(new KItemListWidgetCreator<DolphinFileItemListWidget>());
controller()->setView(m_fileItemListView);
KItemListStyleOption option;

View file

@ -65,6 +65,7 @@
#include "draganddrophelper.h"
#include "renamedialog.h"
#include "settings/dolphinsettings.h"
#include "versioncontrol/versioncontrolobserver.h"
#include "viewmodecontroller.h"
#include "viewproperties.h"
#include "views/tooltips/tooltipmanager.h"
@ -92,7 +93,8 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
m_currentItemIndex(-1),
m_restoredContentsPosition(),
m_createdItemUrl(),
m_selectedItems()
m_selectedItems(),
m_versionControlObserver(0)
{
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
@ -176,6 +178,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
connect(controller, SIGNAL(itemHovered(int)), this, SLOT(slotItemHovered(int)));
connect(controller, SIGNAL(itemUnhovered(int)), this, SLOT(slotItemUnhovered(int)));
connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)), this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
KItemListSelectionManager* selectionManager = controller->selectionManager();
connect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)),
@ -183,6 +186,12 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
m_toolTipManager = new ToolTipManager(this);
m_versionControlObserver = new VersionControlObserver(this);
m_versionControlObserver->setModel(fileItemModel());
connect(m_versionControlObserver, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
connect(m_versionControlObserver, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
connect(m_versionControlObserver, SIGNAL(operationCompletedMessage(QString)), this, SIGNAL(operationCompletedMessage(QString)));
applyViewProperties();
m_topLayout->addWidget(m_container);
@ -793,6 +802,15 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
DragAndDropHelper::dropUrls(destItem, url(), &dropEvent, this);
}
void DolphinView::slotModelChanged(KItemModelBase* current, KItemModelBase* previous)
{
Q_UNUSED(previous);
Q_ASSERT(qobject_cast<KFileItemModel*>(current));
KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(current);
m_versionControlObserver->setModel(fileItemModel);
}
void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
{
const int currentCount = current.count();

View file

@ -44,8 +44,10 @@ class DolphinItemListContainer;
class KAction;
class KActionCollection;
class KFileItemModel;
class KItemModelBase;
class KUrl;
class ToolTipManager;
class VersionControlObserver;
class ViewProperties;
class QGraphicsSceneDragDropEvent;
class QRegExp;
@ -560,6 +562,7 @@ private slots:
void slotItemHovered(int index);
void slotItemUnhovered(int index);
void slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event);
void slotModelChanged(KItemModelBase* current, KItemModelBase* previous);
/**
* Emits the signal \a selectionChanged() with a small delay. This is
@ -755,6 +758,8 @@ private:
QPoint m_restoredContentsPosition;
KUrl m_createdItemUrl; // URL for a new item that got created by the "Create New..." menu
KFileItemList m_selectedItems; // this is used for making the View to remember selections after F5
VersionControlObserver* m_versionControlObserver;
// For unit tests
friend class TestBase;

View file

@ -25,51 +25,35 @@
#include <KLocale>
#include <KService>
#include <KServiceTypeTrader>
#include <kitemviews/kfileitemmodel.h>
#include <kversioncontrolplugin.h>
#include "pendingthreadsmaintainer.h"
#include "updateitemstatesthread.h"
#include <QAbstractProxyModel>
#include <QAbstractItemView>
#include <QMutexLocker>
#include <QTimer>
VersionControlObserver::VersionControlObserver(QWidget* view) :
QObject(view),
VersionControlObserver::VersionControlObserver(QObject* parent) :
QObject(parent),
m_pendingItemStatesUpdate(false),
m_versionedDirectory(false),
m_silentUpdate(false),
m_view(view),
//m_dirLister(0),
//m_dolphinModel(0),
m_model(0),
m_dirVerificationTimer(0),
m_plugin(0),
m_updateItemStatesThread(0)
{
Q_ASSERT(view);
/*QAbstractProxyModel* proxyModel = qobject_cast<QAbstractProxyModel*>(view->model());
m_dolphinModel = proxyModel ?
qobject_cast<DolphinModel*>(proxyModel->sourceModel()) :
qobject_cast<DolphinModel*>(view->model());
if (m_dolphinModel) {
m_dirLister = m_dolphinModel->dirLister();
connect(m_dirLister, SIGNAL(completed()),
this, SLOT(delayedDirectoryVerification()));
// The verification timer specifies the timeout until the shown directory
// is checked whether it is versioned. Per default it is assumed that users
// don't iterate through versioned directories and a high timeout is used
// The timeout will be decreased as soon as a versioned directory has been
// found (see verifyDirectory()).
m_dirVerificationTimer = new QTimer(this);
m_dirVerificationTimer->setSingleShot(true);
m_dirVerificationTimer->setInterval(500);
connect(m_dirVerificationTimer, SIGNAL(timeout()),
this, SLOT(verifyDirectory()));
}*/
// The verification timer specifies the timeout until the shown directory
// is checked whether it is versioned. Per default it is assumed that users
// don't iterate through versioned directories and a high timeout is used
// The timeout will be decreased as soon as a versioned directory has been
// found (see verifyDirectory()).
m_dirVerificationTimer = new QTimer(this);
m_dirVerificationTimer->setSingleShot(true);
m_dirVerificationTimer->setInterval(500);
connect(m_dirVerificationTimer, SIGNAL(timeout()),
this, SLOT(verifyDirectory()));
}
VersionControlObserver::~VersionControlObserver()
@ -96,6 +80,26 @@ VersionControlObserver::~VersionControlObserver()
}
}
void VersionControlObserver::setModel(KFileItemModel* model)
{
if (m_model) {
disconnect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
}
m_model = model;
if (model) {
connect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
}
}
KFileItemModel* VersionControlObserver::model() const
{
return m_model;
}
QList<QAction*> VersionControlObserver::contextMenuActions(const KFileItemList& items) const
{
QList<QAction*> actions;
@ -131,7 +135,11 @@ void VersionControlObserver::silentDirectoryVerification()
void VersionControlObserver::verifyDirectory()
{
const KUrl versionControlUrl; // = m_dirLister->url();
if (!m_model) {
return;
}
const KUrl versionControlUrl = m_model->rootDirectory();
if (!versionControlUrl.isLocalFile()) {
return;
}
@ -141,7 +149,7 @@ void VersionControlObserver::verifyDirectory()
}
m_plugin = searchPlugin(versionControlUrl);
/*if (m_plugin) {
if (m_plugin) {
connect(m_plugin, SIGNAL(versionStatesChanged()),
this, SLOT(silentDirectoryVerification()));
connect(m_plugin, SIGNAL(infoMessage(QString)),
@ -157,10 +165,8 @@ void VersionControlObserver::verifyDirectory()
// The directory is versioned. Assume that the user will further browse through
// versioned directories and decrease the verification timer.
m_dirVerificationTimer->setInterval(100);
connect(m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)),
this, SLOT(delayedDirectoryVerification()));
connect(m_dirLister, SIGNAL(newItems(KFileItemList)),
this, SLOT(delayedDirectoryVerification()));
connect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
}
updateItemStates();
} else if (m_versionedDirectory) {
@ -170,11 +176,9 @@ void VersionControlObserver::verifyDirectory()
// value, so that browsing through non-versioned directories is not slown down
// by an immediate verification.
m_dirVerificationTimer->setInterval(500);
disconnect(m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)),
disconnect(m_model, SIGNAL(itemsInserted(KItemRangeList)),
this, SLOT(delayedDirectoryVerification()));
disconnect(m_dirLister, SIGNAL(newItems(KFileItemList)),
this, SLOT(delayedDirectoryVerification()));
}*/
}
}
void VersionControlObserver::slotThreadFinished()
@ -184,28 +188,18 @@ void VersionControlObserver::slotThreadFinished()
}
if (!m_updateItemStatesThread->retrievedItems()) {
// ignore m_silentUpdate for an error message
// Ignore m_silentUpdate for an error message
emit errorMessage(i18nc("@info:status", "Update of version information failed."));
return;
}
// QAbstractItemModel::setData() triggers a bottleneck in combination with QListView
// (a detailed description of the root cause is given in the class KFilePreviewGenerator
// from kdelibs). To bypass this bottleneck, the signals of the model are temporary blocked.
// This works as the update of the data does not require a relayout of the views used in Dolphin.
/*const bool signalsBlocked = m_dolphinModel->signalsBlocked();
m_dolphinModel->blockSignals(true);
const QList<ItemState> itemStates = m_updateItemStatesThread->itemStates();
foreach (const ItemState& itemState, itemStates) {
m_dolphinModel->setData(itemState.index,
QVariant(static_cast<int>(itemState.version)),
Qt::DecorationRole);
QHash<QByteArray, QVariant> values;
values.insert("version", QVariant(static_cast<int>(itemState.version)));
m_model->setData(itemState.index, values);
}
m_dolphinModel->blockSignals(signalsBlocked);
m_view->viewport()->repaint();
if (!m_silentUpdate) {
// Using an empty message results in clearing the previously shown information message and showing
// the default status bar information. This is useful as the user already gets feedback that the
@ -216,7 +210,7 @@ void VersionControlObserver::slotThreadFinished()
if (m_pendingItemStatesUpdate) {
m_pendingItemStatesUpdate = false;
updateItemStates();
}*/
}
}
void VersionControlObserver::updateItemStates()
@ -235,7 +229,7 @@ void VersionControlObserver::updateItemStates()
}
QList<ItemState> itemStates;
addDirectory(QModelIndex(), itemStates);
//addDirectory(QModelIndex(), itemStates);
if (!itemStates.isEmpty()) {
if (!m_silentUpdate) {
emit infoMessage(i18nc("@info:status", "Updating version information..."));
@ -245,11 +239,11 @@ void VersionControlObserver::updateItemStates()
}
}
void VersionControlObserver::addDirectory(const QModelIndex& parentIndex, QList<ItemState>& itemStates)
/*void VersionControlObserver::addDirectory(const QModelIndex& parentIndex, QList<ItemState>& itemStates)
{
Q_UNUSED(parentIndex);
Q_UNUSED(itemStates);
/*const int rowCount = m_dolphinModel->rowCount(parentIndex);
const int rowCount = m_dolphinModel->rowCount(parentIndex);
for (int row = 0; row < rowCount; ++row) {
const QModelIndex index = m_dolphinModel->index(row, DolphinModel::Version, parentIndex);
addDirectory(index, itemStates);
@ -260,8 +254,8 @@ void VersionControlObserver::addDirectory(const QModelIndex& parentIndex, QList<
itemState.version = KVersionControlPlugin::UnversionedVersion;
itemStates.append(itemState);
}*/
}
}
}*/
KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& directory) const
{
@ -297,12 +291,12 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
// Verify whether the current directory contains revision information
// like .svn, .git, ...
Q_UNUSED(directory);
/*foreach (KVersionControlPlugin* plugin, plugins) {
foreach (KVersionControlPlugin* plugin, plugins) {
// Use the KDirLister cache to check for .svn, .git, ... files
KUrl dirUrl(directory);
KUrl fileUrl = dirUrl;
fileUrl.addPath(plugin->fileName());
const KFileItem item = m_dirLister->findByUrl(fileUrl);
const KFileItem item; // = m_dirLister->findByUrl(fileUrl);
if (!item.isNull()) {
return plugin;
}
@ -325,7 +319,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
upUrl = dirUrl.upUrl();
}
}
}*/
}
return 0;
}

View file

@ -27,13 +27,10 @@
#include <QList>
#include <QMutex>
#include <QObject>
#include <QPersistentModelIndex>
#include <QString>
class DolphinModel;
class KDirLister;
class KFileItemList;
class QAbstractItemView;
class KFileItemModel;
class QAction;
class QTimer;
class UpdateItemStatesThread;
@ -41,8 +38,8 @@ class UpdateItemStatesThread;
/**
* @brief Observes all version control plugins.
*
* The item view gets updated automatically if the currently shown
* directory is under version control.
* The items of the directory-model get updated automatically if the currently
* shown directory is under version control.
*
* @see VersionControlPlugin
*/
@ -51,9 +48,12 @@ class LIBDOLPHINPRIVATE_EXPORT VersionControlObserver : public QObject
Q_OBJECT
public:
VersionControlObserver(QWidget* parent);
explicit VersionControlObserver(QObject* parent = 0);
virtual ~VersionControlObserver();
void setModel(KFileItemModel* model);
KFileItemModel* model() const;
QList<QAction*> contextMenuActions(const KFileItemList& items) const;
QList<QAction*> contextMenuActions(const QString& directory) const;
@ -103,7 +103,7 @@ private slots:
private:
struct ItemState
{
QPersistentModelIndex index;
int index;
KFileItem item;
KVersionControlPlugin::VersionState version;
};
@ -114,7 +114,7 @@ private:
* Adds recursively all items from the directory \p parentIndex into
* the list \p itemStates.
*/
void addDirectory(const QModelIndex& parentIndex, QList<ItemState>& itemStates);
//void addDirectory(const QModelIndex& parentIndex, QList<ItemState>& itemStates);
/**
* Returns a matching plugin for the given directory.
@ -133,9 +133,7 @@ private:
bool m_silentUpdate; // if true, no messages will be send during the update
// of version states
QWidget* m_view;
//KDirLister* m_dirLister;
//DolphinModel* m_dolphinModel;
KFileItemModel* m_model;
QTimer* m_dirVerificationTimer;