Does anyone have a more evolved version of the code below ? The intent is to
allow for a secundary buffer/clipboard. This is for those cases, encountered
mostly by a layouter, when he has carefully selected a number of devices to do
some operation, and only later realises that he needs to make another operation
first, which would make him loose his selected set.
I suppose this has been written before, in a better style than mine (that is a
usual assumption :) so please post code or dejanews references if you know any. TIA.
procedure(CmSwapAltSelect()
let((buf cv)
unless(boundp('CmAltSelectBuffer) CmAltSelectBuffer='(()) )
cv=concat('cv substring( sprintf(nil "%L" geGetEditCellView()) 4)) ;;
cv72505388 instead of db:72505388
buf=setof(x geGetSelectedSet() x && type(x)=='dbobject)
geDeselectAll()
foreach(x get(CmAltSelectBuffer cv)
geSelectObjectNoFilter(x)
)
putprop(CmAltSelectBuffer buf cv)
)
)
foreach(key '("<Key>grave" "<Key>F12")
foreach(app '("Layout" "Schematics")
hiSetBindKey(app key "CmSwapAltSelect()") ))
;;Added a "dbIsId" check before selecting.
procedure(CmSwapAltSelect()
let((buf cv)
unless(boundp('CmAltSelectBuffer) CmAltSelectBuffer='(()) )
cv=concat('cv substring( sprintf(nil "%L" geGetEditCellView()) 4)) ;;
cv72505388 instead of db:72505388
buf=setof( x geGetSelectedSet() x && type(x)=='dbobject )
geDeselectAll()
foreach(x get(CmAltSelectBuffer cv)
dbIsId(x) && geSelectObjectNoFilter(x)
)
putprop(CmAltSelectBuffer buf cv)
));let & proc
I would probably not use a DPL for this, particularly as you're assigning
to a literal list in the code - which will end up destructively modifying the program.
procedure(CmSwapAltSelect(@optional (win (hiGetCurrentWindow))
let((buf cv)
unless(boundp('CmAltSelectBuffer)
CmAltSelectBuffer=makeTable('selectBuffer nil)
) ; unless
buf=geGetSelSet(win)
cv=geGetEditCellView(win)
geDeselectAll(win)
foreach(obj CmAltSelectBuffer[cv]
dbIsId(obj) && geSelectObjectNoFilter(obj)
) ; foreach
CmAltSelectBuffer[cv]=buf
t
) ; let
) ; procedure
I've not actually run this, so this is just typed in with no checking. The key
differences:
1. Not using a DPL - using a table instead.
2. No need to check the selected set for db objects, since they will always be
dbobjects.
3. bit more flexibility about passing in a window id (perhaps?)
Note, you need to be slightly careful with this, because odd things might happen if
you close and reopen a cellView - dbIds can get re-used.
You might want to add some code to remove entries from the table
for cellView id's that are no longer valid. Something like:
foreach(cv CmAltSelectBuffer
unless(dbIsId(cv) remove(cv CmAltSelectBuffer))
)
Andrew.
Andrew Beckett wrote:
> On Tue, 19 Jul 2005 12:23:11 +0200, fogh <cad_s...@skipthisandunderscores.catena.nl> wrote:
>
>>procedure(CmSwapAltSelect()
>>let((buf cv)
>> unless(boundp('CmAltSelectBuffer) CmAltSelectBuffer='(()) )
>> cv=concat('cv substring( sprintf(nil "%L" geGetEditCellView()) 4)) ;;
>>cv72505388 instead of db:72505388
>> buf=setof( x geGetSelectedSet() x && type(x)=='dbobject )
>> geDeselectAll()
>> foreach(x get(CmAltSelectBuffer cv)
>> dbIsId(x) && geSelectObjectNoFilter(x)
>> )
>> putprop(CmAltSelectBuffer buf cv)
>>));let & proc
>
>
> I would probably not use a DPL for this, particularly as you're assigning
> to a literal list in the code - which will end up destructively modifying the program.
Uh ?
Please Andrew elaborate on this. I can t see what you mean. In any case, I will
use the table instead. It is just that I am not used to.
> procedure(CmSwapAltSelect(@optional (win (hiGetCurrentWindow))
> let((buf cv)
> unless(boundp('CmAltSelectBuffer)
> CmAltSelectBuffer=makeTable('selectBuffer nil)
> ) ; unless
> buf=geGetSelSet(win)
> cv=geGetEditCellView(win)
> geDeselectAll(win)
> foreach(obj CmAltSelectBuffer[cv]
> dbIsId(obj) && geSelectObjectNoFilter(obj)
> ) ; foreach
> CmAltSelectBuffer[cv]=buf
> t
> ) ; let
> ) ; procedure
>
> I've not actually run this, so this is just typed in with no checking. The key
> differences:
>
> 1. Not using a DPL - using a table instead.
> 2. No need to check the selected set for db objects, since they will always be
> dbobjects.
Silly me !
> 3. bit more flexibility about passing in a window id (perhaps?)
>
> Note, you need to be slightly careful with this, because odd things might happen if
> you close and reopen a cellView - dbIds can get re-used.
That can be a feature too (the secundary selection persists during the session,
even if the view was closed). Or do you think I can better zero
CmAltSelectBuffer[cv] any time cv is closed. When do you think I can do that ?
(What triggers )
> You might want to add some code to remove entries from the table
> for cellView id's that are no longer valid. Something like:
>
> foreach(cv CmAltSelectBuffer
> unless(dbIsId(cv) remove(cv CmAltSelectBuffer))
> )
Also for triggers I guess ?
OTOH, those references dont take that much memory. That is not much of a memory
leak, or is it ? (what happens with 30000 via instances ? I did not test.)
I am still a bit surprised that there was no public code for this before. That
is a rather common 'wannahave' functionality.
and if the 'selection' is not only those objects but also the selection
on any-thing
which were selected , it will be much useful.
can anyone make more explicit the diffrence between using a DPL and a
table ? I did not really get the meaning of " would probably not use a
DPL for this, particularly as you're assigning to a literal list in the
code - which will end up destructively modifying the program."
here is the first bug with this: it does not deal with partial selections. A
partial will reappear as a full selection.
Does anyone know well how to save and restore a partial selection ? At first
look, one has to deal with saving/resoring the filter too, since there is no
geSelectFigPointNoFilter()
I have had suprises with DPL before, that i will illustrate with this sample code
procedure( test()
let( (x)
x='(nil)
print( x )
putpropq( x 1 p )
)
)
the output is:
test()
-> (nil)
test()
-> (nil p 1)
so, the DPL is not reset even though it has been assigned a new value...
if however you use x=list(nil) then it works.
strangely enough, if the procedure is redefined, the value of x is redefined as well.
this has to relate to some SKILL internals - maybe this is what Andrew suggested with "literal list".
(however your code doesn't rely on the DPL being reset, as far as i can see)
cheers,
stéphane
Ah, I can answer this one, having recently been called upon to answer
this peculiar query during a SKILL training class.
What's happening is that you're redefining the procedure (!) by
assigning to the DPL. '(nil) is a non-constant object whose pointer
(not value) is stored the procedure definition.
Indeed, if you pretty-print the procedure (i.e., (pp test) ), you'll see
that the definition has changed (!).
By calling (setq x (list nil)), you're using the list function to create
a new object each time.
Strange and non-intuitive, but this is apparently one of those
(mis-)features of Franz Lisp. (Along with dynamic binding...)
Dave
<easyridertone> Wow. Far out man. </easyridertone>
Dave,
Is there some kind of to top-of-the-charts list of such "interesting" language
features ?
Thanks Dave for answering the question as I would have answered it, and
Stephane for giving the example I would have used to illustrate it. I was on
holiday so did not have the opportunity to answer Frederic's question.
Actually, I think such behaviour is fairly intuitive if you understand how lists
are stored and what quote does. The trouble is that many people do not, and so
it seems counterintuitive - also, it can very easily trip you up!
Many languages have these kind of odd things - I remember having to explain at
length to a C programmer years ago that he really should not return a pointer to
an auto-allocated variable - e.g:
char *doSomething(long num)
{
char buffer[256];
sprintf(buffer,"result is %d",num);
return(buffer);
}
well, not unless he minded having strange crashes ;-)
At least with SKILL it tends to take a lot to get it to crash!
Regards,
Andrew.
I suppose you can if the first thing you do with the result is allocate
256byte at the adress returned.
> At least with SKILL it tends to take a lot to get it to crash!
skill.exe itself, maybe, but I remember for instance that CIW prompt a bit too
long could crash the workbench.
All right Andrew, I should stop being of bad faith. Just tied a knot in my
hankerchief to do some more homework and re-read on list data structure, dotted
pairs, scoping and all good things related to not tripping on ones shoelaces.
Would you have an idea on my second question: how to save/restore partial
selections.