Solved Custom UI never closes when opened from a shortcut
#1
I have been working on a custom ui which works fine when it is opened from the addon section in Kodi, but if it is opened from favorites or set as a favorite , submenu and or shortcut. It will never close when the user exists. Instead it will constantly reopen.
Below is the code I am using and it looks like other custom ui addons. This only happens when using windowxml. When using a windowxmldialog it closes as expected.

Any thoughts?


PHP Code:
if (__name__ == '__main__'):
    
from resources.lib.gui.maingui import main;
    
    
main();

exit(); 
Reply
#2
This seems to be some issue with the addon being called using AcyivateWindiw. Any ideas would be appreciated.
Reply
#3
scripts should be called by RunScript(), not ActivateWindow()

btw, if you need help, at least post your full addon code and a Debug Log ;-)
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#4
(2016-12-27, 04:43)ronie Wrote: scripts should be called by RunScript(), not ActivateWindow()

btw, if you need help, at least post your full addon code and a Debug Log ;-)

Thanks Ronnie, but it appears Kodi by default sets to ActivateWindow when you choose an application to be a shortcut. Is there an issue with Kodi? And I apologize I left it short and clean figuring it would be easier.
Reply
#5
nope, kodi does things correctly when you add a script to favourites, scripts are added using RunScript()
only plugins are added with ActivateWindow().
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#6
(2016-12-27, 18:26)ronie Wrote: nope, kodi does things correctly when you add a script to favourites, scripts are added using RunScript()
only plugins are added with ActivateWindow().

Not sure what to tell you, I added it via settings to appear on my home screen under the video section, and the logs show it using ActivateWindow and not runscript. Unless it is possible for skins to set items using the wrong option. I will dig in more when I return home from work.
Reply
#7
kodi itself doesn't have such a setting, so yeah it's likely some skin implementation... perhaps using a helper addon.
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#8
how do you define windowxml class? and how do you call it in main?
Reply
#9
(2016-12-29, 10:13)Taifxx Wrote: how do you define windowxml class? and how do you call it in main?

I did try using RunScript as Ronnie stated, but then i go import errors.
I tried RunAddon as well but i have the same issue, an endless loop of the GUI popping up.

I launch it from the default.py using:

PHP Code:
if (__name__ == '__main__'):
    
from resources.lib.gui.maingui import main;
    
    
main();

exit(); 

and the content of maingui is as below

PHP Code:
import xbmc;
import xbmcgui;
import xbmcaddon;
import xbmcplugin;
import os;
import sys;
import re;
import logging;
import time;
import gc;
import json;

from resources.lib.modules import utils;



class 
NowUI(xbmcgui.WindowXML):

    
def __init__(selfstrXMLnamestrFallbackPathstrDefaultNameforceFallback):

        
self.logger utils.getLogger();


    
def onInit(self):

        
self.runDirectoryChecks();

        
utils.unlock();

        
pass;


    
def runDirectoryChecks(self):

        
dsPath xbmc.translatePath(os.path.join('special://userdata/addon_data'utils.getAddonInfo('id')));

        
self.details_title os.path.join(dsPath'media/details/title');
        
self.details_stats os.path.join(dsPath'media/details/stats');
        
self.details_genre os.path.join(dsPath'media/details/genre');
        
self.details_desc os.path.join(dsPath'media/details/desc');
        
self.details_home_title os.path.join(dsPath'media/details/home/title');

        
utils.checkDirectory(self.details_title);
        
utils.checkDirectory(self.details_stats);
        
utils.checkDirectory(self.details_genre);
        
utils.checkDirectory(self.details_desc);
        
utils.checkDirectory(self.details_home_title);



def main():
    
    
fnui NowUI("now-main.xml"utils.getAddonInfo('path'), 'default'"720p");
   
    
fnui.doModal();
    
    
del fnui
Reply
#10
Maybe i wrong but try add onAction with catching NAV_BACK, PREVIOUS_MENU events and add self.close() as reaction on them. I think when you try close window it was not closing and goes to background. You can check this if you add xbmc.log('....close') after doModal.
Reply
#11
(2016-12-29, 23:50)Taifxx Wrote: Maybe i wrong but try add onAction with catching NAV_BACK, PREVIOUS_MENU events and add self.close() as reaction on them. I think when you try close window it was not closing and goes to background. You can check this if you add xbmc.log('....close') after doModal.

Actually it is there. Same issue. I also tried what you suggested with xbmchui.WindowXML.onAction(self, action).

Here is the unedited code. I apologize for the mess, i have not cleaned it up yet as it is not fully ready.

PHP Code:
import xbmc;
import xbmcgui;
import xbmcaddon;
import xbmcplugin;
import os;
import sys;
import re;
import logging;
import time;
import gc;
import json;



from resources.lib.modules import utils;
from resources.lib.modules import nownow;
from resources.lib.modules import workers;
from resources.lib.modules import syncdata;



EXIT_CODE 2;
SUCCESS_CODE 3;
EXPIRE_CODE 4;
HOME_SCREEN_CODE 5;
BACK_CODE 6;
LOGOUT_CODE 7;

RESULT_CODE EXIT_CODE;
#Action Codes
# See guilib/Key.h
PREVIOUS_WINDOW = (
    
xbmcgui.ACTION_PREVIOUS_MENU
    
xbmcgui.ACTION_NAV_BACK
);

EXIT_CLICK = (
    
xbmcgui.ACTION_MOUSE_DOUBLE_CLICK
    
xbmcgui.ACTION_MOUSE_LONG_CLICK
    
xbmcgui.ACTION_TOUCH_LONGPRESS
);

CURRENT_WINDOW 110102;

HOME_WINDOW 110101;
QUEUE_WINDOW 110102;
ALL_WINDOW 110103;
SIMALCASTS_WINDOW 110104;
DUBS_WINDOW 110105;
GENRES_WINDOW 110106;
SETTINGS_WINDOW 110107;

SIDE_MENU = (
    
HOME_WINDOW,
    
QUEUE_WINDOW,
    
ALL_WINDOW,
    
SIMALCASTS_WINDOW,
    
DUBS_WINDOW,
    
GENRES_WINDOW,
    
SETTINGS_WINDOW
);



SCREEN_NAV_BTNS = (
    
20000,
    
20001,
    
20002,
    
20003,
    
20004,
    
20005,
    
20006,
    
20007,
    
20008,
    
20009
);


SHOW_VIEWS = ('shows''features''myqueue');
EPISODE_VIEWS = ('episodes''history');


LOADING_SET = [['900'], ['200''220''205']];

MENU_IDS = (100110021003100410051006100710081009);
SHOW_IDS = (205002050520506205072050820509);
NAV_LISTS = (20500205012050220503205042050520506205072050820509);

QUE_BTNS dict({
    
2060020500,
    
2060220502,
    
2060520505,
    
2060620506,
    
2060720507,
    
2060820508,
    
2060920509
});

LST_Q_REF dict({
    
2050020600,
    
2050220602,
    
2050520605,
    
2050620606,
    
2050720607,
    
2050820608,
    
2050920609
});


MPAA 'flagging/mpaa/tv-ma_c_us.png';
QUALITY 'flagging/resolution/SD (480p)_c.png';
RATING 'flagging/rating/0.0_c.png';
LOADING 'list_loading_db.gif';

SHOWCASE_DISPLAY 21002;
SHOWCASE_ART_CONTROL 21000;
SHOWCASE_QUALITY_CONTROL 2100200;
SHOWCASE_MPAA_CONTROL 2100201;
SHOWCASE_SHOW_TITLE_CONTROL 2100204;
SHOWCASE_SHOW_STATS_CONTROL 2100205;
SHOWCASE_GENRE_CONTROL 2100206;
SHOWCASE_DESCRIPTION_CONTROL 2100207;
SHOWCASE_STAR_RATING_CONTROL 2100210;

current_date utils.setDate(True);
expire_date utils.setDate(False);


class 
NowUI(xbmcgui.WindowXML):

    
def __init__(selfstrXMLnamestrFallbackPathstrDefaultNameforceFallback):

        
self.logger utils.getLogger();
                   
        
self.initialized False;
        
self.dblstatus False;
        
self.aList None;
        
self.aPos None;
        
self.starter None;

        
self.menus dict();
        
self.mkeys dict();
        
self.updates dict();
        
self.showDetails dict();
        
self.episodeDetails dict();
        
self.episodeDetailExtras dict();
        
self.navigation dict();

        
self.result_code EXIT_CODE;

        
self.landing_page None;


    
def onInit(self):

        if 
self.previousWindow:
            
self.previousWindow.close();

        if 
self.result_code == HOME_SCREEN_CODE:
            
self.result_code EXIT_CODE;

        
elif self.result_code == LOGOUT_CODE:
            
self.close();


        
self.runDirectoryChecks();


        
self.password_string '';
        
self.password_length 0;

        
self.buildDetails();

        
utils.unlock();

        
pass;


    
def setPrevWindow(selfprev):
        
self.previousWindow prev;

        
pass;


    
def setLandingPage(self):
        
self.landing_page self;

        
pass;


    
def onAction(selfaction):

        if 
action.getId() in PREVIOUS_WINDOW:
            
self.close();
            
#xbmcgui.WindowXML.onAction(self, action);

        
if xbmc.getCondVisibility("Control.HasFocus(%s)" 5003):
            
self.updateMaskedPassword();

        
controlID self.adjustPosition(action);

        if 
controlID 20500 or controlID 20509:

            
self.getControl(SHOWCASE_ART_CONTROL).setImage('');
            
self.getControl(21001).setImage('');

        
elif action.getId() in (12):

            if 
20500 <= controlID <= 20509:

                try:

                    
self.startDetailsProcess(controlIDTrue);


                
except Exception as inst:
                    
self.logger.error(inst);

                    
pass;


                
#self.populateDetails(controlID);

            
elif controlID in QUE_BTNS:
                
#self.updateQueue(controlID, update=False); #listitem remove not working with threads
                
workers.DetailsThread(target=self.updateQueueargs=(controlIDFalse,)).start();


            else:
                
self.setVisible(SHOWCASE_DISPLAYFalse);
  
        
        
pass;


    
def onClick(selfcontrolID):

        if 
controlID in range(2050020510):

            
listitem self.getControl(controlID).getSelectedItem();

            
videourl None;
            
viewtype None;

            
videourl listitem.getProperty('videourl');
            
viewtype listitem.getProperty('viewtype');

            if 
videourl:

                
from resources.lib.modules.player import player;

                try:

                    
contMap self.updates.get(20001None);

                    if 
contMap:

                        
pStart contMap.get('startPosition'None);
                        
pDuration contMap.get('duration'None);
                        
pAdd contMap.get('add'None);

                        if 
pStart and pDuration and pAdd:

                            
listitem.setProperty('pStart'str(pStart));
                            
listitem.setProperty('pDuration'str(pDuration));
                            
listitem.setProperty('pAdd'str(pAdd));

                            
self.logger.error(pAdd);


                
except:
                    
pass;


                
player().run(videourllistitem);

            
elif viewtype in SHOW_VIEWS:

                
self.logger.error("This is a show so we are launching the SHOW GUI")
                
from resources.lib.gui.showgui import show;
                
#window = xbmcgui.Window(xbmcgui.getCurrentWindowId());
                
xrfPath listitem.getProperty('detailPath');
                
xrfParam listitem.getProperty('detailParams');

                
self.logger.error(xrfPath)
                
self.logger.error(xrfParam)

                if 
viewtype and viewtype == 'myqueue':
                    
xrfPath listitem.getProperty('detailPath');
                    
xrfParam listitem.getProperty('detailParams');

                else:
                    
xrfPath listitem.getProperty('path');
                    
xrfParam listitem.getProperty('params');

                
show(self.landing_pagexrfPathxrfParam);
                

            else:
                
self.logger.error(viewtype);
                
self.logger.error('No Url Found');
                
# we need to send a notification

                
pass;


        
elif controlID in (10004000110100):
            
#self.starter.close();
            
self.player None;
            
self.close();

        
elif controlID == 5004:
            
self.login();

        
elif controlID == 4002:
            
import webbrowser;

            
webbrowser.open('http://www.now.com/android-mobile/register?territory=US', new=0autoraise=True)

        
elif controlID == 4004:

            
self.createLoginSplash();
            
            
self.getControl(500).setVisible(True);
            
self.getControl(400).setVisible(False);

        
elif controlID == 5000:

            
self.getControl(400).setVisible(True);
            
self.getControl(500).setVisible(False);

        
elif controlID == 5004:

            
self.getControl(400).setVisible(False);
            
self.getControl(500).setVisible(False);
            
self.getControl(401).setVisible(True);


        
elif controlID in MENU_IDS:
            
            
nownow.execute(self.menus[controlID]);


        
elif controlID in QUE_BTNS:
            
#self.updateQueue(controlID, True);
            
workers.DetailsThread(target=self.updateQueueargs=(controlIDTrue,)).start();


        
elif controlID in SCREEN_NAV_BTNS:
            
self.prepNavigation(controlID);


        
elif controlID in SIDE_MENU:
            
self.menuNavigation(controlID);





        
#else:
            #self.logger.error(controlID)
        
pass;


    
def onDoubleClick(selfcontrolID):

        
self.dblstatus True;
        
self.logger.error('DBL CLICK')

        
listitem self.getControl(controlID).getSelectedItem();

        
videourl None;
        
videourl listitem.getProperty('videourl');
        
self.logger.error(videourl)


        
pass;


    
def onFocus(selfcontrolID):

        if 
20500 <= controlID <= 20509:

            try:
                
self.startDetailsProcess(controlIDTrue);

            
except Exception as inst:
                
self.logger.error(inst);

                
pass;


            
#self.populateDetails(controlID);

        
elif controlID in QUE_BTNS:
            
#self.updateQueue(controlID, update=False);
            
workers.DetailsThread(target=self.updateQueueargs=(controlIDFalse,)).start();


        else:
            
self.setVisible(SHOWCASE_DISPLAYFalse);

        
pass;

    
    
def onControl(selfcontrol):

        
self.logger.error('**********ONCONTROL*****************')


    
def adjustPosition(selfaction):

        
#self.logger.error(action.getId())

        
controlID 0;

        for 
idx in NAV_LISTS:

            if 
xbmc.getCondVisibility("Control.HasFocus(%s)" idx):

                
controlID idx;

                break;


        return 
controlID;


    
def getAdjustedImage(selfcontrolID):

        
img str(self.getControl(controlID).getSelectedItem().getProperty('showcaseimg'));
        
imgspec re.search(r'.*h_(\d+),w_(\d+),q_(\d+).*'imgre.I);

        
imgspec.group(1);
        
imgspec.group(2);
        
imgspec.group(3);

        
ah = (int(h) * 2);
        
aw = (int(w) * 2);
        
aq = (int(q) * 2);

        
# we need to add some type of size/quality control for users

        #img = img.replace(str('h_%s,w_%s,q_%s' % (h, w, q)), str('h_%s,w_%s,q_%s' % (ah, aw, aq)));
        #img = img.replace('upload/.*/oth', 'upload/oth');
        
img re.sub(r'upload/.*/oth''upload/oth'img);


        return 
img;


    
def updateMaskedPassword(self):

        
bullet_string '';

        
self.password_field self.getControl(50033);
        
self.hidden_password_field self.getControl(5003);

        
#self.password_string = self.password_string[0:len(self.password_field.getText())];


        
for idx in range(0len(self.hidden_password_field.getText())):
            
bullet_string += '*';


        
self.password_field.setText(bullet_string);

        
#http://zurb.com/article/279/how-to-mask-passwords-like-the-iphone

    
    
def buildDetails(self):

        
self.setLoadingStates(LOADING_SETTrue);

        
menuitems nownow.menu();
        
homescreenitems None;

        if 
menuitems:
            
self.setMenuItems(menuitems);

            
#self.logger.error(self.menus)

            
if 1001 in self.menus:

                
homescreenitems nownow.homescreenmenu(self.menus[1001]);

                if 
homescreenitems:

                    
self.logger.debug(json.dumps(homescreenitems));
                    
self.setHomeScreenItems(homescreenitems);

                else:
                    
self.logger.error('NO HOMESCREEN ITEMS FOUND')

            else:
                
self.logger.error('WE NEED AN ERROR Notification')


    
def setLoadingStates(selfvsetiterate=False):

        if 
iterate:

            for 
idx in range(010):

                for 
ixview in enumerate(vset0):

                    
vstate True if ix else False;

                    for 
cview in view:
                    
                        try:

                            
cview int('%s%02d' % (cviewidx));

                            
self.setVisible(cviewvstate);

                        
except Exception as inst:
                            
#self.logger.error(inst);
                            
pass;

        else:

            for 
ixview in enumerate(vset0):

                
vstate True if ix else False;

                for 
cview in view:
                    
                    try:

                        
self.setVisible(cviewvstate);

                    
except Exception as inst:
                        
#self.logger.error(inst);
                        
pass;


    
def setVisible(selfviewstate):

        
self.getControl(view).setVisible(state);


    
def setMenuItems(selfmenuitems):

        
#1001 - 1009

        
utils.lock();

        
idxoffset 0;

        for 
idxmenu in enumerate(menuitems1):

            try:

                if 
'ratethisapp' != menu['target']:

                    
title None;
                    
target None;
                    
path None;
                    
params None;
                    
size None;
                    
fsize None;

                    if 
'register' == menu['target']:
                        
                        
smenu menu['registration']['registered'];

                        
title smenu['title'];
                        
target smenu['pointer']['target'];
                        
path smenu['pointer']['path'];
                        
params None;

                    else:

                        
title menu['title'];
                        
target menu['target'];
                        
path menu['path'];
                        
params menu['params'];


                    
self.menus.update({
                        
int('100%s' % (idx idxoffset)): dict({
                            
'title'title,
                            
'target'target,
                            
'path'path,
                            
'params'params 
                        
})
                    });

                    
size = (60060) if 'themes' in menu else (60090);
                    
fsize 36 if 'themes' in menu else 58;

                    
utils.text2Button(title'RGB', [(613136), (683151)], [(255255255), (255255255)], fsize'ExtraBold'size, (204), ['menu-focus-button%s' % (idx idxoffset), 'menu-no-focus-button%s' % (idx idxoffset)], True);

                else:
                    
idxoffset += -1;


            
except Exception as inst:
                
self.logger.error(inst);

                
pass;

        
utils.unlock();


    
def setHomeScreenItems(selfpointers):

        
#20000 - 20009
        #20500 - 20509

        
utils.lock();
        
#UI Locking is bad we want some kind of non locking notification for the main gui

        
self.resetListContents();

        
self.logger.error('SETTING HOMESCREEN ITEMS');

        
sysaddon sys.argv[0];
        
syshandle int(sys.argv[1]);

        
threads = [];

        for 
idxpointer in enumerate(pointers0):

            try:

                
itemset None;
                
longList None;
                
navmenu None;

                
#processes = [];

                
mid int('200%02d' idx);
                
lid int('205%02d' idx);
                
qid int('206%02d' idx);

                if 
'themes' in pointer:
                    
itemset nownow.contentCarousel(pointeridx);

                
elif 'longList' in pointer:

                    
longList pointer['longList'];

                    if 
'watchlist' in longList:
                        
itemset nownow.watchlist(pointer=pointeridx=idx);

                        if 
itemset and len(itemset) >= 4:

                            if 
itemset[2]:

                                
mid int('200%02d' idx);
                                
                                
self.menus.update({
                                    
miditemset[2]
                                });

                                
self.mkeys.update({
                                    
itemset[0]: mid
                                
});

                                
self.updates.update({
                                    
miditemset[4]
                                });

                            
self.navigation.update({
                                
middict({
                                    
'navset'itemset[3],
                                    
'navtype''watchlist'
                                
})
                            });

                    else:

                        if 
'themes' in longList:

                            
dset self.menus.get(self.mkeys.get('history'None), None);
                            
itemset nownow.episode(pointeridxdset);

                        else:

                            
dset self.menus.get(self.mkeys.get('myqueue'None), None);
                            
itemset nownow.show(pointeridxdset);


                        if 
itemset:

                            if 
bool(re.compile(r'.*showGenres=true.*'re.I).match(itemset[2].get('params'''))):
                                
navType 'genres';

                            else: 
                                
navType 'dateadded';

                            
self.navigation.update({
                                
middict({
                                    
'navset'itemset[2],
                                    
'navtype'navType
                                
})
                            });

                            
#success = ['shows', shows, navigation];


                
if itemset:
                    
self.formatItemSet(threadsitemsetmidlidqid);

                try:

                    
vset = [[int('200%02d' idx), int('220%02d' idx), int('205%02d' idx)], [int('900%02d' idx)]];

                    
self.setLoadingStates(vsetFalse);

                
except Exception as inst:
                    
self.logger.error(inst);

                    
pass;


            
except Exception as inst:
                
self.logger.error(inst);

                
pass;

        [
i.start() for i in threads];
        
#[i.join() for i in threads];

        
utils.unlock();

        
self.logger.error(self.navigation)


    
def formatItemSet(selfthreadsitemsetmidlidqid):

        
mcontrol self.getControl(mid);
        
lcontrol self.getControl(lid);
        
qcontrol None;

        try:

            
qcontrol self.getControl(qid);
            
#qcontrol.setSelected(False);

        
except Exception as inst:
            
self.logger.error(inst);

            
pass;


        
#for item in itemset[1]:
        
for sIdxitem in enumerate(itemset[1], 0):

            
titles = [];
            
listitem None;
            
listitem xbmcgui.ListItem(item.get('title'''), item.get('subtitle'''), item.get('thumbnail'''), item.get('thumbnail'''));

            if 
itemset[0] == 'episodes' or itemset[0] == 'history':

                
titles = [item.get('title'''), item.get('subtitle''')];

            else:
                
titles = [item.get('title''')];


            
titleimg utils.text2Title(list(titles), self.details_home_titleitem.get('titleimg'''));
                
            
listitem.setProperty('showcaseimg'item.get('thumbnail'''));

            try:

                
listitem.setProperty('viewtype'str(itemset[0]));

                for 
attrval in item.items():

                    
listitem.setProperty(attrstr(val));

            
except Exception as inst:
                
self.logger.error(inst);

                
pass;


            if 
'progress' in item:

                
cprogress item.get('progress'0);

                
listitem.setProperty('cprogress'str(cprogress));


            if 
'inQueue' in item:

                
inQueue item.get('inQueue'None);

                if 
inQueue is not None:

                    
listitem.setProperty('qtexture'str(inQueue));

                
elif qcontrol:
                    
qcontrol.setVisible(False);
            

            if 
titleimg:
                
listitem.setProperty('ctitle'titleimg);

            
lcontrol.addItem(listitem);                      

            
#http://stackoverflow.com/questions/1787397/how-do-i-limit-the-number-of-active-threads-in-python
            
threads.append(workers.DetailsThread(target=self.populateDetailsargs=(lcontrollistitemsIdxitemset[0], lidFalse,)));


        if 
len(itemset) < 4:
            
navmenu itemset[2];

        else: 
            
navmenu itemset[3];


        if 
navmenu:
            
#self.logger.error(navmenu.get('width', '0'))
            
mcontrol.setWidth(int(navmenu.get('width''0')));


    
def startDetailsProcess(selfcontrolIDloadDisplay=False):

        
self.setVisible(SHOWCASE_DISPLAYTrue);

        
self.resetImage(SHOWCASE_ART_CONTROL);
        
self.resetImage(SHOWCASE_DESCRIPTION_CONTROL);

        
self.getControl(SHOWCASE_SHOW_TITLE_CONTROL).setImage(LOADING);
        
self.getControl(SHOWCASE_SHOW_STATS_CONTROL).setImage(LOADING);
        
self.getControl(SHOWCASE_GENRE_CONTROL).setImage(LOADING);
        
self.getControl(SHOWCASE_MPAA_CONTROL).setImage(MPAA);
        
self.getControl(SHOWCASE_QUALITY_CONTROL).setImage(QUALITY);
        
self.getControl(SHOWCASE_STAR_RATING_CONTROL).setImage(RATING);

        
cItem self.getControl(controlID);
        
sItem cItem.getSelectedItem();
        
sIdx cItem.getSelectedPosition();
        
viewtype sItem.getProperty('viewtype');

        
self.aList controlID;
        
self.aPos sIdx;

        
processes = [];               

        
#need extra threading
        #processes.append(workers.Process(self.populateDetails(cItem, sItem, sIdx, viewtype, controlID, loadDisplay)));

        #[i.start() for i in processes];
        #[i.join() for i in processes];

        
workers.DetailsThread(target=self.populateDetailsargs=(cItemsItemsIdxviewtypecontrolIDloadDisplay,)).start();

        
#pp = workers.DetailsThread(target=self.populateDetails, args=(cItem, sItem, sIdx, viewtype, controlID, loadDisplay))
        
'''pp = workers.DetailsThread(target=self.populateDetails, args=(cItem, sItem, sIdx, viewtype, controlID, loadDisplay))

        processes.append(pp);
        pp.start()'''


    
def populateDetails(selfcItemsItemsIdxviewtypecontrolIDloadDisplay):

        try:

            
#if loadDisplay is False:
                #time.sleep(sIdx*2)

            
detailspath os.path.join(utils.getAddonInfo('path'), 'resources/skins/default/media/');

            
titleImg None;
            
statsImg None;
            
genreImg None;
            
descImg None;
            
starImg None;
            
qualityImg None;
            
ratingImg None;


            if 
viewtype in SHOW_VIEWS:
                
                (
starRatingqualityratingsparams) = self.setShowDetails(cItemsItemsIdxviewtypeloadDisplay);

                
titleImg os.path.join(self.details_title, ('%s.png' params));
                
statsImg os.path.join(self.details_stats, ('%s.png' params));
                
genreImg os.path.join(self.details_genre, ('%s.png' params));
                
descImg os.path.join(self.details_desc, ('%s.png' params));
                
            else:

                (
starRatingqualityratingsparams) = self.setEpisodeDetails(cItemsItemsIdxviewtypeloadDisplay);

                
titleImg os.path.join(self.details_title, ('%s.png' params));
                
statsImg os.path.join(self.details_stats, ('%s.png' params));
                
genreImg os.path.join(self.details_genre, ('%s.png' params));
                
descImg os.path.join(self.details_desc, ('%s.png' params));


            
starImg '%sflagging/rating/%s_c.png' % (detailspathstarRating);
            
qualityImg '%sflagging/resolution/%s_c.png' % (detailspathquality);
            
ratingImg = ('%sflagging/mpaa/%s_c_%s.png' % (detailspathratingsutils.setting('fn.territory').lower()));


            if 
loadDisplay:

                
ncItem self.getControl(controlID);
                
nsIdx ncItem.getSelectedPosition();

                if 
self.aList == controlID and self.aPos == nsIdx:

                    
self.getControl(SHOWCASE_ART_CONTROL).setImage(self.getAdjustedImage(controlID));
                    
self.setDownloadedDetails(titleImgstatsImggenreImgdescImgparamsstarImgqualityImgratingImg);           

                
        
except Exception as inst:
            
self.logger.error(inst);

            
pass;


    
def setShowDetails(selfcItemsItemsIdxviewtypeloadDisplay):

        if 
viewtype and viewtype == 'myqueue':
            
path sItem.getProperty('detailPath');
            
params sItem.getProperty('detailParams');

        else:
            
path sItem.getProperty('path');
            
params sItem.getProperty('params');

        
titleimg sItem.getProperty('titleimg');
        
title sItem.getProperty('title');

        
counters None;
        
genres None;
        
description None;

        
starRating '0.0';
        
quality 'HD (1080p)';
        
ratings 'tv-ma';


        if 
loadDisplay:

            
self.getControl(SHOWCASE_SHOW_TITLE_CONTROL).setImage(LOADING);
            
self.getControl(SHOWCASE_SHOW_STATS_CONTROL).setImage(LOADING);
            
self.getControl(SHOWCASE_GENRE_CONTROL).setImage(LOADING);


        if 
params not in self.showDetails:

            
detailData syncdata.getDetailsData(params);
            
dateExpired True;

            if 
detailData:
                
dateExpired utils.dateExpired(detailData[2]);

            if 
dateExpired:

                
sDetails nownow.selection(pathparams'showDesc'viewtypesIdxloadDisplay);

                if 
sDetails:

                    
syncdata.setDetailsData(paramssDetailsexpire_date);

                    
self.showDetails.update({paramssDetails});

                    try:
                        
counters 'Seasons: %02d  |  Episodes: %02d  |  Year: %s' % (sDetails.get('seasons'0), sDetails.get('episodes'0), sDetails.get('releaseYear'2016));

                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_SHOW_STATS_CONTROL);

                        
self.logger.error(inst);

                        
pass;

                    try:
                        
genres 'Genres: %s' sDetails.get('genres''NA');

                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_GENRE_CONTROL);

                        
self.logger.error(inst);

                        
pass;

                    try:
                        
description sDetails.get('description'None);

                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_DESCRIPTION_CONTROL);

                        
self.logger.error(inst);

                        
pass;


                
dtlList = list([
                    [
title56os.path.join(self.details_title, ('%s.png' params))], 
                    [
counters36os.path.join(self.details_stats, ('%s.png' params))], 
                    [
genres36os.path.join(self.details_genre, ('%s.png' params))]
                ]);

                
self.makeDetails(dtlList);

                
os.path.join(self.details_title, ('%s.png' params))
                
os.path.join(self.details_stats, ('%s.png' params))
                
os.path.join(self.details_genre, ('%s.png' params))
                
os.path.join(self.details_desc, ('%s.png' params))


                if 
description:
                    
utils.text2DisplayWrap(description'RGB', (164164164), (255255255), 36, (976400), 52'SemiBold'os.path.join(self.details_desc, ('%s.png' params)), multiplier=1sharpen=Falsebgimage=None);


            else:

                
sDetails json.loads(detailData[1]);

                
self.showDetails.update({paramssDetails});


        else:
            
sDetails self.showDetails.get(paramsNone);


        if 
sDetails:

            
starRating utils.roundQuarter(str(sDetails.get('starRating''0.0')));
            
quality sDetails.get('quality''HD (1080p)');
            
ratings sDetails.get('ratings''tv-ma');


        return list([
starRatingqualityratingsparams]);


    
def setEpisodeDetails(selfcItemsItemsIdxviewtypeloadDisplay):

        
self.logger.error('Setting Episode Details');

        
path sItem.getProperty('path');
        
params sItem.getProperty('params');
        
historyParams sItem.getProperty('historyParams');
        
titleimg sItem.getProperty('titleimg');
        
title sItem.getProperty('title');
        
progress sItem.getProperty('progress');
        
duration sItem.getProperty('duration');
        
quality sItem.getProperty('quality');

        
subtitle None;
        
genres None;
        
description None;
        
seasoninfo None;
        
description None;

        
season 0;
        
episode 0;
        
        
starRating '0.0';
        
ratings 'tv-ma';

        
efname re.search(r'video_id=(\w+)'historyParams);

        try:
            
efname str(efname.group(1));

        
except:
            
efname 'ed_filler';

            
pass;


        if 
loadDisplay:

            
self.getControl(SHOWCASE_SHOW_TITLE_CONTROL).setImage(LOADING);
            
self.getControl(SHOWCASE_SHOW_STATS_CONTROL).setImage(LOADING);
            
self.getControl(SHOWCASE_GENRE_CONTROL).setImage(LOADING);


        if 
params not in self.episodeDetails:

            
detailData syncdata.getDetailsData(params);
            
dateExpired True;

            if 
detailData:
                
dateExpired utils.dateExpired(detailData[2]);

            if 
dateExpired:

                
sDetails nownow.selection(pathparams'episodeDesc'viewtypesIdxloadDisplay);

                if 
sDetails == False:
                    
                    
tparams re.sub(r'audio=ja''audio=1'params);
                    
tparams re.sub(r'audio=en''audio=2'tparams);

                    
sDetails nownow.selection(pathtparams'episodeDesc'viewtypesIdxloadDisplay);


                if 
sDetails:

                    
epsPath sDetails.get('path'None);
                    
epsParam sDetails.get('params'None);

                    if 
epsPath and epsParam:
                        
                        
extras nownow.getEpisodeDetailExtras(epsPathepsParamloadDisplay);

                        
#We need to make sure the extras get incorporated

                        
if extras:

                            
sDetails.update({'starRating'extras.get('starRating''0.0')});


                    
syncdata.setDetailsData(paramssDetailsexpire_date);

                    
self.episodeDetails.update({paramssDetails});


                    try:

                        
seasoninfo self.formatSeasonInfo(sDetailsprogress);

                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_SHOW_STATS_CONTROL);

                        
self.logger.error(inst);

                        
pass;

                    try:
                        
subtitle 'Title: %s' sDetails.get('subtitle''NA');

                        
#self.logger.error(subtitle)

                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_GENRE_CONTROL);

                        
self.logger.error(inst);

                        
pass;

                    try:
                        
description sDetails.get('description'None);


                    
except Exception as inst:

                        if 
loadDisplay:
                            
self.resetImage(SHOWCASE_DESCRIPTION_CONTROL);

                        
self.logger.error(inst);

                        
pass;

                
dtlList = list([
                    [
title56os.path.join(self.details_title, ('%s.png' efname))], 
                    [
seasoninfo36os.path.join(self.details_stats, ('%s.png' efname))], 
                    [
subtitle36os.path.join(self.details_genre, ('%s.png' efname))]
                ]);

                
self.makeDetails(dtlList);


                if 
description:
                    
utils.text2DisplayWrap(description'RGB', (164164164), (255255255), 36, (976400), 52'SemiBold'os.path.join(self.details_desc, ('%s.png' efname)), multiplier=1sharpen=Falsebgimage=None);

            else:

                
sDetails json.loads(detailData[1]);

                
self.episodeDetails.update({paramssDetails});


        else:

            
sDetails self.episodeDetails.get(paramsNone);

            try:

                
seasoninfo self.formatSeasonInfo(sDetailsprogress);

                
dtlList = list([
                    [
seasoninfo36os.path.join(self.details_stats, ('%s.png' efname))], 
                ]);

                
self.makeDetails(dtlList);


            
except Exception as inst:

                if 
loadDisplay:
                    
self.resetImage(SHOWCASE_SHOW_STATS_CONTROL);

                
self.logger.error(inst);

                
pass;


        if 
sDetails:

            
videourl sDetails.get('videourl'None);
            
starRating sDetails.get('starRating''0.0');

            if 
videourl:
                
sItem.setProperty('videourl'videourl);


            
starRating utils.roundQuarter(str(starRating));
            
quality quality if quality is not None else 'HD (1080p)';
            
ratings sDetails.get('ratings''tv-ma');


        return list([
starRatingqualityratingsefname]);


    
def resetImage(selfcontrol):

        
self.getControl(control).setImage('');


    
def makeDetails(selfdetails):

        for 
detail in details:

            if 
detail[0]:
                 
utils.text2Display(detail[0], 'RGB', (164164164), (255255255), detail[1], 'ExtraBold'detail[2], multiplier=1sharpen=Falsebgimage=None);


    
def formatSeasonInfo(selfsDetailsprogress):

        
import datetime;

        
season sDetails.get('season''Season 0');
        
episode sDetails.get('episode''Episode 0');
        
#We wanted a special parser but since the new API sucks it is more trouble to determine the video type

        
duration sDetails.get('duration'0);

        
duration int((if (duration is None or len(duration) < 1) else int(duration)) * 0.001);
        
progress str(if (progress is None or len(str(progress)) < 1) else progress);

        
#Doesnt appear to work in all versions of Kodi
        #duration = '{}'.format(datetime.timedelta(seconds=int(duration)));
        #progress = '{}%'.format(progress);

        
duration str(datetime.timedelta(seconds=int(duration)));
        
progress += '%';

        
# we might need to change this later so that we cna update the progress realtime

        
seasoninfo '%s  |  %s  |  Duration: %s  |  Progress: %s' % (seasonepisodedurationprogress);

        
        return 
seasoninfo;


    
def resetListContents(self):

        for 
idx in range(010):

            try:

                
idx int('205%02d' idx);

                
tlControl self.getControl(idx);

                if 
tlControl:
                    
tlControl.reset();

            
except:
                
pass;

    
    
def setDownloadedDetails(selftitleImgstatsImggenreImgdescImgparamsstarImgqualityImgratingImg):

        
gc.collect();
        
        
self.getControl(SHOWCASE_SHOW_TITLE_CONTROL).setImage(titleImgFalse);
        
self.getControl(SHOWCASE_SHOW_STATS_CONTROL).setImage(statsImgFalse);
        
self.getControl(SHOWCASE_GENRE_CONTROL).setImage(genreImgFalse);
        
self.getControl(SHOWCASE_DESCRIPTION_CONTROL).setImage(descImgFalse);
        
self.getControl(SHOWCASE_STAR_RATING_CONTROL).setImage(starImgFalse);
        
self.getControl(SHOWCASE_QUALITY_CONTROL).setImage(qualityImgFalse);
        
self.getControl(SHOWCASE_MPAA_CONTROL).setImage(ratingImgFalse);
        
self.setVisible(SHOWCASE_ART_CONTROLTrue);


    
def updateQueue(selfcontrolIDupdate=False):

        try:

            
qBtn self.getControl(controlID);
            
qCtrl self.getControl(QUE_BTNS[controlID]);
            
qPos qCtrl.getSelectedPosition();
            
qItem qCtrl.getSelectedItem();
            
qState int(qItem.getProperty('qtexture'));

            
updateQ False;

            if 
update:

                
viewtype qItem.getProperty('viewtype');

                if 
viewtype == 'myqueue':

                    
updateQ True;

                    
qPath qItem.getProperty('myQueuePath');
                    
qParams qItem.getProperty('myQueueParams');

                else:

                    
qPath qItem.getProperty('togglePath');
                    
qParams qItem.getProperty('toggleParams');


                if 
qPath and qParams:

                    
updated nownow.updateQueue(qPathqParamsqState);

                    if 
updated:

                        if 
qState 0:

                            
qItem.setProperty('qtexture''0');
                            
qBtn.setSelected(0);

                            
self.adjustNavShowQueueState(qParams0);


                            if 
not updateQ:

                                
itemset nownow.watchlist('myqueue'qParamspointer=Noneidx=None);

                                if 
itemset:

                                    
threads = [];

                                    
self.formatItemSet(threadsitemset200022050220602);

                                    [
i.start() for i in threads];

                        else:
                            
                            
qItem.setProperty('qtexture''1');
                            
qBtn.setSelected(1);

                            
self.adjustNavShowQueueState(qParams'1');

                            if 
updateQ:
                                
qCtrl.removeItem(qPos);

                            else:

                                try:
                                    
                                    
tCtrl self.getControl(20502);
                                    
tSize tCtrl.size();

                                    for 
tix in range(0tSize):

                                        try:

                                            
tItem tCtrl.getListItem(tix);

                                            if 
tItem:

                                                
tParam tItem.getProperty('myQueueParams');

                                                if 
tParam == qParams:
                                                    
tCtrl.removeItem(tix);

                                                    break;

                                        
except Exception as inst:
                                            
#self.logger.error(inst);
                                            
                                            
pass;


                                
except Exception as inst:
                                    
self.logger.error(inst);

                                    
pass;


                                
#needs to add que lookup for epty list
                    

            
else:
                
qBtn.setSelected(qState);


        
except Exception as inst:
            
self.logger.error(inst);

            
pass;


    
def adjustNavShowQueueState(selfqParamsqState):

        for 
idx in SHOW_IDS:

            try:

                
sList self.getControl(idx);
                
sSize sList.size();

                for 
sIdx in range(0sSize):

                    
lItem sList.getListItem(sIdx);

                    if 
lItem:

                        
lParam lItem.getProperty('toggleParams');

                        if 
lParam == qParams:
                            
lItem.setProperty('qtexture'str(qState));

                            break;


            
except Exception as inst:
                
self.logger.error(inst);

                
pass;


    
def prepNavigation(selfcontrolID):

        
navSet self.navigation.get(controlIDNone);

        if 
navSet:

            
navtype navSet.get('navtype'None);
            
navset navSet.get('navset'None);

            
#self.logger.error(navtype)
            #self.logger.error(navset)
            #self.logger.error(json.dumps(self.navigation))

            
if navset:

                if 
navtype == 'genres':
                    
from resources.lib.gui.genreselectgui import genreselect;

                    
self.result_code genreselect(self.landing_pagenavset);

                    
pass;

                
                
elif navtype == 'dateadded':
                    
from resources.lib.gui.audioselectgui import audioselect;

                    
self.result_code audioselect(self.landing_pagenavset);

                    
pass;


                
elif navtype == 'watchlist':
                    
from resources.lib.gui.watchlistgui import watchlist;

                    
self.result_code watchlist(self.landing_pagenavset);

                    
pass;

            else:
                
self.logger.error('Navigation error we need to send an alert');

            
pass;

        else:
            
self.logger.error('NO NAV SET FOUND')
            
self.logger.error('-------------------')

        
pass;


    
def menuNavigation(selfcontrolID):

        
from resources.lib.modules import menunav;

        
self.result_code menunav.chooser(self.landing_pageselfCURRENT_WINDOWcontrolID);

        if 
self.result_code == HOME_SCREEN_CODE:
            
pass;


        
pass;


    
def runDirectoryChecks(self):

        
dsPath xbmc.translatePath(os.path.join('special://userdata/addon_data'utils.getAddonInfo('id')));

        
self.details_title os.path.join(dsPath'media/details/title');
        
self.details_stats os.path.join(dsPath'media/details/stats');
        
self.details_genre os.path.join(dsPath'media/details/genre');
        
self.details_desc os.path.join(dsPath'media/details/desc');
        
self.details_home_title os.path.join(dsPath'media/details/home/title');

        
utils.checkDirectory(self.details_title);
        
utils.checkDirectory(self.details_stats);
        
utils.checkDirectory(self.details_genre);
        
utils.checkDirectory(self.details_desc);
        
utils.checkDirectory(self.details_home_title);


    


def main(prev=None):
    
    
fnui NowUI("now-main.xml"utils.getAddonInfo('path'), 'default'"720p");

    
fnui.setPrevWindow(prev);
    
fnui.setLandingPage();
    
    
fnui.doModal();
    
    
del fnui
Reply
#12
1. xbmcgui.WindowXML.onAction(self, action) should be in the end of the function. It's mean: if some events was not catched in your onAction you send them to default onAction.
2. WindowXML can have behavior (reaction on nav_back etc.) different from WindowXMLDialog behavior and in your case goes to background.
3. In your code some IF which can be run simultaneously (after self.close too). Use return to prevent this.
Reply
#13
I tried your suggestions but I still encounter the same issue. It actually looks like Dialog would be doing it too, but it is not happening due to an exception.
default.py" has left several classes in memory that we couldn't clean up. The classes include: class PythonBindings::XBMCAddon_xbmcgui_WindowXMLDialog_Director. I do not want to use dialog BTW, was just using it for testing purposes.
I cleaned out onAction and left nothing but the default, and it continues to happen.

I am not sure why there is a difference between going into addons and opening it, and using a shortcut to open it.
Reply
#14
Another assumption:
Do you have this block in addon.xml?
<extension point="xbmc.python.script" library="default.py"/>
Reply
#15
(2016-12-30, 18:27)Taifxx Wrote: Another assumption:
Do you have this block in addon.xml?
<extension point="xbmc.python.script" library="default.py"/>

Mine actually states <extension point="xbmc.python.pluginsource" library="default.py">

I changed it to script, but now i am getting some exceptions. I will troubleshoot these exceptions and see if i can get them resolved in order to see if that addresses the problem.
Reply

Logout Mark Read Team Forum Stats Members Help
Custom UI never closes when opened from a shortcut0