/* * File: wx_msnip.cc * Purpose: wxMediaSnip implementation * Author: Matthew Flatt * Created: 1995 * Copyright: (c) 2004-2009 PLT Scheme Inc. * Copyright: (c) 1995, Matthew Flatt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #if defined(_MSC_VER) && defined(MZ_PRECISE_GC) # include "wx.h" #endif #include "common.h" #include "wx_media.h" #include #include #include #include #include "wx_mpriv.h" #include "wx_gcrct.h" wxMediaSnip::wxMediaSnip(wxMediaBuffer *useme, Bool border, int lm, int tm, int rm, int bm, int li, int ti, int ri, int bi, double w, double W, double h, double H) { Bool istemp; wxSnipClassList *scl; #if USE_OLD_TYPE_SYSTEM __type = wxTYPE_MEDIA_SNIP; #endif flags |= wxSNIP_HANDLES_EVENTS; scl = &wxTheSnipClassList; snipclass = scl->Find("wxmedia"); withBorder = border; leftMargin = lm; topMargin = tm; rightMargin = rm; bottomMargin = bm; leftInset = li; topInset = ti; rightInset = ri; bottomInset = bi; minWidth = w; maxWidth = W; minHeight = h; maxHeight = H; if (useme && !useme->GetAdmin()) { me = useme; } else { me = wxsMakeMediaEdit(); } { wxMediaSnipMediaAdmin *msma; msma = new WXGC_PTRS wxMediaSnipMediaAdmin(this); myAdmin = msma; } if (!me->GetFilename(&istemp) || istemp) /* Turn on flag to mirror filename: */ flags |= wxSNIP_USES_BUFFER_PATH; me->OwnCaret(FALSE); } wxMediaSnip::~wxMediaSnip() { #if 1 /* The only way a snip should be deleted if by GC, and it wouldn't get GC'd if the editor isn't also going to be GCd. It's important *not* to call SetAdmin(), because that can trigger Scheme code. */ DELETE_OBJ me; me = NULL; #else if (me) { if (me->GetAdmin() == myAdmin) me->SetAdmin(NULL); } #endif DELETE_OBJ myAdmin; } void wxMediaSnip::SetAdmin(wxSnipAdmin *a) { if (PTRNE(a, admin)) { wxSnip::SetAdmin(a); if (me) { if (a) { if (me->GetAdmin()) me = NULL; /* traitor! - get rid of it */ else me->SetAdmin(myAdmin); } else me->SetAdmin(NULL); } } if (admin && (flags & wxSNIP_USES_BUFFER_PATH)) { /* Propogate a filename change: */ Bool istemp; if (me && (!me->GetFilename(&istemp) || istemp)) { wxMediaBuffer *b; b = admin->GetMedia(); if (b) { char *filename; filename = b->GetFilename(); if (filename) me->SetFilename(filename, TRUE); } } else flags -= wxSNIP_USES_BUFFER_PATH; /* Turn off the flag; not needed */ } } void wxMediaSnip::SetMedia(wxMediaBuffer *b) { if (me == b) return; if (me && admin) me->SetAdmin(NULL); me = b; if (b) { if (b->GetAdmin()) { me = NULL; return; } else if (admin) { me->SetAdmin(myAdmin); } } if (admin) admin->Resized(this, TRUE); } wxMediaBuffer *wxMediaSnip::GetThisMedia(void) { return me; } wxCursor *wxMediaSnip::AdjustCursor(wxDC *dc, double x, double y, double, double, wxMouseEvent *event) { wxMSMA_SnipDrawState *save; wxCursor *c; if (!me) return NULL; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); c = me->AdjustCursor(event); myAdmin->RestoreState(save); return c; } void wxMediaSnip::OnEvent(wxDC *dc, double x, double y, double, double, wxMouseEvent *event) { wxMSMA_SnipDrawState *save; if (!me) return; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); me->OnEvent(event); myAdmin->RestoreState(save); } void wxMediaSnip::OnChar(wxDC *dc, double x, double y, double, double, wxKeyEvent *event) { wxMSMA_SnipDrawState *save; if (!me) return; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); me->OnChar(event); myAdmin->RestoreState(save); } void wxMediaSnip::OwnCaret(Bool ownit) { if (me) me->OwnCaret(ownit); } void wxMediaSnip::BlinkCaret(wxDC *dc, double x, double y) { if (me) { wxMSMA_SnipDrawState *save; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); me->BlinkCaret(); myAdmin->RestoreState(save); } } void wxMediaSnip::DoEdit(int op, Bool recursive, long time) { if (me) me->DoEdit(op, recursive, time); } Bool wxMediaSnip::CanEdit(int op, Bool recursive) { if (me) return me->CanEdit(op, recursive); else return FALSE; } void wxMediaSnip::DoFont(int op, Bool recursive) { if (me) me->DoFont(op, recursive); } Bool wxMediaSnip::Match(wxSnip *) { return FALSE; } void wxMediaSnip::SizeCacheInvalid(void) { if (me) me->SizeCacheInvalid(); } wxchar *wxMediaSnip::GetText(long offset, long num, Bool flat, long *got) { if (offset >= 1 || !num) { if (got) *got = 0; return wx_empty_wxstr; } if (!flat) { wxchar *s; s = new WXGC_ATOMIC wxchar[2]; s[0] = '.'; s[1] = 0; if (got) *got = 1; return s; } else if (me) return me->GetFlattenedText(got); else return wx_empty_wxstr; } void wxMediaSnip::GetExtent(wxDC *dc, double x, double y, double *w, double *h, double *_descent, double *_space, double *lspace, double *rspace) { wxMSMA_SnipDrawState *save; double descent, space, origH, dummyH; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); if (!h && alignTopLine) h = &dummyH; if (me) me->GetExtent(w, h); else { if (w) *w = 0; if (h) *h = 0; } origH = alignTopLine ? *h : 0.0; if (w) { if (me && (me->bufferType == wxEDIT_BUFFER)) { if (tightFit) (*w) -= CURSOR_WIDTH; else --(*w); /* It still looks better to subtract 1 */ if (*w < 0) *w = 0; } if (*w < minWidth) *w = minWidth; else if (maxWidth > 0 && *w > maxWidth) *w = maxWidth; (*w) += rightMargin + leftMargin; } if (h) { if (me && (me->bufferType == wxEDIT_BUFFER)) { if (tightFit) { (*h) -= ((wxMediaEdit *)me)->GetLineSpacing(); if (*h < 0) *h = 0; } } if (*h < minHeight) *h = minHeight; else if (maxHeight > 0 && *h > maxHeight) *h = maxHeight; (*h) += topMargin + bottomMargin; } { descent = (me ? me->GetDescent() : 0.0) + bottomMargin; if (me && (me->bufferType == wxEDIT_BUFFER)) { if (alignTopLine) descent = origH - ((wxMediaEdit *)me)->GetTopLineBase() + bottomMargin; if (tightFit) { descent -= ((wxMediaEdit *)me)->GetLineSpacing(); if (descent < 0) descent = 0; } } } space = (me ? me->GetSpace() : 0.0) + topMargin; if (maxHeight > 0 && (descent + space >= maxHeight + topMargin + bottomMargin)) { /* Just give up on spaces in this case: */ space = topMargin; descent = bottomMargin; } if (_descent) *_descent = descent; if (_space) *_space = space; if (lspace) *lspace = leftMargin; if (rspace) *rspace = rightMargin; myAdmin->RestoreState(save); } void wxMediaSnip::Draw(wxDC *dc, double x, double y, double left, double top, double right, double bottom, double WXUNUSED(dx), double WXUNUSED(dy), int show_caret) { double w, h, r, b, orig_x, orig_y; double t, l; wxColour *bgColor = wxWHITE; wxMSMA_SnipDrawState *save; save = new WXGC_PTRS wxMSMA_SnipDrawState; myAdmin->SaveState(save, dc, x, y); if (me) { w = h = 0.0; me->GetExtent(&w, &h); if (me && (me->bufferType == wxEDIT_BUFFER)) { if (tightFit) w -= CURSOR_WIDTH; else --w; /* It still looks better to subtract 1 */ if (w < 0) w = 0; } if (me && (me->bufferType == wxEDIT_BUFFER)) { if (tightFit) { h -= ((wxMediaEdit *)me)->GetLineSpacing(); if (h < 0) h = 0; } } } else w = h = 0.0; if (w < minWidth) w = minWidth; else if (maxWidth > 0 && w > maxWidth) w = maxWidth; if (h < minHeight) h = minHeight; else if (maxHeight > 0 && h > maxHeight) h = maxHeight; orig_x = x; orig_y = y; x += leftMargin; y += topMargin; r = x + w; b = y + h; l = ((x > left) ? x : left); t = ((y > top) ? y : top); r = ((r < right) ? r : right); b = ((b < bottom) ? b : bottom); if (useStyleBG) { if (style->GetTransparentTextBacking()) { bgColor = NULL; } else { wxBrush *saveb, *fill; wxPen *savep, *transPen; bgColor = style->GetBackground(); l = orig_x + leftInset; t = orig_y + topInset; r = l + (w + leftMargin + rightMargin - (leftInset + rightInset)) - 1; b = t + (h + topMargin + bottomMargin - (topInset + bottomInset)) - 1; transPen = wxThePenList->FindOrCreatePen(bgColor, 0, wxTRANSPARENT); fill = wxTheBrushList->FindOrCreateBrush(bgColor, wxSOLID); savep = dc->GetPen(); saveb = dc->GetBrush(); dc->SetPen(transPen); dc->SetBrush(fill); dc->DrawRectangle(l, t, r - l, b - t); dc->SetBrush(saveb); dc->SetPen(savep); } } if (me) me->Refresh(l - x, t - y, r - l, b - t, show_caret, bgColor); if (withBorder) { double mt, ml, mb, mr; l = orig_x + leftInset; t = orig_y + topInset; r = l + (w + leftMargin + rightMargin - (leftInset + rightInset)) - 1; b = t + (h + topMargin + bottomMargin - (topInset + bottomInset)) - 1; ml = ((l > left) ? ((l < right) ? l : right) : left); mr = ((r > left) ? ((r < right) ? r : right) : left); mt = ((t > top) ? ((t < bottom) ? t : bottom) : top); mb = ((b > top) ? ((b < bottom) ? b : bottom) : top); if (l >= left && l < right && mt < mb + GC_LINE_EXTEND) dc->DrawLine(l, mt, l, mb + GC_LINE_EXTEND); if (r >= left && r < right && mt < mb + GC_LINE_EXTEND) dc->DrawLine(r, mt, r, mb + GC_LINE_EXTEND); if (t >= top && t < bottom && ml < mr + GC_LINE_EXTEND) dc->DrawLine(ml, t, mr + GC_LINE_EXTEND, t); if (b >= top && b < bottom && ml < mr + GC_LINE_EXTEND) dc->DrawLine(ml, b, mr + GC_LINE_EXTEND, b); } myAdmin->RestoreState(save); } wxSnip *wxMediaSnip::Copy(void) { wxMediaSnip *ms; wxMediaBuffer *mb; mb = (me ? me->CopySelf() : (wxMediaBuffer *)NULL); ms = wxsMakeMediaSnip(mb, withBorder, leftMargin, topMargin, rightMargin, bottomMargin, leftInset, topInset, rightInset, bottomInset, minWidth, maxWidth, minHeight, maxHeight); /* Copy core snip info: */ wxSnip::Copy(ms); ms->tightFit = tightFit; ms->alignTopLine = alignTopLine; if (!me) ms->SetMedia(NULL); return ms; } void wxMediaSnip::Write(wxMediaStreamOut *f) { Bool wb = withBorder, tf = tightFit, ta = alignTopLine, usbg = useStyleBG; f->Put((me ? me->bufferType : 0)); f->Put(wb); f->Put(leftMargin); f->Put(topMargin); f->Put(rightMargin); f->Put(bottomMargin); f->Put(leftInset); f->Put(topInset); f->Put(rightInset); f->Put(bottomInset); f->Put(minWidth); f->Put(maxWidth); f->Put(minHeight); f->Put(maxHeight); f->Put(tf); f->Put(ta); f->Put(usbg); if (me) me->WriteToFile(f); } void wxMediaSnip::SetMaxWidth(double w) { maxWidth = w; if (admin) admin->Resized(this, TRUE); } void wxMediaSnip::SetMinWidth(double w) { minWidth = w; if (admin) admin->Resized(this, TRUE); } void wxMediaSnip::SetMaxHeight(double h) { maxHeight = h; if (admin) admin->Resized(this, TRUE); } void wxMediaSnip::SetMinHeight(double h) { minHeight = h; if (admin) admin->Resized(this, TRUE); } double wxMediaSnip::GetMaxWidth(void) { return maxWidth; } double wxMediaSnip::GetMaxHeight(void) { return maxHeight; } double wxMediaSnip::GetMinWidth(void) { return minWidth; } double wxMediaSnip::GetMinHeight(void) { return minHeight; } Bool wxMediaSnip::GetTightTextFit(void) { return tightFit; } void wxMediaSnip::SetTightTextFit(Bool t) { tightFit = (t ? TRUE : FALSE); if (admin) admin->Resized(this, TRUE); } Bool wxMediaSnip::GetAlignTopLine(void) { return alignTopLine; } void wxMediaSnip::SetAlignTopLine(Bool t) { alignTopLine = (t ? TRUE : FALSE); if (admin) admin->Resized(this, TRUE); } void wxMediaSnip::UseStyleBG(Bool useit) { if ((useStyleBG ? 1 : 0) != (useit ? 1 : 0)) { useStyleBG = (useit ? TRUE : FALSE); RequestRefresh(); } } Bool wxMediaSnip::StyleBGUsed() { return useStyleBG; } Bool wxMediaSnip::Resize(double w, double h) { w -= leftMargin + rightMargin; h -= topMargin + bottomMargin; if (w < 0) w = 0; if (h < 0) h = 0; minWidth = maxWidth = w; minHeight = maxHeight = h; if (me) { me->SetMaxWidth(w); me->SetMinWidth(w); } if (admin) admin->Resized(this, TRUE); return TRUE; } void wxMediaSnip::RequestRefresh() { if (admin) { wxDC *dc; double w, h; dc = admin->GetDC(); if (dc) { w = h = 0.0; GetExtent(dc, 0, 0, &w, &h); admin->NeedsUpdate(this, leftInset, topInset, w + rightMargin - rightInset, h + bottomMargin - bottomInset); } } } void wxMediaSnip::ShowBorder(Bool show) { if ((withBorder ? 1 : 0) != (show ? 1 : 0)) { withBorder = (show ? TRUE : FALSE); RequestRefresh(); } } Bool wxMediaSnip::BorderVisible() { return withBorder; } void wxMediaSnip::SetMargin(int lm, int tm, int rm, int bm) { leftMargin = lm; topMargin = tm; rightMargin = rm; bottomMargin = bm; if (admin) admin->Resized(this, TRUE); } void wxMediaSnip::GetMargin(int *lm, int *tm, int *rm, int *bm) { *lm = leftMargin; *tm = topMargin; *rm = rightMargin; *bm = bottomMargin; } void wxMediaSnip::SetInset(int lm, int tm, int rm, int bm) { leftMargin = lm; topMargin = tm; rightMargin = rm; bottomMargin = bm; if (admin) { wxDC *dc; double w, h; dc = admin->GetDC(); if (dc) { w = h = 0.0; GetExtent(dc, 0, 0, &w, &h); admin->NeedsUpdate(this, 0, 0, w + rightMargin + leftMargin, h + bottomMargin + topMargin); } } } void wxMediaSnip::GetInset(int *li, int *ti, int *ri, int *bi) { *li = leftInset; *ti = topInset; *ri = rightInset; *bi = bottomInset; } long wxMediaSnip::GetNumScrollSteps() { return (me ? me->NumScrollLines() : 1); } long wxMediaSnip::FindScrollStep(double y) { return (me ? me->FindScrollLine(y - topMargin) : 0); } double wxMediaSnip::GetScrollStepOffset(long i) { return (me ? me->ScrollLineLocation(i) + topMargin : 0); } void wxMediaSnip::SetUnmodified() { if (me) me->SetModified(FALSE); } /****************************************************************/ wxMediaSnipMediaAdmin::wxMediaSnipMediaAdmin(wxMediaSnip *s) { #if USE_OLD_TYPE_SYSTEM __type = wxTYPE_MEDIA_SNIP_MEDIA_ADMIN; #endif snip = s; state = new WXGC_PTRS wxMSMA_SnipDrawState; state->drawing = 0; WXGC_IGNORE(state, state->dc); } wxMediaSnipMediaAdmin::~wxMediaSnipMediaAdmin() { state->dc = NULL; } wxDC *wxMediaSnipMediaAdmin::GetDC(double *xp, double *yp) { if (state->drawing) { if (xp) *xp = -state->x; if (yp) *yp = -state->y; } else { if (xp) *xp = 0; if (yp) *yp = 0; } if (state->drawing) return state->dc; else { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) return sadmin->GetDC(); else return NULL; } } void wxMediaSnipMediaAdmin::SaveState(wxMSMA_SnipDrawState *save, wxDC *dc, double x, double y) { save->drawing = state->drawing; save->dc = state->dc; save->x = state->x; save->y = state->y; state->drawing = TRUE; state->x = x + snip->leftMargin; state->y = y + snip->topMargin; state->dc = dc; } void wxMediaSnipMediaAdmin::RestoreState(wxMSMA_SnipDrawState *saved) { state->drawing = saved->drawing; state->dc = saved->dc; state->x = saved->x; state->y = saved->y; } void wxMediaSnipMediaAdmin::GetView(double *x, double *y, double *w, double *h, Bool full) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (!sadmin) { if (x) *x = 0; if (y) *y = 0; if (w) *w = 0; if (h) *h = 0; return; } if (full) { sadmin->GetView(x, y, w, h, NULL); } else { double sx, sy, sw, sh; sadmin->GetView(&sx, &sy, &sw, &sh, snip); if (x) { *x = sx - snip->leftMargin; if (*x < 0) *x = 0; } if (y) { *y = sy - snip->topMargin; if (*y < 0) *y = 0; } if (w || h) { if (sw || sh) { /* w and h might be too big due to margins - but they might be small enough already because part of the snip itself is not viewed. */ double rw, rh; /* We want the internal, non-overridden method: */ snip->wxMediaSnip::GetExtent(state->dc, 0, 0, &rw, &rh); /* remember: sx and sy are in snip coordinates */ if (w) { double leftMargin, rightMargin; leftMargin = snip->leftMargin - sx; if (leftMargin < 0) leftMargin = 0; sw -= leftMargin; rw -= snip->leftMargin; rightMargin = snip->rightMargin - (rw - sw); if (rightMargin < 0) rightMargin = 0; sw -= rightMargin; if (sw < 0) sw = 0; *w = sw; } if (h) { double topMargin, bottomMargin; topMargin = snip->topMargin - sy; if (topMargin < 0) topMargin = 0; sh -= topMargin; rh -= snip->topMargin; bottomMargin = snip->bottomMargin - (rh - sh); if (bottomMargin < 0) bottomMargin = 0; sh -= bottomMargin; if (sh < 0) sh = 0; *h = sh; } } else { if (w) *w = 0; if (h) *h = 0; } } } } Bool wxMediaSnipMediaAdmin::ScrollTo(double localx, double localy, double w, double h, Bool refresh, int bias) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) return sadmin->ScrollTo(snip, localx + snip->leftMargin, localy + snip->topMargin, w, h, refresh, bias); else return FALSE; } void wxMediaSnipMediaAdmin::GrabCaret(int dist) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) sadmin->SetCaretOwner(snip, dist); } void wxMediaSnipMediaAdmin::Resized(Bool redraw_now) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) sadmin->Resized(snip, redraw_now); } void wxMediaSnipMediaAdmin::NeedsUpdate(double localx, double localy, double w, double h) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) sadmin->NeedsUpdate(snip, localx + snip->leftMargin, localy + snip->topMargin, w, h); } void wxMediaSnipMediaAdmin::UpdateCursor() { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) sadmin->UpdateCursor(); } Bool wxMediaSnipMediaAdmin::PopupMenu(void *m, double x, double y) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) return sadmin->PopupMenu(m, snip, x + snip->leftMargin, y + snip->topMargin); else return FALSE; } Bool wxMediaSnipMediaAdmin::DelayRefresh() { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (!sadmin) return 1; if (sadmin->__type == wxTYPE_MEDIA_SNIP_ADMIN) { wxMediaBuffer *b; b = ((wxStandardSnipAdmin *)sadmin)->GetMedia(); return b->RefreshDelayed(); } else return 0; } void wxMediaSnipMediaAdmin::Modified(Bool modified) { wxSnipAdmin *sadmin; sadmin = snip->GetAdmin(); if (sadmin) sadmin->Modified(snip, modified); } /************************************************************************/ extern wxMediaBuffer *objscheme_unbundle_wxMediaBuffer(Scheme_Object *, const char*, int); #define GET_EDIT(buf) ((buf->bufferType == wxEDIT_BUFFER) ? (wxMediaEdit *)buf : NULL) #define GET_BUF(bv) objscheme_unbundle_wxMediaBuffer((Scheme_Object *)vb, NULL, 0) #define edf(name, action) \ static Bool ed_##name(void *vb, wxEvent *, void *) \ { wxMediaBuffer *buf; wxMediaEdit *b; \ buf = GET_BUF(vb); \ b = GET_EDIT(buf); \ if (!b) return FALSE; \ b->action; return TRUE; } \ edf(right, MovePosition(WXK_RIGHT)) edf(left, MovePosition(WXK_LEFT)) edf(up, MovePosition(WXK_UP)) edf(down, MovePosition(WXK_DOWN)) edf(pageup, MovePosition(WXK_UP, FALSE, wxMOVE_PAGE)) edf(pagedown, MovePosition(WXK_DOWN, FALSE, wxMOVE_PAGE)) edf(rightword, MovePosition(WXK_RIGHT, FALSE, wxMOVE_WORD)) edf(leftword, MovePosition(WXK_LEFT, FALSE, wxMOVE_WORD)) edf(selectright, MovePosition(WXK_RIGHT, TRUE)) edf(selectleft, MovePosition(WXK_LEFT, TRUE)) edf(selectup, MovePosition(WXK_UP, TRUE)) edf(selectdown, MovePosition(WXK_DOWN, TRUE)) edf(selectpageup, MovePosition(WXK_UP, TRUE, wxMOVE_PAGE)) edf(selectpagedown, MovePosition(WXK_DOWN, TRUE, wxMOVE_PAGE)) edf(selectrightword, MovePosition(WXK_RIGHT, TRUE, wxMOVE_WORD)) edf(selectleftword, MovePosition(WXK_LEFT, TRUE, wxMOVE_WORD)) edf(startofline, MovePosition(WXK_LEFT, FALSE, wxMOVE_LINE)) edf(endofline, MovePosition(WXK_RIGHT, FALSE, wxMOVE_LINE)) edf(home, MovePosition(WXK_HOME)) edf(end, MovePosition(WXK_END)) edf(selecttostartofline, MovePosition(WXK_LEFT, TRUE, wxMOVE_LINE)) edf(selecttoendofline, MovePosition(WXK_RIGHT, TRUE, wxMOVE_LINE)) edf(selecttohome, MovePosition(WXK_HOME, TRUE)) edf(selecttoend, MovePosition(WXK_END, TRUE)) edf(clear, Erase()) edf(delete, Delete()) edf(pastenext, PasteNext()) static Bool ed_deletenext(void *vb, wxEvent *, void *) { long s, e; wxMediaEdit *edit; wxMediaBuffer *buf; buf = GET_BUF(vb); edit = GET_EDIT(buf); if (!edit) return FALSE; edit->GetPosition(&s, &e); if (s != e) edit->Delete(); else edit->Delete(s, s + 1); return TRUE; } static Bool ed_deletenextword(void *vb, wxEvent *event, void *) { wxMediaEdit *edit; wxMediaBuffer *buf; buf = GET_BUF(vb); edit = GET_EDIT(buf); if (!edit) return FALSE; edit->BeginEditSequence(); ed_selectrightword(edit, event, NULL); ed_delete(edit, event, NULL); edit->EndEditSequence(); return TRUE; } static Bool ed_deleteprevword(void *vb, wxEvent *event, void *) { wxMediaEdit *edit; wxMediaBuffer *buf; buf = GET_BUF(vb); edit = GET_EDIT(buf); if (!edit) return FALSE; edit->BeginEditSequence(); ed_selectleftword(edit, event, NULL); ed_delete(edit, event, NULL); edit->EndEditSequence(); return TRUE; } static Bool ed_deleteline(void *vb, wxEvent *event, void *) { wxMediaEdit *edit; wxMediaBuffer *buf; buf = GET_BUF(vb); edit = GET_EDIT(buf); if (!edit) return FALSE; edit->BeginEditSequence(); ed_startofline(edit, event, NULL); ed_selecttoendofline(edit, event, NULL); ed_delete(edit, event, NULL); edit->EndEditSequence(); return TRUE; } void wxMediaEdit::AddEditorFunctions(wxKeymap *tab) { wxAddMediaEditorFunctions(tab); } void wxAddMediaEditorFunctions(wxKeymap *tab) { #define setf(name, func) tab->AddFunction(name, ed_##func, NULL) setf("forward-character", right); setf("backward-character", left); setf("previous-line", up); setf("next-line", down); setf("previous-page", pageup); setf("next-page", pagedown); setf("forward-word", rightword); setf("backward-word", leftword); setf("forward-select", selectright); setf("backward-select", selectleft); setf("select-down", selectdown); setf("select-up", selectup); setf("select-page-up", selectpageup); setf("select-page-down", selectpagedown); setf("forward-select-word", selectrightword); setf("backward-select-word", selectleftword); setf("beginning-of-file", home); setf("end-of-file", end); setf("beginning-of-line", startofline); setf("end-of-line", endofline); setf("select-to-beginning-of-file", selecttohome); setf("select-to-end-of-file", selecttoend); setf("select-to-beginning-of-line", selecttostartofline); setf("select-to-end-of-line", selecttoendofline); setf("delete-previous-character", delete); setf("delete-next-character", deletenext); setf("clear-buffer", clear); setf("delete-next-word", deletenextword); setf("delete-previous-word", deleteprevword); setf("delete-line", deleteline); setf("paste-next", pastenext); wxAddMediaBufferFunctions(tab); } /*************************************************************/ wxMediaWordbreakMap::wxMediaWordbreakMap() { int i; char *old; usage = 0; memset(map, 0, sizeof(map)); /* Use default locale... */ old = setlocale(LC_CTYPE, NULL); old = copystring(old); setlocale(LC_CTYPE, ""); for (i = 0; i < 256; i++) { if (isalnum(i)) map[i] = wxBREAK_FOR_CARET | wxBREAK_FOR_LINE | wxBREAK_FOR_SELECTION; else if ((i >= 128) || !isspace(i)) map[i] = wxBREAK_FOR_LINE; } setlocale(LC_CTYPE, old); map[(int)'-'] -= wxBREAK_FOR_LINE; } void wxMediaWordbreakMap::SetMap(int ch, int mask) { if ((ch >= 0) && (ch <= 255)) map[ch] = mask; } int wxMediaWordbreakMap::GetMap(int ch) { if ((ch >= 0) && (ch <= 255)) return map[ch]; else return 0; }