MythTV  0.26-pre
logviewer.cpp
Go to the documentation of this file.
00001 #include <unistd.h>
00002 #include <iostream>
00003 #include <cstdlib>
00004 
00005 // qt
00006 #include <QKeyEvent>
00007 #include <QFile>
00008 #include <QTextStream>
00009 
00010 // mythtv
00011 #include <mythcontext.h>
00012 #include <mythdbcon.h>
00013 #include <mythmainwindow.h>
00014 #include <mythdialogbox.h>
00015 #include <mythuibutton.h>
00016 #include <mythuibuttonlist.h>
00017 #include <mythuitext.h>
00018 
00019 // mytharchive
00020 #include "archiveutil.h"
00021 #include "logviewer.h"
00022 
00023 const int DEFAULT_UPDATE_TIME = 5;
00024 
00025 void showLogViewer(void)
00026 {
00027     MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00028     QString logDir = getTempDirectory() + "logs";
00029 
00030     // do any logs exist?
00031     if (QFile::exists(logDir + "/progress.log") || QFile::exists(logDir + "/mythburn.log"))
00032     {
00033         LogViewer *viewer = new LogViewer(mainStack);
00034         viewer->setFilenames(logDir + "/progress.log", logDir + "/mythburn.log");
00035         if (viewer->Create())
00036             mainStack->AddScreen(viewer);
00037     }
00038     else
00039         showWarningDialog(QObject::tr("Cannot find any logs to show!"));
00040 }
00041 
00042 LogViewer::LogViewer(MythScreenStack *parent) :
00043     MythScreenType(parent, "logviewer"),
00044     m_autoUpdate(false),
00045     m_updateTime(DEFAULT_UPDATE_TIME),
00046     m_updateTimer(NULL),
00047     m_currentLog(),
00048     m_progressLog(),
00049     m_fullLog(),
00050     m_logList(NULL),
00051     m_logText(NULL),
00052     m_exitButton(NULL),
00053     m_cancelButton(NULL),
00054     m_updateButton(NULL)
00055 {
00056     m_updateTime = gCoreContext->GetNumSetting(
00057         "LogViewerUpdateTime", DEFAULT_UPDATE_TIME);
00058     m_autoUpdate = gCoreContext->GetNumSetting("LogViewerAutoUpdate", 1);
00059 }
00060 
00061 LogViewer::~LogViewer(void)
00062 {
00063     gCoreContext->SaveSetting("LogViewerUpdateTime", m_updateTime);
00064     gCoreContext->SaveSetting("LogViewerAutoUpdate", m_autoUpdate ? "1" : "0");
00065 
00066     if (m_updateTimer)
00067         delete m_updateTimer;
00068 }
00069 
00070 bool LogViewer::Create(void)
00071 {
00072     bool foundtheme = false;
00073 
00074     // Load the theme for this screen
00075     foundtheme = LoadWindowFromXML("mytharchive-ui.xml", "logviewer", this);
00076 
00077     if (!foundtheme)
00078         return false;
00079 
00080     bool err = false; 
00081     UIUtilE::Assign(this, m_logList, "loglist", &err);
00082     UIUtilE::Assign(this, m_logText, "logitem_text", &err);
00083     UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
00084     UIUtilE::Assign(this, m_updateButton, "update_button", &err);
00085     UIUtilE::Assign(this, m_exitButton, "exit_button", &err);
00086 
00087     if (err)
00088     {
00089         LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'logviewer'");
00090         return false;
00091     }
00092 
00093     connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelClicked()));
00094     connect(m_updateButton, SIGNAL(Clicked()), this, SLOT(updateClicked()));
00095     connect(m_exitButton, SIGNAL(Clicked()), this, SLOT(Close()));
00096 
00097     connect(m_logList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00098             this, SLOT(updateLogItem(MythUIButtonListItem*)));
00099 
00100     m_updateTimer = NULL;
00101     m_updateTimer = new QTimer(this);
00102     connect(m_updateTimer, SIGNAL(timeout()), SLOT(updateTimerTimeout()) );
00103 
00104     BuildFocusList();
00105 
00106     SetFocusWidget(m_logList);
00107 
00108     return true;
00109 }
00110 
00111 void LogViewer::Init(void)
00112 {
00113     updateClicked();
00114     if (m_logList->GetCount() > 0)
00115         m_logList->SetItemCurrent(m_logList->GetCount() - 1);
00116 }
00117 
00118 bool LogViewer::keyPressEvent(QKeyEvent *event)
00119 {
00120     if (GetFocusWidget()->keyPressEvent(event))
00121          return true;
00122 
00123     bool handled = false;
00124     QStringList actions;
00125     handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
00126 
00127     for (int i = 0; i < actions.size() && !handled; i++)
00128     {
00129         QString action = actions[i];
00130         handled = true;
00131 
00132         if (action == "MENU")
00133             showMenu();
00134         else
00135             handled = false;
00136     }
00137 
00138     if (!handled && MythScreenType::keyPressEvent(event))
00139         handled = true;
00140 
00141     return handled;
00142 }
00143 
00144 void LogViewer::updateTimerTimeout()
00145 {
00146     updateClicked();
00147 }
00148 
00149 void LogViewer::toggleAutoUpdate(void)
00150 {
00151     m_autoUpdate = ! m_autoUpdate;
00152 
00153     if (m_autoUpdate)
00154         m_updateTimer->start(m_updateTime * 1000);
00155     else
00156         m_updateTimer->stop();
00157 }
00158 
00159 void LogViewer::updateLogItem(MythUIButtonListItem *item)
00160 {
00161     if (item)
00162         m_logText->SetText(item->GetText());
00163 }
00164 
00165 void LogViewer::cancelClicked(void)
00166 {
00167     QString tempDir = gCoreContext->GetSetting("MythArchiveTempDir", "");
00168     QFile lockFile(tempDir + "/logs/mythburncancel.lck");
00169 
00170     if (!lockFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
00171         LOG(VB_GENERAL, LOG_ERR,
00172             "LogViewer: Failed to create mythburncancel.lck file");
00173 
00174     lockFile.write("Cancel\n\r");
00175     lockFile.close();
00176 
00177     ShowOkPopup(QObject::tr("Background creation has been asked to stop.\n" 
00178                             "This may take a few minutes."));
00179 }
00180 
00181 void LogViewer::updateClicked(void)
00182 {
00183     m_updateTimer->stop();
00184 
00185     QStringList list;
00186     loadFile(m_currentLog, list, m_logList->GetCount());
00187 
00188     if (list.size() > 0)
00189     {
00190         bool bUpdateCurrent =
00191                 (m_logList->GetCount() == m_logList->GetCurrentPos() + 1) ||
00192                 (m_logList->GetCurrentPos() == 0);
00193 
00194         for (int x = 0; x < list.size(); x++)
00195             new MythUIButtonListItem(m_logList, list[x]);
00196 
00197         if (bUpdateCurrent)
00198             m_logList->SetItemCurrent(m_logList->GetCount() - 1);
00199     }
00200 
00201     bool bRunning = (getSetting("MythArchiveLastRunStatus") == "Running");
00202 
00203     if (!bRunning)
00204     {
00205         m_cancelButton->SetEnabled(false);
00206         m_updateButton->SetEnabled(false);
00207     }
00208 
00209     if (m_autoUpdate)
00210     {
00211         if (m_logList->GetCount() > 0)
00212             m_updateTimer->start(m_updateTime * 1000);
00213         else
00214             m_updateTimer->start(500);
00215     }
00216 }
00217 
00218 QString LogViewer::getSetting(const QString &key)
00219 {
00220     // read the setting direct from the DB rather than from the settings cache 
00221     // which isn't aware that the script may have changed something
00222     MSqlQuery query(MSqlQuery::InitCon());
00223     if (query.isConnected())
00224     {
00225         query.prepare("SELECT data FROM settings WHERE value = :VALUE "
00226                 "AND hostname = :HOSTNAME ;");
00227         query.bindValue(":VALUE", key);
00228         query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
00229 
00230         if (query.exec() && query.next())
00231         {
00232             return query.value(0).toString();
00233         }
00234     }
00235     else
00236     {
00237         LOG(VB_GENERAL, LOG_ERR, 
00238             QString("Database not open while trying to load setting: %1")
00239                 .arg(key));
00240     }
00241 
00242     return QString("");
00243 }
00244 
00245 bool LogViewer::loadFile(QString filename, QStringList &list, int startline)
00246 {
00247     list.clear();
00248 
00249     QFile file(filename);
00250 
00251     if (!file.exists())
00252         return false;
00253 
00254     if (file.open( QIODevice::ReadOnly ))
00255     {
00256         QString s;
00257         QTextStream stream(&file);
00258 
00259          // ignore the first startline lines
00260         while ( !stream.atEnd() && startline > 0)
00261         {
00262             stream.readLine();
00263             startline--;
00264         }
00265 
00266          // read rest of file
00267         while ( !stream.atEnd() )
00268         {
00269             s = stream.readLine();
00270             list.append(s);
00271         }
00272         file.close();
00273     }
00274     else
00275         return false;
00276 
00277     return true;
00278 }
00279 
00280 void LogViewer::setFilenames(const QString &progressLog, const QString &fullLog)
00281 {
00282     m_progressLog = progressLog;
00283     m_fullLog = fullLog;
00284     m_currentLog = progressLog;
00285 }
00286 
00287 void LogViewer::showProgressLog(void)
00288 {
00289     m_currentLog = m_progressLog;
00290     m_logList->Reset();
00291     updateClicked();
00292 }
00293 
00294 void LogViewer::showFullLog(void)
00295 {
00296     m_currentLog = m_fullLog;
00297     m_logList->Reset();
00298     updateClicked();
00299 }
00300 
00301 void LogViewer::showMenu()
00302 {
00303     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00304     MythDialogBox *menuPopup = new MythDialogBox(tr("Menu"), popupStack, "actionmenu");
00305 
00306     if (menuPopup->Create())
00307         popupStack->AddScreen(menuPopup);
00308 
00309     menuPopup->SetReturnEvent(this, "action");
00310 
00311     if (m_autoUpdate)
00312         menuPopup->AddButton(tr("Don't Auto Update"), SLOT(toggleAutoUpdate()));
00313     else
00314         menuPopup->AddButton(tr("Auto Update"), SLOT(toggleAutoUpdate()));
00315 
00316     menuPopup->AddButton(tr("Show Progress Log"), SLOT(showProgressLog()));
00317     menuPopup->AddButton(tr("Show Full Log"), SLOT(showFullLog()));
00318 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends