Print Page | Close Window

Reordering the Quick Access Toolbar

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Command Bars
Forum Description: Topics Related to Codejock Command Bars
URL: http://forum.codejock.com/forum_posts.asp?TID=9638
Printed Date: 01 March 2025 at 11:36am
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: Reordering the Quick Access Toolbar
Posted By: mrmathis
Subject: Reordering the Quick Access Toolbar
Date Posted: 19 February 2008 at 6:26pm
I am trying to extend the Quick Access customization page by adding "Move Up" and "Move Down" buttons a la MS Word's version of this dialog, but I'm not having much success.  Here is some sample code from my CustomizeQAT::OnMoveUp handler that can be used to replace the body of CXTPRibbonCustomizeQuickAccessPage::OnButtonReset to illustrate what I am trying to do.

// Swap the selected item in the Quick Access list with the previous item
void MyQuickAccessPage::OnButtonMoveUp()
{
    if (!GetDlgItem(IDC_RIBBONBUTTON_MOVE_UP)->IsWindowEnabled())
        return;
 
    int nSel = m_lstQuickAccess.GetCurSel();
    if (nSel < 1)
        return;
 
    CXTPControl* pControlInList = (CXTPControl*)m_lstQuickAccess.GetItemDataPtr(nSel);
    if (!pControlInList)
        return;
 
    CXTPRibbonQuickAccessControls* pQuickAccessControls = GetRibbonBar()->GetQuickAccessControls();
    if (!pQuickAccessControls)
        return;
 
    CXTPControl* pControlInQAT = pQuickAccessControls->FindControl(pControlInList->GetID());
    if (!pControlInQAT)
        return;
 
    // I'm not convinced that GetIndex is the same as the position in the array,
    // so this may not be correct.  Is GetIndex 1-based rather than 0-based?
    long nPrev = pControlInQAT->GetIndex() - 1 - 1;
    if (nPrev < 0)
        return;
 
    // This was my first try.  It asserts and crashes in CXTPControls::MoveBefore
    // because pQuickAccessControls != pControlInQAT->GetControls()
    //pQuickAccessControls->MoveBefore(pControlInQAT, (int)nPrev);
 
    // This seems like it would work.  It does result in the objects in the list
    // control swapping, but no corresponding change happens on the QAT.
    pQuickAccessControls->AddClone(pControlInList, nPrev);
    pQuickAccessControls->Remove(pControlInQAT);
 
    GetRibbonBar()->OnRecalcLayout();
    RefreshQuickAccessList();
}
 
I wrote some code to dump the QAT try to track what is going on and called it from the debugger at strategic points. Here's that function:
 
void DumpQAT()
{
    . . . get the ribbon bar . . .
            if (CXTPRibbonQuickAccessControls* pQuickAccessControls = pRibbonBar->GetQuickAccessControls())
            {
                int nCount = pQuickAccessControls->GetCount();
                TRACE("Count: %d\n", nCount);
                for (int n = 0; n < nCount; ++n)
                {
                    if (CXTPControl* pControl = pQuickAccessControls->GetAt(n))
                    {
                        int nID = pControl->GetID();
                        long nIndex = pControl->GetIndex();
                        CString strName = pControl->GetCaption();
                        TRACE("%d: %#010x  %5d  %4d  %s\n", n, pControl, nID, nIndex, (LPCSTR)strName);
                    }
                }
            }
        }
    }
}
 
Before the call to AddClone, I had this:
 
Count: 6
0: 0x0a2b9548  57600     1  &New
1: 0x0a2b9820  57601     2  &Open
2: 0x0a0c4630  57603     3  &Save
3: 0x0a2b9270  57607     4  &Print
4: 0x1f01c6b8  40002     5  Send To Mail Recipient
5: 0x1f334bf8  40003     6  Send To Routing Recipient
 
After that call, I had what I expected in terms of overall order, although the index column seems odd:
Count: 7
0: 0x0a2b9548  57600     1  &New
1: 0x0a2b9820  57601     2  &Open
2: 0x0a0c4630  57603     3  &Save
3: 0x0a2b9270  57607     4  &Print
4: 0x1f334da0  40003     7  Send To Routing Recipient
5: 0x1f01c6b8  40002     5  Send To Mail Recipient
6: 0x1f334bf8  40003     6  Send To Routing Recipient
 
After the call to Remove, I got this:

Count: 6
0: 0x0a2b9548  57600     1  &New
1: 0x0a2b9820  57601     2  &Open
2: 0x0a0c4630  57603     3  &Save
3: 0x0a2b9270  57607     4  &Print
4: 0x1f334da0  40003     6  Send To Routing Recipient
5: 0x1f01c6b8  40002     5  Send To Mail Recipient
 
The part that throws me is the index, which I believe is contributing to me not seeing the results I expect.  Notice that "Send to Routing Recipient" has an index of 6, when I would expect it to have 5 and "Send to Mail Recipient" to have 6.  I stepped all the way through Remove into CXTPControls::RefreshIndexes and saw the indices recomputed sequentially, but I'm not positive that the correct thing is getting recomputed.  There are controls visited in that loop that I didn't expect to see (eg CXTPRibbonScrollableBar::CControlGroupsScroll, CXTPRibbonBarControlQuickAccessPopup).
 
Can someone enlighten me?  I went into this thinking it shouldn't be too difficult.
 
 


-------------
--Mike



Replies:
Posted By: Oleg
Date Posted: 04 March 2008 at 5:16am
Hi,
Yes, right :( problem in our sources that assumes that Quick Acccess controls always added in the end of list.
 
Here fix for source:
 
int CXTPRibbonQuickAccessControls::IndexOf(CXTPControl* pControl) const
{
 for (int nIndex = GetCount() - 1; nIndex >= 0; nIndex--)
 {
  if (GetAt(nIndex) == pControl)
  {
   return nIndex;
  }
 }
 return -1;
}
void CXTPRibbonQuickAccessControls::OnControlAdded(CXTPControl* pControl)
{
 int nIndex = IndexOf(pControl) + (((CXTPRibbonBar*)m_pParent)->GetSystemButton() ? 1 : 0);
 m_pParent->GetControls()->InsertAt(pControl, nIndex);
 pControl->InternalAddRef();
}
 
Here your method to move:
 
void CXTPRibbonCustomizeQuickAccessPage::OnButtonReset()
{
 int nSel = m_lstQuickAccess.GetCurSel();
    if (nSel < 1)
        return;
 
    CXTPControl* pControl = (CXTPControl*)m_lstQuickAccess.GetItemDataPtr(nSel);
    if (!pControl)
        return;
 
    CXTPRibbonQuickAccessControls* pQuickAccessControls = GetRibbonBar()->GetQuickAccessControls();
    if (!pQuickAccessControls)
        return;
 int nIndex = pQuickAccessControls->IndexOf(pControl);
 
    pQuickAccessControls->AddClone(pControl, nIndex - 1);
    pQuickAccessControls->Remove(pControl);
 
    GetRibbonBar()->OnRecalcLayout();
    RefreshQuickAccessList();
}
 
 
Thanks


-------------
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net