def testRefCount(self):
        model = QStandardItemModel(5, 5)
        items = []
        for r in range(5):
            row = []
            for c in range(5):
                row.append(QStandardItem("%d,%d" % (r,c)) )
                self.assertEqual(sys.getrefcount(row[c]), 2)

            model.insertRow(r, row)

            for c in range(5):
                ref_after = sys.getrefcount(row[c])
                # check if the ref count was incremented after insertRow
                self.assertEqual(ref_after, 3)

            items.append(row)
            row = None

        for r in range(3):
            my_row = model.takeRow(0)
            my_row = None
            for c in range(5):
                # only rest 1 reference
                self.assertEqual(sys.getrefcount(items[r][c]), 2)

        my_i = model.item(0,0)
        # ref(my_i) + parent_ref + items list ref
        self.assertEqual(sys.getrefcount(my_i), 4)

        model.clear()
        # ref(my_i)
        self.assertEqual(sys.getrefcount(my_i), 3)
Example #2
0
    def testRefCount(self):
        model = QStandardItemModel(5, 5)
        items = []
        for r in range(5):
            row = []
            for c in range(5):
                row.append(QStandardItem("%d,%d" % (r,c)) )
                self.assertEqual(sys.getrefcount(row[c]), 2)

            model.insertRow(r, row)

            for c in range(5):
                ref_after = sys.getrefcount(row[c])
                # check if the ref count was incremented after insertRow
                self.assertEqual(ref_after, 3)

            items.append(row)
            row = None

        for r in range(3):
            my_row = model.takeRow(0)
            my_row = None
            for c in range(5):
                # only rest 1 reference
                self.assertEqual(sys.getrefcount(items[r][c]), 2)

        my_i = model.item(0,0)
        # ref(my_i) + parent_ref + items list ref
        self.assertEqual(sys.getrefcount(my_i), 4)

        model.clear()
        # ref(my_i)
        self.assertEqual(sys.getrefcount(my_i), 3)
Example #3
0
class List(QDialog):
    """All Notes dialog"""

    def __init__(self, app, *args, **kwargs):
        QDialog.__init__(self, *args, **kwargs)
        self.app = app
        self.closed = False
        self.sort_order = None
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())

        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(self.notebook_context_menu)

        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(self.sort_order_updated)

        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.notebook_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        QDialog.showEvent(self, *args, **kwargs)
        self._reload_notebooks_list()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0
        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '', notebook_filter, dbus.Array([], signature='i'),
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self):
        name, status = self._notebook_new_name(self.tr('Create new notebook'))
        if status:
            notebook_struct = self.app.provider.create_notebook(name)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name,
        )
        if status:
            notebook.name = name
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr("Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') % item.note.title,
            QMessageBox.Yes | QMessageBox.No
        )
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'), self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_notebooks_list(self, select_notebook_id=None):
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Notes'))
        self.notebooksModel.appendRow(root)

        selected_item = root
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)
            root.appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()
        if selected_item:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name, self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self, title, self.tr('Enter notebook name:'), text=exclude)
        while name in names and status:
            message = self.tr('Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        return name, status
Example #4
0
    def testClear(self):

        model = QStandardItemModel()
        root = model.invisibleRootItem()
        model.clear()
        self.assertFalse(shiboken.isValid(root))
Example #5
0
class serverManagerWindow(QMainWindow):
    def __init__(self, _app, parent=None):
        QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.iTrayIcon = QSystemTrayIcon()
        self.iTrayIcon.setIcon(QIcon("drapes.ico"))
        self.iTrayIcon.show()
        self.iTrayIcon.setToolTip("One world, One dream!")
        self.iTrayIcon.activated.connect(self.iconActivated)
        self.quitAction = QAction("&Quit", self, triggered=QApplication.quit)
        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.quitAction)
        self.iTrayIcon.setContextMenu(self.trayIconMenu)

        #选择MYSQL保留用户信息
        QObject.connect(self.ui.mysql_groupBox, SIGNAL("clicked()"), self, SLOT("choiceSql()"))
        #选择XT文件留用户信息
        QObject.connect(self.ui.text_groupBox, SIGNAL("clicked()"), self, SLOT("choiceTxt()"))
        #选择XML文件留用户信息
        QObject.connect(self.ui.xml_groupBox, SIGNAL("clicked()"), self, SLOT("choiceXml()"))                
        #节面显示英文
        QObject.connect(self.ui.actionEnglish, SIGNAL("activated()"), self, SLOT("loadEnglish()"))
        #节面显示中文
        QObject.connect(self.ui.actionChinese, SIGNAL("activated()"), self, SLOT("loadChinese()"))
        
        #加载配置文件
        QObject.connect(self.ui.actionLoad_Config, SIGNAL("activated()"), self, SLOT("loadConfig()"))
        #保留配置文件
        QObject.connect(self.ui.actionSave_Config, SIGNAL("activated()"), self, SLOT("saveConfig()"))
        #about操作
        QObject.connect(self.ui.actionAbout, SIGNAL("activated()"), self, SLOT("about()"))
        
        #选择XML文件
        QObject.connect(self.ui.openXml_pushButton, SIGNAL("clicked()"), self, SLOT("xml_open()"))
        #选择TXT文件
        QObject.connect(self.ui.openText_pushButton, SIGNAL("clicked()"), self, SLOT("txt_open()"))
        #启动服务
        QObject.connect(self.ui.startServer_pushButton, SIGNAL("clicked()"), self, SLOT("startServer()"))
        #停止服务
        QObject.connect(self.ui.stopServer_pushButton, SIGNAL("clicked()"), self, SLOT("stopServer()"))

        self.ui.sqlTypeComboBox.activated[str].connect(self.sqlServer)
                
        QObject.connect(self.ui.openSqlpushButton, SIGNAL("clicked()"), self, SLOT("database_open()"))
        

        #界面语言
        self.translator = None
        self.app = _app
        self.translator = QTranslator() 
        self.connect = None
        self.users = None
        self.ControlMediaPath = None
        self.ControlMedia = None
        self.delUsrInfo = None

        self.userModel = QStandardItemModel()
        self.userModel.setHorizontalHeaderItem(0, QStandardItem("user"))
        self.userModel.setHorizontalHeaderItem(1, QStandardItem("friends"))
        

        self.userModel.setVerticalHeaderItem(0, QStandardItem("1"))
        self.userModel.setVerticalHeaderItem(1, QStandardItem("2"))
        self.userModel.setVerticalHeaderItem(2, QStandardItem("3"))

        self.loginUserModel = QStandardItemModel()
        self.loginUserModel.setHorizontalHeaderItem(0, QStandardItem("user"))
        self.loginUserModel.setHorizontalHeaderItem(1, QStandardItem("instance"))
        
        self.messageModel = QStandardItemModel()
        self.messageModel.setHorizontalHeaderItem(0, QStandardItem("message"))

        #读取系统配置文件
        self.readConfig(configFile)
        self.statusBar().showMessage("server is stopped!")
        
        self.ui.userInfo_tableView.setModel(self.userModel)
        self.createUserInfoContextMenu()
        self.ui.loginUsers_tableView.setModel(self.loginUserModel)
        self.createloginUsersContextMenu()
        self.ui.messageLogs_listView.setModel(self.messageModel)

        #界面多语处理
        self.updateLanguage(self.language)
        
        self.center()
        
    def iconActivated(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            self.show()
        print "iconActivated"
    
    def closeEvent(self, event):
        event.ignore()
        self.hide()
        print "closeEvent"

#    def changeEvent(self,event):
#        if (event.type() == QEvent.WindowStateChange) and (self.isMinimized()):
#            QTimer.singleShot(100, self, SLOT("close"))
#            
#        print "changeEvent"    
                
    def sqlServer(self, index):
        if index == "MySQL":
            self.ui.openSqlpushButton.setDisabled(True)
            self.ui.userLineEdit.setEnabled(True)
            self.ui.passwordlineEdit.setEnabled(True)        
            
        if  index == "Sqlite":
            self.ui.openSqlpushButton.setEnabled(True)
            self.ui.userLineEdit.setDisabled(True)
            self.ui.passwordlineEdit.setDisabled(True)        
        
    def center(self):  
        screen = QDesktopWidget().screenGeometry()  
        size = self.geometry()  
        self.move((screen.width() - size.width()) / 2,
            (screen.height() - size.height()) / 2)  
        
    def createUserInfoContextMenu(self):
        '''添加用户信息快捷菜单'''
        #pylint: disable=W0201
        self.addUserAct = QAction(self)
#        self.addUserAct.setText("add User")
        
        self.delUserAct = QAction(self)
#        self.delUserAct.setText("del User")

        self.undoDelUserAct = QAction(self)
#        self.undoDelUserAct.setText("undo del User")
        
        self.saveDataRowAct = QAction(self)
#        self.saveDataRowAct.setText("save Data")
        
        self.ui.userInfo_tableView.addAction(self.addUserAct)
        self.ui.userInfo_tableView.addAction(self.delUserAct)
        self.ui.userInfo_tableView.addAction(self.undoDelUserAct)
        self.ui.userInfo_tableView.addAction(self.saveDataRowAct)
        
        QObject.connect(self.addUserAct, SIGNAL("activated()"), self, SLOT("userInfoAddRow()"))
        QObject.connect(self.delUserAct, SIGNAL("activated()"), self, SLOT("userInfoDelRow()"))
        QObject.connect(self.undoDelUserAct, SIGNAL("activated()"), self, SLOT("userInfoUndoDelRow()"))        
        QObject.connect(self.saveDataRowAct, SIGNAL("activated()"), self, SLOT("userInfoSaveData()"))
        
        self.ui.userInfo_tableView.setContextMenuPolicy(Qt.ActionsContextMenu)

    
    def userInfoAddRow(self):
        '''添加一条用户数据'''
#        self.userModel.appendRow(QStandardItem(""))
        index = self.ui.userInfo_tableView.selectionModel().currentIndex()
        model = self.ui.userInfo_tableView.model()

        if not model.insertRow(index.row() + 1, index.parent()):
            return

        for column in range(model.columnCount(index.parent())):
            child = model.index(index.row() + 1, column, index.parent())
            model.setData(child, "[No data]", Qt.EditRole)
            
        uiDebug("userInfoAddRow")
    

    def userInfoDelRow(self):
        '''删除数据,且保留此次删除的数据'''
        model = self.ui.userInfo_tableView.model()
        index = self.ui.userInfo_tableView.selectionModel().currentIndex()
        user = model.item(index.row(), 0).index().data()
        friendlist = model.item(index.row(), 1).index().data()
        self.delUsrInfo = [index.row(), user, friendlist]
#        print self.delUsrInfo
        try:
            model.removeRow(index.row(), index.parent())
            self.users.deleteUser(user)
            self.users.userDataSave()
            #pylint: disable=W0702 
        except:    
            pass        
        uiDebug("userInfoDelRow")        

    def userInfoUndoDelRow(self):
        '''恢复前次删除的数据'''
        if self.delUsrInfo != None:
            model = self.ui.userInfo_tableView.model()
            if not model.insertRow(self.delUsrInfo[0]):
                return
            user = self.delUsrInfo[1]
            friendlist = self.delUsrInfo[2]      
            self.userModel.setItem(self.delUsrInfo[0], 0, QStandardItem(user))
            self.userModel.setItem(self.delUsrInfo[0], 1, QStandardItem(friendlist))
            if user != "[No data]":
                self.users.addUser(user, "admin")
            if friendlist != "[No data]":    
                for friend in friendlist.split(","):            
                    self.users.addUserFriend(user, friend)
            self.users.userDataSave()    
        self.delUsrInfo = None        
        uiDebug("userInfoUndoDelRow")


    def userInfoSaveData(self):
        '''保留用户数据'''
        if self.users:
            model = self.ui.userInfo_tableView.model()
            index = self.ui.userInfo_tableView.selectionModel().currentIndex()
            for row in range(model.rowCount(index.parent())):
                user = model.item(row, 0).index().data()
                friendlist = model.item(row, 1).index().data()
                if user != "[No data]":
                    self.users.addUser(user, "admin")
                if friendlist != "[No data]":
                    for friend in friendlist.split(","):
                        if friend != '':
                            self.users.addUserFriend(user, friend)   
        
            self.users.userDataSave()
            self.clearUserInfo()    
            self.showUserinfo()
        uiDebug("userInfoSaveData")        
    

    def showConfig(self):
        '''显示配置'''
#        print self.Config.getControlMedia()    
#        print self.Config.getControlMediaPath()   
#        print self.ControlMedia
#        print self.ControlMediaPath     
        self.ui.information_textBrowser.setText("Control Media: " + self.ControlMedia)
        self.ui.information_textBrowser.append("Control Media path: " + self.ControlMediaPath)

    def showUserinfo(self):
        '''显示用户信息'''
        userlist = self.users.getUsers()
        print "showUserinfo "
        print userlist
        row = 0
        for user in userlist:
            friends = userlist[user]
            self.userModel.setItem(row, 0, QStandardItem(user))
            self.userModel.setItem(row, 1, QStandardItem(friends))
            row = row + 1  
        #pylint: disable=W0201    
        self.delUsrInfo = None
    
    def clearUserInfo(self):
        '''清除用户信息'''
        self.userModel.clear()
        self.delUsrInfo = None

        
    def userConfig(self):
        self.showConfig()
        if self.users != None:
            del self.users        
        #服务器配置
        if self.ControlMedia == mediaValue[txt]:
            #txt文件保留用户信息
            self.users = txtUserControl(self.ControlMediaPath)
            self.ui.text_groupBox.setChecked(True)
            self.ui.text_lineEdit.setText(self.ControlMediaPath)
        elif self.ControlMedia == mediaValue[xml]:
            #xml文件保留用户信息
            self.users = xmlUserControl(self.ControlMediaPath)
            self.ui.xml_groupBox.setChecked(True)
            self.ui.xml_lineEdit.setText(self.ControlMediaPath)
            
        elif self.ControlMedia == mediaValue[mysql]:
            #mysql数据库保留用户信息   
            self.ui.mysql_groupBox.setChecked(True)
            self.ui.ServerLineEdit.setText(self.ControlMediaPath)
            self.ui.sqlTypeComboBox.setCurrentIndex(0)
#            print "mysql" 
            self.sqlServer(mysql)    
        elif self.ControlMedia == mediaValue[sqlite]:
            self.ui.mysql_groupBox.setChecked(True)
            self.ui.ServerLineEdit.setText(self.ControlMediaPath)
            self.ui.sqlTypeComboBox.setCurrentIndex(1)
            self.users = sqliteUserControl(self.ControlMediaPath)
            self.sqlServer(sqlite)
#            print "sqlite"
            
        #用户数据初始化
            
        try:     
            self.users.userDataInit()
#            self.showUserinfo()
            #pylint: disable=W0702
        except:
            self.users = None

        if self.users != None:
            self.clearUserInfo()
            self.showUserinfo()
                    
    def readConfig(self, _file):
        '''读取服务器端配置文件'''
        #pylint: disable=W0201
        self.Config = serverConfig(_file)
        self.ControlMedia = self.Config.getControlMedia() 
        self.ControlMediaPath = self.Config.getControlMediaPath()        
        self.language = self.Config.getLanguage()
        self.userConfig()
        uiDebug("readConfig")
                    
    def startServer(self):
        '''#启动服务'''
        self.ui.startServer_pushButton.setEnabled(False)
        self.ui.stopServer_pushButton.setEnabled(True)
        self.connect = server_twisted.serverMain(8002, self.users)
        self.saveConfig()
#        self.readConfig(configFile)
        self.userConfig()
        self.ui.mysql_groupBox.setDisabled(True)
        self.ui.text_groupBox.setDisabled(True)
        self.ui.xml_groupBox.setDisabled(True)
        self.statusBar().showMessage("server is starting!")
        
        if self.users != None:
            self.clearUserInfo()
            self.showUserinfo()
        uiDebug("startServer")

    def stopServer(self):
        ''' #停止服务'''
        if self.connect != None:
            self.ui.startServer_pushButton.setEnabled(True)
            self.ui.stopServer_pushButton.setEnabled(False)
            self.ui.mysql_groupBox.setDisabled(False)
            self.ui.text_groupBox.setDisabled(False)
            self.ui.xml_groupBox.setDisabled(False)  
            #pylint: disable=E1101          
            reactor.disconnectAll()
#            self.clearUserInfo()
            self.statusBar().showMessage("server is stopped!")
        uiDebug("stopServer")
        

    def loadChinese(self):
        '''加载中文'''
        self.updateLanguage(Chinese)

    def loadEnglish(self):
        '''加载英文'''
        self.updateLanguage(English)
        
    def updateLanguage(self, language):
        '''设置界面语言'''
        if self.translator != None:
            self.app.removeTranslator(self.translator)
            
        if language == Chinese:
            #中文处理
            self.translator.load(chineseLanguageFile)
            self.app.installTranslator(self.translator)  
            self.Config.setLanguage(Chinese)
        elif language == English:
            #英文处理
            self.Config.setLanguage(English)   
        else:
            pass
    
        #更新界面
        self.retranslateUi()
        #保留配置
        self.Config.saveServerConfig()
        
            
    def txt_open(self):
        self.fileOpen(self.ui.text_lineEdit, txt)
        
    def xml_open(self):
        self.fileOpen(self.ui.xml_lineEdit, xml)

    def database_open(self):
        self.fileOpen(self.ui.ServerLineEdit, mysql)

    def fileOpen(self, lineEdit, filters):
        openFile = QFileDialog.getOpenFileName(self, "Find Files", QDir.currentPath(), filters="*." + filters)
        uiDebug(openFile)
        if openFile != None :
            lineEdit.setText(openFile[0])
            self.setUserConfig()
            self.showConfig()
                    
    def choiceSql(self):
        uiDebug("choiceMysql")
        self.ui.text_groupBox.setChecked(False)
        self.ui.xml_groupBox.setChecked(False)
        if  self.ui.sqlTypeComboBox.currentText() == mysql:
            self.ui.openSqlpushButton.setDisabled(True)
            self.ui.userLineEdit.setEnabled(True)
            self.ui.passwordlineEdit.setEnabled(True)   
            
        if  self.ui.sqlTypeComboBox.currentText() == sqlite:
            self.ui.openSqlpushButton.setEnabled(True)
            self.ui.userLineEdit.setDisabled(True)
            self.ui.passwordlineEdit.setDisabled(True)
            
    def choiceTxt(self):
        uiDebug("choiceTxt")
        self.ui.mysql_groupBox.setChecked(False)
        self.ui.xml_groupBox.setChecked(False)

    def choiceXml(self):
        uiDebug("choiceXml")
        self.ui.mysql_groupBox.setChecked(False)
        self.ui.text_groupBox.setChecked(False)

    def setUserConfig(self):
        '''保留用户配置'''
        if self.ui.xml_groupBox.isChecked() == True:
            if self.ui.xml_lineEdit.text() != "":
                self.ControlMedia = xml
                self.ControlMediaPath = self.ui.xml_lineEdit.text()
                uiDebug("setUserConfig xml: " + xml)
         
        if self.ui.text_groupBox.isChecked() == True:
            if self.ui.text_lineEdit.text() != "":
                self.ControlMedia = txt
                self.ControlMediaPath = self.ui.text_lineEdit.text()
                uiDebug("setUserConfig txt: " + txt)
         
        if self.ui.mysql_groupBox.isChecked() == True:
            if self.ui.sqlTypeComboBox.currentText() == mysql:
                self.ControlMedia = mysql
                uiDebug("setUserConfig mysql: " + mysql)
            if self.ui.sqlTypeComboBox.currentText() == sqlite:
                self.ControlMedia = sqlite
                uiDebug("setUserConfig sqlite: " + sqlite)
            self.ControlMediaPath = self.ui.ServerLineEdit.text()

        self.Config.setContrlMedia(self.ControlMedia)
        self.Config.setControlMediaPath(self.ControlMediaPath)
        self.userConfig()    
        
    def createloginUsersContextMenu(self):
        '''添加登陆用户快捷菜单'''
        #pylint: disable=W0201
        self.killUserAct = QAction(self)
#        self.killUserAct.setText("kill user")
        
        self.messageUserAct = QAction(self)
#        self.messageUserAct.setText("message user")
        
        self.ui.loginUsers_tableView.addAction(self.killUserAct)
        self.ui.loginUsers_tableView.addAction(self.messageUserAct)
        
        QObject.connect(self.killUserAct, SIGNAL("activated()"), self, SLOT("killUser()"))
        QObject.connect(self.messageUserAct, SIGNAL("activated()"), self, SLOT("messageUser()"))
        
        self.ui.loginUsers_tableView.setContextMenuPolicy(Qt.ActionsContextMenu)

    def killUser(self):
        '''踢出一个用户'''
        try:
            index = self.ui.loginUsers_tableView.selectionModel().currentIndex()
            model = self.ui.loginUsers_tableView.model()
            user = model.item(index.row(), 0).index().data()
            self.connect.killUser(user)
            #pylint: disable=W0702
        except:
            pass    
#        model.removeRow(index.row(), index.parent())
        uiDebug("killUser")

    def messageUser(self):
        '''发送消息给用户'''
        uiDebug("messageUser")        
    
    def addUsers(self, user, instance):
        '''添加一条登陆用户数据'''

        index = self.ui.loginUsers_tableView.selectionModel().currentIndex()
        model = self.ui.loginUsers_tableView.model()
        row = model.rowCount(index.parent())
        model.setItem(row, 0, QStandardItem(user))
        model.setItem(row, 1, QStandardItem(str(instance)))
        
        uiDebug("loginUser")
    
    def removeUser(self, user):
        '''删除一条登陆用户数据'''
        index = self.ui.loginUsers_tableView.selectionModel().currentIndex()
        model = self.ui.loginUsers_tableView.model()
        maxRow = model.rowCount(index.parent())
#        print user
        for row in range(maxRow):
#            print row
#            print model.item(row, 0).index().data()
#            print type(model.item(row, 0).index().data())
            if user == model.item(row, 0).index().data():
                model.removeRow(row, index.parent())                             
                
        uiDebug("logoutUser")

    def refreshReceMessage(self, message):
        '''添加接收信息'''
        model = self.ui.messageLogs_listView.model()
#        model.setItem(model.rowCount(),QStandardItem(message))
        model.appendRow(QStandardItem(message))
        uiDebug("refreshReceMessage")        

    def refreshSendMessage(self, message):
        '''添加发送信息'''
        model = self.ui.messageLogs_listView.model()
#        model.setItem(model.rowCount(),QStandardItem(message))
        model.appendRow(QStandardItem(message))
        uiDebug("refreshSendMessage")        

    def retranslateUi(self):
        self.addUserAct.setText(QApplication.translate("MainWindow", "add User", None, QApplication.UnicodeUTF8))
        self.delUserAct.setText(QApplication.translate("MainWindow", "del User", None, QApplication.UnicodeUTF8))
        self.undoDelUserAct.setText(QApplication.translate("MainWindow", "undo del  User", None, QApplication.UnicodeUTF8))
        self.saveDataRowAct.setText(QApplication.translate("MainWindow", "save Data", None, QApplication.UnicodeUTF8))
        self.killUserAct.setText(QApplication.translate("MainWindow", "kill User", None, QApplication.UnicodeUTF8))
        self.messageUserAct.setText(QApplication.translate("MainWindow", "message User", None, QApplication.UnicodeUTF8))
        self.quitAction.setText(QApplication.translate("MainWindow", "Quit", None, QApplication.UnicodeUTF8))
        self.iTrayIcon.setToolTip(QApplication.translate("MainWindow", "One world, One dream!", None, QApplication.UnicodeUTF8))
        
        self.ui.retranslateUi(self)

    def loadConfig(self):
        '''加载配置文件'''
        configfile = QFileDialog.getOpenFileName(self, "Load Config File", QDir.currentPath(), filter="*.cfg")
        uiDebug(configfile)
        if configfile != None :
            self.readConfig(configfile)
            self.stopServer()
            self.startServer()
            self.showConfig()
        uiDebug("loadConfig") 

    def saveConfig(self):
        '''保留配置文件'''
        self.setUserConfig()
        self.Config.saveServerConfig()
        uiDebug("saveConfig") 

    def about(self):
        '''about'''
        aboutInfo = '''<HTML>
         <p>xdIm ver 0.2.0</p>
         <p>xdIm program is a software program by xd.</p>
         <p>Copy Right : "(C) 2008-2010 Programmers and Coders Everywhere"</p>
         <p><a href="http://www.xdIm.org/">http://www.xdIm.org</a></p>
         </HTML>"'''
         
        tranAboutInfo = QApplication.translate("MainWindow", aboutInfo, None, QApplication.UnicodeUTF8)
        QMessageBox.information(self, "xdIm information", tranAboutInfo)
        uiDebug("about") 
Example #6
0
class List(QMainWindow):
    """All Notes dialog"""
    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.closed = False
        self.sort_order = None
        self._init_interface()
        self.app.data_changed.connect(self._reload_data)
        self._init_notebooks()
        self._init_tags()
        self._init_notes()

    def _init_interface(self):
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())
        self.setWindowTitle(self.tr("Everpad / All Notes"))
        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(
            QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    def _init_notebooks(self):
        self._current_notebook = None
        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(
            self.notebook_context_menu)

    def _init_tags(self):
        self._current_tag = None
        self.tagsModel = QStandardItemModel()
        self.ui.tagsList.setModel(self.tagsModel)
        self.ui.tagsList.selection.connect(self.tag_selection_changed)
        self.ui.tagsList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tagsList.customContextMenuRequested.connect(
            self.tag_context_menu)

    def _init_notes(self):
        self._current_note = None
        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.selection.connect(self.note_selection_changed)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(
            self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(
            self.sort_order_updated)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.tagsList.clearSelection()
            self.notebook_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def tag_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.notebooksList.clearSelection()
            self.tag_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def note_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.note_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        super(List, self).showEvent(*args, **kwargs)
        self._reload_data()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def note_selected(self, index):
        self._current_note = index

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0

        self._current_notebook = notebook_id
        self._current_tag = SELECT_NONE

        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array(
            [], signature='i')

        if hasattr(
                item,
                'stack'):  # stack selected, retrieve all underlying notebooks
            notebook_filter = []
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    notebook_filter.append(notebook.id)

        notes = self.app.provider.find_notes(
            '',
            notebook_filter,
            dbus.Array([], signature='i'),
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64

        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    def tag_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            tag_id = item.tag.id
        else:
            tag_id = 0

        self._current_notebook = SELECT_NONE
        self._current_tag = tag_id

        tag_filter = [tag_id] if tag_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '',
            dbus.Array([], signature='i'),
            tag_filter,
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self, oldStack=''):
        name, status, stack = self._notebook_new_name(
            self.tr('Create new notebook'), '', oldStack)
        if status:
            notebook_struct = self.app.provider.create_notebook(name, stack)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(
                self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status, stack = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name, notebook.stack)
        if status:
            notebook.name = name
            notebook.stack = stack
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(
                self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr(
                "Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(
                self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def rename_stack(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        stack = item.stack
        name, status = self._stack_new_name(
            self.tr('Rename stack'),
            stack,
        )
        if status:
            # loop notebooks and update stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    notebook.stack = name
                    self.app.provider.update_notebook(notebook.struct)

            self.app.send_notify(self.tr('Stack "%s" renamed!') % name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_stack(self):
        msg = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a stack"),
            self.
            tr("Are you sure want to delete this stack? Notebooks and notes are preserved."
               ), QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            # loop notebooks and remove stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if (notebook.stack == item.stack):
                    print "Clearing one notebook from its stack."
                    notebook.stack = ''
                    self.app.provider.update_notebook(notebook.struct)

            self._reload_notebooks_list()

    @Slot()
    def remove_tag(self):
        msg = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a tag"),
            self.
            tr("Are you sure want to delete this tag and untag all notes tagged with it?"
               ), QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.tagsList.currentIndex()
            item = self.tagsModel.itemFromIndex(index)
            self.app.provider.delete_tag(item.tag.id)
            self.app.send_notify(self.tr('Tag "%s" deleted!') % item.tag.name)
            self._reload_tags_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') %
            item.note.title, QMessageBox.Yes | QMessageBox.No)
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(
                self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
        if hasattr(item, 'stack'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_stack)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_stack)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def tag_context_menu(self, pos):
        index = self.ui.tagsList.currentIndex()
        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            menu = QMenu(self.ui.tagsList)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_tag)
            menu.exec_(self.ui.tagsList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'),
                       self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                       self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_data(self):
        self._reload_notebooks_list(self._current_notebook)
        self._reload_tags_list(self._current_tag)
        self._mark_note_selected(self._current_note)

    def _reload_notebooks_list(self, select_notebook_id=None):
        # TODO could enable selecting an already selected stack
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'),
                             self.tr('All Notes'))
        self.notebooksModel.appendRow(root)
        selected_item = root

        stacks = {}
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)

            if (notebook.stack == ''):
                root.appendRow(item)
            else:
                if (notebook.stack not in stacks.keys()):
                    stack = QStandardItem(QIcon.fromTheme('user-home'),
                                          notebook.stack)
                    stack.stack = notebook.stack
                    root.appendRow(stack)
                    stacks[notebook.stack] = stack

                stacks[notebook.stack].appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()

        if selected_item and not select_notebook_id == SELECT_NONE:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude='', oldStack=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name,
                    self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter notebook name:'),
                                            text=exclude)
        while name in names and status:
            message = self.tr(
                'Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        if status:
            stack, status = QInputDialog.getText(
                self,
                title,
                self.tr('Enter stack name (empty for no stack):'),
                text=oldStack)
        else:
            stack = oldStack
        return name, status, stack

    def _stack_new_name(self, title, value=''):
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter stack name:'),
                                            text=value)
        return name, status

    def _reload_tags_list(self, select_tag_id=None):
        # TODO nested tags
        self.tagsModel.clear()
        tagRoot = QStandardItem(QIcon.fromTheme('user-home'),
                                self.tr('All Tags'))
        self.tagsModel.appendRow(tagRoot)
        selected_item = tagRoot

        for tag_struct in self.app.provider.list_tags():
            tag = Tag.from_tuple(tag_struct)
            count = self.app.provider.get_tag_notes_count(tag.id)
            item = QTagItem(tag, count)
            tagRoot.appendRow(item)

            if select_tag_id and tag.id == select_tag_id:
                selected_item = item

        self.ui.tagsList.expandAll()
        if selected_item and not select_tag_id == SELECT_NONE:
            index = self.tagsModel.indexFromItem(selected_item)
            self.ui.tagsList.setCurrentIndex(index)
            self.tag_selected(index)

    def _mark_note_selected(self, index):
        if index:
            self.ui.notesList.setCurrentIndex(index)
Example #7
0
class List(QDialog):
    """All Notes dialog"""
    def __init__(self, app, *args, **kwargs):
        QDialog.__init__(self, *args, **kwargs)
        self.app = app
        self.closed = False
        self.sort_order = None
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())

        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(
            self.notebook_context_menu)

        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(
            self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(
            self.sort_order_updated)

        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.notebook_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        QDialog.showEvent(self, *args, **kwargs)
        self._reload_notebooks_list()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0
        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array(
            [], signature='i')
        notes = self.app.provider.find_notes(
            '',
            notebook_filter,
            dbus.Array([], signature='i'),
            0,
            2**31 - 1,
            Note.ORDER_TITLE,
            -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self):
        name, status = self._notebook_new_name(self.tr('Create new notebook'))
        if status:
            notebook_struct = self.app.provider.create_notebook(name)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(
                self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status = self._notebook_new_name(
            self.tr('Rename notebook'),
            notebook.name,
        )
        if status:
            notebook.name = name
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(
                self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr(
                "Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No)
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(
                self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical, self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') %
            item.note.title, QMessageBox.Yes | QMessageBox.No)
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(
                self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'),
                           self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                           self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'),
                       self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'),
                       self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_notebooks_list(self, select_notebook_id=None):
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'),
                             self.tr('All Notes'))
        self.notebooksModel.appendRow(root)

        selected_item = root
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)
            root.appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()
        if selected_item:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name,
                    self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self,
                                            title,
                                            self.tr('Enter notebook name:'),
                                            text=exclude)
        while name in names and status:
            message = self.tr(
                'Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        return name, status
Example #8
0
class List(QMainWindow):
    """All Notes dialog"""

    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.closed = False
        self.sort_order = None
        self._init_interface()
        self.app.data_changed.connect(self._reload_data)
        self._init_notebooks()
        self._init_tags()
        self._init_notes()

    def _init_interface(self):
        self.ui = Ui_List()
        self.ui.setupUi(self)
        self.setWindowIcon(get_icon())
        self.setWindowTitle(self.tr("Everpad / All Notes"))
        self.ui.newNotebookBtn.setIcon(QIcon.fromTheme('folder-new'))
        self.ui.newNotebookBtn.clicked.connect(self.new_notebook)

        self.ui.newNoteBtn.setIcon(QIcon.fromTheme('document-new'))
        self.ui.newNoteBtn.clicked.connect(self.new_note)

        self.ui.newNoteBtn.setShortcut(QKeySequence(self.tr('Ctrl+n')))
        self.ui.newNotebookBtn.setShortcut(QKeySequence(self.tr('Ctrl+Shift+n')))
        QShortcut(QKeySequence(self.tr('Ctrl+q')), self, self.close)

    def _init_notebooks(self):
        self._current_notebook = None
        self.notebooksModel = QStandardItemModel()
        self.ui.notebooksList.setModel(self.notebooksModel)
        self.ui.notebooksList.selection.connect(self.selection_changed)
        self.ui.notebooksList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notebooksList.customContextMenuRequested.connect(self.notebook_context_menu)

    def _init_tags(self):
        self._current_tag = None
        self.tagsModel = QStandardItemModel()
        self.ui.tagsList.setModel(self.tagsModel)
        self.ui.tagsList.selection.connect(self.tag_selection_changed)
        self.ui.tagsList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.tagsList.customContextMenuRequested.connect(self.tag_context_menu)

    def _init_notes(self):
        self._current_note = None
        self.notesModel = QStandardItemModel()
        self.notesModel.setHorizontalHeaderLabels(
            [self.tr('Title'), self.tr('Last Updated')])

        self.ui.notesList.setModel(self.notesModel)
        self.ui.notesList.selection.connect(self.note_selection_changed)
        self.ui.notesList.doubleClicked.connect(self.note_dblclicked)
        self.ui.notesList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.notesList.customContextMenuRequested.connect(self.note_context_menu)
        self.ui.notesList.header().sortIndicatorChanged.connect(self.sort_order_updated)

    @Slot(QItemSelection, QItemSelection)
    def selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.tagsList.clearSelection()
            self.notebook_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def tag_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.ui.notebooksList.clearSelection()
            self.tag_selected(selected.indexes()[-1])

    @Slot(QItemSelection, QItemSelection)
    def note_selection_changed(self, selected, deselected):
        if len(selected.indexes()):
            self.note_selected(selected.indexes()[-1])

    def showEvent(self, *args, **kwargs):
        super(List, self).showEvent(*args, **kwargs)
        self._reload_data()
        self.readSettings()

    def writeSettings(self):
        self.app.settings.setValue('list-geometry', self.saveGeometry())
        for key, widget in self._getRestorableItems():
            self.app.settings.setValue(key, widget.saveState())

    def _getRestorableItems(self):
        return (
            ('list-splitter-state', self.ui.splitter),
            ('list-header-state', self.ui.notesList.header()),
        )

    def readSettings(self):
        geometry = self.app.settings.value('list-geometry')
        if geometry:
            self.restoreGeometry(geometry)

        for key, widget in self._getRestorableItems():
            state = self.app.settings.value(key)
            if state:
                widget.restoreState(state)

    def closeEvent(self, event):
        self.writeSettings()
        event.ignore()
        self.closed = True
        self.hide()

    @Slot(int, Qt.SortOrder)
    def sort_order_updated(self, logicalIndex, order):
        self.sort_order = (logicalIndex, order.name)
        self.app.settings.setValue('list-notes-sort-order', self.sort_order)

    def note_selected(self, index):
        self._current_note = index

    def notebook_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            notebook_id = item.notebook.id
        else:
            notebook_id = 0

        self._current_notebook = notebook_id
        self._current_tag = SELECT_NONE

        notebook_filter = [notebook_id] if notebook_id > 0 else dbus.Array([], signature='i')

        if hasattr(item, 'stack'):  # stack selected, retrieve all underlying notebooks
            notebook_filter = []
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    notebook_filter.append(notebook.id)

        notes = self.app.provider.find_notes(
            '', notebook_filter, dbus.Array([], signature='i'),
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64

        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    def tag_selected(self, index):
        self.notesModel.setRowCount(0)

        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            tag_id = item.tag.id
        else:
            tag_id = 0

        self._current_notebook = SELECT_NONE
        self._current_tag = tag_id

        tag_filter = [tag_id] if tag_id > 0 else dbus.Array([], signature='i')
        notes = self.app.provider.find_notes(
            '', dbus.Array([], signature='i'), tag_filter,
            0, 2 ** 31 - 1, Note.ORDER_TITLE, -1,
        )  # fails with sys.maxint in 64
        for note_struct in notes:
            note = Note.from_tuple(note_struct)
            self.notesModel.appendRow(QNoteItemFactory(note).make_items())

        sort_order = self.sort_order
        if sort_order is None:
            sort_order = self.app.settings.value('list-notes-sort-order')

        if sort_order:
            logicalIndex, order = sort_order
            order = Qt.SortOrder.values[order]
            self.ui.notesList.sortByColumn(int(logicalIndex), order)

    @Slot()
    def note_dblclicked(self, index):
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def new_notebook(self, oldStack=''):
        name, status, stack = self._notebook_new_name(self.tr('Create new notebook'), '', oldStack)
        if status:
            notebook_struct = self.app.provider.create_notebook(name, stack)
            notebook = Notebook.from_tuple(notebook_struct)

            self.app.send_notify(self.tr('Notebook "%s" created!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def rename_notebook(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        notebook = item.notebook
        name, status, stack = self._notebook_new_name(
            self.tr('Rename notebook'), notebook.name, notebook.stack
        )
        if status:
            notebook.name = name
            notebook.stack = stack
            self.app.provider.update_notebook(notebook.struct)
            self.app.send_notify(self.tr('Notebook "%s" renamed!') % notebook.name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_notebook(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a notebook"),
            self.tr("Are you sure want to delete this notebook and its notes?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            self.app.provider.delete_notebook(item.notebook.id)
            self.app.send_notify(self.tr('Notebook "%s" deleted!') % item.notebook.name)
            self._reload_notebooks_list()

    @Slot()
    def rename_stack(self):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        stack = item.stack
        name, status = self._stack_new_name(
            self.tr('Rename stack'), stack,
        )
        if status:
            # loop notebooks and update stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    notebook.stack = name
                    self.app.provider.update_notebook(notebook.struct)

            self.app.send_notify(self.tr('Stack "%s" renamed!') % name)
            self._reload_notebooks_list(notebook.id)

    @Slot()
    def remove_stack(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a stack"),
            self.tr("Are you sure want to delete this stack? Notebooks and notes are preserved."),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.notebooksList.currentIndex()
            item = self.notebooksModel.itemFromIndex(index)
            # loop notebooks and remove stack str
            for notebook_struct in self.app.provider.list_notebooks():
                notebook = Notebook.from_tuple(notebook_struct)
                if(notebook.stack == item.stack):
                    print "Clearing one notebook from its stack."
                    notebook.stack = ''
                    self.app.provider.update_notebook(notebook.struct)

            self._reload_notebooks_list()

    @Slot()
    def remove_tag(self):
        msg = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a tag"),
            self.tr("Are you sure want to delete this tag and untag all notes tagged with it?"),
            QMessageBox.Yes | QMessageBox.No
        )
        if msg.exec_() == QMessageBox.Yes:
            index = self.ui.tagsList.currentIndex()
            item = self.tagsModel.itemFromIndex(index)
            self.app.provider.delete_tag(item.tag.id)
            self.app.send_notify(self.tr('Tag "%s" deleted!') % item.tag.name)
            self._reload_tags_list()

    @Slot()
    def new_note(self):
        index = self.ui.notebooksList.currentIndex()
        notebook_id = NONE_ID
        if index.row():
            item = self.notebooksModel.itemFromIndex(index)
            notebook_id = item.notebook.id

        self.app.indicator.create(notebook_id=notebook_id)

    @Slot()
    def edit_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        self.app.indicator.open(item.note)

    @Slot()
    def remove_note(self):
        index = self.ui.notesList.currentIndex()
        item = self.notesModel.itemFromIndex(index)
        msgBox = QMessageBox(
            QMessageBox.Critical,
            self.tr("You are trying to delete a note"),
            self.tr('Are you sure want to delete note "%s"?') % item.note.title,
            QMessageBox.Yes | QMessageBox.No
        )
        if msgBox.exec_() == QMessageBox.Yes:
            self.app.provider.delete_note(item.note.id)
            self.app.send_notify(self.tr('Note "%s" deleted!') % item.note.title)
            self.notebook_selected(self.ui.notebooksList.currentIndex())

    @Slot(QPoint)
    def notebook_context_menu(self, pos):
        index = self.ui.notebooksList.currentIndex()
        item = self.notebooksModel.itemFromIndex(index)
        if hasattr(item, 'notebook'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_notebook)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_notebook)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))
        if hasattr(item, 'stack'):
            menu = QMenu(self.ui.notebooksList)
            menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Rename'), self.rename_stack)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_stack)
            menu.exec_(self.ui.notebooksList.mapToGlobal(pos))

    @Slot(QPoint)
    def tag_context_menu(self, pos):
        index = self.ui.tagsList.currentIndex()
        item = self.tagsModel.itemFromIndex(index)
        if hasattr(item, 'tag'):
            menu = QMenu(self.ui.tagsList)
            menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_tag)
            menu.exec_(self.ui.tagsList.mapToGlobal(pos))

    @Slot(QPoint)
    def note_context_menu(self, pos):
        menu = QMenu(self.ui.notesList)
        menu.addAction(QIcon.fromTheme('gtk-edit'), self.tr('Edit'), self.edit_note)
        menu.addAction(QIcon.fromTheme('gtk-delete'), self.tr('Remove'), self.remove_note)
        menu.exec_(self.ui.notesList.mapToGlobal(pos))

    def _reload_data(self):
        self._reload_notebooks_list(self._current_notebook)
        self._reload_tags_list(self._current_tag)
        self._mark_note_selected(self._current_note)

    def _reload_notebooks_list(self, select_notebook_id=None):
        # TODO could enable selecting an already selected stack
        self.notebooksModel.clear()
        root = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Notes'))
        self.notebooksModel.appendRow(root)
        selected_item = root

        stacks = {}
        for notebook_struct in self.app.provider.list_notebooks():
            notebook = Notebook.from_tuple(notebook_struct)
            count = self.app.provider.get_notebook_notes_count(notebook.id)
            item = QNotebookItem(notebook, count)

            if(notebook.stack == ''):
                root.appendRow(item)
            else:
                if(notebook.stack not in stacks.keys()):
                    stack = QStandardItem(QIcon.fromTheme('user-home'), notebook.stack)
                    stack.stack = notebook.stack
                    root.appendRow(stack)
                    stacks[notebook.stack] = stack

                stacks[notebook.stack].appendRow(item)

            if select_notebook_id and notebook.id == select_notebook_id:
                selected_item = item

        self.ui.notebooksList.expandAll()

        if selected_item and not select_notebook_id == SELECT_NONE:
            index = self.notebooksModel.indexFromItem(selected_item)
            self.ui.notebooksList.setCurrentIndex(index)
            self.notebook_selected(index)

    def _notebook_new_name(self, title, exclude='', oldStack=''):
        names = map(lambda nb: Notebook.from_tuple(nb).name, self.app.provider.list_notebooks())
        try:
            names.remove(exclude)
        except ValueError:
            pass
        name, status = QInputDialog.getText(self, title, self.tr('Enter notebook name:'), text=exclude)
        while name in names and status:
            message = self.tr('Notebook with this name already exist. Enter notebook name')
            name, status = QInputDialog.getText(self, title, message)
        if status:
            stack, status = QInputDialog.getText(self, title, self.tr('Enter stack name (empty for no stack):'), text=oldStack)
        else:
            stack = oldStack
        return name, status, stack

    def _stack_new_name(self, title, value=''):
        name, status = QInputDialog.getText(self, title, self.tr('Enter stack name:'), text=value)
        return name, status

    def _reload_tags_list(self, select_tag_id=None):
        # TODO nested tags
        self.tagsModel.clear()
        tagRoot = QStandardItem(QIcon.fromTheme('user-home'), self.tr('All Tags'))
        self.tagsModel.appendRow(tagRoot)
        selected_item = tagRoot

        for tag_struct in self.app.provider.list_tags():
            tag = Tag.from_tuple(tag_struct)
            count = self.app.provider.get_tag_notes_count(tag.id)
            item = QTagItem(tag, count)
            tagRoot.appendRow(item)

            if select_tag_id and tag.id == select_tag_id:
                selected_item = item

        self.ui.tagsList.expandAll()
        if selected_item and not select_tag_id == SELECT_NONE:
            index = self.tagsModel.indexFromItem(selected_item)
            self.ui.tagsList.setCurrentIndex(index)
            self.tag_selected(index)

    def _mark_note_selected(self, index):
        if index:
            self.ui.notesList.setCurrentIndex(index)
    def testClear(self):

        model = QStandardItemModel()
        root = model.invisibleRootItem()
        model.clear()
        self.assertFalse(shiboken.isValid(root))
Example #10
0
class ConsoleWidget(QMainWindow):
    def __init__(self):
        super(ConsoleWidget, self).__init__()
        self.setWindowTitle('1c query')

        self._connection = None

        self._home = os.path.expanduser('~/%s' % QApplication.applicationName())
        if not os.path.isdir(self._home):
            os.mkdir(self._home)

        self.queryToolBar = self.addToolBar('Query')
        self.queryAction = self.queryToolBar.addAction('Run', self.executeQuery)
        self.queryAction.setDisabled(True)

        uri_history = list()
        path = os.path.join(self._home, 'uri_history.txt')
        if os.path.isfile(path):
            uri_history = open(path, 'r').read().split('\n')

        self.connectionToolBar = self.addToolBar('Connection')
        self.connectionUriCombo = QComboBox(self)
        self.connectionUriCombo.setEditable(True)
        if not uri_history:
            self.connectionUriCombo.addItem('File="";usr="";pwd="";')
            self.connectionUriCombo.addItem('Srvr="{host}";Ref="{ref}";Usr="******";Pwd="{password}";')
        else:
            self.connectionUriCombo.addItems(uri_history)
            self.connectionUriCombo.setCurrentIndex(len(uri_history) - 1)
        self.connectionUriCombo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
        self.connectionToolBar.addWidget(self.connectionUriCombo)

        self.onesVersionCombo = QComboBox(self)
        self.onesVersionCombo.addItems(['8.3', '8.2', '8.1', '8.0'])
        self.onesVersionCombo.setCurrentIndex(0)
        self.connectionToolBar.addWidget(self.onesVersionCombo)
        self.connectAction = self.connectionToolBar.addAction('Connect', self.connectOneS)
        self.disconnectAction = self.connectionToolBar.addAction('Disconnect', self.disconnectOneS)
        self.disconnectAction.setDisabled(True)

        self.logEdit = QPlainTextEdit(self)
        self.logDock = QDockWidget('Log', self)
        self.logDock.setWidget(self.logEdit)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logDock, Qt.Horizontal)

        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)

        self.sqlEdit = QTextEdit(self)
        self.sqlEdit.setLineWrapMode(QTextEdit.NoWrap)

        path = os.path.join(self._home, 'last-sql.txt')
        if os.path.isfile(path):
            sql = open(path, 'r').read()
            self.sqlEdit.setText(sql)

        self.model = QStandardItemModel(self)
        self.tableView = QTableView(self)
        self.tableView.setModel(self.model)

        self.splitter.addWidget(self.sqlEdit)
        self.splitter.addWidget(self.tableView)
        self.splitter.setStretchFactor(0, 3)
        self.splitter.setStretchFactor(1, 2)

    def query(self, sql):
        if not self._connection:
            self.logEdit.appendPlainText('No connection')
            return None

        try:
            query = self._connection.NewObject('Query', sql)
            result = query.Execute()
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return None

        return result

    def refresh(self, result):
        self.model.clear()

        columns = list()
        result_columns = result.Columns
        for index in range(result_columns.Count()):
            name = result_columns.Get(index).Name
            columns.append(name)

        self.model.setColumnCount(len(columns))
        for section, name in enumerate(columns):
            self.model.setHeaderData(section, Qt.Horizontal, name)

        select = result.Choose()
        self.logEdit.appendPlainText('Selected %d records' % select.Count())
        while select.Next():
            items = list()
            for index in range(len(columns)):
                value = select.Get(index)

                item = QStandardItem('')
                if isinstance(value, bool):
                    item.setText(value and 'Yes' or 'No')

                elif isinstance(value, (int, str)):
                    item.setText(str(value))

                elif isinstance(value, datetime.datetime):
                    item.setText(value.strftime('%Y.%m.%d %H:%M:%S'))

                else:
                    item.setText(str(value))
                items.append(item)

            self.model.appendRow(items)

    @Slot()
    def executeQuery(self):
        sql = self.sqlEdit.toPlainText()
        result = self.query(sql)
        if result:
            path = os.path.join(self._home, 'last-sql.txt')
            open(path, 'w').write(sql)
            self.refresh(result)

    @Slot()
    def connectOneS(self):
        uri = self.connectionUriCombo.currentText().strip()
        if not uri:
            self.logEdit.appendPlainText('Need a connection string')
            return

        version = self.onesVersionCombo.currentText()
        comName = "V%s.COMConnector" % str(version).replace('.', '')

        pythoncom.CoInitialize()
        try:
            obj = win32com.client.Dispatch(comName)
            self._connection = obj.Connect(uri)
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return

        self.connectAction.setDisabled(True)
        self.disconnectAction.setEnabled(True)
        self.queryAction.setEnabled(True)

        uri_history = list()
        for i in range(self.connectionUriCombo.count()):
            uri_history.append(self.connectionUriCombo.itemText(i))

        if uri not in uri_history:
            self.connectionUriCombo.clearEditText()
            self.connectionUriCombo.addItem(uri)
            self.connectionUriCombo.setCurrentIndex(len(uri_history))
            uri_history.append(uri)
            path = os.path.join(self._home, 'uri_history.txt')
            open(path, 'w').write('\n'.join(uri_history))

    @Slot()
    def disconnectOneS(self):
        pythoncom.CoUninitialize()
        self._connection = None
        self.connectAction.setEnabled(True)
        self.disconnectAction.setDisabled(True)
        self.queryAction.setDisabled(True)