def drawFull(self, month, year): # should be called only once when we draw the calendar for # the first time self.vp = VerticalPanel() self.vp.setSpacing(2) self.vp.addStyleName("calendarbox calendar-module calendar") self.setWidget(self.vp) self.setVisible(False) # mth = int(month) yr = int(year) tp = HorizontalPanel() tp.addStyleName("calendar-top-panel") tp.setSpacing(5) h1 = Hyperlink('<<') h1.addClickListener(getattr(self, 'onPreviousYear')) h2 = Hyperlink('<') h2.addClickListener(getattr(self, 'onPreviousMonth')) h4 = Hyperlink('>') h4.addClickListener(getattr(self, 'onNextMonth')) h5 = Hyperlink('>>') h5.addClickListener(getattr(self, 'onNextYear')) tp.add(h1) tp.add(h2) # titlePanel can be changed, whenever we draw, so keep the reference txt = "<b>" txt += self.getMonthsOfYear()[mth - 1] + " " + str(yr) txt += "</b>" self.titlePanel = SimplePanel() self.titlePanel.setWidget(HTML(txt)) self.titlePanel.setStyleName("calendar-center") tp.add(self.titlePanel) tp.add(h4) tp.add(h5) tvp = VerticalPanel() tvp.setSpacing(10) tvp.add(tp) self.vp.add(tvp) # done with top panel self.middlePanel = SimplePanel() grid = self.drawGrid(mth, yr) self.middlePanel.setWidget(grid) self.vp.add(self.middlePanel) self.defaultGrid = grid self._gridShortcutsLinks() self._gridCancelLink() # # add code to test another way of doing the layout # self.setVisible(True) return
def drawFull(self, month, year): # should be called only once when we draw the calendar for # the first time self.vp = VerticalPanel() self.vp.setSpacing(2) self.vp.addStyleName("calendarbox calendar-module calendar") self.setWidget(self.vp) self.setVisible(False) # mth = int(month) yr = int(year) tp = HorizontalPanel() tp.addStyleName("calendar-top-panel") tp.setSpacing(5) h1 = Hyperlink('<<') h1.addClickListener(getattr(self, 'onPreviousYear')) h2 = Hyperlink('<') h2.addClickListener(getattr(self, 'onPreviousMonth')) h4 = Hyperlink('>') h4.addClickListener(getattr(self, 'onNextMonth')) h5 = Hyperlink('>>') h5.addClickListener(getattr(self, 'onNextYear')) tp.add(h1) tp.add(h2) # titlePanel can be changed, whenever we draw, so keep the reference txt = "<b>" txt += self.getMonthsOfYear()[mth-1] + " " + str(yr) txt += "</b>" self.titlePanel = SimplePanel() self.titlePanel.setWidget(HTML(txt)) self.titlePanel.setStyleName("calendar-center") tp.add(self.titlePanel) tp.add(h4) tp.add(h5) tvp = VerticalPanel() tvp.setSpacing(10) tvp.add(tp) self.vp.add(tvp) # done with top panel self.middlePanel = SimplePanel() grid = self.drawGrid(mth, yr) self.middlePanel.setWidget(grid) self.vp.add(self.middlePanel) self.defaultGrid = grid self._gridShortcutsLinks() self._gridCancelLink() # # add code to test another way of doing the layout # self.setVisible(True) return
def _gridShortcutsLinks(self): bh1 = Hyperlink(_("Current")) bh1.addClickListener(getattr(self, 'onToday')) b2 = Button(_("Choose"), self.onMonthSelected) bh3 = Hyperlink(self.cancel) bh3.addClickListener(getattr(self, 'onCancel')) b = HorizontalPanel() b.addStyleName("calendar-shortcuts") b.add(bh1) b.add(b2) b.add(bh3) self.vp.add(b)
def _gridShortcutsLinks(self): bh1 = Hyperlink(_("Current")) bh1.addClickListener(getattr(self, 'onToday')) b2 = Button(_("Choose"),self.onMonthSelected) bh3 = Hyperlink(self.cancel) bh3.addClickListener(getattr(self, 'onCancel')) b = HorizontalPanel() b.addStyleName("calendar-shortcuts") b.add(bh1) b.add(b2) b.add(bh3) self.vp.add(b)
def _gridShortcutsLinks(self): # # some links & handlers # bh1 = Hyperlink(self.yesterday) bh1.addClickListener(getattr(self, 'onYesterday')) bh2 = Hyperlink(self.today) bh2.addClickListener(getattr(self, 'onToday')) bh3 = Hyperlink(self.tomorrow) bh3.addClickListener(getattr(self, 'onTomorrow')) b = HorizontalPanel() b.add(bh1) b.add(bh2) b.add(bh3) b.addStyleName("calendar-shortcuts") self.vp.add(b)
class RichTextEditor(Composite): def run(self): try: self.getSelection() rng = Selection.getRange() if (self.m_timerRange is None) or (not self.m_timerRange.equals(rng)): self.onSelectionChange(rng) self.m_timerRange = rng except: GWT.log("Error in timer selection", ex) def __init__(self): Composite.__init__(self) self.m_isInText = False self.m_lastText = "" self.trigger = False self.m_lastRange = None # Timer for trying real time selection change stuff self.m_timerRange = None self.m_selTimer = Timer() self.m_mainPanel = DockPanel() self.m_toolbarPanel = HorizontalPanel() self.m_toolbarPanel.setWidth("100%") self.m_toolbarPanel.setHeight("25px") self.m_toolbarPanel.setBorderWidth(1) self.m_toolbarPanel.addStyleName("timeline-RichTextToolbar") self.m_textW = RichTextArea() self.m_textW.addClickListener(self) self.m_textW.addKeyboardListener(self) self.m_textW.addFocusListener(self) self.m_textW.addMouseListener(self) # According to gwt doc, these do need to be set because this is a frame self.m_textW.setHeight("100%") self.m_textW.setWidth("100%") # Add buttons self.m_formatter = self.getFormatter() self.m_boldW = self.addToggleButton(self.m_toolbarPanel, Icons.bold_icon, "Bold") self.m_italicW = self.addToggleButton(self.m_toolbarPanel, Icons.italics_icon, "Italic") self.m_underlineW = self.addToggleButton(self.m_toolbarPanel, Icons.underline_icon, "Underline") self.m_subscriptW = self.addToggleButton(self.m_toolbarPanel, Icons.subscript_icon, "Subscript") self.m_superscriptW = self.addToggleButton(self.m_toolbarPanel, Icons.superscript_icon, "Superscript") self.m_strikethroughW = self.addToggleButton(self.m_toolbarPanel, Icons.strikethrough_icon, "Strikethrough") self.m_indentW = self.addPushButton(self.m_toolbarPanel, Icons.indentmore_icon, "Indent Right") self.m_outdentW = self.addPushButton(self.m_toolbarPanel, Icons.indentless_icon, "Indent Left") self.m_justifyLeftW = self.addPushButton(self.m_toolbarPanel, Icons.justifyleft_icon, "Justify Left") self.m_justifyCenterW = self.addPushButton(self.m_toolbarPanel, Icons.justifycenter_icon, "Justify Center") self.m_justifyRightW = self.addPushButton(self.m_toolbarPanel, Icons.justifyright_icon, "Justify Right") self.m_hrW = self.addPushButton(self.m_toolbarPanel, Icons.horizontalrule_icon, "Horizontal Rule") self.m_olW = self.addPushButton(self.m_toolbarPanel, Icons.numberedlist_icon, "Numbered List") self.m_ulW = self.addPushButton(self.m_toolbarPanel, Icons.list_icon, "List") self.m_newLinkW = self.addPushButton(self.m_toolbarPanel, Icons.link_icon, "Link Document") self.m_removeFormatW = self.addPushButton(self.m_toolbarPanel, Icons.noformat_icon, "No Format") self.m_mainPanel.add(self.m_toolbarPanel, DockPanel.NORTH) self.m_mainPanel.add(self.m_textW, DockPanel.CENTER) self.initWidget(self.m_mainPanel) self.sinkEvents(Event.ONCLICK) def getFormatter(self): return self.m_textW.getExtendedFormatter() def getRichTextArea(self): return self.m_textW def addPushButton(self, panel, imagep, tip): img = Image(imagep) img.setWidth("20px") img.setHeight("20px") pb = PushButton(img) self.addAnyButton(panel, pb, tip) return pb def addToggleButton(self, panel, imagep, tip): img = Image(imagep) img.setWidth("20px") img.setHeight("20px") tb = ToggleButton(img) self.addAnyButton(panel, tb, tip) return tb def addAnyButton(self, panel, button, tip): button.addStyleName("richText-button") button.setTitle(tip) button.setWidth(BUTTON_WIDTH) button.setHeight("100%") panel.add(button) panel.setCellWidth(button, BUTTON_WIDTH) button.addClickListener(self) def onClick(self, sender): if sender == self.m_boldW: self.m_formatter.toggleBold() elif sender == self.m_italicW: self.m_formatter.toggleItalic() elif sender == self.m_underlineW: self.m_formatter.toggleUnderline() elif sender == self.m_subscriptW: self.m_formatter.toggleSubscript() elif sender == self.m_superscriptW: self.m_formatter.toggleSuperscript() elif sender == self.m_strikethroughW: self.m_formatter.toggleStrikethrough() elif sender == self.m_indentW: self.m_formatter.rightIndent() elif sender == self.m_outdentW: self.m_formatter.leftIndent() elif sender == self.m_justifyLeftW: self.m_formatter.setJustification(RichTextArea.Justification.LEFT) elif sender == self.m_justifyCenterW: self.m_formatter.setJustification( RichTextArea.Justification.CENTER) elif sender == self.m_justifyRightW: self.m_formatter.setJustification(RichTextArea.Justification.RIGHT) elif sender == self.m_hrW: self.m_formatter.insertHorizontalRule() elif sender == self.m_olW: self.m_formatter.insertOrderedList() elif sender == self.m_ulW: self.m_formatter.insertUnorderedList() elif sender == self.m_removeFormatW: self.m_formatter.removeFormat() elif sender == self.m_newLinkW: EventLinkPopup.open(self) elif sender == self.m_textW: self.updateStatus() self.checkForChange() def onKeyDown(self, sender, keycode, modifiers): pass def onKeyUp(self, sender, keycode, modifiers): if sender == self.m_textW: self.updateStatus() self.checkForChange() def onMouseLeave(self, event): pass def onMouseEnter(self, event): pass def onMouseUp(self, event, x, y): pass def onMouseMove(self, event, x, y): pass def onMouseDown(self, event, x, y): self.trigger = True def onFocus(self, event): pass def onLostFocus(self, event): self.checkForChange() def onMouseOut(self, event): if self.m_isInText and self.isOnTextBorder(event): self.m_isInText = False self.captureSelection() self.endSelTimer() def onMouseOver(self, event): if not self.m_isInText: self.m_isInText = True self.m_textW.setFocus(True) self.m_lastRange = None self.startSelTimer() """* * This captures the selection when the mouse leaves the RTE, because in IE * the selection indicating the cursor position is lost once another widget * gains focus. Could be implemented for IE only. """ def captureSelection(self): try: self.getSelection() self.m_lastRange = Selection.getRange() except: GWT.log("Error capturing selection for IE", ex) # Gets run every time the selection is changed def onSelectionChange(self, sel): pass def isOnTextBorder(self, event): sender = event.getSource() twX = self.m_textW.getAbsoluteLeft() twY = self.m_textW.getAbsoluteTop() x = event.getClientX() - twX y = event.getClientY() - twY width = self.m_textW.getOffsetWidth() height = self.m_textW.getOffsetHeight() return ((sender == self.m_textW) and ((x <= 0) or (x >= width) or (y <= 0) or (y >= height))) def startSelTimer(self): self.m_selTimer.scheduleRepeating(250) def endSelTimer(self): self.m_selTimer.cancel() def getRange(self): if self.m_lastRange is None: self.getSelection() return Selection.getRange() else: return self.m_lastRange def getSelection(self): res = None try: window = self.getWindow() Selection.getSelection(window) except: print "Error getting the selection" traceback.print_exc() def getWindow(self, iFrame=None): if iFrame is None: iFrame = self.m_textW.getElement() iFrameWin = iFrame.contentWindow or iFrame.contentDocument if not iFrameWin.document: iFrameWin = iFrameWin.parentNode # FBJS version of parentNode #print "getWindow", iFrameWin, dir(iFrameWin) return iFrameWin def getDocument(self): return Selection.getDocument(self.getWindow()) def setHtml(self, text): self.m_textW.setHTML(text) self.m_lastText = text def getHtml(self): return self.m_textW.getHTML() def checkForChange(self): text = self.m_textW.getHTML() if text != self.m_lastText: nEvt = doc().createEvent("HTMLEvents") nEvt.initEvent("change", False, True) self.getElement().dispatchEvent(nEvt) self.m_lastText = text # Update edit buttons based on current cursor location def updateStatus(self): if self.m_formatter is None: return self.m_boldW.setDown(self.m_formatter.isBold()) self.m_italicW.setDown(self.m_formatter.isItalic()) self.m_underlineW.setDown(self.m_formatter.isUnderlined()) self.m_subscriptW.setDown(self.m_formatter.isSubscript()) self.m_superscriptW.setDown(self.m_formatter.isSuperscript()) self.m_strikethroughW.setDown(self.m_formatter.isStrikethrough()) def addChangeHandler(self, handler): return addDomHandler(handler, ChangeEvent.getType())
class StockWatcher: def onModuleLoad(self): ''' This is the main entry point method. ''' # Setup JSON RPC self.remote = DataService() # Initialize member variables self.mainPanel = VerticalPanel() self.stocksFlexTable = FlexTable() self.addPanel = HorizontalPanel() self.newSymbolTextBox = TextBox() self.lastUpdatedLabel = Label() self.addStockButton = Button('Add', self.addStock) self.stocks = [] self.stocksTableColumns = ['Symbol', 'Price', 'Change', 'Remove'] # Add styles to elements in the stock list table self.stocksFlexTable.getRowFormatter().addStyleName(0, 'watchListHeader') self.stocksFlexTable.addStyleName('watchList') self.stocksFlexTable.getCellFormatter().addStyleName(0, 1, 'watchListNumericColumn') self.stocksFlexTable.getCellFormatter().addStyleName(0, 2, 'watchListNumericColumn') self.stocksFlexTable.getCellFormatter().addStyleName(0, 3, 'watchListRemoveColumn') # Create table for stock data for i in range(len(self.stocksTableColumns)): self.stocksFlexTable.setText(0, i, self.stocksTableColumns[i]) # Assemble Add Stock panel self.addPanel.add(self.newSymbolTextBox) self.addPanel.add(self.addStockButton) self.addPanel.addStyleName('addPanel') # Assemble Main panel self.mainPanel.add(self.stocksFlexTable) self.mainPanel.add(self.addPanel) self.mainPanel.add(self.lastUpdatedLabel) # Associate the Main panel with the HTML host page RootPanel().add(self.mainPanel) # Move cursor focus to the input box self.newSymbolTextBox.setFocus(True) # Setup timer to refresh list automatically refresh = self.refreshWatchlist class MyTimer(Timer): def run(self): refresh() refreshTimer = MyTimer() refreshTimer.scheduleRepeating(5000) # Listen for keyboard events in the input box self_addStock = self.addStock class StockTextBox_KeyboardHandler(): def onKeyPress(self, sender, keycode, modifiers): if keycode == KEY_ENTER: self_addStock() def onKeyDown(self, sender, keycode, modifiers): return def onKeyUp(self, sender, keycode, modifiers): return self.newSymbolTextBox.addKeyboardListener(StockTextBox_KeyboardHandler()) # Load the stocks self.remote.getStocks(self) def addStock(self, sender, symbol=None): ''' Add stock to FlexTable. Executed when the user clicks the addStockButton or presses enter in the newSymbolTextBox ''' if symbol is None: # Get the symbol symbol = self.newSymbolTextBox.getText().upper().trim() self.newSymbolTextBox.setText('') # Don't add the stock if it's already in the table if symbol in self.stocks: return # Tell the server that we're adding this stock self.remote.addStock(symbol, self) self.newSymbolTextBox.setFocus(True) # Stocks code must be between 1 and 10 chars that are numbers/letters/dots p = re.compile('^[0-9A-Z\\.]{1,10}$') if p.match(symbol) == None: Window.alert('"%s" is not a valid symbol.' % symbol) self.newSymbolTextBox.selectAll() return # Add the stock to the table row = self.stocksFlexTable.getRowCount() self.stocks.append(symbol) self.stocksFlexTable.setText(row, 0, symbol) self.stocksFlexTable.setWidget(row, 2, Label()) self.stocksFlexTable.getCellFormatter().addStyleName(row, 1, 'watchListNumericColumn') self.stocksFlexTable.getCellFormatter().addStyleName(row, 2, 'watchListNumericColumn') self.stocksFlexTable.getCellFormatter().addStyleName(row, 3, 'watchListRemoveColumn') # Add a button to remove this stock from the table def _removeStockButton_Click(event): if symbol not in self.stocks: return removedIndex = self.stocks.index(symbol) self.remote.deleteStock(symbol, self) self.stocks.remove(symbol) self.stocksFlexTable.removeRow(removedIndex + 1) removeStockButton = Button('x', _removeStockButton_Click) removeStockButton.addStyleDependentName('remove') self.stocksFlexTable.setWidget(row, 3, removeStockButton) # Get the stock price self.refreshWatchlist() def refreshWatchlist(self): ''' Update the price change for each stock ''' MAX_PRICE = 100.0 MAX_PRICE_CHANGE = 0.02 prices = [] for i in range(len(self.stocks)): price = random.random() * MAX_PRICE change = price * MAX_PRICE_CHANGE * (random.random() * 2.0 - 1.0) prices.append(StockPrice(self.stocks[i], price, change)) self.updateTable(prices) def updateTable(self, prices): ''' Update the price and change fields of all the rows in the stock table prices -- List of StockPrice objects for all rows ''' # Type checking assert isinstance(prices, list) for price in prices: assert isinstance(price, StockPrice) # Nothing to do... if len(prices) == 0: return # Update each individual row for i in range(len(prices)): self.updateRow(prices[i]) # Display timestamp showing last refresh self.lastUpdatedLabel.setText("Last update: %s" % datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p")) def updateRow(self, price): ''' Update a single row in the stock table price -- StockPrice object for a single row ''' # Type checking assert isinstance(price, StockPrice) # Make sure the stock is still in the stock table if price.symbol not in self.stocks: return # Find the index of row = self.stocks.index(price.symbol) + 1 # Populate the price and change fields with new data self.stocksFlexTable.setText(row, 1, '%.2f' % price.price) changeWidget = self.stocksFlexTable.getWidget(row, 2) changeWidget.setText('%.2f (%.2f%%)' % (price.change, price.getChangePercent())) # Change the color of the text in the Change field based on its value changeStyleName = 'noChange' if price.getChangePercent() < -0.1: changeStyleName = 'negativeChange' else: changeStyleName = 'positiveChange' changeWidget.setStyleName(changeStyleName) def onRemoteResponse(self, response, request_info): ''' Called when a response is received from a RPC. ''' if request_info.method in DataService.methods: # Compare self.stocks and the stocks in response stocks_set = set(self.stocks) response_set = set(response) # Add the differences for symbol in list(response_set.difference(stocks_set)): self.addStock(None, symbol) else: Window.alert('Unrecognized JSONRPC method.') def onRemoteError(self, code, message, request_info): Window.alert(message)
class MovieRatings: def onModuleLoad(self): # Setup JSON RPC self.remote = DataService() ### Initialize member variables self.mainPanel = HorizontalPanel() self.rightPanel = VerticalPanel() self.moviesPanel = VerticalPanel() self.topRatedPanel = VerticalPanel() self.categoriesPanel = VerticalPanel() self.moviesFlexTable = FlexTable() self.topRatedMoviesFlexTable = FlexTable() self.topCategoryMoviesFlexTable = FlexTable() self.lessThanFiveLabel = Label('There are less than 5 movies. Add more movies!') self.moviesListLabel = Label('Movies List') self.addPanel = VerticalPanel() self.newMovieCategoryTextBox = TextBox() self.newMovieNameTextBox = TextBox() self.newMovieRatingListBox = ListBox(False) self.addMovieButton = Button('Add', self.addMovieButton_Click) self.movies = [] self.topRatedMovies = [] self.categories = {} self.MAX_RATING = 10 ### Add Movie Panel # Add ratings to list box for i in range(self.MAX_RATING + 1): self.newMovieRatingListBox.addItem(str(i)) # Add label and textbox to horizontal panel self.labelPanel = HorizontalPanel() self.labelPanel.add(Label("Add a movie:")) self.categoryPanel = HorizontalPanel() self.categoryPanel.add(Label("Category: ")) self.categoryPanel.add(self.newMovieCategoryTextBox) self.namePanel = HorizontalPanel() self.namePanel.add(Label("Movie Name: ")) self.namePanel.add(self.newMovieNameTextBox) self.ratingPanel = HorizontalPanel() self.ratingPanel.add(Label("Movie Rating: ")) self.ratingPanel.add(self.newMovieRatingListBox) self.labelPanel.addStyleName("addLabel") self.labelPanel.setSpacing(5) self.categoryPanel.addStyleName("addPanel") self.categoryPanel.setSpacing(5) self.namePanel.addStyleName("addPanel") self.namePanel.setSpacing(5) self.ratingPanel.addStyleName("addPanel") self.ratingPanel.setSpacing(5) self.newMovieCategoryTextBox.addStyleName("addPanel-input") self.newMovieNameTextBox.addStyleName("addPanel-input") self.newMovieRatingListBox.addStyleName("addPanel-input") self.addPanel.add(self.labelPanel) self.addPanel.add(self.categoryPanel) self.addPanel.add(self.namePanel) self.addPanel.add(self.ratingPanel) self.addPanel.add(self.addMovieButton) self.addPanel.addStyleName("addPanel") self.addMovieButton.addStyleName('addButton') self.addPanel.add(self.addMovieButton) self.addPanel.addStyleName('addPanel') ### Movies table self.moviesFlexTable.setText(0, 1, "Category") self.moviesFlexTable.setText(0, 2, "Title") self.moviesFlexTable.setText(0, 3, "Rating") self.moviesFlexTable.addStyleName("movieList") self.moviesFlexTable.getRowFormatter().addStyleName(0, "listHeader") self.moviesFlexTable.setCellPadding(6) self.moviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn") self.moviesFlexTable.getCellFormatter().setStyleName(0, 2, "listHeaderColumn") self.moviesListLabel.addStyleName("listLabel") self.moviesPanel.add(self.moviesListLabel) self.moviesPanel.add(self.moviesFlexTable) self.moviesPanel.setStyleName("moviesPanel") ### Top rated movies table self.topRatedMoviesFlexTable.setText(0, 0, "Category") self.topRatedMoviesFlexTable.setText(0, 1, "Title") self.topRatedMoviesFlexTable.setText(0, 2, "Rating") self.topRatedMoviesFlexTable.addStyleName("topMoviesList") self.topRatedMoviesFlexTable.getRowFormatter().addStyleName(0, "listHeader") self.topRatedMoviesFlexTable.setCellPadding(6) self.topRatedMoviesFlexTable.getCellFormatter().setStyleName(0, 0, "listHeaderColumn") self.topRatedMoviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn") self.topRatedLabel = Label("Top 5 Rated Movies") self.topRatedLabel.addStyleName("listLabel") self.lessThanFiveLabel.addStyleName("noticeLabel") self.topRatedPanel.add(self.topRatedLabel) self.topRatedPanel.add(self.topRatedMoviesFlexTable) self.topRatedPanel.add(self.lessThanFiveLabel) self.topRatedPanel.setStyleName("topRatedPanel") ### Categories table self.topCategoryMoviesFlexTable.setText(0, 0, "Category") self.topCategoryMoviesFlexTable.setText(0, 1, "Top Movie") self.topCategoryMoviesFlexTable.setText(0, 2, "Average Rating") self.topCategoryMoviesFlexTable.addStyleName("topCategoryMoviesList") self.topCategoryMoviesFlexTable.getRowFormatter().addStyleName(0, "listHeader") self.topCategoryMoviesFlexTable.setCellPadding(6) self.topCategoryMoviesFlexTable.getCellFormatter().setStyleName(0, 0, "listHeaderColumn") self.topCategoryMoviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn") self.categoriesLabel = Label("Movie Categories") self.categoriesLabel.addStyleName("listLabel") self.categoriesPanel.add(self.categoriesLabel) self.categoriesPanel.add(self.topCategoryMoviesFlexTable) self.categoriesPanel.setStyleName("categoriesPanel") ### Assemble Main panel self.rightPanel.add(self.topRatedPanel) self.rightPanel.add(self.categoriesPanel) self.mainPanel.add(self.moviesPanel) self.mainPanel.add(self.rightPanel) self.mainPanel.setStyleName("mainPanel") self.mainPanel.setSpacing(25) # Associate panels with the HTML host page RootPanel('addPanel').add(self.addPanel) RootPanel('main').add(self.mainPanel) # Move cursor focus to the input box self.newMovieNameTextBox.setFocus(True) # Load the movies self.remote.getMovies(self) def verifyInputs(self, name, category): if len(name) == 0: Window.alert("Movie name cannot be empty.") return False if len(name) > 100: Window.alert("Movie name is too long. Maximum length is 100 characters.") return False if len(category) == 0: Window.alert("Category cannot be empty.") return False p = re.compile('^[0-9A-Za-z\\.\\-\\(\\) ]{1,100}$') if p.match(category) == None: Window.alert('"%s" is not a valid category.' % category) return False return True def addMovieButton_Click(self, event): name = self.newMovieNameTextBox.getText().trim() cat = self.newMovieCategoryTextBox.getText().trim().lower() category = cat[0].upper() + cat[1:] rating = self.newMovieRatingListBox.getSelectedIndex() if not self.verifyInputs(name, category): return movie = Movie(name, category, rating) if movie in self.movies: Window.alert("'" + name + "' is already in table.") self.newMovieNameTextBox.selectAll() return self.remote.addMovie((name, category, rating), self) self.newMovieNameTextBox.setText('') def addMovie(self, sender, movie): self.movies.append(movie) row = self.moviesFlexTable.getRowCount() self.moviesFlexTable.setText(row, 1, movie.category) self.moviesFlexTable.setText(row, 2, movie.name) self.moviesFlexTable.setText(row, 3, movie.rating) # Adds buttons for remove, edit, save and cancel removeMovieButton = Button("x") editMovieButton = Button("Edit") saveButton = Button("Save") cancelButton = Button("Cancel") # Save and cancel are hidden by default saveButton.setVisible(False) cancelButton.setVisible(False) # Add buttons to row buttons = HorizontalPanel() buttons.add(removeMovieButton) buttons.add(editMovieButton) buttons.add(cancelButton) buttons.add(saveButton) self.moviesFlexTable.setWidget(row, 0, buttons) def removeMovieButton_Click(sender): self.remote.deleteMovie((movie.name, movie.category), self) removeMovieButton.addClickListener(removeMovieButton_Click) def editMovieButton_Click(sender): # Add textboxes and listbox editMovieButton.setVisible(False) cancelButton.setVisible(True) saveButton.setVisible(True) editCategory = TextBox() editName = TextBox() editRating = ListBox(False) for i in range(self.MAX_RATING + 1): editRating.addItem(str(i)) # Variable width textboxes catlen = len(movie.category) namelen = len(movie.name) if (catlen > 8): editCategory.setWidth(str(catlen*10) + "px") else: editCategory.setWidth("80px") if (namelen > 8): editName.setWidth(str(namelen*10) + "px") else: editName.setWidth("80px") self.moviesFlexTable.setWidget(row, 1, editCategory) self.moviesFlexTable.setWidget(row, 2, editName) self.moviesFlexTable.setWidget(row, 3, editRating) editCategory.setText(movie.category) editName.setText(movie.name) editRating.setSelectedIndex(movie.rating) editMovieButton.addClickListener(editMovieButton_Click) def saveButton_Click(sender): catText = self.moviesFlexTable.getWidget(row, 1) nameText = self.moviesFlexTable.getWidget(row, 2) ratingList = self.moviesFlexTable.getWidget(row, 3) newCategory = catText.getText().trim().lower() newCategory = newCategory[0].upper() + newCategory[1:] newName = nameText.getText().trim() newRating = ratingList.getSelectedIndex() if not self.verifyInputs(newName, newCategory): return # Removes temporarily to check for duplicates self.movies.remove(movie) newMovie = Movie(newName, newCategory, newRating) if newMovie in self.movies: Window.alert("'" + newName + "' is already in table.") nameText.selectAll() return self.remote.editMovie((movie.name, movie.category), (newMovie.name, newMovie.category, newMovie.rating), self) saveButton.addClickListener(saveButton_Click) def cancelButton_Click(sender): self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 1)) self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 2)) self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 3)) # Reverts fields to old movie info self.moviesFlexTable.setText(row, 1, movie.category) self.moviesFlexTable.setText(row, 2, movie.name) self.moviesFlexTable.setText(row, 3, movie.rating) cancelButton.setVisible(False) saveButton.setVisible(False) editMovieButton.setVisible(True) cancelButton.addClickListener(cancelButton_Click) def updateTopRatedMovies(self): numTopRated = len(self.topRatedMovies) self.clearTable(self.topRatedMoviesFlexTable) for row in range(numTopRated): self.topRatedMoviesFlexTable.setText(row+1, 0, self.topRatedMovies[row].category) self.topRatedMoviesFlexTable.setText(row+1, 1, self.topRatedMovies[row].name) self.topRatedMoviesFlexTable.setText(row+1, 2, self.topRatedMovies[row].rating) # Label should only be visible if less than 5 movies self.lessThanFiveLabel.setVisible(numTopRated < 5) def updateCategories(self): self.clearTable(self.topCategoryMoviesFlexTable) for row, cat in enumerate(self.categories): self.topCategoryMoviesFlexTable.setText(row+1, 0, cat + " (" + str(self.categories[cat][2]) + ")") self.topCategoryMoviesFlexTable.setText(row+1, 1, self.categories[cat][0]) self.topCategoryMoviesFlexTable.setText(row+1, 2, "%.1f" % float(self.categories[cat][1])) def clearTable(self, table): try: for i in range(table.getRowCount()): table.removeRow(1) except: pass # Called when a response is received from a RPC. def onRemoteResponse(self, response, request_info): if request_info.method in ['getMovies', 'addMovie', 'deleteMovie', 'editMovie']: # Clear current and add all self.movies = [] self.clearTable(self.moviesFlexTable) for m in response: movie = Movie(m[0], m[1], m[2]) self.addMovie(None, movie) self.moviesListLabel.setText("Movies List (" + str(len(self.movies)) + ")") self.remote.getTopRated(self) self.remote.getCategories(self) if request_info.method == 'getTopRated': # Update top rated self.topRatedMovies = [] for m in response: movie = Movie(m[0], m[1], m[2]) self.topRatedMovies.append(movie) self.updateTopRatedMovies() if request_info.method == 'getCategories': # Update categories self.categories = response self.updateCategories()
def drawFull(self, month, year): # should be called only once when we draw the calendar for # the first time self.vp = VerticalPanel() self.vp.setSpacing(0) self.vp.setPadding(0) self.vp.addStyleName("calendarbox calendar-module calendar") self.setWidget(self.vp) self.setVisible(False) # mth = int(month) yr = int(year) tp = HorizontalPanel(Width="100%") tp.addStyleName("calendar-top-panel") tp.setSpacing(0) tp.setPadding(0) self.h1 = None self.h2 = None self.h4 = None self.h5 = None if self.backyear: self.h1 = self.bkls(self.backyear, StyleName="calendar-arrows") self.h1.addClickListener(getattr(self, 'onPreviousYear')) tp.add(self.h1) tp.setCellHorizontalAlignment(self.h1, "left") if self.backmonth: self.h2 = self.bkls(self.backmonth, StyleName="calendar-arrows") self.h2.addClickListener(getattr(self, 'onPreviousMonth')) tp.add(self.h2) tp.setCellHorizontalAlignment(self.h2, "left") # titlePanel can be changed, whenever we draw, so keep the reference txt = "<b>" txt += self.getMonthsOfYear()[mth-1] + " " + str(yr) txt += "</b>" self.titlePanel = SimplePanel() self.titlePanel.setWidget(HTML(txt)) self.titlePanel.setStyleName("calendar-center") tp.add(self.titlePanel) tp.setCellHorizontalAlignment(self.titlePanel, "center") tp.setCellWidth(self.titlePanel, "100%") if self.fwdmonth: self.h4 = self.bkls(self.fwdmonth, StyleName="calendar-arrows") self.h4.addClickListener(getattr(self, 'onNextMonth')) tp.add(self.h4) tp.setCellHorizontalAlignment(self.h4, "right") tp.setCellWidth(self.h4, "100%") self.h4.setWidth("100%") if self.fwdyear: self.h5 = self.bkls(self.fwdyear, StyleName="calendar-arrows") self.h5.addClickListener(getattr(self, 'onNextYear')) tp.add(self.h5) tp.setCellHorizontalAlignment(self.h5, "right") tvp = VerticalPanel(Width="100%") tvp.setSpacing(2) tvp.add(tp) self.vp.add(tvp) # done with top panel self.middlePanel = SimplePanel() grid = self.drawGrid(mth, yr) self.middlePanel.setWidget(grid) self.vp.add(self.middlePanel) self.defaultGrid = grid if self.addbuttons: # # some links & handlers # bh1 = Hyperlink(self.yesterday) bh1.addClickListener(getattr(self, 'onYesterday')) bh2 = Hyperlink(self.today) bh2.addClickListener(getattr(self, 'onToday')) bh3 = Hyperlink(self.tomorrow) bh3.addClickListener(getattr(self, 'onTomorrow')) bh4 = Hyperlink(self.cancel) bh4.addClickListener(getattr(self, 'onCancel')) # # add code to test another way of doing the layout # b = HorizontalPanel() b.add(bh1) b.add(bh2) b.add(bh3) b.addStyleName("calendar-shortcuts") self.vp.add(b) b2 = SimplePanel() b2.add(bh4) b2.addStyleName("calendar-cancel") self.vp.add(b2) self.checkLinks(mth, yr) self.setVisible(True)
class RichTextEditor(Composite): def run(self): try: self.getSelection() rng = Selection.getRange() if (self.m_timerRange is None) or (not self.m_timerRange.equals(rng)): self.onSelectionChange(rng) self.m_timerRange = rng except: GWT.log("Error in timer selection", ex) def __init__(self): Composite.__init__(self) self.m_isInText = False self.m_lastText = "" self.trigger = False self.m_lastRange = None # Timer for trying real time selection change stuff self.m_timerRange = None self.m_selTimer = Timer() self.m_mainPanel = DockPanel() self.m_toolbarPanel = HorizontalPanel() self.m_toolbarPanel.setWidth("100%") self.m_toolbarPanel.setHeight("25px") self.m_toolbarPanel.setBorderWidth(1) self.m_toolbarPanel.addStyleName("timeline-RichTextToolbar") self.m_textW = RichTextArea() self.m_textW.addClickListener(self) self.m_textW.addKeyboardListener(self) self.m_textW.addFocusListener(self) self.m_textW.addMouseListener(self) # According to gwt doc, these do need to be set because this is a frame self.m_textW.setHeight("100%") self.m_textW.setWidth("100%") # Add buttons self.m_formatter = self.getFormatter() self.m_boldW = self.addToggleButton(self.m_toolbarPanel, Icons.bold_icon, "Bold") self.m_italicW = self.addToggleButton(self.m_toolbarPanel, Icons.italics_icon, "Italic") self.m_underlineW = self.addToggleButton(self.m_toolbarPanel, Icons.underline_icon, "Underline") self.m_subscriptW = self.addToggleButton(self.m_toolbarPanel, Icons.subscript_icon, "Subscript") self.m_superscriptW = self.addToggleButton(self.m_toolbarPanel, Icons.superscript_icon, "Superscript") self.m_strikethroughW = self.addToggleButton(self.m_toolbarPanel, Icons.strikethrough_icon, "Strikethrough") self.m_indentW = self.addPushButton(self.m_toolbarPanel, Icons.indentmore_icon, "Indent Right") self.m_outdentW = self.addPushButton(self.m_toolbarPanel, Icons.indentless_icon, "Indent Left") self.m_justifyLeftW = self.addPushButton(self.m_toolbarPanel, Icons.justifyleft_icon, "Justify Left") self.m_justifyCenterW = self.addPushButton(self.m_toolbarPanel, Icons.justifycenter_icon, "Justify Center") self.m_justifyRightW = self.addPushButton(self.m_toolbarPanel, Icons.justifyright_icon, "Justify Right") self.m_hrW = self.addPushButton(self.m_toolbarPanel, Icons.horizontalrule_icon, "Horizontal Rule") self.m_olW = self.addPushButton(self.m_toolbarPanel, Icons.numberedlist_icon, "Numbered List") self.m_ulW = self.addPushButton(self.m_toolbarPanel, Icons.list_icon, "List") self.m_newLinkW = self.addPushButton(self.m_toolbarPanel, Icons.link_icon, "Link Document") self.m_removeFormatW = self.addPushButton(self.m_toolbarPanel, Icons.noformat_icon, "No Format") self.m_mainPanel.add(self.m_toolbarPanel, DockPanel.NORTH) self.m_mainPanel.add(self.m_textW, DockPanel.CENTER) self.initWidget(self.m_mainPanel) self.sinkEvents(Event.ONCLICK) def getFormatter(self): return self.m_textW.getExtendedFormatter() def getRichTextArea(self): return self.m_textW def addPushButton(self, panel, imagep, tip): img = Image(imagep) img.setWidth("20px") img.setHeight("20px") pb = PushButton(img) self.addAnyButton(panel, pb, tip) return pb def addToggleButton(self, panel, imagep, tip): img = Image(imagep) img.setWidth("20px") img.setHeight("20px") tb = ToggleButton(img) self.addAnyButton(panel, tb, tip) return tb def addAnyButton(self, panel, button, tip): button.addStyleName("richText-button") button.setTitle(tip) button.setWidth(BUTTON_WIDTH) button.setHeight("100%") panel.add(button) panel.setCellWidth(button, BUTTON_WIDTH) button.addClickListener(self) def onClick(self, sender): if sender == self.m_boldW: self.m_formatter.toggleBold() elif sender == self.m_italicW: self.m_formatter.toggleItalic() elif sender == self.m_underlineW: self.m_formatter.toggleUnderline() elif sender == self.m_subscriptW: self.m_formatter.toggleSubscript() elif sender == self.m_superscriptW: self.m_formatter.toggleSuperscript() elif sender == self.m_strikethroughW: self.m_formatter.toggleStrikethrough() elif sender == self.m_indentW: self.m_formatter.rightIndent() elif sender == self.m_outdentW: self.m_formatter.leftIndent() elif sender == self.m_justifyLeftW: self.m_formatter.setJustification(RichTextArea.Justification.LEFT) elif sender == self.m_justifyCenterW: self.m_formatter.setJustification(RichTextArea.Justification.CENTER) elif sender == self.m_justifyRightW: self.m_formatter.setJustification(RichTextArea.Justification.RIGHT) elif sender == self.m_hrW: self.m_formatter.insertHorizontalRule() elif sender == self.m_olW: self.m_formatter.insertOrderedList() elif sender == self.m_ulW: self.m_formatter.insertUnorderedList() elif sender == self.m_removeFormatW: self.m_formatter.removeFormat() elif sender == self.m_newLinkW: EventLinkPopup.open(self) elif sender == self.m_textW: self.updateStatus() self.checkForChange() def onKeyDown(self, sender, keycode, modifiers): pass def onKeyUp(self, sender, keycode, modifiers): if sender == self.m_textW: self.updateStatus() self.checkForChange() def onMouseLeave(self, event): pass def onMouseEnter(self, event): pass def onMouseUp(self, event, x, y): pass def onMouseMove(self, event, x, y): pass def onMouseDown(self, event, x, y): self.trigger = True def onFocus(self, event): pass def onLostFocus(self, event): self.checkForChange() def onMouseOut(self, event): if self.m_isInText and self.isOnTextBorder(event): self.m_isInText = False self.captureSelection() self.endSelTimer() def onMouseOver(self, event): if not self.m_isInText: self.m_isInText = True self.m_textW.setFocus(True) self.m_lastRange = None self.startSelTimer() """* * This captures the selection when the mouse leaves the RTE, because in IE * the selection indicating the cursor position is lost once another widget * gains focus. Could be implemented for IE only. """ def captureSelection(self): try: self.getSelection() self.m_lastRange = Selection.getRange() except: GWT.log("Error capturing selection for IE", ex) # Gets run every time the selection is changed def onSelectionChange(self, sel): pass def isOnTextBorder(self, event): sender = event.getSource() twX = self.m_textW.getAbsoluteLeft() twY = self.m_textW.getAbsoluteTop() x = event.getClientX() - twX y = event.getClientY() - twY width = self.m_textW.getOffsetWidth() height = self.m_textW.getOffsetHeight() return ((sender == self.m_textW) and ((x <= 0) or (x >= width) or (y <= 0) or (y >= height))) def startSelTimer(self): self.m_selTimer.scheduleRepeating(250) def endSelTimer(self): self.m_selTimer.cancel() def getRange(self): if self.m_lastRange is None: self.getSelection() return Selection.getRange() else: return self.m_lastRange def getSelection(self): res = None try: window = self.getWindow() Selection.getSelection(window) except: print "Error getting the selection" traceback.print_exc() def getWindow(self, iFrame=None): if iFrame is None: iFrame = self.m_textW.getElement() iFrameWin = iFrame.contentWindow or iFrame.contentDocument if not iFrameWin.document: iFrameWin = iFrameWin.parentNode # FBJS version of parentNode #print "getWindow", iFrameWin, dir(iFrameWin) return iFrameWin def getDocument(self): return Selection.getDocument(self.getWindow()) def setHtml(self, text): self.m_textW.setHTML(text) self.m_lastText = text def getHtml(self): return self.m_textW.getHTML() def checkForChange(self): text = self.m_textW.getHTML() if text != self.m_lastText: nEvt = doc().createEvent("HTMLEvents") nEvt.initEvent("change", False, True) self.getElement().dispatchEvent(nEvt) self.m_lastText = text # Update edit buttons based on current cursor location def updateStatus(self): if self.m_formatter is None: return self.m_boldW.setDown(self.m_formatter.isBold()) self.m_italicW.setDown(self.m_formatter.isItalic()) self.m_underlineW.setDown(self.m_formatter.isUnderlined()) self.m_subscriptW.setDown(self.m_formatter.isSubscript()) self.m_superscriptW.setDown(self.m_formatter.isSuperscript()) self.m_strikethroughW.setDown(self.m_formatter.isStrikethrough()) def addChangeHandler(self, handler): return addDomHandler(handler, ChangeEvent.getType())