X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e589112ed07376c4dea69920943e8eb3cd30e45b..60a040b3bb30c990a795c9c9f58ea97ed972a73f:/user/wxLayout/wxllist.cpp?ds=sidebyside diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index c0b4110420..aadf0b416e 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -14,7 +14,7 @@ #pragma implementation "wxllist.h" #endif -//#include "Mpch.h" +#include "Mpch.h" #include "wx/wxprec.h" @@ -24,9 +24,11 @@ #ifdef M_BASEDIR # include "gui/wxllist.h" -# include "gui/wxMDialogs.h" +# define SHOW_SELECTIONS 1 #else # include "wxllist.h" +# include "wxlparser.h" +# define SHOW_SELECTIONS 1 #endif #ifndef USE_PCH @@ -103,12 +105,17 @@ void GrowRect(wxRect &r, CoordType x, CoordType y) r.height = y - r.y; } +#if 0 +// unused /// returns true if the point is in the rectangle static bool Contains(const wxRect &r, const wxPoint &p) { return r.x <= p.x && r.y <= p.y && (r.x+r.width) >= p.x && (r.y + r.height) >= p.y; } +#endif + + //@} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -147,9 +154,34 @@ wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const } void -wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords) +wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords, + wxLayoutList *wxllist, + CoordType begin, CoordType end) { - dc.DrawText(m_Text, coords.x, coords.y-m_Top); + if(begin == -1) + dc.DrawText(m_Text, coords.x, coords.y-m_Top); + else + { + // highlight the bit between begin and len + wxString str; + CoordType + xpos = coords.x, + ypos = coords.y-m_Top; + long width, height, descent; + + str = m_Text.Mid(0, begin); + dc.DrawText(str, xpos, ypos); + dc.GetTextExtent(str, &width, &height, &descent); + xpos += width; + wxllist->StartHighlighting(dc); + str = m_Text.Mid(begin, end-begin); + dc.DrawText(str, xpos, ypos); + dc.GetTextExtent(str, &width, &height, &descent); + xpos += width; + wxllist->EndHighlighting(dc); + str = m_Text.Mid(end, m_Text.Length()-end); + dc.DrawText(str, xpos, ypos); + } } CoordType @@ -178,7 +210,7 @@ wxLayoutObjectText::GetOffsetScreen(wxDC &dc, CoordType xpos) const } void -wxLayoutObjectText::Layout(wxDC &dc) +wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList * ) { long descent = 0l; @@ -222,14 +254,16 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap *icon) } void -wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint const &coords) +wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint const &coords, + wxLayoutList *wxllist, + CoordType begin, CoordType /* len */) { dc.DrawBitmap(*m_Icon, coords.x, coords.y-m_Icon->GetHeight(), (m_Icon->GetMask() == NULL) ? FALSE : TRUE); } void -wxLayoutObjectIcon::Layout(wxDC & /* dc */) +wxLayoutObjectIcon::Layout(wxDC & /* dc */, class wxLayoutList * ) { } @@ -245,29 +279,74 @@ wxLayoutObjectIcon::GetSize(CoordType *top, CoordType *bottom) const /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - wxLayoutObjectIcon + wxLayoutObjectCmd * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int - weight, bool underline, - wxColour &fg, wxColour &bg) + +wxLayoutStyleInfo::wxLayoutStyleInfo(int ifamily, + int isize, + int istyle, + int iweight, + int iul, + wxColour *fg, + wxColour *bg) +{ + family = ifamily; size = isize; + style = istyle; weight = iweight; + underline = iul; + if(fg) + { + m_fg = *fg; + m_fg_valid = TRUE; + } + else + m_fg = *wxBLACK; + if(bg) + { + m_bg = *bg; + m_bg_valid = TRUE; + } + else + m_bg = *wxWHITE; +} + +#define COPY_SI_(what) if(right.what != -1) what = right.what; + +wxLayoutStyleInfo & +wxLayoutStyleInfo::operator=(const wxLayoutStyleInfo &right) +{ + COPY_SI_(family); + COPY_SI_(style); + COPY_SI_(size); + COPY_SI_(weight); + COPY_SI_(underline); + if(right.m_fg_valid) m_fg = right.m_fg; + if(right.m_bg_valid) m_bg = right.m_bg; + return *this; +} + +wxLayoutObjectCmd::wxLayoutObjectCmd(int family, int size, int style, int + weight, int underline, + wxColour *fg, wxColour *bg) { - m_font = new wxFont(size,family,style,weight,underline); - m_ColourFG = fg; - m_ColourBG = bg; + m_StyleInfo = new wxLayoutStyleInfo(family, size,style,weight,underline,fg,bg); } wxLayoutObject * wxLayoutObjectCmd::Copy(void) { - wxLayoutStyleInfo si; - GetStyle(&si); - wxLayoutObjectCmd *obj = new wxLayoutObjectCmd( - si.size, si.family, si.style, si.weight, si.underline, - m_ColourFG, m_ColourBG); + m_StyleInfo->size, + m_StyleInfo->family, + m_StyleInfo->style, + m_StyleInfo->weight, + m_StyleInfo->underline, + m_StyleInfo->m_fg_valid ? + &m_StyleInfo->m_fg : NULL, + m_StyleInfo->m_bg_valid ? + &m_StyleInfo->m_bg : NULL); obj->SetUserData(m_UserData); return obj; } @@ -275,40 +354,29 @@ wxLayoutObjectCmd::Copy(void) wxLayoutObjectCmd::~wxLayoutObjectCmd() { - delete m_font; + delete m_StyleInfo; } -void -wxLayoutObjectCmd::GetStyle(wxLayoutStyleInfo *si) const +wxLayoutStyleInfo * +wxLayoutObjectCmd::GetStyle(void) const { - si->size = m_font->GetPointSize(); - si->family = m_font->GetFamily(); - si->style = m_font->GetStyle(); - si->underline = m_font->GetUnderlined(); - si->weight = m_font->GetWeight(); - - si->fg_red = m_ColourFG.Red(); - si->fg_green = m_ColourFG.Green(); - si->fg_blue = m_ColourFG.Blue(); - si->bg_red = m_ColourBG.Red(); - si->bg_green = m_ColourBG.Green(); - si->bg_blue = m_ColourBG.Blue(); + return m_StyleInfo; } void -wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */) +wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */, + wxLayoutList *wxllist, + CoordType begin, CoordType /* len */) { - wxASSERT(m_font); - dc.SetFont(*m_font); - dc.SetTextForeground(m_ColourFG); - dc.SetTextBackground(m_ColourBG); + wxASSERT(m_StyleInfo); + wxllist->ApplyStyle(m_StyleInfo, dc); } void -wxLayoutObjectCmd::Layout(wxDC &dc) +wxLayoutObjectCmd::Layout(wxDC &dc, class wxLayoutList * llist) { // this get called, so that recalculation uses right font sizes - Draw(dc, wxPoint(0,0)); + Draw(dc, wxPoint(0,0), llist); } @@ -350,9 +418,13 @@ wxLayoutLine::~wxLayoutLine() wxPoint wxLayoutLine::RecalculatePosition(wxLayoutList *llist) { + wxASSERT(m_Previous || GetLineNumber() == 0); + if(m_Previous) - m_Position = m_Previous->GetPosition() + - wxPoint(0,m_Previous->GetHeight()); + { + m_Position = m_Previous->GetPosition(); + m_Position.y += m_Previous->GetHeight(); + } else m_Position = wxPoint(0,0); llist->SetUpdateRect(m_Position); @@ -419,12 +491,12 @@ wxLayoutLine::FindObjectScreen(wxDC &dc, for(i = m_ObjectList.begin(); i != NULLIT; i++) { - (**i).Layout(dc); +//FIXME! (**i).Layout(dc, NULL); width = (**i).GetWidth(); if( x <= xpos && xpos <= x + width ) { *cxpos = cx + (**i).GetOffsetScreen(dc, xpos-x); - wxLogDebug("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos); +// WXLO_DEBUG(("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos)); if(found) *found = true; return i; } @@ -437,6 +509,38 @@ wxLayoutLine::FindObjectScreen(wxDC &dc, return m_ObjectList.tail(); } +/** Finds text in this line. + @param needle the text to find + @param xpos the position where to start the search + @return the cursoor coord where it was found or -1 +*/ +CoordType +wxLayoutLine::FindText(const wxString &needle, CoordType xpos) const +{ + int + cpos = 0, + relpos = -1; + wxString const *text; + + for(wxLOiterator i = m_ObjectList.begin(); i != m_ObjectList.end(); i++) + { + if(cpos >= xpos) // search from here! + { + if((**i).GetType() == WXLO_TYPE_TEXT) + { + text = & ((wxLayoutObjectText*)(*i))->GetText(); + relpos = text->Find(needle); + if(relpos >= cpos-xpos) // -1 if not found + { + return cpos+relpos; + } + } + cpos += (**i).GetLength(); + } + } + return -1; // not found +} + bool wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj) { @@ -636,11 +740,43 @@ wxLayoutLine::Draw(wxDC &dc, pos = pos + GetPosition(); pos.y += m_BaseLine; - + + CoordType xpos = 0; // cursorpos, lenght of line + + CoordType from, to, tempto; + llist->ApplyStyle(&((wxLayoutLine *)this)->m_StyleInfo, dc); + int highlight = llist->IsSelected(this, &from, &to); +// WXLO_DEBUG(("highlight=%d", highlight )); + if(highlight == 1) // we need to draw the whole line inverted! + llist->StartHighlighting(dc); + else + llist->EndHighlighting(dc); + for(i = m_ObjectList.begin(); i != NULLIT; i++) { - (**i).Draw(dc, pos); + if(highlight == -1) // partially highlight line + { + // parts of the line need highlighting + tempto = xpos+(**i).GetLength(); + if(tempto >= from && xpos <= to) + { + tempto = to-xpos; + if(tempto > (**i).GetLength()) + tempto = (**i).GetLength(); + CoordType tmp = from-xpos; + if(tmp < 0) tmp = 0; + (**i).Draw(dc, pos, llist, from-xpos, tempto); + } + else + { + llist->EndHighlighting(dc); // FIXME! inefficient + (**i).Draw(dc, pos, llist); + } + } + else + (**i).Draw(dc, pos, llist); pos.x += (**i).GetWidth(); + xpos += (**i).GetLength(); } } @@ -673,10 +809,11 @@ wxLayoutLine::Layout(wxDC &dc, *cursorPos = m_Position; if(cursorSize) *cursorSize = wxPoint(0,0); } - + + llist->ApplyStyle(&m_StyleInfo, dc); for(i = m_ObjectList.begin(); i != NULLIT; i++) { - (**i).Layout(dc); + (**i).Layout(dc, llist); size = (**i).GetSize(&objTopHeight, &objBottomHeight); if(cursorPos && ! cursorFound) @@ -766,6 +903,7 @@ wxLayoutLine::Layout(wxDC &dc, if(m_BaseLine >= cursorSize->y) // the normal case anyway cursorPos->y += m_BaseLine-cursorSize->y; } + RecalculatePositions(1, llist); } @@ -909,15 +1047,79 @@ wxLayoutLine::Debug(void) { wxString tmp; wxPoint pos = GetPosition(); - tmp.Printf("Line %ld, Pos (%ld,%ld), Height %ld", + WXLO_DEBUG(("Line %ld, Pos (%ld,%ld), Height %ld", (long int) GetLineNumber(), (long int) pos.x, (long int) pos.y, - (long int) GetHeight()); - - wxLogDebug(tmp); + (long int) GetHeight())); + if(m_ObjectList.begin() != NULLIT) + (**m_ObjectList.begin()).Debug(); + } #endif +void +wxLayoutLine::Copy(wxLayoutList *llist, + CoordType from, + CoordType to) +{ + CoordType firstOffset, lastOffset; + + if(to == -1) to = GetLength(); + + wxLOiterator first = FindObject(from, &firstOffset); + wxLOiterator last = FindObject(to, &lastOffset); + + // Common special case: only one object + if( *first == *last ) + { + if( (**first).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText + *)*first)->GetText().substr(firstOffset, + lastOffset-firstOffset)) + ); + return; + } + else // what can we do? + { + if(lastOffset > firstOffset) // i.e. +1 :-) + llist->Insert( (**first).Copy() ); + return; + } + } + + // If we reach here, we can safely copy the whole first object from + // the firstOffset position on: + if((**first).GetType() == WXLO_TYPE_TEXT && firstOffset != 0) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*first)->GetText().substr(firstOffset)) + ); + } + else if(firstOffset == 0) + llist->Insert( (**first).Copy() ); + // else nothing to copy :-( + + // Now we copy all objects before the last one: + wxLOiterator i = first; i++; + for( ; i != last; i++) + llist->Insert( (**i).Copy() ); + + // And now the last object: + if(lastOffset != 0) + { + if( (**last).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*last)->GetText().substr(0,lastOffset)) + ); + } + else + llist->Insert( (**last).Copy() ); + } +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The wxLayoutList object @@ -926,10 +1128,7 @@ wxLayoutLine::Debug(void) wxLayoutList::wxLayoutList() { - m_DefaultSetting = NULL; m_FirstLine = NULL; - m_ColourFG = *wxBLACK; - m_ColourBG = *wxWHITE; InvalidateUpdateRect(); Clear(); } @@ -959,11 +1158,20 @@ void wxLayoutList::InternalClear(void) { Empty(); - if(m_DefaultSetting) - { - delete m_DefaultSetting; - m_DefaultSetting = NULL; - } + m_Selection.m_selecting = false; + m_Selection.m_valid = false; + + m_DefaultSetting.family = wxSWISS; + m_DefaultSetting.size = WXLO_DEFAULTFONTSIZE; + m_DefaultSetting.style = wxNORMAL; + m_DefaultSetting.weight = wxNORMAL; + m_DefaultSetting.underline = 0; + m_DefaultSetting.m_fg_valid = TRUE; + m_DefaultSetting.m_fg = *wxBLACK; + m_DefaultSetting.m_bg_valid = TRUE; + m_DefaultSetting.m_bg = *wxWHITE; + + m_CurrentSetting = m_DefaultSetting; } void @@ -971,18 +1179,21 @@ wxLayoutList::SetFont(int family, int size, int style, int weight, int underline, wxColour *fg, wxColour *bg) { - if(family != -1) m_FontFamily = family; - if(size != -1) m_FontPtSize = size; - if(style != -1) m_FontStyle = style; - if(weight != -1) m_FontWeight = weight; - if(underline != -1) m_FontUnderline = underline != 0; - - if(fg != NULL) m_ColourFG = *fg; - if(bg != NULL) m_ColourBG = *bg; - + if(family != -1) m_CurrentSetting.family = family; + if(size != -1) m_CurrentSetting.size = size; + if(style != -1) m_CurrentSetting.style = style; + if(weight != -1) m_CurrentSetting.weight = weight; + if(underline != -1) m_CurrentSetting.underline = underline != 0; + if(fg) m_CurrentSetting.m_fg = *fg; + if(bg) m_CurrentSetting.m_bg = *bg; Insert( - new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline, - m_ColourFG, m_ColourBG)); + new wxLayoutObjectCmd( + m_CurrentSetting.family, + m_CurrentSetting.size, + m_CurrentSetting.style, + m_CurrentSetting.weight, + m_CurrentSetting.underline, + fg, bg)); } void @@ -1004,31 +1215,35 @@ wxLayoutList::SetFont(int family, int size, int style, int weight, void wxLayoutList::Clear(int family, int size, int style, int weight, - int /* underline */, wxColour *fg, wxColour *bg) + int underline, wxColour *fg, wxColour *bg) { InternalClear(); - - // set defaults - m_FontPtSize = size; - m_FontUnderline = false; - m_FontFamily = family; - m_FontStyle = style; - m_FontWeight = weight; - if(fg) m_ColourFG = *fg; - if(bg) m_ColourBG = *bg; - - m_ColourFG = *wxBLACK; - m_ColourBG = *wxWHITE; - - if(m_DefaultSetting) - delete m_DefaultSetting; - - m_DefaultSetting = new - wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle, - m_FontWeight,m_FontUnderline, - m_ColourFG, m_ColourBG); + m_DefaultSetting = wxLayoutStyleInfo(family, size, style, weight, + underline, fg, bg); + m_CurrentSetting = m_DefaultSetting; } +wxPoint +wxLayoutList::FindText(const wxString &needle, const wxPoint &cpos) const +{ + int xpos; + + wxLayoutLine *line; + for(line = m_FirstLine; + line; + line = line->GetNextLine()) + { + if(line->GetLineNumber() >= cpos.y) + { + xpos = line->FindText(needle, + (line->GetLineNumber() == cpos.y) ? + cpos.x : 0); + if(xpos != -1) + return wxPoint(xpos, line->GetLineNumber()); + } + } + return wxPoint(-1,-1); +} bool @@ -1160,6 +1375,7 @@ wxLayoutList::Insert(wxString const &text) SetUpdateRect(m_CursorScreenPos+m_CursorSize); m_CursorLine->Insert(m_CursorPos.x, text); m_CursorPos.x += text.Length(); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1171,6 +1387,7 @@ wxLayoutList::Insert(wxLayoutObject *obj) SetUpdateRect(m_CursorScreenPos+m_CursorSize); m_CursorLine->Insert(m_CursorPos.x, obj); m_CursorPos.x += obj->GetLength(); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1186,6 +1403,7 @@ wxLayoutList::LineBreak(void) m_FirstLine = m_CursorLine->GetPreviousLine(); m_CursorPos.y++; m_CursorPos.x = 0; + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1207,6 +1425,7 @@ wxLayoutList::WrapLine(CoordType column) LineBreak(); Delete(1); // delete the space m_CursorPos.x = newpos; + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } } @@ -1248,6 +1467,7 @@ wxLayoutList::Delete(CoordType npos) } } while(left); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return left == 0; } @@ -1264,6 +1484,7 @@ wxLayoutList::DeleteLines(int n) { // we cannot delete this line, but we can clear it MoveCursorToBeginOfLine(); DeleteToEndOfLine(); + m_CursorLine->RecalculatePositions(2, this); return n-1; } //else: @@ -1285,7 +1506,7 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) // first, make sure everything is calculated - this might not be // needed, optimise it later - m_DefaultSetting->Layout(dc); + ApplyStyle(&m_DefaultSetting, dc); while(line) { line->RecalculatePosition(this); // so we don't need to do it all the time @@ -1316,9 +1537,10 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) // first, make sure everything is calculated - this might not be // needed, optimise it later - m_DefaultSetting->Layout(dc); + ApplyStyle(&m_DefaultSetting, dc); while(line) { + line->GetStyleInfo() = m_CurrentSetting; if(line == m_CursorLine) line->Layout(dc, this, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x); else @@ -1347,9 +1569,8 @@ wxLayoutList::Draw(wxDC &dc, { wxLayoutLine *line = m_FirstLine; - Layout(dc, bottom); - m_DefaultSetting->Draw(dc, wxPoint(0,0)); - wxBrush brush(m_ColourBG, wxSOLID); + ApplyStyle(&m_DefaultSetting, dc); + wxBrush brush(m_DefaultSetting.m_bg, wxSOLID); dc.SetBrush(brush); while(line) @@ -1361,11 +1582,12 @@ wxLayoutList::Draw(wxDC &dc, if(bottom != -1 && line->GetPosition().y > bottom) break; line = line->GetNextLine(); } - // can only be 0 if we are on the first line and have no next line - wxASSERT(m_CursorSize.x != 0 || (m_CursorLine && - m_CursorLine->GetNextLine() == NULL && - m_CursorLine == m_FirstLine)); InvalidateUpdateRect(); + + WXLO_DEBUG(("Selection is %s : l%d,%ld/%ld,%ld", + m_Selection.m_valid ? "valid" : "invalid", + m_Selection.m_CursorA.x, m_Selection.m_CursorA.y, + m_Selection.m_CursorB.x, m_Selection.m_CursorB.y)); } wxLayoutObject * @@ -1378,7 +1600,7 @@ wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos, wxPoint p; // we need to run a layout here to get font sizes right :-( - m_DefaultSetting->Layout(dc); + ApplyStyle(&m_DefaultSetting, dc); while(line) { p = line->GetPosition(); @@ -1425,6 +1647,7 @@ wxLayoutList::GetSize(void) const return maxPoint; } + void wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate) { @@ -1446,11 +1669,19 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate) dc.SetLogicalFunction(wxXOR); dc.SetPen(wxPen(*wxBLACK,1,wxSOLID)); if(active) - dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x, - m_CursorSize.y); + { + dc.DrawRectangle(coords.x, coords.y, + m_CursorSize.x, m_CursorSize.y); + SetUpdateRect(coords.x, coords.y); + SetUpdateRect(coords.x+m_CursorSize.x, coords.y+m_CursorSize.y); + } else + { dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1, - coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1); + coords.x, coords.y); + SetUpdateRect(coords.x, coords.y+m_CursorSize.y-1); + SetUpdateRect(coords.x, coords.y); + } dc.SetLogicalFunction(wxCOPY); //dc.SetBrush(wxNullBrush); } @@ -1473,21 +1704,39 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y) void wxLayoutList::StartSelection(void) { - wxLogDebug("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + WXLO_DEBUG(("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorA = m_CursorPos; + m_Selection.m_CursorB = m_CursorPos; m_Selection.m_selecting = true; m_Selection.m_valid = false; } void -wxLayoutList::EndSelection(void) +wxLayoutList::ContinueSelection(void) { - wxLogDebug("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + wxASSERT(m_Selection.m_selecting == true); + wxASSERT(m_Selection.m_valid == false); + WXLO_DEBUG(("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorB = m_CursorPos; + // We always want m_CursorA <= m_CursorB! + if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB)) + { + wxPoint help = m_Selection.m_CursorB; + m_Selection.m_CursorB = m_Selection.m_CursorA; + m_Selection.m_CursorA = help; + } +} + +void +wxLayoutList::EndSelection(void) +{ + ContinueSelection(); + WXLO_DEBUG(("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_selecting = false; m_Selection.m_valid = true; } + bool wxLayoutList::IsSelecting(void) { @@ -1497,14 +1746,232 @@ wxLayoutList::IsSelecting(void) bool wxLayoutList::IsSelected(const wxPoint &cursor) { + if(! m_Selection.m_valid && ! m_Selection.m_selecting) + return false; return m_Selection.m_CursorA <= cursor && cursor <= m_Selection.m_CursorB; } + +/** Tests whether this layout line is selected and needs + highlighting. + @param line to test for + @return 0 = not selected, 1 = fully selected, -1 = partially + selected + */ +int +wxLayoutList::IsSelected(const wxLayoutLine *line, CoordType *from, + CoordType *to) +{ + wxASSERT(line); wxASSERT(to); wxASSERT(from); + + if(! m_Selection.m_valid && ! m_Selection.m_selecting) + return 0; + + CoordType y = line->GetLineNumber(); + if(m_Selection.m_CursorA.y < y && m_Selection.m_CursorB.y > y) + return 1; + else if(m_Selection.m_CursorA.y == y) + { + *from = m_Selection.m_CursorA.x; + if(m_Selection.m_CursorB.y == y) + *to = m_Selection.m_CursorB.x; + else + *to = line->GetLength(); + return -1; + } + else if(m_Selection.m_CursorB.y == y) + { + *to = m_Selection.m_CursorB.x; + if(m_Selection.m_CursorA.y == y) + *from = m_Selection.m_CursorA.x; + else + *from = 0; + return -1; + } + else + return 0; +} + +void +wxLayoutList::DeleteSelection(void) +{ + if(! m_Selection.m_valid) + return; + + m_Selection.m_valid = false; + + // Only delete part of the current line? + if(m_Selection.m_CursorA.y == m_Selection.m_CursorB.y) + { + MoveCursorTo(m_Selection.m_CursorA); + Delete(m_Selection.m_CursorB.x - m_Selection.m_CursorA.x); + return; + } + + + wxLayoutLine + * firstLine = NULL, + * lastLine = NULL; + + for(firstLine = m_FirstLine; + firstLine && firstLine->GetLineNumber() < m_Selection.m_CursorA.y; + firstLine=firstLine->GetNextLine()) + ; + if(!firstLine || firstLine->GetLineNumber() != m_Selection.m_CursorA.y) + return; + + + for(lastLine = m_FirstLine; + lastLine && lastLine->GetLineNumber() < m_Selection.m_CursorB.y; + lastLine=lastLine->GetNextLine()) + ; + if(!lastLine || lastLine->GetLineNumber() != m_Selection.m_CursorB.y) + return; + + + // We now know that the two lines are different: + + // First, delete what's left of this line: + MoveCursorTo(m_Selection.m_CursorA); + DeleteToEndOfLine(); + + wxLayoutLine *nextLine = firstLine->GetNextLine(); + while(nextLine && nextLine != lastLine) + nextLine = nextLine->DeleteLine(false, this); + + // Now nextLine = lastLine; + Delete(1); // This joins firstLine and nextLine + Delete(m_Selection.m_CursorB.x); // This deletes the first x + // positions + + /// Recalculate: + firstLine->RecalculatePositions(1, this); +} + +/// Starts highlighting the selection +void +wxLayoutList::StartHighlighting(wxDC &dc) +{ +#if SHOW_SELECTIONS + dc.SetTextForeground(m_CurrentSetting.m_bg); + dc.SetTextBackground(m_CurrentSetting.m_fg); +#endif +} + +/// Ends highlighting the selection +void +wxLayoutList::EndHighlighting(wxDC &dc) +{ +#if SHOW_SELECTIONS + dc.SetTextForeground(m_CurrentSetting.m_fg); + dc.SetTextBackground(m_CurrentSetting.m_bg); +#endif +} + + +wxLayoutList * +wxLayoutList::Copy(const wxPoint &from, + const wxPoint &to) +{ + wxLayoutLine + * firstLine = NULL, + * lastLine = NULL; + + for(firstLine = m_FirstLine; + firstLine && firstLine->GetLineNumber() < from.y; + firstLine=firstLine->GetNextLine()) + ; + if(!firstLine || firstLine->GetLineNumber() != from.y) + return NULL; + + for(lastLine = m_FirstLine; + lastLine && lastLine->GetLineNumber() < to.y; + lastLine=lastLine->GetNextLine()) + ; + if(!lastLine || lastLine->GetLineNumber() != to.y) + return NULL; + + if(to <= from) + { + wxLayoutLine *tmp = firstLine; + firstLine = lastLine; + lastLine = tmp; + } + + wxLayoutList *llist = new wxLayoutList(); + + if(firstLine == lastLine) + { + firstLine->Copy(llist, from.x, to.x); + } + else + { + // Extract objects from first line + firstLine->Copy(llist, from.x); + llist->LineBreak(); + // Extract all lines between + for(wxLayoutLine *line = firstLine->GetNextLine(); + line != lastLine; + line = line->GetNextLine()) + { + line->Copy(llist); + llist->LineBreak(); + } + // Extract objects from last line + lastLine->Copy(llist, 0, to.x); + } + return llist; +} + +wxLayoutList * +wxLayoutList::GetSelection(void) +{ + if(! m_Selection.m_valid) + { + if(m_Selection.m_selecting) + EndSelection(); + else + return NULL; + } + + m_Selection.m_valid = false; + return Copy( m_Selection.m_CursorA, m_Selection.m_CursorB ); +} + + + +#define COPY_SI(what) if(si->what != -1) { m_CurrentSetting.what = si->what; fontChanged = TRUE; } + +void +wxLayoutList::ApplyStyle(wxLayoutStyleInfo *si, wxDC &dc) +{ + bool fontChanged = FALSE; + COPY_SI(family); + COPY_SI(size); + COPY_SI(style); + COPY_SI(weight); + COPY_SI(underline); + if(fontChanged) + dc.SetFont( m_FontCache.GetFont(m_CurrentSetting) ); + + if(si->m_fg_valid) + { + m_CurrentSetting.m_fg = si->m_fg; + dc.SetTextForeground(m_CurrentSetting.m_fg); + } + if(si->m_bg_valid) + { + m_CurrentSetting.m_bg = si->m_bg; + dc.SetTextBackground(m_CurrentSetting.m_bg); + } +} + + #ifdef WXLAYOUT_DEBUG void -wxLayoutList::Debug(void) +wxLayoutList::Debug(void) { wxLayoutLine *line; @@ -1530,16 +1997,10 @@ wxLayoutPrintout::wxLayoutPrintout(wxLayoutList *llist, { m_llist = llist; m_title = title; -#ifdef M_BASEDIR - m_ProgressDialog = NULL; -#endif } wxLayoutPrintout::~wxLayoutPrintout() { -#ifdef M_BASEDIR - if(m_ProgressDialog) delete m_ProgressDialog; -#endif } float @@ -1594,12 +2055,6 @@ wxLayoutPrintout::ScaleDC(wxDC *dc) bool wxLayoutPrintout::OnPrintPage(int page) { -#ifdef M_BASEDIR - wxString msg; - msg.Printf(_("Printing page %d..."), page); - if(! m_ProgressDialog->Update(page, msg)) - return false; -#endif wxDC *dc = GetDC(); ScaleDC(dc); @@ -1650,12 +2105,6 @@ void wxLayoutPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, *selPageFrom = 1; *selPageTo = m_NumOfPages; wxRemoveFile(WXLLIST_TEMPFILE); - -#ifdef M_BASEDIR - m_ProgressDialog = new MProgressDialog( - title, _("Printing..."),m_NumOfPages, NULL, false, true); -#endif - } bool wxLayoutPrintout::HasPage(int pageNum) @@ -1705,3 +2154,18 @@ wxLayoutPrintout::DrawHeader(wxDC &dc, #endif +wxFont & +wxFontCache::GetFont(int family, int size, int style, int weight, + bool underline) +{ + for(wxFCEList::iterator i = m_FontList.begin(); + i != m_FontList.end(); i++) + if( (**i).Matches(family, size, style, weight, underline) ) + return (**i).GetFont(); + // not found: + wxFontCacheEntry *fce = new wxFontCacheEntry(family, size, style, + weight, underline); + m_FontList.push_back(fce); + return fce->GetFont(); +} +