* Program..: MleCol.prg * Author...: Jeremy Suiter * Date.....: 19/03/2003 * * Notice...: Copyright (c) 2003, Jeremy Suiter, All Rights Reserved * Notes....: Visual DbEditor MLE column functions (modified from ATSAG samples) #include "Appevent.ch" #include "Common.ch" #include "Xbp.ch" #Include "Resources.ch" CLASS XbpMleColumn FROM XbpGetColumn PROTECTED: VAR MemoDlg IS xbpGet IN XbpGetColumn VAR _dataLink METHOD setPosAndSize EXPORTED: METHOD create METHOD createXbp METHOD firstMemoLine METHOD hiliteRow ENDCLASS /* * Replace the :dataLink code block before the object is :create()ed. * The original :dataLink code block is preserved and used later for * XbpMLE. The new code block retrieves the first line of text from the * memo field. */ METHOD XbpMleColumn:create(p1, p2, p3, p4, p5, p6) ::bufferLength:=50 ::_dataLink :=::dataLink ::dataLink :={|| ::firstMemoLine() } ::xbpGetColumn:create(p1, p2, p3, p4, p5, p6) Return Self METHOD XbpMleColumn:firstMemoLine Return TRIM(MemoLine(Eval(::_dataLink), ::bufferLength, 1)) /* * Create a MemoEditDialog instead of the XbpGet object and assign the * original :dataLink code block which accesses the memo field. * * Note 1: the instance variable :MemoDlg is actually declared as * :xbpGet in the super class, but renamed in this class. * This makes the code better readable. * * Note 2: The owner of the MemoEditDialog is the window that contains the * browser. The parent of the MemoEditDialog is the same as for the * browser window. If the browser window is moved, the MemoEditDialog * window is moved as well. */ METHOD XbpMleColumn:createXbp LOCAL oOwner:=::setParent() LOCAL oParent, aSize:={400, 400} DO WHILE .NOT. oOwner:IsDerivedFrom("XbpDialog") oOwner:=oOwner:setParent() ENDDO oParent:=oOwner:setParent() //aSize[1] :=::currentSize()[1] ::MemoDlg :=MemoEditDialog():new(oParent, oOwner,, aSize,, .F.) ::MemoDlg:icon :=ICON_MAIN ::MemoDlg:controller :=Self ::MemoDlg:dataLink :=::_dataLink ::MemoDlg:moveWithOwner:=.T. ::MemoDlg:title :=::heading:getCell(1) ::MemoDlg:create() Return Self /* * Overloaded from XbpGetColumn: only the position of the MemoEditDialog window * changes with the browse cursor, not the size * * Note: The position of the browse cursor cannot be directly used for * positioning of the MemoEditDialog window. The coordinates must be * transformed to the origin of the coordinate system that is * valid for the browser window. */ METHOD XbpMleColumn:setPosAndSize(nRowPos) LOCAL aRect:=::dataArea:cellRect(nRowPos) LOCAL aPos :={ aRect[1], aRect[2] + (aRect[4]-aRect[2]) } LOCAL aSize:=::MemoDlg:currentSize() LOCAL oOwner:=::MemoDlg:setOwner() aPos[1] += ::currentPos()[1] + ::setParent():currentPos()[1] aPos[2] += ::footing:currentSize()[2] aPos[1] += ::browser:currentPos()[1] aPos[2] += ::browser:currentPos()[2] aPos[1] += oOwner:currentPos()[1] aPos[2] += oOwner:currentPos()[2] aPos[1]:=Max(0, Min(aPos[1], oOwner:setParent():currentSize()[1]-aSize[1])) aPos[2]:=Max(0, aPos[2]-aSize[2]) ::MemoDlg:setPos(aPos) Return Self /* * Overloaded from XbpGetColumn: The MemoEditDialog window remains visible * during (de)hilighting. */ METHOD XbpMleColumn:hiliteRow(nRowPos, lHilite, lFrame, lRepaint) DEFAULT nRowPos TO ::browser:rowPos If ::active If lHilite ::read(nRowPos) Else If ::MemoDlg:changed ::MemoDlg:getData() ::xbpColumn:refreshRows(nRowPos, nRowPos) EndIf EndIf EndIf ::xbpColumn:hiliteRow(nRowPos, lHilite, lFrame, lRepaint) Return Self ****************************************************************************** /* * MemoEditDialog with embedded XbpMle and :dataLink code block */ CLASS MemoEditDialog FROM XbpDialog PROTECTED: VAR btnSave VAR bntUndo EXPORTED: VAR controller VAR MLE VAR dataLink VAR changed VAR bufferLength ACCESS ASSIGN METHOD dataLink ACCESS ASSIGN METHOD changed METHOD init METHOD create METHOD setData METHOD getData METHOD editBuffer METHOD clear METHOD undo METHOD setMarked METHOD keyboard ENDCLASS METHOD MemoEditDialog:init(oParent, oOwner, aPos, aSize, aPP, lVisible) LOCAL aMinSize:={218,160} DEFAULT oParent TO AppDesktop(), ; aPos TO {0,0}, ; aSize TO {218,160}, ; lVisible TO .F. aSize[1]:=Max(aSize[1], aMinSize[1]) aSize[2]:=Max(aSize[2], aMinSize[2]) ::XbpDialog:init(oParent, oOwner, aPos, aSize, aPP, lVisible) ::XbpDialog:taskList:=.F. ::XbpDialog:title :="Memo" ::XbpDialog:minSize :=aMinSize ::XbpDialog:close :={|| ::controller:killRead() } ::XbpDialog:setInputFocus:={|x,y,obj| SetAppFocus(IIf(obj:isVisible(),obj:MLE, obj:controller)) } ::MLE :=XbpMle():new(::drawingArea) ::MLE:ignoreTab :=.T. ::MLE:wordWrap :=.T. ::MLE:horizScroll :=.F. ::btnSave :=XbpPushButton():new(::drawingArea, , {8,8}, {88,24}) ::btnSave:caption :="~Save" ::btnSave:activate :={|| ::getData(), ::controller:killRead() } ::bntUndo :=XbpPushButton():new(::drawingArea, , {112,8}, {88,24}) ::bntUndo:caption :="~Undo" ::bntUndo:activate :={|| ::undo() , ::controller:killRead() } ::bufferLength :=66 Return Self METHOD MemoEditDialog:create(oParent, oOwner, aPos, aSize, aPP, lVisible) ::XbpDialog:create(oParent, oOwner, aPos, aSize, aPP, lVisible) aPos :={8,48} aSize :=::drawingArea:currentSize() aSize[1] -= 16 aSize[2] -= 56 ::MLE:create(,, aPos, aSize) ::MLE:setEditable(lEditable) ::btnSave:create() ::bntUndo:create() ::drawingArea:resize:={|aOld, aNew| aNew[1] -= 16, ; aNew[2] -= 56, ; ::Mle:setSize(aNew) } Return Self /* * Methods for editing */ METHOD MemoEditDialog:setData(xValue) If .NOT. ::isVisible() ::show() EndIf If PCount() == 0 xValue:=::MLE:setData() Else xValue:=::MLE:setData(xValue) EndIf Return xValue METHOD MemoEditDialog:getData LOCAL xRet:=::MLE:getData() ::changed:=.F. ::controller:browser:refreshCurrent() Return xRet METHOD MemoEditDialog:editBuffer Return ::MLE:editBuffer() METHOD MemoEditDialog:clear Return ::MLE:clear() METHOD MemoEditDialog:undo Return ::MLE:undo() METHOD MemoEditDialog:setMarked(aMarked) Return ::MLE:setMarked(aMarked) METHOD MemoEditDialog:dataLink(bBlock) If PCount() == 1 ::MLE:dataLink:=bBlock EndIf Return ::MLE:dataLink METHOD MemoEditDialog:changed(lChanged) If Valtype(lChanged) == "L" ::MLE:changed(lChanged) EndIf Return ::MLE:changed /* * xbeK_ALT_UP and xbeK_ALT_DOWN are used for browser navigation */ METHOD MemoEditDialog:keyboard(nKey) DO CASE CASE nKey == xbeK_ALT_F4 ::controller:killRead() CASE nKey == xbeK_ALT_UP ::controller:keyboard(xbeK_UP) SetAppFocus(Self) CASE nKey == xbeK_ALT_DOWN ::controller:keyboard(xbeK_DOWN) SetAppFocus(Self) CASE nKey == xbeK_ALT_O .or. nKey == xbeK_ALT_S ::getData() ::controller:killRead() CASE nKey == xbeK_ALT_U ::setData() ::controller:killRead() CASE .NOT. ::controller:keyboard(nKey) ::xbpDialog:keyboard(nKey) ENDCASE Return Self