summaryrefslogtreecommitdiff
path: root/wizards/com/sun/star/wizards/agenda
diff options
context:
space:
mode:
Diffstat (limited to 'wizards/com/sun/star/wizards/agenda')
-rw-r--r--wizards/com/sun/star/wizards/agenda/AgendaTemplate.py1197
-rw-r--r--wizards/com/sun/star/wizards/agenda/AgendaWizardDialog.py293
-rw-r--r--wizards/com/sun/star/wizards/agenda/AgendaWizardDialogConst.py63
-rw-r--r--wizards/com/sun/star/wizards/agenda/AgendaWizardDialogImpl.py463
-rw-r--r--wizards/com/sun/star/wizards/agenda/AgendaWizardDialogResources.py153
-rw-r--r--wizards/com/sun/star/wizards/agenda/CGAgenda.py27
-rw-r--r--wizards/com/sun/star/wizards/agenda/CGTopic.py45
-rw-r--r--wizards/com/sun/star/wizards/agenda/TopicsControl.py886
8 files changed, 3127 insertions, 0 deletions
diff --git a/wizards/com/sun/star/wizards/agenda/AgendaTemplate.py b/wizards/com/sun/star/wizards/agenda/AgendaTemplate.py
new file mode 100644
index 000000000000..d98536ec568c
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/AgendaTemplate.py
@@ -0,0 +1,1197 @@
+import uno
+from TemplateConsts import *
+from threading import RLock
+from wizards.text.TextDocument import *
+from wizards.common.FileAccess import FileAccess
+from wizards.text.TextSectionHandler import TextSectionHandler
+from TopicsControl import TopicsControl
+from datetime import date as dateTimeObject
+
+from com.sun.star.text.PlaceholderType import TEXT
+from com.sun.star.i18n.NumberFormatIndex import TIME_HHMM, DATE_SYSTEM_LONG
+
+def synchronized(lock):
+ ''' Synchronization decorator. '''
+ def wrap(f):
+ def newFunction(*args, **kw):
+ lock.acquire()
+ try:
+ return f(*args, **kw)
+ finally:
+ lock.release()
+ return newFunction
+ return wrap
+
+'''
+The classes here implement the whole document-functionality of the agenda wizard:
+the live-preview and the final "creation" of the document,
+when the user clicks "finish". <br/>
+<br/>
+<h2>Some terminology:<h2/>
+items are names or headings. we don't make any distinction.
+
+<br/>
+The Agenda Template is used as general "controller"
+of the whole document, whereas the two child-classes ItemsTable
+and TopicsTable control the item tables (note plural!) and the
+topics table (note singular).<br/>
+<br/>
+Other small classes are used to abstract the handling of cells and text and we
+try to use them as components.
+<br/><br/>
+We tried to keep the Agenda Template as flexible as possible, though there
+must be many limitations, because it is generated dynamically.<br/><br/>
+To keep the template flexible the following decisions were made:<br/>
+1. Item tables.<br/>
+1.a. there might be arbitrary number of Item tables.<br/>
+1.b. Item tables design (bordewr, background) is arbitrary.<br/>
+1.c. Items text styles are individual,
+and use stylelist styles with predefined names.<br/>
+As result the following limitations:<br/>
+Pairs of Name->value for each item.<br/>
+Tables contain *only* those pairs.<br/>
+2. Topics table.<br/>
+2.a. arbitrary structure.<br/>
+2.b. design is arbitrary.<br/>
+As result the following limitations:<br/>
+No column merge is allowed.<br/>
+One compolsary Heading row.<br/>
+<br/><br/>
+To let the template be flexible, we use a kind of "detection": we look where
+the items are read the design of each table, reaplying it after writing the
+table.AgendaTemplate.document
+<br/><br/>
+A note about threads:<br/>
+Many methods here are synchronized, in order to avoid colission made by
+events fired too often.
+@author rpiterman
+'''
+class AgendaTemplate(TextDocument):
+
+ writtenTopics = []
+ itemsCache = None
+ _allItems = []
+ items = []
+ itemsMap = {}
+ document = None
+ textSectionHandler = None
+ template = None
+ agenda = None
+ lock = RLock()
+
+ '''constructor. The document is *not* loaded here.
+ only some formal members are set.
+ @param AgendaTemplate.document_ service factory.
+ @param agenda_ the data model (CGAgenda)
+ @param resources_ resources.
+ '''
+
+ def __init__(self, xmsf_, agenda_, resources_, listener):
+ super(AgendaTemplate,self).__init__(xmsf_,listener, None,
+ "WIZARD_LIVE_PREVIEW")
+ AgendaTemplate.agenda = agenda_
+ self.resources = resources_
+
+ if AgendaTemplate.itemsCache is None:
+ self.initItemsCache()
+
+ AgendaTemplate._allItems = None
+
+ @synchronized(lock)
+ def load(self, templateURL, topics):
+ AgendaTemplate.template = self.calcTemplateName(templateURL)
+ AgendaTemplate.document = self.loadAsPreview(templateURL, False)
+ self.xFrame.ComponentWindow.Enable = False
+ self.xTextDocument.lockControllers()
+ self.initialize()
+ self.initializeData(topics)
+ self.xTextDocument.unlockControllers()
+
+ '''
+ The agenda templates are in format of aw-XXX.ott
+ the templates name is then XXX.ott.
+ This method calculates it.
+ @param url
+ @return the template name without the "aw-" at the beginning.
+ '''
+
+ def calcTemplateName(self, url):
+ return FileAccess.connectURLs(
+ FileAccess.getParentDir(url), FileAccess.getFilename(url)[3:])
+
+ '''synchronize the document to the model.<br/>
+ this method rewrites all titles, item tables , and the topics table-
+ thus synchronizing the document to the data model (CGAgenda).
+ @param topicsData since the model does not contain Topics
+ information (it is only actualized on save) the given list
+ supplies this information.
+ '''
+
+ def initializeData(self, topicsData):
+ for i in self.itemsTables:
+ try:
+ i.write("")
+ except Exception, ex:
+ traceback.print_exc()
+
+ self.redrawTitle("txtTitle")
+ self.redrawTitle("txtDate")
+ self.redrawTitle("txtTime")
+ self.redrawTitle("cbLocation")
+ if AgendaTemplate.agenda.cp_TemplateName is None:
+ AgendaTemplate.agenda.cp_TemplateName = ""
+ self.setTemplateTitle(AgendaTemplate.agenda.cp_TemplateName)
+
+ '''redraws/rewrites the table which contains the given item
+ This method is called when the user checks/unchecks an item.
+ The table is being found, in which the item is, and redrawn.
+ @param itemName
+ '''
+
+ @classmethod
+ @synchronized(lock)
+ def redraw(self, itemName):
+ AgendaTemplate.xTextDocument.lockControllers()
+ try:
+ # get the table in which the item is...
+ itemsTable = AgendaTemplate.itemsMap[itemName]
+ # rewrite the table.
+ itemsTable.write(None)
+ except Exception, e:
+ traceback.print_exc()
+ AgendaTemplate.xTextDocument.unlockControllers()
+
+ '''update the documents title property to the given title
+ @param newTitle title.
+ '''
+
+ @synchronized(lock)
+ def setTemplateTitle(self, newTitle):
+ self.m_xDocProps.Title = newTitle
+
+ '''checks the data model if the
+ item corresponding to the given string should be shown
+ @param itemName a string representing an Item (name or heading).
+ @return true if the model specifies that the item should be displayed.
+ '''
+
+ @classmethod
+ def isShowItem(self, itemName):
+ if itemName == FILLIN_MEETING_TYPE:
+ return AgendaTemplate.agenda.cp_ShowMeetingType
+ elif itemName == FILLIN_READ:
+ return AgendaTemplate.agenda.cp_ShowRead
+ elif itemName == FILLIN_BRING:
+ return AgendaTemplate.agenda.cp_ShowBring
+ elif itemName == FILLIN_NOTES:
+ return AgendaTemplate.agenda.cp_ShowNotes
+ elif itemName == FILLIN_FACILITATOR:
+ return AgendaTemplate.agenda.cp_ShowFacilitator
+ elif itemName == FILLIN_TIMEKEEPER:
+ return AgendaTemplate.agenda.cp_ShowTimekeeper
+ elif itemName == FILLIN_NOTETAKER:
+ return AgendaTemplate.agenda.cp_ShowNotetaker
+ elif itemName == FILLIN_PARTICIPANTS:
+ return AgendaTemplate.agenda.cp_ShowAttendees
+ elif itemName == FILLIN_CALLED_BY:
+ return AgendaTemplate.agenda.cp_ShowCalledBy
+ elif itemName == FILLIN_OBSERVERS:
+ return AgendaTemplate.agenda.cp_ShowObservers
+ elif itemName == FILLIN_RESOURCE_PERSONS:
+ return AgendaTemplate.agenda.cp_ShowResourcePersons
+ else:
+ raise ValueError("No such item")
+
+ '''itemsCache is a Map containing all agenda item. These are object which
+ "write themselfs" to the table, given a table cursor.
+ A cache is used in order to reuse the objects, instead of recreate them.
+ This method fills the cache will all items objects (names and headings).
+ '''
+
+ def initItemsCache(self):
+ AgendaTemplate.itemsCache = {}
+ # Headings
+ AgendaTemplate.itemsCache[FILLIN_MEETING_TYPE] = AgendaItem(
+ FILLIN_MEETING_TYPE,
+ TextElement (self.resources.itemMeetingType),
+ PlaceholderElement(
+ self.resources.reschkMeetingTitle_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_BRING] = AgendaItem(
+ FILLIN_BRING, TextElement (self.resources.itemBring),
+ PlaceholderElement (
+ self.resources.reschkBring_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_READ] = AgendaItem (
+ FILLIN_READ, TextElement (self.resources.itemRead),
+ PlaceholderElement (
+ self.resources.reschkRead_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_NOTES] = AgendaItem (
+ FILLIN_NOTES, TextElement (self.resources.itemNote),
+ PlaceholderElement (
+ self.resources.reschkNotes_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+
+ # Names
+ AgendaTemplate.itemsCache[FILLIN_CALLED_BY] = AgendaItem(
+ FILLIN_CALLED_BY,
+ TextElement (self.resources.itemCalledBy),
+ PlaceholderElement (
+ self.resources.reschkConvenedBy_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_FACILITATOR] = AgendaItem(
+ FILLIN_FACILITATOR,
+ TextElement (self.resources.itemFacilitator),
+ PlaceholderElement (
+ self.resources.reschkPresiding_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_PARTICIPANTS] = AgendaItem(
+ FILLIN_PARTICIPANTS,
+ TextElement (self.resources.itemAttendees),
+ PlaceholderElement(
+ self.resources.reschkAttendees_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_NOTETAKER] = AgendaItem(
+ FILLIN_NOTETAKER,
+ TextElement(self.resources.itemNotetaker),
+ PlaceholderElement(
+ self.resources.reschkNoteTaker_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_TIMEKEEPER] = AgendaItem(
+ FILLIN_TIMEKEEPER,
+ TextElement (self.resources.itemTimekeeper),
+ PlaceholderElement(
+ self.resources.reschkTimekeeper_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_OBSERVERS] = AgendaItem(
+ FILLIN_OBSERVERS,
+ TextElement(self.resources.itemObservers),
+ PlaceholderElement(
+ self.resources.reschkObservers_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+ AgendaTemplate.itemsCache[FILLIN_RESOURCE_PERSONS] = AgendaItem(
+ FILLIN_RESOURCE_PERSONS,
+ TextElement(self.resources.itemResource),
+ PlaceholderElement(
+ self.resources.reschkResourcePersons_value,
+ self.resources.resPlaceHolderHint, self.xMSF))
+
+ '''Initializes a template.<br/>
+ This method does the following tasks:<br/>
+ Get a Time and Date format for the document, and retrieve the null
+ date of the document (which is document-specific).<br/>
+ Initializes the Items Cache map.
+ Analyses the document:<br/>
+ -find all "fille-ins" (apear as &gt;xxx&lt; in the document).
+ -analyze all items sections (and the tables in them).
+ -locate the titles and actualize them
+ -analyze the topics table
+ '''
+
+ def initialize(self):
+ '''
+ Get the default locale of the document,
+ and create the date and time formatters.
+ '''
+ AgendaTemplate.dateUtils = Helper.DateUtils(
+ self.xMSF, AgendaTemplate.document)
+ AgendaTemplate.formatter = AgendaTemplate.dateUtils.formatter
+ AgendaTemplate.dateFormat = AgendaTemplate.dateUtils.getFormat(DATE_SYSTEM_LONG)
+ AgendaTemplate.timeFormat = AgendaTemplate.dateUtils.getFormat(TIME_HHMM)
+
+ '''
+ get the document properties object.
+ '''
+
+ self.m_xDocProps = AgendaTemplate.document.DocumentProperties
+ self.initItemsCache()
+ AgendaTemplate._allItems = self.searchFillInItems()
+ self.initializeTitles()
+ self.initializeItemsSections()
+ AgendaTemplate.textSectionHandler = TextSectionHandler(
+ AgendaTemplate.document, AgendaTemplate.document)
+ self.topics = Topics()
+ del AgendaTemplate._allItems[:]
+ AgendaTemplate._allItems = None
+
+ '''
+ locates the titles (name, location, date, time)
+ and saves a reference to thier Text ranges.
+ '''
+
+ def initializeTitles(self):
+ i = 0
+ while i < len(AgendaTemplate._allItems):
+ workwith = AgendaTemplate._allItems[i]
+ text = workwith.String.lstrip().lower()
+ if text == FILLIN_TITLE:
+ AgendaTemplate.teTitle = PlaceholderTextElement(
+ workwith, self.resources.resPlaceHolderTitle,
+ self.resources.resPlaceHolderHint,
+ AgendaTemplate.document)
+ AgendaTemplate.trTitle = workwith
+ del AgendaTemplate._allItems[i]
+ i -= 1
+ elif text == FILLIN_DATE:
+ AgendaTemplate.teDate = PlaceholderTextElement(
+ workwith, self.resources.resPlaceHolderDate,
+ self.resources.resPlaceHolderHint,
+ AgendaTemplate.document)
+ AgendaTemplate.trDate = workwith
+ del AgendaTemplate._allItems[i]
+ i -= 1
+ elif text == FILLIN_TIME:
+ AgendaTemplate.teTime = PlaceholderTextElement(
+ workwith, self.resources.resPlaceHolderTime,
+ self.resources.resPlaceHolderHint,
+ AgendaTemplate.document)
+ AgendaTemplate.trTime = workwith
+ del AgendaTemplate._allItems[i]
+ i -= 1
+ elif text == FILLIN_LOCATION:
+ AgendaTemplate.teLocation = PlaceholderTextElement(
+ workwith, self.resources.resPlaceHolderLocation,
+ self.resources.resPlaceHolderHint,
+ AgendaTemplate.document)
+ AgendaTemplate.trLocation = workwith
+ del AgendaTemplate._allItems[i]
+ i -= 1
+ i += 1
+
+ '''
+ searches the document for items in the format "&gt;*&lt;"
+ @return a vector containing the XTextRanges of the found items
+ '''
+
+ def searchFillInItems(self):
+ try:
+ sd = AgendaTemplate.document.createSearchDescriptor()
+ sd.setSearchString("<[^>]+>")
+ sd.setPropertyValue("SearchRegularExpression", True)
+ sd.setPropertyValue("SearchWords", True)
+ ia = AgendaTemplate.document.findAll(sd)
+ try:
+ l = [ia.getByIndex(i) for i in xrange(ia.Count)]
+ except Exception, ex:
+ print "Nonfatal Error in finding fillins."
+ return l
+ except Exception, ex:
+ traceback.print_exc()
+ raise AttributeError (
+ "Fatal Error: Loading template failed: searching fillins failed")
+
+ '''
+ analyze the item sections in the template.
+ delegates the analyze of each table to the ItemsTable class.
+ '''
+
+ def initializeItemsSections(self):
+ sections = self.getSections(AgendaTemplate.document, SECTION_ITEMS)
+ # for each section - there is a table...
+ self.itemsTables = []
+ for i in sections:
+ try:
+ self.itemsTables.append(
+ ItemsTable(self.getSection(i), self.getTable(i)))
+ except Exception, ex:
+ traceback.print_exc()
+ raise AttributeError (
+ "Fatal Error while initialilzing \
+ Template: items table in section " + i)
+
+
+ def getSections(self, document, s):
+ allSections = document.TextSections.ElementNames
+ return self.getNamesWhichStartWith(allSections, s)
+
+ @classmethod
+ def getSection(self, name):
+ return getattr(AgendaTemplate.document.TextSections, name)
+
+ @classmethod
+ def getTable(self, name):
+ return getattr(AgendaTemplate.document.TextTables, name)
+
+ @classmethod
+ @synchronized(lock)
+ def redrawTitle(self, controlName):
+ try:
+ if controlName == "txtTitle":
+ self.writeTitle(
+ AgendaTemplate.teTitle, AgendaTemplate.trTitle,
+ AgendaTemplate.agenda.cp_Title)
+ elif controlName == "txtDate":
+ self.writeTitle(
+ AgendaTemplate.teDate, AgendaTemplate.trDate,
+ self.getDateString(AgendaTemplate.agenda.cp_Date))
+ elif controlName == "txtTime":
+ self.writeTitle(
+ AgendaTemplate.teTime, AgendaTemplate.trTime,
+ self.getTimeString(AgendaTemplate.agenda.cp_Time))
+ elif controlName == "cbLocation":
+ self.writeTitle(
+ AgendaTemplate.teLocation, AgendaTemplate.trLocation,
+ AgendaTemplate.agenda.cp_Location)
+ else:
+ raise IllegalArgumentException ("No such title control...")
+ except Exception:
+ traceback.print_exc()
+
+ @classmethod
+ def writeTitle(self, te, tr, text):
+ if text is None:
+ te.text = ""
+ else:
+ te.text = text
+ te.write(tr)
+
+ @classmethod
+ def getDateString(self, d):
+ if d is None or d == "":
+ return ""
+ date = int(d)
+ year = date / 10000
+ month = (date % 10000) / 100
+ day = date % 100
+ dateObject = dateTimeObject(year, month, day)
+ return AgendaTemplate.dateUtils.format(
+ AgendaTemplate.dateFormat, dateObject)
+
+ @classmethod
+ def getTimeString(self, s):
+ if s is None or s == "":
+ return ""
+ time = int(s)
+ t = ((time / float(1000000)) / float(24)) \
+ + ((time % 1000000) / float(1000000)) / float(35)
+ return self.formatter.convertNumberToString(AgendaTemplate.timeFormat, t)
+
+ @synchronized(lock)
+ def finish(self, topics):
+ self.createMinutes(topics)
+ self.deleteHiddenSections()
+ AgendaTemplate.textSectionHandler.removeAllTextSections()
+
+ '''
+ hidden sections exist when an item's section is hidden because the
+ user specified not to display any items which it contains.
+ When finishing the wizard removes this sections entireley from the document.
+ '''
+
+ def deleteHiddenSections(self):
+ allSections = AgendaTemplate.document.TextSections.ElementNames
+ try:
+ for i in allSections:
+ self.section = self.getSection(i)
+ visible = bool(Helper.getUnoPropertyValue(
+ self.section, "IsVisible"))
+ if not visible:
+ self.section.Anchor.String = ""
+
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''
+ create the minutes for the given topics or remove the minutes
+ section from the document.
+ If no topics are supplied, or the user specified not to create minuts,
+ the minutes section will be removed,
+ @param topicsData supplies PropertyValue arrays containing
+ the values for the topics.
+ '''
+
+ @synchronized(lock)
+ def createMinutes(self, topicsData):
+ # if the minutes section should be removed (the
+ # user did not check "create minutes")
+ if not AgendaTemplate.agenda.cp_IncludeMinutes \
+ or len(topicsData) <= 1:
+ try:
+ minutesAllSection = self.getSection(SECTION_MINUTES_ALL)
+ minutesAllSection.Anchor.String = ""
+ except Exception, ex:
+ traceback.print_exc()
+
+ # the user checked "create minutes"
+ else:
+ try:
+ topicStartTime = int(AgendaTemplate.agenda.cp_Time)
+ #first I replace the minutes titles...
+ AgendaTemplate.items = self.searchFillInItems()
+ itemIndex = 0
+ for item in self.items:
+ itemText = item.String.lstrip().lower()
+ if itemText == FILLIN_MINUTES_TITLE:
+ self.fillMinutesItem(
+ item, AgendaTemplate.agenda.cp_Title,
+ self.resources.resPlaceHolderTitle)
+ elif itemText == FILLIN_MINUTES_LOCATION:
+ self.fillMinutesItem(
+ item, AgendaTemplate.agenda.cp_Location,
+ self.resources.resPlaceHolderLocation)
+ elif itemText == FILLIN_MINUTES_DATE:
+ self.fillMinutesItem(
+ item, getDateString(AgendaTemplate.agenda.cp_Date),
+ self.resources.resPlaceHolderDate)
+ elif itemText == FILLIN_MINUTES_TIME:
+ self.fillMinutesItem(
+ item, getTimeString(AgendaTemplate.agenda.cp_Time),
+ self.resources.resPlaceHolderTime)
+
+ self.items.clear()
+ '''
+ now add minutes for each topic.
+ The template contains *one* minutes section, so
+ we first use the one available, and then add a one...
+ topics data has *always* an empty topic at the end...
+ '''
+
+ for i in xrange(len(topicsData) - 1):
+ topic = topicsData[i]
+ AgendaTemplate.items = self.searchFillInItems()
+ itemIndex = 0
+ for item in self.items:
+ itemText = item.String.lstrip().lower()
+ if itemText == FILLIN_MINUTE_NUM:
+ fillMinutesItem(item, topic[0].Value, "")
+ elif itemText == FILLIN_MINUTE_TOPIC:
+ fillMinutesItem(item, topic[1].Value, "")
+ elif itemText == FILLIN_MINUTE_RESPONSIBLE:
+ fillMinutesItem(item, topic[2].Value, "")
+ elif itemText == FILLIN_MINUTE_TIME:
+ topicTime = 0
+ try:
+ topicTime = topic[3].Value
+ except Exception, ex:
+ pass
+
+ '''
+ if the topic has no time, we do not
+ display any time here.
+ '''
+ if topicTime == 0 or topicStartTime == 0:
+ time = topic[3].Value
+ else:
+ time = getTimeString(str(topicStartTime)) + " - "
+ topicStartTime += topicTime * 1000
+ time += getTimeString(str(topicStartTime))
+
+ fillMinutesItem(item, time, "")
+
+ AgendaTemplate.textSectionHandler.removeTextSectionbyName(
+ SECTION_MINUTES)
+ # after the last section we do not insert a one.
+ if i < len(topicsData) - 2:
+ AgendaTemplate.textSectionHandler.insertTextSection(
+ SECTION_MINUTES, AgendaTemplate.template, False)
+
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''given a text range and a text, fills the given
+ text range with the given text.
+ If the given text is empty, uses a placeholder with the giveb
+ placeholder text.
+ @param range text range to fill
+ @param text the text to fill to the text range object.
+ @param placeholder the placeholder text to use, if the
+ text argument is empty (null or "")
+ '''
+
+ def fillMinutesItem(self, Range, text, placeholder):
+ paraStyle = Helper.getUnoPropertyValue(Range, "ParaStyleName")
+ Range.setString(text)
+ Helper.setUnoPropertyValue(Range, "ParaStyleName", paraStyle)
+ if text == None or text == "":
+ if placeholder != None and not placeholder == "":
+ placeHolder = createPlaceHolder(
+ AgendaTemplate.document, placeholder,
+ self.resources.resPlaceHolderHint)
+ try:
+ Range.Start.Text.insertTextContent(
+ Range.Start, placeHolder, True)
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''creates a placeholder field with the given text and given hint.
+ @param AgendaTemplate.document service factory
+ @param ph place holder text
+ @param hint hint text
+ @return the place holder field.
+ '''
+
+ @classmethod
+ def createPlaceHolder(self, xmsf, ph, hint):
+ try:
+ placeHolder = xmsf.createInstance(
+ "com.sun.star.text.TextField.JumpEdit")
+ except Exception, ex:
+ traceback.print_exc()
+ return None
+
+ Helper.setUnoPropertyValue(placeHolder, "PlaceHolder", ph)
+ Helper.setUnoPropertyValue(placeHolder, "Hint", hint)
+ Helper.setUnoPropertyValue(
+ placeHolder, "PlaceHolderType", uno.Any("short",TEXT))
+ return placeHolder
+
+ def getNamesWhichStartWith(self, allNames, prefix):
+ v = []
+ for i in allNames:
+ if i.startswith(prefix):
+ v.append(i)
+ return v
+
+ '''Convenience method for inserting some cells into a table.
+ @param table
+ @param start
+ @param count
+ '''
+
+ @classmethod
+ def insertTableRows(self, table, start, count):
+ rows = table.Rows
+ rows.insertByIndex(start, count)
+
+ '''returns the row index for this cell name.
+ @param cellName
+ @return the row index for this cell name.
+ '''
+
+ @classmethod
+ def getRowIndex(self, cellName):
+ return int(cellName.RangeName[1:])
+
+ '''returns the rows count of this table, assuming
+ there is no vertical merged cells.
+ @param table
+ @return the rows count of the given table.
+ '''
+
+ @classmethod
+ def getRowCount(self, table):
+ cells = table.getCellNames()
+ return int(cells[len(cells) - 1][1:])
+
+class ItemsTable(object):
+ '''
+ the items in the table.
+ '''
+ items = []
+ table = None
+
+ def __init__(self, section_, table_):
+ ItemsTable.table = table_
+ self.section = section_
+ self.items = []
+ '''
+ go through all <*> items in the document
+ and each one if it is in this table.
+ If they are, register them to belong here, notice their order
+ and remove them from the list of all <*> items, so the next
+ search will be faster.
+ '''
+ i = 0
+ while i < len(AgendaTemplate._allItems):
+ workwith = AgendaTemplate._allItems[i]
+ t = Helper.getUnoPropertyValue(workwith, "TextTable")
+ if t == ItemsTable.table:
+ iText = workwith.String.lower().lstrip()
+ ai = AgendaTemplate.itemsCache[iText]
+ if ai is not None:
+ self.items.append(ai)
+ del AgendaTemplate._allItems[i]
+ AgendaTemplate.itemsMap[iText] = self
+ i -= 1
+ i += 1
+
+ '''
+ link the section to the template. this will restore the original table
+ with all the items.<br/>
+ then break the link, to make the section editable.<br/>
+ then, starting at cell one, write all items that should be visible.
+ then clear the rest and remove obsolete rows.
+ If no items are visible, hide the section.
+ @param dummy we need a param to make this an Implementation
+ of AgendaElement.
+ @throws Exception
+ '''
+
+ def write(self, dummy):
+ with AgendaTemplate.lock:
+ name = self.section.Name
+ # link and unlink the section to the template.
+ AgendaTemplate.textSectionHandler.linkSectiontoTemplate(
+ AgendaTemplate.template, name, self.section)
+ AgendaTemplate.textSectionHandler.breakLinkOfTextSection(
+ self.section)
+ # we need to get a instance after linking.
+ ItemsTable.table = AgendaTemplate.getTable(name)
+ self.section = AgendaTemplate.getSection(name)
+ cursor = ItemsTable.table.createCursorByCellName("A1")
+ # should this section be visible?
+ visible = False
+ # write items
+ # ===========
+ cellName = ""
+ '''
+ now go through all items that belong to this
+ table. Check each one agains the model. If it should
+ be display, call it's write method.
+ All items are of type AgendaItem which means they write
+ two cells to the table: a title (text) and a placeholder.
+ see AgendaItem class below.
+ '''
+ for i in self.items:
+ if AgendaTemplate.isShowItem(i.name):
+ visible = True
+ i.table = ItemsTable.table
+ i.write(cursor)
+ # I store the cell name which was last written...
+ cellName = cursor.RangeName
+ cursor.goRight(1, False)
+
+ if visible:
+ boolean = True
+ else:
+ boolean = False
+ Helper.setUnoPropertyValue(self.section, "IsVisible", boolean)
+ if not visible:
+ return
+ '''
+ remove obsolete rows
+ ====================
+ if the cell that was last written is the current cell,
+ it means this is the end of the table, so we end here.
+ (because after getting the cellName above,
+ I call the goRight method.
+ If it did not go right, it means its the last cell.
+ '''
+
+ if cellName == cursor.RangeName:
+ return
+ '''
+ if not, we continue and clear all cells until
+ we are at the end of the row.
+ '''
+
+ while not cellName == cursor.RangeName and \
+ not cursor.RangeName.startswith("A"):
+ cell = ItemsTable.table.getCellByName(cursor.RangeName)
+ cell.String = ""
+ cellName = cursor.RangeName
+ cursor.goRight(1, False)
+
+ '''
+ again: if we are at the end of the table, end here.
+ '''
+ if cellName == cursor.RangeName:
+ return
+
+ rowIndex = AgendaTemplate.getRowIndex(cursor)
+ rowsCount = AgendaTemplate.getRowCount(ItemsTable.table)
+ '''
+ now before deleteing i move the cursor up so it
+ does not disappear, because it will crash office.
+ '''
+ cursor.gotoStart(False)
+
+'''
+This class handles the preview of the topics table.
+You can call it the controller of the topics table.
+It differs from ItemsTable in that it has no data model -
+the update is done programttically.<br/>
+<br/>
+The decision to make this class a class by its own
+was done out of logic reasons and not design/functionality reasons,
+since there is anyway only one instance of this class at runtime
+it could have also be implemented in the AgendaTemplate class
+but for clarity and separation I decided to make a sub class for it.
+
+@author rp143992
+'''
+
+class Topics(object):
+ '''Analyze the structure of the Topics table.
+ The structure Must be as follows:<br>
+ -One Header Row. <br>
+ -arbitrary number of rows per topic <br>
+ -arbitrary content in the topics row <br>
+ -only soft formatting will be restored. <br>
+ -the topic rows must repeat three times. <br>
+ -in the topics rows, placeholders for number, topic, responsible,
+ and duration must be placed.<br><br>
+ A word about table format: to reconstruct the format of the table we hold
+ to the following formats: first row (header), topic, and last row.
+ We hold the format of the last row, because one might wish to give it
+ a special format, other than the one on the bottom of each topic.
+ The left and right borders of the whole table are, on the other side,
+ part of the topics rows format, and need not be preserved seperateley.
+ '''
+ table = None
+ lastRowFormat = []
+ numCell = -1
+ topicCell = -1
+ responsibleCell = -1
+ timeCell = -1
+ rowsPerTopic = None
+ topicCells = []
+
+ def __init__(self):
+ self.topicItems = {}
+ self.firstRowFormat = []
+ # This is the topics table. say hallo :-)
+ try:
+ Topics.table = AgendaTemplate.getTable(SECTION_TOPICS)
+ except Exception, ex:
+ traceback.print_exc()
+ raise AttributeError (
+ "Fatal error while loading template: table " + \
+ SECTION_TOPICS + " could not load.")
+
+ '''
+ first I store all <*> ranges
+ which are in the topics table.
+ I store each <*> range in this - the key
+ is the cell it is in. Later when analyzing the topic,
+ cell by cell, I check in this map to know
+ if a cell contains a <*> or not.
+ '''
+ items = {}
+ for i in AgendaTemplate._allItems:
+ t = Helper.getUnoPropertyValue(i, "TextTable")
+ if t == Topics.table:
+ cell = Helper.getUnoPropertyValue(i, "Cell")
+ iText = cell.CellName
+ items[iText] = i
+
+ '''
+ in the topics table, there are always one
+ title row and three topics defined.
+ So no mutter how many rows a topic takes - we
+ can restore its structure and format.
+ '''
+ rows = AgendaTemplate.getRowCount(Topics.table)
+ Topics.rowsPerTopic = (rows - 1) / 3
+ firstCell = "A" + str(1 + Topics.rowsPerTopic + 1)
+ afterLastCell = "A" + str(1 + (Topics.rowsPerTopic * 2) + 1)
+ # go to the first row of the 2. topic
+ cursor = Topics.table.createCursorByCellName(firstCell)
+ # analyze the structure of the topic rows.
+ while not cursor.RangeName == afterLastCell:
+ cell = Topics.table.getCellByName(cursor.RangeName)
+ # first I store the content and para style of the cell
+ ae = TextElement(cell)
+ # if the cell contains a relevant <...>
+ # i add the text element to the hash,
+ # so it's text can be updated later.
+ try:
+ if items[cell.CellName] is not None:
+ self.topicItems[cell.String.lower().lstrip()] = ae
+ except KeyError:
+ pass
+
+ Topics.topicCells.append(ae)
+ # goto next cell.
+ cursor.goRight(1, False)
+ '''
+ now - in which cell is every fillin?
+ '''
+
+ Topics.numCell = Topics.topicCells.index(
+ self.topicItems[FILLIN_TOPIC_NUMBER])
+ Topics.topicCell = Topics.topicCells.index(
+ self.topicItems[FILLIN_TOPIC_TOPIC])
+ Topics.responsibleCell = Topics.topicCells.index(
+ self.topicItems[FILLIN_TOPIC_RESPONSIBLE])
+ Topics.timeCell = Topics.topicCells.index(
+ self.topicItems[FILLIN_TOPIC_TIME])
+
+ '''@param topic the topic number to write
+ @param data the data of the topic.
+ @return the number of rows that have been added
+ to the table. 0 or a negative number: no rows added.
+ '''
+
+ @classmethod
+ def write2(self, topic, data):
+ if topic >= len(AgendaTemplate.writtenTopics):
+ size = topic - len(AgendaTemplate.writtenTopics)
+ AgendaTemplate.writtenTopics += [None] * size
+ AgendaTemplate.writtenTopics.insert(topic, "")
+ # make sure threr are enough rows for me...
+ rows = AgendaTemplate.getRowCount(Topics.table)
+ reqRows = 1 + (topic + 1) * Topics.rowsPerTopic
+ firstRow = reqRows - Topics.rowsPerTopic + 1
+ diff = reqRows - rows
+ if diff > 0:
+ AgendaTemplate.insertTableRows(Topics.table, rows, diff)
+ # set the item's text...
+
+ self.setItemText(Topics.numCell, data[0].Value)
+ self.setItemText(Topics.topicCell, data[1].Value)
+ self.setItemText(Topics.responsibleCell, data[2].Value)
+ self.setItemText(Topics.timeCell, data[3].Value)
+ # now write !
+ cursor = Topics.table.createCursorByCellName("A" + str(firstRow))
+ for i in Topics.topicCells:
+ i.write(Topics.table.getCellByName(cursor.RangeName))
+ cursor.goRight(1, False)
+ # now format !
+ cursor.gotoCellByName("A" + str(firstRow), False)
+ return diff
+
+ '''check if the topic with the given index is written to the table.
+ @param topic the topic number (0 base)
+ @return true if the topic is already written to the table. False if not.
+ (false would mean rows must be added to the table in order to
+ be able to write this topic).
+ '''
+
+ def isWritten(self, topic):
+ return (len(AgendaTemplate.writtenTopics) > topic \
+ and AgendaTemplate.writtenTopics[topic] is not None)
+
+ '''rewrites a single cell containing.
+ This is used in order to refresh the topic/responsible/duration data
+ in the preview document, in response to a change in the gui (by the user)
+ Since the structure of the topics table is flexible,
+ we don't reference a cell number. Rather, we use "what" argument to
+ specify which cell should be redrawn.
+ The Topics object, which analyzed the structure of the topics table appon
+ initialization, refreshes the approperiate cell.
+ @param topic index of the topic (0 based).
+ @param what 0 for num, 1 for topic, 2 for responsible, 3 for duration
+ @param data the row's data.
+ @throws Exception if something goes wrong (thow nothing should)
+ '''
+
+ def writeCell(self, topic, what, data):
+ # if the whole row should be written...
+ if not self.isWritten(topic):
+ self.write(topic, data)
+ # write only the "what" cell.
+ else:
+ # calculate the table row.
+ firstRow = 1 + (topic * Topics.rowsPerTopic) + 1
+ # go to the first cell of this topic.
+ cursor = Topics.table.createCursorByCellName("A" + str(firstRow))
+ te = None
+ cursorMoves = 0
+ if what == 0:
+ te = self.setItemText(Topics.numCell, data[0].Value)
+ cursorMoves = Topics.numCell
+ elif what == 1:
+ te = self.setItemText(Topics.topicCell, data[1].Value)
+ cursorMoves = Topics.topicCell
+ elif what == 2:
+ te = self.setItemText(Topics.responsibleCell, data[2].Value)
+ cursorMoves = Topics.responsibleCell
+ elif what == 3:
+ te = self.setItemText(Topics.timeCell, data[3].Value)
+ cursorMoves = Topics.timeCell
+
+ # move the cursor to the needed cell...
+ cursor.goRight(cursorMoves, False)
+ xc = Topics.table.getCellByName(cursor.RangeName)
+ # and write it !
+ te.write(xc)
+
+ '''writes the given topic.
+ if the first topic was involved, reformat the
+ first row.
+ If any rows were added to the table, reformat
+ the last row.
+ @param topic the index of the topic to write.
+ @param data the topic's data. (see TopicsControl
+ for explanation about the topics data model)
+ @throws Exception if something goes wrong (though nothing should).
+ '''
+
+ def write(self, topic, data):
+ diff = self.write2(topic, data)
+ '''if the first topic has been written,
+ one needs to reformat the first row.
+ '''
+ if topic == 0:
+ self.formatFirstRow()
+ '''
+ if any rows were added, one needs to format
+ the whole table again.
+ '''
+
+ if diff > 0:
+ self.formatLastRow()
+
+ '''removes obsolete rows, reducing the
+ topics table to the given number of topics.
+ Note this method does only reducing - if
+ the number of topics given is greater than the
+ number of actuall topics it does *not* add
+ rows !
+ Note also that the first topic will never be removed.
+ If the table contains no topics, the whole section will
+ be removed uppon finishing.
+ The reason for that is a "table-design" one: the first topic is
+ maintained in order to be able to add rows with a design of this topic,
+ and not of the header row.
+ @param topics the number of topics the table should contain.
+ @throws Exception
+ '''
+
+ def reduceDocumentTo(self, topics):
+ # we never remove the first topic...
+ if topics <= 0:
+ topics = 1
+
+ tableRows = Topics.table.Rows
+ targetNumOfRows = topics * Topics.rowsPerTopic + 1
+ '''if tableRows.Count > targetNumOfRows:
+ tableRows.removeByIndex(
+ targetNumOfRows, tableRows.Count - targetNumOfRows)'''
+
+ self.formatLastRow()
+ while len(AgendaTemplate.writtenTopics) > topics:
+ del AgendaTemplate.writtenTopics[topics]
+
+ '''reapply the format of the first (header) row.
+ '''
+
+ def formatFirstRow(self):
+ cursor = Topics.table.createCursorByCellName("A1")
+ self.formatTable(cursor, self.firstRowFormat, False)
+
+ '''reaply the format of the last row.
+ '''
+ @classmethod
+ def formatLastRow(self):
+ cursor = Topics.table.createCursorByCellName("A1")
+ cursor.gotoEnd(False)
+ self.formatTable(cursor, Topics.lastRowFormat, True)
+
+ '''returns a text element for the given cell,
+ which will write the given text.
+ @param cell the topics cell number.
+ @param value the value to write.
+ @return a TextElement object which will write the given value
+ to the given cell.
+ '''
+
+ @classmethod
+ def setItemText(self, cell, value):
+ if cell >= 0:
+ te = Topics.topicCells[cell]
+ if te is not None:
+ te.text = str(value)
+ return te
+
+ return None
+
+ '''formats a series of cells from the given one,
+ using the given List of TableCellFormatter objects,
+ in the given order.
+ This method is used to format the first (header) and the last
+ rows of the table.
+ @param cursor a table cursor, pointing to the start cell to format
+ @param formats a List containing TableCellFormatter objects.
+ Each will format one cell in the direction specified.
+ @param reverse if true the cursor will move left,
+ formatting in reverse order (used for the last row).
+ '''
+ @classmethod
+ def formatTable(self, cursor, formats, reverse):
+ for i in formats:
+ i.format(Topics.table.getCellByName(cursor.RangeName))
+ if reverse:
+ cursor.goLeft(1, False)
+ else:
+ cursor.goRight(1, False)
+
+'''
+A basic implementation of AgendaElement:
+writes a String to the given XText/XTextRange, and applies
+a ParaStyle to it (using the parent class).
+@author rp143992
+'''
+class TextElement(object):
+
+ def __init__(self, text_):
+ self.text = text_
+
+ def write(self, textRange):
+ textRange.String = self.text
+
+'''
+A Text element which, if the text to write is empty (null or "")
+inserts a placeholder instead.
+@author rp143992
+'''
+
+class PlaceholderTextElement(TextElement):
+
+ def __init__(self, textRange, placeHolderText_, hint_, xmsf_):
+ super(PlaceholderTextElement,self).__init__(textRange)
+
+ self.placeHolderText = placeHolderText_
+ self.hint = hint_
+ self.xmsf = xmsf_
+
+ def write(self, textRange):
+ textRange.String = self.text
+ if self.text is None or self.text == "":
+ try:
+ xTextContent = AgendaTemplate.createPlaceHolder(
+ self.xmsf, self.placeHolderText, self.hint)
+ textRange.Text.insertTextContent(
+ textRange.Start, xTextContent, True)
+ except Exception, ex:
+ traceback.print_exc()
+
+'''
+An Agenda element which writes no text, but inserts a placeholder, and formats
+it using a ParaStyleName.
+@author rp143992
+'''
+
+class PlaceholderElement(object):
+
+ def __init__(self, placeHolderText_, hint_, xmsf_):
+ self.placeHolderText = placeHolderText_
+ self.hint = hint_
+ self.xmsf = xmsf_
+
+ def write(self, textRange):
+ try:
+ xTextContent = AgendaTemplate.createPlaceHolder(
+ AgendaTemplate.document, self.placeHolderText, self.hint)
+ textRange.Text.insertTextContent(
+ textRange.Start, xTextContent, True)
+ except Exception, ex:
+ traceback.print_exc()
+
+'''
+An implementation of AgendaElement which
+gets as a parameter a table cursor, and writes
+a text to the cell marked by this table cursor, and
+a place holder to the next cell.
+@author rp143992
+'''
+
+class AgendaItem(object):
+
+ def __init__(self, name_, te, f):
+ self.name = name_
+ self.field = f
+ self.textElement = te
+
+ def write(self, tableCursor):
+ cellname = tableCursor.RangeName
+ cell = ItemsTable.table.getCellByName(cellname)
+ self.textElement.write(cell)
+ tableCursor.goRight(1, False)
+ #second field is actually always null...
+ # this is a preparation for adding placeholders.
+ if self.field is not None:
+ self.field.write(ItemsTable.table.getCellByName(
+ tableCursor.RangeName))
diff --git a/wizards/com/sun/star/wizards/agenda/AgendaWizardDialog.py b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialog.py
new file mode 100644
index 000000000000..3555a2d6244a
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialog.py
@@ -0,0 +1,293 @@
+from wizards.ui.WizardDialog import *
+from AgendaWizardDialogConst import *
+from AgendaWizardDialogResources import AgendaWizardDialogResources
+
+from com.sun.star.awt.FontUnderline import SINGLE
+
+class AgendaWizardDialog(WizardDialog):
+
+ def __init__(self, xmsf):
+ super(AgendaWizardDialog,self).__init__(xmsf, HID )
+ #Load Resources
+ self.resources = AgendaWizardDialogResources(xmsf)
+ #set dialog properties...
+ Helper.setUnoPropertyValues(
+ self.xDialogModel, ("Closeable",
+ PropertyNames.PROPERTY_HEIGHT,
+ "Moveable",
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ "Title",
+ PropertyNames.PROPERTY_WIDTH),
+ (True, 210, True, 200, 52, 1, 1,
+ self.resources.resAgendaWizardDialog_title,310))
+
+ self.IMGHELP1_HID = ""
+ self.PROPS_LIST = ("Dropdown",
+ PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_LABEL_B = ("FontDescriptor",
+ PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_MULTILINE,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_CHECK = (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STATE,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_BUTTON = (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_X = (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_TEXTAREA = (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_MULTILINE,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_TEXT = (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.PROPS_IMAGE = ("Border",
+ PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_IMAGEURL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ "ScaleImage",
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ self.fontDescriptor1 = \
+ uno.createUnoStruct('com.sun.star.awt.FontDescriptor')
+ self.fontDescriptor2 = \
+ uno.createUnoStruct('com.sun.star.awt.FontDescriptor')
+ self.fontDescriptor4 = \
+ uno.createUnoStruct('com.sun.star.awt.FontDescriptor')
+ #Set member- FontDescriptors...
+ self.fontDescriptor1.Weight = 150
+ self.fontDescriptor1.Underline = SINGLE
+ self.fontDescriptor2.Weight = 100
+ self.fontDescriptor4.Weight = 150
+
+ '''
+ build components
+ '''
+ def buildStep1(self):
+ self.insertLabel("lblTitle1", self.PROPS_LABEL_B, (self.fontDescriptor4,
+ 16, self.resources.reslblTitle1_value, True, 91, 8, 1, 100,212))
+ self.insertLabel("lblPageDesign", self.PROPS_TEXT,
+ (8, self.resources.reslblPageDesign_value, 97, 32, 1, 101, 66))
+ self.listPageDesign = self.insertListBox("listPageDesign",
+ None, LISTPAGEDESIGN_ACTION_PERFORMED, self.PROPS_LIST,
+ (True, 12, LISTPAGEDESIGN_HID, 166, 30, 1, 102, 70), self)
+ self.chkMinutes = self.insertCheckBox("chkMinutes", None,
+ self.PROPS_CHECK, (9, CHKMINUTES_HID,
+ self.resources.reschkMinutes_value, 97, 50, 0, 1, 103, 203), self)
+ self.insertImage("imgHelp1", self.PROPS_IMAGE,
+ (0, 10, self.IMGHELP1_HID,
+ INFO_IMAGE_URL, 92,
+ 145, False, 1, 104, 10))
+ self.insertLabel("lblHelp1", self.PROPS_TEXTAREA,
+ (39, self.resources.reslblHelp1_value, True,104,145, 1, 105,199))
+
+ def buildStep2(self):
+ self.insertLabel("lblTitle2", self.PROPS_LABEL_B,
+ (self.fontDescriptor4, 16,
+ self.resources.reslblTitle2_value, True,91, 8, 2, 200,212))
+ self.insertLabel("lblDate", self.PROPS_TEXT,
+ (8, self.resources.reslblDate_value, 97, 32, 2, 201,66))
+ self.txtDate = self.insertDateField(
+ "txtDate", TXTDATE_TEXT_CHANGED, self.PROPS_LIST,
+ (True, 12, TXTDATE_HID,166,30, 2, 202,70), self)
+ self.insertLabel("lblTime", self.PROPS_TEXT,
+ (8, self.resources.reslblTime_value, 97, 50, 2, 203, 66))
+ self.txtTime = self.insertTimeField("txtTime", TXTTIME_TEXT_CHANGED,
+ (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ "StrictFormat",
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH),
+ (12, TXTTIME_HID, 166, 48, 2, True, 204,70), self)
+ self.insertLabel("lblTitle", self.PROPS_TEXT,
+ (8, self.resources.reslblTitle_value, 97, 68, 2, 205,66))
+ self.txtTitle = self.insertTextField(
+ "txtTitle", TXTTITLE_TEXT_CHANGED,
+ (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_MULTILINE,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH),
+ (26, TXTTITLE_HID, True, 166, 66, 2, 206, 138), self)
+ self.insertLabel("lblLocation", self.PROPS_TEXT,
+ (8, self.resources.reslblLocation_value, 97, 100, 2, 207, 66))
+ self.cbLocation = self.insertTextField(
+ "cbLocation", TXTLOCATION_TEXT_CHANGED,
+ (PropertyNames.PROPERTY_HEIGHT,
+ PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_MULTILINE,
+ PropertyNames.PROPERTY_POSITION_X,
+ PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP,
+ PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH),
+ (34, CBLOCATION_HID, True, 166,98, 2, 208, 138), self)
+ self.insertImage("imgHelp2", self.PROPS_IMAGE,
+ (0, 10, self.IMGHELP1_HID,
+ INFO_IMAGE_URL,
+ 92, 145, False, 2, 209, 10))
+ self.insertLabel("lblHelp2", self.PROPS_TEXTAREA,
+ (39, self.resources.reslblHelp2_value, True, 104, 145, 2, 210, 199))
+
+ def buildStep3(self):
+ self.insertLabel("lblTitle3", self.PROPS_LABEL_B,
+ (self.fontDescriptor4, 16, self.resources.reslblTitle3_value,
+ True, 91, 8, 3, 300,212))
+ self.chkMeetingTitle = self.insertCheckBox("chkMeetingTitle",
+ CHKUSEMEETINGTYPE_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKMEETINGTITLE_HID, self.resources.reschkMeetingTitle_value,
+ 97, 32, 1, 3, 301, 69), self)
+ self.chkRead = self.insertCheckBox("chkRead",
+ CHKUSEREAD_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKREAD_HID, self.resources.reschkRead_value,
+ 97, 46, 0, 3, 302, 162), self)
+ self.chkBring = self.insertCheckBox("chkBring",
+ CHKUSEBRING_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKBRING_HID, self.resources.reschkBring_value,
+ 97, 60, 0, 3, 303, 162), self)
+ self.chkNotes = self.insertCheckBox("chkNotes",
+ CHKUSENOTES_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKNOTES_HID, self.resources.reschkNotes_value,
+ 97, 74, 1, 3, 304, 160), self)
+ self.insertImage("imgHelp3", self.PROPS_IMAGE, (0, 10,
+ self.IMGHELP1_HID, INFO_IMAGE_URL,
+ 92, 145, False, 3, 305, 10))
+ self.insertLabel("lblHelp3", self.PROPS_TEXTAREA,
+ (39, self.resources.reslblHelp3_value, True,104, 145, 3, 306, 199))
+
+ def buildStep4(self):
+ self.insertLabel("lblTitle5", self.PROPS_LABEL_B,
+ (self.fontDescriptor4, 16, self.resources.reslblTitle5_value,
+ True, 91, 8, 4, 400, 212))
+ self.chkConvenedBy = self.insertCheckBox("chkConvenedBy",
+ CHKUSECALLEDBYNAME_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKCONVENEDBY_HID, self.resources.reschkConvenedBy_value,
+ 97, 32, 1, 4, 401, 150), self)
+ self.chkPresiding = self.insertCheckBox("chkPresiding",
+ CHKUSEFACILITATOR_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKPRESIDING_HID, self.resources.reschkPresiding_value,
+ 97, 46, 0, 4, 402, 150), self)
+ self.chkNoteTaker = self.insertCheckBox("chkNoteTaker",
+ CHKUSENOTETAKER_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKNOTETAKER_HID, self.resources.reschkNoteTaker_value,
+ 97, 60, 0, 4, 403, 150), self)
+ self.chkTimekeeper = self.insertCheckBox("chkTimekeeper",
+ CHKUSETIMEKEEPER_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKTIMEKEEPER_HID, self.resources.reschkTimekeeper_value,
+ 97, 74, 0, 4, 404, 150), self)
+ self.chkAttendees = self.insertCheckBox("chkAttendees",
+ CHKUSEATTENDEES_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKATTENDEES_HID, self.resources.reschkAttendees_value,
+ 97, 88, 1, 4, 405, 150), self)
+ self.chkObservers = self.insertCheckBox("chkObservers",
+ CHKUSEOBSERVERS_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKOBSERVERS_HID, self.resources.reschkObservers_value,
+ 97, 102, 0, 4, 406, 150), self)
+ self.chkResourcePersons = self.insertCheckBox("chkResourcePersons",
+ CHKUSERESOURCEPERSONS_ITEM_CHANGED, self.PROPS_CHECK,
+ (8, CHKRESOURCEPERSONS_HID, self.resources.reschkResourcePersons_value,
+ 97, 116, 0, 4, 407, 150), self)
+ self.insertImage("imgHelp4", self.PROPS_IMAGE,
+ (0, 10, self.IMGHELP1_HID, INFO_IMAGE_URL,
+ 92, 145, False, 4, 408, 10))
+ self.insertLabel("lblHelp4", self.PROPS_TEXTAREA,
+ (39, self.resources.reslblHelp4_value, True, 104, 145, 4, 409, 199))
+
+ def buildStep5(self):
+ self.insertLabel("lblTitle4", self.PROPS_LABEL_B,
+ (self.fontDescriptor4, 16, self.resources.reslblTitle4_value,
+ True, 91, 8, 5, 500, 212))
+ self.insertLabel("lblTopic", self.PROPS_TEXT,
+ (8, self.resources.reslblTopic_value, 107, 28, 5, 71, 501))
+ self.insertLabel("lblResponsible", self.PROPS_TEXT,
+ (8, self.resources.reslblResponsible_value, 195, 28, 5, 72, 502))
+ self.insertLabel("lblDuration", self.PROPS_TEXT,
+ (8, self.resources.reslblDuration_value, 267, 28, 5, 73, 503))
+ self.btnInsert = self.insertButton("btnInsert", BTNINSERT_ACTION_PERFORMED,
+ self.PROPS_BUTTON, (14, BTNINSERT_HID,
+ self.resources.resButtonInsert, 92, 136, 5, 580, 40), self)
+ self.btnRemove = self.insertButton("btnRemove", BTNREMOVE_ACTION_PERFORMED,
+ self.PROPS_BUTTON, (14, BTNREMOVE_HID,
+ self.resources.resButtonRemove, 134, 136, 5, 581, 40), self)
+ self.btnUp = self.insertButton("btnUp", BTNUP_ACTION_PERFORMED,
+ self.PROPS_BUTTON, (14, BTNUP_HID,
+ self.resources.resButtonUp, 222, 136, 5, 582, 40), self)
+ self.btnDown = self.insertButton("btnDown", BTNDOWN_ACTION_PERFORMED,
+ self.PROPS_BUTTON, (14, BTNDOWN_HID,
+ self.resources.resButtonDown, 264, 136, 5, 583, 40), self)
+
+ def buildStep6(self):
+ self.insertLabel("lblTitle6", self.PROPS_LABEL_B,
+ (self.fontDescriptor4, 16, self.resources.reslblTitle6_value,
+ True, 91, 8, 6, 600, 212))
+ self.insertLabel("lblHelpPg6", self.PROPS_TEXTAREA,
+ (24, self.resources.reslblHelpPg6_value, True,
+ 97, 32, 6, 601,204))
+ self.insertLabel("lblTemplateName", self.PROPS_TEXT,
+ (8, self.resources.reslblTemplateName_value,
+ 97, 62, 6, 602, 101))
+ self.txtTemplateName = self.insertTextField("txtTemplateName",
+ TXTTEMPLATENAME_TEXT_CHANGED, self.PROPS_X,
+ (12, TXTTEMPLATENAME_HID, 202, 60, 6, 603, 100), self)
+ self.insertLabel("lblProceed", self.PROPS_TEXT,
+ (8, self.resources.reslblProceed_value, 97, 101, 6, 607,204))
+ self.optCreateAgenda = self.insertRadioButton("optCreateAgenda", None,
+ self.PROPS_CHECK, (8, OPTCREATEAGENDA_HID,
+ self.resources.resoptCreateAgenda_value,
+ 103, 113, 1, 6, 608, 198), self)
+ self.optMakeChanges = self.insertRadioButton("optMakeChanges", None,
+ self.PROPS_BUTTON, (8, OPTMAKECHANGES_HID,
+ self.resources.resoptMakeChanges_value, 103, 125, 6, 609, 198), self)
+ self.insertImage("imgHelp6", self.PROPS_IMAGE, (0, 10, self.IMGHELP1_HID,
+ INFO_IMAGE_URL, 92, 145, False, 6, 610, 10))
+ self.insertLabel("lblHelp6", self.PROPS_TEXTAREA,
+ (39, self.resources.reslblHelp6_value, True, 104, 145, 6, 611, 199))
diff --git a/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogConst.py b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogConst.py
new file mode 100644
index 000000000000..2e26a350cd8b
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogConst.py
@@ -0,0 +1,63 @@
+from wizards.common.HelpIds import HelpIds
+
+TXTTITLE_TEXT_CHANGED = "txtTitleTextChanged"
+TXTDATE_TEXT_CHANGED = "txtDateTextChanged"
+TXTTIME_TEXT_CHANGED = "txtTimeTextChanged"
+TXTLOCATION_TEXT_CHANGED = "txtLocationTextChanged"
+CHKMINUTES_ITEM_CHANGED = "chkMinutesItemChanged"
+CHKUSEMEETINGTYPE_ITEM_CHANGED = "chkUseMeetingTypeItemChanged"
+CHKUSEREAD_ITEM_CHANGED = "chkUseReadItemChanged"
+CHKUSEBRING_ITEM_CHANGED = "chkUseBringItemChanged"
+CHKUSENOTES_ITEM_CHANGED = "chkUseNotesItemChanged"
+CHKUSECALLEDBYNAME_ITEM_CHANGED = "chkUseCalledByItemChanged"
+CHKUSEFACILITATOR_ITEM_CHANGED = "chkUseFacilitatorItemChanged"
+CHKUSENOTETAKER_ITEM_CHANGED = "chkUseNoteTakerItemChanged"
+CHKUSETIMEKEEPER_ITEM_CHANGED = "chkUseTimeKeeperItemChanged"
+CHKUSEATTENDEES_ITEM_CHANGED = "chkUseAttendeesItemChanged"
+CHKUSEOBSERVERS_ITEM_CHANGED = "chkUseObserversItemChanged"
+CHKUSERESOURCEPERSONS_ITEM_CHANGED = "chkUseResourcePersonsItemChanged"
+LISTPAGEDESIGN_ACTION_PERFORMED = "pageDesignChanged"
+TXTTEMPLATENAME_TEXT_CHANGED = "templateTitleChanged"
+BTNTEMPLATEPATH_ACTION_PERFORMED = "saveAs"
+BTNINSERT_ACTION_PERFORMED = "insertRow"
+BTNREMOVE_ACTION_PERFORMED = "removeRow"
+BTNUP_ACTION_PERFORMED = "rowUp"
+BTNDOWN_ACTION_PERFORMED = "rowDown"
+
+INFO_IMAGE_URL = "private:resource/dbu/image/19205"
+
+HID = 41051
+
+LISTPAGEDESIGN_HID = HelpIds.getHelpIdString(HID + 6)
+CHKMINUTES_HID = HelpIds.getHelpIdString(HID + 7)
+TXTTIME_HID = HelpIds.getHelpIdString(HID + 8)
+TXTDATE_HID = HelpIds.getHelpIdString(HID + 9)
+TXTTITLE_HID = HelpIds.getHelpIdString(HID + 10)
+CBLOCATION_HID = HelpIds.getHelpIdString(HID + 11)
+
+CHKMEETINGTITLE_HID = HelpIds.getHelpIdString(HID + 12)
+CHKREAD_HID = HelpIds.getHelpIdString(HID + 13)
+CHKBRING_HID = HelpIds.getHelpIdString(HID + 14)
+CHKNOTES_HID = HelpIds.getHelpIdString(HID + 15)
+
+CHKCONVENEDBY_HID = HelpIds.getHelpIdString(HID + 16)
+CHKPRESIDING_HID = HelpIds.getHelpIdString(HID + 17)
+CHKNOTETAKER_HID = HelpIds.getHelpIdString(HID + 18)
+CHKTIMEKEEPER_HID = HelpIds.getHelpIdString(HID + 19)
+CHKATTENDEES_HID = HelpIds.getHelpIdString(HID + 20)
+CHKOBSERVERS_HID = HelpIds.getHelpIdString(HID + 21)
+CHKRESOURCEPERSONS_HID = HelpIds.getHelpIdString(HID + 22)
+
+TXTTEMPLATENAME_HID = HelpIds.getHelpIdString(HID + 23)
+TXTTEMPLATEPATH_HID = HelpIds.getHelpIdString(HID + 24)
+BTNTEMPLATEPATH_HID = HelpIds.getHelpIdString(HID + 25)
+
+OPTCREATEAGENDA_HID = HelpIds.getHelpIdString(HID + 26)
+OPTMAKECHANGES_HID = HelpIds.getHelpIdString(HID + 27)
+
+BTNINSERT_HID = HelpIds.getHelpIdString(HID + 28)
+BTNREMOVE_HID = HelpIds.getHelpIdString(HID + 29)
+BTNUP_HID = HelpIds.getHelpIdString(HID + 30)
+BTNDOWN_HID = HelpIds.getHelpIdString(HID + 31)
+
+LAST_HID = HID + 32
diff --git a/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogImpl.py b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogImpl.py
new file mode 100644
index 000000000000..68e39f29b72c
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogImpl.py
@@ -0,0 +1,463 @@
+from AgendaWizardDialog import *
+from AgendaTemplate import *
+from CGAgenda import CGAgenda
+from wizards.ui.PathSelection import PathSelection
+from wizards.ui.event.UnoDataAware import UnoDataAware
+from wizards.ui.event.RadioDataAware import RadioDataAware
+from wizards.common.NoValidPathException import NoValidPathException
+from wizards.common.SystemDialog import SystemDialog
+
+from com.sun.star.view.DocumentZoomType import OPTIMAL
+from com.sun.star.awt.VclWindowPeerAttribute import YES_NO, DEF_NO
+from com.sun.star.awt.VclWindowPeerAttribute import OK
+
+class AgendaWizardDialogImpl(AgendaWizardDialog):
+
+ fileAccess1 = None
+ pageDesign = None
+
+ def __init__(self, xmsf):
+ super(AgendaWizardDialogImpl, self).__init__(xmsf)
+ self.filenameChanged = False
+
+ def enterStep(self, OldStep, NewStep):
+ pass
+
+ def leaveStep(self, OldStep, NewStep):
+ pass
+
+ '''
+ used in developement to start the wizard
+ '''
+
+ @classmethod
+ def main(self, args):
+ ConnectStr = \
+ "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext"
+ try:
+ xLocMSF = Desktop.connect(ConnectStr)
+ wizard = AgendaWizardDialogImpl(xLocMSF)
+ wizard.startWizard()
+ except Exception, exception:
+ traceback.print_exc()
+
+ '''
+ read the configuration data, open the specified template,
+ initialize the template controller (AgendaTemplate) and
+ set the status of the displayed template to the one
+ read from the configuration.
+ build the dialog.
+ Synchronize the dialog to the same status (read from
+ the configuration).
+ show the dialog.
+ '''
+
+ def startWizard(self):
+ self.running = True
+ try:
+ #Number of steps on WizardDialog
+ self.nMaxStep = 6
+
+ # initialize the agenda template
+ self.agenda = CGAgenda()
+ self.agendaTemplate = AgendaTemplate(
+ self.xMSF, self.agenda, self.resources, self)
+
+ # build the dialog.
+ self.drawNaviBar()
+
+ self.buildStep1()
+ self.buildStep2()
+ self.buildStep3()
+ self.buildStep4()
+ self.buildStep5()
+ self.buildStep6()
+
+ self.topicsControl = TopicsControl(self, self.xMSF, self.agenda)
+
+ self.initializePaths()
+ #special Control for setting the save Path:
+ self.insertPathSelectionControl()
+
+ self.initializeTemplates()
+
+ # synchronize GUI and CGAgenda object.
+ self.initConfiguration()
+
+ if self.myPathSelection.xSaveTextBox.Text.lower() == "":
+ self.myPathSelection.initializePath()
+
+ # create the peer
+ xContainerWindow = self.agendaTemplate.xFrame.ContainerWindow
+ self.createWindowPeer(xContainerWindow)
+
+ # initialize roadmap
+ self.insertRoadmap()
+
+ self.pageDesignChanged()
+
+ self.executeDialogFromComponent(self.agendaTemplate.xFrame)
+ self.removeTerminateListener()
+ self.closeDocument()
+ self.running = False
+ except Exception, ex:
+ self.removeTerminateListener()
+ traceback.print_exc()
+ self.running = False
+ return
+
+ def insertPathSelectionControl(self):
+ self.myPathSelection = PathSelection(
+ self.xMSF, self, PathSelection.TransferMode.SAVE,
+ PathSelection.DialogTypes.FILE)
+ self.myPathSelection.insert(6, 97, 70, 205, 45,
+ self.resources.reslblTemplatePath_value, True,
+ HelpIds.getHelpIdString(HID + 24),
+ HelpIds.getHelpIdString(HID + 25))
+ self.myPathSelection.sDefaultDirectory = self.sUserTemplatePath
+ self.myPathSelection.sDefaultName = "myAgendaTemplate.ott"
+ self.myPathSelection.sDefaultFilter = "writer8_template"
+ self.myPathSelection.addSelectionListener(
+ self.myPathSelectionListener())
+
+ def initializePaths(self):
+ try:
+ self.sTemplatePath = FileAccess.getOfficePath2(
+ self.xMSF, "Template", "share", "/wizard")
+ self.sUserTemplatePath = FileAccess.getOfficePath2(
+ self.xMSF, "Template", "user", "")
+ self.sBitmapPath = FileAccess.combinePaths(
+ self.xMSF, self.sTemplatePath, "/../wizard/bitmap")
+ except NoValidPathException:
+ traceback.print_exc()
+
+ def checkSavePath(self):
+ if self.agenda.cp_TemplatePath is None \
+ or self.agenda.cp_TemplatePath == "" \
+ or not self.getFileAccess().exists(
+ FileAccess.getParentDir(self.agenda.cp_TemplatePath), False) \
+ or not self.getFileAccess().isDirectory(
+ FileAccess.getParentDir(self.agenda.cp_TemplatePath)):
+ try:
+ self.agenda.cp_TemplatePath = FileAccess.connectURLs(
+ FileAccess.getOfficePath2(self.xMSF, "Work", "", ""),
+ self.resources.resDefaultFilename)
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''
+ bind controls to the agenda member (DataAware model)
+ '''
+
+ def initConfiguration(self):
+ # read configuration data.
+ root = Configuration.getConfigurationRoot(
+ self.xMSF, "/org.openoffice.Office.Writer/Wizards/Agenda", False)
+ self.agenda.readConfiguration(root, "cp_")
+
+ self.setControlProperty(
+ "listPageDesign", "StringItemList", tuple(self.agendaTemplates[0]))
+ self.checkSavePath()
+ UnoDataAware.attachListBox(
+ self.agenda, "cp_AgendaType", self.listPageDesign, True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_IncludeMinutes", self.chkMinutes, True).updateUI()
+ UnoDataAware.attachEditControl(
+ self.agenda, "cp_Title", self.txtTitle, True).updateUI()
+ UnoDataAware.attachDateControl(
+ self.agenda, "cp_Date", self.txtDate, True).updateUI()
+ UnoDataAware.attachTimeControl(
+ self.agenda, "cp_Time", self.txtTime, True).updateUI()
+ UnoDataAware.attachEditControl(
+ self.agenda, "cp_Location", self.cbLocation, True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowMeetingType", self.chkMeetingTitle,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowRead", self.chkRead, True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowBring", self.chkBring, True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowNotes", self.chkNotes, True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowCalledBy", self.chkConvenedBy,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowFacilitator", self.chkPresiding,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowNotetaker", self.chkNoteTaker,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowTimekeeper", self.chkTimekeeper,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowAttendees", self.chkAttendees,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowObservers", self.chkObservers,
+ True).updateUI()
+ UnoDataAware.attachCheckBox(
+ self.agenda, "cp_ShowResourcePersons",self.chkResourcePersons,
+ True).updateUI()
+ UnoDataAware.attachEditControl(
+ self.agenda, "cp_TemplateName", self.txtTemplateName,
+ True).updateUI()
+ RadioDataAware.attachRadioButtons(
+ self.agenda, "cp_ProceedMethod",
+ (self.optCreateAgenda, self.optMakeChanges), True).updateUI()
+
+ def saveConfiguration(self):
+ root = Configuration.getConfigurationRoot(
+ self.xMSF, "/org.openoffice.Office.Writer/Wizards/Agenda", True)
+ self.agenda.writeConfiguration(root, "cp_")
+ root.commitChanges()
+
+ def insertRoadmap(self):
+ self.addRoadmap()
+
+ self.insertRoadMapItems(
+ [True, True, True, True, True, True],
+ [self.resources.resStep1, self.resources.resStep2,
+ self.resources.resStep3, self.resources.resStep4,
+ self.resources.resStep5, self.resources.resStep6])
+
+ self.setRoadmapInteractive(True)
+ self.setRoadmapComplete(True)
+ self.setCurrentRoadmapItemID(1)
+
+ '''
+ read the available agenda wizard templates.
+ '''
+
+ def initializeTemplates(self):
+ try:
+ self.sTemplatePath = FileAccess.getOfficePath2(
+ self.xMSF, "Template", "share", "/wizard")
+ sAgendaPath = FileAccess.combinePaths(
+ self.xMSF, self.sTemplatePath, "/wizard/agenda")
+ self.agendaTemplates = FileAccess.getFolderTitles(
+ self.xMSF, "aw", sAgendaPath)
+ return True
+ except NoValidPathException:
+ traceback.print_exc()
+ return False
+
+ '''
+ first page, page design listbox changed.
+ '''
+
+ def pageDesignChanged(self):
+ try:
+ SelectedItemPos = self.listPageDesign.SelectedItemPos
+ #avoid to load the same item again
+ if AgendaWizardDialogImpl.pageDesign is not SelectedItemPos:
+ AgendaWizardDialogImpl.pageDesign = SelectedItemPos
+ self.agendaTemplate.load(
+ self.agendaTemplates[1][SelectedItemPos],
+ self.topicsControl.scrollfields)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ last page, template title changed...
+ '''
+
+ def templateTitleChanged(self):
+ title = Helper.getUnoPropertyValue(getModel(txtTemplateName), "Text")
+ self.agendaTemplate.setTemplateTitle(title)
+
+ #textFields listeners
+ def txtTitleTextChanged(self):
+ AgendaTemplate.redrawTitle("txtTitle")
+
+ def txtDateTextChanged(self):
+ AgendaTemplate.redrawTitle("txtDate")
+
+ def txtTimeTextChanged(self):
+ AgendaTemplate.redrawTitle("txtTime")
+
+ def txtLocationTextChanged(self):
+ AgendaTemplate.redrawTitle("cbLocation")
+
+ #checkbox listeners
+ def chkUseMeetingTypeItemChanged(self):
+ AgendaTemplate.agenda.cp_IncludeMinutes = bool(self.chkMinutes.State)
+
+ def chkUseMeetingTypeItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_MEETING_TYPE)
+
+ def chkUseReadItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_READ)
+
+ def chkUseBringItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_BRING)
+
+ def chkUseNotesItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_NOTES)
+
+ def chkUseCalledByItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_CALLED_BY)
+
+ def chkUseFacilitatorItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_FACILITATOR)
+
+ def chkUseNoteTakerItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_NOTETAKER)
+
+ def chkUseTimeKeeperItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_TIMEKEEPER)
+
+ def chkUseAttendeesItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_PARTICIPANTS)
+
+ def chkUseObserversItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_OBSERVERS)
+
+ def chkUseResourcePersonsItemChanged(self):
+ AgendaTemplate.redraw(FILLIN_RESOURCE_PERSONS)
+
+ '''
+ convenience method.
+ instead of creating a FileAccess object every time
+ it is needed, I have a FileAccess object memeber.
+ the first time it is needed it will be created, and
+ then be reused...
+ @return the FileAccess memeber object.
+ '''
+
+ def getFileAccess(self):
+ if AgendaWizardDialogImpl.fileAccess1 is None:
+ try:
+ AgendaWizardDialogImpl.fileAccess1 = FileAccess(self.xMSF)
+ except Exception, e:
+ traceback.print_exc()
+ return AgendaWizardDialogImpl.fileAccess1
+
+ '''
+ last page, "browse" ("...") button was clicked...
+ '''
+
+ def saveAs(self):
+ try:
+ checkSavePath()
+ saveAs = SystemDialog.createStoreDialog(xMSF)
+ saveAs.addFilterToDialog("ott", "writer8_template", True)
+ # call the saveAs dialog.
+ url = saveAs.callStoreDialog(
+ FileAccess.getParentDir(self.agenda.cp_TemplatePath),
+ FileAccess.getFilename(self.agenda.cp_TemplatePath))
+ if url != None:
+ self.agenda.cp_TemplatePath = url
+ setFilename(url)
+ self.filenameChanged = True
+
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''
+ is called when the user
+ changes the path through the "save as" dialog.
+ The path displayed is a translated, user-friendly, platform dependant path.
+ @param url the new save url.
+ '''
+
+ def setFilename(self, url):
+ try:
+ path = getFileAccess().getPath(url, "")
+ Helper.setUnoPropertyValue(
+ getModel(self.myPathSelection.xSaveTextBox), "Text", path)
+ except Exception, ex:
+ traceback.print_exc()
+
+ def insertRow(self):
+ self.topicsControl.insertRow()
+
+ def removeRow(self):
+ self.topicsControl.removeRow()
+
+ def rowUp(self):
+ self.topicsControl.rowUp()
+
+ def rowDown(self):
+ self.topicsControl.rowDown()
+
+ def cancelWizard(self):
+ self.xUnoDialog.endExecute()
+ self.running = False
+
+ def finishWizard(self):
+ self.switchToStep(self.getCurrentStep(), self.nMaxStep)
+ bSaveSuccess = False
+ endWizard = True
+ try:
+ fileAccess = FileAccess(self.xMSF)
+ self.sPath = self.myPathSelection.getSelectedPath()
+ if self.sPath == "":
+ self.myPathSelection.triggerPathPicker()
+ self.sPath = self.myPathSelection.getSelectedPath()
+
+ self.sPath = fileAccess.getURL(self.sPath)
+ #first, if the filename was not changed, thus
+ #it is coming from a saved session, check if the
+ # file exists and warn the user.
+ if not self.filenameChanged:
+ if fileAccess.exists(self.sPath, True):
+ answer = SystemDialog.showMessageBox(
+ self.xMSF, "MessBox", YES_NO + DEF_NO,
+ self.resources.resFileExists,
+ self.xUnoDialog.Peer)
+ if answer == 3:
+ # user said: no, do not overwrite
+ endWizard = False
+ return False
+
+ xTextDocument = self.agendaTemplate.document
+ bSaveSuccess = OfficeDocument.store(
+ self.xMSF, AgendaTemplate.xTextDocument, self.sPath,
+ "writer8_template")
+
+ if bSaveSuccess:
+ self.saveConfiguration()
+
+ self.agendaTemplate.finish(self.topicsControl.scrollfields)
+
+ loadValues = range(2)
+ loadValues[0] = uno.createUnoStruct( \
+ 'com.sun.star.beans.PropertyValue')
+ loadValues[0].Name = "AsTemplate"
+ if self.agenda.cp_ProceedMethod == 1:
+ loadValues[0].Value = True
+ else:
+ loadValues[0].Value = False
+
+ loadValues[1] = uno.createUnoStruct( \
+ 'com.sun.star.beans.PropertyValue')
+ loadValues[1].Name = "InteractionHandler"
+
+ xIH = self.xMSF.createInstance(
+ "com.sun.star.comp.uui.UUIInteractionHandler")
+ loadValues[1].Value = xIH
+
+ oDoc = OfficeDocument.load(
+ Desktop.getDesktop(self.xMSF),
+ self.sPath, "_default", loadValues)
+ myViewHandler = ViewHandler(self.xMSF, oDoc)
+ myViewHandler.setViewSetting("ZoomType", OPTIMAL)
+ else:
+ pass
+
+ except Exception, e:
+ traceback.print_exc()
+ finally:
+ if endWizard:
+ self.xUnoDialog.endExecute()
+ self.running = False
+ return True
+
+ def closeDocument(self):
+ try:
+ xCloseable = self.agendaTemplate.xFrame
+ xCloseable.close(False)
+ except CloseVetoException, e:
+ traceback.print_exc()
diff --git a/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogResources.py b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogResources.py
new file mode 100644
index 000000000000..332c342d9d54
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/AgendaWizardDialogResources.py
@@ -0,0 +1,153 @@
+from wizards.common.Resource import Resource
+
+class AgendaWizardDialogResources(Resource):
+ MODULE_NAME = "dbw"
+ RID_AGENDAWIZARDDIALOG_START = 5000
+ RID_COMMON_START = 500
+
+ def __init__(self, xmsf):
+ super(AgendaWizardDialogResources,self).__init__(xmsf,
+ AgendaWizardDialogResources.MODULE_NAME)
+ #Delete the String, uncomment the getResText method
+ self.resAgendaWizardDialog_title = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 1)
+ self.resoptMakeChanges_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 2)
+ self.reslblTemplateName_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 3)
+ self.reslblTemplatePath_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 4)
+ self.reslblProceed_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 5)
+ self.reslblTitle1_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 6)
+ self.reslblTitle3_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 7)
+ self.reslblTitle2_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 8)
+ self.reslblTitle4_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 9)
+ self.reslblTitle5_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 10)
+ self.reslblTitle6_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 11)
+ self.reschkMinutes_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 12)
+ self.reslblHelp1_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 13)
+ self.reslblTime_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 14)
+ self.reslblTitle_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 15)
+ self.reslblLocation_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 16)
+ self.reslblHelp2_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 17)
+ self.resbtnTemplatePath_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 18)
+ self.resoptCreateAgenda_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 19)
+ self.reslblHelp6_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 20)
+ self.reslblTopic_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 21)
+ self.reslblResponsible_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 22)
+ self.reslblDuration_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 23)
+ self.reschkConvenedBy_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 24)
+ self.reschkPresiding_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 25)
+ self.reschkNoteTaker_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 26)
+ self.reschkTimekeeper_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 27)
+ self.reschkAttendees_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 28)
+ self.reschkObservers_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 29)
+ self.reschkResourcePersons_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 30)
+ self.reslblHelp4_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 31)
+ self.reschkMeetingTitle_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 32)
+ self.reschkRead_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 33)
+ self.reschkBring_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 34)
+ self.reschkNotes_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 35)
+ self.reslblHelp3_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 36)
+ self.reslblDate_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 38)
+ self.reslblHelpPg6_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 39)
+ self.reslblPageDesign_value = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 40)
+ self.resDefaultFilename = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 41)
+ self.resDefaultFilename = self.resDefaultFilename[:-4] + ".ott"
+ self.resDefaultTitle = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 42)
+ self.resErrSaveTemplate = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 43)
+ self.resPlaceHolderTitle = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 44)
+ self.resPlaceHolderDate = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 45)
+ self.resPlaceHolderTime = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 46)
+ self.resPlaceHolderLocation = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 47)
+ self.resPlaceHolderHint = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 48)
+ self.resStep1 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 50)
+ self.resStep2 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 51)
+ self.resStep3 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 52)
+ self.resStep4 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 53)
+ self.resStep5 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 54)
+ self.resStep6 = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 55)
+ self.resErrOpenTemplate = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 56)
+ self.itemMeetingType = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 57)
+ self.itemBring = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 58)
+ self.itemRead = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 59)
+ self.itemNote = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 60)
+ self.itemCalledBy = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 61)
+ self.itemFacilitator = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 62)
+ self.itemAttendees = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 63)
+ self.itemNotetaker = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 64)
+ self.itemTimekeeper = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 65)
+ self.itemObservers = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 66)
+ self.itemResource = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 67)
+ self.resButtonInsert = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 68)
+ self.resButtonRemove = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 69)
+ self.resButtonUp = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 70)
+ self.resButtonDown = self.getResText(
+ AgendaWizardDialogResources.RID_AGENDAWIZARDDIALOG_START + 71)
+
+ self.resFileExists = self.getResText(
+ AgendaWizardDialogResources.RID_COMMON_START + 19)
diff --git a/wizards/com/sun/star/wizards/agenda/CGAgenda.py b/wizards/com/sun/star/wizards/agenda/CGAgenda.py
new file mode 100644
index 000000000000..a1261de90f1a
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/CGAgenda.py
@@ -0,0 +1,27 @@
+from wizards.common.ConfigGroup import ConfigGroup
+from wizards.common.ConfigSet import ConfigSet
+from CGTopic import CGTopic
+
+class CGAgenda(ConfigGroup):
+ cp_AgendaType = int()
+ cp_IncludeMinutes = bool()
+ cp_Title = ""
+ cp_Date = str()
+ cp_Time = str()
+ cp_Location = ""
+ cp_ShowMeetingType = bool()
+ cp_ShowRead = bool()
+ cp_ShowBring = bool()
+ cp_ShowNotes = bool()
+ cp_ShowCalledBy = bool()
+ cp_ShowFacilitator = bool()
+ cp_ShowNotetaker = bool()
+ cp_ShowTimekeeper = bool()
+ cp_ShowAttendees = bool()
+ cp_ShowObservers = bool()
+ cp_ShowResourcePersons = bool()
+ cp_TemplateName = str()
+ cp_TemplatePath = str()
+ cp_ProceedMethod = int()
+
+ cp_Topics = ConfigSet(CGTopic())
diff --git a/wizards/com/sun/star/wizards/agenda/CGTopic.py b/wizards/com/sun/star/wizards/agenda/CGTopic.py
new file mode 100644
index 000000000000..e9d57ec72cb4
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/CGTopic.py
@@ -0,0 +1,45 @@
+from wizards.common.ConfigGroup import *
+
+'''
+CGTopic means: Configuration Group Topic.
+This object encapsulates a configuration group with topic information.
+Since the topics gui conftrol uses its own data model, there is
+also code here to convert from the data model to CGTopic object (the constructor)
+and vice versa (setDataToRow method - used when loading the last session...)
+'''
+
+class CGTopic(ConfigGroup):
+
+ cp_Index = int()
+ cp_Topic = str()
+ cp_Responsible = str()
+ cp_Time = str()
+
+ '''
+ create a new CGTopic object with data from the given row.
+ the row object is a PropertyValue array, as used
+ by the TopicsControl's data model.
+ @param row PropertyValue array as used by the TopicsControl data model.
+ '''
+
+ def __init__(self, row=None):
+ if row is None:
+ return
+ num = row[0].Value
+ CGTopic.cp_Index = int(row[0].Value[:-1])
+ CGTopic.cp_Topic = row[1].Value
+ CGTopic.cp_Responsible = row[2].Value
+ CGTopic.cp_Time = row[3].Value
+
+ '''
+ copies the data in this CGTopic object
+ to the given row.
+ @param row the row object (PropertyValue array) to
+ copy the data to.
+ '''
+
+ def setDataToRow(self, row):
+ row[0].Value = "" + str(CGTopic.cp_Index) + "."
+ row[1].Value = CGTopic.cp_Topic
+ row[2].Value = CGTopic.cp_Responsible
+ row[3].Value = CGTopic.cp_Time
diff --git a/wizards/com/sun/star/wizards/agenda/TopicsControl.py b/wizards/com/sun/star/wizards/agenda/TopicsControl.py
new file mode 100644
index 000000000000..1ec37b293fd2
--- /dev/null
+++ b/wizards/com/sun/star/wizards/agenda/TopicsControl.py
@@ -0,0 +1,886 @@
+from threading import RLock
+from CGTopic import CGTopic
+from wizards.ui.ControlScroller import *
+from AgendaWizardDialogConst import LAST_HID
+from wizards.common.Properties import Properties
+from wizards.ui.event.CommonListener import FocusListenerProcAdapter, KeyListenerProcAdapter
+
+from com.sun.star.awt.Key import DOWN, UP, TAB
+from com.sun.star.awt.KeyModifier import SHIFT, MOD1
+
+'''
+@author rpiterman
+This class implements the UI functionality of the topics scroller control.
+<br/>
+During developement, there has been a few changes which were not *fully* done
+mainly in converting the topics and time boxes
+from combobox and time box to normal textboxes,
+so in the code they might be referenced as combobox or timebox. This should be
+rather understood as topicstextbox and timetextbox.<br/><br/>
+Important behaiviour of this control is that there is always a
+blank row at the end, in which the user can enter data.<br/>
+Once the row is not blank (thus, the user entered data...),
+a new blank row is added.<br/>
+Once the user removes the last *unempty* row, binsertRowy deleteing its data, it becomes
+the *last empty row* and the one after is being automatically removed.<br/><br/>
+The contorl shows 5 rows at a time.<br/>
+If, for example, only 2 rows exist (from which the 2ed one is empty...)
+then the other three rows, which do not exist in the data model, are disabled.
+<br/>
+The following other functionality is implemented:
+<br/>
+0. synchroniting data between controls, data model and live preview.
+1. Tab scrolling.<br/>
+2. Keyboard scrolling.<br/>
+3. Removing rows and adding new rows.<br/>
+4. Moving rows up and down. <br/>
+<br/>
+This control relays on the ControlScroller control which uses the following
+Data model:<br/>
+1. It uses a vector, whos members are arrays of PropertyValue.<br/>
+2. Each array represents a row.<br/>
+(Note: the Name and Value memebrs of the PropertyValue object are being used)
+3. Each property Value represents a value
+for a single control with the following rules:<br/>
+3. a. the Value of the property is used for as value
+of the controls (usually text).<br/>
+3. b. the Name of the property is used to map values
+to UI controls in the following manner:<br/>
+3. b. 1. only the Name of the first X Rows is regarded,
+where X is the number of visible rows (in the ainsertRowgenda wizard this would be 5,
+since 5 topic rows are visible on the dialog).<br/>
+3. b. 2. The Names of the first X (or 5...) rows are the names
+of the UI Controls to hold values. When the control scroller scrolls,
+it looks at the first 5 rows and uses the names specified there to map the
+current values to the specified controls. <br/>
+This data model makes the following limitations on the implementation:
+When moving rows, only the values should be moved. The Rows objects,
+which contain also the Names of the controls should not be switched. <br/>
+also when deleting or inserting rows, attention should be paid that no rows
+should be removed or inserted. Instead, only the Values should rotate. <br/><br/>
+To save the topics in the registry a ConfigSet of objects of type CGTopic is
+being used.
+This one is not synchronized "live", since it is unnecessary... instead, it is
+synchronized on call, before the settings should be saved.
+'''
+
+def synchronized(lock):
+ ''' Synchronization decorator. '''
+ def wrap(f):
+ def newFunction(*args, **kw):
+ lock.acquire()
+ try:
+ return f(*args, **kw)
+ finally:
+ lock.release()
+ return newFunction
+ return wrap
+
+class TopicsControl(ControlScroller):
+
+ lock = RLock()
+ LABEL = "lblTopicCnt_"
+ TOPIC = "txtTopicTopic_"
+ RESP = "cbTopicResp_"
+ TIME = "txtTopicTime_"
+ nscrollvalue = 0
+ LABEL_PROPS = (PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_LABEL,
+ PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ TEXT_PROPS = (PropertyNames.PROPERTY_HEIGHT, PropertyNames.PROPERTY_HELPURL,
+ PropertyNames.PROPERTY_POSITION_X, PropertyNames.PROPERTY_POSITION_Y,
+ PropertyNames.PROPERTY_STEP, PropertyNames.PROPERTY_TABINDEX,
+ PropertyNames.PROPERTY_WIDTH)
+ lastFocusRow = 0
+ lastFocusControl = None
+
+ def __init__(self, dialog, xmsf, agenda):
+ try:
+ super(TopicsControl, self).__init__(
+ dialog, xmsf, 5, 92, 38, 212, 5, 18, LAST_HID)
+ self.initializeScrollFields(agenda)
+ # set some focus listeners for TAB scroll down and up...
+ # prepare scroll down on tab press...
+ self.lastTime = \
+ self.ControlGroupVector[self.nblockincrement - 1].timebox
+
+ self.lastTime.addKeyListener(KeyListenerProcAdapter(
+ self.lastControlKeyPressed))
+ #prepare scroll up on tab press...
+ self.firstTopic = self.ControlGroupVector[0].textbox
+ self.firstTopic.addKeyListener(KeyListenerProcAdapter(
+ self.firstControlKeyPressed))
+ self.enableButtons()
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ initializes the data of the control.
+ @param agenda
+ '''
+
+ def initializeScrollFields(self, agenda):
+ # create a row for each topic with the given values....
+ for i in xrange(agenda.cp_Topics.getSize()):
+ row = self.newRow(i)
+ agenda.cp_Topics.getElementAt(i).setDataToRow(row)
+ # a parent class method
+ self.registerControlGroup(row, i)
+ self.updateDocumentRow(i)
+ # inserts a blank row at the end...
+ self.insertRowAtEnd()
+
+ '''
+ Insert a blank (empty) row
+ as last row of the control.
+ The control has always a blank row at the
+ end, which enables the user to enter data...
+ '''
+
+ @classmethod
+ def insertRowAtEnd(self):
+ l = len(ControlScroller.scrollfields)
+ self.registerControlGroup(self.newRow(l), l)
+ self.setTotalFieldCount(l + 1)
+ # if the new row is visible, it must have been disabled
+ # so it should be now enabled...
+ if l - ControlScroller.nscrollvalue < self.nblockincrement:
+ self.ControlGroupVector[l - ControlScroller.nscrollvalue].\
+ setEnabled(True)
+
+ '''
+ remove the last row
+ '''
+
+ @classmethod
+ def removeLastRow(self):
+ l = len(ControlScroller.scrollfields)
+ # if we should scroll up...
+ if (l - ControlScroller.nscrollvalue) >= 1 \
+ and (l - ControlScroller.nscrollvalue) <= self.nblockincrement \
+ and ControlScroller.nscrollvalue > 0:
+ while (l - ControlScroller.nscrollvalue >= 1) \
+ and l - ControlScroller.nscrollvalue <= self.nblockincrement \
+ and ControlScroller.nscrollvalue > 0:
+ self.setScrollValue(ControlScroller.nscrollvalue - 1)
+ # if we should disable a row...
+ elif ControlScroller.nscrollvalue == 0 and l - 1 < self.nblockincrement:
+ self.ControlGroupVector[l - 1].setEnabled(False)
+
+ self.unregisterControlGroup(l - 1)
+ self.setTotalFieldCount(l - 1)
+
+ '''
+ in order to use the "move up", "down" "insert" and "remove" buttons,
+ we track the last control the gained focus, in order to know which
+ row should be handled.
+ @param fe
+ '''
+
+ @classmethod
+ def focusGained(self, fe):
+ xc = fe.Source
+ self.focusGained2(xc)
+
+ '''
+ Sometimes I set the focus programatically to a control
+ (for example when moving a row up or down, the focus should move
+ with it).
+ In such cases, no VCL event is being triggered so it must
+ be called programtically.
+ This is done by this method.
+ @param control
+ '''
+
+ @classmethod
+ def focusGained2(self, control):
+ try:
+ #calculate in which row we are...
+ name = Helper.getUnoPropertyValue(
+ control.Model, PropertyNames.PROPERTY_NAME)
+ num = name[name.index("_") + 1:]
+ TopicsControl.lastFocusRow = int(num) + ControlScroller.nscrollvalue
+ TopicsControl.lastFocusControl = control
+ # enable/disable the buttons...
+ self.enableButtons()
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ enable or disable the buttons according to the
+ current row we are in.
+ '''
+
+ @classmethod
+ def enableButtons(self):
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnInsert,
+ TopicsControl.lastFocusRow < len(ControlScroller.scrollfields))
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnRemove,
+ TopicsControl.lastFocusRow < len(ControlScroller.scrollfields) - 1)
+ if TopicsControl.lastFocusControl is not None:
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnUp, TopicsControl.lastFocusRow > 0)
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnDown,
+ TopicsControl.lastFocusRow < len(ControlScroller.scrollfields) - 1)
+ else:
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnUp, False)
+ UnoDialog.setEnabled(
+ ControlScroller.CurUnoDialog.btnDown, False)
+
+ '''
+ Removes the current row.
+ See general class documentation explanation about the
+ data model used and the limitations which explain the implementation here.
+ '''
+
+ def removeRow(self):
+ try:
+ for i in xrange(TopicsControl.lastFocusRow,
+ len(ControlScroller.scrollfields) - 1):
+ pv1 = ControlScroller.scrollfields[i]
+ pv2 = ControlScroller.scrollfields[i + 1]
+ pv1[1].Value = pv2[1].Value
+ pv1[2].Value = pv2[2].Value
+ pv1[3].Value = pv2[3].Value
+ self.updateDocumentRow(i)
+ if i - ControlScroller.nscrollvalue < self.nblockincrement:
+ self.fillupControl(i - ControlScroller.nscrollvalue)
+
+ self.removeLastRow()
+ # update the live preview background document
+ self.reduceDocumentToTopics()
+ self.enableButtons()
+ if TopicsControl.lastFocusControl is not None:
+ # the focus should return to the edit control
+ self.focus(TopicsControl.lastFocusControl)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ Inserts a row before the current row.
+ See general class documentation explanation about the
+ data model used and the limitations which explain the implementation here.
+ '''
+
+ def insertRow(self):
+ try:
+ self.insertRowAtEnd()
+ for i in xrange(len(ControlScroller.scrollfields) - 2,
+ TopicsControl.lastFocusRow, -1):
+ pv1 = ControlScroller.scrollfields[i]
+ pv2 = ControlScroller.scrollfields[i - 1]
+ pv1[1].Value = pv2[1].Value
+ pv1[2].Value = pv2[2].Value
+ pv1[3].Value = pv2[3].Value
+ self.updateDocumentRow(i)
+ if i - ControlScroller.nscrollvalue < self.nblockincrement:
+ self.fillupControl(i - ControlScroller.nscrollvalue)
+
+ # after rotating all the properties from this row on,
+ # we clear the row, so it is practically a new one...
+ pv1 = ControlScroller.scrollfields[TopicsControl.lastFocusRow]
+ pv1[1].Value = ""
+ pv1[2].Value = ""
+ pv1[3].Value = ""
+ # update the preview document.
+ self.updateDocumentRow(TopicsControl.lastFocusRow)
+ self.fillupControl(
+ TopicsControl.lastFocusRow - ControlScroller.nscrollvalue)
+ self.enableButtons()
+
+ if TopicsControl.lastFocusControl is not None:
+ self.focus(TopicsControl.lastFocusControl)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ create a new row with the given index.
+ The index is important because it is used in the
+ Name member of the PropertyValue objects.
+ To know why see general class documentation above (data model explanation)
+ @param i the index of the new row
+ @return
+ '''
+
+ @classmethod
+ def newRow(self, i):
+ pv = [None] * 4
+ pv[0] = Properties.createProperty(
+ TopicsControl.LABEL + str(i), "" + str(i + 1) + ".")
+ pv[1] = Properties.createProperty(TopicsControl.TOPIC + str(i), "")
+ pv[2] = Properties.createProperty(TopicsControl.RESP + str(i), "")
+ pv[3] = Properties.createProperty(TopicsControl.TIME + str(i), "")
+ return pv
+
+ '''
+ Implementation of ControlScroller
+ This is a UI method which inserts a new row to the control.
+ It uses the child-class ControlRow. (see below).
+ @param _index
+ @param npos
+ @see ControlRow
+ '''
+
+ def insertControlGroup(self, _index, npos):
+ oControlRow = ControlRow(
+ ControlScroller.CurUnoDialog, self.iCompPosX, npos, _index,
+ ControlRow.tabIndex)
+ self.ControlGroupVector.append(oControlRow)
+ ControlRow.tabIndex += 4
+
+ '''
+ Checks if a row is empty.
+ This is used when the last row is changed.
+ If it is empty, the next row (which is always blank) is removed.
+ If it is not empty, a next row must exist.
+ @param row the index number of the row to check.
+ @return true if empty. false if not.
+ '''
+
+ @classmethod
+ def isRowEmpty(self, row):
+ data = self.getTopicData(row)
+ # now - is this row empty?
+ return data[1].Value and data[2].Value and data[3].Value
+
+ '''
+ update the preview document and
+ remove/insert rows if needed.
+ @param guiRow
+ @param column
+ '''
+ oldData = []
+
+ @classmethod
+ def fieldChanged(self, guiRow, column):
+ with TopicsControl.lock:
+ try:
+ # First, I update the document
+ data = self.getTopicData(guiRow + ControlScroller.nscrollvalue)
+ if data is None:
+ return
+
+ dataValue = [i.Value for i in data]
+ if dataValue == TopicsControl.oldData:
+ return
+ else:
+ TopicsControl.oldData = dataValue
+
+ self.updateDocumentCell(
+ guiRow + ControlScroller.nscrollvalue, column, data)
+ if self.isRowEmpty(guiRow + ControlScroller.nscrollvalue):
+ '''
+ if this is the row before the last one
+ (the last row is always empty)
+ delete the last row...
+ '''
+ if (guiRow + ControlScroller.nscrollvalue) \
+ == len(ControlScroller.scrollfields) - 2:
+ self.removeLastRow()
+ '''now consequentially check the last two rows,
+ and remove the last one if they are both empty.
+ (actually I check always the "before last" row,
+ because the last one is always empty...
+ '''
+ while len(ControlScroller.scrollfields) > 1 \
+ and self.isRowEmpty(len(ControlScroller.scrollfields) - 2):
+ removeLastRow()
+ cr = self.ControlGroupVector[
+ ControlScroller.scrollfields.size - ControlScroller.nscrollvalue - 1]
+ # if a remove was performed, set focus
+ #to the last row with some data in it...
+ self.focus(getControl(cr, column))
+ # update the preview document.
+ self.reduceDocumentToTopics()
+
+ else:
+ # row contains data
+ # is this the last row?
+ if (guiRow + ControlScroller.nscrollvalue + 1) \
+ == len(ControlScroller.scrollfields):
+ self.insertRowAtEnd()
+
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ return the corresponding row data for the given index.
+ @param topic index of the topic to get.
+ @return a PropertyValue array with the data for the given topic.
+ '''
+
+ @classmethod
+ def getTopicData(self, topic):
+ if topic < len(ControlScroller.scrollfields):
+ return ControlScroller.scrollfields[topic]
+ else:
+ return None
+
+ '''
+ If the user presses tab on the last control, and
+ there *are* more rows in the model, scroll down.
+ @param event
+ '''
+
+ def lastControlKeyPressed(self, event):
+ # if tab without shift was pressed...
+ try:
+ if event.KeyCode == TAB and event.Modifiers == 0:
+ # if there is another row...
+ if (self.nblockincrement + ControlScroller.nscrollvalue) \
+ < len(ControlScroller.scrollfields):
+ self.setScrollValue(ControlScroller.nscrollvalue + 1)
+ self.focus(self.getControlByIndex(self.ControlGroupVector[4], 1))
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ If the user presses shift-tab on the first control, and
+ there *are* more rows in the model, scroll up.
+ @param event
+ '''
+
+ def firstControlKeyPressed(self, event):
+ # if tab with shift was pressed...
+ if (event.KeyCode == TAB) and \
+ (event.Modifiers == SHIFT):
+ if ControlScroller.nscrollvalue > 0:
+ setScrollValue(ControlScroller.nscrollvalue - 1)
+ focus(self.lastTime)
+
+ '''
+ sets focus to the given control.
+ @param textControl
+ '''
+
+ @classmethod
+ def focus(self, textControl):
+ textControl.setFocus()
+ text = textControl.Text
+ textControl.Selection = uno.createUnoStruct( \
+ 'com.sun.star.awt.Selection', 0, len(text))
+ self.focusGained2(textControl)
+
+ '''
+ moves the given row one row down.
+ @param guiRow the gui index of the row to move.
+ @param control the control to gain focus after moving.
+ '''
+
+ @synchronized(lock)
+ def rowDown(self, guiRow=None, control=None):
+ try:
+ if guiRow is None and control is None:
+ guiRow = TopicsControl.lastFocusRow - ControlScroller.nscrollvalue
+ control = TopicsControl.lastFocusControl
+ # only perform if this is not the last row.
+ actuallRow = guiRow + ControlScroller.nscrollvalue
+ if actuallRow + 1 < len(ControlScroller.scrollfields):
+ # get the current selection
+ selection = control.Selection
+ # the last row should scroll...
+ scroll = (guiRow == self.nblockincrement - 1)
+ if scroll:
+ self.setScrollValue(ControlScroller.nscrollvalue + 1)
+
+ scroll1 = ControlScroller.nscrollvalue
+ if scroll:
+ aux = -1
+ else:
+ aux = 1
+ self.switchRows(guiRow, guiRow + aux)
+ if ControlScroller.nscrollvalue != scroll1:
+ guiRow += (ControlScroller.nscrollvalue - scroll1)
+
+ self.setSelection(guiRow + (not scroll), control, selection)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ move the current row up
+ '''
+
+ @synchronized(lock)
+ def rowUp(self, guiRow=None, control=None):
+ try:
+ if guiRow is None and control is None:
+ guiRow = TopicsControl.lastFocusRow - ControlScroller.nscrollvalue
+ control = TopicsControl.lastFocusControl
+ # only perform if this is not the first row
+ actuallRow = guiRow + ControlScroller.nscrollvalue
+ if actuallRow > 0:
+ # get the current selection
+ selection = control.Selection
+ # the last row should scroll...
+ scroll = (guiRow == 0)
+ if scroll:
+ self.setScrollValue(ControlScroller.nscrollvalue - 1)
+ if scroll:
+ aux = 1
+ else:
+ aux = -1
+ self.switchRows(guiRow, guiRow + aux)
+ self.setSelection(guiRow - (not scroll), control, selection)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ moves the cursor up.
+ @param guiRow
+ @param control
+ '''
+
+ @classmethod
+ @synchronized(lock)
+ def cursorUp(self, guiRow, control):
+ # is this the last full row ?
+ actuallRow = guiRow + ControlScroller.nscrollvalue
+ #if this is the first row
+ if actuallRow == 0:
+ return
+ # the first row should scroll...
+
+ scroll = (guiRow == 0)
+ if scroll:
+ self.setScrollValue(ControlScroller.nscrollvalue - 1)
+ upperRow = self.ControlGroupVector[guiRow]
+ else:
+ upperRow = self.ControlGroupVector[guiRow - 1]
+
+ self.focus(self.getControl(upperRow, control))
+
+ '''
+ moves the cursor down
+ @param guiRow
+ @param control
+ '''
+
+ @classmethod
+ @synchronized(lock)
+ def cursorDown(self, guiRow, control):
+ # is this the last full row ?
+ actuallRow = guiRow + ControlScroller.nscrollvalue
+ #if this is the last row, exit
+ if actuallRow == len(ControlScroller.scrollfields) - 1:
+ return
+ # the first row should scroll...
+
+ scroll = (guiRow == self.nblockincrement - 1)
+ if scroll:
+ self.setScrollValue(ControlScroller.nscrollvalue + 1)
+ lowerRow = self.ControlGroupVector[guiRow]
+ else:
+ # if we scrolled we are done...
+ #otherwise..
+ lowerRow = self.ControlGroupVector[guiRow + 1]
+
+ self.focus(self.getControl(lowerRow, control))
+
+ '''
+ changes the values of the given rows with eachother
+ @param row1 one can figure out what this parameter is...
+ @param row2 one can figure out what this parameter is...
+ '''
+
+ def switchRows(self, row1, row2):
+ o1 = ControlScroller.scrollfields[row1 + ControlScroller.nscrollvalue]
+ o2 = ControlScroller.scrollfields[row2 + ControlScroller.nscrollvalue]
+ temp = None
+ for i in xrange(1, len(o1)):
+ temp = o1[i].Value
+ o1[i].Value = o2[i].Value
+ o2[i].Value = temp
+ self.fillupControl(row1)
+ self.fillupControl(row2)
+ self.updateDocumentRow(row1 + ControlScroller.nscrollvalue, o1)
+ self.updateDocumentRow(row2 + ControlScroller.nscrollvalue, o2)
+
+ '''
+ if we changed the last row, add another one...
+ '''
+ if (row1 + ControlScroller.nscrollvalue + 1 == \
+ len(ControlScroller.scrollfields)) \
+ or (row2 + ControlScroller.nscrollvalue + 1 == \
+ len(ControlScroller.scrollfields)):
+
+ self.insertRowAtEnd()
+ '''
+ if we did not change the last row but
+ we did change the one before - check if we
+ have two empty rows at the end.
+ If so, delete the last one...
+ '''
+ elif (row1 + ControlScroller.nscrollvalue) + \
+ (row2 + ControlScroller.nscrollvalue) \
+ == (len(ControlScroller.scrollfields) * 2 - 5):
+ if self.isRowEmpty(len(ControlScroller.scrollfields) - 2) \
+ and self.isRowEmpty(len(ControlScroller.scrollfields) - 1):
+ self.removeLastRow()
+ self.reduceDocumentToTopics()
+
+ '''
+ sets a text selection to a given control.
+ This is used when one moves a row up or down.
+ After moving row X to X+/-1, the selection (or cursor position) of the
+ last focused control should be restored.
+ The control's row is the given guiRow.
+ The control's column is detecte4d according to the given event.
+ This method is called as subsequent to different events,
+ thus it is comfortable to use the event here to detect the column,
+ rather than in the different event methods.
+ @param guiRow the row of the control to set the selection to.
+ @param eventSource helps to detect
+ the control's column to set the selection to.
+ @param s the selection object to set.
+ '''
+
+ def setSelection(self, guiRow, eventSource, s):
+ cr = self.ControlGroupVector[guiRow]
+ control = self.getControl(cr, eventSource)
+ control.setFocus()
+ control.setSelection(s)
+
+ '''
+ returns a control out of the given row, according to a column number.
+ @param cr control row object.
+ @param column the column number.
+ @return the control...
+ '''
+
+ @classmethod
+ def getControlByIndex(self, cr, column):
+ tmp_switch_var1 = column
+ if tmp_switch_var1 == 0:
+ return cr.label
+ elif tmp_switch_var1 == 1:
+ return cr.textbox
+ elif tmp_switch_var1 == 2:
+ return cr.combobox
+ elif tmp_switch_var1 == 3:
+ return cr.timebox
+ else:
+ raise IllegalArgumentException ("No such column");
+
+ '''getControl
+ returns a control out of the given row, which is
+ in the same column as the given control.
+ @param cr control row object
+ @param control a control indicating a column.
+ @return
+ '''
+
+ @classmethod
+ def getControl(self, cr, control):
+ column = self.getColumn(control)
+ return self.getControlByIndex(cr, column)
+
+ '''
+ returns the column number of the given control.
+ @param control
+ @return
+ '''
+
+ @classmethod
+ def getColumn(self, control):
+ name = Helper.getUnoPropertyValue(
+ control.Model, PropertyNames.PROPERTY_NAME)
+ if name.startswith(TopicsControl.TOPIC):
+ return 1
+ if name.startswith(TopicsControl.RESP):
+ return 2
+ if name.startswith(TopicsControl.TIME):
+ return 3
+ if name.startswith(TopicsControl.LABEL):
+ return 0
+ return -1
+
+ '''
+ update the given row in the preview document with the given data.
+ @param row
+ @param data
+ '''
+
+ def updateDocumentRow(self, row, data=None):
+ if data is None:
+ data = ControlScroller.scrollfields[row]
+ try:
+ ControlScroller.CurUnoDialog.agendaTemplate.topics.write(
+ row, data)
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''
+ updates a single cell in the preview document.
+ Is called when a single value is changed, since we really
+ don't have to update the whole row for one small changhe...
+ @param row the data row to update (topic number).
+ @param column the column to update (a gui column, not a document column).
+ @param data the data of the entire row.
+ '''
+
+ @classmethod
+ def updateDocumentCell(self, row, column, data):
+ try:
+ ControlScroller.CurUnoDialog.agendaTemplate.topics.writeCell(
+ row, column, data)
+ except Exception, ex:
+ traceback.print_exc()
+
+ '''
+ when removeing rows, this method updates
+ the preview document to show the number of rows
+ according to the data model.
+ '''
+
+ def reduceDocumentToTopics(self):
+ try:
+ ControlScroller.CurUnoDialog.agendaTemplate.topics.reduceDocumentTo(
+ len(ControlScroller.scrollfields) - 1)
+ except Exception, ex:
+ traceback.print_exc()
+
+'''
+@author rp143992
+A class represting a single GUI row.
+Note that the instance methods of this class
+are being called and handle controls of
+a single row.
+'''
+
+class ControlRow(object):
+
+ tabIndex = 520
+ '''
+ constructor. Create the row in the given dialog given cordinates,
+ with the given offset (row number) and tabindex.
+ Note that since I use this specifically for the agenda wizard,
+ the step and all control coordinates inside the
+ row are constant (5).
+ @param dialog the agenda dialog
+ @param x x coordinates
+ @param y y coordinates
+ @param i the gui row index
+ @param tabindex first tab index for this row.
+ '''
+
+ def __init__(self, dialog, x, y, i, tabindex):
+ self.offset = i
+ self.dialog = dialog
+ self.label = self.dialog.insertLabel(
+ TopicsControl.LABEL + str(i),
+ TopicsControl.LABEL_PROPS,
+ (8, "" + str(i + 1) + ".",
+ x + 4, y + 2, ControlScroller.iStep, tabindex, 10))
+ self.textbox = self.dialog.insertTextField(
+ TopicsControl.TOPIC + str(i), "topicTextChanged",
+ TopicsControl.TEXT_PROPS,
+ (12, HelpIds.getHelpIdString(ControlScroller.curHelpIndex + i * 3 + 1),
+ x + 15, y, ControlScroller.iStep, tabindex + 1, 84), self)
+ self.combobox = self.dialog.insertTextField(
+ TopicsControl.RESP + str(i), "responsibleTextChanged",
+ TopicsControl.TEXT_PROPS,
+ (12, HelpIds.getHelpIdString(ControlScroller.curHelpIndex + i * 3 + 2),
+ x + 103, y, ControlScroller.iStep, tabindex + 2, 68), self)
+ self.timebox = self.dialog.insertTextField(
+ TopicsControl.TIME + str(i), "timeTextChanged",
+ TopicsControl.TEXT_PROPS,
+ (12, HelpIds.getHelpIdString(ControlScroller.curHelpIndex + i * 3 + 3),
+ x + 175, y, ControlScroller.iStep, tabindex + 3, 20), self)
+ self.setEnabled(False)
+ self.textbox.addKeyListener(KeyListenerProcAdapter(self.keyPressed))
+ self.combobox.addKeyListener(KeyListenerProcAdapter(self.keyPressed))
+ self.timebox.addKeyListener(KeyListenerProcAdapter(self.keyPressed))
+ self.textbox.addFocusListener(FocusListenerProcAdapter(
+ TopicsControl.focusGained))
+ self.combobox.addFocusListener(FocusListenerProcAdapter(
+ TopicsControl.focusGained))
+ self.timebox.addFocusListener(FocusListenerProcAdapter(
+ TopicsControl.focusGained))
+
+ def topicTextChanged(self):
+ try:
+ # update the data model
+ ControlScroller.fieldInfo(self.offset, 1)
+ # update the preview document
+ TopicsControl.fieldChanged(self.offset, 1)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ called through an event listener when the
+ responsible text is changed by the user.
+ updates the data model and the preview document.
+ '''
+
+ def responsibleTextChanged(self):
+ try:
+ # update the data model
+ ControlScroller.fieldInfo(self.offset, 2)
+ # update the preview document
+ TopicsControl.fieldChanged(self.offset, 2)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ called through an event listener when the
+ time text is changed by the user.
+ updates the data model and the preview document.
+ '''
+
+ def timeTextChanged(self):
+ try:
+ # update the data model
+ ControlScroller.fieldInfo(self.offset, 3)
+ # update the preview document
+ TopicsControl.fieldChanged(self.offset, 3)
+ except Exception:
+ traceback.print_exc()
+
+ '''
+ enables/disables the row.
+ @param enabled true for enable, false for disable.
+ '''
+
+ def setEnabled(self, enabled):
+ self.dialog.setEnabled(self.label, enabled)
+ self.dialog.setEnabled(self.textbox, enabled)
+ self.dialog.setEnabled(self.combobox, enabled)
+ self.dialog.setEnabled(self.timebox, enabled)
+
+ '''
+ Impelementation of XKeyListener.
+ Optionally performs the one of the following:
+ cursor up, or down, row up or down
+ '''
+
+ def keyPressed(self, event):
+ try:
+ if self.isMoveDown(event):
+ TopicsControl.rowDown(self.offset, event.Source)
+ elif self.isMoveUp(event):
+ TopicsControl.rowUp(self.offset, event.Source)
+ elif self.isDown(event):
+ TopicsControl.cursorDown(self.offset, event.Source)
+ elif self.isUp(event):
+ TopicsControl.cursorUp(self.offset, event.Source)
+
+ TopicsControl.enableButtons()
+ except Exception:
+ traceback.print_exc()
+
+ def isMoveDown(self, e):
+ return (e.KeyCode == DOWN) and (e.Modifiers == MOD1)
+
+ def isMoveUp(self, e):
+ return (e.KeyCode == UP) and (e.Modifiers == MOD1)
+
+ def isDown(self, e):
+ return (e.KeyCode == DOWN) and (e.Modifiers == 0)
+
+ def isUp(self, e):
+ return (e.KeyCode == UP) and (e.Modifiers == 0)