[ADD] outlook module: taken outlook plugin from trunk-extra-addons
bzr revid: hmo@tinyerp.com-20100803140656-ugtgo0w4lzvplbo3
This commit is contained in:
parent
d264f31bb3
commit
12f6b99419
|
@ -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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
|
@ -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:
|
|
@ -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")
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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())
|
|
@ -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"
|
|
@ -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
|
@ -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 |
|
@ -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()
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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))
|
|
@ -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
|
Loading…
Reference in New Issue