Sat, 23 Mar 2013 19:41:38 +0100
Continued porting the Django project plug-in from eric4.
--- a/PluginDjango.e4p Fri Mar 22 19:26:49 2013 +0100 +++ b/PluginDjango.e4p Sat Mar 23 19:41:38 2013 +0100 @@ -20,10 +20,14 @@ <Source>ProjectDjango/ConfigurationPage/DjangoPage.py</Source> <Source>ProjectDjango/Project.py</Source> <Source>ProjectDjango/DjangoDialog.py</Source> + <Source>ProjectDjango/DjangoLoaddataDataDialog.py</Source> + <Source>ProjectDjango/DjangoDumpdataDataDialog.py</Source> </Sources> <Forms> <Form>ProjectDjango/ConfigurationPage/DjangoPage.ui</Form> <Form>ProjectDjango/DjangoDialog.ui</Form> + <Form>ProjectDjango/DjangoDumpdataDataDialog.ui</Form> + <Form>ProjectDjango/DjangoLoaddataDataDialog.ui</Form> </Forms> <Translations/> <Resources/>
--- a/PluginProjectDjango.py Fri Mar 22 19:26:49 2013 +0100 +++ b/PluginProjectDjango.py Sat Mar 23 19:41:38 2013 +0100 @@ -213,9 +213,12 @@ e5App().getObject("Project").projectOpenedHooks.connect( self.__object.projectOpenedHooks) e5App().getObject("Project").projectClosedHooks.connect( - self.__object.projectClosedHooks) + self.__object.projectClosedHooks) e5App().getObject("Project").newProjectHooks.connect( - self.__object.projectOpenedHooks) + self.__object.projectOpenedHooks) + + e5App().getObject("Project").projectAboutToBeCreated.connect( + self.__object.startProjectOrApplication) return None, True @@ -236,6 +239,9 @@ e5App().getObject("Project").newProjectHooks.disconnect( self.__object.projectOpenedHooks) + e5App().getObject("Project").projectAboutToBeCreated.disconnect( + self.__object.startProjectOrApplication) + self.__e5project.unregisterProjectType("Django") self.__object.projectClosedHooks()
--- a/ProjectDjango/DjangoDialog.py Fri Mar 22 19:26:49 2013 +0100 +++ b/ProjectDjango/DjangoDialog.py Sat Mar 23 19:41:38 2013 +0100 @@ -250,12 +250,12 @@ self.fileFilters, None) - if not fname.isEmpty(): + if fname: ext = QFileInfo(fname).suffix() - if ext.isEmpty(): - ex = selectedFilter.section('(*', 1, 1).section(')', 0, 0) - if not ex.isEmpty(): - fname.append(ex) + if not ext: + ex = selectedFilter.split("(*")[1].split(")")[0] + if ex: + fname += ex txt = self.resultbox.toPlainText()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjango/DjangoDumpdataDataDialog.py Sat Mar 23 19:41:38 2013 +0100 @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2013 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter the data for the 'dumpdata' command. +""" + +from PyQt4.QtGui import QDialog + +from .Ui_DjangoDumpdataDataDialog import Ui_DjangoDumpdataDataDialog + + +class DjangoDumpdataDataDialog(QDialog, Ui_DjangoDumpdataDataDialog): + """ + Class implementing a dialog to enter the data for the 'dumpdata' command. + """ + def __init__(self, project, parent=None): + """ + Constructor + + @param project reference to the Django project object + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + self.__project = project + if self.__project.getDjangoVersion() < (1, 0): + self.excludeGroup.setEnabled(False) + + apps = self.__project.getRecentApplications() + self.applicationsCombo.addItems(apps) + self.excludeCombo.addItems(apps) + self.excludeCombo.setEditText("") + + self.formatCombo.addItem(self.trUtf8("JSON"), "json") + self.formatCombo.addItem(self.trUtf8("XML"), "xml") + try: + import yaml # __IGNORE_WARNING__ + self.formatCombo.addItem(self.trUtf8("YAML"), "yaml") + except ImportError: + pass + + def getData(self): + """ + Public method to get the data entered into the dialog. + + @return tuple of two lists of strings, a string and an integer giving + the list of applications to work on, the list of applications to + exclude, the dump format and the indentation level + """ + applStr = self.applicationsCombo.currentText() + if applStr: + self.__project.setMostRecentApplication(applStr) + appls = applStr.split() + else: + appls = [] + + exclStr = self.excludeCombo.currentText() + if exclStr: + excl = exclStr.split() + else: + excl = [] + + format = self.formatCombo.itemData(self.formatCombo.currentIndex()) + + return appls, excl, format, self.indentationSpinBox.value()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjango/DjangoDumpdataDataDialog.ui Sat Mar 23 19:41:38 2013 +0100 @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DjangoDumpdataDataDialog</class> + <widget class="QDialog" name="DjangoDumpdataDataDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>287</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>dumpdata Command Options</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>6</number> + </property> + <item> + <widget class="QGroupBox" name="applicationsGroup"> + <property name="title"> + <string>Applications</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>6</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Enter the list of applications separated by spaces. Leave empty for all.</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="applicationsCombo"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="excludeGroup"> + <property name="title"> + <string>Exclude Applications</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Enter the list of applications separated by spaces.</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="excludeCombo"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="formatGroup"> + <property name="title"> + <string>Dump Format</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Serialization Format:</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="formatCombo"> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + </widget> + </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>374</width> + <height>19</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Indentation Level:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="indentationSpinBox"> + <property name="toolTip"> + <string>Enter the indentation level to be used when pretty-printing output</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="minimum"> + <number>2</number> + </property> + <property name="maximum"> + <number>12</number> + </property> + <property name="singleStep"> + <number>2</number> + </property> + <property name="value"> + <number>2</number> + </property> + </widget> + </item> + <item row="1" column="2" colspan="2"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>389</width> + <height>18</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>applicationsCombo</tabstop> + <tabstop>excludeCombo</tabstop> + <tabstop>formatCombo</tabstop> + <tabstop>indentationSpinBox</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DjangoDumpdataDataDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DjangoDumpdataDataDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjango/DjangoLoaddataDataDialog.py Sat Mar 23 19:41:38 2013 +0100 @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2013 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter the data for the 'loaddata' command. +""" + +from PyQt4.QtCore import pyqtSlot +from PyQt4.QtGui import QDialog, QDialogButtonBox + +from E5Gui import E5FileDialog + +from .Ui_DjangoLoaddataDataDialog import Ui_DjangoLoaddataDataDialog + +import Utilities + + +class DjangoLoaddataDataDialog(QDialog, Ui_DjangoLoaddataDataDialog): + """ + Class implementing a dialog to enter the data for the 'loaddata' command. + """ + def __init__(self, project, parent=None): + """ + Constructor + + @param project reference to the Django project object + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + self.__project = project + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) + + @pyqtSlot(str) + def on_fixturesEdit_textChanged(self, txt): + """ + Private slot to handle a change of the fixtures text. + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) + + @pyqtSlot() + def on_fixtureFileButton_clicked(self): + """ + Private slot to select a fixture file via a file selection dialog. + """ + fileFilters = self.trUtf8("JSON Files (*.json);;XML Files (*.xml);;") + try: + import yaml # __IGNORE_WARNING__ + fileFilters += self.trUtf8("YAML Files (*.yaml);;") + except ImportError: + pass + fileFilters += self.trUtf8("All Files (*)") + + fixtureFiles = E5FileDialog.getOpenFileNames( + self, + self.trUtf8("Select fixture file"), + self.__project.getProjectPath(), + fileFilters) + + if fixtureFiles: + self.fixturesEdit.setText(" ".join( + [Utilities.toNativeSeparators(f) for f in fixtureFiles])) + + def getData(self): + """ + Public method to get the data entered into the dialog. + + @return list of fixtures (list of strings) + """ + fixturesStr = self.fixturesEdit.text() + fixtures = fixturesStr.split() + + return fixtures
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjango/DjangoLoaddataDataDialog.ui Sat Mar 23 19:41:38 2013 +0100 @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DjangoLoaddataDataDialog</class> + <widget class="QDialog" name="DjangoLoaddataDataDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>102</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>loaddata Command Options</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Enter the list of fixture patterns or the path of a fixture file.</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="fixturesEdit"/> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="fixtureFileButton"> + <property name="toolTip"> + <string>Select a fixture file via a file selection dialog</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>fixturesEdit</tabstop> + <tabstop>fixtureFileButton</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DjangoLoaddataDataDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DjangoLoaddataDataDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/ProjectDjango/Project.py Fri Mar 22 19:26:49 2013 +0100 +++ b/ProjectDjango/Project.py Sat Mar 23 19:41:38 2013 +0100 @@ -9,12 +9,14 @@ import sys import os +import re -from PyQt4.QtCore import QObject -from PyQt4.QtGui import QMenu, QInputDialog, QLineEdit +from PyQt4.QtCore import QObject, QProcess, QTimer, QUrl, QFileInfo +from PyQt4.QtGui import QMenu, QInputDialog, QLineEdit, QDesktopServices, QDialog, \ + QFileDialog from E5Gui.E5Application import e5App -from E5Gui import E5MessageBox +from E5Gui import E5MessageBox, E5FileDialog from E5Gui.E5Action import E5Action from .DjangoDialog import DjangoDialog @@ -62,6 +64,9 @@ """ Public method to define the Pyramid actions. """ + # TODO: add support for manage.py changepassword + # TODO: add support for manage.py createsuperuser + # TODO: add support for manage.py clearsession self.actions = [] self.selectSiteAct = E5Action(self.trUtf8('Current Project'), @@ -128,55 +133,54 @@ 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) -## + ############################## + ## run actions below ## + ############################## + + self.runServerAct = E5Action(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.runServerAct.triggered[()].connect(self.__runServer) + self.actions.append(self.runServerAct) + + self.runBrowserAct = E5Action(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.runBrowserAct.triggered[()].connect(self.__runBrowser) + self.actions.append(self.runBrowserAct) + + ############################## + ## caching actions below ## + ############################## + + self.createCacheTableAct = E5Action(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.createCacheTableAct.triggered[()].connect(self.__createCacheTables) + self.actions.append(self.createCacheTableAct) + ############################## ## help action below ## ############################## @@ -210,351 +214,295 @@ )) 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) -## + + self.__initDatabaseActions() + self.__initDatabaseSqlActions() + self.__initToolsActions() + self.__initTestingActions() + + def __initDatabaseActions(self): + """ + Private method to define the database related actions. + """ + self.syncDatabaseAct = E5Action(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.syncDatabaseAct.triggered[()].connect(self.__databaseSynchronize) + self.actions.append(self.syncDatabaseAct) + + self.inspectDatabaseAct = E5Action(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.inspectDatabaseAct.triggered[()].connect(self.__databaseInspect) + self.actions.append(self.inspectDatabaseAct) + + self.flushDatabaseAct = E5Action(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.flushDatabaseAct.triggered[()].connect(self.__databaseFlush) + self.actions.append(self.flushDatabaseAct) + + self.databaseClientAct = E5Action(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.databaseClientAct.triggered[()].connect(self.__runDatabaseClient) + self.actions.append(self.databaseClientAct) + + def __initDatabaseSqlActions(self): + """ + Private method to define the database SQL related actions. + """ + self.databaseSqlCreateTablesAct = E5Action(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.databaseSqlCreateTablesAct.triggered[()].connect( + self.__databaseSqlCreateTables) + self.actions.append(self.databaseSqlCreateTablesAct) + + self.databaseSqlCreateIndexesAct = E5Action(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.databaseSqlCreateIndexesAct.triggered[()].connect( + self.__databaseSqlCreateIndexes) + self.actions.append(self.databaseSqlCreateIndexesAct) + + self.databaseSqlCreateEverythingAct = E5Action(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.databaseSqlCreateEverythingAct.triggered[()].connect( + self.__databaseSqlCreateEverything) + self.actions.append(self.databaseSqlCreateEverythingAct) + + self.databaseSqlCustomAct = E5Action(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.databaseSqlCustomAct.triggered[()].connect( + self.__databaseSqlCustom) + self.actions.append(self.databaseSqlCustomAct) + + self.databaseSqlDropTablesAct = E5Action(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.databaseSqlDropTablesAct.triggered[()].connect( + self.__databaseSqlDropTables) + self.actions.append(self.databaseSqlDropTablesAct) + + self.databaseSqlFlushAct = E5Action(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.databaseSqlFlushAct.triggered[()].connect( + self.__databaseSqlFlushDatabase) + self.actions.append(self.databaseSqlFlushAct) + + self.databaseSqlResetSeqAct = E5Action(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.databaseSqlResetSeqAct.triggered[()].connect( + self.__databaseSqlResetSequences) + self.actions.append(self.databaseSqlResetSeqAct) + + def __initToolsActions(self): + """ + Private method to define the tool actions. + """ + self.diffSettingsAct = E5Action(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.diffSettingsAct.triggered[()].connect(self.__diffSettings) + self.actions.append(self.diffSettingsAct) + + self.cleanupAct = E5Action(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.cleanupAct.triggered[()].connect(self.__cleanup) + self.actions.append(self.cleanupAct) + + self.validateAct = E5Action(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.validateAct.triggered[()].connect(self.__validate) + self.actions.append(self.validateAct) + + self.runPythonShellAct = E5Action(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.runPythonShellAct.triggered[()].connect(self.__runPythonShell) + self.actions.append(self.runPythonShellAct) + + def __initTestingActions(self): + """ + Private method to define the testing actions. + """ + self.dumpDataAct = E5Action(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.dumpDataAct.triggered[()].connect(self.__dumpData) + self.actions.append(self.dumpDataAct) + + self.loadDataAct = E5Action(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.loadDataAct.triggered[()].connect(self.__loadData) + self.actions.append(self.loadDataAct) + + self.runTestAct = E5Action(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.runTestAct.triggered[()].connect(self.__runTestSuite) + self.actions.append(self.runTestAct) + + self.runTestServerAct = E5Action(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.runTestServerAct.triggered[()].connect(self.__runTestServer) + self.actions.append(self.runTestServerAct) + def initMenu(self): """ Public slot to initialize the Django menu. @@ -566,8 +514,8 @@ menu.addAction(self.selectSiteAct) menu.addSeparator() -## menu.addAction(self.runServerAct) -## menu.addAction(self.runBrowserAct) + menu.addAction(self.runServerAct) + menu.addAction(self.runBrowserAct) menu.addSeparator() menu.addAction(self.startProjectAct) menu.addAction(self.startGlobalApplicationAct) @@ -577,7 +525,7 @@ menu.addSeparator() menu.addMenu(self.__initToolsMenu()) menu.addSeparator() -## menu.addAction(self.createCacheTableAct) + menu.addAction(self.createCacheTableAct) menu.addSeparator() menu.addMenu(self.__initTestingMenu()) menu.addSeparator() @@ -598,14 +546,13 @@ menu = QMenu(self.trUtf8("&Database"), self.__ui) menu.setTearOffEnabled(True) -## menu.addAction(self.syncDatabaseAct) + menu.addAction(self.syncDatabaseAct) menu.addSeparator() -## menu.addAction(self.inspectDatabaseAct) + menu.addAction(self.inspectDatabaseAct) menu.addSeparator() -## menu.addAction(self.flushDatabaseAct) -## menu.addAction(self.resetDatabaseAct) + menu.addAction(self.flushDatabaseAct) menu.addSeparator() -## menu.addAction(self.databaseClientAct) + menu.addAction(self.databaseClientAct) menu.addSeparator() menu.addMenu(self.__initDatabaseSqlMenu()) @@ -620,17 +567,16 @@ 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.addAction(self.databaseSqlCreateTablesAct) + menu.addAction(self.databaseSqlCreateIndexesAct) + menu.addAction(self.databaseSqlCreateEverythingAct) menu.addSeparator() -## menu.addAction(self.databaseSqlDropTablesAct) + menu.addAction(self.databaseSqlCustomAct) menu.addSeparator() -## menu.addAction(self.databaseSqlFlushAct) -## menu.addAction(self.databaseSqlResetApplAct) -## menu.addAction(self.databaseSqlResetSeqAct) + menu.addAction(self.databaseSqlDropTablesAct) + menu.addSeparator() + menu.addAction(self.databaseSqlFlushAct) + menu.addAction(self.databaseSqlResetSeqAct) return menu @@ -643,12 +589,11 @@ 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.addAction(self.diffSettingsAct) + menu.addAction(self.cleanupAct) + menu.addAction(self.validateAct) menu.addSeparator() -## menu.addAction(self.runPythonShellAct) + menu.addAction(self.runPythonShellAct) return menu @@ -661,11 +606,11 @@ menu = QMenu(self.trUtf8("T&esting"), self.__ui) menu.setTearOffEnabled(True) -## menu.addAction(self.dumpDataAct) -## menu.addAction(self.loadDataAct) + menu.addAction(self.dumpDataAct) + menu.addAction(self.loadDataAct) menu.addSeparator() -## menu.addAction(self.runTestAct) -## menu.addAction(self.runTestServerAct) + menu.addAction(self.runTestAct) + menu.addAction(self.runTestServerAct) return menu @@ -691,6 +636,12 @@ self.updateCatalogs, self.trUtf8("Update all catalogs")) self.__translationsBrowser.addHookMethodAndMenuEntry("generateSelected", self.updateSelectedCatalogs, self.trUtf8("Update selected catalogs")) + self.__translationsBrowser.addHookMethodAndMenuEntry( + "generateAllWithObsolete", self.updateCatalogsWithObsolete, + self.trUtf8("Update all catalogs (with obsolete)")) + self.__translationsBrowser.addHookMethodAndMenuEntry( + "generateSelectedWithObsolete", self.updateSelectedCatalogsWithObsolete, + self.trUtf8("Update selected catalogs (with obsolete)")) self.__translationsBrowser.addHookMethodAndMenuEntry("releaseAll", self.compileCatalogs, self.trUtf8("Compile all catalogs")) self.__translationsBrowser.addHookMethodAndMenuEntry("releaseSelected", @@ -711,6 +662,8 @@ self.__projectLanguageAdded) self.__translationsBrowser.removeHookMethod("generateAll") self.__translationsBrowser.removeHookMethod("generateSelected") + self.__translationsBrowser.removeHookMethod("generateAllWithObsolete") + self.__translationsBrowser.removeHookMethod("generateSelectedWithObsolete") self.__translationsBrowser.removeHookMethod("releaseAll") self.__translationsBrowser.removeHookMethod("releaseSelected") self.__translationsBrowser = None @@ -723,62 +676,63 @@ @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) + fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( + self.__ui, + self.trUtf8("New Form"), + path, + filter, + None, + QFileDialog.Options(QFileDialog.DontConfirmOverwrite)) + + if not fname: + # user aborted or didn't enter a filename + return + + ext = QFileInfo(fname).suffix() + if not ext: + ex = selectedFilter.split("(*")[1].split(")")[0] + if ex: + fname += ex + + if os.path.exists(fname): + res = E5MessageBox.yesNo(self.__ui, + self.trUtf8("New Form"), + self.trUtf8("The file already exists! Overwrite it?"), + icon=E5MessageBox.Warning) + + if not res: + # user selected to not overwrite + return + + try: + f = open(fname, "w") + f.write('<!DOCTYPE html>') + f.write('<html>\n') + f.write(' <head>\n') + f.write(' <meta content="" />\n') + f.write(' <title></title>\n') + f.write(' <link rel="stylesheet" type="text/css" href="style.css"/>') + f.write(' <!--[if lte IE 7]>') + f.write(' <link rel="stylesheet" type="text/css" href="ie.css"/>') + f.write(' <![endif]-->') + f.write(' </head>\n') + f.write('\n') + f.write(' <body class="bodyclass">\n') + f.write(' <div id="container">') + f.write(' </div>') + f.write(' </body>\n') + f.close() + f.write('</html>\n') + f.close() + except (IOError, OSError) as e: + E5MessageBox.critical(self.__ui, + self.trUtf8("New Form"), + self.trUtf8("<p>The new form file <b>{0}</b> could not be created.<br>" + "Problem: {1}</p>").format(fname, str(e))) + return + + self.__e5project.appendFile(fname) + self.__formsBrowser.sourceFile.emit(fname) ################################################################## ## slots below implement general functionality @@ -814,33 +768,33 @@ ).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 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 (list of strings) + """ + applStr, ok = QInputDialog.getItem( + self.__ui, + self.trUtf8("Select Applications"), + self.trUtf8("Enter the list of applications separated by spaces."), + self.getRecentApplications(), + 0, True) + if ok and applStr != "": + self.setMostRecentApplication(applStr) + return applStr.split() + else: + return [] + def __loadRecentApplications(self): """ Private method to load the recently used applications list. @@ -898,6 +852,7 @@ @return Python executable (string) """ + # TODO: make this differentiate between Python2 and Python3 return sys.executable.replace("pythonw", "python") def __showHelpIndex(self): @@ -908,34 +863,48 @@ "Documentation", "help", "index.html") self.__ui.launchHelpViewer(page) + def __isSpawningConsole(self, consoleCmd): + """ + Private method to check, if the given console is a spawning console. + + @param consoleCmd console command (string) + @return tuple of two entries giving an indication, if the console + is spawning (boolean) and the (possibly) cleaned console command + (string) + """ + if consoleCmd and consoleCmd[0] == '@': + return (True, consoleCmd[1:]) + else: + return (False, consoleCmd) + ################################################################## ## 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 startProjectOrApplication(self): + """ + Public slot to start a new Django project or application. + """ + if self.__e5project.getProjectType() == "Django": + projectStr = self.trUtf8("Project") + applStr = self.trUtf8("Application") + selections = ["", projectStr, applStr] + selection, ok = QInputDialog.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 bool(selection): + if selection == projectStr: + path, projectName = os.path.split(self.__e5project.getProjectPath()) + self.__createProject(projectName, path) + elif selection == applStr: + path, applName = os.path.split(self.__e5project.getProjectPath()) + self.__createApplication(applName, path) + def __createProject(self, projectName, path): """ Private slot to create a new Django project. @@ -1184,751 +1153,717 @@ ## 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())) + def __runServer(self): + """ + Private slot to start the Django Web server. + """ + consoleCmd = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommand"))[1] + 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.__serverProc.finished.connect(self.__serverProcFinished) + self.__serverProc.setWorkingDirectory(self.__sitePath()) + self.__serverProc.start(args[0], args[1:]) + serverProcStarted = self.__serverProc.waitForStarted() + if not serverProcStarted: + E5MessageBox.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.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 = "8000" + url = QUrl("http://127.0.0.1:{0}".format(port)) + res = QDesktopServices.openUrl(url) + if not res: + E5MessageBox.critical(None, + self.trUtf8('Run Web-Browser'), + self.trUtf8('Could not start the web-browser for the url "{0}".')\ + .format(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 + def __databaseSynchronize(self): + """ + Private slot to synchronize the database. + """ + consoleCmd = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommandNoClose"))[1] + if consoleCmd: + 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: + E5MessageBox.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 = [] + 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 = E5MessageBox.yesNo(self.__ui, + title, + self.trUtf8("""Flushing the database will destroy all data. Are you sure?""")) + if res: + args = [] + 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 __runDatabaseClient(self): + """ + Private slot to start a database client for a Django project. + """ + consoleCmd = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommand"))[1] + if consoleCmd: + 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: + E5MessageBox.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") + def __sqlCommand(self, title, command, requestApps = True): + """ + Private method to perform an SQL creation function. + + @param title dialog title (string) + @param command Django sql... command (string) + @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 not apps: + return + else: + apps = [] + + args = [] + 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 __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 + def __diffSettings(self): + """ + Private slot to show the changes made to the settings.py file. + """ + title = self.trUtf8("Diff Settings") + + args = [] + 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 = [] + 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 = [] + 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 __runPythonShell(self): + """ + Private slot to start a Python console for a Django project. + """ + consoleCmd = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommand"))[1] + if consoleCmd: + 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: + E5MessageBox.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_() + 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 = QInputDialog.getText( + self.__ui, + title, + self.trUtf8("Enter the names of the cache tables separated by spaces."), + QLineEdit.Normal) + if ok and tblStr != "": + tableNames = tblStr.split() + + args = [] + 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 + 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 + + from .DjangoDumpdataDataDialog import DjangoDumpdataDataDialog + dlg = DjangoDumpdataDataDialog(self, self.__ui) + if dlg.exec_() == QDialog.Accepted: + appls, excls, format, indent = dlg.getData() + + args = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("dumpdata") + args.append("--format={0}".format(format)) + args.append("--indent={0}".format(indent)) + for excl in excls: + args.append("--exclude={0}".format(excl)) + 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 + + from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog + dlg = DjangoLoaddataDataDialog(self, self.__ui) + if dlg.exec_() == QDialog.Accepted: + fixtures = dlg.getData() + + args = [] + 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 = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommandNoClose"))[1] + if consoleCmd: + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + return + + 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: + E5MessageBox.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 = self.__isSpawningConsole( + self.__plugin.getPreferences("ConsoleCommand"))[1] + if consoleCmd: + from .DjangoLoaddataDataDialog import DjangoLoaddataDataDialog + 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.__testServerProc.finished.connect(self.__serverProcFinished) + self.__testServerProc.setWorkingDirectory(self.__sitePath()) + self.__testServerProc.start(args[0], args[1:]) + serverProcStarted = self.__testServerProc.waitForStarted() + if not serverProcStarted: + E5MessageBox.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.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 + # TODO: the below stuff needs testing + 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) + @return extracted locale (string) or None + """ + if self.__e5project.pdata["TRANSLATIONPATTERN"]: + pattern = self.__e5project.pdata["TRANSLATIONPATTERN"][0]\ + .replace("%language%", "(.*?)") + match = re.search(pattern, 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 strings) + @return normalized file names (list of strings) + """ + nfilenames = [] + for filename in filenames: + 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 strings) + @return file names belonging to the current site (list of strings) + """ + site = self.__site() + nfilenames = [] + for filename in filenames: + 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) + @param code language code of the new language (string) """ -## 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) + title = self.trUtf8("Initializing message catalog for '{0}'").format(code) + + args = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("makemessages") + args.append("--domain=django") + args.append("--domain=djangojs") + args.append("-l") + args.append(code) + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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.__e5project.pdata["TRANSLATIONPATTERN"][0]\ + .replace("%language%", code) + self.__e5project.appendFile(langFile) def updateSelectedCatalogs(self, filenames): """ Public method to update the message catalogs. + @param filenames list of file names (list of strings) + """ + title = self.trUtf8("Updating message catalogs") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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 = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("makemessages") + args.append("--no-obsolete") + args.append("--domain=django") + args.append("--domain=djangojs") + args.append("-l") + args.append(locale) + argsLists.append(args) + + if len(argsLists) == 0: + E5MessageBox.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 updateSelectedCatalogsWithObsolete(self, filenames): + """ + Public method to update the message catalogs keeping obsolete messages. + @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_() + title = self.trUtf8("Updating message catalogs (keeping obsolete messages)") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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 = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("makemessages") + args.append("--domain=django") + args.append("--domain=djangojs") + args.append("-l") + args.append(locale) + argsLists.append(args) + + if len(argsLists) == 0: + E5MessageBox.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): """ @@ -1936,29 +1871,64 @@ @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_() + title = self.trUtf8("Updating message catalogs") + + args = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("makemessages") + args.append("-a") + args.append("--no-obsolete") + args.append("--domain=django") + args.append("--domain=djangojs") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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 updateCatalogsWithObsolete(self, filenames): + """ + Public method to update the message catalogs keeping obsolete messages. + + @param filenames list of filenames (not used) + """ + title = self.trUtf8("Updating message catalogs (keeping obsolete messages)") + + args = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("makemessages") + args.append("-a") + args.append("--domain=django") + args.append("--domain=djangojs") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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): """ @@ -1966,49 +1936,48 @@ @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) + title = self.trUtf8("Compiling message catalogs") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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 = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("compilemessages") + args.append("-l") + args.append(locale) + argsLists.append(args) + + if len(argsLists) == 0: + E5MessageBox.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.__e5project.appendFile(fullName) def compileCatalogs(self, filenames): """ @@ -2016,31 +1985,31 @@ @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) + title = self.trUtf8("Compiling message catalogs") + + args = [] + args.append(self.__getPythonExecutable()) + args.append("manage.py") + args.append("compilemessages") + + try: + wd = self.__sitePath() + except DjangoNoSiteSelectedException: + E5MessageBox.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.__e5project.appendFile(fullName)