Example #1
0
class TrayStarter(QSystemTrayIcon):
    """
    Class implementing a starter for the system tray.
    """
    def __init__(self):
        """
        Constructor
        """
        QSystemTrayIcon.__init__(self, 
            UI.PixmapCache.getIcon(
                unicode(Preferences.getTrayStarter("TrayStarterIcon"))))
        
        self.maxMenuFilePathLen = 75
        
        self.rsettings = QSettings(QSettings.IniFormat, 
            QSettings.UserScope, 
            Globals.settingsNameOrganization, 
            Globals.settingsNameRecent)
        
        self.recentProjects = QStringList()
        self.__loadRecentProjects()
        self.recentMultiProjects = QStringList()
        self.__loadRecentMultiProjects()
        self.recentFiles = QStringList()
        self.__loadRecentFiles()
        
        self.connect(self, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"),
                     self.__activated)
        
        self.__menu = QMenu(self.trUtf8("Eric4 tray starter"))
        
        self.recentProjectsMenu = QMenu(self.trUtf8('Recent Projects'), self.__menu)
        self.connect(self.recentProjectsMenu, SIGNAL('aboutToShow()'), 
                     self.__showRecentProjectsMenu)
        self.connect(self.recentProjectsMenu, SIGNAL('triggered(QAction *)'),
                     self.__openRecent)
        
        self.recentMultiProjectsMenu = \
            QMenu(self.trUtf8('Recent Multiprojects'), self.__menu)
        self.connect(self.recentMultiProjectsMenu, SIGNAL('aboutToShow()'), 
                     self.__showRecentMultiProjectsMenu)
        self.connect(self.recentMultiProjectsMenu, SIGNAL('triggered(QAction *)'),
                     self.__openRecent)
        
        self.recentFilesMenu = QMenu(self.trUtf8('Recent Files'), self.__menu)
        self.connect(self.recentFilesMenu, SIGNAL('aboutToShow()'), 
                     self.__showRecentFilesMenu)
        self.connect(self.recentFilesMenu, SIGNAL('triggered(QAction *)'),
                     self.__openRecent)
        
        act = self.__menu.addAction(
            self.trUtf8("Eric4 tray starter"), self.__about)
        font = act.font()
        font.setBold(True)
        act.setFont(font)
        self.__menu.addSeparator()
        
        self.__menu.addAction(self.trUtf8("QRegExp editor"), self.__startQRegExp)
        self.__menu.addAction(self.trUtf8("Python re editor"), self.__startPyRe)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("uiPreviewer.png"),
            self.trUtf8("UI Previewer"), self.__startUIPreviewer)
        self.__menu.addAction(UI.PixmapCache.getIcon("trPreviewer.png"),
            self.trUtf8("Translations Previewer"), self.__startTRPreviewer)
        self.__menu.addAction(UI.PixmapCache.getIcon("unittest.png"),
            self.trUtf8("Unittest"), self.__startUnittest)
        self.__menu.addAction(UI.PixmapCache.getIcon("ericWeb.png"),
            self.trUtf8("eric4 Web Browser"), self.__startHelpViewer)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("diffFiles.png"),
            self.trUtf8("Compare Files"), self.__startDiff)
        self.__menu.addAction(UI.PixmapCache.getIcon("compareFiles.png"),
            self.trUtf8("Compare Files side by side"), self.__startCompare)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("sqlBrowser.png"), 
            self.trUtf8("SQL Browser"), self.__startSqlBrowser)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("iconEditor.png"), 
            self.trUtf8("Icon Editor"), self.__startIconEditor)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("pluginInstall.png"),
            self.trUtf8("Install Plugin"), self.__startPluginInstall)
        self.__menu.addAction(UI.PixmapCache.getIcon("pluginUninstall.png"),
            self.trUtf8("Uninstall Plugin"), self.__startPluginUninstall)
        self.__menu.addAction(UI.PixmapCache.getIcon("pluginRepository.png"),
            self.trUtf8("Plugin Repository"), self.__startPluginRepository)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("configure.png"),
            self.trUtf8('Preferences'), self.__startPreferences)
        self.__menu.addAction(UI.PixmapCache.getIcon("erict.png"),
            self.trUtf8("eric4 IDE"), self.__startEric)
        self.__menu.addAction(UI.PixmapCache.getIcon("editor.png"), 
            self.trUtf8("eric4 Mini Editor"), self.__startMiniEditor)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("configure.png"),
            self.trUtf8('Preferences (tray starter)'), self.__showPreferences)
        self.__menu.addSeparator()
        
        # recent files
        self.menuRecentFilesAct = self.__menu.addMenu(self.recentFilesMenu)
        # recent multi projects
        self.menuRecentMultiProjectsAct = \
            self.__menu.addMenu(self.recentMultiProjectsMenu)
        # recent projects
        self.menuRecentProjectsAct = self.__menu.addMenu(self.recentProjectsMenu)
        self.__menu.addSeparator()
        
        self.__menu.addAction(UI.PixmapCache.getIcon("exit.png"),
            self.trUtf8('Quit'), qApp.quit)
    
    def __loadRecentProjects(self):
        """
        Private method to load the recently opened project filenames.
        """
        rp = self.rsettings.value(Globals.recentNameProject)
        if rp.isValid():
            for f in rp.toStringList():
                if QFileInfo(f).exists():
                    self.recentProjects.append(f)
    
    def __loadRecentMultiProjects(self):
        """
        Private method to load the recently opened multi project filenames.
        """
        rmp = self.rsettings.value(Globals.recentNameMultiProject)
        if rmp.isValid():
            for f in rmp.toStringList():
                if QFileInfo(f).exists():
                    self.recentMultiProjects.append(f)
    
    def __loadRecentFiles(self):
        """
        Private method to load the recently opened filenames.
        """
        rf = self.rsettings.value(Globals.recentNameFiles)
        if rf.isValid():
            for f in rf.toStringList():
                if QFileInfo(f).exists():
                    self.recentFiles.append(f)
    
    def __activated(self, reason):
        """
        Private slot to handle the activated signal.
        
        @param reason reason code of the signal (QSystemTrayIcon.ActivationReason)
        """
        if reason == QSystemTrayIcon.Context or \
           reason == QSystemTrayIcon.MiddleClick:
            self.__showContextMenu()
        elif reason == QSystemTrayIcon.DoubleClick:
            self.__startEric()
    
    def __showContextMenu(self):
        """
        Private slot to show the context menu.
        """
        self.menuRecentProjectsAct.setEnabled(len(self.recentProjects) > 0)
        self.menuRecentMultiProjectsAct.setEnabled(len(self.recentMultiProjects) > 0)
        self.menuRecentFilesAct.setEnabled(len(self.recentFiles) > 0)
        
        pos = QCursor.pos()
        x = pos.x() - self.__menu.sizeHint().width()
        pos.setX(x > 0 and x or 0)
        y = pos.y() - self.__menu.sizeHint().height()
        pos.setY(y > 0 and y or 0)
        self.__menu.popup(pos)
    
    def __startProc(self, applName, *applArgs):
        """
        Private method to start an eric4 application.
        
        @param applName name of the eric4 application script (string)
        @param *applArgs variable list of application arguments
        """
        proc = QProcess()
        applPath = os.path.join(getConfig("ericDir"), applName)
        
        args = QStringList()
        args.append(applPath)
        for arg in applArgs:
            args.append(unicode(arg))
        
        if not os.path.isfile(applPath) or not proc.startDetached(sys.executable, args):
            QMessageBox.critical(self,
                self.trUtf8('Process Generation Error'),
                self.trUtf8(
                    '<p>Could not start the process.<br>'
                    'Ensure that it is available as <b>%1</b>.</p>'
                ).arg(applPath),
                self.trUtf8('OK'))
    
    def __startMiniEditor(self):
        """
        Private slot to start the eric4 Mini Editor.
        """
        self.__startProc("eric4_editor.py", "--config=%s" % Utilities.getConfigDir())
    
    def __startEric(self):
        """
        Private slot to start the eric4 IDE.
        """
        self.__startProc("eric4.py", "--config=%s" % Utilities.getConfigDir())

    def __startPreferences(self):
        """
        Private slot to start the eric4 configuration dialog.
        """
        self.__startProc("eric4_configure.py", "--config=%s" % Utilities.getConfigDir())

    def __startPluginInstall(self):
        """
        Private slot to start the eric4 plugin installation dialog.
        """
        self.__startProc("eric4_plugininstall.py", 
                         "--config=%s" % Utilities.getConfigDir())

    def __startPluginUninstall(self):
        """
        Private slot to start the eric4 plugin uninstallation dialog.
        """
        self.__startProc("eric4_pluginuninstall.py", 
                         "--config=%s" % Utilities.getConfigDir())

    def __startPluginRepository(self):
        """
        Private slot to start the eric4 plugin repository dialog.
        """
        self.__startProc("eric4_pluginrepository.py", 
                         "--config=%s" % Utilities.getConfigDir())

    def __startHelpViewer(self):
        """
        Private slot to start the eric4 web browser.
        """
        self.__startProc("eric4_webbrowser.py", "--config=%s" % Utilities.getConfigDir())

    def __startUIPreviewer(self):
        """
        Private slot to start the eric4 UI previewer.
        """
        self.__startProc("eric4_uipreviewer.py", "--config=%s" % Utilities.getConfigDir())

    def __startTRPreviewer(self):
        """
        Private slot to start the eric4 translations previewer.
        """
        self.__startProc("eric4_trpreviewer.py", "--config=%s" % Utilities.getConfigDir())

    def __startUnittest(self):
        """
        Private slot to start the eric4 unittest dialog.
        """
        self.__startProc("eric4_unittest.py", "--config=%s" % Utilities.getConfigDir())

    def __startDiff(self):
        """
        Private slot to start the eric4 diff dialog.
        """
        self.__startProc("eric4_diff.py", "--config=%s" % Utilities.getConfigDir())

    def __startCompare(self):
        """
        Private slot to start the eric4 compare dialog.
        """
        self.__startProc("eric4_compare.py", "--config=%s" % Utilities.getConfigDir())
    
    def __startSqlBrowser(self):
        """
        Private slot to start the eric4 sql browser dialog.
        """
        self.__startProc("eric4_sqlbrowser.py", "--config=%s" % Utilities.getConfigDir())

    def __startIconEditor(self):
        """
        Private slot to start the eric4 icon editor dialog.
        """
        self.__startProc("eric4_iconeditor.py", "--config=%s" % Utilities.getConfigDir())

    def __startQRegExp(self):
        """
        Private slot to start the eric4 QRegExp editor dialog.
        """
        self.__startProc("eric4_qregexp.py", "--config=%s" % Utilities.getConfigDir())

    def __startPyRe(self):
        """
        Private slot to start the eric4 Python re editor dialog.
        """
        self.__startProc("eric4_re.py", "--config=%s" % Utilities.getConfigDir())

    def __showRecentProjectsMenu(self):
        """
        Private method to set up the recent projects menu.
        """
        self.recentProjects.clear()
        self.rsettings.sync()
        self.__loadRecentProjects()
        
        self.recentProjectsMenu.clear()
        
        idx = 1
        for rp in self.recentProjects:
            if idx < 10:
                formatStr = '&%d. %s'
            else:
                formatStr = '%d. %s'
            act = self.recentProjectsMenu.addAction(\
                formatStr % (idx, 
                    Utilities.compactPath(unicode(rp), self.maxMenuFilePathLen)))
            act.setData(QVariant(rp))
            idx += 1
    
    def __showRecentMultiProjectsMenu(self):
        """
        Private method to set up the recent multi projects menu.
        """
        self.recentMultiProjects.clear()
        self.rsettings.sync()
        self.__loadRecentMultiProjects()
        
        self.recentMultiProjectsMenu.clear()
        
        idx = 1
        for rmp in self.recentMultiProjects:
            if idx < 10:
                formatStr = '&%d. %s'
            else:
                formatStr = '%d. %s'
            act = self.recentMultiProjectsMenu.addAction(\
                formatStr % (idx, 
                    Utilities.compactPath(unicode(rmp), self.maxMenuFilePathLen)))
            act.setData(QVariant(rmp))
            idx += 1
    
    def __showRecentFilesMenu(self):
        """
        Private method to set up the recent files menu.
        """
        self.recentFiles.clear()
        self.rsettings.sync()
        self.__loadRecentFiles()
        
        self.recentFilesMenu.clear()
        
        idx = 1
        for rf in self.recentFiles:
            if idx < 10:
                formatStr = '&%d. %s'
            else:
                formatStr = '%d. %s'
            act = self.recentFilesMenu.addAction(\
                formatStr % (idx, 
                    Utilities.compactPath(unicode(rf), self.maxMenuFilePathLen)))
            act.setData(QVariant(rf))
            idx += 1
    
    def __openRecent(self, act):
        """
        Private method to open a project or file from the list of rencently opened 
        projects or files.
        
        @param act reference to the action that triggered (QAction)
        """
        filename = unicode(act.data().toString())
        if filename:
            self.__startProc("eric4.py", filename)
    
    def __showPreferences(self):
        """
        Private slot to set the preferences.
        """
        from Preferences.ConfigurationDialog import ConfigurationDialog
        dlg = ConfigurationDialog(None, 'Configuration', True, 
                                  fromEric = True, 
                                  displayMode = ConfigurationDialog.TrayStarterMode)
        self.connect(dlg, SIGNAL('preferencesChanged'), self.preferencesChanged)
        dlg.show()
        dlg.showConfigurationPageByName("trayStarterPage")
        dlg.exec_()
        QApplication.processEvents()
        if dlg.result() == QDialog.Accepted:
            dlg.setPreferences()
            Preferences.syncPreferences()
            self.preferencesChanged()
    
    def preferencesChanged(self):
        """
        Public slot to handle a change of preferences.
        """
        self.setIcon(
            UI.PixmapCache.getIcon(
                unicode(Preferences.getTrayStarter("TrayStarterIcon"))))

    def __about(self):
        """
        Private slot to handle the About dialog.
        """
        from Plugins.AboutPlugin.AboutDialog import AboutDialog
        dlg = AboutDialog()
        dlg.exec_()
Example #2
0
class Player(QWidget):
    def __init__(self,app):
        super(Player,self).__init__()
        self.mpd   = app.mpd
        self.ih    = app.imagehelper
        self.timer = None
        self.initGUI()
        self.initState()
        
    def initGUI(self):
        self.setWindowTitle(QApplication.applicationName())
        self.fmt = QFontMetrics(QFont())
        layout = QVBoxLayout()
        
        toplayout = QHBoxLayout()
        currentLayout = QGridLayout()
        currentLayout.setContentsMargins(0,20,0,20)
        currentLayout.setHorizontalSpacing(100)
        currentLayout.setVerticalSpacing(20)
        # current song information
        currentLayout.addWidget(QLabel("<b>Artist</b>"),1,0)
        self.artist = QLabel()
        currentLayout.addWidget(self.artist,1,1)
        currentLayout.addWidget(QLabel("<b>Title</b>"),2,0)
        self.title  = QLabel()
        currentLayout.addWidget(self.title,2,1)
        currentLayout.addWidget(QLabel("<b>Albumartist</b>"),3,0)
        self.albumartist = QLabel()
        currentLayout.addWidget(self.albumartist,3,1)
        currentLayout.addWidget(QLabel("<b>Album</b>"),4,0)
        self.album  = QLabel()
        currentLayout.addWidget(self.album,4,1)
        # playlist and song position
        self.playlistposition = QLabel()
        currentLayout.addWidget(self.playlistposition,5,0)
        poslayout = QHBoxLayout()
        poslayout.setSpacing(10)
        self.time = QLabel("00:00")
        poslayout.addWidget(self.time)
        self.position = QSlider(Qt.Horizontal)
        self.position.setTracking(False)
        self.position.setSingleStep(10)
        self.position.sliderReleased.connect( self.seek)
        self.position.sliderMoved.connect(
            lambda x: self.time.setText(self.mpd.timeString(x)))
        poslayout.addWidget(self.position)
        self.length = QLabel("00:00")
        poslayout.addWidget(self.length)
        currentLayout.addLayout(poslayout,5,1)
        toplayout.addLayout(currentLayout)
        layout.addLayout(toplayout)
        layout.addStretch(1)
        
        self.settingsWidget = QMenu()
        self.consumeBtn = self.settingsWidget.addAction("Consume")
        self.consumeBtn.setCheckable(True)
        self.consumeBtn.triggered.connect( lambda x: self.mpd.consume(int(x)))
        self.singleBtn  = self.settingsWidget.addAction("Single")
        self.singleBtn.setCheckable(True)
        self.singleBtn.triggered.connect( lambda x: self.mpd.single(int(x)))
        
        toolLayout = QHBoxLayout()
        self.settingsBtn = QToolButton()
        self.settingsBtn.setFixedSize(64,64)
        self.settingsBtn.setIcon( self.ih.settingsButton)
        self.settingsBtn.clicked.connect(self.showAdditionalControls)
        toolLayout.addWidget(self.settingsBtn)

        
        toolWidget = QStackedWidget()
        transpWidget = QWidget()
        transpLayout = QHBoxLayout()
        self.prevBtn = self.createButton(
            self.ih.prevButton, self.ih.prevButtonPressed)
        self.prevBtn.clicked.connect( lambda x: self.mpd.previous())
        transpLayout.addWidget(self.prevBtn)
        self.playBtn = self.createCheckButton(
            self.ih.playButton, self.ih.pauseButton)
        self.playBtn.clicked.connect( self.playPressed)
        transpLayout.addWidget(self.playBtn)
        self.stopBtn = self.createButton(
            self.ih.stopButton, self.ih.stopButtonPressed)
        self.stopBtn.clicked.connect( lambda x: self.mpd.stop())
        transpLayout.addWidget(self.stopBtn)
        self.nextBtn = self.createButton(
            self.ih.nextButton, self.ih.nextButtonPressed)
        self.nextBtn.clicked.connect( lambda x: self.mpd.next())
        transpLayout.addWidget(self.nextBtn)
        self.shuffleBtn = self.createCheckButton(
            self.ih.shuffleButton, self.ih.shuffleButtonPressed)
        self.shuffleBtn.toggled.connect(
            lambda x: self.mpd.random(1) if x else self.mpd.random(0))
        transpLayout.addWidget(self.shuffleBtn)
        self.repeatBtn = self.createCheckButton(
            self.ih.repeatButton, self.ih.repeatButtonPressed)
        self.repeatBtn.toggled.connect(
            lambda x: self.mpd.repeat(1) if x else self.mpd.repeat(0))
        transpLayout.addWidget(self.repeatBtn)
        transpLayout.addSpacing(64)
        transpWidget.setLayout(transpLayout)
        toolWidget.addWidget( transpWidget)
        
        self.volume = QSlider(Qt.Horizontal)
        self.volume.valueChanged.connect(self.mpd.setvol)
        toolWidget.addWidget(self.volume)
        
        toolLayout.addWidget(toolWidget)
        self.volumeBtn = QToolButton()
        self.volumeBtn.setFixedSize(64,64)
        self.volumeBtn.setCheckable(True)
        self.volumeBtn.setIcon( self.ih.volumeButton)
        self.volumeBtn.toggled.connect(
            lambda x: toolWidget.setCurrentIndex(x))
        toolLayout.addWidget(self.volumeBtn)
        layout.addLayout(toolLayout)
        self.setLayout(layout)

    def showAdditionalControls(self):
        pos = self.settingsBtn.pos()
        pos.setY( pos.y()-self.settingsWidget.sizeHint().height())
        self.settingsWidget.popup( self.mapToGlobal(pos))

    def createCheckButton(self, offIcon, onIcon):
        i = QIcon()
        i.addPixmap( offIcon.pixmap(64), QIcon.Normal, QIcon.Off)
        i.addPixmap(  onIcon.pixmap(64), QIcon.Normal, QIcon.On)
        b = QToolButton()
        b.setFixedSize(64,64)
        b.setCheckable(True)
        b.setIcon(i)
        b.setStyleSheet("* { background: transparent }")
        return b

    def createButton(self, normal, pressed):
        b = QToolButton()
        b.setFixedSize(64,64)
        b.setIcon(normal)
        b.setStyleSheet("* { background: transparent }")
        b.pressed.connect( lambda: b.setIcon(pressed))
        b.released.connect( lambda: b.setIcon(normal))
        return b
    
    def playPressed(self,state):
        if   self.state == 'stop': self.mpd.play()
        else: self.mpd.pause(int(not state))
        
    def initState(self):
        self.songid  = -1
        self.state = 'stop'
        self.artist.setText("Unknown Artist")
        self.title.setText("Unknown Title")
        self.albumartist.setText("Unknown Artist")
        self.album.setText("Unknown Album")
        self.position.setRange(0,0)
        self.position.setValue(0)
        self.position.setEnabled(False)
        self.length.setText("00:00")
        self.playlistposition.setText("0/0")
        self.setStopState()
        
    def setStopState(self):
        self.playBtn.setChecked(False)
        self.time.setText("00:00")
        self.position.setValue(0)
        self.volume.setEnabled(False)

    def updateStatus(self):
        status = self.mpd.status()
        self.repeatBtn.setChecked(int(status['repeat']))
        self.shuffleBtn.setChecked(int(status['random']))
        self.consumeBtn.setChecked(int(status['consume']))
        self.singleBtn.setChecked(int(status['single']))
        if not status.has_key('songid') and self.songid != -1:
            self.initState()
            return
        stateChanged = False
        state = status['state']
        if state != self.state:
            stateChanged = True
        self.state = state
        volume = int(status['volume'])
        if self.state == 'play' or self.state == 'pause':
            self.playBtn.setChecked(True if self.state == 'play' else False)
            songid = int(status['songid'])
            if songid != self.songid:
                self.songid = songid
                self.updateCurrentSong()
            playlistlength = int(status['playlistlength'])
            song = int(status.get('song',-1))
            self.playlistposition.setText("%d/%d" % (song+1,playlistlength))
            playlistlength = int(status['playlistlength'])
            elapsed = float(status['elapsed'])
            if not self.position.isSliderDown():
                timeString = self.mpd.timeString(round(elapsed))
                self.time.setFixedSize(
                    (len(timeString)+1)*self.fmt.averageCharWidth(),
                    self.fmt.height())
                self.time.setText(timeString)
                if self.position.maximum() > 0:
                    self.position.setSliderPosition(round(elapsed))
            if stateChanged:
                self.volume.setEnabled(True)
            if not self.volume.isSliderDown():
                self.volume.setValue(volume)
            #nextsong = int(status['nextsong'])
        else:
            if self.songid == -1: return
            self.setStopState()
            
    def updateCurrentSong(self):
        currentsong = self.mpd.unifySongInfo(self.mpd.currentsong())
        self.artist.setText(      currentsong['artist'])
        self.title.setText(       currentsong['title'])
        self.albumartist.setText( currentsong['albumartist'])
        self.album.setText(       currentsong['album'])
        self.length.setText(      currentsong['length'])
        self.position.setRange(0,currentsong['time'])
        self.position.setEnabled(True if self.position.maximum() > 0 else False)
        self.position.setValue(0)
        self.time.setText("00:00")
        self.volume.setEnabled(True)

    def seek(self):
        secs = self.position.sliderPosition()
        if self.songid == -1: return
        self.mpd.seekid(self.songid, secs)
       
    def hideEvent(self, ev):
        if self.timer:
            self.killTimer( self.timer)
            self.timer = None
        super(Player,self).hideEvent(ev)

    def showEvent(self,ev):
        if not self.timer:
            self.updateStatus()
            self.timer = self.startTimer(1000)
        super(Player,self).showEvent(ev)

    def timerEvent(self,ev):
        try:
            self.updateStatus()
        except ConnectionError, e:
            self.hide()
            QMaemo5InformationBox.information(
                self, "Connection Error: %s" % str(e),
                QMaemo5InformationBox.DefaultTimeout)
        except socket.error, e:
            QMaemo5InformationBox.information(
                self, "Connection Error: %s" % e[1],
                QMaemo5InformationBox.DefaultTimeout)
            self.hide()
Example #3
0
class StockMain(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        """
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.initTypeCombo()
        self.ids = []
        self.tableSetting = None
        self.selectedGroup = None
        self.classifyMenuGroup = None
        regx = QRegExp("[0-9]*[\.]{0,1}[0-9]*$")
        validator = QRegExpValidator(regx, self)
        self.smallValueEdit.setValidator(validator)
        self.bigValueEdit.setValidator(validator)
        self.weightEdit.setValidator(validator)
        self.on_daySumRadio_clicked()
        self.initCmpMethCombo()
        self.initCmpTypeCombo()
        self.initCrossTypeCombo()
        self.filter = ''
        #        myGlobal.init()
        #        myGlobal.initDealDays()
        self.dayInfoModel = CustomModel(self)
        self.dayInfoModel.setRestApi('liststockdayinfo')
        self.dayInfoModel.setPageSize(10000)
        self.calcModel = CustomModel(self)
        self.calcModel.setRestApi('listmonthsum')
        self.calcModel.setPageSize(20000)
        self.calcModel2 = CustomModel(self)
        self.calcModel2.setRestApi('liststockdaysdiff')
        self.calcModel2.setPageSize(10000)
        self.crossModel = CustomModel(self)
        self.crossModel.setRestApi('listcrossinfo')
        self.crossModel.setPageSize(10000)
        self.combineModel = CombineModel(self)
        self.combineModel.setPageSize(10000)
        self.classifyMenu = None
        self.endDate = QDate.currentDate()
        self.startDate = self.endDate.addDays(-1)
        self.calcTableWidget.setButtonsVisible(False)
        self.combineWidget.setButtonsVisible(False)
        self.combineWidget.clearBtn.setVisible(True)
        self.combineWidget.undoBtn.setVisible(True)
        #self.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu);
        savedSetting = config.readSetting()
        if 'groups' in savedSetting:
            self.groups = savedSetting['groups']
        else:
            self.groups = {}
        self.updateFilter()
        self.listWidget.setVisible(False)
        self.listWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.modifyDateEdit()
        self.showGroupBtn.setChecked(True)
        self.on_showGroupBtn_clicked()
        self.showMaximized()

    def modifyDateEdit(self):
        curIndex = self.tabWidget.currentIndex()
        if curIndex == 0:
            self.startDateEdit = self.startDateEdit_1
            self.endDateEdit = self.endDateEdit_1
        elif curIndex == 1:
            self.startDateEdit = self.startDateEdit_2
            self.endDateEdit = self.endDateEdit_2
        elif curIndex == 2:
            self.startDateEdit = self.startDateEdit_3
            self.endDateEdit = self.endDateEdit_3
        elif curIndex == 3:
            self.startDateEdit = self.startDateEdit_4
            self.endDateEdit = self.endDateEdit_4

        self.startDateEdit.setDate(self.startDate)
        self.endDateEdit.setDate(self.endDate)

    def updateFilter(self):
        config.writeSetting('groups', self.groups)
        self.listWidget.clear()
        for key in self.groups:
            self.listWidget.addItem(key)

    def initTypeCombo(self):
        self.customName = u'均价'
        self.customType = 'D'
        self.customNum = 3
        self.typeNames = {
                            u'均价':'avg_price', \
                            u'涨幅':'growth', \
                            u'换手':'turn',\
                            u'振幅':'amp',\
                            u'总金额':'total',\
                            u'量比':'vol'}
        for key in self.typeNames:
            self.typeCombo.addItem(key)

        self.sumTypeNames = {
                            u'正和':'positive', \
                            u'负和':'negative', \
                            u'所有和':'all'
                    }
        for key in self.sumTypeNames:
            self.sumTypeCombo.addItem(key)

    def initCmpMethCombo(self):
        self.cmpMethNames = {
                             u'指定两天加':'plus', \
                             u'指定两天减':'minus', \
                             u'指定两天比值':'divide', \
                             u'指定时间段内最大值减最小值':'maxmin', \
                             u'指定时间段内最大值比最小值':'maxmindivide', \
                             u'指定时间段内的和':'sum', \
                             u'两个时间内涨幅,振幅数据分段':"seperate",
                             }

        for key in self.cmpMethNames:
            self.cmpMethCombo.addItem(key)

    def initCmpTypeCombo(self):
        #avg_price,growth_ratio,current_price,total_stock,total_value,avg_circulation_value,cir_of_cap_stock
        self.cmpTypeCombo.clear()
        self.cmpTypeNames = {
        u'均价':'avg_price', \
        u'涨幅':'growth_ratio', \
        u'总股本':'total_stock', \
        u'总市值':'total_value', \
        u'均价流通市值':'avg_circulation_value', \
        u'流通股本':'cir_of_cap_stock', \
        u'现价':'current_price',\
        u'换手':'turnover_ratio',\
        u'总金额':'total_money',\
        u'振幅':'amplitude_ratio',\
        u'量比':'volume_ratio'}
        for key in self.cmpTypeNames:
            self.cmpTypeCombo.addItem(key)

    def initCrossTypeCombo(self):
        #avg_price,growth_ratio,current_price,total_stock,total_value,avg_circulation_value,cir_of_cap_stock
        self.crossTypeCombo.clear()
        self.crossTypeNames = {
            u'昨收': 'ytd_end_price',
            u'均价': 'avg_price',
            u'均价流通市值': 'avg_circulation_value',
            u'总市值': 'total_value',
            u'总股本': 'total_stock',
            u'流通股本': 'cir_of_cap_stock',
        }
        for key in self.crossTypeNames:
            self.crossTypeCombo.addItem(key)

    @pyqtSignature("")
    def on_daySumRadio_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        self.customType = 'D'
        self.numCombo.clear()
        items = [str(i) for i in range(3, 31)]
        for item in items:
            self.numCombo.addItem(item)
        #raise NotImplementedError

    @pyqtSignature("")
    def on_weekSumRadio_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        self.customType = 'W'
        self.numCombo.clear()
        items = [str(i) for i in range(1, 7)]
        for item in items:
            self.numCombo.addItem(item)
        #raise NotImplementedError

    @pyqtSignature("")
    def on_monthSumRadio_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        self.customType = 'M'
        self.numCombo.clear()
        items = [str(i) for i in range(1, 13)]
        for item in items:
            self.numCombo.addItem(item)

    def chooseNearDate(
        self,
        d,
    ):
        lastDate = ''
        for tmpDate in myGlobal.dealDays:

            if tmpDate > d:
                if lastDate != '':
                    return lastDate.strftime(
                        "%Y-%m-%d") + ', ' + tmpDate.strftime("%Y-%m-%d")
                else:
                    return u'无, ' + tmpDate.strftime("%Y-%m-%d")
            lastDate = tmpDate

        return lastDate.strftime("%Y-%m-%d") + u', 无'

    def testDate(self, startD, endD):
        if startD >= endD:
            QMessageBox.warning(self, 'warning', u'开始时间大于或等于结束时间')
            return False
        if startD not in myGlobal.dealDays:
            QMessageBox.warning(
                self, 'warning', u'开始时间非交易日或无数据,请重新选择,前后的交易日期分别为: ' +
                self.chooseNearDate(startD))
            return False
        if endD not in myGlobal.dealDays:
            QMessageBox.warning(
                self, 'warning',
                u'结束时间非交易日或无数据,请重新选择,前后的交易日期分别为: ' + self.chooseNearDate(endD))
            return False
        return True

    @pyqtSignature("")
    def on_queryBtn_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #        from loading import Loading
        #        import http
        #        http.callRestAsync(self, "xxx",  {"sss":'s'},  self.callBack)
        #        if True:
        #            return
        if len(self.ids) == 0:
            QMessageBox.warning(self, 'warning', u'所选代码为空,请选择代码')
            return

        startD = self.startDateEdit.date().toPyDate()
        endD = self.endDateEdit.date().toPyDate()
        self.startDate = self.startDateEdit.date()
        self.endDate = self.endDateEdit.date()
        if not self.testDate(startD, endD):
            return

        #response=json&page=2&pagesize=20&stockid=000001,000002,000003,000004,000005&starttime=2008-09-24&sortname=turnover_ratio
        config.collect(
            'info',
            u'原始数据查询, 起始时间:%s, 结束时间:%s, 代码: %s' % (startD, endD, self.ids))
        args = {}
        if len(self.ids) == len(myGlobal.id2name.keys()):
            args = {'starttime': startD, 'endtime': endD}
        else:
            args = {
                'stockid': ','.join(self.ids),
                'starttime': startD,
                'endtime': endD
            }
        self.dayInfoModel.setRestArgs(args)

        self.srcTableWidget.init(self.dayInfoModel, 2, self.tableSetting, self)

    @pyqtSignature("")
    def on_queryBtn_2_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet

        if len(self.ids) == 0:
            QMessageBox.warning(self, 'warning', u'所选代码为空,请选择代码')
            return

        startD = self.startDateEdit_2.date().toPyDate()
        endD = self.endDateEdit_2.date().toPyDate()
        self.startDate = self.startDateEdit.date()
        self.endDate = self.endDateEdit.date()
        #response=json&page=2&pagesize=20&stockid=000001,000002,000003,000004,000005&starttime=2008-09-24&sortname=turnover_ratio
        if not self.testDate(startD, endD):
            return

        customNum = self.numCombo.currentText().toInt()[0]
        calcName = self.typeNames[str(
            self.typeCombo.currentText().toUtf8()).decode('utf-8')]
        sumType = self.sumTypeNames[str(
            self.sumTypeCombo.currentText().toUtf8()).decode('utf-8')]
        log.log(calcName)
        config.collect(
            'info', u'X日和查询, 起始时间:%s, 结束时间:%s, 查询指标:%s, 查询类型:%s 代码: %s,' %
            (startD, endD, str(
                self.typeCombo.currentText().toUtf8()).decode('utf-8'),
             str(customNum) + self.customType.replace('D', u'日').replace(
                 'W', u'周').replace('M', u'月'), self.ids))
        if len(self.ids) == len(myGlobal.id2name.keys()):
            args = {
                'starttime': startD,
                'endtime': endD,
                'sumtype': sumType,
                'sumname': calcName
            }
        else:
            args = {
                'stockid': ','.join(self.ids),
                'starttime': startD,
                'endtime': endD,
                'sumType': sumType,
                'sumname': calcName
            }
        if self.customType == 'D':
            self.calcModel.setRestApi('listdaysum')
            args['days'] = customNum
        elif self.customType == 'W':
            self.calcModel.setRestApi('listweeksum')
            args['weeks'] = customNum
        elif self.customType == 'M':
            self.calcModel.setRestApi('listmonthsum')
            args['months'] = customNum
        self.calcModel.setRestArgs(args)
        self.sumTableWidget.init(self.calcModel, parent=self)

        #raise NotImplementedError
    @pyqtSignature("")
    def on_action_triggered(self):
        """
        Slot documentation goes here.
        设置dayinfo表中的显示列
        """
        # TODO: not implemented yet
        if not self.srcTableWidget.inited:
            QMessageBox.warning(self, 'warning', u'列表中尚无内容,请先查询')
            return
        tableSetting = TableSetting.getSetting(self.srcTableWidget.getView(),
                                               self)
        log.log(tableSetting)
        if tableSetting is not None:
            self.tableSetting = tableSetting
            self.srcTableWidget.setSetting(self.tableSetting)

    @pyqtSignature("QPoint")
    def on_listWidget_customContextMenuRequested(self, pos):
        """
        Slot documentation goes here.
        代码筛选框中的右键
        """
        # TODO: not implemented yet
        cur = self.cursor()
        curPos = cur.pos()
        log.log(curPos.x(), curPos.y())
        menu = QMenu(self)
        menu.addAction(self.action_addGroup)
        if self.listWidget.itemAt(pos):
            menu.addAction(self.action_editGroup)
            menu.addAction(self.action_deleteGroup)
        menu.exec_(curPos)
#        #raise NotImplementedError

    def getTextFromItem(self, item):
        selectItem = None
        if type(item) == type([]):
            if len(item) <= 0:
                QMessageBox.warning(self, 'warning', u'没有选中任何组')
                return None
            selectItem = item[0]
        else:
            selectItem = item
        selectedItemText = str(selectItem.text().toUtf8()).decode('utf-8')
        return selectedItemText

    @pyqtSignature("")
    def on_action_addGroup_triggered(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        ret = ChooseId.getIds(self, self.groups)
        if ret is None:
            return
        self.groups[ret[0]] = ret[1]
        #            self.listWidget.addItem(ret[0])
        config.collect(
            'info', u'添加分组, 分组名称: %s, 分组详情: %s' % (ret[0], ','.join(ret[1])))
        log.log(self.groups)
        self.updateFilter()

        #raise NotImplementedError

    @pyqtSignature("")
    def on_action_editGroup_triggered(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #print 'delete'
        selectedItemText = self.getTextFromItem(self.listWidget.selectedItems(
        ))  #str(selectedItems[0].text().toUtf8()).decode('utf-8')
        if selectedItemText not in self.groups:
            QMessageBox.warning(self, 'warning', u'未知分组')
            return
        ret = ChooseId.getIds(self, self.groups, selectedItemText)
        if ret is not None:
            if selectedItemText != ret[0]:
                self.groups.pop(selectedItemText)
            self.groups[ret[0]] = ret[1]
        else:
            return
        config.collect(
            'info', u'编辑分组, 分组名称: %s, 新分组详情: %s' % (ret[0], ','.join(ret[1])))
        self.updateFilter()
        #        config.writeSetting('groups',  self.groups)
        if self.selectedGroup == selectedItemText:
            self.ids = self.groups[self.selectedGroup]
            self.clearClassify()
            self.changeIds(self.groups[self.selectedGroup])
        #raise NotImplementedError

    @pyqtSignature("")
    def on_action_deleteGroup_triggered(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #raise NotImplementedError
        selectedItemText = self.getTextFromItem(
            self.listWidget.selectedItems())
        if selectedItemText not in self.groups:
            QMessageBox.warning(self, 'warning', u'未知分组')
            return
        config.collect(
            'info', u'删除分组, 分组名称: %s, 分组详情: %s' %
            (selectedItemText, ','.join(self.groups[selectedItemText])))
        self.groups.pop(selectedItemText)
        self.updateFilter()
#        config.writeSetting('groups',  self.groups)

#    @pyqtSignature("bool")
#    def on_action_showGroupView_triggered(self, checked):
#        """
#        Slot documentation goes here.
#        """
#        # TODO: not implemented yet
#        if checked:
#            self.groupView.show()
#        else:
#            self.groupView.hide()
#        #raise NotImplementedError

#    @pyqtSignature("bool")
#    def on_groupView_visibilityChanged(self, visible):
#        """
#        Slot documentation goes here.
#        """
#        # TODO: not implemented yet
#        if visible:
#            self.action_showGroupView.setChecked(True)
#        else:
#            self.action_showGroupView.setChecked(False)
#        #raise NotImplementedError

    @pyqtSignature("QListWidgetItem*")
    def on_listWidget_itemDoubleClicked(self, item):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        self.selectedGroup = self.getTextFromItem(
            self.listWidget.selectedItems())
        if self.selectedGroup not in self.groups:
            QMessageBox.warning(self, 'warning', u'未知分组')
            return
#        log.log('self.ids:',  self.ids)
        self.clearClassify()
        self.changeIds(self.groups[self.selectedGroup])

#        log('self.ids:',  self.ids)
#        curIndex = self.tabWidget.currentIndex()
#        if curIndex == 0:
#            self.on_queryBtn_clicked()
#        elif curIndex == 1:
#            self.on_queryBtn_2_clicked()
#        elif curIndex == 2:
#            self.on_calculateBtn_clicked()
#raise NotImplementedError

    @pyqtSignature("")
    def on_calculateBtn_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #raise NotImplementedError

        if len(self.ids) == 0:
            QMessageBox.warning(self, 'warning', u'所选代码为空,请选择代码')
            return
        startD = self.startDateEdit_3.date().toPyDate()
        endD = self.endDateEdit_3.date().toPyDate()
        self.startDate = self.startDateEdit.date()
        self.endDate = self.endDateEdit.date()
        if not self.testDate(startD, endD):
            return
        #response=json&page=2&pagesize=20&stockid=000001,000002,000003,000004,000005&starttime=2008-09-24&sortname=turnover_ratio
        #optname=avg_price,growth_ratio,current_price&opt=-&starttime=2008-03-25&endtime=2008-03-28&page=4&pagesize=20
        optname = self.cmpTypeNames[str(
            self.cmpTypeCombo.currentText().toUtf8()).decode(
                'utf-8')]  #self.cmpTypeCombo.currentText().toInt()[0]
        opt = self.cmpMethNames[str(
            self.cmpMethCombo.currentText().toUtf8()).decode('utf-8')]
        log.log(opt)
        config.collect(
            'info', u'计算查询, 起始时间:%s, 结束时间:%s, 计算指标:%s, 计算类型:%s, 代码: %s' %
            (startD, endD, str(
                self.cmpTypeCombo.currentText().toUtf8()).decode('utf-8'),
             str(self.cmpMethCombo.currentText().toUtf8()).decode('utf-8'),
             self.ids))

        if opt == 'seperate':
            args = {
                'stockid': ','.join(self.ids),
                'starttime': startD,
                'endtime': endD
            }
            self.calcModel2.setRestApi('listgrowthampdis')
        elif opt == 'sum':
            args = {
                'stockid': ','.join(self.ids),
                'starttime': startD,
                'endtime': endD,
                'sumname': optname
            }
            self.calcModel2.setRestApi('listndayssum')
        else:
            args = {
                'stockid': ','.join(self.ids),
                'starttime': startD,
                'endtime': endD,
                'optname': optname,
                'opt': opt
            }
            self.calcModel2.setRestApi('liststockdaysdiff')

        log.log("ids", len(self.ids), len(myGlobal.id2name.keys()))
        if len(self.ids) == len(myGlobal.id2name.keys()):
            args.pop('stockid')

        self.calcModel2.setRestArgs(args)

        if self.calcModel2.restApi == 'listgrowthampdis':
            self.calcTableWidget.init(self.calcModel2, 6, parent=self)
        else:
            self.calcTableWidget.init(self.calcModel2, 2, parent=self)

#        smallLimit = self.smallValueEdit.text().toFloat()
#        bigLimit = self.bigValueEdit.text().toFloat()
#        smallValue = None
#        bigValue = None
#        if smallLimit[1]:
#            smallValue = smallLimit[0]
#        if bigLimit[1]:
#            bigValue = bigLimit[0]
#        hideRows = self.calcModel2.calcRowsInLimit(4,  smallValue,  bigValue)
#        log(hideRows)
#        log(self.smallValueEdit.text().toFloat()).

#        log(self.bigValueEdit.text().toFloat())
#        self.calcTableWidget.init(self.calcModel2,  0,  {'hideRows': hideRows})

    @pyqtSignature("int")
    def on_tabWidget_currentChanged(self, index):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #        raise NotImplementedError
        self.modifyDateEdit()
        self.clearClassify()
        if index == 0:
            self.dayInfoModel.removeFilter()
        elif index == 1:
            self.calcModel.removeFilter()
        elif index == 2:
            self.calcModel2.removeFilter()

    def changeIds(self, ids):
        log.log('ChangeIds')
        log.log('self.ids:', self.ids)
        self.ids = ids
        curIndex = self.tabWidget.currentIndex()
        if curIndex == 0:
            self.dayInfoModel.removeFilter()
            self.on_queryBtn_clicked()
        elif curIndex == 1:
            self.calcModel.removeFilter()
            self.on_queryBtn_2_clicked()
        elif curIndex == 2:
            self.calcModel2.removeFilter()
            self.on_calculateBtn_clicked()

    @pyqtSignature("")
    def on_showGroupBtn_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #raise NotImplementedError
        if self.classifyBtn.isChecked():
            self.classifyBtn.setChecked(False)
        if self.showGroupBtn.isChecked():
            self.listWidget.setVisible(True)
        else:
            self.listWidget.setVisible(False)

    @pyqtSignature("")
    def on_classifyBtn_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #raise NotImplementedError
        if self.showGroupBtn.isChecked():
            self.showGroupBtn.setChecked(False)
            self.on_showGroupBtn_clicked()
        if self.classifyMenu is None:
            self.classifyMenu = QMenu(self)
            subMenu = QMenu(self)
            subMenu.setTitle(u'地区板块')
            self.classifyMenuGroup = QActionGroup(self)
            for key in myGlobal.area2ids:
                if len(key) != 0:
                    action = MyAction(key, myGlobal.area2ids[key],
                                      self.changeIds, self)
                    subMenu.addAction(action)
                    self.classifyMenuGroup.addAction(action)
            self.classifyMenu.addMenu(subMenu)
            subMenu = QMenu(self)
            subMenu.setTitle(u'行业板块')
            for key in myGlobal.industry2ids:
                if len(key) != 0:
                    action = MyAction(key, myGlobal.industry2ids[key],
                                      self.changeIds, self)
                    subMenu.addAction(action)
                    self.classifyMenuGroup.addAction(action)
            self.classifyMenu.addMenu(subMenu)
            subMenu = MyMenu(u'向上版块', 'FLAG_UP', self, self.classifyMenuGroup)
            self.classifyMenu.addMenu(subMenu)
            subMenu = MyMenu(u'向下版块', 'FLAG_DOWN', self,
                             self.classifyMenuGroup)
            self.classifyMenu.addMenu(subMenu)

        self.classifyBtn.setChecked(True)
        pos = QPoint()
        pos.setX(0)
        pos.setY(-self.classifyMenu.sizeHint().height())
        self.classifyMenu.exec_(self.classifyBtn.mapToGlobal(pos))

    def clearClassify(self):
        if self.classifyMenuGroup is not None:
            checkedAction = self.classifyMenuGroup.checkedAction()
            if checkedAction is not None:
                checkedAction.setChecked(False)

    @pyqtSignature("QString")
    def on_cmpMethCombo_currentIndexChanged(self, p0):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #raise NotImplementedError
        if str(p0.toUtf8()).decode('utf-8') == u'两个时间内涨幅,振幅数据分段':
            self.cmpTypeCombo.setEnabled(False)
        else:
            self.cmpTypeCombo.setEnabled(True)

    @pyqtSignature("QListWidgetItem*")
    def on_listWidget_itemClicked(self, item):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        self.selectedGroup = self.getTextFromItem(
            self.listWidget.selectedItems())
        if self.selectedGroup not in self.groups:
            QMessageBox.warning(self, 'warning', u'未知分组')
            return
        self.ids = self.groups[self.selectedGroup]
        #        log.log('self.ids:',  self.ids)
        self.clearClassify()
        #raise NotImplementedError
    def detailClassifyDate(self, arg):
        clz, switchType, subType = arg.split('_')
        if switchType != '5':
            return
        subTypeL = subType.split('.')
        subType = subTypeL[0]
        year = int(subTypeL[1])
        self.startDate, self.endDate = {
            '0': (QDate(year, 1, 1), QDate(year, 3, 31)),  #u'第 1 季度'
            '1': (QDate(year, 4, 1), QDate(year, 6, 30)),  #u'第 2 季度'
            '2': (QDate(year, 7, 1), QDate(year, 9, 30)),  #u'第 3 季度'
            '3': (QDate(year, 10, 1), QDate(year, 12, 31)),  #u'第 4 季度'
            '4': (QDate(year, 1, 1), QDate(year, 2, 1).addDays(-1)),  #u'1 月'
            '5': (QDate(year, 2, 1), QDate(year, 3, 1).addDays(-1)),  #u'2 月'
            '6': (QDate(year, 3, 1), QDate(year, 4, 1).addDays(-1)),  #u'3 月'
            '7': (QDate(year, 4, 1), QDate(year, 5, 1).addDays(-1)),  #u'4 月'
            '8': (QDate(year, 5, 1), QDate(year, 6, 1).addDays(-1)),  #u'5 月'
            '9': (QDate(year, 6, 1), QDate(year, 7, 1).addDays(-1)),  #u'6 月'
            '10': (QDate(year, 7, 1), QDate(year, 8, 1).addDays(-1)),  #u'7 月'
            '11': (QDate(year, 8, 1), QDate(year, 9, 1).addDays(-1)),  #u'8 月'
            '12': (QDate(year, 9, 1), QDate(year, 10, 1).addDays(-1)),  #u'9 月'
            '13': (QDate(year, 10, 1), QDate(year, 11,
                                             1).addDays(-1)),  #u'10 月'
            '14': (QDate(year, 11, 1), QDate(year, 12,
                                             1).addDays(-1)),  #u'11 月'
            '14': (QDate(year, 12, 1), QDate(year, 12, 31)),  #u'12 月'
        }[subType]
        self.modifyDateEdit()

    def detailClassify(self, type, arg):
        curIndex = self.tabWidget.currentIndex()
        self.detailClassifyDate(arg)

        if curIndex == 0:
            self.dayInfoModel.setFilter(type + '__' + arg)
            self.on_queryBtn_clicked()
        elif curIndex == 1:
            self.calcModel.setFilter(type + '__' + arg)
            self.on_queryBtn_2_clicked()
        elif curIndex == 2:
            self.calcModel2.setFilter(type + '__' + arg)
            self.on_calculateBtn_clicked()

    @pyqtSignature("")
    def on_crossBtn_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        #        raise NotImplementedError

        startD = self.startDateEdit.date().toPyDate()
        endD = self.endDateEdit.date().toPyDate()
        self.startDate = self.startDateEdit.date()
        self.endDate = self.endDateEdit.date()
        if not self.testDate(startD, endD):
            return
        #response=json&page=2&pagesize=20&stockid=000001,000002,000003,000004,000005&starttime=2008-09-24&sortname=turnover_ratio
        #optname=avg_price,growth_ratio,current_price&opt=-&starttime=2008-03-25&endtime=2008-03-28&page=4&pagesize=20
        optname = self.crossTypeNames[str(
            self.crossTypeCombo.currentText().toUtf8()).decode(
                'utf-8')]  #self.cmpTypeCombo.currentText().toInt()[0]
        weight = str(self.weightEdit.text().toUtf8())
        try:
            weight = float(weight)
        except:
            QMessageBox.warning(self, 'warning', u'权重输入有误')
            return
        args = {
            'starttime': startD,
            'endtime': endD,
            'optname': optname,
            'weight': weight
        }
        log.log(args)
        self.crossModel.setRestArgs(args)
        self.crossTableWidget.init(self.crossModel, parent=self)