Index: libs/libmythui/mythscreentype.h =================================================================== --- libs/libmythui/mythscreentype.h (revision 22720) +++ libs/libmythui/mythscreentype.h (working copy) @@ -8,6 +8,7 @@ #include class MythScreenStack; +class MythUIBusyDialog; /** * Base Screen type @@ -22,11 +23,13 @@ virtual ~MythScreenType(); virtual bool Create(void); // do the actual work of making the screen. - virtual void Init(void); virtual bool keyPressEvent(QKeyEvent *); virtual bool gestureEvent(MythGestureEvent *); virtual void ShowMenu(void); + void doInit(void); + void LoadInForeground(void); + // if the widget is full screen and obscures widgets below it bool IsFullscreen(void) const; void SetFullscreen(bool full); @@ -44,6 +47,9 @@ bool IsDeleting(void) const; void SetDeleting(bool deleting); + bool IsLoading(void) { return m_IsLoading; } + bool IsLoaded(void) { return m_IsLoaded; } + void SetTextFromMap(QHash &infoMap); void ResetMap(QHash &infoMap); @@ -62,8 +68,15 @@ virtual void CreateCopy(MythUIType *parent); virtual bool ParseElement(QDomElement &element); + virtual void Load(void); // ONLY to be used for loading data, NO UI WORK + virtual void Init(void); // UI work to draw data loaded + + void LoadInBackground(void); + bool m_FullScreen; bool m_IsDeleting; + bool m_IsLoading; + bool m_IsLoaded; MythUIType *m_CurrentFocusWidget; //TODO We are currently dependant on the internal sorting of QMap for @@ -72,6 +85,7 @@ QMap m_FocusWidgetList; MythScreenStack *m_ScreenStack; + MythUIBusyDialog *m_BusyPopup; QRegion m_SavedMask; Index: libs/libmythui/mythscreenstack.cpp =================================================================== --- libs/libmythui/mythscreenstack.cpp (revision 22720) +++ libs/libmythui/mythscreenstack.cpp (working copy) @@ -180,7 +180,8 @@ void MythScreenStack::ScheduleInitIfNeeded(void) { // make sure Init() is called outside the paintEvent - if (m_DoInit && m_topScreen && !m_InitTimerStarted) + if (m_DoInit && m_topScreen && !m_InitTimerStarted && + !m_topScreen->IsLoading()) { m_InitTimerStarted = true; QTimer::singleShot(100, this, SLOT(doInit())); @@ -192,7 +193,11 @@ if (m_DoInit && m_topScreen) { m_DoInit = false; - m_topScreen->Init(); + + if (!m_topScreen->IsLoaded()) + m_topScreen->LoadInForeground(); + + m_topScreen->doInit(); } m_InitTimerStarted = false; } Index: libs/libmythui/mythscreentype.cpp =================================================================== --- libs/libmythui/mythscreentype.cpp (revision 22720) +++ libs/libmythui/mythscreentype.cpp (working copy) @@ -2,13 +2,32 @@ #include "mythscreentype.h" #include +#include +#include #include "mythverbose.h" #include "mythscreenstack.h" #include "mythmainwindow.h" #include "mythuihelper.h" +#include "mythprogressdialog.h" +class ScreenLoadTask : public QRunnable +{ + public: + ScreenLoadTask(MythScreenType *parent) : m_parent(parent) {} + + private: + void run() + { + if (m_parent) + m_parent->LoadInForeground(); + } + + MythScreenType *m_parent; +}; + + MythScreenType::MythScreenType(MythScreenStack *parent, const QString &name, bool fullscreen) : MythUIType(parent, name) @@ -17,7 +36,10 @@ m_CurrentFocusWidget = NULL; m_ScreenStack = parent; + m_BusyPopup = NULL; m_IsDeleting = false; + m_IsLoading = false; + m_IsLoaded = false; // Can be overridden, of course, but default to full sized. m_Area = GetMythMainWindow()->GetUIScreenRect(); @@ -226,12 +248,57 @@ return true; } +// This method should only load data, it should never perform UI routines +void MythScreenType::Load(void) +{ + // Virtual +} + +void MythScreenType::LoadInBackground(void) +{ + m_IsLoading = true; + + MythScreenStack *popupStack = + GetMythMainWindow()->GetStack("popup stack"); + QString message(tr("Loading...")); + m_BusyPopup = + new MythUIBusyDialog(message, popupStack, "mythscreentypebusydialog"); + + if (m_BusyPopup->Create()) + popupStack->AddScreen(m_BusyPopup, false); + + ScreenLoadTask *loadTask = new ScreenLoadTask(this); + QThreadPool::globalInstance()->start(loadTask); +} + +void MythScreenType::LoadInForeground(void) +{ + m_IsLoading = true; + Load(); + m_IsLoaded = true; + m_IsLoading = false; +} + +void MythScreenType::doInit(void) +{ + if (m_BusyPopup) + m_BusyPopup->Close(); + m_BusyPopup = NULL; + + Init(); +} + void MythScreenType::Init(void) { + // Virtual } void MythScreenType::Close(void) { + if (m_BusyPopup) + m_BusyPopup->Close(); + m_BusyPopup = NULL; + GetScreenStack()->PopScreen(this); } Index: programs/mythfrontend/playbackbox.cpp =================================================================== --- programs/mythfrontend/playbackbox.cpp (revision 22720) +++ programs/mythfrontend/playbackbox.cpp (working copy) @@ -469,9 +469,16 @@ connect(m_fillListTimer, SIGNAL(timeout()), SLOT(listChanged())); BuildFocusList(); + LoadInBackground(); return true; } +void PlaybackBox::Load() +{ + QMutexLocker locker(&m_progCacheLock); + m_progCache = RemoteGetRecordedList(m_allOrder == 0 || m_type == Delete); +} + void PlaybackBox::Init() { m_groupList->SetLCDTitles(tr("Groups")); Index: programs/mythfrontend/viewscheduled.h =================================================================== --- programs/mythfrontend/viewscheduled.h (revision 22720) +++ programs/mythfrontend/viewscheduled.h (working copy) @@ -53,8 +53,11 @@ void Close(void); private: + virtual void Load(void); + virtual void Init(void); + void FillList(void); - void LoadList(void); + void LoadList(bool useExistingData = false); void setShowAll(bool all); void viewCards(void); void viewInputs(void); Index: programs/mythfrontend/guidegrid.cpp =================================================================== --- programs/mythfrontend/guidegrid.cpp (revision 22720) +++ programs/mythfrontend/guidegrid.cpp (working copy) @@ -273,18 +273,46 @@ m_timeCount = m_guideGrid->getTimeCount() * 6; m_verticalLayout = m_guideGrid->isVerticalLayout(); - m_currentRow = (int)(m_channelCount / 2); - m_currentCol = 0; + m_currentEndTime = m_currentStartTime.addSecs(m_timeCount * 60 * 5); - fillTimeInfos(); + LoadInBackground(); + return true; +} + +void GuideGrid::Load(void) +{ + m_recList.FromScheduler(); fillChannelInfos(); + int maxchannel = max((int)GetChannelCount() - 1, 0); setStartChannel((int)(m_currentStartChannel) - (int)(m_channelCount / 2)); m_channelCount = min(m_channelCount, maxchannel + 1); + + for (int y = 0; y < m_channelCount; ++y) + { + int chanNum = y + m_currentStartChannel; + if (chanNum >= (int) m_channelInfos.size()) + chanNum -= (int) m_channelInfos.size(); + if (chanNum >= (int) m_channelInfos.size()) + continue; + + if (chanNum < 0) + chanNum = 0; + + m_programs[y] = getProgramListFromProgram(chanNum); + } +} + +void GuideGrid::Init(void) +{ + m_currentRow = (int)(m_channelCount / 2); + m_currentCol = 0; + + fillTimeInfos(); + updateChannels(); - m_recList.FromScheduler(); - fillProgramInfos(); + fillProgramInfos(true); updateInfo(); m_updateTimer = new QTimer(this); @@ -300,8 +328,6 @@ m_changroupname->SetText(changrpname); gContext->addListener(this); - - return true; } GuideGrid::~GuideGrid() @@ -958,25 +984,49 @@ m_currentEndTime = t; } -void GuideGrid::fillProgramInfos(void) +void GuideGrid::fillProgramInfos(bool useExistingData) { m_guideGrid->ResetData(); for (int y = 0; y < m_channelCount; ++y) { - fillProgramRowInfos(y); + fillProgramRowInfos(y, useExistingData); } } -void GuideGrid::fillProgramRowInfos(unsigned int row) +ProgramList *GuideGrid::getProgramListFromProgram(int chanNum) { + ProgramList *proglist = new ProgramList(); + + if (proglist) + { + MSqlBindings bindings; + QString querystr = "WHERE program.chanid = :CHANID " + " AND program.endtime >= :STARTTS " + " AND program.starttime <= :ENDTS " + " AND program.manualid = 0 "; + bindings[":CHANID"] = GetChannelInfo(chanNum)->chanid; + bindings[":STARTTS"] = m_currentStartTime.toString("yyyy-MM-ddThh:mm:00"); + bindings[":ENDTS"] = m_currentEndTime.toString("yyyy-MM-ddThh:mm:00"); + + proglist->FromProgram(querystr, bindings, m_recList); + } + + return proglist; +} + +void GuideGrid::fillProgramRowInfos(unsigned int row, bool useExistingData) +{ m_guideGrid->ResetRow(row); ProgramList *proglist; - if (m_programs[row]) - delete m_programs[row]; - m_programs[row] = NULL; + if (!useExistingData) + { + if (m_programs[row]) + delete m_programs[row]; + m_programs[row] = NULL; + } for (int x = 0; x < m_timeCount; ++x) { @@ -995,19 +1045,11 @@ if (chanNum < 0) chanNum = 0; - m_programs[row] = proglist = new ProgramList(); + if (useExistingData) + proglist = m_programs[row]; + else + m_programs[row] = proglist = getProgramListFromProgram(chanNum); - MSqlBindings bindings; - QString querystr = "WHERE program.chanid = :CHANID " - " AND program.endtime >= :STARTTS " - " AND program.starttime <= :ENDTS " - " AND program.manualid = 0 "; - bindings[":CHANID"] = GetChannelInfo(chanNum)->chanid; - bindings[":STARTTS"] = m_currentStartTime.toString("yyyy-MM-ddThh:mm:00"); - bindings[":ENDTS"] = m_currentEndTime.toString("yyyy-MM-ddThh:mm:00"); - - proglist->FromProgram(querystr, bindings, m_recList); - QDateTime ts = m_currentStartTime; QDateTime tnow = QDateTime::currentDateTime(); Index: programs/mythfrontend/viewscheduled.cpp =================================================================== --- programs/mythfrontend/viewscheduled.cpp (revision 22720) +++ programs/mythfrontend/viewscheduled.cpp (working copy) @@ -97,8 +97,6 @@ m_schedulesList->SetLCDTitles(tr("Scheduled Recordings"), "shortstarttimedate|channel|titlesubtitle|card"); - LoadList(); - if (m_groupList) { connect(m_groupList, SIGNAL(itemSelected(MythUIButtonListItem*)), @@ -112,10 +110,21 @@ EmbedTVWindow(); BuildFocusList(); + LoadInBackground(); return true; } +void ViewScheduled::Load() +{ + m_recList.FromScheduler(m_conflictBool); +} + +void ViewScheduled::Init() +{ + LoadList(true); +} + void ViewScheduled::Close() { // don't fade the screen if we are returning to the player @@ -222,7 +231,7 @@ } } -void ViewScheduled::LoadList(void) +void ViewScheduled::LoadList(bool useExistingData) { if (m_inFill) return; @@ -256,7 +265,8 @@ m_recgroupList.clear(); - m_recList.FromScheduler(m_conflictBool); + if (!useExistingData) + m_recList.FromScheduler(m_conflictBool); ProgramList::iterator pit = m_recList.begin(); QString currentDate; Index: programs/mythfrontend/playbackbox.h =================================================================== --- programs/mythfrontend/playbackbox.h (revision 22720) +++ programs/mythfrontend/playbackbox.h (working copy) @@ -119,6 +119,7 @@ ~PlaybackBox(void); bool Create(void); + virtual void Load(void); virtual void Init(void); bool keyPressEvent(QKeyEvent *); void customEvent(QEvent *event); Index: programs/mythfrontend/guidegrid.h =================================================================== --- programs/mythfrontend/guidegrid.h (revision 22720) +++ programs/mythfrontend/guidegrid.h (working copy) @@ -94,6 +94,8 @@ virtual void SetJumpToChannel(JumpToChannel *ptr); bool Create(void); + virtual void Load(void); + virtual void Init(void); bool keyPressEvent(QKeyEvent *event); virtual void aboutToShow(); @@ -163,8 +165,9 @@ void fillChannelInfos(bool gotostartchannel = true); void fillTimeInfos(void); - void fillProgramInfos(void); - void fillProgramRowInfos(unsigned int row); + void fillProgramInfos(bool useExistingData = false); + void fillProgramRowInfos(unsigned int row, bool useExistingData = false); + ProgramList *getProgramListFromProgram(int chanNum); void setStartChannel(int newStartChannel);