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)
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
def testClear(self): model = QStandardItemModel() root = model.invisibleRootItem() model.clear() self.assertFalse(shiboken.isValid(root))
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")
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)
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
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)
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)