comparison src/mainwindow.cpp @ 506:470829a21f98

Identify closed branches and display them in a lighter shade
author Chris Cannam
date Mon, 17 Oct 2011 22:08:05 +0100
parents 1c05e7576ea5
children 459aa20d3eee
comparison
equal deleted inserted replaced
505:1c05e7576ea5 506:470829a21f98
321 params << "branch"; 321 params << "branch";
322 m_runner->requestAction(HgAction(ACT_QUERY_BRANCH, m_workFolderPath, params)); 322 m_runner->requestAction(HgAction(ACT_QUERY_BRANCH, m_workFolderPath, params));
323 */ 323 */
324 } 324 }
325 325
326 void MainWindow::hgQueryHeadsActive()
327 {
328 QStringList params;
329 params << "heads" << "--active";
330 m_runner->requestAction(HgAction(ACT_QUERY_HEADS_ACTIVE, m_workFolderPath, params));
331 }
332
326 void MainWindow::hgQueryHeads() 333 void MainWindow::hgQueryHeads()
327 { 334 {
328 QStringList params; 335 QStringList params;
329 // On empty repos, "hg heads" will fail -- we don't care about 336 // On empty repos, "hg heads" will fail -- we don't care about
330 // that. Use --closed option so as to include closed branches; 337 // that. Use --closed option so as to include closed branches;
1249 DEBUG << "MainWindow::clearState" << endl; 1256 DEBUG << "MainWindow::clearState" << endl;
1250 foreach (Changeset *cs, m_currentParents) delete cs; 1257 foreach (Changeset *cs, m_currentParents) delete cs;
1251 m_currentParents.clear(); 1258 m_currentParents.clear();
1252 foreach (Changeset *cs, m_currentHeads) delete cs; 1259 foreach (Changeset *cs, m_currentHeads) delete cs;
1253 m_currentHeads.clear(); 1260 m_currentHeads.clear();
1261 m_closedHeadIds.clear();
1254 m_currentBranch = ""; 1262 m_currentBranch = "";
1255 m_lastStatOutput = ""; 1263 m_lastStatOutput = "";
1256 m_lastRevertedFiles.clear(); 1264 m_lastRevertedFiles.clear();
1257 m_mergeTargetRevision = ""; 1265 m_mergeTargetRevision = "";
1258 m_mergeCommitComment = ""; 1266 m_mergeCommitComment = "";
1977 void MainWindow::reportNewRemoteHeads(QString output) 1985 void MainWindow::reportNewRemoteHeads(QString output)
1978 { 1986 {
1979 bool headsAreLocal = false; 1987 bool headsAreLocal = false;
1980 1988
1981 if (m_currentParents.size() == 1) { 1989 if (m_currentParents.size() == 1) {
1982 int m_currentBranchHeads = 0; 1990 int currentBranchActiveHeads = 0;
1983 bool parentIsHead = false; 1991 bool parentIsHead = false;
1984 Changeset *parent = m_currentParents[0]; 1992 Changeset *parent = m_currentParents[0];
1985 foreach (Changeset *head, m_currentHeads) { 1993 foreach (Changeset *head, m_activeHeads) {
1986 if (head->isOnBranch(m_currentBranch)) { 1994 if (head->isOnBranch(m_currentBranch)) {
1987 ++m_currentBranchHeads; 1995 ++currentBranchActiveHeads;
1988 } 1996 }
1989 if (parent->id() == head->id()) { 1997 if (parent->id() == head->id()) {
1990 parentIsHead = true; 1998 parentIsHead = true;
1991 } 1999 }
1992 } 2000 }
1993 if (m_currentBranchHeads == 2 && parentIsHead) { 2001 if (currentBranchActiveHeads == 2 && parentIsHead) {
1994 headsAreLocal = true; 2002 headsAreLocal = true;
1995 } 2003 }
1996 } 2004 }
1997 2005
1998 if (headsAreLocal) { 2006 if (headsAreLocal) {
2136 } else if (output.contains("entry cancelled")) { 2144 } else if (output.contains("entry cancelled")) {
2137 // ignore this, user cancelled username or password dialog 2145 // ignore this, user cancelled username or password dialog
2138 return; 2146 return;
2139 } 2147 }
2140 break; // go on to default report 2148 break; // go on to default report
2149 case ACT_QUERY_HEADS_ACTIVE:
2141 case ACT_QUERY_HEADS: 2150 case ACT_QUERY_HEADS:
2142 // fails if repo is empty; we don't care (if there's a genuine 2151 // fails if repo is empty; we don't care (if there's a genuine
2143 // problem, something else will fail too). Pretend it 2152 // problem, something else will fail too). Pretend it
2144 // succeeded, so that any further actions that are contingent 2153 // succeeded, so that any further actions that are contingent
2145 // on the success of the heads query get carried out properly. 2154 // on the success of the heads query get carried out properly.
2322 QStringList parentIds = Changeset::getIds(m_currentParents); 2331 QStringList parentIds = Changeset::getIds(m_currentParents);
2323 m_hgTabs->setCurrent(parentIds, m_currentBranch); 2332 m_hgTabs->setCurrent(parentIds, m_currentBranch);
2324 } 2333 }
2325 break; 2334 break;
2326 2335
2336 case ACT_QUERY_HEADS_ACTIVE:
2337 foreach (Changeset *cs, m_activeHeads) delete cs;
2338 m_activeHeads = Changeset::parseChangesets(output);
2339 break;
2340
2327 case ACT_QUERY_HEADS: 2341 case ACT_QUERY_HEADS:
2328 { 2342 {
2329 oldHeadIds = Changeset::getIds(m_currentHeads); 2343 oldHeadIds = Changeset::getIds(m_currentHeads);
2330 Changesets newHeads = Changeset::parseChangesets(output); 2344 Changesets newHeads = Changeset::parseChangesets(output);
2331 QStringList newHeadIds = Changeset::getIds(newHeads); 2345 QStringList newHeadIds = Changeset::getIds(newHeads);
2334 DEBUG << "Old heads: " << oldHeadIds.join(",") << endl; 2348 DEBUG << "Old heads: " << oldHeadIds.join(",") << endl;
2335 DEBUG << "New heads: " << newHeadIds.join(",") << endl; 2349 DEBUG << "New heads: " << newHeadIds.join(",") << endl;
2336 headsChanged = true; 2350 headsChanged = true;
2337 foreach (Changeset *cs, m_currentHeads) delete cs; 2351 foreach (Changeset *cs, m_currentHeads) delete cs;
2338 m_currentHeads = newHeads; 2352 m_currentHeads = newHeads;
2353 updateClosedHeads();
2339 } 2354 }
2340 } 2355 }
2341 break; 2356 break;
2342 2357
2343 case ACT_COMMIT: 2358 case ACT_COMMIT:
2484 case ACT_STAT: 2499 case ACT_STAT:
2485 hgResolveList(); 2500 hgResolveList();
2486 break; 2501 break;
2487 2502
2488 case ACT_RESOLVE_LIST: 2503 case ACT_RESOLVE_LIST:
2504 hgQueryHeadsActive();
2505 break;
2506
2507 case ACT_QUERY_HEADS_ACTIVE:
2489 hgQueryHeads(); 2508 hgQueryHeads();
2490 break; 2509 break;
2491 2510
2492 case ACT_QUERY_HEADS: 2511 case ACT_QUERY_HEADS:
2493 if (headsChanged && !m_needNewLog) { 2512 if (headsChanged && !m_needNewLog) {
2723 bool canUpdate = false; 2742 bool canUpdate = false;
2724 bool haveMerge = false; 2743 bool haveMerge = false;
2725 bool emptyRepo = false; 2744 bool emptyRepo = false;
2726 bool noWorkingCopy = false; 2745 bool noWorkingCopy = false;
2727 bool newBranch = false; 2746 bool newBranch = false;
2728 int m_currentBranchHeads = 0; 2747 bool closedBranch = false;
2748 int currentBranchActiveHeads = 0;
2729 2749
2730 if (m_currentParents.size() == 1) { 2750 if (m_currentParents.size() == 1) {
2731 bool parentIsHead = false; 2751 bool parentIsHead = false;
2752 bool parentIsActiveHead = false;
2732 Changeset *parent = m_currentParents[0]; 2753 Changeset *parent = m_currentParents[0];
2733 foreach (Changeset *head, m_currentHeads) { 2754 foreach (Changeset *head, m_activeHeads) {
2734 DEBUG << "head branch " << head->branch() << ", current branch " << m_currentBranch << endl;
2735 if (head->isOnBranch(m_currentBranch)) { 2755 if (head->isOnBranch(m_currentBranch)) {
2736 ++m_currentBranchHeads; 2756 ++currentBranchActiveHeads;
2737 } 2757 }
2738 if (parent->id() == head->id()) { 2758 if (parent->id() == head->id()) {
2739 parentIsHead = true; 2759 parentIsActiveHead = parentIsHead = true;
2740 } 2760 }
2741 } 2761 }
2742 if (m_currentBranchHeads == 2 && parentIsHead) { 2762 if (!parentIsActiveHead) {
2763 foreach (Changeset *head, m_currentHeads) {
2764 if (parent->id() == head->id()) {
2765 parentIsHead = true;
2766 }
2767 }
2768 }
2769 if (currentBranchActiveHeads == 2 && parentIsActiveHead) {
2743 canMerge = true; 2770 canMerge = true;
2744 } 2771 }
2745 if (m_currentBranchHeads == 0 && parentIsHead) { 2772 if (currentBranchActiveHeads == 0 && parentIsActiveHead) {
2746 // Just created a new branch 2773 // Just created a new branch
2747 newBranch = true; 2774 newBranch = true;
2748 } 2775 }
2749 if (!parentIsHead) { 2776 if (!parentIsHead) {
2750 canUpdate = true; 2777 canUpdate = true;
2751 DEBUG << "parent id = " << parent->id() << endl; 2778 DEBUG << "parent id = " << parent->id() << endl;
2752 DEBUG << " head ids "<<endl; 2779 DEBUG << " head ids "<<endl;
2753 foreach (Changeset *h, m_currentHeads) { 2780 foreach (Changeset *h, m_currentHeads) {
2754 DEBUG << "head id = " << h->id() << endl; 2781 DEBUG << "head id = " << h->id() << endl;
2755 } 2782 }
2783 } else if (!parentIsActiveHead) {
2784 closedBranch = true;
2756 } 2785 }
2757 m_justMerged = false; 2786 m_justMerged = false;
2758 } else if (m_currentParents.size() == 0) { 2787 } else if (m_currentParents.size() == 0) {
2759 if (m_currentHeads.size() == 0) { 2788 if (m_currentHeads.size() == 0) {
2760 // No heads -> empty repo 2789 // No heads -> empty repo
2776 m_hgPullAct->setEnabled(m_remoteRepoActionsEnabled); 2805 m_hgPullAct->setEnabled(m_remoteRepoActionsEnabled);
2777 // permit push even if no remote yet; we'll ask for one 2806 // permit push even if no remote yet; we'll ask for one
2778 m_hgPushAct->setEnabled(m_localRepoActionsEnabled && !emptyRepo); 2807 m_hgPushAct->setEnabled(m_localRepoActionsEnabled && !emptyRepo);
2779 2808
2780 m_hgMergeAct->setEnabled(m_localRepoActionsEnabled && 2809 m_hgMergeAct->setEnabled(m_localRepoActionsEnabled &&
2781 (canMerge || m_hgTabs->canResolve())); 2810 (canMerge || m_hgTabs->canResolve()));
2782 m_hgUpdateAct->setEnabled(m_localRepoActionsEnabled && 2811 m_hgUpdateAct->setEnabled(m_localRepoActionsEnabled &&
2783 (canUpdate && !m_hgTabs->haveChangesToCommit())); 2812 (canUpdate && !m_hgTabs->haveChangesToCommit()));
2784 2813
2785 // Set the state field on the file status widget 2814 // Set the state field on the file status widget
2786 2815
2787 QString branchText; 2816 QString branchText;
2788 if (m_currentBranch == "" || m_currentBranch == "default") { 2817 if (m_currentBranch == "" || m_currentBranch == "default") {
2807 m_workStatus->setState(tr("Have unresolved files following merge on %1").arg(branchText)); 2836 m_workStatus->setState(tr("Have unresolved files following merge on %1").arg(branchText));
2808 } else if (haveMerge) { 2837 } else if (haveMerge) {
2809 m_workStatus->setState(tr("Have merged but not yet committed on %1").arg(branchText)); 2838 m_workStatus->setState(tr("Have merged but not yet committed on %1").arg(branchText));
2810 } else if (newBranch) { 2839 } else if (newBranch) {
2811 m_workStatus->setState(tr("On %1. New branch: has not yet been committed").arg(branchText)); 2840 m_workStatus->setState(tr("On %1. New branch: has not yet been committed").arg(branchText));
2841 } else if (closedBranch) {
2842 if (canUpdate) {
2843 m_workStatus->setState(tr("On a closed branch. Not at the head of the branch"));
2844 } else {
2845 m_workStatus->setState(tr("At the head of a closed branch"));
2846 }
2812 } else if (canUpdate) { 2847 } else if (canUpdate) {
2813 if (m_hgTabs->haveChangesToCommit()) { 2848 if (m_hgTabs->haveChangesToCommit()) {
2814 // have uncommitted changes 2849 // have uncommitted changes
2815 m_workStatus->setState(tr("On %1. Not at the head of the branch").arg(branchText)); 2850 m_workStatus->setState(tr("On %1. Not at the head of the branch").arg(branchText));
2816 } else { 2851 } else {
2817 // no uncommitted changes 2852 // no uncommitted changes
2818 m_workStatus->setState(tr("On %1. Not at the head of the branch: consider updating").arg(branchText)); 2853 m_workStatus->setState(tr("On %1. Not at the head of the branch: consider updating").arg(branchText));
2819 } 2854 }
2820 } else if (m_currentBranchHeads > 1) { 2855 } else if (currentBranchActiveHeads > 1) {
2821 m_workStatus->setState(tr("At one of %n heads of %1", "", m_currentBranchHeads).arg(branchText)); 2856 m_workStatus->setState(tr("At one of %n heads of %1", "", currentBranchActiveHeads).arg(branchText));
2822 } else { 2857 } else {
2823 m_workStatus->setState(tr("At the head of %1").arg(branchText)); 2858 m_workStatus->setState(tr("At the head of %1").arg(branchText));
2824 } 2859 }
2825 } 2860 }
2826 2861
2862
2863 void MainWindow::updateClosedHeads()
2864 {
2865 m_closedHeadIds.clear();
2866 QSet<QString> activeIds;
2867 foreach (Changeset *cs, m_activeHeads) {
2868 activeIds.insert(cs->id());
2869 }
2870 foreach (Changeset *cs, m_currentHeads) {
2871 if (!activeIds.contains(cs->id())) {
2872 m_closedHeadIds.insert(cs->id());
2873 }
2874 }
2875 m_hgTabs->setClosedHeadIds(m_closedHeadIds);
2876 }
2827 2877
2828 void MainWindow::updateRecentMenu() 2878 void MainWindow::updateRecentMenu()
2829 { 2879 {
2830 m_recentMenu->clear(); 2880 m_recentMenu->clear();
2831 RecentFiles rf("Recent-local"); 2881 RecentFiles rf("Recent-local");