# HG changeset patch # User Aziz K?ksal # Date 1192565617 -7200 # Node ID 5968e273449b02718fd7d02409df2460cc8597c7 # Parent cdbb2bf6dd072d2d169d9fcce8827ee1e84320f8 Translator: added new modules; made fixes and many additions. diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/langfile.py --- a/trunk/src/translator/langfile.py Fri Oct 12 22:51:40 2007 +0200 +++ b/trunk/src/translator/langfile.py Tue Oct 16 22:13:37 2007 +0200 @@ -1,52 +1,56 @@ # -*- coding: utf-8 -*- # Author: Aziz Köksal # License: GPL2 -import exceptions import yaml +from errors import LoadingError class LangFile: - class LoadingError(exceptions.Exception): - def __init__(self, msg): - self.msg = msg - return - def __str__(self): - return self.msg - def __init__(self, filePath): + self.filePath = filePath # Load language file and check data integrity. doc = yaml.load(open(filePath, "r")) self.doc = doc self.checkType(doc, dict) try: - self.langCode = doc["LangCode"] - self.authors = doc["Authors"] - self.license = doc["License"] - self.messages = doc["Messages"] + self.langCode = str(doc["LangCode"]) + self.authors = list(doc["Authors"]) + self.license = unicode(doc["License"]) + self.messages = list(doc["Messages"]) except KeyError, e: raise LoadingError("Missing member '%s' in '%s'" % (e.message, filePath)) - self.checkType(self.langCode, dict) - self.checkType(self.authors, list) + authors = [] for author in self.authors: - self.checkType(author, list) - if len(author) != 2: - raise LoadingError("") - self.checkType(author[0], str) - self.checkType(author[1], str) - self.checkType(self.license, str) - self.checkType(self.messages, list) + author = list(author) + author_len = len(author) + if author_len == 0: + pass + elif author_len == 1: + authors += [unicode(author[0]), ""] + else: + authors += [unicode(author[0]), unicode(author[1])] + self.authors = authors + + messages = [] for msg in self.messages: - self.checkType(msg, dict) - if not msg.has_key("ID") or \ - not msg.has_key("Text") or \ - not msg.has_key("Annotation") or \ - not msg.has_key("LastEdited"): - raise LoadingError("") + self.checkType(msg, dict, "LangFile: messages must be of type dict.") + try: + msg["ID"] = int(msg["ID"]) + msg["Text"] = unicode(msg["Text"]) + msg["Annot"] = unicode(msg["Annot"]) + msg["LastEd"] = unicode(msg["LastEd"]) + except KeyError, e: + raise LoadingError("LangFile: a message is missing the '%s' key." % str(e)) + messages += [msg] + self.messages = messages def checkType(self, var, type_, msg=""): if not isinstance(var, type_): raise LoadingError(msg) + def save(self): + pass + def newLangFile(langCode, authors, license): return { "LangCode":langCode, diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/project.py --- a/trunk/src/translator/project.py Fri Oct 12 22:51:40 2007 +0200 +++ b/trunk/src/translator/project.py Tue Oct 16 22:13:37 2007 +0200 @@ -1,18 +1,13 @@ # -*- coding: utf-8 -*- # Author: Aziz Köksal # License: GPL2 +import os +from errors import LoadingError import langfile import datetime -import exceptions import yaml class Project: - class LoadingError(exceptions.Exception): - def __init__(self, msg): - self.msg = msg - return - def __str__(self): - return self.msg # Members: # name # source @@ -21,42 +16,53 @@ # msgids # creationDate def __init__(self, projectPath): + self.projectPath = projectPath # Load project file and check data integrity. doc = yaml.load(open(projectPath, "r")) self.doc = doc self.checkType(doc, dict) try: - self.name = doc["Name"] - self.source = doc["SourceLangFile"] - self.langFilePaths = doc["LangFiles"] - self.msgIDs = doc["MsgIDs"] - self.creationDate = doc["CreationDate"] + self.name = str(doc["Name"]) + self.source = str(doc["SourceLangFile"]) + self.langFilePaths = list(doc["LangFiles"]) + self.msgIDs = list(doc["MsgIDs"]) + self.creationDate = str(doc["CreationDate"]) except KeyError, e: - raise LoadingError("Missing member '%s' in '%s'" % (e.message, filePath)) + raise LoadingError("Missing member '%s' in '%s'" % (e.message, projectPath)) - self.checkType(self.name, str) - self.checkType(self.source, str) - self.checkType(self.langFilePaths, list) for path in self.langFilePaths: self.checkType(path, str) - self.checkType(self.msgIDs, list) + + msgIDs = [] for msg in self.msgIDs: - if not isinstance(msg, dict) or \ - not msg.has_key("ID") or \ - not msg.has_key("Name") or \ - not msg.has_key("Order"): - raise LoadingError("") - self.checkType(self.creationDate, str) + self.checkType(msg, dict) + try: + msg["ID"] = int(msg["ID"]) + msg["Name"] = unicode(msg["Name"]) + msg["Order"] = int(msg["Order"]) + except KeyError, e: + raise LoadingError("Project: a message is missing the '%s' key." % str(e)) + msgIDs += [msg] + self.msgIDs = msgIDs # Load language files. self.langFiles = [] for filePath in self.langFilePaths: - self.langFiles += LangFile(filePath) + if not os.path.exists(filePath): + projectDir = os.path.dirname(projectPath) + filePath2 = os.path.join(projectDir, filePath) + if not os.path.exists(filePath2): + raise LoadingError("Project: Language file '%s' doesn't exist"%filePath) + filePath = filePath2 + self.langFiles += [langfile.LangFile(filePath)] def checkType(self, var, type_): if not isinstance(var, type_): raise LoadingException("%s is not of type %s" % (str(var), str(type_))) + def save(self): + pass + def newProjectData(projectName): return { "Name":projectName, @@ -65,3 +71,4 @@ "MsgIDs":[], "CreationDate":str(datetime.datetime.utcnow()) } + diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/project_properties.ui --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/translator/project_properties.ui Tue Oct 16 22:13:37 2007 +0200 @@ -0,0 +1,112 @@ + + ProjectProperties + + + + 0 + 0 + 400 + 148 + + + + Project Properties + + + + + + + + Project name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + projectNameField + + + + + + + + + + Build command: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + buildCommandField + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ProjectProperties + accept() + + + 227 + 278 + + + 157 + 274 + + + + + buttonBox + rejected() + ProjectProperties + reject() + + + 295 + 284 + + + 286 + 274 + + + + + diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/translator.py --- a/trunk/src/translator/translator.py Fri Oct 12 22:51:40 2007 +0200 +++ b/trunk/src/translator/translator.py Tue Oct 16 22:13:37 2007 +0200 @@ -10,11 +10,13 @@ from ui_translator import Ui_MainWindow from ui_about import Ui_AboutDialog from ui_new_project import Ui_NewProjectDialog +from ui_project_properties import Ui_ProjectProperties from project import Project g_scriptDir = sys.path[0] g_CWD = os.getcwd() +g_projectExt = ".tproj" g_settingsFile = os.path.join(g_scriptDir, "settings.yaml") g_settings = {} @@ -23,12 +25,15 @@ QtGui.QMainWindow.__init__(self) self.setupUi(self) + self.project = None # Modifications - + self.disableMenuItems() # Custom connections QtCore.QObject.connect(self.action_About, QtCore.SIGNAL("triggered()"), self.showAboutDialog) QtCore.QObject.connect(self.action_New_Project, QtCore.SIGNAL("triggered()"), self.createNewProject) - QtCore.QObject.connect(self.action_Open_Project, QtCore.SIGNAL("triggered()"), self.openProject) + QtCore.QObject.connect(self.action_Open_Project, QtCore.SIGNAL("triggered()"), self.openProjectAction) + QtCore.QObject.connect(self.action_Close_Project, QtCore.SIGNAL("triggered()"), self.closeProject) + QtCore.QObject.connect(self.action_Properties, QtCore.SIGNAL("triggered()"), self.showProjectProperties) self.readSettings() @@ -37,15 +42,66 @@ Ui_AboutDialog().setupUi(about) about.exec_() + def showProjectProperties(self): + dialog = QtGui.QDialog() + Ui_ProjectProperties().setupUi(dialog) + dialog.exec_() + def createNewProject(self): NewProjectDialog().exec_() - def openProject(self): - filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Translator Project (*.tproj)"); + def openProjectAction(self): + if self.closeProjectIfOpen(): + return + filePath = QtGui.QFileDialog.getOpenFileName(self, "Select Project File", g_CWD, "Translator Project (*%s)" % g_projectExt); + if filePath: + self.openProject(str(filePath)) + + def openProject(self, filePath): + from errors import LoadingError + try: + self.project = Project(filePath) + except LoadingError, e: + QtGui.QMessageBox.critical(self, "Error", u"Couldn't load project file:\n\n"+str(e)) + return + self.enableMenuItems() + self.projectTree = ProjectTree(self) + self.projectTree.setProject(self.project) + self.vboxlayout.addWidget(self.projectTree) - project = Project(filePath) + def closeProjectIfOpen(self): + if self.project == None: + return False + return self.closeProject() + + def closeProject(self): + if self.project == None: + return True + + button = QtGui.QMessageBox.question(self, "Closing", "Close the current project?", QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) + if button == QtGui.QMessageBox.Cancel: + return False + + del self.project + self.project = None + self.disableMenuItems() + self.vboxlayout.removeWidget(self.projectTree) + self.projectTree.close() + return True + + def enableMenuItems(self): + self.action_Close_Project.setEnabled(True) + self.menubar.insertMenu(self.menu_Help.menuAction(), self.menu_Project) + + def disableMenuItems(self): + self.action_Close_Project.setEnabled(False) + self.menubar.removeAction(self.menu_Project.menuAction()) def closeEvent(self, event): + if self.closeProject() == False: + event.ignore() + return + # Exitting self.writeSettings() def moveToCenterOfDesktop(self): @@ -83,11 +139,35 @@ } yaml.dump(g_settings, open(g_settingsFile, "w")) #default_flow_style=False +class MsgIDItem(QtGui.QTreeWidgetItem): + def __init__(self, parent, text): + QtGui.QTreeWidgetItem.__init__(self, parent, [text]) + +class LangFileItem(QtGui.QTreeWidgetItem): + def __init__(self, parent, text): + QtGui.QTreeWidgetItem.__init__(self, parent, [text]) class ProjectTree(QtGui.QTreeWidget): def __init__(self, parent): QtGui.QTreeWidget.__init__(self, parent) + self.topItem = None + self.msgIDsItem = None + def setProject(self, project): + self.project = project + + self.topItem = QtGui.QTreeWidgetItem([self.project.name]) + self.addTopLevelItem(self.topItem) + + self.msgIDsItem = QtGui.QTreeWidgetItem(self.topItem, ["Message IDs"]) + for msgID in self.project.msgIDs: + MsgIDItem(self.msgIDsItem, msgID["Name"]) + + for langFile in self.project.langFiles: + langFileItem = LangFileItem(self.topItem, langFile.langCode) + + for x in [self.topItem, self.msgIDsItem]: + x.setExpanded(True) class NewProjectDialog(QtGui.QDialog, Ui_NewProjectDialog): def __init__(self): @@ -97,10 +177,12 @@ QtCore.QObject.connect(self.pickFileButton, QtCore.SIGNAL("clicked()"), self.pickFilePath) def pickFilePath(self): - filePath = QtGui.QFileDialog.getSaveFileName(self, "New Project File", g_CWD, "Translator Project (*.tproj)"); + filePath = QtGui.QFileDialog.getSaveFileName(self, "New Project File", g_CWD, "Translator Project (*%s)" % g_projectExt); + if not filePath: + return filePath = str(filePath) # Convert QString - if os.path.splitext(filePath)[1] != ".tproj": - filePath += ".tproj" + if os.path.splitext(filePath)[1] != g_projectExt: + filePath += g_projectExt self.projectFilePath.setText(filePath) def accept(self): @@ -116,8 +198,8 @@ projectData = Project.newProjectData(projectName) - if os.path.splitext(filePath)[1] != ".tproj": - filePath += ".tproj" + if os.path.splitext(filePath)[1] != g_projectExt: + filePath += g_projectExt try: yaml.dump(projectData, open(filePath, "w"), default_flow_style=False) diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/translator.ui --- a/trunk/src/translator/translator.ui Fri Oct 12 22:51:40 2007 +0200 +++ b/trunk/src/translator/translator.ui Tue Oct 16 22:13:37 2007 +0200 @@ -44,7 +44,7 @@ &Project - + @@ -75,7 +75,7 @@ Ctrl+N - + &Add catalogue diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/ui_project_properties.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/translator/ui_project_properties.py Tue Oct 16 22:13:37 2007 +0200 @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'project_properties.ui' +# +# Created: Tue Oct 16 21:58:58 2007 +# by: PyQt4 UI code generator 4.1 +# +# WARNING! All changes made in this file will be lost! + +import sys +from PyQt4 import QtCore, QtGui + +class Ui_ProjectProperties(object): + def setupUi(self, ProjectProperties): + ProjectProperties.setObjectName("ProjectProperties") + ProjectProperties.resize(QtCore.QSize(QtCore.QRect(0,0,400,148).size()).expandedTo(ProjectProperties.minimumSizeHint())) + + self.vboxlayout = QtGui.QVBoxLayout(ProjectProperties) + self.vboxlayout.setObjectName("vboxlayout") + + self.gridlayout = QtGui.QGridLayout() + self.gridlayout.setObjectName("gridlayout") + + self.label_2 = QtGui.QLabel(ProjectProperties) + self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_2.setObjectName("label_2") + self.gridlayout.addWidget(self.label_2,0,0,1,1) + + self.projectNameField = QtGui.QLineEdit(ProjectProperties) + self.projectNameField.setObjectName("projectNameField") + self.gridlayout.addWidget(self.projectNameField,0,1,1,1) + + self.label = QtGui.QLabel(ProjectProperties) + self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label.setObjectName("label") + self.gridlayout.addWidget(self.label,1,0,1,1) + + self.buildCommandField = QtGui.QLineEdit(ProjectProperties) + self.buildCommandField.setObjectName("buildCommandField") + self.gridlayout.addWidget(self.buildCommandField,1,1,1,1) + self.vboxlayout.addLayout(self.gridlayout) + + spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding) + self.vboxlayout.addItem(spacerItem) + + self.buttonBox = QtGui.QDialogButtonBox(ProjectProperties) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName("buttonBox") + self.vboxlayout.addWidget(self.buttonBox) + self.label_2.setBuddy(self.projectNameField) + self.label.setBuddy(self.buildCommandField) + + self.retranslateUi(ProjectProperties) + QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),ProjectProperties.accept) + QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),ProjectProperties.reject) + QtCore.QMetaObject.connectSlotsByName(ProjectProperties) + + def retranslateUi(self, ProjectProperties): + ProjectProperties.setWindowTitle(QtGui.QApplication.translate("ProjectProperties", "Project Properties", None, QtGui.QApplication.UnicodeUTF8)) + self.label_2.setText(QtGui.QApplication.translate("ProjectProperties", "Project name:", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("ProjectProperties", "Build command:", None, QtGui.QApplication.UnicodeUTF8)) + diff -r cdbb2bf6dd07 -r 5968e273449b trunk/src/translator/ui_translator.py --- a/trunk/src/translator/ui_translator.py Fri Oct 12 22:51:40 2007 +0200 +++ b/trunk/src/translator/ui_translator.py Tue Oct 16 22:13:37 2007 +0200 @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'translator.ui' # -# Created: Fri Oct 12 22:49:36 2007 +# Created: Sun Oct 14 13:11:43 2007 # by: PyQt4 UI code generator 4.1 # # WARNING! All changes made in this file will be lost! @@ -49,8 +49,8 @@ self.action_New_Project = QtGui.QAction(MainWindow) self.action_New_Project.setObjectName("action_New_Project") - self.action_Add_catalogue = QtGui.QAction(MainWindow) - self.action_Add_catalogue.setObjectName("action_Add_catalogue") + self.action_Add_Catalogue = QtGui.QAction(MainWindow) + self.action_Add_Catalogue.setObjectName("action_Add_Catalogue") self.action_Properties = QtGui.QAction(MainWindow) self.action_Properties.setObjectName("action_Properties") @@ -69,7 +69,7 @@ self.menu_File.addSeparator() self.menu_File.addAction(self.action_Quit) self.menu_Help.addAction(self.action_About) - self.menu_Project.addAction(self.action_Add_catalogue) + self.menu_Project.addAction(self.action_Add_Catalogue) self.menu_Project.addAction(self.action_Build_Project) self.menu_Project.addSeparator() self.menu_Project.addAction(self.action_Properties) @@ -91,7 +91,7 @@ self.action_About.setText(QtGui.QApplication.translate("MainWindow", "&About", None, QtGui.QApplication.UnicodeUTF8)) self.action_New_Project.setText(QtGui.QApplication.translate("MainWindow", "&New Project...", None, QtGui.QApplication.UnicodeUTF8)) self.action_New_Project.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+N", None, QtGui.QApplication.UnicodeUTF8)) - self.action_Add_catalogue.setText(QtGui.QApplication.translate("MainWindow", "&Add catalogue", None, QtGui.QApplication.UnicodeUTF8)) + self.action_Add_Catalogue.setText(QtGui.QApplication.translate("MainWindow", "&Add catalogue", None, QtGui.QApplication.UnicodeUTF8)) self.action_Properties.setText(QtGui.QApplication.translate("MainWindow", "&Properties", None, QtGui.QApplication.UnicodeUTF8)) self.action_Build_Project.setText(QtGui.QApplication.translate("MainWindow", "&Build Project", None, QtGui.QApplication.UnicodeUTF8)) self.action_Open_Project.setText(QtGui.QApplication.translate("MainWindow", "&Open Project...", None, QtGui.QApplication.UnicodeUTF8))