Mercurial > hg > easyhg
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"); |