SageTV Community

SageTV Community (http://forums.sagetv.com/forums/index.php)
-   SageTV Studio (http://forums.sagetv.com/forums/forumdisplay.php?f=34)
-   -   Utility functions to simplify STV import (http://forums.sagetv.com/forums/showthread.php?t=17063)

dflachbart 03-29-2006 02:37 PM

Utility functions to simplify STV import
 
Hi everyone,

I don't know if this is true for everyone, but since I started Studio development and writing my own plugins I soon discovered that certain tasks are always tedious and time consuming. To make my life easier I started to factor out certain functionality into java code which has grown to a java library over time. E.g., I found that a quite common task is to find an existing widget in the current STV which one will link to or modify. If it's a theme or a menu this is still relatively easy by using studio widgets (provided the name is unique), but to find arbitray nodes walking through the tree using widget code is quite cumbersome. A function in the library which takes a path to the widget makes this rather pretty easy:

e.g. to get a reference to the 'TV Details' panel of the OSD menu you can simply write

panel = df_sageutils_Import_findExistingWidget("MediaPlayer OSD/DisplayInfo/DetailedInfo/mf = GetCurrentMediaFile()/IsTVFile(mf)/true/TV Details")


The path parameter consists of the names of all widgets along the path. If there is no ambiguity, you can use wildcards to save typing:

panel = df_sageutils_Import_findExistingWidget("MediaPlayer OSD/Disp*/Detail*/mf =*/IsTV*/true/TV Details")


You can even omit the intermediate path altogether (but not recommended for large subtrees which go into breadth instead of depth) :

panel = df_sageutils_Import_findExistingWidget("MediaPlayer OSD//TV Details")


This function alone saves me a lot of time compared to coding the same with Studio widgets. The library also contains a bunch of other useful functions like automatic linking of imported widgets (e.g. themes) to existing ones, a tree deletion routine which can handle loops and does not leave any orphaned nodes behind, or simple one-line calls to retrieve existing/imported menus, hooks, and themes by name.


Just wanted to throw this out here in case anyone would be interested to use it. I haven't written any documentation yet, but I could generate some javadoc if there is demand for that.

Dirk

BobPhoenix 03-29-2006 03:37 PM

Sound real good to me. I had to walk down 8 levels in my plugin for SageMC because that was the only unique widget available and I needed to apply a change there.

BobP.

dflachbart 04-01-2006 09:11 PM

Well, if someone is interested, I uploaded the library including javadoc and template STVi to the Download section.

Dirk

BobPhoenix 04-01-2006 10:18 PM

Thank you will try this out in a few days.

BobP.

BobPhoenix 06-18-2006 02:48 PM

OK have one question for you on this.

How does deleteWidgetTree handle code in other menus that the imported menu may be linked too? In otherwords does it stop the deletion when it gets to the link or should we unlink this prior to calling your deleteWidgetTree routine?

BobP.

dflachbart 06-18-2006 03:30 PM

Quote:

Originally Posted by BobPhoenix
OK have one question for you on this.

How does deleteWidgetTree handle code in other menus that the imported menu may be linked too? In otherwords does it stop the deletion when it gets to the link or should we unlink this prior to calling your deleteWidgetTree routine?

BobP.

Hi Bob,

as long as you link your code to existing widgets by using the df_sageutils_Import_defineLink() method, this get's handled automatically, you don't have to perform any manual unlinking prior to deleting trees. When the deleteWidgetTree() method encounters a link to existing code, it will stop deletion at this point and simply unlink the widget.

Feel free to post any other questions you might have.

Dirk

alon24 06-19-2006 12:14 AM

Sounds great, I will try it today! :)

BobPhoenix 06-19-2006 09:32 PM

Quote:

Originally Posted by flachbar
Hi Bob,

as long as you link your code to existing widgets by using the df_sageutils_Import_defineLink() method, this get's handled automatically, you don't have to perform any manual unlinking prior to deleting trees. When the deleteWidgetTree() method encounters a link to existing code, it will stop deletion at this point and simply unlink the widget.

Feel free to post any other questions you might have.

Dirk

OK still not understanding so will give a more complete example below. I have a menu that I added to the STV that I want to delete for an update. I wont be updating the internal code because it is easier just to import a new version delete the old version. My problem is with deleting the existing menu because it links to other code that I do not want to delete.
Code:

ResultsTable (table widget)
+-Airing (table component widget)
  +-Untitled (item widget)
      +-Right (listener widget)
      +-Info (listener widget)
      +-MouseClick (listener widget)
      +-"REM Selected item, so show options for it" (linked action widget don't want to delete this)

What will happen if I call deleteWidgetTree on a menu with this code snippet in it. Will it stop at the "REM..." or will it continue on. How would you handle a situation like this where you want everything deleted in the menu but you just want some of them unlinked rather than deleted. I can see how I would link the new code to this with df_sageutils_Import_defineLink() but what about the existing code from a prior import.

Sorry still a little confused.

BobP.

dflachbart 06-20-2006 07:48 AM

Hi Bob,

Quote:

Originally Posted by BobPhoenix
What will happen if I call deleteWidgetTree on a menu with this code snippet in it. Will it stop at the "REM..." or will it continue on. How would you handle a situation like this where you want everything deleted in the menu but you just want some of them unlinked rather than deleted. I can see how I would link the new code to this with df_sageutils_Import_defineLink() but what about the existing code from a prior import.

Ahh ok, now I see what you mean. Let's look at this that way:

If you had used my library from the beginning, you would have coded it like this:

Code:

My Menu
+...
+-ResultsTable (table widget)
  +-Airing (table component widget)
    +-Untitled (item widget)
        +-Right (listener widget)
        +-Info (listener widget)
        +-MouseClick (listener widget)
        +-LinkToREMSelectedItem  <- dummy widget
       
df_sageutils_Import_defineLink("LinkToREMSelectedItem", PATH_TO_EXISTING_REM_WIDGET)

// delete old existing version
myMenu = df_sageutils_Import_getExistingMenu("My Menu")
df_sageutils_Import_deleteWidgetTree(myMenu)

Now - when you call deleteWidgetTree(myMenu) in your update code to delete the old version, the deletion code automatically knows (because you have called 'defineLink()' before) that the REM widget is part of other code that you have linked to, and will *not* continue deletion, but instead unlink the widget, before continuing the deletion on your New Menu.

The nice thing is that this will also work for the existing code of your plugin that is currently out there. Since you have marked the widget located at PATH_TO_EXISTING_REM_WIDGET as a linked widget (by having called 'defineLink()' before), the deletion code will unlink instead of deleting it.

So the point is that 'defineLink()' serves two purposes:

1) to locate both widgets and perform the actual linking for you
2) to mark the widget the path points to as "linked code", which will not be touched by deleteWidgetTree()


If you cant use this automatic mechanism for any reason, you can always unlink any widgets manually before deleting the tree (which is equivalent):

Code:

myWidget = df_sageutils_Import_getExistingWidget("New Menu/.../ResultsTable*/Airing*/Untitled*")
linkedWidget = df_sageutils_Import_getExistingWidget(PATH_TO_EXISTING_REM_WIDGET)
RemoveWidgetChild(myWidget, linkedWidget)

myMenu = df_sageutils_Import_getExistingMenu(My Menu")
df_sageutils_Import_deleteWidgetTree(myMenu)

You see that using defineLink() will do a lot of the work for you ...


Hope this is a little bit more clear now (I know I'm not that great at explaining things), but dont hesitate to ask more questions if you need to. Also have a look at any of my other plugins as an example for the update/deletion code.

Dirk

BobPhoenix 06-20-2006 01:35 PM

That's what I thought. And the code I was thinking of is actually code in the STV by default so no possiblity that it was used before. I just used the example above because it was the easiest one I could find. You explained it fine I just needed to define it better. Still think this will work out better just need to code the unlink points and unlink them manually before I delete a tree.

Thanks.
BobP.

alon24 06-20-2006 02:16 PM

I would add 2 functions:
1. find the location of a widget within a specific parent.
so that if I have:
parent->
child1
child2

and i want to know where to link my code (after child2) and I found child2 and know its the widget, so something like getLocationInParent(widget, parent)

2. a simple debug loop to print the children of a widget:
printChildren(widget), for making sure we select the correct widget (debugging mainly)

alon24 06-20-2006 03:09 PM

Another Idea releated to the ones from before.
1. What about Link at position
2. What about Link After, so that I tell it to link after a widget on its parent
Parent->
widget1
widget2
widget3

LinkAfter (parent, widget2, newWidget)
so now we have
Parent->
widget1
widget2
newWidget
widget3

Edit:
why not LinkAfter ("parentName", widget2, newWidget)

no need to find both the parent widget and the child if u know the child and the parent name.

why not also have findParentByName("parentName", childWidget)

It seems like I am adding a big grocery list here.

Sorry about that.

dflachbart 06-21-2006 10:24 AM

Quote:

Originally Posted by alon24
I would add 2 functions:
1. find the location of a widget within a specific parent.
so that if I have:
parent->
child1
child2

and i want to know where to link my code (after child2) and I found child2 and know its the widget, so something like getLocationInParent(widget, parent)

So this method should return the index of the child ?


Quote:

Originally Posted by alon24
2. a simple debug loop to print the children of a widget:
printChildren(widget), for making sure we select the correct widget (debugging mainly)

Good idea, certainly possible ..


Dirk

alon24 06-21-2006 02:01 PM

Quote:

So this method should return the index of the child ?
Yes sure.
This is a prelude to the next suggestion, which is linkAfter and LinkAfter+delta.

Also another idea is:

findParent(widget,"String parent name, or path starting from widget and going up)

parent1
--subParent1
-----widget1
parent2
--parent3
----subParent2
-------widget1

if I want to find parent3 all I have to do is:
parent=findParent(widget1,"parent3/subParent2")

because the path is from the widget and up)

These are just some examples, and I think It would make an incredible toolkit, because there is a lot of ideas that run through my head, and this is only my first STVI... :)

koelec 06-23-2006 05:09 AM

great helper code
 
Quote:

Originally Posted by flachbar
Well, if someone is interested, I uploaded the library including javadoc and template STVi to the Download section.

Dirk

Thanks Dirk,
This is exactly what I need. I was having problems with updating the web radio plugin, removing old widget chains and also enabling reimporting the same version. I coudn't get it working correctly.
This code really makes creating STVi's easier.

thanks again, :clap:
- Chris

dflachbart 06-23-2006 06:39 AM

Quote:

Originally Posted by koelec
Thanks Dirk,
This is exactly what I need. I was having problems with updating the web radio plugin, removing old widget chains and also enabling reimporting the same version. I coudn't get it working correctly.
This code really makes creating STVi's easier.

thanks again, :clap:
- Chris

Hi Chris,

nice to see that this is useful for someone else.

Especially when it helps further development of the webradio plugin, which is absolutely great, and one of my favorite plugins. :dance:
I wanna thank you for that...


Dirk

koelec 06-23-2006 11:04 AM

Quote:

Originally Posted by flachbar
Hi Chris,

nice to see that this is useful for someone else.

Especially when it helps further development of the webradio plugin, which is absolutely great, and one of my favorite plugins. :dance:
I wanna thank you for that...


Dirk

Dirk,
the linkWidget method seems to stop after the first found placeholder. Is it true that when I have multiple Widget references to the same existing widget, I have to create a separate define link for each one of them?
thanks,
-Chris

dflachbart 06-23-2006 11:15 AM

Quote:

Originally Posted by koelec
Dirk,
the linkWidget method seems to stop after the first found placeholder. Is it true that when I have multiple Widget references to the same existing widget, I have to create a separate define link for each one of them?
thanks,
-Chris

Hi Chris,

well you just discovered a bug, I checked the code and it does indeed only link one widget. I will try to fix this asap, for now as a workaround you can define separate links for each dummy widget (but name them differently, e.g. LinkToMainMenuTheme1, LinkToMainMenuTheme2, etc)

Thanks for the QA, ;)

Dirk

dflachbart 06-24-2006 11:41 AM

Quote:

Originally Posted by koelec
Dirk,
the linkWidget method seems to stop after the first found placeholder. Is it true that when I have multiple Widget references to the same existing widget, I have to create a separate define link for each one of them?
thanks,
-Chris

Chris,

support for this has been added in v1.3

Dirk

dflachbart 06-24-2006 11:41 AM

I uploaded version 1.3, download it here

Changes in v1.3:

- defineLink() can now handle multiple widgets with the same name
- added the following utility functions:

void print(Object widget):
prints the widget name and type to the debug log

void printChildren(Object parent):
prints the all children to the debug log

void printParents(Object child):
prints the all parents to the debug log

int getPositionInParent(Object parent, Object child):
returns the index of a child widget within its parent

void linkChild(Object parent, Object child):
links a widget to another (equivalent to 'AddWidgetChild()', for sake of completeness)

void linkChildAtPosition(Object parent, Object child, int pos):
links a widget to another at a certain position (equivalent to 'InsertWidgetChild()', for sake of completeness)

void linkChildBefore(String parentName, Object newChild, Object existingChild):
links a widget to another at the position before a specific existing child widget

void linkChildAfter(String parentName, Object newChild, Object existingChild):
links a widget to another at the position after a specific existing child widget


Note that the new 'link' functions are for general purpose linking, they do not affect the automatic linking performed by 'defineLink()', and thus will not automatically get unlinked on 'deleteWidgetTree()'

Dirk

koelec 06-25-2006 03:05 AM

Quote:

Originally Posted by flachbar
Chris,

support for this has been added in v1.3

Dirk

Hi Dirk,
Using v1.3. Works great ! :clap:
thanks,
Chris

BobPhoenix 06-25-2006 01:44 PM

I'm making an assumption that I hope is true with these utility functions. For Listener widgets it uses either the Widget Name or the ListenerEvent property when using findWidget, findExistingWidget or findImportedWidget. The reason I ask is that while some Listeners have both not all do. I have found some with just the property and some with just a name so you can't even count on the ListenerEvent property always being present. For example the Left command in the ARAdjustZoom menu in the default STV has the name Left but the ListenerEvent is blank. So is my assumption valid?

Thanks.
BobP.

dflachbart 06-25-2006 03:12 PM

Quote:

Originally Posted by BobPhoenix
I'm making an assumption that I hope is true with these utility functions. For Listener widgets it uses either the Widget Name or the ListenerEvent property when using findWidget, findExistingWidget or findImportedWidget. The reason I ask is that while some Listeners have both not all do. I have found some with just the property and some with just a name so you can't even count on the ListenerEvent property always being present. For example the Left command in the ARAdjustZoom menu in the default STV has the name Left but the ListenerEvent is blank. So is my assumption valid?

Thanks.
BobP.

Hi Bob,

yes your assumption is correct :)

GetWidgetName() (which is used by the implementation of all find...() methods) first looks at the name, and if this is empty, returns the ListenerEvent property.

Dirk

BobPhoenix 06-28-2006 07:14 PM

1 Attachment(s)
Possible bug but maybe it's just me.

Code first:
Code:

existing code from previous import:
Main Menu
+-BeforeMenuLoad
  +-"REM FCL Main Menu code"

Code in the import to remove the prior code (that works):
+-"REM unlink Main Menu menu code"
    +-LinkLocation=df_sageutils_Import_findExistingWidget("Main Menu/BeforeMenuLoad")
      +-widget=df_sageutils_Import_findExistingWidget("Main Menu/BeforeMenuLoad/\"REM FCL Main Menu code*")
          +-If widget != null



Code in the import to remove the same as above (that doesn't work - this is include in ZIP):
+-"REM unlink Main Menu menu code"
    +-LinkLocation=df_sageutils_Import_findExistingWidget("Main Menu/BeforeMenuLoad")
      +-widget=df_sageutils_Import_findWidget(LinkLocation, "\"REM FCL Main Menu code*")
          +-If widget != null

Obviously I can make this work by just using findExistingWidget and I'm converting my code now but if you can reproduce this and it really is a bug I thought you would like to know about it.

Now for the problem:
The problem is that I get a Java error - sorry it's as a graphic (in zip) - too much to write. Also included is my log file from SageTV and the import itself. All in the same Zip file. The code has no problem on the first import. NO Java error. But when I re-import I get the included error.

Edit: Opps forgot SageMC 6.6 and 1.3 of this import utility.

Thanks.
BobP.

dflachbart 06-28-2006 08:20 PM

Quote:

Originally Posted by BobPhoenix
Possible bug but maybe it's just me.

Hi Bob,

my Internet connection was down all evening, but I'll have a look at it tomorrow. Thanks for the detailed description.

Dirk

BobPhoenix 06-28-2006 08:24 PM

Quote:

Originally Posted by flachbar
Hi Bob,

my Internet connection was down all evening, but I'll have a look at it tomorrow. Thanks for the detailed description.

Dirk

No rush. I'm just coding around what may just be my problem anyway.

BobP.

BobPhoenix 06-28-2006 09:53 PM

I think I have a clue now as to why it didn't work for me. I have multiple links to widgets that existed in the STV before the first import. I unlinked them and reestablished the original links in an attempt to return it to what the STV was like before the first import. However I still have some left over links from the code in "Imported Nodes" to those objects. I then proceed to try to import new code and link it up and in the process it executes the code you had in the template for removing the old hook. I'm thinking my problem is that I need to unlink all widgets from those that I linked back into the STV and this problem might go away. I'm going to test this theory out tomorrow night when I get home from work - too late to start now.

If you do look at this maybe you will see what I did wrong if you get to it tomorrow. Also if you need anything else let me know but I really think it is just me and I'm just not using your routines correctly.

Thanks.
BobP.

PS I'm taking a CBT on Java but other than what I've seen so far and in Studio it's still a foreign language. If it was COBOL I would be better off since that is what I do all day.

BobPhoenix 06-29-2006 09:19 AM

One last note on this. I did get all of my findWidget's converted to findExistingWidget's and that got rid of the Java errors but it still won't import correctly it actually destroy's the main menu - as in it is broken apart into multiple root level entries. As far as I can tell it should re-import correctly so anything you can suggest would be great.

Thanks.
BobP.

dflachbart 06-29-2006 09:22 AM

Quote:

Originally Posted by BobPhoenix
One last note on this. I did get all of my findWidget's converted to findExistingWidget's and that got rid of the Java errors but it still won't import correctly it actually destroy's the main menu - as in it is broken apart into multiple root level entries. As far as I can tell it should re-import correctly so anything you can suggest would be great.

Thanks.
BobP.

Bob, got my emails I sent this morning ?

dflachbart 06-29-2006 10:17 AM

Quote:

Originally Posted by BobPhoenix
One last note on this. I did get all of my findWidget's converted to findExistingWidget's and that got rid of the Java errors but it still won't import correctly it actually destroy's the main menu - as in it is broken apart into multiple root level entries. As far as I can tell it should re-import correctly so anything you can suggest would be great.

Thanks.
BobP.

Hi Bob,

I think I found the problem in your code: you are deleting your old existing menu before calling the defineLink() methods, this way deleteWidgetTree() does not know about your linked widgets and will not stop deletion on widgets of the original STV you linked to ...

After changing the order of defineLink() in your import I noticed the next issue: the defineLink() does not work for some widgets when re-importing, because the original target widget has been replaced with a different one:

e.g. the defineLink("LinkToSetFocusForVariable", "Guide/MenuNeeds*/*/Ensure*/Has*/SetFocusForVariable*") works fine on the first import, but the import code replaces the SetFocusForVariable widget with "REM FCL Guide MenuNeedsDefaultFocus hook code", so that when the plugin is reimported again the defineLink() can't find the widget any more, and the automatic linking fails ... If you modify the link targets in such a way, you will either have to restore the original state before defining the links, or use manual linking for those widgets

Dirk

BobPhoenix 06-29-2006 11:29 AM

Quote:

Originally Posted by flachbar
Bob, got my emails I sent this morning ?

Nope. I assume you repeated them in the other post. Figured I was misunderstanding how to use it. Thanks for looking at this. Now I know how to proceed.

BobP.

aperry 07-09-2006 12:29 AM

So, using this import/Java routines, I could link to the CenteredDirectoryBrower OptionsMenu widget in the main SageTV STV? Assuming that the answer is yes, then how do I know which one to link to?

Currently, the "main" copy of it is in:
Configuration Wizard - Set Video Recording Dirs/MenuContainer/MenuItems/Add New Directory/... a few more levels .../CenteredDirectoryBrower

There are references to it in four other places, like:
StorageDeviceAdded/if false/... more levels .../CenteredDirectoryBrower

So, if I understand the JavaDoc correctly, could I just do something like this to link in CenteredDirectoryBrower from the main SageTV STV?
df_sageutils_Import_defineLink("MTDirectoryBrowser", "//CenteredDirectoryBrower")

The reason I ask is that the one that Sage considers to be the "main" one does not remain static, at any given time, it could be any of the five occurrences.

----------

Once I get that done, what do I put into my import to call the main CenteredDirectoryBrower OptionsMenu?

dflachbart 07-09-2006 08:01 AM

Quote:

Originally Posted by aperry
Currently, the "main" copy of it is in:
Configuration Wizard - Set Video Recording Dirs/MenuContainer/MenuItems/Add New Directory/... a few more levels .../CenteredDirectoryBrower

There are references to it in four other places, like:
StorageDeviceAdded/if false/... more levels .../CenteredDirectoryBrower

The reason I ask is that the one that Sage considers to be the "main" one does not remain static, at any given time, it could be any of the five occurrences.

Hi aperry,

the answer is: it doesn't matter to which occurence you link to, they are actually all the same widget... The concept of "primary reference'" (bold) and "secondary reference" (italic) is just a display thing inside of Studio.

Quote:

Originally Posted by aperry
So, if I understand the JavaDoc correctly, could I just do something like this to link in CenteredDirectoryBrower from the main SageTV STV?
df_sageutils_Import_defineLink("MTDirectoryBrowser", "//CenteredDirectoryBrower")

"//" can't be used at the beginning of a path expression. But more importantly: my advice is to not use the "//" shortcut for any paths into the STV, since it has to follow all possible paths between the widgets, and since everything is interlinked in the STV this will visit a huge amount of nodes and take very long ...

Instead, to save typing, use the "*" wildcard in path expressions: for widgets with only one child, you can just use the "*" :

Code:

w1
+-w2
    +-w3
        +w4

w1/*/*/w4



For widgets with multiple children use as much of the widget name as is necessary to distinguish it from the other children:

Code:

w1
+-w2Listener
    +-w3Action
        +w4
    +-w3Item
+-w2Hook

w1/w2L*/w3A*/w4

So just pick the shortest path to the CenteredDirectoryBrowser and use this path in the defineLink() call ...


Quote:

Originally Posted by aperry

Once I get that done, what do I put into my import to call the main CenteredDirectoryBrower OptionsMenu?

Not quite sure, what do you mean by "call the OptionsMenu" ?


Dirk

aperry 07-09-2006 12:32 PM

Quote:

Originally Posted by flachbar
Not quite sure, what do you mean by "call the OptionsMenu" ?

What I mean is that assuming I put in something like:

df_sageutils_Import_defineLink("MTDirectoryBrowser", "/path/CenteredDirectoryBrower")

Inside my import, do I then just create an options menu item called "MTDirectoryBrowser"? If not, what do I put in my import so that once it gets imported, the CenteredDirectoryBrower gets called the way I would expect?

Thanks!

alon24 07-09-2006 01:38 PM

Hi,
I wrote this in a seperate post, but no one answered, maybe you can help, since you already did thiss with DeleteWidgetTree.

I am trying to do some cleanup after I broke some child parent relationship, and clean house.
I am trying to do RemoveWidget but it fails with the following error:

Code:

private static void removeLeftOvers()
        throws InvocationTargetException
    {
        ArrayList lst = new ArrayList();
//        Object[] widgets =(Object[]) SageApi.Api("GetAllWidgets");
//        int size = SageApi.IntApi("Size", new Object[]{widgets});
//        log("all widgets = " +widgets+", " + size);
//        log("children size = " + size);
        List imported = Arrays.asList((Object[])_importedWidgets);
        for (Iterator iter = imported.iterator(); iter.hasNext();)
        {
            Object widget = (Object) iter.next();
            Object[] parents =(Object[]) SageApi.Api("GetWidgetParents", new Object[]{widget});
//            log("checking " + widget);
            if (parents.length>0)
                continue;
 
            ImportAction act = isImportActionsWidgets(widget);
            if (act != null)
            {
                lst.add(widget);
                log("found to delete " + widget);
            }
        }
 
        for (Iterator iter = lst.iterator(); iter.hasNext();)
        {
            Object widget = (Object) iter.next();
            log("the widget to del = " + widget);
            SageApi.Api("RemoveWidget", new Object[]{widget});//line 109
        }
    }

Code:


found to delete TimerExport:null|Action:linkme to Menu, Main Menu
Sun 7/9 13:18:02.580 the widget to del = TimerExport:null|Action:linkme to Menu, Main Menu
java.lang.NullPointerException
Sun 7/9 13:18:02.581  at sage.c.l$6.new(Unknown Source)
Sun 7/9 13:18:02.582  at sage.at.a(Unknown Source)
Sun 7/9 13:18:02.582  at sage.d.a(Unknown Source)
Sun 7/9 13:18:02.583  at sage.SageTV.api(Unknown Source)
Sun 7/9 13:18:02.584  at net.sf.sageplugins.sageutils.SageApi.Api(SageApi.java:17)
Sun 7/9 13:18:02.585  at alon24.Utils.removeLeftOvers(Utils.java:109)
Sun 7/9 13:18:02.585  at alon24.Utils.finish(Utils.java:74)
Sun 7/9 13:18:02.586  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Sun 7/9 13:18:02.586  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
Sun 7/9 13:18:02.586  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
Sun 7/9 13:18:02.587  at java.lang.reflect.Method.invoke(Unknown Source)
Sun 7/9 13:18:02.587  at sage.d$d.a(Unknown Source)
Sun 7/9 13:18:02.588  at sage.d.d.a(Unknown Source)
Sun 7/9 13:18:02.588  at sage.d.c.a(Unknown Source)
Sun 7/9 13:18:02.588  at sage.d.d.a(Unknown Source)
Sun 7/9 13:18:02.589  at sage.d.m.a(Unknown Source)
Sun 7/9 13:18:02.589  at sage.d.a(Unknown Source)
Sun 7/9 13:18:02.589  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.590  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.590  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.591  at sage.d.a(Unknown Source)
Sun 7/9 13:18:02.591  at tv.sage.b.k.a(Unknown Source)
Sun 7/9 13:18:02.591  at tv.sage.c.a(Unknown Source)
Sun 7/9 13:18:02.592  at sage.StudioFrame.actionPerformed(Unknown Source)
Sun 7/9 13:18:02.592  at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
Sun 7/9 13:18:02.593  at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
Sun 7/9 13:18:02.593  at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
Sun 7/9 13:18:02.594  at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
Sun 7/9 13:18:02.594  at javax.swing.AbstractButton.doClick(Unknown Source)
Sun 7/9 13:18:02.595  at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
Sun 7/9 13:18:02.595  at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
Sun 7/9 13:18:02.596  at java.awt.Component.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.596  at javax.swing.JComponent.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.597  at java.awt.Component.processEvent(Unknown Source)
Sun 7/9 13:18:02.598  at java.awt.Container.processEvent(Unknown Source)
Sun 7/9 13:18:02.599  at java.awt.Component.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.599  at java.awt.Container.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.600  at java.awt.Component.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.602  at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
Sun 7/9 13:18:02.603  at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.604  at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.605  at java.awt.Container.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.606  at java.awt.Window.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.607  at java.awt.Component.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.608  at java.awt.EventQueue.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.609  at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
Sun 7/9 13:18:02.610  at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
Sun 7/9 13:18:02.611  at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
Sun 7/9 13:18:02.612  at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
Sun 7/9 13:18:02.612  at java.awt.EventDispatchThread.run(Unknown Source)
java.lang.reflect.InvocationTargetException
Sun 7/9 13:18:02.616  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Sun 7/9 13:18:02.616  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
Sun 7/9 13:18:02.617  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
Sun 7/9 13:18:02.617  at java.lang.reflect.Method.invoke(Unknown Source)
Sun 7/9 13:18:02.618  at sage.d$d.a(Unknown Source)
Sun 7/9 13:18:02.618  at sage.d.d.a(Unknown Source)
Sun 7/9 13:18:02.618  at sage.d.c.a(Unknown Source)
Sun 7/9 13:18:02.619  at sage.d.d.a(Unknown Source)
Sun 7/9 13:18:02.619  at sage.d.m.a(Unknown Source)
Sun 7/9 13:18:02.620  at sage.d.a(Unknown Source)
Sun 7/9 13:18:02.620  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.621  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.621  at sage.a6.a(Unknown Source)
Sun 7/9 13:18:02.621  at sage.d.a(Unknown Source)
Sun 7/9 13:18:02.622  at tv.sage.b.k.a(Unknown Source)
Sun 7/9 13:18:02.622  at tv.sage.c.a(Unknown Source)
Sun 7/9 13:18:02.622  at sage.StudioFrame.actionPerformed(Unknown Source)
Sun 7/9 13:18:02.623  at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
Sun 7/9 13:18:02.623  at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
Sun 7/9 13:18:02.624  at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
Sun 7/9 13:18:02.624  at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
Sun 7/9 13:18:02.625  at javax.swing.AbstractButton.doClick(Unknown Source)
Sun 7/9 13:18:02.625  at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
Sun 7/9 13:18:02.625  at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
Sun 7/9 13:18:02.626  at java.awt.Component.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.626  at javax.swing.JComponent.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.627  at java.awt.Component.processEvent(Unknown Source)
Sun 7/9 13:18:02.627  at java.awt.Container.processEvent(Unknown Source)
Sun 7/9 13:18:02.627  at java.awt.Component.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.628  at java.awt.Container.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.628  at java.awt.Component.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.628  at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
Sun 7/9 13:18:02.629  at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
Sun 7/9 13:18:02.629  at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.630  at java.awt.Container.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.630  at java.awt.Window.dispatchEventImpl(Unknown Source)
Sun 7/9 13:18:02.630  at java.awt.Component.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.631  at java.awt.EventQueue.dispatchEvent(Unknown Source)
Sun 7/9 13:18:02.631  at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
Sun 7/9 13:18:02.631  at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
Sun 7/9 13:18:02.632  at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
Sun 7/9 13:18:02.632  at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
Sun 7/9 13:18:02.633  at java.awt.EventDispatchThread.run(Unknown Source)
Sun 7/9 13:18:02.634 Caused by: java.lang.reflect.InvocationTargetException: Exception while executing SageApi: "RemoveWidget" numargs=1
Sun 7/9 13:18:02.634  at net.sf.sageplugins.sageutils.SageApi.Api(SageApi.java:20)
Sun 7/9 13:18:02.635  at alon24.Utils.removeLeftOvers(Utils.java:109)
Sun 7/9 13:18:02.635  at alon24.Utils.finish(Utils.java:74)
Sun 7/9 13:18:02.636  ... 43 more
Sun 7/9 13:18:02.636


Do you have any ideas?
I need to do cleanup, I could also not break the parent but it wont delete it there either.

nielm 07-09-2006 01:47 PM

Quote:

Originally Posted by aperry
If not, what do I put in my import so that once it gets imported, the CenteredDirectoryBrower gets called the way I would expect?

In your import, make the item and the action tree as normal, including setting up the variables required for the browser but add a text action as a placeholder:
"REM CenteredDirectoryBrowser to me", then in the actions after this one you can use the result of the browser...

In the import code, link the CenteredDirectoryBrowser to the imported text action

nielm 07-09-2006 01:49 PM

Quote:

Originally Posted by alon24
Hi,
I wrote this in a seperate post, but no one answered, maybe you can help, since you already did thiss with DeleteWidgetTree.

I am trying to do some cleanup after I broke some child parent relationship, and clean house.
I am trying to do RemoveWidget but it fails with the following error:
...
Do you have any ideas?

I am not sure but I think you need to call the Api with a UI context when you perform widget AP calls...

alon24 07-09-2006 02:33 PM

Thanks Nielm, that did the trick.

Where can I find out the rules about the different context, and when to use them?

dflachbart 07-09-2006 05:14 PM

Quote:

Originally Posted by aperry
What I mean is that assuming I put in something like:

df_sageutils_Import_defineLink("MTDirectoryBrowser", "/path/CenteredDirectoryBrower")

Inside my import, do I then just create an options menu item called "MTDirectoryBrowser"? If not, what do I put in my import so that once it gets imported, the CenteredDirectoryBrower gets called the way I would expect?

Thanks!

Hi aperry,

you just have to create a dummy widget (type doesn't matter) with the name "MTDirectoryBrowser" at exactly the place where you want the "CenteredDirectoryBrower' widget to appear. As Niel said, you first have to set up the variables used by the browser. It would look like:

Code:

+- AddVideoDir = ...
  +- DirBrowseTitle = ...
      +- CurrentDirPath = ...
        +- UseLocalDirPaths = ...
            +- SelectedDirPath = null
              +- MTDirectoryBrowser  <- dummy widget (any type, with name used in defineLink())
              +- if SelectedDirPath != null
                  +-  do something

Don't forget to call df_sageutils_Import_linkWidgets() at some point in your import code.

Important: I discovered that linkWidgets() did not maintain the position of the link within the parent. Since the above code will not work if the position is not maintained, please download the current version 1.5 of the import library where this issue has been fixed.

Dirk

aperry 07-09-2006 09:20 PM

You had previously mentioned to avoid using the // notation. However, can't it get used with little to no impact once you get into a structure like this:

Code:

-Menu
 +Thing1
 -Thing2
  -Thing21
  -Thing211
    -Thing2111
    -ThingIWant

In other words, if I put in "Menu/Thing2//ThingIWant", that in theory shouldn't be any slower than if I spelled it out, correct? As I understand it, there is only one path to get to "ThingIWant" once I get to "Thing2" in the path, right?

This would be especially useful in a situation like what I have where there are 4 or 5 variables set before calling the CenteredDirectoryBrower, so if I could skip most of those variable setups for specifying my destination widget path, that would make it easier for me.


All times are GMT -6. The time now is 05:22 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.