Exemple #1
0
int wxNotebook::DoSetSelection( size_t page, int flags )
{
    wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid notebook") );

    wxCHECK_MSG( page < m_pagesData.GetCount(), -1, wxT("invalid notebook index") );

    int selOld = GetSelection();

    if ( !(flags & SetSelection_SendEvent) )
        m_skipNextPageChangeEvent = true;

    // cache the selection
    m_selection = page;
    gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page );

    // gtk_notebook_set_current_page is supposed to emit the switch-page signal
    // which should be caught by our gtk_notebook_page_change_callback which
    // should have reset the flag to false, check it:
    wxASSERT_LEVEL_2_MSG(
        (flags & SetSelection_SendEvent) || !m_skipNextPageChangeEvent,
        "internal error in selection events generation"
    );

    wxNotebookPage *client = GetPage(page);
    if ( client )
        client->SetFocus();

    return selOld;
}
Exemple #2
0
/* static and protected */
wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxDC& dc,
        wxEllipsizeMode mode, int maxFinalWidthPx,
        int replacementWidthPx)
{
    wxASSERT_MSG(replacementWidthPx > 0, "Invalid parameters");
    wxASSERT_LEVEL_2_MSG(!curLine.Contains('\n'),
                         "Use Ellipsize() instead!");

    wxASSERT_MSG( mode != wxELLIPSIZE_NONE, "shouldn't be called at all then" );

    // NOTE: this function assumes that any mnemonic/tab character has already
    //       been handled if it was necessary to handle them (see Ellipsize())

    if (maxFinalWidthPx <= 0)
        return wxEmptyString;

    size_t len = curLine.length();
    if (len <= 1 )
        return curLine;

    EllipsizeCalculator calc(curLine, dc, maxFinalWidthPx, replacementWidthPx);

    if ( !calc.IsOk() )
        return curLine;

    if ( calc.EllipsizationNotNeeded() )
        return curLine;

    // let's compute the range of characters to remove depending on the ellipsization mode:
    switch (mode)
    {
    case wxELLIPSIZE_START:
    {
        calc.Init(0, 1);
        while ( !calc.IsShortEnough() )
            calc.RemoveFromEnd();

        // always show at least one character of the string:
        if ( calc.m_nCharsToRemove == len )
            return wxString(wxELLIPSE_REPLACEMENT) + curLine[len-1];

        break;
    }

    case wxELLIPSIZE_MIDDLE:
    {
        // NOTE: the following piece of code works also when len == 1

        // start the removal process from the middle of the string
        // i.e. separe the string in three parts:
        // - the first one to preserve, valid range [0;initialCharToRemove-1] or the empty range if initialCharToRemove==0
        // - the second one to remove, valid range [initialCharToRemove;endCharToRemove]
        // - the third one to preserve, valid range [endCharToRemove+1;len-1] or the empty range if endCharToRemove==len-1
        // NOTE: empty range != range [0;0] since the range [0;0] contains 1 character (the zero-th one)!

        calc.Init(len/2, 0);

        bool removeFromStart = true;

        while ( !calc.IsShortEnough() )
        {
            const bool canRemoveFromStart = calc.GetFirstRemoved() > 0;
            const bool canRemoveFromEnd = calc.GetLastRemoved() < len - 1;

            if ( !canRemoveFromStart && !canRemoveFromEnd )
            {
                // we need to remove all the characters of the string!
                break;
            }

            // Remove from the beginning in even steps and from the end
            // in odd steps, unless we exhausted one side already:
            removeFromStart = !removeFromStart;
            if ( removeFromStart && !canRemoveFromStart )
                removeFromStart = false;
            else if ( !removeFromStart && !canRemoveFromEnd )
                removeFromStart = true;

            if ( removeFromStart )
                calc.RemoveFromStart();
            else
                calc.RemoveFromEnd();
        }

        // Always show at least one character of the string.
        // Additionally, if there's only one character left, prefer
        // "a..." to "...a":
        if ( calc.m_nCharsToRemove == len ||
                calc.m_nCharsToRemove == len - 1 )
        {
            return curLine[0] + wxString(wxELLIPSE_REPLACEMENT);
        }
    }
    break;

    case wxELLIPSIZE_END:
    {
        calc.Init(len - 1, 1);
        while ( !calc.IsShortEnough() )
            calc.RemoveFromStart();

        // always show at least one character of the string:
        if ( calc.m_nCharsToRemove == len )
            return curLine[0] + wxString(wxELLIPSE_REPLACEMENT);

        break;
    }

    case wxELLIPSIZE_NONE:
    default:
        wxFAIL_MSG("invalid ellipsize mode");
        return curLine;
    }

    return calc.GetEllipsizedText();
}
Exemple #3
0
/* static and protected */
wxString wxControlBase::DoEllipsizeSingleLine(const wxString& curLine, const wxDC& dc,
                                              wxEllipsizeMode mode, int maxFinalWidthPx,
                                              int replacementWidthPx, int marginWidthPx)
{
    wxASSERT_MSG(replacementWidthPx > 0 && marginWidthPx > 0,
                 "Invalid parameters");
    wxASSERT_LEVEL_2_MSG(!curLine.Contains('\n'),
                         "Use Ellipsize() instead!");

    wxASSERT_MSG( mode != wxELLIPSIZE_NONE, "shouldn't be called at all then" );

    // NOTE: this function assumes that any mnemonic/tab character has already
    //       been handled if it was necessary to handle them (see Ellipsize())

    if (maxFinalWidthPx <= 0)
        return wxEmptyString;

    wxArrayInt charOffsetsPx;
    size_t len = curLine.length();
    if (len == 0 ||
        !dc.GetPartialTextExtents(curLine, charOffsetsPx))
        return curLine;

    wxASSERT(charOffsetsPx.GetCount() == len);

    // NOTE: charOffsetsPx[n] is the width in pixels of the first n characters (with the last one INCLUDED)
    //       thus charOffsetsPx[len-1] is the total width of the string
    size_t totalWidthPx = charOffsetsPx.Last();
    if ( totalWidthPx <= (size_t)maxFinalWidthPx )
        return curLine;     // we don't need to do any ellipsization!

    int excessPx = wxMin(totalWidthPx - maxFinalWidthPx +
                         replacementWidthPx +
                         marginWidthPx,     // security margin
                         totalWidthPx);
    wxASSERT(excessPx>0);       // excessPx should be in the [1;totalWidthPx] range

    // REMEMBER: indexes inside the string have a valid range of [0;len-1] if not otherwise constrained
    //           lengths/counts of characters (e.g. nCharsToRemove) have a valid range of [0;len] if not otherwise constrained
    // NOTE: since this point we know we have for sure a non-empty string from which we need
    //       to remove _at least_ one character (thus nCharsToRemove below is constrained to be >= 1)

    size_t initialCharToRemove,     // index of first character to erase, valid range is [0;len-1]
           nCharsToRemove;          // how many chars do we need to erase? valid range is [1;len-initialCharToRemove]

    // let's compute the range of characters to remove depending on the ellipsization mode:
    switch (mode)
    {
        case wxELLIPSIZE_START:
            initialCharToRemove = 0;
            for ( nCharsToRemove = 1;
                  nCharsToRemove < len && charOffsetsPx[nCharsToRemove-1] < excessPx;
                  nCharsToRemove++ )
                ;
            break;

        case wxELLIPSIZE_MIDDLE:
            {
                // NOTE: the following piece of code works also when len == 1

                // start the removal process from the middle of the string
                // i.e. separe the string in three parts: 
                // - the first one to preserve, valid range [0;initialCharToRemove-1] or the empty range if initialCharToRemove==0
                // - the second one to remove, valid range [initialCharToRemove;endCharToRemove]
                // - the third one to preserve, valid range [endCharToRemove+1;len-1] or the empty range if endCharToRemove==len-1
                // NOTE: empty range != range [0;0] since the range [0;0] contains 1 character (the zero-th one)!
                initialCharToRemove = len/2;
                size_t endCharToRemove = len/2;     // index of the last character to remove; valid range is [0;len-1]

                int removedPx = 0;
                for ( ; removedPx < excessPx; )
                {
                    // try to remove the last character of the first part of the string
                    if (initialCharToRemove > 0)
                    {
                        // width of the (initialCharToRemove-1)-th character
                        int widthPx;
                        if (initialCharToRemove >= 2)
                            widthPx = charOffsetsPx[initialCharToRemove-1] - charOffsetsPx[initialCharToRemove-2];
                        else
                            widthPx = charOffsetsPx[initialCharToRemove-1];     
                                // the (initialCharToRemove-1)-th character is the first char of the string
                        
                        wxASSERT(widthPx >= 0);     // widthPx is zero for e.g. tab characters

                        // mark the (initialCharToRemove-1)-th character as removable
                        initialCharToRemove--;
                        removedPx += widthPx;
                    }

                    // try to remove the first character of the last part of the string
                    if (endCharToRemove < len - 1 &&
                        removedPx < excessPx)
                    {
                        // width of the (endCharToRemove+1)-th character
                        int widthPx = charOffsetsPx[endCharToRemove+1] -
                                      charOffsetsPx[endCharToRemove];

                        wxASSERT(widthPx >= 0);     // widthPx is zero for e.g. tab characters

                        // mark the (endCharToRemove+1)-th character as removable
                        endCharToRemove++;
                        removedPx += widthPx;
                    }

                    if (initialCharToRemove == 0 && endCharToRemove == len-1)
                    {
                        // we need to remove all the characters of the string!
                        break;
                    }
                }

                nCharsToRemove = endCharToRemove - initialCharToRemove + 1;
            }
            break;

        case wxELLIPSIZE_END:
            {
                int maxWidthPx = totalWidthPx - excessPx;

                // go backward from the end of the string toward the start
                for ( initialCharToRemove = len-1;
                      initialCharToRemove > 0 && charOffsetsPx[initialCharToRemove-1] > maxWidthPx;
                      initialCharToRemove-- )
                    ;
                nCharsToRemove = len - initialCharToRemove;
            }
            break;

        case wxELLIPSIZE_NONE:
        default:
            wxFAIL_MSG("invalid ellipsize mode");
            return curLine;
    }

#ifdef __VMS
#pragma message disable unscomzer
   // suppress warnings on comparison of unsigned numbers
#endif
   wxASSERT(initialCharToRemove >= 0 && initialCharToRemove <= len-1);  // see valid range for initialCharToRemove above
#ifdef __VMS
#pragma message enable unscomzer
   // suppress warnings on comparison of unsigned numbers
#endif
    wxASSERT(nCharsToRemove >= 1 && nCharsToRemove <= len-initialCharToRemove);  // see valid range for nCharsToRemove above

    // erase nCharsToRemove characters after initialCharToRemove (included);
    // e.g. if we have the string "foobar" (len = 6)
    //                               ^
    //                               \--- initialCharToRemove = 2
    //      and nCharsToRemove = 2, then we get "foar"
    wxString ret(curLine);
    ret.erase(initialCharToRemove, nCharsToRemove);

    int removedPx;
    if (initialCharToRemove >= 1)
        removedPx = charOffsetsPx[initialCharToRemove+nCharsToRemove-1] - charOffsetsPx[initialCharToRemove-1];
    else 
        removedPx = charOffsetsPx[initialCharToRemove+nCharsToRemove-1];
    wxASSERT(removedPx >= excessPx);

    // if there is space for the replacement dots, add them
    if ((int)totalWidthPx-removedPx+replacementWidthPx < maxFinalWidthPx)
        ret.insert(initialCharToRemove, wxELLIPSE_REPLACEMENT);

    // if everything was ok, we should have shortened this line
    // enough to make it fit in maxFinalWidthPx:
    wxASSERT_LEVEL_2(dc.GetTextExtent(ret).GetWidth() <= maxFinalWidthPx);

    return ret;
}