File: mswDoc.py

package info (click to toggle)
bibus 1.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 12,328 kB
  • sloc: python: 30,792; sql: 211; makefile: 186; xml: 10; sh: 3
file content (353 lines) | stat: -rw-r--r-- 14,550 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# Copyright 2006 Mounir Errami. m.errami@gmail.com
# This file is part of Bibus, a bibliographic database that can
# work together with OpenOffice.org to generate bibliographic indexes.
#
# Bibus is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Bibus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Bibus; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
#
import Format.Converter
import copy,sys
import BIB, RefList
import win32com.client
import win32com.gen_py
import pywintypes
from pywintypes import IID
from pywintypes import *
import bibMSW.mswRef
import bibMSW.mswFormatter
import bibMSW.mswUtils
import bibMSW.mswCONST
import wx

# For documentation on the Document and Field Interfaces used see
#http://msdn2.microsoft.com/en-us/library/ms254954(en-us,VS.80).aspx
#It details the word objects scriptable from Python
#Example: for the Field Interface: see http://msdn2.microsoft.com/en-us/library/microsoft.office.interop.word.field_members.aspx
class mswDoc:
	"""Class that defines interaction between Bibus and MS Word active document
	mswDoc is calss that represents Microsfot Word Application instance!!!!!!
	the active document in ms word is accessed using the property :
	mswDoc.ActiveDocument
	"""
	def __init__(self):
		"""Grab the active word document
		Bibus doesn't keep any info about the doc, so a new doc is created
		for each operation (insertion, update, etc...)
		All information is kept in the active doc itself (ALT+F9 in msword dispay elements in each inserted field)
		This class contains functions to interact with a msword doc """
		self.application = win32com.client.Dispatch("Word.Application") #doc = msword application
		#self.application.Visible = False
		self.hasDocuments = False
		self.bibStyle = BIB.FORMAT_DICO
		self.mswFormatter = bibMSW.mswFormatter.mswFormatter(self.bibStyle,self.application)
		self.conv = self.__getConverter(self.bibStyle)
		self.biblioList = []
		#self.printConverterInfo()
	def hasOpenedDocuments(self):
		if self.application.Documents.Count>0:
			return True
		else:
			#self.application.Quit()
			return False
		
	def MSWInsert(self, ref):
		"""Inserts a Field in the document corresponding to the selected ref in Bibus so that
		The Field is an Addin Type, so its value is hidden to the user (to display in the word doc, ALT+F9)
		Field.Result.Text is what you see in the doc
		Field.Code.Text is hidden and is <Author> Mounir Errami</Author><Year>2005</Year> etc...
		The XML keys depends are set according to bibus conf depending on the type of reference to insert => xmlKeys = BIB.EDIT[BIB.BIB_TYPE[int(ref[0][2])]][0]"""
		allRefText =bibMSW.mswCONST.me_MSWBIBUS_ADDIN_REF_TAG
		for t in BIB.BIB_FIELDS[:-1]:
			if not unicode(ref[0][BIB.BIBLIOGRAPHIC_FIELDS[t]]):
				continue
			elif t!="BibliographicType":
 				allRefText=allRefText+"<"+str(t)+">"+unicode(ref[0][BIB.BIBLIOGRAPHIC_FIELDS[t]])+"</"+str(t)+">"
			else:
				allRefText=allRefText+"<"+str(t)+">"+BIB.BIB_TYPE[ref[0][BIB.BIBLIOGRAPHIC_FIELDS[t]]]+"</"+str(t)+">"
		allRefText = allRefText+"<"+bibMSW.mswCONST.me_MSWBIBUS_CITE_RANGES+">"+"for ranges"+"</"+bibMSW.mswCONST.me_MSWBIBUS_CITE_RANGES+">"
		allRefText = allRefText+"<"+bibMSW.mswCONST.me_MSWBIBUS_CITE_DUPLICATES+"></"+bibMSW.mswCONST.me_MSWBIBUS_CITE_DUPLICATES+">"
		#resText is the text displayed to the user when reference is inserted ([1] or Smith et al, 2005)
		#resText depends on the style and has to be set accordingly
		resText = "{"+ref[0][1]+"}"
		nfo =bibMSW.mswRef.mswRef(self,None,bibMSW.mswCONST.me_MSWBIBUS_CITE_TAG,resText,allRefText)
		
	def MSWgetBibusBiblio(self):
		"""Gets the bibliographic field (only one per document)
		This field has the following particularity
		Field.Data ==me_MSWBIBUS_BIBLIO_TAG
		Note: citation fields within the doc have the following particularity
		Field.Data ==me_MSWBIBUS_CITE_TAG"""
		for myField in self.application.ActiveDocument.Fields:
    			if myField.Type == bibMSW.mswCONST.me_wdFieldAddin :
				if myField.Data==bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_TAG :
					return myField
		return None

	def MSWCreateBiblio(self):
		"""Create the bibliographic Field"""
		f_biblioField=self.MSWgetBibusBiblio()
		if f_biblioField!=None:
			f_biblioField.Result.Select()
		else:# f_biblioField == None:
			ar=self.application.ActiveDocument.Range()
			ar.Collapse(0x0)
			ar.InsertBreak(bibMSW.mswCONST.me_wdPageBreak)
			rToInsert = ar.Select()
			self.application.Selection.Collapse(0x0)
		try:
			f_biblioField =self.application.ActiveDocument.Fields.Add(self.application.Selection.Range,bibMSW.mswCONST.me_wdFieldEmpty,"BiblioInsert",False) 
			f_biblioField.Code.Text="ADDIN BibusBiblio"
			f_biblioField.Data=bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_TAG
			#print " Passing "
		except (pywintypes.com_error):
			pass
		self.MSWUpdateBiblio()
			
	def MSWUpdateBiblio(self):
		"""Fill the bibliographic Field
		Adds information from each citation field and concatenate into the biblioField.Result.Text (visible to the user)
		"""
		f_biblioField=self.MSWgetBibusBiblio()
		if f_biblioField == None:
			#print "COuldn't create Biblio"
			self.MSWCreateBiblio()
			return
		biblioResStr=""
		biblioCodeStr=""
		biblioResStr,biblioCodeStr = self.createBiblioStrings()
		f_biblioField.Result.Text = biblioResStr
		f_biblioField.Code.Text = biblioCodeStr
		f_biblioField.Data = bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_TAG
	
		
		
		
	def isFieldBiblio(self,field):
		"""Check if a field is a bibliographic field"""
		if field.Type != bibMSW.mswCONST.me_wdFieldAddin :
			return False
		if field.Data!=bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_TAG:
			return False
		return True
		
	def __setStyle(self,style):
		"""Set the bibus Style to insert the ref"""
		self.bibStyle = style
		self.conv = self.__getConverter(self.bibStyle)
	
	def __getConverter(self,style):
		"""Set the Converter or read from default
		Take into account the different versions of bibus styles"""
		if style:
			if style['version'] == 1.0:
				return Format.Converter.Converter(conv=style)
			else:
				return Format.Converter.Converter(conv=style['fields'])
		else:
			return Format.Converter.Converter()
		
	def printConverterInfo(self):
		"""This a development function called via menu print conv info"""
		#self.mswFormatter.fuseCitations(self.application.ActiveDocument.Fields)
		#print aField.Result, aField.Result.Start , aField.Result.End
		#wdW = 0x2
		#aField.Result.Delete()
		#print aField.Result.Find.Execute("Cheong", ReplaceWith = "allo")
		#if find == True:
		#	print "Found"
		#print aField.Result.Text
		
		citationFields = bibMSW.mswUtils.getCitationFields(self.application.ActiveDocument.Fields)
		#for f in self.application.ActiveDocument.Fields:
		#	code = f.Code.Text
		#	if code.find("BibusRef")!=-1:
		#		f.Data = bibMSW.mswCONST.me_MSWBIBUS_CITE_TAG
		#	print f.Result.Text
		#fuseCitations
		self.mswFormatter.fuseCitations(citationFields)
		#citationFields = bibMSW.mswUtils.getCitationFields(self.application.ActiveDocument.Fields)
		#for f in self.application.ActiveDocument.Fields:
		#	print f.Result.Text
		##self.mswFormatter.addDuplicateInfo(citationFields)	
		#print int("a")
		#self.trySequence()
		return

	def trySequence(self):
		"""Development function to find out the best sequence when finalizing
		i.e. shortest time and correct result"""
		self.updateCitationText()
		self.fuseCitations(self.application.ActiveDocument.Fields)
		self.preFormatCitations()
		#self.MSWCreateBiblio()
		#self.formatBiblioString()
		
	def createBiblioStrings(self):
		"""
		Adds information from each citation field and concatenate into 
		biblioResultString (visible to the user) and into
		biblioCodeString (invisible, unless ALT+F9 entered)
		biblioCodeString is in XML format and it will be used for final formatting
		Far far far too long
		"""
		#bibRangeList = [] 
		#relativeStart = 0
		biblioResultString="\n"+ self.mswFormatter.getBiblioTitle() +", bibus Generated - Not formatted"
		biblioCodeString=bibMSW.mswCONST.me_MSWBIBUS_ADDIN_BIB_TAG
		i=1
		entryList=[]
		self.biblioList = []
		newEntry= bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_NEWENTRY
		for myField in self.application.ActiveDocument.Fields:
			#bibRangeEntryList = []
			biblioCodeEntry=""
			biblioResultEntry=""
			if bibMSW.mswUtils.isFieldCitation(myField)==False:
				continue
			else:
				stringToAnalyze = myField.Code.Text
				wordCitationFields = bibMSW.mswUtils.getXmlKeysFromString(stringToAnalyze)
				wordCitationBiblioType = bibMSW.mswUtils.getXmlValueFromString("BibliographicType",stringToAnalyze)
				jfield = 0
				myId =""
				for field in wordCitationFields: 
					if self.conv[wordCitationBiblioType].has_key(field)==False:
						continue
					func,param = self.conv[bibMSW.mswUtils.getXmlValueFromString("BibliographicType",stringToAnalyze)][field]# NEED VALUE FROM BIB_TYPE, ORI CODE = func,param = self.conv[BIB_TYPE[dbref[1]]][field]
					#if field == "Title" :
					#	print " field func=", param
					valueToFormat = bibMSW.mswUtils.getXmlValueFromString(field,stringToAnalyze)
					tmpdata =  apply(func,(valueToFormat,self.conv['locale']) + param)
					biblioCodeEntry =biblioCodeEntry+"<"+field+">"+tmpdata+"</"+field+">"
					if jfield>=3 :#This suppresses Id, identifier, adress
						biblioResultEntry=biblioResultEntry+tmpdata+";"
					jfield=jfield+1
					if field == "Identifier":
						myId =	valueToFormat
				myId = bibMSW.mswUtils.getXmlValueFromString("Identifier",stringToAnalyze)
				if entryList.count(myId)==0: 
					entryList.append(myId)
					biblioResultString= biblioResultString +"\n%s"%i+".\t"+biblioResultEntry
					biblioCodeString =biblioCodeString+"\n<"+newEntry+">"
					tIdConst= bibMSW.mswCONST.me_MSWBIBUS_BIBLIO_IDENTIFIER
					biblioCodeString =biblioCodeString+"<"+tIdConst+">"+str(i)+"</"+tIdConst+">"
					biblioCodeString =biblioCodeString+biblioCodeEntry
					biblioCodeString =biblioCodeString+"</"+newEntry+">"
					self.biblioList.append(biblioCodeEntry)
					i=i+1
		#print self.biblioList
		return (biblioResultString,biblioCodeString)
	
	def formatBiblioString(self):
		"""This function formats the biblio according to the Style chosen by the user"""
		biblioString = self.mswFormatter.getFormattedBiblioString(self.biblioList, self)
		bibField = self.MSWgetBibusBiblio()
		nfo = bibMSW.mswRef.mswRef(self,bibField)
		nfo.setResult(biblioString)
		#print "rangePosList=",self.mswFormatter.getBiblioRangesFromMSW(self.application)
		self.mswFormatter.formatBibliographicIndex(self)
		
	def getMSWFormatter(self):
		return self.mswFormatter
		
	def getMSWApplication(self):
		return self.application
		
		
	def updateCitationText(self):
		"""Update the citation text if numbering is selected"""
		#print "Update called"
		
		oBrackets,cBrakets = self.mswFormatter.getBracket()
		Fields = self.application.ActiveDocument.Fields
		isCitation = bibMSW.mswCONST.me_MSWBIBUS_CITE_TAG
		idList = []
		if self.mswFormatter.isNumberEntries()==True :#and self.mswFormatter.isSortByPosition() == True :
			refIds = {}
			nbUnik =1
			
			for myField in Fields:
				#print "myField.Result=" ,myField.Result.Text, "Data =",myField.Data
				if bibMSW.mswUtils.isFieldCitation(myField)==True:
					idToComp = bibMSW.mswUtils.getXmlValueFromString("Identifier",myField.Code.Text)
					if idList.count(idToComp)==0:
						idList.append(idToComp)
					myField.Result.Text=oBrackets+str(idList.index(idToComp)+1)+cBrakets
		else :
			citationFields =[]
			for myField in Fields:
				if bibMSW.mswUtils.isFieldCitation(myField)==False:
					continue
				nfo = bibMSW.mswRef.mswRef(self,myField)
				citationFields.append(myField)
				idToCite,newCiteText= self.mswFormatter.applyCitationTemplate(myField)
				nfo.setResult(oBrackets+idToCite+cBrakets)
				myField.Code.Text = newCiteText #if modify Code before changing Result, miscrosoft word bugs and won't accept the changes!
				myField.Data = bibMSW.mswCONST.me_MSWBIBUS_CITE_TAG #if modify Code before changing Result, miscrosoft word bugs and won't accept the changes!
				self.mswFormatter.normalizeCitationRangeFont(myField.Result)

	def preFormatCitations(self): 
		mFields =  bibMSW.mswUtils.getCitationFields(self.application.ActiveDocument.Fields)
		self.mswFormatter.preFormatCitations(mFields)
		return mFields
			
	def fuseCitations(self,mFields):
		#mFields =  bibMSW.mswUtils.getCitationFields(self.application.ActiveDocument.Fields)
		self.mswFormatter.fuseCitations(mFields)
		return mFields

	def minimizeWindow(self):
		"""Faster when MS Word window is minimzed"""
		#print " Version =>%s<"%self.application.Version
		Version = float(self.application.Version)
		if Version <=9:
			return			
		if self.application.WindowState !=bibMSW.mswCONST.me_wdWindowStateMinimize:
			self.application.Activate()
			self.application.WindowState = bibMSW.mswCONST.me_wdWindowStateMinimize
	
	def normalWindow(self):
		"""Display windows to normal size, called after minimisation"""
		self.application.Activate()
		self.application.WindowState =  bibMSW.mswCONST.me_wdWindowStateNormal
	
	def finaliseDoc(self,awxWindow):
		"""Finalization of citation, checks if document if saved
		if save fails, the user can still go on if he wants to"""
		activeDoc = self.application.ActiveDocument
		if activeDoc.Saved == False:
			dlg = wx.MessageDialog(awxWindow, "Your file must be saved before proceeding","The file must be saved!",wx.OK|wx.CANCEL|wx.ICON_EXCLAMATION,wx.DefaultPosition)
			if dlg.ShowModal()==wx.ID_OK:
				try:
					self.normalWindow()
					activeDoc.Save()
				except (pywintypes.com_error):
					ndlg = wx.MessageDialog(awxWindow, "File could not be saved. Do you want Bibus to proceed anyway? (Make a copy of your document before)","Proceed anyway?",wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION,wx.DefaultPosition)
					if ndlg.ShowModal()==wx.ID_YES:
						 s="proceed"
					else :
						s= "aborting"
						return
			else:
				s= "returning"
				return
		wdps = 0xa
		activeDoc.Content.Copy()
		self.application.Visible = 1
		newDoc = self.application.Documents.Add()
		newDoc.Activate()
		newDoc.Content.Paste()