You can subscribe to this list here.
| 2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(5) |
Jun
(43) |
Jul
(2) |
Aug
(6) |
Sep
(13) |
Oct
(5) |
Nov
|
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Stas Z. <sta...@us...> - 2005-07-05 15:16:47
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8541 Added Files: ModalPopUpDialog_forms.py ModalPopupDialog.ui.h Log Message: added qt forms --- NEW FILE: ModalPopupDialog.ui.h --- /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ void ModalPopUpDialog::pushButtonCancel_clicked() { self.done(False) } void ModalPopUpDialog::pushButtonOk_clicked() { self.done(True) } --- NEW FILE: ModalPopUpDialog_forms.py --- # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'ModalPopupDialog.ui' # # Created: Tue Jul 5 15:49:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # # WARNING! All changes made in this file will be lost! from qt import * image0_data = \ "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \ "\x49\x48\x44\x52\x00\x00\x00\x20\x00\x00\x00\x20" \ "\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\x00\x00\x08" \ "\xad\x49\x44\x41\x54\x58\x85\xe5\x97\xcb\x6f\x1b" \ "\xd7\x15\xc6\x7f\x77\x66\xc8\x21\x29\x52\x0f\x4a" \ "\x91\xac\xd8\xae\x9c\x58\xb2\x15\x39\x8e\x11\xc7" \ "\x8f\x22\x86\x1b\xa3\x69\x0a\x7b\x51\x34\x0d\xba" \ "\x08\x52\xa0\x06\xbc\x49\x17\xfd\x0f\x0a\x78\xd3" \ "\x4d\x16\xd9\xb8\x45\xe2\x00\x29\xea\xa2\x1b\x23" \ "\x4d\xe0\x00\xad\xfb\x4a\x53\x35\x88\x9d\xda\xce" \ "\xa3\x52\x6c\xc7\xb2\x1c\xd9\x92\x28\xca\x22\x29" \ "\x92\x43\x71\x48\xce\x0c\x67\xee\xdc\x2e\x24\xb1" \ "\x96\x25\xb7\x41\xd1\x5d\x0f\x70\xc0\x8b\xb9\x33" \ "\xf7\xfb\xce\x77\xce\x87\xe1\xc0\xff\x7b\x88\x8d" \ "\x2e\x6e\xdd\x14\x37\x8a\x96\x67\x2a\xc5\x56\x19" \ "\x86\x8f\x9b\x86\xfe\xac\x21\xc4\x36\x04\xdb\xc2" \ "\x50\x19\x41\xa8\x1e\xd2\x34\x11\x9a\x11\xbd\x89" \ "\x82\x40\x86\xba\x17\x84\xa6\x26\x94\x0c\xa1\xa9" \ "\x42\x1c\xa0\x22\x51\x45\x0d\xf1\xc7\xbe\x9e\xd8" \ "\x2f\xe7\x72\x8e\xf5\x95\x08\x44\x0c\xb1\x2b\x6a" \ "\x88\xef\x03\x27\x13\xa6\x61\x1d\x1d\x79\x6c\xea" \ "\xc9\xbd\xfb\x36\xb5\x77\x76\x26\x23\xa8\x88\xae" \ "\x69\x7a\xc2\xd0\xe3\x1a\x4a\x0b\x65\x40\x18\x04" \ "\x10\x86\xb8\x4d\x9f\xa6\x0c\xdc\x40\x86\x72\x7e" \ "\x3e\x6b\x7f\xf4\xf9\xf5\xe6\x8c\x55\x23\xe7\xd4" \ "\x53\x0a\xda\x12\x71\x23\x2a\xa5\x7a\xb1\x2d\x61" \ "\x7c\x3c\x97\x73\xa6\x37\x22\x90\xd2\x04\x2f\x24" \ "\x62\xda\xe9\x1d\xbd\x7d\xe5\x63\xbb\x87\x7b\x87" \ "\x1e\xee\x8b\xa4\xe3\x31\xbc\x5a\x15\xdb\xb2\x50" \ "\x28\x40\x20\x64\x00\x2a\x44\x13\x02\x5d\x08\x84" \ "\x00\x81\x40\xd7\x04\x9a\x58\x3e\xb2\xd1\x0c\xb0" \ "\x5c\x8f\xb9\x6a\x9d\xaa\xe7\xf3\xfe\xcc\xbc\xb5" \ "\xd4\x6c\x86\xa1\xa0\x23\x54\x3c\x6b\xd7\x83\x0f" \ "\x5b\x04\x52\x6d\x46\x7f\xd4\x30\x7f\x10\x86\xfe" \ "\x4f\x4f\x1c\xda\xcf\xc1\x47\x06\x62\x46\xd0\xa4" \ "\x64\x55\xb0\xaa\x55\x94\x52\xc4\x4c\x13\xbd\xbd" \ "\x93\xe4\xe6\x01\xda\x92\x29\x12\xbd\x7d\x08\x23" \ "\x82\x58\xa9\x41\x95\xf3\x74\xa6\x52\xd4\x32\xb7" \ "\xa9\xe7\xe6\xf1\x6b\x36\x00\x5e\x10\x50\xf7\x03" \ "\xe6\xaa\x0d\x6e\x15\xab\xcd\xb1\xc5\x62\x6e\xd1" \ "\x75\xfb\xda\x93\x91\xc7\xe6\x72\xce\xb4\x48\xb5" \ "\x19\x03\x86\x61\xbc\xd8\x69\xc6\x7e\xf2\xca\xf7" \ "\x8e\x26\x84\x53\xd7\x17\x8b\x45\x1a\x42\x23\xd1" \ "\xd3\xcb\xd7\xf6\x7e\x1d\x63\xd3\x56\xb6\xee\x7a" \ "\x82\x74\x3a\x4d\x32\x99\x24\x12\x89\x2c\x83\x2a" \ "\x85\x52\xaa\xb5\x5e\x0d\xa5\x14\xf5\xc5\x1c\xd6" \ "\xe4\x17\xe4\x3e\xb9\x88\x3d\x3f\x4b\x6d\x31\x4f" \ "\xcd\xf3\xb9\x3c\xbf\xc8\x9f\xef\x64\xed\x42\xc3" \ "\xbd\xed\x07\x3c\x29\xcc\x88\x78\xf6\x5b\xdb\x37" \ "\xbf\xf7\xd4\xd0\x60\xf0\x78\x47\x22\x7a\xfb\x6e" \ "\x8e\x44\xff\x16\xba\xf6\x1e\xe2\xe0\x73\x47\xe9" \ "\xdf\xf6\x08\x86\x61\x20\x56\xa4\x0d\xc3\x70\x0d" \ "\xd0\xfd\xc0\xf7\xef\xc9\xa6\x47\x2d\x3b\xcb\xdc" \ "\x87\xef\x91\xb9\xf4\x01\xb3\x8b\x65\xee\x54\x6c" \ "\xce\x4e\x4c\xd5\x6a\x8e\x4a\x19\x86\xa1\x1d\x3e" \ "\x3c\xf4\xa8\x18\x48\x18\xd1\xa9\xbb\x39\xd2\x8f" \ "\x0c\xb1\xf9\x3b\x2f\xf2\xcd\xe7\xbe\xdd\x3a\x6c" \ "\x15\x54\xd3\x34\x62\xb1\x58\xeb\x5a\x18\x86\x48" \ "\x29\xf1\x7d\xff\x81\x84\x84\x11\x21\xb5\x6d\x90" \ "\xc7\x06\xb6\x13\x49\xb5\x53\x3b\x77\x96\x99\x4a" \ "\x8d\xb6\x68\x44\xd6\x9c\x26\x5a\x20\xc3\x43\x42" \ "\x80\xe3\x4b\x92\x51\x83\xce\xc1\x61\x76\x3d\xb1" \ "\x07\xa5\x54\x0b\x64\x75\x6d\x18\x06\xa5\x52\x89" \ "\xd3\xa7\x4f\xf3\xf4\xd3\x4f\x33\x34\x34\xc4\xc8" \ "\xc8\x08\x7b\xf7\xee\x65\x74\x74\x14\xc7\x71\x5a" \ "\xcf\x6c\x94\x1d\x83\x23\x44\x0d\x0d\xa9\x14\xba" \ "\x2e\x22\x00\x9a\x2e\xd8\xab\x09\x2d\x54\x28\x74" \ "\xa1\xb1\x69\x68\x18\xd3\x34\xd7\x3d\xac\x69\x1a" \ "\x42\x08\xde\x7e\xfb\x6d\xde\x78\xe3\x0d\x82\x20" \ "\x60\xdf\xbe\x7d\x0c\x0f\x0f\x93\x4c\x26\x39\x79" \ "\xf2\x24\x57\xae\x5c\x59\x96\x5d\x4a\xa4\x94\x2d" \ "\x85\x56\xd7\x9a\x61\x60\x68\x1a\x86\x26\x68\x8b" \ "\x47\x24\x80\x66\x18\x9a\x67\xe8\x1a\x20\x70\x03" \ "\x89\xaa\x5a\xad\x8a\xef\x57\xc1\xf7\x7d\xce\x9f" \ "\x3f\x8f\x65\x59\x9c\x38\x71\x82\x37\xdf\x7c\x93" \ "\x33\x67\xce\x70\xec\xd8\x31\xca\xe5\x32\xaf\xbd" \ "\xf6\x5a\x0b\xec\xfe\x04\x70\x8b\x39\x9a\x52\x2e" \ "\x5b\x19\x5c\x00\x43\x29\x5c\x3f\x90\x44\x13\x31" \ "\xea\x7e\x40\xf5\xce\x2d\x3c\xd7\x25\x91\x48\xac" \ "\xe9\xab\x10\x02\x29\x25\xba\xae\x63\x18\x06\x41" \ "\x10\x2c\xdb\x33\x16\x63\xcb\x96\x2d\xcb\x96\xf3" \ "\xbc\x16\xd9\x75\x83\x29\x03\x4a\xd7\xc7\x70\x7d" \ "\x49\xa8\x42\xa2\xba\x7e\x73\x65\xae\x44\xd1\xd4" \ "\x35\xd1\x96\x88\x13\x33\x34\xaa\xf9\xbb\x54\x0b" \ "\xb9\x75\x15\xf8\xbe\x8f\x94\x92\x97\x5e\x7a\x89" \ "\x9d\x3b\x77\x92\x4e\xa7\x31\x0c\x83\x6c\x36\xcb" \ "\xf8\xf8\x38\x42\x08\x06\x07\x07\x37\x54\x4e\x4a" \ "\x89\x53\xcc\xd3\x58\xcc\xd3\xf0\x03\x9a\x32\xc4" \ "\x09\x82\x69\x00\x23\x1a\xd1\xfe\xa0\x3c\x67\x7f" \ "\xc5\x6f\xcf\xb5\xc5\x62\x9b\x6a\x85\x3c\xd9\x6b" \ "\x63\xf4\x3f\x3a\x88\x10\x62\x9d\xcf\x0f\x1e\x3c" \ "\xc8\xc0\xc0\x00\x3b\x76\xec\xc0\xf3\x3c\x46\x47" \ "\x47\xf9\xf4\xd3\x4f\xe9\xe8\xe8\xe0\xc8\x91\x23" \ "\x48\x29\xd7\x55\xaf\xeb\x3a\xb5\xec\x2c\xb5\xec" \ "\x0c\x0b\x35\x87\xdb\xb5\x6a\xce\x93\x72\x06\x10" \ "\x9a\xdb\x0c\x47\x6f\x55\x96\x98\x5c\x2c\x7f\xd9" \ "\x93\x4a\x62\xd9\x36\x8d\xe9\x49\x2c\xcb\x5a\x57" \ "\x4d\x18\x86\xc4\x62\x31\x86\x87\x87\x09\xc3\x90" \ "\xab\x57\xaf\x72\xf6\xec\x59\x0a\x85\x02\xc7\x8f" \ "\x1f\xe7\x99\x67\x9e\xd9\xb0\xff\x42\x08\x8a\x9f" \ "\x7f\x8c\x17\x04\xd8\x9e\x4f\xce\x75\x74\x3f\x50" \ "\x67\x01\x5d\xb3\xeb\xc1\x87\xbf\xbd\x3d\xfd\xeb" \ "\xdf\x5c\x1d\x7b\x34\x88\xc6\x4a\x71\x43\xa7\x32" \ "\x79\x9d\xdb\x5f\x5c\xa3\x5e\xaf\xaf\x19\xaa\x7b" \ "\x27\x3a\x9f\xcf\x73\xfe\xfc\x79\x32\x99\x0c\xfb" \ "\xf6\xed\xe3\xf9\xe7\x9f\x5f\x73\xcf\x6a\x2a\xa5" \ "\xa8\xcf\x4d\x53\x18\xbb\xc2\x6c\xa5\x4e\xae\xe1" \ "\x58\xa1\x52\xd9\x7c\xc9\xcb\x01\x86\x06\x90\xcd" \ "\xbb\xc7\x83\x50\x76\xe4\x3d\x79\x37\x65\x46\xb0" \ "\xaa\x36\xcd\x9b\xe3\x2c\x2c\x2c\x3c\xd0\xd3\xe5" \ "\x72\x99\xf1\xf1\x71\xa2\xd1\x28\x7b\xf6\xec\x41" \ "\xd7\xf5\x0d\xfb\x8f\x94\x14\x3f\xfb\x3b\xb6\xdb" \ "\x64\xba\x62\x33\x55\xaf\xea\x6e\x20\x6f\x02\x29" \ "\x20\xaa\xad\xf6\xcb\xf5\xe4\x89\xd7\x2f\x5e\x48" \ "\x77\xb4\xb7\x13\x33\x74\xca\x37\xae\x92\xbd\x36" \ "\x86\xeb\xba\xeb\x54\xa8\xd5\x6a\xf4\xf7\xf7\xb3" \ "\x7f\xff\x7e\x34\x4d\xc3\x30\x8c\x35\xea\xac\xde" \ "\x07\xe0\xcd\xcf\x90\xff\xc7\x25\xb2\xd5\x3a\x7e" \ "\x18\xfa\x35\xdf\xcf\x55\x6c\xff\x1d\xc0\x04\x34" \ "\x7d\x95\x40\xc3\x95\xb7\x12\x71\xed\x95\x87\x7a" \ "\xfa\xee\x6e\x4f\x98\xed\xf3\x8b\x65\xba\x3b\x52" \ "\xf8\xe9\x3e\x3a\x3b\x3b\x5b\x76\x5c\xcd\xce\xce" \ "\x4e\x46\x46\x46\xd8\xbe\x7d\x3b\x07\x0e\x1c\x20" \ "\x1e\x8f\xaf\xd9\x07\x30\x4d\x93\xcc\xef\xde\xa2" \ "\x78\xe7\x4b\x26\x8b\x4b\x4c\xd9\xd5\xc2\x42\xcd" \ "\x19\xab\xd8\xc1\x28\xd0\x00\xea\x2d\x05\x80\xc0" \ "\xf5\xe4\x53\xe7\xc6\x3f\xd7\xc3\x44\xd2\x4e\xc7" \ "\x23\x64\x3f\xfe\x08\x6b\xea\x26\xd5\x6a\x75\x4d" \ "\x75\xa6\x69\xe2\xfb\x3e\xa3\xa3\xa3\x5c\xb8\x70" \ "\x81\x89\x89\x89\x35\x7d\x0f\xc3\x10\x43\xd3\x58" \ "\xbc\xfc\x01\xf9\xb1\x2b\xcc\x58\x55\x66\xab\xb6" \ "\x3b\x5d\xb7\x13\x76\x3d\xb8\xcc\xf2\xdf\x80\x10" \ "\x08\xf5\x7b\x08\xd0\x70\x65\x3e\x95\x34\x0f\xd4" \ "\xa5\x6a\xdf\xd3\x95\x4a\x2f\xb9\x1e\x86\xdb\x40" \ "\x76\x3d\x44\xba\xb7\xaf\x55\x9d\x69\x9a\x64\x32" \ "\x19\x4e\x9d\x3a\xc5\xa5\x4b\x97\xc8\xe7\xf3\x1c" \ "\x3d\x7a\xb4\xb5\x1f\x89\x44\xf0\x0b\x77\xc9\x9c" \ "\x7f\x8b\xf9\x42\x81\xeb\x79\x8b\x9b\xb5\xa5\x4a" \ "\xce\x72\xdf\x6d\x78\xe1\x17\x40\x01\xa8\x00\xf6" \ "\xbd\x0a\x00\x60\xd5\x79\xf9\xa3\x3b\x53\x9b\xf2" \ "\x22\x6a\x0d\x74\xb5\x93\x9b\x9a\x24\xf3\xa7\x77" \ "\xc9\x66\x32\xf8\xbe\x4f\x18\x86\xd4\x6a\x35\x4c" \ "\xd3\x64\x64\x64\x84\x44\x22\x41\x4f\x4f\xcf\xbf" \ "\x2a\x37\x0c\x70\xea\x4c\xbf\x73\x86\xd2\xfc\x1c" \ "\x37\x16\x2b\x6a\xc1\x75\xaa\x0b\xb6\x73\xcb\x97" \ "\x2a\xb7\x22\xbd\x0b\x78\x80\xd4\xef\x27\xe0\x79" \ "\x9e\xab\x14\x1f\x4c\x96\x0a\xdf\xdd\xb3\x75\x0b" \ "\x3d\x11\x2d\x56\x2e\x15\x69\x36\x9b\x18\xdd\x7d" \ "\xb4\x25\x93\x2d\xb0\xa1\xa1\x21\x0e\x1f\x3e\xcc" \ "\x91\x23\x47\x30\x4d\x93\x58\x2c\x86\x2e\x03\x16" \ "\x46\x7f\x4f\x6e\xfc\x13\xa6\xac\x2a\x5f\x5a\xb6" \ "\x7f\xb3\x5a\x29\x97\xaa\xfe\xfb\x4d\x3f\xbc\x06" \ "\xe4\x80\x05\xa0\x0e\xb8\xeb\x08\x00\x34\xfd\x30" \ "\xab\xa4\x9a\x99\x28\x2d\x7e\xe3\xd0\xc0\xd6\xb6" \ "\x6e\xd3\xd0\xad\xcc\x0c\xf6\xc2\x1c\x74\xf6\x60" \ "\x26\x53\xad\xf7\x40\x77\x77\x37\x89\x44\x82\x44" \ "\x3c\x4e\xb3\x98\x63\xee\xdc\xaf\x28\x7c\x76\x99" \ "\x1b\x8b\x16\x53\x65\x5b\x7e\x66\x15\x1b\xb3\x79" \ "\xe7\x75\x19\xaa\x0c\x90\x5d\x91\xdf\x02\x9c\x0d" \ "\x15\x58\x0d\xc7\x97\x77\x02\x29\xe7\xa7\xaa\x4b" \ "\x07\x0e\x6c\x7e\xb8\x2d\xa9\xa3\xfb\x56\x89\xda" \ "\xc2\x1c\xbe\xe7\x11\xdf\xb4\x99\x54\x2a\x45\x24" \ "\x12\x41\x57\x8a\xc2\xa5\xbf\x51\xbc\xf8\x17\x2a" \ "\xb7\x6f\x32\x6b\xd9\x4c\x94\x96\xe4\xf5\x8a\x55" \ "\x9a\xca\xd5\x5f\x05\x32\xc0\xcc\xca\x6f\x09\xb0" \ "\x01\x1f\x08\x37\xfc\x2e\xb8\x37\x36\xa5\x63\xaf" \ "\xa6\x13\xb1\x17\x7e\xb4\x7b\x67\x6f\x6f\x22\xd6" \ "\xd6\x94\x12\x4d\x08\xcc\xae\x1e\xda\x77\xec\x42" \ "\x03\x9c\x99\x5b\x78\x56\x19\xb7\xe9\x71\xa3\x60" \ "\x31\x55\xb6\xbd\xb1\x4a\x69\xa9\x54\xf7\xfe\x6a" \ "\x55\xfd\x73\xc0\xdc\x0a\x70\x79\xa5\xff\x4d\x56" \ "\x5c\xf0\x1f\x09\x00\xd1\x74\x32\x7a\x2c\x9d\x8a" \ "\x9e\xfa\xe1\xce\xc1\xe8\xf6\xae\xf6\xfe\x88\xbe" \ "\x6e\x76\x29\x35\x1c\x26\x4b\x55\x26\xcb\x4b\xb5" \ "\x09\xbb\xe2\x96\xed\xe6\xcf\xab\xf5\x60\x74\x05" \ "\xb8\x04\xd4\x58\x1e\x3c\x56\xc0\x15\x3c\xe0\xcb" \ "\x68\xa3\xe8\x4d\x47\x5f\x30\x34\xed\xc7\x3d\xb1" \ "\xd8\xe6\xdd\xdd\x5d\xf1\xdd\xdd\xe9\xce\x58\x44" \ "\x4b\x55\x9c\xa6\xb2\xdc\x66\xf3\x7a\xa9\xec\xe4" \ "\x3c\xa7\x66\x35\x9b\x6e\xc3\x91\x3f\xab\xd8\xfe" \ "\x45\xa0\xc8\xb2\xdc\xb5\x7b\x40\xd5\xbd\xe7\x7e" \ "\x65\x02\x80\x48\x77\x44\xfa\x35\xc4\xa1\x84\xa9" \ "\xbf\x1c\xd1\xf4\x5e\x21\x54\x07\xa0\x02\xa5\xa2" \ "\xa1\x52\x79\xd7\x0f\x7f\xe1\x07\xe1\x84\x55\xf5" \ "\x6f\xb0\x6c\x37\x07\x08\xee\x07\xfd\x6f\x09\x00" \ "\x68\x2b\x69\x00\x46\x57\x7b\xa4\x4f\x81\x40\x29" \ "\xad\x62\x07\x45\x40\xae\xa4\xbf\x02\xdc\x92\xfa" \ "\x7f\x45\x60\x35\x1e\xe4\x1e\xc5\x06\x32\xff\xbb" \ "\xf8\x27\x68\x7d\xcd\xf9\x93\x0d\xe2\x60\x00\x00" \ "\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82" class ModalPopUpDialog(QDialog): def __init__(self,parent = None,name = None,modal = 0,fl = 0): QDialog.__init__(self,parent,name,modal,fl) self.image0 = QPixmap() self.image0.loadFromData(image0_data,"PNG") if not name: self.setName("ModalPopUpDialog") self.pixmapLabel1 = QLabel(self,"pixmapLabel1") self.pixmapLabel1.setGeometry(QRect(20,20,32,32)) self.pixmapLabel1.setPixmap(self.image0) self.pixmapLabel1.setScaledContents(1) self.textLabel1 = QLabel(self,"textLabel1") self.textLabel1.setGeometry(QRect(90,20,230,60)) self.pushButtonCancel = QPushButton(self,"pushButtonCancel") self.pushButtonCancel.setGeometry(QRect(30,90,100,26)) self.pushButtonOk = QPushButton(self,"pushButtonOk") self.pushButtonOk.setGeometry(QRect(210,90,100,26)) self.languageChange() self.resize(QSize(332,120).expandedTo(self.minimumSizeHint())) self.clearWState(Qt.WState_Polished) self.connect(self.pushButtonCancel,SIGNAL("clicked()"),self.pushButtonCancel_clicked) self.connect(self.pushButtonOk,SIGNAL("clicked()"),self.pushButtonOk_clicked) def languageChange(self): self.setCaption(self.__tr("ModalPopUpDialog")) self.textLabel1.setText(QString.null) self.pushButtonCancel.setText(self.__tr("Cancel")) self.pushButtonOk.setText(self.__tr("OK")) def pushButtonCancel_clicked(self): self.done(False) def pushButtonOk_clicked(self): self.done(True) def __tr(self,s,c = None): return qApp.translate("ModalPopUpDialog",s,c) |
|
From: Stas Z. <sta...@us...> - 2005-07-05 15:15:21
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7611 Modified Files: AddressEditDialog_forms.py AddressEditDialog_forms.pyc Contrgcm.py GuiQTgcm.py LoginDialog_forms.py MainWinContacts_forms.py Makefile QgcmDialogs.py testContrgcm.py Added Files: ModalPopupDialog.ui Log Message: Finally found the proper design :-) Started to implement it Index: testContrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/testContrgcm.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** testContrgcm.py 15 Jun 2005 14:48:39 -0000 1.1 --- testContrgcm.py 5 Jul 2005 15:15:03 -0000 1.2 *************** *** 49,58 **** def test2_setup_DB(self): """Create a new database""" ! filename = '/tmp/testdatabase' if os.path.exists(filename): os.remove(filename) ! DB = Contrgcm.DBase(filename) ! Contrgcm._DBase = DB ! self.assertEqual(os.path.exists(filename),1,"Failed to create database") def test3_store_contacts_DB(self): --- 49,57 ---- def test2_setup_DB(self): """Create a new database""" ! filename = 'testdatabase' if os.path.exists(filename): os.remove(filename) ! DB = Contrgcm.setup_database(filename) ! self.assertEqual(os.path.exists(DB),1,"Failed to create database %s" % filename) def test3_store_contacts_DB(self): *************** *** 100,108 **** name = raw_input("Gmail account name:") pw = getpass.getpass("Password: ") ! account = libgmail2.GmailAccount(name, pw) ! try: ! account.login() ! print "Login successful.\n" except libgmail2.GmailLoginFailure,e: print "\nLogin failed. (%s)" % e.message --- 99,109 ---- name = raw_input("Gmail account name:") pw = getpass.getpass("Password: ") ! try: ! result = Contrgcm.login_gmail(name,pw) ! if result[0]: ! account = result[2] ! print "Login successful.\n" ! else: raise libgmail2.GmailLoginFailure(result[1]) except libgmail2.GmailLoginFailure,e: print "\nLogin failed. (%s)" % e.message Index: AddressEditDialog_forms.pyc =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/AddressEditDialog_forms.pyc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 Binary files /tmp/cvsKb3l8W and /tmp/cvsmHjLpC differ Index: LoginDialog_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/LoginDialog_forms.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** LoginDialog_forms.py 18 Jun 2005 11:27:26 -0000 1.2 --- LoginDialog_forms.py 5 Jul 2005 15:15:03 -0000 1.3 *************** *** 3,7 **** # Form implementation generated from reading ui file 'LoginDialog.ui' # ! # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'LoginDialog.ui' # ! # Created: Tue Jul 5 15:49:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # Index: QgcmDialogs.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/QgcmDialogs.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** QgcmDialogs.py 18 Jun 2005 11:27:26 -0000 1.3 --- QgcmDialogs.py 5 Jul 2005 15:15:03 -0000 1.4 *************** *** 19,25 **** # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! from qt import QProgressDialog,QLabel,QMessageBox from LoginDialog_forms import FormLogin from AddressEditDialog_forms import FormAddressEdit from Observers import Observer,Observable import Contrgcm --- 19,26 ---- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! from qt import QProgressDialog,QLabel,QMessageBox,QDialog,QRect,QSize from LoginDialog_forms import FormLogin from AddressEditDialog_forms import FormAddressEdit + from ModalPopUpDialog_forms import ModalPopUpDialog from Observers import Observer,Observable import Contrgcm *************** *** 28,32 **** class Login(FormLogin,Observable): """A login dialog. ! You should pass this object a observer which is notified on a succesfull login. """ def __init__(self,Qapplication,observer=None,parent=None,name=None,modal=1,fl=0): --- 29,33 ---- class Login(FormLogin,Observable): """A login dialog. ! You could pass this object an observer which is notified on a succesfull login. """ def __init__(self,Qapplication,observer=None,parent=None,name=None,modal=1,fl=0): *************** *** 65,73 **** def _do_login(self,log,pas): self.progress_dlg.show() ! result = Contrgcm.login_gmail(log,pas) self.pushButtonCancel_clicked() self.progress_dlg.update() retval = False ! if result[0]: QMessageBox.critical(self, "Error", result[1], --- 66,75 ---- def _do_login(self,log,pas): self.progress_dlg.show() ! self.ga = Contrgcm.GC(log,pas) self.pushButtonCancel_clicked() self.progress_dlg.update() retval = False ! result = self.ga.login_gmail() ! if not result[0]: QMessageBox.critical(self, "Error", result[1], *************** *** 75,83 **** else: self.notifyObservers(result[2]) - self.ga = result[2] retval = True self.progress_dlg.update() if self.keepsettings: ! if not Contrgcm.store_login(log,pas): QMessageBox.critical(self, "Error", "Failed to store the login data to disk", --- 77,84 ---- else: self.notifyObservers(result[2]) retval = True self.progress_dlg.update() if self.keepsettings: ! if not self.ga.store_login(log,pas): QMessageBox.critical(self, "Error", "Failed to store the login data to disk", *************** *** 120,122 **** --- 121,135 ---- + class ModalPopup(ModalPopUpDialog): + """Simple dialog which is modal and blocks the main eventloop. + Can be used as a replacement for the QMessageBox to prompt the user + for critical decissions.""" + def __init__(self,title="Question",text='',parent=None,name=None,fl=0): + ModalPopUpDialog.__init__(self,parent=None,name=None,modal=1,fl=0) + self.setCaption(title) + self.textLabel1.setText(text) + def start(self): + return self.exec_loop() + + Index: AddressEditDialog_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/AddressEditDialog_forms.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AddressEditDialog_forms.py 18 Jun 2005 11:28:37 -0000 1.1 --- AddressEditDialog_forms.py 5 Jul 2005 15:15:02 -0000 1.2 *************** *** 3,7 **** # Form implementation generated from reading ui file 'AddressEditDialog.ui' # ! # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'AddressEditDialog.ui' # ! # Created: Tue Jul 5 15:49:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # Index: GuiQTgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/GuiQTgcm.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GuiQTgcm.py 18 Jun 2005 11:27:26 -0000 1.5 --- GuiQTgcm.py 5 Jul 2005 15:15:03 -0000 1.6 *************** *** 26,32 **** from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable ! from QgcmDialogs import Login import Contrgcm class MainWin(FormMainWin,Observable): def __init__(self, parent=None, name=None, fl=0,att=[],application=None): --- 26,35 ---- from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable ! from QgcmDialogs import Login,ModalPopup import Contrgcm + # Observable is intended for future stuff when this is used by other apps + # XXX + class MainWin(FormMainWin,Observable): def __init__(self, parent=None, name=None, fl=0,att=[],application=None): *************** *** 36,44 **** self.Qapplication = application # Needed for a Qprogressdialog self.ga = None - self.show() # test stuff ! self.Myobs = Observer(self.test) ! self.addObserver(self.Myobs) def test(self,*args): --- 39,56 ---- self.Qapplication = application # Needed for a Qprogressdialog self.ga = None self.show() + + txt = "Do you want to import your contacts from your Gmail account?\n"+\ + "If you do not then a local copy, if available, will be used.\n"+\ + "Be aware that any changes you want to make require access to your\n"+\ + "Gmail account." + dlg = ModalPopup(parent=self,text=txt) + if dlg.start(): + self.contactsImportcontacts_activated() + else: + pass # test stuff ! #self.Myobs = Observer(self.test) ! #self.addObserver(self.Myobs) def test(self,*args): *************** *** 61,71 **** entry = self.listViewContacts.selectedItem() if not self.ga: ! text = "You're currently working with a contacts list which\n"+\ ! "is constructed from the local contacts database.\n"+\ ! "You should import a new Gmail contacts list from your\n"+\ ! "Gmail account before editing any contacts to keep everything\n"+\ ! "syncronized\n\n"+\ ! "Shall I import your contacts from your Gmail account?" ! QMessageBox.information(self,"Question", text,QMessageBox.Ok) return AddressBookEditDialog(entry,parent=self,ga=self.ga) --- 73,79 ---- entry = self.listViewContacts.selectedItem() if not self.ga: ! text = "You're not logged in your Gmail account.\n",\ ! "Use the 'Import contacts' button to login your account" ! QMessageBox.information(self,"Information", text,QMessageBox.Ok) return AddressBookEditDialog(entry,parent=self,ga=self.ga) *************** *** 77,81 **** print "FormMainWin.helpContents_activated(): Not implemented yet" #This callback is only used for testing purposes ! self.notifyObservers("this is data") def helpAbout_activated(self): --- 85,92 ---- print "FormMainWin.helpContents_activated(): Not implemented yet" #This callback is only used for testing purposes ! #self.notifyObservers("this is data") ! dlg = ModalPopup(parent=self,text="dit is een test tekst\nRegel2\nRegel3\nRegel4\nRegel5") ! result = dlg.start() ! print "result is",result def helpAbout_activated(self): *************** *** 108,112 **** else: self.ga = dlg.get_account_object() ! contacts = Contrgcm.import_contacts_gmail(self.ga) self._load(contacts) --- 119,123 ---- else: self.ga = dlg.get_account_object() ! contacts = self.ga.import_contacts_gmail() self._load(contacts) *************** *** 130,133 **** --- 141,145 ---- nameshash = {}# used as a lookup hash by the search object for line in conlist: + print "line",line item = QListViewItem(self.listViewContacts) try: *************** *** 136,140 **** item.setText(1,line[1]) item.setText(2,line[2][:60]) - item.setText(3,line[3]) except Exception,info: if GQ_DEBUG: --- 148,151 ---- Index: Makefile =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Makefile 18 Jun 2005 11:27:26 -0000 1.3 --- Makefile 5 Jul 2005 15:15:03 -0000 1.4 *************** *** 4,5 **** --- 4,7 ---- pyuic LoginDialog.ui -o LoginDialog_forms.py pyuic AddressEditDialog.ui -o AddressEditDialog_forms.py + pyuic ModalPopupDialog.ui -o ModalPopUpDialog_forms.py + \ No newline at end of file Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Contrgcm.py 18 Jun 2005 11:27:26 -0000 1.6 --- Contrgcm.py 5 Jul 2005 15:15:02 -0000 1.7 *************** *** 19,25 **** # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ ! Contrgcm is a module which acts as a abstraction layer for libgmail2 and it's ! intended to be used by libgmail frontends. ! It knows nothing about the GUI, only about libgmail2. """ --- 19,26 ---- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ ! Contrgcm is a module which acts as a abstraction layer for the libgmail2 contacts ! support and it's intended to present a simple API to graphical frontends. ! It also implements simple databases for every Gmail account. ! It knows nothing about the GUI. """ *************** *** 33,39 **** # Python <=2.3? pass ! if CG_DEBUG: logging.debug("Starting") def load_login(section='Login'): """load_login --> The tuple logname,password or None. --- 34,48 ---- # Python <=2.3? pass ! ! RCFILE = os.path.expanduser('~/.gmailagent') ! if CG_DEBUG: logging.debug("Starting") + class NoDBaseError(Exception): + def __init__(self,message): + self.message = message + def __str__(self): + return repr(self.message) + def load_login(section='Login'): """load_login --> The tuple logname,password or None. *************** *** 44,50 **** if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") configdict = ConfigParser.ConfigParser() ! rcfile = os.path.expanduser('~/.gmailagent') try: ! configdict.readfp(open(rcfile)) if section == 'Login': name,pas = configdict.get(section,'name'), configdict.get(section,'pas') --- 53,60 ---- if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") configdict = ConfigParser.ConfigParser() ! ! name,pas = None,None try: ! configdict.readfp(open(RCFILE)) if section == 'Login': name,pas = configdict.get(section,'name'), configdict.get(section,'pas') *************** *** 56,263 **** if CG_DEBUG: print info ! logging.warning("Failed to load the password from %s" % rcfile) return None return (name,pas) - - def get_default_database_path(path): - """get_default_database_path --> path on succes, False on faillure. - It will return the path as it's currently stored in the rc file. - There's no garantee that the database will actually exist. - Use the 'store_default_database_path' to set the path. - """ - db_path,spam = load_login('Default') - if os.path.exists(db_path): - return db_path - else: - return False - def get_dbase_pathname(): - """get_dbase_pathname --> pathname on succes, False on faillure. - The difference with 'get_default_database_path' is that this will - return the path of the database currently in use or None if theres - no database in use. - """ - global _DBase - try: - path = _Dbase._get_path() - except: - return False - return path ! def store_default_database_path(path): ! """store_default_database_path --> True on succes, False on faillure. ! Stores the default database path to use. ! Use get_default_database_path' to retrieve it. ! """ ! return store_login(path,None,'Default') ! def store_login(name,pas,section='Login'): ! """store_login --> True on succes, False on faillure. ! Stores the login data and sets the default db path in a dot file in the ! users home directory. ! The name of the rc file is always '.gmailagent'. ! @name is the Gmail account name. ! @pas is the password. ! @section defaults to 'Login' and is intended for internal purposes. ! """ ! if CG_DEBUG: logging.debug("Store the login data %s %s %s" % (name,pas,section)) ! rcfile = os.path.expanduser('~/.gmailagent') ! configdict = ConfigParser.ConfigParser() ! if not configdict.has_section(section): ! configdict.add_section(section) ! if section == 'Login': ! configdict.set(section,'name',name) ! configdict.set(section,'pas',pas) ! # store the name of the default database for this account ! # I f the database actual exist is the problem of the ! # 'get_default_database_path' function. ! db_name = os.path.expanduser('~/.gcm_database')+'.'+name ! if not configdict.has_section('Default'): ! configdict.add_section('Default') ! configdict.set('Default','path',db_name) ! if CG_DEBUG: logging.debug("Store the default data %s %s" % (db_name,section)) ! elif section == 'Default': ! configdict.set(section,'path',name) ! try: ! f = open(rcfile,'w') ! configdict.write(f) ! except: f.close() ! if CG_DEBUG: logging.warning("Failed to store the password in %s" % rcfile) ! return False ! f.close() ! return True ! ! def login_gmail(name,pas): ! """login_gmail --> a tuple of '0 or 1','message',libgmail login object or None. ! The first value of the returnt tuple indicates faillure (0) or succes (1). ! @name is the Gmail account name. ! @pas is the password for the account. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: login_gmail") ! ga = libgmail2.GmailAccount(name,pas) ! try: ! ga.login() ! except (libgmail2.GmailLoginFailure,urllib2.HTTPError),info: ! if CG_DEBUG: logging.warning("%s" % info) ! return (1,"%s" % info,None) ! else: ! setup_database(name) ! return (0,"Log in successful.",ga) ! def setup_database(name): ! """setup_database --> path or None ! This will setup the database if it's not already available. ! It's possible to have multiple databases which different names. ! Every Gmail account has it's own database. ! """ ! global _DBase ! try: ! _Dbase._close() ! except: pass - db_name = os.path.expanduser('~/.gcm_database')+'.'+name - try: - _DBase = DBase(name=db_name) - except Exception,info: - print info - logging.critical("Failed to create database %s" % info) - if CG_DEBUG: logging.debug("Shelve DB %s created %s" % (db_name,_DBase)) - - def import_contacts_gmail(ga): - """import_contacts_gmail --> contacts in a list of tuples or None. - Import contacts from a gmail account and store them in a local - database. When the db exist it will be updated else it will be created. - @ga is a libgmail GmailAccount object. - """ - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") - contacts = ga.getContacts().getAllContacts() - if CG_DEBUG: logging.debug("Contacts imported:\n%s" % contacts) - if not contacts: - return None - conlist = [] - for obj in contacts: - conitem = (obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId()) - conlist.append(conitem) - store_contact_db(conitem[3],conitem) - if CG_DEBUG: logging.debug("Database values %s" % _DBase._get_all_values()) - return conlist ! def import_contacts_db(): ! """import_contacts_db --> contacts in a list of tuples or None. ! Import contacts from the local database and return them in a ! list of tuples.""" ! pass ! def store_contacts_gmail(contacts,ga): ! """store_contacts_gmail --> True on succes, False on faillure. ! Stores the contacts in a Gmail account. ! @contacts is a list of tuples containing the contacts. The format must be ! the same as returnt by import_contacts_db. ! When a empty list is passed it will upload only the differences between ! the local database and the online Gmail contacts. ! @ga is a libgmail GmailAccount. ! """ ! pass ! def store_contacts_db(contacts): ! """store_contacts_db --> True on succes, False on faillure. ! Stores the contacts in the local database. ! @contacts is a list of tuples containing the contacts. The format must be ! the same as returnt by import_contacts_db. ! """ ! pass ! def store_contact_gmail(contact,ga): ! """store_contact_db --> True on succes, False on faillure ! Stores the contact in a Gmail account. ! @contact is a tuple containing the contact. ! """ ! pass ! def store_contact_db(key,contact): ! """store_contact_db --> True on succes, False on faillure ! Stores the contact in a local database. ! @key is the dbase key. ! @contact is a tuple containing the contact. ! This is probably only used by Contrgcm internally. ! """ ! try: ! _DBase._store_value(key,contact) ! except Exception,info: ! print info ! logging.critical("Failed to store %s with key %s" % (contact,key)) ! def remove_contacts_gmail(ga): ! """remove_contacts_gmail --> True on succes, False on faillure. ! Remove all contacts from a Gmail account. ! This should be used with care, the removal is final. ! The contacts removed are stored in the local database and can be restored ! by calling restore_contacts. ! @ga is a libgmail GmailAccount. ! """ ! pass ! def remove_contacts_db(): ! """remove_contacts_db --> True on succes, False on faillure. ! Remove all contacts from the local database. ! The database can be restored by calling import_contacts_gmail. ! """ ! pass ! def export_contacts(file): ! """export_contacts --> True on succes, False on faillure. ! Export contacts into the VCard format to a file. ! @file must be a valid path writable by the user. ! """ ! pass - def sync_contacts(self): - """sync_contacts --> True on succes, False on faillure. - XXX I'm not really clear on the way to do this :-) - """ - pass - class DBase: def __init__(self,name=''): """@name is to setup different databases for various accounts""" - print "name",name if not name: self.db_name = os.path.expanduser('~/.gcm_database') else: self.db_name = name ! self.DB_dict = shelve.open(self.db_name) def _get_path(self): return self.db_name --- 66,320 ---- if CG_DEBUG: print info ! logging.warning("Failed to load the password from %s" % RCFILE) return None return (name,pas) ! class GC: ! def __init__(self,name,pas): ! """Create a object to control the access to Gmail contacts. ! @name and @pas are the account and password. ! A NoDBaseError is raised when the local database can't be created. ! """ ! self.ga = libgmail2.GmailAccount(name,pas) ! self._DBase = self.setup_database(name) ! if not self._DBase: ! raise NoDBaseError("Failed to setup the database, check the stderr for additional information") ! ! def load_login(self,section='Login'): ! """load_login --> The tuple logname,password or None. ! Loads the login data from a dot file in the users home directory. ! The name of the rc file is always '.gmailagent'. ! @section defaults to 'Login' and is intended for internal purposes. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") ! configdict = ConfigParser.ConfigParser() ! ! name,pas = None,None ! try: ! configdict.readfp(open(RCFILE)) ! if section == 'Login': ! name,pas = configdict.get(section,'name'), configdict.get(section,'pas') ! elif section == 'Default': ! name,pas = configdict.get(section,'path'),None ! except (IOError,\ ! ConfigParser.MissingSectionHeaderError,\ ! ConfigParser.NoOptionError),info: ! if CG_DEBUG: ! print info ! logging.warning("Failed to load the password from %s" % RCFILE) ! return None ! return (name,pas) ! def get_default_database_path(self,path): ! """get_default_database_path --> path on succes, False on faillure. ! It will return the path as it's currently stored in the rc file. ! There's no garantee that the database will actually exist. ! Use the 'store_default_database_path' to set the path. ! """ ! db_path,spam = load_login('Default') ! if os.path.exists(db_path): ! return db_path ! else: ! return False ! def get_dbase_pathname(self): ! """get_dbase_pathname --> pathname on succes, False on faillure. ! The difference with 'get_default_database_path' is that this will ! return the path of the database currently in use or None if theres ! no database in use. ! """ ! if not self._DBase: return False ! try: ! path = self._DBase._get_path() ! except: ! return False ! return path ! ! def store_default_database_path(self,path): ! """store_default_database_path --> True on succes, False on faillure. ! Stores the default database path to use. ! Use get_default_database_path' to retrieve it. ! """ ! return store_login(path,None,'Default') ! ! def store_login(self,name,pas,section='Login'): ! """store_login --> True on succes, False on faillure. ! Stores the login data and sets the default db path in a dot file in the ! users home directory. ! The name of the rc file is always '.gmailagent'. ! @name is the Gmail account name. ! @pas is the password. ! @section defaults to 'Login' and is intended for internal purposes. ! """ ! if CG_DEBUG: logging.debug("Store the login data %s %s %s" % (name,pas,section)) ! rcfile = os.path.expanduser('~/.gmailagent') ! configdict = ConfigParser.ConfigParser() ! if not configdict.has_section(section): ! configdict.add_section(section) ! if section == 'Login': ! configdict.set(section,'name',name) ! configdict.set(section,'pas',pas) ! # Also set the database default to this account ! db_name = os.path.expanduser('~/.gcm_database')+'.'+name ! if not configdict.has_section('Default'): ! configdict.add_section('Default') ! configdict.set('Default','path',db_name) ! if CG_DEBUG: logging.debug("Store the default data %s %s" % (db_name,section)) ! elif section == 'Default': ! configdict.set(section,'path',name) ! try: ! f = open(rcfile,'w') ! configdict.write(f) ! except: ! f.close() ! if CG_DEBUG: logging.warning("Failed to store the password in %s" % rcfile) ! return False f.close() ! return True ! ! def login_gmail(self): ! """login_gmail --> a tuple of '0 or 1','message',libgmail login object or None. ! The first value of the returnt tuple indicates faillure (0) or succes (1). ! @name is the Gmail account name. ! @pas is the password for the account. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: login_gmail") ! ! try: ! self.ga.login() ! except (libgmail2.GmailLoginFailure,urllib2.HTTPError),info: ! if CG_DEBUG: logging.warning("%s" % info) ! return (0,"%s" % info,None) ! else: ! return (1,"Log in successful.",self.ga) ! ! def setup_database(self,name): ! """setup_database --> path or None ! This is normally called by the class constructor. ! This will setup the database if it's not already available. ! It's possible to have multiple databases which different names. ! Every Gmail account has it's own database. ! """ ! try: ! self._DBase._close() ! except: ! pass ! db_name = os.path.expanduser('~/.gcm_database')+'.'+name ! try: ! DB = DBase(name=db_name) ! except Exception,info: ! print info ! logging.critical("Failed to create database %s" % info) ! return None ! if CG_DEBUG: logging.debug("Shelve DB %s created %s" % (db_name,DB)) ! return DB ! def import_contacts_db(self): ! # XXX BIG problem: if there's no login we don't have a database :-( ! """import_contacts_db --> contacts in a list of tuples or None. ! Use this to get contacts without the need to login a Gmail account. ! """ ! keys = self._DBase._get_all_keys() ! if not keys: ! return None ! contacts = [] ! for key in keys: ! v = self._DBase._get_value(key) ! contacts.append((v[0],v[1],v[2],v[3])) ! return contacts ! ! def import_contacts_gmail(self): ! """import_contacts_gmail --> contacts in a list of tuples or None. ! Import contacts from a gmail account and store them in a local ! database. When the db exist it will be updated else it will be created. ! @ga is a libgmail GmailAccount object. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts_gmail") ! if not self.ga: return None ! try: ! contacts = self.ga.getContacts().getAllContacts() ! except Exception,info: ! print info ! return None ! if CG_DEBUG: logging.debug("Contacts imported:\n%s" % contacts) ! if not contacts: ! return None ! conlist = [] ! for obj in contacts: ! conitem = (obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId()) ! conlist.append(conitem) ! self._DBase._store_value(conitem[3],conitem) ! if CG_DEBUG: logging.debug("Database values %s" % self._DBase._get_all_values()) ! return conlist ! ! def store_contacts_gmail(self,contacts): ! """store_contacts_gmail --> True on succes, False on faillure. ! Stores the contacts in a Gmail account. ! @contacts is a list of tuples containing the contacts. The format must be ! the same as returnt by import_contacts_gmail. ! """ ! if not self.ga: return False ! contacts = ga.getContacts()# get an fresh contacts list ! for obj in contacts: ! Name,Email,Notes,Id = obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId() ! if Id: ! # we deal with a existing contact so we first need to remove it ! contact = contacts.getContactById(Id) ! if contact: ! if not self.remove_contact_gmail(contact): ! return False ! if not self.store_contact_gmail(Name,Email,Notes): ! return False ! ! return True ! def store_contact_gmail(self,name,email,notes,id=None): ! """store_contact_gmail --> True on succes, False on faillure. ! Creates a gmail contact from the arguments and stores it into the ! current Gmail account. ! When an id is given we assume it's an altered Gmail contact and the ! existing contact is removed before the new one is stored. ! """ ! if self.ga.addContact(name,email,notes) and\ ! self._DBase._store_value(id,(name,email,notes,id)): ! return True ! else: ! logging.warning("Failed to store contact %s" % contact) ! return False ! ! def remove_contact_gmail(self,contact): ! """remove_contact_gmail --> True on succes, False on faillure. ! Removes the contact from a Gmail account and the database. ! This should be used with care, the removal is final. ! @contact is a libgmail contact object. ! """ ! if self.ga.removeContact(contact) and self._DBase._remove_value(Id): ! logging.warning("Failed to remove contact %s" % contact) ! return True ! else: ! return False ! ! def export_contacts(self,file): ! """export_contacts --> True on succes, False on faillure. ! Export contacts into the VCard format to a file. ! @file must be a valid path writable by the user. ! """ pass ! def sync_contacts(self): ! """sync_contacts --> True on succes,print "name",name False on faillure. ! XXX I'm not really clear on the way to do this :-) ! """ ! pass class DBase: def __init__(self,name=''): """@name is to setup different databases for various accounts""" if not name: self.db_name = os.path.expanduser('~/.gcm_database') else: self.db_name = name ! try: ! self.DB_dict = shelve.open(self.db_name) ! except Exception,info: ! print info def _get_path(self): return self.db_name *************** *** 267,448 **** return self.DB_dict.keys() def _store_value(self,key,value): ! self.DB_dict[key] = value def _get_value(self,key): ! return self.DB_dict[key] def _close(self): self.DB_dict.close() - - - ###### Old stuff, perhaps we can use parts of it ########### - def upload_local_contacts(addrfile,ga): - """Returns the contacts from the local file which don't have a ID entry. - Contacts without an ID are considered local only and must be added to the Gmail - contacts list. - This function is called whenever the user logs into Gmail. - Returns error message on faillure, None on succes.""" - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") - contacts = load_addressfile(addrfile) - for line in contacts: - if CG_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) - if not line[3]: - logging.debug("Adding %s %s %s %s to Gmail" % line) - if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception - return ("Unable to add contact %s %s %s %s" % line) - # Now we reload the contacts to create a new local contacts list - #import_contacts(addrfile,ga) - - - def store_address(addrfile,name,addr,notes='',id='',ga=None): - """The contacts will be stored in the local copy on disk. - If the id is given we assume the contact has a valid Gmail id and - the contact is removed from the online contacts and replaced by the - given contact. It will get a new id from Gmail. - """ - if CG_DEBUG: - logging.debug("\n>>>>>>>> Function: store_address") - logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) - if id and ga: - if CG_DEBUG: logging.debug("Found id, removing original contact first") - contacts = ga.getContacts() - contact = contacts.getContactById(id) - if contact: - if not ga.removeContact(contact): - logging.warning("Failed to remove contact %s" % contact) - else: - # Build the new local file with the contacts from Gmail - import_contacts(addrfile,ga) - # now we add the new contact to the local file - store_address(addrfile,name,addr,notes) - # And upload it to Gmail - upload_local_contacts(addrfile,ga) - # Retrieve Gmail contacts so that we have get an id for the new contact. - import_contacts(addrfile,ga) - # stuff is stored in a file like this: - # name&&addr&¬es&&id - # Contacts that are not (yet) in the Gmail contacts list have an empty - # string as id. - # After syncronizing the file with the contacts the id fields will be asigned. - try: - f = open(addrfile,'r') - lines = f.readlines() - f.close() - except IOError,info: - mesg = "Failed to check the address (IO), %s" % info - if CG_DEBUG: logging.warning(mesg) - return mesg - else: - for line in lines: - if name in line and addr in line: - return - # It's a new entry - line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) - if CG_DEBUG: logging.debug("Found new contact %s" % line) - try: - f = open(addrfile,'a') - f.write(line) - f.close() - except IOError,info: - f.close() - mesg = "Failed to store address, %s" % info - if CG_DEBUG: logging.warning(mesg) - return mesg - - def load_addressfile(filename): - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") - try: - f = open(filename,'r') - lines = f.readlines() - f.close() - except IOError,info: - if CG_DEBUG: logging.warning(str(info)) - return - if CG_DEBUG: logging.debug(str(lines)) - newlines = [] - for line in lines: - newlines.append(tuple(line[:-1].split("&&"))) - return (newlines) - - def import_contacts(addrfile,ga): - """This gets the gmail contacts create a new local contacts list on disk.""" - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") - upload_local_contacts(addrfile,ga) - contacts = ga.getContacts().getAllContacts() - logging.debug("Contacts imported:\n%s" % contacts) - if contacts: - # remove local file, we can remove it because the upload_local_contacts method will make sure - # that the contacts are syncronized. - logging.debug("Removing local file") - open(addrfile,'w').close() - else: - return - for obj in contacts: - store_address(addrfile,\ - obj.getName(),\ - obj.getEmail(),\ - obj.getNotes(),\ - obj.getId()) - return load_addressfile(addrfile) - - def export_contacts(addrfile,ga): - """This will remove the contacts at the online contacts list and replace - it with the local copy fom disk. - It will return a message on any error. - It returns None on succes.""" - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") - entries = load_addressfile(addrfile) - if len(entries) < 1: - text = "Failed to load address file, %s" % addrfile - if CG_DEBUG: logging.critical(text) - return text - try: - contacts = ga.getContacts().getAllContacts() - # Just to test save_contacts - save_contacts(contacts) - for contact in contacts: - if CG_DEBUG: logging.debug("Removing contact %s", contact) - ga.removeContact(contact) - except Exception,info: - logging.critical(str(info)) - if contacts: - save_contacts(contacts) - return "An error occured, tried to save your contacts to\n%s and %s" %\ - ('~/.GmailContacts.txt','~/.GmailContacts.pickle') - # Now we fill the contacts list again from the local file. - try: - for entry in entries: - if CG_DEBUG: logging.debug("Adding contact %s", entry) - apply(ga.addContact,entry[:-1]) - except Exception,info: - logging.critical(str(info)) - save_contacts(contacts) - - def save_contacts(contacts): - """Save the contact in case of an error. This is an attempt to prevent - data loss in case of an error when interacting with Gmail contacts.""" - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") - try: - f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') - pickle.dump(contacts,f) - ## XXX TODO: some way to load the pickled object and restore it - except Exception,info: - text = "Attempt to pickle the contacts %s" % str(info) - logging.critical(text) - f.close() - try: - f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') - text = "#An error occured in GmailAgent and these contacts are saved\n"+\ - "#to this file in an attempt to save them\n"+\ - "#A contact is saved as follows:\n"+\ - "#GmailID Name email notes\n" - f.write(text) - for con in contacts: - name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() - f.write("%s %s %s %s\n" % (con.getId(),\ - con.getName(),\ - con.getEmail(),\ - con.getNotes())) - f.close() - except Exception,info: - logging.critical(str(info)) - return str(info) - --- 324,350 ---- return self.DB_dict.keys() def _store_value(self,key,value): ! try: ! self.DB_dict[key] = value ! except Exception,info: ! print info ! logging.warning("Failed to store %s,%s" % key,value) ! else: ! return True ! def _remove_value(key): ! try: ! del self.DB_dict[key] ! except KeyError,info: ! print info ! logging.warning("Failed to remove %s" % key) ! else: ! return True def _get_value(self,key): ! try: ! v = self.DB_dict[key] ! except KeyError,info: ! print info ! logging.warning("Failed to retrieve %s" % key) ! else: ! return v def _close(self): self.DB_dict.close() --- NEW FILE: ModalPopupDialog.ui --- <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> <class>ModalPopUpDialog</class> <widget class="QDialog"> <property name="name"> <cstring>ModalPopUpDialog</cstring> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>332</width> <height>120</height> </rect> </property> <property name="caption"> <string>ModalPopUpDialog</string> </property> <widget class="QLabel"> <property name="name"> <cstring>pixmapLabel1</cstring> </property> <property name="geometry"> <rect> <x>20</x> <y>20</y> <width>32</width> <height>32</height> </rect> </property> <property name="pixmap"> <pixmap>image0</pixmap> </property> <property name="scaledContents"> <bool>true</bool> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel1</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>20</y> <width>230</width> <height>60</height> </rect> </property> <property name="text"> <string></string> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonCancel</cstring> </property> <property name="geometry"> <rect> <x>30</x> <y>90</y> <width>100</width> <height>26</height> </rect> </property> <property name="text"> <string>Cancel</string> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonOk</cstring> </property> <property name="geometry"> <rect> <x>210</x> <y>90</y> <width>100</width> <height>26</height> </rect> </property> <property name="text"> <string>OK</string> </property> </widget> </widget> <images> <image name="image0"> <data format="PNG" length="2278">89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000008ad494441545885e597cb6f1bd715c67f7766c82129520f4a91acd8ae9c58b215398e11c78f22861ba3690a7b51340dba0852a006bc4917fd0f0a78d34d16d9b845e20029eaa21b234de000adfb4a5335889ddacea3526cc7b21cd99228ca222992437148ce0c67eedc2e24b19625b741d15d0f70c08bb933f7fbce77ce87e1c0ff7b888d2e6edd14378a96672ac55619868f9b86feac21c43604dbc2501941a81ed234119a11bd89824086ba1784a626940ca1a9421ca02251450df1c7be9ed82fe7728ef59508440cb12b6a88ef032713a6611d1d796ceac9bdfb36b577762623a888ae697ac2d0e31a4a0b654018041086b84d9fa60cdc4086727e3e6b7ff4f9f5e68c5523e7d4530ada1271232aa57ab12d617c3c9773a6372290d2042f2462dae91dbd7de563bb877b871eee8ba4e331bc5a15dbb25028402064002a4413025d0884008140d7049a583eb2d10cb05c8fb96a9daae7f3feccbcb5d46c86a1a023543c6bd7830f5b04526d467fd4307f1086fe4f4f1cdacfc147066246d0a46455b0aa559452c44c13bdbd93e4e601da922912bd7d08238258a94195f374a652d432b7a9e7e6f16b36005e1050f703e6aa0d6e15abcdb1c5626ed175fbda9391c7e672ceb448b519038661bcd869c67ef2caf78e268453d7178b451a4223d1d3cbd7f67e1d63d356b6ee7a82743a4d32992412892c832a8552aab55e0da514f5c51cd6e417e43eb9883d3f4b6d314fcdf3b93cbfc89fef64ed42c3bded073c29cc8878f65bdb37bff7d4d060f07847227afb6e8e44ff16baf61ee2e07347e9dff60886612056a40dc3700dd0fdc0f7efc9a6472d3bcbdc87ef91b9f401b38b65ee546cce4e4cd56a8e4a1986a11d3e3cf4a8184818d1a9bb39d28f0cb1f93b2ff2cde7bedd3a6c1554d33462b158eb5a18864829f17dff8184841121b56d90c706b61349b5533b7796994a8db66844d69c265a20c3434280e34b925183cec161763db107a5540b64756d1806a55289d3a74ff3f4d34f333434c4c8c8087bf7ee65747414c7715acf6c941d8323440d0da914ba2e22009a2ed8ab092d542874a1b1696818d334d73dac691a4208de7efb6dde78e30d822060dfbe7d0c0f0f934c263979f22457ae5c59965d4aa4942d8556d79a6160681a8626688b47248066189a67e81a20700389aa5aad8aef57c1f77dce9f3f8f65599c38718237df7c933367ce70ecd831cae532afbdf65a0becfe04708b399a522e5b195c0043295c3f90441331ea7e40f5ce2d3cd7259148ace9ab10022925baae63180641102cdb331663cb962dcb96f3bc16d9758329034ad7c7707d49a842a2ba7e7365ae44d1d435d19688133334aaf9bb540bb97515f8be8f9492975e7a899d3b77924ea7310c836c36cbf8f838420806070737544e4a8953ccd358ccd3f0039a32c409826900231ad1fea03c677fc56fcfb5c5629b6a853cd96b63f43f3a8810629dcf0f1e3cc8c0c0003b76ecc0f33c464747f9f4d34fe9e8e8e0c891234829d755afeb3ab5ec2cb5ec0c0b3587dbb56ace937206109adb0c476f5596985c2c7fd9934a62d9368de9492ccb5a574d1886c4623186878709c390ab57af72f6ec590a8502c78f1fe799679ed9b0ff42088a9f7f8c1704d89e4fce75743f5067015db3ebc187bfbd3dfdebdf5c1d7b3488c64a7143a732799ddb5f5ca35eafaf19aa7b273a9fcf73fefc7932990cfbf6ede3f9e79f5f73cf6a2aa5a8cf4d5318bbc26ca54eaee158a152d97cc9cb01860690cdbbc7835076e43d79376546b0aa36cd9be32c2c2c3cd0d3e57299f1f171a2d1287bf6ec41d7f50dfb8f94143ffb3bb6db64ba623355afea6e206f022920aaadf6cbf5e489d72f5e4877b4b7133374ca37ae92bd3686ebbaeb54a8d56af4f7f7b37fff7e344dc3308c35eaacde07e0cdcf90ffc725b2d53a7e18fa35dfcf556cff1dc004347d9540c395b71271ed95877afaee6e4f98edf38b65ba3b52f8e93e3a3b3b5b765ccdcece4e464646d8be7d3b070e1c201e8fafd907304d93ccefdea278e74b268b4b4cd9d5c242cd19abd8c128d000ea2d0580c0f5e453e7c63fd7c344d24ec723643ffe086bea26d56a754d75a669e2fb3ea3a3a35cb87081898989357d0fc31043d358bcfc01f9b12bcc585566abb63b5db713763db8ccf2df801008f57b08d070653e95340fd4a56adfd3954a2fb91e86db40763d44bab7af559d699a6432194e9d3ac5a54b97c8e7f31c3d7ab4b51f8944f00b77c99c7f8bf94281eb798b9bb5a54ace72df6d78e1174001a800f6bd0a0060d579f9a33b539bf2226a0d74b5939b9a24f3a777c96632f8be4f1886d46a354cd3646464844422414f4fcfbf2a370c70ea4cbf7386d2fc1c37162b6ac175aa0bb673cb972ab722bd0b7880d4ef27e0799eab141f4c960adfddb3750b3d112d562e1569369b18dd7db425932db0a1a1210e1f3ecc912347304d93582c862e0316467f4f6efc13a6ac2a5f5ab67fb35a2997aafefb4d3fbc06e48005a00eb8eb080034fd30aba49a99282d7ee3d0c0d6b66ed3d0adcc0cf6c21c74f6602653adf740777737894482443c4eb39863eedcaf287c76991b8b1653655b7e66151bb379e77519aa0c905d91df029c0d15580dc797770229e7a7aa4b070e6c7eb82da9a3fb5689dac21cbee711dfb499542a45241241578ac2a5bf51bcf8172ab76f326bd94c9496e4f58a559acad55f0532c0ccca6f09b0011f0837fc2eb83736a563afa613b1177eb47b676f6f22d6d694124d08ccae1eda77ec42039c995b785619b7e971a3603155b6bdb14a69a954f7fe6a55fd73c0dc0a7079a5ff4d565cf01f0900d174327a2c9d8a9efae1cec1e8f6aef6fe88be6e7629351c264b5526cb4bb509bbe296ede6cfabf5607405b804d4581e3c56c0153ce0cb68a3e84d475f3034edc73db1d8e6dddd5df1dddde9ce58444b559ca6b2dc66f37aa9ece43ca766359b6ec3913fabd8fe45a0c8b2dcb57b40d5bde77e650280487744fa35c4a184a9bf1cd1f45e215407a002a5a2a15279d70f7fe107e18455f56fb06c370708ee07fd6f0900682b690046577ba44f814029ad62074540aea4bf02dc92fa7f4560351ee41ec50632ffbbf827687dcdf9930de2600000000049454e44ae426082</data> </image> </images> <connections> <connection> <sender>pushButtonCancel</sender> <signal>clicked()</signal> <receiver>ModalPopUpDialog</receiver> <slot>pushButtonCancel_clicked()</slot> </connection> <connection> <sender>pushButtonOk</sender> <signal>clicked()</signal> <receiver>ModalPopUpDialog</receiver> <slot>pushButtonOk_clicked()</slot> </connection> </connections> <includes> <include location="local" impldecl="in implementation">ModalPopupDialog.ui.h</include> </includes> <slots> <slot>pushButtonCancel_clicked()</slot> <slot>pushButtonOk_clicked()</slot> </slots> <layoutdefaults spacing="6" margin="11"/> </UI> Index: MainWinContacts_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts_forms.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** MainWinContacts_forms.py 18 Jun 2005 11:27:26 -0000 1.4 --- MainWinContacts_forms.py 5 Jul 2005 15:15:03 -0000 1.5 *************** *** 3,7 **** # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Tue Jul 5 15:49:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # |
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30691 Added Files: AddressEditDialog.ui AddressEditDialog.ui.h AddressEditDialog.ui.h~ AddressEditDialog.ui~ AddressEditDialog_forms.py AddressEditDialog_forms.pyc Log Message: add a contacts edit window --- NEW FILE: AddressEditDialog.ui~ --- <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> <class>FormAddressEdit</class> <widget class="QDialog"> <property name="name"> <cstring>FormAddressEdit</cstring> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>360</width> <height>250</height> </rect> </property> <property name="sizePolicy"> <sizepolicy> <hsizetype>0</hsizetype> <vsizetype>0</vsizetype> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>360</width> <height>250</height> </size> </property> <property name="caption"> <string>GmailAgent - Edit an contact</string> </property> <widget class="QLabel"> <property name="name"> <cstring>textLabel2</cstring> </property> <property name="geometry"> <rect> <x>50</x> <y>20</y> <width>40</width> <height>20</height> </rect> </property> <property name="text"> <string>Name:</string> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel3</cstring> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>80</width> <height>20</height> </rect> </property> <property name="text"> <string>Email Address:</string> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel4</cstring> </property> <property name="geometry"> <rect> <x>50</x> <y>80</y> <width>40</width> <height>20</height> </rect> </property> <property name="text"> <string>Notes:</string> </property> </widget> <widget class="QTextEdit"> <property name="name"> <cstring>textEditNotes</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>80</y> <width>240</width> <height>104</height> </rect> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditEmail</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>50</y> <width>240</width> <height>20</height> </rect> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditName</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>20</y> <width>240</width> <height>20</height> </rect> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonCancel</cstring> </property> <property name="geometry"> <rect> <x>230</x> <y>210</y> <width>106</width> <height>26</height> </rect> </property> <property name="text"> <string>Cancel</string> </property> <property name="default"> <bool>true</bool> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonOk</cstring> </property> <property name="geometry"> <rect> <x>30</x> <y>210</y> <width>106</width> <height>26</height> </rect> </property> <property name="text"> <string>OK</string> </property> </widget> </widget> <connections> <connection> <sender>pushButtonOk</sender> <signal>clicked()</signal> <receiver>FormAddressEdit</receiver> <slot>pushButtonOk_clicked()</slot> </connection> <connection> <sender>pushButtonCancel</sender> <signal>clicked()</signal> <receiver>FormAddressEdit</receiver> <slot>pushButtonCancel_clicked()</slot> </connection> </connections> <includes> <include location="local" impldecl="in implementation">AddressEditDialog.ui.h</include> </includes> <slots> <slot>pushButtonOk_clicked()</slot> <slot>pushButtonCancel_clicked()</slot> </slots> <layoutdefaults spacing="6" margin="11"/> </UI> --- NEW FILE: AddressEditDialog_forms.pyc --- (This appears to be a binary file; contents omitted.) --- NEW FILE: AddressEditDialog.ui.h~ --- /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ void FormAddressEdit::pushButtonOk_clicked() { } void FormAddressEdit::pushButtonCancel_clicked() { } --- NEW FILE: AddressEditDialog.ui.h --- /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ void FormAddressEdit::pushButtonOk_clicked() { } void FormAddressEdit::pushButtonCancel_clicked() { self.done(0) } --- NEW FILE: AddressEditDialog.ui --- <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> <class>FormAddressEdit</class> <widget class="QDialog"> <property name="name"> <cstring>FormAddressEdit</cstring> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>360</width> <height>250</height> </rect> </property> <property name="sizePolicy"> <sizepolicy> <hsizetype>0</hsizetype> <vsizetype>0</vsizetype> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>360</width> <height>250</height> </size> </property> <property name="caption"> <string>GCM - Edit this contact</string> </property> <widget class="QLabel"> <property name="name"> <cstring>textLabel2</cstring> </property> <property name="geometry"> <rect> <x>50</x> <y>20</y> <width>40</width> <height>20</height> </rect> </property> <property name="text"> <string>Name:</string> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel3</cstring> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>80</width> <height>20</height> </rect> </property> <property name="text"> <string>Email Address:</string> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel4</cstring> </property> <property name="geometry"> <rect> <x>50</x> <y>80</y> <width>40</width> <height>20</height> </rect> </property> <property name="text"> <string>Notes:</string> </property> </widget> <widget class="QTextEdit"> <property name="name"> <cstring>textEditNotes</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>80</y> <width>240</width> <height>104</height> </rect> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditEmail</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>50</y> <width>240</width> <height>20</height> </rect> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditName</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>20</y> <width>240</width> <height>20</height> </rect> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonCancel</cstring> </property> <property name="geometry"> <rect> <x>230</x> <y>210</y> <width>106</width> <height>26</height> </rect> </property> <property name="text"> <string>Cancel</string> </property> <property name="default"> <bool>true</bool> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonOk</cstring> </property> <property name="geometry"> <rect> <x>30</x> <y>210</y> <width>106</width> <height>26</height> </rect> </property> <property name="text"> <string>OK</string> </property> </widget> </widget> <connections> <connection> <sender>pushButtonOk</sender> <signal>clicked()</signal> <receiver>FormAddressEdit</receiver> <slot>pushButtonOk_clicked()</slot> </connection> <connection> <sender>pushButtonCancel</sender> <signal>clicked()</signal> <receiver>FormAddressEdit</receiver> <slot>pushButtonCancel_clicked()</slot> </connection> </connections> <includes> <include location="local" impldecl="in implementation">AddressEditDialog.ui.h</include> </includes> <slots> <slot>pushButtonOk_clicked()</slot> <slot>pushButtonCancel_clicked()</slot> </slots> <layoutdefaults spacing="6" margin="11"/> </UI> --- NEW FILE: AddressEditDialog_forms.py --- # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'AddressEditDialog.ui' # # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # # WARNING! All changes made in this file will be lost! from qt import * class FormAddressEdit(QDialog): def __init__(self,parent = None,name = None,modal = 0,fl = 0): QDialog.__init__(self,parent,name,modal,fl) if not name: self.setName("FormAddressEdit") self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.sizePolicy().hasHeightForWidth())) self.setMinimumSize(QSize(360,250)) self.textLabel2 = QLabel(self,"textLabel2") self.textLabel2.setGeometry(QRect(50,20,40,20)) self.textLabel3 = QLabel(self,"textLabel3") self.textLabel3.setGeometry(QRect(10,50,80,20)) self.textLabel4 = QLabel(self,"textLabel4") self.textLabel4.setGeometry(QRect(50,80,40,20)) self.textEditNotes = QTextEdit(self,"textEditNotes") self.textEditNotes.setGeometry(QRect(90,80,240,104)) self.lineEditEmail = QLineEdit(self,"lineEditEmail") self.lineEditEmail.setGeometry(QRect(90,50,240,20)) self.lineEditName = QLineEdit(self,"lineEditName") self.lineEditName.setGeometry(QRect(90,20,240,20)) self.pushButtonCancel = QPushButton(self,"pushButtonCancel") self.pushButtonCancel.setGeometry(QRect(230,210,106,26)) self.pushButtonCancel.setDefault(1) self.pushButtonOk = QPushButton(self,"pushButtonOk") self.pushButtonOk.setGeometry(QRect(30,210,106,26)) self.languageChange() self.resize(QSize(360,250).expandedTo(self.minimumSizeHint())) self.clearWState(Qt.WState_Polished) self.connect(self.pushButtonOk,SIGNAL("clicked()"),self.pushButtonOk_clicked) self.connect(self.pushButtonCancel,SIGNAL("clicked()"),self.pushButtonCancel_clicked) def languageChange(self): self.setCaption(self.__tr("GCM - Edit this contact")) self.textLabel2.setText(self.__tr("Name:")) self.textLabel3.setText(self.__tr("Email Address:")) self.textLabel4.setText(self.__tr("Notes:")) self.pushButtonCancel.setText(self.__tr("Cancel")) self.pushButtonOk.setText(self.__tr("OK")) def pushButtonOk_clicked(self): print "FormAddressEdit.pushButtonOk_clicked(): Not implemented yet" def pushButtonCancel_clicked(self): self.done(0) def __tr(self,s,c = None): return qApp.translate("FormAddressEdit",s,c) |
|
From: Stas Z. <sta...@us...> - 2005-06-18 11:27:36
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29993 Modified Files: Contrgcm.py GuiQTgcm.py LoginDialog_forms.py MainWinContacts.ui MainWinContacts.ui.h MainWinContacts_forms.py Makefile Qgcm.e3p QgcmDialogs.py Log Message: More work done on the abstraction layer Index: Qgcm.e3p =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Qgcm.e3p,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Qgcm.e3p 16 Jun 2005 13:03:12 -0000 1.3 --- Qgcm.e3p 18 Jun 2005 11:27:26 -0000 1.4 *************** *** 2,6 **** <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-15, 20:22:08 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> --- 2,6 ---- <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-18, 13:26:49 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> *************** *** 39,42 **** --- 39,48 ---- <Name>MainWinContacts.ui.h</Name> </Form> + <Form> + <Name>AddressEditDialog.ui</Name> + </Form> + <Form> + <Name>AddressEditDialog.ui.h</Name> + </Form> </Forms> <Translations> Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Contrgcm.py 15 Jun 2005 18:21:53 -0000 1.5 --- Contrgcm.py 18 Jun 2005 11:27:26 -0000 1.6 *************** *** 18,23 **** # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! CG_DEBUG = 0 import libgmail2,logging,os,shelve,urllib2,ConfigParser --- 18,28 ---- # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + """ + Contrgcm is a module which acts as a abstraction layer for libgmail2 and it's + intended to be used by libgmail frontends. + It knows nothing about the GUI, only about libgmail2. + """ ! CG_DEBUG = 1 import libgmail2,logging,os,shelve,urllib2,ConfigParser *************** *** 31,38 **** if CG_DEBUG: logging.debug("Starting") ! def load_login(): """load_login --> The tuple logname,password or None. Loads the login data from a dot file in the users home directory. The name of the rc file is always '.gmailagent'. """ if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") --- 36,44 ---- if CG_DEBUG: logging.debug("Starting") ! def load_login(section='Login'): """load_login --> The tuple logname,password or None. Loads the login data from a dot file in the users home directory. The name of the rc file is always '.gmailagent'. + @section defaults to 'Login' and is intended for internal purposes. """ if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") *************** *** 41,64 **** try: configdict.readfp(open(rcfile)) ! name,pas = configdict.get('Login','name'), configdict.get('Login','pas') ! except: ! if CG_DEBUG: logging.warning("Failed to load the password from %s" % rcfile) return None return (name,pas) ! def store_login(name,pas): """store_login --> True on succes, False on faillure. ! Stores the login data in a dot file in the users home directory. ! The name of the rc file is always '.gmail'. @name is the Gmail account name. @pas is the password. """ ! if CG_DEBUG: logging.debug("Store the login data") rcfile = os.path.expanduser('~/.gmailagent') configdict = ConfigParser.ConfigParser() ! if not configdict.has_section('Login'): ! configdict.add_section('Login') ! configdict.set('Login','name',name) ! configdict.set('Login','pas',pas) try: f = open(rcfile,'w') --- 47,121 ---- try: configdict.readfp(open(rcfile)) ! if section == 'Login': ! name,pas = configdict.get(section,'name'), configdict.get(section,'pas') ! elif section == 'Default': ! name,pas = configdict.get(section,'path'),None ! except (IOError,\ ! ConfigParser.MissingSectionHeaderError,\ ! ConfigParser.NoOptionError),info: ! if CG_DEBUG: ! print info ! logging.warning("Failed to load the password from %s" % rcfile) return None return (name,pas) ! def get_default_database_path(path): ! """get_default_database_path --> path on succes, False on faillure. ! It will return the path as it's currently stored in the rc file. ! There's no garantee that the database will actually exist. ! Use the 'store_default_database_path' to set the path. ! """ ! db_path,spam = load_login('Default') ! if os.path.exists(db_path): ! return db_path ! else: ! return False ! def get_dbase_pathname(): ! """get_dbase_pathname --> pathname on succes, False on faillure. ! The difference with 'get_default_database_path' is that this will ! return the path of the database currently in use or None if theres ! no database in use. ! """ ! global _DBase ! try: ! path = _Dbase._get_path() ! except: ! return False ! return path ! ! def store_default_database_path(path): ! """store_default_database_path --> True on succes, False on faillure. ! Stores the default database path to use. ! Use get_default_database_path' to retrieve it. ! """ ! return store_login(path,None,'Default') ! ! def store_login(name,pas,section='Login'): """store_login --> True on succes, False on faillure. ! Stores the login data and sets the default db path in a dot file in the ! users home directory. ! The name of the rc file is always '.gmailagent'. @name is the Gmail account name. @pas is the password. + @section defaults to 'Login' and is intended for internal purposes. """ ! if CG_DEBUG: logging.debug("Store the login data %s %s %s" % (name,pas,section)) rcfile = os.path.expanduser('~/.gmailagent') configdict = ConfigParser.ConfigParser() ! if not configdict.has_section(section): ! configdict.add_section(section) ! if section == 'Login': ! configdict.set(section,'name',name) ! configdict.set(section,'pas',pas) ! # store the name of the default database for this account ! # I f the database actual exist is the problem of the ! # 'get_default_database_path' function. ! db_name = os.path.expanduser('~/.gcm_database')+'.'+name ! if not configdict.has_section('Default'): ! configdict.add_section('Default') ! configdict.set('Default','path',db_name) ! if CG_DEBUG: logging.debug("Store the default data %s %s" % (db_name,section)) ! elif section == 'Default': ! configdict.set(section,'path',name) try: f = open(rcfile,'w') *************** *** 136,139 **** --- 193,198 ---- @contacts is a list of tuples containing the contacts. The format must be the same as returnt by import_contacts_db. + When a empty list is passed it will upload only the differences between + the local database and the online Gmail contacts. @ga is a libgmail GmailAccount. """ *************** *** 154,160 **** def store_contact_db(key,contact): """store_contact_db --> True on succes, False on faillure ! Stores the contact in a Gmail account. @key is the dbase key. @contact is a tuple containing the contact. """ try: --- 213,220 ---- def store_contact_db(key,contact): """store_contact_db --> True on succes, False on faillure ! Stores the contact in a local database. @key is the dbase key. @contact is a tuple containing the contact. + This is probably only used by Contrgcm internally. """ try: *************** *** 185,188 **** --- 245,254 ---- pass + def sync_contacts(self): + """sync_contacts --> True on succes, False on faillure. + XXX I'm not really clear on the way to do this :-) + """ + pass + class DBase: def __init__(self,name=''): Index: LoginDialog_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/LoginDialog_forms.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** LoginDialog_forms.py 15 Jun 2005 14:50:13 -0000 1.1 --- LoginDialog_forms.py 18 Jun 2005 11:27:26 -0000 1.2 *************** *** 3,7 **** # Form implementation generated from reading ui file 'LoginDialog.ui' # ! # Created: Wed Jun 15 14:36:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'LoginDialog.ui' # ! # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # Index: MainWinContacts.ui.h =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts.ui.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MainWinContacts.ui.h 12 Jun 2005 06:17:01 -0000 1.1 --- MainWinContacts.ui.h 18 Jun 2005 11:27:26 -0000 1.2 *************** *** 81,94 **** - void FormMainWin::listViewContacts_pressed( QListViewItem * ) - { - - } - - - void FormMainWin::listViewContacts_clicked( QListViewItem *, const QPoint &, int ) - { - - } --- 81,84 ---- Index: QgcmDialogs.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/QgcmDialogs.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** QgcmDialogs.py 15 Jun 2005 18:21:53 -0000 1.2 --- QgcmDialogs.py 18 Jun 2005 11:27:26 -0000 1.3 *************** *** 21,24 **** --- 21,25 ---- from qt import QProgressDialog,QLabel,QMessageBox from LoginDialog_forms import FormLogin + from AddressEditDialog_forms import FormAddressEdit from Observers import Observer,Observable import Contrgcm *************** *** 48,52 **** self.lineEditLogin.setText(result[0]) self.lineEditPass.setText(result[1]) ! self.exec_loop() def pushButtonLogin_clicked(self): --- 49,58 ---- self.lineEditLogin.setText(result[0]) self.lineEditPass.setText(result[1]) ! ! def start(self): ! """You should call this to start the dialog and get a usefull return ! value. True when the login succeeds and False on faillure. ! The return value is set by the 'done' call.""" ! return self.exec_loop() def pushButtonLogin_clicked(self): *************** *** 62,66 **** self.pushButtonCancel_clicked() self.progress_dlg.update() ! if result[0]: QMessageBox.critical(self, --- 68,72 ---- self.pushButtonCancel_clicked() self.progress_dlg.update() ! retval = False if result[0]: QMessageBox.critical(self, *************** *** 70,73 **** --- 76,80 ---- self.notifyObservers(result[2]) self.ga = result[2] + retval = True self.progress_dlg.update() if self.keepsettings: *************** *** 76,88 **** "Error", "Failed to store the login data to disk", QMessageBox.Ok) ! self.done(1) def get_account_object(self): return self.ga def pushButtonCancel_clicked(self): ! self.done(1) def checkBoxPass_toggled(self,a0): self.keepsettings = a0 class ProgressDialog: def __init__(self,parent,Qapplication,label='',steps=1,modal=0,): --- 83,97 ---- "Error", "Failed to store the login data to disk", QMessageBox.Ok) ! self.done(retval) def get_account_object(self): return self.ga def pushButtonCancel_clicked(self): ! self.done(False) def checkBoxPass_toggled(self,a0): self.keepsettings = a0 + ### XXX The progressdialog should have a way to become 'on top' when called + ### XXX perhaps with a call to focus? or modal? class ProgressDialog: def __init__(self,parent,Qapplication,label='',steps=1,modal=0,): *************** *** 103,104 **** --- 112,122 ---- self.Qapplication.processEvents() self.index += 1 + + class AddressEditDialog(FormAddressEdit): + """Dialog to display and edit the contact""" + def __init__(self,contact,parent=None,name=None,modal=1,fl=0): + FormAddressEdit.__init__(self,parent,name,modal,fl) + self.contact_org = contact + + + Index: GuiQTgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/GuiQTgcm.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** GuiQTgcm.py 15 Jun 2005 14:48:39 -0000 1.4 --- GuiQTgcm.py 18 Jun 2005 11:27:26 -0000 1.5 *************** *** 36,39 **** --- 36,40 ---- self.Qapplication = application # Needed for a Qprogressdialog self.ga = None + self.show() # test stuff *************** *** 57,61 **** def editEditcontact_activated(self): ! print "FormMainWin.editEditcontact_activated(): Not implemented yet" def editDeletecontact_activated(self): --- 58,73 ---- def editEditcontact_activated(self): ! print "FormMainWin.editEditcontact_activated()" ! entry = self.listViewContacts.selectedItem() ! if not self.ga: ! text = "You're currently working with a contacts list which\n"+\ ! "is constructed from the local contacts database.\n"+\ ! "You should import a new Gmail contacts list from your\n"+\ ! "Gmail account before editing any contacts to keep everything\n"+\ ! "syncronized\n\n"+\ ! "Shall I import your contacts from your Gmail account?" ! QMessageBox.information(self,"Question", text,QMessageBox.Ok) ! return ! AddressBookEditDialog(entry,parent=self,ga=self.ga) def editDeletecontact_activated(self): *************** *** 64,68 **** def helpContents_activated(self): print "FormMainWin.helpContents_activated(): Not implemented yet" ! #This callback is used for testing purposes self.notifyObservers("this is data") --- 76,80 ---- def helpContents_activated(self): print "FormMainWin.helpContents_activated(): Not implemented yet" ! #This callback is only used for testing purposes self.notifyObservers("this is data") *************** *** 85,94 **** print "FormMainWin.contactsExportcontacts_activated(): Not implemented yet" - def listViewContacts_pressed(self,a0): - print "FormMainWin.listViewContacts_pressed(QListViewItem*): Not implemented yet" - - def listViewContacts_clicked(self,a0,a1,a2): - print "FormMainWin.listViewContacts_clicked(QListViewItem*,const QPoint&,int): Not implemented yet" - def lineEditSearchToolbar_textChanged(self,a0): print "FormMainWin.lineEditSearchToolbar_textChanged(const QString&): Not implemented yet" --- 97,100 ---- *************** *** 97,110 **** if GQ_DEBUG: logging.debug("FormMainWin.contactsImportcontacts_activated()") if not self.ga: ! # keep a reference to the observer to prevent the Python Garbage ! # collector from removing it. ! self.Myobs = Observer(self._import_contacts_observerCB) ! # See _import_contacts_observerCB for an explanation why we use this ! Login(self.Qapplication,self.Myobs,parent=self) ! else: ! contacts = Contrgcm.import_contacts_gmail(self.ga) ! self._load(contacts) ! return 1 ! def contactsSave_activated(self): print "FormMainWin.contactsSave_activated(): Not implemented yet" --- 103,114 ---- if GQ_DEBUG: logging.debug("FormMainWin.contactsImportcontacts_activated()") if not self.ga: ! dlg = Login(self.Qapplication,parent=self) ! if not dlg.start(): ! return #login has failled, the dialog will displays it's own message ! else: ! self.ga = dlg.get_account_object() ! contacts = Contrgcm.import_contacts_gmail(self.ga) ! self._load(contacts) ! def contactsSave_activated(self): print "FormMainWin.contactsSave_activated(): Not implemented yet" *************** *** 119,133 **** self.close(1) ! ####### Internal used methods ################ ! ! def _import_contacts_observerCB(self,caller,data): ! """Called by the observer from the Login object. ! This is used when there's no libgmail login object. ! The problem is that we first must get a valid Gmail login but ! that the Login dialog isn't blocking the program execution. ! A QT Dialog can be made to block but it can return a useable value.""" ! self.ga = data[0] ! contacts = Contrgcm.import_contacts_gmail(self.ga) ! self._load(contacts) def _load(self,conlist): --- 123,127 ---- self.close(1) ! ####### Methods to do stuff with things :-) ################ def _load(self,conlist): Index: Makefile =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Makefile 15 Jun 2005 11:14:02 -0000 1.2 --- Makefile 18 Jun 2005 11:27:26 -0000 1.3 *************** *** 3,5 **** pyuic MainWinContacts.ui -o MainWinContacts_forms.py pyuic LoginDialog.ui -o LoginDialog_forms.py ! \ No newline at end of file --- 3,5 ---- pyuic MainWinContacts.ui -o MainWinContacts_forms.py pyuic LoginDialog.ui -o LoginDialog_forms.py ! pyuic AddressEditDialog.ui -o AddressEditDialog_forms.py Index: MainWinContacts.ui =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts.ui,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MainWinContacts.ui 15 Jun 2005 14:48:39 -0000 1.2 --- MainWinContacts.ui 18 Jun 2005 11:27:26 -0000 1.3 *************** *** 782,787 **** <slot>listViewContacts_doubleClicked( QListViewItem * )</slot> <slot>contactsExportcontacts_activated()</slot> - <slot>listViewContacts_pressed( QListViewItem * )</slot> - <slot>listViewContacts_clicked( QListViewItem *, const QPoint &, int )</slot> <slot>lineEditSearchToolbar_textChanged( const QString & )</slot> <slot>contactsImportcontacts_activated()</slot> --- 782,785 ---- Index: MainWinContacts_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts_forms.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MainWinContacts_forms.py 15 Jun 2005 14:48:39 -0000 1.3 --- MainWinContacts_forms.py 18 Jun 2005 11:27:26 -0000 1.4 *************** *** 3,7 **** # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Wed Jun 15 14:36:48 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Sat Jun 18 08:29:10 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # *************** *** 1554,1563 **** print "FormMainWin.contactsExportcontacts_activated(): Not implemented yet" - def listViewContacts_pressed(self,a0): - print "FormMainWin.listViewContacts_pressed(QListViewItem*): Not implemented yet" - - def listViewContacts_clicked(self,a0,a1,a2): - print "FormMainWin.listViewContacts_clicked(QListViewItem*,const QPoint&,int): Not implemented yet" - def lineEditSearchToolbar_textChanged(self,a0): print "FormMainWin.lineEditSearchToolbar_textChanged(const QString&): Not implemented yet" --- 1554,1557 ---- |
|
From: Stas Z. <sta...@us...> - 2005-06-16 13:36:52
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11771 Modified Files: libgmail2.py Log Message: Added one \n in the VCard export Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libgmail2.py 16 Jun 2005 13:19:04 -0000 1.8 --- libgmail2.py 16 Jun 2005 13:36:43 -0000 1.9 *************** *** 913,918 **** vcard += "FN:%s\n" % self.getName() vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() ! vcard += "END:VCARD\n" # Final newline in case we want to put more than one in a file? return vcard --- 913,919 ---- vcard += "FN:%s\n" % self.getName() vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() ! vcard += "END:VCARD\n\n" # Final newline in case we want to put more than one in a file? + # Yes :-) return vcard |
|
From: Stas Z. <sta...@us...> - 2005-06-16 13:19:13
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv416 Modified Files: libgmail2.py testlibgmail2.py Log Message: Removed more hard tabs Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libgmail2.py 16 Jun 2005 05:09:05 -0000 1.7 --- libgmail2.py 16 Jun 2005 13:19:04 -0000 1.8 *************** *** 900,919 **** def getVCard(self): """Returns a vCard 3.0 for this ! contact, as a string""" ! vcard = "BEGIN:VCARD\n" ! vcard += "VERSION:3.0\n" ! # Deal with multiline notes ! vcard += "NOTE:%s\n" % self.getNotes().replace("\n","\\n") ! # Fake-out N by splitting up whatever we get out of getName ! # This might not always do 'the right thing' ! # but it's a *reasonable* compromise ! fullname = self.getName().split() ! fullname.reverse() ! vcard += "N:%s" % ';'.join(fullname) + "\n" ! vcard += "FN:%s\n" % self.getName() ! vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() ! vcard += "END:VCARD\n" ! # Final newline in case we want to put more than one in a file? ! return vcard class GmailContactList: --- 900,919 ---- def getVCard(self): """Returns a vCard 3.0 for this ! contact, as a string""" ! vcard = "BEGIN:VCARD\n" ! vcard += "VERSION:3.0\n" ! # Deal with multiline notes ! vcard += "NOTE:%s\n" % self.getNotes().replace("\n","\\n") ! # Fake-out N by splitting up whatever we get out of getName ! # This might not always do 'the right thing' ! # but it's a *reasonable* compromise ! fullname = self.getName().split() ! fullname.reverse() ! vcard += "N:%s" % ';'.join(fullname) + "\n" ! vcard += "FN:%s\n" % self.getName() ! vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() ! vcard += "END:VCARD\n" ! # Final newline in case we want to put more than one in a file? ! return vcard class GmailContactList: Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** testlibgmail2.py 16 Jun 2005 13:03:47 -0000 1.7 --- testlibgmail2.py 16 Jun 2005 13:19:04 -0000 1.8 *************** *** 155,161 **** def test9_vCard(self): """Test vCard export""" ! waseem = GmailContact("0", "Waseem Daher", "wd...@mi...", "GmailAgent developer") ! vcard = waseem.getVCard() ! expectedVCard="""BEGIN:VCARD VERSION:3.0 NOTE:GmailAgent developer --- 155,161 ---- def test9_vCard(self): """Test vCard export""" ! waseem = GmailContact("0", "Waseem Daher", "wd...@mi...", "GmailAgent developer") ! vcard = waseem.getVCard() ! expectedVCard="""BEGIN:VCARD VERSION:3.0 NOTE:GmailAgent developer *************** *** 167,174 **** self.assertEqual(vcard, expectedVCard, "getVCard() did not export what we expected for Waseem") ! # Test multi-line NOTEs ! bob = GmailContact("0", "BillyJo", "bi...@jo...", "I like multilines\nwoo") ! bobvcard=bob.getVCard() ! bobexpectedVCard="""BEGIN:VCARD VERSION:3.0 NOTE:I like multilines\\nwoo --- 167,174 ---- self.assertEqual(vcard, expectedVCard, "getVCard() did not export what we expected for Waseem") ! # Test multi-line NOTEs ! bob = GmailContact("0", "BillyJo", "bi...@jo...", "I like multilines\nwoo") ! bobvcard=bob.getVCard() ! bobexpectedVCard="""BEGIN:VCARD VERSION:3.0 NOTE:I like multilines\\nwoo *************** *** 179,183 **** """ self.assertEqual(vcard, expectedVCard, "getVCard() didn't export what we expected for BillyJo") ! if __name__ == '__main__': #unittest.main() --- 179,183 ---- """ self.assertEqual(vcard, expectedVCard, "getVCard() didn't export what we expected for BillyJo") ! if __name__ == '__main__': #unittest.main() |
|
From: Stas Z. <sta...@us...> - 2005-06-16 13:03:55
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24848 Modified Files: testlibgmail2.py Log Message: removed a few hard tabs Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** testlibgmail2.py 16 Jun 2005 05:32:00 -0000 1.6 --- testlibgmail2.py 16 Jun 2005 13:03:47 -0000 1.7 *************** *** 38,44 **** def test1_BasicAddContact(self): """Create and retrieve an entry-level contact""" ! name = 'John Smith' ! email = 'joh...@gm...' ! notes = 'I am average' account.addContact(name, email, notes) myContacts = account.getContacts() --- 38,44 ---- def test1_BasicAddContact(self): """Create and retrieve an entry-level contact""" ! name = 'John Smith' ! email = 'joh...@gm...' ! notes = 'I am average' account.addContact(name, email, notes) myContacts = account.getContacts() *************** *** 50,56 **** def test2_AdvancedAddContact(): """Create and retrieve a contact with a newline in the notes""" ! name = 'W4533m' ! email = 'fak...@gm...' ! notes = 'Is\nawesome' account.addContact(name, email, notes) myContacts = account.getContacts() --- 50,56 ---- def test2_AdvancedAddContact(): """Create and retrieve a contact with a newline in the notes""" ! name = 'W4533m' ! email = 'fak...@gm...' ! notes = 'Is\nawesome' account.addContact(name, email, notes) myContacts = account.getContacts() |
|
From: Stas Z. <sta...@us...> - 2005-06-16 13:03:23
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24389/frontend Modified Files: Qgcm.e3p Log Message: Removed hard tabs Index: Qgcm.e3p =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Qgcm.e3p,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Qgcm.e3p 15 Jun 2005 18:21:53 -0000 1.2 --- Qgcm.e3p 16 Jun 2005 13:03:12 -0000 1.3 *************** *** 2,6 **** <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-15, 18:04:46 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> --- 2,6 ---- <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-15, 20:22:08 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> *************** *** 28,31 **** --- 28,34 ---- <Name>testContrgcm.py</Name> </Source> + <Source> + <Name>QgcmDialogs.py</Name> + </Source> </Sources> <Forms> |
|
From: Waseem D. <wd...@us...> - 2005-06-16 05:32:09
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17805 Modified Files: testlibgmail2.py Log Message: Added new "newline contact" test (fails with error right now, since we don't do the right thing.) Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** testlibgmail2.py 16 Jun 2005 05:09:05 -0000 1.5 --- testlibgmail2.py 16 Jun 2005 05:32:00 -0000 1.6 *************** *** 35,38 **** --- 35,63 ---- account.removeContact(contact) + + def test1_BasicAddContact(self): + """Create and retrieve an entry-level contact""" + name = 'John Smith' + email = 'joh...@gm...' + notes = 'I am average' + account.addContact(name, email, notes) + myContacts = account.getContacts() + contact = myContacts.getContactByName(name) + self.assertEqual(contact.getName(), name, "Returned name isn't the one we created initially") + self.assertEqual(contact.getEmail(), email, "Returned email isn't the one we created initially") + self.assertEqual(contact.getNotes(), notes, "Returned note isn't the one we created initially") + + def test2_AdvancedAddContact(): + """Create and retrieve a contact with a newline in the notes""" + name = 'W4533m' + email = 'fak...@gm...' + notes = 'Is\nawesome' + account.addContact(name, email, notes) + myContacts = account.getContacts() + contact = myContacts.getContactByName(name) + self.assertEqual(contact.getName(), name, "Returned name isn't the one we created initially") + self.assertEqual(contact.getEmail(), email, "Returned email isn't the one we created initially") + self.assertEqual(contact.getNotes(), notes, "Returned note isn't the one we created initially") + def test3_GmailContact(self): """Check that GmailContact equality and accessor methods work""" *************** *** 154,158 **** """ self.assertEqual(vcard, expectedVCard, "getVCard() didn't export what we expected for BillyJo") ! if __name__ == '__main__': #unittest.main() --- 179,183 ---- """ self.assertEqual(vcard, expectedVCard, "getVCard() didn't export what we expected for BillyJo") ! if __name__ == '__main__': #unittest.main() |
|
From: Waseem D. <wd...@us...> - 2005-06-16 05:09:16
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7485 Modified Files: libgmail2.py testlibgmail2.py Log Message: Added support for multiline notes in vCard export (not convinced that we'll ever get these from Gmail, or that we can even add contacts with multiline notes successfully, but it's still worth dealing with this case in the vCard export) Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libgmail2.py 16 Jun 2005 05:01:20 -0000 1.6 --- libgmail2.py 16 Jun 2005 05:09:05 -0000 1.7 *************** *** 903,909 **** vcard = "BEGIN:VCARD\n" vcard += "VERSION:3.0\n" ! # This might not adhere to the spec ! # if the note is multi-line? ! vcard += "NOTE:%s\n" % self.getNotes() # Fake-out N by splitting up whatever we get out of getName # This might not always do 'the right thing' --- 903,908 ---- vcard = "BEGIN:VCARD\n" vcard += "VERSION:3.0\n" ! # Deal with multiline notes ! vcard += "NOTE:%s\n" % self.getNotes().replace("\n","\\n") # Fake-out N by splitting up whatever we get out of getName # This might not always do 'the right thing' Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** testlibgmail2.py 16 Jun 2005 05:01:20 -0000 1.4 --- testlibgmail2.py 16 Jun 2005 05:09:05 -0000 1.5 *************** *** 140,145 **** END:VCARD """ ! self.assertEqual(vcard, expectedVCard, "getVCard() did not export what we expected") if __name__ == '__main__': --- 140,157 ---- END:VCARD """ ! self.assertEqual(vcard, expectedVCard, "getVCard() did not export what we expected for Waseem") + # Test multi-line NOTEs + bob = GmailContact("0", "BillyJo", "bi...@jo...", "I like multilines\nwoo") + bobvcard=bob.getVCard() + bobexpectedVCard="""BEGIN:VCARD + VERSION:3.0 + NOTE:I like multilines\\nwoo + N:BillyJo + FN:BillyJo + EMAIL;TYPE=INTERNET:bi...@jo... + END:VCARD + """ + self.assertEqual(vcard, expectedVCard, "getVCard() didn't export what we expected for BillyJo") if __name__ == '__main__': |
|
From: Waseem D. <wd...@us...> - 2005-06-16 05:01:31
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3226 Modified Files: libgmail2.py testlibgmail2.py Log Message: Deal with N: in vCard a little more sanely Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libgmail2.py 16 Jun 2005 03:44:53 -0000 1.5 --- libgmail2.py 16 Jun 2005 05:01:20 -0000 1.6 *************** *** 906,913 **** # if the note is multi-line? vcard += "NOTE:%s\n" % self.getNotes() ! # TODO: Take a stab at adding an N field? vcard += "FN:%s\n" % self.getName() vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() vcard += "END:VCARD\n" return vcard --- 906,919 ---- # if the note is multi-line? vcard += "NOTE:%s\n" % self.getNotes() ! # Fake-out N by splitting up whatever we get out of getName ! # This might not always do 'the right thing' ! # but it's a *reasonable* compromise ! fullname = self.getName().split() ! fullname.reverse() ! vcard += "N:%s" % ';'.join(fullname) + "\n" vcard += "FN:%s\n" % self.getName() vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() vcard += "END:VCARD\n" + # Final newline in case we want to put more than one in a file? return vcard Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** testlibgmail2.py 16 Jun 2005 03:44:53 -0000 1.3 --- testlibgmail2.py 16 Jun 2005 05:01:20 -0000 1.4 *************** *** 135,138 **** --- 135,139 ---- VERSION:3.0 NOTE:GmailAgent developer + N:Daher;Waseem FN:Waseem Daher EMAIL;TYPE=INTERNET:wd...@mi... |
|
From: Waseem D. <wd...@us...> - 2005-06-16 03:45:01
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32675 Modified Files: libgmail2.py testlibgmail2.py Log Message: Added basic vCard export (could use a little improvement trying to build FN, and trying to deal with multiline notes?) Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libgmail2.py 15 Jun 2005 11:14:01 -0000 1.4 --- libgmail2.py 16 Jun 2005 03:44:53 -0000 1.5 *************** *** 8,12 **** # # Contacts support added by wd...@mi... ! # (with massive help from 'gmail.py' and the Johnvey Gmail API) # # License: GPL 2.0 --- 8,14 ---- # # Contacts support added by wd...@mi... ! # (with massive initial help from ! # Adrian Holovaty's 'gmail.py' ! # and the Johnvey Gmail API) # # License: GPL 2.0 *************** *** 896,899 **** --- 898,914 ---- def getNotes(self): return self.notes + def getVCard(self): + """Returns a vCard 3.0 for this + contact, as a string""" + vcard = "BEGIN:VCARD\n" + vcard += "VERSION:3.0\n" + # This might not adhere to the spec + # if the note is multi-line? + vcard += "NOTE:%s\n" % self.getNotes() + # TODO: Take a stab at adding an N field? + vcard += "FN:%s\n" % self.getName() + vcard += "EMAIL;TYPE=INTERNET:%s\n" % self.getEmail() + vcard += "END:VCARD\n" + return vcard class GmailContactList: Index: testlibgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/testlibgmail2.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** testlibgmail2.py 2 Jun 2005 14:12:20 -0000 1.2 --- testlibgmail2.py 16 Jun 2005 03:44:53 -0000 1.3 *************** *** 128,131 **** --- 128,144 ---- self.assertEqual(myContactList.getCount(), 0) + def test9_vCard(self): + """Test vCard export""" + waseem = GmailContact("0", "Waseem Daher", "wd...@mi...", "GmailAgent developer") + vcard = waseem.getVCard() + expectedVCard="""BEGIN:VCARD + VERSION:3.0 + NOTE:GmailAgent developer + FN:Waseem Daher + EMAIL;TYPE=INTERNET:wd...@mi... + END:VCARD + """ + self.assertEqual(vcard, expectedVCard, "getVCard() did not export what we expected") + if __name__ == '__main__': |
|
From: Stas Z. <sta...@us...> - 2005-06-15 18:22:05
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1812 Modified Files: Contrgcm.py Qgcm.e3p QgcmDialogs.py Log Message: More hacking Index: QgcmDialogs.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/QgcmDialogs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** QgcmDialogs.py 15 Jun 2005 14:50:13 -0000 1.1 --- QgcmDialogs.py 15 Jun 2005 18:21:53 -0000 1.2 *************** *** 72,79 **** self.progress_dlg.update() if self.keepsettings: ! result = Contrgcm.store_login(log,pas) ! if result[0]: QMessageBox.critical(self, ! "Error", result[1], QMessageBox.Ok) self.done(1) --- 72,78 ---- self.progress_dlg.update() if self.keepsettings: ! if not Contrgcm.store_login(log,pas): QMessageBox.critical(self, ! "Error", "Failed to store the login data to disk", QMessageBox.Ok) self.done(1) Index: Qgcm.e3p =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Qgcm.e3p,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Qgcm.e3p 15 Jun 2005 14:50:13 -0000 1.1 --- Qgcm.e3p 15 Jun 2005 18:21:53 -0000 1.2 *************** *** 2,6 **** <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-14, 16:56:57 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> --- 2,6 ---- <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> ! <!-- Saved: 2005-06-15, 18:04:46 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> *************** *** 25,28 **** --- 25,31 ---- <Name>GuiQTgcm.py</Name> </Source> + <Source> + <Name>testContrgcm.py</Name> + </Source> </Sources> <Forms> Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Contrgcm.py 15 Jun 2005 14:48:39 -0000 1.4 --- Contrgcm.py 15 Jun 2005 18:21:53 -0000 1.5 *************** *** 54,61 **** @pas is the password. """ ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: store_login") rcfile = os.path.expanduser('~/.gmailagent') configdict = ConfigParser.ConfigParser() ! configdict.add_section('Login') configdict.set('Login','name',name) configdict.set('Login','pas',pas) --- 54,62 ---- @pas is the password. """ ! if CG_DEBUG: logging.debug("Store the login data") rcfile = os.path.expanduser('~/.gmailagent') configdict = ConfigParser.ConfigParser() ! if not configdict.has_section('Login'): ! configdict.add_section('Login') configdict.set('Login','name',name) configdict.set('Login','pas',pas) *************** *** 65,69 **** except: f.close() ! if GM_DEBUG: logging.warning("Failed to store the password in %s" % rcfile) return False f.close() --- 66,70 ---- except: f.close() ! if CG_DEBUG: logging.warning("Failed to store the password in %s" % rcfile) return False f.close() *************** *** 84,89 **** --- 85,110 ---- return (1,"%s" % info,None) else: + setup_database(name) return (0,"Log in successful.",ga) + def setup_database(name): + """setup_database --> path or None + This will setup the database if it's not already available. + It's possible to have multiple databases which different names. + Every Gmail account has it's own database. + """ + global _DBase + try: + _Dbase._close() + except: + pass + db_name = os.path.expanduser('~/.gcm_database')+'.'+name + try: + _DBase = DBase(name=db_name) + except Exception,info: + print info + logging.critical("Failed to create database %s" % info) + if CG_DEBUG: logging.debug("Shelve DB %s created %s" % (db_name,_DBase)) + def import_contacts_gmail(ga): """import_contacts_gmail --> contacts in a list of tuples or None. *************** *** 101,105 **** conitem = (obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId()) conlist.append(conitem) ! _DBase._store_value(conitem[3],conitem) if CG_DEBUG: logging.debug("Database values %s" % _DBase._get_all_values()) return conlist --- 122,126 ---- conitem = (obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId()) conlist.append(conitem) ! store_contact_db(conitem[3],conitem) if CG_DEBUG: logging.debug("Database values %s" % _DBase._get_all_values()) return conlist *************** *** 131,134 **** --- 152,166 ---- """ pass + def store_contact_db(key,contact): + """store_contact_db --> True on succes, False on faillure + Stores the contact in a Gmail account. + @key is the dbase key. + @contact is a tuple containing the contact. + """ + try: + _DBase._store_value(key,contact) + except Exception,info: + print info + logging.critical("Failed to store %s with key %s" % (contact,key)) def remove_contacts_gmail(ga): """remove_contacts_gmail --> True on succes, False on faillure. *************** *** 155,159 **** class DBase: def __init__(self,name=''): ! """@name is only meant for the unittest suite""" if not name: self.db_name = os.path.expanduser('~/.gcm_database') --- 187,192 ---- class DBase: def __init__(self,name=''): ! """@name is to setup different databases for various accounts""" ! print "name",name if not name: self.db_name = os.path.expanduser('~/.gcm_database') *************** *** 161,164 **** --- 194,199 ---- self.db_name = name self.DB_dict = shelve.open(self.db_name) + def _get_path(self): + return self.db_name def _get_all_values(self): return self.DB_dict.values() *************** *** 172,177 **** self.DB_dict.close() - _DBase = DBase() - if CG_DEBUG: logging.debug("Shelve DB created %s" % _DBase) ###### Old stuff, perhaps we can use parts of it ########### --- 207,210 ---- |
|
From: Stas Z. <sta...@us...> - 2005-06-15 14:50:21
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13690 Added Files: LoginDialog.ui LoginDialog.ui.h LoginDialog_forms.py Qgcm.e3p QgcmDialogs.py Log Message: added QT forms --- NEW FILE: QgcmDialogs.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # QgcmDialogs.py # # 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 Library 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. from qt import QProgressDialog,QLabel,QMessageBox from LoginDialog_forms import FormLogin from Observers import Observer,Observable import Contrgcm import os class Login(FormLogin,Observable): """A login dialog. You should pass this object a observer which is notified on a succesfull login. """ def __init__(self,Qapplication,observer=None,parent=None,name=None,modal=1,fl=0): """@observer must be an Observer object from the Observers module. Or any other object with a 'notify' method. @Qapplication must be the QApplication. This is needed for the progressdialog. """ FormLogin.__init__(self,parent,name,modal,fl) Observable.__init__(self) # the observer is called after a succesfull login if observer: self.addObserver(observer) self.progress_dlg = ProgressDialog(self,Qapplication,"Log into Gmail",2) self.parent = parent self.keepsettings = 0 self.ga = None # Try to get the data from a rcfile result = Contrgcm.load_login() if result: self.lineEditLogin.setText(result[0]) self.lineEditPass.setText(result[1]) self.exec_loop() def pushButtonLogin_clicked(self): log = str(self.lineEditLogin.text()) pas = str(self.lineEditPass.text()) if not log or not pas: return self._do_login(log,pas) def _do_login(self,log,pas): self.progress_dlg.show() result = Contrgcm.login_gmail(log,pas) self.pushButtonCancel_clicked() self.progress_dlg.update() if result[0]: QMessageBox.critical(self, "Error", result[1], QMessageBox.Ok) else: self.notifyObservers(result[2]) self.ga = result[2] self.progress_dlg.update() if self.keepsettings: result = Contrgcm.store_login(log,pas) if result[0]: QMessageBox.critical(self, "Error", result[1], QMessageBox.Ok) self.done(1) def get_account_object(self): return self.ga def pushButtonCancel_clicked(self): self.done(1) def checkBoxPass_toggled(self,a0): self.keepsettings = a0 class ProgressDialog: def __init__(self,parent,Qapplication,label='',steps=1,modal=0,): """Wrapper class for a QProgressDialog. @Qapplication is the QApplication called at the start of any QT app.""" self.QPD = QProgressDialog(label,"Dismiss", steps, parent, "progress", modal) self.index = 1 self.parent = parent self.Qapplication = Qapplication def show(self): self.Qapplication.processEvents() self.QPD.show() def set_label(self,label): qlabel = QLabel(self.parent,label) self.QPD.setLabel(qlabel) def update(self): self.QPD.setProgress(self.index) self.Qapplication.processEvents() self.index += 1 --- NEW FILE: Qgcm.e3p --- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project SYSTEM "Project-3.5.dtd"> <!-- Project file for project Qgcm --> <!-- Saved: 2005-06-14, 16:56:57 --> <!-- Copyright (C) 2005 , --> <Project version="3.5"> <Description></Description> <Version>0.1</Version> <Author></Author> <Email></Email> <Sources> <Source> <Name>Qgcm.py</Name> </Source> <Source> <Name>MainWinContacts_forms.py</Name> </Source> <Source> <Name>Observers.py</Name> </Source> <Source> <Name>Contrgcm.py</Name> </Source> <Source> <Name>GuiQTgcm.py</Name> </Source> </Sources> <Forms> <Form> <Name>MainWinContacts.ui</Name> </Form> <Form> <Name>MainWinContacts.ui.h</Name> </Form> </Forms> <Translations> </Translations> <Interfaces> </Interfaces> <Others> </Others> <MainScript> <Name>Qgcm.py</Name> </MainScript> <Vcs> <VcsType>CVS</VcsType> <VcsOptions>{'status': [u'-v'], 'log': [], 'global': [u'-f'], 'update': [u'-dP'], 'remove': [u'-f'], 'add': [], 'tag': [u'-c'], 'export': [], 'diff': [u'-u3', u'-p'], 'commit': [], 'checkout': [], 'history': [u'-e', u'-a']}</VcsOptions> <VcsOtherData>{}</VcsOtherData> </Vcs> </Project> --- NEW FILE: LoginDialog.ui --- <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> <class>FormLogin</class> <widget class="QDialog"> <property name="name"> <cstring>FormLogin</cstring> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>332</width> <height>172</height> </rect> </property> <property name="caption"> <string>GmailAgent - Gmail login</string> </property> <property name="modal"> <bool>true</bool> </property> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonCancel</cstring> </property> <property name="geometry"> <rect> <x>30</x> <y>130</y> <width>100</width> <height>26</height> </rect> </property> <property name="text"> <string>Cancel</string> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonLogin</cstring> </property> <property name="geometry"> <rect> <x>190</x> <y>130</y> <width>100</width> <height>26</height> </rect> </property> <property name="text"> <string>Login</string> </property> </widget> <widget class="QGroupBox"> <property name="name"> <cstring>groupBox4</cstring> </property> <property name="geometry"> <rect> <x>20</x> <y>10</y> <width>290</width> <height>110</height> </rect> </property> <property name="title"> <string></string> </property> <widget class="QLabel"> <property name="name"> <cstring>textLabel6</cstring> </property> <property name="geometry"> <rect> <x>10</x> <y>20</y> <width>40</width> <height>20</height> </rect> </property> <property name="text"> <string>Login :</string> </property> </widget> <widget class="QLabel"> <property name="name"> <cstring>textLabel7</cstring> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>57</width> <height>20</height> </rect> </property> <property name="text"> <string>Password :</string> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditLogin</cstring> </property> <property name="geometry"> <rect> <x>70</x> <y>20</y> <width>200</width> <height>20</height> </rect> </property> </widget> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditPass</cstring> </property> <property name="geometry"> <rect> <x>70</x> <y>50</y> <width>200</width> <height>20</height> </rect> </property> <property name="echoMode"> <enum>Password</enum> </property> </widget> <widget class="QCheckBox"> <property name="name"> <cstring>checkBoxPass</cstring> </property> <property name="geometry"> <rect> <x>90</x> <y>80</y> <width>130</width> <height>20</height> </rect> </property> <property name="text"> <string>Remember password</string> </property> </widget> </widget> </widget> <connections> <connection> <sender>pushButtonLogin</sender> <signal>clicked()</signal> <receiver>FormLogin</receiver> <slot>pushButtonLogin_clicked()</slot> </connection> <connection> <sender>pushButtonCancel</sender> <signal>clicked()</signal> <receiver>FormLogin</receiver> <slot>pushButtonCancel_clicked()</slot> </connection> <connection> <sender>checkBoxPass</sender> <signal>toggled(bool)</signal> <receiver>FormLogin</receiver> <slot>checkBoxPass_toggled(bool)</slot> </connection> </connections> <includes> <include location="local" impldecl="in implementation">LoginDialog.ui.h</include> </includes> <slots> <slot>pushButtonLogin_clicked()</slot> <slot>pushButtonCancel_clicked()</slot> <slot>checkBoxPass_toggled( bool )</slot> </slots> <layoutdefaults spacing="6" margin="11"/> </UI> --- NEW FILE: LoginDialog_forms.py --- # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'LoginDialog.ui' # # Created: Wed Jun 15 14:36:49 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # # WARNING! All changes made in this file will be lost! from qt import * class FormLogin(QDialog): def __init__(self,parent = None,name = None,modal = 0,fl = 0): QDialog.__init__(self,parent,name,modal,fl) if not name: self.setName("FormLogin") self.setModal(1) self.pushButtonCancel = QPushButton(self,"pushButtonCancel") self.pushButtonCancel.setGeometry(QRect(30,130,100,26)) self.pushButtonLogin = QPushButton(self,"pushButtonLogin") self.pushButtonLogin.setGeometry(QRect(190,130,100,26)) self.groupBox4 = QGroupBox(self,"groupBox4") self.groupBox4.setGeometry(QRect(20,10,290,110)) self.textLabel6 = QLabel(self.groupBox4,"textLabel6") self.textLabel6.setGeometry(QRect(10,20,40,20)) self.textLabel7 = QLabel(self.groupBox4,"textLabel7") self.textLabel7.setGeometry(QRect(10,50,57,20)) self.lineEditLogin = QLineEdit(self.groupBox4,"lineEditLogin") self.lineEditLogin.setGeometry(QRect(70,20,200,20)) self.lineEditPass = QLineEdit(self.groupBox4,"lineEditPass") self.lineEditPass.setGeometry(QRect(70,50,200,20)) self.lineEditPass.setEchoMode(QLineEdit.Password) self.checkBoxPass = QCheckBox(self.groupBox4,"checkBoxPass") self.checkBoxPass.setGeometry(QRect(90,80,130,20)) self.languageChange() self.resize(QSize(332,172).expandedTo(self.minimumSizeHint())) self.clearWState(Qt.WState_Polished) self.connect(self.pushButtonLogin,SIGNAL("clicked()"),self.pushButtonLogin_clicked) self.connect(self.pushButtonCancel,SIGNAL("clicked()"),self.pushButtonCancel_clicked) self.connect(self.checkBoxPass,SIGNAL("toggled(bool)"),self.checkBoxPass_toggled) def languageChange(self): self.setCaption(self.__tr("GmailAgent - Gmail login")) self.pushButtonCancel.setText(self.__tr("Cancel")) self.pushButtonLogin.setText(self.__tr("Login")) self.groupBox4.setTitle(QString.null) self.textLabel6.setText(self.__tr("Login :")) self.textLabel7.setText(self.__tr("Password :")) self.checkBoxPass.setText(self.__tr("Remember password")) def pushButtonLogin_clicked(self): print "FormLogin.pushButtonLogin_clicked(): Not implemented yet" def pushButtonCancel_clicked(self): print "FormLogin.pushButtonCancel_clicked(): Not implemented yet" def checkBoxPass_toggled(self,a0): print "FormLogin.checkBoxPass_toggled(bool): Not implemented yet" def __tr(self,s,c = None): return qApp.translate("FormLogin",s,c) --- NEW FILE: LoginDialog.ui.h --- /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ void FormLogin::pushButtonLogin_clicked() { } void FormLogin::pushButtonCancel_clicked() { } void FormLogin::checkBoxPass_toggled( bool ) { } |
|
From: Stas Z. <sta...@us...> - 2005-06-15 14:48:48
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12120 Modified Files: Contrgcm.py GuiQTgcm.py MainWinContacts.ui MainWinContacts_forms.py Added Files: testContrgcm.py Log Message: More work on the contacts stuff Added a unittest Index: GuiQTgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/GuiQTgcm.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** GuiQTgcm.py 15 Jun 2005 11:14:01 -0000 1.3 --- GuiQTgcm.py 15 Jun 2005 14:48:39 -0000 1.4 *************** *** 26,30 **** from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable ! from QLogin import Login import Contrgcm --- 26,30 ---- from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable ! from QgcmDialogs import Login import Contrgcm *************** *** 37,40 **** --- 37,41 ---- self.ga = None self.show() + # test stuff self.Myobs = Observer(self.test) self.addObserver(self.Myobs) *************** *** 44,47 **** --- 45,56 ---- print "args",args + def closeEvent(self,ev): + """Called by QT when the user closes the window""" + ans = QMessageBox.information(self, + "Question", "Do you really want to quit?", + QMessageBox.Cancel,QMessageBox.Ok) + if ans == 1: + ev.accept() + def editNewcontact_activated(self): print "FormMainWin.editNewcontact_activated(): Not implemented yet" *************** *** 62,66 **** def pushButtonClose_clicked(self): ! print "FormMainWin.pushButtonClose_clicked(): Not implemented yet" def pushButtonCloseSave_clicked(self): --- 71,75 ---- def pushButtonClose_clicked(self): ! self.contactsExit_activated() def pushButtonCloseSave_clicked(self): *************** *** 92,98 **** self.Myobs = Observer(self._import_contacts_observerCB) # See _import_contacts_observerCB for an explanation why we use this ! Login(self.Myobs,self.Qapplication,self) else: contacts = Contrgcm.import_contacts_gmail(self.ga) def contactsSave_activated(self): --- 101,109 ---- self.Myobs = Observer(self._import_contacts_observerCB) # See _import_contacts_observerCB for an explanation why we use this ! Login(self.Qapplication,self.Myobs,parent=self) else: contacts = Contrgcm.import_contacts_gmail(self.ga) + self._load(contacts) + return 1 def contactsSave_activated(self): *************** *** 106,110 **** def contactsExit_activated(self): ! print "FormMainWin.contactsExit_activated(): Not implemented yet" ####### Internal used methods ################ --- 117,121 ---- def contactsExit_activated(self): ! self.close(1) ####### Internal used methods ################ *************** *** 114,124 **** This is used when there's no libgmail login object. The problem is that we first must get a valid Gmail login but ! that the Login dialog isn't blocking the program execution.""" ! print "_import_contacts_observerCB",caller,data self.ga = data[0] - print self.ga contacts = Contrgcm.import_contacts_gmail(self.ga) ! def _load( self, conlist): """Loads a contacts list into the widget.""" self.listViewContacts.clear() --- 125,135 ---- This is used when there's no libgmail login object. The problem is that we first must get a valid Gmail login but ! that the Login dialog isn't blocking the program execution. ! A QT Dialog can be made to block but it can return a useable value.""" self.ga = data[0] contacts = Contrgcm.import_contacts_gmail(self.ga) + self._load(contacts) ! def _load(self,conlist): """Loads a contacts list into the widget.""" self.listViewContacts.clear() *************** *** 134,141 **** except Exception,info: if GQ_DEBUG: ! logging.warning("Reading addressbook failed, %s" % str(info)) ! print info return - self.parent._load(addrfile)# fill the parents view try: self.progress_dlg.update() --- 145,150 ---- except Exception,info: if GQ_DEBUG: ! logging.warning("Setting contacts failed, %s" % str(info)) return try: self.progress_dlg.update() Index: MainWinContacts.ui =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts.ui,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MainWinContacts.ui 12 Jun 2005 06:17:01 -0000 1.1 --- MainWinContacts.ui 15 Jun 2005 14:48:39 -0000 1.2 *************** *** 16,19 **** --- 16,60 ---- <string>GCM - Gmail Contacts Manager</string> </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>pushButtonClose</cstring> + </property> + <property name="geometry"> + <rect> + <x>410</x> + <y>330</y> + <width>120</width> + <height>26</height> + </rect> + </property> + <property name="text"> + <string>Close</string> + </property> + <property name="toolTip" stdset="0"> + <string>Close without saving</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>pushButtonCloseSave</cstring> + </property> + <property name="geometry"> + <rect> + <x>40</x> + <y>330</y> + <width>120</width> + <height>26</height> + </rect> + </property> + <property name="text"> + <string>Close and Save</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Close and save your contacts</string> + </property> + </widget> <widget class="QListView"> <column> *************** *** 50,64 **** </property> </column> - <column> - <property name="text"> - <string>Gmail ID</string> - </property> - <property name="clickable"> - <bool>false</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> <item> <property name="text"> --- 91,94 ---- *************** *** 71,80 **** <string></string> </property> - <property name="text"> - <string></string> - </property> - <property name="pixmap"> - <pixmap></pixmap> - </property> <property name="pixmap"> <pixmap></pixmap> --- 101,104 ---- *************** *** 114,158 **** </property> </widget> - <widget class="QPushButton"> - <property name="name"> - <cstring>pushButtonClose</cstring> - </property> - <property name="geometry"> - <rect> - <x>410</x> - <y>330</y> - <width>120</width> - <height>26</height> - </rect> - </property> - <property name="text"> - <string>Close</string> - </property> - <property name="toolTip" stdset="0"> - <string>Close without saving</string> - </property> - </widget> - <widget class="QPushButton"> - <property name="name"> - <cstring>pushButtonCloseSave</cstring> - </property> - <property name="geometry"> - <rect> - <x>40</x> - <y>330</y> - <width>120</width> - <height>26</height> - </rect> - </property> - <property name="text"> - <string>Close and Save</string> - </property> - <property name="default"> - <bool>true</bool> - </property> - <property name="toolTip" stdset="0"> - <string>Close and save your contacts</string> - </property> - </widget> </widget> <menubar> --- 138,141 ---- --- NEW FILE: testContrgcm.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # testContrgcm.py # # 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 Library 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. import unittest,os import getpass import libgmail2 import Contrgcm class TestsContrgcmDB(unittest.TestCase): """ Set of tests that exercise the database portion of Contrgcm.py. """ def test1_cleanup_and_setup(self): """Delete all entries in the addressbook and add 5 new contacts. """ contacts = account.getContacts().getAllContacts() for contact in contacts: account.removeContact(contact) # add 5 contacts con1 = ('1','1@1','text1') con2 = ('2','2@2','text2') con3 = ('3','3@3','text3') con4 = ('4','4@4','text4') con5 = ('5','5@5','text5') conlist_org = [con1,con2,con3,con4,con5] for item in conlist_org: account.addContact(item[0],item[1],item[2]) conlist_gmail = account.getContacts().getAllContacts() self.assertEqual(len(conlist_org),len(conlist_gmail),\ "Number of contacts differ") def test2_setup_DB(self): """Create a new database""" filename = '/tmp/testdatabase' if os.path.exists(filename): os.remove(filename) DB = Contrgcm.DBase(filename) Contrgcm._DBase = DB self.assertEqual(os.path.exists(filename),1,"Failed to create database") def test3_store_contacts_DB(self): """Check if the Gmail contacts and the entries in the database are equal""" con1 = ('1','1@1','text1') con2 = ('2','2@2','text2') con3 = ('3','3@3','text3') con4 = ('4','4@4','text4') con5 = ('5','5@5','text5') conlist_org = [con1,con2,con3,con4,con5] conlist_gmail = Contrgcm.import_contacts_gmail(account) conlist_db = Contrgcm._DBase._get_all_values() len_db = len(conlist_db) len_gm = len(conlist_gmail) self.assertEqual(len_db,len_gm,\ "Number of contacts differ, db:%s ,gm:%s" % (len_db,len_gm)) def test4_check_keys_ids(self): """Check if the gmail id's and db keys equal""" keylist_gm = [] keylist_db = Contrgcm._DBase._get_all_keys() for item in account.getContacts().getAllContacts(): self.assertEqual(1, item.getId() in keylist_db,"Database keys and Gmail ids differ") def test5_compare_every_DBvalue(self): """Compare db entries and gmail contacts""" for item in account.getContacts().getAllContacts(): id = item.getId() db_con = Contrgcm._DBase._get_value(id) gm_con = (item.getName(),item.getEmail(),item.getNotes()) self.assertEqual(True,(db_con[0] == gm_con[0] and\ db_con[1] == gm_con[1] and\ db_con[2] == gm_con[2]) ,\ "DBase and contacts differ %s\n%s" % (db_con,gm_con)) if __name__ == '__main__': print "\n==============================================" print "Start 'Contrgcm database' testsuite" print "------------------------------------------------\n" print "WARNING: THIS WILL DELETE/REARRANGE" print " YOUR ADDRESSBOOK/EMAILS" print " BE SURE TO RUN THIS TEST ONLY ON A 'test' ACCOUNT" name = raw_input("Gmail account name:") pw = getpass.getpass("Password: ") account = libgmail2.GmailAccount(name, pw) try: account.login() print "Login successful.\n" except libgmail2.GmailLoginFailure,e: print "\nLogin failed. (%s)" % e.message else: suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestsContrgcmDB)) unittest.TextTestRunner(verbosity=2).run(suite) Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Contrgcm.py 15 Jun 2005 11:14:01 -0000 1.3 --- Contrgcm.py 15 Jun 2005 14:48:39 -0000 1.4 *************** *** 19,23 **** # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! CG_DEBUG = 1 import libgmail2,logging,os,shelve,urllib2,ConfigParser --- 19,23 ---- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! CG_DEBUG = 0 import libgmail2,logging,os,shelve,urllib2,ConfigParser *************** *** 97,101 **** if not contacts: return None ! def import_contacts_db(): """import_contacts_db --> contacts in a list of tuples or None. --- 97,108 ---- if not contacts: return None ! conlist = [] ! for obj in contacts: ! conitem = (obj.getName(),obj.getEmail(),obj.getNotes(),obj.getId()) ! conlist.append(conitem) ! _DBase._store_value(conitem[3],conitem) ! if CG_DEBUG: logging.debug("Database values %s" % _DBase._get_all_values()) ! return conlist ! def import_contacts_db(): """import_contacts_db --> contacts in a list of tuples or None. *************** *** 147,165 **** class DBase: ! def __init__(self): ! self.db_name = '.gcm_dbase' self.DB_dict = shelve.open(self.db_name) def _get_all_values(self): ! pass def _get_all_keys(self): ! pass ! def _store_value(self,key,*args): ! pass def _get_value(self,key): ! pass def _close(self): ! pass ! ! ###### Old stuff, perhaps we can use parts of it ########### def upload_local_contacts(addrfile,ga): --- 154,178 ---- class DBase: ! def __init__(self,name=''): ! """@name is only meant for the unittest suite""" ! if not name: ! self.db_name = os.path.expanduser('~/.gcm_database') ! else: ! self.db_name = name self.DB_dict = shelve.open(self.db_name) def _get_all_values(self): ! return self.DB_dict.values() def _get_all_keys(self): ! return self.DB_dict.keys() ! def _store_value(self,key,value): ! self.DB_dict[key] = value def _get_value(self,key): ! return self.DB_dict[key] def _close(self): ! self.DB_dict.close() ! ! _DBase = DBase() ! if CG_DEBUG: logging.debug("Shelve DB created %s" % _DBase) ! ###### Old stuff, perhaps we can use parts of it ########### def upload_local_contacts(addrfile,ga): Index: MainWinContacts_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts_forms.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MainWinContacts_forms.py 15 Jun 2005 11:14:01 -0000 1.2 --- MainWinContacts_forms.py 15 Jun 2005 14:48:39 -0000 1.3 *************** *** 3,7 **** # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Wed Jun 15 10:23:18 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Wed Jun 15 14:36:48 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # *************** *** 1288,1297 **** self.setCentralWidget(QWidget(self,"qt_central_widget")) self.listViewContacts = QListView(self.centralWidget(),"listViewContacts") self.listViewContacts.addColumn(self.__tr("Name")) self.listViewContacts.addColumn(self.__tr("Email address")) self.listViewContacts.addColumn(self.__tr("Notes")) - self.listViewContacts.addColumn(self.__tr("Gmail ID")) - self.listViewContacts.header().setClickEnabled(0,self.listViewContacts.header().count() - 1) self.listViewContacts.setGeometry(QRect(10,10,560,310)) self.listViewContacts.setFrameShape(QListView.StyledPanel) --- 1288,1302 ---- self.setCentralWidget(QWidget(self,"qt_central_widget")) + self.pushButtonClose = QPushButton(self.centralWidget(),"pushButtonClose") + self.pushButtonClose.setGeometry(QRect(410,330,120,26)) + + self.pushButtonCloseSave = QPushButton(self.centralWidget(),"pushButtonCloseSave") + self.pushButtonCloseSave.setGeometry(QRect(40,330,120,26)) + self.pushButtonCloseSave.setDefault(1) + self.listViewContacts = QListView(self.centralWidget(),"listViewContacts") self.listViewContacts.addColumn(self.__tr("Name")) self.listViewContacts.addColumn(self.__tr("Email address")) self.listViewContacts.addColumn(self.__tr("Notes")) self.listViewContacts.setGeometry(QRect(10,10,560,310)) self.listViewContacts.setFrameShape(QListView.StyledPanel) *************** *** 1301,1311 **** self.listViewContacts.setShowSortIndicator(1) - self.pushButtonClose = QPushButton(self.centralWidget(),"pushButtonClose") - self.pushButtonClose.setGeometry(QRect(410,330,120,26)) - - self.pushButtonCloseSave = QPushButton(self.centralWidget(),"pushButtonCloseSave") - self.pushButtonCloseSave.setGeometry(QRect(40,330,120,26)) - self.pushButtonCloseSave.setDefault(1) - self.fileNewAction = QAction(self,"fileNewAction") self.fileNewAction.setIconSet(QIconSet(self.image0)) --- 1306,1309 ---- *************** *** 1430,1444 **** def languageChange(self): self.setCaption(self.__tr("GCM - Gmail Contacts Manager")) self.listViewContacts.header().setLabel(0,self.__tr("Name")) self.listViewContacts.header().setLabel(1,self.__tr("Email address")) self.listViewContacts.header().setLabel(2,self.__tr("Notes")) - self.listViewContacts.header().setLabel(3,self.__tr("Gmail ID")) self.listViewContacts.clear() item = QListViewItem(self.listViewContacts,None) - self.pushButtonClose.setText(self.__tr("Close")) - QToolTip.add(self.pushButtonClose,self.__tr("Close without saving")) - self.pushButtonCloseSave.setText(self.__tr("Close and Save")) - QToolTip.add(self.pushButtonCloseSave,self.__tr("Close and save your contacts")) self.fileNewAction.setText(self.__tr("New")) self.fileNewAction.setMenuText(self.__tr("&New")) --- 1428,1441 ---- def languageChange(self): self.setCaption(self.__tr("GCM - Gmail Contacts Manager")) + self.pushButtonClose.setText(self.__tr("Close")) + QToolTip.add(self.pushButtonClose,self.__tr("Close without saving")) + self.pushButtonCloseSave.setText(self.__tr("Close and Save")) + QToolTip.add(self.pushButtonCloseSave,self.__tr("Close and save your contacts")) self.listViewContacts.header().setLabel(0,self.__tr("Name")) self.listViewContacts.header().setLabel(1,self.__tr("Email address")) self.listViewContacts.header().setLabel(2,self.__tr("Notes")) self.listViewContacts.clear() item = QListViewItem(self.listViewContacts,None) self.fileNewAction.setText(self.__tr("New")) self.fileNewAction.setMenuText(self.__tr("&New")) |
|
From: Stas Z. <sta...@us...> - 2005-06-15 11:14:13
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25516/frontend Modified Files: Contrgcm.py GuiQTgcm.py MainWinContacts_forms.py Makefile Log Message: Fixed contacts eror. It seems Gmail has changed the contacts page so when one tries to extract the contacts it will throw a exception about a missing dict key called 'a' It seems the key to get is now 'cl' Index: GuiQTgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/GuiQTgcm.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** GuiQTgcm.py 14 Jun 2005 14:39:00 -0000 1.2 --- GuiQTgcm.py 15 Jun 2005 11:14:01 -0000 1.3 *************** *** 19,22 **** --- 19,24 ---- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + GQ_DEBUG = 1 + import logging from qt import * *************** *** 24,34 **** from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable class MainWin(FormMainWin,Observable): def __init__(self, parent=None, name=None, fl=0,att=[],application=None): FormMainWin.__init__(self,parent,name,fl) Observable.__init__(self) ! global Qapplication# Needed for a Qprogressdialog ! Qapplication = application self.show() self.Myobs = Observer(self.test) --- 26,39 ---- from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable + from QLogin import Login + import Contrgcm class MainWin(FormMainWin,Observable): def __init__(self, parent=None, name=None, fl=0,att=[],application=None): + logging.debug("MainWin constructor called") FormMainWin.__init__(self,parent,name,fl) Observable.__init__(self) ! self.Qapplication = application # Needed for a Qprogressdialog ! self.ga = None self.show() self.Myobs = Observer(self.test) *************** *** 81,85 **** def contactsImportcontacts_activated(self): ! print "FormMainWin.contactsImportcontacts_activated(): Not implemented yet" def contactsSave_activated(self): --- 86,98 ---- def contactsImportcontacts_activated(self): ! if GQ_DEBUG: logging.debug("FormMainWin.contactsImportcontacts_activated()") ! if not self.ga: ! # keep a reference to the observer to prevent the Python Garbage ! # collector from removing it. ! self.Myobs = Observer(self._import_contacts_observerCB) ! # See _import_contacts_observerCB for an explanation why we use this ! Login(self.Myobs,self.Qapplication,self) ! else: ! contacts = Contrgcm.import_contacts_gmail(self.ga) def contactsSave_activated(self): *************** *** 94,96 **** --- 107,145 ---- def contactsExit_activated(self): print "FormMainWin.contactsExit_activated(): Not implemented yet" + + ####### Internal used methods ################ + def _import_contacts_observerCB(self,caller,data): + """Called by the observer from the Login object. + This is used when there's no libgmail login object. + The problem is that we first must get a valid Gmail login but + that the Login dialog isn't blocking the program execution.""" + print "_import_contacts_observerCB",caller,data + self.ga = data[0] + print self.ga + contacts = Contrgcm.import_contacts_gmail(self.ga) + + def _load( self, conlist): + """Loads a contacts list into the widget.""" + self.listViewContacts.clear() + nameshash = {}# used as a lookup hash by the search object + for line in conlist: + item = QListViewItem(self.listViewContacts) + try: + nameshash[line[0]] = item + item.setText(0,line[0]) + item.setText(1,line[1]) + item.setText(2,line[2][:60]) + item.setText(3,line[3]) + except Exception,info: + if GQ_DEBUG: + logging.warning("Reading addressbook failed, %s" % str(info)) + print info + return + self.parent._load(addrfile)# fill the parents view + try: + self.progress_dlg.update() + except: + pass + + Index: Makefile =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Makefile 12 Jun 2005 06:17:01 -0000 1.1 --- Makefile 15 Jun 2005 11:14:02 -0000 1.2 *************** *** 2,4 **** --- 2,5 ---- all: pyuic MainWinContacts.ui -o MainWinContacts_forms.py + pyuic LoginDialog.ui -o LoginDialog_forms.py \ No newline at end of file Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Contrgcm.py 14 Jun 2005 18:58:55 -0000 1.2 --- Contrgcm.py 15 Jun 2005 11:14:01 -0000 1.3 *************** *** 20,34 **** CG_DEBUG = 1 ! import libgmail2,logging,os,shelve def import_contacts_gmail(ga): ! """import_contacts_gmail --> contacts in a list of tuples. Import contacts from a gmail account and store them in a local database. When the db exist it will be updated else it will be created. @ga is a libgmail GmailAccount object. """ ! pass def import_contacts_db(): ! """import_contacts_db --> contacts in a list of tuples. Import contacts from the local database and return them in a list of tuples.""" --- 20,103 ---- CG_DEBUG = 1 ! import libgmail2,logging,os,shelve,urllib2,ConfigParser ! ! try: ! logging.basicConfig(level=logging.DEBUG,\ ! format='%(levelname)s,%(module)s:LineNo %(lineno)d:%(message)s') ! except TypeError: ! # Python <=2.3? ! pass ! ! if CG_DEBUG: logging.debug("Starting") ! ! def load_login(): ! """load_login --> The tuple logname,password or None. ! Loads the login data from a dot file in the users home directory. ! The name of the rc file is always '.gmailagent'. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_login") ! configdict = ConfigParser.ConfigParser() ! rcfile = os.path.expanduser('~/.gmailagent') ! try: ! configdict.readfp(open(rcfile)) ! name,pas = configdict.get('Login','name'), configdict.get('Login','pas') ! except: ! if CG_DEBUG: logging.warning("Failed to load the password from %s" % rcfile) ! return None ! return (name,pas) ! ! def store_login(name,pas): ! """store_login --> True on succes, False on faillure. ! Stores the login data in a dot file in the users home directory. ! The name of the rc file is always '.gmail'. ! @name is the Gmail account name. ! @pas is the password. ! """ ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: store_login") ! rcfile = os.path.expanduser('~/.gmailagent') ! configdict = ConfigParser.ConfigParser() ! configdict.add_section('Login') ! configdict.set('Login','name',name) ! configdict.set('Login','pas',pas) ! try: ! f = open(rcfile,'w') ! configdict.write(f) ! except: ! f.close() ! if GM_DEBUG: logging.warning("Failed to store the password in %s" % rcfile) ! return False ! f.close() ! return True ! ! def login_gmail(name,pas): ! """login_gmail --> a tuple of '0 or 1','message',libgmail login object or None. ! The first value of the returnt tuple indicates faillure (0) or succes (1). ! @name is the Gmail account name. ! @pas is the password for the account. ! """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: login_gmail") ! ga = libgmail2.GmailAccount(name,pas) ! try: ! ga.login() ! except (libgmail2.GmailLoginFailure,urllib2.HTTPError),info: ! if CG_DEBUG: logging.warning("%s" % info) ! return (1,"%s" % info,None) ! else: ! return (0,"Log in successful.",ga) def import_contacts_gmail(ga): ! """import_contacts_gmail --> contacts in a list of tuples or None. Import contacts from a gmail account and store them in a local database. When the db exist it will be updated else it will be created. @ga is a libgmail GmailAccount object. """ ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") ! contacts = ga.getContacts().getAllContacts() ! if CG_DEBUG: logging.debug("Contacts imported:\n%s" % contacts) ! if not contacts: ! return None ! def import_contacts_db(): ! """import_contacts_db --> contacts in a list of tuples or None. Import contacts from the local database and return them in a list of tuples.""" Index: MainWinContacts_forms.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/MainWinContacts_forms.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MainWinContacts_forms.py 12 Jun 2005 06:17:01 -0000 1.1 --- MainWinContacts_forms.py 15 Jun 2005 11:14:01 -0000 1.2 *************** *** 3,7 **** # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Sat Jun 11 11:39:15 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # --- 3,7 ---- # Form implementation generated from reading ui file 'MainWinContacts.ui' # ! # Created: Wed Jun 15 10:23:18 2005 # by: The PyQt User Interface Compiler (pyuic) 3.14.1 # |
|
From: Stas Z. <sta...@us...> - 2005-06-15 11:14:13
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25516 Modified Files: libgmail2.py Log Message: Fixed contacts eror. It seems Gmail has changed the contacts page so when one tries to extract the contacts it will throw a exception about a missing dict key called 'a' It seems the key to get is now 'cl' Index: libgmail2.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/libgmail2.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libgmail2.py 2 Jun 2005 13:14:48 -0000 1.3 --- libgmail2.py 15 Jun 2005 11:14:01 -0000 1.4 *************** *** 774,783 **** # This comes back with a dictionary # with entry 'a' ! addresses = myData['a'] extractEntries(addresses) ! ! #print "rawPage", self._retrievePage(myUrl) ! #print "\n\n" ! #print "myData", myData #print "mydata[a]", myData['a'] #print "cl", contactList --- 774,782 ---- # This comes back with a dictionary # with entry 'a' ! addresses = myData['cl'] extractEntries(addresses) ! ## print "rawPage", self._retrievePage(myUrl) ! ## print "\n\n" ! ## print "myData", myData #print "mydata[a]", myData['a'] #print "cl", contactList |
|
From: Stas Z. <sta...@us...> - 2005-06-14 18:59:04
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8918 Modified Files: Contrgcm.py Log Message: Added templates for the new contacts framework Index: Contrgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Contrgcm.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Contrgcm.py 14 Jun 2005 14:29:39 -0000 1.1 --- Contrgcm.py 14 Jun 2005 18:58:55 -0000 1.2 *************** *** 20,26 **** CG_DEBUG = 1 ! import libgmail2,logging,os def upload_local_contacts(addrfile,ga): """Returns the contacts from the local file which don't have a ID entry. --- 20,97 ---- CG_DEBUG = 1 ! import libgmail2,logging,os,shelve + def import_contacts_gmail(ga): + """import_contacts_gmail --> contacts in a list of tuples. + Import contacts from a gmail account and store them in a local + database. When the db exist it will be updated else it will be created. + @ga is a libgmail GmailAccount object. + """ + pass + def import_contacts_db(): + """import_contacts_db --> contacts in a list of tuples. + Import contacts from the local database and return them in a + list of tuples.""" + pass + def store_contacts_gmail(contacts,ga): + """store_contacts_gmail --> True on succes, False on faillure. + Stores the contacts in a Gmail account. + @contacts is a list of tuples containing the contacts. The format must be + the same as returnt by import_contacts_db. + @ga is a libgmail GmailAccount. + """ + pass + def store_contacts_db(contacts): + """store_contacts_db --> True on succes, False on faillure. + Stores the contacts in the local database. + @contacts is a list of tuples containing the contacts. The format must be + the same as returnt by import_contacts_db. + """ + pass + def store_contact_gmail(contact,ga): + """store_contact_db --> True on succes, False on faillure + Stores the contact in a Gmail account. + @contact is a tuple containing the contact. + """ + pass + def remove_contacts_gmail(ga): + """remove_contacts_gmail --> True on succes, False on faillure. + Remove all contacts from a Gmail account. + This should be used with care, the removal is final. + The contacts removed are stored in the local database and can be restored + by calling restore_contacts. + @ga is a libgmail GmailAccount. + """ + pass + def remove_contacts_db(): + """remove_contacts_db --> True on succes, False on faillure. + Remove all contacts from the local database. + The database can be restored by calling import_contacts_gmail. + """ + pass + def export_contacts(file): + """export_contacts --> True on succes, False on faillure. + Export contacts into the VCard format to a file. + @file must be a valid path writable by the user. + """ + pass + class DBase: + def __init__(self): + self.db_name = '.gcm_dbase' + self.DB_dict = shelve.open(self.db_name) + def _get_all_values(self): + pass + def _get_all_keys(self): + pass + def _store_value(self,key,*args): + pass + def _get_value(self,key): + pass + def _close(self): + pass + + + ###### Old stuff, perhaps we can use parts of it ########### def upload_local_contacts(addrfile,ga): """Returns the contacts from the local file which don't have a ID entry. |
|
From: Stas Z. <sta...@us...> - 2005-06-14 14:39:27
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3009 Modified Files: GuiQTgcm.py Qgcm.py Log Message: Restore some errors Index: Qgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Qgcm.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Qgcm.py 14 Jun 2005 14:22:19 -0000 1.1 --- Qgcm.py 14 Jun 2005 14:39:01 -0000 1.2 *************** *** 20,28 **** import sys from qt import * ! import GuiQTgmc app = QApplication(sys.argv) ! w = GuiQTgmc.MainWin(application=app) app.setMainWidget(w) w.show() --- 20,28 ---- import sys from qt import * ! import GuiQTgcm app = QApplication(sys.argv) ! w = GuiQTgcm.MainWin(application=app) app.setMainWidget(w) w.show() Index: GuiQTgcm.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/GuiQTgcm.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** GuiQTgcm.py 14 Jun 2005 14:22:19 -0000 1.1 --- GuiQTgcm.py 14 Jun 2005 14:39:00 -0000 1.2 *************** *** 3,7 **** # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # ! # Contrgmc.py # # This program is free software; you can redistribute it and/or modify --- 3,7 ---- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # ! # GuiQTgmc.py # # This program is free software; you can redistribute it and/or modify *************** *** 20,197 **** ! CG_DEBUG = 1 ! import libgmail2,pickle ! def upload_local_contacts(addrfile,ga): ! """Returns the contacts from the local file which don't have a ID entry. ! Contacts without an ID are considered local only and must be added to the Gmail ! contacts list. ! This function is called whenever the user logs into Gmail. ! Returns error message on faillure, None on succes.""" ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") ! contacts = load_addressfile(addrfile) ! for line in contacts: ! if CG_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) ! if not line[3]: ! logging.debug("Adding %s %s %s %s to Gmail" % line) ! if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception ! return ("Unable to add contact %s %s %s %s" % line) ! # Now we reload the contacts to create a new local contacts list ! #import_contacts(addrfile,ga) ! ! def store_address(addrfile,name,addr,notes='',id='',ga=None): ! """The contacts will be stored in the local copy on disk. ! If the id is given we assume the contact has a valid Gmail id and ! the contact is removed from the online contacts and replaced by the ! given contact. It will get a new id from Gmail. ! """ ! if CG_DEBUG: ! logging.debug("\n>>>>>>>> Function: store_address") ! logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) ! if id and ga: ! if CG_DEBUG: logging.debug("Found id, removing original contact first") ! contacts = ga.getContacts() ! contact = contacts.getContactById(id) ! if contact: ! if not ga.removeContact(contact): ! logging.warning("Failed to remove contact %s" % contact) ! else: ! # Build the new local file with the contacts from Gmail ! import_contacts(addrfile,ga) ! # now we add the new contact to the local file ! store_address(addrfile,name,addr,notes) ! # And upload it to Gmail ! upload_local_contacts(addrfile,ga) ! # Retrieve Gmail contacts so that we have get an id for the new contact. ! import_contacts(addrfile,ga) ! # stuff is stored in a file like this: ! # name&&addr&¬es&&id ! # Contacts that are not (yet) in the Gmail contacts list have an empty ! # string as id. ! # After syncronizing the file with the contacts the id fields will be asigned. ! try: ! f = open(addrfile,'r') ! lines = f.readlines() ! f.close() ! except IOError,info: ! mesg = "Failed to check the address (IO), %s" % info ! if CG_DEBUG: logging.warning(mesg) ! return mesg ! else: ! for line in lines: ! if name in line and addr in line: ! return ! # It's a new entry ! line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) ! if CG_DEBUG: logging.debug("Found new contact %s" % line) ! try: ! f = open(addrfile,'a') ! f.write(line) ! f.close() ! except IOError,info: ! f.close() ! mesg = "Failed to store address, %s" % info ! if CG_DEBUG: logging.warning(mesg) ! return mesg ! ! def load_addressfile(filename): ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") ! try: ! f = open(filename,'r') ! lines = f.readlines() ! f.close() ! except IOError,info: ! if CG_DEBUG: logging.warning(str(info)) ! return ! if CG_DEBUG: logging.debug(str(lines)) ! newlines = [] ! for line in lines: ! newlines.append(tuple(line[:-1].split("&&"))) ! return (newlines) ! def import_contacts(addrfile,ga): ! """This gets the gmail contacts create a new local contacts list on disk.""" ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") ! upload_local_contacts(addrfile,ga) ! contacts = ga.getContacts().getAllContacts() ! logging.debug("Contacts imported:\n%s" % contacts) ! if contacts: ! # remove local file, we can remove it because the upload_local_contacts method will make sure ! # that the contacts are syncronized. ! logging.debug("Removing local file") ! open(addrfile,'w').close() ! else: ! return ! for obj in contacts: ! store_address(addrfile,\ ! obj.getName(),\ ! obj.getEmail(),\ ! obj.getNotes(),\ ! obj.getId()) ! return load_addressfile(addrfile) ! def export_contacts(addrfile,ga): ! """This will remove the contacts at the online contacts list and replace ! it with the local copy fom disk. ! It will return a message on any error. ! It returns None on succes.""" ! if CG_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") ! entries = load_addressfile(addrfile) ! if len(entries) < 1: ! text = "Failed to load address file, %s" % addrfile ! if CG_DEBUG: logging.critical(text) ! return text ! try: ! contacts = ga.getContacts().getAllContacts() ! # Just to test save_contacts ! save_contacts(contacts) ! for contact in contacts: ! if CG_DEBUG: logging.debug("Removing contact %s", contact) ! ga.removeContact(contact) ! except Exception,info: ! logging.critical(str(info)) ! if contacts: ! save_contacts(contacts) ! return "An error occured, tried to save your contacts to\n%s and %s" %\ ! ('~/.GmailContacts.txt','~/.GmailContacts.pickle') ! # Now we fill the contacts list again from the local file. ! try: ! for entry in entries: ! if CG_DEBUG: logging.debug("Adding contact %s", entry) ! apply(ga.addContact,entry[:-1]) ! except Exception,info: ! logging.critical(str(info)) ! save_contacts(contacts) - def save_contacts(contacts): - # This is probably not needed anymore, if shelve turn out OK - """Save the contact in case of an error. This is an attempt to prevent - data loss in case of an error when interacting with Gmail contacts.""" - if CG_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") - try: - f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') - pickle.dump(contacts,f) - ## XXX TODO: some way to load the pickled object and restore it - except Exception,info: - text = "Attempt to pickle the contacts %s" % str(info) - logging.critical(text) - f.close() - try: - f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') - text = "#An error occured in GmailAgent and these contacts are saved\n"+\ - "#to this file in an attempt to save them\n"+\ - "#A contact is saved as follows:\n"+\ - "#GmailID Name email notes\n" - f.write(text) - for con in contacts: - name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() - f.write("%s %s %s %s\n" % (con.getId(),\ - con.getName(),\ - con.getEmail(),\ - con.getNotes())) - f.close() - except Exception,info: - logging.critical(str(info)) - return str(info) - --- 20,96 ---- ! from qt import * ! from MainWinContacts_forms import FormMainWin ! from Observers import Observer,Observable ! ! class MainWin(FormMainWin,Observable): ! def __init__(self, parent=None, name=None, fl=0,att=[],application=None): ! FormMainWin.__init__(self,parent,name,fl) ! Observable.__init__(self) ! global Qapplication# Needed for a Qprogressdialog ! Qapplication = application ! self.show() ! self.Myobs = Observer(self.test) ! self.addObserver(self.Myobs) ! def test(self,*args): ! print "test called" ! print "args",args ! ! def editNewcontact_activated(self): ! print "FormMainWin.editNewcontact_activated(): Not implemented yet" ! def editEditcontact_activated(self): ! print "FormMainWin.editEditcontact_activated(): Not implemented yet" ! def editDeletecontact_activated(self): ! print "FormMainWin.editDeletecontact_activated(): Not implemented yet" ! ! def helpContents_activated(self): ! print "FormMainWin.helpContents_activated(): Not implemented yet" ! #This callback is used for testing purposes ! self.notifyObservers("this is data") ! ! def helpAbout_activated(self): ! print "FormMainWin.helpAbout_activated(): Not implemented yet" ! ! def pushButtonClose_clicked(self): ! print "FormMainWin.pushButtonClose_clicked(): Not implemented yet" ! ! def pushButtonCloseSave_clicked(self): ! print "FormMainWin.pushButtonCloseSave_clicked(): Not implemented yet" ! ! def listViewContacts_clicked(self,a0): ! print "FormMainWin.listViewContacts_clicked(QListViewItem*): Not implemented yet" ! ! def listViewContacts_doubleClicked(self,a0): ! print "FormMainWin.listViewContacts_doubleClicked(QListViewItem*): Not implemented yet" ! ! def contactsExportcontacts_activated(self): ! print "FormMainWin.contactsExportcontacts_activated(): Not implemented yet" ! ! def listViewContacts_pressed(self,a0): ! print "FormMainWin.listViewContacts_pressed(QListViewItem*): Not implemented yet" ! ! def listViewContacts_clicked(self,a0,a1,a2): ! print "FormMainWin.listViewContacts_clicked(QListViewItem*,const QPoint&,int): Not implemented yet" ! ! def lineEditSearchToolbar_textChanged(self,a0): ! print "FormMainWin.lineEditSearchToolbar_textChanged(const QString&): Not implemented yet" ! ! def contactsImportcontacts_activated(self): ! print "FormMainWin.contactsImportcontacts_activated(): Not implemented yet" ! ! def contactsSave_activated(self): ! print "FormMainWin.contactsSave_activated(): Not implemented yet" ! ! def contactsSaveAs_activated(self): ! print "FormMainWin.contactsSaveAs_activated(): Not implemented yet" ! ! def contactsPrintAction_activated(self): ! print "FormMainWin.contactsPrintAction_activated(): Not implemented yet" ! ! def contactsExit_activated(self): ! print "FormMainWin.contactsExit_activated(): Not implemented yet" |
|
From: Stas Z. <sta...@us...> - 2005-06-14 14:29:56
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30582 Added Files: Contrgcm.py Log Message: Added control as in MVC --- NEW FILE: Contrgcm.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # Contrgcm.py # # 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 Library 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. CG_DEBUG = 1 import libgmail2,logging,os def upload_local_contacts(addrfile,ga): """Returns the contacts from the local file which don't have a ID entry. Contacts without an ID are considered local only and must be added to the Gmail contacts list. This function is called whenever the user logs into Gmail. Returns error message on faillure, None on succes.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") contacts = load_addressfile(addrfile) for line in contacts: if CG_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) if not line[3]: logging.debug("Adding %s %s %s %s to Gmail" % line) if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception return ("Unable to add contact %s %s %s %s" % line) # Now we reload the contacts to create a new local contacts list #import_contacts(addrfile,ga) def store_address(addrfile,name,addr,notes='',id='',ga=None): """The contacts will be stored in the local copy on disk. If the id is given we assume the contact has a valid Gmail id and the contact is removed from the online contacts and replaced by the given contact. It will get a new id from Gmail. """ if CG_DEBUG: logging.debug("\n>>>>>>>> Function: store_address") logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) if id and ga: if CG_DEBUG: logging.debug("Found id, removing original contact first") contacts = ga.getContacts() contact = contacts.getContactById(id) if contact: if not ga.removeContact(contact): logging.warning("Failed to remove contact %s" % contact) else: # Build the new local file with the contacts from Gmail import_contacts(addrfile,ga) # now we add the new contact to the local file store_address(addrfile,name,addr,notes) # And upload it to Gmail upload_local_contacts(addrfile,ga) # Retrieve Gmail contacts so that we have get an id for the new contact. import_contacts(addrfile,ga) # stuff is stored in a file like this: # name&&addr&¬es&&id # Contacts that are not (yet) in the Gmail contacts list have an empty # string as id. # After syncronizing the file with the contacts the id fields will be asigned. try: f = open(addrfile,'r') lines = f.readlines() f.close() except IOError,info: mesg = "Failed to check the address (IO), %s" % info if CG_DEBUG: logging.warning(mesg) return mesg else: for line in lines: if name in line and addr in line: return # It's a new entry line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) if CG_DEBUG: logging.debug("Found new contact %s" % line) try: f = open(addrfile,'a') f.write(line) f.close() except IOError,info: f.close() mesg = "Failed to store address, %s" % info if CG_DEBUG: logging.warning(mesg) return mesg def load_addressfile(filename): if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") try: f = open(filename,'r') lines = f.readlines() f.close() except IOError,info: if CG_DEBUG: logging.warning(str(info)) return if CG_DEBUG: logging.debug(str(lines)) newlines = [] for line in lines: newlines.append(tuple(line[:-1].split("&&"))) return (newlines) def import_contacts(addrfile,ga): """This gets the gmail contacts create a new local contacts list on disk.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") upload_local_contacts(addrfile,ga) contacts = ga.getContacts().getAllContacts() logging.debug("Contacts imported:\n%s" % contacts) if contacts: # remove local file, we can remove it because the upload_local_contacts method will make sure # that the contacts are syncronized. logging.debug("Removing local file") open(addrfile,'w').close() else: return for obj in contacts: store_address(addrfile,\ obj.getName(),\ obj.getEmail(),\ obj.getNotes(),\ obj.getId()) return load_addressfile(addrfile) def export_contacts(addrfile,ga): """This will remove the contacts at the online contacts list and replace it with the local copy fom disk. It will return a message on any error. It returns None on succes.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") entries = load_addressfile(addrfile) if len(entries) < 1: text = "Failed to load address file, %s" % addrfile if CG_DEBUG: logging.critical(text) return text try: contacts = ga.getContacts().getAllContacts() # Just to test save_contacts save_contacts(contacts) for contact in contacts: if CG_DEBUG: logging.debug("Removing contact %s", contact) ga.removeContact(contact) except Exception,info: logging.critical(str(info)) if contacts: save_contacts(contacts) return "An error occured, tried to save your contacts to\n%s and %s" %\ ('~/.GmailContacts.txt','~/.GmailContacts.pickle') # Now we fill the contacts list again from the local file. try: for entry in entries: if CG_DEBUG: logging.debug("Adding contact %s", entry) apply(ga.addContact,entry[:-1]) except Exception,info: logging.critical(str(info)) save_contacts(contacts) def save_contacts(contacts): """Save the contact in case of an error. This is an attempt to prevent data loss in case of an error when interacting with Gmail contacts.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") try: f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') pickle.dump(contacts,f) ## XXX TODO: some way to load the pickled object and restore it except Exception,info: text = "Attempt to pickle the contacts %s" % str(info) logging.critical(text) f.close() try: f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') text = "#An error occured in GmailAgent and these contacts are saved\n"+\ "#to this file in an attempt to save them\n"+\ "#A contact is saved as follows:\n"+\ "#GmailID Name email notes\n" f.write(text) for con in contacts: name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() f.write("%s %s %s %s\n" % (con.getId(),\ con.getName(),\ con.getEmail(),\ con.getNotes())) f.close() except Exception,info: logging.critical(str(info)) return str(info) |
|
From: Stas Z. <sta...@us...> - 2005-06-14 14:22:30
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26544 Modified Files: Observers.py Added Files: GuiQTgcm.py Qgcm.py Removed Files: GuiQTgmc.py Qgmc.py Log Message: renamed files --- Qgmc.py DELETED --- --- NEW FILE: Qgcm.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # Qgmc.py # # 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 Library 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. import sys from qt import * import GuiQTgmc app = QApplication(sys.argv) w = GuiQTgmc.MainWin(application=app) app.setMainWidget(w) w.show() app.exec_loop() --- NEW FILE: GuiQTgcm.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # Contrgmc.py # # 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 Library 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. CG_DEBUG = 1 import libgmail2,pickle def upload_local_contacts(addrfile,ga): """Returns the contacts from the local file which don't have a ID entry. Contacts without an ID are considered local only and must be added to the Gmail contacts list. This function is called whenever the user logs into Gmail. Returns error message on faillure, None on succes.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") contacts = load_addressfile(addrfile) for line in contacts: if CG_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) if not line[3]: logging.debug("Adding %s %s %s %s to Gmail" % line) if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception return ("Unable to add contact %s %s %s %s" % line) # Now we reload the contacts to create a new local contacts list #import_contacts(addrfile,ga) def store_address(addrfile,name,addr,notes='',id='',ga=None): """The contacts will be stored in the local copy on disk. If the id is given we assume the contact has a valid Gmail id and the contact is removed from the online contacts and replaced by the given contact. It will get a new id from Gmail. """ if CG_DEBUG: logging.debug("\n>>>>>>>> Function: store_address") logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) if id and ga: if CG_DEBUG: logging.debug("Found id, removing original contact first") contacts = ga.getContacts() contact = contacts.getContactById(id) if contact: if not ga.removeContact(contact): logging.warning("Failed to remove contact %s" % contact) else: # Build the new local file with the contacts from Gmail import_contacts(addrfile,ga) # now we add the new contact to the local file store_address(addrfile,name,addr,notes) # And upload it to Gmail upload_local_contacts(addrfile,ga) # Retrieve Gmail contacts so that we have get an id for the new contact. import_contacts(addrfile,ga) # stuff is stored in a file like this: # name&&addr&¬es&&id # Contacts that are not (yet) in the Gmail contacts list have an empty # string as id. # After syncronizing the file with the contacts the id fields will be asigned. try: f = open(addrfile,'r') lines = f.readlines() f.close() except IOError,info: mesg = "Failed to check the address (IO), %s" % info if CG_DEBUG: logging.warning(mesg) return mesg else: for line in lines: if name in line and addr in line: return # It's a new entry line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) if CG_DEBUG: logging.debug("Found new contact %s" % line) try: f = open(addrfile,'a') f.write(line) f.close() except IOError,info: f.close() mesg = "Failed to store address, %s" % info if CG_DEBUG: logging.warning(mesg) return mesg def load_addressfile(filename): if CG_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") try: f = open(filename,'r') lines = f.readlines() f.close() except IOError,info: if CG_DEBUG: logging.warning(str(info)) return if CG_DEBUG: logging.debug(str(lines)) newlines = [] for line in lines: newlines.append(tuple(line[:-1].split("&&"))) return (newlines) def import_contacts(addrfile,ga): """This gets the gmail contacts create a new local contacts list on disk.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") upload_local_contacts(addrfile,ga) contacts = ga.getContacts().getAllContacts() logging.debug("Contacts imported:\n%s" % contacts) if contacts: # remove local file, we can remove it because the upload_local_contacts method will make sure # that the contacts are syncronized. logging.debug("Removing local file") open(addrfile,'w').close() else: return for obj in contacts: store_address(addrfile,\ obj.getName(),\ obj.getEmail(),\ obj.getNotes(),\ obj.getId()) return load_addressfile(addrfile) def export_contacts(addrfile,ga): """This will remove the contacts at the online contacts list and replace it with the local copy fom disk. It will return a message on any error. It returns None on succes.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") entries = load_addressfile(addrfile) if len(entries) < 1: text = "Failed to load address file, %s" % addrfile if CG_DEBUG: logging.critical(text) return text try: contacts = ga.getContacts().getAllContacts() # Just to test save_contacts save_contacts(contacts) for contact in contacts: if CG_DEBUG: logging.debug("Removing contact %s", contact) ga.removeContact(contact) except Exception,info: logging.critical(str(info)) if contacts: save_contacts(contacts) return "An error occured, tried to save your contacts to\n%s and %s" %\ ('~/.GmailContacts.txt','~/.GmailContacts.pickle') # Now we fill the contacts list again from the local file. try: for entry in entries: if CG_DEBUG: logging.debug("Adding contact %s", entry) apply(ga.addContact,entry[:-1]) except Exception,info: logging.critical(str(info)) save_contacts(contacts) def save_contacts(contacts): # This is probably not needed anymore, if shelve turn out OK """Save the contact in case of an error. This is an attempt to prevent data loss in case of an error when interacting with Gmail contacts.""" if CG_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") try: f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') pickle.dump(contacts,f) ## XXX TODO: some way to load the pickled object and restore it except Exception,info: text = "Attempt to pickle the contacts %s" % str(info) logging.critical(text) f.close() try: f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') text = "#An error occured in GmailAgent and these contacts are saved\n"+\ "#to this file in an attempt to save them\n"+\ "#A contact is saved as follows:\n"+\ "#GmailID Name email notes\n" f.write(text) for con in contacts: name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() f.write("%s %s %s %s\n" % (con.getId(),\ con.getName(),\ con.getEmail(),\ con.getNotes())) f.close() except Exception,info: logging.critical(str(info)) return str(info) Index: Observers.py =================================================================== RCS file: /cvsroot/gmailagent/GA-libgmail2/frontend/Observers.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Observers.py 12 Jun 2005 06:17:01 -0000 1.1 --- Observers.py 14 Jun 2005 14:22:19 -0000 1.2 *************** *** 69,71 **** print "observable",self cb = getattr(observer,func,None) ! cb(self,data) --- 69,71 ---- print "observable",self cb = getattr(observer,func,None) ! apply(cb,(self,data)) --- GuiQTgmc.py DELETED --- |
|
From: Stas Z. <sta...@us...> - 2005-06-14 14:17:40
|
Update of /cvsroot/gmailagent/GA-main In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23812 Modified Files: Gmail.py GmailAgent.py GuiQT.py Makefile Log Message: Started the switch to a separate contacts application. From this point on all the contacts support in GA will be transferred to the new contacts package. Index: GuiQT.py =================================================================== RCS file: /cvsroot/gmailagent/GA-main/GuiQT.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** GuiQT.py 10 Jun 2005 09:22:07 -0000 1.34 --- GuiQT.py 14 Jun 2005 14:17:31 -0000 1.35 *************** *** 185,188 **** --- 185,195 ---- # lineEditTo.setCurrentText will called when the model calls the update method of the obs #The 'To:' field is filled by the AddressBookDialog through the observer + if not Gmail.USE_CONTACTS: + text = "You don't have the Gmail Contacts manager installed.\n"+\ + "See the GmailAgent website for more information." + QMessageBox.information(self, + "Info",text, + QMessageBox.Ok) + return self.obs = Observer(self.lineEditTo.setText) ad = AddressBookDialog(self,observer=self.obs) Index: Gmail.py =================================================================== RCS file: /cvsroot/gmailagent/GA-main/Gmail.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Gmail.py 10 Jun 2005 09:23:42 -0000 1.18 --- Gmail.py 14 Jun 2005 14:17:31 -0000 1.19 *************** *** 20,24 **** GM_DEBUG = 1 ! import libgmail2,urllib2,logging,ConfigParser,os,pickle def login(name,pas): --- 20,31 ---- GM_DEBUG = 1 ! import libgmail2,urllib2,logging,ConfigParser,os ! ! try: ! import Contrgmc ! except ImportError,info: ! USE_CONTACTS = False ! else: ! USE_CONTACTS = True def login(name,pas): *************** *** 81,254 **** ######## Leave it here until the new contacts frontend is functional ########### ! def upload_local_contacts(addrfile,ga): ! """Returns the contacts from the local file which don't have a ID entry. ! Contacts without an ID are considered local only and must be added to the Gmail ! contacts list. ! This function is called whenever the user logs into Gmail. ! Returns error message on faillure, None on succes.""" ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") ! contacts = load_addressfile(addrfile) ! for line in contacts: ! if GM_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) ! if not line[3]: ! logging.debug("Adding %s %s %s %s to Gmail" % line) ! if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception ! return ("Unable to add contact %s %s %s %s" % line) ! # Now we reload the contacts to create a new local contacts list ! #import_contacts(addrfile,ga) ! ! ! def store_address(addrfile,name,addr,notes='',id='',ga=None): ! """The contacts will be stored in the local copy on disk. ! If the id is given we assume the contact has a valid Gmail id and ! the contact is removed from the online contacts and replaced by the ! given contact. It will get a new id from Gmail. ! """ ! if GM_DEBUG: ! logging.debug("\n>>>>>>>> Function: store_address") ! logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) ! if id and ga: ! if GM_DEBUG: logging.debug("Found id, removing original contact first") ! contacts = ga.getContacts() ! contact = contacts.getContactById(id) ! if contact: ! if not ga.removeContact(contact): ! logging.warning("Failed to remove contact %s" % contact) ! else: ! # Build the new local file with the contacts from Gmail ! import_contacts(addrfile,ga) ! # now we add the new contact to the local file ! store_address(addrfile,name,addr,notes) ! # And upload it to Gmail ! upload_local_contacts(addrfile,ga) ! # Retrieve Gmail contacts so that we have get an id for the new contact. ! import_contacts(addrfile,ga) ! # stuff is stored in a file like this: ! # name&&addr&¬es&&id ! # Contacts that are not (yet) in the Gmail contacts list have an empty ! # string as id. ! # After syncronizing the file with the contacts the id fields will be asigned. ! try: ! f = open(addrfile,'r') ! lines = f.readlines() ! f.close() ! except IOError,info: ! mesg = "Failed to check the address (IO), %s" % info ! if GM_DEBUG: logging.warning(mesg) ! return mesg ! else: ! for line in lines: ! if name in line and addr in line: ! return ! # It's a new entry ! line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) ! if GM_DEBUG: logging.debug("Found new contact %s" % line) ! try: ! f = open(addrfile,'a') ! f.write(line) ! f.close() ! except IOError,info: ! f.close() ! mesg = "Failed to store address, %s" % info ! if GM_DEBUG: logging.warning(mesg) ! return mesg ! ! def load_addressfile(filename): ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") ! try: ! f = open(filename,'r') ! lines = f.readlines() ! f.close() ! except IOError,info: ! if GM_DEBUG: logging.warning(str(info)) ! return ! if GM_DEBUG: logging.debug(str(lines)) ! newlines = [] ! for line in lines: ! newlines.append(tuple(line[:-1].split("&&"))) ! return (newlines) ! ! def import_contacts(addrfile,ga): ! """This gets the gmail contacts create a new local contacts list on disk.""" ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") ! upload_local_contacts(addrfile,ga) ! contacts = ga.getContacts().getAllContacts() ! logging.debug("Contacts imported:\n%s" % contacts) ! if contacts: ! # remove local file, we can remove it because the upload_local_contacts method will make sure ! # that the contacts are syncronized. ! logging.debug("Removing local file") ! open(addrfile,'w').close() ! else: ! return ! for obj in contacts: ! store_address(addrfile,\ ! obj.getName(),\ ! obj.getEmail(),\ ! obj.getNotes(),\ ! obj.getId()) ! return load_addressfile(addrfile) ! ! def export_contacts(addrfile,ga): ! """This will remove the contacts at the online contacts list and replace ! it with the local copy fom disk. ! It will return a message on any error. ! It returns None on succes.""" ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") ! entries = load_addressfile(addrfile) ! if len(entries) < 1: ! text = "Failed to load address file, %s" % addrfile ! if GM_DEBUG: logging.critical(text) ! return text ! try: ! contacts = ga.getContacts().getAllContacts() ! # Just to test save_contacts ! save_contacts(contacts) ! for contact in contacts: ! if GM_DEBUG: logging.debug("Removing contact %s", contact) ! ga.removeContact(contact) ! except Exception,info: ! logging.critical(str(info)) ! if contacts: ! save_contacts(contacts) ! return "An error occured, tried to save your contacts to\n%s and %s" %\ ! ('~/.GmailContacts.txt','~/.GmailContacts.pickle') ! # Now we fill the contacts list again from the local file. ! try: ! for entry in entries: ! if GM_DEBUG: logging.debug("Adding contact %s", entry) ! apply(ga.addContact,entry[:-1]) ! except Exception,info: ! logging.critical(str(info)) ! save_contacts(contacts) ! ! def save_contacts(contacts): ! """Save the contact in case of an error. This is an attempt to prevent ! data loss in case of an error when interacting with Gmail contacts.""" ! if GM_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") ! try: ! f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') ! pickle.dump(contacts,f) ! ## XXX TODO: some way to load the pickled object and restore it ! except Exception,info: ! text = "Attempt to pickle the contacts %s" % str(info) ! logging.critical(text) ! f.close() ! try: ! f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') ! text = "#An error occured in GmailAgent and these contacts are saved\n"+\ ! "#to this file in an attempt to save them\n"+\ ! "#A contact is saved as follows:\n"+\ ! "#GmailID Name email notes\n" ! f.write(text) ! for con in contacts: ! name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() ! f.write("%s %s %s %s\n" % (con.getId(),\ ! con.getName(),\ ! con.getEmail(),\ ! con.getNotes())) ! f.close() ! except Exception,info: ! logging.critical(str(info)) ! return str(info) ! --- 88,261 ---- ######## Leave it here until the new contacts frontend is functional ########### ! ##def upload_local_contacts(addrfile,ga): ! ## """Returns the contacts from the local file which don't have a ID entry. ! ## Contacts without an ID are considered local only and must be added to the Gmail ! ## contacts list. ! ## This function is called whenever the user logs into Gmail. ! ## Returns error message on faillure, None on succes.""" ! ## if GM_DEBUG: logging.debug("\n>>>>>>>> Function: upload_local_contacts") ! ## contacts = load_addressfile(addrfile) ! ## for line in contacts: ! ## if GM_DEBUG: logging.debug("Found local contact %s %s %s %s" % line) ! ## if not line[3]: ! ## logging.debug("Adding %s %s %s %s to Gmail" % line) ! ## if not ga.addContact(line[0],line[1],line[2]):#libgmail2 checks for exception ! ## return ("Unable to add contact %s %s %s %s" % line) ! ## # Now we reload the contacts to create a new local contacts list ! ## #import_contacts(addrfile,ga) ! ## ! ## ! ##def store_address(addrfile,name,addr,notes='',id='',ga=None): ! ## """The contacts will be stored in the local copy on disk. ! ## If the id is given we assume the contact has a valid Gmail id and ! ## the contact is removed from the online contacts and replaced by the ! ## given contact. It will get a new id from Gmail. ! ## """ ! ## if GM_DEBUG: ! ## logging.debug("\n>>>>>>>> Function: store_address") ! ## logging.debug("store contact %s %s %s %s %s" % (name,addr,notes,id,ga)) ! ## if id and ga: ! ## if GM_DEBUG: logging.debug("Found id, removing original contact first") ! ## contacts = ga.getContacts() ! ## contact = contacts.getContactById(id) ! ## if contact: ! ## if not ga.removeContact(contact): ! ## logging.warning("Failed to remove contact %s" % contact) ! ## else: ! ## # Build the new local file with the contacts from Gmail ! ## import_contacts(addrfile,ga) ! ## # now we add the new contact to the local file ! ## store_address(addrfile,name,addr,notes) ! ## # And upload it to Gmail ! ## upload_local_contacts(addrfile,ga) ! ## # Retrieve Gmail contacts so that we have get an id for the new contact. ! ## import_contacts(addrfile,ga) ! ## # stuff is stored in a file like this: ! ## # name&&addr&¬es&&id ! ## # Contacts that are not (yet) in the Gmail contacts list have an empty ! ## # string as id. ! ## # After syncronizing the file with the contacts the id fields will be asigned. ! ## try: ! ## f = open(addrfile,'r') ! ## lines = f.readlines() ! ## f.close() ! ## except IOError,info: ! ## mesg = "Failed to check the address (IO), %s" % info ! ## if GM_DEBUG: logging.warning(mesg) ! ## return mesg ! ## else: ! ## for line in lines: ! ## if name in line and addr in line: ! ## return ! ## # It's a new entry ! ## line = "%s&&%s&&%s&&%s\n" % (name,addr,notes,id) ! ## if GM_DEBUG: logging.debug("Found new contact %s" % line) ! ## try: ! ## f = open(addrfile,'a') ! ## f.write(line) ! ## f.close() ! ## except IOError,info: ! ## f.close() ! ## mesg = "Failed to store address, %s" % info ! ## if GM_DEBUG: logging.warning(mesg) ! ## return mesg ! ## ! ##def load_addressfile(filename): ! ## if GM_DEBUG: logging.debug("\n>>>>>>>> Function: load_addressfile") ! ## try: ! ## f = open(filename,'r') ! ## lines = f.readlines() ! ## f.close() ! ## except IOError,info: ! ## if GM_DEBUG: logging.warning(str(info)) ! ## return ! ## if GM_DEBUG: logging.debug(str(lines)) ! ## newlines = [] ! ## for line in lines: ! ## newlines.append(tuple(line[:-1].split("&&"))) ! ## return (newlines) ! ## ! ##def import_contacts(addrfile,ga): ! ## """This gets the gmail contacts create a new local contacts list on disk.""" ! ## if GM_DEBUG: logging.debug("\n>>>>>>>> Function: import_contacts") ! ## upload_local_contacts(addrfile,ga) ! ## contacts = ga.getContacts().getAllContacts() ! ## logging.debug("Contacts imported:\n%s" % contacts) ! ## if contacts: ! ## # remove local file, we can remove it because the upload_local_contacts method will make sure ! ## # that the contacts are syncronized. ! ## logging.debug("Removing local file") ! ## open(addrfile,'w').close() ! ## else: ! ## return ! ## for obj in contacts: ! ## store_address(addrfile,\ ! ## obj.getName(),\ ! ## obj.getEmail(),\ ! ## obj.getNotes(),\ ! ## obj.getId()) ! ## return load_addressfile(addrfile) ! ## ! ##def export_contacts(addrfile,ga): ! ## """This will remove the contacts at the online contacts list and replace ! ## it with the local copy fom disk. ! ## It will return a message on any error. ! ## It returns None on succes.""" ! ## if GM_DEBUG: logging.debug("\n>>>>>>>> Function: export_contacts") ! ## entries = load_addressfile(addrfile) ! ## if len(entries) < 1: ! ## text = "Failed to load address file, %s" % addrfile ! ## if GM_DEBUG: logging.critical(text) ! ## return text ! ## try: ! ## contacts = ga.getContacts().getAllContacts() ! ## # Just to test save_contacts ! ## save_contacts(contacts) ! ## for contact in contacts: ! ## if GM_DEBUG: logging.debug("Removing contact %s", contact) ! ## ga.removeContact(contact) ! ## except Exception,info: ! ## logging.critical(str(info)) ! ## if contacts: ! ## save_contacts(contacts) ! ## return "An error occured, tried to save your contacts to\n%s and %s" %\ ! ## ('~/.GmailContacts.txt','~/.GmailContacts.pickle') ! ## # Now we fill the contacts list again from the local file. ! ## try: ! ## for entry in entries: ! ## if GM_DEBUG: logging.debug("Adding contact %s", entry) ! ## apply(ga.addContact,entry[:-1]) ! ## except Exception,info: ! ## logging.critical(str(info)) ! ## save_contacts(contacts) ! ## ! ##def save_contacts(contacts): ! ## """Save the contact in case of an error. This is an attempt to prevent ! ## data loss in case of an error when interacting with Gmail contacts.""" ! ## if GM_DEBUG: logging.debug("\n>>>>>>>> Function: save_contacts") ! ## try: ! ## f = open(os.path.expanduser('~/.GmailContacts.pickle'),'w') ! ## pickle.dump(contacts,f) ! ## ## XXX TODO: some way to load the pickled object and restore it ! ## except Exception,info: ! ## text = "Attempt to pickle the contacts %s" % str(info) ! ## logging.critical(text) ! ## f.close() ! ## try: ! ## f =open(os.path.expanduser('~/.GmailContacts.txt'),'w') ! ## text = "#An error occured in GmailAgent and these contacts are saved\n"+\ ! ## "#to this file in an attempt to save them\n"+\ ! ## "#A contact is saved as follows:\n"+\ ! ## "#GmailID Name email notes\n" ! ## f.write(text) ! ## for con in contacts: ! ## name,email,notes,id = con.getName(),con.getEmail(),con.getNotes(),con.getId() ! ## f.write("%s %s %s %s\n" % (con.getId(),\ ! ## con.getName(),\ ! ## con.getEmail(),\ ! ## con.getNotes())) ! ## f.close() ! ## except Exception,info: ! ## logging.critical(str(info)) ! ## return str(info) ! ## Index: Makefile =================================================================== RCS file: /cvsroot/gmailagent/GA-main/Makefile,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Makefile 6 Jun 2005 18:26:08 -0000 1.9 --- Makefile 14 Jun 2005 14:17:31 -0000 1.10 *************** *** 6,10 **** pyuic HelpDialog.ui -o HelpDialog_forms.py pyuic AddressDialog.ui -o AddressDialog_forms.py ! pyuic AddressEditDialog.ui -o AddressEditDialog_forms.py ! pyuic AddressEditorDialog.ui -o AddressEditorDialog_forms.py ! \ No newline at end of file --- 6,9 ---- pyuic HelpDialog.ui -o HelpDialog_forms.py pyuic AddressDialog.ui -o AddressDialog_forms.py ! # pyuic AddressEditDialog.ui -o AddressEditDialog_forms.py ! # pyuic AddressEditorDialog.ui -o AddressEditorDialog_forms.py Index: GmailAgent.py =================================================================== RCS file: /cvsroot/gmailagent/GA-main/GmailAgent.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** GmailAgent.py 8 Jun 2005 12:28:17 -0000 1.15 --- GmailAgent.py 14 Jun 2005 14:17:31 -0000 1.16 *************** *** 90,98 **** --- 90,104 ---- ### Start GUI if GM_DEBUG: print "\n===== Starting GUI =======" + import GuiQT + app = QApplication(sys.argv) QObject.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()")) + w = GuiQT.win(att=files,application=app) + app.setMainWidget(w) + w.show() + app.exec_loop() |
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26164/frontend Added Files: GuiQTgmc.py MainWinContacts.ui MainWinContacts.ui.h MainWinContacts_forms.py Makefile Observers.py Qgmc.py Log Message: removed obsolete test suite example from stas. Added the QT frontend stuff in a separate directory. --- NEW FILE: Qgmc.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # Qgmc.py # # 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 Library 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. import sys from qt import * import GuiQTgmc app = QApplication(sys.argv) w = GuiQTgmc.MainWin(application=app) app.setMainWidget(w) w.show() app.exec_loop() --- NEW FILE: MainWinContacts.ui --- <!DOCTYPE UI><UI version="3.3" stdsetdef="1"> <class>FormMainWin</class> <widget class="QMainWindow"> <property name="name"> <cstring>FormMainWin</cstring> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>578</width> <height>432</height> </rect> </property> <property name="caption"> <string>GCM - Gmail Contacts Manager</string> </property> <widget class="QListView"> <column> <property name="text"> <string>Name</string> </property> <property name="clickable"> <bool>true</bool> </property> <property name="resizable"> <bool>true</bool> </property> </column> <column> <property name="text"> <string>Email address</string> </property> <property name="clickable"> <bool>true</bool> </property> <property name="resizable"> <bool>true</bool> </property> </column> <column> <property name="text"> <string>Notes</string> </property> <property name="clickable"> <bool>true</bool> </property> <property name="resizable"> <bool>true</bool> </property> </column> <column> <property name="text"> <string>Gmail ID</string> </property> <property name="clickable"> <bool>false</bool> </property> <property name="resizable"> <bool>true</bool> </property> </column> <item> <property name="text"> <string></string> </property> <property name="text"> <string></string> </property> <property name="text"> <string></string> </property> <property name="text"> <string></string> </property> <property name="pixmap"> <pixmap></pixmap> </property> <property name="pixmap"> <pixmap></pixmap> </property> <property name="pixmap"> <pixmap></pixmap> </property> <property name="pixmap"> <pixmap></pixmap> </property> </item> <property name="name"> <cstring>listViewContacts</cstring> </property> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>560</width> <height>310</height> </rect> </property> <property name="frameShape"> <enum>StyledPanel</enum> </property> <property name="frameShadow"> <enum>Sunken</enum> </property> <property name="selectionMode"> <enum>Single</enum> </property> <property name="allColumnsShowFocus"> <bool>true</bool> </property> <property name="showSortIndicator"> <bool>true</bool> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonClose</cstring> </property> <property name="geometry"> <rect> <x>410</x> <y>330</y> <width>120</width> <height>26</height> </rect> </property> <property name="text"> <string>Close</string> </property> <property name="toolTip" stdset="0"> <string>Close without saving</string> </property> </widget> <widget class="QPushButton"> <property name="name"> <cstring>pushButtonCloseSave</cstring> </property> <property name="geometry"> <rect> <x>40</x> <y>330</y> <width>120</width> <height>26</height> </rect> </property> <property name="text"> <string>Close and Save</string> </property> <property name="default"> <bool>true</bool> </property> <property name="toolTip" stdset="0"> <string>Close and save your contacts</string> </property> </widget> </widget> <menubar> <property name="name"> <cstring>MenuBar</cstring> </property> <item text="&Contacts" name="Contacts"> <action name="contactsImportcontacts"/> <action name="contactsExportcontacts"/> <separator/> <action name="contactsSave"/> <action name="contactsSaveAs"/> <separator/> <action name="contactsPrintAction"/> <separator/> <action name="contactsExit"/> </item> <item text="&Edit" name="editMenu"> <action name="editNewcontact"/> <action name="editEditcontact"/> <separator/> <action name="editDeletecontact"/> </item> <item text="&Help" name="helpMenu"> <action name="helpContents"/> <separator/> <action name="helpAbout"/> </item> </menubar> <toolbars> <toolbar dock="2"> <property name="name"> <cstring>Toolbar</cstring> </property> <property name="label"> <string>Toolbar</string> </property> <action name="contactsImportcontacts"/> <action name="contactsExportcontacts"/> <separator/> <action name="contactsSave"/> <action name="contactsSaveAs"/> <separator/> <action name="contactsPrintAction"/> <separator/> <action name="editNewcontact"/> <action name="editEditcontact"/> <action name="editDeletecontact"/> <separator/> <action name="helpContents"/> <separator/> </toolbar> <toolbar dock="2"> <property name="name"> <cstring>Toolbar_2</cstring> </property> <property name="label"> <string>Toolbar_2</string> </property> <widget class="QLineEdit"> <property name="name"> <cstring>lineEditSearchToolbar</cstring> </property> <property name="minimumSize"> <size> <width>180</width> <height>0</height> </size> </property> <property name="focusPolicy"> <enum>StrongFocus</enum> </property> <property name="text"> <string></string> </property> <property name="toolTip" stdset="0"> <string>Search for a contact</string> </property> </widget> <separator/> </toolbar> </toolbars> <actions> <action> <property name="name"> <cstring>fileNewAction</cstring> </property> <property name="iconSet"> <iconset>image0</iconset> </property> <property name="text"> <string>New</string> </property> <property name="menuText"> <string>&New</string> </property> <property name="accel"> <string>Ctrl+N</string> </property> </action> <action> <property name="name"> <cstring>fileOpenAction</cstring> </property> <property name="iconSet"> <iconset>image1</iconset> </property> <property name="text"> <string>Open</string> </property> <property name="menuText"> <string>&Open...</string> </property> <property name="accel"> <string>Ctrl+O</string> </property> </action> <action> <property name="name"> <cstring>contactsSave</cstring> </property> <property name="iconSet"> <iconset>image2</iconset> </property> <property name="text"> <string>Save</string> </property> <property name="menuText"> <string>&Save</string> </property> <property name="toolTip"> <string>Save your contacts to disk</string> </property> <property name="accel"> <string>Ctrl+S</string> </property> </action> <action> <property name="name"> <cstring>contactsSaveAs</cstring> </property> <property name="iconSet"> <iconset>image3</iconset> </property> <property name="text"> <string>Save As</string> </property> <property name="menuText"> <string>Save &As...</string> </property> <property name="toolTip"> <string>Save your contacts to disk </string> </property> <property name="accel"> <string>Ctrl+A</string> </property> </action> <action> <property name="name"> <cstring>contactsPrintAction</cstring> </property> <property name="iconSet"> <iconset>image4</iconset> </property> <property name="text"> <string>Print</string> </property> <property name="menuText"> <string>&Print...</string> </property> <property name="toolTip"> <string>Print your contacts</string> </property> <property name="accel"> <string>Ctrl+P</string> </property> </action> <action> <property name="name"> <cstring>contactsExit</cstring> </property> <property name="iconSet"> <iconset>image5</iconset> </property> <property name="text"> <string>Exit</string> </property> <property name="menuText"> <string>E&xit</string> </property> <property name="toolTip"> <string>Exit the application</string> </property> <property name="accel"> <string>Ctrl+X</string> </property> </action> <action> <property name="name"> <cstring>editUndoAction</cstring> </property> <property name="iconSet"> <iconset>image6</iconset> </property> <property name="text"> <string>Undo</string> </property> <property name="menuText"> <string>&Undo</string> </property> <property name="accel"> <string>Ctrl+Z</string> </property> </action> <action> <property name="name"> <cstring>editRedoAction</cstring> </property> <property name="iconSet"> <iconset>image7</iconset> </property> <property name="text"> <string>Redo</string> </property> <property name="menuText"> <string>&Redo</string> </property> <property name="accel"> <string>Ctrl+Y</string> </property> </action> <action> <property name="name"> <cstring>editCutAction</cstring> </property> <property name="iconSet"> <iconset>image8</iconset> </property> <property name="text"> <string>Cut</string> </property> <property name="menuText"> <string>Cu&t</string> </property> <property name="accel"> <string>Ctrl+X</string> </property> </action> <action> <property name="name"> <cstring>editCopyAction</cstring> </property> <property name="iconSet"> <iconset>image9</iconset> </property> <property name="text"> <string>Copy</string> </property> <property name="menuText"> <string>&Copy</string> </property> <property name="accel"> <string>Ctrl+C</string> </property> </action> <action> <property name="name"> <cstring>editPasteAction</cstring> </property> <property name="iconSet"> <iconset>image10</iconset> </property> <property name="text"> <string>Paste</string> </property> <property name="menuText"> <string>&Paste</string> </property> <property name="accel"> <string>Ctrl+V</string> </property> </action> <action> <property name="name"> <cstring>editFindAction</cstring> </property> <property name="iconSet"> <iconset>image11</iconset> </property> <property name="text"> <string>Find</string> </property> <property name="menuText"> <string>&Find...</string> </property> <property name="accel"> <string>Ctrl+F</string> </property> </action> <action> <property name="name"> <cstring>helpContents</cstring> </property> <property name="iconSet"> <iconset>image12</iconset> </property> <property name="text"> <string>Contents</string> </property> <property name="menuText"> <string>&Contents...</string> </property> <property name="toolTip"> <string>Show the help contents</string> </property> <property name="accel"> <string></string> </property> </action> <action> <property name="name"> <cstring>helpIndexAction</cstring> </property> <property name="text"> <string>Index</string> </property> <property name="menuText"> <string>&Index...</string> </property> <property name="accel"> <string></string> </property> </action> <action> <property name="name"> <cstring>helpAbout</cstring> </property> <property name="iconSet"> <iconset>image13</iconset> </property> <property name="text"> <string>About</string> </property> <property name="menuText"> <string>&About</string> </property> <property name="toolTip"> <string>About GMC</string> </property> <property name="accel"> <string></string> </property> </action> <action> <property name="name"> <cstring>contactsImportcontacts</cstring> </property> <property name="iconSet"> <iconset>image14</iconset> </property> <property name="text"> <string>&Import contacts</string> </property> <property name="menuText"> <string>&Import contacts</string> </property> <property name="toolTip"> <string>Import contacts from a Gmail account</string> </property> <property name="accel"> <string>Ctrl+I</string> </property> </action> <action> <property name="name"> <cstring>editNewcontact</cstring> </property> <property name="iconSet"> <iconset>image15</iconset> </property> <property name="text"> <string>&New contact</string> </property> <property name="menuText"> <string>New contact</string> </property> <property name="toolTip"> <string>Create a new contact</string> </property> <property name="accel"> <string>Ctrl+N</string> </property> </action> <action> <property name="name"> <cstring>editEditcontact</cstring> </property> <property name="iconSet"> <iconset>image16</iconset> </property> <property name="text"> <string>&Edit contact</string> </property> <property name="menuText"> <string>&Edit contact</string> </property> <property name="toolTip"> <string>Edit a existing contact</string> </property> <property name="accel"> <string>Ctrl+E</string> </property> </action> <action> <property name="name"> <cstring>editDeletecontact</cstring> </property> <property name="iconSet"> <iconset>image17</iconset> </property> <property name="text"> <string>Delete contact</string> </property> <property name="menuText"> <string>Delete contact</string> </property> <property name="toolTip"> <string>Delete a contact</string> </property> <property name="accel"> <string>Ctrl+D</string> </property> </action> <action> <property name="name"> <cstring>contactsExportcontacts</cstring> </property> <property name="iconSet"> <iconset>image18</iconset> </property> <property name="text"> <string>Exp&ort contacts</string> </property> <property name="menuText"> <string>Exp&ort contacts</string> </property> <property name="toolTip"> <string>Export your contacts to a local file</string> </property> <property name="accel"> <string>Ctrl+O</string> </property> </action> <action> <property name="name"> <cstring>editFind_contact</cstring> </property> <property name="iconSet"> <iconset>image19</iconset> </property> <property name="text"> <string>Find contact</string> </property> <property name="menuText"> <string>Find contact</string> </property> <property name="accel"> <string>Ctrl+F</string> </property> </action> </actions> <images> <image name="image0"> <data format="PNG" length="173">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388dedd5c109c0200c05d06fe936812c10b2ffdd85d25385b6a991480f053f081af0291210f828c5a9d9c4de96cd2b9ad9eb0000660e2fe0c2519839c4f70c4c446d5e6b3538cf928245e4b2f6f014acaa8fda1d4fc1a5741b22079f9d111d96ea8a912c78c10bee64e60719f57e9203ad452a04cc4e50200000000049454e44ae426082</data> </image> <image name="image1"> <data format="PNG" length="210">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000009949444154388ded94410e85200c445f89c7367f61bc775d2848a42860ffced9548bbe8e13043e1d928177f481a123dc2b34f6f47a3de2b865a8843f4001982a0b3d5f62c58300aa1ad70550449ab9d507a773a8a4ba4f92a2df333c64c63bebbd82e5b8addecbcc7820eb4266c639745dfa80f36faf66c66fa19c3f882fb470ec05cdc0bed07893f68e171492635f686c3eeff6ba3c8fdd366dc4c0452c8781f8080000000049454e44ae426082</data> </image> <image name="image2"> <data format="PNG" length="987">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000003a2494441544889bd95cb6b9c5514c07fdf63de993ca6499a485c44414a1102457c90a1d58af1b1105d44224584e0a28a888b2258445d047453c145fe87414366611024b89026e2a3d6a24549ad6017914c8279ce7ccf7bef71318f646a2209150f5cbe7bcebd9cdf3de7dcf35df89f641c90ff70bc08b88065350072f9d72a7f7a5b5c294d73f1b9c7b01d073106e379603bd0d055e083658398fad7b251c90c1f7df6258f9e7b9df5ad1d5e3e7b12a013f0dd66088154b9f5fb1facadaeb3f5cd65a86d8201154590ca607c9f2893031513d57c2c04711cbced2a62341baa87ebbf5ce7c7abd79a2e73806a01442c8c36a4536956aa1a274e8211b01258b120891cd5d52df25d1dd4024daed0835759c112839f2e90b49244b160449a2e1380dd02286310d790cb3b3cf4eed4918bf8c5850bd8b68d5151d36401d84dcd01de1e3fc3f2f2f2919def15ad559beeee4eeba1954a25c6c6c618191939b4d3eded6d0012ae4318466d6b2d8011ab659c9c9c64616181d1d1d14343e6e6e6ea7e543ba095221398b68562b1c8e2e2e2a10100228218dd666b4510daffd84fb15864666686e1e1e17f751c04416bdee51e50033b21dc2e4749d3ecec2c4a1bb48af70744ba1d30313141b95ca65c2eef9e54092e1ad775dbf67a9e47b2b30fc7b6a8d4c2fd0112ef025eb978897b4edc5f3f91114404d7b1498631f96c0a6934936ddbc44a33984ee28731ae63a3c28352d4886cfc8d29f203c3cc97a6b170e8ee29d0dddb8fd61aad638c3618ad10843808a9041ab3b1c699f1f30c0f1e0373c0359504bcf9f12788d12c7df5292f3c7d9aa79e7916d7754967b2f53d22d4aa3b6c6e6d10053e3f5dbbcafcf737a81546b879738953232731e6801a80a0b40263f0aa551e7fe249d29934efbff70e6bab15003ef8f012ebeb6b84be47e07b3cf0f028a5cfbf267bf77162159071051db40376fb404004924e5d4f67b2641a276f4a75679b38aaa7a070ac8f7c4727e94c86668ba6f6b9eabb3f3ba5314663b421f03d8cd6c4b162b5b28231f5268ca200a315b98e3cfd0377914e67512ac69108a32d2abe90b20ea8c1cf8bf32448505386380af13d0fcff3d04ab76e4d18f8f4147ae93b3e482a95260c038cd1446144c208c608a2f7efe407a7a7defaeeecf3e7c8771718baf73e7eb8f22d434343bcf6ea797afb0700c8757492cf77e1ba093637fee2b71b4b844140070e3a0a886c83b41286dc0e7a843b7c8b4f9c3add9cbf040c009926cea2fe24641b23b1c77e541120066a80bfd74113e236be77221a5080fe1b18eee1afe18f5a2f0000000049454e44ae426082</data> </image> <image name="image3"> <data format="PNG" length="1215">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df800000486494441544889a5956d68956518c77fcfdb79db39c7ed6c73c75842045141c86cf99234319152282b32a8e85b1fcca8be944546f94128a4eccbfcd2200d84a4c8b70f23b60f1152644e370d69eac4c46c3b1eb69de9f69ce7edbeee3e9c17b7dc20f1828be77eeee77efebffbb9aeeb7e2eb83b33005df557801460dda5e65cf170748dbed1fb4c0db2b40a316a8bccea75cbac9dfc5f97a8f804d1e9246f7e75b9a6770598015e066cc0a891f4f13fa7f9c79d62e0e05e3e7c6e1da665a14510d705d382ea7d5876c96f7a91a8b0867020c57bdf4dd2fdcd00ebd76f60f3ebef62a7b26cdbbc1a200b94ed1adad3d35cb9f417c5eb134cfd761c664a20100501c49348b98c9f48f1c8ce3d047f3f8e7722c95b5f17d97764880fba1ee35c32c3b542818b974ed4241b80a80ed0da4094908827189b5658610c4483e160841ab153acd8b907fff26afc9309dede5f64dfd1337cb9711d4eba99ab4e163b9ec6306b51c701cc3a201241db4243c662e5c7bbe664536b8d699af823ab70cfb5f0fef7d7d877f40cfdfdfde47239dadadab8b07b37b17802ada2d945401d6001e2cb6da55213f78657523e1567fb91abf47c3b445f5f1f4d4d4de4f37972b91cb66d639a26ea16803900d0685d190d0e0ea2b5466b4d676727eed915cc0cc479e787290e1c1ea2bbbb9b42a180528a2008181e1ec6300c1cdbc2f783f901a20d4445944a253a3a3a2a7352f9a22b235dec3ed6cf81c367e8ebeb2397cb91cfe7696e6e26168b619a26bdbdbd9577a285009ea04ca1b1b1b11e1acbb2d8bcae95875ef81c6041f1d9e1d4a2e607f82648f5e1e0e0204a55c6477f2ad2d3d38361188c8f8f23220441c0e8e8685ddcf3bcbae0227b811c988e2666803b36464747072242a954a25028100401d96c96743a4d434303b1580ca37e462b76e8d0212225a8289c1f10288d1744c41f5dcb8e1d3bf03c0f11218a2a3bb22c8b509bd8281cc79923e2ba2eb16c2b96695098f1e707e850e3fb8a4c633b666e2969d3208c144a095a6b6cdbc20b2232a938ba5a6ea66912468a258918653fc4b64c227fa11085200813375c4cd364e8c7fd18583436e5686c598c520aa5424409a222349ad0f329780a992cb276cb56ee5bd20cb2401569074429d08af33f1fe3a58d5d3cbde9596cdb26914c55d668cdccf44d4a5393045e99b343a7e93f798199dc324646ceb37cd9c3882c9003d0442a0211dce969d66f788a4432c1ce4f3ea278bd00c0a79f7dc1c44411bfece2955d3a57ade160efafa4ee6d238c3c92b646797301f522160d5a43acda8f12c914c9eace6b367df30661500941aeb9954c3a4b2299ac7797b8c96d76eb6717294414a204afec224a118611d70b63f5131d041ea2221ad21916e7ef219148114521960e106550286be2c60239f8e3977e1c1c6622210c7ccaae8bebbaa848d5abc6f7ca34e55a686d5b423c9ec0f73d4414811fe0884644a3d5fc2779c5de5ddb7f7ff2f957c934e668bfff014e0d9ca0bdbd9d6d6f6ca565711e808674964c6611b6ed509a1ce7e285f3f89e471a0b157804a6a06fb563fd5fd06aeebc2fcff1079777d5c6af01792059c319545a42aaeaceacf93b350d84549a7ff95f3adf5c8a3ae0440a0000000049454e44ae426082</data> </image> <image name="image4"> <data format="PNG" length="725">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000029c49444154388d8d95ad76db4010853ff718cc3289d950d06136344c98c362964087256f503f426161021be6b2842550612e8be14299496c866dc14ab2fc77da2192665777eedc3b5af53813afafaf414448d3742f6f6600a82a005555912409575757bdeebefe396011613299b440876b4d946589f7fe68cf596080cd6673047658485571cefd3ff02900333b2a70aa23806fa792799e07336b9938e770ceede9dde82f2247fa9e65acaa244942599688486b54374eb5ff4fc6105b3c9c882e6853ec9c142719376c4e31ede655756f42ba71a40dc06ab50a5996311c0ecf8237467e7e7e022092309f5fb7787b8cdfdfdf83f79efc2347668288b40087d786695994e479ceb6daf2f0f01066b319d7d7d7bd5e1774b3f154c5163580d34c019ca408020e7ce159afffb0dd16a81a1717198bc5224ad130bd9c5ee2d2145503538e6c3103849c4f3e78656a53d2af94e79767fc57fcfad4946c7411419f9e7e85b228c3ffc457f80aa3300a12248cc228acd7ebf0e3fbcf301e8fc360908524494236c842bfda56dcdddd9c75f73052522e999223cc98311e8f4964486905cfbf5ea8aa8a7490d237c0fb22cea31988106b48ed36385c54dc14c4f160dfb9c133b4217fd88019e97018d76b77fa6551e045a29e66b4be39882ed69d38031520e604f0b6c5886788df6c5a4f1cf5b835096b00b17628148b35746f673b39d278da0945e9236065e705adc976371a200a76b8e2302ba9fb6c7a633299f20debb06cc96a7cb4faba07ea9a6d35680d58cb39180c582cee2263ef7d631588412540159d338b30d2b0b21d183bcd31430496cb25f3f9bcd7cfb28c8fb70f7ebfbda16ac4f347d81b3ee93ccb0eb2edb39ea6e572c9e3e3630f3a87d06ab50aabd51bdbfaffa5686dcace99dd5f0354cb785f1993e984dbdb5beeefef5bbcbfd1f69e0c3fec24860000000049454e44ae426082</data> </image> <image name="image5"> <data format="PNG" length="814">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000002f5494441544889b5954f4f134118c67fbb3b33bba58845a002954b4362c4782131e16abc48e2cdc8450f9e3c79207e008dd16fe017d004442140895151280d51a3098289316a30913f2905da40a574f9a7743d144a9bb694607892c926f3eef33cefbcf3ce0c1c31b41271e77ff545a93fbe7dfbcafcfc02b1d802d1688ce99919e2cbcb99782834caf4f44c517e31830a2001e0f3f9f0783c3434f8b0ed359a9b9384c36126263ea369904aa5f64d502f32bf0254172355569ea0a5a585dada3a2ccb75280380d87e44b7db4d5353133e5ffde10c16efdf0260696929675ed372fbc2eff723a4402881346566641b380506cec61a91f636fcfe46e2f1389aa6e589ef424803a5245209942951590602e077e0311b63a33924e3440deb1f8659bc73939367cf3136f611295511038121f49c24ec6c03677585f50fc305c96bef0689b4b7517fbe8550288852e9ec3a3a3ab97efd5a5a44098430d00d3d6f95fb6d72069b5f3e12696fe3c2858b241289ccfc952b57d306c240ee94a660897ecd24f83432bbbfcbc82ced5e2fadad9779f2a493fefe00bdbd3d7477f720a4402a81218cbc15943cc9bb78090c44a3f4f5f5e07697d3dbdb9389494ba22c757883103000bc78f11c8fe738c9a49d139752209544c82206fda110cbe4c2024eef883f0582c121aaaaaab0ed645e02e9ee01c3d03184916ff02018cc23ddce127ffffe2d5e6f0db6bd5670857fb6fe2294004d4348816eecf58eb871ef525e273dba3b98fa050480f1f131eaeaea0a66be8bedededf4a5a769e84247c8bdca17dd83c0ceb7b1b111dbb6f3e2b66d138fc7595d5d459912d35298a6c43415c6410c8033c0f742c2e17098c9c99f0c8dbe612519c7537d9cb2721796db442a995ba242cabad07dde539ee8c2f4328ee3e0380eb1588c486481a9a929bafa3ad94a6de2ae28e354ad0fd352e973200d743db7e2259fccc9c91fcccdcd313432c4ebd020c2a5e3725b98652696cb442881b19371768b3e7b38000779325f0dbfa27ba00bf398e2a4bf1ad3a5308b1caa4238f247ff3ff9a5f10f1280ecfb22017cda0000000049454e44ae426082</data> </image> <image name="image6"> <data format="PNG" length="172">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007349444154388ded92c10e80200840b1ef661d1cff4d876aa888a17669f9360f283ed80060f159425f3a71f53602e08e992b098801d02854176ae47f21ce1fb5b05d38eddc9060d0f11379635b3bc92bd518e239a943ec1d5ab7785cee107be4b215af4091f894de47181ecea59ede9ec59f380062ac28b1e3d701d90000000049454e44ae426082</data> </image> <image name="image7"> <data format="PNG" length="173">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388ded92c10ac02008406ddf2d3b84ffed0ea3586a26d165e0830ea53e8504487e4b910f5489f19ea5a3ca0f8a896365b306c42dd613c649bdc2598316136219f0f936c0a2ef00d75a62614d3ab22996f2a362ffa337c5ebede962aad1a2e84aaaa2f750dd12748c0fd0ab9324677800596e28b1743f46860000000049454e44ae426082</data> </image> <image name="image8"> <data format="PNG" length="187">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000008249444154388dcdd341128020080550e8e02ebc38ad3273503e48537fe3e48c4f2425fa28e29c6f39920bf9276cb60185358877611388c2576418cda015f520b4e6b55be109dc0622b8e22acf31056e18dfdff80606aa551cc63564c4dcf80cd0201d577a5c85a8845fdc025ea5307afccd07e23a1df283ec2b37d9ad5fb4dfefd49cfbf72fac98c8cc890000000049454e44ae426082</data> </image> <image name="image9"> <data format="PNG" length="248">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000bf49444154388dd593410a83301045df488ee51dbc8c3ba98bf46a9eabd385350d266362444a3f0c4266fcf3f824f06f12402b66da8c55f3de2212cf9d92cb98c0ba2d7c4544cf9a07638bbad53c4491235ecf7cc1623697a92540c11ff4fda75275015d24a9389e7d6f53df4fe4ccab323eea0f03c0c4b2a0712ce6add89b59b7661c3be095985f261679ee4ebcc22c9788551fe6a2cbc4969a894bcb6f23ee361aab62e252c57294dfbfb610bbf2c897b8a46cc6677eaa519571fa087ea83762da9abacb20235f0000000049454e44ae426082</data> </image> <image name="image10"> <data format="PNG" length="270">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000d549444154388dc5955d0a84300c8427e2a90a9e6c8b0f4b3dd982d7ca3e58d7fe4cd0ba5d7640024df265da0a057e2439c9eb8d9eaa8841a0c9aad8c82ab32f9c425be1e30e0dcf00c00308f0b3a7a07410a9d7142e00b42c5a5fab696b979b1c837fc0c316b6e4165b64f78d716359919bdc4570de47c04732dd5e5bcc35f0c97762ae787936dccf7513577e79f48c4b27aa0f1327b240f5117fcbe348aa33b6e0224b054d0746b8025e2e3b3e73cde0dd1c97f02e8ed9d0af1db381224bdf33eee698a934a0f617b45540d00bcf4ca08fc0dff406e325c1981bc418760000000049454e44ae426082</data> </image> <image name="image11"> <data format="PNG" length="662">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000025d49444154388dd593a172db4010863f670a56ecc42278d0653693a0c21c68d6c2e60df21a818111349499c254a8329b55f0e089ddb15ba602b79d6692d699b6d399fee86e67e7db7f77efe07fd3e2c74bd775b3730eef3d5115002382b5166b2d5757578b1729bf02b76d3b0f8703b92d58aed7600400ef1ce3c70306a8aa8aebebeb57c117dfa06ddb525dd754efb600a82a49138a123532ec3ac42b9bcde655ce2ffabe9f87c340fde13dcb4d8daaa24e48ee12c6823808c107969b1a8a9ce3f1f8aa515c38e7c8ada5aa6b00c45f129c67d223938c88e6c860d118b1d592d139baae9bcf83a78965b5465134801b1d2e1f4945c0e350096408ea154490c2e0bd3fef5853c2e486a0019f4d84f58418418362b0408e8b23c924501093314dd359f01b809814112025144015f1964c0bbc1b484b07e4688880c029ebd78e4141f5b434fd76864c053f1e084b0f8580265440634044ce838bbcc03987a61350a3a2285e1d5a4414d0708aa598082162ad3d0fb6d6e287cfa498508d274050447370428c91af8d10fd4481608c390b5e00dcddddcd8e80a9de420248e804840856f03e02907d729465c9ba5ae3468731e6a79fe50260b55a6102c4ee40a6894c33f2cb0cb106512814f8f899b22cb9b9b959b8d1f1f8f848d334b46dfbe29bfe5eadeffbf9783c323a871881ecb4200d1151a8eb9aed76bb00188661eeba8efd7e8f3186ed76cb6ab57ae2fe591b5dd7cdde7b628c8808799e63ada5aaaa67b9bbdd6e6e9a06ef3d755d3f29fec7eafb7ebebdbd9dadb5735996f3fdfdfdfca2e3dfd5c3c3c3dc340dd334b1d96cfe1e184e63dceff7a494fe26f61fe90bbc4c5e59d614caf40000000049454e44ae426082</data> </image> <image name="image12"> <data format="PNG" length="1632">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000006274944415448897d96796c14e719c67f73ecae77d7b58d0fd64e4a7d84e21ae303c4e1d4841c5693b440a58a969ad2d258214a25d4a84953a584284d4309ad42142153b975020a49a06ada8410e550948304426d64d785023e16db38c6f858aff718ef35b3b3f3f58fdda58e1af5915e69fe7835cffbbddff33c3312693c08dc0b2480578177f6edfd4dc9f48c6ffbe0e0d0dd8343defaa9a9690f80c7e3f15555965fac282fffc8ee701c3b7ce4251fe004ee0672800f811916600b9004da815780d9cd9b3676a8aa9a6c68a8139f9efa40f87d53223a1f125ac82f3ebf3a2c4ebcfe9aa8ae5e2664594edebe61430730028c0141600af02c247805781660ffbedfd6ae6dacfb576969a94826a2c23213c24844453412165a784e6821bf0807674538302b7c3393c23b784900a2202f6fb2a5e5f6f540217006d89b7db90c9c070a9e79fac9da3f3dfbdcfbbb5de1c66bed7b10e100dafc3c9aa611894448c4750cc3c4342dcc948522cb14c4352eaf76f1803b56f6cfb35d7f6b6e5e5703fc15d89425508000b0367cb96fd7333545d59b0f1ec1546c045e3e40a4763db15894583c8691340081ac2848928404188f6fc51e0df10db7423c6ee67e3c32b52e615951201f389a25986b5d5175e7b94062cb9113274906e708bf779cc0f000fed93902051ebc435e8687bd18ba8edd6ec76eb3917aeb25c4676f8104765962a953e6d0a4b158820ae067c075c0e277bf7ca84495481a275f1446efc762f6e99d62704b9df86475be68afb00be00b555c5c28f6ed7e5478d7b985ff89ed6266fb2a31b1de2d469bdce2f02d760198aa2caf04dc802ccfe8e6f61d6d6daa7ac7f788757f40f84217d3e3e35cf2c7f9f998915de5fdc0adc02abf3fb075cffe03fc7e4427d67f1ee7c61d28858b511558f1d01e6459564ccbfa6146ba0adf6ab9ebbdeb13e3c24c1a627cf0a238b369b978b3d6b170eabb803a60095002145755542c03c491ba42117cee61117a61aff08d0c882bde7e515dbd54009f015f039cf2a0d75be776b988c7a3442d301f394860ed0d11dc07cc66ca9fd17968746cecdab66d5b5b8e8e8590563461ffd1c358aeaf202cc1ca867a80af030e4095a7a6a63d76bb4a2a65a2c80a8aa260acd990251800424018d0013353fa27a74e77f7a4ecd89bbf8d65a5304d13ddd071e7ba018a003ba0c800a6692201b22c63b3a9141517670992a4e32309580bcc69793c8b9320a3aa2a494347d713cc6b11ae0c0f2ff498a47a3c25be603074537e7e1eaacd86cde6a0a4643145458b989b0b2e0526f8126c6b6d6d18bd3a822ccba452167ac220168b72fa7417196fa5592a2b2b2ff5f5f52121e174e650b8a8008fa7945d4d7500afdd5255b508b0652602e0e4c913459d2f1eee79a0ae0a0b81611ac4130922b168b665387362215796977ff8ebc79f404f265115957c879d8237fe485ba1c9fd654e464647875a5b7f706b5969694e6343bdade350fb371f7b6cb7ffe0c6661a1beb88ffbd9398df47d2d0e9ebedcd127403069092daeedb71f3d1975f1d1becffb79a77b91be9edc3c84565a8375590d4c2bcfdc69b1cf559f4687172725c6c5b59c3af766c65c9aab5c4bd17f01d6fc7f7f928feefee62d39307c84c7e0fe0056625406d5ab3bab3bba7b7ad7fb58b3ca70df5e6726c9535386edb0c868eb9a605352f1fbbcd810258fd3dc43f7a1dedcc3b0467a6f027040f0ec5f126009803ee241ddb6105606272f28eb27c779195308a6a5c126a24486ae20ac98b5dc8b76dc6beb49ea4a1234912a600edfc3f081d7b1e2d184033a0635ce7d37991ddfd57816319711872e6022b5636afffc99ffd4c1f1a33988c59184981eec82551db84a6058944234ccf4c333e3ec6f525cbb9a6e671454bb17320c65f0216a4cdb81f48653ca003960aa8c0d577df7dff6273f3baef1fefedebec988d2f7fa1cac6b25f3c4a816f062b6591d0752291088661a069614ee5d7d2397043f35ee0a98cc14ce042860829d3f053d261e6029c6e67ce5c349ed829492895959534d42f27373797d1ab639c3d7b6ea11d2ca01f788474f43f058c023fe68bc604a09c74a8b98045723a72ff009c25fd11cfc6c42cd0053c0f7c27f39c0dc673a473e80624fe1752661a07e9c87592fe5bb0f35fb359a475ae67aa2c439c1de4ff12642167ca46fa9e9405fd82f48eb3a74a7dd94a00fe03b52ecaf4de678e070000000049454e44ae426082</data> </image> <image name="image13"> <data format="PNG" length="449">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df800000188494441544889ed94cf4b025110c73ffbd6d456a5554289bc7408ba14215d3a54209da4bf22e8161d2282fae742ebd2ad5bdd3b69d22f4d3775f77570566c3378760b7cf078b3c36798d979f3be1693973566eb5f182356451d9583dc09102cb8b10d203189f90b1b569201f47367574b35452005d8914a8d59e5666389c3a3a54b2000de1b6f3b2865717bb7d5071e8176793f7b06388ea352a6ac24c2921dbc7a7b137febd30b28b8d7002b40136819b24f40470156a1102fb9c9ea8f808fb61f0654c2aaf2f9b92d5316b014a0ebf5de0380e705df826e6aafbe985da003f41a8dfebd290b68c5f082fa00c9a462d0d7b8c92a5ac3ea9a634bd000f08433650761022409d5ab97ee62a6463a6d5f64e7ab047e10ce75205bcb69ca8e965a2e264ec55906b6814d406732ea1c28013986736e4fc18ee6d5928b5994b3257d7480b4d84de92f53b07afcf1d80c5fa32d17340062405cec1ee04fcb8e2708bfa33ea41d519d3162a3daa12b07b963c05f7063eb52114c16bc69d85145332d9a69d14c8bfea3167d01a26f638c1c1ccdec0000000049454e44ae426082</data> </image> <image name="image14"> <data format="PNG" length="1108">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df80000041b494441544889b5946d685b6514c77f37b969979925902c4d715d83b4b5ccae4db7c218881faa6b61745056158a5fc482d2aa155fc059cabeb8c198b458a5ea10d974942a94214a3f8d16ab532b95e05a8da44d9a642d514c739b366de342729feb87f686364be74476e0709fc3739fffef9cf3bc48e45947478733128934aeacac3c69b3d96a272727abd3e9b401a0a8a848783c9ed9442231633018aecdcece4e004bf91adb4dd207e7ce9d330e0f0f3fa328ca3b478e1cb1d6d5d5995d2e9764369b5155155555c964326c6c6cb0b8b8a8cdcdcdfdedf3f9928944e24d6018500b018c00a3a3a3725f5f5fbfdfefbfd8dddd6d696c6c34391c0ec96432e5c485100821902409abd52ab9dd6e93d3e9b4cccccc9c06acc038200a02a2d1e8535eafb76f707090f2f2f29ce876f1fc580881c562a1a6a606afd77b1cf819982b0870381c43edededa55555553b84b2d9ecae00fd2bcb324ea793a2a2a2b2582cf6693ec000303d3ded397af4e81d190a21d034edaeb1aaaa949595e1f3f91e2bb40706004dd324a3d178c7c2ed71be6f07190c06344d93ee0628287a2fd90b21309bcd689a56487f1320cb32994c06bd8aff92bdd16824994cea7a6f017e601aa8cf01f6efdfafcdcfcf93cd66d9bb77ef3d67afdf917038ac032efc19fab67a6cf4a33ae0971c40511452a9140b0b0bacaeaee276bb738bf321b22c63b15870b95c24120982c12081404007bcf86acf8778aaf7e9f1231280c96412fdfdfd522814420881dd6ea7a6a60697cb953bae7a8fd7d7d7b97efd3a8aa2108944501485868606464646004a80d8dae2175cbd3acc4bbd5f5f90018a8b8b595a5aa2b2b29268344a201020100860b55a319bcdb9bd49a7d3a452292e5fbebc63232b2a2af4e1d3a74e1cda4cdd300ed0236f6525a55229e2f1382e978baaaa2a42a1107ebf9f783ccec4c4444eacb5b595cece4e2e5dba44528962751c20180cead31f0c5d7997ccda4fd8f76d9e5a599f3978f020914884e5e565ec763b1e8f87e6e6665455a5b7b777478bdadada588985915237000887c39c3a7188a12bef23d67e20796b8ae5b5cdff25809292928bc5c5c5af9f3973468e46a32c2c2c00146cd1e0e0202bb13022fe19007b4a9ec855773b360e40fcd7afb8f6a3a0e7bde9dc73edb6d96c63c78e1d7ba8a5a5c568b55a776d517c711ac3da97ec66c95b53acce7f87e7e57580b7b75fefc7816ea7d3d9dad5d525d5d6d6ee38454d4d4d24fff2715b994292f6dc212c326ba4977f27f1db27dc5cade7d9deef011ecd7f3f1e065e00de70381c5a7373b3545a5a8a2ccb0821b83936c0732d65d43ea8ec5a412861e3f4d928c079e06ca107ca0c1cdeaae8f896976ecd2dd7d7d7db5f3999a2e1c01f0044569d68484848643523039f07b9e113e781b3bb66710fa60dbc7658fbe6c2031ab0dd3f064efe1fe11d90f3cf97ebc2f7cdee3be05fed1f48a9ca09a28f6bf00000000049454e44ae426082</data> </image> <image name="image15"> <data format="PNG" length="725">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df80000029c494441544889ad95cb4e14411486bfaa1984197118c4184d3024b2213e013b437c09dc98f00cac7d02f7262e7c0559f002ee340aba60e9c20bad84c82531304c5fea1c17d55ddd33d33340f4744eeaa4bafbffeb5c0bfe83acafafdbab7cf714d06b680ff8d3e97474656545373636be0033801947a07b7b7bdaebf5f43289e358e3b8af71dcd78383038da2487777777569692902ee00b51e5d09bc24e9ebe9e9896e6dbdd1c3c3435555dddeded6d5d55507740a9201a656ab35367eaa1a5611c96d383f3f677a7a1a80b5b535363737edd4d4d40ba00598e658c40ab057c1188baa9073d16c364992946eb73bfcdb63a00b2466104b6b81551922f0dfa569c6b76f5ff9b9bfcf879d8f18e057f48397af5e47c013e0fb880775c0c59e317e4515632d2a8ed9d95996971f32bf709ba3a3234e8e7f03dc041ab521127123c014ab317e0f45920c11a13bd701a0d56e93c47de66ecd00cc4f201805561415c558838a8610351a0da0c1c5458f2c4d78b0b848bb2c140b504b300c5cd8c619bfa78a730e154181244dc2fff7efdd2d4c534fe05c000602a0cf81293d13414448d30497391acd262ecb86e1ea3d0871ce6d5b001739c87b21cb7c1eac35a13786e54a43ea5f64c483cc652189452eb24a7ff86d25cbd2e089cf857f9cb8c904ceb9b22c2b80220e6b1b480ee09ccbc7a6072d2bef120fc4b9caac292673b5018bf215a4a8a6eabb4b4394bb5e3dbdc15793a12c53c9aba8500df684102549124e440e880127124ad498b2620a60542b0d3ac183b3b3b390038c3fbdb516a92130e0931bc254ceaeaa0c94691445a0e2e33b26045ab52b7784e2e798c8a00b031ebc7ff796f60de3631d126c10cd4f8cef7fffce847817a0a2c2cea7cf217d0cc933ae77e94fd2e7c02360a67ae13481855ca786d9af2929700c1cff05c1d9e473833c28770000000049454e44ae426082</data> </image> <image name="image16"> <data format="PNG" length="992">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000003a7494441544889ad955f685b6518c67fdf49d2b46b17b7741b51c15e899db23bb7652d0abdd50ec1ab5a412882178a0ace55101c5eab375e887f8af5a21499c36cda4b11b765adb35bbb69194c3619c38cb48cb6b434c9f972cef7bd5e9c93d3fc6975055ff84838499ee7799fe79c27f03fccd0d090f320df7b09901d9c32b09e4aa5a4b7b7574646466e01ed80da8e40161616a45c2ecb7f8dd65ab476456b578ac5a2140a05999b9b939e9e9e02b00fd872a30702df247165757545ce9ecdc9d2d29288884c4d4d49369b3540aa4612af67e8e8e800209fcfb7b28ba094424410118cf1715d4da95422994c0230303080ebbacef0f0f0c79ee7bd13da588fd13ad65a31c688ef7bd1abe779a2b52bebebeb323e3ebe5d462340423511441bd4948a5882cb12e6175c07f07dc3e26291cc8103fc76659653a73ec42bf653b99626f5dc1440670b413370f02a0d162182721caa5ab3bcb282a75d1e7fe220fefd67f06693bc36569489733714b0bf2103006b0d172fe623a5012008824221a103d608d61aacb53c3f781c7fa91f6fb69d93dfad1282bf0fb4b76ce079d53ae0900441aca01c85d84d8b4484dda987a816faa8ceefe2cdc90dbe397db986f73270618b0d2c97f29722a50160eb06be6f181c3c8ebe730c7da59dd7275698c8cdf3f61baff2e9675f03ac016e2b81311cebcb223654596755749b5acb9ebddde8db59ca37f6f1de997b4ce4e619fbf273eedeb959835a05f4d61b4c4f073e87763821b0522af2dcbd7994ca5c92d1737f33f6ed7546474f90ee4e535a4bd7a02a80692100e8efeb4310acb50d04007bf67653fee308a5ab49decaad3199bbced8575f904ea7793893616df95ea4159a9e6400dff84c4fcfd4720f830e02f53c0f80bbb79fe5a31f7f6232f73b27df3d41717111413874e8295453d5b5101863c81e3d1229861a7895471e7d8c1706f673f0c54f00f8fecc69ba767791c9644826db504ae1a8c69edb32e49999991038d84244d05a03f0c32ff7b970fe6794a3e8eaec241e4fd0d69620168ba19ae56f6991ef71f8f0d30deac55a7ce3f3d7ad3f510e542a2e89443cc8c771a267c61883b5667b826ab58a3126b427b8ef51412ed65a8cf5b1be259188138bc5366b43a9e87775ceb6126c6c6c608c09bc513428544aa194221e8f07efc3ed6ab9d57757fd3424522814402c22166b374fbd5247299a65067542d84d8d9f356c70f9d7f3ec6a53412548add615566c58d4d4295791df35502b96abf3d7225e9ae61576f6a7ff6fe703e0499ada340e748727d1ccbec3f1806560f91fbb7804f0a352bf410000000049454e44ae426082</data> </image> <image name="image17"> <data format="PNG" length="1268">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000004bb4944415448899d945d6c145514c77f33b333bbd3fd6a77db6ea175b3b685ba0215a2822116c5060479020dc883cfc6378d09beea8baf36f1c184279f880821be9822063fa0c6a44a80d6562abb545ab6d8ddee677777667676667c68b7e91711bcc9cddc7be79effef9c7bcebdf0dfed04e03ca2bffd18f68f6c3230d4d5d5e59c3973c6999b9b73c6c7c79debd7af3b434343ced1a3471b901f809d8f2b7a08f8b2e1e191d7079c2b97cf393333d34eb15870d2f3734ea9947332e994f3f34fdf3aa74ebee19c387e7875445f00cfaf1614568ddf022e7c75ee33dada424892c8ecec43467f1b23d8dccead5b7f6218551cdb64c7ce5d9c3a7982426186e1e16b1c3e7480726591f9f905deffe05380c3c0f700d22ac0c4d7e73fa7a7b7179f3788df1fa6b468e3767bb97a7584bb7713080864b339c6c627b87f3f493cde832cb7108b3d8555d7f1799b18187881e1e16bef009f00b81aea1e8f87bebe7e4cb38ce26e4255fdc4620eb62371ecd81172b92cf7a6ef9149cf138d76100a05191f4b70e09597582c6590151997cb45c0ef5d73e62b005dd7f178bc6cdbb687546a1ad3b48844b6208a127d7d3d68d545b2d9340226ba51a15828d1b1a50db3564592447c3e3f994c8e743ab73900e0f6eddf49de9b6370f010822050abe9589680a697f1b8c3789b646cdba258ccd01cf4232b2a2d2d1134ad4e2e97e3c68d312a550d607a03201c0edfcce7d37b64596674f4573a3ba378bd3eb66c8d218a2220e0d816966d61183aba56a658cc914afdcdc4c438b3b33354ab1ad95c0120bf0190cd664746466eecd9bbd7a45cae5229ff432cf62ca5d202ba56a55235b0ad1a9a56c0aa9ba4e666c9e7b2d88e83280888a2886dc3624907b8d8d05d5d45f3636353ef1a860b555551942622edad28b24ca552c0ed16310c8d622145bdaea1aa0aa659279b2b50d50cf2f90a1393f7f9eeca8f001f010fd7df030067dfbe5ddcb93343fc996dbc7af0204fc7a2148b19e2f1ed687a0d435be0416a1e8f5b61fc8f04a5c53ac964929b37c7d8b1a387898924403350dc906480fdfb77138b45c964f25cba7401d314a8d56aa452297a7b7b4924126bf6b7b787696d0db27b771fc1a0bfb15cdcb48a0054d583cba53038f832c56285eeee1e92c92489c45dfafbfbc9641e303999a4bbbb8b52a94c3a9d231209333d9d22140aae97435cbfe0f5aa88a284cfe7c3e7f3130ab521cb0a96e5e0f5fa0885da96132aa02832b6ed601826822020491be4560022ab126edb169d9d5b912489969666e2f1388aa2a0aa4db4b575ac1807023e64d94557578440c04b7b7b785380b02c2eaffea1eb1a008a2211087888445a89463bf0f91442a100bdbd5154d58328aeaf9325b386c30d800cf856ef100461cdf7095b33e001c406c00744368bc0719cff03e804820d800bf0035180ead25b82dbed7962d54a456b0c232c45213592ab2e13c964569e112ccb7a6c714591d175a3315df14e04ea2c5d8c0cf0e1d9b317a9d70da6a6fea25c2e522a9528144a88a288284a6b4475ddc0b66d1616f298669df3e72f037c0c2c2e774b6029074d400bd00ebc08bc073c0770faf4711c47a75ad5d8bebd8f6c76816c3687699a000c0f8f3478bf00df00a32cbd430f00ad51228d4a5297610af026f01a1000061e713257804960049802ece5d3c80206e0fc0bf314013e649a83420000000049454e44ae426082</data> </image> <image name="image18"> <data format="PNG" length="1264">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000004b7494441544889a5966d4cd55518c07ff77fefe5de0b5c440411435ab3b9624d054b7b1b0e5d886e39ab594d47f689419b5b61eb83385f9a4ecbb9a69b9b73ac31ed037e725933c22591aba920306c12660433e05e8837bdf77fff6fe79c3ec0bd8081593ddbb39de77f5e7ee779ce73cef377f1ff454c6bbb1fecd4fec3824b817b93ba0ab01bbebda801f6a41def5b3a1db015508fa87776eedc19acaa7a3f08b4949614fbfafee8a1b4a4d807b41c397c20080c006d80cb350950573a23f4ebe3b4d49d64f7966234b71b252552d74173c3a49db7e975bebbdcc0c8c830e1d040c2adf1f1317c3e3fe1503f57afdda0bea13102ccf7c407182a42ef6f3d0c0d8e307ef50a44c740826359e00b206331ac400a9f6fdfc2baa2f59c3c751c80864b97f125b9793aff19c646fbd16331ea1b1a01de00bc0980522ea490f87d7e421181db4e02a9c0e5c5652b943785d5fb8e01b0a1a41880a6a626060787e8ebebe3d6ad2e2a2bcb696dbd41694931f50d8db5405202e04889f24852826ed6ec3d38ebe9ba0e7dc6a79f1c263f7f19e1d000a625e8eefe9d707890b479696cd8b899de9e6e8c258ff1ee3b6fe5d49e39379cc82237204df990e49990ea3d7b3971fc04002b57ae202b3383d4602a1feeda856918f4f587b87bb78fda33e78601e9999aaa506aa2d5d6d6868a1bd3a4b9b999cece4ecacbcba9a8aca0b7a79bfd07f6b1b2e039464786f9faabf300f133d8017c9fc8a26f3a06686efd99de2b75d4d4d4cce9415a5a1ae7eace108d448844eed3dbd30d801e8b0130101a6468f04fea1b1aa34076c20369488426494f4fffc7301d3c7494c7f316f3e5858b14bdbc86e5cbf3e9e8b8c5e51faeb2bef8c5b807002400a606528a878608e0ecd9b36cdbb68df6f6764e9f3e4d555515966d73bdb99df2dd4739f5f107f1a11b670034af22c9057a28444141c19cbb2f2c2c241a8d26ecaaaa2a3a6efe821082ecbc2779f5ed1d9cffa206a07706c0120ac372f0ad5a4b757535a669fe6d71c3517810783c53b951565686aeeb24a565e1d65c84a333e74d5d345b619a82607a2e5a461ea99a0b4748845428a5f0b835924c9b60b22f113e4dd3b01d418e3f899869e3716b38a6333b40b3412219b9a7a3691aedf5b5b870933e3f83f4cc85082110c2460a89140e0a856d98840d811c1d62edd60a9ec85900d29ac3032f48214009ba9a2ef0e6c6224a376dc6e3f1e00f244f8c518a68e43e63e3a358468c8ef6562e35df269ab1823b77ba285c918f94f6ec005038c20129d12311d6bfb2017fc0cffe7d7b181a0c0370f8c83146468630633a464ce7d9e75fa2eee24f242fc9c6760c021e85306602124f8554a014244dd6247f2099c0e4cee312b97f0fdb9a0841c6822c82a969f80301e2b7d5374bf99a7aec1c8194022924464c470a816d3b0c86434839f146599681140e29a941162e5a8cdf9f8ce3d8b89585142ec23185cf35c719dcfcf1125ebc441d896d99c4741d5dd7118e48648d69c4989f914956760e3e9f1fd33490526099165ea99052a1849815b0fae4c18faeaf7b6d3bc1f40c72972ee346cb3572737379afb282cc858b0048494d23189c87c7e3656c74985f6f77611a06a9b8119681a549542260a807412ff0e87579567daab028de2e0316018138cec54449489e54efb4efff5614137f185120f617720d5d981aea85900000000049454e44ae426082</data> </image> <image name="image19"> <data format="PNG" length="1060">89504e470d0a1a0a0000000d4948445200000018000000180806000000e0773df8000003eb494441544889bd954d485c5718869f73e77ffc99993b6a124b43a725606c2b8d85da34ad1aa3a421086dad8d2dc476d182d925e922d05dbb482981da555a2a11b110d2bf4069024203890acd08b54d145cb86b501a304653e75ee7cedc734e17e34cd4516336fd2e1fdf3d97c3fb9ef7bddf3907fec77817d08f999f019eed12e8c9c9496ddbb67e54388ea3a7a7a7755757970686013f2036025dfd51dbb64d2814dad66a92c924e170189fcf476d6d2d400870569415c2583dd80a5c6b5da84a291cc7211a8d525d5d4d5f5f1fc032105cafc42842da0058298552724d5d58b84f3018241289d0dada4a6f6f2f80bd9e64538262e0d529b12c8b40200040656525cdcdcd0c0e0e02fc0804d62b59c1d45a29a5a594da75b37a6868481f3edca4c3e1900e8743fae8d143faca955ff5b26de9fefefeadbaeb53c0c73a16adb5464a17ade1f2e59f3977ee2c274ebc4f7dfd735896cdd8d82d2e5dfa8533673ea1adb58df9f9792c2bc5ccec2c77ffb9cbeddb13584b73f4f55f0488018b4516e52db870e16b7a7aba696b3bc4eedd75b8ae64cf9ea7686f6f6560e05b96524b78bc1e028100894482babae7696a7a8d679e4ee4a1ca36fc074a2994948c8e8eb17fff8becda55cbd4d44d2ccb2695b2a9ae7e826bd746999b9bc31002d3348945a30483212a2bab08f8fd79280f80b788404aa49280c0b26ceedc992295b2b1ac5cc6e33b310c837b73f72859d907524a229132a4cca2945c83574ca014d295343636904cfe494dcdbfd8f6329665138b559148d4d0d2f22ae9741ac771c8641c0cc3402945a4bc9c7038bc066fd3366d6fef6070f027c6c727585ab288442ad8b1e349eaeb5fe2ead56b28a50a9b6f759495966cadc0952e52498e1c791dcbb21819f98debd77f07a0a1e1654e9f3ac997bd5ff1c69b6ff1dde000070ebc025a937fe4a32c9252a295c2ebf1d072f0207b6b6ae83ad64d26e3208481301e76f6f1ee0ff8e1fb8becdbf7028661e414ad1355dc455222a5c4e7f311899453555541bcc2c4344d4c3346453ccec7a74f16ec79e7d87b0c0f8fe0baee8696155be4660b1343a120f1789cd2d2525c378b408080cece0e96d369ce9fff06800f3fea61fc8f24c14060eb2eca6432398b746ec70b04c160009f2f372d4fecf57ae97cbb836824c2d9cfbf00e0fefc3ca669a294de9c20954a21a504ad41e4000d23e7a210a250fd7e3fb15894e6a6469eaddd4b3a9d66f1c1034a4a4ab75630333343b43c8cd61aad1fae58298521044a6b0c21f01806a1609078dcc4f0182c2c2ce2f7fbd05a6dad2079f30661bf40200a3681406985288cf2c402d7cd92cd6671322e8610ccfeede1af5b136c16c779fc4b7fb33c05ec84b5c7b541ee042c5f79dff012df66a4814520fd1fdf3130e729639b660000000049454e44ae426082</data> </image> </images> <connections> <connection> <sender>editNewcontact</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>editNewcontact_activated()</slot> </connection> <connection> <sender>editEditcontact</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>editEditcontact_activated()</slot> </connection> <connection> <sender>editDeletecontact</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>editDeletecontact_activated()</slot> </connection> <connection> <sender>helpContents</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>helpContents_activated()</slot> </connection> <connection> <sender>helpAbout</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>helpAbout_activated()</slot> </connection> <connection> <sender>pushButtonClose</sender> <signal>clicked()</signal> <receiver>FormMainWin</receiver> <slot>pushButtonClose_clicked()</slot> </connection> <connection> <sender>pushButtonCloseSave</sender> <signal>clicked()</signal> <receiver>FormMainWin</receiver> <slot>pushButtonCloseSave_clicked()</slot> </connection> <connection> <sender>listViewContacts</sender> <signal>clicked(QListViewItem*)</signal> <receiver>FormMainWin</receiver> <slot>listViewContacts_clicked(QListViewItem*)</slot> </connection> <connection> <sender>listViewContacts</sender> <signal>doubleClicked(QListViewItem*)</signal> <receiver>FormMainWin</receiver> <slot>listViewContacts_doubleClicked(QListViewItem*)</slot> </connection> <connection> <sender>lineEditSearchToolbar</sender> <signal>textChanged(const QString&)</signal> <receiver>FormMainWin</receiver> <slot>lineEditSearchToolbar_textChanged(const QString&)</slot> </connection> <connection> <sender>contactsExportcontacts</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsExportcontacts_activated()</slot> </connection> <connection> <sender>contactsImportcontacts</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsImportcontacts_activated()</slot> </connection> <connection> <sender>contactsSave</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsSave_activated()</slot> </connection> <connection> <sender>contactsSaveAs</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsSaveAs_activated()</slot> </connection> <connection> <sender>contactsPrintAction</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsPrintAction_activated()</slot> </connection> <connection> <sender>contactsExit</sender> <signal>activated()</signal> <receiver>FormMainWin</receiver> <slot>contactsExit_activated()</slot> </connection> </connections> <includes> <include location="local" impldecl="in implementation">MainWinContacts.ui.h</include> </includes> <slots> <slot>editNewcontact_activated()</slot> <slot>editEditcontact_activated()</slot> <slot>editDeletecontact_activated()</slot> <slot>helpContents_activated()</slot> <slot>helpAbout_activated()</slot> <slot>pushButtonClose_clicked()</slot> <slot>pushButtonCloseSave_clicked()</slot> <slot>listViewContacts_clicked( QListViewItem * )</slot> <slot>listViewContacts_doubleClicked( QListViewItem * )</slot> <slot>contactsExportcontacts_activated()</slot> <slot>listViewContacts_pressed( QListViewItem * )</slot> <slot>listViewContacts_clicked( QListViewItem *, const QPoint &, int )</slot> <slot>lineEditSearchToolbar_textChanged( const QString & )</slot> <slot>contactsImportcontacts_activated()</slot> <slot>contactsSave_activated()</slot> <slot>contactsSaveAs_activated()</slot> <slot>contactsPrintAction_activated()</slot> <slot>contactsExit_activated()</slot> </slots> <layoutdefaults spacing="6" margin="11"/> </UI> --- NEW FILE: MainWinContacts.ui.h --- /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ void Form1::editNewcontact_activated() { } void Form1::editEditcontact_activated() { } void Form1::editDeletecontact_activated() { } void Form1::helpContents_activated() { } void Form1::helpAbout_activated() { } void Form1::pushButtonClose_clicked() { } void Form1::pushButtonCloseSave_clicked() { } void Form1::listViewContacts_clicked( QListViewItem * ) { } void Form1::listViewContacts_doubleClicked( QListViewItem * ) { } void FormMainWin::contactsExportcontacts_activated() { } void FormMainWin::listViewContacts_pressed( QListViewItem * ) { } void FormMainWin::listViewContacts_clicked( QListViewItem *, const QPoint &, int ) { } void FormMainWin::lineEditSearchToolbar_textChanged( const QString & ) { } void FormMainWin::contactsImportcontacts_activated() { } void FormMainWin::contactsSave_activated() { } void FormMainWin::contactsSaveAs_activated() { } void FormMainWin::contactsPrintAction_activated() { } void FormMainWin::contactsExit_activated() { } --- NEW FILE: GuiQTgmc.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # GuiQTgmc.py # # 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 Library 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. from qt import * from MainWinContacts_forms import FormMainWin from Observers import Observer,Observable class MainWin(FormMainWin,Observable): def __init__(self, parent=None, name=None, fl=0,att=[],application=None): FormMainWin.__init__(self,parent,name,fl) Observable.__init__(self) global Qapplication# Needed for a Qprogressdialog Qapplication = application self.show() self.Myobs = Observer(self.test) self.addObserver(self.Myobs) def test(self,*args): print "test called" print "args",args def editNewcontact_activated(self): print "FormMainWin.editNewcontact_activated(): Not implemented yet" def editEditcontact_activated(self): print "FormMainWin.editEditcontact_activated(): Not implemented yet" def editDeletecontact_activated(self): print "FormMainWin.editDeletecontact_activated(): Not implemented yet" def helpContents_activated(self): print "FormMainWin.helpContents_activated(): Not implemented yet" #This callback is used for testing purposes self.notifyObservers("this is data") def helpAbout_activated(self): print "FormMainWin.helpAbout_activated(): Not implemented yet" def pushButtonClose_clicked(self): print "FormMainWin.pushButtonClose_clicked(): Not implemented yet" def pushButtonCloseSave_clicked(self): print "FormMainWin.pushButtonCloseSave_clicked(): Not implemented yet" def listViewContacts_clicked(self,a0): print "FormMainWin.listViewContacts_clicked(QListViewItem*): Not implemented yet" def listViewContacts_doubleClicked(self,a0): print "FormMainWin.listViewContacts_doubleClicked(QListViewItem*): Not implemented yet" def contactsExportcontacts_activated(self): print "FormMainWin.contactsExportcontacts_activated(): Not implemented yet" def listViewContacts_pressed(self,a0): print "FormMainWin.listViewContacts_pressed(QListViewItem*): Not implemented yet" def listViewContacts_clicked(self,a0,a1,a2): print "FormMainWin.listViewContacts_clicked(QListViewItem*,const QPoint&,int): Not implemented yet" def lineEditSearchToolbar_textChanged(self,a0): print "FormMainWin.lineEditSearchToolbar_textChanged(const QString&): Not implemented yet" def contactsImportcontacts_activated(self): print "FormMainWin.contactsImportcontacts_activated(): Not implemented yet" def contactsSave_activated(self): print "FormMainWin.contactsSave_activated(): Not implemented yet" def contactsSaveAs_activated(self): print "FormMainWin.contactsSaveAs_activated(): Not implemented yet" def contactsPrintAction_activated(self): print "FormMainWin.contactsPrintAction_activated(): Not implemented yet" def contactsExit_activated(self): print "FormMainWin.contactsExit_activated(): Not implemented yet" --- NEW FILE: Observers.py --- # -*- coding: latin-1 -*- # Copyright (c) 2005 Stas Zykiewicz <st...@li...> # # Observers.py # # 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 h... [truncated message content] |
|
From: Stas Z. <sta...@us...> - 2005-06-12 06:17:09
|
Update of /cvsroot/gmailagent/GA-libgmail2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26164 Removed Files: testlibgmail2_stas.py Log Message: removed obsolete test suite example from stas. Added the QT frontend stuff in a separate directory. --- testlibgmail2_stas.py DELETED --- |
|
From: Stas Z. <sta...@us...> - 2005-06-12 06:12:57
|
Update of /cvsroot/gmailagent/GA-libgmail2/frontend In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25864/frontend Log Message: Directory /cvsroot/gmailagent/GA-libgmail2/frontend added to the repository |