示例#1
0
class MainWin(KMainWindow):

    """Main window"""

    SB_TEXT = 1
    SB_TIMEOUT = 10000
    MON_TIMEOUT = 1000
    CHANGE_TIMEOUT = 3001

    def __init__(self, *args):
        apply(KMainWindow.__init__, (self,) + args)
        
        self.lastDir = "/var/log"
        self.monitors = []
        self.currentPage = None
        self.tab = QTabWidget(self)
        self.settingsDlg = SettingsDlg(self)
        self.cfg = LoviConfig().getInstance()
        self.bellIcon = \
            QIconSet(KIconLoader().loadIcon("idea", KIcon.Small, 11))
        self.noIcon = QIconSet()
        self.findDlg = KEdFind(self, "find", False)
        self.connect(self.findDlg, SIGNAL("search()"), self.doFind)
        
        self.setCentralWidget(self.tab)
        self.connect(self.tab, SIGNAL("currentChanged(QWidget *)"), 
            self.onPageChange)
        self.setGeometry(0, 0, 600, 400)
        self.setCaption(makeCaption("(none)"))

        # Timers
        self.timer = QTimer(self)
        self.timer.start(MainWin.MON_TIMEOUT)
        self.statusTimer = QTimer(self)
        self.connect(self.statusTimer, SIGNAL("timeout()"), 
            self.onStatusTimeout)
        self.changeTimer = QTimer(self)
        self.changeTimer.start(MainWin.CHANGE_TIMEOUT)
        self.connect(self.changeTimer, SIGNAL("timeout()"),
            self.onChangeTimeout)

        # Initialize actions
        actions = self.actionCollection()
        self.openAction = KStdAction.open(self.onOpen, actions)
        self.closeAction = KStdAction.close(self.onClose, actions)
        self.closeAction.setEnabled(False)
        self.quitAction = KStdAction.quit(self.onQuit, actions)
        self.copyAction = KStdAction.copy(self.onCopy, actions)
        self.copyAction.setEnabled(False)
        self.clearAction = KStdAction.clear(self.onClear, actions)
        self.clearAction.setEnabled(False)
        self.selectAllAction = KStdAction.selectAll(self.onSelectAll, actions)
        self.selectAllAction.setEnabled(False)
        self.addBookmarkAction = \
            KStdAction.addBookmark(self.onAddBookmark, actions)
        self.addBookmarkAction.setEnabled(False)
        self.settingsAction = KStdAction.preferences(self.onSettings, actions)
        self.findAction = KStdAction.find(self.onFind, actions)
        self.findAction.setEnabled(False)
        self.findNextAction = KStdAction.findNext(self.onFindNext, actions)
        self.findNextAction.setEnabled(False)
        self.findPrevAction = KStdAction.findPrev(self.onFindPrev, actions)
        self.findPrevAction.setEnabled(False)
        
        # Initialize menus
        
        fileMenu = QPopupMenu(self)
        self.openAction.plug(fileMenu)
        self.closeAction.plug(fileMenu)
        fileMenu.insertSeparator()
        self.quitAction.plug(fileMenu)
        self.menuBar().insertItem(i18n("&File"), fileMenu)
        
        editMenu = QPopupMenu(self)
        self.copyAction.plug(editMenu)
        self.clearAction.plug(editMenu)
        editMenu.insertSeparator()
        self.selectAllAction.plug(editMenu)
        self.addBookmarkAction.plug(editMenu)
        editMenu.insertSeparator()
        self.findAction.plug(editMenu)
        self.findNextAction.plug(editMenu)
        self.findPrevAction.plug(editMenu)
        self.menuBar().insertItem(i18n("&Edit"), editMenu)
        
        settingsMenu = QPopupMenu(self)
        self.settingsAction.plug(settingsMenu)
        self.menuBar().insertItem(i18n("&Settings"), settingsMenu)
        
        helpMenu = self.helpMenu("")
        self.menuBar().insertItem(i18n("&Help"), helpMenu)
        
        # Initialize status bar
        self.sb = self.statusBar()
        self.bell = BellButton(None)
        self.displayStatus(False, "")
        
    def displayStatus(self, changed, msg):
        """Display a message in the status bar."""
        self.statusTimer.stop()
        self.sb.removeWidget(self.bell)
        self.sb.removeItem(MainWin.SB_TEXT)
        if changed:
            self.sb.addWidget(self.bell, 1, False)
        self.sb.insertItem(msg, MainWin.SB_TEXT, 1000, True)
        self.sb.setItemAlignment(MainWin.SB_TEXT, 
                                 Qt.AlignLeft|Qt.AlignVCenter)
        self.statusTimer.start(MainWin.SB_TIMEOUT, True)
       
    def onOpen(self, id = -1):
        """Open file for monitoring."""
        fileName = KFileDialog.getOpenFileName(self.lastDir, "*", self, 
            str(i18n("Open Log File")))
        if not fileName.isEmpty():
            fileName = str(fileName)
            self.lastDir = os.path.dirname(fileName)
            self.monitor(fileName)
    
    def onClose(self, id = -1):
        """Close a monitored file."""
        self.monitors.remove(self.currentPage)
        self.currentPage.close()
        self.tab.removePage(self.currentPage)
        self.displayStatus(False, "")
        self.saveFileList()
        if len(self.monitors) == 0:
            # Update interface when the last page is deleted
            self.setCaption(makeCaption("(none)"))
            self.closeAction.setEnabled(False)
            self.copyAction.setEnabled(False)
            self.selectAllAction.setEnabled(False)
            self.clearAction.setEnabled(False)
            self.addBookmarkAction.setEnabled(False)
            self.findAction.setEnabled(False)
            self.findNextAction.setEnabled(False)
            self.findPrevAction.setEnabled(False)

    def onQuit(self, id = -1):
        """Quit application."""
        self.close()
        
    def onCopy(self, id = -1):
        """Copy text to clipboard."""
        self.currentPage.copy()
        
    def onClear(self, id = -1):
        """Clear text window."""
        self.currentPage.setText("")
        
    def onSelectAll(self, id = -1):
        """Select all text."""
        self.currentPage.selectAll(True)
        
    def onAddBookmark(self, id = -1):
        """Add a bookmark to the log."""
        bookmark = "<font color=\"blue\">"
        bookmark += datetime.datetime.now().strftime("%b %d %H:%M:%S ")
        bookmark += "--------------------------------------------------------"
        bookmark += "</font>"
        self.currentPage.append(bookmark)
    
    def onSettings(self, id = -1):
        """Display settings dialog"""
        if self.settingsDlg.exec_loop():
            self.cfg.writeConfig()
            self.cfg.processConfig()
            self.reconfigure()
        
    def onPageChange(self, page):
        """Update widget when the top level tab changes."""
        self.currentPage = page
        self.setCaption(makeCaption(os.path.basename(page.getFileName())))
        self.copyAction.setEnabled(page.hasSelectedText())
        # self.tab.setTabIconSet(page, self.noIcon)
                        
    def onStatusTimeout(self):
        """Clear status bar on timeout."""
        self.displayStatus(False, "")
        for m in self.monitors:
            self.tab.setTabIconSet(m, self.noIcon)
        
    def onChangeTimeout(self):
        """Look for changes in monitored files. """
        changeList = []
        for m in self.monitors:
            if m.isChanged():
                changeList.append(os.path.basename(m.getFileName()))
                self.tab.setTabIconSet(m, self.bellIcon)
        if len(changeList):
            msg = changeList[0]
            for f in changeList[1:]:
                msg += ", %s" % f
            msg = str(i18n("Change to %s")) % msg
            self.displayStatus(True, msg)
            
    def onCopyAvailable(self, available):
        """Update Copy menu item when there is a selection available."""
        self.copyAction.setEnabled(available)
        
    def onFind(self):
        self.findDlg.show()
    
    def onFindPrev(self):
        if self.findDlg.getText() == "":
            self.onFind()
        else:
            self.currentPage.find(self.findDlg.getText(), 
                self.findDlg.case_sensitive(), True)
    
    def onFindNext(self):
        if self.findDlg.getText() == "":
            self.onFind()
        else:
            self.currentPage.find(self.findDlg.getText(), 
                self.findDlg.case_sensitive(), False)

    def monitor(self, fileName):
        """Start monitoring a file."""
        try:
            tailer = Tail(fileName)
        except:
            KMessageBox.error(self, 
                str(i18n("Cannot open file for monitoring:\n%s")) % 
                    fileName, makeCaption("Error"))
            return
        mon = Monitor(self.tab, tailer)
        base = os.path.basename(fileName)
        self.monitors.append(mon)
        self.tab.addTab(mon, base)
        self.tab.showPage(mon)
        self.tab.setTabToolTip(mon, fileName)
        self.currentPage = mon
        self.setCaption(makeCaption(base))
        self.displayStatus(False, str(i18n("Monitoring %s")) % fileName)
        self.connect(self.timer, SIGNAL("timeout()"), mon.follow)
        self.saveFileList()
        self.connect(mon, SIGNAL("copyAvailable(bool)"), self.onCopyAvailable)
        self.closeAction.setEnabled(True)
        self.copyAction.setEnabled(False)
        self.clearAction.setEnabled(True)
        self.selectAllAction.setEnabled(True)
        self.addBookmarkAction.setEnabled(True)
        self.findAction.setEnabled(True)
        self.findNextAction.setEnabled(True)
        self.findPrevAction.setEnabled(True)
        
    def saveFileList(self):
        """Update the list of monitored files in the configuration file."""
        files = []
        for mon in self.monitors:
            files.append(mon.getFileName())
        cfg = KApplication.kApplication().config()
        cfg.setGroup("Monitor")
        cfg.writeEntry("files", files)
        
    def reconfigure(self):
        """Update self with configuration changes."""
        for mon in self.monitors:
            mon.reconfigure()
            
    def doFind(self):
        self.currentPage.find(self.findDlg.getText(), 
            self.findDlg.case_sensitive(), self.findDlg.get_direction())