From 51a74879c83904ed25cecb952d8568cb672d14a6 Mon Sep 17 00:00:00 2001 From: kostas Date: Sat, 11 Jul 2015 11:11:23 +0000 Subject: [PATCH] Folder state generation and propagation now happens during workspace scan. FossilOrigin-Name: 309756d79851ed8606d748fb226b2eab3d2276a8 --- manifest | 17 +++++------- manifest.uuid | 2 +- src/MainWindow.cpp | 62 ++++++++++++++++++++++++-------------------- src/Workspace.cpp | 64 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 99 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 6767e57..cf80497 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\swork\son\sworkspace\sfolder\sstate\svisualization\n -D 2015-07-10T19:52:55.124 +C Folder\sstate\sgeneration\sand\spropagation\snow\shappens\sduring\sworkspace\sscan. +D 2015-07-11T11:11:23.497 F .travis.yml 77966888a81c4ceee1fcc79bce842c9667ad8a35 F debian/changelog eb4304dfcb6bb66850ec740838090eb50ce1249b F debian/compat b6abd567fa79cbe0196d093a067271361dc6ca8b @@ -224,7 +224,7 @@ F src/FslSettingsDialog.cpp 2531d3709f0eab66651671e3edead2ca720d07d5 F src/FslSettingsDialog.h dfe2a61884a55a74cbb9206b6f6b482b979725e7 F src/LoggedProcess.cpp 2a1e5c94bc1e57c8984563e66c210e43a14dc60c F src/LoggedProcess.h 85df7c635c807a5a0e8c4763f17a0752aaff7261 -F src/MainWindow.cpp c8157260127f662ec1e9f613840552d3fdf53ce0 +F src/MainWindow.cpp 8fa06052057d3baea6940bb678a3d5635c923028 F src/MainWindow.h 765c362ad4937da808276ec321adf4a351ab5b28 F src/RemoteDialog.cpp 8540cc5e2e41c4127ed8a028d84691604fa6ecac F src/RemoteDialog.h 5e0438c2bd7c79b1bb44bfbd58c2181b544a9e5d @@ -238,7 +238,7 @@ F src/SettingsDialog.cpp cab739fb0569bd26550e57f97136c7515fe757fe F src/SettingsDialog.h 5eb3ae2cbb00ab5544e1889860f5376f69fe47cd F src/Utils.cpp e047c7aaeb4fb4b64c1383df5cb35d269abb87ed F src/Utils.h cb0499ead8dd5662b184dbeabb6e66c3ae65eebc -F src/Workspace.cpp 32ddf5ff2b5f92d9921aedb422bb906edcf601a8 +F src/Workspace.cpp b4f0bb95dfc49c1e906f8a163d518050c3f945db F src/Workspace.h 731ec8ae7e97d500f85ee13b18024efbd3d55516 F src/main.cpp d8c65ea5e54102e4989fef9fd8cfd4f13ef8a8f0 F tools/git-push.sh 62cc58434cae5b7bcd6bd9d4cce8b08739f31cd7 x @@ -252,10 +252,7 @@ F ui/MainWindow.ui 10181826a25056ed5aba2b23a7d110159be7c043 F ui/RemoteDialog.ui 95a4750d972ed8c49bb10b95db91ff16cfe2dd0b F ui/RevisionDialog.ui 27c3b98c665fec014a50cbf3352c0627f75e68cd F ui/SettingsDialog.ui 47b9a31e28ad523f14a1c4cd361270b6babbdf7d -P ccbdbff89e2354c6d8f38d994587328a04112eaa -R ed08a22c30e3753dc2cddf745977971b -T *branch * folder-state -T *sym-folder-state * -T -sym-trunk * +P a2d5250064d0499d5ceea87b5eadaa8b90057ba8 +R 6b66888091a002191379c9bfc712f500 U kostas -Z 79996f85066e37f8eb88b62ea7d82f6a +Z 4e5fa5b655da848f296886ad1e62bf9b diff --git a/manifest.uuid b/manifest.uuid index 58c64e3..89fdda2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2d5250064d0499d5ceea87b5eadaa8b90057ba8 \ No newline at end of file +309756d79851ed8606d748fb226b2eab3d2276a8 \ No newline at end of file diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 2e3d295..606bea0 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -62,25 +62,38 @@ struct WorkspaceItem TYPE_REMOTE, }; + enum + { + STATE_DEFAULT, + STATE_CLEAN, + STATE_MODIFIED, + STATE_UNKNOWN + }; + + WorkspaceItem() : Type(TYPE_UNKNOWN) + , State(STATE_DEFAULT) { } - WorkspaceItem(int type, const QString &value) - : Type(type), Value(value) + WorkspaceItem(int type, const QString &value, int state=STATE_DEFAULT) + : Type(type), State(state), Value(value) { } WorkspaceItem(const WorkspaceItem &other) { Type = other.Type; + State = other.State; Value = other.Value; } int Type; + int State; QString Value; + operator QVariant() const { return QVariant::fromValue(*this); @@ -703,7 +716,7 @@ void MainWindow::scanWorkspace() } //------------------------------------------------------------------------------ -static void addPathToTree(QStandardItem &root, const QString &path, const QIcon &folderDefaultIcon, const QIcon &folderIconClean, const QIcon &folderIconDirty, const pathstate_map_t &pathState) +static void addPathToTree(QStandardItem &root, const QString &path, const QIcon &iconDefault, const QIcon &iconClean, const QIcon &iconDirty, const QIcon &iconUnknown, const pathstate_map_t &pathState) { QStringList dirs = path.split('/'); QStandardItem *parent = &root; @@ -729,7 +742,7 @@ static void addPathToTree(QStandardItem &root, const QString &path, const QIcon if(!found) // Generate it { - const QIcon *icon = &folderDefaultIcon; + int state = WorkspaceItem::STATE_DEFAULT; pathstate_map_t::const_iterator state_it = pathState.find(fullpath); if(state_it != pathState.end()) @@ -737,34 +750,27 @@ static void addPathToTree(QStandardItem &root, const QString &path, const QIcon WorkspaceFile::Type type = state_it.value(); if(type & (WorkspaceFile::TYPE_MODIFIED)) - icon = &folderIconDirty; + state = WorkspaceItem::STATE_MODIFIED; + else if(type == WorkspaceFile::TYPE_UNKNOWN) + state = WorkspaceItem::STATE_UNKNOWN; else - icon = &folderIconClean; + state = WorkspaceItem::STATE_CLEAN; } - QStandardItem *child = new QStandardItem(*icon, dir); - child->setData(WorkspaceItem(WorkspaceItem::TYPE_FOLDER, fullpath), ROLE_WORKSPACE_ITEM); + QStandardItem *child = new QStandardItem(dir); + child->setData(WorkspaceItem(WorkspaceItem::TYPE_FOLDER, fullpath, state), ROLE_WORKSPACE_ITEM); + + if(state == WorkspaceItem::STATE_CLEAN) + child->setIcon(iconClean); + else if(state == WorkspaceItem::STATE_MODIFIED) + child->setIcon(iconDirty); + else if(state == WorkspaceItem::STATE_UNKNOWN) + child->setIcon(iconUnknown); + else + child->setIcon(iconDefault); + parent->appendRow(child); parent = child; - - // Update icons of parents - if(icon != &folderDefaultIcon) // Default Icon is not inherited by parent - { - QStandardItem *p = parent; - while(p && p != &root) // Ascend parents except the root node - { - const QIcon &parent_icon = p->icon(); - - // Dirty is inherited - if(icon == &folderIconDirty) - p->setIcon(*icon); - // Clean is inherited if not dirty - else if(icon == &folderIconClean && (&parent_icon != &folderIconDirty)) - p->setIcon(*icon); - - p = p->parent(); - } - } } fullpath += '/'; @@ -811,7 +817,7 @@ void MainWindow::updateWorkspaceView() if(dir.isEmpty()) continue; - addPathToTree(*workspace, dir, getInternalIcon(":icons/icon-item-folder"), getInternalIcon(":icons/icons/Folder Generic Green-01.png"), getInternalIcon(":icons/icons/Folder Generic Red-01.png"), getWorkspace().getPathState()); + addPathToTree(*workspace, dir, getInternalIcon(":icons/icon-item-folder"), getInternalIcon(":icons/icons/Folder Generic Green-01.png"), getInternalIcon(":icons/icons/Folder Generic Red-01.png"), getInternalIcon(":icons/icons/Folder Generic Silver-01.png"), getWorkspace().getPathState()); } // Expand root folder diff --git a/src/Workspace.cpp b/src/Workspace.cpp index 10d7392..3219e92 100644 --- a/src/Workspace.cpp +++ b/src/Workspace.cpp @@ -22,7 +22,7 @@ void Workspace::clearState() getFiles().clear(); getPaths().clear(); - getPathState().clear(); + pathState.clear(); stashMap.clear(); branchList.clear(); tags.clear(); @@ -149,6 +149,12 @@ bool Workspace::scanDirectory(QFileInfoList &entries, const QString& dirPath, co return true; } +//------------------------------------------------------------------------------ +static bool StringLengthDescending(const QString &l, const QString &r) +{ + return l.length() > r.length(); +} + //------------------------------------------------------------------------------ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModified, bool scanUnchanged, const QString &ignoreGlob, UICallback &uiCallback, bool &operationAborted) { @@ -168,6 +174,8 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie clearState(); + QStringList paths; + operationAborted = false; uiCallback.beginProcess(""); @@ -196,9 +204,22 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie if(filename == FOSSIL_CHECKOUT1 || filename == FOSSIL_CHECKOUT2 || (!fossil().getRepositoryFile().isEmpty() && QFileInfo(fullpath) == QFileInfo(fossil().getRepositoryFile()))) continue; - WorkspaceFile *rf = new WorkspaceFile(*it, WorkspaceFile::TYPE_UNKNOWN, wkdir); + WorkspaceFile::Type type = WorkspaceFile::TYPE_UNKNOWN; + + WorkspaceFile *rf = new WorkspaceFile(*it, type, wkdir); + const QString &path = rf->getPath(); getFiles().insert(rf->getFilePath(), rf); - getPaths().insert(rf->getPath()); + getPaths().insert(path); + + // Add or merge file state into directory state + pathstate_map_t::iterator state_it = pathState.find(path); + if(state_it != pathState.end()) + state_it.value() = static_cast(state_it.value() | type); + else + { + pathState.insert(path, type); + paths.append(path); // keep path in list for depth sort + } } } uiCallback.endProcess(); @@ -206,7 +227,6 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie uiCallback.beginProcess(QObject::tr("Updating...")); // Update Files and Directories - for(QStringList::iterator line_it=res.begin(); line_it!=res.end(); ++line_it) { QString line = (*line_it).trimmed(); @@ -281,12 +301,42 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie getPaths().insert(path); // Add or merge file state into directory state - pathstate_map_t::iterator state_it = getPathState().find(path); - if(state_it != getPathState().end()) + pathstate_map_t::iterator state_it = pathState.find(path); + if(state_it != pathState.end()) state_it.value() = static_cast(state_it.value() | type); else - getPathState().insert(path, type); + { + pathState.insert(path, type); + paths.append(path); // keep path in list for depth sort + } + } + // Sort paths, so that children (longer path) are before parents (shorter path) + std::sort(paths.begin(), paths.end(), StringLengthDescending); + foreach(const QString &p, paths) + { + pathstate_map_t::iterator state_it = pathState.find(p); + Q_ASSERT(state_it != pathState.end()); + WorkspaceFile::Type state = state_it.value(); + + // Propagate child dir state to parents + QString parent_path = p; + while(!parent_path.isEmpty()) + { + // Extract parent path + int sep_index = parent_path.lastIndexOf(PATH_SEPARATOR); + if(sep_index>=0) + parent_path = parent_path.left(sep_index); + else + parent_path = ""; + + // Merge path of child to parent + pathstate_map_t::iterator state_it = pathState.find(parent_path); + if(state_it != pathState.end()) + state_it.value() = static_cast(state_it.value() | state); + else + pathState.insert(parent_path, state); + } } // Check if the repository needs integration