[ADD] outlook module: taken outlook plugin from trunk-extra-addons

bzr revid: hmo@tinyerp.com-20100803140656-ugtgo0w4lzvplbo3
This commit is contained in:
Mod2 Team (OpenERP) 2010-08-03 19:36:56 +05:30 committed by Harry (OpenERP)
parent d264f31bb3
commit 12f6b99419
21 changed files with 9565 additions and 0 deletions

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

View File

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name" : "Accounting and Financial Management",
"version" : "1.1",
"author" : "OpenERP SA",
"category": 'Generic Modules/Accounting',
"description": """Financial and accounting module that covers:
General accountings
Cost / Analytic accounting
Third party accounting
Taxes management
Budgets
Customer and Supplier Invoices
Bank statements
Reconciliation process by partner
Creates a dashboards for accountants that includes:
* List of uninvoiced quotations
* Graph of aged receivables
* Graph of aged incomes
The processes like maintaining of general ledger is done through the defined financial Journals (entry move line or
grouping is maintained through journal) for a particular financial year and for preparation of vouchers there is a
module named account_vouchers
""",
'website': 'http://www.openerp.com',
'init_xml': [],
"depends" : ["product", "analytic", "process","board"],
'update_xml': [
#'test/test_parent_structure.yml',
'security/account_security.xml',
'security/ir.model.access.csv',
'account_menuitem.xml',
'account_wizard.xml',
'wizard/account_statement_from_invoice_view.xml',
'wizard/account_move_bank_reconcile_view.xml',
'wizard/account_use_model_view.xml',
'account_view.xml',
'account_report.xml',
'wizard/account_report_common_view.xml',
'wizard/account_invoice_refund_view.xml',
'wizard/account_period_close_view.xml',
'wizard/account_fiscalyear_close_state.xml',
'wizard/account_chart_view.xml',
'wizard/account_move_journal_view.xml',
'wizard/account_move_line_reconcile_select_view.xml',
'wizard/account_open_closed_fiscalyear_view.xml',
'wizard/account_move_line_unreconcile_select_view.xml',
'wizard/account_vat_view.xml',
'wizard/account_report_print_journal_view.xml',
'wizard/account_report_general_journal_view.xml',
'wizard/account_report_central_journal_view.xml',
'wizard/account_subscription_generate_view.xml',
'wizard/account_fiscalyear_close_view.xml',
'wizard/account_state_open_view.xml',
'wizard/account_journal_select_view.xml',
'wizard/account_change_currency_view.xml',
'wizard/account_validate_move_view.xml',
'wizard/account_pay_invoice_view.xml',
'wizard/account_unreconcile_view.xml',
'wizard/account_report_general_ledger_view.xml',
'wizard/account_invoice_state_view.xml',
'wizard/account_report_partner_balance_view.xml',
'wizard/account_report_account_balance_view.xml',
# 'wizard/account_move_line_select_view.xml',
'wizard/account_report_aged_partner_balance_view.xml',
'wizard/account_compare_account_balance_report_view.xml',
'wizard/account_report_partner_ledger_view.xml',
'wizard/account_reconcile_view.xml',
'wizard/account_reconcile_partner_process_view.xml',
'wizard/account_automatic_reconcile_view.xml',
'project/wizard/project_account_analytic_line_view.xml',
'account_end_fy.xml',
'account_invoice_view.xml',
'partner_view.xml',
'data/account_invoice.xml',
'data/account_data2.xml',
'account_invoice_workflow.xml',
'project/project_view.xml',
'project/project_report.xml',
'project/wizard/account_analytic_check_view.xml',
'project/wizard/account_analytic_balance_report_view.xml',
'project/wizard/account_analytic_cost_ledger_view.xml',
'project/wizard/account_analytic_inverted_balance_report.xml',
'project/wizard/account_analytic_journal_report_view.xml',
'project/wizard/account_analytic_cost_ledger_for_journal_report_view.xml',
'project/wizard/account_analytic_chart_view.xml',
'product_view.xml',
'account_assert_test.xml',
'process/statement_process.xml',
'process/customer_invoice_process.xml',
'process/supplier_invoice_process.xml',
'sequence_view.xml',
'company_view.xml',
'account_installer.xml',
'report/account_invoice_report_view.xml',
'report/account_entries_report_view.xml',
'report/account_report_view.xml',
'report/account_analytic_report_view.xml',
'report/account_account_report_view.xml',
'report/account_analytic_entries_report_view.xml',
'board_account_view.xml',
"wizard/account_report_profit_loss_view.xml",
"wizard/account_report_balance_sheet_view.xml"
],
'demo_xml': [
#'demo/price_accuracy00.yml',
'account_demo.xml',
'project/project_demo.xml',
'project/analytic_account_demo.xml',
'demo/account_minimal.xml',
'account_unit_test.xml',
'board_account_demo.xml',
],
'test': [
'test/account_customer_invoice.yml',
'test/account_supplier_invoice.yml',
'test/account_change_currency.yml',
'test/chart_of_account.yml',
'test/account_period_close.yml',
'test/account_fiscalyear_close_state.yml',
#'test/account_invoice_state.yml',
'test/account_use_model.yml',
'test/account_validate_account_move.yml',
'test/account_fiscalyear_close.yml',
],
'installable': True,
'active': False,
'certificate': '0080331923549',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

204
addons/outlook/plugin/addin.py Executable file
View File

@ -0,0 +1,204 @@
#!/usr/bin/python
#-*- encoding: utf-8 -*-
from win32com import universal
from win32com.server.exception import COMException
from win32com.client import gencache, DispatchWithEvents
import winerror
import pythoncom
from win32com.client import constants
import sys
import os
from win32com.client import Dispatch
import win32con
sys.path.append(os.path.abspath(os.path.dirname(__file__))) #outlook
sys.path.append(os.path.abspath(__file__)) #outlook/addin
import manager
from win32com.client import CastTo
import win32ui
from tiny_xmlrpc import *
import locale
locale.setlocale(locale.LC_NUMERIC, "C")
# Support for COM objects we use.
gencache.EnsureModule('{00062FFF-0000-0000-C000-000000000046}', 0, 9, 0, bForDemand=True) # Outlook 9
gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 1, bForDemand=True) # Office 9
# The TLB defiining the interfaces we implement
universal.RegisterInterfaces('{AC0714F2-3D04-11D1-AE7D-00A0C90F26F4}', 0, 1, 0, ["_IDTExtensibility2"])
global NewConn
# Retrieves registered XMLRPC connection
def GetConn():
d=Dispatch("Python.OpenERP.XMLRpcConn")
mngr = manager.GetManager()
return d
class ButtonEvent:
def OnClick(self, button, cancel):
mngr = manager.GetManager()
mngr.ShowManager()
return cancel
#
class ViewPartners:
def OnClick(self, button, cancel):
from win32com.client import Dispatch
import win32con
mngr = manager.GetManager()
data=mngr.LoadConfig()
outlook = Dispatch("Outlook.Application")
ex = outlook.ActiveExplorer()
if ex:
is_login = str(data['login'])
if is_login == 'False':
win32ui.MessageBox("Please login to the database first", "Database Connection", win32con.MB_ICONEXCLAMATION)
elif ex.Selection.Count == 1 or ex.Selection.Count == 0:
mngr = manager.GetManager()
mngr.ShowManager("IDD_VIEW_PARTNER_DIALOG")
elif ex.Selection.Count > 1:
win32ui.MessageBox("Multiple selection not allowed. Please select only one mail at a time.","",win32con.MB_ICONINFORMATION)
return cancel
#
class ArchiveEvent:
def OnClick(self, button, cancel):
from win32com.client import Dispatch
import win32con
mngr = manager.GetManager()
data=mngr.LoadConfig()
outlook = Dispatch("Outlook.Application")
ex = outlook.ActiveExplorer()
if ex:
is_login = str(data['login'])
if is_login == 'False':
win32ui.MessageBox("Please login to the database first", "Database Connection", win32con.MB_ICONEXCLAMATION)
elif ex.Selection.Count == 1:
mngr = manager.GetManager()
mngr.ShowManager("IDD_SYNC")
elif ex.Selection.Count == 0:
win32ui.MessageBox("No mail selected to archive to OpenERP","",win32con.MB_ICONINFORMATION)
elif ex.Selection.Count > 1:
win32ui.MessageBox("Multiple selection not allowed. Please select only one mail at a time.","",win32con.MB_ICONINFORMATION)
return cancel
#
class OutlookAddin:
_com_interfaces_ = ['_IDTExtensibility2']
_public_methods_ = ['OnConnection','GetAppDataPath']
_reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
_reg_clsid_ = "{0F47D9F3-598B-4d24-B7E3-92AC15ED27E8}"
_reg_progid_ = "Python.OpenERP.OutlookAddin"
_reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"
def OnConnection(self, application, connectMode, addin, custom):
# ActiveExplorer may be none when started without a UI (eg, WinCE synchronisation)
activeExplorer = application.ActiveExplorer()
if activeExplorer is not None:
bars = activeExplorer.CommandBars
menu_bar = bars.Item("Menu Bar")
tools_menu = menu_bar.Controls(5)
tools_menu = CastTo(tools_menu, "CommandBarPopup")
item = tools_menu.Controls.Add(Type=constants.msoControlButton, Temporary=True)
# Hook events for the item
item = self.menu_bar_Button = DispatchWithEvents(item, ButtonEvent)
item.Caption="OpenERP Configuration"
item.TooltipText = "Click to configure OpenERP"
item.Enabled = True
item = tools_menu.Controls.Add(Type=constants.msoControlButton, Temporary=True)
# Hook events for the item
item = self.menu_bar_arch_Button = DispatchWithEvents(item, ArchiveEvent)
item.Caption="Archive to OpenERP"
item.TooltipText = "Click to archive to OpenERP"
item.Enabled = True
toolbar = bars.Item("Standard")
item = toolbar.Controls.Add(Type=constants.msoControlButton, Temporary=True)
# Hook events for the item
item = self.toolbarButton = DispatchWithEvents(item, ArchiveEvent)
item.Caption="Archive to OpenERP"
item.TooltipText = "Click to archive to OpenERP"
item.Enabled = True
# Adding Menu in Menu Bar to the Web Menu of the Outlook
toolbarweb = bars.Item("Web")
# Hook events for the item
item = toolbarweb.Controls.Add(Type = constants.msoControlButton, Temporary = True)
item = self.toolbarButtonPartner = DispatchWithEvents(item, ViewPartners)
item.Caption = "Open Contact"
item.TooltipText = "Click to Open OpenERP Partner Contact Information."
item.Enabled = True
item = tools_menu.Controls.Add(Type=constants.msoControlButton, Temporary=True)
# Hook events for the item
item = self.menu_bar_viewpartner_Button = DispatchWithEvents(item, ViewPartners)
item.Caption = "Open Contact"
item.TooltipText = "Click to Open Partner detail"
item.Enabled = True
def OnDisconnection(self, mode, custom):
mngr = manager.GetManager()
mngr.config['login'] = False
mngr.SaveConfig()
print "OnDisconnection"
def OnAddInsUpdate(self, custom):
print "OnAddInsUpdate", custom
def OnStartupComplete(self, custom):
print "OnStartupComplete", custom
def OnBeginShutdown(self, custom):
print "OnBeginShutdown", custom
def GetAppDataPath(self):
mngr = manager.GetManager()
return mngr.data_directory
def RegisterAddin(klass):
import _winreg
key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Outlook\\Addins")
subkey = _winreg.CreateKey(key, klass._reg_progid_)
_winreg.SetValueEx(subkey, "CommandLineSafe", 0, _winreg.REG_DWORD, 0)
_winreg.SetValueEx(subkey, "LoadBehavior", 0, _winreg.REG_DWORD, 3)
_winreg.SetValueEx(subkey, "Description", 0, _winreg.REG_SZ, klass._reg_progid_)
_winreg.SetValueEx(subkey, "FriendlyName", 0, _winreg.REG_SZ, klass._reg_progid_)
def UnregisterAddin(klass):
import _winreg
try:
_winreg.DeleteKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Outlook\\Addins\\" + klass._reg_progid_)
except WindowsError:
pass
def UnregisterXMLConn(klass):
import _winreg
try:
_winreg.DeleteKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Outlook\\Addins\\XMLConnection" + klass._reg_progid_)
except WindowsError:
pass
def RegisterXMLConn(klass):
import _winreg
key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Outlook\\Addins\\XMLConnection")
subkey = _winreg.CreateKey(key, klass._reg_progid_)
_winreg.SetValueEx(subkey, "CommandLineSafe", 0, _winreg.REG_DWORD, 0)
_winreg.SetValueEx(subkey, "LoadBehavior", 0, _winreg.REG_DWORD, 3)
_winreg.SetValueEx(subkey, "Description", 0, _winreg.REG_SZ, klass._reg_progid_)
_winreg.SetValueEx(subkey, "FriendlyName", 0, _winreg.REG_SZ, klass._reg_progid_)
if __name__ == '__main__':
import win32com.server.register
NewConn=XMLRpcConn()
win32com.server.register.UseCommandLine(OutlookAddin)
win32com.server.register.UseCommandLine(NewConn)
if "--unregister" in sys.argv:
UnregisterAddin(OutlookAddin)
UnregisterXMLConn(NewConn)
else:
RegisterAddin(OutlookAddin)
RegisterXMLConn(NewConn)
#mngr = manager.GetManager()
#mngr.ShowManager("IDD_MANAGER")

5469
addons/outlook/plugin/chilkat.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
# This package defines dialog boxes used by the main
import os, sys, stat
#import dialog_map
def LoadDialogs(rc_name = "dialogs.rc"):
base_name = os.path.splitext(rc_name)[0]
mod_name = "dialogs.resources." + base_name
mod = None
# If we are running from source code, check the .py file is up to date
# wrt the .rc file passed in.
# If we are running from binaries, the rc name is not used at all - we
# assume someone running from source previously generated the .py!
if not hasattr(sys, "frozen"):
from resources import rc2py
rc_path = os.path.dirname( rc2py.__file__ )
if not os.path.isabs(rc_name):
rc_name = os.path.join( rc_path, rc_name)
py_name = os.path.join(rc_path, base_name + ".py")
mtime = size = None
if os.path.exists(py_name):
try:
mod = __import__(mod_name)
mod = sys.modules[mod_name]
mtime = mod._rc_mtime_
size = mod._rc_size_
except (ImportError, AttributeError):
mtime = None
try:
stat_data = os.stat(rc_name)
rc_mtime = stat_data[stat.ST_MTIME]
rc_size = stat_data[stat.ST_SIZE]
except OSError:
rc_mtime = rc_size = None
if rc_mtime!=mtime or rc_size!=size:
# Need to generate the dialog.
print "Generating %s from %s" % (py_name, rc_name)
rc2py.convert(rc_name, py_name)
if mod is not None:
reload(mod)
if mod is None:
mod = __import__(mod_name)
mod = sys.modules[mod_name]
return mod.FakeParser()
def ShowDialog(parent, manager, config, idd):
"""Displays another dialog"""
if manager.dialog_parser is None:
manager.dialog_parser = LoadDialogs()
import dialog_map
print dir(dialog_map)
commands = dialog_map.dialog_map[idd]
if not parent:
import win32gui
try:
parent = win32gui.GetActiveWindow()
except win32gui.error:
pass
import dlgcore
dlg = dlgcore.ProcessorDialog(parent, manager, config, idd, commands)
return dlg.DoModal()
def MakePropertyPage(parent, manager, config, idd, yoffset=24):
"""Creates a child dialog box to use as property page in a tab control"""
if manager.dialog_parser is None:
manager.dialog_parser = LoadDialogs()
import dialog_map
commands = dialog_map.dialog_map[idd]
if not parent:
raise "Parent must be the tab control"
import dlgcore
dlg = dlgcore.ProcessorPage(parent, manager, config, idd, commands, yoffset)
return dlg
import dlgutils
SetWaitCursor = dlgutils.SetWaitCursor

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,319 @@
# A core, data-driven dialog.
# Driven completely by "Control Processor" objects.
import win32gui, win32api, win32con
import commctrl
import struct, array
from dlgutils import *
# Isolate the nasty stuff for tooltips somewhere.
class TooltipManager:
def __init__(self, dialog):
self.dialog = dialog
self.hwnd_tooltip = None
self.tooltip_tools = {}
def HideTooltip(self):
if self.hwnd_tooltip is not None:
win32gui.SendMessage(self.hwnd_tooltip, commctrl.TTM_TRACKACTIVATE, 0, 0)
def ShowTooltipForControl(self, control_id, text):
# Note sure this tooltip stuff is quite right!
# Hide an existing one, so the new one gets created.
# (new one empty is no big deal, but hiding the old one is, so
# we get re-queried for the text.
hwnd_dialog = self.dialog.hwnd
self.HideTooltip()
if self.hwnd_tooltip is None:
TTS_BALLOON = 0x40
self.hwnd_tooltip = win32gui.CreateWindowEx(0, "tooltips_class32", None,
win32con.WS_POPUP | TTS_BALLOON,
win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
hwnd_dialog, 0, 0, None)
# 80 chars max for our tooltip
# hrm - how to measure this in pixels!
win32gui.SendMessage(self.hwnd_tooltip,
commctrl.TTM_SETMAXTIPWIDTH,
0, 300)
format = "iiiiiiiiiii"
tt_size = struct.calcsize(format)
buffer = array.array("c", text + "\0")
text_address, size = buffer.buffer_info()
uID = control_id
flags = commctrl.TTF_TRACK | commctrl.TTF_ABSOLUTE
data = struct.pack(format, tt_size, flags, hwnd_dialog, uID, 0,0,0,0, 0, text_address, 0)
# Add a tool for this control only if we haven't already
if control_id not in self.tooltip_tools:
win32gui.SendMessage(self.hwnd_tooltip,
commctrl.TTM_ADDTOOL,
0, data)
self.tooltip_tools[control_id] = 1
control = win32gui.GetDlgItem(hwnd_dialog, control_id)
child_rect = win32gui.GetWindowRect(control)
xOff = yOff = 15 # just below and right of the control
win32gui.SendMessage(self.hwnd_tooltip,
commctrl.TTM_TRACKPOSITION,
0,
MAKELONG(child_rect[0]+xOff, child_rect[1]+yOff))
win32gui.SendMessage(self.hwnd_tooltip,
commctrl.TTM_TRACKACTIVATE,
1,data)
# A base dialog class, that loads from resources. Has no real smarts.
class Dialog:
def __init__(self, parent, parser, idd):
win32gui.InitCommonControls()
self.hinst = win32api.GetModuleHandle(None)
self.parent = parent
self.dialog_parser = parser
self.template = parser.dialogs[idd]
def _GetIDName(self, cid):
return self.dialog_parser.names.get(cid, str(cid))
def CreateWindow(self):
return self._DoCreate(win32gui.CreateDialogIndirect)
def DoModal(self):
return self._DoCreate(win32gui.DialogBoxIndirect)
def GetMessageMap(self):
ret = {
win32con.WM_COMMAND: self.OnCommand,
win32con.WM_NOTIFY: self.OnNotify,
win32con.WM_INITDIALOG: self.OnInitDialog,
win32con.WM_CLOSE: self.OnClose,
win32con.WM_DESTROY: self.OnDestroy,
win32con.WM_RBUTTONUP: self.OnRButtonUp,
}
return ret
def DoInitialPosition(self):
# centre the dialog
desktop = win32gui.GetDesktopWindow()
l,t,r,b = win32gui.GetWindowRect(self.hwnd)
w = r-l
h = b-t
dt_l, dt_t, dt_r, dt_b = win32gui.GetWindowRect(desktop)
centre_x, centre_y = win32gui.ClientToScreen( desktop, ( (dt_r-dt_l)/2, (dt_b-dt_t)/2) )
win32gui.MoveWindow(self.hwnd, centre_x-(w/2), centre_y-(h/2), w, h, 0)
def OnInitDialog(self, hwnd, msg, wparam, lparam):
self.hwnd = hwnd
self.DoInitialPosition()
def OnCommand(self, hwnd, msg, wparam, lparam):
pass
def OnNotify(self, hwnd, msg, wparam, lparam):
pass
def OnClose(self, hwnd, msg, wparam, lparam):
pass
def OnDestroy(self, hwnd, msg, wparam, lparam):
pass
def OnRButtonUp(self, hwnd, msg, wparam, lparam):
pass
def _DoCreate(self, fn):
message_map = self.GetMessageMap()
return win32gui.DialogBoxIndirect(self.hinst, self.template, self.parent, message_map)
# A couple of helpers
def GetDlgItem(self, id):
if type(id)==type(''):
id = self.dialog_parser.ids[id]
return win32gui.GetDlgItem(self.hwnd, id)
def SetDlgItemText(self, id, text):
hchild = self.GetDlgItem(id)
win32gui.SendMessage(hchild, win32con.WM_SETTEXT, 0, text)
# A dialog with a tooltip manager
class TooltipDialog(Dialog):
def __init__(self, parent, parser, idd):
Dialog.__init__(self, parent, parser, idd)
self.tt = TooltipManager(self)
def GetMessageMap(self):
ret = Dialog.GetMessageMap(self)
ret.update( {
win32con.WM_HELP: self.OnHelp,
win32con.WM_LBUTTONDOWN: self.OnLButtonDown,
win32con.WM_ACTIVATE: self.OnActivate,
})
return ret
def OnLButtonDown(self, hwnd, msg, wparam, lparam):
self.tt.HideTooltip()
def OnActivate(self, hwnd, msg, wparam, lparam):
self.tt.HideTooltip()
def OnDestroy(self, hwnd, msg, wparam, lparam):
self.tt.HideTooltip()
def OnHelp(self, hwnd, msg, wparam, lparam):
format = "iiiiiii"
buf = win32gui.PyMakeBuffer(struct.calcsize(format), lparam)
cbSize, iContextType, iCtrlId, hItemHandle, dwContextID, x, y = \
struct.unpack(format, buf)
tt_text = self.GetPopupHelpText(iCtrlId)
if tt_text:
self.tt.ShowTooltipForControl(iCtrlId, tt_text)
else:
self.tt.HideTooltip()
return 1
def GetPopupHelpText(self, control_id):
return None
# A "Processor Dialog" works with Command Processors, to link Outlook-Plugin
# options with control IDS, giving a "data driven" dialog.
class ProcessorDialog(TooltipDialog):
def __init__(self, parent, manager, config, idd, option_handlers):
TooltipDialog.__init__(self, parent, manager.dialog_parser, idd)
parser = manager.dialog_parser
self.manager = manager
self.config = config
self.command_processors = {}
self.processor_message_map = {}
self.all_processors = []
for data in option_handlers:
klass = data[0]
id_names = data[1]
rest = data[2:]
ids = id_names.split()
int_ids = [ parser.ids[id] for id in ids]
instance = klass(self,int_ids, *rest)
self.all_processors.append(instance)
for int_id in int_ids:
self.command_processors[int_id] = instance
for message in instance.GetMessages():
existing = self.processor_message_map.setdefault(message, [])
existing.append(instance)
def GetMessageMap(self):
ret = TooltipDialog.GetMessageMap(self)
for key in self.processor_message_map.keys():
if key in ret:
print "*** WARNING: Overwriting message!!!"
ret[key] = self.OnCommandProcessorMessage
return ret
def OnInitDialog(self, hwnd, msg, wparam, lparam):
TooltipDialog.OnInitDialog(self, hwnd, msg, wparam, lparam)
if __debug__: # this is just a debugging aid
for int_id in self.command_processors:
try:
self.GetDlgItem(int_id)
except win32gui.error:
print "ERROR: Dialog item %s refers to an invalid control" % \
self._GetIDName(int_id)
self.LoadAllControls()
def GetPopupHelpText(self, iCtrlId):
cp = self.command_processors.get(iCtrlId)
tt_text = None
if cp is not None:
return cp.GetPopupHelpText(iCtrlId)
print "Can not get command processor for", self._GetIDName(iCtrlId)
return None
def OnRButtonUp(self, hwnd, msg, wparam, lparam):
for cp in self.command_processors.values():
cp.OnRButtonUp(wparam,lparam)
def OnCommandProcessorMessage(self, hwnd, msg, wparam, lparam):
for p in self.processor_message_map[msg]:
p.OnMessage(msg, wparam, lparam)
# Called back by a processor when it changes an option. We tell all other
# options on our page that the value changed.
def OnOptionChanged(self, changed_by, option):
for p in self.all_processors:
if p is not changed_by:
p.OnOptionChanged(option)
def OnDestroy(self, hwnd, msg, wparam, lparam):
for p in self.all_processors:
p.Term()
TooltipDialog.OnDestroy(self, hwnd, msg, wparam, lparam)
self.command_processors = None
self.all_processors = None
self.processor_message_map = None
def LoadAllControls(self):
for p in self.all_processors:
p.Init()
def ApplyHandlingOptionValueError(self, func, *args):
try:
return func(*args)
except ValueError, why:
mb_flags = win32con.MB_ICONEXCLAMATION | win32con.MB_OK
win32gui.MessageBox(self.hwnd, str(why), "OpenERP Configuration", mb_flags)
return False
def SaveAllControls(self):
for p in self.all_processors:
if not self.ApplyHandlingOptionValueError(p.Done):
win32gui.SetFocus(p.GetControl())
return False
return True
def OnClose(self, hwnd, msg, wparam, lparam):
if TooltipDialog.OnClose(self, hwnd, msg, wparam, lparam):
return 1
if not self.SaveAllControls():
return 1
win32gui.EndDialog(hwnd, 0)
def OnNotify(self, hwnd, msg, wparam, lparam):
# Parse the NMHDR
TooltipDialog.OnNotify(self, hwnd, msg, wparam, lparam)
format = "iii"
buf = win32gui.PyMakeBuffer(struct.calcsize(format), lparam)
hwndFrom, idFrom, code = struct.unpack(format, buf)
code += 0x4f0000 # hrm - wtf - commctrl uses this, and it works with mfc. *sigh*
# delegate rest to our commands.
self._GetIDName(idFrom)
if self.command_processors is not None:
handler = self.command_processors.get(idFrom)
if handler is None:
print "Ignoring OnNotify for", self._GetIDName(idFrom)
return
return handler.OnNotify( (hwndFrom, idFrom, code), wparam, lparam)
return
def OnCommand(self, hwnd, msg, wparam, lparam):
TooltipDialog.OnCommand(self, hwnd, msg, wparam, lparam)
id = win32api.LOWORD(wparam)
# Sometimes called after OnDestroy???
if self.command_processors is None:
print "Ignoring OnCommand for", self._GetIDName(id)
return
else:
handler = self.command_processors.get(id)
if handler is None:
print "Ignoring OnCommand for", self._GetIDName(id)
return
self.ApplyHandlingOptionValueError(handler.OnCommand, wparam, lparam)
class ProcessorPage(ProcessorDialog):
def __init__(self, parent, manager, config, idd, option_handlers, yoffset):
ProcessorDialog.__init__(self, parent, manager, config, idd,option_handlers)
self.yoffset = yoffset
def DoInitialPosition(self):
# The hardcoded values are a bit of a hack.
win32gui.SetWindowPos(self.hwnd, win32con.HWND_TOP, 1, self.yoffset, 0, 0, win32con.SWP_NOSIZE)
def CreateWindow(self):
# modeless. Pages should have the WS_CHILD window style
message_map = self.GetMessageMap()
# remove frame from dialog and make sure it is a child
self.template[0][2] = self.template[0][2] & ~(win32con.DS_MODALFRAME|win32con.WS_POPUP|win32con.WS_OVERLAPPED|win32con.WS_CAPTION)
self.template[0][2] = self.template[0][2] | win32con.WS_CHILD
return win32gui.CreateDialogIndirect(self.hinst, self.template, self.parent, message_map)

View File

@ -0,0 +1,14 @@
# Generic utilities for dialog functions.
def MAKELONG(l,h):
return ((h & 0xFFFF) << 16) | (l & 0xFFFF)
MAKELPARAM=MAKELONG
def SetWaitCursor(wait):
import win32gui, win32con
if wait:
hCursor = win32gui.LoadCursor(0, win32con.IDC_WAIT)
else:
hCursor = win32gui.LoadCursor(0, 0)
win32gui.SetCursor(hCursor)

View File

@ -0,0 +1,287 @@
# Option Control Processors for our dialog.
# These are extensions to basic Control Processors that are linked with
# Outlook-Plugin options.
import win32gui, win32api, win32con, win32ui
import commctrl
import struct, array
from dlgutils import *
import xmlrpclib
import processors
verbose = 0 # set to 1 to see option values fetched and set.
# A ControlProcessor that is linked up with options. These get a bit smarter.
class OptionControlProcessor(processors.ControlProcessor):
def __init__(self, window, control_ids):
processors.ControlProcessor.__init__(self, window, control_ids)
def GetPopupHelpText(self, idFrom):
doc = " ".join(self.option.doc().split())
if self.option.default_value:
doc += " (the default value is %s)" % self.option.default_value
return doc
# We override Init, and break it into 2 steps.
def Init(self):
self.UpdateControl_FromValue()
def Done(self):
self.UpdateValue_FromControl()
return True
# # Only sub-classes know how to update their controls from the value.
def UpdateControl_FromValue(self):
raise NotImplementedError
def UpdateValue_FromControl(self):
raise NotImplementedError
class ComboProcessor(OptionControlProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
OptionControlProcessor.__init__(self, window, control_ids)
def OnCommand(self, wparam, lparam):
code = win32api.HIWORD(wparam)
if code == win32con.CBN_SELCHANGE:
self.UpdateValue_FromControl()
def Init(self):
self.UpdateControl_FromValue()
def UpdateControl_FromValue(self):
pass
def UpdateValue_FromControl(self):
pass
class DBComboProcessor(ComboProcessor):
def Init(self):
self.UpdateControl_FromValue()
def UpdateControl_FromValue(self):
combo = self.GetControl()
conn = self.func()
list = conn.GetDBList()
db = conn.getitem('_dbname')
if list == -1:
hinst = win32gui.dllhandle
parent = self.window.hwnd
dwStyle = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_TABSTOP | win32con.WS_BORDER | \
win32con.ES_AUTOHSCROLL | win32con.FF_ROMAN | win32con.FW_EXTRALIGHT
hwndImg = win32gui.CreateWindow (
"EDIT",
db,
dwStyle,
67,80,180,20,
parent,
7000,
0,
None);
self.active_control_id = 7000
win32gui.ShowWindow(combo, False)
else:
try:
txtbx = win32gui.GetDlgItem(self.window.hwnd, 7000)
win32gui.DestroyWindow(txtbx)
except Exception,e:
print "Exception : %s"%str(e)
pass
win32gui.ShowWindow(combo, True)
win32gui.SendMessage(combo, win32con.CB_RESETCONTENT,0, 0);
for item in list:
win32gui.SendMessage(combo, win32con.CB_ADDSTRING, 0, str(item))
sel = win32gui.SendMessage(combo, win32con.CB_SELECTSTRING, 0, db)
dbb=win32gui.GetDlgItemText(self.window.hwnd, 2004)
if sel == -1:
win32gui.SendMessage(combo, win32con.CB_SETCURSEL, 0, 0)
self.active_control_id = self.control_id
def UpdateValue_FromControl(self):
db = win32gui.GetDlgItemText(self.window.hwnd, self.active_control_id)
conn = self.func()
if conn.getitem('_dbname') != db:
conn.setitem('_dbname', db)
conn.setitem('_login', 'False')
class PartnersComboProcessor(ComboProcessor):
def UpdateControl_FromValue(self):
from manager import ustr
import win32ui
combo = self.GetControl()
conn = self.func()
win32gui.SendMessage(combo, win32con.CB_RESETCONTENT,0, 0);
id_list = {}
p_list=[]
try:
p_list = list(conn.GetPartners())
cnt=0
for item in p_list:
win32gui.SendMessage(combo, win32con.CB_ADDSTRING, 0, ustr(item[1]).encode('iso-8859-1'))
id_list[cnt] = item[0]
cnt+=1
conn.setitem('partner_id_list', str(id_list))
cnt = win32gui.SendMessage(combo, win32con.CB_GETCOUNT, 0, 0)
win32gui.SendMessage(combo, win32con.CB_SETCURSEL, -1, 0)
return
except xmlrpclib.Fault,e:
msg = str(e.faultCode) or e.faultString or e.message or str(e)
except Exception,e:
msg = str(e)
win32ui.MessageBox(str(e),"Partners",win32con.MB_ICONEXCLAMATION)
win32gui.DestroyWindow(self.window.hwnd)
def UpdateValue_FromControl(self):
combo = self.GetControl()
conn = self.func()
sel = win32gui.SendMessage(combo, win32con.CB_GETCURSEL)
conn.setitem('sel_id', sel)
class StateComboProcessor(ComboProcessor):
def Init(self):
self.UpdateControl_FromValue()
def UpdateControl_FromValue(self):
from manager import ustr
import win32ui
combo = self.GetControl()
conn = self.func()
win32gui.SendMessage(combo, win32con.CB_RESETCONTENT, 0, 0);
id_list = {}
state_list=[]
try:
state_list = list(conn.GetAllState())
for item in state_list:
win32gui.SendMessage(combo, win32con.CB_ADDSTRING, 0, ustr(item[1]).encode('iso-8859-1'))
win32gui.SendMessage(combo, win32con.CB_SETCURSEL, -1, 0)
cnt = win32gui.SendMessage(combo, win32con.CB_GETCOUNT, 0, 0)
return
except xmlrpclib.Fault,e:
msg = str(e.faultCode) or e.faultString or e.message or str(e)
win32ui.MessageBox(msg, "Open Partner")
except Exception,e:
win32ui.MessageBox(str(e), "Open Partner")
def UpdateValue_FromControl(self):
pass
class CountryComboProcessor(ComboProcessor):
def Init(self):
self.UpdateControl_FromValue()
def UpdateControl_FromValue(self):
from manager import ustr
import win32ui
combo = self.GetControl()
conn = self.func()
win32gui.SendMessage(combo, win32con.CB_RESETCONTENT, 0, 0);
id_list = {}
state_list=[]
try:
country_list = list(conn.GetAllCountry())
for item in country_list:
win32gui.SendMessage(combo, win32con.CB_ADDSTRING, 0, ustr(item[1]).encode('iso-8859-1'))
win32gui.SendMessage(combo, win32con.CB_SETCURSEL, -1, 0)
cnt = win32gui.SendMessage(combo, win32con.CB_GETCOUNT, 0, 0)
return
except xmlrpclib.Fault,e:
msg = str(e.faultCode) or e.faultString or e.message or str(e)
win32ui.MessageBox(msg, "Open Partner")
except Exception,e:
win32ui.MessageBox(str(e), "Open Partner")
def UpdateValue_FromControl(self):
pass
class CSComboProcessor(ComboProcessor):
def UpdateControl_FromValue(self):
combo = self.GetControl()
conn = self.func()
if str(conn.getitem('_iscrm')) == 'False':
win32gui.EnableWindow(combo, False)
return
try:
list=['CRM Lead']#, 'CRM Helpdesk', 'CRM Lead', 'CRM Meeting', 'CRM Opportunity', 'CRM Phonecall']
objlist = conn.GetAllObjects()
if 'crm.claim' in objlist:
list.append('CRM Claim')
if 'crm.helpdesk' in objlist:
list.append('CRM Helpdesk')
if 'crm.fundraising' in objlist:
list.append('CRM Fundraising')
if'hr.applicant' in objlist:
list.append('HR Applicant')
if'project.issue' in objlist:
list.append('Project Issue')
win32gui.SendMessage(combo, win32con.CB_RESETCONTENT,0, 0);
for item in list:
win32gui.SendMessage(combo, win32con.CB_ADDSTRING, 0, str(item))
win32gui.SendMessage(combo, win32con.CB_SETCURSEL, 0, 0)
return
except xmlrpclib.Fault,e:
win32ui.MessageBox(str(e.faultCode),"CRM Case",win32con.MB_ICONEXCLAMATION)
except Exception,e:
win32ui.MessageBox(str(e),"CRM Case",win32con.MB_ICONEXCLAMATION)
def UpdateValue_FromControl(self):
pass
class TextProcessor(OptionControlProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
OptionControlProcessor.__init__(self, window, control_ids)
def UpdateControl_FromValue(self):
args = (self,)+(self.window,) + self.args
self.func(*args)
def UpdateValue_FromControl(self):
pass
class ListBoxProcessor(OptionControlProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
OptionControlProcessor.__init__(self, window, control_ids)
def Init(self):
args = (self,)+(self.window,) + self.args
if not self.init_done:
self.func(*args)
def UpdateControl_FromValue(self):
pass
def UpdateValue_FromControl(self):
pass
class ListBoxProcessor(OptionControlProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
OptionControlProcessor.__init__(self, window, control_ids)
def Init(self):
args = (self,)+(self.window,) + self.args
if not self.init_done:
self.func(*args)
def UpdateControl_FromValue(self):
pass
def UpdateValue_FromControl(self):
pass
class GroupProcessor(OptionControlProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
OptionControlProcessor.__init__(self, window, control_ids)
def Init(self):
args = (self,)+(self.window,) + self.args
self.func(*args)
def UpdateControl_FromValue(self):
pass
def UpdateValue_FromControl(self):
pass

View File

@ -0,0 +1,135 @@
# Control Processors for our dialog.
import win32gui, win32api, win32con
import commctrl
import struct, array
from dlgutils import *
import win32ui
# Cache our leaky bitmap handles
bitmap_handles = {}
# A generic set of "ControlProcessors". A control processor by itself only
# does a few basic things.
class ControlProcessor:
def __init__(self, window, control_ids):
self.control_id = control_ids[0]
self.other_ids = control_ids[1:]
self.window = window
self.init_done=False
def Init(self):
pass
def Done(self): # done with 'ok' - ie, save options. May return false.
return True
def Term(self): # closing - can't fail.
pass
def GetControl(self, control_id = None):
control_id = control_id or self.control_id
try:
h = win32gui.GetDlgItem(self.window.hwnd, control_id)
except:
hparent = win32gui.GetParent(self.window.hwnd)
hparent = win32gui.GetParent(hparent)
h = win32gui.GetDlgItem(hparent, control_id)
return h
def GetPopupHelpText(self, idFrom):
return None
def OnCommand(self, wparam, lparam):
pass
def OnNotify(self, nmhdr, wparam, lparam):
pass
def GetMessages(self):
return []
def OnMessage(self, msg, wparam, lparam):
raise RuntimeError, "I don't hook any messages, so I shouldn't be called"
def OnOptionChanged(self, option):
pass
def OnRButtonUp(self, wparam, lparam):
pass
class ImageProcessor(ControlProcessor):
def Init(self):
rcp = self.window.manager.dialog_parser;
bmp_id = int(win32gui.GetWindowText(self.GetControl()))
if bitmap_handles.has_key(bmp_id):
handle = bitmap_handles[bmp_id]
else:
import resources
mod_handle, mod_bmp, extra_flags = resources.GetImageParamsFromBitmapID(rcp, bmp_id)
load_flags = extra_flags|win32con.LR_COLOR|win32con.LR_SHARED
handle = win32gui.LoadImage(mod_handle, mod_bmp,win32con.IMAGE_BITMAP,0,0,load_flags)
bitmap_handles[bmp_id] = handle
win32gui.SendMessage(self.GetControl(), win32con.STM_SETIMAGE, win32con.IMAGE_BITMAP, handle)
def GetPopupHelpText(self, cid):
return None
class ButtonProcessor(ControlProcessor):
def OnCommand(self, wparam, lparam):
code = win32api.HIWORD(wparam)
id = win32api.LOWORD(wparam)
if code == win32con.BN_CLICKED:
self.OnClicked(id)
class RadioButtonProcessor(ControlProcessor):
def __init__(self, window, control_ids, func='', args=''):
self.func = func
self.args = args
ControlProcessor.__init__(self, window, control_ids)
def OnCommand(self, wparam, lparam):
code = win32api.HIWORD(wparam)
id = win32api.LOWORD(wparam)
if code == win32con.BN_CLICKED:
text=win32gui.GetDlgItemText(self.window.hwnd, self.control_id)
conn = self.func()
conn.setitem('protocol', text)
p=conn.getitem('protocol')
# def OnCommand(self, wparam, lparam):
# win32ui.MessageBox("clicked===",'')
# code = win32api.HIWORD(wparam)
# id = win32api.LOWORD(wparam)
# win32ui.MessageBox("clicked===",'')
# if code == win32con.BN_CLICKED:
# win32ui.MessageBox("clicked===",'')
# import win32ui
# conn = self.func()
# win32ui.MessageBox("clicked===",'')
# text=win32gui.GetDlgItemText(self.window.hwnd, self.control_id)
# win32ui.MessageBox("clicked===",'')
# conn.setitem('protocol', text)
# win32ui.MessageBox("clicked==="+text,'')
class CloseButtonProcessor(ButtonProcessor):
def OnClicked(self, id):
win32gui.EndDialog(self.window.hwnd, id)
class CancelButtonProcessor(ButtonProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
ControlProcessor.__init__(self, window, control_ids)
def OnClicked(self, id):
a=self.func(self.window)
win32gui.EndDialog(self.window.hwnd, id)
class CommandButtonProcessor(ButtonProcessor):
def __init__(self, window, control_ids, func, args):
self.func = func
self.args = args
ControlProcessor.__init__(self, window, control_ids)
def OnClicked(self, id):
# Bit of a hack - always pass the manager as the first arg.
self.id = id
args = (self, ) + self.args
self.func(*args)
def GetPopupHelpText(self, ctrlid):
assert ctrlid == self.control_id
doc = self.func.__doc__
if doc is None:
return ""
return " ".join(doc.split())

View File

@ -0,0 +1,26 @@
# Package that manages and defines dialog resources
def GetImageParamsFromBitmapID(rc_parser, bmpid):
import os, sys
import win32gui, win32con, win32api
if type(bmpid)==type(0):
bmpid = rc_parser.names[bmpid]
int_bmpid = rc_parser.ids[bmpid]
# For both binary and source versions, we currently load from files.
# In future py2exe built binary versions we will be able to load the
# bitmaps directly from our DLL.
filename = rc_parser.bitmaps[bmpid]
if hasattr(sys, "frozen"):
# in our .exe/.dll - load from that.
if sys.frozen=="dll":
hmod = sys.frozendllhandle
else:
hmod = win32api.GetModuleHandle(None)
return hmod, int_bmpid, 0
else:
# source code - load the .bmp directly.
if not os.path.isabs(filename):
# In this directory
filename = os.path.join( os.path.dirname( __file__ ), filename)
return 0, filename, win32con.LR_LOADFROMFILE
assert 0, "not reached"

View File

@ -0,0 +1,181 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by dialogs.rc
//
#define IDD_MANAGER 101
#define IDD_TRAINING 102
#define IDD_FILTER 103
#define IDD_FILTER_NOW 104
#define IDD_FOLDER_SELECTOR 105
#define IDD_ABOUT 106
#define IDD_GENERAL 108
//#define IDD_FILTER_SPAM 110
#define IDD_FILTER_UNSURE 111
#define IDD_DIAGNOSTIC 113
#define IDD_WIZARD 114
#define IDD_WIZARD_WELCOME 115
#define IDD_WIZARD_FINISHED_UNTRAINED 116
#define IDD_WIZARD_FOLDERS_REST 117
#define IDD_WIZARD_FOLDERS_WATCH 118
#define IDD_WIZARD_FINISHED_UNCONFIGURED 119
#define IDD_WIZARD_FOLDERS_TRAIN 120
#define IDD_WIZARD_TRAIN 121
#define IDD_WIZARD_FINISHED_TRAINED 122
#define IDD_WIZARD_TRAINING_IS_IMPORTANT 123
#define IDD_WIZARD_FINISHED_TRAIN_LATER 124
#define IDB_SBWIZLOGO 125
#define IDB_FOLDERS 127
#define IDC_PROGRESS 1000
#define IDC_PROGRESS_TEXT 1001
#define IDC_STATIC_HAM 1002
#define IDC_STATIC_SPAM 1003
#define IDC_BROWSE_HAM 1004
#define IDC_BROWSE_SPAM 1005
#define IDC_START 1006
#define IDC_BUT_REBUILD 1007
#define IDC_BUT_RESCORE 1008
#define IDC_VERSION 1009
#define IDC_BUT_TRAIN_FROM_SPAM_FOLDER 1010
#define IDC_BUT_TRAIN_TO_SPAM_FOLDER 1011
#define IDC_BUT_TRAIN_NOW 1012
#define IDC_BUT_FILTER_ENABLE 1013
#define IDC_FILTER_STATUS 1014
#define IDC_BUT_FILTER_DEFINE 1016
#define IDC_BUT_ABOUT 1017
#define IDC_BUT_ACT_SCORE 1018
#define IDC_BUT_ACT_ALL 1019
#define IDC_BUT_UNREAD 1020
#define IDC_BUT_UNSEEN 1021
#define IDC_SLIDER_CERTAIN 1023
#define IDC_EDIT_CERTAIN 1024
#define IDC_ACTION_CERTAIN 1025
#define IDC_FOLDER_CERTAIN 1027
#define IDC_BROWSE_CERTAIN 1028
#define IDC_SLIDER_UNSURE 1029
#define IDC_EDIT_UNSURE 1030
#define IDC_ACTION_UNSURE 1031
#define IDC_FOLDER_UNSURE 1033
#define IDC_BROWSE_UNSURE 1034
#define IDC_TRAINING_STATUS 1035
#define IDC_FOLDER_NAMES 1036
#define IDC_BROWSE 1037
#define IDC_FOLDER_WATCH 1038
#define IDC_BROWSE_WATCH 1039
#define IDC_LIST_FOLDERS 1040
#define IDC_BUT_SEARCHSUB 1041
#define IDC_BUT_CLEARALL 1042
#define IDC_STATUS1 1043
#define IDC_STATUS2 1044
#define IDC_BUT_NEW 1046
#define IDC_MARK_SPAM_AS_READ 1047
#define IDC_SAVE_SPAM_SCORE 1048
#define IDC_MARK_UNSURE_AS_READ 1051
#define IDC_DELAY1_SLIDER 1056
#define IDC_DELAY1_TEXT 1057
#define IDC_DELAY2_SLIDER 1058
#define IDC_DELAY2_TEXT 1059
#define IDC_INBOX_TIMER_ONLY 1060
#define IDC_VERBOSE_LOG 1061
#define IDB_OPENERPLOGO 1062
#define IDC_TAB 1068
#define IDC_BACK_BTN 1069
#define IDC_BUT_WIZARD 1070
#define IDC_SHOW_DATA_FOLDER 1071
#define IDC_ABOUT_BTN 1072
#define IDC_BUT_RESET 1073
#define IDC_DEL_SPAM_RS 1074
#define IDC_RECOVER_RS 1075
#define IDC_FORWARD_BTN 1077
#define IDC_PAGE_PLACEHOLDER 1078
#define IDC_BUT_SHOW_DIAGNOSTICS 1080
#define IDC_BUT_PREPARATION 1081
#define IDC_FOLDER_HAM 1083
#define IDC_BUT_UNTRAINED 1088
#define IDC_BUT_TRAIN 1089
#define IDC_BUT_TIMER_ENABLED 1091
#define IDC_WIZ_GRAPHIC 1092
#define IDC_BUT_VIEW_LOG 1093
#define IDC_EDIT1 1094
#define IDC_STATISTICS 1095
#define ID_SERVER 2001
#define ID_PORT 2002
#define ID_SERVER_PORT 2003
#define ID_DB_DROPDOWNLIST 2004
#define ID_USERNAME 2005
#define ID_PASSWORD 2006
#define ID_BUT_TESTCONNECTION 2007
#define ID_DONE 2008
#define IDD_OBJECT_SETTINGS 2009
#define IDC_BUT_LOAD_IMAGE 2010
#define IDC_BUT_SAVE_OBJECT 2011
#define IDC_BUT_DEL_OBJECT 2012
#define IDC_OBJECT_TITLE 2013
#define IDC_OBJECT_NAME 2014
#define IDC_IMAGE_PATH 2015
#define IDC_LIST 2016
#define IDC_HEADER 2017
#define ID_CREATE_CONTACT 2018
#define ID_MAKE_ATTACHMENT 2019
#define ID_CREATE_CASE 2020
#define IDC_BUT_SET_SERVER_PORT 2021
#define IDD_SERVER_PORT_DIALOG 2022
#define IDC_CHKBX 2023
#define IDC_STATIC_GROUP 2024
#define ID_ATT_METHOD_DROPDOWNLIST 2025
#define IDC_NAME_LIST 2026
#define IDD_ABOUT 2027
#define IDC_ABOUT 2028
#define IDC_CONTACT_LIST 2029
#define ID_NAME_TEXT 2030
#define IDD_NEW_CONTACT_DIALOG 2031
#define ID_PARTNER_DROPDOWNLIST 2032
#define ID_NEW_PARTNER_BUTTON 2033
#define IDD_NEW_PARTNER_DIALOG 2034
#define ID_SAVE_PARTNER_BUTTON 2035
#define ID_PARTNER_NAME_TEXT 2036
#define IDC_NAME_LIST1 2037
#define IDC_RELOAD 2038
#define ID_PROTOCOL_GRP 2040
#define IDR_XML_PROTOCOL 2041
#define IDR_XMLS_PROTOCOL 2042
#define IDR_NETRPC_PROTOCOL 2043
#define IDD_VIEW_PARTNER_DIALOG 2044
#define IDET_PARTNER_NAME 2045
#define IDET_PARTNER_CONTACT_NAME 2046
#define IDET_PARTNER_EMAIL 2047
#define IDET_PARTNER_OFFICENO 2048
#define IDET_PARTNER_MOBILENO 2050
#define IDET_SEARCH_PARTNER 2051
#define IDPB_SEARCH_PARTNER 2052
#define IDET_PARTNER_STREET 2053
#define IDET_PARTNER_STREET2 2054
#define IDET_PARTNER_COUNTRY 2057
#define IDET_PARTNER_FAX 2058
#define IDPB_WRITE_CHANGES 2059
#define ID_ALL_STATE_DROPDOWNLIST 2060
#define ID_ALL_COUNTRY_DROPDOWNLIST 2061
//
#define ID_STREET_TEXT 2062
#define ID_STREET2_TEXT 2063
#define ID_FED_STATE_DROPLIST 2064
#define ID_COUNTRY_DROPLIST 2065
#define ID_FAX_TEXT 2066
#define ID_PARTNER_CITY_TEXT 2067
#define ID_ZIP_TEXT 2068
#define ID_PARTNER_DROPLIST 2069
#define ID_NEW_PART_BUTTON 2070
#define IDPB_NEWPARTNER_BUTTON 2071
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 128
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1096
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,234 @@
// Microsoft Visual C++ generated resource script.
//
#include "dialogs.h"
IDB_OPENERPLOGO BITMAP "OpenERP_Logo.bmp"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MANAGER DIALOGEX 0, 0, 460, 260
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME
CAPTION "OpenERP Configuarion"
FONT 8, "Tahoma", 1000, 0, 0x0
BEGIN
DEFPUSHBUTTON "Done",ID_DONE,400,239,50,14//,WS_VISIBLE //| WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,340,239,50,14//, WS_VISIBLE //| WS_TABSTOP
CONTROL "",IDC_TAB,"SysTabControl32",0x0,8,7,440,228
CONTROL "",IDC_LIST,"SysListView32",WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL |
LVS_SHOWSELALWAYS | LVS_REPORT | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES,0,0,0,0
END
IDD_GENERAL DIALOGEX 0, 0, 430, 210
STYLE DS_SETFONT | WS_CHILD | WS_CAPTION | WS_SYSMENU
CAPTION "Connection Parameters"
FONT 8, "Tahoma", 0, 0, 0x1
BEGIN
GROUPBOX "",IDC_STATIC_GROUP, 10, 10,250,130
LTEXT "Server : ",IDC_STATIC,30,30,100,17
EDITTEXT ID_SERVER_PORT,85,30,120,12,ES_READONLY | WS_VISIBLE | WS_TABSTOP// left top width height
PUSHBUTTON "Change",IDC_BUT_SET_SERVER_PORT,210,30,30,13, WS_VISIBLE | WS_TABSTOP
LTEXT "Database : ",IDC_STATIC,30,50,100,17
COMBOBOX ID_DB_DROPDOWNLIST,85,50,120,40,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Reload",IDC_RELOAD,210,50,30,13, WS_VISIBLE | WS_TABSTOP
LTEXT "Username : ",IDC_STATIC,30,70,100,17
EDITTEXT ID_USERNAME,85,70,154,12,ES_AUTOHSCROLL | WS_VISIBLE | WS_TABSTOP
LTEXT "Password : ",IDC_STATIC,30,90,100,17
EDITTEXT ID_PASSWORD,85,90,154,12,ES_AUTOHSCROLL | WS_VISIBLE | WS_TABSTOP | ES_PASSWORD
PUSHBUTTON "Test Connection",ID_BUT_TESTCONNECTION,179,110,60,13, WS_VISIBLE | WS_TABSTOP
END
IDD_OBJECT_SETTINGS DIALOGEX 0, 0, 430, 210
STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Documents Setting"
FONT 8, "Tahoma", 0, 0, 0x1
BEGIN
GROUPBOX "Document Attributes",IDC_STATIC_GROUP, 2, 2, 340, 32
LTEXT "Title",IDC_STATIC,6,15,30,17
EDITTEXT IDC_OBJECT_TITLE,20,14,57,12,ES_AUTOHSCROLL | WS_TABSTOP// left top width height
LTEXT "Document Name",IDC_STATIC,83,15,60,17
EDITTEXT IDC_OBJECT_NAME,138,14,57,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Image",IDC_STATIC,200,15,20,17
EDITTEXT IDC_IMAGE_PATH,220,14,57,12,ES_AUTOHSCROLL | WS_TABSTOP
PUSHBUTTON "Load Image",IDC_BUT_LOAD_IMAGE,286,13,50,15,WS_TABSTOP
PUSHBUTTON "Add",IDC_BUT_SAVE_OBJECT,347,13,38,15,WS_TABSTOP
PUSHBUTTON "Remove",IDC_BUT_DEL_OBJECT,391,13,38,15,WS_TABSTOP
CONTROL "List1",IDC_LIST,"SysListView32",WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL |
LVS_SHOWSELALWAYS | LVS_EX_GRIDLINES | LVS_REPORT | LVS_EX_FULLROWSELECT, 8,40,535,160
END
IDD_ABOUT DIALOGEX 0, 0, 430, 210
STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "About"
FONT 8, "Tahoma", 400, 0, 0x0
BEGIN
GROUPBOX "About Plugin",IDC_STATIC,7,3,422,200
CONTROL 1062,IDB_OPENERPLOGO,"Static",SS_BITMAP | SS_REALSIZEIMAGE,60,30,20,20
LTEXT "",IDC_ABOUT,80,90,250,100
END
IDD_SERVER_PORT_DIALOG DIALOGEX 0, 0, 160, 90
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Server and Port"
FONT 8, "Tahoma", 400, 0, 0x0
BEGIN
LTEXT "Server : ",IDC_STATIC,5,3,150,17
EDITTEXT ID_SERVER,40,3,94,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Port : ",IDC_STATIC,5,18,100,17
EDITTEXT ID_PORT,40,18,94,12,ES_AUTOHSCROLL | WS_TABSTOP
GROUPBOX " Protocol ", IDC_STATIC_GROUP, 5, 35, 150, 30
PUSHBUTTON "XML-RPC",IDR_XML_PROTOCOL,8,45,50,14,BS_AUTORADIOBUTTON | BST_CHECKED |WS_TABSTOP
PUSHBUTTON "XML-RPCS",IDR_XMLS_PROTOCOL,55,45,50,14,BS_AUTORADIOBUTTON | WS_TABSTOP
PUSHBUTTON "NET-RPC",IDR_NETRPC_PROTOCOL,105,45,45,14,BS_AUTORADIOBUTTON | WS_TABSTOP
PUSHBUTTON "Close",IDCANCEL,60,70,45,14,WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,110,70,45,14,WS_TABSTOP
END
IDD_SYNC DIALOGEX 0, 0, 470, 300
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Archive to OpenERP"
FONT 8, "Tahoma", 1000, 0, 0x0
BEGIN
GROUPBOX " Link to an Existing Documents ", IDC_STATIC_GROUP, 8,5,250,290,WS_TABSTOP
LTEXT "Search for : ",IDC_STATIC,15,17,40,12
EDITTEXT ID_SEARCH_TEXT,60,15,120,12,ES_AUTOHSCROLL | WS_TABSTOP// left top width height
PUSHBUTTON "Search",ID_SEARCH,187,15,40,14,WS_TABSTOP
CONTROL "List1",IDC_NAME_LIST,"SysListView32",WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_SHOWSELALWAYS | LVS_REPORT | WS_TABSTOP, 15,150,234,110
PUSHBUTTON "Upload to OpenERP",ID_MAKE_ATTACHMENT,160,270,85,14,WS_TABSTOP
GROUPBOX " Create a Document ", IDC_STATIC_GROUP, 263,5,202,100,WS_TABSTOP
LTEXT "Type of Document : ",IDC_STATIC,266,25,100,12
COMBOBOX ID_ATT_METHOD_DROPDOWNLIST,332,24,75,45,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Create",ID_CREATE_CASE,412,23,50,14,WS_TABSTOP
GROUPBOX " Create a Contact ", IDC_STATIC_GROUP, 263, 110,202,185,WS_TABSTOP
LTEXT "Create a New Contact : ",IDC_STATIC,280,140,100,12
PUSHBUTTON "Create Contact",ID_CREATE_CONTACT,360,138,60,14,WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,385,270,60,14,WS_TABSTOP
END
IDD_NEW_CONTACT_DIALOG DIALOGEX 0, 0, 350, 190
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Create a New Contact"
FONT 8, "Tahoma", 1000, 0, 0x0
BEGIN
LTEXT "Select Partner : ",IDC_STATIC,13,20,50,17
COMBOBOX ID_PARTNER_DROPDOWNLIST, 70, 18, 200, 80 ,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "New Partner",ID_NEW_PARTNER_BUTTON,280,17,55,14, WS_TABSTOP
GROUPBOX "Postal Address ", IDC_STATIC_GROUP,10,35,175,125
LTEXT "Contact Name : ",IDC_STATIC, 18, 53, 100, 17
EDITTEXT ID_CONTACT_NAME_TEXT, 76, 52, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Street : ",IDC_STATIC, 18, 67, 40, 17
EDITTEXT ID_STREET_TEXT, 76, 66, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Street2 : ",IDC_STATIC, 18, 81, 40, 17
EDITTEXT ID_STREET2_TEXT, 76, 80, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Zip : ",IDC_STATIC,18, 94, 50, 17
EDITTEXT ID_ZIP_TEXT,76, 93, 100, 12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "City : ",IDC_STATIC,18,108,50,17
EDITTEXT ID_PARTNER_CITY_TEXT,76,107,100,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Fed. State : ",IDC_STATIC, 18, 123, 40, 17
COMBOBOX ID_FED_STATE_DROPLIST, 76, 122, 100, 80,CBS_DROPDOWNLIST |WS_VSCROLL | WS_TABSTOP
LTEXT "Country : ",IDC_STATIC, 18, 137, 40, 17
COMBOBOX ID_COUNTRY_DROPLIST, 76, 136, 100, 80,CBS_DROPDOWNLIST |WS_VSCROLL | WS_TABSTOP
GROUPBOX "Communication ", IDC_STATIC_GROUP, 188, 35, 150, 125
LTEXT "Office : ",IDC_STATIC,194, 53, 30, 17
EDITTEXT ID_CONTACT_OFFICE_TEXT, 224, 52, 100, 12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Mobile : ",IDC_STATIC,194, 67, 30, 17
EDITTEXT ID_CONTACT_MOBILE_TEXT, 224, 66, 100, 12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Fax : ",IDC_STATIC,194, 81, 30, 17
EDITTEXT ID_FAX_TEXT, 224, 80, 100, 12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Email : ",IDC_STATIC, 194, 95, 30, 17
EDITTEXT ID_CONTACT_EMAIL_TEXT, 224, 94, 100, 12,ES_AUTOHSCROLL | WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,290,170,45,14, WS_TABSTOP
PUSHBUTTON "Save",ID_CONTACT_SAVE_BUTTON,240,170,45,14, WS_TABSTOP
END
IDD_NEW_PARTNER_DIALOG DIALOGEX 0, 0, 140,40
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Create a New Partner"
FONT 8, "Tahoma", 400, 0, 0x0
BEGIN
LTEXT "Name : ",IDC_STATIC,5,3,100,17
EDITTEXT ID_PARTNER_NAME_TEXT,40,3,94,12,ES_AUTOHSCROLL | WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,90,22,45,14,WS_TABSTOP
DEFPUSHBUTTON "Save",ID_SAVE_PARTNER_BUTTON,40,22,45,14,WS_TABSTOP
END
IDD_VIEW_PARTNER_DIALOG DIALOGEX 0, 0, 350, 215
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTEXTHELP
CAPTION "Open Contact"
FONT 8, "Tahoma", 400, 0, 0x0
BEGIN
LTEXT "Email ID : ",IDC_STATIC,32,17,40,12
EDITTEXT IDET_SEARCH_PARTNER, 70, 15, 200, 12, ES_AUTOHSCROLL | WS_TABSTOP
PUSHBUTTON "Search Partner ",IDPB_SEARCH_PARTNER,280,15,60,14,WS_TABSTOP
LTEXT "Partner Name : ",IDC_STATIC,13,42,50,17
COMBOBOX ID_PARTNER_DROPLIST, 70, 42, 200, 80 ,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "New Partner",ID_NEW_PART_BUTTON,280,41,60,14, WS_TABSTOP
GROUPBOX "Postal Address ", IDC_STATIC_GROUP,10,65,175,125
LTEXT "Contact Name : ",IDC_STATIC,18,83,50,17
EDITTEXT IDET_PARTNER_CONTACT_NAME,76,82,100,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Street : ",IDC_STATIC,18,97,50,17
EDITTEXT IDET_PARTNER_STREET,76,96,100,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Street2 : ",IDC_STATIC,18,112,50,17
EDITTEXT IDET_PARTNER_STREET2, 76, 111, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Zip : ",IDC_STATIC, 18, 126, 50,14
EDITTEXT IDET_ZIP, 76, 125, 100, 12 , ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "City : ",IDC_STATIC,18,140,50,17
EDITTEXT IDET_PARTNER_CITY,76,139,100,12,ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Fed. State : ",IDC_STATIC,18,154,50,17
COMBOBOX ID_ALL_STATE_DROPDOWNLIST, 76, 153, 100, 50,CBS_DROPDOWNLIST |WS_VSCROLL | WS_TABSTOP
LTEXT "Country :",IDC_STATIC, 18, 169, 35, 17
COMBOBOX ID_ALL_COUNTRY_DROPDOWNLIST, 76, 168,100,50,CBS_DROPDOWNLIST |WS_VSCROLL | WS_TABSTOP
GROUPBOX "Communication ", IDC_STATIC_GROUP, 188, 65, 152, 125
LTEXT "Phone : ",IDC_STATIC, 194, 83, 30, 17
EDITTEXT IDET_PARTNER_OFFICENO, 224, 82, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Mobile : ",IDC_STATIC, 194, 97, 30, 17
EDITTEXT IDET_PARTNER_MOBILENO, 224, 96, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
LTEXT "Email : ",IDC_STATIC, 194, 111, 30, 17
EDITTEXT IDET_PARTNER_FAX, 224, 110, 100, 12, ES_AUTOHSCROLL |ES_READONLY
LTEXT "Fax : ",IDC_STATIC,194,125,30,17
EDITTEXT IDET_PARTNER_EMAIL, 224, 124, 100, 12, ES_AUTOHSCROLL | WS_TABSTOP
PUSHBUTTON "Create a New Contact", IDPB_NEWPARTNER_BUTTON, 124, 195, 82, 14, WS_TABSTOP
PUSHBUTTON "Save", IDPB_WRITE_CHANGES, 213, 195, 60, 14, WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 281, 195, 60, 14, WS_TABSTOP
END

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -0,0 +1,39 @@
# rc2py.py
# This module is part of the spambayes project, which is Copyright 2003
# The Python Software Foundation and is covered by the Python Software
# Foundation license.
__author__="Adam Walker"
__doc__=""""
Converts an .rc windows resource source file into a python source file
with the same basic public interface as the rcparser module.
"""
import sys, os, stat
import rcparser
def convert(inputFilename = None, outputFilename = None):
"""See the module doc string"""
if inputFilename is None:
inputFilename = "dialogs.rc"
if outputFilename is None:
outputFilename = "test.py"
rcp = rcparser.ParseDialogs(inputFilename)
in_stat = os.stat(inputFilename)
out = open(outputFilename, "wt")
out.write("#%s\n" % outputFilename)
out.write("#This is a generated file. Please edit %s instead.\n" % inputFilename)
out.write("_rc_size_=%d\n_rc_mtime_=%d\n" % (in_stat[stat.ST_SIZE], in_stat[stat.ST_MTIME]))
out.write("class FakeParser:\n")
out.write("\tdialogs = "+repr(rcp.dialogs)+"\n")
out.write("\tids = "+repr(rcp.ids)+"\n")
out.write("\tnames = "+repr(rcp.names)+"\n")
out.write("\tbitmaps = "+repr(rcp.bitmaps)+"\n")
out.write("def ParseDialogs(s):\n")
out.write("\treturn FakeParser()\n")
out.close()
if __name__=="__main__":
if len(sys.argv)>1:
convert(sys.argv[1], sys.argv[2])
else:
convert()

View File

@ -0,0 +1,377 @@
# Windows dialog .RC file parser, by Adam Walker.
# This module is part of the spambayes project, which is Copyright 2003
# The Python Software Foundation and is covered by the Python Software
# Foundation license.
__author__="Adam Walker"
import sys, os, shlex
import win32con
#import win32gui
import commctrl
_controlMap = {"DEFPUSHBUTTON":0x80,
"PUSHBUTTON":0x80,
"Button":0x80,
"GROUPBOX":0x80,
"Static":0x82,
"CTEXT":0x82,
"RTEXT":0x82,
"LTEXT":0x82,
"LISTBOX":0x83,
"SCROLLBAR":0x84,
"COMBOBOX":0x85,
"EDITTEXT":0x81,
}
_addDefaults = {"EDITTEXT":win32con.WS_BORDER,
"GROUPBOX":win32con.BS_GROUPBOX,
"LTEXT":win32con.SS_LEFT,
"DEFPUSHBUTTON":win32con.BS_DEFPUSHBUTTON,
"CTEXT":win32con.SS_CENTER,
"RTEXT":win32con.SS_RIGHT}
defaultControlStyle = win32con.WS_CHILD | win32con.WS_VISIBLE
class DialogDef:
name = ""
id = 0
style = 0
styleEx = None
caption = ""
font = "MS Sans Serif"
fontSize = 8
x = 0
y = 0
w = 0
h = 0
template = None
def __init__(self, n, i):
self.name = n
self.id = i
self.styles = []
self.stylesEx = []
self.controls = []
#print "dialog def for ",self.name, self.id
def createDialogTemplate(self):
t = None
self.template = [[self.caption, (self.x,self.y,self.w,self.h), self.style, self.styleEx, (self.fontSize, self.font)]]
# Add the controls
for control in self.controls:
self.template.append(control.createDialogTemplate())
return self.template
class ControlDef:
id = ""
controlType = ""
subType = ""
idNum = 0
style = defaultControlStyle
label = ""
x = 0
y = 0
w = 0
h = 0
def __init__(self):
self.styles = []
def toString(self):
s = "<Control id:"+self.id+" controlType:"+self.controlType+" subType:"+self.subType\
+" idNum:"+str(self.idNum)+" style:"+str(self.style)+" styles:"+str(self.styles)+" label:"+self.label\
+" x:"+str(self.x)+" y:"+str(self.y)+" w:"+str(self.w)+" h:"+str(self.h)+">"
return s
def createDialogTemplate(self):
ct = self.controlType
if "CONTROL"==ct:
ct = self.subType
if ct in _addDefaults:
self.style |= _addDefaults[ct]
if ct in _controlMap:
ct = _controlMap[ct]
t = [ct, self.label, self.idNum, (self.x, self.y, self.w, self.h), self.style]
#print t
return t
class RCParser:
next_id = 1001
dialogs = {}
_dialogs = {}
debugEnabled = False;
token = ""
def __init__(self):
self.ids = {"IDOK":1, "IDCANCEL":2, "IDC_STATIC": -1}
self.names = {1:"IDOK", 2:"IDCANCEL", -1:"IDC_STATIC"}
self.bitmaps = {}
def debug(self, *args):
if self.debugEnabled:
print args
def getToken(self):
self.token = self.lex.get_token()
self.debug("getToken returns:", self.token)
if self.token=="":
self.token = None
return self.token
def getCommaToken(self):
tok = self.getToken()
assert tok == ",", "Token '%s' should be a comma!" % tok
def loadDialogs(self, rcFileName):
"""
RCParser.loadDialogs(rcFileName) -> None
Load the dialog information into the parser. Dialog Definations can then be accessed
using the "dialogs" dictionary member (name->DialogDef). The "ids" member contains the dictionary of id->name.
The "names" member contains the dictionary of name->id
"""
hFileName = rcFileName[:-2]+"h"
try:
h = open(hFileName, "rU")
self.parseH(h)
h.close()
except OSError:
print "No .h file. ignoring."
f = open(rcFileName)
self.open(f)
self.getToken()
while self.token!=None:
self.parse()
self.getToken()
f.close()
def open(self, file):
self.lex = shlex.shlex(file)
self.lex.commenters = "//#"
def parseH(self, file):
lex = shlex.shlex(file)
lex.commenters = "//"
token = " "
while token is not None:
token = lex.get_token()
if token == "" or token is None:
token = None
else:
if token=='define':
n = lex.get_token()
i = int(lex.get_token())
self.ids[n] = i
if self.names.has_key(i):
# ignore AppStudio special ones.
if not n.startswith("_APS_"):
print "Duplicate id",i,"for",n,"is", self.names[i]
else:
self.names[i] = n
if self.next_id<=i:
self.next_id = i+1
def parse(self):
deep = 0
if self.token == None:
more == None
elif "BEGIN" == self.token:
deep = 1
while deep!=0:
self.getToken()
if "BEGIN" == self.token:
deep += 1
elif "END" == self.token:
deep -= 1
elif "IDD_" == self.token[:4]:
possibleDlgName = self.token
#print "possible dialog:", possibleDlgName
self.getToken()
if "DIALOG" == self.token or "DIALOGEX" == self.token:
self.dialog(possibleDlgName)
elif "IDB_" == self.token[:4]:
possibleBitmap = self.token
self.getToken()
if "BITMAP" == self.token:
self.getToken()
if self.token=="MOVEABLE":
self.getToken() # PURE
self.getToken() # bmpname
bmf = self.token[1:-1] # quotes
self.bitmaps[possibleBitmap] = bmf
print "BITMAP", possibleBitmap, bmf
#print win32gui.LoadImage(0, bmf, win32con.IMAGE_BITMAP,0,0,win32con.LR_DEFAULTCOLOR|win32con.LR_LOADFROMFILE)
def addId(self, id_name):
if id_name in self.ids:
id = self.ids[id_name]
else:
id = self.next_id
self.next_id += 1
self.ids[id_name] = id
self.names[id] = id_name
return id
def lang(self):
while self.token[0:4]=="LANG" or self.token[0:7]=="SUBLANG" or self.token==',':
self.getToken();
def dialog(self, name):
dlg = DialogDef(name,self.addId(name))
assert len(dlg.controls)==0
self._dialogs[name] = dlg
extras = []
self.getToken()
while not self.token.isdigit():
self.debug("extra", self.token)
extras.append(self.token)
self.getToken()
dlg.x = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.y = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.w = int(self.token)
self.getCommaToken()
self.getToken() # number
dlg.h = int(self.token)
self.getToken()
while not (self.token==None or self.token=="" or self.token=="END"):
if self.token=="STYLE":
self.dialogStyle(dlg)
elif self.token=="EXSTYLE":
self.dialogExStyle(dlg)
elif self.token=="CAPTION":
self.dialogCaption(dlg)
elif self.token=="FONT":
self.dialogFont(dlg)
elif self.token=="BEGIN":
self.controls(dlg)
else:
break
self.dialogs[name] = dlg.createDialogTemplate()
def dialogStyle(self, dlg):
dlg.style, dlg.styles = self.styles( [], win32con.WS_VISIBLE | win32con.DS_SETFONT)
def dialogExStyle(self, dlg):
self.getToken()
dlg.styleEx, dlg.stylesEx = self.styles( [], 0)
def styles(self, defaults, defaultStyle):
list = defaults
style = defaultStyle
if "STYLE"==self.token:
self.getToken()
i = 0
Not = False
while ((i%2==1 and ("|"==self.token or "NOT"==self.token)) or (i%2==0)) and not self.token==None:
Not = False;
if "NOT"==self.token:
Not = True
self.getToken()
i += 1
if self.token!="|":
if self.token in win32con.__dict__:
value = getattr(win32con,self.token)
else:
if self.token in commctrl.__dict__:
value = getattr(commctrl,self.token)
else:
value = 0
if Not:
list.append("NOT "+self.token)
self.debug("styles add Not",self.token, value)
style &= ~value
else:
list.append(self.token)
self.debug("styles add", self.token, value)
style |= value
self.getToken()
self.debug("style is ",style)
return style, list
def dialogCaption(self, dlg):
if "CAPTION"==self.token:
self.getToken()
self.token = self.token[1:-1]
self.debug("Caption is:",self.token)
dlg.caption = self.token
self.getToken()
def dialogFont(self, dlg):
if "FONT"==self.token:
self.getToken()
dlg.fontSize = int(self.token)
self.getCommaToken()
self.getToken() # Font name
dlg.font = self.token[1:-1] # it's quoted
self.getToken()
while "BEGIN"!=self.token:
self.getToken()
def controls(self, dlg):
if self.token=="BEGIN": self.getToken()
while self.token!="END":
control = ControlDef()
control.controlType = self.token;
#print self.token
self.getToken()
if self.token[0:1]=='"':
control.label = self.token[1:-1]
self.getCommaToken()
self.getToken()
elif self.token.isdigit():
control.label = self.token
self.getCommaToken()
self.getToken()
# msvc seems to occasionally replace "IDC_STATIC" with -1
if self.token=='-':
if self.getToken() != '1':
raise RuntimeError, \
"Negative literal in rc script (other than -1) - don't know what to do"
self.token = "IDC_STATIC"
control.id = self.token
control.idNum = self.addId(control.id)
self.getCommaToken()
if control.controlType == "CONTROL":
self.getToken()
control.subType = self.token[1:-1]
# Styles
self.getCommaToken()
self.getToken()
control.style, control.styles = self.styles([], defaultControlStyle)
#self.getToken() #,
# Rect
control.x = int(self.getToken())
self.getCommaToken()
control.y = int(self.getToken())
self.getCommaToken()
control.w = int(self.getToken())
self.getCommaToken()
self.getToken()
control.h = int(self.token)
self.getToken()
if self.token==",":
self.getToken()
control.style, control.styles = self.styles([], defaultControlStyle)
#print control.toString()
dlg.controls.append(control)
def ParseDialogs(rc_file):
rcp = RCParser()
try:
rcp.loadDialogs(rc_file)
except:
lex = getattr(rcp, "lex", None)
if lex:
print "ERROR parsing dialogs at line", lex.lineno
print "Next 10 tokens are:"
for i in range(10):
print lex.get_token(),
print
raise
return rcp
if __name__=='__main__':
rc_file = os.path.join(os.path.dirname(__file__), "dialogs.rc")
d = ParseDialogs(rc_file)
import pprint
for id, ddef in d.dialogs.items():
print "Dialog %s (%d controls)" % (id, len(ddef))
pprint.pprint(ddef)
print

82
addons/outlook/plugin/eml.py Executable file
View File

@ -0,0 +1,82 @@
import sys
import chilkat
import os
from manager import ustr
import win32ui
email = chilkat.CkEmail()
dt = chilkat.SYSTEMTIME()
def generateEML(mail):
sub = (mail.Subject).replace(' ','')
body = mail.Body.encode("utf-8")
recipients = mail.Recipients
sender_email = mail.SenderEmailAddress
sender_name = mail.SenderName
attachments=mail.Attachments
# to = mail.To
# cc = mail.CC
# rec_date = mail.ReceivedTime
email = chilkat.CkEmail()
email.put_Subject (ustr(sub).encode('iso-8859-1'))
email.put_Body (ustr(body).encode('utf-8'))
email.put_FromAddress (ustr(sender_email).encode('iso-8859-1'))
email.put_From (ustr(sender_name).encode('iso-8859-1'))
for i in xrange(1, recipients.Count+1):
name = ustr(recipients.Item(i).Name).encode('iso-8859-1')
address = ustr(recipients.Item(i).Address).encode('iso-8859-1')
email.AddTo(name,address)
# email.AddMultipleTo(to)
# email.AddMultipleCC(cc)
# win32ui.MessageBox("cccc---"+str(dir(cc)),'')
# for i in xrange(1, cc.Count+1):
# name = ustr(recipients.Item(i).Name).encode('iso-8859-1')
# address = ustr(recipients.Item(i).Address).encode('iso-8859-1')
# email.AddCC(name,address)
eml_name= ustr(sub).encode('iso-8859-1')+'-'+str(mail.EntryID)[-9:]
ls = ['*', '/', '\\', '<', '>', ':', '?', '"', '|', '\t', '\n']
attachments_folder_path = os.path.abspath(os.path.dirname(__file__)+"\\dialogs\\resources\\attachments\\")
if not os.path.exists(attachments_folder_path):
os.makedirs(attachments_folder_path)
for i in xrange(1, attachments.Count+1):
fn = eml_name + '-' + ustr(attachments[i].FileName).encode('iso-8859-1')
for c in ls:
fn = fn.replace(c,'')
if len(fn) > 64:
l = 64 - len(fn)
f = fn.split('-')
fn = '-'.join(f[1:])
if len(fn) > 64:
l = 64 - len(fn)
f = fn.split('.')
fn = f[0][0:l] + '.' + f[-1]
att_file = os.path.join(attachments_folder_path, fn)
if os.path.exists(att_file):
os.remove(att_file)
f1 = att_file
attachments[i].SaveAsFile(att_file)
contentType = email.addFileAttachment(att_file)
if (contentType == None ):
print mail.lastErrorText()
sys.exit()
mails_folder_path = os.path.abspath(os.path.dirname(__file__)+"\\dialogs\\resources\\mails\\")
if not os.path.exists(mails_folder_path):
os.makedirs(mails_folder_path)
for c in ls:
eml_name = eml_name.replace(c,'')
if len(eml_name) > 64:
l = 64 - len(eml_name)
f = eml_name.split('-')
eml_name = f[0][0:l] + '.' + f[-1]
eml_path = ustr(os.path.join(mails_folder_path,eml_name+".eml")).encode('iso-8859-1')
success = email.SaveEml(eml_path)
if (success == False):
print email.lastErrorText()
sys.exit()
print "Saved EML!",eml_path
return eml_path

168
addons/outlook/plugin/manager.py Executable file
View File

@ -0,0 +1,168 @@
import os
import sys
import win32api, win32con
import win32com.client
import pythoncom
try:
True, False
except NameError:
# Maintain compatibility with Python 2.2
True, False = 1, 0
try:
filesystem_encoding = sys.getfilesystemencoding()
except AttributeError:
filesystem_encoding = "mbcs"
# Work out our "application directory", which is
# the directory of our main .py/.dll/.exe file we
# are running from.
if hasattr(sys, "frozen"):
assert sys.frozen == "dll", "outlook only supports inproc servers"
this_filename = win32api.GetModuleFileName(sys.frozendllhandle)
else:
try:
this_filename = os.path.abspath(__file__)
except NameError: # no __file__ - means Py2.2 and __name__=='__main__'
this_filename = os.path.abspath(sys.argv[0])
# See if we can use the new bsddb module. (The old one is unreliable
# on Windows, so we don't use that)
try:
import bsddb3 as bsddb
# bsddb3 is definitely not broken
use_db = True
except ImportError:
# Not using the 3rd party bsddb3, so try the one in the std library
try:
import bsddb
use_db = hasattr(bsddb, "db") # This name is not in the old one.
except ImportError:
# No DB library at all!
assert not hasattr(sys, "frozen"), \
"Don't build binary versions without bsddb!"
use_db = False
def ustr(value):
"""This method is similar to the builtin `str` method, except
it will return Unicode string.
@param value: the value to convert
@rtype: unicode
@return: unicode string
"""
if isinstance(value, unicode):
return value
if hasattr(value, '__unicode__'):
return unicode(value)
if not isinstance(value, str):
value = str(value)
try: # first try utf-8
return unicode(value, 'utf-8')
except:
pass
try: # then extened iso-8858
return unicode(value, 'iso-8859-15')
except:
pass
filesystem_encoding = sys.getfilesystemencoding()
d = unicode(value, filesystem_encoding)
return d
class OpenERPManager:
def __init__(self, config_base="default", outlook=None, verbose=0):
self.outlook = outlook
self.dialog_parser = None
self.application_directory = os.path.dirname(this_filename)
self.windows_data_directory = self.LocateDataDirectory()
self.data_directory = self.windows_data_directory
self.default_objects = [('Partners','res.partner',''),('Partner Address','res.partner.address',''), \
('Account Invoices','account.invoice',''), ('Accounts','account.account',''), \
('Projects', 'project.project',''),('Sale Orders','sale.order',''), \
('Project Tasks','project.task',''), ('Products', 'product.product', '')]
self.config=self.LoadConfig()
def WorkerThreadStarting(self):
pythoncom.CoInitialize()
def WorkerThreadEnding(self):
pythoncom.CoUninitialize()
def LocateDataDirectory(self):
# Locate the best directory for our data files.
from win32com.shell import shell, shellcon
try:
appdata = shell.SHGetFolderPath(0,shellcon.CSIDL_APPDATA,0,0)
path = os.path.join(appdata, "OpenERP-Plugin")
if not os.path.isdir(path):
os.makedirs(path)
return path
except pythoncom.com_error:
# Function doesn't exist on early win95,
# and it may just fail anyway!
return self.application_directory
except EnvironmentError:
# Can't make the directory.
return self.application_directory
def ShowManager(self, id="IDD_MANAGER"):
import dialogs
dialogs.ShowDialog(0, self, self.config, id)
def LoadConfig(self):
import win32ui
path = os.path.join(self.data_directory, 'tiny.ini')
data = {'server' : 'localhost', 'port' : '8069', 'protocol' : 'http://', 'database' : '', 'objects' : self.default_objects, 'uname':'admin', 'pwd':'a', 'login':False}
if os.path.exists(path):
fp = open(path, 'r')
data = fp.readlines()
try:
data = eval(data[0])
return data
except e:
return data
else:
return data
def SaveConfig(self):
path = os.path.join(self.data_directory, 'tiny.ini')
fp = open(path, 'w')
fp.write(str(self.config))
fp.close()
_mgr = None
def GetManager(outlook = None):
global _mgr
if _mgr is None:
if outlook is None:
outlook = win32com.client.Dispatch("Outlook.Application")
_mgr = OpenERPManager(outlook=outlook)
return _mgr
def ShowManager(mgr):
mgr.c()
def main(verbose_level = 1):
mgr = GetManager()
ShowManager(mgr)
return 0
def usage():
print "Usage: manager [-v ...]"
sys.exit(1)
if __name__=='__main__':
verbose = 1
import getopt
opts, args = getopt.getopt(sys.argv[1:], "v")
if args:
usage()
for opt, val in opts:
if opt=="-v":
verbose += 1
else:
usage()
sys.exit(main(verbose))

View File

@ -0,0 +1,360 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import xmlrpclib
import sys
import socket
import os
import pythoncom
import time
from manager import ustr
waittime = 10
wait_count = 0
wait_limit = 12
def execute(connector, method, *args):
global wait_count
res = False
try:
res = getattr(connector,method)(*args)
except socket.error,e:
if e.args[0] == 111:
if wait_count > wait_limit:
print "Server is taking too long to start, it has exceeded the maximum limit of %d seconds."%(wait_limit)
clean()
sys.exit(1)
print 'Please wait %d sec to start server....'%(waittime)
wait_count += 1
time.sleep(waittime)
res = execute(connector, method, *args)
else:
return res
wait_count = 0
return res
class XMLRpcConn(object):
__name__ = 'XMLRpcConn'
_com_interfaces_ = ['_IDTExtensibility2']
_public_methods_ = ['GetDBList', 'login', 'GetAllObjects', 'GetObjList', 'InsertObj', 'DeleteObject', \
'ArchiveToOpenERP', 'IsCRMInstalled', 'GetPartners', 'GetObjectItems', \
'CreateCase', 'MakeAttachment', 'CreateContact', 'CreatePartner', 'getitem', 'setitem', \
'SearchPartnerDetail', 'WritePartnerValues', 'GetAllState', 'GetAllCountry' ]
_reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
_reg_clsid_ = "{C6399AFD-763A-400F-8191-7F9D0503CAE2}"
_reg_progid_ = "Python.OpenERP.XMLRpcConn"
_reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"
def __init__(self,server='localhost',port=8069,uri='http://localhost:8069'):
self._server=server
self._port=port
self._uri=uri
self._obj_list=[]
self._dbname=''
self._uname='admin'
self._pwd='a'
self._login=False
self._running=False
self._uid=False
self._iscrm=True
self.partner_id_list=None
self.protocol=None
def getitem(self, attrib):
v=self.__getattribute__(attrib)
return str(v)
def setitem(self, attrib, value):
return self.__setattr__(attrib, value)
def GetDBList(self):
conn = xmlrpclib.ServerProxy(self._uri + '/xmlrpc/db')
try:
db_list = execute(conn, 'list')
if db_list == False:
self._running=False
return []
else:
self._running=True
except:
db_list=-1
self._running=True
return db_list
def login(self,dbname, user, pwd):
self._dbname = dbname
self._uname = user
self._pwd = pwd
conn = xmlrpclib.ServerProxy(str(self._uri) + '/xmlrpc/common')
uid = execute(conn,'login',dbname, ustr(user), ustr(pwd))
return uid
def GetAllObjects(self):
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[])
objects = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','read',ids,['model'])
obj_list = [item['model'] for item in objects]
return obj_list
def GetObjList(self):
self._obj_list=list(self._obj_list)
self._obj_list.sort(reverse=True)
return self._obj_list
def InsertObj(self, obj_title,obj_name,image_path):
self._obj_list=list(self._obj_list)
self._obj_list.append((obj_title,obj_name,ustr(image_path).encode('iso-8859-1')))
self._obj_list.sort(reverse=True)
def DeleteObject(self,sel_text):
self._obj_list=list(self._obj_list)
for obj in self._obj_list:
if obj[0] == sel_text:
self._obj_list.remove(obj)
break
def ArchiveToOpenERP(self, recs, mail):
import win32ui, win32con
conn = xmlrpclib.ServerProxy(self._uri + '/xmlrpc/object')
import eml
msg = ""
ext_msg = ""
eml_path=eml.generateEML(mail)
att_name = ustr(eml_path.split('\\')[-1])
cnt=1
flag=False
for rec in recs: #[('res.partner', 3, 'Agrolait')]
cnt+=1
obj = rec[0]
obj_id = rec[1]
ids=execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.attachment','search',[('res_id','=',obj_id),('name','=',att_name)])
object_ids = execute ( conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[('model','=',obj)])
object_name = execute( conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','read',object_ids,['name'])[0]['name']
sub = ustr(mail.Subject)
if ids:
name=execute(conn,'execute',self._dbname,int(self._uid),self._pwd,obj,'read',obj_id,['name'])['name']
ext_msg+=""" - File "{0}.eml" is already archived to {1} "{2}" .
""".format(sub,object_name,name)
continue
if len(sub) > 60:
l = 60 - len(sub)
sub = sub[0:l]
res={}
res['res_model'] = obj
content = "".join(open(eml_path,"r").readlines()).encode('base64')
res['name'] = att_name
res['datas_fname'] = sub+".eml"
res['datas'] = content
res['res_id'] = obj_id
execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.attachment','create',res)
msg+=""" - File "{0}.eml" archived to {1} "{2}".
""".format(sub,object_name,str(rec[2]))
flag=True
if flag:
t = "Mail archived to OpenERP.\nArchive Summary : \n"
if ext_msg != "" :
t+="\nAlready Attached Documents : \n"+ext_msg +"\n"
t+="Newly Attachment Documents:\n"+msg
win32ui.MessageBox(t,"Archive To OpenERP",win32con.MB_ICONINFORMATION)
return flag
def IsCRMInstalled(self):
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
id = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[('model','=','crm.lead')])
return id
def GetPartners(self):
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
ids=[]
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner','search',[])
ids.sort()
obj_list=[]
obj_list.append((-999, ustr('')))
for id in ids:
object = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner','read',[id],['id','name'])[0]
obj_list.append((object['id'], ustr(object['name']).encode('iso-8859-1')))
return obj_list
def GetObjectItems(self, search_list=[], search_text=''):
import win32ui
res = []
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
for obj in search_list:
object_ids = execute ( conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','search',[('model','=',obj)])
object_name = execute( conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.model','read',object_ids,['name'])[0]['name']
if obj == "res.partner.address":
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,obj,'search',['|',('name','ilike',ustr(search_text)),('email','ilike',ustr(search_text))])
recs = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,obj,'read',ids,['id','name','street','city'])
for rec in recs:
name = ustr(rec['name']).encode('iso-8859-1')
if rec['street']:
name += ', ' + ustr(rec['street']).encode('iso-8859-1')
if rec['city']:
name += ', ' + ustr(rec['city']).encode('iso-8859-1')
res.append((obj,rec['id'],name,object_name))
else:
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,obj,'search',[('name','ilike',ustr(search_text))])
recs = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,obj,'read',ids,['id','name'])
for rec in recs:
name = ustr(rec['name']).encode('iso-8859-1')
res.append((obj,rec['id'],name,object_name))
return res
def CreateCase(self, section, mail, partner_ids, with_attachments=True):
res={}
import win32ui
section=str(section)
partner_ids=eval(str(partner_ids))
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
res['name'] = ustr(mail.Subject)
res['description'] = ustr(mail.Body)
res['partner_name'] = ustr(mail.SenderName)
res['email_from'] = ustr(mail.SenderEmailAddress)
if partner_ids:
for partner_id in partner_ids:
res['partner_id'] = partner_id
partner_addr = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner','address_get',[partner_id])
res['partner_address_id'] = partner_addr['default']
id=execute(conn,'execute',self._dbname,int(self._uid),self._pwd,section,'create',res)
if section == 'project.issue':
execute(conn,'execute',self._dbname,int(self._uid),self._pwd,section,'convert_to_bug',[id])
recs=[(section,id,'')]
if with_attachments:
self.MakeAttachment(recs, mail)
else:
id=execute(conn,'execute',self._dbname,int(self._uid),self._pwd,section,'create',res)
recs=[(section,id,'')]
if with_attachments:
self.MakeAttachment(recs, mail)
def MakeAttachment(self, recs, mail):
attachments = mail.Attachments
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
att_folder_path = os.path.abspath(os.path.dirname(__file__)+"\\dialogs\\resources\\attachments\\")
if not os.path.exists(att_folder_path):
os.makedirs(att_folder_path)
for rec in recs: #[('res.partner', 3, 'Agrolait')]
obj = rec[0]
obj_id = rec[1]
res={}
res['res_model'] = obj
for i in xrange(1, attachments.Count+1):
fn = ustr(attachments[i].FileName).encode('iso-8859-1')
if len(fn) > 64:
l = 64 - len(fn)
f = fn.split('.')
fn = f[0][0:l] + '.' + f[-1]
att_path = os.path.join(att_folder_path,fn)
attachments[i].SaveAsFile(att_path)
f=open(att_path,"rb")
content = "".join(f.readlines()).encode('base64')
f.close()
res['name'] = ustr(attachments[i].DisplayName)
res['datas_fname'] = ustr(fn)
res['datas'] = content
res['res_id'] = obj_id
execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'ir.attachment','create',res)
def CreateContact(self, sel=None, res=None):
res=eval(str(res))
self.partner_id_list=eval(str(self.partner_id_list))
if self.partner_id_list.get(sel,-999) != -999:
res['partner_id'] = self.partner_id_list[sel]
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
id = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner.address','create',res)
return id
def CreatePartner(self, res):
res=eval(str(res))
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
ids = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner','search',[('name','=',res['name'])])
if ids:
return False
id = execute(conn,'execute',self._dbname,int(self._uid),self._pwd,'res.partner','create',res)
return id
def SearchPartnerDetail(self, search_email_id):
import win32ui
res_vals = []
address = {}
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
address_id = execute(conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.partner.address', 'search', [('email','ilike',ustr(search_email_id))])
if not address_id :
return
address = execute(conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.partner.address','read',address_id[0],['id','partner_id','name','street','street2','city','state_id','country_id','phone','mobile','email','fax','zip'])
for key, vals in address.items():
res_vals.append([key,vals])
return res_vals
def WritePartnerValues(self, new_vals):
import win32ui
flag = -1
new_dict = dict(new_vals)
email=new_dict['email']
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
address_id = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.partner.address', 'search', [('email','=',ustr(email))])
if not address_id:
return flag
address = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.partner.address','read',address_id[0],['id','partner_id','state_id','country_id'])
vals_res_address={ 'name' : new_dict['name'],
'street':new_dict['street'],
'street2' : new_dict['street2'],
'city' : new_dict['city'],
'phone' : new_dict['phone'],
'mobile' : new_dict['mobile'],
'fax' : new_dict['fax'],
'zip' : new_dict['zip'],
}
if new_dict['partner_id'] != -1:
vals_res_address['partner_id'] = new_dict['partner_id']
if new_dict['state_id'] != -1:
vals_res_address['state_id'] = new_dict['state_id']
if new_dict['country_id'] != -1:
vals_res_address['country_id'] = new_dict['country_id']
temp = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.partner.address', 'write', address_id, vals_res_address)
if temp:
flag=1
else:
flag=0
return flag
def GetAllState(self):
import win32ui
state_list = []
state_ids = []
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
state_ids = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.country.state', 'search', [])
for state_id in state_ids:
obj = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.country.state', 'read', [state_id],['id','name'])[0]
state_list.append((obj['id'], ustr(obj['name']).encode('iso-8859-1')))
return state_list
def GetAllCountry(self):
import win32ui
country_list = []
country_ids = []
conn = xmlrpclib.ServerProxy(self._uri+ '/xmlrpc/object')
country_ids = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.country', 'search', [])
for country_id in country_ids:
obj = execute( conn, 'execute', self._dbname, int(self._uid), self._pwd, 'res.country','read', [country_id], ['id','name'])[0]
country_list.append((obj['id'], ustr(obj['name']).encode('iso-8859-1')))
return country_list