BloGTK.py :  » GUI » BloGTK » BloGTK-1.1 » src » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » BloGTK 
BloGTK » BloGTK 1.1 » src » BloGTK.py
#!/usr/bin/env python

# BloGTK Version 1.1
# (C)2004 Jay Reding
# Code released under the terms of the BSD License. (See file LICENSE)
# This program allows users to post to various weblog systems without starting a
# web browser.

import pygtk
pygtk.require("2.0") # This fixes a problem that sometimes causes an earlier 
                     # library to be loaded
import gtk
import gtk.glade
import gtkhtml2
import pango
import gobject
import os
import ConfigParser
import cPickle
import sys
import string
import xmlrpclib

# Import modules from the BloGTK app tree.
import config
import post
import customtags
import preview
import spellcheck
import proxy

# 0.5-1 - Python 2.3 doesn't like values named None as arguments. Hence, I will 
# be a smart-ass and replace 'None' with 'foo'

foo = 0

# 1.1 - I should also make a global variable for the version number so that I don't
# have to constantly be changing strings.

version = "1.1"

class BloGTK:

   def delete_event(self, widget, event, data=None):
      return gtk.FALSE

   def destroy(self, widget, data=None):
      gtk.main_quit()

   def displayPrefs(self, widget):

      # 0.7 - Here's where we do the new preferences code...
      prefsInstance = config.blogtkPrefs()
      prefsInstance.drawPrefs(self.mainGlade, foo)

      # 0.3 - When we load the prefs we want to ensure that the user must 
      # reconnect with the new prefs before posting.
      self.postButton.set_sensitive(gtk.FALSE)

      # 0.9 - We also ensure that the title entry must be explictly reactivated 
      # for MetaWeblog or MT users.
      self.titleEntry.set_sensitive(gtk.FALSE)

      # 0.9 - We should also make it clear that when you pop up the preferences 
      # window you disconnect from the server.
      self.mainStatus.push(1, "Disconnected from server. Use File/Connect to re-connect")

      # 0.95 - And you can't retrieve a post list while disconnected... DUH!
      self.recallMenuOption.set_sensitive(gtk.FALSE)
      # 0.95 - We also need to disable our other entry systems.
      self.titleEntry.set_sensitive(gtk.FALSE)
      self.extendedView.set_sensitive(gtk.FALSE)
      self.excerptView.set_sensitive(gtk.FALSE)
      self.commentsCheck.set_sensitive(gtk.FALSE)
      self.pingsCheck.set_sensitive(gtk.FALSE)
      self.breaksCheck.set_sensitive(gtk.FALSE)
      self.keywordEntry.set_sensitive(gtk.FALSE)
      self.trackbackEntry.set_sensitive(gtk.FALSE)

   def __init__(self):

     # Open the glade file doors, Hal!
      self.mainGlade = gtk.glade.XML('/usr/share/blogtk/blogtk.glade')
      self.mainWindow = self.mainGlade.get_widget('mainWindow')

      # Let's grab some widgets for later editing/manipulating/inappropriate fondling
      self.blogCombo = self.mainGlade.get_widget('blogCombo')
      self.titleEntry = self.mainGlade.get_widget('titleEntry')
      self.bodyView = self.mainGlade.get_widget('bodyView')
      self.publishCheck = self.mainGlade.get_widget('publishCheck')
      self.catCombo = self.mainGlade.get_widget('catCombo')
      self.mainStatus = self.mainGlade.get_widget('mainStatus')
      self.postButton = self.mainGlade.get_widget('postButton')
      self.postsWindow = self.mainGlade.get_widget('recallDialog')
      self.editPostsItem = self.mainGlade.get_widget('recall1')
      self.mainStatus = self.mainGlade.get_widget('mainStatus')
      self.recallMenuOption = self.mainGlade.get_widget('recall1')
      self.extendedView = self.mainGlade.get_widget('extendedView')
      self.excerptView = self.mainGlade.get_widget('excerptView')
      self.keywordEntry = self.mainGlade.get_widget('keywordEntry')
      self.trackbackEntry = self.mainGlade.get_widget('trackbackEntry')
      self.breaksCheck = self.mainGlade.get_widget('breaksCheck')
      self.pingsCheck = self.mainGlade.get_widget('pingsCheck')
      self.commentsCheck = self.mainGlade.get_widget('commentsCheck')

      # Here's where we get our callbacks. This time, we don't even have to sleep
      # with the director.
      self.mainWindow.connect("delete_event", self.delete_event)
      self.mainWindow.connect("destroy", self.destroy)
      self.blogCombo.entry.connect("changed", self.blogCheck, foo)

      # We can autoconnect the signals from the menu items as they don't require 
      # multiple args.
      self.mainGlade.signal_autoconnect({'on_preferences1_activate': self.displayPrefs})
      self.mainGlade.signal_autoconnect({'on_quit1_activate': self.destroy})
      self.mainGlade.signal_autoconnect({'on_connect1_activate': self.getBlogs})
      self.mainGlade.signal_autoconnect({'on_new1_activate': self.confirmClear})
      self.mainGlade.signal_autoconnect({'on_open1_activate': self.fileOpen})
      self.mainGlade.signal_autoconnect({'on_save1_activate': self.fileSave})
      self.mainGlade.signal_autoconnect({'on_save_as1_activate': self.fileSaveAs})
      self.mainGlade.signal_autoconnect({'on_about1_activate': self.displayAbout})
      self.mainGlade.signal_autoconnect({'on_recall1_activate': self.showPostsWin})
      self.mainGlade.signal_autoconnect({'on_postButton_clicked': self.prepPost})

      # Check for the existence of our new preferences directory
      self.homeDir = os.path.expanduser('~')
      self.configDir = self.homeDir + "/.BloGTK"
      if os.path.exists(self.configDir) == 0:
         print "Creating new BloGTK prefs directory"
         os.mkdir(self.configDir)

      # Now that we have a config dir, let's check for that config file
      if os.path.isfile(self.configDir + "/BloGTK.conf") == 0:
         # Oh crap, there's no config file! What to do? Create one!
         print "Config file not found - Will Open Prefs!"
         self.displayPrefs(self)
      else:
         self.grabConfig()

      # 0.6 - We also want to create our custom tags file if it doesn't already exist.
      if os.path.isfile(self.configDir + "/tags.conf") == 0:
         # Well, now we should create one.
         print "Creating file for custom tag entry"
         conf = open(self.configDir + "/tags.conf", "w")
         conf.write("; tags.conf\n")
         conf.write("; Custom tag data file for BloGTK.\n\n")
         conf.close()
      else:
         pass

      # 0.3 - We now have our own unique appkey! Hooray!
      self.appkey = "542ACD141588E5FEA3970055CF5796008A9063"

      # 0.4 - We don't want the ability to edit posts unless we've already connected
      # to a server.
      self.editPostsItem.set_sensitive(gtk.FALSE)

      # 0.4 - We want to set the hidden postIDLabel widget to a value of 'New' for all
      # new posts.
      self.postIDLabel = self.mainGlade.get_widget('postIDLabel')
      self.postIDLabel.set_text('New')

      # 0.4 - Here's where we attach our toolbar callbacks.
      self.mainGlade.signal_autoconnect({'on_newToolButton_clicked': self.confirmClear})
      self.mainGlade.signal_autoconnect({'on_openToolButton_clicked': self.fileOpen})
      self.mainGlade.signal_autoconnect({'on_saveToolButton_clicked': self.fileSave})
      self.mainGlade.signal_autoconnect({'on_boldToolButton_clicked': self.insertTag_Bold})
      self.mainGlade.signal_autoconnect({'on_italicToolButton_clicked': self.insertTag_Italic})
      self.mainGlade.signal_autoconnect({'on_ulineToolButton_clicked': self.insertTag_Uline})
      self.mainGlade.signal_autoconnect({'on_strikeToolButton_clicked': self.insertTag_Strike})
      self.mainGlade.signal_autoconnect({'on_leftToolButton_clicked': self.insertTag_Left})
      self.mainGlade.signal_autoconnect({'on_centerToolButton_clicked': self.insertTag_Center})
      self.mainGlade.signal_autoconnect({'on_rightToolButton_clicked': self.insertTag_Right})
      self.mainGlade.signal_autoconnect({'on_fillToolButton_clicked': self.insertTag_Fill})
      self.mainGlade.signal_autoconnect({'on_cutToolButton_clicked': self.cut})
      self.mainGlade.signal_autoconnect({'on_copyToolButton_clicked': self.copy})
      self.mainGlade.signal_autoconnect({'on_pasteToolButton_clicked': self.paste})
      self.mainGlade.signal_autoconnect({'on_cut1_activate': self.cut})
      self.mainGlade.signal_autoconnect({'on_copy1_activate': self.copy})
      self.mainGlade.signal_autoconnect({'on_paste1_activate': self.paste})
      self.mainGlade.signal_autoconnect({'on_edit_tags1_activate': self.custTags})
      self.mainGlade.signal_autoconnect({'on_applyTagButton_clicked': self.applyCustTag})
      self.mainGlade.signal_autoconnect({'on_paraToolButton_clicked': self.insertTag_Para})
      self.mainGlade.signal_autoconnect({'on_blockToolButton_clicked': self.insertTag_Block})
      self.mainGlade.signal_autoconnect({'on_linkToolButton_clicked': self.showLinkDialog})
      self.mainGlade.signal_autoconnect({'on_imageToolButton_clicked': self.showImageDialog})
      self.mainGlade.signal_autoconnect({'on_tableToolButton_clicked': self.showTableDialog})
      self.mainGlade.signal_autoconnect({'on_notebook2_switch_page': self.callPreview})
      self.mainGlade.signal_autoconnect({'on_spellToolButton_clicked': self.callSpellCheck})

      #self.notebook2 = self.mainGlade.get_widget('notebook2')
      #self.notebook2.connect("switch_page", self.callPreview)

      # 0.6 - These signal connections fix a problem where entries would be made once for
      # each button press. Using signal_autoconnect is a hack, but it works, so I'm happy...
      self.mainGlade.signal_autoconnect({'on_linkOK_clicked': self.makeLink})
      self.mainGlade.signal_autoconnect({'on_imageOKButton_clicked': self.insertImageTag})
      self.mainGlade.signal_autoconnect({'on_tableOKButton_clicked': self.insertTableTag})

      # 0.9 - We need to activate our toolbar tooltips. Hopefully this will work - if not there is
      # a patch in Bugzilla to fix tooltips in toolbars and PyGTK.

      self.toolbar1 = self.mainGlade.get_widget('toolbar1')
      self.toolbar2 = self.mainGlade.get_widget('toolbar2')

      self.toolbar1.set_tooltips(gtk.TRUE)
      self.toolbar2.set_tooltips(gtk.TRUE)

      # 0.5 - We need to initialize our file pointer.
      self.file = ""

      # 0.6 - We need to pull our custom tag list from the config file as well.
      self.mainTagCombo = self.mainGlade.get_widget("mainTagCombo")
      confDir = os.path.expanduser('~') + "/.BloGTK"
      conf_file = confDir + "/tags.conf"
      config = ConfigParser.ConfigParser()
      config.readfp(open(conf_file))
      tags = config.sections()
      self.mainTagCombo.set_popdown_strings(tags)

      # 0.9-3 - First we need to get our TreeView...
      self.treeView = self.mainGlade.get_widget('blogTreeView')

      # 0.9-3 - Now we need to initiate our List Store...
      self.model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
      self.treeView.set_model(self.model)
      self.treeView.set_headers_visible(gtk.TRUE)

      renderer=gtk.CellRendererText()
      column=gtk.TreeViewColumn("Post Title",renderer, text=0)
      column.set_resizable(gtk.TRUE)
      self.treeView.append_column(column)

      self.treeView.show()      

      # 0.7 - We need to initialize our preview system on init.
   
      self.view = gtkhtml2.View()
   
      scrollwindow = gtk.ScrolledWindow()
      scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
      scrollwindow.set_shadow_type(gtk.SHADOW_IN)
      scrollwindow.add(self.view)
   
      vbox = self.mainGlade.get_widget('preview_vbox')
   
      vbox.pack_start(scrollwindow)
   
      scrollwindow.show()
      self.view.show()

      scrollwindow.connect('focus', self.callPreview, foo)


      # 0.95 - Let's try and pull our tooltips back into our toolbars, since
      # libglade doesn't yet seem to do so. (Although the patch is on bugzilla.)
      # First, we'll pull all our toolbuttons, then we'll assign their tooltips.
    
      self.tooltips = gtk.Tooltips()
    
      self.newToolButton = self.mainGlade.get_widget('newToolButton')
      self.openToolButton = self.mainGlade.get_widget('openToolButton')
      self.saveToolButton = self.mainGlade.get_widget('saveToolButton')
      self.cutToolButton = self.mainGlade.get_widget('cutToolButton')
      self.copyToolButton = self.mainGlade.get_widget('copyToolButton')
      self.pasteToolButton = self.mainGlade.get_widget('pasteToolButton')
      self.boldToolButton = self.mainGlade.get_widget('boldToolButton')
      self.italicToolButton = self.mainGlade.get_widget('italicToolButton')
      self.ulineToolButton = self.mainGlade.get_widget('ulineToolButton')
      self.strikeToolButton = self.mainGlade.get_widget('strikeToolButton')
      self.leftToolButton = self.mainGlade.get_widget('leftToolButton')
      self.centerToolButton = self.mainGlade.get_widget('centerToolButton')
      self.rightToolButton = self.mainGlade.get_widget('rightToolButton')
      self.fillToolButton = self.mainGlade.get_widget('fillToolButton')
      self.paraToolButton = self.mainGlade.get_widget('paraToolButton')
      self.blockToolButton = self.mainGlade.get_widget('blockToolButton')
      self.linkToolButton = self.mainGlade.get_widget('linkToolButton')
      self.imageToolButton = self.mainGlade.get_widget('imageToolButton')
      self.tableToolButton = self.mainGlade.get_widget('tableToolButton')
      self.applyTagButton = self.mainGlade.get_widget('applyTagButton')
      self.spellToolButton = self.mainGlade.get_widget('spellToolButton')
    
      self.tooltips.set_tip(self.newToolButton, "Create a new entry")
      self.tooltips.set_tip(self.openToolButton, "Open a saved entry")
      self.tooltips.set_tip(self.saveToolButton, "Save current entry")
      self.tooltips.set_tip(self.cutToolButton, "Cut selected text to clipboard")
      self.tooltips.set_tip(self.copyToolButton, "Copy selected text to clipboard")
      self.tooltips.set_tip(self.pasteToolButton, "Paste text in clipboard")
      self.tooltips.set_tip(self.cutToolButton, "Open a saved entry")
      self.tooltips.set_tip(self.boldToolButton, "Make text bold")
      self.tooltips.set_tip(self.italicToolButton, "Make text italicized")
      self.tooltips.set_tip(self.ulineToolButton, "Underline text")
      self.tooltips.set_tip(self.strikeToolButton, "Strikethrough text")
      self.tooltips.set_tip(self.leftToolButton, "Align text left")
      self.tooltips.set_tip(self.centerToolButton, "Align text center")
      self.tooltips.set_tip(self.rightToolButton, "Align text right")
      self.tooltips.set_tip(self.fillToolButton, "Justify text")
      self.tooltips.set_tip(self.paraToolButton, "Add paragraph")
      self.tooltips.set_tip(self.blockToolButton, "Add blockquote")
      self.tooltips.set_tip(self.linkToolButton, "Insert new link")
      self.tooltips.set_tip(self.imageToolButton, "Insert an image")
      self.tooltips.set_tip(self.tableToolButton, "Insert a table")
      self.tooltips.set_tip(self.applyTagButton, "Apply custom tag")
      self.tooltips.set_tip(self.spellToolButton, "Spellcheck post")

   def main(self):
      gtk.main()

   def grabConfig(self):

      # 0.7 - We also need to set the account selection widget to the default account name of
      # 'Default' (creative, ain't I?).
      # Accounts can be changed from the Account and Settings window.
      # Also, we need to see if someone is using an older config that the old default of
      # 'server' gets changed over to default.

      self.blogNameLabel = self.mainGlade.get_widget('blogNameLabel')

      if self.blogNameLabel.get_text() == "":
         self.blogNameLabel.set_text("Default")
      else:
         pass

      self.sectionName = self.blogNameLabel.get_text()

      # 0.5 Pull up our values from the config file using Python's builtin ConfigParser module
      self.conf = ConfigParser.ConfigParser()
      self.conf.readfp(open(self.configDir + "/BloGTK.conf"))

      # 0.7 - Here's where we change the default 'server' entry to the new default of 'Default'

      self.sections = self.conf.sections()

      for item in self.sections:
         if item == "server":
            self.conf.add_section("Default")
            self.url = self.conf.get("server", "server")
            self.user = self.conf.get("server", "user")
            self.passwd = self.conf.get("server", "pass")
            self.system = self.conf.get("server", "system")

            try:
               self.font = self.conf.get("server", "font")
      
            except ConfigParser.NoOptionError, error:
               self.font = "Sans 12"
      
            self.conf.set("Default", "server", self.url)
            self.conf.set("Default", "user", self.user)
            self.conf.set("Default", "pass", self.passwd)
            self.conf.set("Default", "system", self.system)
            self.conf.set("Default", "font", self.font)
      
            self.conf.remove_option("server", "server")
            self.conf.remove_option("server", "user")
            self.conf.remove_option("server", "pass")
            self.conf.remove_option("server", "system")
            try:
               self.conf.remove_option("server", "font")
            except:
               pass

            self.conf.remove_section("server")
   
            file = open(self.configDir + "/BloGTK.conf", "w")
         
            self.conf.write(file)
   
            file.close()


      self.url = self.conf.get(self.sectionName, 'server')
      self.user = self.conf.get(self.sectionName, 'user')
      self.passwd = self.conf.get(self.sectionName, 'pass')
      self.system = self.conf.get(self.sectionName, 'system')

      # 0.5 - If there's an error with importing the font selection, 
      # set the font value.
      try:
         self.font = self.conf.get(self.sectionName, 'font')
         # 0.3 - Pull our font selection from the config and apply it to the editor windows.
         font_desc = pango.FontDescription(self.font)
         self.bodyView.modify_font(font_desc)
         self.titleEntry.modify_font(font_desc)
         self.extendedView.modify_font(font_desc)
         self.excerptView.modify_font(font_desc)

      except ConfigParser.NoOptionError, error:
         print "Adding default font section"

         self.conf.set('server', 'font', 'Sans 12')
         conf_file = open(self.configDir + "/BloGTK.conf", 'w+')
         self.conf.write(conf_file)
         conf_file.close()
   
         self.font = "Sans 12"

      # 0.9 - If we're upgrading from a previous version, our general options won't have been
      # set yet. Therefore we'll now have to set them to their default values.

      try:
         self.useUTF = self.conf.get("Default", "useUTF")
         self.defaultPublish = self.conf.get("Default", "defaultPublish")
         self.retrievalNumber = self.conf.get("Default", "retrievalNumber")

         if self.defaultPublish == "1":
            self.publishCheck.set_active(gtk.TRUE)
         else:
            pass

      except:

         print "Creating general settings configuration..."

         self.conf.set("Default", "useUTF", "0")
         self.conf.set("Default", "defaultPublish", "0")
         self.conf.set("Default", "retrievalNumber", "10")
         conf_file = open(self.configDir + "/BloGTK.conf", 'w+')
         self.conf.write(conf_file)
         conf_file.close()
   
         self.useUTF = "0"
         self.defaultPublish = "0"
         self.retrievalNumber = "10"

      self.rpcServer = proxy.get_xmlrpc_server(self.url)

   def displayAbout(self, widget):
      self.aboutDialog = self.mainGlade.get_widget('aboutDialog')
      self.closeButton = self.mainGlade.get_widget('closebutton1')

      self.aboutDialog.show()

      self.aboutDialog.connect("delete_event", self.hideAbout)
      self.closeButton.connect("clicked", self.hideAbout, foo)

   def hideAbout(self, widget, foo):
      self.aboutDialog.hide()
      return gtk.TRUE

   def confirmClear(self, widget):
      self.clearDialog = self.mainGlade.get_widget('confirmClear')
      self.okButton = self.mainGlade.get_widget('okbutton1')
      self.cancelButton = self.mainGlade.get_widget('cancelbutton1')

      self.clearDialog.connect("delete_event", self.hideWindow)

      self.okButton.connect("clicked", self.clearForm, foo)
      self.cancelButton.connect("clicked", self.hideWindow, foo)

      self.clearDialog.show()

   def clearForm (self, widget, foo):
      self.titleEntry.set_text("")
      self.clearDialog.hide()

      buffer = self.bodyView.get_buffer()
      startiter = buffer.get_start_iter()
      enditer = buffer.get_end_iter()

      buffer.delete(startiter, enditer)

      buffer2 = self.extendedView.get_buffer()
      startiter = buffer2.get_start_iter()
      enditer = buffer2.get_end_iter()

      buffer2.delete(startiter, enditer)

      buffer3 = self.excerptView.get_buffer()
      startiter = buffer3.get_start_iter()
      enditer = buffer3.get_end_iter()

      buffer3.delete(startiter, enditer)

      self.keywordEntry.set_text("")
      self.trackbackEntry.set_text("")

      # 0.4 - We want to set the hidden postIDLabel widget to a value of 'New'
      # for all new posts.
      self.postIDLabel.set_text('New')

      # 0.5-1 We also want to make sure that we clear the filename when we 
      # create a new file.
      self.file = ""

      # 0.96 - We should also let the user know we've done all this...
      self.mainStatus.push(1, "Post cleared.")

   def hideWindow(self, widget, foo):
      # Strike me down, and I'll become invisible like Obi-Wan did...
      self.clearDialog.hide()
      return gtk.TRUE

   def getBlogs(self, widget):

      self.grabConfig()
      # Retrieve list of blogs for user.
      try:
         blogs = self.rpcServer.blogger.getUsersBlogs(self.appkey, self.user, self.passwd)
         blogName = []
         blogID = []

         for item in blogs:
        blogName.append(item['blogName'])
        blogID.append(item['blogid'])

         self.blogCombo.set_popdown_strings(blogName)

   # 0.4 - We want to enable those hidden options now...
   self.postButton.set_sensitive(gtk.TRUE)
   self.editPostsItem.set_sensitive(gtk.TRUE)

   self.mainStatus.push(1, "Connected to server at " + self.url)

      except xmlrpclib.Fault, error:
       errString = str(error)
       self.mainStatus.push(1, "An error occurred while connecting to the server: " + errString)

      except:
       self.mainStatus.push(1, "An error occurred while connecting. Check your settings.")

      # 0.9 - If the blogging system is either MetaWeblog or Blogger we can activate our Title Entry field...
      # 0.95 - We can also activate our other options

      if self.system == "mt":
      self.titleEntry.set_sensitive(gtk.TRUE)
      self.extendedView.set_sensitive(gtk.TRUE)
       self.excerptView.set_sensitive(gtk.TRUE)
       self.commentsCheck.set_sensitive(gtk.TRUE)
       self.pingsCheck.set_sensitive(gtk.TRUE)
       self.breaksCheck.set_sensitive(gtk.TRUE)
       self.keywordEntry.set_sensitive(gtk.TRUE)
      self.trackbackEntry.set_sensitive(gtk.TRUE)
      elif self.system == "metaweblog":
      self.titleEntry.set_sensitive(gtk.TRUE)
      self.extendedView.set_sensitive(gtk.TRUE)
      self.excerptView.set_sensitive(gtk.TRUE)
      else:
      pass

      # 0.95 - We can now also activate our option to edit/delete posts...
      self.recallMenuOption.set_sensitive(gtk.TRUE)

   def blogCheck(self, widget, foo):

      if self.system == "mt":
         self.getCategories(self, widget)
      else:
         return 0

      text = self.blogCombo.entry.get_text()

      # 1.1 - Make sure we pull our version string rather than having to manually update each release.
      self.mainWindow.set_title("BloGTK " + version + " - " + text)

   def getCategories(self, widget, foo):

      blogName = self.blogCombo.entry.get_text()

      blogs = self.rpcServer.blogger.getUsersBlogs(self.appkey, self.user, self.passwd)

      # self.blogID = ""

      for item in blogs:
         for k,v in item.items():
        if item['blogName'] == blogName:
           # 0.3 - By casting this variable as self, it fixes an assignment error
           self.blogID = item['blogid']

      # Retrieve category list from the server
      categories = self.rpcServer.mt.getCategoryList(self.blogID, self.user, self.passwd)
      categoryName = []
      categoryID = []

      for item in categories:
         categoryName.append(item['categoryName'])
         categoryID.append(item['categoryId'])

      if categoryName != []:
         categoryName.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
         self.catCombo.set_popdown_strings(categoryName)
      else:
         print "No Categories To File"
         categoryName = [""]
         self.catCombo.set_popdown_strings(categoryName)

   def prepPost(self, widget):

      # We also need to retrieve the blogID and catID informtion...
      checkPublish = self.publishCheck.get_active()

      # Grab the title.
      title = self.titleEntry.get_text()

      # Grab that body, and hopefully we won't get sued for sexual harrassment.
      buffer = self.bodyView.get_buffer()
      startiter = buffer.get_start_iter()
      enditer = buffer.get_end_iter()
      body = buffer.get_text(startiter, enditer, include_hidden_chars=1).encode("utf-8")

      # Now to pull our blogid.
      blogName = self.blogCombo.entry.get_text()

      blogs = self.rpcServer.blogger.getUsersBlogs(self.appkey, self.user, self.passwd)

      for item in blogs:
         for k,v in item.items():
      if item['blogName'] == blogName:
         blogID = item['blogid']

      # Are we using MT? If so, we need to pull the category ID as well.
      if self.system == "mt":
      
         catName = self.catCombo.entry.get_text()

         cats = self.rpcServer.mt.getCategoryList(blogID, self.user, self.passwd)

         for item in cats:
            for k,v in item.items():
          if item['categoryName'] == catName:
            catID = item['categoryId']
      else:
         catID = "0"

      # 0.95 - We also need to pull our extended entry as well as our other
    # fields
      buffer = self.extendedView.get_buffer()
      startiter = buffer.get_start_iter()
      enditer = buffer.get_end_iter()
      extended = buffer.get_text(startiter, enditer, include_hidden_chars=1).encode("utf-8")
      
      buffer = self.excerptView.get_buffer()
      startiter = buffer.get_start_iter()
      enditer = buffer.get_end_iter()
      excerpt = buffer.get_text(startiter, enditer, include_hidden_chars=1).encode("utf-8")

      keywords = self.keywordEntry.get_text()
      trackbackURLS = self.trackbackEntry.get_text()

      if self.breaksCheck.get_active() == gtk.TRUE:
         breaks = "1"
      else:
         breaks = "0"

      if self.commentsCheck.get_active() == gtk.TRUE:
         commentsAllow = "1"
      else:
         commentsAllow = "0"

      if self.pingsCheck.get_active() == gtk.TRUE:
         pingsAllow = "1"
      else:
         pingsAllow = "0"
      
      # 0.4 - We need to determine if this is a new post, or one that's being edited.
      self.postStatus = self.postIDLabel.get_text()

      if self.postStatus == 'New': 
         post.getPostInfo(self.url, self.user, self.passwd, self.system, blogID, catID, title, body, checkPublish, self.mainGlade, self.useUTF, extended, excerpt, keywords, trackbackURLS, breaks, commentsAllow, pingsAllow)
      else:
         post.repost(self.url, self.user, self.passwd, self.system, blogID, catID, title, body, checkPublish, self.postStatus, self.mainGlade, self.useUTF, extended, excerpt, keywords, trackbackURLS, breaks, commentsAllow, pingsAllow)

   def showPostsWin(self, foo):
      # 0.4 - This pops open our window that lets us retrieve our old posts.
      # TODO - 0.95 - TODONE
      self.postsWin_cancel = self.mainGlade.get_widget('recallCancelButton')

      # 0.95 - These functions allow us to use a ListView to view our posts in a more sensible
      # manner.

      self.postsWindow.show()

      self.postsWindow.connect("delete_event", self.hidePostsWin)
      self.postsWin_cancel.connect("clicked", self.hidePostsWin, foo)

      # 0.4 - Let's grab that BlogID from the main combo entry.

      # We don't need to do error checking here, since we've done this operation before.
      blogName = self.blogCombo.entry.get_text()

      blogs = self.rpcServer.blogger.getUsersBlogs(self.appkey, self.user, self.passwd)

      for item in blogs:
         for k,v in item.items():
      if item['blogName'] == blogName:
         blogID = item['blogid']

      if self.system == "mt":
         post.mt_grabPostList(self.mainGlade, self.url, self.user, self.passwd, self.system, blogID, self.model, self.treeView, self.retrievalNumber)
      elif self.system == "blogger":
         post.blogger_grabPostList(self.mainGlade, self.url, self.user, self.passwd, self.system, blogID, self.model, self.treeView, self.retrievalNumber)
      elif self.system == "metaweblog":
         post.mw_grabPostList(self.mainGlade, self.url, self.user, self.passwd, self.system, blogID, self.model, self.treeView, self.retrievalNumber)

   def hidePostsWin(self, widget, foo):
      self.model.clear()
      self.postsWindow.hide()
      return gtk.TRUE

### BEGIN TOOLBAR TAG INSERTION CODE ###

   def insertTag_Bold(self, widget):
      
      self.tagInsertionLogic(widget, "<strong>","</strong>")

   def insertTag_Italic(self, widget):

      self.tagInsertionLogic(widget, "<em>", "</em>")

   def insertTag_Uline(self, widget):

      self.tagInsertionLogic(widget, "<span style=\"text-decoration: underline;\">", "</span>")

   def insertTag_Strike(self, widget):

      self.tagInsertionLogic(widget, "<span style=\"text-decoration: line-through;\">", "</span>")

   def insertTag_Left(self, widget):

      self.tagInsertionLogic(widget, "<div style=\"text-align: left;\">", "</div>")

   def insertTag_Center(self, widget):

      self.tagInsertionLogic(widget, "<div style=\"text-align: center;\">", "</div>")

   def insertTag_Right(self, widget):

      self.tagInsertionLogic(widget, "<div style=\"text-align: right;\">", "</div>")

   def insertTag_Fill(self, widget):

     self.tagInsertionLogic(widget, "<div style=\"text-align: justify;\">", "</div>")

   # 0.6 - More tags to insert for more fun! Hooray!

   def insertTag_Block(self,widget):

      self.tagInsertionLogic(widget, "<blockquote>", "</blockquote>")

   def insertTag_Para(self,widget):

      self.tagInsertionLogic(widget, "<p>", "</p>")

   def tagInsertionLogic(self, widget, tagStart, tagEnd):

      # 0.5 - This code is an amazing kludge, yet it works. In essence, what we do is determine
      # if there is a selection or not. If not, the code is relatively simple. If there is, we
      # first grab the selected text, then we add the tags, delete the original, then we insert
      # the text+tags. After that we actually search for the original text and set the selection
      # to our search results. As I stated, it's an amazingly convoluted piece of code, but it
      # works, so I'm willing to live with it. This code is repeated for each button.

      # 0.95 - Here comes another kludge... we're going to test and see how we can find which
      # field is actually being used then cast it as our selectedWindow.

      if self.bodyView.is_focus() == 1:
         self.selectedWindow = self.bodyView
      elif self.extendedView.is_focus() == 1:
         self.selectedWindow = self.extendedView
      elif self.excerptView.is_focus() == 1:
         self.selectedWindow = self.excerptView

      self.buffer = self.selectedWindow.get_buffer()

      selMark = self.buffer.get_selection_bound()
      insMark = self.buffer.get_insert()

      try:
         start, end = self.buffer.get_selection_bounds()
         text = self.buffer.get_text(start, end)
         new_text = tagStart + text + tagEnd
         self.buffer.delete(start, end)
         self.buffer.insert(start, new_text, -1)
         cur_pos = self.buffer.get_iter_at_mark(self.buffer.get_insert())
         match_start, match_end = cur_pos.backward_search(text, gtk.TEXT_SEARCH_TEXT_ONLY)
         self.buffer.move_mark(selMark, match_end)
         self.buffer.move_mark(insMark, match_start)
      except:
         self.buffer.insert_at_cursor(tagStart + tagEnd, -1)
         end = self.buffer.get_iter_at_mark(selMark)
         end.backward_chars(len(tagEnd))
         self.buffer.place_cursor(end)

   # 0.4 - This adds our cut/copy/paste logic from the toolbar/menubar

   def cut(self, widget):

      if self.bodyView.is_focus() == 1:
         self.bodyView.emit("cut-clipboard")
      elif self.titleEntry.is_focus() == 1:
         self.titleEntry.emit("cut-clipboard")
      elif self.extendedView.is_focus() == 1:
         self.extendedView.emit("cut-clipboard")
      elif self.excerptView.is_focus() == 1:
         self.excerptView.emit("cut-clipboard")
      elif self.keywordEntry.is_focus() == 1:
         self.keywordEntry.emit("cut-clipboard")
      elif self.trackbackEntry.is_focus() == 1:
         self.trackbackEntry.emit("cut-clipboard")
      else:
         pass

   def copy(self, widget):

      if self.bodyView.is_focus() == 1:
         self.bodyView.emit("copy-clipboard")
      elif self.titleEntry.is_focus() == 1:
         self.titleEntry.emit("copy-clipboard")
      elif self.extendedView.is_focus() == 1:
         self.extendedView.emit("copy-clipboard")
      elif self.excerptView.is_focus() == 1:
         self.excerptView.emit("copy-clipboard")
      elif self.keywordEntry.is_focus() == 1:
         self.keywordEntry.emit("copy-clipboard")
      elif self.trackbackEntry.is_focus() == 1:
         self.trackbackEntry.emit("copy-clipboard")
      else:
         pass

   def paste(self, widget):

      if self.bodyView.is_focus() == 1:
         self.bodyView.emit("paste-clipboard")
      elif self.titleEntry.is_focus() == 1:
         self.titleEntry.emit("paste-clipboard")
      elif self.extendedView.is_focus() == 1:
         self.extendedView.emit("paste-clipboard")
      elif self.excerptView.is_focus() == 1:
         self.excerptView.emit("paste-clipboard")
      elif self.keywordEntry.is_focus() == 1:
         self.keywordEntry.emit("paste-clipboard")
      elif self.trackbackEntry.is_focus() == 1:
         self.trackbackEntry.emit("paste-clipboard")
      else:
         pass

   # 0.5 - Here is our code for opening arbitrarily saved files.

   def fileOpen(self, widget):

      self.openDialog = self.mainGlade.get_widget("openFileDialog")
      self.openDialog_cancel = self.mainGlade.get_widget("cancel_button3")
      self.openDialog_ok = self.mainGlade.get_widget("ok_button3")
      self.openDialog.show()

      self.openDialog.connect("delete_event", self.openHide)
      self.openDialog_cancel.connect("clicked", self.openHide, foo)
      self.openDialog_ok.connect("clicked", self.openFile)

   def openFile(self, widget):

      self.file = self.openDialog.get_filename()

      try:
         openFile = open(self.file, "r")

         title = cPickle.load(openFile)
         body = cPickle.load(openFile)
         extended = cPickle.load(openFile)
         excerpt = cPickle.load(openFile)
         keywords = cPickle.load(openFile)
         trackbackURLS = cPickle.load(openFile)

         self.titleEntry.set_text(title)
         buffer = self.bodyView.get_buffer()
         buffer.set_text(body)
         
         buffer2 = self.extendedView.get_buffer()
         buffer2.set_text(extended)

         buffer3 = self.excerptView.get_buffer()
         buffer3.set_text(excerpt)

         self.keywordEntry.set_text(keywords)

         self.trackbackEntry.set_text(trackbackURLS)

         self.mainStatus.push(1, "Opened File " + self.file)
      except:
         self.mainStatus.push(1, "An error occurred in opening the file.")
         self.file = ""

      self.openHide(widget, foo)

   def openHide(self, widget, foo):
      self.openDialog.hide()
      return gtk.TRUE

   # 0.5 - This is where we save our posts to an arbitrary file.

   def fileSave(self, widget):

      if self.file == "":
         self.saveDialog = self.mainGlade.get_widget("saveFileDialog")
         self.saveDialog_cancel = self.mainGlade.get_widget("cancel_button4")
         self.saveDialog_ok = self.mainGlade.get_widget("ok_button4")
         self.saveDialog.show()

         self.saveDialog.connect("delete_event", self.saveHide)
         self.saveDialog_cancel.connect("clicked", self.saveHide, foo)
         self.saveDialog_ok.connect("clicked", self.saveFile)
      else:
         self.writeFile(widget, foo)

   def fileSaveAs(self, widget):
      self.file = ""
      self.fileSave(widget)

   def saveFile(self, widget):
      self.file = self.saveDialog.get_filename()

      if os.path.isfile(self.file) == 1:

         # 1.0 - Rather than creating a new widget in code, we now pull our
         # confirmation dialog from the Glade file.
         self.overwriteDialog = self.mainGlade.get_widget('overwriteDialog')

         self.overwrite_ButtonOK = self.mainGlade.get_widget('overwrite_buttonOK')
         self.overwrite_ButtonCancel = self.mainGlade.get_widget('overwrite_buttonCancel')

         self.overwrite_ButtonOK.connect("clicked", self.preWrite, foo)
         self.overwrite_ButtonCancel.connect("clicked", self.closeSaveDialog)

         self.overwriteDialog.connect("delete_event", self.closeSaveDialog)
         self.overwriteDialog.connect("destroy", self.closeSaveDialog)

         self.overwriteDialog.show()

      else:
         self.writeFile(widget, foo)

   def preWrite(self, widget, foo):

      self.writeFile(widget, foo)
      self.closeSaveDialog(widget)

   def closeSaveDialog(self, widget):

      self.overwriteDialog.hide()

      self.saveDialog.hide()
      return gtk.TRUE

   def writeFile(self, widget, foo):

      title = self.titleEntry.get_text()
      buffer = self.bodyView.get_buffer()
      startiter = buffer.get_start_iter()
      enditer = buffer.get_end_iter()
      body = buffer.get_text(startiter, enditer, include_hidden_chars=1)

      buffer2 = self.extendedView.get_buffer()
      startiter = buffer2.get_start_iter()
      enditer = buffer2.get_end_iter()
      extended = buffer2.get_text(startiter, enditer, include_hidden_chars=1)

      buffer3 = self.excerptView.get_buffer()
      startiter = buffer3.get_start_iter()
      enditer = buffer3.get_end_iter()
      excerpt = buffer3.get_text(startiter, enditer, include_hidden_chars=1)

      keywords = self.keywordEntry.get_text()
      trackbackURLS = self.trackbackEntry.get_text()

      saveFile = open(self.file, "w")
      cPickle.dump(title, saveFile)
      cPickle.dump(body, saveFile)
      cPickle.dump(extended, saveFile)
      cPickle.dump(excerpt, saveFile)
      cPickle.dump(keywords, saveFile)
      cPickle.dump(trackbackURLS, saveFile)
      try:
         self.saveHide(widget, foo)
      except:
         pass
      saveFile.close()
      self.mainStatus.push(1, "Wrote post to file: " + self.file)

   def saveHide(self, widget, foo):
      self.saveDialog.hide()
      return gtk.TRUE

   # 0.6 - This is where we call our new custom tag handing functions.
   def custTags(self, widget):
      customtags.displayTagsWindow(self.mainGlade)

   def applyCustTag(self, widget):
      mainTagEntry = self.mainGlade.get_widget("mainTagEntry")

      tag_name = mainTagEntry.get_text()

      confDir = os.path.expanduser('~') + "/.BloGTK"
      conf_file = confDir + "/tags.conf"
      config = ConfigParser.ConfigParser()
      config.readfp(open(conf_file))

     # 0.6 - For some reason, Python throws a NoSectionError with this code, despite the fact that
     # there's no error. For convenience's sake, we'll escape this error for now.

      try:
         start_tag = config.get(tag_name, "start_tag")
      except ConfigParser.NoSectionError:
         pass

      try:
         script_tag = config.get(tag_name, "script_tag")
      except ConfigParser.NoSectionError:
         pass

      try:
         end_tag = config.get(tag_name, "end_tag")
      except ConfigParser.NoSectionError:
         pass

      # 0.95 - Here comes another kludge... we're going to test and see how we can find which
      # field is actually being used then cast it as our selectedWindow.

      if self.bodyView.is_focus() == 1:
         self.selectedWindow = self.bodyView
      elif self.extendedView.is_focus() == 1:
         self.selectedWindow = self.extendedView
      elif self.excerptView.is_focus() == 1:
         self.selectedWindow = self.excerptView

      self.buffer = self.selectedWindow.get_buffer()

      selMark = self.buffer.get_selection_bound()
      insMark = self.buffer.get_insert()

      child = os.popen(script_tag)
      script_output = child.read()

      try:
         start, end = self.buffer.get_selection_bounds()
         text = self.buffer.get_text(start, end)
         new_text = start_tag + script_output + text + end_tag
         self.buffer.delete(start, end)
         self.buffer.insert(start, new_text, -1)
         cur_pos = self.buffer.get_iter_at_mark(self.buffer.get_insert())
         match_start, match_end = cur_pos.backward_search(text, gtk.TEXT_SEARCH_TEXT_ONLY)
         self.buffer.move_mark(selMark, match_end)
         self.buffer.move_mark(insMark, match_start)
      except:
         self.buffer.insert_at_cursor(start_tag + script_output + end_tag, -1)
   end = self.buffer.get_iter_at_mark(selMark)
   cur_point = len(end_tag)
   end.backward_chars(cur_point)
   self.buffer.place_cursor(end)

   # 0.6 - Here's where we handle the insertion of links from the link dialog.

   def showLinkDialog(self, widget):
      self.linkDialog = self.mainGlade.get_widget("linkDialog")
      self.linkOKButton = self.mainGlade.get_widget("linkOK")
      self.linkCancelButton = self.mainGlade.get_widget("linkCancel")

      self.linkDialog.show()

      self.linkDialog.connect_object("delete_event", self.linksHide, foo)
      self.linkCancelButton.connect_object("clicked", self.linksHide, widget, foo)

      self.linkURLEntry = self.mainGlade.get_widget("linkURLEntry")
      self.linkTargetEntry = self.mainGlade.get_widget("linkTargetEntry")
      self.linkTextEntry = self.mainGlade.get_widget("linkTextEntry")

   def makeLink(self, widget):

      self.linkURL = self.linkURLEntry.get_text()
      self.linkTarget = self.linkTargetEntry.get_text()

      self.linkDialog.hide()

      # 0.95 - Here comes another kludge... we're going to test and see how we can find which
      # field is actually being used then cast it as our selectedWindow.

      if self.bodyView.is_focus() == 1:
         self.selectedWindow = self.bodyView
      elif self.extendedView.is_focus() == 1:
         self.selectedWindow = self.extendedView
      elif self.excerptView.is_focus() == 1:
         self.selectedWindow = self.excerptView

      self.buffer = self.selectedWindow.get_buffer()

      selMark = self.buffer.get_selection_bound()
      insMark = self.buffer.get_insert()

      try:
         start, end = self.buffer.get_selection_bounds()
         text = self.buffer.get_text(start, end)
         new_text = '<a href=\"' + self.linkURL + '\" target=\"' + self.linkTarget + '\">' + text + '</a>'
         self.buffer.delete(start, end)
         self.buffer.insert(start, new_text, -1)
         cur_pos = self.buffer.get_iter_at_mark(self.buffer.get_insert())
         match_start, match_end = cur_pos.backward_search(text, gtk.TEXT_SEARCH_TEXT_ONLY)
         self.buffer.move_mark(selMark, match_end)
         self.buffer.move_mark(insMark, match_start)
      except:
         self.buffer.insert_at_cursor('<a href=\"' + self.linkURL + '\" target=\"' + self.linkTarget + '\"></a>', -1)
   end = self.buffer.get_iter_at_mark(selMark)
   end.backward_chars(4)
   self.buffer.place_cursor(end)

   def linksHide(self, widget, foo):
      self.linkDialog.hide()
      return gtk.TRUE

   #0.6 - These functions are for the image insertion dialog.

   def showImageDialog(self, widget):
      self.imageDialog = self.mainGlade.get_widget("imageDialog")
      self.imageOKButton = self.mainGlade.get_widget("imageOKButton")
      self.imageCancelButton = self.mainGlade.get_widget("imageCancelButton")
      self.imageAlignEntry = self.mainGlade.get_widget("imageAlignEntry")
      self.imageAlignCombo = self.mainGlade.get_widget("imageAlignCombo")

      self.imageURLEntry = self.mainGlade.get_widget("imageURLEntry")
      self.imageAltEntry = self.mainGlade.get_widget("imageAltEntry")
      self.imageHeightEntry = self.mainGlade.get_widget("imageHeightEntry")
      self.imageWidthEntry = self.mainGlade.get_widget("imageWidthEntry")

      self.imageDialog.show()

      self.imageDialog.connect_object("delete_event", self.imageHide, foo)
      self.imageCancelButton.connect_object("clicked", self.imageHide, widget, foo)

      self.alignments = ["Left", "Right", "Middle", "AbsMiddle", "Top", "Bottom", "Center"]

      self.imageAlignCombo.set_popdown_strings(self.alignments)

   def insertImageTag(self, widget):

      self.imageURL = self.imageURLEntry.get_text()
      self.imageAlt = self.imageAltEntry.get_text()
      self.imageHeight = str(self.imageHeightEntry.get_value_as_int())
      self.imageWidth = str(self.imageWidthEntry.get_value_as_int())
      self.imageAlign = self.imageAlignEntry.get_text()

      self.imageDialog.hide()

      # 0.95 - Here comes another kludge... we're going to test and see how we can find which
      # field is actually being used then cast it as our selectedWindow.

      if self.bodyView.is_focus() == 1:
         self.selectedWindow = self.bodyView
      elif self.extendedView.is_focus() == 1:
         self.selectedWindow = self.extendedView
      elif self.excerptView.is_focus() == 1:
         self.selectedWindow = self.excerptView

      self.buffer = self.selectedWindow.get_buffer()

      self.buffer.insert_at_cursor("<img src=\"" + self.imageURL + "\" align=\"" + self.imageAlign + "\" width=\"" + self.imageWidth + "\" height=\"" + self.imageHeight + "\" alt=\"" + self.imageAlt + "\" / >", -1)

   def imageHide(self, widget, foo):
      self.imageDialog.hide()
      return gtk.TRUE

   # 0.6 - These function control inserting the table tags.
   def showTableDialog(self, widget):
      self.tableDialog = self.mainGlade.get_widget("tableDialog")

      self.tableRowsEntry = self.mainGlade.get_widget("tableRowsEntry")
      self.tableColsEntry = self.mainGlade.get_widget("tableColsEntry")
      self.tableWidthEntry = self.mainGlade.get_widget("tableWidthEntry")
      self.tableSpacingEntry = self.mainGlade.get_widget("tableSpacingEntry")
      self.tablePaddingEntry = self.mainGlade.get_widget("tablePaddingEntry")
      self.tableBorderEntry = self.mainGlade.get_widget("tableBorderEntry")

      self.tableCancelButton = self.mainGlade.get_widget("tableCancelButton")

      self.tableDialog.show()

      self.tableDialog.connect_object("delete_event", self.tableHide, foo)
      self.tableCancelButton.connect_object("clicked", self.tableHide, widget, foo)

   def insertTableTag(self, widget):

      self.mainStatus.push(1, "")

      self.tableCols = self.tableColsEntry.get_text()
      self.tableRows = self.tableRowsEntry.get_text()
      self.tableWidth = self.tableWidthEntry.get_text()
      self.tablePadding = self.tablePaddingEntry.get_text()
      self.tableSpacing = self.tableSpacingEntry.get_text()
      self.tableBorder = self.tableBorderEntry.get_text()

      try:

         int(self.tableRows)
   
         # 0.95 - Here comes another kludge... we're going to test and see how we can find which
         # field is actually being used then cast it as our selectedWindow.

         if self.bodyView.is_focus() == 1:
            self.selectedWindow = self.bodyView
         elif self.extendedView.is_focus() == 1:
            self.selectedWindow = self.extendedView
         elif self.excerptView.is_focus() == 1:
            self.selectedWindow = self.excerptView

         self.buffer = self.selectedWindow.get_buffer()

         self.buffer.insert_at_cursor("<table width=\"" + self.tableWidth +"\" border=\"" + self.tableBorder + "\" cellspacing=\"" + self.tableSpacing + "\" cellpadding=\"" + self.tablePadding + "\">\n")

         for i in range(0, int(self.tableRows)):
            self.buffer.insert_at_cursor("<tr>")
            for i in range(0, int(self.tableCols)):
               self.buffer.insert_at_cursor("<td>Insert Text Here</td>")
            self.buffer.insert_at_cursor("</tr>\n")

         self.buffer.insert_at_cursor("</table>")

   self.tableHide(widget, foo)

      except:
         self.mainStatus.push(1, "Please enter a numeric value for table columns and rows.")

   def tableHide(self, widget, foo):
      self.tableDialog.hide()
      return gtk.TRUE

   def callPreview(self, widget, foo, page):

      # 0.7 - This just exports all the necessary arguments to our preview function library

      if page == 1:
         preview.previewEntry(self.mainGlade, self.view)
      elif page == 2:
         # 0.96 - D'OH! I spend hours debugging only to find that I forgot to
         # add the right callback for the Advanced tab. I'm an idiot...
         preview.previewEntry(self.mainGlade, self.view)
      else:
         pass

   def callSpellCheck(self, widget):

      SpellCheck = spellcheck.SpellCheck()
      SpellCheck.displaySpellWindow(self.mainGlade)

# This function initializes the app on load, calling the main function.
# When the main function is called __init__ is done automagically.
if __name__ == "__main__":
   blogtk = BloGTK()
   blogtk.main()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.