--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjango/Project.py Fri Mar 22 19:26:49 2013 +0100 @@ -0,0 +1,2046 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2013 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the Django project support. +""" + +import sys +import os + +from PyQt4.QtCore import QObject +from PyQt4.QtGui import QMenu, QInputDialog, QLineEdit + +from E5Gui.E5Application import e5App +from E5Gui import E5MessageBox +from E5Gui.E5Action import E5Action + +from .DjangoDialog import DjangoDialog + +import Preferences +import Utilities + + +class DjangoNoSiteSelectedException(Exception): + """ + Exception thrown to signal, that there is no current site. + """ + pass + + +class Project(QObject): + """ + Class implementing the Django project support. + """ + RecentApplicationsKey = "Django/RecentApplications" + + def __init__(self, plugin, parent=None): + """ + Constructor + + @param plugin reference to the plugin object + @param parent parent (QObject) + """ + super().__init__(parent) + + self.__plugin = plugin + self.__ui = parent + self.__e5project = e5App().getObject("Project") + self.__hooksInstalled = False + + self.__mainMenu = None + + self.__serverProc = None + self.__testServerProc = None + + self.__recentApplications = [] + self.__loadRecentApplications() + + def initActions(self): + """ + Public method to define the Pyramid actions. + """ + self.actions = [] + + self.selectSiteAct = E5Action(self.trUtf8('Current Project'), + "", + 0, 0, + self,'django_current_project') + self.selectSiteAct.setStatusTip(self.trUtf8( + 'Selects the current project')) + self.selectSiteAct.setWhatsThis(self.trUtf8( + """<b>Current Project</b>""" + """<p>Selects the current project. Used for multi-project """ + """Django projects to switch between the projects.</p>""" + )) + self.selectSiteAct.triggered[()].connect(self.__selectSite) + self.actions.append(self.selectSiteAct) + self.__setCurrentSite(None) + + ############################## + ## start actions below ## + ############################## + + self.startProjectAct = E5Action(self.trUtf8('Start Project'), + self.trUtf8('Start &Project'), + 0, 0, + self,'django_start_project') + self.startProjectAct.setStatusTip(self.trUtf8( + 'Starts a new Django project')) + self.startProjectAct.setWhatsThis(self.trUtf8( + """<b>Start Project</b>""" + """<p>Starts a new Django project using "django-admin.py startproject".</p>""" + )) + self.startProjectAct.triggered[()].connect(self.__startProject) + self.actions.append(self.startProjectAct) + + self.startGlobalApplicationAct = E5Action( + self.trUtf8('Start Application (global)'), + self.trUtf8('Start Application (&global)'), + 0, 0, + self,'django_start_global_application') + self.startGlobalApplicationAct.setStatusTip(self.trUtf8( + 'Starts a new global Django application')) + self.startGlobalApplicationAct.setWhatsThis(self.trUtf8( + """<b>Start Application (global)</b>""" + """<p>Starts a new global Django application using""" + """ "django-admin.py startapp".</p>""" + )) + self.startGlobalApplicationAct.triggered[()].connect( + self.__startGlobalApplication) + self.actions.append(self.startGlobalApplicationAct) + + self.startLocalApplicationAct = E5Action( + self.trUtf8('Start Application (local)'), + self.trUtf8('Start Application (&local)'), + 0, 0, + self,'django_start_local_application') + self.startLocalApplicationAct.setStatusTip(self.trUtf8( + 'Starts a new local Django application')) + self.startLocalApplicationAct.setWhatsThis(self.trUtf8( + """<b>Start Application (local)</b>""" + """<p>Starts a new local Django application using""" + """ "manage.py startapp".</p>""" + )) + self.startLocalApplicationAct.triggered[()].connect( + self.__startLocalApplication) + self.actions.append(self.startLocalApplicationAct) + +## ############################## +## ## run actions below ## +## ############################## +## +## self.runServerAct = E4Action(self.trUtf8('Run Server'), +## self.trUtf8('Run &Server'), +## 0, 0, +## self,'django_run_server') +## self.runServerAct.setStatusTip(self.trUtf8( +## 'Starts the Django Web server')) +## self.runServerAct.setWhatsThis(self.trUtf8( +## """<b>Run Server</b>""" +## """<p>Starts the Django Web server using "manage.py runserver".</p>""" +## )) +## self.connect(self.runServerAct, SIGNAL('triggered()'), self.__runServer) +## self.actions.append(self.runServerAct) +## +## self.runBrowserAct = E4Action(self.trUtf8('Run Web-Browser'), +## self.trUtf8('Run &Web-Browser'), +## 0, 0, +## self,'django_run_browser') +## self.runBrowserAct.setStatusTip(self.trUtf8( +## 'Starts the default Web-Browser with the URL of the Django Web server')) +## self.runBrowserAct.setWhatsThis(self.trUtf8( +## """<b>Run Web-Browser</b>""" +## """<p>Starts the default Web-Browser with the URL of the """ +## """Django Web server.</p>""" +## )) +## self.connect(self.runBrowserAct, SIGNAL('triggered()'), self.__runBrowser) +## self.actions.append(self.runBrowserAct) +## +## ############################## +## ## caching actions below ## +## ############################## +## +## self.createCacheTableAct = E4Action(self.trUtf8('Create Cache Tables'), +## self.trUtf8('C&reate Cache Tables'), +## 0, 0, +## self,'django_create_cache_tables') +## self.createCacheTableAct.setStatusTip(self.trUtf8( +## 'Creates the tables needed to use the SQL cache backend')) +## self.createCacheTableAct.setWhatsThis(self.trUtf8( +## """<b>Create Cache Tables</b>""" +## """<p>Creates the tables needed to use the SQL cache backend.</p>""" +## )) +## self.connect(self.createCacheTableAct, SIGNAL('triggered()'), +## self.__createCacheTables) +## self.actions.append(self.createCacheTableAct) +## + ############################## + ## help action below ## + ############################## + + self.helpAct = E5Action(self.trUtf8('Help'), + self.trUtf8('&Help'), + 0, 0, + self,'django_help') + self.helpAct.setStatusTip(self.trUtf8( + 'Shows the Django help index')) + self.helpAct.setWhatsThis(self.trUtf8( + """<b>Help</b>""" + """<p>Shows the Django help index page.</p>""" + )) + self.helpAct.triggered[()].connect(self.__showHelpIndex) + self.actions.append(self.helpAct) + + ############################## + ## about action below ## + ############################## + + self.aboutDjangoAct = E5Action(self.trUtf8('About Django'), + self.trUtf8('About D&jango'), + 0, 0, + self,'django_about') + self.aboutDjangoAct.setStatusTip(self.trUtf8( + 'Shows some information about Django')) + self.aboutDjangoAct.setWhatsThis(self.trUtf8( + """<b>About Django</b>""" + """<p>Shows some information about Django.</p>""" + )) + self.aboutDjangoAct.triggered[()].connect(self.__djangoInfo) + self.actions.append(self.aboutDjangoAct) +## +## self.__initDatabaseActions() +## self.__initDatabaseSqlActions() +## self.__initToolsActions() +## self.__initTestingActions() +## +## def __initDatabaseActions(self): +## """ +## Private method to define the database related actions. +## """ +## self.syncDatabaseAct = E4Action(self.trUtf8('Synchronize'), +## self.trUtf8('&Synchronize'), +## 0, 0, +## self,'django_database_syncdb') +## self.syncDatabaseAct.setStatusTip(self.trUtf8( +## 'Synchronizes the database')) +## self.syncDatabaseAct.setWhatsThis(self.trUtf8( +## """<b>Synchronize</b>""" +## """<p>Synchronizes the database.</p>""" +## )) +## self.connect(self.syncDatabaseAct, SIGNAL('triggered()'), +## self.__databaseSynchronize) +## self.actions.append(self.syncDatabaseAct) +## +## self.inspectDatabaseAct = E4Action(self.trUtf8('Introspect'), +## self.trUtf8('&Introspect'), +## 0, 0, +## self,'django_database_inspect') +## self.inspectDatabaseAct.setStatusTip(self.trUtf8( +## 'Introspects the database tables and outputs a Django model module')) +## self.inspectDatabaseAct.setWhatsThis(self.trUtf8( +## """<b>Introspect</b>""" +## """<p>Introspects the database tables and outputs a """ +## """Django model module.</p>""" +## )) +## self.connect(self.inspectDatabaseAct, SIGNAL('triggered()'), +## self.__databaseInspect) +## self.actions.append(self.inspectDatabaseAct) +## +## self.flushDatabaseAct = E4Action(self.trUtf8('Flush'), +## self.trUtf8('&Flush'), +## 0, 0, +## self,'django_database_flush') +## self.flushDatabaseAct.setStatusTip(self.trUtf8( +## 'Returns all database tables to the state just after their installation')) +## self.flushDatabaseAct.setWhatsThis(self.trUtf8( +## """<b>Flush</b>""" +## """<p>Returns all database tables to the state """ +## """just after their installation.</p>""" +## )) +## self.connect(self.flushDatabaseAct, SIGNAL('triggered()'), +## self.__databaseFlush) +## self.actions.append(self.flushDatabaseAct) +## +## self.resetDatabaseAct = E4Action(self.trUtf8('Reset Application(s)'), +## self.trUtf8('&Reset Application(s)'), +## 0, 0, +## self,'django_database_reset_application') +## self.resetDatabaseAct.setStatusTip(self.trUtf8( +## 'Resets the database tables of one or more applications')) +## self.resetDatabaseAct.setWhatsThis(self.trUtf8( +## """<b>Reset Application(s)</b>""" +## """<p>Resets the database tables of one or more applications.</p>""" +## )) +## self.connect(self.resetDatabaseAct, SIGNAL('triggered()'), +## self.__databaseReset) +## self.actions.append(self.resetDatabaseAct) +## +## self.databaseClientAct = E4Action(self.trUtf8('Start Client Console'), +## self.trUtf8('Start &Client Console'), +## 0, 0, +## self,'django_database_client') +## self.databaseClientAct.setStatusTip(self.trUtf8( +## 'Starts a console window for the database client')) +## self.databaseClientAct.setWhatsThis(self.trUtf8( +## """<b>Start Client Console</b>""" +## """<p>Starts a console window for the database client.</p>""" +## )) +## self.connect(self.databaseClientAct, SIGNAL('triggered()'), +## self.__runDatabaseClient) +## self.actions.append(self.databaseClientAct) +## +## def __initDatabaseSqlActions(self): +## """ +## Private method to define the database SQL related actions. +## """ +## self.databaseSqlCreateTablesAct = E4Action(self.trUtf8('Create Tables'), +## self.trUtf8('Create &Tables'), +## 0, 0, +## self,'django_database_sql_create_tables') +## self.databaseSqlCreateTablesAct.setStatusTip(self.trUtf8( +## 'Prints the CREATE TABLE SQL statements for one or more applications')) +## self.databaseSqlCreateTablesAct.setWhatsThis(self.trUtf8( +## """<b>Create Tables</b>""" +## """<p>Prints the CREATE TABLE SQL statements for one or """ +## """more applications.</p>""" +## )) +## self.connect(self.databaseSqlCreateTablesAct, SIGNAL('triggered()'), +## self.__databaseSqlCreateTables) +## self.actions.append(self.databaseSqlCreateTablesAct) +## +## self.databaseSqlCreateIndexesAct = E4Action(self.trUtf8('Create Indexes'), +## self.trUtf8('Create &Indexes'), +## 0, 0, +## self,'django_database_sql_create_indexes') +## self.databaseSqlCreateIndexesAct.setStatusTip(self.trUtf8( +## 'Prints the CREATE INDEX SQL statements for one or more applications')) +## self.databaseSqlCreateIndexesAct.setWhatsThis(self.trUtf8( +## """<b>Create Indexes</b>""" +## """<p>Prints the CREATE INDEX SQL statements for one or """ +## """more applications.</p>""" +## )) +## self.connect(self.databaseSqlCreateIndexesAct, SIGNAL('triggered()'), +## self.__databaseSqlCreateIndexes) +## self.actions.append(self.databaseSqlCreateIndexesAct) +## +## self.databaseSqlCreateEverythingAct = E4Action(self.trUtf8('Create Everything'), +## self.trUtf8('Create &Everything'), +## 0, 0, +## self,'django_database_sql_create_everything') +## self.databaseSqlCreateEverythingAct.setStatusTip(self.trUtf8( +## 'Prints the CREATE ... SQL statements for one or more applications')) +## self.databaseSqlCreateEverythingAct.setWhatsThis(self.trUtf8( +## """<b>Create Everything</b>""" +## """<p>Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL """ +## """statements for one or more applications.</p>""" +## )) +## self.connect(self.databaseSqlCreateEverythingAct, SIGNAL('triggered()'), +## self.__databaseSqlCreateEverything) +## self.actions.append(self.databaseSqlCreateEverythingAct) +## +## self.databaseSqlCustomAct = E4Action(self.trUtf8('Custom Statements'), +## self.trUtf8('&Custom Statements'), +## 0, 0, +## self,'django_database_sql_custom') +## self.databaseSqlCustomAct.setStatusTip(self.trUtf8( +## 'Prints the custom table modifying SQL statements for ' +## 'one or more applications')) +## self.databaseSqlCustomAct.setWhatsThis(self.trUtf8( +## """<b>Custom Statements</b>""" +## """<p>Prints the custom table modifying SQL statements """ +## """for one or more applications.</p>""" +## )) +## self.connect(self.databaseSqlCustomAct, SIGNAL('triggered()'), +## self.__databaseSqlCustom) +## self.actions.append(self.databaseSqlCustomAct) +## +## self.databaseSqlDropTablesAct = E4Action(self.trUtf8('Drop Tables'), +## self.trUtf8('&Drop Tables'), +## 0, 0, +## self,'django_database_sql_drop_tables') +## self.databaseSqlDropTablesAct.setStatusTip(self.trUtf8( +## 'Prints the DROP TABLE SQL statements for ' +## 'one or more applications')) +## self.databaseSqlDropTablesAct.setWhatsThis(self.trUtf8( +## """<b>Drop Tables</b>""" +## """<p>Prints the DROP TABLE SQL statements """ +## """for one or more applications.</p>""" +## )) +## self.connect(self.databaseSqlDropTablesAct, SIGNAL('triggered()'), +## self.__databaseSqlDropTables) +## self.actions.append(self.databaseSqlDropTablesAct) +## +## self.databaseSqlFlushAct = E4Action(self.trUtf8('Flush Database'), +## self.trUtf8('&Flush Database'), +## 0, 0, +## self,'django_database_sql_flush_database') +## self.databaseSqlFlushAct.setStatusTip(self.trUtf8( +## 'Prints a list of statements to return all database tables to the state ' +## 'just after their installation')) +## self.databaseSqlFlushAct.setWhatsThis(self.trUtf8( +## """<b>Flush Database</b>""" +## """<p>Prints a list of statements to return all database tables to """ +## """the state just after their installation.</p>""" +## )) +## self.connect(self.databaseSqlFlushAct, SIGNAL('triggered()'), +## self.__databaseSqlFlushDatabase) +## self.actions.append(self.databaseSqlFlushAct) +## +## self.databaseSqlResetApplAct = E4Action(self.trUtf8('Reset Application(s)'), +## self.trUtf8('Reset &Application(s)'), +## 0, 0, +## self,'django_database_sql_reset_application') +## self.databaseSqlResetApplAct.setStatusTip(self.trUtf8( +## 'Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for ' +## 'one or more applications')) +## self.databaseSqlResetApplAct.setWhatsThis(self.trUtf8( +## """<b>Reset Application(s)</b>""" +## """<p>Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for """ +## """one or more applications.</p>""" +## )) +## self.connect(self.databaseSqlResetApplAct, SIGNAL('triggered()'), +## self.__databaseSqlResetApplication) +## self.actions.append(self.databaseSqlResetApplAct) +## +## self.databaseSqlResetSeqAct = E4Action(self.trUtf8('Reset Sequences'), +## self.trUtf8('Reset &Sequences'), +## 0, 0, +## self,'django_database_sql_reset_sequences') +## self.databaseSqlResetSeqAct.setStatusTip(self.trUtf8( +## 'Prints the SQL statements for resetting sequences for ' +## 'one or more applications')) +## self.databaseSqlResetSeqAct.setWhatsThis(self.trUtf8( +## """<b>Reset Sequences</b>""" +## """<p>Prints the SQL statements for resetting sequences for """ +## """one or more applications.</p>""" +## )) +## self.connect(self.databaseSqlResetSeqAct, SIGNAL('triggered()'), +## self.__databaseSqlResetSequences) +## self.actions.append(self.databaseSqlResetSeqAct) +## +## def __initToolsActions(self): +## """ +## Private method to define the tool actions. +## """ +## self.diffSettingsAct = E4Action(self.trUtf8('Diff Settings'), +## self.trUtf8('&Diff Settings'), +## 0, 0, +## self,'django_tools_diffsettings') +## self.diffSettingsAct.setStatusTip(self.trUtf8( +## 'Shows the modification made to the settings')) +## self.diffSettingsAct.setWhatsThis(self.trUtf8( +## """<b>Diff Settings</b>""" +## """<p>Shows the modification made to the settings.</p>""" +## )) +## self.connect(self.diffSettingsAct, SIGNAL('triggered()'), +## self.__diffSettings) +## self.actions.append(self.diffSettingsAct) +## +## self.cleanupAct = E4Action(self.trUtf8('Cleanup'), +## self.trUtf8('&Cleanup'), +## 0, 0, +## self,'django_tools_cleanup') +## self.cleanupAct.setStatusTip(self.trUtf8( +## 'Cleans out old data from the database')) +## self.cleanupAct.setWhatsThis(self.trUtf8( +## """<b>Cleanup</b>""" +## """<p>Cleans out old data from the database.</p>""" +## )) +## self.connect(self.cleanupAct, SIGNAL('triggered()'), +## self.__cleanup) +## self.actions.append(self.cleanupAct) +## +## self.validateAct = E4Action(self.trUtf8('Validate'), +## self.trUtf8('&Validate'), +## 0, 0, +## self,'django_tools_validate') +## self.validateAct.setStatusTip(self.trUtf8( +## 'Validates all installed models')) +## self.validateAct.setWhatsThis(self.trUtf8( +## """<b>Validate</b>""" +## """<p>Validates all installed models.</p>""" +## )) +## self.connect(self.validateAct, SIGNAL('triggered()'), +## self.__validate) +## self.actions.append(self.validateAct) +## +## self.adminindexAct = E4Action(self.trUtf8('Admin Index'), +## self.trUtf8('&Admin Index'), +## 0, 0, +## self,'django_tools_adminindex') +## self.adminindexAct.setStatusTip(self.trUtf8( +## 'Prints the admin-index template snippet')) +## self.adminindexAct.setWhatsThis(self.trUtf8( +## """<b>Admin Index</b>""" +## """<p>Prints the admin-index template snippet.</p>""" +## )) +## self.connect(self.adminindexAct, SIGNAL('triggered()'), +## self.__adminIndex) +## self.actions.append(self.adminindexAct) +## +## self.runPythonShellAct = E4Action(self.trUtf8('Start Python Console'), +## self.trUtf8('Start &Python Console'), +## 0, 0, +## self,'django_tools_pythonconsole') +## self.runPythonShellAct.setStatusTip(self.trUtf8( +## 'Starts a Python interactive interpreter')) +## self.runPythonShellAct.setWhatsThis(self.trUtf8( +## """<b>Start Python Console</b>""" +## """<p>Starts a Python interactive interpreter.</p>""" +## )) +## self.connect(self.runPythonShellAct, SIGNAL('triggered()'), +## self.__runPythonShell) +## self.actions.append(self.runPythonShellAct) +## +## def __initTestingActions(self): +## """ +## Private method to define the testing actions. +## """ +## self.dumpDataAct = E4Action(self.trUtf8('Dump Data'), +## self.trUtf8('&Dump Data'), +## 0, 0, +## self,'django_tools_dumpdata') +## self.dumpDataAct.setStatusTip(self.trUtf8( +## 'Dump the database data to a fixture')) +## self.dumpDataAct.setWhatsThis(self.trUtf8( +## """<b>Dump Data</b>""" +## """<p>Dump the database data to a fixture.</p>""" +## )) +## self.connect(self.dumpDataAct, SIGNAL('triggered()'), +## self.__dumpData) +## self.actions.append(self.dumpDataAct) +## +## self.loadDataAct = E4Action(self.trUtf8('Load Data'), +## self.trUtf8('&Load Data'), +## 0, 0, +## self,'django_tools_loaddata') +## self.loadDataAct.setStatusTip(self.trUtf8( +## 'Load data from fixture files')) +## self.loadDataAct.setWhatsThis(self.trUtf8( +## """<b>Load Data</b>""" +## """<p>Load data from fixture files.</p>""" +## )) +## self.connect(self.loadDataAct, SIGNAL('triggered()'), +## self.__loadData) +## self.actions.append(self.loadDataAct) +## +## self.runTestAct = E4Action(self.trUtf8('Run Testsuite'), +## self.trUtf8('Run &Testsuite'), +## 0, 0, +## self,'django_tools_run_test') +## self.runTestAct.setStatusTip(self.trUtf8( +## 'Run the test suite for applications or the whole site')) +## self.runTestAct.setWhatsThis(self.trUtf8( +## """<b>Run Testsuite</b>""" +## """<p>Run the test suite for applications or the whole site.</p>""" +## )) +## self.connect(self.runTestAct, SIGNAL('triggered()'), +## self.__runTestSuite) +## self.actions.append(self.runTestAct) +## +## self.runTestServerAct = E4Action(self.trUtf8('Run Testserver'), +## self.trUtf8('Run Test&server'), +## 0, 0, +## self,'django_tools_run_test_server') +## self.runTestServerAct.setStatusTip(self.trUtf8( +## 'Run a development server with data from a set of fixtures')) +## self.runTestServerAct.setWhatsThis(self.trUtf8( +## """<b>Run Testserver</b>""" +## """<p>Run a development server with data from a set of fixtures.</p>""" +## )) +## self.connect(self.runTestServerAct, SIGNAL('triggered()'), +## self.__runTestServer) +## self.actions.append(self.runTestServerAct) +## + def initMenu(self): + """ + Public slot to initialize the Django menu. + + @return the menu generated (QMenu) + """ + menu = QMenu(self.trUtf8('D&jango'), self.__ui) + menu.setTearOffEnabled(True) + + menu.addAction(self.selectSiteAct) + menu.addSeparator() +## menu.addAction(self.runServerAct) +## menu.addAction(self.runBrowserAct) + menu.addSeparator() + menu.addAction(self.startProjectAct) + menu.addAction(self.startGlobalApplicationAct) + menu.addAction(self.startLocalApplicationAct) + menu.addSeparator() + menu.addMenu(self.__initDatabaseMenu()) + menu.addSeparator() + menu.addMenu(self.__initToolsMenu()) + menu.addSeparator() +## menu.addAction(self.createCacheTableAct) + menu.addSeparator() + menu.addMenu(self.__initTestingMenu()) + menu.addSeparator() + menu.addAction(self.aboutDjangoAct) + menu.addSeparator() + menu.addAction(self.helpAct) + + self.__mainMenu = menu + + return menu + + def __initDatabaseMenu(self): + """ + Private slot to initialize the database menu. + + @return the menu generated (QMenu) + """ + menu = QMenu(self.trUtf8("&Database"), self.__ui) + menu.setTearOffEnabled(True) + +## menu.addAction(self.syncDatabaseAct) + menu.addSeparator() +## menu.addAction(self.inspectDatabaseAct) + menu.addSeparator() +## menu.addAction(self.flushDatabaseAct) +## menu.addAction(self.resetDatabaseAct) + menu.addSeparator() +## menu.addAction(self.databaseClientAct) + menu.addSeparator() + menu.addMenu(self.__initDatabaseSqlMenu()) + + return menu + + def __initDatabaseSqlMenu(self): + """ + Private slot to initialize the database SQL submenu. + + @return the menu generated (QMenu) + """ + menu = QMenu(self.trUtf8("Show &SQL"), self.__ui) + menu.setTearOffEnabled(True) + +## menu.addAction(self.databaseSqlCreateTablesAct) +## menu.addAction(self.databaseSqlCreateIndexesAct) +## menu.addAction(self.databaseSqlCreateEverythingAct) + menu.addSeparator() +## menu.addAction(self.databaseSqlCustomAct) + menu.addSeparator() +## menu.addAction(self.databaseSqlDropTablesAct) + menu.addSeparator() +## menu.addAction(self.databaseSqlFlushAct) +## menu.addAction(self.databaseSqlResetApplAct) +## menu.addAction(self.databaseSqlResetSeqAct) + + return menu + + def __initToolsMenu(self): + """ + Private slot to initialize the tools menu. + + @return the menu generated (QMenu) + """ + menu = QMenu(self.trUtf8("&Tools"), self.__ui) + menu.setTearOffEnabled(True) + +## menu.addAction(self.diffSettingsAct) +## menu.addAction(self.cleanupAct) +## menu.addAction(self.validateAct) +## menu.addAction(self.adminindexAct) + menu.addSeparator() +## menu.addAction(self.runPythonShellAct) + + return menu + + def __initTestingMenu(self): + """ + Private slot to initialize the testing menu. + + @return the menu generated (QMenu) + """ + menu = QMenu(self.trUtf8("T&esting"), self.__ui) + menu.setTearOffEnabled(True) + +## menu.addAction(self.dumpDataAct) +## menu.addAction(self.loadDataAct) + menu.addSeparator() +## menu.addAction(self.runTestAct) +## menu.addAction(self.runTestServerAct) + + return menu + + ################################################################## + ## methods below implement the various hook related functions + ################################################################## + + def projectOpenedHooks(self): + """ + Public method to add our hook methods. + """ + if self.__e5project.getProjectType() == "Django": + self.__formsBrowser = \ + e5App().getObject("ProjectBrowser").getProjectBrowser("forms") + self.__formsBrowser.addHookMethodAndMenuEntry("newForm", + self.newForm, self.trUtf8("New template...")) + + self.__e5project.projectLanguageAddedByCode.connect( + self.__projectLanguageAdded) + self.__translationsBrowser = \ + e5App().getObject("ProjectBrowser").getProjectBrowser("translations") + self.__translationsBrowser.addHookMethodAndMenuEntry("generateAll", + self.updateCatalogs, self.trUtf8("Update all catalogs")) + self.__translationsBrowser.addHookMethodAndMenuEntry("generateSelected", + self.updateSelectedCatalogs, self.trUtf8("Update selected catalogs")) + self.__translationsBrowser.addHookMethodAndMenuEntry("releaseAll", + self.compileCatalogs, self.trUtf8("Compile all catalogs")) + self.__translationsBrowser.addHookMethodAndMenuEntry("releaseSelected", + self.compileSelectedCatalogs, + self.trUtf8("Compile selected catalogs")) + + self.__hooksInstalled = True + + def projectClosedHooks(self): + """ + Public method to remove our hook methods. + """ + if self.__hooksInstalled: + self.__formsBrowser.removeHookMethod("newForm") + self.__formsBrowser = None + + self.__e5project.projectLanguageAddedByCode.disconnect( + self.__projectLanguageAdded) + self.__translationsBrowser.removeHookMethod("generateAll") + self.__translationsBrowser.removeHookMethod("generateSelected") + self.__translationsBrowser.removeHookMethod("releaseAll") + self.__translationsBrowser.removeHookMethod("releaseSelected") + self.__translationsBrowser = None + + self.__hooksInstalled = False + + def newForm(self, path): + """ + Public method to create a new form. + + @param path full directory path for the new form file (string) + """ +## selectedFilter = QString("") +## filter = self.trUtf8("HTML Files (*.html);;All Files (*)") +## fname = KQFileDialog.getSaveFileName(\ +## self.__ui, +## self.trUtf8("New Form"), +## path, +## filter, +## selectedFilter, +## QFileDialog.Options(QFileDialog.DontConfirmOverwrite)) +## +## if fname.isEmpty(): +## # user aborted or didn't enter a filename +## return +## +## ext = QFileInfo(fname).suffix() +## if ext.isEmpty(): +## ex = selectedFilter.section('(*',1,1).section(')',0,0) +## if not ex.isEmpty(): +## fname.append(ex) +## +## fname = unicode(fname) +## if os.path.exists(fname): +## res = KQMessageBox.warning(self.__ui, +## self.trUtf8("New Form"), +## self.trUtf8("The file already exists! Overwrite it?"), +## QMessageBox.StandardButtons(\ +## QMessageBox.No | \ +## QMessageBox.Yes), +## QMessageBox.No) +## if res != QMessageBox.Yes: +## # user selected to not overwrite +## return +## +## try: +## f = open(fname, "wb") +## f.write('<html>\n') +## f.write(' <head>\n') +## f.write(' <meta content="" />\n') +## f.write(' <title></title>\n') +## f.write(' <style>\n') +## f.write(' </style>\n') +## f.write(' </head>\n') +## f.write('\n') +## f.write(' <body>\n') +## f.write(' </body>\n') +## f.write('</html>\n') +## f.close() +## except IOError, e: +## KQMessageBox.critical(self.__ui, +## self.trUtf8("New Form"), +## self.trUtf8("<p>The new form file <b>%1</b> could not be created.<br>" +## "Problem: %2</p>").arg(fname).arg(unicode(e))) +## return +## +## self.__e4project.appendFile(fname) +## self.__formsBrowser.emit(SIGNAL('sourceFile'), fname) + + ################################################################## + ## slots below implement general functionality + ################################################################## + + def projectClosed(self): + """ + Public method to handle the closing of a project. + """ + if self.__serverProc is not None: + self.__serverProcFinished() + self.__setCurrentSite(None) + + def __djangoInfo(self): + """ + Private slot to show some info about Django. + """ + from django import VERSION + version = '.'.join([str(i) for i in VERSION[:-1]]) + if VERSION[-1]: + version += '-' + VERSION[-1] + + E5MessageBox.about(self.__ui, + self.trUtf8("About Django"), + self.trUtf8( + "<p>Django is a high-level Python Web framework that encourages rapid " + "development and clean, pragmatic design.</p>" + "<p><table>" + "<tr><td>Version:</td><td>{0}</td></tr>" + "<tr><td>URL:</td><td><a href=\"http://www.djangoproject.com\">" + "http://www.djangoproject.com</a></td></tr>" + "</table></p>" + ).format(version) + ) + +## def getDjangoVersion(self): +## """ +## Public method to get the Django version. +## +## @return Django version as a tuple +## """ +## from django import VERSION +## return VERSION +## +## def __getApplications(self): +## """ +## Private method to ask the user for a list of application names. +## +## @return list of application names (QStringList) +## """ +## applStr, ok = KQInputDialog.getItem(\ +## self.__ui, +## self.trUtf8("Select Applications"), +## self.trUtf8("Enter the list of applications separated by spaces."), +## self.getRecentApplications(), +## 0, True) +## if ok and not applStr.isEmpty(): +## self.setMostRecentApplication(applStr) +## return applStr.split(" ", QString.SkipEmptyParts) +## else: +## return QStringList() +## + def __loadRecentApplications(self): + """ + Private method to load the recently used applications list. + """ + self.__recentApplications = [] + Preferences.Prefs.rsettings.sync() + ra = Preferences.Prefs.rsettings.value(self.RecentApplicationsKey) + if ra is not None: + maxRecentApps = self.__plugin.getPreferences("RecentNumberApps") + self.__recentApplications = ra[:maxRecentApps] + + def __saveRecentApplications(self): + """ + Private method to save the list of recently used applications list. + """ + Preferences.Prefs.rsettings.setValue(self.RecentApplicationsKey, + self.__recentApplications) + Preferences.Prefs.rsettings.sync() + + def getRecentApplications(self): + """ + Public method to get the list of recent applications. + + @return list of recent applications entries (list of strings) + """ + self.__loadRecentApplications() + return self.__recentApplications + + def setMostRecentApplication(self, applStr): + """ + Public method to set the most recently used applications entry. + + @param applStr applications entry (string) + """ + if applStr in self.__recentApplications: + self.__recentApplications.remove(applStr) + self.__recentApplications.insert(0, applStr) + + maxRecentApps = self.__plugin.getPreferences("RecentNumberApps") + if len(self.__recentApplications) > maxRecentApps: + self.__recentApplications = self.recent[:maxRecentApps] + self.__saveRecentApplications() + + def getProjectPath(self): + """ + Public method to get the path of the eric5 project. + + @return path of the eric5 project (string) + """ + return self.__e5project.getProjectPath() + + def __getPythonExecutable(self): + """ + Private method to determine the name of the Python executable. + + @return Python executable (string) + """ + return sys.executable.replace("pythonw", "python") + + def __showHelpIndex(self): + """ + Private slot to show the help index page. + """ + page = os.path.join(os.path.dirname(__file__), + "Documentation", "help", "index.html") + self.__ui.launchHelpViewer(page) + + ################################################################## + ## slots below implement creation functions + ################################################################## + +## def startProjectOrApplication(self): +## """ +## Public slot to start a new Django project or application. +## """ +## if self.__e4project.getProjectType() == "Django": +## projectStr = self.trUtf8("Project") +## applStr = self.trUtf8("Application") +## selections = QStringList() << QString("") << projectStr << applStr +## selection, ok = KQInputDialog.getItem(\ +## self.__ui, +## self.trUtf8("Start Django"), +## self.trUtf8("Select if this project should be a " +## "Django Project or Application.<br />" +## "Select the empty entry for none."), +## selections, +## 0, False) +## if ok and not selection.isEmpty(): +## if selection == projectStr: +## path, projectName = os.path.split(self.__e4project.getProjectPath()) +## self.__createProject(projectName, path) +## elif selection == applStr: +## path, applName = os.path.split(self.__e4project.getProjectPath()) +## self.__createApplication(applName, path) +## + def __createProject(self, projectName, path): + """ + Private slot to create a new Django project. + + @param projectName name of the new project (string) + @param path the directory where the project should be created + (string) + @return flag indicating a successful creation (boolean) + """ + title = self.trUtf8("Start Django Project") + + args = [] + if Utilities.isWindowsPlatform(): + args.append(self.__getPythonExecutable()) + args.append(os.path.join(sys.exec_prefix, "Scripts", "django-admin.py")) + else: + if Utilities.isinpath("django-admin.py"): + args.append("django-admin.py") + elif Utilities.isinpath("django-admin"): + args.append("django-admin") + else: + # fall back + args.append("django-admin.py") + args.append("startproject") + args.append(projectName) + + dia = DjangoDialog(title, + msgSuccess = self.trUtf8("Django project created successfully.")) + res = dia.startProcess(args, path) + if res: + dia.exec_() + + # create the base directory for translations + i18nPath = os.path.join(path, projectName, "locale") + if not os.path.exists(i18nPath): + os.makedirs(i18nPath) + + if os.path.join(path, projectName) == self.__e5project.getProjectPath(): + self.__setCurrentSite("") + else: + self.__setCurrentSite(projectName) + + return res + + def __startProject(self): + """ + Private slot to start a new Django project. + """ + projectName, ok = QInputDialog.getText( + self.__ui, + self.trUtf8("Start Django Project"), + self.trUtf8("Enter the name of the new Django project."), + QLineEdit.Normal) + if ok and projectName != "": + res = self.__createProject(projectName, self.__e5project.getProjectPath()) + if res: + # search for new files and add them to the project + sitePath = os.path.join(self.__e5project.getProjectPath(), + projectName) + for entry in os.walk(sitePath): + for fileName in entry[2]: + fullName = os.path.join(entry[0], fileName) + self.__e5project.appendFile(fullName) + + def __createApplication(self, applName, path, isGlobal = True): + """ + Private slot to create a new Django application. + + @param applName name of the new application (string) + @param path the directory where the application should be created + (string) + @param isGlobal flag indicating a standalone Django application (boolean) + @return flag indicating a successful creation (boolean) + """ + title = self.trUtf8("Start Django Application") + + args = [] + if isGlobal: + if Utilities.isWindowsPlatform(): + args.append(self.__getPythonExecutable()) + args.append(os.path.join(sys.exec_prefix, "Scripts", "django-admin.py")) + else: + if Utilities.isinpath("django-admin.py"): + args.append("django-admin.py") + elif Utilities.isinpath("django-admin"): + args.append("django-admin") + else: + # fall back + args.append("django-admin.py") + else: + args.append(self.__getPythonExecutable()) + args.append("manage.py") + try: + path = self.__sitePath() + except DjangoNoSiteSelectedException: + return False + args.append("startapp") + args.append(applName) + + dia = DjangoDialog(title, + msgSuccess = self.trUtf8("Django application created successfully.")) + res = dia.startProcess(args, path) + if res: + dia.exec_() + return res + + def __startGlobalApplication(self): + """ + Private slot to start a new global Django application. + """ + applName, ok = QInputDialog.getText( + self.__ui, + self.trUtf8("Start Global Django Application"), + self.trUtf8("Enter the name of the new global Django application."), + QLineEdit.Normal) + if ok and applName != "": + res = self.__createApplication(applName, self.__e5project.getProjectPath()) + if res: + # search for new files and add them to the project + appPath = os.path.join(self.__e5project.getProjectPath(), applName) + for entry in os.walk(appPath): + for fileName in entry[2]: + fullName = os.path.join(entry[0], fileName) + self.__e5project.appendFile(fullName) + + def __startLocalApplication(self): + """ + Private slot to start a new local Django application. + """ + applName, ok = QInputDialog.getText( + self.__ui, + self.trUtf8("Start Local Django Application"), + self.trUtf8("Enter the name of the new local Django application."), + QLineEdit.Normal) + if ok and applName != "": + res = self.__createApplication(applName, "", False) + if res: + try: + # search for new files and add them to the project + appPath = os.path.join(self.__sitePath(), applName) + for entry in os.walk(appPath): + for fileName in entry[2]: + fullName = os.path.join(entry[0], fileName) + self.__e5project.appendFile(fullName) + except DjangoNoSiteSelectedException: + return + + ################################################################## + ## methods below implement site related functions + ################################################################## + + def __findSites(self): + """ + Private method to determine the relative path to all manage.py scripts. + + @return list of sites (list of strings) + """ + sites = [] + for file in sorted(self.__e5project.getSources()): + if os.path.basename(file) == "manage.py": + sites.append(os.path.dirname(file)) + return sites + + def __selectSite(self): + """ + Private method to select a site to work with. + + @return selected site (string) + """ + sites = self.__findSites() + if len(sites) == 1: + site = sites[0] + else: + if self.__currentSite is not None: + if self.__currentSite in sites: + cur = sites.index(self.__currentSite) + else: + cur = 0 + else: + cur = 0 + site, ok = QInputDialog.getItem( + self.__ui, + self.trUtf8("Select Project"), + self.trUtf8("Select the Django project to work with."), + sites, + cur, False) + if not ok: + site = None + self.__setCurrentSite(site) + + def __sitePath(self): + """ + Private method to calculate the full path of the Django site. + + @exception DjangoNoSiteSelectedException raised, if no site is selected + @return path of the site (string) + """ + if self.__currentSite is None: + self.__selectSite() + + if self.__currentSite is None: + raise DjangoNoSiteSelectedException + else: + return os.path.join(self.__e5project.getProjectPath(), + self.__currentSite) + + def __setCurrentSite(self, site): + """ + Private slot to set the current site. + + @param site name of the site (string) + """ + self.__currentSite = site + if self.__currentSite is None: + curSite = self.trUtf8("None") + elif self.__currentSite == "": + curSite = self.trUtf8("Project") + else: + curSite = self.__currentSite + self.selectSiteAct.setText( + self.trUtf8('&Current Django project ({0})').format(curSite)) + + if self.__currentSite is None: + self.__e5project.pdata["TRANSLATIONPATTERN"] = [] + else: + self.__e5project.pdata["TRANSLATIONPATTERN"] = [ + os.path.join(site, "locale", "%language%", "LC_MESSAGES", "django.po") + ] + + def __site(self): + """ + Private method to get the name of the current site. + + @exception DjangoNoSiteSelectedException raised, if no site is selected + @return name of the site (string) + """ + if self.__currentSite is None: + self.__selectSite() + + if self.__currentSite is None: + raise DjangoNoSiteSelectedException + else: + return self.__currentSite + + ################################################################## + ## slots below implement run functions + ################################################################## + +## def __runServer(self): +## """ +## Private slot to start the Django Web server. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommand")) +## if consoleCmd: +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("runserver") +## addr = self.__plugin.getPreferences("ServerAddress") +## if addr: +## args.append(addr) +## +## try: +## if Utilities.isWindowsPlatform(): +## serverProcStarted, pid = \ +## QProcess.startDetached(args[0], args[1:], self.__sitePath()) +## else: +## if self.__serverProc is not None: +## self.__serverProcFinished() +## +## self.__serverProc = QProcess() +## self.connect(self.__serverProc, +## SIGNAL('finished(int, QProcess::ExitStatus)'), +## self.__serverProcFinished) +## self.__serverProc.setWorkingDirectory(self.__sitePath()) +## self.__serverProc.start(args[0], args[1:]) +## serverProcStarted = self.__serverProc.waitForStarted() +## if not serverProcStarted: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django server could not be started.')) +## except DjangoNoSiteSelectedException: +## pass +## +## def __serverProcFinished(self): +## """ +## Private slot connected to the finished signal. +## """ +## if self.__serverProc is not None and \ +## self.__serverProc.state() != QProcess.NotRunning: +## self.__serverProc.terminate() +## QTimer.singleShot(2000, self.__serverProc, SLOT('kill()')) +## self.__serverProc.waitForFinished(3000) +## self.__serverProc = None +## +## def __runBrowser(self): +## """ +## Private slot to start the default web browser with the server URL. +## """ +## addr = self.__plugin.getPreferences("ServerAddress") +## if addr: +## if ':' in addr: +## port = addr.split(':')[1] +## else: +## port = addr +## else: +## port = QString("8000") +## url = QUrl(QString("http://127.0.0.1:%1").arg(port)) +## res = QDesktopServices.openUrl(url) +## if not res: +## KQMessageBox.critical(None, +## self.trUtf8('Run Web-Browser'), +## self.trUtf8('Could not start the web-browser for the url "%1".')\ +## .arg(url.toString())) + + ################################################################## + ## slots below implement database related functions + ################################################################## + +## def __databaseSynchronize(self): +## """ +## Private slot to synchronize the database. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommandNoClose")) +## if consoleCmd: +## proc = QProcess() +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("syncdb") +## try: +## wd = self.__sitePath() +## started, pid = QProcess.startDetached(args[0], args[1:], wd) +## if not started: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django process could not be started.')) +## except DjangoNoSiteSelectedException: +## pass +## +## def __databaseInspect(self): +## """ +## Private slot to introspect the database and output a Django model module. +## """ +## title = self.trUtf8("Introspect Database") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("inspectdb") +## +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dia = DjangoDialog(title, fixed = True, linewrap = False) +## res = dia.startProcess(args, path, False) +## if res: +## dia.exec_() +## +## def __databaseFlush(self): +## """ +## Private slot to return all database tables to the state just after their +## installation. +## """ +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## title = self.trUtf8("Flush Database") +## +## res = KQMessageBox.question(self.__ui, +## title, +## self.trUtf8("""Flushing the database will destroy all data. Are you sure?"""), +## QMessageBox.StandardButtons(\ +## QMessageBox.No | \ +## QMessageBox.Yes), +## QMessageBox.No) +## if res == QMessageBox.No: +## return +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("flush") +## args.append("--noinput") +## +## dia = DjangoDialog(title, +## msgSuccess = self.trUtf8("Database tables flushed successfully.")) +## res = dia.startProcess(args, path) +## if res: +## dia.exec_() +## +## def __databaseReset(self): +## """ +## Private slot to reset the database tables of one or more applications. +## """ +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## title = self.trUtf8("Reset Application(s)") +## +## apps = self.__getApplications() +## if apps.isEmpty(): +## return +## +## res = KQMessageBox.question(self.__ui, +## title, +## self.trUtf8("""Resetting the database tables for the applications '%1' """ +## """will destroy all data. Are you sure?""")\ +## .arg(apps.join(", ")), +## QMessageBox.StandardButtons(\ +## QMessageBox.No | \ +## QMessageBox.Yes), +## QMessageBox.No) +## if res == QMessageBox.No: +## return +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("reset") +## args.append("--noinput") +## args += apps +## +## dia = DjangoDialog(title, +## msgSuccess = self.trUtf8("Database tables for applications '%1' reset " +## "successfully.").arg(apps.join(", ")) +## ) +## res = dia.startProcess(args, path) +## if res: +## dia.exec_() +## +## def __runDatabaseClient(self): +## """ +## Private slot to start a database client for a Django project. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommand")) +## if consoleCmd: +## proc = QProcess() +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("dbshell") +## try: +## wd = self.__sitePath() +## started, pid = QProcess.startDetached(args[0], args[1:], wd) +## if not started: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django process could not be started.')) +## except DjangoNoSiteSelectedException: +## pass + + ####################################################################### + ## slots below implement database functions outputting SQL statements + ####################################################################### + +## def __sqlCommand(self, title, command, requestApps = True): +## """ +## Private method to perform an SQL creation function. +## +## @param title dialog title (string or QString) +## @param command Django sql... command (string or QString) +## @param requestApps flag indicating to request a list of applications +## to work on (boolean) +## """ +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## if requestApps: +## apps = self.__getApplications() +## if apps.isEmpty(): +## return +## else: +## apps = QStringList() +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append(command) +## args += apps +## +## fileFilter = self.trUtf8("SQL Files (*.sql)") +## +## dia = DjangoDialog(title, fixed = True, linewrap = False, +## saveFilters = fileFilter) +## res = dia.startProcess(args, path, False) +## if res: +## dia.exec_() +## +## def __databaseSqlCreateTables(self): +## """ +## Private slot to print the CREATE TABLE SQL statements for one +## or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Create Tables"), "sql") +## +## def __databaseSqlCreateIndexes(self): +## """ +## Private slot to print the CREATE INDEX SQL statements for one +## or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Create Indexes"), "sqlindexes") +## +## def __databaseSqlCreateEverything(self): +## """ +## Private slot to print the CREATE TABLE, custom SQL and +## CREATE INDEX SQL statements for one or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Create Everything"), "sqlall") +## +## def __databaseSqlCustom(self): +## """ +## Private slot to print the custom table modifying SQL statements +## for one or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Custom Statements"), "sqlcustom") +## +## def __databaseSqlDropTables(self): +## """ +## Private slot to print the DROP TABLE SQL statements for one or +## more applications. +## """ +## self.__sqlCommand(self.trUtf8("Drop Tables"), "sqlclear") +## +## def __databaseSqlFlushDatabase(self): +## """ +## Private slot to print a list of statements to return all database +## tables to their initial state. +## """ +## self.__sqlCommand(self.trUtf8("Flush Database"), "sqlflush", False) +## +## def __databaseSqlResetApplication(self): +## """ +## Private slot to print the DROP TABLE SQL, then the CREATE TABLE SQL +## for one or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Reset Application(s)"), "sqlreset") +## +## def __databaseSqlResetSequences(self): +## """ +## Private slot to print the SQL statements for resetting sequences for +## one or more applications. +## """ +## self.__sqlCommand(self.trUtf8("Reset Sequences"), "sqlsequencereset") + + ################################################################## + ## slots below implement some tool functions + ################################################################## + +## def __diffSettings(self): +## """ +## Private slot to show the changes made to the settings.py file. +## """ +## title = self.trUtf8("Diff Settings") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("diffsettings") +## +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dia = DjangoDialog(title, fixed = True, linewrap = False) +## res = dia.startProcess(args, path, False) +## if res: +## dia.exec_() +## +## def __cleanup(self): +## """ +## Private slot to clean out old data from the database. +## """ +## title = self.trUtf8("Cleanup") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("cleanup") +## +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dia = DjangoDialog(title, +## msgSuccess = self.trUtf8("Database cleaned up successfully.")) +## res = dia.startProcess(args, path) +## if res: +## dia.exec_() +## +## def __validate(self): +## """ +## Private slot to validate all installed models. +## """ +## title = self.trUtf8("Validate") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("validate") +## +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dia = DjangoDialog(title) +## res = dia.startProcess(args, path) +## if res: +## dia.exec_() +## +## def __adminIndex(self): +## """ +## Private slot to print the admin-index template snippet. +## """ +## apps = self.__getApplications() +## if apps.isEmpty(): +## return +## +## title = self.trUtf8("Print admin-index") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("adminindex") +## args += apps +## +## try: +## path = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dia = DjangoDialog(title, fixed = True, linewrap = False) +## res = dia.startProcess(args, path, False) +## if res: +## dia.exec_() +## +## def __runPythonShell(self): +## """ +## Private slot to start a Python console for a Django project. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommand")) +## if consoleCmd: +## proc = QProcess() +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("shell") +## if self.__plugin.getPreferences("UsePlainPython"): +## args.append("--plain") +## try: +## wd = self.__sitePath() +## started, pid = QProcess.startDetached(args[0], args[1:], wd) +## if not started: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django process could not be started.')) +## except DjangoNoSiteSelectedException: +## pass + + ################################################################## + ## slots below implement caching functions + ################################################################## + +## def __createCacheTables(self): +## """ +## Private slot to create the tables for the SQL caching backend. +## """ +## title = self.trUtf8("Create Cache Tables") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## tblStr, ok = KQInputDialog.getText(\ +## self.__ui, +## title, +## self.trUtf8("Enter the names of the cache tables separated by spaces."), +## QLineEdit.Normal) +## if ok and not tblStr.isEmpty(): +## tableNames = tblStr.split(" ", QString.SkipEmptyParts) +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("createcachetable") +## args += tableNames +## +## dia = DjangoDialog(title, +## msgSuccess = self.trUtf8("Cache tables created successfully.")) +## res = dia.startProcess(args, wd) +## if res: +## dia.exec_() + + ################################################################## + ## slots below implement testing functions + ################################################################## + +## def __dumpData(self): +## """ +## Private slot to dump the database data to a fixture. +## """ +## title = self.trUtf8("Dump Data") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dlg = DjangoDumpdataDataDialog(self, self.__ui) +## if dlg.exec_() == QDialog.Accepted: +## appls, excls, format = dlg.getData() +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("dumpdata") +## args.append("--format=%s" % format) +## args.append("--indent=2") +## for excl in excls: +## args.append("--exclude=%s" % excl) +## if not appls.isEmpty(): +## args += appls +## +## if format == "json": +## fileFilters = self.trUtf8("JSON Files (*.json)") +## elif format == "xml": +## fileFilters = self.trUtf8("XML Files (*.xml)") +## elif format == "yaml": +## fileFilters = self.trUtf8("YAML Files (*.yaml)") +## +## dia = DjangoDialog(title, fixed = True, linewrap = False, +## saveFilters = fileFilters) +## res = dia.startProcess(args, wd, showCommand = False) +## if res: +## dia.exec_() +## +## def __loadData(self): +## """ +## Private slot to load data from fixture files. +## """ +## title = self.trUtf8("Load Data") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## dlg = DjangoLoaddataDataDialog(self, self.__ui) +## if dlg.exec_() == QDialog.Accepted: +## fixtures = dlg.getData() +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("loaddata") +## args += fixtures +## +## dia = DjangoDialog(title) +## res = dia.startProcess(args, wd) +## if res: +## dia.exec_() +## +## def __runTestSuite(self): +## """ +## Private slot to run the test suite for applications or the whole site. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommandNoClose")) +## if consoleCmd: +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## return +## +## proc = QProcess() +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("test") +## args += self.__getApplications() +## +## started, pid = QProcess.startDetached(args[0], args[1:], wd) +## if not started: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django process could not be started.')) +## +## def __runTestServer(self): +## """ +## Private slot to run a development server with data from a set of fixtures. +## """ +## consoleCmd = unicode(self.__plugin.getPreferences("ConsoleCommand")) +## if consoleCmd: +## dlg = DjangoLoaddataDataDialog(self, self.__ui) +## if dlg.exec_() == QDialog.Accepted: +## fixtures = dlg.getData() +## +## args = Utilities.parseOptionString(consoleCmd) +## args[0] = Utilities.getExecutablePath(args[0]) +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("testserver") +## addr = self.__plugin.getPreferences("ServerAddress") +## if addr: +## args.append("--addrport=%s" % addr) +## args += fixtures +## +## try: +## if Utilities.isWindowsPlatform(): +## serverProcStarted, pid = \ +## QProcess.startDetached(args[0], args[1:], self.__sitePath()) +## else: +## if self.__testServerProc is not None: +## self.__testServerProcFinished() +## +## self.__testServerProc = QProcess() +## self.connect(self.__testServerProc, +## SIGNAL('finished(int, QProcess::ExitStatus)'), +## self.__serverProcFinished) +## +## self.__testServerProc.setWorkingDirectory(self.__sitePath()) +## self.__testServerProc.start(args[0], args[1:]) +## serverProcStarted = self.__testServerProc.waitForStarted() +## if not serverProcStarted: +## KQMessageBox.critical(None, +## self.trUtf8('Process Generation Error'), +## self.trUtf8('The Django test server could not be started.')) +## except DjangoNoSiteSelectedException: +## pass +## +## def __testServerProcFinished(self): +## """ +## Private slot connected to the finished signal of the test server. +## """ +## if self.__testServerProc is not None and \ +## self.__testServerProc.state() != QProcess.NotRunning: +## self.__testServerProc.terminate() +## QTimer.singleShot(2000, self.__testServerProc, SLOT('kill()')) +## self.__testServerProc.waitForFinished(3000) +## self.__testServerProc = None + + ################################################################## + ## slots below implement translation functions + ################################################################## + +## def __getLocale(self, filename): +## """ +## Private method to extract the locale out of a file name. +## +## @param filename name of the file used for extraction (string or QString) +## @return extracted locale (string) or None +## """ +## if self.__e4project.pdata["TRANSLATIONPATTERN"]: +## pattern = unicode(self.__e4project.pdata["TRANSLATIONPATTERN"][0])\ +## .replace("%language%", "(.*?)") +## match = re.search(pattern, unicode(filename)) +## if match is not None: +## loc = match.group(1) +## return loc +## else: +## loc = None +## else: +## loc = None +## +## return loc +## +## def __normalizeList(self, filenames): +## """ +## Private method to normalize a list of file names. +## +## @param filenames list of file names to normalize (list of string or QString) +## @return normalized file names (list of string) +## """ +## nfilenames = [] +## for filename in filenames: +## filename = unicode(filename) +## if filename.endswith(".mo"): +## filename = filename.replace(".mo", ".po") +## if filename not in nfilenames: +## nfilenames.append(filename) +## +## return nfilenames +## +## def __siteFilteredList(self, filenames): +## """ +## Private method to filter a list of file names by site. +## +## @param filenames list of file names to be filtered (list of string or QString) +## @return file names belonging to the current site (list of string) +## """ +## site = self.__site() +## nfilenames = [] +## for filename in filenames: +## filename = unicode(filename) +## if site == "" or filename.startswith(site + os.sep): +## nfilenames.append(filename) +## +## return nfilenames + + def __projectLanguageAdded(self, code): + """ + Private slot handling the addition of a new language. + + @param code language code of the new language (string or QString) + """ +## title = self.trUtf8("Initializing message catalog for '%1'").arg(code) +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("makemessages") +## args.append("-l") +## args.append(code) +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No current site selected or no site created yet.' +## ' Aborting...')) +## return +## +## dia = DjangoDialog(title, +## msgSuccess = \ +## self.trUtf8("\nMessage catalog initialized successfully.")) +## res = dia.startProcess(args, wd) +## if res: +## dia.exec_() +## +## langFile = self.__e4project.pdata["TRANSLATIONPATTERN"][0]\ +## .replace("%language%", code) +## self.__e4project.appendFile(langFile) + + def updateSelectedCatalogs(self, filenames): + """ + Public method to update the message catalogs. + + @param filenames list of filenames + """ +## title = self.trUtf8("Updating message catalogs") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No current site selected or no site created yet.' +## ' Aborting...')) +## return +## +## argsLists = [] +## +## for filename in self.__normalizeList(self.__siteFilteredList(filenames)): +## locale = self.__getLocale(filename) +## if locale: +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("makemessages") +## args.append("-l") +## args.append(locale) +## argsLists.append(args) +## +## if len(argsLists) == 0: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No locales detected.' +## ' Aborting...')) +## return +## +## dia = DjangoDialog(title, +## msgSuccess = \ +## self.trUtf8("\nMessage catalogs updated successfully.")) +## res = dia.startBatchProcesses(argsLists, wd) +## if res: +## dia.exec_() + + def updateCatalogs(self, filenames): + """ + Public method to update the message catalogs. + + @param filenames list of filenames (not used) + """ +## title = self.trUtf8("Updating message catalogs") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("makemessages") +## args.append("-a") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No current site selected or no site created yet.' +## ' Aborting...')) +## return +## +## dia = DjangoDialog(title, +## msgSuccess = \ +## self.trUtf8("\nMessage catalogs updated successfully.")) +## res = dia.startProcess(args, wd) +## if res: +## dia.exec_() + + def compileSelectedCatalogs(self, filenames): + """ + Public method to update the message catalogs. + + @param filenames list of filenames + """ +## title = self.trUtf8("Compiling message catalogs") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No current site selected or no site created yet.' +## ' Aborting...')) +## return +## +## argsLists = [] +## +## for filename in self.__normalizeList(self.__siteFilteredList(filenames)): +## locale = self.__getLocale(filename) +## if locale: +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("compilemessages") +## args.append("-l") +## args.append(locale) +## argsLists.append(args) +## +## if len(argsLists) == 0: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No locales detected.' +## ' Aborting...')) +## return +## +## dia = DjangoDialog(title, +## msgSuccess = \ +## self.trUtf8("\nMessage catalogs compiled successfully.")) +## res = dia.startBatchProcesses(argsLists, wd, mergedOutput = True) +## if res: +## dia.exec_() +## +## for entry in os.walk(self.__sitePath()): +## for fileName in entry[2]: +## fullName = os.path.join(entry[0], fileName) +## if fullName.endswith('.mo'): +## self.__e4project.appendFile(fullName) + + def compileCatalogs(self, filenames): + """ + Public method to compile the message catalogs. + + @param filenames list of filenames (not used) + """ +## title = self.trUtf8("Compiling message catalogs") +## +## args = QStringList() +## args.append(self.__getPythonExecutable()) +## args.append("manage.py") +## args.append("compilemessages") +## +## try: +## wd = self.__sitePath() +## except DjangoNoSiteSelectedException: +## KQMessageBox.warning(None, +## title, +## self.trUtf8('No current site selected or no site created yet.' +## ' Aborting...')) +## return +## +## dia = DjangoDialog(title, +## msgSuccess = \ +## self.trUtf8("\nMessage catalogs compiled successfully.")) +## res = dia.startProcess(args, wd, mergedOutput = True) +## if res: +## dia.exec_() +## +## for entry in os.walk(self.__sitePath()): +## for fileName in entry[2]: +## fullName = os.path.join(entry[0], fileName) +## if fullName.endswith('.mo'): +## self.__e4project.appendFile(fullName)