Adjust uncrustify config, reformat all but Mac client

There're places where manual intervention is still required as uncrustify
is not ideal (unfortunately), but at least one may rely on it to do the
right thing most of the time (e.g. when sending in a patch).

The style itself is quite different from what we had before but making it
uniform across all the codebase is the key. I also hope that it'll make the
code more readable (YMMV) and less sensitive to further changes.
This commit is contained in:
Mike Gelfand
2017-04-19 15:04:45 +03:00
parent fdfbe225da
commit d7930984ef
297 changed files with 69885 additions and 63878 deletions

View File

@@ -15,538 +15,613 @@
namespace
{
class PathIteratorBase
{
protected:
PathIteratorBase(const QString& path, int slashIndex):
myPath (path),
mySlashIndex (slashIndex),
myToken ()
{
myToken.reserve (path.size () / 2);
}
protected:
const QString& myPath;
int mySlashIndex;
QString myToken;
class PathIteratorBase
{
protected:
PathIteratorBase(const QString& path, int slashIndex) :
myPath(path),
mySlashIndex(slashIndex),
myToken()
{
myToken.reserve(path.size() / 2);
}
static const QChar SlashChar;
};
protected:
const QString& myPath;
int mySlashIndex;
QString myToken;
const QChar PathIteratorBase::SlashChar = QLatin1Char ('/');
static const QChar SlashChar;
};
class ForwardPathIterator: public PathIteratorBase
{
public:
ForwardPathIterator (const QString& path):
PathIteratorBase (path, path.size () - 1)
{
}
const QChar PathIteratorBase::SlashChar = QLatin1Char('/');
bool hasNext () const
{
class ForwardPathIterator : public PathIteratorBase
{
public:
ForwardPathIterator(const QString& path) :
PathIteratorBase(path, path.size() - 1)
{
}
bool hasNext() const
{
return mySlashIndex > 0;
}
}
const QString& next ()
{
int newSlashIndex = myPath.lastIndexOf (SlashChar, mySlashIndex);
myToken.truncate (0);
myToken += myPath.midRef (newSlashIndex + 1, mySlashIndex - newSlashIndex);
const QString& next()
{
int newSlashIndex = myPath.lastIndexOf(SlashChar, mySlashIndex);
myToken.truncate(0);
myToken += myPath.midRef(newSlashIndex + 1, mySlashIndex - newSlashIndex);
mySlashIndex = newSlashIndex - 1;
return myToken;
}
};
}
};
class BackwardPathIterator: public PathIteratorBase
{
public:
BackwardPathIterator (const QString& path):
PathIteratorBase (path, 0)
{
}
class BackwardPathIterator : public PathIteratorBase
{
public:
BackwardPathIterator(const QString& path) :
PathIteratorBase(path, 0)
{
}
bool hasNext () const
{
return mySlashIndex < myPath.size ();
}
bool hasNext() const
{
return mySlashIndex < myPath.size();
}
const QString& next()
{
int newSlashIndex = myPath.indexOf(SlashChar, mySlashIndex);
const QString& next ()
{
int newSlashIndex = myPath.indexOf (SlashChar, mySlashIndex);
if (newSlashIndex == -1)
newSlashIndex = myPath.size ();
myToken.truncate (0);
myToken += myPath.midRef (mySlashIndex, newSlashIndex - mySlashIndex);
{
newSlashIndex = myPath.size();
}
myToken.truncate(0);
myToken += myPath.midRef(mySlashIndex, newSlashIndex - mySlashIndex);
mySlashIndex = newSlashIndex + 1;
return myToken;
}
};
}
}
};
FileTreeModel::FileTreeModel (QObject * parent, bool isEditable):
QAbstractItemModel(parent),
myIsEditable (isEditable),
myRootItem (new FileTreeItem),
myIndexCache ()
} // namespace
FileTreeModel::FileTreeModel(QObject* parent, bool isEditable) :
QAbstractItemModel(parent),
myIsEditable(isEditable),
myRootItem(new FileTreeItem),
myIndexCache()
{
}
FileTreeModel::~FileTreeModel()
{
clear();
clear();
delete myRootItem;
delete myRootItem;
}
void
FileTreeModel::setEditable (bool editable)
void FileTreeModel::setEditable(bool editable)
{
myIsEditable = editable;
myIsEditable = editable;
}
FileTreeItem *
FileTreeModel::itemFromIndex (const QModelIndex& index) const
FileTreeItem* FileTreeModel::itemFromIndex(const QModelIndex& index) const
{
if (!index.isValid())
return nullptr;
assert (index.model () == this);
return static_cast<FileTreeItem*>(index.internalPointer());
}
QModelIndexList
FileTreeModel::getOrphanIndices (const QModelIndexList& indices) const
{
QModelIndexList orphanIndices = indices;
qSort (orphanIndices);
for (QMutableListIterator<QModelIndex> it (orphanIndices); it.hasNext ();)
if (!index.isValid())
{
QModelIndex walk = it.next ();
return nullptr;
}
for (;;)
assert(index.model() == this);
return static_cast<FileTreeItem*>(index.internalPointer());
}
QModelIndexList FileTreeModel::getOrphanIndices(const QModelIndexList& indices) const
{
QModelIndexList orphanIndices = indices;
qSort(orphanIndices);
for (QMutableListIterator<QModelIndex> it(orphanIndices); it.hasNext();)
{
QModelIndex walk = it.next();
for (;;)
{
walk = parent (walk, walk.column ());
if (!walk.isValid ())
break;
walk = parent(walk, walk.column());
if (qBinaryFind (orphanIndices, walk) != orphanIndices.end ())
if (!walk.isValid())
{
it.remove ();
break;
break;
}
if (qBinaryFind(orphanIndices, walk) != orphanIndices.end())
{
it.remove();
break;
}
}
}
return orphanIndices;
return orphanIndices;
}
QVariant
FileTreeModel::data (const QModelIndex &index, int role) const
QVariant FileTreeModel::data(const QModelIndex& index, int role) const
{
QVariant value;
QVariant value;
if (index.isValid())
value = itemFromIndex(index)->data (index.column(), role);
return value;
}
Qt::ItemFlags
FileTreeModel::flags (const QModelIndex& index) const
{
int i(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
if(myIsEditable && (index.column() == COL_NAME))
i |= Qt::ItemIsEditable;
if(index.column() == COL_WANTED)
i |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
return Qt::ItemFlags(i);
}
bool
FileTreeModel::setData (const QModelIndex& index, const QVariant& newname, int role)
{
if (role == Qt::EditRole)
if (index.isValid())
{
FileTreeItem * item = itemFromIndex (index);
emit pathEdited (item->path (), newname.toString ());
value = itemFromIndex(index)->data(index.column(), role);
}
return false; // don't update the view until the session confirms the change
return value;
}
QVariant
FileTreeModel::headerData (int column, Qt::Orientation orientation, int role) const
Qt::ItemFlags FileTreeModel::flags(const QModelIndex& index) const
{
QVariant data;
int i(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
if (orientation==Qt::Horizontal && role==Qt::DisplayRole)
if (myIsEditable && (index.column() == COL_NAME))
{
switch (column)
i |= Qt::ItemIsEditable;
}
if (index.column() == COL_WANTED)
{
i |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
}
return Qt::ItemFlags(i);
}
bool FileTreeModel::setData(const QModelIndex& index, const QVariant& newname, int role)
{
if (role == Qt::EditRole)
{
FileTreeItem* item = itemFromIndex(index);
emit pathEdited(item->path(), newname.toString());
}
return false; // don't update the view until the session confirms the change
}
QVariant FileTreeModel::headerData(int column, Qt::Orientation orientation, int role) const
{
QVariant data;
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
switch (column)
{
case COL_NAME:
data.setValue (tr("File"));
case COL_NAME:
data.setValue(tr("File"));
break;
case COL_SIZE:
data.setValue (tr("Size"));
case COL_SIZE:
data.setValue(tr("Size"));
break;
case COL_PROGRESS:
data.setValue (tr("Progress"));
case COL_PROGRESS:
data.setValue(tr("Progress"));
break;
case COL_WANTED:
data.setValue (tr("Download"));
case COL_WANTED:
data.setValue(tr("Download"));
break;
case COL_PRIORITY:
data.setValue (tr("Priority"));
case COL_PRIORITY:
data.setValue(tr("Priority"));
break;
default:
default:
break;
}
}
return data;
return data;
}
QModelIndex
FileTreeModel::index (int row, int column, const QModelIndex& parent) const
QModelIndex FileTreeModel::index(int row, int column, const QModelIndex& parent) const
{
QModelIndex i;
QModelIndex i;
if (hasIndex (row, column, parent))
if (hasIndex(row, column, parent))
{
FileTreeItem * parentItem;
FileTreeItem* parentItem;
if (!parent.isValid ())
if (!parent.isValid())
{
parentItem = myRootItem;
}
else
{
parentItem = itemFromIndex(parent);
}
FileTreeItem* childItem = parentItem->child(row);
if (childItem)
{
i = createIndex(row, column, childItem);
}
}
return i;
}
QModelIndex FileTreeModel::parent(const QModelIndex& child) const
{
return parent(child, 0); // QAbstractItemModel::parent() wants col 0
}
QModelIndex FileTreeModel::parent(const QModelIndex& child, int column) const
{
QModelIndex parent;
if (child.isValid())
{
parent = indexOf(itemFromIndex(child)->parent(), column);
}
return parent;
}
int FileTreeModel::rowCount(const QModelIndex& parent) const
{
FileTreeItem* parentItem;
if (parent.isValid())
{
parentItem = itemFromIndex(parent);
}
else
{
parentItem = myRootItem;
else
parentItem = itemFromIndex (parent);
FileTreeItem * childItem = parentItem->child (row);
if (childItem)
i = createIndex (row, column, childItem);
}
return i;
return parentItem->childCount();
}
QModelIndex
FileTreeModel::parent (const QModelIndex& child) const
int FileTreeModel::columnCount(const QModelIndex& parent) const
{
return parent (child, 0); // QAbstractItemModel::parent() wants col 0
Q_UNUSED(parent);
return NUM_COLUMNS;
}
QModelIndex
FileTreeModel::parent (const QModelIndex& child, int column) const
QModelIndex FileTreeModel::indexOf(FileTreeItem* item, int column) const
{
QModelIndex parent;
if (child.isValid())
parent = indexOf (itemFromIndex(child)->parent(), column);
return parent;
}
int
FileTreeModel::rowCount (const QModelIndex& parent) const
{
FileTreeItem * parentItem;
if (parent.isValid())
parentItem = itemFromIndex (parent);
else
parentItem = myRootItem;
return parentItem->childCount();
}
int
FileTreeModel::columnCount (const QModelIndex& parent) const
{
Q_UNUSED(parent);
return NUM_COLUMNS;
}
QModelIndex
FileTreeModel::indexOf (FileTreeItem * item, int column) const
{
if (!item || item==myRootItem)
return QModelIndex();
return createIndex(item->row(), column, item);
}
void
FileTreeModel::clearSubtree (const QModelIndex& top)
{
size_t i = rowCount (top);
while (i > 0)
clearSubtree(index(--i, 0, top));
FileTreeItem * const item = itemFromIndex (top);
if (item == 0)
return;
if (item->fileIndex () != -1)
myIndexCache.remove (item->fileIndex ());
delete item;
}
void
FileTreeModel::clear ()
{
beginResetModel ();
clearSubtree (QModelIndex());
endResetModel ();
assert (myIndexCache.isEmpty ());
}
FileTreeItem *
FileTreeModel::findItemForFileIndex (int fileIndex) const
{
return myIndexCache.value (fileIndex, 0);
}
void
FileTreeModel::addFile (int fileIndex,
const QString& filename,
bool wanted,
int priority,
uint64_t totalSize,
uint64_t have,
bool updateFields)
{
FileTreeItem * item;
item = findItemForFileIndex (fileIndex);
if (item) // this file is already in the tree, we've added this
if (!item || item == myRootItem)
{
QModelIndex indexWithChangedParents;
ForwardPathIterator filenameIt (filename);
while (filenameIt.hasNext ())
return QModelIndex();
}
return createIndex(item->row(), column, item);
}
void FileTreeModel::clearSubtree(const QModelIndex& top)
{
size_t i = rowCount(top);
while (i > 0)
{
clearSubtree(index(--i, 0, top));
}
FileTreeItem* const item = itemFromIndex(top);
if (item == 0)
{
return;
}
if (item->fileIndex() != -1)
{
myIndexCache.remove(item->fileIndex());
}
delete item;
}
void FileTreeModel::clear()
{
beginResetModel();
clearSubtree(QModelIndex());
endResetModel();
assert(myIndexCache.isEmpty());
}
FileTreeItem* FileTreeModel::findItemForFileIndex(int fileIndex) const
{
return myIndexCache.value(fileIndex, 0);
}
void FileTreeModel::addFile(int fileIndex, const QString& filename, bool wanted, int priority, uint64_t totalSize,
uint64_t have, bool updateFields)
{
FileTreeItem* item;
item = findItemForFileIndex(fileIndex);
if (item) // this file is already in the tree, we've added this
{
QModelIndex indexWithChangedParents;
ForwardPathIterator filenameIt(filename);
while (filenameIt.hasNext())
{
const QString& token = filenameIt.next ();
const std::pair<int,int> changed = item->update (token, wanted, priority, have, updateFields);
if (changed.first >= 0)
const QString& token = filenameIt.next();
const std::pair<int, int> changed = item->update(token, wanted, priority, have, updateFields);
if (changed.first >= 0)
{
emit dataChanged (indexOf (item, changed.first), indexOf (item, changed.second));
if (!indexWithChangedParents.isValid () &&
changed.first <= COL_PRIORITY && changed.second >= COL_SIZE)
indexWithChangedParents = indexOf (item, 0);
emit dataChanged(indexOf(item, changed.first), indexOf(item, changed.second));
if (!indexWithChangedParents.isValid() && changed.first <= COL_PRIORITY && changed.second >= COL_SIZE)
{
indexWithChangedParents = indexOf(item, 0);
}
}
item = item->parent();
item = item->parent();
}
assert(item == myRootItem);
if (indexWithChangedParents.isValid())
{
emitParentsChanged(indexWithChangedParents, COL_SIZE, COL_PRIORITY);
}
assert (item == myRootItem);
if (indexWithChangedParents.isValid ())
emitParentsChanged (indexWithChangedParents, COL_SIZE, COL_PRIORITY);
}
else // we haven't build the FileTreeItems for these tokens yet
else // we haven't build the FileTreeItems for these tokens yet
{
bool added = false;
bool added = false;
item = myRootItem;
BackwardPathIterator filenameIt (filename);
while (filenameIt.hasNext ())
item = myRootItem;
BackwardPathIterator filenameIt(filename);
while (filenameIt.hasNext())
{
const QString& token = filenameIt.next ();
FileTreeItem * child(item->child(token));
if (!child)
{
added = true;
QModelIndex parentIndex (indexOf(item, 0));
const int n (item->childCount());
const QString& token = filenameIt.next();
FileTreeItem* child(item->child(token));
beginInsertRows (parentIndex, n, n);
if (!filenameIt.hasNext ())
child = new FileTreeItem (token, fileIndex, totalSize);
else
child = new FileTreeItem (token);
item->appendChild (child);
endInsertRows ();
if (!child)
{
added = true;
QModelIndex parentIndex(indexOf(item, 0));
const int n(item->childCount());
beginInsertRows(parentIndex, n, n);
if (!filenameIt.hasNext())
{
child = new FileTreeItem(token, fileIndex, totalSize);
}
else
{
child = new FileTreeItem(token);
}
item->appendChild(child);
endInsertRows();
}
item = child;
item = child;
}
if (item != myRootItem)
if (item != myRootItem)
{
assert (item->fileIndex() == fileIndex);
assert (item->totalSize() == totalSize);
assert(item->fileIndex() == fileIndex);
assert(item->totalSize() == totalSize);
myIndexCache[fileIndex] = item;
myIndexCache[fileIndex] = item;
const std::pair<int,int> changed = item->update (item->name(), wanted, priority, have, added || updateFields);
if (changed.first >= 0)
emit dataChanged (indexOf (item, changed.first), indexOf (item, changed.second));
const std::pair<int, int> changed = item->update(item->name(), wanted, priority, have, added || updateFields);
if (changed.first >= 0)
{
emit dataChanged(indexOf(item, changed.first), indexOf(item, changed.second));
}
}
}
}
void
FileTreeModel::emitParentsChanged (const QModelIndex& index, int firstColumn, int lastColumn, QSet<QModelIndex> * visitedParentIndices)
void FileTreeModel::emitParentsChanged(const QModelIndex& index, int firstColumn, int lastColumn,
QSet<QModelIndex>* visitedParentIndices)
{
assert (firstColumn <= lastColumn);
assert(firstColumn <= lastColumn);
QModelIndex walk = index;
QModelIndex walk = index;
for (;;)
for (;;)
{
walk = parent (walk, firstColumn);
if (!walk.isValid ())
break;
walk = parent(walk, firstColumn);
if (visitedParentIndices != nullptr)
if (!walk.isValid())
{
if (visitedParentIndices->contains (walk))
break;
visitedParentIndices->insert (walk);
}
emit dataChanged (walk, walk.sibling (walk.row (), lastColumn));
if (visitedParentIndices != nullptr)
{
if (visitedParentIndices->contains(walk))
{
break;
}
visitedParentIndices->insert(walk);
}
emit dataChanged(walk, walk.sibling(walk.row(), lastColumn));
}
}
void
FileTreeModel::emitSubtreeChanged (const QModelIndex& index, int firstColumn, int lastColumn)
void FileTreeModel::emitSubtreeChanged(const QModelIndex& index, int firstColumn, int lastColumn)
{
assert (firstColumn <= lastColumn);
assert(firstColumn <= lastColumn);
const int childCount = rowCount (index);
if (!childCount)
return;
const int childCount = rowCount(index);
// tell everyone that this item changed
emit dataChanged (index.child (0, firstColumn), index.child (childCount - 1, lastColumn));
if (!childCount)
{
return;
}
// walk the subitems
for (int i=0; i<childCount; ++i)
emitSubtreeChanged (index.child (i, 0), firstColumn, lastColumn);
// tell everyone that this item changed
emit dataChanged(index.child(0, firstColumn), index.child(childCount - 1, lastColumn));
// walk the subitems
for (int i = 0; i < childCount; ++i)
{
emitSubtreeChanged(index.child(i, 0), firstColumn, lastColumn);
}
}
void
FileTreeModel::twiddleWanted (const QModelIndexList& indices)
void FileTreeModel::twiddleWanted(const QModelIndexList& indices)
{
QMap<bool, QModelIndexList> wantedIndices;
for (const QModelIndex& i: getOrphanIndices (indices))
QMap<bool, QModelIndexList> wantedIndices;
for (const QModelIndex& i : getOrphanIndices(indices))
{
const FileTreeItem * const item = itemFromIndex (i);
wantedIndices[item->isSubtreeWanted () != Qt::Checked] << i;
const FileTreeItem* const item = itemFromIndex(i);
wantedIndices[item->isSubtreeWanted() != Qt::Checked] << i;
}
for (int i = 0; i <= 1; ++i)
for (int i = 0; i <= 1; ++i)
{
if (wantedIndices.contains (i))
setWanted (wantedIndices[i], i != 0);
if (wantedIndices.contains(i))
{
setWanted(wantedIndices[i], i != 0);
}
}
}
void
FileTreeModel::twiddlePriority (const QModelIndexList& indices)
void FileTreeModel::twiddlePriority(const QModelIndexList& indices)
{
QMap<int, QModelIndexList> priorityIndices;
for (const QModelIndex& i: getOrphanIndices (indices))
QMap<int, QModelIndexList> priorityIndices;
for (const QModelIndex& i : getOrphanIndices(indices))
{
const FileTreeItem * const item = itemFromIndex (i);
int priority = item->priority ();
const FileTreeItem* const item = itemFromIndex(i);
int priority = item->priority();
// ... -> normal -> high -> low -> normal -> ...; mixed -> normal
if (priority == FileTreeItem::NORMAL)
priority = TR_PRI_HIGH;
else if (priority == FileTreeItem::HIGH)
priority = TR_PRI_LOW;
else
priority = TR_PRI_NORMAL;
// ... -> normal -> high -> low -> normal -> ...; mixed -> normal
if (priority == FileTreeItem::NORMAL)
{
priority = TR_PRI_HIGH;
}
else if (priority == FileTreeItem::HIGH)
{
priority = TR_PRI_LOW;
}
else
{
priority = TR_PRI_NORMAL;
}
priorityIndices[priority] << i;
priorityIndices[priority] << i;
}
for (int i = TR_PRI_LOW; i <= TR_PRI_HIGH; ++i)
for (int i = TR_PRI_LOW; i <= TR_PRI_HIGH; ++i)
{
if (priorityIndices.contains (i))
setPriority (priorityIndices[i], i);
if (priorityIndices.contains(i))
{
setPriority(priorityIndices[i], i);
}
}
}
void
FileTreeModel::setWanted (const QModelIndexList& indices, bool wanted)
void FileTreeModel::setWanted(const QModelIndexList& indices, bool wanted)
{
if (indices.isEmpty ())
return;
const QModelIndexList orphanIndices = getOrphanIndices (indices);
QSet<int> fileIds;
for (const QModelIndex& i: orphanIndices)
if (indices.isEmpty())
{
FileTreeItem * const item = itemFromIndex (i);
item->setSubtreeWanted (wanted, fileIds);
emit dataChanged (i, i);
emitSubtreeChanged (i, COL_WANTED, COL_WANTED);
return;
}
// emit parent changes separately to avoid multiple updates for same items
QSet<QModelIndex> parentIndices;
for (const QModelIndex& i: orphanIndices)
emitParentsChanged (i, COL_SIZE, COL_WANTED, &parentIndices);
const QModelIndexList orphanIndices = getOrphanIndices(indices);
if (!fileIds.isEmpty ())
emit wantedChanged (fileIds, wanted);
}
QSet<int> fileIds;
void
FileTreeModel::setPriority (const QModelIndexList& indices, int priority)
{
if (indices.isEmpty ())
return;
const QModelIndexList orphanIndices = getOrphanIndices (indices);
QSet<int> fileIds;
for (const QModelIndex& i: orphanIndices)
for (const QModelIndex& i : orphanIndices)
{
FileTreeItem * const item = itemFromIndex (i);
item->setSubtreePriority (priority, fileIds);
FileTreeItem* const item = itemFromIndex(i);
item->setSubtreeWanted(wanted, fileIds);
emit dataChanged (i, i);
emitSubtreeChanged (i, COL_PRIORITY, COL_PRIORITY);
emit dataChanged(i, i);
emitSubtreeChanged(i, COL_WANTED, COL_WANTED);
}
// emit parent changes separately to avoid multiple updates for same items
QSet<QModelIndex> parentIndices;
for (const QModelIndex& i: orphanIndices)
emitParentsChanged (i, COL_PRIORITY, COL_PRIORITY, &parentIndices);
// emit parent changes separately to avoid multiple updates for same items
QSet<QModelIndex> parentIndices;
if (!fileIds.isEmpty ())
emit priorityChanged (fileIds, priority);
for (const QModelIndex& i : orphanIndices)
{
emitParentsChanged(i, COL_SIZE, COL_WANTED, &parentIndices);
}
if (!fileIds.isEmpty())
{
emit wantedChanged(fileIds, wanted);
}
}
bool
FileTreeModel::openFile (const QModelIndex& index)
void FileTreeModel::setPriority(const QModelIndexList& indices, int priority)
{
if (!index.isValid ())
return false;
if (indices.isEmpty())
{
return;
}
FileTreeItem * const item = itemFromIndex (index);
if (item->fileIndex () < 0 || !item->isComplete ())
return false;
const QModelIndexList orphanIndices = getOrphanIndices(indices);
emit openRequested (item->path ());
return true;
QSet<int> fileIds;
for (const QModelIndex& i : orphanIndices)
{
FileTreeItem* const item = itemFromIndex(i);
item->setSubtreePriority(priority, fileIds);
emit dataChanged(i, i);
emitSubtreeChanged(i, COL_PRIORITY, COL_PRIORITY);
}
// emit parent changes separately to avoid multiple updates for same items
QSet<QModelIndex> parentIndices;
for (const QModelIndex& i : orphanIndices)
{
emitParentsChanged(i, COL_PRIORITY, COL_PRIORITY, &parentIndices);
}
if (!fileIds.isEmpty())
{
emit priorityChanged(fileIds, priority);
}
}
bool FileTreeModel::openFile(const QModelIndex& index)
{
if (!index.isValid())
{
return false;
}
FileTreeItem* const item = itemFromIndex(index);
if (item->fileIndex() < 0 || !item->isComplete())
{
return false;
}
emit openRequested(item->path());
return true;
}