Thread: [Pymoul-svn] SF.net SVN: pymoul: [17] pymoul/trunk/src/moul
Status: Alpha
Brought to you by:
tiran
From: <ti...@us...> - 2007-01-12 18:14:33
|
Revision: 17 http://pymoul.svn.sourceforge.net/pymoul/?rev=17&view=rev Author: tiran Date: 2007-01-12 10:14:31 -0800 (Fri, 12 Jan 2007) Log Message: ----------- Let's stick to singular package and module names Added Paths: ----------- pymoul/trunk/src/moul/file/ Removed Paths: ------------- pymoul/trunk/src/moul/files/ Copied: pymoul/trunk/src/moul/file (from rev 13, pymoul/trunk/src/moul/files) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-15 15:15:28
|
Revision: 22 http://pymoul.svn.sourceforge.net/pymoul/?rev=22&view=rev Author: tiran Date: 2007-01-15 07:15:25 -0800 (Mon, 15 Jan 2007) Log Message: ----------- Added stub to handle D'ni time and Cavern time Added Paths: ----------- pymoul/trunk/src/moul/time/ pymoul/trunk/src/moul/time/README.txt pymoul/trunk/src/moul/time/__init__.py pymoul/trunk/src/moul/time/cavern.py pymoul/trunk/src/moul/time/dni.py Added: pymoul/trunk/src/moul/time/README.txt =================================================================== --- pymoul/trunk/src/moul/time/README.txt (rev 0) +++ pymoul/trunk/src/moul/time/README.txt 2007-01-15 15:15:25 UTC (rev 22) @@ -0,0 +1,30 @@ +Cavern time +----------- + +Cavern time is MDT (mountain time with daylight saving) + +D'ni time +--------- + +sources: + http://www.mystlore.com/wiki/D%27ni_time + http://www.mystlore.com/wiki/D%27ni_timekeeping_conversion_algorithms + +year 0: 7656 B.C. +hahrtee fahrah -> 625 hahr (100 pentovigesimal years) +hahr -> year +vai-lee (pl vai-lee-tee) -> month + hahr as 10 vai-lee-tee +yahr (pl yahr-tee) -> day with about 30h 14mins (1.26 earth days) + vai-lee has 29 yahr-tee +gahr-tah-vo-tee -> 6h 3mins (5 per yahr) +tah-vo-tee -> 14.5mins (25 per gahr-tah-vo) +gor-ahn-tee -> 36secs (25 per tah-vo) +pro-rahn-tee -> 1.5sec (25 per gor-ahn) + +The ten vaileetee are Leefo (April 21st to May 27th), Leebro (May 28th to July 3rd), Leesahn (July 3rd to August 8th), Leetar (August 9th and September 14th), Leevot (September 14th to October 20th), Leevofo (October 21st to November 26th), Leevobro (November 26th to January 1st), Leevosahn (January 2nd to February 7th), Leevotar (February 7th to March 15th) and Leenovoo (March 16th to April 21st). +New Year, traditionally a significant holiday, therefore occurs on April 21st in human terms: i.e., on Leefo 1. + +solar year: 365 days, 6 hours, 9 minutes and 9 seconds -> 31556925 seconds +D'ni hahr: 10×29×5×25×25×25 prorahntee -> 22656250 prorahntee +factor: 1.39285738 Added: pymoul/trunk/src/moul/time/__init__.py =================================================================== --- pymoul/trunk/src/moul/time/__init__.py (rev 0) +++ pymoul/trunk/src/moul/time/__init__.py 2007-01-15 15:15:25 UTC (rev 22) @@ -0,0 +1,8 @@ +# MOUL package +# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + Added: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py (rev 0) +++ pymoul/trunk/src/moul/time/cavern.py 2007-01-15 15:15:25 UTC (rev 22) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""pyMoul cavern time tool +""" +__all__ = ['TIMEZONE_NAMES',] + +from datetime import datetime +from datetime import timedelta + +from pytz import common_timezones +from pytz import timezone +from pytz import utc as UTC + +TIMEZONE_NAMES = common_timezones + +# Cyan HQ is near Spokane / Washington +# Cavern time is Mountain Time Zone (MDT) with daylight savings (MST) +CAVERN_TZ_NAME = 'US/Mountain' # MDT / MST +CAVERN_TZ = timezone(CAVERN_TZ_NAME) + Added: pymoul/trunk/src/moul/time/dni.py =================================================================== --- pymoul/trunk/src/moul/time/dni.py (rev 0) +++ pymoul/trunk/src/moul/time/dni.py 2007-01-15 15:15:25 UTC (rev 22) @@ -0,0 +1,55 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""pyMoul D'ni time tool +""" +from operator import mul + +FARAH_1 = -7656 # hahrtee fahrah 1 starts at April 21st 7656 B.C +DNI_FACTORS = ( + ('hahrtee fahrah', 625), + ('hahr', 10), + ('vai-lee', 29), + ('yahr', 5), + ('gahr-tah-vo', 25), + ('tah-vo', 25), + ('gor-ahn', 25), + ('pro-rahn', 1), + ) + +VAILATEE = ( + ('Leefo', ( 4, 21), ( 5, 27)), # 1: April 21st to May 27th + ('Leebro', ( 5, 28), ( 7, 3)), # 2: May 28th to July 3rd + ('Leesahn', ( 7, 3), ( 8, 8)), # 3: July 3rd to August 8th + ('Leetar', ( 8, 9), ( 9, 15)), # 4: August 9th and September 14th + ('Leevot', ( 9, 14), (10, 20)), # 5: September 14th to October 20th + ('Leevofo', (10, 21), (11, 26)), # 6: October 21st to November 26th + ('Leevobro', (11, 26), ( 1, 1)), # 7: November 26th to January 1st + ('Leevosahn', ( 1, 2), ( 2, 7)), # 8: January 2nd to February 7th + ('Leevotar', ( 2, 7), ( 3, 15)), # 9: February 7th to March 15th + ('Leenovoo', ( 3, 16), ( 4, 21)), # 10: March 16th to April 21st + ) +PRORAHN_PER_HAHR = reduce(mul, + [float(factor) for name, factor in DNI_FACTORS[1:-1]]) + +# Official SI year 365.25 days = 31.557.600 seconds +YEAR_SI = 31557600 +# Sidereal year: 365.256 363 051 days (365 d 6 h 9 min 9 s) +YEAR_SIDEREAL = (((((365 * 24) + 6 ) * 60 ) + 9 ) * 60 ) + 9 +YEAR = float(YEAR_SIDEREAL) + +FACTOR = YEAR / PRORAHN_PER_HAHR This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-15 19:01:47
|
Revision: 28 http://pymoul.svn.sourceforge.net/pymoul/?rev=28&view=rev Author: tiran Date: 2007-01-15 11:01:38 -0800 (Mon, 15 Jan 2007) Log Message: ----------- * Added example WDYS, ELF and KI image * Added unittests for ELF and WDYS files * Fixed implementation of WDYS and ELF crypt functions Modified Paths: -------------- pymoul/trunk/src/moul/crypt/elf.py pymoul/trunk/src/moul/crypt/whatdoyousee.py Added Paths: ----------- pymoul/trunk/src/moul/crypt/tests/test_elf.py pymoul/trunk/src/moul/file/tests/audio.ini pymoul/trunk/src/moul/file/tests/audio.txt pymoul/trunk/src/moul/file/tests/audiocaps.0.elf pymoul/trunk/src/moul/file/tests/audiocaps.0.txt pymoul/trunk/src/moul/file/tests/avatar.jpg pymoul/trunk/src/moul/file/tests/graphics.ini pymoul/trunk/src/moul/file/tests/graphics.txt Modified: pymoul/trunk/src/moul/crypt/elf.py =================================================================== --- pymoul/trunk/src/moul/crypt/elf.py 2007-01-15 19:00:16 UTC (rev 27) +++ pymoul/trunk/src/moul/crypt/elf.py 2007-01-15 19:01:38 UTC (rev 28) @@ -19,6 +19,8 @@ Based on the C++ code from Marack """ +import struct + def list2int(lst): return [ord(s) for s in lst] @@ -26,7 +28,7 @@ return [chr(s) for s in lst] def decryptElf(fin): - """Decrypts an encrypted log file (MOUL elf file) + """Decrypt an encrypted log file (MOUL elf file) fin - log file opened in binary mode result - list of unencrypted lines @@ -40,21 +42,30 @@ out = [] while True: fpos = fin.tell() - if fpos == fsize: + if fpos >= fsize: + # EOF reached, add an empty line + out.append('') break seghead = fin.read(2) # Kudos to the programmer who thought up this little trick # Very nice work (and highly confusing to reverse engineer)! - segsize = str2int(seghead) ^ (fpos & 0xffff) + segsize = struct.unpack("<H", seghead)[0] ^ (fpos & 0xffff) key = fpos & 0xff - - #print "Pos: %s, size: %s, key: %s" % (fpos, segsize, key) seg = fin.read(segsize) uncrypt = decipher(seg, segsize, key) out.append(uncrypt) return out +def encryptElf(instr, fout): + """Encrypt an encrypted log file (MOUL elf file) + + instr - input as string + fout - log file to write (binary mode) + """ + # XXX NotImplemented + raise NotImplementedError + def decipher(crypt, size, key): """decipher for ELF (encrypted log files) Added: pymoul/trunk/src/moul/crypt/tests/test_elf.py =================================================================== --- pymoul/trunk/src/moul/crypt/tests/test_elf.py (rev 0) +++ pymoul/trunk/src/moul/crypt/tests/test_elf.py 2007-01-15 19:01:38 UTC (rev 28) @@ -0,0 +1,52 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.crypt.elf unit tests +""" +import os +import unittest +from doctest import DocTestSuite + +import moul.file +from moul.crypt.elf import decryptElf + +base = os.path.dirname(moul.file.__file__) +elf_enc = os.path.join(base, 'tests', 'audiocaps.0.elf') +elf_dec = os.path.join(base, 'tests', 'audiocaps.0.txt') + +class ElfTest(unittest.TestCase): + def setUp(self): + self.enc = open(elf_enc, 'rb') + self.dec = open(elf_dec, 'r') + + def tearDown(self): + self.enc.close() + self.dec.close() + + def test_compare(self): + data = '\n'.join(decryptElf(self.enc)) + self.failUnlessEqual(data, self.dec.read()) + +def test_suite(): + return unittest.TestSuite(( + unittest.makeSuite(ElfTest), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") + + Modified: pymoul/trunk/src/moul/crypt/whatdoyousee.py =================================================================== --- pymoul/trunk/src/moul/crypt/whatdoyousee.py 2007-01-15 19:00:16 UTC (rev 27) +++ pymoul/trunk/src/moul/crypt/whatdoyousee.py 2007-01-15 19:01:38 UTC (rev 28) @@ -46,7 +46,7 @@ raise IOError("Not a whatdoyousee/xTEA encrypted file") header = fin.read(4) - struct.unpack(ENDIAN+"L", header) + length = struct.unpack(ENDIAN+"L", header)[0] out = [] pos = 0 @@ -59,7 +59,9 @@ else: out.append(block) pos += 8 - return ''.join(out) + data = ''.join(out) + # XXX: dos format + return data.replace("\r\n", "\n") def encryptWDYS(instr, fout): """Encrypt whatdoyousee files @@ -68,6 +70,8 @@ fout - out file descriptor in write and binary mode return - None """ + # XXX: dos format + instr = instr.replace("\n", "\r\n") fin.seek(0) fout.write(HEADER) Added: pymoul/trunk/src/moul/file/tests/audio.ini =================================================================== (Binary files differ) Property changes on: pymoul/trunk/src/moul/file/tests/audio.ini ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: pymoul/trunk/src/moul/file/tests/audio.txt =================================================================== --- pymoul/trunk/src/moul/file/tests/audio.txt (rev 0) +++ pymoul/trunk/src/moul/file/tests/audio.txt 2007-01-15 19:01:38 UTC (rev 28) @@ -0,0 +1,11 @@ +Audio.Initialize true +Audio.UseEAX true +Audio.SetPriorityCutoff 6 +Audio.MuteAll 0 +Audio.SetChannelVolume SoundFX 1 +Audio.SetChannelVolume BgndMusic 1 +Audio.SetChannelVolume Ambience 1 +Audio.SetChannelVolume NPCVoice 1 +Audio.EnableVoiceRecording 1 +Audio.SetDeviceName "Generic Hardware" +Audio.SetChannelVolume GUI 1 Property changes on: pymoul/trunk/src/moul/file/tests/audio.txt ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/audiocaps.0.elf =================================================================== (Binary files differ) Property changes on: pymoul/trunk/src/moul/file/tests/audiocaps.0.elf ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: pymoul/trunk/src/moul/file/tests/audiocaps.0.txt =================================================================== --- pymoul/trunk/src/moul/file/tests/audiocaps.0.txt (rev 0) +++ pymoul/trunk/src/moul/file/tests/audiocaps.0.txt 2007-01-15 19:01:38 UTC (rev 28) @@ -0,0 +1,6 @@ +SB Audigy 2 ZS Audio [C800] +Bluetooth Audio +Default DirectSound Device +Default WaveOut Device +DirectSound: Bluetooth Audio +DirectSound: SB Audigy 2 ZS Audio [C800] Property changes on: pymoul/trunk/src/moul/file/tests/audiocaps.0.txt ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/avatar.jpg =================================================================== (Binary files differ) Property changes on: pymoul/trunk/src/moul/file/tests/avatar.jpg ___________________________________________________________________ Name: svn:mime-type + image/jpeg Added: pymoul/trunk/src/moul/file/tests/graphics.ini =================================================================== (Binary files differ) Property changes on: pymoul/trunk/src/moul/file/tests/graphics.ini ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: pymoul/trunk/src/moul/file/tests/graphics.txt =================================================================== --- pymoul/trunk/src/moul/file/tests/graphics.txt (rev 0) +++ pymoul/trunk/src/moul/file/tests/graphics.txt 2007-01-15 19:01:38 UTC (rev 28) @@ -0,0 +1,12 @@ +Graphics.Width 1024 +Graphics.Height 768 +Graphics.ColorDepth 32 +Graphics.Windowed true +Graphics.AntiAliasAmount 2 +Graphics.AnisotropicLevel 2 +Graphics.TextureQuality 2 +Quality.Level 2 +Graphics.Shadow.Enable 1 +Graphics.EnablePlanarReflections 1 +Graphics.EnableVSync false +Graphics.Shadow.VisibleDistance 0.337126016617 Property changes on: pymoul/trunk/src/moul/file/tests/graphics.txt ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-16 12:40:27
|
Revision: 34 http://pymoul.svn.sourceforge.net/pymoul/?rev=34&view=rev Author: tiran Date: 2007-01-16 04:40:27 -0800 (Tue, 16 Jan 2007) Log Message: ----------- * Time zone tab with time zone chooser partly working Modified Paths: -------------- pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/time/cavern.py Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-16 11:16:50 UTC (rev 33) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-16 12:40:27 UTC (rev 34) @@ -1,10 +1,16 @@ import sys -from PyQt4 import QtCore from PyQt4 import QtGui +from PyQt4.QtCore import QDir +from PyQt4.QtCore import QString +from PyQt4.QtCore import QStringList +from PyQt4.QtCore import pyqtSignature +from PyQt4.QtCore import SIGNAL +from PyQt4.QtCore import QFileInfo from moul.qt.ui.mainwindow import Ui_MainWindow -from moul.time import cavern as caverntime +from moul.time.cavern import CavernTime +from moul.time.cavern import TIMEZONE_NAMES class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def __init__(self): @@ -12,6 +18,46 @@ # Set up the user interface from Designer. self.setupUi(self) - # timezone - self.cb_timezone_chooser.addItems(caverntime.TIMEZONE_NAMES) + self._timezone_init() + + def _timezone_init(self): + """Init time zone tab""" + tz = 'Europe/Berlin' + self._caverntime = CavernTime(tz) + + chooser = self.cb_timezone_chooser + curidx = TIMEZONE_NAMES.index(tz) + chooser.addItems(QStringList(TIMEZONE_NAMES)) + chooser.setCurrentIndex(curidx) + + self.connect(self.cb_timezone_chooser, + SIGNAL("currentIndexChanged (const QString&)"), + self.on_cb_timezone_chooser_changed) + + self._timezone_update() + + def _timezone_update(self, ct=None): + """Update datetime widgets""" + if ct is None: + ct = self._caverntime() + + self.dt_cavern.setDateTime(ct['cavern']['datetime']) + self.dt_local.setDateTime(ct['local']['datetime']) + + # TODO: handle fractions + off = ct['cavern']['utcoffset'] + txt = "UTC %s%i" % (off[0], abs(off[1])) + self.lb_cavern_utc.setText(QString(txt)) + + off = ct['local']['utcoffset'] + txt = "UTC %s%i" % (off[0], abs(off[1])) + self.lb_local_utc.setText(QString(txt)) + + def on_cb_timezone_chooser_changed(self, name): + """Change time zone event + SIGNAL: currentIndexChanged (const QString&) + """ + name = str(name) + self._caverntime.setLocalTZ(name) + self._timezone_update() Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-16 11:16:50 UTC (rev 33) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-16 12:40:27 UTC (rev 34) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Tue Jan 16 01:02:23 2007 +# Created: Tue Jan 16 12:47:17 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -58,12 +58,6 @@ self.pushButton.setObjectName("pushButton") self.hboxlayout.addWidget(self.pushButton) - self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) - self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) - self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) - self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") - self.label = QtGui.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(15,10,430,58)) self.label.setFrameShape(QtGui.QFrame.StyledPanel) @@ -290,6 +284,14 @@ self.tab_time = QtGui.QWidget() self.tab_time.setObjectName("tab_time") + self.gb_timezone = QtGui.QGroupBox(self.tab_time) + self.gb_timezone.setGeometry(QtCore.QRect(10,10,421,81)) + self.gb_timezone.setObjectName("gb_timezone") + + self.cb_timezone_chooser = QtGui.QComboBox(self.gb_timezone) + self.cb_timezone_chooser.setGeometry(QtCore.QRect(10,30,271,21)) + self.cb_timezone_chooser.setObjectName("cb_timezone_chooser") + self.gb_caverntime = QtGui.QGroupBox(self.tab_time) self.gb_caverntime.setGeometry(QtCore.QRect(10,100,421,121)) self.gb_caverntime.setObjectName("gb_caverntime") @@ -309,12 +311,13 @@ self.dt_cavern = QtGui.QDateTimeEdit(self.horizontalLayout_2) self.dt_cavern.setReadOnly(True) + self.dt_cavern.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) self.dt_cavern.setObjectName("dt_cavern") self.hboxlayout5.addWidget(self.dt_cavern) - self.label_3 = QtGui.QLabel(self.horizontalLayout_2) - self.label_3.setObjectName("label_3") - self.hboxlayout5.addWidget(self.label_3) + self.lb_cavern_utc = QtGui.QLabel(self.horizontalLayout_2) + self.lb_cavern_utc.setObjectName("lb_cavern_utc") + self.hboxlayout5.addWidget(self.lb_cavern_utc) self.horizontalLayout_3 = QtGui.QWidget(self.gb_caverntime) self.horizontalLayout_3.setGeometry(QtCore.QRect(20,70,261,31)) @@ -334,21 +337,13 @@ self.dt_local.setObjectName("dt_local") self.hboxlayout6.addWidget(self.dt_local) - self.label_11 = QtGui.QLabel(self.horizontalLayout_3) - self.label_11.setObjectName("label_11") - self.hboxlayout6.addWidget(self.label_11) + self.lb_local_utc = QtGui.QLabel(self.horizontalLayout_3) + self.lb_local_utc.setObjectName("lb_local_utc") + self.hboxlayout6.addWidget(self.lb_local_utc) self.gb_dnitime = QtGui.QGroupBox(self.tab_time) self.gb_dnitime.setGeometry(QtCore.QRect(10,230,421,111)) self.gb_dnitime.setObjectName("gb_dnitime") - - self.gb_timezone = QtGui.QGroupBox(self.tab_time) - self.gb_timezone.setGeometry(QtCore.QRect(10,10,421,81)) - self.gb_timezone.setObjectName("gb_timezone") - - self.cb_timezone_chooser = QtGui.QComboBox(self.gb_timezone) - self.cb_timezone_chooser.setGeometry(QtCore.QRect(10,30,271,21)) - self.cb_timezone_chooser.setObjectName("cb_timezone_chooser") self.tabWidget.addTab(self.tab_time,"") self.tab_4 = QtGui.QWidget() @@ -359,6 +354,12 @@ self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.tabWidget.addTab(self.tab_4,"") + + self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) + self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) + self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) + self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) @@ -392,13 +393,13 @@ self.label_7.setText(QtGui.QApplication.translate("MainWindow", "Ultra", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_graphics), QtGui.QApplication.translate("MainWindow", "Graphis", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_audio), QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_timezone.setTitle(QtGui.QApplication.translate("MainWindow", "Time Zone", None, QtGui.QApplication.UnicodeUTF8)) self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Cavern Time", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_cavern_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Local time:", None, QtGui.QApplication.UnicodeUTF8)) - self.label_11.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_local_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_timezone.setTitle(QtGui.QApplication.translate("MainWindow", "Time Zone", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.label_6.setText(QtGui.QApplication.translate("MainWindow", "pyMoul tools", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-16 11:16:50 UTC (rev 33) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-16 12:40:27 UTC (rev 34) @@ -78,22 +78,6 @@ </item> </layout> </widget> - <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > - <property name="geometry" > - <rect> - <x>10</x> - <y>480</y> - <width>441</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> <widget class="QLabel" name="label" > <property name="geometry" > <rect> @@ -564,6 +548,29 @@ <attribute name="title" > <string>Time</string> </attribute> + <widget class="QGroupBox" name="gb_timezone" > + <property name="geometry" > + <rect> + <x>10</x> + <y>10</y> + <width>421</width> + <height>81</height> + </rect> + </property> + <property name="title" > + <string>Time Zone</string> + </property> + <widget class="QComboBox" name="cb_timezone_chooser" > + <property name="geometry" > + <rect> + <x>10</x> + <y>30</y> + <width>271</width> + <height>21</height> + </rect> + </property> + </widget> + </widget> <widget class="QGroupBox" name="gb_caverntime" > <property name="geometry" > <rect> @@ -604,10 +611,13 @@ <property name="readOnly" > <bool>true</bool> </property> + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> </widget> </item> <item> - <widget class="QLabel" name="label_3" > + <widget class="QLabel" name="lb_cavern_utc" > <property name="text" > <string>UTC</string> </property> @@ -646,7 +656,7 @@ </widget> </item> <item> - <widget class="QLabel" name="label_11" > + <widget class="QLabel" name="lb_local_utc" > <property name="text" > <string>UTC</string> </property> @@ -668,29 +678,6 @@ <string>D'ni time</string> </property> </widget> - <widget class="QGroupBox" name="gb_timezone" > - <property name="geometry" > - <rect> - <x>10</x> - <y>10</y> - <width>421</width> - <height>81</height> - </rect> - </property> - <property name="title" > - <string>Time Zone</string> - </property> - <widget class="QComboBox" name="cb_timezone_chooser" > - <property name="geometry" > - <rect> - <x>10</x> - <y>30</y> - <width>271</width> - <height>21</height> - </rect> - </property> - </widget> - </widget> </widget> <widget class="QWidget" name="tab_4" > <attribute name="title" > @@ -714,6 +701,22 @@ </widget> </widget> </widget> + <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > + <property name="geometry" > + <rect> + <x>10</x> + <y>480</y> + <width>441</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> Modified: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py 2007-01-16 11:16:50 UTC (rev 33) +++ pymoul/trunk/src/moul/time/cavern.py 2007-01-16 12:40:27 UTC (rev 34) @@ -17,10 +17,9 @@ # """pyMoul cavern time tool """ -__all__ = ['TIMEZONE_NAMES',] +__all__ = ['TIMEZONE_NAMES', 'CavernTime'] from datetime import datetime -from datetime import timedelta #from pytz import common_timezones from pytz import all_timezones @@ -40,6 +39,9 @@ else: unsupported.append(tz) continue + split = tz.split('/') + if len(split) > 2: + continue prefix, postfix = tz.split('/')[:2] if prefix in SUPPORTED_TZ: supported.append(tz) @@ -57,8 +59,9 @@ CAVERN_TZ = timezone(CAVERN_TZ_NAME) def diffTD(td1, td2): - """Difference of two timedelta objects -> int + """Difference of two objects -> int + >>> from datetime import timedelta >>> type(diffTD(timedelta(0, 3600), timedelta(0, -3600))) <type 'int'> >>> diffTD(timedelta(0, 3600), timedelta(0, -3600)) @@ -82,6 +85,8 @@ def td2int(td): """timedelta to int + + >>> from datetime import timedelta >>> td2int(timedelta(0, 3600)) 3600 >>> td2int(timedelta(0, -3600)) @@ -100,41 +105,40 @@ cavern datetime -- Current time in cavern TZ as <datetime> object tz -- Cavern time zone object - utcoffset -- (hours, fraction) offset from UTC + utcoffset -- (signum, hours, fraction) offset from UTC cavern datetime -- Current time in local TZ as <datetime> object tz -- Local time zone object - utcoffset -- (hours, fraction) offset from UTC + utcoffset -- (signum, hours, fraction) offset from UTC >>> ct = CavernTime(local="Europe/Berlin") >>> result = ct() >>> 'utc' in result, 'local' in result, 'cavern' in result (True, True, True) >>> coff = result['cavern']['utcoffset'] - >>> coff == (-7, 0.0) or coff == (-8, 0.0) or coff + >>> coff == ('-', -7, 0.0) or coff == ('-', -8, 0.0) or coff True >>> loff = result['local']['utcoffset'] - >>> loff == (1, 0.0) or loff == (2, 0.0) or loff + >>> loff == ('+', 1, 0.0) or loff == ('+', 2, 0.0) or loff True + + >>> 'UTC' in CavernTime.timezones + True + >>> 'UTC' in ct.timezones + True """ - _timezones = TIMEZONE_NAMES + timezones = TIMEZONE_NAMES _cavern = CAVERN_TZ _local = None def __init__(self, local): - self.setLocal(local) + self.setLocalTZ(local) - def setLocal(self, local): + def setLocalTZ(self, local): """Set local time zone """ self._local = timezone(local) - @property - def timezones(self): - """Available time zones as strings - """ - return self._timezones - @staticmethod def _utcnow(): """Get current time in UTC @@ -155,8 +159,9 @@ for id, tz in (('cavern', self._cavern), ('local', self._local)): info = result.setdefault(id, {}) utcoffset = td2int(tz.utcoffset(now)) + signum = utcoffset > 0 and '+' or '-' info['tz'] = tz - info['utcoffset'] = int(utcoffset/3600), float((utcoffset%3600)/3600.0) + info['utcoffset'] = signum,int(utcoffset/3600), float((utcoffset%3600)/3600.0) info['datetime'] = self._normalize(tz, now) result['utc'] = {'datetime' : now} return result This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-16 13:11:23
|
Revision: 36 http://pymoul.svn.sourceforge.net/pymoul/?rev=36&view=rev Author: tiran Date: 2007-01-16 05:11:23 -0800 (Tue, 16 Jan 2007) Log Message: ----------- Minor fixes Modified Paths: -------------- pymoul/trunk/src/moul/tests/test_i18n.py pymoul/trunk/src/moul/time/cavern.py Modified: pymoul/trunk/src/moul/tests/test_i18n.py =================================================================== --- pymoul/trunk/src/moul/tests/test_i18n.py 2007-01-16 13:09:30 UTC (rev 35) +++ pymoul/trunk/src/moul/tests/test_i18n.py 2007-01-16 13:11:23 UTC (rev 36) @@ -16,6 +16,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # """moul.i18n unit tests +""" __author__ = "Christian Heimes" __version__ = "$Id$" __revision__ = "$Revision$" Modified: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py 2007-01-16 13:09:30 UTC (rev 35) +++ pymoul/trunk/src/moul/time/cavern.py 2007-01-16 13:11:23 UTC (rev 36) @@ -163,7 +163,7 @@ for id, tz in (('cavern', self._cavern), ('local', self._local)): info = result.setdefault(id, {}) utcoffset = td2int(tz.utcoffset(now)) - signum = utcoffset > 0 and '+' or '-' + signum = utcoffset < 0 and '-' or '+' info['tz'] = tz info['utcoffset'] = signum,int(utcoffset/3600), float((utcoffset%3600)/3600.0) info['datetime'] = self._normalize(tz, now) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-16 20:52:04
|
Revision: 37 http://pymoul.svn.sourceforge.net/pymoul/?rev=37&view=rev Author: tiran Date: 2007-01-16 12:43:19 -0800 (Tue, 16 Jan 2007) Log Message: ----------- * Added PST time zone because the support used PST instead of MST/cavern time * Updated UI to use a timer for the time zone display. Qt is cool :) Modified Paths: -------------- pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/moulqt.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/time/cavern.py Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-16 13:11:23 UTC (rev 36) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-16 20:43:19 UTC (rev 37) @@ -24,12 +24,11 @@ import sys from PyQt4 import QtGui -from PyQt4.QtCore import QDir from PyQt4.QtCore import QString from PyQt4.QtCore import QStringList from PyQt4.QtCore import pyqtSignature from PyQt4.QtCore import SIGNAL -from PyQt4.QtCore import QFileInfo +from PyQt4.QtCore import QTimer from moul.qt.ui.mainwindow import Ui_MainWindow from moul.time.cavern import CavernTime @@ -45,19 +44,16 @@ def _timezone_init(self): """Init time zone tab""" - tz = 'Europe/Berlin' - self._caverntime = CavernTime(tz) - - chooser = self.cb_timezone_chooser - curidx = TIMEZONE_NAMES.index(tz) - chooser.addItems(QStringList(TIMEZONE_NAMES)) - chooser.setCurrentIndex(curidx) - - self.connect(self.cb_timezone_chooser, - SIGNAL("currentIndexChanged (const QString&)"), - self.on_cb_timezone_chooser_changed) - + # create info object and update display the first time + self._caverntime = CavernTime() self._timezone_update() + + # create a timer to update the display every second + self._timezone_timer = timer = QTimer(self) + timer.setInterval(1000) # 1 sec + # TODO: needs optimization? run only when timer tab is active + self.connect(timer, SIGNAL('timeout()'), self._timezone_update) + timer.start() def _timezone_update(self, ct=None): """Update datetime widgets""" @@ -65,22 +61,12 @@ ct = self._caverntime() self.dt_cavern.setDateTime(ct['cavern']['datetime']) - self.dt_local.setDateTime(ct['local']['datetime']) + self.dt_pacific.setDateTime(ct['pacific']['datetime']) - # TODO: handle fractions off = ct['cavern']['utcoffset'] txt = "UTC %s%i" % (off[0], abs(off[1])) self.lb_cavern_utc.setText(QString(txt)) - off = ct['local']['utcoffset'] + off = ct['pacific']['utcoffset'] txt = "UTC %s%i" % (off[0], abs(off[1])) - self.lb_local_utc.setText(QString(txt)) - - def on_cb_timezone_chooser_changed(self, name): - """Change time zone event - - SIGNAL: currentIndexChanged (const QString&) - """ - name = str(name) - self._caverntime.setLocalTZ(name) - self._timezone_update() + self.lb_pacific_utc.setText(QString(txt)) Modified: pymoul/trunk/src/moul/qt/moulqt.py =================================================================== --- pymoul/trunk/src/moul/qt/moulqt.py 2007-01-16 13:11:23 UTC (rev 36) +++ pymoul/trunk/src/moul/qt/moulqt.py 2007-01-16 20:43:19 UTC (rev 37) @@ -30,7 +30,6 @@ from moul.file import plasmalog from moul.file import wdysini from moul.file import kiimage -from moul.time import cavern as caverntime from moul.time import dni as dnitime def main(*args): Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-16 13:11:23 UTC (rev 36) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-16 20:43:19 UTC (rev 37) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Tue Jan 16 13:40:50 2007 +# Created: Tue Jan 16 21:38:16 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -65,6 +65,12 @@ self.label.setPixmap(QtGui.QPixmap(":/resources/moul_logo.png")) self.label.setObjectName("label") + self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) + self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) + self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) + self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") + self.tabWidget = QtGui.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(5,100,450,375)) self.tabWidget.setTabPosition(QtGui.QTabWidget.North) @@ -284,65 +290,49 @@ self.tab_time = QtGui.QWidget() self.tab_time.setObjectName("tab_time") - self.gb_timezone = QtGui.QGroupBox(self.tab_time) - self.gb_timezone.setGeometry(QtCore.QRect(10,10,421,81)) - self.gb_timezone.setObjectName("gb_timezone") - - self.cb_timezone_chooser = QtGui.QComboBox(self.gb_timezone) - self.cb_timezone_chooser.setGeometry(QtCore.QRect(10,30,271,21)) - self.cb_timezone_chooser.setObjectName("cb_timezone_chooser") - self.gb_caverntime = QtGui.QGroupBox(self.tab_time) - self.gb_caverntime.setGeometry(QtCore.QRect(10,100,421,121)) + self.gb_caverntime.setGeometry(QtCore.QRect(10,10,431,111)) self.gb_caverntime.setObjectName("gb_caverntime") - self.horizontalLayout_2 = QtGui.QWidget(self.gb_caverntime) - self.horizontalLayout_2.setGeometry(QtCore.QRect(20,20,261,31)) - self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.gridLayout = QtGui.QWidget(self.gb_caverntime) + self.gridLayout.setGeometry(QtCore.QRect(10,20,281,80)) + self.gridLayout.setObjectName("gridLayout") - self.hboxlayout5 = QtGui.QHBoxLayout(self.horizontalLayout_2) - self.hboxlayout5.setMargin(0) - self.hboxlayout5.setSpacing(6) - self.hboxlayout5.setObjectName("hboxlayout5") + self.gridlayout = QtGui.QGridLayout(self.gridLayout) + self.gridlayout.setMargin(0) + self.gridlayout.setSpacing(6) + self.gridlayout.setObjectName("gridlayout") - self.label_4 = QtGui.QLabel(self.horizontalLayout_2) - self.label_4.setObjectName("label_4") - self.hboxlayout5.addWidget(self.label_4) - - self.dt_cavern = QtGui.QDateTimeEdit(self.horizontalLayout_2) + self.dt_cavern = QtGui.QDateTimeEdit(self.gridLayout) self.dt_cavern.setReadOnly(True) self.dt_cavern.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) self.dt_cavern.setObjectName("dt_cavern") - self.hboxlayout5.addWidget(self.dt_cavern) + self.gridlayout.addWidget(self.dt_cavern,0,1,1,1) - self.lb_cavern_utc = QtGui.QLabel(self.horizontalLayout_2) + self.label_4 = QtGui.QLabel(self.gridLayout) + self.label_4.setObjectName("label_4") + self.gridlayout.addWidget(self.label_4,0,0,1,1) + + self.lb_cavern_utc = QtGui.QLabel(self.gridLayout) self.lb_cavern_utc.setObjectName("lb_cavern_utc") - self.hboxlayout5.addWidget(self.lb_cavern_utc) + self.gridlayout.addWidget(self.lb_cavern_utc,0,2,1,1) - self.horizontalLayout_3 = QtGui.QWidget(self.gb_caverntime) - self.horizontalLayout_3.setGeometry(QtCore.QRect(20,70,261,31)) - self.horizontalLayout_3.setObjectName("horizontalLayout_3") - - self.hboxlayout6 = QtGui.QHBoxLayout(self.horizontalLayout_3) - self.hboxlayout6.setMargin(0) - self.hboxlayout6.setSpacing(6) - self.hboxlayout6.setObjectName("hboxlayout6") - - self.label_5 = QtGui.QLabel(self.horizontalLayout_3) + self.label_5 = QtGui.QLabel(self.gridLayout) self.label_5.setObjectName("label_5") - self.hboxlayout6.addWidget(self.label_5) + self.gridlayout.addWidget(self.label_5,1,0,1,1) - self.dt_local = QtGui.QDateTimeEdit(self.horizontalLayout_3) - self.dt_local.setReadOnly(True) - self.dt_local.setObjectName("dt_local") - self.hboxlayout6.addWidget(self.dt_local) + self.dt_pacific = QtGui.QDateTimeEdit(self.gridLayout) + self.dt_pacific.setReadOnly(True) + self.dt_pacific.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.dt_pacific.setObjectName("dt_pacific") + self.gridlayout.addWidget(self.dt_pacific,1,1,1,1) - self.lb_local_utc = QtGui.QLabel(self.horizontalLayout_3) - self.lb_local_utc.setObjectName("lb_local_utc") - self.hboxlayout6.addWidget(self.lb_local_utc) + self.lb_pacific_utc = QtGui.QLabel(self.gridLayout) + self.lb_pacific_utc.setObjectName("lb_pacific_utc") + self.gridlayout.addWidget(self.lb_pacific_utc,1,2,1,1) self.gb_dnitime = QtGui.QGroupBox(self.tab_time) - self.gb_dnitime.setGeometry(QtCore.QRect(10,230,421,111)) + self.gb_dnitime.setGeometry(QtCore.QRect(10,130,431,211)) self.gb_dnitime.setObjectName("gb_dnitime") self.tabWidget.addTab(self.tab_time,"") @@ -354,12 +344,6 @@ self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.tabWidget.addTab(self.tab_4,"") - - self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) - self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) - self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) - self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) @@ -367,7 +351,7 @@ MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) - self.tabWidget.setCurrentIndex(2) + self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.buttonbox_rresavcl,QtCore.SIGNAL("rejected()"),MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -393,12 +377,11 @@ self.label_7.setText(QtGui.QApplication.translate("MainWindow", "Ultra", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_graphics), QtGui.QApplication.translate("MainWindow", "Graphis", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_audio), QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_timezone.setTitle(QtGui.QApplication.translate("MainWindow", "Time Zone", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Cavern Time", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Time zones", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) self.lb_cavern_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Local time:", None, QtGui.QApplication.UnicodeUTF8)) - self.lb_local_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Pacific time:", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_pacific_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.label_6.setText(QtGui.QApplication.translate("MainWindow", "pyMoul tools", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-16 13:11:23 UTC (rev 36) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-16 20:43:19 UTC (rev 37) @@ -100,6 +100,22 @@ <pixmap resource="moulqt.qrc" >:/resources/moul_logo.png</pixmap> </property> </widget> + <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > + <property name="geometry" > + <rect> + <x>10</x> + <y>480</y> + <width>441</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> <widget class="QTabWidget" name="tabWidget" > <property name="geometry" > <rect> @@ -113,7 +129,7 @@ <enum>QTabWidget::North</enum> </property> <property name="currentIndex" > - <number>2</number> + <number>0</number> </property> <widget class="QWidget" name="tab_graphics" > <attribute name="title" > @@ -548,65 +564,35 @@ <attribute name="title" > <string>Time</string> </attribute> - <widget class="QGroupBox" name="gb_timezone" > + <widget class="QGroupBox" name="gb_caverntime" > <property name="geometry" > <rect> <x>10</x> <y>10</y> - <width>421</width> - <height>81</height> + <width>431</width> + <height>111</height> </rect> </property> <property name="title" > - <string>Time Zone</string> + <string>Time zones</string> </property> - <widget class="QComboBox" name="cb_timezone_chooser" > + <widget class="QWidget" name="gridLayout" > <property name="geometry" > <rect> <x>10</x> - <y>30</y> - <width>271</width> - <height>21</height> - </rect> - </property> - </widget> - </widget> - <widget class="QGroupBox" name="gb_caverntime" > - <property name="geometry" > - <rect> - <x>10</x> - <y>100</y> - <width>421</width> - <height>121</height> - </rect> - </property> - <property name="title" > - <string>Cavern Time</string> - </property> - <widget class="QWidget" name="horizontalLayout_2" > - <property name="geometry" > - <rect> - <x>20</x> <y>20</y> - <width>261</width> - <height>31</height> + <width>281</width> + <height>80</height> </rect> </property> - <layout class="QHBoxLayout" > + <layout class="QGridLayout" > <property name="margin" > <number>0</number> </property> <property name="spacing" > <number>6</number> </property> - <item> - <widget class="QLabel" name="label_4" > - <property name="text" > - <string>Cavern time:</string> - </property> - </widget> - </item> - <item> + <item row="0" column="1" > <widget class="QDateTimeEdit" name="dt_cavern" > <property name="readOnly" > <bool>true</bool> @@ -616,47 +602,39 @@ </property> </widget> </item> - <item> + <item row="0" column="0" > + <widget class="QLabel" name="label_4" > + <property name="text" > + <string>Cavern time:</string> + </property> + </widget> + </item> + <item row="0" column="2" > <widget class="QLabel" name="lb_cavern_utc" > <property name="text" > <string>UTC</string> </property> </widget> </item> - </layout> - </widget> - <widget class="QWidget" name="horizontalLayout_3" > - <property name="geometry" > - <rect> - <x>20</x> - <y>70</y> - <width>261</width> - <height>31</height> - </rect> - </property> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> + <item row="1" column="0" > <widget class="QLabel" name="label_5" > <property name="text" > - <string>Local time:</string> + <string>Pacific time:</string> </property> </widget> </item> - <item> - <widget class="QDateTimeEdit" name="dt_local" > + <item row="1" column="1" > + <widget class="QDateTimeEdit" name="dt_pacific" > <property name="readOnly" > <bool>true</bool> </property> + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> </widget> </item> - <item> - <widget class="QLabel" name="lb_local_utc" > + <item row="1" column="2" > + <widget class="QLabel" name="lb_pacific_utc" > <property name="text" > <string>UTC</string> </property> @@ -669,9 +647,9 @@ <property name="geometry" > <rect> <x>10</x> - <y>230</y> - <width>421</width> - <height>111</height> + <y>130</y> + <width>431</width> + <height>211</height> </rect> </property> <property name="title" > @@ -701,22 +679,6 @@ </widget> </widget> </widget> - <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > - <property name="geometry" > - <rect> - <x>10</x> - <y>480</y> - <width>441</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> Modified: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py 2007-01-16 13:11:23 UTC (rev 36) +++ pymoul/trunk/src/moul/time/cavern.py 2007-01-16 20:43:19 UTC (rev 37) @@ -59,11 +59,14 @@ # Cyan HQ is near Spokane / Washington # Cavern time is Mountain Time Zone (MDT) with daylight savings (MST) -CAVERN_TZ_NAME = 'US/Mountain' # MDT / MST +CAVERN_TZ_NAME = 'US/Mountain' # MST / MDT CAVERN_TZ = timezone(CAVERN_TZ_NAME) +PACIFIC_TZ_NAME = 'US/Pacific' # PST / PDT +PACIFIC_TZ = timezone(PACIFIC_TZ_NAME) + def diffTD(td1, td2): - """Difference of two objects -> int + """Difference of two objects -> int >>> from datetime import timedelta >>> type(diffTD(timedelta(0, 3600), timedelta(0, -3600))) @@ -101,31 +104,49 @@ class CavernTime(object): """Cavern time calculator - Calculates the cavern time and local time based on a given local time + Calculates the cavern time and other useful tz based on a given local time zone. Call a CavernTime object: utc datetime -- Current time in UTC as <datetime> object - cavern - datetime -- Current time in cavern TZ as <datetime> object - tz -- Cavern time zone object + cavern, pacific + datetime -- current time TZ as <datetime> object + tz -- time zone object + dst -- dst in seconds if dst utcoffset -- (signum, hours, fraction) offset from UTC - cavern - datetime -- Current time in local TZ as <datetime> object - tz -- Local time zone object - utcoffset -- (signum, hours, fraction) offset from UTC + name -- long time like US/Mountain + id -- short name like MST - >>> ct = CavernTime(local="Europe/Berlin") + >>> ct = CavernTime() >>> result = ct() - >>> 'utc' in result, 'local' in result, 'cavern' in result - (True, True, True) - >>> coff = result['cavern']['utcoffset'] - >>> coff == ('-', -7, 0.0) or coff == ('-', -8, 0.0) or coff + >>> 'utc' in result True - >>> loff = result['local']['utcoffset'] - >>> loff == ('+', 1, 0.0) or loff == ('+', 2, 0.0) or loff + + >>> cav = result['cavern'] + >>> off = cav['utcoffset'] + >>> dst = cav['dst'] + >>> (not dst and off == ('-', -7, 0.0)) or (dst and off == ('-', -8, 0.0)) or off True + >>> cav['id'] + 'MST' + >>> cav['name'] + 'US/Mountain' + >>> cav['dst'] in (0, 3600) + True + >>> del cav + >>> pst = result['pacific'] + >>> dst = pst['dst'] + >>> (not dst and off == ('-', -7, 0.0)) or (dst and off == ('-', -8, 0.0)) or off + True + >>> pst['id'] + 'PST' + >>> pst['name'] + 'US/Pacific' + >>> pst['dst'] in (0, 3600) + True + >>> del pst + >>> 'UTC' in CavernTime.timezones True >>> 'UTC' in ct.timezones @@ -133,15 +154,7 @@ """ timezones = TIMEZONE_NAMES _cavern = CAVERN_TZ - _local = None - - def __init__(self, local): - self.setLocalTZ(local) - - def setLocalTZ(self, local): - """Set local time zone - """ - self._local = timezone(local) + _pacific = PACIFIC_TZ @staticmethod def _utcnow(): @@ -160,12 +173,18 @@ def __call__(self): now = self._utcnow() result = {} - for id, tz in (('cavern', self._cavern), ('local', self._local)): + for id, tz in (('cavern', self._cavern), ('pacific', self._pacific)): info = result.setdefault(id, {}) utcoffset = td2int(tz.utcoffset(now)) signum = utcoffset < 0 and '-' or '+' info['tz'] = tz info['utcoffset'] = signum,int(utcoffset/3600), float((utcoffset%3600)/3600.0) info['datetime'] = self._normalize(tz, now) + info['name'] = str(tz) + info['id'] = tz._tzname + info['dst'] = td2int(tz.dst(now)) result['utc'] = {'datetime' : now} return result + + def __str__(self): + return str(self._cavern) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-17 11:28:11
|
Revision: 39 http://pymoul.svn.sourceforge.net/pymoul/?rev=39&view=rev Author: tiran Date: 2007-01-17 03:28:12 -0800 (Wed, 17 Jan 2007) Log Message: ----------- Added unit test stubs. ATM most unit tests are NOOPs that simply import the module and try to apply a DocTestSuite. At least the tests are catching syntax errors :) Modified Paths: -------------- pymoul/trunk/src/moul/crypt/tests/test_elf.py pymoul/trunk/src/moul/crypt/tests/test_wdys.py pymoul/trunk/src/moul/qt/moulqt.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/tests/test_i18n.py pymoul/trunk/src/moul/time/tests/test_cavern.py Added Paths: ----------- pymoul/trunk/src/moul/file/tests/test_chatlog.py pymoul/trunk/src/moul/file/tests/test_kiimage.py pymoul/trunk/src/moul/file/tests/test_localization.py pymoul/trunk/src/moul/file/tests/test_plasmalog.py pymoul/trunk/src/moul/file/tests/test_wdysini.py pymoul/trunk/src/moul/time/tests/test_dni.py Modified: pymoul/trunk/src/moul/crypt/tests/test_elf.py =================================================================== --- pymoul/trunk/src/moul/crypt/tests/test_elf.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/crypt/tests/test_elf.py 2007-01-17 11:28:12 UTC (rev 39) @@ -48,6 +48,7 @@ def test_suite(): return unittest.TestSuite(( unittest.makeSuite(ElfTest), + DocTestSuite('moul.crypt.elf'), )) if __name__ == '__main__': Modified: pymoul/trunk/src/moul/crypt/tests/test_wdys.py =================================================================== --- pymoul/trunk/src/moul/crypt/tests/test_wdys.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/crypt/tests/test_wdys.py 2007-01-17 11:28:12 UTC (rev 39) @@ -62,6 +62,8 @@ def test_suite(): return unittest.TestSuite(( unittest.makeSuite(WDYSTest), + DocTestSuite('moul.crypt.whatdoyousee'), + DocTestSuite('moul.crypt.xtea'), )) if __name__ == '__main__': Added: pymoul/trunk/src/moul/file/tests/test_chatlog.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_chatlog.py (rev 0) +++ pymoul/trunk/src/moul/file/tests/test_chatlog.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.file. unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.file.chatlog + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.file.chatlog') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/file/tests/test_chatlog.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/test_kiimage.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_kiimage.py (rev 0) +++ pymoul/trunk/src/moul/file/tests/test_kiimage.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.file.kiimage unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.file.kiimage + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.file.kiimage') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/file/tests/test_kiimage.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/test_localization.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_localization.py (rev 0) +++ pymoul/trunk/src/moul/file/tests/test_localization.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.file.localization unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.file.localization + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.file.localization') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/file/tests/test_localization.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/test_plasmalog.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_plasmalog.py (rev 0) +++ pymoul/trunk/src/moul/file/tests/test_plasmalog.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.file.plasmalog unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.file.plasmalog + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.file.plasmalog') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/file/tests/test_plasmalog.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/file/tests/test_wdysini.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_wdysini.py (rev 0) +++ pymoul/trunk/src/moul/file/tests/test_wdysini.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.file.wdysini unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.file.wdysini + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.file.wdysini') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/file/tests/test_wdysini.py ___________________________________________________________________ Name: svn:eol-style + native Modified: pymoul/trunk/src/moul/qt/moulqt.py =================================================================== --- pymoul/trunk/src/moul/qt/moulqt.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/qt/moulqt.py 2007-01-17 11:28:12 UTC (rev 39) @@ -27,10 +27,6 @@ from PyQt4 import QtGui from moul.qt.mainwindow import MainWindow -from moul.file import plasmalog -from moul.file import wdysini -from moul.file import kiimage -from moul.time import dni as dnitime def main(*args): app = QtGui.QApplication(*args) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-17 11:28:12 UTC (rev 39) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Tue Jan 16 22:34:20 2007 +# Created: Wed Jan 17 01:43:35 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! Modified: pymoul/trunk/src/moul/tests/test_i18n.py =================================================================== --- pymoul/trunk/src/moul/tests/test_i18n.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/tests/test_i18n.py 2007-01-17 11:28:12 UTC (rev 39) @@ -24,6 +24,8 @@ import unittest from doctest import DocTestSuite +import moul.i18n + def test_suite(): return unittest.TestSuite(( DocTestSuite('moul.i18n'), Modified: pymoul/trunk/src/moul/time/tests/test_cavern.py =================================================================== --- pymoul/trunk/src/moul/time/tests/test_cavern.py 2007-01-16 21:39:46 UTC (rev 38) +++ pymoul/trunk/src/moul/time/tests/test_cavern.py 2007-01-17 11:28:12 UTC (rev 39) @@ -25,6 +25,8 @@ import unittest from doctest import DocTestSuite +import moul.time.cavern + def test_suite(): return unittest.TestSuite(( DocTestSuite('moul.time.cavern'), Added: pymoul/trunk/src/moul/time/tests/test_dni.py =================================================================== --- pymoul/trunk/src/moul/time/tests/test_dni.py (rev 0) +++ pymoul/trunk/src/moul/time/tests/test_dni.py 2007-01-17 11:28:12 UTC (rev 39) @@ -0,0 +1,36 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.time.dni unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import os +import unittest +from doctest import DocTestSuite + +import moul.time.dni + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.time.dni'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/time/tests/test_dni.py ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-17 11:29:32
|
Revision: 40 http://pymoul.svn.sourceforge.net/pymoul/?rev=40&view=rev Author: tiran Date: 2007-01-17 03:29:30 -0800 (Wed, 17 Jan 2007) Log Message: ----------- Added moul.server package. The package contains a list of game servers and two classes to DNS lookup and socket.connect() servers. Added Paths: ----------- pymoul/trunk/src/moul/server/ pymoul/trunk/src/moul/server/__init__.py pymoul/trunk/src/moul/server/ping.py pymoul/trunk/src/moul/server/serverlist.py pymoul/trunk/src/moul/server/tests/ pymoul/trunk/src/moul/server/tests/__init__.py pymoul/trunk/src/moul/server/tests/test_ping.py pymoul/trunk/src/moul/server/tests/test_serverlist.py Added: pymoul/trunk/src/moul/server/__init__.py =================================================================== --- pymoul/trunk/src/moul/server/__init__.py (rev 0) +++ pymoul/trunk/src/moul/server/__init__.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,7 @@ +# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + Property changes on: pymoul/trunk/src/moul/server/__init__.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/server/ping.py =================================================================== --- pymoul/trunk/src/moul/server/ping.py (rev 0) +++ pymoul/trunk/src/moul/server/ping.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,135 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Server ping + +>>> server = Server(SERVER_LIST[0], PORT) +>>> result = server.dns() +>>> isinstance(result, float) +True +>>> result = server.portping() +>>> isinstance(result, float) +True + +>>> server = Server('bogus.nonworking.example.foo', PORT) +>>> result = server.dns() +>>> isinstance(result, socket.gaierror) +True + +>>> server = Server(name=SERVER_LIST[0], port=12345, timeout=1.0) +>>> result = server.portping() +>>> isinstance(result, socket.timeout) +True + +>>> serverlist = ServerList(names=SERVER_LIST, port=PORT, timeout=1.0) +>>> for name, stat in serverlist.dns(): +... print name, stat +>>> for name, stat in serverlist.portping(): +... print name, stat + +""" +import socket +from time import time + +from moul.server.serverlist import PORT +from moul.server.serverlist import SERVER_LIST + +def isError(stat): + return isinstance(stat, socket.error) + +class Server(object): + """A server object + """ + + def __init__(self, name, port, timeout=3.0): + self._name = name + self._port = int(port) + self._timeout = float(timeout) + # None: not yet resolved, False: failure, str: IP address + self._ip = None + self._stats = { + 'dns' : None, + 'portping' : None, + } + + def dns(self): + """Resolve IP address + """ + start = time() + try: + ip = socket.gethostbyname(self._name) + except socket.error, msg: + self._ip = False + self._stats['dns'] = msg + return msg + + period = time() - start + self._ip = ip + self._stats['dns'] = period + return period + + def portping(self): + """Connects to the game server port and terminates immediatly + """ + if self._ip is None: + self.dns() + if self._ip is False: + return + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(self._timeout) + start = time() + try: + try: + sock.connect((self._ip, self._port)) + sock.send('\n') + data = sock.recv(1024) + except socket.error, msg: + self._stats['portping'] = msg + return msg + finally: + sock.close() + + period = time() - start + self._stats['portping'] = period + return period + + def __str__(self): + return self._name + + @property + def name(self): + return self._name + +class ServerList(object): + """A list of servers to test + """ + def __init__(self, names, port, timeout=3.0): + self._names = names + self._port = int(port) + self._timeout = float(timeout) + self._servers = [] + for name in names: + self._servers.append(Server(name, port=port, timeout=timeout)) + + def dns(self): + for server in self._servers: + yield server.name, server.dns() + + def portping(self): + for server in self._servers: + yield server.name, server.portping() Property changes on: pymoul/trunk/src/moul/server/ping.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/server/serverlist.py =================================================================== --- pymoul/trunk/src/moul/server/serverlist.py (rev 0) +++ pymoul/trunk/src/moul/server/serverlist.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,53 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Server list +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +PORT = 14617 + +SERVER_LIST = [ + 'beta-auth.urulive.com', + 'beta-file.urulive.com', + 'uruapp-cw01.ibs.aol.com', + 'uruapp-cw02.ibs.aol.com', + 'uruapp-cw03.ibs.aol.com', + 'uruapp-cw04.ibs.aol.com', + 'uruapp-cw05.ibs.aol.com', + 'uruapp-cw06.ibs.aol.com', + 'uruapp-cw07.ibs.aol.com', + 'uruapp-cw08.ibs.aol.com', + 'uruapp-cw09.ibs.aol.com', + 'uruapp-cw10.ibs.aol.com', + 'uruapp-cw11.ibs.aol.com', + 'uruapp-cw12.ibs.aol.com', + 'uruapp-cw13.ibs.aol.com', + 'uruapp-cw14.ibs.aol.com', + 'uruapp-cw15.ibs.aol.com', + 'uruapp-cw16.ibs.aol.com', + 'uruapp-cw17.ibs.aol.com', + ## The servers below are available via ICMP ping but have no running game + ## server (2006-01-17) + #'uruapp-cw18.ibs.aol.com', + #'uruapp-cw19.ibs.aol.com', + #'uruapp-cw20.ibs.aol.com', + #'uruapp-cw21.ibs.aol.com', + #'uruapp-cw22.ibs.aol.com', +] Property changes on: pymoul/trunk/src/moul/server/serverlist.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/server/tests/__init__.py =================================================================== --- pymoul/trunk/src/moul/server/tests/__init__.py (rev 0) +++ pymoul/trunk/src/moul/server/tests/__init__.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,2 @@ +# testing package + Property changes on: pymoul/trunk/src/moul/server/tests/__init__.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/server/tests/test_ping.py =================================================================== --- pymoul/trunk/src/moul/server/tests/test_ping.py (rev 0) +++ pymoul/trunk/src/moul/server/tests/test_ping.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.server.serverlist unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.server.ping + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.server.ping'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/server/tests/test_ping.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/server/tests/test_serverlist.py =================================================================== --- pymoul/trunk/src/moul/server/tests/test_serverlist.py (rev 0) +++ pymoul/trunk/src/moul/server/tests/test_serverlist.py 2007-01-17 11:29:30 UTC (rev 40) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.server.serverlist unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.server.serverlist + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.server.serverlist'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/server/tests/test_serverlist.py ___________________________________________________________________ Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-17 13:37:56
|
Revision: 42 http://pymoul.svn.sourceforge.net/pymoul/?rev=42&view=rev Author: tiran Date: 2007-01-17 05:37:52 -0800 (Wed, 17 Jan 2007) Log Message: ----------- PING box works but I need to use a seperate thread or event loop. The main loops freezes when the ping method is invoked. Modified Paths: -------------- pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/server/ping.py pymoul/trunk/src/moul/server/tests/test_ping.py Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-17 12:52:49 UTC (rev 41) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-17 13:37:52 UTC (rev 42) @@ -33,6 +33,8 @@ from moul.qt.ui.mainwindow import Ui_MainWindow from moul.time.cavern import CavernTime from moul.file.wdysini import GraphicsIni +from moul.server.ping import ServerList +from moul.server.ping import isSocketError class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def __init__(self): @@ -42,6 +44,7 @@ self._timezone_init() self._graphics_init() + self._ping_init() # ************************************************************************ # graphics @@ -99,3 +102,41 @@ ct = self._caverntime() self.dt_cavern.setDateTime(ct['cavern']) self.dt_pacific.setDateTime(ct['pacific']) + + # ************************************************************************ + # ping + def _ping_init(self): + """init ping tab + """ + self.connect(self.button_ping, SIGNAL("clicked()"), self.on_button_ping_clicked) + + def _ping_servers(self): + # TODO: Use a seperate thread! + self.text_ping.clear() + insertText = self.text_ping.insertPlainText + + serverlist = ServerList() + # dns + for server in serverlist: + insertText("%s ... " % server.name) + result = server.dns() + if isSocketError(result): + insertText("DNS: FAILED\n") + continue + + insertText("dns: %0.3f " % result) + result = server.portping() + if isSocketError(result): + insertText("ping: FAILED\n") + continue + insertText("pin: %0.3f\n" % result) + + @pyqtSignature("") + def on_button_ping_clicked(self): + """SIGNAL: clicked() + """ + self.button_ping.setEnabled(False) + try: + self._ping_servers() + finally: + self.button_ping.setEnabled(True) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-17 12:52:49 UTC (rev 41) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-17 13:37:52 UTC (rev 42) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Wed Jan 17 13:36:40 2007 +# Created: Wed Jan 17 14:23:33 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -341,14 +341,18 @@ self.gb_servers.setGeometry(QtCore.QRect(10,0,421,341)) self.gb_servers.setObjectName("gb_servers") - self.but_ping = QtGui.QPushButton(self.gb_servers) - self.but_ping.setGeometry(QtCore.QRect(330,310,75,24)) - self.but_ping.setObjectName("but_ping") - self.text_ping = QtGui.QTextEdit(self.gb_servers) self.text_ping.setGeometry(QtCore.QRect(10,20,401,271)) self.text_ping.setReadOnly(True) self.text_ping.setObjectName("text_ping") + + self.button_ping = QtGui.QPushButton(self.gb_servers) + self.button_ping.setGeometry(QtCore.QRect(330,300,75,24)) + self.button_ping.setObjectName("button_ping") + + self.label_3 = QtGui.QLabel(self.gb_servers) + self.label_3.setGeometry(QtCore.QRect(170,300,151,16)) + self.label_3.setObjectName("label_3") self.tabWidget.addTab(self.tab,"") self.tab_4 = QtGui.QWidget() @@ -372,7 +376,7 @@ MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) - self.tabWidget.setCurrentIndex(2) + self.tabWidget.setCurrentIndex(3) QtCore.QObject.connect(self.buttonbox_rresavcl,QtCore.SIGNAL("rejected()"),MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -406,11 +410,12 @@ self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.gb_servers.setTitle(QtGui.QApplication.translate("MainWindow", "Ping servers", None, QtGui.QApplication.UnicodeUTF8)) - self.but_ping.setText(QtGui.QApplication.translate("MainWindow", "Ping", None, QtGui.QApplication.UnicodeUTF8)) self.text_ping.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + self.button_ping.setText(QtGui.QApplication.translate("MainWindow", "Ping", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setText(QtGui.QApplication.translate("MainWindow", "TODO: Use a seperate thread", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("MainWindow", "Servers", None, QtGui.QApplication.UnicodeUTF8)) self.label_6.setText(QtGui.QApplication.translate("MainWindow", "pyMoul tools", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-17 12:52:49 UTC (rev 41) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-17 13:37:52 UTC (rev 42) @@ -113,7 +113,7 @@ <enum>QTabWidget::North</enum> </property> <property name="currentIndex" > - <number>2</number> + <number>3</number> </property> <widget class="QWidget" name="tab_graphics" > <attribute name="title" > @@ -669,19 +669,6 @@ <property name="title" > <string>Ping servers</string> </property> - <widget class="QPushButton" name="but_ping" > - <property name="geometry" > - <rect> - <x>330</x> - <y>310</y> - <width>75</width> - <height>24</height> - </rect> - </property> - <property name="text" > - <string>Ping</string> - </property> - </widget> <widget class="QTextEdit" name="text_ping" > <property name="geometry" > <rect> @@ -701,6 +688,32 @@ <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> </property> </widget> + <widget class="QPushButton" name="button_ping" > + <property name="geometry" > + <rect> + <x>330</x> + <y>300</y> + <width>75</width> + <height>24</height> + </rect> + </property> + <property name="text" > + <string>Ping</string> + </property> + </widget> + <widget class="QLabel" name="label_3" > + <property name="geometry" > + <rect> + <x>170</x> + <y>300</y> + <width>151</width> + <height>16</height> + </rect> + </property> + <property name="text" > + <string>TODO: Use a seperate thread</string> + </property> + </widget> </widget> </widget> <widget class="QWidget" name="tab_4" > Modified: pymoul/trunk/src/moul/server/ping.py =================================================================== --- pymoul/trunk/src/moul/server/ping.py 2007-01-17 12:52:49 UTC (rev 41) +++ pymoul/trunk/src/moul/server/ping.py 2007-01-17 13:37:52 UTC (rev 42) @@ -24,7 +24,7 @@ from moul.server.serverlist import PORT from moul.server.serverlist import SERVER_LIST -def isError(stat): +def isSocketError(stat): return isinstance(stat, socket.error) class Server(object): @@ -94,7 +94,7 @@ class ServerList(object): """A list of servers to test """ - def __init__(self, names, port, timeout=3.0): + def __init__(self, names=SERVER_LIST, port=PORT, timeout=3.0): self._names = names self._port = int(port) self._timeout = float(timeout) Modified: pymoul/trunk/src/moul/server/tests/test_ping.py =================================================================== --- pymoul/trunk/src/moul/server/tests/test_ping.py 2007-01-17 12:52:49 UTC (rev 41) +++ pymoul/trunk/src/moul/server/tests/test_ping.py 2007-01-17 13:37:52 UTC (rev 42) @@ -26,7 +26,7 @@ from moul.server.ping import Server from moul.server.ping import ServerList -from moul.server.ping import isError +from moul.server.ping import isSocketError from moul.server.serverlist import SERVER_LIST from moul.server.serverlist import PORT @@ -42,7 +42,7 @@ def test_ping_bogus(self): server = Server('bogus.nonworking.example.foo', PORT) result = server.dns() - self.failUnless(isError(result)) + self.failUnless(isSocketError(result)) result = server.portping() self.failUnless(result is False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-02 17:45:44
|
Revision: 124 http://pymoul.svn.sourceforge.net/pymoul/?rev=124&view=rev Author: tiran Date: 2007-02-02 09:45:42 -0800 (Fri, 02 Feb 2007) Log Message: ----------- Fixed errors introduced by the run of importorder / importcheck Modified Paths: -------------- pymoul/trunk/src/moul/__init__.py pymoul/trunk/src/moul/file/localization.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/moulqt_rc.py pymoul/trunk/src/moul/qt/ui/simpleprogressbar.py pymoul/trunk/src/moul/time/cavern.py Modified: pymoul/trunk/src/moul/__init__.py =================================================================== --- pymoul/trunk/src/moul/__init__.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/__init__.py 2007-02-02 17:45:42 UTC (rev 124) @@ -3,8 +3,6 @@ try: __import__('pkg_resources').declare_namespace(__name__) except ImportError: - from pkgutil import extend_p - -ath + from pkgutil import extend_path __path__ = extend_path(__path__, __name__) Modified: pymoul/trunk/src/moul/file/localization.py =================================================================== --- pymoul/trunk/src/moul/file/localization.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/file/localization.py 2007-02-02 17:45:42 UTC (rev 124) @@ -17,9 +17,9 @@ # """LOC file parser """ +from __future__ import with_statement import glob import os -from __future__ import with_statement from xml.sax import ContentHandler from xml.sax import make_parser from xml.sax.handler import feature_namespaces Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-02 17:45:42 UTC (rev 124) @@ -18,13 +18,14 @@ """Moul QT GUI main windows """ +from __future__ import with_statement + import sys from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4.QtCore import Qt from PyQt4.QtCore import SIGNAL from PyQt4.QtCore import pyqtSignature -from __future__ import with_statement from moul import metadata from moul.config import lookupDir Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-02 17:45:42 UTC (rev 124) @@ -1,17 +1,15 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'src/moul/qt/ui/mainwindow.ui' +# Form implementation generated from reading ui file './src/moul/qt/ui/mainwindow.ui' # -# Created: Fri Feb 2 17:26:46 2007 +# Created: Fri Feb 2 18:43:30 2007 # by: PyQt4 UI code generator 4.1.1 # -# WARNING! All changes made in this file will be losimport sys -from PyQt4 import QtCore, Qt +# WARNING! All changes made in this file will be lost! -t! +import sys +from PyQt4 import QtCore, QtGui -Gui - class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") Modified: pymoul/trunk/src/moul/qt/ui/moulqt_rc.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/moulqt_rc.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/qt/ui/moulqt_rc.py 2007-02-02 17:45:42 UTC (rev 124) @@ -2,15 +2,13 @@ # Resource object code # -# Created: So Jan 28 18:10:39 2007 +# Created: Fr Feb 2 18:43:48 2007 # by: The Resource Compiler for PyQt (Qt v4.2.0) # -# WARNING! All changes made in this file will be losfrom PyQt4 import QtC +# WARNING! All changes made in this file will be lost! -t! +from PyQt4 import QtCore -ore - qt_resource_data = "\ \x00\x00\x07\xea\ \x89\ Modified: pymoul/trunk/src/moul/qt/ui/simpleprogressbar.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/simpleprogressbar.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/qt/ui/simpleprogressbar.py 2007-02-02 17:45:42 UTC (rev 124) @@ -1,17 +1,15 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'src/moul/qt/ui/simpleprogressbar.ui' +# Form implementation generated from reading ui file './src/moul/qt/ui/simpleprogressbar.ui' # -# Created: Fri Feb 2 15:36:30 2007 +# Created: Fri Feb 2 18:43:31 2007 # by: PyQt4 UI code generator 4.1.1 # -# WARNING! All changes made in this file will be losimport sys -from PyQt4 import QtCore, Qt +# WARNING! All changes made in this file will be lost! -t! +import sys +from PyQt4 import QtCore, QtGui -Gui - class Ui_SimpleProgressbar(object): def setupUi(self, SimpleProgressbar): SimpleProgressbar.setObjectName("SimpleProgressbar") Modified: pymoul/trunk/src/moul/time/cavern.py =================================================================== --- pymoul/trunk/src/moul/time/cavern.py 2007-02-02 17:37:43 UTC (rev 123) +++ pymoul/trunk/src/moul/time/cavern.py 2007-02-02 17:45:42 UTC (rev 124) @@ -24,20 +24,17 @@ __all__ = ['CavernTime'] from datetime import datetime -from pytz import all_timezones -from pytz import timezone -from pytz import utc as UTC from moul.osdependent import __FROZEN__ - # pytz is an egg if not __FROZEN__: import pkg_resources pkg_resources.require("pytz>=2006p") -#from pytz import common_timezones +from pytz import all_timezones +from pytz import timezone +from pytz import utc as UTC - ## not used in the current version #SUPPORTED_TZ = ('America', 'Canada', 'Etc', 'Europe', 'US') #ADDITIONAL_TZ = ('GMT', 'UTC') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-03 19:27:04
|
Revision: 130 http://pymoul.svn.sourceforge.net/pymoul/?rev=130&view=rev Author: tiran Date: 2007-02-03 11:26:53 -0800 (Sat, 03 Feb 2007) Log Message: ----------- Completely moved loc and wdysini gui code to seperate containers. Fixed signal loc decorator to forward pyqtSignature Modified Paths: -------------- pymoul/trunk/src/moul/log.py pymoul/trunk/src/moul/qt/localization.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/utils.py Added Paths: ----------- pymoul/trunk/src/moul/qt/wdysini.py Modified: pymoul/trunk/src/moul/log.py =================================================================== --- pymoul/trunk/src/moul/log.py 2007-02-03 18:41:23 UTC (rev 129) +++ pymoul/trunk/src/moul/log.py 2007-02-03 19:26:53 UTC (rev 130) @@ -146,6 +146,7 @@ __logger__.debug("%s(*%s, **%s)" % (func.__name__, repr(args[1:]), repr(kwargs))) return func(*args, **kwargs) + logwrapper._signature = getattr(func, '_signature', None) logwrapper.__name__ = func.__name__ logwrapper.__doc__ = func.__doc__ return logwrapper Modified: pymoul/trunk/src/moul/qt/localization.py =================================================================== --- pymoul/trunk/src/moul/qt/localization.py 2007-02-03 18:41:23 UTC (rev 129) +++ pymoul/trunk/src/moul/qt/localization.py 2007-02-03 19:26:53 UTC (rev 130) @@ -41,10 +41,6 @@ LOG = getLogger('moul.loc') -def insertDummyQ(lst): - dummy = type(lst)(["<choose>"]) - return QtCore.QStringList(dummy+lst) - class LocalizationContainer(QNamespaceContainer): """ Mixin for documentation tab @@ -64,6 +60,12 @@ self.connect(self.cb_doc_set, SIGNAL("currentIndexChanged(int)"), self.on_cb_doc_set_currentIndexChanged) + @staticmethod + def insertDummyQ(lst): + dummy = type(lst)(["<choose>"]) + return QtCore.QStringList(dummy+lst) + + @pyqtSignature("") @signalLogDecorator(LOG) def on_localization_doload(self): """ @@ -79,7 +81,7 @@ self.lb_doc_status.setText( self.trUtf8("Unable to load journals.")) return - + loc.findLocs() if not len(loc): self.lb_doc_status.setText( @@ -98,6 +100,7 @@ self.progressbar.increase) self.threadlet.detach(loc) + @pyqtSignature("") @signalLogDecorator(LOG) def on_localization_loaded(self): """ @@ -122,7 +125,7 @@ languages = sorted(tr.languages()) self._documents_state['languages'] = languages self.cb_doc_language.clear() - self.cb_doc_language.addItems(insertDummyQ(languages)) + self.cb_doc_language.addItems(self.insertDummyQ(languages)) self.cb_doc_language.setCurrentIndex(0) self.cb_doc_language.setEnabled(True) @@ -157,7 +160,7 @@ ages = sorted(tr._tree[lang].keys()) self._documents_state['curlanguage'] = lang self._documents_state['ages'] = ages - self.cb_doc_age.addItems(insertDummyQ(ages)) + self.cb_doc_age.addItems(self.insertDummyQ(ages)) self.cb_doc_age.setEnabled(True) @pyqtSignature("int") @@ -171,7 +174,7 @@ sets = sorted(tr._tree[lang][age].keys()) self._documents_state['curage'] = (lang, age) self._documents_state['sets'] = sets - self.cb_doc_set.addItems(insertDummyQ(sets)) + self.cb_doc_set.addItems(self.insertDummyQ(sets)) self.cb_doc_set.setEnabled(True) @pyqtSignature("int") @@ -185,7 +188,7 @@ elements = sorted(tr._tree[lang][age][set].keys()) self._documents_state['curset'] = (lang, age, set) self._documents_state['elements'] = elements - self.cb_doc_element.addItems(insertDummyQ(elements)) + self.cb_doc_element.addItems(self.insertDummyQ(elements)) self.cb_doc_element.setEnabled(True) @pyqtSignature("int") Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-03 18:41:23 UTC (rev 129) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-03 19:26:53 UTC (rev 130) @@ -44,11 +44,11 @@ from moul.time.cavern import CavernTime from moul.qt.localization import LocalizationContainer +from moul.qt.wdysini import IniFileContainer from moul.qt.simpleprogressbar import SimpleProgressbar from moul.qt.threadlet import YieldingThreadlet from moul.qt.ui.mainwindow import Ui_MainWindow - LOG = getLogger('moul.qt') class MainWindow(QtGui.QMainWindow, Ui_MainWindow): @@ -75,16 +75,12 @@ # init handlers self._timezone_init() - self._graphics_init() - self._audio_init() self._ping_init() self._systray_init() self._about_init() self.qcLocalization = LocalizationContainer(self) + self.qcIniFile = IniFileContainer(self) - # connect additional - QtCore.QMetaObject.connectSlotsByName(self) - # run checker self._moulrunning = None self._moulrunning_thread = MoulRunningThread() @@ -165,19 +161,7 @@ self.main_buttonbox_reset.setEnabled(True) # ************************************************************************ - # system tray - def _systray_init(self): - self.systemtray = QtGui.QSystemTrayIcon() - self.systemtray.setIcon(QtGui.QIcon(":/resources/uru_icon_32x32.png")) - self.systemtray.setVisible(True) - self.systemtray.setToolTip(QtCore.QString('pyMoul')) - - def _systray_close(self): - self.systemtray.setVisible(False) - - # ************************************************************************ # tasks - @pyqtSignature("") @signalLogDecorator(LOG) def on_pb_kiimage_repair_clicked(self): @@ -219,278 +203,23 @@ # TODO: msg # ************************************************************************ - # graphics settings - def _about_init(self): - self.te_license.setPlainText(metadata.LICENSE) + # system tray + def _systray_init(self): + self.systemtray = QtGui.QSystemTrayIcon() + self.systemtray.setIcon(QtGui.QIcon(":/resources/uru_icon_32x32.png")) + self.systemtray.setVisible(True) + self.systemtray.setToolTip(QtCore.QString('pyMoul')) - # ************************************************************************ - # graphics settings - def _graphics_init(self): - """ - init graphics tab - """ - self.connect(self, SIGNAL("graphicsini_loaded()"), self.on_graphicsini_loaded) - self.connect(self, SIGNAL("graphicsini_reset()"), self.on_graphicsini_reset) - self.connect(self, SIGNAL("graphicsini_save()"), self.on_graphicsini_save) - self.connect(self.main_buttonbox_reset, SIGNAL("clicked()"), self.on_graphicsini_reset) - self.connect(self.main_buttonbox_save, SIGNAL("clicked()"), self.on_graphicsini_save) - self.emit(SIGNAL("graphicsini_loaded()")) # XXX: hard coded emit + def _systray_close(self): + self.systemtray.setVisible(False) - @signalLogDecorator(LOG) - def on_graphicsini_loaded(self): - """ - @qtslot graphicsini_loaded(): notify when a graphics.ini is loaded - """ - gini = self.urupersonaldir.graphicsini - try: - gini.read() - except Exception, msg: - LOG.exception("Something bad happened while parsing the graphics.ini file") - QtGui.QMessageBox.critical(None, - self.trUtf8("Error opening graphics.ini"), - self.trUtf8("""Something bad happend while opening the graphics.ini\n%s""" % msg)) - return - self._graphicsini_setstate() - - @signalLogDecorator(LOG) - def on_graphicsini_reset(self): - """ - SIGNAL graphicsini_reset() - """ - self.urupersonaldir.graphicsini.reset() - self._graphicsini_setstate() - - @signalLogDecorator(LOG) - def on_graphicsini_save(self): - """ - SIGNAL graphicsini_save() - """ - #self._notimplemented() - self.urupersonaldir.graphicsini.write() - self.setDirty(False) - - def _graphicsini_setstate(self): - """ - Set sliders according to graphics ini settings - """ - gini = self.urupersonaldir.graphicsini - length = len(videoModes) - 1 - self.sl_gra_screenres.setMaximum(length) - - self.sl_gra_screenres.setValue(gini.screenres) - self.sl_gra_quality.setValue(gini.quality) - self.sl_gra_texture.setValue(gini.texture) - self.sl_gra_antialias.setValue(gini.antialias) - self.sl_gra_anisotropic.setValue(gini.anisotropic) - self.sl_gra_shadow.setValue(gini.shadow) - self.cb_gra_windowed.setChecked(gini.windowed) - self.cb_gra_vsync.setChecked(gini.vsync) - self.cb_gra_shadow.setChecked(gini.shadow_enabled) - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_screenres_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - # XXX: fixme - txt = videoModes.getVidModeHuman(idx) - self.lb_screenres.setText(QtCore.QString(txt)) - self.urupersonaldir.graphicsini.screenres = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_screenres_sliderMoved(self, idx): - """ - SIGNAL: sliderMoved(int) - """ - txt = videoModes.getVidModeHuman(idx) - self.lb_screenres.setText(QtCore.QString(txt)) - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_quality_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - self.urupersonaldir.graphicsini.quality = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_texture_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - self.urupersonaldir.graphicsini.texture = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_antialias_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - self.urupersonaldir.graphicsini.antialias = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_anisotropic_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - self.urupersonaldir.graphicsini.anisotropic = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_gra_shadow_valueChanged(self, idx): - """ - SIGNAL: valueChanged (int) - """ - self.urupersonaldir.graphicsini.shadow = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_gra_windowed_stateChanged(self, state): - """ - SIGNAL: stateChanged(int) - """ - self.urupersonaldir.graphicsini.windowed = state - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_gra_vsync_stateChanged (self, state): - """ - SIGNAL: stateChanged(int) - """ - self.urupersonaldir.graphicsini.vsync = state - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_gra_shadow_stateChanged (self, state): - """ - SIGNAL: stateChanged(int) - """ - self.urupersonaldir.graphicsini.shadow_enabled = state - # ************************************************************************ - # audio settings + # about tab + def _about_init(self): + self.te_license.setPlainText(metadata.LICENSE) - def _audio_init(self): - """ - init graphics tab - """ - self.connect(self, SIGNAL("audioini_loaded()"), self.on_audioini_loaded) - self.connect(self, SIGNAL("audiini_reset()"), self.on_audioini_reset) - self.connect(self, SIGNAL("audiini_save()"), self.on_audioini_save) - self.connect(self.main_buttonbox_reset, SIGNAL("clicked()"), self.on_audioini_reset) - self.connect(self.main_buttonbox_save, SIGNAL("clicked()"), self.on_audioini_save) - self.emit(SIGNAL("audioini_loaded()")) # XXX: hard coded emit - - @signalLogDecorator(LOG) - def on_audioini_loaded(self): - """ - SIGNAL: audioini_loaded() - """ - aini = self.urupersonaldir.audioini - try: - aini.read() - except Exception, msg: - LOG.exception("Something bad happened while parsing the audio.ini file") - QtGui.QMessageBox.critical(None, - self.trUtf8("Error opening audio.ini"), - self.trUtf8("""Something bad happend while opening the audio.ini\n%s""" % msg)) - return - self._audioini_setstate() - - @signalLogDecorator(LOG) - def on_audioini_reset(self): - """ - SIGNAL audioini_reset() - """ - self.urupersonaldir.audioini.reset() - self._audioini_setstate() - - @signalLogDecorator(LOG) - def on_audioini_save(self): - """ - SIGNAL audioini_save() - """ - #self._notimplemented() - self.urupersonaldir.audioini.write() - self.setDirty(False) # urks - - def _audioini_setstate(self): - """ - Set sliders according to audio ini settings - """ - aini = self.urupersonaldir.audioini - self.sl_aud_device.setMaximum(aini.numberOfDevices()-1) - - self.sl_aud_npc.setValue(aini.npc) - self.sl_aud_music.setValue(aini.music) - self.sl_aud_fx.setValue(aini.fx) - self.sl_aud_ambience.setValue(aini.ambience) - self.sl_aud_priority.setValue(aini.priority) - self.sl_aud_device.setValue(aini.device) - self.cb_aud_eax.setChecked(aini.eax) - self.cb_aud_mute.setChecked(aini.mute) - self.cb_aud_voicechat.setChecked(aini.enablevoice) - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_device_valueChanged(self, idx): - self.urupersonaldir.audioini.device = idx - txt = self.urupersonaldir.audioini.getDeviceName(idx) - self.lb_aud_device.setText(QtCore.QString(txt[1:-1])) - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_device_sliderMoved(self, idx): - txt = self.urupersonaldir.audioini.getDeviceName(idx) - self.lb_aud_device.setText(QtCore.QString(txt[1:-1])) - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_npc_valueChanged(self, idx): - self.urupersonaldir.audioini.npc = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_music_valueChanged(self, idx): - self.urupersonaldir.audioini.music = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_fx_valueChanged(self, idx): - self.urupersonaldir.audioini.fx = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_ambience_valueChanged(self, idx): - self.urupersonaldir.audioini.ambience = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_sl_aud_priority_valueChanged(self, idx): - self.urupersonaldir.audioini.priority = idx - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_aud_eax_stateChanged (self, state): - self.urupersonaldir.audioini.eax = state - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_aud_mute_stateChanged (self, state): - self.urupersonaldir.audioini.mute = state - - @signalLogDecorator(LOG) - @pyqtSignature("int") - def on_cb_aud_voicechat_stateChanged (self, state): - self.urupersonaldir.audioini.voicechat = state - # ************************************************************************ # time zones - def _timezone_init(self): """ Init time zone tab""" Modified: pymoul/trunk/src/moul/qt/utils.py =================================================================== --- pymoul/trunk/src/moul/qt/utils.py 2007-02-03 18:41:23 UTC (rev 129) +++ pymoul/trunk/src/moul/qt/utils.py 2007-02-03 19:26:53 UTC (rev 130) @@ -25,6 +25,7 @@ __version__ = "$Id" __revision__ = "$Revision$" +import logging import re import warnings from PyQt4.QtCore import QObject @@ -32,10 +33,6 @@ from PyQt4 import QtGui from types import UnboundMethodType as UnboundMethod -from moul.log import getLogger - - -LOG = getLogger('moul.qt.utils') _marker=object() SLOT_RE = re.compile('^on_(.+)_([^_]+)$') @@ -95,8 +92,8 @@ Shortcut for self.parent().connect(*args) """ if args[0] is self: - warnings.warn("You used self as first argument but should use " - "self.context!", SyntaxWarning, stacklevel=2) + warnings.warn("You are using self as first argument but should " + "use self.context!", SyntaxWarning, stacklevel=2) self.parent().connect(*args) def disconnect(self, *args): @@ -104,8 +101,8 @@ Shortcut for self.parent().disconnect(*args) """ if args[0] is self: - warnings.warn("You used self as first argument but should use " - "self.context!", SyntaxWarning, stacklevel=2) + warnings.warn("You used self as first argument but should " + "use self.context!", SyntaxWarning, stacklevel=2) self.parent().disconnect(*args) def emit(self, *args): @@ -178,7 +175,13 @@ continue # Support the QtCore.pyqtSignature decorator. - signature = '%s(%s)' % (nsignal, getattr(method, '_signature', '')) + qtsig = getattr(method, '_signature', _marker) + if qtsig is _marker: + warnings.warn("No signature found for %s.%s. use @pyqtSignature()!" + % (callobj.__class__.__name__, method.__name__), + stacklevel=3) + qtsig = '' + signature = '%s(%s)' % (nsignal, qtsig) #logging.debug('Connecting: %s to %s: %s' % (widget, signature, method)) QObject.connect(widget, SIGNAL(signature), method) Copied: pymoul/trunk/src/moul/qt/wdysini.py (from rev 129, pymoul/trunk/src/moul/qt/mainwindow.py) =================================================================== --- pymoul/trunk/src/moul/qt/wdysini.py (rev 0) +++ pymoul/trunk/src/moul/qt/wdysini.py 2007-02-03 19:26:53 UTC (rev 130) @@ -0,0 +1,303 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +"""Moul QT GUI main windows +""" +from __future__ import with_statement + +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import sys +from PyQt4 import QtCore +from PyQt4 import QtGui +from PyQt4.QtCore import Qt +from PyQt4.QtCore import SIGNAL +from PyQt4.QtCore import pyqtSignature + +from moul import metadata +from moul.config import lookupDir +from moul.file.directory import UruGameDataDirectory +from moul.file.directory import UruPersonalDataDirectory +from moul.file.wdysini import videoModes +from moul.log import getLogger +from moul.log import signalLogDecorator +from moul.qt.utils import QNamespaceContainer + +LOG = getLogger('moul.qt') + +class IniFileContainer(QNamespaceContainer): + def initialize(self): + # graphics.ini + self.connect(self.context, SIGNAL("graphicsini_loaded()"), self.on_graphicsini_loaded) + self.connect(self.context, SIGNAL("graphicsini_reset()"), self.on_graphicsini_reset) + self.connect(self.context, SIGNAL("graphicsini_save()"), self.on_graphicsini_save) + self.connect(self.main_buttonbox_reset, SIGNAL("clicked()"), self.on_graphicsini_reset) + self.connect(self.main_buttonbox_save, SIGNAL("clicked()"), self.on_graphicsini_save) + self.context.emit(SIGNAL("graphicsini_loaded()")) # XXX: hard coded emit + # audio.ini + self.connect(self.context, SIGNAL("audioini_loaded()"), self.on_audioini_loaded) + self.connect(self.context, SIGNAL("audiini_reset()"), self.on_audioini_reset) + self.connect(self.context, SIGNAL("audiini_save()"), self.on_audioini_save) + self.connect(self.main_buttonbox_reset, SIGNAL("clicked()"), self.on_audioini_reset) + self.connect(self.main_buttonbox_save, SIGNAL("clicked()"), self.on_audioini_save) + self.context.emit(SIGNAL("audioini_loaded()")) # XXX: hard coded emit + + @signalLogDecorator(LOG) + @pyqtSignature("") + def on_graphicsini_loaded(self): + """ + @qtslot graphicsini_loaded(): notify when a graphics.ini is loaded + """ + gini = self.urupersonaldir.graphicsini + try: + gini.read() + except Exception, msg: + LOG.exception("Something bad happened while parsing the graphics.ini file") + QtGui.QMessageBox.critical(None, + self.trUtf8("Error opening graphics.ini"), + self.trUtf8("""Something bad happend while opening the graphics.ini\n%s""" % msg)) + return + self._graphicsini_setstate() + + @signalLogDecorator(LOG) + @pyqtSignature("") + def on_graphicsini_reset(self): + """ + SIGNAL graphicsini_reset() + """ + self.urupersonaldir.graphicsini.reset() + self._graphicsini_setstate() + + @signalLogDecorator(LOG) + @pyqtSignature("") + def on_graphicsini_save(self): + """ + SIGNAL graphicsini_save() + """ + #self._notimplemented() + self.urupersonaldir.graphicsini.write() + self.setDirty(False) + + def _graphicsini_setstate(self): + """ + Set sliders according to graphics ini settings + """ + gini = self.urupersonaldir.graphicsini + length = len(videoModes) - 1 + txt = videoModes.getVidModeHuman(gini.screenres) + + self.sl_gra_screenres.setMaximum(length) + self.sl_gra_screenres.setValue(gini.screenres) + self.lb_screenres.setText(QtCore.QString(txt)) + self.sl_gra_quality.setValue(gini.quality) + self.sl_gra_texture.setValue(gini.texture) + self.sl_gra_antialias.setValue(gini.antialias) + self.sl_gra_anisotropic.setValue(gini.anisotropic) + self.sl_gra_shadow.setValue(gini.shadow) + self.cb_gra_windowed.setChecked(gini.windowed) + self.cb_gra_vsync.setChecked(gini.vsync) + self.cb_gra_shadow.setChecked(gini.shadow_enabled) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_screenres_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.screenres = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_screenres_sliderMoved(self, idx): + """ + SIGNAL: sliderMoved(int) + """ + txt = videoModes.getVidModeHuman(idx) + self.lb_screenres.setText(QtCore.QString(txt)) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_quality_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.quality = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_texture_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.texture = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_antialias_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.antialias = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_anisotropic_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.anisotropic = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_gra_shadow_valueChanged(self, idx): + """ + SIGNAL: valueChanged (int) + """ + self.urupersonaldir.graphicsini.shadow = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_gra_windowed_stateChanged(self, state): + """ + SIGNAL: stateChanged(int) + """ + self.urupersonaldir.graphicsini.windowed = state + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_gra_vsync_stateChanged (self, state): + """ + SIGNAL: stateChanged(int) + """ + self.urupersonaldir.graphicsini.vsync = state + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_gra_shadow_stateChanged (self, state): + """ + SIGNAL: stateChanged(int) + """ + self.urupersonaldir.graphicsini.shadow_enabled = state + + # ************************************************************************ + # audio settings + + @signalLogDecorator(LOG) + def on_audioini_loaded(self): + """ + SIGNAL: audioini_loaded() + """ + aini = self.urupersonaldir.audioini + try: + aini.read() + except Exception, msg: + LOG.exception("Something bad happened while parsing the audio.ini file") + QtGui.QMessageBox.critical(None, + self.trUtf8("Error opening audio.ini"), + self.trUtf8("""Something bad happend while opening the audio.ini\n%s""" % msg)) + return + self._audioini_setstate() + + @signalLogDecorator(LOG) + def on_audioini_reset(self): + """ + SIGNAL audioini_reset() + """ + self.urupersonaldir.audioini.reset() + self._audioini_setstate() + + @signalLogDecorator(LOG) + def on_audioini_save(self): + """ + SIGNAL audioini_save() + """ + #self._notimplemented() + self.urupersonaldir.audioini.write() + self.setDirty(False) # urks + + def _audioini_setstate(self): + """ + Set sliders according to audio ini settings + """ + aini = self.urupersonaldir.audioini + txt = self.urupersonaldir.audioini.getDeviceName(aini.device) + + self.sl_aud_device.setMaximum(aini.numberOfDevices()-1) + self.sl_aud_npc.setValue(aini.npc) + self.sl_aud_music.setValue(aini.music) + self.sl_aud_fx.setValue(aini.fx) + self.sl_aud_ambience.setValue(aini.ambience) + self.sl_aud_priority.setValue(aini.priority) + self.sl_aud_device.setValue(aini.device) + self.lb_aud_device.setText(QtCore.QString(txt[1:-1])) + self.cb_aud_eax.setChecked(aini.eax) + self.cb_aud_mute.setChecked(aini.mute) + self.cb_aud_voicechat.setChecked(aini.enablevoice) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_device_valueChanged(self, idx): + self.urupersonaldir.audioini.device = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_device_sliderMoved(self, idx): + txt = self.urupersonaldir.audioini.getDeviceName(idx) + self.lb_aud_device.setText(QtCore.QString(txt[1:-1])) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_npc_valueChanged(self, idx): + self.urupersonaldir.audioini.npc = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_music_valueChanged(self, idx): + self.urupersonaldir.audioini.music = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_fx_valueChanged(self, idx): + self.urupersonaldir.audioini.fx = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_ambience_valueChanged(self, idx): + self.urupersonaldir.audioini.ambience = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_priority_valueChanged(self, idx): + self.urupersonaldir.audioini.priority = idx + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_aud_eax_stateChanged (self, state): + self.urupersonaldir.audioini.eax = state + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_aud_mute_stateChanged (self, state): + self.urupersonaldir.audioini.mute = state + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_cb_aud_voicechat_stateChanged (self, state): + self.urupersonaldir.audioini.voicechat = state This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-07 15:01:57
|
Revision: 155 http://pymoul.svn.sourceforge.net/pymoul/?rev=155&view=rev Author: tiran Date: 2007-02-07 07:01:15 -0800 (Wed, 07 Feb 2007) Log Message: ----------- Fix for Windows socket error issue Modified Paths: -------------- pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/server/ping.py Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-07 13:28:12 UTC (rev 154) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-07 15:01:15 UTC (rev 155) @@ -40,6 +40,7 @@ from moul.osdependent import isMoulRunning from moul.server.ping import ServerList from moul.server.ping import isSocketError +from moul.server.ping import fmtSocketError from moul.time.cavern import CavernTime from moul.qt.localization import LocalizationContainer @@ -498,15 +499,17 @@ name = server.name dns = server.dns() if isSocketError(dns): + errno, msg = fmtSocketError(dns) self.emit(SIGNAL("dnserror(const QString&, int, const QString&)"), - name, dns.args[0], dns.args[1]) + name, errno, msg) continue self.emit(SIGNAL("dns(const QString&, float)"), name, dns) ping = server.portping() if isSocketError(ping): + errno, msg = fmtSocketError(dns) self.emit(SIGNAL("pingerror(const QString&, int, const QString&)"), - name, ping.args[0], ping.args[1]) + name, errno, msg) continue self.emit(SIGNAL("ping(const QString&, float)"), name, ping) Modified: pymoul/trunk/src/moul/server/ping.py =================================================================== --- pymoul/trunk/src/moul/server/ping.py 2007-02-07 13:28:12 UTC (rev 154) +++ pymoul/trunk/src/moul/server/ping.py 2007-02-07 15:01:15 UTC (rev 155) @@ -28,6 +28,29 @@ def isSocketError(stat): return isinstance(stat, socket.error) +def fmtSocketError(exc): + """Formats the output of a socket error + + @param exc: a socket exception + @type. exc: socket.error instance + @return: errno, msg + @rtype: tuple (int, str) + """ + errno, msg = -1, '' + if isinstance(exc, socket.timeout): + msg = str(exc) + elif isinstance(exc, socket.gaierror): + # address-related errors + errno, msg = exc[0], exc[1] + elif isinstance(exc, socket.herror): + # address-related errors using h_errno + errno, msg = exc[0], exc[1] + elif isinstance(exc, socket.error): + errno, msg = exc[0], exc[1] + else: + msg = str(exc) + return errno, msg + class Server(object): """A server object """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-17 21:49:31
|
Revision: 176 http://pymoul.svn.sourceforge.net/pymoul/?rev=176&view=rev Author: tiran Date: 2007-02-17 13:49:15 -0800 (Sat, 17 Feb 2007) Log Message: ----------- Some optimizations and fine tunings on the D'ni clock Modified Paths: -------------- pymoul/trunk/src/moul/qt/dninumbers.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/time/dni.py Modified: pymoul/trunk/src/moul/qt/dninumbers.py =================================================================== --- pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-17 18:10:20 UTC (rev 175) +++ pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-17 21:49:15 UTC (rev 176) @@ -33,6 +33,7 @@ from moul.time.cavern import CavernTime from moul.time.dni import DniTime from moul.time.dni import FACTOR_SP +from moul.time.dni import decimal2dni from moul.log import getLogger from moul.qt.utils import QNamespaceContainer from moul.qt.utils import QSignalLoggerMetaclass @@ -52,17 +53,16 @@ def initialize(self): # D'ni numbers self.dninumbers = QDniNumbers() + self.dnitime = DniTime() self.setup_dniclock() self.setup_dninumbers() - # D'ni date and time - self.dnitime = DniTime() - self.on_dnitimer_timeout() self.dnitime_timer = QtCore.QTimer(self.context) self.dnitime_timer.setInterval(FACTOR_SP*1000) self.connect(self.dnitime_timer, SIGNAL('timeout()'), self.on_dnitimer_timeout) self.dnitime_timer.start() + self.on_dnitimer_timeout(True) # time zone self.caverntime = CavernTime() @@ -104,13 +104,14 @@ @pyqtSignature("") @skipLogging - def on_dnitimer_timeout(self): + def on_dnitimer_timeout(self, initialize=False): """ SIGNAL: QTimer timeout """ - dni = self.dnitime.fromUTC() # set to now + self.dnitime.fromUTC() # set to now self.context.le_dnitime.setText(str(self.dnitime)+", bell: %s" % self.dnitime.pahrtovo) + self.setClockByDnidate(self.dnitime, initialize) def setup_dniclock(self): height = 15 @@ -140,18 +141,35 @@ self.yahrl.setPos(widthyahr, height+space) self.yahrr = QDniNumberRing(dniclock, 0, 24, height, 'right') self.yahrr.setPos(widthyahr+widthl, height+space) - - for i, ring in enumerate((self.hahrl, self.hahrm, self.hahrr, self.vailee, - self.yahrl, self.yahrr)): - ring.setNumber(i) - for i, name in enumerate(('gahrtahvo', 'tahvo', 'gorahn', 'prorahn')): ring = QDniNumberRing(dniclock, 0, 24, height, cyclic=True) setattr(self, name, ring) ring.setPos((width+space)*i+width/2, 0) - ring.setNumber(i) + #ring.setNumber(i) + #for i, ring in enumerate((self.hahrl, self.hahrm, self.hahrr, self.vailee, + #self.yahrl, self.yahrr)): + #ring.setNumber(i) + def setClockByDnidate(self, dnitime, initialize=False): + if dnitime.prorahn == self.prorahn.get() and not initialize: + return + hahr = decimal2dni(dnitime.hahr, digits=3) + self.hahrl.setNumber(hahr[0]) + self.hahrm.setNumber(hahr[1]) + self.hahrr.setNumber(hahr[2]) + + self.vailee.setNumber(dnitime.vailee) + + yahr = decimal2dni(dnitime.yahr, digits=2) + self.yahrl.setNumber(yahr[0]) + self.yahrr.setNumber(yahr[1]) + + self.gahrtahvo.setNumber(dnitime.gahrtahvo) + self.tahvo.setNumber(dnitime.tahvo) + self.gorahn.setNumber(dnitime.gorahn) + self.prorahn.setNumber(dnitime.prorahn) + def setup_dninumbers(self): # may change! widget = self.context.gridLayout_3 @@ -360,18 +378,7 @@ def setByDecimal(self, number, digits=1): """Set numbers by decial value with minimum digits """ - numbers = [] - pos = 0 - while True: - div = 25**pos - cur = (number / div) % 25 - number -= cur * div - pos+=1 - numbers.insert(0, cur) - if not number: - break - while len(numbers) < digits: - numbers.insert(0, 0) + numbers = decimal2dni(number, digits) return self.setNumbers(*numbers) def setNumbers(self, *args): @@ -458,11 +465,11 @@ >>> example = QDniNumberRing(scene, start=1, stop=25) >>> example.setPosition(24) - <Pixmap Graphics Item 24> + 24 >>> example.next() - <Pixmap Graphics Item 25> + 25 >>> example.next() - <Pixmap Graphics Item 25> + 1 """ __slots__ = ('_elements', '_first', '_last', '_pos') @@ -484,6 +491,9 @@ def __getitem__(self, pos): return self._elements[pos - self._first] + def get(self): + return self._pos + def next(self): """Get next item @@ -497,7 +507,7 @@ self._pos = pos element = self[pos] element.show() - return element + return pos def setNumber(self, nr): """Set current number to nr @@ -509,7 +519,7 @@ element = self[nr] element.show() self._pos = nr - return element + return nr def setPos(self, xpos, y=None): """Set position of element Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-17 18:10:20 UTC (rev 175) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-17 21:49:15 UTC (rev 176) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file './src/moul/qt/ui/mainwindow.ui' # -# Created: Sat Feb 17 18:51:48 2007 +# Created: Sat Feb 17 22:12:04 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -142,11 +142,11 @@ self.hboxlayout1.addItem(spacerItem3) self.gb_caverntime = QtGui.QGroupBox(self.tab_tasks) - self.gb_caverntime.setGeometry(QtCore.QRect(10,180,451,101)) + self.gb_caverntime.setGeometry(QtCore.QRect(10,180,451,91)) self.gb_caverntime.setObjectName("gb_caverntime") self.gridLayout = QtGui.QWidget(self.gb_caverntime) - self.gridLayout.setGeometry(QtCore.QRect(10,20,431,74)) + self.gridLayout.setGeometry(QtCore.QRect(10,20,431,61)) self.gridLayout.setObjectName("gridLayout") self.gridlayout1 = QtGui.QGridLayout(self.gridLayout) @@ -203,20 +203,20 @@ self.gridlayout1.addItem(spacerItem4,0,3,1,1) self.gb_dnitime = QtGui.QGroupBox(self.tab_tasks) - self.gb_dnitime.setGeometry(QtCore.QRect(10,280,451,121)) + self.gb_dnitime.setGeometry(QtCore.QRect(10,270,451,131)) self.gb_dnitime.setObjectName("gb_dnitime") + self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) + self.gv_dniclock.setGeometry(QtCore.QRect(10,20,150,55)) + self.gv_dniclock.setAcceptDrops(False) + self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) + self.gv_dniclock.setObjectName("gv_dniclock") + self.le_dnitime = QtGui.QLineEdit(self.gb_dnitime) - self.le_dnitime.setGeometry(QtCore.QRect(200,20,241,25)) + self.le_dnitime.setGeometry(QtCore.QRect(10,90,271,25)) self.le_dnitime.setEchoMode(QtGui.QLineEdit.Normal) self.le_dnitime.setReadOnly(True) self.le_dnitime.setObjectName("le_dnitime") - - self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) - self.gv_dniclock.setGeometry(QtCore.QRect(10,20,181,94)) - self.gv_dniclock.setAcceptDrops(False) - self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) - self.gv_dniclock.setObjectName("gv_dniclock") self.tabwidget.addTab(self.tab_tasks,"") self.tab_settings = QtGui.QWidget() Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-17 18:10:20 UTC (rev 175) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-17 21:49:15 UTC (rev 176) @@ -349,7 +349,7 @@ <x>10</x> <y>180</y> <width>451</width> - <height>101</height> + <height>91</height> </rect> </property> <property name="title" > @@ -361,7 +361,7 @@ <x>10</x> <y>20</y> <width>431</width> - <height>74</height> + <height>61</height> </rect> </property> <layout class="QGridLayout" > @@ -470,44 +470,44 @@ <property name="geometry" > <rect> <x>10</x> - <y>280</y> + <y>270</y> <width>451</width> - <height>121</height> + <height>131</height> </rect> </property> <property name="title" > <string>D'ni time</string> </property> - <widget class="QLineEdit" name="le_dnitime" > + <widget class="QGraphicsView" name="gv_dniclock" > <property name="geometry" > <rect> - <x>200</x> + <x>10</x> <y>20</y> - <width>241</width> - <height>25</height> + <width>150</width> + <height>55</height> </rect> </property> - <property name="echoMode" > - <enum>QLineEdit::Normal</enum> + <property name="acceptDrops" > + <bool>false</bool> </property> - <property name="readOnly" > - <bool>true</bool> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> </property> </widget> - <widget class="QGraphicsView" name="gv_dniclock" > + <widget class="QLineEdit" name="le_dnitime" > <property name="geometry" > <rect> <x>10</x> - <y>20</y> - <width>181</width> - <height>94</height> + <y>90</y> + <width>271</width> + <height>25</height> </rect> </property> - <property name="acceptDrops" > - <bool>false</bool> + <property name="echoMode" > + <enum>QLineEdit::Normal</enum> </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> + <property name="readOnly" > + <bool>true</bool> </property> </widget> </widget> Modified: pymoul/trunk/src/moul/time/dni.py =================================================================== --- pymoul/trunk/src/moul/time/dni.py 2007-02-17 18:10:20 UTC (rev 175) +++ pymoul/trunk/src/moul/time/dni.py 2007-02-17 21:49:15 UTC (rev 176) @@ -151,6 +151,23 @@ return checker return wrapper +def decimal2dni(number, digits=1): + """Convert decimal number to dni number + """ + numbers = [] + pos = 0 + while True: + div = 25**pos + cur = (number / div) % 25 + number -= cur * div + pos+=1 + numbers.insert(0, cur) + if not number: + break + while len(numbers) < digits: + numbers.insert(0, 0) + return numbers + class DniTime(object): """D'ni time representation This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-22 14:14:31
|
Revision: 181 http://pymoul.svn.sourceforge.net/pymoul/?rev=181&view=rev Author: tiran Date: 2007-02-22 06:14:24 -0800 (Thu, 22 Feb 2007) Log Message: ----------- Time fixes (round microseconds) Moved Threadlets to utils Modified Paths: -------------- pymoul/trunk/src/moul/qt/dninumbers.py pymoul/trunk/src/moul/qt/localization.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/qt/utils.py pymoul/trunk/src/moul/time/dni.py pymoul/trunk/src/moul/time/utils.py Removed Paths: ------------- pymoul/trunk/src/moul/qt/threadlet.py Modified: pymoul/trunk/src/moul/qt/dninumbers.py =================================================================== --- pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-22 14:14:24 UTC (rev 181) @@ -22,9 +22,10 @@ __version__ = "$Id$" __revision__ = "$Revision$" +import math import operator -import math import sys +import time from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4.QtCore import Qt @@ -35,10 +36,15 @@ from moul.time.dni import DniTime from moul.time.dni import FACTOR_SP from moul.time.dni import decimal2dni +from moul.time.dni import VAILEETEE +from moul.time.dni import DNI_HOLIDAYS +from moul.time.utils import ts2utc +from moul.time.utils import utcnow from moul.log import getLogger from moul.qt.utils import QNamespaceContainer from moul.qt.utils import QSignalLoggerMetaclass from moul.qt.utils import skipLogging +from moul.qt.utils import QTimerThreadlet NUMBER_HEIGHT = 25 @@ -62,8 +68,9 @@ self.clockscene = QDniClockScene(view.parent()) view.setScene(self.clockscene) view.show() - self.dnitime_timer = QtCore.QTimer(self.context) - self.dnitime_timer.setInterval(FACTOR_SP*1000+60) # XXX: smooth + self.dnitime_timer = QTimerThreadlet(None) + self.dnitime_timer.setInterval(FACTOR_SP*1000.0/1.0) # XXX: smooth + #fself.dnitime_timer.setCallable(self.clockscene.timeEvent) # time zone # TODO: change timer from every second to once a minute? @@ -75,6 +82,13 @@ off = ct['pacific']['utcoffset'] self.lb_pacific_utc.setText("UTC %s%i" % (off[0], abs(off[1]))) + # chooser + self.dte_earthtime.setDateTime(QtCore.QDateTime(utcnow())) + for i, name in enumerate(VAILEETEE): + self.cb_vailee.addItem("%2i %s" % (i+1, name)) + for name, date in DNI_HOLIDAYS: + self.cb_dniholidays.addItem(self.trUtf8(name)) + self.connect(self.timezone_timer, SIGNAL('timeout()'), self.on_timezone_timer_timeout) self.connect(self.dnitime_timer, SIGNAL('timeout()'), @@ -82,7 +96,7 @@ self.connect(self.context, SIGNAL("timerEnable(bool)"), self.on_timer_timerEnable) # TODO: needs optimization? run only when timer tab is active - self.emit(SIGNAL("timerEnable(bool)"), True) + #self.emit(SIGNAL("timerEnable(bool)"), True) @pyqtSignature("bool") def on_timer_timerEnable(self, value=True): @@ -106,6 +120,42 @@ self.dt_cavern.setDateTime(ct['cavern']) self.dt_pacific.setDateTime(ct['pacific']) + @pyqtSignature("bool") + def on_rb_curtime_clicked(self, value): + if value: + self.emit(SIGNAL("timerEnable(bool)"), True) + + @pyqtSignature("bool") + def on_rb_earthtime_clicked(self, value): + if value: + self.emit(SIGNAL("timerEnable(bool)"), False) + + @pyqtSignature("bool") + def on_rb_dnitime_clicked(self, value): + if value: + self.emit(SIGNAL("timerEnable(bool)"), False) + + @pyqtSignature("bool") + def on_rb_dniholiday_clicked(self, value): + if value: + self.emit(SIGNAL("timerEnable(bool)"), False) + + @pyqtSignature("") + def on_pb_time_update_clicked(self): + if self.rb_curtime.isChecked(): + pass + elif self.rb_earthtime.isChecked(): + qdt = self.dte_earthtime.dateTime() + utc_dt = ts2utc(qdt.toTime_t()) + self.clockscene.setClockFromUTC(utc_dt) + elif self.rb_dnitime.isChecked(): + pass + elif self.rb_dniholiday.isChecked(): + pass + else: + LOG.warning("Unknown state of time chooser") + + def setup_dninumbers(self): # may change! widget = self.context.gridLayout_3 @@ -434,7 +484,7 @@ # initialize view self.timeEvent(initialize=True) - def setClockByDnidate(self, dnitime, initialize=False): + def setClockFromDnidate(self, dnitime, initialize=False): if dnitime.prorahn == self.prorahn.get() and not initialize: return @@ -455,6 +505,10 @@ self.gorahn.setNumber(dnitime.gorahn) self.prorahn.setNumber(dnitime.prorahn) + def setClockFromUTC(self, utc_dt): + self.dnitime.fromUTC(utc_dt) + self.setClockFromDnidate(self.dnitime, initialize=True) + @pyqtSignature("") @skipLogging def timeEvent(self, initialize=False): @@ -462,7 +516,7 @@ SIGNAL: QTimer timeout """ self.dnitime.fromUTC() # set to now - self.setClockByDnidate(self.dnitime, initialize) + self.setClockFromDnidate(self.dnitime, initialize) class QDniClockCircle(QtGui.QGraphicsItem): """Circular part of the D'ni clock Modified: pymoul/trunk/src/moul/qt/localization.py =================================================================== --- pymoul/trunk/src/moul/qt/localization.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/localization.py 2007-02-22 14:14:24 UTC (rev 181) @@ -34,7 +34,7 @@ from moul.log import getLogger from moul.qt.simpleprogressbar import SimpleProgressbar -from moul.qt.threadlet import YieldingThreadlet +from moul.qt.utils import QYieldingThreadlet from moul.qt.utils import QNamespaceContainer from moul.qt.utils import QSignalLoggerMetaclass @@ -88,7 +88,7 @@ self.progressbar.setProgressbar(0, len(loc), 0) self.progressbar.show() - self.threadlet = YieldingThreadlet(self.context) + self.threadlet = QYieldingThreadlet(self.context) self.connect(self.threadlet, SIGNAL('finished()'), self.on_localization_loaded) self.connect(self.threadlet, SIGNAL("yield(const QString&)"), Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-02-22 14:14:24 UTC (rev 181) @@ -46,8 +46,8 @@ from moul.qt.localization import LocalizationContainer from moul.qt.wdysini import IniFileContainer from moul.qt.simpleprogressbar import SimpleProgressbar -from moul.qt.threadlet import YieldingThreadlet -from moul.qt.threadlet import Threadlet +from moul.qt.utils import QYieldingThreadlet +from moul.qt.utils import QThreadlet from moul.qt.ui.mainwindow import Ui_MainWindow from moul.qt import utils as qtutils @@ -211,7 +211,7 @@ # ************************************************************************ # tasks def _chatlog_init(self): - self._chatlog_threadlet = Threadlet(self) + self._chatlog_threadlet = QThreadlet(self) self.connect(self, SIGNAL("chatlogsUpdated()"), self._chatlog_threadlet.start) self.connect(self._chatlog_threadlet, SIGNAL("finished()"), @@ -266,7 +266,7 @@ self._kiimage_progressbar = SimpleProgressbar(self) self._kiimage_progressbar.setWindowTitle( self.trUtf8("Repairing KI images")) - self._kiimage_threadlet = YieldingThreadlet(self) + self._kiimage_threadlet = QYieldingThreadlet(self) self._kiimage_progressbar.setProgressbar(0, len(kimover), 0) self.connect(self._kiimage_threadlet, SIGNAL("yield(const QString&)"), Deleted: pymoul/trunk/src/moul/qt/threadlet.py =================================================================== --- pymoul/trunk/src/moul/qt/threadlet.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/threadlet.py 2007-02-22 14:14:24 UTC (rev 181) @@ -1,128 +0,0 @@ -#!/usr/bin/env python2.5 -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -"""Threadlet - execute a function in a seperate thread -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - -import sys -from PyQt4 import QtCore -from PyQt4.QtCore import SIGNAL - -from moul.log import getLogger - - -LOG = getLogger('moul.tasklet') - -class Threadlet(QtCore.QThread): - """Threadlet - execute a function in a seperate thread - - Use this class to run a CPU or I/O bound function in a seperate thread. - - - >>> def pow(x, y): return x**y - >>> def printer(r): print r - >>> parent.example = Threadlet() - >>> parent.connect(parent.example, SIGNAL('done(result)'), printer) - >>> parent.example.detach(pow, 2, 6) - - Signals emitted: - - started() - - done(result) - - finished() - - You should disconnect all signals after the threadlet has finished - >>> parent.disconnect(parent.example, SIGNAL('done(result)')) - >>> del parent.example - - @qtsignal started(): Signal is emitted when the thread starts executing. - @qtsignal finished(): Signal is emitted when the thread has finished. - @qtsignal terminated(): Signal is emitted when the thread is terminated. - - @warning: The function and all applied arguments must be thread safe! - """ - def __init__(self, parent=None): - """Constructor - - @param parent: Qt parent object - @type parent: QObject instance or None - """ - QtCore.QThread.__init__(self, parent) - self.mutex = QtCore.QMutex() - self.clear() - - def clear(self): - """ - Clear variables - - Mutex must be locked before clear() is called from a method! - """ - self._func = None - self._args = None - self._kwargs = None - - def __del__(self): - self.clear() - - def detach(self, obj, *args, **kwargs): - """ - Detach a function call - - @param obj: a callable (or iterable for YieldingThreadlet) - @param *args: additional arguments for the function - @param **kwargs: additional keyword arguments for the function - """ - self.mutex.lock() - self._obj = obj - self._args = args or () - self._kwargs = kwargs or {} - self.mutex.unlock() - if not self.isRunning(): - self.start() - - def run(self): - """ - Payload - runs the callable and emits done(result) - - The function and its args/kwargs are cleared after the function has - run to avoid cyclic references. - - @qtsignal done(result): Signal is emitted when the function has returned. - """ - self.mutex.lock() - result = self._obj(*self._args, **self._kwargs) - self.emit(SIGNAL("done(result)"), result) - self.mutex.unlock() - -class YieldingThreadlet(Threadlet): - """ - Similar to Threadlet by iters over the object and yields each value - """ - def run(self): - """ - Paylad - iters over the object and yields each value - - @qtsignal yield(const QString&): yield - """ - self.mutex.lock() - for result in iter(self._obj): - self.emit(SIGNAL("yield(const QString&)"), result) - self.mutex.unlock() Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-22 14:14:24 UTC (rev 181) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file './src/moul/qt/ui/mainwindow.ui' # -# Created: Mon Feb 19 21:09:28 2007 +# Created: Tue Feb 20 15:52:22 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -44,12 +44,6 @@ spacerItem1 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout.addItem(spacerItem1) - self.main_buttonbox = QtGui.QDialogButtonBox(self.centralwidget) - self.main_buttonbox.setGeometry(QtCore.QRect(10,520,451,32)) - self.main_buttonbox.setOrientation(QtCore.Qt.Horizontal) - self.main_buttonbox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.main_buttonbox.setObjectName("main_buttonbox") - self.tabwidget = QtGui.QTabWidget(self.centralwidget) self.tabwidget.setGeometry(QtCore.QRect(0,80,471,434)) self.tabwidget.setTabPosition(QtGui.QTabWidget.North) @@ -755,12 +749,29 @@ self.tab_time = QtGui.QWidget() self.tab_time.setObjectName("tab_time") + self.gb_dnitime = QtGui.QGroupBox(self.tab_time) + self.gb_dnitime.setGeometry(QtCore.QRect(10,220,451,181)) + self.gb_dnitime.setObjectName("gb_dnitime") + + self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) + self.gv_dniclock.setGeometry(QtCore.QRect(10,20,431,151)) + self.gv_dniclock.setFocusPolicy(QtCore.Qt.NoFocus) + self.gv_dniclock.setContextMenuPolicy(QtCore.Qt.NoContextMenu) + self.gv_dniclock.setAcceptDrops(False) + self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) + self.gv_dniclock.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.gv_dniclock.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.gv_dniclock.setInteractive(False) + self.gv_dniclock.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) + self.gv_dniclock.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.SmoothPixmapTransform|QtGui.QPainter.TextAntialiasing) + self.gv_dniclock.setObjectName("gv_dniclock") + self.groupBox_3 = QtGui.QGroupBox(self.tab_time) - self.groupBox_3.setGeometry(QtCore.QRect(10,0,451,181)) + self.groupBox_3.setGeometry(QtCore.QRect(10,0,451,221)) self.groupBox_3.setObjectName("groupBox_3") self.gridLayout_5 = QtGui.QWidget(self.groupBox_3) - self.gridLayout_5.setGeometry(QtCore.QRect(10,20,431,154)) + self.gridLayout_5.setGeometry(QtCore.QRect(10,20,431,184)) self.gridLayout_5.setObjectName("gridLayout_5") self.gridlayout2 = QtGui.QGridLayout(self.gridLayout_5) @@ -768,138 +779,144 @@ self.gridlayout2.setSpacing(6) self.gridlayout2.setObjectName("gridlayout2") + spacerItem4 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) + self.gridlayout2.addItem(spacerItem4,0,1,1,1) + self.hboxlayout9 = QtGui.QHBoxLayout() self.hboxlayout9.setMargin(0) self.hboxlayout9.setSpacing(6) self.hboxlayout9.setObjectName("hboxlayout9") - self.sb_ = QtGui.QSpinBox(self.gridLayout_5) - self.sb_.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.sb_.setMaximum(4) - self.sb_.setProperty("value",QtCore.QVariant(0)) - self.sb_.setObjectName("sb_") - self.hboxlayout9.addWidget(self.sb_) + self.sb_hahr = QtGui.QSpinBox(self.gridLayout_5) + self.sb_hahr.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.sb_hahr.setMaximum(9999) + self.sb_hahr.setProperty("value",QtCore.QVariant(9662)) + self.sb_hahr.setObjectName("sb_hahr") + self.hboxlayout9.addWidget(self.sb_hahr) - self.sb_1 = QtGui.QSpinBox(self.gridLayout_5) - self.sb_1.setMinimumSize(QtCore.QSize(0,0)) - self.sb_1.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.sb_1.setMaximum(24) - self.sb_1.setProperty("value",QtCore.QVariant(0)) - self.sb_1.setObjectName("sb_1") - self.hboxlayout9.addWidget(self.sb_1) + self.cb_vailee = QtGui.QComboBox(self.gridLayout_5) + self.cb_vailee.setMinimumSize(QtCore.QSize(0,0)) + self.cb_vailee.setObjectName("cb_vailee") + self.hboxlayout9.addWidget(self.cb_vailee) - self.sb_2 = QtGui.QSpinBox(self.gridLayout_5) - self.sb_2.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.sb_2.setMaximum(24) - self.sb_2.setProperty("value",QtCore.QVariant(0)) - self.sb_2.setObjectName("sb_2") - self.hboxlayout9.addWidget(self.sb_2) + self.sb_yahr = QtGui.QSpinBox(self.gridLayout_5) + self.sb_yahr.setMaximum(29) + self.sb_yahr.setMinimum(1) + self.sb_yahr.setProperty("value",QtCore.QVariant(1)) + self.sb_yahr.setObjectName("sb_yahr") + self.hboxlayout9.addWidget(self.sb_yahr) - self.sb_3 = QtGui.QSpinBox(self.gridLayout_5) - self.sb_3.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.sb_3.setMaximum(24) - self.sb_3.setProperty("value",QtCore.QVariant(0)) - self.sb_3.setObjectName("sb_3") - self.hboxlayout9.addWidget(self.sb_3) + spacerItem5 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) + self.hboxlayout9.addItem(spacerItem5) + self.gridlayout2.addLayout(self.hboxlayout9,2,1,1,1) - spacerItem4 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) - self.hboxlayout9.addItem(spacerItem4) - self.gridlayout2.addLayout(self.hboxlayout9,3,1,1,1) + self.rb_dnitime = QtGui.QRadioButton(self.gridLayout_5) + self.rb_dnitime.setObjectName("rb_dnitime") + self.gridlayout2.addWidget(self.rb_dnitime,2,0,1,1) self.hboxlayout10 = QtGui.QHBoxLayout() self.hboxlayout10.setMargin(0) self.hboxlayout10.setSpacing(6) self.hboxlayout10.setObjectName("hboxlayout10") - self.dateTimeEdit = QtGui.QDateTimeEdit(self.gridLayout_5) - self.dateTimeEdit.setCalendarPopup(True) - self.dateTimeEdit.setObjectName("dateTimeEdit") - self.hboxlayout10.addWidget(self.dateTimeEdit) + self.dte_earthtime = QtGui.QDateTimeEdit(self.gridLayout_5) + self.dte_earthtime.setCalendarPopup(True) + self.dte_earthtime.setObjectName("dte_earthtime") + self.hboxlayout10.addWidget(self.dte_earthtime) - self.comboBox_2 = QtGui.QComboBox(self.gridLayout_5) - self.comboBox_2.setObjectName("comboBox_2") - self.hboxlayout10.addWidget(self.comboBox_2) + self.cb_earthtime_tz = QtGui.QComboBox(self.gridLayout_5) + self.cb_earthtime_tz.setEnabled(False) - spacerItem5 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) - self.hboxlayout10.addItem(spacerItem5) - self.gridlayout2.addLayout(self.hboxlayout10,1,1,1,1) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(3),QtGui.QSizePolicy.Policy(0)) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.cb_earthtime_tz.sizePolicy().hasHeightForWidth()) + self.cb_earthtime_tz.setSizePolicy(sizePolicy) + self.cb_earthtime_tz.setEditable(False) + self.cb_earthtime_tz.setObjectName("cb_earthtime_tz") + self.hboxlayout10.addWidget(self.cb_earthtime_tz) spacerItem6 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) - self.gridlayout2.addItem(spacerItem6,0,1,1,1) + self.hboxlayout10.addItem(spacerItem6) + self.gridlayout2.addLayout(self.hboxlayout10,1,1,1,1) - self.radioButton_4 = QtGui.QRadioButton(self.gridLayout_5) - self.radioButton_4.setObjectName("radioButton_4") - self.gridlayout2.addWidget(self.radioButton_4,4,0,1,1) - self.hboxlayout11 = QtGui.QHBoxLayout() self.hboxlayout11.setMargin(0) self.hboxlayout11.setSpacing(6) self.hboxlayout11.setObjectName("hboxlayout11") - self.sb_4 = QtGui.QSpinBox(self.gridLayout_5) - self.sb_4.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.sb_4.setMaximum(9999) - self.sb_4.setProperty("value",QtCore.QVariant(9662)) - self.sb_4.setObjectName("sb_4") - self.hboxlayout11.addWidget(self.sb_4) + self.cb_dniholidays = QtGui.QComboBox(self.gridLayout_5) + self.cb_dniholidays.setObjectName("cb_dniholidays") + self.hboxlayout11.addWidget(self.cb_dniholidays) - self.comboBox_3 = QtGui.QComboBox(self.gridLayout_5) - self.comboBox_3.setMinimumSize(QtCore.QSize(0,0)) - self.comboBox_3.setObjectName("comboBox_3") - self.hboxlayout11.addWidget(self.comboBox_3) - - self.spinBox_2 = QtGui.QSpinBox(self.gridLayout_5) - self.spinBox_2.setMaximum(29) - self.spinBox_2.setMinimum(1) - self.spinBox_2.setProperty("value",QtCore.QVariant(1)) - self.spinBox_2.setObjectName("spinBox_2") - self.hboxlayout11.addWidget(self.spinBox_2) - spacerItem7 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout11.addItem(spacerItem7) - self.gridlayout2.addLayout(self.hboxlayout11,2,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout11,4,1,1,1) - self.radioButton = QtGui.QRadioButton(self.gridLayout_5) - self.radioButton.setObjectName("radioButton") - self.gridlayout2.addWidget(self.radioButton,0,0,1,1) - - self.radioButton_3 = QtGui.QRadioButton(self.gridLayout_5) - self.radioButton_3.setObjectName("radioButton_3") - self.gridlayout2.addWidget(self.radioButton_3,2,0,1,1) - - self.radioButton_2 = QtGui.QRadioButton(self.gridLayout_5) - self.radioButton_2.setObjectName("radioButton_2") - self.gridlayout2.addWidget(self.radioButton_2,1,0,1,1) - self.hboxlayout12 = QtGui.QHBoxLayout() self.hboxlayout12.setMargin(0) self.hboxlayout12.setSpacing(6) self.hboxlayout12.setObjectName("hboxlayout12") - self.comboBox = QtGui.QComboBox(self.gridLayout_5) - self.comboBox.setObjectName("comboBox") - self.hboxlayout12.addWidget(self.comboBox) + self.sb_gahrtahvo = QtGui.QSpinBox(self.gridLayout_5) + self.sb_gahrtahvo.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.sb_gahrtahvo.setMaximum(4) + self.sb_gahrtahvo.setProperty("value",QtCore.QVariant(0)) + self.sb_gahrtahvo.setObjectName("sb_gahrtahvo") + self.hboxlayout12.addWidget(self.sb_gahrtahvo) + self.sb_tahvo = QtGui.QSpinBox(self.gridLayout_5) + self.sb_tahvo.setMinimumSize(QtCore.QSize(0,0)) + self.sb_tahvo.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.sb_tahvo.setMaximum(24) + self.sb_tahvo.setProperty("value",QtCore.QVariant(0)) + self.sb_tahvo.setObjectName("sb_tahvo") + self.hboxlayout12.addWidget(self.sb_tahvo) + + self.sb_gorahn = QtGui.QSpinBox(self.gridLayout_5) + self.sb_gorahn.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.sb_gorahn.setMaximum(24) + self.sb_gorahn.setProperty("value",QtCore.QVariant(0)) + self.sb_gorahn.setObjectName("sb_gorahn") + self.hboxlayout12.addWidget(self.sb_gorahn) + + self.sb_prorahn = QtGui.QSpinBox(self.gridLayout_5) + self.sb_prorahn.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.sb_prorahn.setMaximum(24) + self.sb_prorahn.setProperty("value",QtCore.QVariant(0)) + self.sb_prorahn.setObjectName("sb_prorahn") + self.hboxlayout12.addWidget(self.sb_prorahn) + spacerItem8 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout12.addItem(spacerItem8) - self.gridlayout2.addLayout(self.hboxlayout12,4,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout12,3,1,1,1) - self.gb_dnitime = QtGui.QGroupBox(self.tab_time) - self.gb_dnitime.setGeometry(QtCore.QRect(10,220,451,181)) - self.gb_dnitime.setObjectName("gb_dnitime") + self.rb_earthtime = QtGui.QRadioButton(self.gridLayout_5) + self.rb_earthtime.setChecked(True) + self.rb_earthtime.setObjectName("rb_earthtime") + self.gridlayout2.addWidget(self.rb_earthtime,1,0,1,1) - self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) - self.gv_dniclock.setGeometry(QtCore.QRect(10,20,431,151)) - self.gv_dniclock.setFocusPolicy(QtCore.Qt.NoFocus) - self.gv_dniclock.setContextMenuPolicy(QtCore.Qt.NoContextMenu) - self.gv_dniclock.setAcceptDrops(False) - self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) - self.gv_dniclock.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.gv_dniclock.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.gv_dniclock.setInteractive(False) - self.gv_dniclock.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) - self.gv_dniclock.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.SmoothPixmapTransform|QtGui.QPainter.TextAntialiasing) - self.gv_dniclock.setObjectName("gv_dniclock") + self.rb_curtime = QtGui.QRadioButton(self.gridLayout_5) + self.rb_curtime.setObjectName("rb_curtime") + self.gridlayout2.addWidget(self.rb_curtime,0,0,1,1) + + self.rb_dniholiday = QtGui.QRadioButton(self.gridLayout_5) + self.rb_dniholiday.setObjectName("rb_dniholiday") + self.gridlayout2.addWidget(self.rb_dniholiday,4,0,1,1) + + self.hboxlayout13 = QtGui.QHBoxLayout() + self.hboxlayout13.setMargin(0) + self.hboxlayout13.setSpacing(6) + self.hboxlayout13.setObjectName("hboxlayout13") + + spacerItem9 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) + self.hboxlayout13.addItem(spacerItem9) + + self.pb_time_update = QtGui.QPushButton(self.gridLayout_5) + self.pb_time_update.setMaximumSize(QtCore.QSize(16777215,22)) + self.pb_time_update.setObjectName("pb_time_update") + self.hboxlayout13.addWidget(self.pb_time_update) + self.gridlayout2.addLayout(self.hboxlayout13,5,1,1,1) self.tabwidget.addTab(self.tab_time,"") self.tab_browse = QtGui.QWidget() @@ -1056,6 +1073,12 @@ self.tb_license.setObjectName("tb_license") self.tabwidget_about.addTab(self.tab_sub_license,"") self.tabwidget.addTab(self.tab_about,"") + + self.main_buttonbox = QtGui.QDialogButtonBox(self.centralwidget) + self.main_buttonbox.setGeometry(QtCore.QRect(10,520,451,32)) + self.main_buttonbox.setOrientation(QtCore.Qt.Horizontal) + self.main_buttonbox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.main_buttonbox.setObjectName("main_buttonbox") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) @@ -1134,13 +1157,16 @@ self.gb_servers.setTitle(QtGui.QApplication.translate("MainWindow", "Ping servers", None, QtGui.QApplication.UnicodeUTF8)) self.button_ping.setText(QtGui.QApplication.translate("MainWindow", "Ping", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_ping), QtGui.QApplication.translate("MainWindow", "Servers", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_3.setTitle(QtGui.QApplication.translate("MainWindow", "Choose Time", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_4.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Holiday", None, QtGui.QApplication.UnicodeUTF8)) - self.comboBox_3.addItem(QtGui.QApplication.translate("MainWindow", "8 Leevosahn", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton.setText(QtGui.QApplication.translate("MainWindow", "Current Time", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_3.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Time", None, QtGui.QApplication.UnicodeUTF8)) - self.radioButton_2.setText(QtGui.QApplication.translate("MainWindow", "Earth Time", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_dnitime.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Time", None, QtGui.QApplication.UnicodeUTF8)) + self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "local time", None, QtGui.QApplication.UnicodeUTF8)) + self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "cavern time", None, QtGui.QApplication.UnicodeUTF8)) + self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_earthtime.setText(QtGui.QApplication.translate("MainWindow", "Earth Time", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_curtime.setText(QtGui.QApplication.translate("MainWindow", "Current Time", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_dniholiday.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Holiday", None, QtGui.QApplication.UnicodeUTF8)) + self.pb_time_update.setText(QtGui.QApplication.translate("MainWindow", "Update", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_5.setTitle(QtGui.QApplication.translate("MainWindow", "Read chatlogs", None, QtGui.QApplication.UnicodeUTF8)) self.tb_chatlog_view.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-22 14:14:24 UTC (rev 181) @@ -97,22 +97,6 @@ </item> </layout> </widget> - <widget class="QDialogButtonBox" name="main_buttonbox" > - <property name="geometry" > - <rect> - <x>10</x> - <y>520</y> - <width>451</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> <widget class="QTabWidget" name="tabwidget" > <property name="geometry" > <rect> @@ -1612,13 +1596,63 @@ <attribute name="title" > <string>Time</string> </attribute> + <widget class="QGroupBox" name="gb_dnitime" > + <property name="geometry" > + <rect> + <x>10</x> + <y>220</y> + <width>451</width> + <height>181</height> + </rect> + </property> + <property name="title" > + <string>D'ni time</string> + </property> + <widget class="QGraphicsView" name="gv_dniclock" > + <property name="geometry" > + <rect> + <x>10</x> + <y>20</y> + <width>431</width> + <height>151</height> + </rect> + </property> + <property name="focusPolicy" > + <enum>Qt::NoFocus</enum> + </property> + <property name="contextMenuPolicy" > + <enum>Qt::NoContextMenu</enum> + </property> + <property name="acceptDrops" > + <bool>false</bool> + </property> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> + </property> + <property name="verticalScrollBarPolicy" > + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy" > + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="interactive" > + <bool>false</bool> + </property> + <property name="alignment" > + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="renderHints" > + <set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set> + </property> + </widget> + </widget> <widget class="QGroupBox" name="groupBox_3" > <property name="geometry" > <rect> <x>10</x> <y>0</y> <width>451</width> - <height>181</height> + <height>221</height> </rect> </property> <property name="title" > @@ -1630,7 +1664,7 @@ <x>10</x> <y>20</y> <width>431</width> - <height>154</height> + <height>184</height> </rect> </property> <layout class="QGridLayout" > @@ -1640,7 +1674,20 @@ <property name="spacing" > <number>6</number> </property> - <item row="3" column="1" > + <item row="0" column="1" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1" > <layout class="QHBoxLayout" > <property name="margin" > <number>0</number> @@ -1649,60 +1696,38 @@ <number>6</number> </property> <item> - <widget class="QSpinBox" name="sb_" > + <widget class="QSpinBox" name="sb_hahr" > <property name="buttonSymbols" > <enum>QAbstractSpinBox::UpDownArrows</enum> </property> <property name="maximum" > - <number>4</number> + <number>9999</number> </property> <property name="value" > - <number>0</number> + <number>9662</number> </property> </widget> </item> <item> - <widget class="QSpinBox" name="sb_1" > + <widget class="QComboBox" name="cb_vailee" > <property name="minimumSize" > <size> <width>0</width> <height>0</height> </size> </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - <property name="maximum" > - <number>24</number> - </property> - <property name="value" > - <number>0</number> - </property> </widget> </item> <item> - <widget class="QSpinBox" name="sb_2" > - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> + <widget class="QSpinBox" name="sb_yahr" > <property name="maximum" > - <number>24</number> + <number>29</number> </property> - <property name="value" > - <number>0</number> + <property name="minimum" > + <number>1</number> </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="sb_3" > - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - <property name="maximum" > - <number>24</number> - </property> <property name="value" > - <number>0</number> + <number>1</number> </property> </widget> </item> @@ -1721,6 +1746,13 @@ </item> </layout> </item> + <item row="2" column="0" > + <widget class="QRadioButton" name="rb_dnitime" > + <property name="text" > + <string>D'ni Time</string> + </property> + </widget> + </item> <item row="1" column="1" > <layout class="QHBoxLayout" > <property name="margin" > @@ -1730,14 +1762,44 @@ <number>6</number> </property> <item> - <widget class="QDateTimeEdit" name="dateTimeEdit" > + <widget class="QDateTimeEdit" name="dte_earthtime" > <property name="calendarPopup" > <bool>true</bool> </property> </widget> </item> <item> - <widget class="QComboBox" name="comboBox_2" /> + <widget class="QComboBox" name="cb_earthtime_tz" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable" > + <bool>false</bool> + </property> + <item> + <property name="text" > + <string>local time</string> + </property> + </item> + <item> + <property name="text" > + <string>cavern time</string> + </property> + </item> + <item> + <property name="text" > + <string>UTC</string> + </property> + </item> + </widget> </item> <item> <spacer> @@ -1754,27 +1816,33 @@ </item> </layout> </item> - <item row="0" column="1" > - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> + <item row="4" column="1" > + <layout class="QHBoxLayout" > + <property name="margin" > + <number>0</number> </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> + <property name="spacing" > + <number>6</number> </property> - </spacer> + <item> + <widget class="QComboBox" name="cb_dniholidays" /> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> </item> - <item row="4" column="0" > - <widget class="QRadioButton" name="radioButton_4" > - <property name="text" > - <string>D'ni Holiday</string> - </property> - </widget> - </item> - <item row="2" column="1" > + <item row="3" column="1" > <layout class="QHBoxLayout" > <property name="margin" > <number>0</number> @@ -1783,43 +1851,60 @@ <number>6</number> </property> <item> - <widget class="QSpinBox" name="sb_4" > + <widget class="QSpinBox" name="sb_gahrtahvo" > <property name="buttonSymbols" > <enum>QAbstractSpinBox::UpDownArrows</enum> </property> <property name="maximum" > - <number>9999</number> + <number>4</number> </property> <property name="value" > - <number>9662</number> + <number>0</number> </property> </widget> </item> <item> - <widget class="QComboBox" name="comboBox_3" > + <widget class="QSpinBox" name="sb_tahvo" > <property name="minimumSize" > <size> <width>0</width> <height>0</height> </size> </property> - <item> - <property name="text" > - <string>8 Leevosahn</string> - </property> - </item> + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> + <property name="maximum" > + <number>24</number> + </property> + <property name="value" > + <number>0</number> + </property> </widget> </item> <item> - <widget class="QSpinBox" name="spinBox_2" > + <widget class="QSpinBox" name="sb_gorahn" > + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> <property name="maximum" > - <number>29</number> + <number>24</number> </property> - <property name="minimum" > - <number>1</number> + <property name="value" > + <number>0</number> </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="sb_prorahn" > + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> + <property name="maximum" > + <number>24</number> + </property> <property name="value" > - <number>1</number> + <number>0</number> </property> </widget> </item> @@ -1838,28 +1923,31 @@ </item> </layout> </item> - <item row="0" column="0" > - <widget class="QRadioButton" name="radioButton" > + <item row="1" column="0" > + <widget class="QRadioButton" name="rb_earthtime" > <property name="text" > - <string>Current Time</string> + <string>Earth Time</string> </property> + <property name="checked" > + <bool>true</bool> + </property> </widget> </item> - <item row="2" column="0" > - <widget class="QRadioButton" name="radioButton_3" > + <item row="0" column="0" > + <widget class="QRadioButton" name="rb_curtime" > <property name="text" > - <string>D'ni Time</string> + <string>Current Time</string> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QRadioButton" name="radioButton_2" > + <item row="4" column="0" > + <widget class="QRadioButton" name="rb_dniholiday" > <property name="text" > - <string>Earth Time</string> + <string>D'ni Holiday</string> </property> </widget> </item> - <item row="4" column="1" > + <item row="5" column="1" > <layout class="QHBoxLayout" > <property name="margin" > <number>0</number> @@ -1868,9 +1956,6 @@ <number>6</number> </property> <item> - <widget class="QComboBox" name="comboBox" /> - </item> - <item> <spacer> <property name="orientation" > <enum>Qt::Horizontal</enum> @@ -1883,61 +1968,24 @@ </property> </spacer> </item> + <item> + <widget class="QPushButton" name="pb_time_update" > + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>22</height> + </size> + </property> + <property name="text" > + <string>Update</string> + </property> + </widget> + </item> </layout> </item> </layout> </widget> </widget> - <widget class="QGroupBox" name="gb_dnitime" > - <property name="geometry" > - <rect> - <x>10</x> - <y>220</y> - <width>451</width> - <height>181</height> - </rect> - </property> - <property name="title" > - <string>D'ni time</string> - </property> - <widget class="QGraphicsView" name="gv_dniclock" > - <property name="geometry" > - <rect> - <x>10</x> - <y>20</y> - <width>431</width> - <height>151</height> - </rect> - </property> - <property name="focusPolicy" > - <enum>Qt::NoFocus</enum> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="acceptDrops" > - <bool>false</bool> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="interactive" > - <bool>false</bool> - </property> - <property name="alignment" > - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - <property name="renderHints" > - <set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set> - </property> - </widget> - </widget> </widget> <widget class="QWidget" name="tab_browse" > <attribute name="title" > @@ -2289,6 +2337,22 @@ </widget> </widget> </widget> + <widget class="QDialogButtonBox" name="main_buttonbox" > + <property name="geometry" > + <rect> + <x>10</x> + <y>520</y> + <width>451</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> Modified: pymoul/trunk/src/moul/qt/utils.py =================================================================== --- pymoul/trunk/src/moul/qt/utils.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/qt/utils.py 2007-02-22 14:14:24 UTC (rev 181) @@ -19,6 +19,12 @@ """Misc utilities +* QSignalLoggerMetaclass - logs signals to a logging logger +* QNamespaceContainer - transparent container for code and data +* connectSlotsByName - alternative implementation for connecting slots +* Threadlet and YieldingThreadlet - execute code in its own thread +* QTimerThread - QTimer in its own thread + It also contains several functions to create message boxes. """ __author__ = "Christian Heimes" @@ -257,6 +263,185 @@ #logging.debug('Connecting: %s to %s: %s' % (widget, signature, method)) QtCore.QObject.connect(widget, SIGNAL(signature), method) +class QThreadlet(QtCore.QThread): + """Threadlet - execute a function in a seperate thread + + Use this class to run a CPU or I/O bound function in a seperate thread. + + + >>> def pow(x, y): return x**y + >>> def printer(r): print r + >>> parent.example = Threadlet() + >>> parent.connect(parent.example, SIGNAL('done(result)'), printer) + >>> parent.example.detach(pow, 2, 6) + + Signals emitted: + - started() + - done(result) + - finished() + + You should disconnect all signals after the threadlet has finished + >>> parent.disconnect(parent.example, SIGNAL('done(result)')) + >>> del parent.example + + @qtsignal started(): Signal is emitted when the thread starts executing. + @qtsignal finished(): Signal is emitted when the thread has finished. + @qtsignal terminated(): Signal is emitted when the thread is terminated. + + @warning: The function and all applied arguments must be thread safe! + """ + def __init__(self, parent=None): + """Constructor + + @param parent: Qt parent object + @type parent: QObject instance or None + """ + QtCore.QThread.__init__(self, parent) + self.mutex = QtCore.QMutex() + self.clear() + + def clear(self): + """ + Clear variables + + Mutex must be locked before clear() is called from a method! + """ + self._func = None + self._args = None + self._kwargs = None + + def __del__(self): + self.wait() + self.clear() + + def detach(self, obj, *args, **kwargs): + """ + Detach a function call + + @param obj: a callable (or iterable for YieldingThreadlet) + @param *args: additional arguments for the function + @param **kwargs: additional keyword arguments for the function + """ + self.mutex.lock() + self._obj = obj + self._args = args or () + self._kwargs = kwargs or {} + self.mutex.unlock() + if not self.isRunning(): + self.start() + + def run(self): + """ + Payload - runs the callable and emits done(result) + + The function and its args/kwargs are cleared after the function has + run to avoid cyclic references. + + @qtsignal done(result): Signal is emitted when the function has returned. + """ + self.mutex.lock() + result = self._obj(*self._args, **self._kwargs) + self.emit(SIGNAL("done(result)"), result) + self.mutex.unlock() + +class QYieldingThreadlet(QThreadlet): + """ + Similar to Threadlet by iters over the object and yields each value + """ + def run(self): + """ + Paylad - iters over the object and yields each value + + @qtsignal yield(const QString&): yield + """ + self.mutex.lock() + for result in iter(self._obj): + self.emit(SIGNAL("yield(const QString&)"), result) + self.mutex.unlock() + self.clear() + +class QTimerThreadlet(QtCore.QThread): + """Timed Threadlet - a QTimer like threadlet + """ + def __init__(self, parent=None): + """Constructor + + @param parent: Qt parent object + @type parent: QObject instance or None + """ + QtCore.QThread.__init__(self, parent) + self.mutex = QtCore.QMutex() + self._quit = True + self._interval = None + self.clear() + + def clear(self): + """ + Clear variables + + Mutex must be locked before clear() is called from a method! + """ + self.stop() + self._func = None + self._args = None + self._kwargs = None + + def __del__(self): + self.stop() + self.wait() + self.clear() + + def setInterval(self, msec): + """Set interval in mili seconds + """ + self.mutex.lock() + self._interval = int(round(msec)) + self.mutex.unlock() + + def isActive(self): + """Alias for isRunning + """ + return self.isRunning() + + #def setCallable(self, obj, *args, **kwargs): + #""" + #Set callable to run each timeout + + #@param obj: a callable (or iterable for YieldingThreadlet) + #@param *args: additional arguments for the function + #@param **kwargs: additional keyword arguments for the function + #""" + #if not self._interval: + #raise ValueError("Interval not set") + #self.mutex.lock() + #self._obj = obj + #self._args = args or () + #self._kwargs = kwargs or {} + #self.mutex.unlock() + + def start(self): + """Start the timer + """ + self._quit = False + return QtCore.QThread.start(self) + + def stop(self): + """Stop the timer + """ + self._quit = True + + def run(self): + """Payload + """ + self.mutex.lock() + try: + interval = self._interval + while not self._quit: + self.emit(SIGNAL("timeout()")) + self.msleep(interval) + finally: + self.mutex.unlock() + def _mkMessageBox(context, title, text, icon='Information'): """ Create a message box Modified: pymoul/trunk/src/moul/time/dni.py =================================================================== --- pymoul/trunk/src/moul/time/dni.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/time/dni.py 2007-02-22 14:14:24 UTC (rev 181) @@ -23,15 +23,6 @@ official sources say that: 00:00:00:00, Leefo 1, 9654 DE = 10:35:18 UTC, April 21, 1998 CE -D'ni New Year - Leefo 1, April 21 -First Feast of the Maker - Lenovoo 10, March 27 (Pre-earth celebration) -The Common Library Opened - Leefo 12, May 5 -Second Feast of the Maker - Leebro 20, June 21 (Pre-earth celebration) -The Day of Dancing - Leetar 21, September 3 -First Arrival of the Great King - Leevot 12, September 28 -Third Feast of the Maker - Leevofo 18, November 11 (Pre-earth celebration) -Coronation of King Kerath - Leevofo 27, November 23 - >>> from datetime import timedelta >>> LEEFO_1_TABLE = [ @@ -117,6 +108,17 @@ 'Leenovoo', # 10: March 16th to April 21st ) +DNI_HOLIDAYS = ( + ("D'ni New Year", (1, 1)), + ("First Feast of the Maker (PEC)", (10, 10)), + ("The Common Library Opened", (1, 12)), + ("Second Feast of the Maker (PEC)", (2, 20)), + ("The Day of Dancing", (4, 21)), + ("First Arrival of the Great King", (5, 12)), + ("Third Feast of the Maker (PEC)", (6, 18)), + ("Coronation of King Kerath", (6, 27)), +) + # 00:00:00:00, Leefo 1, 9654 DE = 10:35:18 1998/4/21 BASE_GREGORIAN = datetime(1998, 4, 21, 10, 35, 18, 0, tzinfo=UTC) BASE_HAHR = 9654 Modified: pymoul/trunk/src/moul/time/utils.py =================================================================== --- pymoul/trunk/src/moul/time/utils.py 2007-02-19 20:12:39 UTC (rev 180) +++ pymoul/trunk/src/moul/time/utils.py 2007-02-22 14:14:24 UTC (rev 181) @@ -69,13 +69,18 @@ >>> td2sec(timedelta(0, -3600)) -3600 """ - return td.seconds + 86400 * td.days + return 86400 * td.days + td.seconds + td.microseconds/1000000.0 def utcnow(): """Get current time in UTC """ return UTC.localize(datetime.utcnow()) +def ts2utc(ts): + """Get utc from time stamp + """ + return UTC.localize(datetime.fromtimestamp(ts)) + def normalizeTZ(tz, utc_dt=None): """Normalize a datetime object with UTC tz using another tz """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-02-23 15:19:18
|
Revision: 186 http://pymoul.svn.sourceforge.net/pymoul/?rev=186&view=rev Author: tiran Date: 2007-02-23 07:19:19 -0800 (Fri, 23 Feb 2007) Log Message: ----------- Working on an enhanced time tab Modified Paths: -------------- pymoul/trunk/src/moul/qt/dninumbers.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/qt/utils.py pymoul/trunk/src/moul/time/utils.py Modified: pymoul/trunk/src/moul/qt/dninumbers.py =================================================================== --- pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-23 15:17:20 UTC (rev 185) +++ pymoul/trunk/src/moul/qt/dninumbers.py 2007-02-23 15:19:19 UTC (rev 186) @@ -31,6 +31,7 @@ from PyQt4.QtCore import Qt from PyQt4.QtCore import SIGNAL from PyQt4.QtCore import pyqtSignature +from logging import getLogger from moul.time.cavern import CavernTime from moul.time.dni import DniTime @@ -38,13 +39,13 @@ from moul.time.dni import decimal2dni from moul.time.dni import VAILEETEE from moul.time.dni import DNI_HOLIDAYS -from moul.time.utils import ts2utc from moul.time.utils import utcnow -from logging import getLogger from moul.qt.utils import QNamespaceContainer from moul.qt.utils import QSignalLoggerMetaclass from moul.qt.utils import skipLogging from moul.qt.utils import QTimerThreadlet +from moul.qt.utils import dt2qdt +from moul.qt.utils import qdt2dt NUMBER_HEIGHT = 25 @@ -61,6 +62,7 @@ # D'ni numbers self.dninumbers = QDniNumbers() self.caverntime = CavernTime() + self.dnitime = DniTime() self.setup_dninumbers() # D'ni date and time @@ -83,20 +85,28 @@ self.lb_pacific_utc.setText("UTC %s%i" % (off[0], abs(off[1]))) # chooser - self.dte_earthtime.setDateTime(QtCore.QDateTime(utcnow())) + self.dte_earthtime.setDateTime(dt2qdt(utcnow())) + self.cb_vailee.clear() for i, name in enumerate(VAILEETEE): self.cb_vailee.addItem("%2i %s" % (i+1, name)) for name, date in DNI_HOLIDAYS: self.cb_dniholidays.addItem(self.trUtf8(name)) self.connect(self.timezone_timer, SIGNAL('timeout()'), - self.on_timezone_timer_timeout) + self.on_timezone_timeout) self.connect(self.dnitime_timer, SIGNAL('timeout()'), - self.clockscene.timeEvent) + self.on_dniclock_timeout) self.connect(self.context, SIGNAL("timerEnable(bool)"), self.on_timer_timerEnable) # TODO: needs optimization? run only when timer tab is active - #self.emit(SIGNAL("timerEnable(bool)"), True) + for name in ('sb_hahr', 'sb_yahr', 'sb_gahrtahvo', + 'sb_tahvo', 'sb_gorahn', 'sb_prorahn'): + self.connect(getattr(self, name), SIGNAL("valueChanged(int)"), + self.update_dni) + self.connect(self.cb_vailee, SIGNAL("currentIndexChanged(int)"), + self.update_dni) + # setup defaults + self.rb_earthtime.click() @pyqtSignature("bool") def on_timer_timerEnable(self, value=True): @@ -112,7 +122,7 @@ @pyqtSignature("") @skipLogging - def on_timezone_timer_timeout(self): + def on_timezone_timeout(self): """ SIGNAL: QTimer timeout """ @@ -120,6 +130,16 @@ self.dt_cavern.setDateTime(ct['cavern']) self.dt_pacific.setDateTime(ct['pacific']) + @pyqtSignature("") + @skipLogging + def on_dniclock_timeout(self): + """ + SIGNAL: QTimer timeout + """ + self.dnitime.fromUTC() + self.clockscene.setClockFromDniTime(self.dnitime) + self.setWidgetDniTime(self.dnitime) + @pyqtSignature("bool") def on_rb_curtime_clicked(self, value): if value: @@ -129,6 +149,7 @@ def on_rb_earthtime_clicked(self, value): if value: self.emit(SIGNAL("timerEnable(bool)"), False) + self.update_earthtime(self.dte_earthtime.dateTime()) @pyqtSignature("bool") def on_rb_dnitime_clicked(self, value): @@ -140,22 +161,75 @@ if value: self.emit(SIGNAL("timerEnable(bool)"), False) - @pyqtSignature("") - def on_pb_time_update_clicked(self): - if self.rb_curtime.isChecked(): - pass - elif self.rb_earthtime.isChecked(): - qdt = self.dte_earthtime.dateTime() - utc_dt = ts2utc(qdt.toTime_t()) - self.clockscene.setClockFromUTC(utc_dt) - elif self.rb_dnitime.isChecked(): - pass - elif self.rb_dniholiday.isChecked(): - pass - else: - LOG.warning("Unknown state of time chooser") + @pyqtSignature("int") + def on_sb_fahrah_valueChanged(self, value): + hahr = self.sb_fahrah_hahr.value() + self.sb_hahr.setValue(value * 625 + hahr) + @pyqtSignature("int") + def on_sb_fahrah_hahr_valueChanged(self, value): + fahrah = self.sb_fahrah.value() + self.sb_hahr.setValue(fahrah * 625 + value) + @pyqtSignature("int") + def on_sb_hahr_valueChanged(self, value): + fahrah = value // 625 + hahr = value - fahrah * 625 + self.sb_fahrah_hahr.setValue(hahr) + self.sb_fahrah.setValue(fahrah) + + @pyqtSignature("int") + def on_cb_dniholidays_currentIndexChanged(self, idx): + self.rb_dniholidays.setChecked(True) + + @pyqtSignature("const QDateTime &") + def on_dte_earthtime_dateTimeChanged(self, qdt): + self.rb_earthtime.setChecked(True) + self.update_earthtime(qdt) + + def update_dni(self, ignored=None): + """Update view from D'ni time widgets + """ + if not self.rb_dnitime.isChecked(): + return + self.dnitime.set(*self.getWidgetDniTime()) + self.clockscene.setClockFromDniTime(self.dnitime) + self.dte_earthtime.setDateTime(dt2qdt(self.dnitime.toUTC())) + + def update_earthtime(self, qdt): + """Update view from earth time widget + """ + dt = qdt2dt(qdt) + self.dnitime.fromUTC(dt) + self.clockscene.setClockFromDniTime(self.dnitime) + self.setWidgetDniTime(self.dnitime) + + def update_holiday(self, idx): + """Update view from D'ni holiday widget + """ + + def getWidgetDniTime(self): + """Get D'ni date and time from widgets + """ + return (self.sb_hahr.value(), + self.cb_vailee.currentIndex() + 1, + self.sb_yahr.value(), + self.sb_gahrtahvo.value(), + self.sb_tahvo.value(), + self.sb_gorahn.value(), + self.sb_prorahn.value()) + + def setWidgetDniTime(self, dnitime): + """Set D'ni date and time of widgets + """ + self.sb_hahr.setValue(dnitime.hahr) + self.cb_vailee.setCurrentIndex(dnitime.vailee-1) + self.sb_yahr.setValue(dnitime.yahr) + self.sb_gahrtahvo.setValue(dnitime.gahrtahvo) + self.sb_tahvo.setValue(dnitime.tahvo) + self.sb_gorahn.setValue(dnitime.gorahn) + self.sb_prorahn.setValue(dnitime.prorahn) + def setup_dninumbers(self): # may change! widget = self.context.gridLayout_3 @@ -436,12 +510,14 @@ def __init__(self, parent=None): QtGui.QGraphicsScene.__init__(self, parent) self.dninumbers = QDniNumbers() - self.dnitime = DniTime() + self._prorahn = None + self.setup() - height = 15 + def setup(self): + height = 20 space = 5 xoff = 50 - yoff = 20 + yoff = 40 # set widths from pixmaps width = self.dninumbers.get(0, height=height).width() @@ -475,21 +551,18 @@ # clock text # XXX: parent? - self.clocktext = QtGui.QGraphicsTextItem(None, self) - self.clocktext.setPos(0, yoff+2*height+2*space) + #self.clocktext = QtGui.QGraphicsTextItem(None, self) + #self.clocktext.setPos(0, yoff+2*height+2*space) # circular day clock self.circle = QDniClockCircle(None, self) self.circle.setPos(250, 3) - # initialize view - self.timeEvent(initialize=True) - - def setClockFromDnidate(self, dnitime, initialize=False): - if dnitime.prorahn == self.prorahn.get() and not initialize: + def setClockFromDniTime(self, dnitime): + if dnitime._prorahn == self._prorahn: return + self._prorahn = dnitime._prorahn - self.clocktext.setPlainText(str(self.dnitime)) - + #self.clocktext.setPlainText(str(dnitime)) self.circle.setPahrtovo(dnitime.getPahrtovoFraction()) hahr = decimal2dni(dnitime.hahr, digits=3) @@ -505,23 +578,10 @@ self.gorahn.setNumber(dnitime.gorahn) self.prorahn.setNumber(dnitime.prorahn) - def setClockFromUTC(self, utc_dt): - self.dnitime.fromUTC(utc_dt) - self.setClockFromDnidate(self.dnitime, initialize=True) - - @pyqtSignature("") - @skipLogging - def timeEvent(self, initialize=False): - """ - SIGNAL: QTimer timeout - """ - self.dnitime.fromUTC() # set to now - self.setClockFromDnidate(self.dnitime, initialize) - class QDniClockCircle(QtGui.QGraphicsItem): """Circular part of the D'ni clock """ - r = 70.0 # radios of circle + r = 60.0 # radios of circle rdot = 3.0 # radius of dots rinner = 6.0 # radius of inner circle outrect = QtCore.QRectF(0.0, 0.0, 2.0*r, 2.0*r) @@ -533,7 +593,7 @@ def __init__(self, parent=None, scene=None): QtGui.QGraphicsItem.__init__(self, parent, scene) self._pahrtovo = 0.0 - self._dni =QDniNumbers() + self._dni = QDniNumbers() def boundingRect(self): return self.outrect Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-23 15:17:20 UTC (rev 185) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-02-23 15:19:19 UTC (rev 186) @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' +# Form implementation generated from reading ui file './src/moul/qt/ui/mainwindow.ui' # -# Created: Thu Feb 22 16:50:00 2007 +# Created: Fri Feb 23 05:05:02 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -44,12 +44,6 @@ spacerItem1 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout.addItem(spacerItem1) - self.main_buttonbox = QtGui.QDialogButtonBox(self.centralwidget) - self.main_buttonbox.setGeometry(QtCore.QRect(10,520,451,32)) - self.main_buttonbox.setOrientation(QtCore.Qt.Horizontal) - self.main_buttonbox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.main_buttonbox.setObjectName("main_buttonbox") - self.tabwidget = QtGui.QTabWidget(self.centralwidget) self.tabwidget.setGeometry(QtCore.QRect(0,80,471,434)) self.tabwidget.setTabPosition(QtGui.QTabWidget.North) @@ -697,23 +691,97 @@ self.tab_time = QtGui.QWidget() self.tab_time.setObjectName("tab_time") + self.gb_dnitime = QtGui.QGroupBox(self.tab_time) + self.gb_dnitime.setGeometry(QtCore.QRect(10,240,451,161)) + self.gb_dnitime.setObjectName("gb_dnitime") + + self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) + self.gv_dniclock.setGeometry(QtCore.QRect(10,20,431,131)) + self.gv_dniclock.setFocusPolicy(QtCore.Qt.NoFocus) + self.gv_dniclock.setContextMenuPolicy(QtCore.Qt.NoContextMenu) + self.gv_dniclock.setAcceptDrops(False) + self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) + self.gv_dniclock.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.gv_dniclock.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.gv_dniclock.setInteractive(False) + self.gv_dniclock.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) + self.gv_dniclock.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.SmoothPixmapTransform|QtGui.QPainter.TextAntialiasing) + self.gv_dniclock.setObjectName("gv_dniclock") + + self.gb_caverntime = QtGui.QGroupBox(self.tab_time) + self.gb_caverntime.setGeometry(QtCore.QRect(10,160,451,81)) + self.gb_caverntime.setObjectName("gb_caverntime") + + self.gridLayout = QtGui.QWidget(self.gb_caverntime) + self.gridLayout.setGeometry(QtCore.QRect(10,20,292,56)) + self.gridLayout.setObjectName("gridLayout") + + self.gridlayout1 = QtGui.QGridLayout(self.gridLayout) + self.gridlayout1.setMargin(0) + self.gridlayout1.setSpacing(6) + self.gridlayout1.setObjectName("gridlayout1") + + self.label_5 = QtGui.QLabel(self.gridLayout) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0),QtGui.QSizePolicy.Policy(5)) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth()) + self.label_5.setSizePolicy(sizePolicy) + self.label_5.setObjectName("label_5") + self.gridlayout1.addWidget(self.label_5,0,0,1,1) + + self.lb_cavern_utc = QtGui.QLabel(self.gridLayout) + self.lb_cavern_utc.setObjectName("lb_cavern_utc") + self.gridlayout1.addWidget(self.lb_cavern_utc,0,2,1,1) + + self.dt_cavern = QtGui.QDateTimeEdit(self.gridLayout) + self.dt_cavern.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape(0))) + self.dt_cavern.setFocusPolicy(QtCore.Qt.NoFocus) + self.dt_cavern.setContextMenuPolicy(QtCore.Qt.NoContextMenu) + self.dt_cavern.setReadOnly(True) + self.dt_cavern.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.dt_cavern.setObjectName("dt_cavern") + self.gridlayout1.addWidget(self.dt_cavern,0,1,1,1) + + self.dt_pacific = QtGui.QDateTimeEdit(self.gridLayout) + self.dt_pacific.setFocusPolicy(QtCore.Qt.NoFocus) + self.dt_pacific.setContextMenuPolicy(QtCore.Qt.NoContextMenu) + self.dt_pacific.setReadOnly(True) + self.dt_pacific.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) + self.dt_pacific.setObjectName("dt_pacific") + self.gridlayout1.addWidget(self.dt_pacific,1,1,1,1) + + self.label_8 = QtGui.QLabel(self.gridLayout) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0),QtGui.QSizePolicy.Policy(5)) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) + self.label_8.setSizePolicy(sizePolicy) + self.label_8.setObjectName("label_8") + self.gridlayout1.addWidget(self.label_8,1,0,1,1) + + self.lb_pacific_utc = QtGui.QLabel(self.gridLayout) + self.lb_pacific_utc.setObjectName("lb_pacific_utc") + self.gridlayout1.addWidget(self.lb_pacific_utc,1,2,1,1) + self.groupBox_3 = QtGui.QGroupBox(self.tab_time) - self.groupBox_3.setGeometry(QtCore.QRect(10,0,451,151)) + self.groupBox_3.setGeometry(QtCore.QRect(10,0,451,161)) self.groupBox_3.setObjectName("groupBox_3") self.gridLayout_5 = QtGui.QWidget(self.groupBox_3) - self.gridLayout_5.setGeometry(QtCore.QRect(10,10,444,141)) + self.gridLayout_5.setGeometry(QtCore.QRect(10,20,451,138)) self.gridLayout_5.setObjectName("gridLayout_5") - self.gridlayout1 = QtGui.QGridLayout(self.gridLayout_5) - self.gridlayout1.setMargin(0) - self.gridlayout1.setSpacing(6) - self.gridlayout1.setObjectName("gridlayout1") + self.gridlayout2 = QtGui.QGridLayout(self.gridLayout_5) + self.gridlayout2.setMargin(0) + self.gridlayout2.setSpacing(2) + self.gridlayout2.setObjectName("gridlayout2") self.rb_earthtime = QtGui.QRadioButton(self.gridLayout_5) - self.rb_earthtime.setChecked(True) self.rb_earthtime.setObjectName("rb_earthtime") - self.gridlayout1.addWidget(self.rb_earthtime,1,0,1,1) + self.gridlayout2.addWidget(self.rb_earthtime,1,0,1,1) self.hboxlayout9 = QtGui.QHBoxLayout() self.hboxlayout9.setMargin(0) @@ -726,11 +794,11 @@ spacerItem4 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout9.addItem(spacerItem4) - self.gridlayout1.addLayout(self.hboxlayout9,4,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout9,4,1,1,1) self.rb_curtime = QtGui.QRadioButton(self.gridLayout_5) self.rb_curtime.setObjectName("rb_curtime") - self.gridlayout1.addWidget(self.rb_curtime,0,0,1,1) + self.gridlayout2.addWidget(self.rb_curtime,0,0,1,1) self.hboxlayout10 = QtGui.QHBoxLayout() self.hboxlayout10.setMargin(0) @@ -780,14 +848,14 @@ spacerItem5 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout10.addItem(spacerItem5) - self.gridlayout1.addLayout(self.hboxlayout10,3,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout10,3,1,1,1) - self.rb_dniholiday = QtGui.QRadioButton(self.gridLayout_5) - self.rb_dniholiday.setObjectName("rb_dniholiday") - self.gridlayout1.addWidget(self.rb_dniholiday,4,0,1,1) + self.rb_dniholidays = QtGui.QRadioButton(self.gridLayout_5) + self.rb_dniholidays.setObjectName("rb_dniholidays") + self.gridlayout2.addWidget(self.rb_dniholidays,4,0,1,1) spacerItem6 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) - self.gridlayout1.addItem(spacerItem6,0,1,1,1) + self.gridlayout2.addItem(spacerItem6,0,1,1,1) self.hboxlayout11 = QtGui.QHBoxLayout() self.hboxlayout11.setMargin(0) @@ -795,6 +863,7 @@ self.hboxlayout11.setObjectName("hboxlayout11") self.sb_fahrah = QtGui.QSpinBox(self.gridLayout_5) + self.sb_fahrah.setMaximumSize(QtCore.QSize(46,16777215)) self.sb_fahrah.setMaximum(15) self.sb_fahrah.setMinimum(1) self.sb_fahrah.setProperty("value",QtCore.QVariant(15)) @@ -802,6 +871,7 @@ self.hboxlayout11.addWidget(self.sb_fahrah) self.sb_fahrah_hahr = QtGui.QSpinBox(self.gridLayout_5) + self.sb_fahrah_hahr.setMaximumSize(QtCore.QSize(46,16777215)) self.sb_fahrah_hahr.setMaximum(249) self.sb_fahrah_hahr.setMinimum(0) self.sb_fahrah_hahr.setProperty("value",QtCore.QVariant(87)) @@ -819,29 +889,28 @@ self.sb_hahr.setObjectName("sb_hahr") self.hboxlayout11.addWidget(self.sb_hahr) - self.label_4 = QtGui.QLabel(self.gridLayout_5) - self.label_4.setObjectName("label_4") - self.hboxlayout11.addWidget(self.label_4) - self.cb_vailee = QtGui.QComboBox(self.gridLayout_5) - self.cb_vailee.setMinimumSize(QtCore.QSize(0,0)) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0)) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.cb_vailee.sizePolicy().hasHeightForWidth()) + self.cb_vailee.setSizePolicy(sizePolicy) + self.cb_vailee.setMinimumSize(QtCore.QSize(105,0)) self.cb_vailee.setObjectName("cb_vailee") self.hboxlayout11.addWidget(self.cb_vailee) - self.label_6 = QtGui.QLabel(self.gridLayout_5) - self.label_6.setObjectName("label_6") - self.hboxlayout11.addWidget(self.label_6) - self.sb_yahr = QtGui.QSpinBox(self.gridLayout_5) + self.sb_yahr.setMaximumSize(QtCore.QSize(46,16777215)) self.sb_yahr.setMaximum(29) self.sb_yahr.setMinimum(1) - self.sb_yahr.setProperty("value",QtCore.QVariant(1)) + self.sb_yahr.setProperty("value",QtCore.QVariant(29)) self.sb_yahr.setObjectName("sb_yahr") self.hboxlayout11.addWidget(self.sb_yahr) spacerItem7 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout11.addItem(spacerItem7) - self.gridlayout1.addLayout(self.hboxlayout11,2,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout11,2,1,1,1) self.hboxlayout12 = QtGui.QHBoxLayout() self.hboxlayout12.setMargin(0) @@ -867,86 +936,11 @@ spacerItem8 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum) self.hboxlayout12.addItem(spacerItem8) - self.gridlayout1.addLayout(self.hboxlayout12,1,1,1,1) + self.gridlayout2.addLayout(self.hboxlayout12,1,1,1,1) self.rb_dnitime = QtGui.QRadioButton(self.gridLayout_5) self.rb_dnitime.setObjectName("rb_dnitime") - self.gridlayout1.addWidget(self.rb_dnitime,2,0,1,1) - - self.gb_caverntime = QtGui.QGroupBox(self.tab_time) - self.gb_caverntime.setGeometry(QtCore.QRect(10,150,451,71)) - self.gb_caverntime.setObjectName("gb_caverntime") - - self.gridLayout = QtGui.QWidget(self.gb_caverntime) - self.gridLayout.setGeometry(QtCore.QRect(10,10,292,56)) - self.gridLayout.setObjectName("gridLayout") - - self.gridlayout2 = QtGui.QGridLayout(self.gridLayout) - self.gridlayout2.setMargin(0) - self.gridlayout2.setSpacing(6) - self.gridlayout2.setObjectName("gridlayout2") - - self.label_5 = QtGui.QLabel(self.gridLayout) - - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0),QtGui.QSizePolicy.Policy(5)) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth()) - self.label_5.setSizePolicy(sizePolicy) - self.label_5.setObjectName("label_5") - self.gridlayout2.addWidget(self.label_5,0,0,1,1) - - self.lb_cavern_utc = QtGui.QLabel(self.gridLayout) - self.lb_cavern_utc.setObjectName("lb_cavern_utc") - self.gridlayout2.addWidget(self.lb_cavern_utc,0,2,1,1) - - self.dt_cavern = QtGui.QDateTimeEdit(self.gridLayout) - self.dt_cavern.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape(0))) - self.dt_cavern.setFocusPolicy(QtCore.Qt.NoFocus) - self.dt_cavern.setContextMenuPolicy(QtCore.Qt.NoContextMenu) - self.dt_cavern.setReadOnly(True) - self.dt_cavern.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.dt_cavern.setObjectName("dt_cavern") - self.gridlayout2.addWidget(self.dt_cavern,0,1,1,1) - - self.dt_pacific = QtGui.QDateTimeEdit(self.gridLayout) - self.dt_pacific.setFocusPolicy(QtCore.Qt.NoFocus) - self.dt_pacific.setContextMenuPolicy(QtCore.Qt.NoContextMenu) - self.dt_pacific.setReadOnly(True) - self.dt_pacific.setButtonSymbols(QtGui.QAbstractSpinBox.UpDownArrows) - self.dt_pacific.setObjectName("dt_pacific") - self.gridlayout2.addWidget(self.dt_pacific,1,1,1,1) - - self.label_8 = QtGui.QLabel(self.gridLayout) - - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0),QtGui.QSizePolicy.Policy(5)) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) - self.label_8.setSizePolicy(sizePolicy) - self.label_8.setObjectName("label_8") - self.gridlayout2.addWidget(self.label_8,1,0,1,1) - - self.lb_pacific_utc = QtGui.QLabel(self.gridLayout) - self.lb_pacific_utc.setObjectName("lb_pacific_utc") - self.gridlayout2.addWidget(self.lb_pacific_utc,1,2,1,1) - - self.gb_dnitime = QtGui.QGroupBox(self.tab_time) - self.gb_dnitime.setGeometry(QtCore.QRect(10,220,451,181)) - self.gb_dnitime.setObjectName("gb_dnitime") - - self.gv_dniclock = QtGui.QGraphicsView(self.gb_dnitime) - self.gv_dniclock.setGeometry(QtCore.QRect(10,20,431,151)) - self.gv_dniclock.setFocusPolicy(QtCore.Qt.NoFocus) - self.gv_dniclock.setContextMenuPolicy(QtCore.Qt.NoContextMenu) - self.gv_dniclock.setAcceptDrops(False) - self.gv_dniclock.setFrameShadow(QtGui.QFrame.Plain) - self.gv_dniclock.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.gv_dniclock.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.gv_dniclock.setInteractive(False) - self.gv_dniclock.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) - self.gv_dniclock.setRenderHints(QtGui.QPainter.Antialiasing|QtGui.QPainter.SmoothPixmapTransform|QtGui.QPainter.TextAntialiasing) - self.gv_dniclock.setObjectName("gv_dniclock") + self.gridlayout2.addWidget(self.rb_dnitime,2,0,1,1) self.tabwidget.addTab(self.tab_time,"") self.tab_browse = QtGui.QWidget() @@ -1103,6 +1097,12 @@ self.tb_license.setObjectName("tb_license") self.tabwidget_about.addTab(self.tab_sub_license,"") self.tabwidget.addTab(self.tab_about,"") + + self.main_buttonbox = QtGui.QDialogButtonBox(self.centralwidget) + self.main_buttonbox.setGeometry(QtCore.QRect(10,520,451,32)) + self.main_buttonbox.setOrientation(QtCore.Qt.Horizontal) + self.main_buttonbox.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.main_buttonbox.setObjectName("main_buttonbox") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) @@ -1176,32 +1176,31 @@ self.gb_servers.setTitle(QtGui.QApplication.translate("MainWindow", "Ping servers", None, QtGui.QApplication.UnicodeUTF8)) self.button_ping.setText(QtGui.QApplication.translate("MainWindow", "Ping", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_ping), QtGui.QApplication.translate("MainWindow", "Servers", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Time zones", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_cavern_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC -0", None, QtGui.QApplication.UnicodeUTF8)) + self.label_8.setText(QtGui.QApplication.translate("MainWindow", "Cyan time:", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_pacific_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC -0", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_3.setTitle(QtGui.QApplication.translate("MainWindow", "Choose Time", None, QtGui.QApplication.UnicodeUTF8)) self.rb_earthtime.setText(QtGui.QApplication.translate("MainWindow", "Earth Time", None, QtGui.QApplication.UnicodeUTF8)) - self.rb_curtime.setText(QtGui.QApplication.translate("MainWindow", "Current Time", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_curtime.setText(QtGui.QApplication.translate("MainWindow", "Clock", None, QtGui.QApplication.UnicodeUTF8)) self.label_9.setText(QtGui.QApplication.translate("MainWindow", ":", None, QtGui.QApplication.UnicodeUTF8)) self.label_10.setText(QtGui.QApplication.translate("MainWindow", ":", None, QtGui.QApplication.UnicodeUTF8)) self.label_11.setText(QtGui.QApplication.translate("MainWindow", ":", None, QtGui.QApplication.UnicodeUTF8)) - self.rb_dniholiday.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Holiday", None, QtGui.QApplication.UnicodeUTF8)) + self.rb_dniholidays.setText(QtGui.QApplication.translate("MainWindow", "Holidays", None, QtGui.QApplication.UnicodeUTF8)) self.label_12.setText(QtGui.QApplication.translate("MainWindow", "/", None, QtGui.QApplication.UnicodeUTF8)) - self.label_4.setText(QtGui.QApplication.translate("MainWindow", ".", None, QtGui.QApplication.UnicodeUTF8)) - self.label_6.setText(QtGui.QApplication.translate("MainWindow", ".", None, QtGui.QApplication.UnicodeUTF8)) + self.cb_vailee.addItem(QtGui.QApplication.translate("MainWindow", "8 Leevosahn", None, QtGui.QApplication.UnicodeUTF8)) self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "local time", None, QtGui.QApplication.UnicodeUTF8)) self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "cavern time", None, QtGui.QApplication.UnicodeUTF8)) self.cb_earthtime_tz.addItem(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) self.rb_dnitime.setText(QtGui.QApplication.translate("MainWindow", "D\'ni Time", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Time zones", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) - self.lb_cavern_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC -0", None, QtGui.QApplication.UnicodeUTF8)) - self.label_8.setText(QtGui.QApplication.translate("MainWindow", "Cyan time:", None, QtGui.QApplication.UnicodeUTF8)) - self.lb_pacific_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC -0", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_5.setTitle(QtGui.QApplication.translate("MainWindow", "Read chatlogs", None, QtGui.QApplication.UnicodeUTF8)) self.tb_chatlog_view.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" - "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" - "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-size:9pt;\">Not implemented</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" + "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Not implemented</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) self.cb_chatlog.addItem(QtGui.QApplication.translate("MainWindow", "Not implemented", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_sub_chatlogs), QtGui.QApplication.translate("MainWindow", "Chat logs", None, QtGui.QApplication.UnicodeUTF8)) self.gb_documents.setTitle(QtGui.QApplication.translate("MainWindow", "Browse journals and notes", None, QtGui.QApplication.UnicodeUTF8)) @@ -1217,13 +1216,13 @@ self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_browse), QtGui.QApplication.translate("MainWindow", "Browse", None, QtGui.QApplication.UnicodeUTF8)) self.tb_abouttext.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" - "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" - "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-size:9pt;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" + "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget_about.setTabText(self.tabwidget_about.indexOf(self.tab_sub_about), QtGui.QApplication.translate("MainWindow", "About pyMoul", None, QtGui.QApplication.UnicodeUTF8)) self.tb_license.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" - "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" - "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-size:9pt;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" + "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget_about.setTabText(self.tabwidget_about.indexOf(self.tab_sub_license), QtGui.QApplication.translate("MainWindow", "License", None, QtGui.QApplication.UnicodeUTF8)) self.tabwidget.setTabText(self.tabwidget.indexOf(self.tab_about), QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-23 15:17:20 UTC (rev 185) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-02-23 15:19:19 UTC (rev 186) @@ -97,22 +97,6 @@ </item> </layout> </widget> - <widget class="QDialogButtonBox" name="main_buttonbox" > - <property name="geometry" > - <rect> - <x>10</x> - <y>520</y> - <width>451</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> <widget class="QTabWidget" name="tabwidget" > <property name="geometry" > <rect> @@ -1502,13 +1486,173 @@ <attribute name="title" > <string>Time</string> </attribute> + <widget class="QGroupBox" name="gb_dnitime" > + <property name="geometry" > + <rect> + <x>10</x> + <y>240</y> + <width>451</width> + <height>161</height> + </rect> + </property> + <property name="title" > + <string>D'ni time</string> + </property> + <widget class="QGraphicsView" name="gv_dniclock" > + <property name="geometry" > + <rect> + <x>10</x> + <y>20</y> + <width>431</width> + <height>131</height> + </rect> + </property> + <property name="focusPolicy" > + <enum>Qt::NoFocus</enum> + </property> + <property name="contextMenuPolicy" > + <enum>Qt::NoContextMenu</enum> + </property> + <property name="acceptDrops" > + <bool>false</bool> + </property> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> + </property> + <property name="verticalScrollBarPolicy" > + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy" > + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="interactive" > + <bool>false</bool> + </property> + <property name="alignment" > + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="renderHints" > + <set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set> + </property> + </widget> + </widget> + <widget class="QGroupBox" name="gb_caverntime" > + <property name="geometry" > + <rect> + <x>10</x> + <y>160</y> + <width>451</width> + <height>81</height> + </rect> + </property> + <property name="title" > + <string>Time zones</string> + </property> + <widget class="QWidget" native="1" name="gridLayout" > + <property name="geometry" > + <rect> + <x>10</x> + <y>20</y> + <width>292</width> + <height>56</height> + </rect> + </property> + <layout class="QGridLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item row="0" column="0" > + <widget class="QLabel" name="label_5" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Cavern time:</string> + </property> + </widget> + </item> + <item row="0" column="2" > + <widget class="QLabel" name="lb_cavern_utc" > + <property name="text" > + <string>UTC -0</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QDateTimeEdit" name="dt_cavern" > + <property name="cursor" > + <cursor>0</cursor> + </property> + <property name="focusPolicy" > + <enum>Qt::NoFocus</enum> + </property> + <property name="contextMenuPolicy" > + <enum>Qt::NoContextMenu</enum> + </property> + <property name="readOnly" > + <bool>true</bool> + </property> + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QDateTimeEdit" name="dt_pacific" > + <property name="focusPolicy" > + <enum>Qt::NoFocus</enum> + </property> + <property name="contextMenuPolicy" > + <enum>Qt::NoContextMenu</enum> + </property> + <property name="readOnly" > + <bool>true</bool> + </property> + <property name="buttonSymbols" > + <enum>QAbstractSpinBox::UpDownArrows</enum> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label_8" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Cyan time:</string> + </property> + </widget> + </item> + <item row="1" column="2" > + <widget class="QLabel" name="lb_pacific_utc" > + <property name="text" > + <string>UTC -0</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> <widget class="QGroupBox" name="groupBox_3" > <property name="geometry" > <rect> <x>10</x> <y>0</y> <width>451</width> - <height>151</height> + <height>161</height> </rect> </property> <property name="title" > @@ -1518,9 +1662,9 @@ <property name="geometry" > <rect> <x>10</x> - <y>10</y> - <width>444</width> - <height>141</height> + <y>20</y> + <width>451</width> + <height>138</height> </rect> </property> <layout class="QGridLayout" > @@ -1528,16 +1672,13 @@ <number>0</number> </property> <property name="spacing" > - <number>6</number> + <number>2</number> </property> <item row="1" column="0" > <widget class="QRadioButton" name="rb_earthtime" > <property name="text" > <string>Earth Time</string> </property> - <property name="checked" > - <bool>true</bool> - </property> </widget> </item> <item row="4" column="1" > @@ -1569,7 +1710,7 @@ <item row="0" column="0" > <widget class="QRadioButton" name="rb_curtime" > <property name="text" > - <string>Current Time</string> + <string>Clock</string> </property> </widget> </item> @@ -1678,7 +1819,7 @@ <item row="4" column="0" > <widget class="QRadioButton" name="rb_dniholidays" > <property name="text" > - <string>D'ni Holiday</string> + <string>Holidays</string> </property> </widget> </item> @@ -1705,6 +1846,12 @@ </property> <item> <widget class="QSpinBox" name="sb_fahrah" > + <property name="maximumSize" > + <size> + <width>46</width> + <height>16777215</height> + </size> + </property> <property name="maximum" > <number>15</number> </property> @@ -1718,6 +1865,12 @@ </item> <item> <widget class="QSpinBox" name="sb_fahrah_hahr" > + <property name="maximumSize" > + <size> + <width>46</width> + <height>16777215</height> + </size> + </property> <property name="maximum" > <number>249</number> </property> @@ -1751,16 +1904,35 @@ </item> <item> <widget class="QComboBox" name="cb_vailee" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="minimumSize" > <size> - <width>0</width> + <width>105</width> <height>0</height> </size> </property> + <item> + <property name="text" > + <string>8 Leevosahn</string> + </property> + </item> </widget> </item> <item> <widget class="QSpinBox" name="sb_yahr" > + <property name="maximumSize" > + <size> + <width>46</width> + <height>16777215</height> + </size> + </property> <property name="maximum" > <number>29</number> </property> @@ -1768,7 +1940,7 @@ <number>1</number> </property> <property name="value" > - <number>1</number> + <number>29</number> </property> </widget> </item> @@ -1860,166 +2032,6 @@ </layout> </widget> </widget> - <widget class="QGroupBox" name="gb_caverntime" > - <property name="geometry" > - <rect> - <x>10</x> - <y>150</y> - <width>451</width> - <height>71</height> - </rect> - </property> - <property name="title" > - <string>Time zones</string> - </property> - <widget class="QWidget" native="1" name="gridLayout" > - <property name="geometry" > - <rect> - <x>10</x> - <y>10</y> - <width>292</width> - <height>56</height> - </rect> - </property> - <layout class="QGridLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="0" column="0" > - <widget class="QLabel" name="label_5" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string>Cavern time:</string> - </property> - </widget> - </item> - <item row="0" column="2" > - <widget class="QLabel" name="lb_cavern_utc" > - <property name="text" > - <string>UTC -0</string> - </property> - </widget> - </item> - <item row="0" column="1" > - <widget class="QDateTimeEdit" name="dt_cavern" > - <property name="cursor" > - <cursor>0</cursor> - </property> - <property name="focusPolicy" > - <enum>Qt::NoFocus</enum> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="readOnly" > - <bool>true</bool> - </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - </widget> - </item> - <item row="1" column="1" > - <widget class="QDateTimeEdit" name="dt_pacific" > - <property name="focusPolicy" > - <enum>Qt::NoFocus</enum> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="readOnly" > - <bool>true</bool> - </property> - <property name="buttonSymbols" > - <enum>QAbstractSpinBox::UpDownArrows</enum> - </property> - </widget> - </item> - <item row="1" column="0" > - <widget class="QLabel" name="label_8" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string>Cyan time:</string> - </property> - </widget> - </item> - <item row="1" column="2" > - <widget class="QLabel" name="lb_pacific_utc" > - <property name="text" > - <string>UTC -0</string> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - <widget class="QGroupBox" name="gb_dnitime" > - <property name="geometry" > - <rect> - <x>10</x> - <y>220</y> - <width>451</width> - <height>181</height> - </rect> - </property> - <property name="title" > - <string>D'ni time</string> - </property> - <widget class="QGraphicsView" name="gv_dniclock" > - <property name="geometry" > - <rect> - <x>10</x> - <y>20</y> - <width>431</width> - <height>151</height> - </rect> - </property> - <property name="focusPolicy" > - <enum>Qt::NoFocus</enum> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="acceptDrops" > - <bool>false</bool> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <property name="verticalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="horizontalScrollBarPolicy" > - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="interactive" > - <bool>false</bool> - </property> - <property name="alignment" > - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - <property name="renderHints" > - <set>QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set> - </property> - </widget> - </widget> </widget> <widget class="QWidget" name="tab_browse" > <attribute name="title" > @@ -2068,8 +2080,8 @@ <property name="html" > <string><html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;">Not implemented</p></body></html></string> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Not implemented</p></body></html></string> </property> <property name="textInteractionFlags" > <enum>Qt::TextSelectableByMouse</enum> @@ -2330,8 +2342,8 @@ <property name="html" > <string><html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p></body></html></string> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> </property> <property name="textInteractionFlags" > <enum>Qt::TextBrowserInteraction</enum> @@ -2357,8 +2369,8 @@ <property name="html" > <string><html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p></body></html></string> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> </property> <property name="textInteractionFlags" > <enum>Qt::TextSelectableByMouse</enum> @@ -2371,6 +2383,22 @@ </widget> </widget> </widget> + <widget class="QDialogButtonBox" name="main_buttonbox" > + <property name="geometry" > + <rect> + <x>10</x> + <y>520</y> + <width>451</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> Modified: pymoul/trunk/src/moul/qt/utils.py =================================================================== --- pymoul/trunk/src/moul/qt/utils.py 2007-02-23 15:17:20 UTC (rev 185) +++ pymoul/trunk/src/moul/qt/utils.py 2007-02-23 15:19:19 UTC (rev 186) @@ -38,14 +38,17 @@ from PyQt4.QtCore import SIGNAL from PyQt4 import QtGui from PyQt4 import QtCore +from datetime import datetime from types import UnboundMethodType from types import FunctionType from moul.osdependent import __FROZEN__ -from logging import getLogger +from moul.time.utils import normalizeTZ +from moul.time.utils import UTC -LOG = getLogger('moul.qt.utils') +LOG = logging.getLogger('moul.qt.utils') + _marker=object() SLOT_RE = re.compile('^on_(.+)_([^_]+)$') @@ -155,8 +158,8 @@ @type parent: a QObject based instance """ QtCore.QObject.__init__(self, parent) + connectSlotsByName(container=parent, callobj=self) self.initialize() - connectSlotsByName(container=parent, callobj=self) @property def context(self): @@ -504,3 +507,21 @@ if text is None: text = context.trUtf8("Sorry, this feature is not implemented yet!") return infoMB(context, title, text) + +def qdt2dt(qdt, tzinfo=UTC): + """Convert QDateTime to datetime.datetime + """ + uqtd = qdt.toUTC() + qd, qt = uqtd.date(), uqtd.time() + utc_dt = datetime(qd.year(), qd.month(), qd.day(), + qt.hour(), qt.minute(), qt.second(), + tzinfo=UTC) + return normalizeTZ(tzinfo, utc_dt) + +def dt2qdt(dt): + """Convert datetime.datetime to QDateTime + """ + udt = normalizeTZ(UTC, dt) + qd = QtCore.QDate(udt.year, udt.month, udt.day) + qt = QtCore.QTime(udt.hour, udt.minute, udt.second) + return QtCore.QDateTime(qd, qt, QtCore.Qt.UTC) Modified: pymoul/trunk/src/moul/time/utils.py =================================================================== --- pymoul/trunk/src/moul/time/utils.py 2007-02-23 15:17:20 UTC (rev 185) +++ pymoul/trunk/src/moul/time/utils.py 2007-02-23 15:19:19 UTC (rev 186) @@ -28,10 +28,14 @@ pkg_resources.require("pytz>=2006p") from datetime import datetime +from logging import getLogger from pytz import utc as UTC from pytz import timezone from pytz import common_timezones + +LOG = getLogger('timeutils') + # timestamp 0 - start of unix time UNIX_0 = datetime(1970, 1, 1, 0, 0, 0, 0, tzinfo=UTC) @@ -76,16 +80,11 @@ """ return UTC.localize(datetime.utcnow()) -def ts2utc(ts): - """Get utc from time stamp +def normalizeTZ(tz=UTC, dt=None): + """Normalize a datetime object using another tz """ - return UTC.localize(datetime.fromtimestamp(ts)) - -def normalizeTZ(tz, utc_dt=None): - """Normalize a datetime object with UTC tz using another tz - """ - if utc_dt is None: - utc_dt = utcnow() + if dt is None: + dt = utcnow() if isinstance(tz, basestring): tz = timezone(tz) - return tz.normalize(utc_dt.astimezone(tz)) + return tz.normalize(dt.astimezone(tz)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-05-24 00:30:39
|
Revision: 289 http://pymoul.svn.sourceforge.net/pymoul/?rev=289&view=rev Author: tiran Date: 2007-05-23 17:30:38 -0700 (Wed, 23 May 2007) Log Message: ----------- Adding first code of the chat relay IRC bot daemon. Modified Paths: -------------- pymoul/trunk/src/moul/time/podage.py Added Paths: ----------- pymoul/trunk/src/moul/chatrelay/ pymoul/trunk/src/moul/chatrelay/__init__.py pymoul/trunk/src/moul/chatrelay/io.py pymoul/trunk/src/moul/chatrelay/ircclient.py Added: pymoul/trunk/src/moul/chatrelay/__init__.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/__init__.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/__init__.py 2007-05-24 00:30:38 UTC (rev 289) @@ -0,0 +1,22 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +""" +__author__ = "Christian Heimes" +__version__ = "$Id: __init__.py 108 2007-01-31 14:46:54Z tiran $" +__revision__ = "$Revision: 108 $" Property changes on: pymoul/trunk/src/moul/chatrelay/__init__.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Added: pymoul/trunk/src/moul/chatrelay/io.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/io.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/io.py 2007-05-24 00:30:38 UTC (rev 289) @@ -0,0 +1,91 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +""" +__author__ = "Christian Heimes" +__version__ = "$Id: __init__.py 108 2007-01-31 14:46:54Z tiran $" +__revision__ = "$Revision: 108 $" + +import os + +class NullFormatter(object): + """A formatter that doesn't change the msg + """ + def format(self, msg): + return msg + +class LogFileReader(object): + """Read log file + """ + def __init__(self, fname): + self._fname = fname + self._fd = None + self._fifo = [] + self._incomplete = [] + + def exists(self): + return os.path.isfile(self._fname) + + def open(self): + self._fd = open(self._fname, 'r') + self._fd.seek(0, 2) # eof + + def close(self): + if self._fd: + self._fd.close() + self._fd = None + self._fifo = [] + self._incomplete = [] + + def _read(self): + fd = self._fd + data = self.read() + if not data: + return + lines = data.split(os.linesep) + # XXX - KISS, don't check for imcomplete lines + for line in lines: + line = line.strip() + if line: + self._fifo.append(line) + + def __iter__(self): + self._read() + return self + + def next(self): + try: + return self._fifo.pop(0) + except IndexError: + raise StopIteration + +class MessageWriter(object): + """Write messages to a channel + """ + maxlength = 80 + + def __init__(self, client, channel, formatter=None): + self._client = client + self._channel = channel + if formatter is None: + formatter = NullFormatter() + self._fmt = formatter + + def log(self, msg): + msg = self._fmt.format(msg) + self._client.say(self._channel, msg, self.maxlength) Property changes on: pymoul/trunk/src/moul/chatrelay/io.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Added: pymoul/trunk/src/moul/chatrelay/ircclient.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/ircclient.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/ircclient.py 2007-05-24 00:30:38 UTC (rev 289) @@ -0,0 +1,285 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Chat relay using Twisted IRC + +Partly based on Buildbot's IRC support +""" +__author__ = "Christian Heimes" +__version__ = "$Id: __init__.py 108 2007-01-31 14:46:54Z tiran $" +__revision__ = "$Revision: 108 $" + +import sys + +from twisted.words.protocols import irc +from twisted.internet import reactor, protocol +from twisted.python import log, failure + +from moul.chatrelay.io import MessageWriter +from moul.chatrelay.io import LogFileReader + +def requirePasswd(func): + """@decorator""" + func.requirePassword = True + return func + +def doesRequirePasswd(func): + return getattr(func, 'requirePassword', False) + +def usage(usage): + """@decorator""" + def wrapper(func): + func.usage = usage + return func + return wrapper + +class UsageError(ValueError): + def __init__(self, string = "Invalid usage", *more): + ValueError.__init__(self, string, *more) + +class InvalidPassword(UsageError): + def __init__(self, string = "Invalid password", *more): + ValueError.__init__(self, string, *more) + +class ChatRelayBot(irc.IRCClient): + """A chat relay bot""" + def __init__(self, nickname, channel, realname=None, username=None, + serverpasswd=None, nickpasswd=None, adminpasswd=None): + """ + """ + self.nickname = nickname + self.channel = channel + self.realname = realname + self.username = username + self.password = serverpasswd + self.nickpasswd = nickpasswd + self.adminpasswd = adminpasswd + + def connectionMade(self): + irc.IRCClient.connectionMade(self) + + def connectionLost(self, reason): + irc.IRCClient.connectionLost(self, reason) + + # callbacks for events + + def signedOn(self): + if self.nickpasswd: + self.msg("Nickserv", "IDENTIFY %s" % self.nickpasswd) + self.join(self.channel) + + def joined(self, channel): + log.msg("I have joined", channel) + + def left(self, channel): + log.msg("I have left", channel) + + def kickedFrom(self, channel, kicker, message): + log.msg("I have been kicked from %s by %s: %s" % + (channel, kicker, message)) + + def privmsg(self, user, channel, message): + """This will get called when the bot receives a message.""" + user = user.split('!', 1)[0] + channel = channel.lower() + if channel == self.nickname.lower(): + # private message + message = "%s: %s" % (self.nickname, message) + reply = user + private = True + else: + reply = channel + private = False + + if message.startswith("%s:" % self.nickname): + message = message[len("%s:" % self.nickname):] + + message = message.lstrip() + + parts = message.split(' ', 1) + if len(parts) == 1: + parts = parts + [''] + cmd, args = parts + log.msg("irc command", cmd) + + error = None + try: + meth, args = self.getCommandMethod(cmd, args, private) + if not meth and message[-1] == '!': + meth = self.command_EXCITED + + if meth: + meth(user, reply, args.strip()) + except UsageError, e: + self.reply(reply, str(e)) + except: + f = failure.Failure() + log.err(f) + error = "Something bad happened (see logs): %s" % f.type + + if error: + try: + self.reply(reply, error) + except: + log.err() + + #self.say(channel, "count %d" % self.counter) + #self.counter += 1 + + def reply(self, dest, message): + # maybe self.notice(dest, message) instead? + self.msg(dest, message) + + def getCommandMethod(self, command, args, private): + meth = getattr(self, 'command_' + command.upper(), None) + if meth is not None: + if doesRequirePasswd(meth): + if not private: + raise UsageError("This command requires a password.") + parts = args.split(' ', 1) + if len(parts) == 1: + parts = parts + [''] + password, args = parts + if password != self.adminpasswd: + raise InvalidPassword() + return meth, args + + @usage("Say hello") + def command_HELLO(self, user, reply, args): + self.reply(reply, "yes?") + + @usage("Say something exciting") + def command_EXCITED(self, user, reply, args): + # like 'buildbot: destroy the sun!' + self.reply(reply, "What you say!") + + def build_commands(self): + commands = [] + for k, v in self.__class__.__dict__.items(): + if k.startswith('command_'): + name = k[8:].lower() + if doesRequirePasswd(v): + name = name+'*' + commands.append(name) + commands.sort() + return commands + + @usage("help <command> - Give help for <command>") + def command_HELP(self, user, reply, args): + args = args.split() + if len(args) == 0: + self.reply(reply, "Get help on what? (try 'help <foo>', or 'commands' for a command list)") + return + command = args[0] + meth = self.getCommandMethod(command) + if not meth: + raise UsageError, "no such command '%s'" % command + usage = getattr(meth, 'usage', None) + if usage: + self.reply(reply, "Usage: %s" % usage) + else: + self.reply(reply, "No usage info for '%s'" % command) + + @usage("commands - List available commands") + def command_COMMANDS(self, user, reply, args): + commands = self.build_commands() + msg = "Chat Relay commands: " + ", ".join(commands) + self.reply(reply, msg) + + @usage("Dance! Let's do the time warp!") + def command_DANCE(self, user, reply, args): + reactor.callLater(1.0, self.reply, reply, "0-<") + reactor.callLater(3.0, self.reply, reply, "0-/") + reactor.callLater(3.5, self.reply, reply, "0-\\") + + @usage("Open the chatlog") + @requirePasswd + def command_OPENLOG(self, user, reply, args): + self.reply(reply, 'Opening chatlog') + + @usage("Close the chatlog") + @requirePasswd + def command_CLOSELOG(self, user, reply, args): + self.reply(reply, 'Closing chatlog') + +class ThrottledClientFactory(protocol.ClientFactory): + lostDelay = 2 + failedDelay = 60 + def clientConnectionLost(self, connector, reason): + reactor.callLater(self.lostDelay, connector.connect) + def clientConnectionFailed(self, connector, reason): + reactor.callLater(self.failedDelay, connector.connect) + +class ChatRelayBotFactory(ThrottledClientFactory): + protocol = ChatRelayBot + + shuttingDown = False + p = None + + def __init__(self, nickname, channel, realname=None, username=None, + serverpasswd=None, nickpasswd=None, adminpasswd=None): + """ + """ + self.nickname = nickname + self.channel = channel + self.realname = realname + self.username = username + self.password = serverpasswd + self.nickpasswd = nickpasswd + self.adminpasswd = adminpasswd + + def __getstate__(self): + d = self.__dict__.copy() + del d['p'] + return d + + def shutdown(self): + self.shuttingDown = True + if self.p: + self.p.quit("Shutting down") + + def buildProtocol(self, address): + p = self.protocol(self.nickname, self.channel, self.realname, + self.username, self.password, self.nickpasswd, + self.adminpasswd) + p.factory = self + self.p = p + return p + + def clientConnectionLost(self, connector, reason): + if self.shuttingDown: + log.msg("not scheduling reconnection attempt") + return + ThrottledClientFactory.clientConnectionLost(self, connector, reason) + + def clientConnectionFailed(self, connector, reason): + if self.shuttingDown: + log.msg("not scheduling reconnection attempt") + return + ThrottledClientFactory.clientConnectionFailed(self, connector, reason) + +def main(): + log.startLogging(sys.stdout) + f = ChatRelayBotFactory('TiransRelay', '#urubot', adminpasswd="moul") + # connect factory to this host and port + reactor.connectTCP("tsunami.justirc.net", 6667, f) + + # run bot + reactor.run() + +if __name__ == '__main__': + main() Property changes on: pymoul/trunk/src/moul/chatrelay/ircclient.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Modified: pymoul/trunk/src/moul/time/podage.py =================================================================== --- pymoul/trunk/src/moul/time/podage.py 2007-04-28 13:27:31 UTC (rev 288) +++ pymoul/trunk/src/moul/time/podage.py 2007-05-24 00:30:38 UTC (rev 289) @@ -303,9 +303,9 @@ fd.close() if __name__ == '__main__': - forumTimeTable(tzlist=('CET',)) - #forumTimeTable(tzlist=('UTC',)) + #forumTimeTable(tzlist=('CET',)) + forumTimeTable(tzlist=('UTC',)) #forumTimeTable(tzlist=('US/Pacific',)) #forumTimeTable() - #allTzList() + allTzList() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-05-24 17:41:18
|
Revision: 292 http://pymoul.svn.sourceforge.net/pymoul/?rev=292&view=rev Author: tiran Date: 2007-05-24 10:41:19 -0700 (Thu, 24 May 2007) Log Message: ----------- Enhanced formatter Modified Paths: -------------- pymoul/trunk/src/moul/chatrelay/io.py pymoul/trunk/src/moul/file/chatlog.py Modified: pymoul/trunk/src/moul/chatrelay/io.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/io.py 2007-05-24 17:19:06 UTC (rev 291) +++ pymoul/trunk/src/moul/chatrelay/io.py 2007-05-24 17:41:19 UTC (rev 292) @@ -24,15 +24,34 @@ import os from moul.file.chatlog import ChatlogParser -from moul.file.chatlog import ChatLineError -from moul.file.chatlog import CHAT_PRIVMSG +from moul.file.chatlog import * class NullFormatter(object): """A formatter that doesn't change the msg """ def format(self, msg): - return msg + return str(msg) +class MOULLogFormatter(NullFormatter): + """Formatter for MOUL + """ + + def __init__(self, skipprivate=True): + self.skipprivate = skipprivate + + def format(self, msg): + if self.skipprivate and msg.typ & CHAT_PRIVMSG: + result = None + elif msg.typ == CHAT_PRIVMSGTO: + result = "-> %s" % msg + elif msg.typ == CHAT_PRIVMSGFROM: + result = "<- %s" % msg + elif msg.typ == CHAT_ACTION: + result = "* %s" % msg + if msg.important: + result = "%B%s" msg + return str(msg) + class LogFileReader(object): """Read log file """ @@ -67,15 +86,7 @@ lines = data.split(os.linesep) # XXX - KISS, don't check for imcomplete lines for line in ChatlogParser(lines): - if isinstance(ChatLineError): - self._fifo.append("PARSER ERROR: " + line) - else: - if line.typ & CHAT_PRIVMSG: - continue - elif line.important: - self._fifo.append("*** " + line) - else: - self._fifo.append(line) + self._fifo.append(line) def __iter__(self): self._read() @@ -99,4 +110,6 @@ def log(self, msg): msg = self._fmt.format(msg) + if not msg: + return self._client.say(self._channel, msg) Modified: pymoul/trunk/src/moul/file/chatlog.py =================================================================== --- pymoul/trunk/src/moul/file/chatlog.py 2007-05-24 17:19:06 UTC (rev 291) +++ pymoul/trunk/src/moul/file/chatlog.py 2007-05-24 17:41:19 UTC (rev 292) @@ -42,6 +42,7 @@ from moul.file.utils import fileModTime # Chat line types +CHAT_UNKNOWN = -1 CHAT_START = 1 << 0 CHAT_STOP = 1 << 1 CHAT_ERROR = 1 << 2 @@ -355,12 +356,11 @@ def parse(self, line): mo = CHAT_RE.match(line) if mo is None: - self.error(line) - return + return ChatLine(line, (1970, 1, 1, 0, 0, 0), CHAT_UNKNOWN) d = mo.groupdict() date = (self._year, int(d['M']), int(d['D']), int(d['h']), int(d['m']), int(d['s'])) - typ = None + typ = CHAT_UNKNOWN msg = d['msg'] info = {} important = False @@ -368,7 +368,7 @@ typ = CHAT_MSG mo = MSG_RE.match(msg) if mo is None: - return ChatLineError(line) + return ChatLine(msg, dte, CHAT_UNKNOWN) info = mo.groupdict() else: if msg == CHATLOG_START: @@ -394,10 +394,7 @@ if user: if user in USER_IMPORTANT: important = True - if typ is not None: - return ChatLine(msg, date, typ, important, info) - else: - return ChatLineError(line) + return ChatLine(msg, date, typ, important, info) def __iter__(self): for line in self._iterable: @@ -416,11 +413,3 @@ def asDatetime(self): return datetime(*self.date) - -class ChatLineError(unicode): - def __new__(cls, ustr): - self = unicode.__new__(cls, ustr) - return self - - def __nonzero(self): - return False \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-05-29 13:49:35
|
Revision: 296 http://pymoul.svn.sourceforge.net/pymoul/?rev=296&view=rev Author: tiran Date: 2007-05-29 06:44:29 -0700 (Tue, 29 May 2007) Log Message: ----------- More work on the IRC chat relay system Modified Paths: -------------- pymoul/trunk/src/moul/chatrelay/filter.py pymoul/trunk/src/moul/chatrelay/formatter.py pymoul/trunk/src/moul/chatrelay/interfaces.py pymoul/trunk/src/moul/file/chatlog.py pymoul/trunk/src/moul/file/tests/test_chatlog.py Added Paths: ----------- pymoul/trunk/src/moul/chatrelay/handler.py Removed Paths: ------------- pymoul/trunk/src/moul/chatrelay/parser.py Modified: pymoul/trunk/src/moul/chatrelay/filter.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/filter.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/chatrelay/filter.py 2007-05-29 13:44:29 UTC (rev 296) @@ -2,6 +2,7 @@ from moul.chatrelay.interfaces import ILineFilter from moul.chatrelay.interfaces import ISnoopyLineFilter +from moul.chatrelay.interfaces import IConfigureableFilter from moul.file.chatlog import (CHAT_UNKNOWN, CHAT_PRIVMSG, CHAT_PRIVMSGTO, CHAT_PRIVMSGFROM, CHAT_ACTION, CHAT_ERROR, CHAT_MSG) @@ -9,42 +10,43 @@ __all__ = [obj for obj in globals() if ILineFilter.isImplementedBy(obj)] class NullFilter(object): + """Filter nothing + """ implements(ILineFilter) - name = 'Null filter' def filter(self, line, **kwargs): return line, kwargs class HightlightImportantFilter(object): + """Highlight important people + """ implements(ILineFilter) - name = 'Highlight important people' def filter(self, line, **kwargs): if kwargs.get('important', False): kwargs['highlight'] = True return line, kwargs -class AbstractMessageFilter(object): +class _AbstractMessageFilter(object): implements(ILineFilter) - name = None - msg_type = None + msg_flags = None def __init__(self): - assert self.msg_type, "No message type applied" + assert self.msg_flags, "No message type applied" def filter(self, line, **kwargs): typ = kwargs.get('type', CHAT_UNKNOWN) - if typ & self.msg_type: - return None, None + if typ & self.msg_flags: + kwargs['skip'] = True return line, kwargs -class PrivateMessageFilter(AbstractMessageFilter): +class PrivateMessageFilter(_AbstractMessageFilter): name = 'Private message filter' - msg_type = CHAT_PRIVMSG + msg_flags = CHAT_PRIVMSG -class ErrorMessageFilter(AbstractMessageFilter): +class ErrorMessageFilter(_AbstractMessageFilter): name = 'Error message filter' - msg_type = CHAT_ERROR + msg_flags = CHAT_ERROR class NonImportantFilter(object): implements(ILineFilter) @@ -52,5 +54,6 @@ def filter(self, line, **kwargs): if not kwargs.get('important', False): - return None, None + kwargs['skip'] = True return line, kwargs + Modified: pymoul/trunk/src/moul/chatrelay/formatter.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/formatter.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/chatrelay/formatter.py 2007-05-29 13:44:29 UTC (rev 296) @@ -8,25 +8,41 @@ __all__ = [obj for obj in globals() if IOutputFormatter.isImplementedBy(obj)] class NullFormatter(object): + """Null formatter + + The null formatter returns the line without changing it. + """ implements(IOutputFormatter) - name = 'Null formatter' def format(self, line, **kwargs): + if kwargs.get('skip', False): + return None return line class MOULFormatter(object): + """MOUL formatter + + The MOUL formatter formats the text based on its type. It also understands + some additional keyword arguments: + + * highlight: text is highlighted with bold characters + * skip: text is skipped (no output) + """ implements(IOutputFormatter) name = 'MOUL formatter' def format(self, line, **kwargs): + if not line: + return typ = kwargs.get('type', CHAT_UNKNOWN) - highlight = kwargs.get('highlight', False) if typ == CHAT_PRIVMSGTO: line = "-> %s" % line elif typ == CHAT_PRIVMSGFROM: line = "<- %s" % line elif typ == CHAT_ACTION: line = "* %s" % line - if highlight: + if kwargs.get('highlight', False): line = "%B%s" % line + if kwargs.get('skip', False): + return None return line Copied: pymoul/trunk/src/moul/chatrelay/handler.py (from rev 295, pymoul/trunk/src/moul/chatrelay/parser.py) =================================================================== --- pymoul/trunk/src/moul/chatrelay/handler.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/handler.py 2007-05-29 13:44:29 UTC (rev 296) @@ -0,0 +1,37 @@ +import os +from zope.interface import implements +from moul.file.chatlog import ChatlogParser +from moul.chatrelay.interfaces import IInputHandler + +__all__ = [obj for obj in globals() if IInputHandler.isImplementedBy(obj)] + +class NullHandler(object): + implements(IInputHandler) + name = 'Null parser' + delimiter = '\n' + + def __init__(self, delimiter=None, **kwargs): + if delimiter: + self.delimiter = delimiter + self._buffer = '' + + def handle(self, raw): + data = self._buffer + raw + lines = data.split(self.delimiter) + self._buffer = lines.pop(-1) + for line in lines: + yield self.parse(line) + + def parse(self, line): + return line, {} + +class MOULChatlogHandler(NullHandler): + name = 'MOUL chatlog parser' + delimiter = os.linesep + + def __init__(self): + super(MOULChatlogHandler).__init__() + self._parser = ChatlogParser([]) + + def parse(self, line): + return self._parser.parse(line) Modified: pymoul/trunk/src/moul/chatrelay/interfaces.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/interfaces.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/chatrelay/interfaces.py 2007-05-29 13:44:29 UTC (rev 296) @@ -4,8 +4,9 @@ class IFileAppendWatchService(Interface): """A service which monitors text files and calls the callback for new lines """ + default_interval = Attribute("Default interval length in seconds") - def monitorFile(path, callback, errback=None): + def monitorFile(path, callback, errback=None, interval=None): """Monitor a file @param path: path to a file @@ -14,8 +15,26 @@ @type callback: callable @param errback: errback function(path, error) @type errback: callable + @param interval: interval in seconds (None for default interval + @type interval: int or None """ + + def pauseFile(path): + """Pause monitoring the file (closes fd) + @param path: path to a registered file + @type path: string + """ + + def resumeFile(path, fromEnd=True): + """Pause monitoring the file (closes fd) + + @param path: path to a registered file + @type path: string + @param fromEnd: start from EOF or last position + @type fromEnd: bool + """ + def unmonitorFile(path): """Stop monitoring files @@ -30,10 +49,19 @@ @rtype: list """ -class IInputParser(Interface): - """Parse input data +class IInputHandler(Interface): + """Handle raw input and parse it """ - name = Attribute("name of the parser") + delimiter = Attribute("line delimiter (default: '\n')") + + def handle(raw): + """Handle raw data + + @param raw: raw data + @type raw: string + @return: parsed data as an iterable + @rtype: generator yielding (str, dict) + """ def parse(line): """Parse a single line @@ -46,17 +74,19 @@ class ILineFilter(Interface): """A line filter + + In order to suppress the output of a line the filter may set + kwargs['skip'] to True. """ - name = Attribute("name of the filter") def filter(line, **kwargs): - """ + """Filter a line @param line: the line to filter @type line: string @param kwargs: additional information - @return: (filtered line, kwargs) or None, None - @rtype: (string, dict) / None, None + @return: (filtered line, kwargs) + @rtype: (string, dict) """ class ISnoopyLineFilter(ILineFilter): @@ -75,10 +105,16 @@ @return: None """ +class IConfigureableFilter(ILineFilter): + """A filter which may be configured using commands + """ + def listCommands(): + """List commands XXX: finish me + """ + class IOutputFormatter(Interface): """A line formatter """ - name = Attribute("name of the output formatter") def format(line, **kwargs): """Format a line @@ -86,8 +122,8 @@ @param line: the line to filter @type line: string @param kwargs: additional information - @return: a formatted line - @rtype: string + @return: a formatted line or None + @rtype: string, None """ class IChatRelay(Interface): @@ -121,3 +157,7 @@ @param name: name of the filter @type name: string """ + + def listFilters(): + """Return a list of filters + """ Deleted: pymoul/trunk/src/moul/chatrelay/parser.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/parser.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/chatrelay/parser.py 2007-05-29 13:44:29 UTC (rev 296) @@ -1,27 +0,0 @@ -from zope.interface import implements - -from moul.file.chatlog import ChatlogParser - -from moul.chatrelay.interfaces import IInputParser - -__all__ = [obj for obj in globals() if IInputParser.isImplementedBy(obj)] - -class NullParser(object): - implements(IInputParser) - name = 'Null parser' - - def __init__(self, *args, **kwargs): - pass - - def parse(self, line): - return line, {} - -class MOULChatlogParser(ChatlogParser): - implements(IInputParser) - name = 'MOUL chatlog parser' - - def __init__(self, year): - self.setYear(year) - - def setYear(self, year): - self._year = int(year) Modified: pymoul/trunk/src/moul/file/chatlog.py =================================================================== --- pymoul/trunk/src/moul/file/chatlog.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/file/chatlog.py 2007-05-29 13:44:29 UTC (rev 296) @@ -349,17 +349,17 @@ New idea, new design """ - def __init__(self, iterable=[], year=2007): + def __init__(self, iterable): self._iterable = iterable - self._year = year # XXX def parse(self, line): mo = CHAT_RE.match(line) if mo is None: - return ChatLine(line, (1970, 1, 1, 0, 0, 0), CHAT_UNKNOWN) + return line, {'type' : CHAT_UNKNOWN} d = mo.groupdict() - dt = (self._year, int(d['M']), int(d['D']), + dt = (0, int(d['M']), int(d['D']), int(d['h']), int(d['m']), int(d['s'])) + dt = self.estimateDT(dt) msg = d['msg'] info = {'type' : CHAT_UNKNOWN, 'datetime' : dt, 'important' : False} if len(d['space']) == 2: @@ -393,6 +393,13 @@ if user in USER_IMPORTANT: info['important'] = True return msg, info + + def estimateDT(self, lst): + lt = localtime() + year = lt[0] + if lst[1:2] == (12, 31) and lt[1:2] == (1, 1): + year = year - 1 + return (year,) + lst[1:] def __iter__(self): for line in self._iterable: Modified: pymoul/trunk/src/moul/file/tests/test_chatlog.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_chatlog.py 2007-05-28 16:53:00 UTC (rev 295) +++ pymoul/trunk/src/moul/file/tests/test_chatlog.py 2007-05-29 13:44:29 UTC (rev 296) @@ -41,17 +41,14 @@ parser = ChatlogParser(TEST_LOG) results = list(iter(parser)) fue = self.failUnlessEqual - for result in results: - fue(result.datetime, (2007, 1, 2, 3, 4, 5)) - fue(results[0].typ, CHAT_START) - fue(results[1].typ, CHAT_STOP) - fue(results[2].typ, CHAT_PRIVMSGFROM) - fue(results[3].typ, CHAT_ERROR) - fue(results[4].typ, CHAT_MSG) - fue(results[5].typ, CHAT_PRIVMSGTO) - fue(results[6].typ, CHAT_ACTION) + for msg, info in results: + fue(info['datetime'], (2007, 1, 2, 3, 4, 5)) + for i, t in enumerate((CHAT_START, CHAT_STOP, CHAT_PRIVMSGFROM, + CHAT_ERROR, CHAT_MSG, CHAT_PRIVMSGTO)): + msg, info = results[i] + fue(info['type'], t) for i in (2, 4, 5): - fue(results[i].info['user'], 'USER') + fue(results[i][1]['user'], 'USER') def test_suite(): return unittest.TestSuite(( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-17 22:28:08
|
Revision: 43 http://pymoul.svn.sourceforge.net/pymoul/?rev=43&view=rev Author: tiran Date: 2007-01-17 14:28:07 -0800 (Wed, 17 Jan 2007) Log Message: ----------- * Auto change log level based on sys.frozen * Added some comments to time.dni * Finally the threaded server ping is working as expected Modified Paths: -------------- pymoul/trunk/src/moul/log.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui pymoul/trunk/src/moul/qt/ui/moulqt_rc.py pymoul/trunk/src/moul/time/dni.py Modified: pymoul/trunk/src/moul/log.py =================================================================== --- pymoul/trunk/src/moul/log.py 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/log.py 2007-01-17 22:28:07 UTC (rev 43) @@ -22,8 +22,15 @@ __revision__ = "$Revision$" import logging +import sys -logging.basicConfig(level=logging.DEBUG, +# py2exe sets sys.frozen +if getattr(sys, 'frozen', False): + level = logging.ERROR +else: + level = logging.DEBUG + +logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S' ) Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-17 22:28:07 UTC (rev 43) @@ -17,6 +17,8 @@ # """Moul QT GUI main windows """ +from __future__ import with_statement + __author__ = "Christian Heimes" __version__ = "$Id$" __revision__ = "$Revision$" @@ -24,18 +26,19 @@ import sys from PyQt4 import QtGui -from PyQt4.QtCore import QString -from PyQt4.QtCore import QStringList +from PyQt4 import QtCore from PyQt4.QtCore import pyqtSignature from PyQt4.QtCore import SIGNAL -from PyQt4.QtCore import QTimer from moul.qt.ui.mainwindow import Ui_MainWindow from moul.time.cavern import CavernTime from moul.file.wdysini import GraphicsIni from moul.server.ping import ServerList from moul.server.ping import isSocketError +from moul.log import getLogger +LOG = getLogger('moul.qt') + class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) @@ -52,18 +55,19 @@ """init graphics tab """ self._graphicsini = GraphicsIni() - length = len(self._graphicsini._videomodes) -1 + length = len(self._graphicsini._videomodes) - 1 self.slid_screenres.setMaximum(length) self.connect(self.slid_screenres, SIGNAL("valueChanged(int)"), self.on_slid_screenres_changed) self.connect(self.slid_screenres, SIGNAL("sliderMoved(int)"), self.on_slid_screenres_changed) + @pyqtSignature("int") def on_slid_screenres_changed(self, idx): """SIGNAL: valueChanged (int) """ txt = self._graphicsini.getVidModeHuman(idx) - self.lb_screenres.setText(QString(txt)) + self.lb_screenres.setText(QtCore.QString(txt)) # ************************************************************************ # time zones @@ -75,7 +79,7 @@ self._timezone_update() # create a timer to update the display every second - self._timezone_timer = timer = QTimer(self) + self._timezone_timer = timer = QtCore.QTimer(self) timer.setInterval(1000) # 1 sec # TODO: needs optimization? run only when timer tab is active self.connect(timer, SIGNAL('timeout()'), self.on_timezone_timer_timeout) @@ -90,12 +94,13 @@ off = ct['cavern']['utcoffset'] txt = "UTC %s%i" % (off[0], abs(off[1])) - self.lb_cavern_utc.setText(QString(txt)) + self.lb_cavern_utc.setText(QtCore.QString(txt)) off = ct['pacific']['utcoffset'] txt = "UTC %s%i" % (off[0], abs(off[1])) - self.lb_pacific_utc.setText(QString(txt)) - + self.lb_pacific_utc.setText(QtCore.QString(txt)) + + @pyqtSignature("") def on_timezone_timer_timeout(self): """SIGNAL: QTimer timeout """ @@ -108,35 +113,83 @@ def _ping_init(self): """init ping tab """ - self.connect(self.button_ping, SIGNAL("clicked()"), self.on_button_ping_clicked) + self._ping_thread = thread = PingServerThread() + self.connect(self.button_ping, SIGNAL("clicked"), + self.on_button_ping_clicked) - def _ping_servers(self): - # TODO: Use a seperate thread! + self.connect(thread, SIGNAL("started"), + self.on_pingthread_started) + self.connect(thread, SIGNAL("done()"), + self.on_pingthread_done) + self.connect(thread, SIGNAL("server(const QString&)"), + self.on_pingthread_server) + self.connect(thread, SIGNAL("dnserror(const QString&, int, const QString&)"), + self.on_pingthread_error) + self.connect(thread, SIGNAL("dns(const QString&, float)"), + self.on_pingthread_dns) + self.connect(thread, SIGNAL("pingerror(const QString&, int, const QString&)"), + self.on_pingthread_error) + self.connect(thread, SIGNAL("ping(const QString&, float)"), + self.on_pingthread_ping) + + def on_pingthread_started(self): + LOG.debug('ping thread STARTED') + self.button_ping.setEnabled(False) self.text_ping.clear() - insertText = self.text_ping.insertPlainText + + def on_pingthread_done(self): + LOG.debug('ping thread DONE') + self.button_ping.setEnabled(True) - serverlist = ServerList() - # dns - for server in serverlist: - insertText("%s ... " % server.name) - result = server.dns() - if isSocketError(result): - insertText("DNS: FAILED\n") + def on_pingthread_server(self, name): + self.text_ping.insertPlainText("%s ... " % name) + + def on_pingthread_dns(self, name, time): + self.text_ping.insertPlainText("dns: %0.3f " % time) + + def on_pingthread_ping(self, name, time): + self.text_ping.insertPlainText("ping: %0.3f\n" % time) + + def on_pingthread_error(self, name, errcode, errmsg): + LOG.debug('error: %s, %i, %s' % (name, errcode, errmsg)) + self.text_ping.insertPlainText("error: %s\n" % errmsg) + + @pyqtSignature("bool") + def on_button_ping_clicked(self): + LOG.debug('ping thread CLICKED') + thread = self._ping_thread + if not thread.isRunning(): + servers = ServerList() + self._ping_thread.pingServers(servers) + +class PingServerThread(QtCore.QThread): + def __init__(self, parent=None): + QtCore.QThread.__init__(self, parent) + self._servers = None + + def pingServers(self, servers): + self.servers = servers + if not self.isRunning(): + self.start() + + def run(self): + self.emit(SIGNAL("started")) + + for server in self.servers: + name = server.name + self.emit(SIGNAL("server(const QString&)"), name) + dns = server.dns() + if isSocketError(dns): + self.emit(SIGNAL("dnserror(const QString&, int, const QString&)"), + name, dns[0], dns[1]) continue + self.emit(SIGNAL("dns(const QString&, float)"), name, dns) - insertText("dns: %0.3f " % result) - result = server.portping() - if isSocketError(result): - insertText("ping: FAILED\n") + ping = server.portping() + if isSocketError(ping): + self.emit(SIGNAL("pingerror(const QString&, int, const QString&)"), + name, ping[0], ping[1]) continue - insertText("pin: %0.3f\n" % result) + self.emit(SIGNAL("ping(const QString&, float)"), name, ping) - @pyqtSignature("") - def on_button_ping_clicked(self): - """SIGNAL: clicked() - """ - self.button_ping.setEnabled(False) - try: - self._ping_servers() - finally: - self.button_ping.setEnabled(True) + self.emit(SIGNAL("done()")) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-17 22:28:07 UTC (rev 43) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Wed Jan 17 14:23:33 2007 +# Created: Wed Jan 17 23:18:34 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -65,6 +65,12 @@ self.pushButton.setObjectName("pushButton") self.hboxlayout.addWidget(self.pushButton) + self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) + self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) + self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) + self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") + self.tabWidget = QtGui.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(5,100,450,375)) self.tabWidget.setTabPosition(QtGui.QTabWidget.North) @@ -283,6 +289,10 @@ self.tab_time = QtGui.QWidget() self.tab_time.setObjectName("tab_time") + self.gb_dnitime = QtGui.QGroupBox(self.tab_time) + self.gb_dnitime.setGeometry(QtCore.QRect(10,130,431,211)) + self.gb_dnitime.setObjectName("gb_dnitime") + self.gb_caverntime = QtGui.QGroupBox(self.tab_time) self.gb_caverntime.setGeometry(QtCore.QRect(10,10,431,111)) self.gb_caverntime.setObjectName("gb_caverntime") @@ -328,10 +338,6 @@ self.lb_pacific_utc = QtGui.QLabel(self.gridLayout) self.lb_pacific_utc.setObjectName("lb_pacific_utc") self.gridlayout.addWidget(self.lb_pacific_utc,1,2,1,1) - - self.gb_dnitime = QtGui.QGroupBox(self.tab_time) - self.gb_dnitime.setGeometry(QtCore.QRect(10,130,431,211)) - self.gb_dnitime.setObjectName("gb_dnitime") self.tabWidget.addTab(self.tab_time,"") self.tab = QtGui.QWidget() @@ -349,10 +355,6 @@ self.button_ping = QtGui.QPushButton(self.gb_servers) self.button_ping.setGeometry(QtCore.QRect(330,300,75,24)) self.button_ping.setObjectName("button_ping") - - self.label_3 = QtGui.QLabel(self.gb_servers) - self.label_3.setGeometry(QtCore.QRect(170,300,151,16)) - self.label_3.setObjectName("label_3") self.tabWidget.addTab(self.tab,"") self.tab_4 = QtGui.QWidget() @@ -363,12 +365,6 @@ self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.tabWidget.addTab(self.tab_4,"") - - self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) - self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) - self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) - self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) @@ -376,7 +372,7 @@ MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) - self.tabWidget.setCurrentIndex(3) + self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.buttonbox_rresavcl,QtCore.SIGNAL("rejected()"),MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -402,20 +398,19 @@ self.label_7.setText(QtGui.QApplication.translate("MainWindow", "Ultra", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_graphics), QtGui.QApplication.translate("MainWindow", "Graphis", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_audio), QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8)) + self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Time zones", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) self.lb_cavern_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Pacific time:", None, QtGui.QApplication.UnicodeUTF8)) self.lb_pacific_utc.setText(QtGui.QApplication.translate("MainWindow", "UTC", None, QtGui.QApplication.UnicodeUTF8)) - self.gb_dnitime.setTitle(QtGui.QApplication.translate("MainWindow", "D\'ni time", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_time), QtGui.QApplication.translate("MainWindow", "Time", None, QtGui.QApplication.UnicodeUTF8)) self.gb_servers.setTitle(QtGui.QApplication.translate("MainWindow", "Ping servers", None, QtGui.QApplication.UnicodeUTF8)) self.text_ping.setHtml(QtGui.QApplication.translate("MainWindow", "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;\">\n" - "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) + "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) self.button_ping.setText(QtGui.QApplication.translate("MainWindow", "Ping", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("MainWindow", "TODO: Use a seperate thread", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("MainWindow", "Servers", None, QtGui.QApplication.UnicodeUTF8)) self.label_6.setText(QtGui.QApplication.translate("MainWindow", "pyMoul tools", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-17 22:28:07 UTC (rev 43) @@ -100,6 +100,22 @@ </item> </layout> </widget> + <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > + <property name="geometry" > + <rect> + <x>10</x> + <y>480</y> + <width>441</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> <widget class="QTabWidget" name="tabWidget" > <property name="geometry" > <rect> @@ -113,7 +129,7 @@ <enum>QTabWidget::North</enum> </property> <property name="currentIndex" > - <number>3</number> + <number>0</number> </property> <widget class="QWidget" name="tab_graphics" > <attribute name="title" > @@ -545,6 +561,19 @@ <attribute name="title" > <string>Time</string> </attribute> + <widget class="QGroupBox" name="gb_dnitime" > + <property name="geometry" > + <rect> + <x>10</x> + <y>130</y> + <width>431</width> + <height>211</height> + </rect> + </property> + <property name="title" > + <string>D'ni time</string> + </property> + </widget> <widget class="QGroupBox" name="gb_caverntime" > <property name="geometry" > <rect> @@ -639,19 +668,6 @@ </layout> </widget> </widget> - <widget class="QGroupBox" name="gb_dnitime" > - <property name="geometry" > - <rect> - <x>10</x> - <y>130</y> - <width>431</width> - <height>211</height> - </rect> - </property> - <property name="title" > - <string>D'ni time</string> - </property> - </widget> </widget> <widget class="QWidget" name="tab" > <attribute name="title" > @@ -685,7 +701,7 @@ <string><html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html></string> </property> </widget> <widget class="QPushButton" name="button_ping" > @@ -701,19 +717,6 @@ <string>Ping</string> </property> </widget> - <widget class="QLabel" name="label_3" > - <property name="geometry" > - <rect> - <x>170</x> - <y>300</y> - <width>151</width> - <height>16</height> - </rect> - </property> - <property name="text" > - <string>TODO: Use a seperate thread</string> - </property> - </widget> </widget> </widget> <widget class="QWidget" name="tab_4" > @@ -738,22 +741,6 @@ </widget> </widget> </widget> - <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > - <property name="geometry" > - <rect> - <x>10</x> - <y>480</y> - <width>441</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> Modified: pymoul/trunk/src/moul/qt/ui/moulqt_rc.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/moulqt_rc.py 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/qt/ui/moulqt_rc.py 2007-01-17 22:28:07 UTC (rev 43) @@ -2,7 +2,7 @@ # Resource object code # -# Created: Di 16. Jan 01:02:23 2007 +# Created: Mi 17. Jan 17:01:45 2007 # by: The Resource Compiler for PyQt (Qt v4.2.2) # # WARNING! All changes made in this file will be lost! Modified: pymoul/trunk/src/moul/time/dni.py =================================================================== --- pymoul/trunk/src/moul/time/dni.py 2007-01-17 13:37:52 UTC (rev 42) +++ pymoul/trunk/src/moul/time/dni.py 2007-01-17 22:28:07 UTC (rev 43) @@ -54,7 +54,47 @@ # Official SI year 365.25 days = 31.557.600 seconds YEAR_SI = 31557600 # Sidereal year: 365.256 363 051 days (365 d 6 h 9 min 9 s) -YEAR_SIDEREAL = (((((365 * 24) + 6 ) * 60 ) + 9 ) * 60 ) + 9 -YEAR = float(YEAR_SIDEREAL) +# YEAR_SIDEREAL = (((((365 * 24) + 6 ) * 60 ) + 9 ) * 60 ) + 9 +YEAR = float(YEAR_SI) FACTOR = YEAR / PRORAHN_PER_HAHR + +class DniTime(object): + """D'ni time handler + + The D'ni were using a complex calendar based on a pentovigesimal (25) + numbering system. + + The DniTime class assumes the following rules: + + * Hahrtee Farah 1 started on 21st of April 7656 B.C. + * Hahrtee Fahrah 15 started 1719 A.C. + * A new hahr starts on 21st of April. + * The reference time for the calculation is Mountain Standard Time (MST) + without (!) DST. The UTC offset is always UTC-7. + * To compensate leap years a new hahr starts on midnight (0:00am) in every + forth year (year % 4 == 0). + * To simplify the code special cases like year % 100 and year % 400 are + NOT taken into account. I'm assuming a year has 365,25 days (which is + wrong). A year according to the Gregorian Calendar has 365,2425 days. + + Overview + --------- + + fahrah millenium 625 years + hahr year 1 year + vailee month 10 per year + yahr day 29 per vailee, about 30h 14min + gahrtahvo section about 6h, 3min + tahvo quarter about 14,5min + gorahn minute 36 seconds + prorahn second about 1.3929 seconds + """ + _fahrah = None # millenium (625 years) + _hahr = None # year (1 year) + _vailee = None # month (10 per year) + _yahr = None # day (29 per vailee) + _gahrtahvo = None # section (about 6h, 3min) + _tahvo = None # quarter (about 14,5min) + _gorahn = None # minute (about 36 seconds) + _prorahn = None # second (1,4 seconds) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-18 17:03:39
|
Revision: 46 http://pymoul.svn.sourceforge.net/pymoul/?rev=46&view=rev Author: tiran Date: 2007-01-18 09:03:10 -0800 (Thu, 18 Jan 2007) Log Message: ----------- Added some platform code to moul.config Stub for DX enumerate sound devices (disabled) Disabled ping tests Logging enhancements Modified Paths: -------------- pymoul/trunk/src/moul/config/__init__.py pymoul/trunk/src/moul/config/win32.py pymoul/trunk/src/moul/log.py pymoul/trunk/src/moul/server/tests/test_ping.py Modified: pymoul/trunk/src/moul/config/__init__.py =================================================================== --- pymoul/trunk/src/moul/config/__init__.py 2007-01-18 17:01:49 UTC (rev 45) +++ pymoul/trunk/src/moul/config/__init__.py 2007-01-18 17:03:10 UTC (rev 46) @@ -21,24 +21,33 @@ import os import sys +from moul.log import getLogger +# a program under py2exe is sys.frozen +__FROZEN__ = bool(getattr(sys, 'frozen', False)) +# OS stuff +__WIN32__ = sys.platform.startswith('win32') # win64, cygwin? +__LINUX__ = sys.platform.startswith('linux2') +__MACOSX__ = sys.platform.startswith('darwin') +__UNIX__ = __LINUX__ or __MACOSX__ + _marker=object() # XXX: what about cygwin, bsd and others? -if sys.platform.startswith('win32'): +if __WIN32__: from moul.config.win32 import ( getMoulUserDataDir, getPyMoulIniLocation, _startMOUL, EXEC_NAME ) -elif sys.platform.startswith('linux2'): +elif __LINUX__: from moul.config.linux import ( getMoulUserDataDir, getPyMoulIniLocation, _startMOUL, EXEC_NAME ) -elif sys.platform.startswith('darwin'): +elif __MACOSX__: from moul.config.darwin import ( getMoulUserDataDir, getPyMoulIniLocation, Modified: pymoul/trunk/src/moul/config/win32.py =================================================================== --- pymoul/trunk/src/moul/config/win32.py 2007-01-18 17:01:49 UTC (rev 45) +++ pymoul/trunk/src/moul/config/win32.py 2007-01-18 17:03:10 UTC (rev 46) @@ -24,6 +24,7 @@ import os from miniwinshell import my_documents from miniwinshell import application_data +#from win32com.directsound import directsound MOUL_DIR = "Uru Live" INI_FILE = ('pyMoul', 'pymoul.ini') @@ -55,3 +56,12 @@ path = os.path.join(installdir, EXEC_NAME) args = (EXEC_NAME,) + args return os.spawnv(mode, path, args) + +#def enumSoundDevices(): +# """ +# """ +# names = [] +# for iid, name, driver in directsound.DirectSoundEnumerate(): +# if iid is not None: +# names.append(name) +# return names Modified: pymoul/trunk/src/moul/log.py =================================================================== --- pymoul/trunk/src/moul/log.py 2007-01-18 17:01:49 UTC (rev 45) +++ pymoul/trunk/src/moul/log.py 2007-01-18 17:03:10 UTC (rev 46) @@ -21,11 +21,16 @@ __version__ = "$Id$" __revision__ = "$Revision$" +__all__ = ['LOG', 'getLogger', 'signalLogDecorator'] + import logging import sys -# py2exe sets sys.frozen -if getattr(sys, 'frozen', False): +# copied from moul.config to prevent circular imports +__FROZEN__ = bool(getattr(sys, 'frozen', False)) +__LOG_SIGNALS__ = not __FROZEN__ + +if __FROZEN__: level = logging.ERROR else: level = logging.DEBUG @@ -34,6 +39,25 @@ format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S' ) - LOG = logging.getLogger('pyMoul') getLogger = logging.getLogger + +def signalLogDecorator(__logger__): + """Decorator to log signals + + Logs signal methods to __logger__.debug() including func name, args + and kwargs. + + signalLogDecorator() is a NOOP when running as a sys.frozen program. + """ + def wrapper(func): + if __LOG_SIGNALS__: + def logwrapper(*args, **kwargs): + __logger__.debug("%s(*%s, **%s)" % (func.__name__, + repr(args[1:]), repr(kwargs))) + return func(*args, **kwargs) + logwrapper.__name__ = func.__name__ + return logwrapper + else: + return func + return wrapper Modified: pymoul/trunk/src/moul/server/tests/test_ping.py =================================================================== --- pymoul/trunk/src/moul/server/tests/test_ping.py 2007-01-18 17:01:49 UTC (rev 45) +++ pymoul/trunk/src/moul/server/tests/test_ping.py 2007-01-18 17:03:10 UTC (rev 46) @@ -57,7 +57,7 @@ def test_suite(): return unittest.TestSuite(( - unittest.makeSuite(PingServerTest), + #unittest.makeSuite(PingServerTest), DocTestSuite('moul.server.ping'), )) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-18 20:25:26
|
Revision: 48 http://pymoul.svn.sourceforge.net/pymoul/?rev=48&view=rev Author: tiran Date: 2007-01-18 12:25:26 -0800 (Thu, 18 Jan 2007) Log Message: ----------- Major work on graphics ini parsing Modified Paths: -------------- pymoul/trunk/src/moul/crypt/whatdoyousee.py pymoul/trunk/src/moul/file/tests/test_wdysini.py pymoul/trunk/src/moul/file/wdysini.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui Modified: pymoul/trunk/src/moul/crypt/whatdoyousee.py =================================================================== --- pymoul/trunk/src/moul/crypt/whatdoyousee.py 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/crypt/whatdoyousee.py 2007-01-18 20:25:26 UTC (rev 48) @@ -76,7 +76,7 @@ """ # XXX: dos format instr = instr.replace("\n", "\r\n") - fin.seek(0) + fout.seek(0) fout.write(HEADER) flen = len(instr) Modified: pymoul/trunk/src/moul/file/tests/test_wdysini.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_wdysini.py 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/file/tests/test_wdysini.py 2007-01-18 20:25:26 UTC (rev 48) @@ -22,9 +22,12 @@ __revision__ = "$Revision$" import os +import string +from StringIO import StringIO import unittest from doctest import DocTestSuite +from moul.crypt.whatdoyousee import decryptWDYS from moul.file.wdysini import AudioIni from moul.file.wdysini import GraphicsIni @@ -47,6 +50,12 @@ def tearDown(self): self.enc_fd.close() self.dec_fd.close() + + def _compareLines(self, first, second): + flines = first.split('\n') + slines = second.split('\n') + for i, fline in enumerate(flines): + self.failUnlessEqual(fline, slines[i]) def test_parseString(self): p = self.parser @@ -55,11 +64,33 @@ self.failUnless(p._filedata) self.failIf(p.isChanged()) newdata = p.writeString() - olines = data.split('\n') - nlines = newdata.split('\n') - for i, oline in enumerate(olines): - self.failUnlessEqual(oline, nlines[i]) - + self._compareLines(data, newdata) + + def test_chars(self): + valid = string.ascii_letters + '_. ' + data = self.dec_fd.read() + self.parser.parseString(data) + for key in self.parser._filedata: + for s in key: + self.failUnless(s in valid, s) + + def test_cryptparse(self): + p = self.parser + data = self.dec_fd.read() + p.parseEncFile(self.enc) + newdata = p.writeString() + self._compareLines(data, newdata) + fdout = StringIO() + p.writeEncFile(fdout) + + # round trip + fdout.seek(0) + encdata = decryptWDYS(fdout) + p.parseString(encdata) + newdata = p.writeString() + self._compareLines(data, newdata) + + class AudioIniTest(GenericIniTest): enc = aud_enc dec = aud_dec @@ -69,7 +100,45 @@ enc = gra_enc dec = gra_dec parserClass = GraphicsIni + + def test_properties(self): + p = self.parser + eq = self.failUnlessEqual + + p.parseEncFile(self.enc) + eq(p.screenres, 1) + eq(p.windowed, True) + eq(p.antialias, 2) + eq(p.anisotropic, 2) + eq(p.texture, 2) + eq(p.quality, 2) + eq(p.shadow_enabled, 1) + eq(p.vsync, False) + def test_property_edit(self): + p = self.parser + eq = self.failUnlessEqual + + p.parseEncFile(self.enc) + self.failIf(p.isChanged()) + + p.vsync = True + eq(p._get('Graphics.EnableVSync'), True) + self.failUnless(p.isChanged()) + p.vsync = False + eq(p._get('Graphics.EnableVSync'), False) + #XXX self.failIf(p.isChanged()) + + p.screenres = 0 + eq(p._get('Graphics.Width'), 800) + eq(p._get('Graphics.Height'), 600) + + p.screenres = 10 + eq(p._get('Graphics.Width'), 1920) + eq(p._get('Graphics.Height'), 1200) + self.failUnless(p.isChanged()) + + def test_suite(): return unittest.TestSuite(( unittest.makeSuite(AudioIniTest), Modified: pymoul/trunk/src/moul/file/wdysini.py =================================================================== --- pymoul/trunk/src/moul/file/wdysini.py 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/file/wdysini.py 2007-01-18 20:25:26 UTC (rev 48) @@ -55,6 +55,13 @@ Traceback (most recent call last): ... ValueError: OK + + >>> BoolString(False) == False + True + >>> BoolString(True) == True + True + >>> BoolString(False) == True + False """ def __init__(self, value=False): @@ -82,8 +89,8 @@ def __repr__(self): return str(self) - def __cmp__(self, other): - return cmp(bool(self), bool(other)) + def __eq__(self, other): + return self._true == bool(other) class FloatString(float): """Float with a slightly different representation @@ -126,15 +133,30 @@ _options = {} def __init__(self): + self.clear() + + def clear(self): self._filedata = {} self._newdata = {} - self._order = [] - + self._order = [] + + def parseEncFile(self, fd_name): + """Read and parse file (fd or file name) + """ + self.clear() + if isinstance(fd_name, basestring): + fd = open(fd_name, 'rb') + else: + fd = fd_name + data = decryptWDYS(fd) + return self.parseString(data) + def parseString(self, s): """Parse string with file contents @param s newline seperated file (string) """ + self.clear() lines = s.split('\n') for line in lines: if not line.strip(): @@ -144,7 +166,9 @@ # not elegant but safe if line.startswith(key): found = True - newkey = key.replace(' ', '_') + #newkey = key.replace(' ', '__') + #newkey = newkey.replace('.', '_') + newkey = key self._order.append(newkey) data = line[len(key)+1:].strip() self._filedata[newkey] = convert(data) @@ -168,12 +192,24 @@ out = [] for newkey in self._order: value = self._newdata[newkey] - key = newkey.replace('_', ' ') + key = newkey + #key = newkey.replace('__', ' ') + #key = key.replace('_', '.') assert key in self._options out.append("%s %s" % (key, value)) out.append('') # new line at EOF return '\n'.join(out) - + + def writeEncFile(self, fd_name): + """Write file (fd or file name) + """ + if isinstance(fd_name, basestring): + fd = open(fd_name, 'wb') + else: + fd = fd_name + data = self.writeString() + return encryptWDYS(data, fd) + class AudioIni(ConfFile): _options = { 'Audio.Initialize' : BoolString, @@ -189,37 +225,99 @@ 'Audio.SetChannelVolume GUI' : FloatString, } +class _VideoModes(object): + """Video mode informations + """ + # width, height, w ratio, h ratio + _videomodes = VIDEO_MODES + # (w, h) -> idx + _reverse_vm = dict([((d[0], d[1]), i) for i, d in enumerate(VIDEO_MODES)]) + + def __len__(self): + return len(self._videomodes) + + def getVidModeByIdx(self, idx): + """Get video mode by index + + >>> videoModes.getVidModeByIdx(0) + (800, 600, 4, 3) + """ + return self._videomodes[idx] + + def getVidModeHuman(self, idx): + """Human readable vidoe mode by index + + >>> videoModes.getVidModeHuman(0) + '800x600 (4:3)' + """ + return "%ix%i (%i:%i)" % self.getVidModeByIdx(idx) + + def getVidIdxByMode(self, w, h): + """Reverse lookup + + >>> videoModes.getVidIdxByMode(800, 600) + 0 + """ + return self._reverse_vm[(w, h)] + +videoModes = _VideoModes() + class GraphicsIni(ConfFile): _options = { 'Graphics.Width' : int, 'Graphics.Height' : int, - 'Graphics.ColorDepth' : int, + 'Graphics.ColorDepth' : int, # no ui 'Graphics.Windowed' : BoolString, 'Graphics.AntiAliasAmount' : int, 'Graphics.AnisotropicLevel' : int, 'Graphics.TextureQuality' : int, 'Quality.Level' : int, 'Graphics.Shadow.Enable' : int, - 'Graphics.EnablePlanarReflections' : int, + 'Graphics.EnablePlanarReflections' : int, # no ui 'Graphics.EnableVSync' : BoolString, 'Graphics.Shadow.VisibleDistance' : FloatString, } - # width, height, w ratio, h ratio - _videomodes = VIDEO_MODES + def _getScreenRes(self): + w = self._newdata['Graphics.Width'] + h = self._newdata['Graphics.Height'] + return videoModes.getVidIdxByMode(w, h) - def getVidModeByIdx(self, idx): - """Get video mode by index - """ - return self._videomodes[idx] + def _setScreenRes(self, idx): + w, h, wf, hf = videoModes.getVidModeByIdx(idx) + self._newdata['Graphics.Width'] = w + self._newdata['Graphics.Height'] = h - def getVidModeHuman(self, idx): - """Human readable vidoe mode by index - """ - return "%ix%i (%i:%i)" % self.getVidModeByIdx(idx) - - def getVidIdxByMode(self, w, h): - for idx, mode in enumerate(self._videomodes): - if mode[0] == w and mode[1] == h: - return idx - raise KeyError("Video mode for %ix%i not found" % (w, h)) + def _get(self, name): + return self._newdata[name] + + def _set(self, name, value): + self._newdata[name] = value + + screenres = property(_getScreenRes, _setScreenRes, doc="Screen resolution by index") + windowed = property(lambda self: self._get('Graphics.Windowed'), + lambda self, v: self._set('Graphics.Windowed', v), + ) + antialias = property(lambda self: self._get('Graphics.AntiAliasAmount'), + lambda self, v: self._set('Graphics.AntiAliasAmount', v), + ) + anisotropic = property(lambda self: self._get('Graphics.AnisotropicLevel'), + lambda self, v: self._set('Graphics.AnisotropicLevel', v), + ) + texture = property(lambda self: self._get('Graphics.TextureQuality'), + lambda self, v: self._set('Graphics.TextureQuality', v), + ) + quality = property(lambda self: self._get('Quality.Level'), + lambda self, v: self._set('Quality.Level', v), + ) + shadow_enabled = property(lambda self: self._get('Graphics.Shadow.Enable'), + lambda self, v: self._set('Graphics.Shadow.Enable', v), + ) + # XXX: shadows + #shadow = property(lambda self: self._get('Graphics.Shadow.VisibleDistance'), + # lambda self, v: self._set('Graphics.Shadow.VisibleDistance', v), + # ) + vsync = property(lambda self: self._get('Graphics.EnableVSync'), + lambda self, v: self._set('Graphics.EnableVSync', v), + ) + Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-18 20:25:26 UTC (rev 48) @@ -33,7 +33,9 @@ from moul.qt.ui.mainwindow import Ui_MainWindow from moul.time.cavern import CavernTime +from moul.file.wdysini import AudioIni from moul.file.wdysini import GraphicsIni +from moul.file.wdysini import videoModes from moul.server.ping import ServerList from moul.server.ping import isSocketError from moul.log import getLogger @@ -96,22 +98,24 @@ def _graphics_init(self): """init graphics tab """ - self._graphicsini = GraphicsIni() - length = len(self._graphicsini._videomodes) - 1 + length = len(videoModes) - 1 self.slid_screenres.setMaximum(length) - #self.connect(self.slid_screenres, SIGNAL("valueChanged(int)"), - # self.on_slid_screenres_changed) - self.connect(self.slid_screenres, SIGNAL("sliderMoved(int)"), + self.connect(self.slid_screenres, SIGNAL("valueChanged(int)"), self.on_slid_screenres_changed) + def on_graphicsini_loaded(self, gini): + """SIGNAL: graphicsIniLoaded(file) + """ + self.slid_screenres.setValue(gini.screenres) + @signalLogDecorator(LOG) @pyqtSignature("int") def on_slid_screenres_changed(self, idx): """SIGNAL: valueChanged (int) """ - txt = self._graphicsini.getVidModeHuman(idx) + txt = videoModes.getVidModeHuman(idx) self.lb_screenres.setText(QtCore.QString(txt)) - + # ************************************************************************ # time zones Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-18 20:25:26 UTC (rev 48) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Thu Jan 18 16:28:04 2007 +# Created: Thu Jan 18 19:42:55 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -65,12 +65,6 @@ self.pushButton.setObjectName("pushButton") self.hboxlayout.addWidget(self.pushButton) - self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) - self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) - self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) - self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) - self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") - self.tabWidget = QtGui.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(5,100,450,375)) self.tabWidget.setTabPosition(QtGui.QTabWidget.North) @@ -667,6 +661,12 @@ self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.tabWidget.addTab(self.tab_4,"") + + self.buttonbox_rresavcl = QtGui.QDialogButtonBox(self.centralwidget) + self.buttonbox_rresavcl.setGeometry(QtCore.QRect(10,480,441,32)) + self.buttonbox_rresavcl.setOrientation(QtCore.Qt.Horizontal) + self.buttonbox_rresavcl.setStandardButtons(QtGui.QDialogButtonBox.Close|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Reset|QtGui.QDialogButtonBox.Save) + self.buttonbox_rresavcl.setObjectName("buttonbox_rresavcl") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-18 17:03:38 UTC (rev 47) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-18 20:25:26 UTC (rev 48) @@ -100,22 +100,6 @@ </item> </layout> </widget> - <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > - <property name="geometry" > - <rect> - <x>10</x> - <y>480</y> - <width>441</width> - <height>32</height> - </rect> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> - </property> - </widget> <widget class="QTabWidget" name="tabWidget" > <property name="geometry" > <rect> @@ -1408,6 +1392,22 @@ </widget> </widget> </widget> + <widget class="QDialogButtonBox" name="buttonbox_rresavcl" > + <property name="geometry" > + <rect> + <x>10</x> + <y>480</y> + <width>441</width> + <height>32</height> + </rect> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons" > + <set>QDialogButtonBox::Close|QDialogButtonBox::NoButton|QDialogButtonBox::Reset|QDialogButtonBox::Save</set> + </property> + </widget> </widget> <widget class="QStatusBar" name="statusbar" /> </widget> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-20 16:32:04
|
Revision: 53 http://pymoul.svn.sourceforge.net/pymoul/?rev=53&view=rev Author: tiran Date: 2007-01-20 08:32:00 -0800 (Sat, 20 Jan 2007) Log Message: ----------- Minor linux fixes KiImage fixes and first tests Modified Paths: -------------- pymoul/trunk/src/moul/file/kiimage.py pymoul/trunk/src/moul/file/tests/test_kiimage.py Added Paths: ----------- pymoul/trunk/src/moul/config/linux.py pymoul/trunk/src/moul/file/tests/avatar_clean.jpg Removed Paths: ------------- pymoul/trunk/src/moul/config/linux2.py Copied: pymoul/trunk/src/moul/config/linux.py (from rev 51, pymoul/trunk/src/moul/config/linux2.py) =================================================================== --- pymoul/trunk/src/moul/config/linux.py (rev 0) +++ pymoul/trunk/src/moul/config/linux.py 2007-01-20 16:32:00 UTC (rev 53) @@ -0,0 +1,57 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Linux configuration for pyMoul + +XXX: untested! +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import os +from moul.log import LOG +LOG.warning('Linux support is not tested') + +MOUL_DIR = "Uru Live" +INI_FILE = ('pyMoul', 'pymoul.ini') +EXEC_NAME = "UruLauncher" +HOME = os.environ['HOME'] + +def getMoulUserDataDir(): + """Get path of MOUL data directory + + The MOUL data directory contains log files, chatlogs, KI images and many + more things. + """ + moul_data = os.path.join(HOME, MOUL_DIR) + +def getPyMoulIniLocation(): + """Get path to the pyMoul ini file + """ + ini_file = os.path.join(HOME, *INI_FILE) + return ini_file + +def _startMOUL(installdir, *args): + """Start MOUL + """ + # P_DETACH is similar to P_NOWAIT, but the new process is detached from + # the console of the calling process. + mode = os.P_DETACH + path = os.path.join(installdir, EXEC_NAME) + args = (EXEC_NAME,) + args + return os.spawnv(mode, path, args) Deleted: pymoul/trunk/src/moul/config/linux2.py =================================================================== --- pymoul/trunk/src/moul/config/linux2.py 2007-01-20 15:28:50 UTC (rev 52) +++ pymoul/trunk/src/moul/config/linux2.py 2007-01-20 16:32:00 UTC (rev 53) @@ -1,57 +0,0 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -"""Linux configuration for pyMoul - -XXX: untested! -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - -import os -from moul.log import LOG -LOG.warning('Linux support is not tested') - -MOUL_DIR = "Uru Live" -INI_FILE = ('pyMoul', 'pymoul.ini') -EXEC_NAME = "UruLauncher" -HOME = os.environ('HOME') - -def getMoulUserDataDir(): - """Get path of MOUL data directory - - The MOUL data directory contains log files, chatlogs, KI images and many - more things. - """ - moul_data = os.path.join(HOME, MOUL_DIR) - -def getPyMoulIniLocation(): - """Get path to the pyMoul ini file - """ - ini_file = os.path.join(HOME, *INI_FILE) - return ini_file - -def _startMOUL(installdir, *args): - """Start MOUL - """ - # P_DETACH is similar to P_NOWAIT, but the new process is detached from - # the console of the calling process. - mode = os.P_DETACH - path = os.path.join(installdir, EXEC_NAME) - args = (EXEC_NAME,) + args - return os.spawnv(mode, path, args) Modified: pymoul/trunk/src/moul/file/kiimage.py =================================================================== --- pymoul/trunk/src/moul/file/kiimage.py 2007-01-20 15:28:50 UTC (rev 52) +++ pymoul/trunk/src/moul/file/kiimage.py 2007-01-20 16:32:00 UTC (rev 53) @@ -23,27 +23,37 @@ import os import tempfile +import struct JPEG_HEADER = "\377\330\377" -class KIImage(object): +class KiImage(object): + """Ki image handler - def __init__(self, filename): - assert os.path.isfile(filename) - self._filename = filename - self._fd = None - self.open() + MOUL's KI images have four leading bytes of junk that encode the file + size. The class allowes to add, remove and verify the header. + """ + + def __init__(self, fd_name): + if isinstance(fd_name, basestring): + name = fd_name + fd = open(fd_name, 'rb') + else: + name = getattr(fd_name, 'name', '<UNKNOWN>') + fd = fd_name + + self._filename = name + self._fd = fd + self._size = None - def open(self): - if not self._fd: - self._fd = open(filename, 'rb') - def close(self): if self._fd: self._fd.close() self._fd = None def getSize(self): + if self._size is not None: + return self._size fd = self._fd opos = fd.tell() size = 0 @@ -52,9 +62,11 @@ size = fd.tell() finally: fd.seek(opos) + self._size = size return size def moulHeaderToSize(self, header=None): + # XXX use struct if header is None: fd = self._fd fd.seek(0) @@ -65,8 +77,9 @@ return size def sizeToMoulHeader(self, size=None): + # XXX use struct if size is None: - size = self.getSize() + 4 + size = self.getSize() + 4 # XXX +4 ? leading = 4* [None] for i in (3,2,1,0): l = size >> 8*i @@ -77,7 +90,7 @@ def verifyMoulHeader(self, header=None): header_size = self.moulHeaderToSize(header) file_size = self.getSize() - if header_size == file_size: + if (header_size + 4) == file_size: return True return False @@ -100,7 +113,7 @@ def removeMoulHeader(self): if not self.isMoulImage(): - raise Exception + raise ValueError('Image has no MOUL header') out = tempfile.TemporaryFile() fd = self._fd fd.seek(4) @@ -108,8 +121,10 @@ return out def addMoulHeader(self): + if self.isMoulImage(): + raise ValueError('Image has already a MOUL header') if not self.isJpeg(): - raise Exception + raise ValueError('File is not a JPEG') out = tempfile.TemporaryFile() header = self.sizeToMoulHeader() fd = self._fd Added: pymoul/trunk/src/moul/file/tests/avatar_clean.jpg =================================================================== (Binary files differ) Property changes on: pymoul/trunk/src/moul/file/tests/avatar_clean.jpg ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: pymoul/trunk/src/moul/file/tests/test_kiimage.py =================================================================== --- pymoul/trunk/src/moul/file/tests/test_kiimage.py 2007-01-20 15:28:50 UTC (rev 52) +++ pymoul/trunk/src/moul/file/tests/test_kiimage.py 2007-01-20 16:32:00 UTC (rev 53) @@ -21,13 +21,49 @@ __version__ = "$Id$" __revision__ = "$Revision$" +import os +from StringIO import StringIO import unittest from doctest import DocTestSuite -import moul.file.kiimage +from moul.file.kiimage import KiImage +base = os.path.dirname(__file__) +kiimg = os.path.join(base, 'avatar.jpg') +kiclean = os.path.join(base, 'avatar_clean.jpg') + +class KiImageTest(unittest.TestCase): + + def setUp(self): + self._ki = open(kiimg, 'rb') + self._clean = open(kiclean, 'rb') + + def tearDown(self): + self._ki.close() + self._clean.close() + + def test_openname(self): + k = KiImage(kiimg) + self.failUnless(k.isMoulImage()) + self.failIf(k.isJpeg()) + + k = KiImage(kiclean) + self.failIf(k.isMoulImage()) + self.failUnless(k.isJpeg()) + + def test_openfd(self): + k = KiImage(self._ki) + self.failUnless(k.isMoulImage()) + self.failIf(k.isJpeg()) + + k = KiImage(self._clean) + self.failIf(k.isMoulImage()) + self.failUnless(k.isJpeg()) + + def test_suite(): return unittest.TestSuite(( + unittest.makeSuite(KiImageTest), DocTestSuite('moul.file.kiimage') )) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-23 13:02:29
|
Revision: 59 http://pymoul.svn.sourceforge.net/pymoul/?rev=59&view=rev Author: tiran Date: 2007-01-23 05:02:21 -0800 (Tue, 23 Jan 2007) Log Message: ----------- Configuration cleanup Moved all os dependent stuff to the right directory Modified Paths: -------------- pymoul/trunk/src/moul/config/__init__.py pymoul/trunk/src/moul/file/localization.py pymoul/trunk/src/moul/file/plasmalog.py pymoul/trunk/src/moul/osdependent/__init__.py pymoul/trunk/src/moul/osdependent/darwin/__init__.py pymoul/trunk/src/moul/osdependent/linux/__init__.py pymoul/trunk/src/moul/osdependent/win32/__init__.py pymoul/trunk/src/moul/qt/ui/mainwindow.py Added Paths: ----------- pymoul/trunk/src/moul/config/tests/test_config.py pymoul/trunk/src/moul/osdependent/win32/registry.py pymoul/trunk/src/moul/osdependent/win32/winpath.py Removed Paths: ------------- pymoul/trunk/src/moul/config/darwin.py pymoul/trunk/src/moul/config/linux.py pymoul/trunk/src/moul/config/win32.py Modified: pymoul/trunk/src/moul/config/__init__.py =================================================================== --- pymoul/trunk/src/moul/config/__init__.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/config/__init__.py 2007-01-23 13:02:21 UTC (rev 59) @@ -34,23 +34,23 @@ _marker=object() # XXX: what about cygwin, bsd and others? if __WIN32__: - from moul.config.win32 import ( + from moul.osdependent.win32 import ( getMoulUserDataDir, - getPyMoulIniLocation, + getPyMoulIniDir, _startMOUL, EXEC_NAME ) elif __LINUX__: - from moul.config.linux import ( + from moul.osdependent.linux import ( getMoulUserDataDir, - getPyMoulIniLocation, + getPyMoulIniDir, _startMOUL, EXEC_NAME ) elif __MACOSX__: - from moul.config.darwin import ( + from moul.osdependent.darwin import ( getMoulUserDataDir, - getPyMoulIniLocation, + getPyMoulIniDir, _startMOUL, EXEC_NAME ) @@ -58,95 +58,137 @@ raise RuntimeError('platform %s not supported' % sys.platform) ## configuration -_configuration = { - 'moul' : {} - } -def getConfigOption(section, name=None, default=_marker): - """Get configuration option - """ - global _configuration - if name is None: - section, name = section.split('.') - sec = _configuration.get(section, default) - if sec is not default: - value = sec.get(name, default) - if value is default and default is _marker: - raise KeyError("%s.%s" % (section, name)) - else: - return value - elif default is _marker: - raise KeyError(section) -def setConfigOption(section, name=None, value=_marker): - """Set configuratin option - """ - global _configuration - if value is _marker: - raise ValueError("No value applied") - if name is None: - section, name = section.split('.') - sec = _configuration[section] - if value is None: - del sec[name] - else: - sec[name] = value +class Configuration(dict): + def __new__(cls, *args, **kwargs): + self = dict.__new__(cls, *args, **kwargs) + self.addSection('moul') + return self -def addConfigSection(section): - """Add a new configuration section - """ - global _configuration - return _configuration.setdefault(section, {}) + def getOption(self, section, name=None, default=_marker): + """Get configuration option + """ + if name is None: + section, name = section.split('.') + sec = self.get(section, default) + if sec is not default: + value = sec.get(name, default) + if value is default and default is _marker: + raise KeyError("%s.%s" % (section, name)) + else: + return value + elif default is _marker: + raise KeyError(section) + + def setOption(self, section, name=None, value=_marker): + """Set configuratin option + """ + if value is _marker: + raise ValueError("No value applied") + if name is None: + section, name = section.split('.') + sec = self[section] + if value is None: + del sec[name] + else: + sec[name] = value + + def addSection(self, section): + """Add a new configuration section + """ + return self.setdefault(section, {}) + + def listConfig(self): + """List + + >>> cfg = listConfig() + >>> len(cfg) > 0 + True + >>> type(cfg) + <type 'dict'> + """ + out = {} + for sec, names in self.items(): + for name, value in names.items(): + fullname = "%s.%s" % (sec, name) + out[fullname] = value + return out -def listConfig(): - """List - """ - global _configuration - out = {} - for sec, names in _configuration.items(): - for name, value in names.items(): - fullname = "%s.%s" % (sec, name) - out[fullname] = value - return out +_configuration = Configuration() +getOption = _configuration.getOption +setOption = _configuration.setOption +addSection = _configuration.addSection +listConfig = _configuration.listConfig -#setConfigOption('moul', 'installdir', 'D:\\games\\MystOnline') +# hard coded for my system +setOption('moul', 'installdir', 'D:\\games\\MystOnline') ## directories -def getMoulInstallDir(): - return getConfigOption('moul.installdir') +class Directories(object): + + _dirmapping = { + 'install' : "%(installdir)s", + 'loc' : "%(installdir)s/dat", + 'dat' : "%(installdir)s/dat", + 'sound' : "%(installdir)s/sfx", + 'soundwav' : "%(installdir)s/sfx/streamingCache", + 'video' : "%(installdir)s/avi", + + 'userdata' : "%(datadir)s", + 'log' : "%(datadir)s/Log", + 'kiimages' : "%(datadir)s/KIimages", + 'avatars' : "%(datadir)s/Avatars", + 'chatlogs' : "%(datadir)s/chatlogs", + 'ini' : "%(datadir)s/init", + + 'pymoul.ini' : "%(pymouldir)s/pymoul.ini", + } + + def __init__(self, config): + self._cache = {} + self._config = config + + def clearCache(self): + self._cache.clear() -def startMOUL(*args): - """Start MOUL wrapper - """ - installdir = getMoulInstallDir() - _startMOUL(installdir, *args) + def getMoulInstallDir(self): + return self._config.getOption('moul.installdir') + + def getMoulUserDataDir(self): + return getMoulUserDataDir() -# name -> (callable, list) -_mapping = { - 'install' : (getMoulInstallDir, ()), - 'loc' : (getMoulInstallDir, ('dat', )), - 'dat' : (getMoulInstallDir, ('dat', )), - 'sound' : (getMoulInstallDir, ('sfx', )), - 'soundwav' : (getMoulInstallDir, ('sfx', 'streamingCache', )), - 'video' : (getMoulInstallDir, ('avi', )), + def getPyMoulIniDir(self): + return getPyMoulIniDir() - 'userdata' : (getMoulUserDataDir, ()), - 'log' : (getMoulUserDataDir, ('Log', )), - 'kiimages' : (getMoulUserDataDir, ('KIimages', )), - 'avatars' : (getMoulUserDataDir, ('Avatars', )), - 'chatlogs' : (getMoulUserDataDir, ('chatlogs', )), - 'ini' : (getMoulUserDataDir, ('init', )), + def lookupDir(self, name): + """Lookup MOUL directory + """ + cached = self._cache.get(name, None) + if cached: + return cached + path = self._dirmapping.get(name) + path = path.replace('/', os.sep) + map = {'installdir' : self.getMoulInstallDir(), + 'datadir' : self.getMoulUserDataDir(), + 'pymouldir' : self.getPyMoulIniDir(), + } + fullpath = path % map + #self._cache[name] = fullpath + return fullpath + + def listDirs(self): + """List all MOUL dirs + + >>> dirs = listDirs() + >>> len(dirs) + 13 + >>> type(dirs) + <type 'dict'> + """ + return dict([(name, self.lookupDir(name)) for name in self._dirmapping]) - 'pymoul.ini' : (getPyMoulIniLocation, ()), - } - -def getMoulDir(name): - """Lookup MOUL directory - """ - callable, args = _mapping.get(name) - return os.path.join(callable(), *args) - -def listMoulDirs(): - """List all MOUL dirs - """ - return dict([(name, getMoulDir(name)) for name in _mapping]) +_directories = Directories(_configuration) +clearCache = _directories.clearCache +lookupDir = _directories.lookupDir +listDirs = _directories.listDirs Deleted: pymoul/trunk/src/moul/config/darwin.py =================================================================== --- pymoul/trunk/src/moul/config/darwin.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/config/darwin.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,57 +0,0 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -"""Darwin (Mac OS X) configuration for pyMoul - -XXX: untested! -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - -import os -from moul.log import LOG -LOG.warning('Darwin/Mac support is not tested') - -MOUL_DIR = "Uru Live" -INI_FILE = ('pyMoul', 'pymoul.ini') -EXEC_NAME = "UruLauncher" -HOME = os.environ['HOME'] - -def getMoulUserDataDir(): - """Get path of MOUL data directory - - The MOUL data directory contains log files, chatlogs, KI images and many - more things. - """ - moul_data = os.path.join(HOME, MOUL_DIR) - -def getPyMoulIniLocation(): - """Get path to the pyMoul ini file - """ - ini_file = os.path.join(HOME, *INI_FILE) - return ini_file - -def _startMOUL(installdir, *args): - """Start MOUL - """ - # P_DETACH is similar to P_NOWAIT, but the new process is detached from - # the console of the calling process. - mode = os.P_DETACH - path = os.path.join(installdir, EXEC_NAME) - args = (EXEC_NAME,) + args - return os.spawnv(mode, path, args) Deleted: pymoul/trunk/src/moul/config/linux.py =================================================================== --- pymoul/trunk/src/moul/config/linux.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/config/linux.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,57 +0,0 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -"""Linux configuration for pyMoul - -XXX: untested! -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - -import os -from moul.log import LOG -LOG.warning('Linux support is not tested') - -MOUL_DIR = "Uru Live" -INI_FILE = ('pyMoul', 'pymoul.ini') -EXEC_NAME = "UruLauncher" -HOME = os.environ['HOME'] - -def getMoulUserDataDir(): - """Get path of MOUL data directory - - The MOUL data directory contains log files, chatlogs, KI images and many - more things. - """ - moul_data = os.path.join(HOME, MOUL_DIR) - -def getPyMoulIniLocation(): - """Get path to the pyMoul ini file - """ - ini_file = os.path.join(HOME, *INI_FILE) - return ini_file - -def _startMOUL(installdir, *args): - """Start MOUL - """ - # P_DETACH is similar to P_NOWAIT, but the new process is detached from - # the console of the calling process. - mode = os.P_DETACH - path = os.path.join(installdir, EXEC_NAME) - args = (EXEC_NAME,) + args - return os.spawnv(mode, path, args) Added: pymoul/trunk/src/moul/config/tests/test_config.py =================================================================== --- pymoul/trunk/src/moul/config/tests/test_config.py (rev 0) +++ pymoul/trunk/src/moul/config/tests/test_config.py 2007-01-23 13:02:21 UTC (rev 59) @@ -0,0 +1,35 @@ +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.config unit tests +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import unittest +from doctest import DocTestSuite + +import moul.config + +def test_suite(): + return unittest.TestSuite(( + DocTestSuite('moul.config') + )) + +if __name__ == '__main__': + unittest.main(defaultTest="test_suite") Property changes on: pymoul/trunk/src/moul/config/tests/test_config.py ___________________________________________________________________ Name: svn:eol-style + native Deleted: pymoul/trunk/src/moul/config/win32.py =================================================================== --- pymoul/trunk/src/moul/config/win32.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/config/win32.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,67 +0,0 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -"""Win32 configuration for pyMoul -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - -import os -from miniwinshell import my_documents -from miniwinshell import application_data -#from win32com.directsound import directsound - -MOUL_DIR = "Uru Live" -INI_FILE = ('pyMoul', 'pymoul.ini') -EXEC_NAME = "UruLauncher.exe" - -def getMoulUserDataDir(): - """Get path of MOUL data directory - - The MOUL data directory contains log files, chatlogs, KI images and many - more things. - """ - mydoc = my_documents() - moul_data = os.path.join(mydoc, MOUL_DIR) - return moul_data - -def getPyMoulIniLocation(): - """Get path to the pyMoul ini file - """ - app_data = application_data() - ini_file = os.path.join(app_data, *INI_FILE) - return ini_file - -def _startMOUL(installdir, *args): - """Start MOUL - """ - # P_DETACH is similar to P_NOWAIT, but the new process is detached from - # the console of the calling process. - mode = os.P_DETACH - path = os.path.join(installdir, EXEC_NAME) - args = (EXEC_NAME,) + args - return os.spawnv(mode, path, args) - -#def enumSoundDevices(): -# """ -# """ -# names = [] -# for iid, name, driver in directsound.DirectSoundEnumerate(): -# if iid is not None: -# names.append(name) -# return names Modified: pymoul/trunk/src/moul/file/localization.py =================================================================== --- pymoul/trunk/src/moul/file/localization.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/file/localization.py 2007-01-23 13:02:21 UTC (rev 59) @@ -33,7 +33,6 @@ from xml.sax import make_parser from xml.sax.handler import feature_namespaces -from moul.config import getMoulDir from moul.log import LOG def _add(d, key, value): @@ -179,7 +178,7 @@ parser.setContentHandler(dh) parser.parse(fd) -def parseLocDirectory(path=None, clear=False): +def parseLocDirectory(path, clear=False): """Parse all loc files in a directory """ files = [] @@ -188,8 +187,6 @@ if clear: translationRegistry.clear() - if path is None: - path = getMoulDir('loc') if not os.path.isdir(path): raise IOError("invalid path %s" % path) @@ -210,10 +207,3 @@ files.append(fname) return {'files' : files, 'errors' : errors } - -def _test(): - path = getMoulDir('loc') - parseDirectory(path) - -if __name__ == '__main__': - _test() Modified: pymoul/trunk/src/moul/file/plasmalog.py =================================================================== --- pymoul/trunk/src/moul/file/plasmalog.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/file/plasmalog.py 2007-01-23 13:02:21 UTC (rev 59) @@ -27,8 +27,6 @@ import zipfile import re -from moul.config import getMoulDir -from moul.config import getConfigOption from moul.crypt.elf import decryptElf PLASMA_LOG = "plasmalog.txt" @@ -54,18 +52,11 @@ return False return getTimeStamp(pl) -def zipLogDir(logdir=None, destdir=None, remove=_marker): +def zipLogDir(logdir, destdir, remove): """Zip all log files This function also zips subdirectories. """ - if logdir is None: - logdir = getMoulDir('log') - if destdir is None: - destdir = getMoulDir('userdata') - if remove is _marker: - remove = getConfigOption('moul', 'removelogs', default=False) - stored_dirs = [] for root, dirs, files in os.walk(logdir): @@ -92,14 +83,11 @@ return stored_dirs -def removeLogs(logdir=None): +def removeLogs(logdir): """Removes log directories The removeLogs function removes only files considered as safe """ - if logdir is None: - logdir = getMoulDir('log') - for root, dirs, files in os.walk(logdir, topdown=False): for name in files: if RE_SAFEXT.search(name): Modified: pymoul/trunk/src/moul/osdependent/__init__.py =================================================================== --- pymoul/trunk/src/moul/osdependent/__init__.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/osdependent/__init__.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,22 +1,22 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -""" -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" Modified: pymoul/trunk/src/moul/osdependent/darwin/__init__.py =================================================================== --- pymoul/trunk/src/moul/osdependent/darwin/__init__.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/osdependent/darwin/__init__.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,23 +1,54 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -""" -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.osdependent.darwin +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import os +from moul.log import LOG +LOG.warning('Darwin/Mac support is not tested') + +MOUL_DIR = "Uru Live" +EXEC_NAME = "UruLauncher" +HOME = os.environ['HOME'] + +def getMoulUserDataDir(): + """Get path of MOUL data directory + + The MOUL data directory contains log files, chatlogs, KI images and many + more things. + """ + moul_data = os.path.join(HOME, MOUL_DIR) + +def getPyMoulIniDir(): + """Get path to the pyMoul ini directory + """ + inidir= os.path.join(HOME, '.pymoul') + return inidir + +def _startMOUL(installdir, *args): + """Start MOUL + """ + # P_DETACH is similar to P_NOWAIT, but the new process is detached from + # the console of the calling process. + mode = os.P_DETACH + path = os.path.join(installdir, EXEC_NAME) + args = (EXEC_NAME,) + args + return os.spawnv(mode, path, args) Modified: pymoul/trunk/src/moul/osdependent/linux/__init__.py =================================================================== --- pymoul/trunk/src/moul/osdependent/linux/__init__.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/osdependent/linux/__init__.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,23 +1,55 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -""" -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.osdependent.linux +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import os +from moul.log import LOG +LOG.warning('Linux support is not tested') + +MOUL_DIR = "Uru Live" +INI_FILE = ('pyMoul', 'pymoul.ini') +EXEC_NAME = "UruLauncher" +HOME = os.environ['HOME'] + +def getMoulUserDataDir(): + """Get path of MOUL data directory + + The MOUL data directory contains log files, chatlogs, KI images and many + more things. + """ + moul_data = os.path.join(HOME, MOUL_DIR) + +def getPyMoulIniDir(): + """Get path to the pyMoul ini directory + """ + inidir= os.path.join(HOME, '.pymoul') + return inidir + +def _startMOUL(installdir, *args): + """Start MOUL + """ + # P_DETACH is similar to P_NOWAIT, but the new process is detached from + # the console of the calling process. + mode = os.P_DETACH + path = os.path.join(installdir, EXEC_NAME) + args = (EXEC_NAME,) + args + return os.spawnv(mode, path, args) Modified: pymoul/trunk/src/moul/osdependent/win32/__init__.py =================================================================== --- pymoul/trunk/src/moul/osdependent/win32/__init__.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/osdependent/win32/__init__.py 2007-01-23 13:02:21 UTC (rev 59) @@ -1,23 +1,69 @@ -# pyMoul - Python interface to Myst Online URU Live -# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., 59 -# Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -""" -""" -__author__ = "Christian Heimes" -__version__ = "$Id$" -__revision__ = "$Revision$" - +# pyMoul - Python interface to Myst Online URU Live +# Copyright (C) 2007 Christian Heimes <christian (at) cheimes (dot) de> + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., 59 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""moul.osdependent.win32 +""" +__author__ = "Christian Heimes" +__version__ = "$Id$" +__revision__ = "$Revision$" + +import os +#from moul.osdependent.win32.miniwinshell import my_documents +#from moul.osdependent.win32.miniwinshell import application_data +#from win32com.directsound import directsound +from moul.osdependent.win32.winpath import get_homedir +from moul.osdependent.win32.winpath import get_appdata + + +MOUL_DIR = "Uru Live" +EXEC_NAME = "UruLauncher.exe" + +def getMoulUserDataDir(): + """Get path of MOUL data directory + + The MOUL data directory contains log files, chatlogs, KI images and many + more things. + """ + mydoc = get_homedir() + moul_data = os.path.join(mydoc, MOUL_DIR) + return moul_data + +def getPyMoulIniDir(): + """Get path to the pyMoul ini file + """ + app_data = get_appdata() + inidir = os.path.join(app_data, 'pyMoul') + return inidir + +def _startMOUL(installdir, *args): + """Start MOUL + """ + # P_DETACH is similar to P_NOWAIT, but the new process is detached from + # the console of the calling process. + mode = os.P_DETACH + path = os.path.join(installdir, EXEC_NAME) + args = (EXEC_NAME,) + args + return os.spawnv(mode, path, args) + +#def enumSoundDevices(): +# """ +# """ +# names = [] +# for iid, name, driver in directsound.DirectSoundEnumerate(): +# if iid is not None: +# names.append(name) +# return names Added: pymoul/trunk/src/moul/osdependent/win32/registry.py =================================================================== --- pymoul/trunk/src/moul/osdependent/win32/registry.py (rev 0) +++ pymoul/trunk/src/moul/osdependent/win32/registry.py 2007-01-23 13:02:21 UTC (rev 59) @@ -0,0 +1,69 @@ +"""Based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146305 +""" +import _winreg as wreg +#import cPickle as pickle + +class WindowsRegistry: + + def __init__(self, company="spirito GmbH", project="TestProg", write=1): + """ + handle registry access + """ + self.write = write + self.company = company + self.project = project + self.keyname = "Software\\%s\\%s" % (self.company, self.project) + + try: + self.key = wreg.OpenKey(wreg.HKEY_CURRENT_USER, self.keyname) + except: + if self.write: + self.key = wreg.CreateKey(wreg.HKEY_CURRENT_USER, self.keyname) + + def set(self, name, value): + " set value in registry " + if not self.write: + raise Exception, "registry is read only" + wreg.SetValue(self.key, name, wreg.REG_SZ,str(value)) + +# def pset(self, name, value): +# " set using pickle " +# self.set(name, pickle.dumps(value)) + + def get(self, name): + " get value out of registry " + return wreg.QueryValue(self.key, name) + + def delkey(self, name): + """Delete a key + """ + if not self.write: + raise Exception, "registry is read only" + return wreg.DeleteKey(self.key, name) + + def delvalue(self, name): + """Delete a value + """ + if not self.write: + raise Exception, "registry is read only" + return wreg.ValueKey(self.key, name) + +# def pget(self, name): +# " get using pickle " +# return pickle.loads(self.get(name)) + + def close(self): + " close the key finally " + self.key.Close() + + def __del__(self): + self.close() + + +if __name__=="__main__": + r = WindowsRegistry(project="MyTestProg", write=1) + r.set("test", "hello string data") + r.pset("testp", 123) + print r.get("test") + print r.pget("testp") + Property changes on: pymoul/trunk/src/moul/osdependent/win32/registry.py ___________________________________________________________________ Name: svn:eol-style + native Added: pymoul/trunk/src/moul/osdependent/win32/winpath.py =================================================================== --- pymoul/trunk/src/moul/osdependent/win32/winpath.py (rev 0) +++ pymoul/trunk/src/moul/osdependent/win32/winpath.py 2007-01-23 13:02:21 UTC (rev 59) @@ -0,0 +1,150 @@ +"""Functions for getting system/language/user dependent paths on windows. + +All path names returned by the functions of this module are unicode strings. + +From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473846/ +""" + +__all__ = [ + 'HKCU', 'HKLM', + 'SHELL_FOLDERS', + 'USER_SHELL_FOLDERS', + 'expandvars', + 'get_appdata', + 'get_common_shellfolders', + 'get_homedir', + 'get_sharedconf', + 'get_shellfolders', + 'get_userconf', + 'get_windir' +] + +__module__ = "winpaths" +__author__ = "Christopher Arndt" +__version__ = "0.1" +__revision__ = "$Rev$" +__date__ = "$Date$" +__copyright__ = "Python license" + +# standard library modules +import _winreg, os + +SHELL_FOLDERS = \ + r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' +USER_SHELL_FOLDERS = \ + r'Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' +HKCU = _winreg.HKEY_CURRENT_USER +HKLM = _winreg.HKEY_LOCAL_MACHINE + +# helper functions +def _substenv(m): + return os.environ.get(m.group(1), m.group(0)) + +_env_rx = None +def expandvars(s): + """Expand environment variables of form %var%. + + Unknown variables are left unchanged. + """ + + global _env_rx + + if '%' not in s: + return s + if _env_rx is None: + import re + _env_rx = re.compile(r'%([^|<>=^%]+)%') + return _env_rx.sub(_substenv, s) + +def _get_reg_value(key, subkey, name): + """Return registry value specified by key, subkey, and name. + + Environment variables in values of type REG_EXPAND_SZ are expanded + if possible. + """ + + key = _winreg.OpenKey(key, subkey) + try: + ret = _winreg.QueryValueEx(key, name) + except WindowsError: + return None + else: + key.Close() + if ret[1] == _winreg.REG_EXPAND_SZ: + return expandvars(ret[0]) + else: + return ret[0] + +def _get_reg_user_value(key, name): + """Return a windows registry value from the CURRENT_USER branch.""" + + return _get_reg_value(HKCU, key, name) + +def _get_reg_machine_value(key, name): + """Return a windows registry value from the LOCAL_MACHINE branch.""" + + return _get_reg_value(HKLM, key, name) + +# public functions +def get_appdata(): + """Return path of directory where apps should store user specific data.""" + + return _get_reg_user_value(SHELL_FOLDERS, 'AppData') + +def get_common_shellfolders(): + """Return mapping of shell folder names (all users) to paths.""" + + return get_shellfolders(branch=HKLM) + +def get_homedir(): + """Return path to user home directory, i.e. 'My Files'.""" + + return _get_reg_user_value(SHELL_FOLDERS, 'Personal') + +def get_sharedconf(prog, *args): + """Return path to shared configuration data for 'prog' from 'vendor'. + + Additional arguments are appended via os.path.join(). + + See also: get_user_conf() + """ + + return os.path.join( + _get_reg_machine_value(SHELL_FOLDERS, 'Common AppData'), + vendor, prog, *args + ) + +def get_shellfolders(branch=HKCU, key=SHELL_FOLDERS): + """Return mapping of shell folder names (current user) to paths.""" + + key = _winreg.OpenKey(branch, key) + folders = {} + i = 0 + while True: + try: + ret = _winreg.EnumValue(key, i) + if ret[2] == _winreg.REG_EXPAND_SZ: + folders[ret[0]] = expandvars(ret[1]) + else: + folders[ret[0]] = ret[1] + except WindowsError: + break + i +=1 + key.Close() + return folders + +def get_userconf(vendor, prog, *args): + """Return path to user configuration data for 'prog' from 'vendor'. + + Additional arguments are appended via os.path.join(), e.g. + use like this: + + optionsfn = get_userconf("ACME Soft", "Exploder", "Options.xml") + """ + + return os.path.join(get_appdata(), vendor, prog, *args) + +def get_windir(): + """Convenience function to get path to windows installation directory.""" + + return unicode(os.environ["WINDIR"]) Property changes on: pymoul/trunk/src/moul/osdependent/win32/winpath.py ___________________________________________________________________ Name: svn:eol-style + native Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-23 11:06:58 UTC (rev 58) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-23 13:02:21 UTC (rev 59) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Fri Jan 19 17:32:22 2007 +# Created: Fri Jan 19 17:47:21 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-23 22:53:02
|
Revision: 63 http://pymoul.svn.sourceforge.net/pymoul/?rev=63&view=rev Author: tiran Date: 2007-01-23 14:53:02 -0800 (Tue, 23 Jan 2007) Log Message: ----------- First version that actually parses a real life graphics.ini file TODO: lot's of checks Modified Paths: -------------- pymoul/trunk/src/moul/config/__init__.py pymoul/trunk/src/moul/file/wdysini.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui Modified: pymoul/trunk/src/moul/config/__init__.py =================================================================== --- pymoul/trunk/src/moul/config/__init__.py 2007-01-23 22:52:09 UTC (rev 62) +++ pymoul/trunk/src/moul/config/__init__.py 2007-01-23 22:53:02 UTC (rev 63) @@ -17,11 +17,8 @@ # """Configuration package """ -__all__ = ('setMoulInstallDir', 'startMOUL', 'getMoulDir') - import os import sys -from moul.log import getLogger # a program under py2exe is sys.frozen __FROZEN__ = bool(getattr(sys, 'frozen', False)) Modified: pymoul/trunk/src/moul/file/wdysini.py =================================================================== --- pymoul/trunk/src/moul/file/wdysini.py 2007-01-23 22:52:09 UTC (rev 62) +++ pymoul/trunk/src/moul/file/wdysini.py 2007-01-23 22:53:02 UTC (rev 63) @@ -21,6 +21,9 @@ __version__ = "$Id$" __revision__ = "$Revision$" +import os +import shutil + from moul.crypt.whatdoyousee import decryptWDYS from moul.crypt.whatdoyousee import encryptWDYS @@ -281,23 +284,57 @@ return self._reverse_vm[(w, h)] def widths(self): + """List of available widths + """ return [w for w, h, wr, hr in self._videomodes] def heights(self): + """List of available heights + """ return [h for w, h, wr, hr in self._videomodes] videoModes = _VideoModes() class ConfFile(object): _options = {} + _filename = None def __init__(self): self.clear() + self._fpath = None def clear(self): self._filedata = {} self._newdata = {} self._order = [] + + def open(self, path): + """Open encrypted file at 'path' + """ + if self._fpath is not None: + raise ValueError("File already open") + self._fpath = os.path.join(path, self._filename) + self.parseEncFile(self._fpath) + + def write(self): + """Write data to file + + The write method uses the savest way possible. The old file is backed + up, the new data is written to another file and at last the original + file is replaced with the new file. + + WINDOWS: os.rename() can't replace the file in place under Windows. + The final operation is not atomic. :( + """ + orig = self._fpath + if orig is None: + raise ValueError("Full path not set") + bak = orig + ".bak" + new = orig + ".new" + shutils.copyfile(orig, bak) # make backup + self.writeEncFile(new) # write new + os.unlink(orig) # stupid windows can't perform an atomic rename + os.rename(new, orig) # move new to orig def parseEncFile(self, fd_name): """Read and parse file (fd or file name) @@ -308,7 +345,8 @@ else: fd = fd_name data = decryptWDYS(fd) - return self.parseString(data) + fd.close() + self.parseString(data) def parseString(self, s): """Parse string with file contents @@ -370,9 +408,21 @@ else: fd = fd_name data = self.writeString() - return encryptWDYS(data, fd) + encryptWDYS(data, fd) + fd.close() + def _get(self, name): + """get descriptor helper + """ + return self._newdata[name] + + def _set(self, name, value): + """set descriptor helper + """ + self._newdata[name] = value + class AudioIni(ConfFile): + _filename = 'audio.ini' _options = { 'Audio.Initialize' : (BoolString, Constrain()), 'Audio.UseEAX' : (BoolString, Constrain()), @@ -388,6 +438,7 @@ } class GraphicsIni(ConfFile): + _filename = 'graphics.ini' _options = { 'Graphics.Width' : (int, Contains(videoModes.widths())), 'Graphics.Height' : (int, Contains(videoModes.heights())), @@ -413,12 +464,6 @@ self._newdata['Graphics.Width'] = w self._newdata['Graphics.Height'] = h - def _get(self, name): - return self._newdata[name] - - def _set(self, name, value): - self._newdata[name] = value - screenres = property(_getScreenRes, _setScreenRes, doc="Screen resolution by index") windowed = property(lambda self: self._get('Graphics.Windowed'), lambda self, v: self._set('Graphics.Windowed', v), Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-23 22:52:09 UTC (rev 62) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-23 22:53:02 UTC (rev 63) @@ -32,14 +32,15 @@ from PyQt4.QtCore import SIGNAL from moul.qt.ui.mainwindow import Ui_MainWindow -from moul.time.cavern import CavernTime -from moul.file.wdysini import AudioIni +from moul.config import lookupDir +#from moul.file.wdysini import AudioIni from moul.file.wdysini import GraphicsIni from moul.file.wdysini import videoModes +from moul.log import getLogger +from moul.log import signalLogDecorator from moul.server.ping import ServerList from moul.server.ping import isSocketError -from moul.log import getLogger -from moul.log import signalLogDecorator +from moul.time.cavern import CavernTime LOG = getLogger('moul.qt') @@ -98,19 +99,36 @@ def _graphics_init(self): """init graphics tab """ + inipath = lookupDir('ini') + self._graphics_ini = gini = GraphicsIni() + gini.open(inipath) + length = len(videoModes) - 1 self.sl_gra_screenres.setMaximum(length) + + self.on_graphicsini_loaded(gini) # XXX: hard coded for testing purpose def on_graphicsini_loaded(self, gini): """SIGNAL: graphicsIniLoaded(file) """ self.sl_gra_screenres.setValue(gini.screenres) + self.sl_gra_quality.setValue(gini.quality) + self.sl_gra_texture.setValue(gini.texture) + self.sl_gra_antialias.setValue(gini.antialias) + self.sl_gra_anisotropic.setValue(gini.anisotropic) + # TODO: self.sl_gra_shadow.setValue(gini.shadow) + self.cb_gra_windowed.setChecked(gini.windowed) + self.cb_gra_vsync.setChecked(gini.vsync) + self.cb_gra_shadow.setChecked(gini.shadow_enabled) @signalLogDecorator(LOG) @pyqtSignature("int") def on_sl_gra_screenres_valueChanged(self, idx): """SIGNAL: valueChanged (int) """ + # XXX: fixme + txt = videoModes.getVidModeHuman(idx) + self.lb_screenres.setText(QtCore.QString(txt)) @signalLogDecorator(LOG) @pyqtSignature("int") Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-23 22:52:09 UTC (rev 62) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-23 22:53:02 UTC (rev 63) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Fri Jan 19 17:47:21 2007 +# Created: Tue Jan 23 23:44:34 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -219,17 +219,17 @@ self.label_13.setObjectName("label_13") self.vboxlayout4.addWidget(self.label_13) - self.sl_gra_aa = QtGui.QSlider(self.verticalLayout_5) - self.sl_gra_aa.setMinimum(1) - self.sl_gra_aa.setMaximum(4) - self.sl_gra_aa.setPageStep(1) - self.sl_gra_aa.setSliderPosition(1) - self.sl_gra_aa.setTracking(False) - self.sl_gra_aa.setOrientation(QtCore.Qt.Horizontal) - self.sl_gra_aa.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_gra_aa.setTickInterval(1) - self.sl_gra_aa.setObjectName("sl_gra_aa") - self.vboxlayout4.addWidget(self.sl_gra_aa) + self.sl_gra_antialias = QtGui.QSlider(self.verticalLayout_5) + self.sl_gra_antialias.setMinimum(1) + self.sl_gra_antialias.setMaximum(4) + self.sl_gra_antialias.setPageStep(1) + self.sl_gra_antialias.setSliderPosition(1) + self.sl_gra_antialias.setTracking(False) + self.sl_gra_antialias.setOrientation(QtCore.Qt.Horizontal) + self.sl_gra_antialias.setTickPosition(QtGui.QSlider.TicksBelow) + self.sl_gra_antialias.setTickInterval(1) + self.sl_gra_antialias.setObjectName("sl_gra_antialias") + self.vboxlayout4.addWidget(self.sl_gra_antialias) self.hboxlayout2 = QtGui.QHBoxLayout() self.hboxlayout2.setMargin(0) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-23 22:52:09 UTC (rev 62) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-23 22:53:02 UTC (rev 63) @@ -433,7 +433,7 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_gra_aa" > + <widget class="QSlider" name="sl_gra_antialias" > <property name="minimum" > <number>1</number> </property> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ti...@us...> - 2007-01-24 16:16:20
|
Revision: 66 http://pymoul.svn.sourceforge.net/pymoul/?rev=66&view=rev Author: tiran Date: 2007-01-24 08:16:05 -0800 (Wed, 24 Jan 2007) Log Message: ----------- Now parses audio.ini and displays shadow setting Modified Paths: -------------- pymoul/trunk/src/moul/file/wdysini.py pymoul/trunk/src/moul/log.py pymoul/trunk/src/moul/osdependent/win32/__init__.py pymoul/trunk/src/moul/qt/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.py pymoul/trunk/src/moul/qt/ui/mainwindow.ui Modified: pymoul/trunk/src/moul/file/wdysini.py =================================================================== --- pymoul/trunk/src/moul/file/wdysini.py 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/file/wdysini.py 2007-01-24 16:16:05 UTC (rev 66) @@ -26,7 +26,10 @@ from moul.crypt.whatdoyousee import decryptWDYS from moul.crypt.whatdoyousee import encryptWDYS +from moul.log import getLogger +LOG = getLogger('moul.file.wdysini') + class BoolStringError(ValueError): pass @@ -147,6 +150,12 @@ def __repr__(self): return str(self) +class QuotedString(str): + """String with extra quotes around it + """ + # TODO: write me + pass + class Constrain(object): """Constrain for configuration values @@ -342,6 +351,7 @@ self.clear() if isinstance(fd_name, basestring): fd = open(fd_name, 'rb') + LOG.debug("Parsing encrypted file %s" % fd_name) close = True else: fd = fd_name @@ -379,7 +389,13 @@ raise ValueError(line) self._newdata = self._filedata.copy() - + self.parserDoneHook() + + def parserDoneHook(self): + """Hook called after the data is read and parsed + """ + pass + def isChanged(self): """Check if the data was changed """ @@ -418,7 +434,7 @@ fd.close() def _get(self, name): - """get descriptor helper + """get descriptor helper """ return self._newdata[name] @@ -426,7 +442,19 @@ """set descriptor helper """ self._newdata[name] = value + + def _getp(self, name): + """get descriptor helper for % sliders + + The slider must have values between 0 and 100 + """ + return int(self._newdata[name] * 100.0) + def _setp(self, name, value): + """set descriptor helper for % sliders + """ + self._newdata[name] = float(value / 100.0) + class AudioIni(ConfFile): _filename = 'audio.ini' _options = { @@ -439,10 +467,81 @@ 'Audio.SetChannelVolume Ambience' : (FloatString, MinMax(0.0, 1.0)), 'Audio.SetChannelVolume NPCVoice' : (FloatString, MinMax(0.0, 1.0)), 'Audio.EnableVoiceRecording' : (int, MinMax(0, 1)), - 'Audio.SetDeviceName' : (str, Constrain()), + 'Audio.SetDeviceName' : (QuotedString, Constrain()), # TODO: add check 'Audio.SetChannelVolume GUI' : (FloatString, MinMax(0.0, 1.0)), } + _devices = ['Generic Software', 'Generic Hardware'] + # plus maybe a custom OpenAL v1.1 device + + def parserDoneHook(self): + """Hook called after the data is read and parsed + """ + # check for OpenAL device + name = self._get('Audio.SetDeviceName') + if name not in self._devices: + LOG.debug("Device added: %s" % name) + self._devices.append(name) + + def getDeviceIdx(self, name): + """Get index by device name + """ + return self._devices.index(name) + def getDeviceName(self, idx): + """Get index by device name + """ + return self._devices[idx] + + def _setFx(self, value): + """Set property helper: SoundFX also changes GUI + """ + self._setp('Audio.SetChannelVolume SoundFX', value) + self._setp('Audio.SetChannelVolume GUI', value) + + def _getDevice(self): + """Get property helpe for device + """ + name = self._get('Audio.SetDeviceName') + return self.getDeviceIdx(name) + + def _setDevice(self, idx): + """Set property helpe for device + """ + name = self.getDeviceName(idx) + self._set('Audio.SetDeviceName', name) + + def numberOfDevices(self): + """Number of devices + """ + return len(self._devices) + + eax = property(lambda self: self._get('Audio.UseEAX'), + lambda self, v: self._set('Audio.UseEAX', v), + ) + mute = property(lambda self: self._get('Audio.MuteAll'), + lambda self, v: self._set('Audio.MuteAll', v), + ) + priority = property(lambda self: self._get('Audio.SetPriorityCutoff'), + lambda self, v: self._set('Audio.SetPriorityCutoff', v), + ) + enablevoice = property(lambda self: self._get('Audio.EnableVoiceRecording'), + lambda self, v: self._set('Audio.EnableVoiceRecording', v), + ) + device = property(_getDevice, _setDevice) + fx = property(lambda self: self._getp('Audio.SetChannelVolume SoundFX'), + _setFx, + ) + music = property(lambda self: self._getp('Audio.SetChannelVolume BgndMusic'), + lambda self, v: self._setp('Audio.SetChannelVolume BgndMusic', v), + ) + ambience = property(lambda self: self._getp('Audio.SetChannelVolume Ambience'), + lambda self, v: self._setp('Audio.SetChannelVolume Ambience', v), + ) + npc = property(lambda self: self._getp('Audio.SetChannelVolume NPCVoice'), + lambda self, v: self._setp('Audio.SetChannelVolume NPCVoice', v), + ) + # TODO: microphon needs an extra handler. The mic slider changes the OS mixer. + class GraphicsIni(ConfFile): _filename = 'graphics.ini' _options = { @@ -489,10 +588,9 @@ shadow_enabled = property(lambda self: self._get('Graphics.Shadow.Enable'), lambda self, v: self._set('Graphics.Shadow.Enable', v), ) - # XXX: shadows - #shadow = property(lambda self: self._get('Graphics.Shadow.VisibleDistance'), - # lambda self, v: self._set('Graphics.Shadow.VisibleDistance', v), - # ) + shadow = property(lambda self: self._getp('Graphics.Shadow.VisibleDistance'), + lambda self, v: self._setp('Graphics.Shadow.VisibleDistance', v), + ) vsync = property(lambda self: self._get('Graphics.EnableVSync'), lambda self, v: self._set('Graphics.EnableVSync', v), ) Modified: pymoul/trunk/src/moul/log.py =================================================================== --- pymoul/trunk/src/moul/log.py 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/log.py 2007-01-24 16:16:05 UTC (rev 66) @@ -57,6 +57,7 @@ repr(args[1:]), repr(kwargs))) return func(*args, **kwargs) logwrapper.__name__ = func.__name__ + logwrapper.__doc__ = func.__doc__ return logwrapper else: return func Modified: pymoul/trunk/src/moul/osdependent/win32/__init__.py =================================================================== --- pymoul/trunk/src/moul/osdependent/win32/__init__.py 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/osdependent/win32/__init__.py 2007-01-24 16:16:05 UTC (rev 66) @@ -24,7 +24,6 @@ import os #from moul.osdependent.win32.miniwinshell import my_documents #from moul.osdependent.win32.miniwinshell import application_data -#from win32com.directsound import directsound from moul.osdependent.win32.winpath import get_homedir from moul.osdependent.win32.winpath import get_appdata @@ -52,18 +51,10 @@ def _startMOUL(installdir, *args): """Start MOUL """ + # TODO: use subprocess module # P_DETACH is similar to P_NOWAIT, but the new process is detached from # the console of the calling process. mode = os.P_DETACH path = os.path.join(installdir, EXEC_NAME) args = (EXEC_NAME,) + args return os.spawnv(mode, path, args) - -#def enumSoundDevices(): -# """ -# """ -# names = [] -# for iid, name, driver in directsound.DirectSoundEnumerate(): -# if iid is not None: -# names.append(name) -# return names Modified: pymoul/trunk/src/moul/qt/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/qt/mainwindow.py 2007-01-24 16:16:05 UTC (rev 66) @@ -33,7 +33,7 @@ from moul.qt.ui.mainwindow import Ui_MainWindow from moul.config import lookupDir -#from moul.file.wdysini import AudioIni +from moul.file.wdysini import AudioIni from moul.file.wdysini import GraphicsIni from moul.file.wdysini import videoModes from moul.log import getLogger @@ -56,6 +56,7 @@ # init handlers self._timezone_init() self._graphics_init() + self._audio_init() self._ping_init() self._systray_init() @@ -95,7 +96,8 @@ self.systemtray.setVisible(False) # ************************************************************************ - # graphics + # graphics settings + def _graphics_init(self): """init graphics tab """ @@ -123,7 +125,8 @@ self.sl_gra_texture.setValue(gini.texture) self.sl_gra_antialias.setValue(gini.antialias) self.sl_gra_anisotropic.setValue(gini.anisotropic) - # TODO: self.sl_gra_shadow.setValue(gini.shadow) + self.sl_gra_shadow.setValue(gini.shadow) + print gini.shadow self.cb_gra_windowed.setChecked(gini.windowed) self.cb_gra_vsync.setChecked(gini.vsync) self.cb_gra_shadow.setChecked(gini.shadow_enabled) @@ -193,6 +196,57 @@ """ # ************************************************************************ + # audio settings + + def _audio_init(self): + """init graphics tab + """ + inipath = lookupDir('ini') + self._audio_ini = aini = AudioIni() + try: + aini.open(inipath) + except Exception, msg: + LOG.exception("Something bad happened while parsing the audio.ini file") + QtGui.QMessageBox.critical(None, + self.trUtf8("Error opening audio.ini"), + self.trUtf8("""Something bad happend while opening the audio.ini\n%s""" % msg)) + return + + self.sl_aud_device.setMaximum(aini.numberOfDevices()-1) + + self.on_audioini_loaded(aini) # XXX: hard coded for testing purpose + + def on_audioini_loaded(self, aini): + """SIGNAL: graphicsIniLoaded(file) + """ + self.sl_aud_npc.setValue(aini.npc) + self.sl_aud_music.setValue(aini.music) + self.sl_aud_fx.setValue(aini.fx) + self.sl_aud_ambience.setValue(aini.ambience) + self.sl_aud_priority.setValue(aini.priority) + self.sl_aud_device.setValue(aini.device) + self.cb_aud_eax.setChecked(aini.eax) + self.cb_aud_mute.setChecked(aini.mute) + self.cb_aud_voicechat.setChecked(aini.enablevoice) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_device_valueChanged(self, idx): + """SIGNAL: valueChanged (int) + """ + # TODO: fixme + txt = self._audio_ini.getDeviceName(idx) + self.lb_aud_device.setText(QtCore.QString(txt)) + + @signalLogDecorator(LOG) + @pyqtSignature("int") + def on_sl_aud_device_sliderMoved(self, idx): + """SIGNAL: sliderMoved(int) + """ + txt = self._audio_ini.getDeviceName(idx) + self.lb_aud_device.setText(QtCore.QString(txt)) + + # ************************************************************************ # time zones def _timezone_init(self): Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.py =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.py 2007-01-24 16:16:05 UTC (rev 66) @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'src\moul\qt\ui\mainwindow.ui' # -# Created: Wed Jan 24 01:37:39 2007 +# Created: Wed Jan 24 16:49:25 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -232,14 +232,15 @@ self.vboxlayout3.addWidget(self.label_15) self.sl_gra_shadow = QtGui.QSlider(self.verticalLayout_8) - self.sl_gra_shadow.setMinimum(1) - self.sl_gra_shadow.setMaximum(3) - self.sl_gra_shadow.setPageStep(1) - self.sl_gra_shadow.setSliderPosition(1) + self.sl_gra_shadow.setMinimum(0) + self.sl_gra_shadow.setMaximum(100) + self.sl_gra_shadow.setPageStep(10) + self.sl_gra_shadow.setProperty("value",QtCore.QVariant(0)) + self.sl_gra_shadow.setSliderPosition(0) self.sl_gra_shadow.setTracking(False) self.sl_gra_shadow.setOrientation(QtCore.Qt.Horizontal) self.sl_gra_shadow.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_gra_shadow.setTickInterval(1) + self.sl_gra_shadow.setTickInterval(25) self.sl_gra_shadow.setObjectName("sl_gra_shadow") self.vboxlayout3.addWidget(self.sl_gra_shadow) @@ -415,46 +416,19 @@ self.sl_aud_npc.setObjectName("sl_aud_npc") self.vboxlayout8.addWidget(self.sl_aud_npc) - self.verticalLayout_11 = QtGui.QWidget(self.groupBox_aud_level) - self.verticalLayout_11.setGeometry(QtCore.QRect(20,80,179,43)) - self.verticalLayout_11.setObjectName("verticalLayout_11") + self.verticalLayout_9 = QtGui.QWidget(self.groupBox_aud_level) + self.verticalLayout_9.setGeometry(QtCore.QRect(20,30,179,43)) + self.verticalLayout_9.setObjectName("verticalLayout_9") - self.vboxlayout9 = QtGui.QVBoxLayout(self.verticalLayout_11) + self.vboxlayout9 = QtGui.QVBoxLayout(self.verticalLayout_9) self.vboxlayout9.setMargin(0) self.vboxlayout9.setSpacing(6) self.vboxlayout9.setObjectName("vboxlayout9") - self.label_30 = QtGui.QLabel(self.verticalLayout_11) - self.label_30.setAlignment(QtCore.Qt.AlignCenter) - self.label_30.setObjectName("label_30") - self.vboxlayout9.addWidget(self.label_30) - - self.sl_aud_music = QtGui.QSlider(self.verticalLayout_11) - self.sl_aud_music.setMinimum(0) - self.sl_aud_music.setMaximum(100) - self.sl_aud_music.setPageStep(10) - self.sl_aud_music.setProperty("value",QtCore.QVariant(0)) - self.sl_aud_music.setSliderPosition(0) - self.sl_aud_music.setTracking(False) - self.sl_aud_music.setOrientation(QtCore.Qt.Horizontal) - self.sl_aud_music.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_aud_music.setTickInterval(25) - self.sl_aud_music.setObjectName("sl_aud_music") - self.vboxlayout9.addWidget(self.sl_aud_music) - - self.verticalLayout_9 = QtGui.QWidget(self.groupBox_aud_level) - self.verticalLayout_9.setGeometry(QtCore.QRect(20,30,179,43)) - self.verticalLayout_9.setObjectName("verticalLayout_9") - - self.vboxlayout10 = QtGui.QVBoxLayout(self.verticalLayout_9) - self.vboxlayout10.setMargin(0) - self.vboxlayout10.setSpacing(6) - self.vboxlayout10.setObjectName("vboxlayout10") - self.label_28 = QtGui.QLabel(self.verticalLayout_9) self.label_28.setAlignment(QtCore.Qt.AlignCenter) self.label_28.setObjectName("label_28") - self.vboxlayout10.addWidget(self.label_28) + self.vboxlayout9.addWidget(self.label_28) self.sl_aud_fx = QtGui.QSlider(self.verticalLayout_9) self.sl_aud_fx.setMinimum(0) @@ -467,75 +441,66 @@ self.sl_aud_fx.setTickPosition(QtGui.QSlider.TicksBelow) self.sl_aud_fx.setTickInterval(25) self.sl_aud_fx.setObjectName("sl_aud_fx") - self.vboxlayout10.addWidget(self.sl_aud_fx) + self.vboxlayout9.addWidget(self.sl_aud_fx) self.verticalLayout_10 = QtGui.QWidget(self.groupBox_aud_level) self.verticalLayout_10.setGeometry(QtCore.QRect(230,30,179,43)) self.verticalLayout_10.setObjectName("verticalLayout_10") - self.vboxlayout11 = QtGui.QVBoxLayout(self.verticalLayout_10) - self.vboxlayout11.setMargin(0) - self.vboxlayout11.setSpacing(6) - self.vboxlayout11.setObjectName("vboxlayout11") + self.vboxlayout10 = QtGui.QVBoxLayout(self.verticalLayout_10) + self.vboxlayout10.setMargin(0) + self.vboxlayout10.setSpacing(6) + self.vboxlayout10.setObjectName("vboxlayout10") self.label_29 = QtGui.QLabel(self.verticalLayout_10) self.label_29.setAlignment(QtCore.Qt.AlignCenter) self.label_29.setObjectName("label_29") - self.vboxlayout11.addWidget(self.label_29) + self.vboxlayout10.addWidget(self.label_29) - self.sl_aud_ambient = QtGui.QSlider(self.verticalLayout_10) - self.sl_aud_ambient.setMinimum(0) - self.sl_aud_ambient.setMaximum(100) - self.sl_aud_ambient.setPageStep(10) - self.sl_aud_ambient.setProperty("value",QtCore.QVariant(0)) - self.sl_aud_ambient.setSliderPosition(0) - self.sl_aud_ambient.setTracking(False) - self.sl_aud_ambient.setOrientation(QtCore.Qt.Horizontal) - self.sl_aud_ambient.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_aud_ambient.setTickInterval(25) - self.sl_aud_ambient.setObjectName("sl_aud_ambient") - self.vboxlayout11.addWidget(self.sl_aud_ambient) + self.sl_aud_ambience = QtGui.QSlider(self.verticalLayout_10) + self.sl_aud_ambience.setMinimum(0) + self.sl_aud_ambience.setMaximum(100) + self.sl_aud_ambience.setPageStep(10) + self.sl_aud_ambience.setProperty("value",QtCore.QVariant(0)) + self.sl_aud_ambience.setSliderPosition(0) + self.sl_aud_ambience.setTracking(False) + self.sl_aud_ambience.setOrientation(QtCore.Qt.Horizontal) + self.sl_aud_ambience.setTickPosition(QtGui.QSlider.TicksBelow) + self.sl_aud_ambience.setTickInterval(25) + self.sl_aud_ambience.setObjectName("sl_aud_ambience") + self.vboxlayout10.addWidget(self.sl_aud_ambience) - self.cb_aud_mute = QtGui.QCheckBox(self.groupBox_aud_level) - self.cb_aud_mute.setGeometry(QtCore.QRect(180,10,70,19)) - self.cb_aud_mute.setObjectName("cb_aud_mute") + self.verticalLayout_11 = QtGui.QWidget(self.groupBox_aud_level) + self.verticalLayout_11.setGeometry(QtCore.QRect(20,80,179,43)) + self.verticalLayout_11.setObjectName("verticalLayout_11") - self.groupBox_voicechat = QtGui.QGroupBox(self.tab_audio) - self.groupBox_voicechat.setEnabled(True) - self.groupBox_voicechat.setGeometry(QtCore.QRect(10,150,431,71)) - self.groupBox_voicechat.setObjectName("groupBox_voicechat") + self.vboxlayout11 = QtGui.QVBoxLayout(self.verticalLayout_11) + self.vboxlayout11.setMargin(0) + self.vboxlayout11.setSpacing(6) + self.vboxlayout11.setObjectName("vboxlayout11") - self.verticalLayout_13 = QtGui.QWidget(self.groupBox_voicechat) - self.verticalLayout_13.setGeometry(QtCore.QRect(20,20,179,43)) - self.verticalLayout_13.setObjectName("verticalLayout_13") + self.label_30 = QtGui.QLabel(self.verticalLayout_11) + self.label_30.setAlignment(QtCore.Qt.AlignCenter) + self.label_30.setObjectName("label_30") + self.vboxlayout11.addWidget(self.label_30) - self.vboxlayout12 = QtGui.QVBoxLayout(self.verticalLayout_13) - self.vboxlayout12.setMargin(0) - self.vboxlayout12.setSpacing(6) - self.vboxlayout12.setObjectName("vboxlayout12") + self.sl_aud_music = QtGui.QSlider(self.verticalLayout_11) + self.sl_aud_music.setMinimum(0) + self.sl_aud_music.setMaximum(100) + self.sl_aud_music.setPageStep(10) + self.sl_aud_music.setProperty("value",QtCore.QVariant(0)) + self.sl_aud_music.setSliderPosition(0) + self.sl_aud_music.setTracking(False) + self.sl_aud_music.setOrientation(QtCore.Qt.Horizontal) + self.sl_aud_music.setTickPosition(QtGui.QSlider.TicksBelow) + self.sl_aud_music.setTickInterval(25) + self.sl_aud_music.setObjectName("sl_aud_music") + self.vboxlayout11.addWidget(self.sl_aud_music) - self.label_33 = QtGui.QLabel(self.verticalLayout_13) - self.label_33.setAlignment(QtCore.Qt.AlignCenter) - self.label_33.setObjectName("label_33") - self.vboxlayout12.addWidget(self.label_33) + self.cb_aud_mute = QtGui.QCheckBox(self.groupBox_aud_level) + self.cb_aud_mute.setGeometry(QtCore.QRect(180,10,70,19)) + self.cb_aud_mute.setObjectName("cb_aud_mute") - self.sl_aud_voicechat = QtGui.QSlider(self.verticalLayout_13) - self.sl_aud_voicechat.setMinimum(0) - self.sl_aud_voicechat.setMaximum(100) - self.sl_aud_voicechat.setPageStep(10) - self.sl_aud_voicechat.setProperty("value",QtCore.QVariant(0)) - self.sl_aud_voicechat.setSliderPosition(0) - self.sl_aud_voicechat.setTracking(False) - self.sl_aud_voicechat.setOrientation(QtCore.Qt.Horizontal) - self.sl_aud_voicechat.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_aud_voicechat.setTickInterval(25) - self.sl_aud_voicechat.setObjectName("sl_aud_voicechat") - self.vboxlayout12.addWidget(self.sl_aud_voicechat) - - self.cb_aud_voicechat = QtGui.QCheckBox(self.groupBox_voicechat) - self.cb_aud_voicechat.setGeometry(QtCore.QRect(250,30,111,19)) - self.cb_aud_voicechat.setObjectName("cb_aud_voicechat") - self.groupBox_aud_hardware = QtGui.QGroupBox(self.tab_audio) self.groupBox_aud_hardware.setEnabled(True) self.groupBox_aud_hardware.setGeometry(QtCore.QRect(10,230,431,101)) @@ -545,45 +510,45 @@ self.verticalLayout_14.setGeometry(QtCore.QRect(230,40,179,43)) self.verticalLayout_14.setObjectName("verticalLayout_14") - self.vboxlayout13 = QtGui.QVBoxLayout(self.verticalLayout_14) - self.vboxlayout13.setMargin(0) - self.vboxlayout13.setSpacing(6) - self.vboxlayout13.setObjectName("vboxlayout13") + self.vboxlayout12 = QtGui.QVBoxLayout(self.verticalLayout_14) + self.vboxlayout12.setMargin(0) + self.vboxlayout12.setSpacing(6) + self.vboxlayout12.setObjectName("vboxlayout12") self.label_34 = QtGui.QLabel(self.verticalLayout_14) self.label_34.setAlignment(QtCore.Qt.AlignCenter) self.label_34.setObjectName("label_34") - self.vboxlayout13.addWidget(self.label_34) + self.vboxlayout12.addWidget(self.label_34) self.sl_aud_priority = QtGui.QSlider(self.verticalLayout_14) - self.sl_aud_priority.setMaximum(2) + self.sl_aud_priority.setMaximum(9) self.sl_aud_priority.setPageStep(1) self.sl_aud_priority.setSliderPosition(0) self.sl_aud_priority.setTracking(False) self.sl_aud_priority.setOrientation(QtCore.Qt.Horizontal) self.sl_aud_priority.setTickPosition(QtGui.QSlider.TicksBelow) - self.sl_aud_priority.setTickInterval(1) + self.sl_aud_priority.setTickInterval(3) self.sl_aud_priority.setObjectName("sl_aud_priority") - self.vboxlayout13.addWidget(self.sl_aud_priority) + self.vboxlayout12.addWidget(self.sl_aud_priority) self.verticalLayout_15 = QtGui.QWidget(self.groupBox_aud_hardware) self.verticalLayout_15.setGeometry(QtCore.QRect(20,20,179,63)) self.verticalLayout_15.setObjectName("verticalLayout_15") - self.vboxlayout14 = QtGui.QVBoxLayout(self.verticalLayout_15) - self.vboxlayout14.setMargin(0) - self.vboxlayout14.setSpacing(6) - self.vboxlayout14.setObjectName("vboxlayout14") + self.vboxlayout13 = QtGui.QVBoxLayout(self.verticalLayout_15) + self.vboxlayout13.setMargin(0) + self.vboxlayout13.setSpacing(6) + self.vboxlayout13.setObjectName("vboxlayout13") self.label_35 = QtGui.QLabel(self.verticalLayout_15) self.label_35.setAlignment(QtCore.Qt.AlignCenter) self.label_35.setObjectName("label_35") - self.vboxlayout14.addWidget(self.label_35) + self.vboxlayout13.addWidget(self.label_35) - self.label_3 = QtGui.QLabel(self.verticalLayout_15) - self.label_3.setAlignment(QtCore.Qt.AlignCenter) - self.label_3.setObjectName("label_3") - self.vboxlayout14.addWidget(self.label_3) + self.lb_aud_device = QtGui.QLabel(self.verticalLayout_15) + self.lb_aud_device.setAlignment(QtCore.Qt.AlignCenter) + self.lb_aud_device.setObjectName("lb_aud_device") + self.vboxlayout13.addWidget(self.lb_aud_device) self.sl_aud_device = QtGui.QSlider(self.verticalLayout_15) self.sl_aud_device.setMaximum(2) @@ -594,11 +559,49 @@ self.sl_aud_device.setTickPosition(QtGui.QSlider.TicksBelow) self.sl_aud_device.setTickInterval(1) self.sl_aud_device.setObjectName("sl_aud_device") - self.vboxlayout14.addWidget(self.sl_aud_device) + self.vboxlayout13.addWidget(self.sl_aud_device) self.cb_aud_eax = QtGui.QCheckBox(self.groupBox_aud_hardware) self.cb_aud_eax.setGeometry(QtCore.QRect(260,10,111,19)) self.cb_aud_eax.setObjectName("cb_aud_eax") + + self.groupBox_voicechat = QtGui.QGroupBox(self.tab_audio) + self.groupBox_voicechat.setEnabled(True) + self.groupBox_voicechat.setGeometry(QtCore.QRect(10,150,431,71)) + self.groupBox_voicechat.setObjectName("groupBox_voicechat") + + self.cb_aud_voicechat = QtGui.QCheckBox(self.groupBox_voicechat) + self.cb_aud_voicechat.setGeometry(QtCore.QRect(250,30,111,19)) + self.cb_aud_voicechat.setObjectName("cb_aud_voicechat") + + self.verticalLayout_13 = QtGui.QWidget(self.groupBox_voicechat) + self.verticalLayout_13.setGeometry(QtCore.QRect(20,20,179,43)) + self.verticalLayout_13.setObjectName("verticalLayout_13") + + self.vboxlayout14 = QtGui.QVBoxLayout(self.verticalLayout_13) + self.vboxlayout14.setMargin(0) + self.vboxlayout14.setSpacing(6) + self.vboxlayout14.setObjectName("vboxlayout14") + + self.label_33 = QtGui.QLabel(self.verticalLayout_13) + self.label_33.setEnabled(False) + self.label_33.setAlignment(QtCore.Qt.AlignCenter) + self.label_33.setObjectName("label_33") + self.vboxlayout14.addWidget(self.label_33) + + self.sl_aud_microphon = QtGui.QSlider(self.verticalLayout_13) + self.sl_aud_microphon.setEnabled(False) + self.sl_aud_microphon.setMinimum(0) + self.sl_aud_microphon.setMaximum(100) + self.sl_aud_microphon.setPageStep(10) + self.sl_aud_microphon.setProperty("value",QtCore.QVariant(0)) + self.sl_aud_microphon.setSliderPosition(0) + self.sl_aud_microphon.setTracking(False) + self.sl_aud_microphon.setOrientation(QtCore.Qt.Horizontal) + self.sl_aud_microphon.setTickPosition(QtGui.QSlider.TicksBelow) + self.sl_aud_microphon.setTickInterval(25) + self.sl_aud_microphon.setObjectName("sl_aud_microphon") + self.vboxlayout14.addWidget(self.sl_aud_microphon) self.tab_graphics.addTab(self.tab_audio,"") self.tab_time = QtGui.QWidget() @@ -710,7 +713,7 @@ MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) - self.tab_graphics.setCurrentIndex(2) + self.tab_graphics.setCurrentIndex(0) QtCore.QObject.connect(self.buttonbox_rresavcl,QtCore.SIGNAL("rejected()"),MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -746,18 +749,18 @@ self.tab_graphics.setTabText(self.tab_graphics.indexOf(self.tab_graphics1), QtGui.QApplication.translate("MainWindow", "Graphics", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_aud_level.setTitle(QtGui.QApplication.translate("MainWindow", "Level", None, QtGui.QApplication.UnicodeUTF8)) self.label_31.setText(QtGui.QApplication.translate("MainWindow", "NPC Voices", None, QtGui.QApplication.UnicodeUTF8)) + self.label_28.setText(QtGui.QApplication.translate("MainWindow", "Sound FX", None, QtGui.QApplication.UnicodeUTF8)) + self.label_29.setText(QtGui.QApplication.translate("MainWindow", "Ambience Sound", None, QtGui.QApplication.UnicodeUTF8)) self.label_30.setText(QtGui.QApplication.translate("MainWindow", "Music", None, QtGui.QApplication.UnicodeUTF8)) - self.label_28.setText(QtGui.QApplication.translate("MainWindow", "Sound FX", None, QtGui.QApplication.UnicodeUTF8)) - self.label_29.setText(QtGui.QApplication.translate("MainWindow", "Ambient Sounds", None, QtGui.QApplication.UnicodeUTF8)) self.cb_aud_mute.setText(QtGui.QApplication.translate("MainWindow", "Mute all", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox_voicechat.setTitle(QtGui.QApplication.translate("MainWindow", "Voice chat", None, QtGui.QApplication.UnicodeUTF8)) - self.label_33.setText(QtGui.QApplication.translate("MainWindow", "Microphon Level", None, QtGui.QApplication.UnicodeUTF8)) - self.cb_aud_voicechat.setText(QtGui.QApplication.translate("MainWindow", "Enable Voice Chat", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_aud_hardware.setTitle(QtGui.QApplication.translate("MainWindow", "Hardware", None, QtGui.QApplication.UnicodeUTF8)) self.label_34.setText(QtGui.QApplication.translate("MainWindow", "Sound Priority", None, QtGui.QApplication.UnicodeUTF8)) self.label_35.setText(QtGui.QApplication.translate("MainWindow", "Audio Modes", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("MainWindow", "Generic Software", None, QtGui.QApplication.UnicodeUTF8)) + self.lb_aud_device.setText(QtGui.QApplication.translate("MainWindow", "Generic Software", None, QtGui.QApplication.UnicodeUTF8)) self.cb_aud_eax.setText(QtGui.QApplication.translate("MainWindow", "Enable EAX", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_voicechat.setTitle(QtGui.QApplication.translate("MainWindow", "Voice chat", None, QtGui.QApplication.UnicodeUTF8)) + self.cb_aud_voicechat.setText(QtGui.QApplication.translate("MainWindow", "Enable Voice Chat", None, QtGui.QApplication.UnicodeUTF8)) + self.label_33.setText(QtGui.QApplication.translate("MainWindow", "Microphon Level", None, QtGui.QApplication.UnicodeUTF8)) self.tab_graphics.setTabText(self.tab_graphics.indexOf(self.tab_audio), QtGui.QApplication.translate("MainWindow", "Audio", None, QtGui.QApplication.UnicodeUTF8)) self.gb_caverntime.setTitle(QtGui.QApplication.translate("MainWindow", "Time zones", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("MainWindow", "Cavern time:", None, QtGui.QApplication.UnicodeUTF8)) Modified: pymoul/trunk/src/moul/qt/ui/mainwindow.ui =================================================================== --- pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-24 00:42:26 UTC (rev 65) +++ pymoul/trunk/src/moul/qt/ui/mainwindow.ui 2007-01-24 16:16:05 UTC (rev 66) @@ -129,7 +129,7 @@ <enum>QTabWidget::North</enum> </property> <property name="currentIndex" > - <number>2</number> + <number>0</number> </property> <widget class="QWidget" name="tab_graphics" > <attribute name="title" > @@ -448,16 +448,19 @@ <item> <widget class="QSlider" name="sl_gra_shadow" > <property name="minimum" > - <number>1</number> + <number>0</number> </property> <property name="maximum" > - <number>3</number> + <number>100</number> </property> <property name="pageStep" > - <number>1</number> + <number>10</number> </property> + <property name="value" > + <number>0</number> + </property> <property name="sliderPosition" > - <number>1</number> + <number>0</number> </property> <property name="tracking" > <bool>false</bool> @@ -469,7 +472,7 @@ <enum>QSlider::TicksBelow</enum> </property> <property name="tickInterval" > - <number>1</number> + <number>25</number> </property> </widget> </item> @@ -838,11 +841,11 @@ </item> </layout> </widget> - <widget class="QWidget" name="verticalLayout_11" > + <widget class="QWidget" name="verticalLayout_9" > <property name="geometry" > <rect> <x>20</x> - <y>80</y> + <y>30</y> <width>179</width> <height>43</height> </rect> @@ -855,9 +858,9 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_30" > + <widget class="QLabel" name="label_28" > <property name="text" > - <string>Music</string> + <string>Sound FX</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -865,7 +868,7 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_aud_music" > + <widget class="QSlider" name="sl_aud_fx" > <property name="minimum" > <number>0</number> </property> @@ -897,10 +900,10 @@ </item> </layout> </widget> - <widget class="QWidget" name="verticalLayout_9" > + <widget class="QWidget" name="verticalLayout_10" > <property name="geometry" > <rect> - <x>20</x> + <x>230</x> <y>30</y> <width>179</width> <height>43</height> @@ -914,9 +917,9 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_28" > + <widget class="QLabel" name="label_29" > <property name="text" > - <string>Sound FX</string> + <string>Ambience Sound</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -924,7 +927,7 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_aud_fx" > + <widget class="QSlider" name="sl_aud_ambience" > <property name="minimum" > <number>0</number> </property> @@ -956,11 +959,11 @@ </item> </layout> </widget> - <widget class="QWidget" name="verticalLayout_10" > + <widget class="QWidget" name="verticalLayout_11" > <property name="geometry" > <rect> - <x>230</x> - <y>30</y> + <x>20</x> + <y>80</y> <width>179</width> <height>43</height> </rect> @@ -973,9 +976,9 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_29" > + <widget class="QLabel" name="label_30" > <property name="text" > - <string>Ambient Sounds</string> + <string>Music</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -983,7 +986,7 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_aud_ambient" > + <widget class="QSlider" name="sl_aud_music" > <property name="minimum" > <number>0</number> </property> @@ -1029,26 +1032,26 @@ </property> </widget> </widget> - <widget class="QGroupBox" name="groupBox_voicechat" > + <widget class="QGroupBox" name="groupBox_aud_hardware" > <property name="enabled" > <bool>true</bool> </property> <property name="geometry" > <rect> <x>10</x> - <y>150</y> + <y>230</y> <width>431</width> - <height>71</height> + <height>101</height> </rect> </property> <property name="title" > - <string>Voice chat</string> + <string>Hardware</string> </property> - <widget class="QWidget" name="verticalLayout_13" > + <widget class="QWidget" name="verticalLayout_14" > <property name="geometry" > <rect> - <x>20</x> - <y>20</y> + <x>230</x> + <y>40</y> <width>179</width> <height>43</height> </rect> @@ -1061,9 +1064,9 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_33" > + <widget class="QLabel" name="label_34" > <property name="text" > - <string>Microphon Level</string> + <string>Sound Priority</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -1071,19 +1074,13 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_aud_voicechat" > - <property name="minimum" > - <number>0</number> - </property> + <widget class="QSlider" name="sl_aud_priority" > <property name="maximum" > - <number>100</number> + <number>9</number> </property> <property name="pageStep" > - <number>10</number> + <number>1</number> </property> - <property name="value" > - <number>0</number> - </property> <property name="sliderPosition" > <number>0</number> </property> @@ -1097,48 +1094,19 @@ <enum>QSlider::TicksBelow</enum> </property> <property name="tickInterval" > - <number>25</number> + <number>3</number> </property> </widget> </item> </layout> </widget> - <widget class="QCheckBox" name="cb_aud_voicechat" > + <widget class="QWidget" name="verticalLayout_15" > <property name="geometry" > <rect> - <x>250</x> - <y>30</y> - <width>111</width> - <height>19</height> - </rect> - </property> - <property name="text" > - <string>Enable Voice Chat</string> - </property> - </widget> - </widget> - <widget class="QGroupBox" name="groupBox_aud_hardware" > - <property name="enabled" > - <bool>true</bool> - </property> - <property name="geometry" > - <rect> - <x>10</x> - <y>230</y> - <width>431</width> - <height>101</height> - </rect> - </property> - <property name="title" > - <string>Hardware</string> - </property> - <widget class="QWidget" name="verticalLayout_14" > - <property name="geometry" > - <rect> - <x>230</x> - <y>40</y> + <x>20</x> + <y>20</y> <width>179</width> - <height>43</height> + <height>63</height> </rect> </property> <layout class="QVBoxLayout" > @@ -1149,9 +1117,9 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_34" > + <widget class="QLabel" name="label_35" > <property name="text" > - <string>Sound Priority</string> + <string>Audio Modes</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -1159,7 +1127,17 @@ </widget> </item> <item> - <widget class="QSlider" name="sl_aud_priority" > + <widget class="QLabel" name="lb_aud_device" > + <property name="text" > + <string>Generic Software</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="sl_aud_device" > <property name="maximum" > <number>2</number> </property> @@ -1185,13 +1163,55 @@ </item> </layout> </widget> - <widget class="QWidget" name="verticalLayout_15" > + <widget class="QCheckBox" name="cb_aud_eax" > <property name="geometry" > <rect> + <x>260</x> + <y>10</y> + <width>111</width> + <height>19</height> + </rect> + </property> + <property name="text" > + <string>Enable EAX</string> + </property> + </widget> + </widget> + <widget class="QGroupBox" name="groupBox_voicechat" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="geometry" > + <rect> + <x>10</x> + <y>150</y> + <width>431</width> + <height>71</height> + </rect> + </property> + <property name="title" > + <string>Voice chat</string> + </property> + <widget class="QCheckBox" name="cb_aud_voicechat" > + <property name="geometry" > + <rect> + <x>250</x> + <y>30</y> + <width>111</width> + <height>19</height> + </rect> + </property> + <property name="text" > + <string>Enable Voice Chat</string> + </property> + </widget> + <widget class="QWidget" name="verticalLayout_13" > + <property name="geometry" > + <rect> <x>20</x> <y>20</y> <width>179</width> - <height>63</height> + <height>43</height> </rect> </property> <layout class="QVBoxLayout" > @@ -1202,9 +1222,12 @@ <number>6</number> </property> <item> - <widget class="QLabel" name="label_35" > + <widget class="QLabel" name="label_33" > + <property name="enabled" > + <bool>false</bool> + </property> <property name="text" > - <string>Audio Modes</string> + <string>Microphon Level</string> </property> <property name="alignment" > <set>Qt::AlignCenter</set> @@ -1212,23 +1235,22 @@ </widget> </item> <item> - <widget class="QLabel" name="label_3" > - <property name="text" > - <string>Generic Software</string> + <widget class="QSlider" name="sl_aud_microphon" > + <property name="enabled" > + <bool>false</bool> </property> - <property name="alignment" > - <set>Qt::AlignCenter</set> + <property name="minimum" > + <number>0</number> </property> - </widget> - </item> - <item> - <widget class="QSlider" name="sl_aud_device" > <property name="maximum" > - <number>2</number> + <number>100</number> </property> <property name="pageStep" > - <number>1</number> + <number>10</number> </property> + <property name="value" > + <number>0</number> + </property> <property name="sliderPosition" > <number>0</number> </property> @@ -1242,25 +1264,12 @@ <enum>QSlider::TicksBelow</enum> </property> <property name="tickInterval" > - <number>1</number> + <number>25</number> </property> </widget> </item> </layout> </widget> - <widget class="QCheckBox" name="cb_aud_eax" > - <property name="geometry" > - <rect> - <x>260</x> - <y>10</y> - <width>111</width> - <height>19</height> - </rect> - </property> - <property name="text" > - <string>Enable EAX</string> - </property> - </widget> </widget> </widget> <widget class="QWidget" name="tab_time" > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |