Drag and Drop Actions Example

dragdropactions.png

 

rem ' DragDropActions.src

open (unt)"X0"
sysgui! = BBjAPI().getSysGui()

window!= sysgui!.addWindow(100,100,500,375,"Drag/Drop Actions",$00010083$)
window!.setCallback(sysgui!.ON_CLOSE,"Close")

rem ' Init
dim drag[1:2],drop[1:2],text$[1:2]
COPY=sysgui!.ACTION_COPY
MOVE=sysgui!.ACTION_MOVE
LINK=sysgui!.ACTION_LINK
NONE=sysgui!.ACTION_NONE
drag[1]=COPY+MOVE
drop[1]=COPY+MOVE
drag[2]=COPY+MOVE
drop[2]=COPY+MOVE
dread text$[all]

rem ' Status Bar
id=100,statbar!=window!.addStatusBar(id)
statbar!.setText("Press CTRL, SHIFT, or CTRL+SHIFT while dragging to select a different action.")

rem ' Group 1
id=id+1,editable1!=window!.addCheckBox(id,20,20,90,25,"Editable?",$0004$)
id=id+1,cedit1!=window!.addCEdit(id,20,50,220,140,text$[1],$0102$)
id=id+1; window!.addGroupBox(id,20,200,100,110,"Drag Actions")
id=id+1,DragMove1!=window!.addCheckBox(id,30,220,80,25,"MOVE",$0004$)
id=id+1,DragCopy1!=window!.addCheckBox(id,30,250,80,25,"COPY",$0004$)
id=id+1,DragLink1!=window!.addCheckBox(id,30,280,80,25,"LINK",$0000$)
id=id+1; window!.addGroupBox(id,130,200,100,110,"Drop Actions")
id=id+1,DropMove1!=window!.addCheckBox(id,140,220,80,25,"MOVE",$0004$)
id=id+1,DropCopy1!=window!.addCheckBox(id,140,250,80,25,"COPY",$0004$)
id=id+1,DropLink1!=window!.addCheckBox(id,140,280,80,25,"LINK",$0000$)

rem ' Group 2
id=id+1,editable2!=window!.addCheckBox(id,260,20,90,25,"Editable?",$0004$)
id=id+1,cedit2!=window!.addCEdit(id,260,50,220,140,text$[2],$0102$)
id=id+1; window!.addGroupBox(id,260,200,100,110,"Drag Actions")
id=id+1,DragMove2!=window!.addCheckBox(id,270,220,80,25,"MOVE",$0004$)
id=id+1,DragCopy2!=window!.addCheckBox(id,270,250,80,25,"COPY",$0004$)
id=id+1,DragLink2!=window!.addCheckBox(id,270,280,80,25,"LINK",$0000$)
id=id+1; window!.addGroupBox(id,370,200,100,110,"Drop Actions")
id=id+1,DropMove2!=window!.addCheckBox(id,380,220,80,25,"MOVE",$0004$)
id=id+1,DropCopy2!=window!.addCheckBox(id,380,250,80,25,"COPY",$0004$)
id=id+1,DropLink2!=window!.addCheckBox(id,380,280,80,25,"LINK",$0000$)

rem ' Reset
id=id+1,reset!=window!.addButton(id,390,320,90,25,"Reset")

rem ' Callbacks
CALLBACK(ON_CHECK_ON,Editable1Checked,sysgui!.getContext(),editable1!.getID())
CALLBACK(ON_CHECK_OFF,Editable1Unchecked,sysgui!.getContext(),editable1!.getID())
CALLBACK(ON_DROP_TARGET_DROP,DropTargetDrop,sysgui!.getContext(),cedit1!.getID())
CALLBACK(ON_DRAG_SOURCE_DROP,DragSourceDrop,sysgui!.getContext(),cedit1!.getID())
CALLBACK(ON_CHECK_ON,DragMove1Checked,sysgui!.getContext(),DragMove1!.getID())
CALLBACK(ON_CHECK_OFF,DragMove1Unchecked,sysgui!.getContext(),DragMove1!.getID())
CALLBACK(ON_CHECK_ON,DragCopy1Checked,sysgui!.getContext(),DragCopy1!.getID())
CALLBACK(ON_CHECK_OFF,DragCopy1Unchecked,sysgui!.getContext(),DragCopy1!.getID())
CALLBACK(ON_CHECK_ON,DragLink1Checked,sysgui!.getContext(),DragLink1!.getID())
CALLBACK(ON_CHECK_OFF,DragLink1Unchecked,sysgui!.getContext(),DragLink1!.getID())
CALLBACK(ON_CHECK_ON,DropMove1Checked,sysgui!.getContext(),DropMove1!.getID())
CALLBACK(ON_CHECK_OFF,DropMove1Unchecked,sysgui!.getContext(),DropMove1!.getID())
CALLBACK(ON_CHECK_ON,DropCopy1Checked,sysgui!.getContext(),DropCopy1!.getID())
CALLBACK(ON_CHECK_OFF,DropCopy1Unchecked,sysgui!.getContext(),DropCopy1!.getID())
CALLBACK(ON_CHECK_ON,DropLink1Checked,sysgui!.getContext(),DropLink1!.getID())
CALLBACK(ON_CHECK_OFF,DropLink1Unchecked,sysgui!.getContext(),DropLink1!.getID())
CALLBACK(ON_CHECK_ON,Editable2Checked,sysgui!.getContext(),editable2!.getID())
CALLBACK(ON_CHECK_OFF,Editable2Unchecked,sysgui!.getContext(),editable2!.getID())
CALLBACK(ON_DROP_TARGET_DROP,DropTargetDrop,sysgui!.getContext(),cedit2!.getID())
CALLBACK(ON_DRAG_SOURCE_DROP,DragSourceDrop,sysgui!.getContext(),cedit2!.getID())
CALLBACK(ON_CHECK_ON,DragMove2Checked,sysgui!.getContext(),DragMove2!.getID())
CALLBACK(ON_CHECK_OFF,DragMove2Unchecked,sysgui!.getContext(),DragMove2!.getID())
CALLBACK(ON_CHECK_ON,DragCopy2Checked,sysgui!.getContext(),DragCopy2!.getID())
CALLBACK(ON_CHECK_OFF,DragCopy2Unchecked,sysgui!.getContext(),DragCopy2!.getID())
CALLBACK(ON_CHECK_ON,DragLink2Checked,sysgui!.getContext(),DragLink2!.getID())
CALLBACK(ON_CHECK_OFF,DragLink2Unchecked,sysgui!.getContext(),DragLink2!.getID())
CALLBACK(ON_CHECK_ON,DropMove2Checked,sysgui!.getContext(),DropMove2!.getID())
CALLBACK(ON_CHECK_OFF,DropMove2Unchecked,sysgui!.getContext(),DropMove2!.getID())
CALLBACK(ON_CHECK_ON,DropCopy2Checked,sysgui!.getContext(),DropCopy2!.getID())
CALLBACK(ON_CHECK_OFF,DropCopy2Unchecked,sysgui!.getContext(),DropCopy2!.getID())
CALLBACK(ON_CHECK_ON,DropLink2Checked,sysgui!.getContext(),DropLink2!.getID())
CALLBACK(ON_CHECK_OFF,DropLink2Unchecked,sysgui!.getContext(),DropLink2!.getID())

CALLBACK(ON_BUTTON_PUSH,Reset,sysgui!.getContext(),reset!.getID())

process_events

Editable1Checked:
    cedit1!.setEditable(1)
    DragMove1!.setEnabled(1)
    DropMove1!.setEnabled(1)
    DropCopy1!.setEnabled(1)
    DropLink1!.setEnabled(1)
return

Editable1Unchecked:
    cedit1!.setEditable(0)
    DragMove1!.setEnabled(0)
    DropMove1!.setEnabled(0)
    DropCopy1!.setEnabled(0)
    DropLink1!.setEnabled(0)
return

DragMove1Checked:
    drag[1]=drag[1]+MOVE
    cedit1!.setDragActions(drag[1])
return

DragMove1Unchecked:
    drag[1]=drag[1]-MOVE
    cedit1!.setDragActions(drag[1])
return

DragCopy1Checked:
    drag[1]=drag[1]+COPY
    cedit1!.setDragActions(drag[1])
return

DragCopy1Unchecked:
    drag[1]=drag[1]-COPY
    cedit1!.setDragActions(drag[1])
return

DragLink1Checked:
    drag[1]=drag[1]+LINK
    cedit1!.setDragActions(drag[1])
return

DragLink1Unchecked:
    drag[1]=drag[1]-LINK
    cedit1!.setDragActions(drag[1])
return

DropMove1Checked:
    drop[1]=drop[1]+MOVE
    cedit1!.setDropActions(drop[1])
return

DropMove1Unchecked:
    drop[1]=drop[1]-MOVE
    cedit1!.setDropActions(drop[1])
return

DropCopy1Checked:
    drop[1]=drop[1]+COPY
    cedit1!.setDropActions(drop[1])
return

DropCopy1Unchecked:
    drop[1]=drop[1]-COPY
    cedit1!.setDropActions(drop[1])
return

DropLink1Checked:
    drop[1]=drop[1]+LINK
    cedit1!.setDropActions(drop[1])
return

DropLink1Unchecked:
    drop[1]=drop[1]-LINK
    cedit1!.setDropActions(drop[1])
return

Editable2Checked:
    cedit2!.setEditable(2)
    DragMove2!.setEnabled(2)
    DropMove2!.setEnabled(2)
    DropCopy2!.setEnabled(2)
    DropLink2!.setEnabled(2)
return

Editable2Unchecked:
    cedit2!.setEditable(0)
    DragMove2!.setEnabled(0)
    DropMove2!.setEnabled(0)
    DropCopy2!.setEnabled(0)
    DropLink2!.setEnabled(0)
return

DragMove2Checked:
    drag[2]=drag[2]+MOVE
    cedit2!.setDragActions(drag[2])
return

DragMove2Unchecked:
    drag[2]=drag[2]-MOVE
    cedit2!.setDragActions(drag[2])
return

DragCopy2Checked:
    drag[2]=drag[2]+COPY
    cedit2!.setDragActions(drag[2])
return

DragCopy2Unchecked:
    drag[2]=drag[2]-COPY
    cedit2!.setDragActions(drag[2])
return

DragLink2Checked:
    drag[2]=drag[2]+LINK
    cedit2!.setDragActions(drag[2])
return

DragLink2Unchecked:
    drag[2]=drag[2]-LINK
    cedit2!.setDragActions(drag[2])
return

DropMove2Checked:
    drop[2]=drop[2]+MOVE
    cedit2!.setDropActions(drop[2])
return

DropMove2Unchecked:
    drop[2]=drop[2]-MOVE
    cedit2!.setDropActions(drop[2])
return

DropCopy2Checked:
    drop[2]=drop[2]+COPY
    cedit2!.setDropActions(drop[2])
return

DropCopy2Unchecked:
    drop[2]=drop[2]-COPY
    cedit2!.setDropActions(drop[2])
return

DropLink2Checked:
    drop[2]=drop[2]+LINK
    cedit2!.setDropActions(drop[2])
return

DropLink2Unchecked:
    drop[2]=drop[2]-LINK
    cedit2!.setDropActions(drop[2])
return

DropTargetDrop:
    event!=sysgui!.getLastEvent()
    print 'lf',"ON_DROP_TARGET_DROP"
    dragSource!=event!.getDragSource()
    dropTarget!=event!.getControl()
    info$="Data was dragged from "+fnControlType$(dragSource!)+" to "+fnControlType$(dropTarget!)+$0a$
    if (dragSource!<>null()) then
        info$=info$+"Drag Source actions were: "+fnActions$(dragSource!.getDragActions())+$0a$
    endif
    info$=info$+"Drop Target actions were: "+fnActions$(dropTarget!.getDropActions())+$0a$
    selection$=fnSelection$(dragSource!,event!.getSelection())
    if (len(selection$)) then
        info$=info$+"Drag selection was "+fnTruncate$(selection$)+$0a$
    endif
    location$=fnDropLocation$(dropTarget!,event!.getDropLocation())
    if (len(location$)) then
        info$=info$+"Drop location was "+location$+$0a$
    endif
    info$=info$+"Action was "+fnAction$(event!.getAction())+$0a$
    if (event!.getText()="") then
        info$=info$+"Data is "+fnData$(event!.getData())
    else
        if (pos($0a$=event!.getText())) then
            info$=info$+"Text data is:"+$0a$+fnTruncate$(event!.getText())
        else
            info$=info$+"Text data is """+fnTruncate$(event!.getText())+""""
        endif
        i=msgbox(info$)
    return

    def fnVector!(string$)
    vector! = BBjAPI().makeVector()
    if (pos($0a$=string$,1,0)) then
        if string$(len(string$))<>$0a$ then
            string$=string$+$0a$
        endif
        count=pos($0a$=string$,1,0)
        dim rec$:"line["+str(count)+"]:c(1*=10)"
        let rec$=string$
        for i=1 to count
            vector!.add(rec.line$[i])
        next i
    else
        vector!.add(string$)
    endif
return vector!
fnend

def fnTruncate$(string$)
vector!=fnVector!(string$)
string$=$$,maxlines=16,maxwidth=128
for i=0 to min(vector!.size()-1,maxlines)
    line$=str(vector!.get(i))
    if len(line$) > maxwidth
        string$=string$+line$(1,maxwidth)+"..."
    else
        string$=string$+line$
    endif
    if (vector!.size()>1) then
        string$=string$+$0a$
    endif
next i
if (vector!.size()>maxlines) then
    string$=string$+"..."
endif
return string$
fnend

DragSourceDrop:
    event!=sysgui!.getLastEvent()
    print 'lf',"ON_DRAG_SOURCE_DROP"
    control!=event!.getControl()
    print "Data dragged from ",control!
    print "Drop action ",fnAction$(event!.getAction())," was ",
    if (event!.getSuccess()) then
        print "completed successfully."
    else
        print "not completed successfully."
    endif
return

def fnControlType$(BBjControl!)
if BBjControl!=null()
    return "Unknown"
endif
switch BBjControl!.getControlType()
    case BBjControl!.BARCHART_CONTROL
    return "BBjBarChart"
    case BBjControl!.CEDIT_CONTROL
    return "BBjCEdit"
    case BBjControl!.CHECKABLE_MENUITEM_CONTROL
    return "BBjCheckableMenuItem"
    case BBjControl!.CHECKBOX_CONTROL
    return "BBjCheckbox"
    case BBjControl!.CHILD_WINDOW
    return "BBjChildWindow"
    case BBjControl!.COLORCHOOSER_CONTROL
    return "BBjColorChooser"
    case BBjControl!.EDIT_CONTROL
    return "BBjEditBox"
    case BBjControl!.EDIT_SPINNER_CONTROL
    return "BBjEditBoxSpinner"
    case BBjControl!.FILECHOOSER_CONTROL
    return "BBjFileChooser"
    case BBjControl!.FONTCHOOSER_CONTROL
    return "BBjFontChooser"
    case BBjControl!.GRID_CONTROL
    return "BBjGrid"
    case BBjControl!.GROUPBOX_CONTROL
    return "BBjGroupBox"
    case BBjControl!.HSCROLL_CONTROL
    return "BBjScrollBar"
    case BBjControl!.HSLIDER_CONTROL
    return "BBjSlider"
    case BBjControl!.IMAGE_CONTROL
    return "BBjImage"
    case BBjControl!.INPUTD_CONTROL
    return "BBjInputD"
    case BBjControl!.INPUTD_SPINNER_CONTROL
    return "BBjInputDSpinner"
    case BBjControl!.INPUTE_CONTROL
    return "BBjInputE"
    case BBjControl!.INPUTE_SPINNER_CONTROL
    return "BBjInputESpinner"
    case BBjControl!.INPUTN_CONTROL
    return "BBjInputN"
    case BBjControl!.INPUTN_SPINNER_CONTROL
    return "BBjInputNSpinner"
    case BBjControl!.LINECHART_CONTROL
    return "BBjLineChart"
    case BBjControl!.LISTBOX_CONTROL
    return "BBjListBox"
    case BBjControl!.LISTBUTTON_CONTROL
    return "BBjListButton"
    case BBjControl!.LISTEDIT_CONTROL
    return "BBjListEdit"
    case BBjControl!.MAIN_WINDOW
    return "BBjWindow"
    case BBjControl!.MENUBUTTON_CONTROL
    return "BBjMenuButton"
    case BBjControl!.MENUITEM_CONTROL
    return "BBjMenuItem"
    case BBjControl!.NAVIGATOR_CONTROL
    return "BBjNavigator"
    case BBjControl!.PIECHART_CONTROL
    return "BBjPieChart"
    case BBjControl!.PROGRESS_CONTROL
    return "BBjProgressBar"
    case BBjControl!.PUSHBUTTON_CONTROL
    return "BBjButton"
    case BBjControl!.RADIOBUTTON_CONTROL
    return "BBjRadioButton"
    case BBjControl!.STATUSBAR_CONTROL
    return "BBjStatusBar"
    case BBjControl!.TAB_CONTROL
    return "BBjTabCtrl"
    case BBjControl!.TEXT_CONTROL
    return "BBjStaticText"
    case BBjControl!.TOOLBUTTON_CONTROL
    return "BBjToolButton"
    case BBjControl!.TREE_CONTROL
    return "BBjTree"
    case BBjControl!.VSCROLL_CONTROL
    return "BBjScrollBar"
    case BBjControl!.VSLIDER_CONTROL
    return "BBjSlider"
    case default
    return "Unknown control type "+str(BBjControl!.getControlType())
swend
fnend

def fnSelection$(BBjControl!,BBjVector!)
if BBjControl!=null()
    return ""
endif
switch BBjControl!.getControlType()
    case BBjControl!.CEDIT_CONTROL
        selection$="Offset "+str(BBjVector!.get(0))+
        :              " through "+str(BBjVector!.get(1))+" ("+
        :             "Paragraph "+str(BBjVector!.get(2))+
        :              ", offset "+str(BBjVector!.get(3))+" through "+
        :             "Paragraph "+str(BBjVector!.get(4))+
        :              ", offset "+str(BBjVector!.get(5))+")"
    return selection$
    case BBjControl!.GRID_CONTROL
        selection$=""
        for i=0 to BBjVector!.size()-1 step 2
            selection$=selection$+
            :          "[row="+str(BBjVector!.get(i))+
            :          ",col="+str(BBjVector!.get(i+1))+"],"
        next i
    return selection$(1,len(selection$)-1)
    case BBjControl!.LISTBOX_CONTROL
        selection$=""
        for i=0 to BBjVector!.size()-1
            selection$=selection$+"[row="+str(BBjVector!.get(i))+"],"
        next i
    return selection$(1,len(selection$)-1)
    case BBjControl!.TREE_CONTROL
        selection$=""
        for i=0 to BBjVector!.size()-1
            selection$=selection$+"[node="+str(BBjVector!.get(i))+"],"
        next i
    return selection$(1,len(selection$)-1)
    case BBjControl!.EDIT_CONTROL
    case BBjControl!.EDIT_SPINNER_CONTROL
    case BBjControl!.INPUTD_CONTROL
    case BBjControl!.INPUTD_SPINNER_CONTROL
    case BBjControl!.INPUTE_CONTROL
    case BBjControl!.INPUTE_SPINNER_CONTROL
    case BBjControl!.INPUTN_CONTROL
    case BBjControl!.INPUTN_SPINNER_CONTROL
    case BBjControl!.LISTEDIT_CONTROL
        selection$="Offset "+str(BBjVector!.get(0))+
        :              " through "+str(BBjVector!.get(1))
    return selection$
    case default
    return "N/A"
swend
fnend

def fnDropLocation$(BBjControl!,BBjVector!)
if BBjControl!=null()
    return ""
endif
switch BBjControl!.getControlType()
    case BBjControl!.CEDIT_CONTROL
        location$="Offset "+str(BBjVector!.get(0))+" ("+
        :            "Paragraph "+str(BBjVector!.get(1))+
        :             ", offset "+str(BBjVector!.get(2))+")"
    return location$
    case BBjControl!.GRID_CONTROL
        location$="[row="+str(BBjVector!.get(0))+
        :               ",col="+str(BBjVector!.get(1))+"]"
    return location$
    case BBjControl!.LISTBOX_CONTROL
        location$="[row="+str(BBjVector!.get(0))+"]"
    return location$
    case BBjControl!.TREE_CONTROL
        Node=BBjVector!.get(0)
        location$="[node="+str(node)+"]: """+BBjControl!.getNodeText(node)+""""
    return location$
    case BBjControl!.EDIT_CONTROL
    case BBjControl!.EDIT_SPINNER_CONTROL
    case BBjControl!.INPUTD_CONTROL
    case BBjControl!.INPUTD_SPINNER_CONTROL
    case BBjControl!.INPUTE_CONTROL
    case BBjControl!.INPUTE_SPINNER_CONTROL
    case BBjControl!.INPUTN_CONTROL
    case BBjControl!.INPUTN_SPINNER_CONTROL
    case BBjControl!.LISTEDIT_CONTROL
        location$="Offset "+str(BBjVector!.get(0))
        return location$
    case default
        return ""
swend
    fnend

def fnAction$(action)
switch action
    case sysgui!.ACTION_NONE; return "NONE"
    case sysgui!.ACTION_COPY; return "COPY"
    case sysgui!.ACTION_MOVE; return "MOVE"
    case sysgui!.ACTION_COPY_OR_MOVE; return "COPY_OR_MOVE"
    case sysgui!.ACTION_LINK; return "LINK"
    case default; return str(action)
    swend
fnend

def fnActions$(action)
actions$=$$
if (fnIsBitSet(action,sysgui!.ACTION_COPY)) then
    actions$=actions$+"COPY|"
endif
if (fnIsBitSet(action,sysgui!.ACTION_MOVE)) then
    actions$=actions$+"MOVE|"
endif
if (fnIsBitSet(action,sysgui!.ACTION_LINK)) then
    actions$=actions$+"LINK|"
endif
if (len(actions$)) then
    return actions$(1,len(actions$)-1)
else
    return "NONE"
endif
fnend

def fnIsBitSet(value,bit)
    return sgn(dec(and(bin(value,4),bin(bit,4))))
fnend

def fnData$(data!)
if data!=null() or data!.isEmpty() then return "<Empty>"
data$=$$
key!=data!.keySet().iterator()
while key!.hasNext()
    data$=data$+str(data!.get(key!.next()))+$0a$
wend
return data$(1,len(data$)-1)
fnend

rem ' Reset
Reset:
    Editable1!.setSelected(1)
    cedit1!.setText(text$[1])
    cedit1!.setEditable(1)
    DragMove1!.setEnabled(1)
    DropMove1!.setEnabled(1)
    DropCopy1!.setEnabled(1)
    DropLink1!.setEnabled(1)
    DragMove1!.setSelected(1)
    DragCopy1!.setSelected(1)
    DragLink1!.setSelected(0)
    DropMove1!.setSelected(1)
    DropCopy1!.setSelected(1)
    DropLink1!.setSelected(0)
    drag[1]=COPY+MOVE
    drop[1]=COPY+MOVE
    Editable2!.setSelected(1)
    cedit2!.setText(text$[2])
    cedit2!.setEditable(1)
    DragMove2!.setEnabled(1)
    DropMove2!.setEnabled(1)
    DropCopy2!.setEnabled(1)
    DropLink2!.setEnabled(1)
    DragMove2!.setSelected(1)
    DragCopy2!.setSelected(1)
    DragLink2!.setSelected(0)
    DropMove2!.setSelected(1)
    DropCopy2!.setSelected(1)
    DropLink2!.setSelected(0)
    drag[2]=COPY+MOVE
    drop[2]=COPY+MOVE
return

rem ' Sample text
data "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur?"
data "At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."

Close:
release