List Info

Thread: Replaceing selected text with Basic Macro




Replaceing selected text with Basic Macro
user name
2007-04-16 17:31:57
I have a small problem that I just can't figure out at these
late hours
(00:13 right now):

I have written a macro that reads highlighted text and
replaces it with
something else (which is calculated by the macro).

To read the highlighted text I use
ThisComponent.getCurrentSelection
().getByIndex(0).getString().

This caused me no problems, however I couldn't figure out
the parameter in
getByIndex(0). Why 0? What does it mean? 0 what? I tried 1
and 2 but they
only caused errors.
Ok, I guess I can figure that one out myself with some help
from Google, so
here is my real question:

When I replace the highlighted text, I do that with
ThisComponent.getCurrentSelection().getByIndex(0).setString(
MyString). The
problem is that I want the new inserted string also to be
highlighted, so I
can perform the macro on it without having to highlight it
manually.

Any ideas? Is there some better way to do this?

Just an example to illustrate what I mean:

"Here is a sentence that will *illustrate* my
example."

I hope you can see that one word ("illustrate") in
the sentence above is
underlined. That is supposed to illustrate that it is
highlighted.

Ok, now I run my macro (this is a fake example, my macro
does something
else) and now it looks like this:

"Here is a sentence that will show my example."

As you hopefully can see, nothing is now underlined, however
the cursor is
placed right after the word "show". What I want,
is that the word "shows" in
this case should be highlighted after the macro was run:

"Here is a sentence that will *show* my example."

This would make it possible to run the macro once again and
get the
following result (still a fake example):

"Here is a sentence that will *help you to understand*
my example."

And so on...

Thanks in advance


Johnny Andersson
Re: Replaceing selected text with Basic Macro
user name
2007-04-16 19:10:30
Alle 00:31, martedì 17 aprile 2007, Johnny Andersson ha
scritto:
> I have a small problem that I just can't figure out at
these late hours
> (00:13 right now):
>
> I have written a macro that reads highlighted text and
replaces it with
> something else (which is calculated by the macro).
>
> To read the highlighted text I use
ThisComponent.getCurrentSelection
> ().getByIndex(0).getString().
>
> This caused me no problems, however I couldn't figure
out the parameter in
> getByIndex(0). Why 0? What does it mean? 0 what? I
tried 1 and 2 but they
> only caused errors.

Because the getCurrentSelection() method in writer normally
gets a
com.sun.star.text.TextRanges (that is a container)
In general it contains at least one TextRange, but in case
of multiple 
selection it contains more elements.
Use the getCount() method to discover how many TextRanges
are actually 
selected


> Ok, I guess I can figure that one out myself with some
help from Google, so
> here is my real question:
>
> When I replace the highlighted text, I do that with
>
ThisComponent.getCurrentSelection().getByIndex(0).setString(
MyString). The
> problem is that I want the new inserted string also to
be highlighted, so I
> can perform the macro on it without having to highlight
it manually.
>
> Any ideas? Is there some better way to do this?
>
> Just an example to illustrate what I mean:
[....]

Hoping that I have correctly understood your example, the
following code 
should do (more or less) what you need.
Check the Andrew Pitonyak's macro document for better
techniques and examples

-----------8<-----------
REM  *****  BASIC  *****

Sub Main

oRange = ThisComponent.currentselection(0)
oText = oRange.getText()

oCursor = oText.createTextCursorByRange(oRange)
bAbsorb = True
oText.insertString( oRange, "new string",
bAbsorb)

'restore selection
ThisComponent.CurrentController.select(oRange)

End Sub
-----------8<-----------


ciao
Paolo M

------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeapi.openoffice.org
For additional commands, e-mail: dev-helpapi.openoffice.org


Re: Replaceing selected text with Basic Macro
user name
2007-04-17 03:28:50
2007/4/17, Paolo Mantovani <p_mantolibero.it>:
>
> Alle 00:31, martedì 17 aprile 2007, Johnny Andersson
ha scritto:
> > I have a small problem that I just can't figure
out at these late hours
> > (00:13 right now):
> >
> > I have written a macro that reads highlighted text
and replaces it with
> > something else (which is calculated by the macro).
> >
> > To read the highlighted text I use
ThisComponent.getCurrentSelection
> > ().getByIndex(0).getString().
> >
> > This caused me no problems, however I couldn't
figure out the parameter
> in
> > getByIndex(0). Why 0? What does it mean? 0 what? I
tried 1 and 2 but
> they
> > only caused errors.
>
> Because the getCurrentSelection() method in writer
normally gets a
> com.sun.star.text.TextRanges (that is a container)
> In general it contains at least one TextRange, but in
case of multiple
> selection it contains more elements.
> Use the getCount() method to discover how many
TextRanges are actually
> selected


Oh, I see. I didn't realize that it was possible to have
more than one
selection in Writer (I knew it's possible in Calc though),
but a quick test
with the Ctrl key certainly proves to me that it's possible.
Yes, maybe I
should include that possibility in my macro, so not only the
first (or
rather 0th...) selection is handled.

> Ok, I guess I can figure that one out myself with some
help from Google,
> so
> > here is my real question:
> >
> > When I replace the highlighted text, I do that
with
> >
ThisComponent.getCurrentSelection().getByIndex(0).setString(
MyString).
> The
> > problem is that I want the new inserted string
also to be highlighted,
> so I
> > can perform the macro on it without having to
highlight it manually.
> >
> > Any ideas? Is there some better way to do this?
> >
> > Just an example to illustrate what I mean:
> [....]
>
> Hoping that I have correctly understood your example,
the following code
> should do (more or less) what you need.
> Check the Andrew Pitonyak's macro document for better
techniques and
> examples
>
> -----------8<-----------
> REM  *****  BASIC  *****
>
> Sub Main
>
> oRange = ThisComponent.currentselection(0)
> oText = oRange.getText()
>
> oCursor = oText.createTextCursorByRange(oRange)
> bAbsorb = True
> oText.insertString( oRange, "new string",
bAbsorb)
>
> 'restore selection
> ThisComponent.CurrentController.select(oRange)
>
> End Sub
> -----------8<-----------
>
>
> ciao
> Paolo M
>
> I haven't tried your suggestion yet, but I will as soon
as possible.

Just one follow-up-question, if you don't mind:

The objects we are talking about here, ThisComponent and its
sub objects (or
whatever I should call them), contain other objects,
variables and methods
etc, right? Many years ago when I studied some C++ (which I
never used since
then, sorry...) I was told that when created classes, it was
a good idea to
keep variables private and do most things with them through
public local
methods.

To me it felt like the proper thing to do is to always use
local methods for
everything, when it comes to changing values and contents of
things.

In your example you go for an object directly:
ThisComponent.CurrentSelection(0).
In my example I do like this to obtain the same (?) thing:
ThisComponent.getCurrentSelection().getByIndex(0)

My thought was something like "since there is a method,
it is probably
supposed to be used".
On the other hand, if ThisComponent.CurrentSelection(0) is
possible to do,
that object is obviously not private, so I should feel free
to use it.

Which is the "proper" way to do things? Is the
rule that "if a variable or
an object is private, use their methods, otherwise
manipulate them
directly"?

Or is it "always use the method designed for what you
want to do with the
variable/object"?

Or is it something else?



Johnny Andersson
Re: Replaceing selected text with Basic Macro
user name
2007-04-17 04:45:04
I was playing around a bit with the
ThisComponent.CurrentSelection.getCount()
function and I found that when I had one selection,
ThisComponent.CurrentSelection.getCount() returned 1, but
when I had more
than one selection (and I am still talking about Writer),
ThisComponent.CurrentSelection.getCount() returned the
number of selections
+ 1 for some reason. In the same case,
ThisComponent.CurrentSelection(0).getText()
returns an empty string.
ThisComponent.CurrentSelection(1).getText() and
ThisComponent.CurrentSelection(2).getText() contains what's
selected,
however.

Is this what always happens or did I do something wrong? I
tried it a few
times only. Do I have to check for this or can I just assume
that if
ThisComponent.CurrentSelection.getCount() > 1 then
ThisComponent.CurrentSelection(0).getText() is always
empty?

Johnny Andersson
Re: Replaceing selected text with Basic Macro
user name
2007-04-17 09:29:50
Am 17.04.2007 11:45 schrieb Johnny Andersson:

> Is this what always happens or did I do something
wrong?

I think no (twice).

I filed a issue:
 http://api.openoffice.org/issues/show_bug.cgi?id=76449



Greetings MRoe
-- 
·-· cut here
·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·->8·-·


------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeapi.openoffice.org
For additional commands, e-mail: dev-helpapi.openoffice.org


Re: Replaceing selected text with Basic Macro
user name
2007-04-17 09:59:09
 I am sorry to bother again. Actually, i made the whole
thing to work
properly now.

However i ran into a new problem:

I modified the macro to make it possible to handle several
selections. The
problem is, that when i restore the selection,
ThisComponent.CurrentController.select(oRange) in your
example, I can only
restore one selection. I have tried for some hours now to
make it possible
to restore a multi-selection, but I failed constantly.

Let's say that I highlight three parts in a text, by
clicking and dragging
while the Ctrl key is held. Then the macro can handle each
one of them,
that's no problem. I get my text replaced and everything is
OK, until the
end of the macro.

So what do I want to happen at the end? Well, I want to
restore the
selections. Not just one of them, ALL of them. Just to make
it possible to
run the same macro again on the same selections.

I use some global variables to "record" what the
macro did last time, and
next time I run it I want it to do something else to the
same text.

Well, if you really want to know, I am trying to make my
own
Uppercase-Lowercase conversion, to use instead of the built
in Change Case
function. I am also doing it to learn about macros.

So I assigned the macro to Shift+F3. My thought is that
first time I hit
Shift+F3, all selected characters are converted to
Uppercase.

Second time the macro is run, it will convert to lowercase
(if the selection
didn't change since last time).

Third time, it will convert to Sentence case (first letter
after ". " (point
+ space) and after ": " will be Uppercase, other
characters won't change).

Fourth time, it's Title Case.

Fifth time it toggles from the ORIGINAL case (which
therefore has to be
remembered the first time the macro runs on a specific
selection/multi
selection).

Sixth time it toggles back again to its original state.

Seventh time is the same as first time and so on.


So, that's why the multi selection needs to stay there after
the macro
finished.

At the moment I just can not figure out (maybe because I am
really stupid)
how to do this. Everything else is working and it works as
long as I don't
do multi selections.

Johnny Andersson
Re: Replaceing selected text with Basic Macro
user name
2007-04-17 17:11:05
Mathias Röllig wrote:
> Am 17.04.2007 11:45 schrieb Johnny Andersson:
>
>   
>> Is this what always happens or did I do something
wrong?
>>     
>
> I think no (twice).
>
> I filed a issue:
>  http://api.openoffice.org/issues/show_bug.cgi?id=76449

>
>
> Greetings MRoe
>   
I replied to the issue, but I would have said that it was
not a bug.
I provided code to demonstrate what is really happening
here. It may be 
a bug, but it has been this way since version 1.0.

-- 
Andrew Pitonyak
My Macro Document: http://www.pi
tonyak.org/AndrewMacro.odt
My Book: http://w
ww.hentzenwerke.com/catalog/oome.htm
Info:  http://www.pitonyak.or
g/oo.php
See Also: http://documentation.openoffice.org/HOW_TO/index.html

------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeapi.openoffice.org
For additional commands, e-mail: dev-helpapi.openoffice.org


Re: Replaceing selected text with Basic Macro
user name
2007-04-17 12:17:06
Johnny Andersson wrote:

> In your example you go for an object directly:
> ThisComponent.CurrentSelection(0).
> In my example I do like this to obtain the same (?)
thing:
> ThisComponent.getCurrentSelection().getByIndex(0)

Simplified explanation: in Basic this is the same. In fact
the first
variant is automatically "translated" into the
second one internally as
the "real" C++ objects only understand that one.

> My thought was something like "since there is a
method, it is probably
> supposed to be used".

That's not like Basic developers want to have it. 
So we added the "syntactic sugar" to our Basic to
meet expectations.

> On the other hand, if ThisComponent.CurrentSelection(0)
is possible to do,
> that object is obviously not private, so I should feel
free to use it.

*Every* object is private in UNO based development. There is
no way to
access any data of a UNO object directly, not in Basic and
not in any
other programming language. "Private" doesn't mean
"not accessible". It
means that you can access the bits of it of directly, only
its
interface. This is the basic building principle of UNO and
there is no
way to circumvent it.

So an object TheObject might contain another object
TheSubObject. In UNO
API it might expose this object by offering the method
getTheSubObject()
or even allow to overwrite this object with another instance
by offering
the method setTheSubObject().

Basic analyses the API of the UNO object at runtime and
every time when
it finds a "getSomething()" method in it it
simulates a "property" type
member of the Basic object representing the UNO object. If
it also finds
a "setSomething()" method it allows to assign an
instance to it
otherwise the "property" is read-only. So in my
example you can write
"TheObject.TheSubObject.doSomething()" if
"TheObject" has this
"getTheSubObject" method and the returned object
has a method "doSomething".

> Which is the "proper" way to do things? Is
the rule that "if a variable or
> an object is private, use their methods, otherwise
manipulate them
> directly"?

As I said, you can't manipulate any UNO object directly,
whatever syntax
you use. You always use its UNO interface, with
"sugar" in Basic or
without in C++ or Java. In Basic you should take the simpler
syntax to
improve the readability of your code but that's a matter of
taste.

Ciao,
Mathias

-- 
Mathias Bauer (mba) - Project Lead OpenOffice.org Writer
OpenOffice.org Engineering at Sun: http://blogs.sun.com/Gu
llFOSS
Please don't reply to "nospamformbagmx.de".
I use it for the OOo lists and only rarely read other mails
sent to it.

------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeapi.openoffice.org
For additional commands, e-mail: dev-helpapi.openoffice.org


[1-8]

about | contact  Other archives ( Real Estate discussion Medical topics )