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 07-09-2006 10:19 PM

Quote:

Originally Posted by aperry
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?

Yes, in this case using the "//" notation would have no noticeable impact, for straight widget chains without branches this shortcut can be safely used.

Just bear in mind that if you need to code a test whether a specific widget is there or not the "//" should still be avoided, since if 'ThingIWant' is not there the search will continue until all possible paths are exhausted. For such a test use "Menu/Thing2/*/*/*/ThingIWant" instead, because it will definetly not go past the point where ThingIWant is expected to be.

Dirk

toricred 07-27-2006 08:14 PM

OK, I need some help using your utilities. I'm trying to create my first import and I can't get the linking to work right. Here's my code for the Imported hook. What am I doing wrong?

STVImported
-"Imported on ..."
-ImportName = "Brian's OSD Clock"
-Version = "1.0"
-"Import code"
-"REM (1) set the ImportName"
-"REM (2) define any widget links after the init() call"
-"REM (3) if you defined any links, call linkWidgets()"
-"REM (4) add any additional import code"
-DebugLog("========== Importing " + ImportName + " ==========")
-df_sageutils_Import_init("MC MediaPlayer OSD", "Main Menu")
-df_sageutils_Import_defineLink("ClockDisplay", "MC MediaPlayer OSD")
-df_sageutils_Import_linkWidgets()
-"### plugin code ###"
-"Remove ghost Main Menu"
-"Remove old import hook"
-"Modify and clean up imported hook"
-df_sageutils_Import_finished()
-SageCommand("Home")

toricred 07-28-2006 08:51 AM

Never mind. I looked at the Excluder import and found my problems. It's working now.

dflachbart 07-28-2006 10:35 AM

Quote:

Originally Posted by toricred
Never mind. I looked at the Excluder import and found my problems. It's working now.

Cool, glad to hear you got it working ... :)


Dirk

toricred 07-28-2006 07:26 PM

Maybe I spoke too soon. I got the panel I want to add in MC MediaPlayer OSD, but I can't get it to add my code to the AfterMenuLoad hook of MC MediaPlayer OSD.

The code for just this piece looks like:

pluginNode = df_sageutils_Import_findImportedWidget("STVImported/\"Imported nodes\"/false/\"REM After*")
hook = df_sageutils_Import_getExistingHook("MC MediaPlayer OSD/AfterM*")
excluderCode = df_sageutils_Import_findWidget(hook, "\"REM AfterMenuLoad addition\"" )
AddWidgetChild(hook,pluginNode)

dflachbart 07-28-2006 08:05 PM

Quote:

Originally Posted by toricred
Code:

hook = df_sageutils_Import_getExistingHook("MC MediaPlayer OSD/AfterM*")

The getExistingHook() method does not take a path as its argument, only a name (and since there is more than one hook with the name "AfterMenuLoad" in the STV you can 't use it).

Use

Code:

hook = df_sageutils_Import_findExistingWidget("MC MediaPlayer OSD/AfterMenuLoad")
instead ...

Dirk

toricred 07-28-2006 08:18 PM

Perfect. Thank you so much for this help. Now to add the options to the menu and I'll be done. I'd been struggling with this for so long until I found your utilities.

BobPhoenix 08-16-2006 04:33 PM

The change you sent me for my FCL plugin to SageMC was the only one I need I think but this exposes a possible bug in this import code. Apparently when linkWidgets is called it stops at the first defineLink that had a problem even if later ones would link correctly. Is there anything you can do to allow the linking to continue past the bad defineLink call? I don't know if it is the defineLinks that stop working or if it is linkWidgets that stops but if you can get your code to just bypass a bad defineLink and continue on I would appreciate it.

BobP.

dflachbart 08-16-2006 04:48 PM

Quote:

Originally Posted by BobPhoenix
The change you sent me for my FCL plugin to SageMC was the only one I need I think but this exposes a possible bug in this import code. Apparently when linkWidgets is called it stops at the first defineLink that had a problem even if later ones would link correctly. Is there anything you can do to allow the linking to continue past the bad defineLink call? I don't know if it is the defineLinks that stop working or if it is linkWidgets that stops but if you can get your code to just bypass a bad defineLink and continue on I would appreciate it.

BobP.

Hi Bob,

this was originally done 'by design' because I assumed that even if just one link fails then the whole import will most likely not work anyway. But I am currently re-coding the 'defineLink" (to perform the link immediately, so no 'linkWidgets()' at the end necessary any more), and based on your suggestion I will let it return a boolean to indicate success/failure instead of throwing an exception, so that the import code can decide what to do ...

Dirk

BobPhoenix 08-16-2006 05:23 PM

Quote:

Originally Posted by flachbar
Hi Bob,

this was originally done 'by design' because I assumed that even if just one link fails then the whole import will most likely not work anyway. But I am currently re-coding the 'defineLink" (to perform the link immediately, so no 'linkWidgets()' at the end necessary any more), and based on your suggestion I will let it return a boolean to indicate success/failure instead of throwing an exception, so that the import code can decide what to do ...

Dirk

Perfect idea! Like the immediate linking as well! Thank you.

BobP.

dflachbart 08-17-2006 01:55 PM

New version 1.7 available
 
Version 1.7 is now available.

Changes:

- added Object[] getSiblings(Object widget) method
- defineLink() will now perfom the link action immediately, and return a result (success/failure) instead of throwing an exception.

This means that it is not necessary to call linkWidgets() any more. To reflect the changed semantics of the linking procedure, the method is now called "link(placeholder, path)" instead of "defineLink(placeholder, path)". But the change/renaming does not affect your existing code in any way, both old methods are still available (linkWidgets() is a no-op, and defineLink() simply calls link()).

And now to the really good stuff :): what's one of the most tedious tasks when writing an import ? To detemine the path of widgets to link to ... Now in version 1.7 you can let the library automatically generate the widget path for you, interactively in Studio:
  • load the STV in Studio
  • find the widget for which you want to determine the path
  • create a new child for this widget, this can be a menu, a hook, or a theme. Which one of those types does not matter, just choose whatever is allowed by Studio as a child widget
  • rename this child widget to "X" (or any other name which is not used for any other STV widget)
  • select the "Expression Evaluator..." in the Studio menu and enter df_sageutils_Import_getPath("X")
  • the evaluation should return successfully with 'true'
  • now you'll see that the name of the newly created child widget has be changed to the generated path of the parent widget ! Simply press F2, copy the path into the clipboard, and paste it somewhere else for later usage (into a text editor, or maybe even into a second Studio instance where you have your import code open)
  • you can now continue the process for other widgets (you can use the same name "X", and as a convenience the library call will still be in the Expression evaluator)
Note that the path generation is intellligent enough to create a reasonable short path. All non-branching path elements will be specified with "*", and for multiple siblings the shortest unique prefix (based on space character tokenization) followed by a wildcard will be used. Also, quotation marks and forward slashs will automatically get escaped, so you can use this path in any library call without modification.

The only limitation right now is that this won't work for a widget that only has paths to top-level non-menu widgets, like. e.g. a top level hook.

I am currently updating another one of my imports, and I found this feature extremely time saving.
Hope it does the same for you ...

Dirk

BobPhoenix 08-17-2006 04:12 PM

:jump:. Will be using the new features with the next plugin conversion I do.

BobP.

dflachbart 08-19-2006 10:36 PM

Minor update: v1.8
 
Here's another minor update (v1.8):

For all linkChild...() methods I added equivalent methods which accept widget paths instead of widget objects as parameter and return the result of the link operation (if the widgets have been found or not).

boolean linkChild(String parentPath, String childPath)
boolean linkChildBefore(String parentName, String newChildPath, String existingChildPath)
boolean linkChildAfter(String parentName, String newChildPath, String existingChildPath)
boolean linkChildAtPosition(String parentPath, String childPath, int pos)

If a widget cannot be found, the error with the corresponding path will be logged to the debug log.


These new methods allow to minimize the code needed for linking in the import. If you had to write

Code:

+- linkWidget = df_sageutils_Import_findImportedWidget("STVImported/xxxx")
+- linkPoint = df_sageutils_Import_findExistingWidget("Archived TV/yyyy")
+- if linkWidget != null && linkPoint != null
  +- true
    +- df_sageutils_Import_linkChild(linkPoint, linkWidget)
  +- false
    +- DebugLog("linkWidget or linkPoint not found")

you can now simply write

Code:

df_sageutils_Import_linkChild("Archived TV/yyyy", "STVImported/xxxx")
which will achieve exactly the same.


Dirk

alon24 08-20-2006 07:35 AM

Hey,

What happens if you have two widgets of different types at the end of the road where you want to link them?

maybe you should add a type field to diffrentiate them ( for the new link(path,path) methods)?

dflachbart 08-22-2006 06:25 AM

Quote:

Originally Posted by alon24
Hey,

What happens if you have two widgets of different types at the end of the road where you want to link them?

maybe you should add a type field to diffrentiate them ( for the new link(path,path) methods)?

Hi Ilan,

not quite sure what you mean, are you talking about if the two widgets have the same name ? Any widget in the STV (or in the import STVi) is uniquely identified by its path. If it happens that there are two widgets with the same name at the end of the path (or at any position in the path, for that matter) a type parameter won't help either, since both widgets can even be of the same type. The only way to cope with those special cases is to use direct access to the widget (e.g. getChild(parent, index)) in those places...

Dirk

dflachbart 09-08-2006 09:24 PM

Update: v1.9
 
Version v1.9 is now available.

Path syntax changes

A widget path now starts with a location prefix ("/STV/" or "/Import/") which specifies if the path denotes a widget in the STV or a widget in the STVi import:

Examples:

/STV/MediaPlayer OSD/DisplayInfo
/Import/STVImported


Simpler interfaces

The path syntax change made it possible that all methods now accept either a widget object or the corresponding widget path as a parameter. Any widget parameter is of type Object and can be called with a widget object or a String containing the path to the object:

e.g. linkChild(Object parent, Object child)

linkChild(w1, w2)
linkChild("/STV/path_to_w1", "/STV/path_to_w2")

This made it possible to eliminate the duplicated linkChild*(String, String) methods. The methods findExistingWidget() / findImportedWidget() could also be consolidated into a single findWidget() method

Note: the interface is backward-compatible, it should not be necessary to change any existing code (but I strongly recommend to use the new path syntax for any new code).



Dirk

Morgan111 09-24-2006 03:17 PM

How do I add an item widget (button) to an existing group of buttons in a menu?

In my import I have defined
Code:

import code
new menu
item
    link to new menu

I can get the parent that I want to add it to, but I cannot seem to get the item from my import when calling findWidget() using "/Import/", "/STV/", or nothing in front of the name. How do you find that type of object when importing widgets like that?

dflachbart 09-24-2006 03:41 PM

Quote:

Originally Posted by Morgan111
How do I add an item widget (button) to an existing group of buttons in a menu?

In my import I have defined
Code:

import code
new menu
item
    link to new menu

I can get the parent that I want to add it to, but I cannot seem to get the item from my import when calling findWidget() using "/Import/", "/STV/", or nothing in front of the name. How do you find that type of object when importing widgets like that?

Hmm, findWidget() should work with "/Import/...."

So if you have

Code:


+- New Menu
  +- button1
  +- ...

in your import, you can link your new button to an existing STV node with

Code:

existingParent = df_sageutils_Import_findWidget("/STV/....")
newButton = df_sageutils_Import_findWidget("/Import/New Menu/button1")
df_sageutils_Import_linkChild(existingParent, newButton)

or even shorter

Code:

df_sageutils_Import_linkChild("/STV/....", "/Import/New Menu/button1")
Let me know if this explanation helps

Dirk

Morgan111 09-24-2006 03:51 PM

Dirk,

button1 is define1 at the top level of the import and contains a link to the new menu which is also at the top level. The idea was to add a button to an existing menu which will lauch the new menu page when pressed.

I had tried to do
newButton = df_sageutils_Import_findWidget("/Import/button1")

Is it ok to have a button at the top level of my import or do I need to do that a different way?

Thanks,
Morgan

dflachbart 09-24-2006 04:03 PM

Quote:

Originally Posted by Morgan111
Dirk,

button1 is define1 at the top level of the import and contains a link to the new menu which is also at the top level. The idea was to add a button to an existing menu which will lauch the new menu page when pressed.

I had tried to do
newButton = df_sageutils_Import_findWidget("/Import/button1")

Is it ok to have a button at the top level of my import or do I need to do that a different way?

Thanks,
Morgan

Ah ok, now I see the problem. No, only Menus, hooks, and listeners are supported on the root level for the search by path. Since you already have the STVImported hook in your import, simply put the button there (I prefer a comment node as a parent in all my imports):

Code:

+- New Menu
+- STVImported
  +- "REM imported nodes"
    +- button1
      +- link to New Menu


df_sageutils_Import_linkChild("/STV/...", "/Import/STVImported/\"REM *"/button1")

But in general you can put the button under any menu, hook, or listener widget.

Dirk

Morgan111 09-24-2006 04:10 PM

Ah! Thanks! Actually I had just tried putting it under The "Main Menu" menu that was already there and was able to import it that way. I don't know if that is kosher or not, but I will do it the way it should be and put it under the section in the template you mentioned.

nathanm 12-14-2006 04:58 PM

I noticed you can use..

df_sageutils_Import_link("LinkToMainMenuTheme", "/STV/THEME ORGANIZER/MenuThemes/MainMenuTheme")

But is it also possible to have the placeholder name to be the actual name of the widget you wish for it to be replaced by.

df_sageutils_Import_link("MainMenuTheme", "/STV/THEME ORGANIZER/MenuThemes/MainMenuTheme")

Would that work?

dflachbart 12-14-2006 06:35 PM

Quote:

Originally Posted by nathanm

But is it also possible to have the placeholder name to be the actual name of the widget you wish for it to be replaced by.

df_sageutils_Import_link("MainMenuTheme", "/STV/THEME ORGANIZER/MenuThemes/MainMenuTheme")

Would that work?

Hi nathanm,

yes this would work. Bear in mind that the placeholder name is really just that, a placeholder which gets replaced by the actual widget name found in the STV at the specified path - you can name it anything you want. Just make sure you use the same name in the placeholder widget and in the link command.

So, both of your examples

http://s91885874.onlinehome.us/html/...getv/link1.jpg http://s91885874.onlinehome.us/html/...getv/link2.jpg

will result in

http://s91885874.onlinehome.us/html/...getv/link3.jpg


Dirk

Tiki 01-03-2007 11:50 PM

flachbar -

I'm using your latest df_sage_utils (2.0) and I've run into two problems.

1.) the Link() function does not appear to work. It will return success, but it doesn't create the link. If I use defineLink() instead with the same parameters, it works properly.

2.) I'm using the template code, but it doesn't delete the import code (the debug log indicates it did, but it really didn't).

I noticed that the code renames the imported hook before it tries to delete the import code. Here is the command it uses to delete the import code:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/STVImported/\"Import code\")
I thought that might be part of the problem, so I tried modifying the import code to use the new name:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/" + ImportName + " import hook" + "/\"Import code\")
I also tried:
Code:

df_sageutils_Import_deleteWidgetTree("/STV/" + ImportName + " import hook" + "/\"Import code\")
Am I doing something wrong or is there a bug here?

dflachbart 01-04-2007 11:53 AM

Hi Tiki,

I can reassure you that those functions are working, so something else must be going wrong

Quote:

Originally Posted by Tiki
1.) the Link() function does not appear to work. It will return success, but it doesn't create the link. If I use defineLink() instead with the same parameters, it works properly.

This is indeed strange. The implementation of defineLink() simply calls link()

Code:

public static boolean defineLink(String placeHolderWidgetName, String pathOfWidgetToLink) {
        return link(placeHolderWidgetName, pathOfWidgetToLink);
    }

so I could not imagine at all why defineLink() would work, but link() would not ...


Quote:

2.) I'm using the template code, but it doesn't delete the import code (the debug log indicates it did, but it really didn't).

I noticed that the code renames the imported hook before it tries to delete the import code. Here is the command it uses to delete the import code:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/STVImported/\"Import code\")
I thought that might be part of the problem, so I tried modifying the import code to use the new name:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/" + ImportName + " import hook" + "/\"Import code\")

Ok, I admit it's not straight forward, but the path ""/Imported/STVImported" will still identify the new imported hook even after is has been renamed. The import library builds a cache for already used path expressions, and it will return the hook widget even with a lookup on the old name.

The hook code removal works in all my plugins, so there must be something else going on. Can you set plugins/df/debug_level=1 in the property file before doing the import, and post the log file ?

Dirk

JREkiwi 01-04-2007 02:07 PM

Quote:

Originally Posted by Tiki
1.) the Link() function does not appear to work. It will return success, but it doesn't create the link. If I use defineLink() instead with the same parameters, it works properly.

Just in case it's not a typo here, but link() should be lower case, caught me out when I changed from defineLink to link

The cleanup code in all the imports I've looked at is
Code:

widget = df_sageutils_Import_findImportedWidget("STVImported;\"Import code\"", ";")
df_sageutils_Import_deleteWidgetTree(widget)

which is different to what's in the current template, but I've no idea where I got it from. Possibly an older version of the template.


John

Tiki 01-04-2007 02:18 PM

2 Attachment(s)
OK Here you go
Quote:

The hook code removal works in all my plugins, so there must be something else going on. Can you set plugins/df/debug_level=1 in the property file before doing the import, and post the log file ?
I attached the log file and the STVi. I am importing this into a copy of the stock STV that came with Sage version 5.04.

As long as you're looking, feel free to point out anything else you see that I might be doing wrong or should be doing differently.

Thanks for the help,
Tom

Tiki 01-04-2007 02:32 PM

Thanks for the input John,

Quote:

Originally Posted by JREkiwi
Just in case it's not a typo here, but link() should be lower case, caught me out when I changed from defineLink to link

John

I just went back and re-tried link() and it is working now. So, you're probably right and I had a type-o of "Link" instead of "link" or something similar.

-Tom

JREkiwi 01-04-2007 02:40 PM

I've tried your import and it works with this cleanup code
Code:

widget = df_sageutils_Import_findImportedWidget("STVImported;\"Import code\"", ";")
df_sageutils_Import_deleteWidgetTree(widget)

John

Tiki 01-04-2007 02:42 PM

Quote:

Originally Posted by JREkiwi
The cleanup code in all the imports I've looked at is
Code:

widget = df_sageutils_Import_findImportedWidget("STVImported;\"Import code\"", ";")
df_sageutils_Import_deleteWidgetTree(widget)

which is different to what's in the current template, but I've no idea where I got it from. Possibly an older version of the template.

John

John - you are right about the missing quote at the end, but that is the way it is in the template.

I tried adding the missing quote - it still doesn't work, but at least it reports an error in the debug log now:
Code:

Thu 1/4 15:33:39.090 *** removing import hook code ***
Thu 1/4 15:33:39.091 invalid path /Imported/STVImported/"Import code"
Thu 1/4 15:33:39.091 root /Imported in path /Imported/STVImported/"Import code" not found
Thu 1/4 15:33:39.091 root /Imported in path /Imported/STVImported/"Import code" not found
Thu 1/4 15:33:39.091 widget path /Imported/STVImported/"Import code" not found
Thu 1/4 15:33:39.091 ERROR: deleteWidgetTree(): root is null
Thu 1/4 15:33:39.091 import hook code removed

I'm getting closer...

Tiki 01-04-2007 02:47 PM

Success!

There was another type-o in the template:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/STVImported/\"Import code\")
should be:
Code:

df_sageutils_Import_deleteWidgetTree("/Import/STVImported/\"Import code\"")
("/Import/" not "/Imported/" and two "s at the end).

JREkiwi 01-04-2007 02:47 PM

Removed as you had got it sorted. Gotta love posts at exactly the same time.:)

John

dflachbart 01-08-2007 11:48 AM

Quote:

Originally Posted by Tiki
Success!

There was another type-o in the template:
Code:

df_sageutils_Import_deleteWidgetTree("/Imported/STVImported/\"Import code\")
should be:
Code:

df_sageutils_Import_deleteWidgetTree("/Import/STVImported/\"Import code\"")
("/Import/" not "/Imported/" and two "s at the end).

Thanks for the heads-up, I'll fix these typos in the download package asap...

Dirk


All times are GMT -6. The time now is 01:13 AM.

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