diff --git a/manifest b/manifest index 20e187f..527ae05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\srefactoring -D 2015-07-10T18:43:33.614 +C Merged\sfolder-state\sbranch +D 2015-07-11T11:50:18.204 F .travis.yml 77966888a81c4ceee1fcc79bce842c9667ad8a35 F debian/changelog eb4304dfcb6bb66850ec740838090eb50ce1249b F debian/compat b6abd567fa79cbe0196d093a067271361dc6ca8b @@ -205,7 +205,7 @@ F rsrc/icons/Zoom-01.png 67ca532922e9166325c5c75fce1ca3fbb0d2b6a6 F rsrc/icons/fuel.icns 81e535004b62db801a02f3e15d0a33afc9d4070b F rsrc/icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038 F rsrc/icons/fuel.png 40daf53b7f6bdcdd0d6aa5ef433d078ec5ea4342 -F rsrc/resources.qrc 388225a5b09c56c12d4cbde8b4d0b4466740fc97 +F rsrc/resources.qrc eee283057169f9a5b32095c0d5cbc99cbc31ad1a F src/BrowserWidget.cpp 8b8f545cdff4a4188edc698a1b4777f5df46f056 F src/BrowserWidget.h 764d66aa9a93b890298bd0301097739cb4e16597 F src/CloneDialog.cpp c341622b01d493387d6e4928018b3392d92471e8 @@ -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 764eb76c1c420ea4677639baae925e5e8fc203d6 +F src/MainWindow.cpp b9920340aaa14152287c482b524b12499067dc33 F src/MainWindow.h 765c362ad4937da808276ec321adf4a351ab5b28 F src/RemoteDialog.cpp 8540cc5e2e41c4127ed8a028d84691604fa6ecac F src/RemoteDialog.h 5e0438c2bd7c79b1bb44bfbd58c2181b544a9e5d @@ -238,8 +238,8 @@ F src/SettingsDialog.cpp cab739fb0569bd26550e57f97136c7515fe757fe F src/SettingsDialog.h 5eb3ae2cbb00ab5544e1889860f5376f69fe47cd F src/Utils.cpp e047c7aaeb4fb4b64c1383df5cb35d269abb87ed F src/Utils.h cb0499ead8dd5662b184dbeabb6e66c3ae65eebc -F src/Workspace.cpp 7004c2c30f79d2e64691aa9b2c55ee72a84d978b -F src/Workspace.h 0ab9b941a537134a7c43cfccee5299b8ccda143a +F src/Workspace.cpp b4f0bb95dfc49c1e906f8a163d518050c3f945db +F src/Workspace.h 731ec8ae7e97d500f85ee13b18024efbd3d55516 F src/main.cpp d8c65ea5e54102e4989fef9fd8cfd4f13ef8a8f0 F tools/git-push.sh 62cc58434cae5b7bcd6bd9d4cce8b08739f31cd7 x F tools/pack.sh d7f38a498c4e9327fecd6a6e5ac27be270d43008 x @@ -252,7 +252,8 @@ F ui/MainWindow.ui 10181826a25056ed5aba2b23a7d110159be7c043 F ui/RemoteDialog.ui 95a4750d972ed8c49bb10b95db91ff16cfe2dd0b F ui/RevisionDialog.ui 27c3b98c665fec014a50cbf3352c0627f75e68cd F ui/SettingsDialog.ui 47b9a31e28ad523f14a1c4cd361270b6babbdf7d -P 7cd82ba8f02f659d13a370043f256212f55669db -R b1470ef543fad9773da5e4edf313b8fb +P ccbdbff89e2354c6d8f38d994587328a04112eaa 0f8cf57fa2a7b38a7d2a8ca22d7e0fa09b1cd24d +R d10a7a3bf72e8afb9416f20dd6e5fec3 +T +closed 0f8cf57fa2a7b38a7d2a8ca22d7e0fa09b1cd24d U kostas -Z 032611050518136012ef63aed85ba8cb +Z 24f7a95608407ce6b9d41dea21fc53e5 diff --git a/manifest.uuid b/manifest.uuid index ef22da4..324b29e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccbdbff89e2354c6d8f38d994587328a04112eaa \ No newline at end of file +cca2042b901945b1079faedaa7339578f6192a3f \ No newline at end of file diff --git a/rsrc/resources.qrc b/rsrc/resources.qrc index 779203f..a89bdb2 100644 --- a/rsrc/resources.qrc +++ b/rsrc/resources.qrc @@ -98,9 +98,9 @@ icons/Folder Explorer-01.png icons/Folder Explorer-01.png icons/Folder Generic Blue-01.png - icons/Folder Generic Green-01.png - icons/Folder Generic Red-01.png - icons/Folder Generic Silver-01.png + icons/Folder Generic Green-01.png + icons/Folder Generic Red-01.png + icons/Folder Generic Silver-01.png icons/Folder Open-01.png icons/Folder RAR-01.png icons/Games-01.png diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 1ed61ce..40672fb 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -62,25 +62,38 @@ struct WorkspaceItem TYPE_REMOTE, }; + enum + { + STATE_DEFAULT, + STATE_UNCHANGED, + 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,9 +716,9 @@ void MainWindow::scanWorkspace() } //------------------------------------------------------------------------------ -static void addPathToTree(QStandardItem &root, const QString &path, const QIcon &folderIcon) +static void addPathToTree(QStandardItem &root, const QString &path, const QIcon &iconDefault, const QIcon &iconUnchanged, const QIcon &iconModified, const QIcon &iconUnknown, const pathstate_map_t &pathState) { - QStringList dirs = path.split('/'); + QStringList dirs = path.split(PATH_SEPARATOR); QStandardItem *parent = &root; QString fullpath; @@ -729,12 +742,51 @@ static void addPathToTree(QStandardItem &root, const QString &path, const QIcon if(!found) // Generate it { - QStandardItem *child = new QStandardItem(folderIcon, dir); - child->setData(WorkspaceItem(WorkspaceItem::TYPE_FOLDER, fullpath), ROLE_WORKSPACE_ITEM); + int state = WorkspaceItem::STATE_DEFAULT; + + pathstate_map_t::const_iterator state_it = pathState.find(fullpath); + if(state_it != pathState.end()) + { + WorkspaceFile::Type type = state_it.value(); + + if(type & (WorkspaceFile::TYPE_MODIFIED)) + state = WorkspaceItem::STATE_MODIFIED; + else if(type == WorkspaceFile::TYPE_UNKNOWN) + state = WorkspaceItem::STATE_UNKNOWN; + else + state = WorkspaceItem::STATE_UNCHANGED; + } + + QStandardItem *child = new QStandardItem(dir); + child->setData(WorkspaceItem(WorkspaceItem::TYPE_FOLDER, fullpath, state), ROLE_WORKSPACE_ITEM); + + QString tooltip = fullpath; + + if(state == WorkspaceItem::STATE_UNCHANGED) + { + child->setIcon(iconUnchanged); + tooltip += " " + QObject::tr("Unchanged"); + } + else if(state == WorkspaceItem::STATE_MODIFIED) + { + child->setIcon(iconModified); + tooltip += " " + QObject::tr("Modified"); + } + else if(state == WorkspaceItem::STATE_UNKNOWN) + { + child->setIcon(iconUnknown); + tooltip += " " + QObject::tr("Unknown"); + } + else + child->setIcon(iconDefault); + + child->setToolTip(tooltip); + parent->appendRow(child); parent = child; } - fullpath += '/'; + + fullpath += PATH_SEPARATOR; } } @@ -769,13 +821,21 @@ void MainWindow::updateWorkspaceView() getWorkspace().getTreeModel().appendRow(workspace); if(viewMode == VIEWMODE_TREE) { - for(stringset_t::iterator it = getWorkspace().getPaths().begin(); it!=getWorkspace().getPaths().end(); ++it) + // FIXME: Change paths to map to allow for automatic sorting + QStringList paths = getWorkspace().getPaths().toList(); + paths.sort(); + + foreach(const QString &dir, paths) { - const QString &dir = *it; if(dir.isEmpty()) continue; - addPathToTree(*workspace, dir, getInternalIcon(":icons/icon-item-folder")); + addPathToTree(*workspace, dir, + getInternalIcon(":icons/icon-item-folder"), + getInternalIcon(":icons/icon-item-folder-unchanged"), + getInternalIcon(":icons/icon-item-folder-modified"), + getInternalIcon(":icons/icon-item-folder-unknown"), + getWorkspace().getPathState()); } // Expand root folder diff --git a/src/Workspace.cpp b/src/Workspace.cpp index 8316b4a..3219e92 100644 --- a/src/Workspace.cpp +++ b/src/Workspace.cpp @@ -22,6 +22,7 @@ void Workspace::clearState() getFiles().clear(); getPaths().clear(); + pathState.clear(); stashMap.clear(); branchList.clear(); tags.clear(); @@ -148,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) { @@ -167,6 +174,8 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie clearState(); + QStringList paths; + operationAborted = false; uiCallback.beginProcess(""); @@ -195,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(); @@ -205,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(); @@ -278,6 +299,44 @@ void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModifie QString path = 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 + } + } + + // 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 diff --git a/src/Workspace.h b/src/Workspace.h index b7cd50e..5f7d241 100644 --- a/src/Workspace.h +++ b/src/Workspace.h @@ -112,6 +112,7 @@ public: }; typedef QMap remote_map_t; +typedef QMap pathstate_map_t; ////////////////////////////////////////////////////////////////////////// @@ -140,6 +141,7 @@ public: filemap_t &getFiles() { return workspaceFiles; } stringset_t &getPaths() { return pathSet; } + pathstate_map_t &getPathState() { return pathState; } stashmap_t &getStashes() { return stashMap; } QStringMap &getTags() { return tags; } QStringList &getBranches() { return branchList; } @@ -162,6 +164,7 @@ private: Fossil bridge; filemap_t workspaceFiles; stringset_t pathSet; + pathstate_map_t pathState; stashmap_t stashMap; QStringList branchList; QStringMap tags;