diff --git a/Charu3.cpp b/Charu3.cpp index 947f10a..f74570d 100644 --- a/Charu3.cpp +++ b/Charu3.cpp @@ -796,11 +796,12 @@ void CCharu3App::closeTreeWindow(int nRet) for (it = m_pTree->m_ltCheckItems.begin(); it != m_pTree->m_ltCheckItems.end(); it++) { if (m_pTree->GetItemState(*it, TVIF_HANDLE)) { data = m_pTree->getData(*it); - - if (m_ini.m_bDebug) { - LOG(_T("closeTreeWindow check paste %s"), data.m_strTitle.GetString()); + if (data.m_cKind & KIND_DATA_ALL) { + if (m_ini.m_bDebug) { + LOG(_T("closeTreeWindow check paste %s"), data.m_strTitle.GetString()); + } + playData(data, strClip, strSelect, isPaste, false); } - playData(data, strClip, strSelect, isPaste, false); } } //一時項目は消す @@ -849,9 +850,6 @@ void CCharu3App::closeTreeWindow(int nRet) resetTreeDialog(); Window::SetFocusInfo(&m_focusInfo); } - else { - m_pTree->ClearChecks(); - } ASSERT(m_nPhase == PHASE_POPUP); m_nPhase = PHASE_IDOL; } diff --git a/Charu3Tree.cpp b/Charu3Tree.cpp index 2960117..51ef715 100644 --- a/Charu3Tree.cpp +++ b/Charu3Tree.cpp @@ -1212,35 +1212,67 @@ void CCharu3Tree::closeFolder(HTREEITEM hStartItem) } while (hItem); } +void CCharu3Tree::SetCheckEx(HTREEITEM hItem, BOOL check) +{ + SetCheck(hItem, check); + if (check) { + // Add this to listItem + m_ltCheckItems.insert(m_ltCheckItems.end(), hItem); + } + else { + // Remove this from listItem + std::list::iterator it; + for (it = m_ltCheckItems.begin(); it != m_ltCheckItems.end(); it++) { + if (*it == hItem) { + m_ltCheckItems.erase(it); + break; + } + } + } +} + +void CCharu3Tree::SetCheckExRecursive(HTREEITEM hItem, BOOL check) +{ + SetCheckEx(hItem, check); + for (hItem = GetChildItem(hItem); hItem; hItem = GetNextItem(hItem, TVGN_NEXT)) { + SetCheckExRecursive(hItem, check); + } +} + //--------------------------------------------------- -//関数名 checkFolder(HTREEITEM hStartItem,bool isCheck) -//機能 指定データ以下にチェックを入れる +//関数名 ToggleItemCheck(HTREEITEM hItem) +//機能 項目のチェックを切替える //--------------------------------------------------- -void CCharu3Tree::checkFolder(HTREEITEM hStartItem, bool isCheck, std::list* listItem) +void CCharu3Tree::ToggleItemCheck(HTREEITEM hItem) { - if (!hStartItem) return; - std::list::iterator it; - SetCheck(hStartItem, isCheck); - HTREEITEM hItem = GetChildItem(hStartItem); - do { + ModifyStyle(NULL, TVS_CHECKBOXES, NULL); + if (hItem) { + BOOL checked = GetCheck(hItem); if (ItemHasChildren(hItem)) { - checkFolder(hItem, isCheck, listItem); - } - SetCheck(hItem, isCheck); - if (isCheck) {//リストに追加 - listItem->insert(listItem->end(), hItem); - } - else {//リストから削除 - std::list::iterator it; - for (it = listItem->begin(); it != listItem->end(); it++) { - if (*it == hItem) { - listItem->erase(it); - break; - } + /* Even if we check a folder, the selected items in the folder + have to be removed from the list first (otherwise duplicates + will be added), so the process of unchecking the subtree should + be done anyway. */ + SetCheckExRecursive(hItem, FALSE); + if (!checked) { + SetCheckExRecursive(hItem, TRUE); } } - hItem = GetNextItem(hItem, TVGN_NEXT); - } while (hItem); + else { + SetCheckEx(hItem, !checked); + } + } +} + +//--------------------------------------------------- +//関数名 UncheckItem(HTREEITEM hItem) +//機能 項目のチェックを外す +//--------------------------------------------------- +void CCharu3Tree::UncheckItem(HTREEITEM hItem) +{ + if (hItem) { + SetCheckExRecursive(hItem, FALSE); + } } //--------------------------------------------------- @@ -1956,83 +1988,6 @@ HTREEITEM CCharu3Tree::moveFolderTop(HTREEITEM hTreeItem) return hRet; } -//--------------------------------------------------- -//関数名 ClearChecks() -//機能 チェックを外す -//--------------------------------------------------- -void CCharu3Tree::ClearChecks() -{ - int nSize = m_MyStringList.size(), i; - HTREEITEM hTreeItem; - for (hTreeItem = GetRootItem(), i = 0; i < nSize && hTreeItem; i++, hTreeItem = getTrueNextItem(hTreeItem)) { - SetCheck(hTreeItem, false); - } -} - -//--------------------------------------------------- -//関数名 ToggleItemCheck(HTREEITEM hItem) -//機能 項目のチェックを切替える -//--------------------------------------------------- -void CCharu3Tree::ToggleItemCheck(HTREEITEM hItem) -{ - // TODO: Should refactor - - if (!hItem) { - return; - } - ModifyStyle(NULL, TVS_CHECKBOXES, NULL); - BOOL checked = GetCheck(hItem); - if (ItemHasChildren(hItem)) { - - // Even if we check a folder, the selected items in the folder have to - // be removed from the list first(otherwise duplicates will be added), - // so the process of unchecking the subtree should be done anyway. - checkFolder(hItem, false, &m_ltCheckItems); - - if (!checked) { - checkFolder(hItem, true, &m_ltCheckItems); - } - } - else { - SetCheck(hItem, !checked); - if (!checked) {//リストに追加 - m_ltCheckItems.insert(m_ltCheckItems.end(), hItem); - } - else {//リストから削除 - std::list::iterator it; - for (it = m_ltCheckItems.begin(); it != m_ltCheckItems.end(); it++) { - if (*it == hItem) { - m_ltCheckItems.erase(it); - break; - } - } - } - } -} - -//--------------------------------------------------- -//関数名 UncheckItem(HTREEITEM hItem) -//機能 項目のチェックを外す -//--------------------------------------------------- -void CCharu3Tree::UncheckItem(HTREEITEM hItem) -{ - // TODO: Should refactor - - if (ItemHasChildren(hItem)) { - checkFolder(hItem, false, &m_ltCheckItems); - } - else if (hItem) { - SetCheck(hItem, false); - std::list::iterator it; - for (it = m_ltCheckItems.begin(); it != m_ltCheckItems.end(); it++) { - if (*it == hItem) { - m_ltCheckItems.erase(it); - break; - } - } - } -} - //--------------------------------------------------- // CCharu3Tree メッセージ ハンドラ //--------------------------------------------------- diff --git a/Charu3Tree.h b/Charu3Tree.h index fbe34f3..edb1538 100644 --- a/Charu3Tree.h +++ b/Charu3Tree.h @@ -129,7 +129,6 @@ class CCharu3Tree : public CTreeCtrl void clearFolder(HTREEITEM hItem); void closeFolder(HTREEITEM hStartItem); void cleanupOneTimeItems(HTREEITEM hStartItem, int nKind = 0); - void ClearChecks(); void changeIcon(HTREEITEM hTreeItem, int nID); void tree2List(HTREEITEM hStartItem, std::list* tmplist, bool isAll = false); @@ -211,7 +210,8 @@ class CCharu3Tree : public CTreeCtrl DWORD getDataOptionHex(CString strData, CString strKind); void archiveHistory(HTREEITEM hTreeItem, int nRirekiCount); - void checkFolder(HTREEITEM hStartItem, bool isCheck, std::list* listItem); + void SetCheckEx(HTREEITEM hItem, BOOL check); + void SetCheckExRecursive(HTREEITEM hStartItem, BOOL check); void UncheckItem(HTREEITEM hItem); bool getPlugin(CString strName, RW_PLUGIN* pPlugin); diff --git a/MyTreeDialog.cpp b/MyTreeDialog.cpp index 0eb8fc4..4e911a0 100644 --- a/MyTreeDialog.cpp +++ b/MyTreeDialog.cpp @@ -404,7 +404,8 @@ void CMyTreeDialog::OnClickMyTree(NMHDR* pNMHDR, LRESULT* pResult) if (hClickItem) { if (m_pTreeCtrl->GetItemRect(hClickItem, &ItemRect, true)) { if (TVHT_ONITEMICON & Flags) { - // Clicking on the icon of the one-time data item in the data tree view changes it to permanent data. + // Clicking on the icon of the one-time data item in the data + // tree view changes it to permanent data. STRING_DATA* pData = m_pTreeCtrl->getDataPtr(hClickItem); if (pData->m_cKind & KIND_ONETIME) { pData->m_cKind = KIND_LOCK; @@ -414,6 +415,10 @@ void CMyTreeDialog::OnClickMyTree(NMHDR* pNMHDR, LRESULT* pResult) if (TVHT_ONITEMSTATEICON & Flags) { // Clicked on checkbox m_pTreeCtrl->ToggleItemCheck(hClickItem); + + // The process above includes toggling the check, but MFC will + // also toggle the check for this item, so reverse the toggle + // once here. m_pTreeCtrl->SetCheck(hClickItem, !m_pTreeCtrl->GetCheck(hClickItem)); } } @@ -683,7 +688,23 @@ BOOL CMyTreeDialog::PreTranslateMessage(MSG* pMsg) bool goBackwards = ::GetKeyState(VK_SHIFT) < 0; if (::GetKeyState(VK_CONTROL) < 0) { m_pTreeCtrl->ToggleItemCheck(m_pTreeCtrl->GetSelectedItem()); - hTreeItem = goBackwards ? m_pTreeCtrl->GetPrevSiblingItem(hTreeItem) : m_pTreeCtrl->GetNextSiblingItem(hTreeItem); + if (goBackwards) { + hTreeItem = m_pTreeCtrl->GetPrevVisibleItem(hTreeItem); + } + else { + HTREEITEM currentItem = hTreeItem; + hTreeItem = m_pTreeCtrl->GetNextSiblingItem(currentItem); // Skip children + if (!hTreeItem) { + hTreeItem = m_pTreeCtrl->GetNextVisibleItem(currentItem); + } + } + std::list::iterator it; + for (it = m_pTreeCtrl->m_ltCheckItems.begin(); it != m_pTreeCtrl->m_ltCheckItems.end(); it++) { + if (m_pTreeCtrl->GetItemState(*it, TVIF_HANDLE)) { + STRING_DATA* data = m_pTreeCtrl->getDataPtr(*it); + LOG(_T("[] %s"), data->m_strTitle.GetString()); + } + } } else { if (goBackwards) {