#!/usr/bin/env python
# -*- coding: utf-8 -*-

#    Copyright (C) 2008-2010 Ivan Garcia capiscuas@gmail.com
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning

""" Create and launch the GUI """
import sys, re, os, traceback, tempfile
import time, thread
import webbrowser
import urllib2
import base64, zlib
import commands
import platform
import os.path
import zipfile

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, QSettings, \
                        QVariant, QSize, QEventLoop, QString, QModelIndex, QFileInfo, QPoint
from PyQt4.QtGui import QPixmap, QSplashScreen, QErrorMessage, QMessageBox, \
                        QFileDialog, QIcon, QItemSelectionModel, QToolBar, \
                        QItemSelection, QActionGroup, QFont, QMainWindow, \
                        QApplication, QTableView

from SplashScreen import SplashScreen, NoneSplashScreen

from core.languages import Languages as languages

import locale, gettext

# create splash screen and show messages to the user
app = QApplication(sys.argv)
splash = SplashScreen()
splash.showMessage("Loading...")
QCoreApplication.flush()

from qt import installErrorHandler, Error, _Warning, extension

from main_ui import Ui_MainWindow
from settings import settingsDialog
from about import aboutDialog
from chooseLanguage import chooseLanguageDialog
from wordlistmodel import  WordListModel
from historylistmodel import  HistoryListModel
from contentSearchModel import  ContentSearchModel
from dictfilemanager import DictFileManager

from core.modules import *
import core.modules.utils as utils
import core.dictionary.engine as engine
from core.dictionary.dictionary import Definition
import logging
import functools

#xmlrpc methods accessor
from core.net.xmlrpc import OnlineService, TimeoutFunctionException

log = logging.getLogger("babiloo.qt.main")

class Main(QMainWindow, Ui_MainWindow):
    def report_error(func):
        """
        Decorator to ensure that unhandled exceptions are displayed
        to users via the GUI
        """
        def function(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception, e:
                Error("There was an error calling " + func.__name__, e)
                raise
        return function

    def SetupInterfaceLang(self):
        if platform.system() == "Linux":
            if self.programFolder == '/usr/share/babiloo':
                localedir = '/usr/share/locale/'
            else:
                localedir = 'locale'
        else:
            localedir = 'locale'
            #Get the local directory since we are not installing anything
            #local_path = os.path.realpath(os.path.dirname(sys.argv[0]))
            #print local_path

        #localedir = 'locale' #remove

        log.debug('Scanning translation files .mo in folder: %s' %localedir)
        self.interface_langs = []
        for root, dirs, files in os.walk(localedir):
            if re.search(".*locale$", os.path.split(root)[0]):
                _lang = os.path.split(root)[-1]
            if 'babiloo.mo' in files:
                self.interface_langs.append(_lang)

        log.debug('Found these translations languages: %r' % self.interface_langs)

        #Check the default locale
        lc, encoding = locale.getdefaultlocale()
        if not lc:
            user_locale = 'en' #In case of language not found
        else:
            if lc in languages.ListAll_locale():
                user_locale = lc
            else:
                user_locale = lc.split('_')[0]

        interface_lang = self.settings.value("settings/interfaceLang", QVariant())
        if not len(self.interface_langs):
            interface_lang = 'en'
        else:
            if interface_lang == QVariant():
                #Use system default locale
                interface_lang = user_locale
                self.settings.setValue("settings/interfaceLang", QVariant(user_locale))
            else:
                interface_lang = str(interface_lang.toString().toUtf8())

        log.debug('Interface language: %s' % interface_lang)

        gettext.translation(domain = "babiloo", localedir = localedir,
            languages = [interface_lang], fallback = True).install(unicode = True)

    def chooseInterfaceLanguage(self, user_locale):
        self.choosenLanguage = 'en' #By default
        dialog = chooseLanguageDialog(self, user_locale)
        dialog.exec_()
        return self.choosenLanguage

    def __init__(self, options):
        splash.showMessage(_("Building main dialog..."))
        super(Main, self).__init__()
        
        QCoreApplication.setOrganizationName("Babiloo")
        QCoreApplication.setApplicationName(APP_TITLE)

        self.menuCheckDictionaries = {} #To keep all the menus to swap dictionaries

        self.options = options
        self.settings = QSettings()
        self.engine = engine.DictionaryEngine()
        self.activeDictionary = None

        self.calculateProgramFolder()
        self.SetupInterfaceLang()
        
        self.setupUi(self)
        self.createTray()
        self.actionGroupDictionaries = QActionGroup(self.menuDictionaries)
        self.actionGroupDictionaries.setExclusive(True)

        self.setWindowTitle(APP_TITLE + " "+APP_VERSION)
        self.setWindowIcon(QIcon(":/icon"))
        #self.read_settings()

        self.wordListModel = WordListModel(self)
        self.historyListModel = HistoryListModel(self)
        self.contentSearchModel = ContentSearchModel(self)
        self.wordList.setModel(self.wordListModel)
        self.historyList.setModel(self.historyListModel)
        self.contentSearchList.setModel(self.contentSearchModel)

        self.wordListSelectionModel = QItemSelectionModel(self.wordListModel)
        self.wordList.setSelectionModel(self.wordListSelectionModel)

        self.historyListSelectionModel = QItemSelectionModel(self.historyListModel)
        self.historyList.setSelectionModel(self.historyListSelectionModel)

        self.contentSearchListSelectionModel = QItemSelectionModel(self.contentSearchModel)
        self.contentSearchList.setSelectionModel(self.contentSearchListSelectionModel)

        QObject.connect(self.actionAbout, SIGNAL("triggered()"), self.onMenuHelpAbout)
        QObject.connect(self.actionVisit_HomePage, SIGNAL("triggered()"), self.onMenuHelpHomePage)
        QObject.connect(self.actionReport_A_Problem, SIGNAL("triggered()"), self.onMenuHelpReportProblem)
        QObject.connect(self.actionTranslate_This_Application, SIGNAL("triggered()"), self.onMenuHelpTranslate)

        QObject.connect(self.actionSettings, SIGNAL("triggered()"), self.onMenuSettings)
        QObject.connect(self.actionQuit, SIGNAL("triggered()"), self.quit_app)

        QObject.connect(self.actionImport_Dictionary, SIGNAL("triggered()"), self.onMenuImportDictionary)
        QObject.connect(self.actionManage_Dictionaries, SIGNAL("triggered()"), self.onMenuManageDictionaries)
        QObject.connect(self.actionDownload_Dictionaries, SIGNAL("triggered()"), self.onMenuDownloadDictionaries)

        QObject.connect(self.wordList, SIGNAL("clicked(QModelIndex)"), self.onClickWordList)
        QObject.connect(self.wordList, SIGNAL("activated (const QModelIndex&)"), self.onClickWordList)

        QObject.connect(self.historyList, SIGNAL("clicked(QModelIndex)"), self.onClickHistoryList)
        QObject.connect(self.historyList, SIGNAL("activated (const QModelIndex&)"), self.onClickHistoryList)
        QObject.connect(self.historyListSelectionModel, SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onHistorySelectionChanged)

        QObject.connect(self.articlesText, SIGNAL("textEdited (const QString&)"), self.onArticlesTextEdited)
        QObject.connect(self.articlesText, SIGNAL("returnPressed()"), self.onArticlesTextActivated)
        QObject.connect(self.articlesSearchButton, SIGNAL("clicked(bool)"), self.onArticlesSearchButton)
        QObject.connect(self.articlesClearButton, SIGNAL("clicked(bool)"), self.onArticlesClearButton)
        self.connect(self.articlesText, SIGNAL("downOrUpKeyPressed (QEvent)"), self.onArticlesTextDownUpKey)

        self.wordList.keyPressEvent = self.onWordListKeyPressed

        #ContentSearch

        QObject.connect(self.contentSearchText, SIGNAL("returnPressed()"), self.onContentSearchTextActivated)
        QObject.connect(self.contentSearchButton, SIGNAL("clicked(bool)"), self.onContentSearchButton)
        QObject.connect(self.contentSearchClearButton, SIGNAL("clicked(bool)"), self.onContentSearchClearButton)
        QObject.connect(self.stopContentSearchButton, SIGNAL("clicked(bool)"), self.onStopContentSearchButton)
        self.connect(self.contentSearchText, SIGNAL("downOrUpKeyPressed (QEvent)"), self.onContentSearchTextDownUpKey)

        QObject.connect(self.contentSearchList, SIGNAL("clicked(QModelIndex)"), self.contentSearchModel.onClick)
        QObject.connect(self.contentSearchList, SIGNAL("clicked(QModelIndex)"), self.contentSearchModel.onClick)
        QObject.connect(self.contentSearchList, SIGNAL("activated (const QModelIndex&)"), self.contentSearchModel.onClick)

        #Status bar
        self.status_label = QtGui.QLabel("v"+ APP_VERSION,self.statusbar)
        self.status_label.setIndent(10)

        self.donate_button = QtGui.QPushButton("   " + _("Help us with a donation"))
        #self.donate_button.setIndent(10)
        
        icondonate = QtGui.QIcon()
        icondonate.addPixmap(QtGui.QPixmap(":/icons/love.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.donate_button.setIcon(icondonate)
            
        self.statusbar.insertWidget(0,self.status_label)
        self.statusbar.addPermanentWidget(self.donate_button, 0)
        QObject.connect(self.donate_button, SIGNAL("clicked(bool)"), self.onMenuHelpDonation)
        #Own signals
        QObject.connect(self, SIGNAL("SoftwareUpdateDetected(QString,QString)"), self.OnSoftwareUpdateDetected)

        self.definitionToolbar = QToolBar(self)
        self.definitionToolbar.setIconSize(QSize(22, 22))
        self.definitionView._main = self #That way we can use getMainApp from definitionView
        self.actionBackward = QtGui.QAction(QIcon(":/icons/go-previous.png"),_("Go to &previous article"),self)
        QObject.connect(self.actionBackward, SIGNAL("triggered()"), self.onActionBackward)
        self.actionBackward.setEnabled(False)
        self.definitionToolbar.addAction(self.actionBackward)

        self.actionForward = QtGui.QAction(QIcon(":/icons/go-next.png"),_("Go to &next article"),self)
        self.actionForward.setEnabled(False)
        QObject.connect(self.actionForward, SIGNAL("triggered()"), self.onActionForward)
        self.definitionToolbar.addAction(self.actionForward)

        self.actionDefinitionSaveAs = QtGui.QAction(QIcon(":/icons/document-save-as.png"),_("&Save to file"),self)
        QObject.connect(self.actionDefinitionSaveAs, SIGNAL("triggered()"), self.onActionDefinitionSaveAs)
        self.definitionToolbar.addAction(self.actionDefinitionSaveAs)
        self.actionDefinitionSaveAs.setEnabled(False)

        self.actionPrint = QtGui.QAction(QIcon(":/icons/document-print.png"),_("Prin&t article"),self)
        QObject.connect(self.actionPrint, SIGNAL("triggered()"), self.onActionPrint)
        self.definitionToolbar.addAction(self.actionPrint)
        self.actionPrint.setEnabled(False)

        self.actionSpeak = QtGui.QAction(QIcon(":/icons/speaker.png"),_("Speak &word"),self)
        QObject.connect(self.actionSpeak, SIGNAL("triggered()"), self.onActionSpeak)
        self.definitionToolbar.addAction(self.actionSpeak)
        self.actionSpeak.setEnabled(False)

        self.verticalDefinitionLayout.insertWidget(0, self.definitionToolbar)

        self.splitter.setSizes([250, 500])
        self.definitionView.setIntroduction()

        self.contentSearchText.setFocus()
        self.articlesText.setFocus()

        vh = self.wordList.verticalHeader().setVisible(False)
        hh = self.wordList.horizontalHeader()
        hh.setStretchLastSection(True)
        hh.setVisible(False)

        #font = QFont("KhmerOS", 8)
        #self.wordList.setFont(font)

        vh = self.historyList.verticalHeader().setVisible(False)
        hh = self.historyList.horizontalHeader()
        hh.setStretchLastSection(True)
        hh.setVisible(False)

        vh = self.contentSearchList.verticalHeader().setVisible(False)
        hh = self.contentSearchList.horizontalHeader()
        hh.setStretchLastSection(True)
        hh.setVisible(False)

        if not options.test:
            thread.start_new_thread(self.establishServerConnection, ())

            self.dictFileManager = DictFileManager(self, splash)

            settingsDictsDirectory = self.dictFileManager.getSettingsDictionaryDirectory()
            if settingsDictsDirectory == None:

                if platform.system() == "Linux":
                    defaultDictsDirectory =  self.dictFileManager.getHomeUserDictionariesDirectory()
                else:
                    defaultDictsDirectory =  self.dictFileManager.getRelativeDictionariesDirectory()

                self.settings.setValue("settings/dictsDefaultDirectory", QVariant(defaultDictsDirectory))
                log.debug('Autodetected dictionaries directory at %s' % defaultDictsDirectory)
            else:
                defaultDictsDirectory = settingsDictsDirectory
                log.debug('Detected dictionaries directory from settings at %s' % defaultDictsDirectory)

            if defaultDictsDirectory != None:
                self.dictFileManager.loadDirectory()

        else :
            #testdict = self.engine.installDictionary('dicts/sampledict.dwa')
            #testdict = self.engine.installDictionary('dicts/Catalan_English.dct')
            #testdict = self.engine.installDictionary('dicts/vi_en.dct')
            #testdict = self.engine.installDictionary('dicts/ChuonNath.dct')
            testdict = self.engine.loadDictionary('own_dicts/dictionaries-bolivia/es_qu-laime/DicQuechuaBolivia-es.dict.dz')

            if testdict['loaded']:
                self.loadDictionary(testdict['dict'])

        splash.finish(self)
        self.recallWinSize()
        self.show()

    def createTray(self):
        self.systray = QtGui.QSystemTrayIcon(QIcon(":/icons/babiloo64.png"), self)
        trayIconMenu = QtGui.QMenu(self)
        trayIconMenu.addAction(self.actionQuit)
        self.systray.setContextMenu(trayIconMenu)
        self.connect(self.systray, QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"),
                self.__icon_activated)
        self.systray.show()

    def recallWinSize(self):
        self.settings.beginGroup("mainWindow")
        self.resize(self.settings.value("size", QVariant(QSize(640, 480))).toSize())
        self.move(self.settings.value("pos", QVariant(QPoint(200, 200))).toPoint())
        self.settings.endGroup()

    def writeWinSize(self):
        self.settings.beginGroup("mainWindow")
        self.settings.setValue("size", QVariant(self.size()))
        self.settings.setValue("pos", QVariant(self.pos()))
        self.settings.sync()
        self.settings.endGroup()
        
    def onMenuHelpDonation(self):
        webbrowser.open( "http://www.babiloo-project.org/donations.html", new=2, autoraise=1)

    def establishServerConnection(self):
        try:
            log.debug('Connecting to the Babiloo XMLRPC Server')
            self.OnlineService = OnlineService(self.options.server, self.options.proxy)
            if platform.system() in ("Windows", "Microsoft"):
                self.detect_software_updates()
            return True
        except TimeoutFunctionException:
            log.error('Unable to connect to the Babiloo XMLRPC Server')

   #AutoUpdate alert methods
    def OnSoftwareUpdateDetected(self, new_version, update_link):
        warningBox = QMessageBox(_("New Version Detected"),
                                    _("A new version of Babiloo has been released.\n\nNew Version: %s\nCurrent Version: %s\n\n" \
                                    "Would you like to download the new version now?") %(new_version, APP_VERSION) ,
                                    QMessageBox.Information,
                                    QMessageBox.Yes | QMessageBox.Default ,
                                    QMessageBox.Cancel | QMessageBox.Escape,
                                    QMessageBox.NoButton,
                                    self)
        answer = warningBox.exec_()
        if answer == QMessageBox.Yes:
            webbrowser.open( update_link, new=2, autoraise=1)
        elif answer == QMessageBox.Cancel :
            return

    def detect_software_updates(self):
        #try:
                log.debug('Checking the Software Updates of Babiloo')
                result = self.OnlineService.CheckSoftwareUpdates('Babiloo')
                if utils.compVer(result['latest_version'], APP_VERSION) == 1:  #if APP_VERSION is < than latest_version
                        self.emit(SIGNAL("SoftwareUpdateDetected(QString,QString)"),result['latest_version'], result['link'])
        #except:
           #     log.debug('Error while asking server CheckSoftwareUpdates()')

   #Interface methods
    def onWordListKeyPressed(self, event):
        if type(event) == QtGui.QKeyEvent:
             #here accept the event and do something
            if event.modifiers() == Qt.NoModifier:
                    text = event.text()
                    if text:
                        self.articlesText.setFocus()
                        self.articlesText.keyPressEvent(event)
                        event.ignore()
                        return

        QTableView.keyPressEvent(self.wordList, event)


    def onContentSearchTextDownUpKey(self, event):
        if self.contentSearchModel.getWordList():
            self.contentSearchList.keyPressEvent(event)
            #self.contentSearchList.setFocus()

    def onArticlesTextDownUpKey(self, event):
        if self.wordListModel.getWordList():
            self.wordList.keyPressEvent(event)
           # self.contentSearchList.setFocus()

    def calculateProgramFolder(self):
        if os.path.isdir(sys.path[0]): #for Linux is /program_folder/
            self.programFolder =  sys.path[0]
        else: #for Windows is the /program_folder/run.py
            self.programFolder =  os.path.dirname(sys.path[0])

    def onArticlesTextActivated(self):
        self.wordListModel.updateSelection()
        if self.wordListModel.rowSelected != None:
            word = self.wordListModel.wordlist[self.wordListModel.rowSelected]
            self.searchWord(word)
        elif len(self.wordListModel.getWordList()):
            word = self.wordListModel.getWordList()[0]
            self.searchWord(word)
            firstWordSelection = QItemSelection(self.wordListModel.createIndex(0, 0),self.wordListModel.createIndex(0, 0))
            self.wordListSelectionModel.select(firstWordSelection, self.wordListSelectionModel.ClearAndSelect)
            #self.onArticlesTextEdited()
        else:
            word = unicode(self.articlesText.text())
            if word:
                self.searchWord(word)

    def onArticlesTextEdited(self):
        if self.activeDictionary:
            word = unicode(self.articlesText.text())
            self.wordListSelectionModel.clearSelection()
            if self.settings.value("settings/autoComplete", QVariant(True)).toBool():
                self.wordList.scrollTo(self.wordList.currentIndex())
                caseSensitive = self.settings.value("settings/caseSensitive", QVariant(False)).toBool()
                ignoreAccents = self.settings.value("settings/ignoreAccents", QVariant(True)).toBool()
                filteredWords = self.engine.filter(word, self.activeDictionary,caseSensitive , ignoreAccents)
                self.wordListModel.setWordList(filteredWords)
                if len(filteredWords) and self.wordListModel.getWordList()[0] == word or len(filteredWords) == 1:
                    #select the first word
                    firstWordSelection = QItemSelection(self.wordListModel.createIndex(0, 0),self.wordListModel.createIndex(0, 0))
                    self.wordListSelectionModel.select(firstWordSelection, self.wordListSelectionModel.ClearAndSelect)
                    #self.wordList.selectRow(0)

    def onArticlesSearchButton(self):
        self.wordListModel.updateSelection()
        if self.wordListModel.rowSelected != None:
            word = self.wordListModel.wordlist[self.wordListModel.rowSelected]
        else:
            word = unicode(self.articlesText.text())

        if word:
            self.searchWord(word)

    def onArticlesClearButton(self):
        self.articlesText.setText('')
        if self.activeDictionary:
            self.wordListModel.setWordList(self.engine.getWords(self.activeDictionary))
        else:
            self.wordListModel.clear()

    def onClickWordList(self, index):
        word = self.wordListModel.getWordFromIndex(index)
        #TODO: emit a signal to search the word
        #self._main.emit(SIGNAL('searchWord(QString)'),selection["id"], selection["title"], "search")
        self.searchWord(word)

    def searchWord(self, word):
        definition = None
        if not self.activeDictionary:
            QMessageBox.about(self,_("Error"),_("Please load a dictionary first."))
        else:
            if self.historyListModel.findWord(word, self.activeDictionary):
                log.debug("Found word %s in history" % word)
                definition = self.historyListModel.getDefinition(word)
            else:
                try:
                    definition = self.engine.search(word, self.activeDictionary)
                except:
                    QMessageBox.about(self,_("Error"),_("Error while loading the word %s") % word)
                    return

            dictionaryName = self.engine.getDictionary(self.activeDictionary).getName()
            dictId = self.activeDictionary
            if definition == None:
                self.definitionView.setDefinition(word, None,  None)
                log.debug('No definition found for %s' % word)
            else:
                if isinstance(definition, list):
                    for defin in definition:
                        self.definitionView.setDefinition(word, defin.content(),  None)
                        self.addWordToHistory(word, defin, dictionaryName, dictId)
                elif isinstance(definition, Definition):
                    #print definition.content()
                    self.definitionView.setDefinition(word, definition.content(),  None)
                    self.addWordToHistory(word, definition.content(), dictionaryName, dictId)
                else:
                    self.definitionView.setDefinition(word, definition,  None)
                    self.addWordToHistory(word, definition, dictionaryName, dictId)

                self.articlesText.setText(word)

    def onMenuHelpAbout(self):
        dialog = aboutDialog(self)
        dialog.ui.label_version.setText(APP_VERSION)
        dialog.exec_()
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def onMenuHelpHomePage(self):
        webbrowser.open( "http://www.babiloo-project.org/", new=2, autoraise=1)

    def onMenuHelpReportProblem(self):
        webbrowser.open( "https://bugs.launchpad.net/babiloo", new=2, autoraise=1)

    def onMenuHelpTranslate(self):
        webbrowser.open( "http://www.babiloo-project.org/translate.html", new=2, autoraise=1)

    def onMenuSettings(self):
        self.settingsDialog = settingsDialog(self)
        self.settingsDialog.exec_()
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def onMenuManageDictionaries(self):
        self.settingsDialog = settingsDialog(self)
        self.settingsDialog.show()
        self.settingsDialog.changeTab(self.settingsDialog.TAB_DICTIONARIES)

        self.settingsDialog.ui.tabInstallDictionaries.setCurrentIndex(self.settingsDialog.TAB_MANAGE_DICTIONARIES)
        self.settingsDialog.exec_()

        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def onMenuDownloadDictionaries(self):
        self.settingsDialog = settingsDialog(self)
        self.settingsDialog.changeTab(self.settingsDialog.TAB_DICTIONARIES)
        self.settingsDialog.ui.tabInstallDictionaries.setCurrentIndex(self.settingsDialog.TAB_DOWNLOAD_DICTIONARIES)
        self.settingsDialog.exec_()

        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    def onMenuImportDictionary(self):
        importWildCard = "All files (*.*);;" \
               "Slowo dictionaries (*.dwa);;" \
               "Mova dictionaries (*.mova);;" \
               "DICT dictionaries (*.dz)"

        currentDir = self.settings.value("mainwindow/workingDirectory", QVariant())
        fileNames = QFileDialog.getOpenFileNames(None, _("Import one or more dictionaries"), currentDir.toString(), importWildCard)
        fileNames = [str(file.toUtf8()) for file in fileNames]
        if fileNames:
            self.settings.setValue("mainwindow/workingDirectory", QVariant(QFileInfo(fileNames[0]).absolutePath()))
            dictionaries = self.engine.loadDictionaries(fileNames)
            if len(dictionaries) == len([dict for dict in dictionaries if not dict['loaded'] and dict['error'] != 'ALREADY_INSTALLED' ]):
                QMessageBox.about(self,_("Error"),_("Error trying to load the dictionary.\nFile corrupted or not supported."))
                return

            successfully_installed = []
            unsuccessfully_installed = []
            result_message = u''

            # installing selected dictionaries
            for newdict in dictionaries:
                if not newdict['loaded']:
                    if result_message:
                        result_message += "\n"
                    result_message += _("%s was not loaded: %s") % (os.path.basename(newdict['file_path']), newdict['error'])
                    continue
                newdict = newdict['dict']
                self.loadDictionary(newdict)
                filename = newdict.getFileName()
                try:
                    self.dictFileManager.saveDictionaryFile(newdict)
                    successfully_installed.append(filename)
                except:
                    unsuccessfully_installed.append(filename)

            if len(successfully_installed):
                result_message += _("Dictionary successfully installed.")
            if len(unsuccessfully_installed):
                result_message += "\n" + _("Dictionary selected couldn't be installed.")
            QMessageBox.about(self,_("Info"),result_message)

    def loadDictionary(self, mydict):
        log.debug('main::Loading dictionary: %s' % mydict.getName())
        self.itemDictionary = QtGui.QAction(mydict.getName(),self)
        self.itemDictionary.setCheckable(True)
        dictId = mydict.getUniqueId()

        if not len(self.menuCheckDictionaries):
            self.menuDictionaries.addSeparator()

        self.menuCheckDictionaries[dictId] = self.itemDictionary

        functionDictionary = functools.partial(self.onActivateDictionary, dictId)
        QObject.connect(self.itemDictionary, SIGNAL("toggled (bool)"), functionDictionary)
        self.actionGroupDictionaries.addAction(self.itemDictionary)
        self.menuDictionaries.addAction(self.itemDictionary)
        print self.activeDictionary

        if not self.activeDictionary:
            self.itemDictionary.setChecked(True)
            self.onActivateDictionary(dictId, True)

    def onActivateDictionary(self, dictId, toggle):
        log.debug('main::onActivateDictionary dictId: %s,' % (dictId))
        if toggle:
            if self.activeDictionary != dictId:
                self.activeDictionary = dictId
                self.wordList.scrollTo(self.wordList.currentIndex())
                menuItem = self.menuCheckDictionaries[dictId]
                menuItem.setChecked(True)
                self.engine.loadIndexes(dictId)
                self.wordListModel.setWordList(self.engine.getWords(dictId))
                self.wordList.horizontalHeader().setStretchLastSection(True)

    def updateActiveDictionary(self):
        #check if the active dictionary is still there
        loadedDictIds = self.menuCheckDictionaries.keys()
        if len(loadedDictIds):
            if self.activeDictionary in loadedDictIds:
                self.onActivateDictionary(self.activeDictionary, True)
            else:
                first_dict = loadedDictIds[0]
                self.onActivateDictionary(first_dict, True)
        else:
                self.wordListModel.clear()


##### HISTORY ACTIONS ######

    def onClickHistoryList(self, index):
        word = self.historyListModel.getWordFromIndex(index)
        self.definitionView.setDefinition(word, self.historyListModel.getDefinition(word),  self.historyListModel.getDictionaryName(word))
        self.updateHistoryButtons()

    def onHistorySelectionChanged(self, selected, unselected):
        index = selected.last().bottomRight()
        word = self.historyListModel.getWordFromIndex(index)
        self.definitionView.setDefinition(word, self.historyListModel.getDefinition(word),  self.historyListModel.getDictionaryName(word))
        self.updateHistoryButtons()

    def addWordToHistory(self, word, definition, dictionaryName = None, dictId = None):
        self.historyListModel.addWord(word, definition, dictionaryName, dictId)
        firstRowSelection = QItemSelection(self.historyListModel.index(0, 0),self.historyListModel.index(0, 0))
        self.historyListSelectionModel.select(firstRowSelection, self.historyListSelectionModel.ClearAndSelect)
        self.updateHistoryButtons()

    def updateHistoryButtons(self):
        if self.historyListModel.canBackward():
            self.actionBackward.setEnabled(True)
        else:
            self.actionBackward.setEnabled(False)

        if self.historyListModel.canForward():
            self.actionForward.setEnabled(True)
        else:
            self.actionForward.setEnabled(False)

    #Search Content actions
    def onContentSearchTextActivated(self):
        word = unicode(self.contentSearchText.text())
        if word:
            self.searchContent(word)

    def onContentSearchButton(self, activated):
        word = unicode(self.contentSearchText.text())
        if word:
            self.searchContent(word)

    def searchContent(self, word):
        self.contentSearchModel.stopSearch()
        self.contentSearchModel.clear()
        self.contentSearchProgress.setValue(0)
        self.stopContentSearchButton.setEnabled(True)
        thread.start_new_thread(self.contentSearchModel.search, (word, ))
        #self.contentSearchModel.search(word)

    def onContentSearchClearButton(self):
        self.contentSearchText.setText('')
        self.contentSearchModel.clear()

    def onStopContentSearchButton(self):
        self.contentSearchProgress.setValue(0)
        self.contentSearchModel.stopSearch()
        self.stopContentSearchButton.setEnabled(False)

    def onActionBackward(self):
        self.actionForward.setEnabled(True)
        (word,definition) = self.historyListModel.getBackward()
        self.definitionView.setDefinition(word,  definition,  None)
        log.debug('main::History Backward to %s' %word )
        self.updateHistoryButtons()

    def onActionForward(self):
        self.actionForward.setEnabled(True)
        (word,  definition) = self.historyListModel.getForward()
        self.definitionView.setDefinition(word,  definition,  None)
        log.debug('main::History Forward to %s' %word )
        self.updateHistoryButtons()

#    def onActionStop(self):
#            self.entry.Enable(1)
#            self.SetStatusText(_("Stopped"))
#            self.timerSearch.Stop()
#            self.timerLoad.Stop()
#
#            if self.search:
#             self.search.stop()
#             self.search = None
#
#            if self.load:
#             self.load.stop()
#             self.load = None
#
#            wx.EndBusyCursor()
#            self.buttonStop.Disable()

    def onActionDefinitionSaveAs(self):
        print "onActionDefinitionSaveAs"

    def onActionPrint(self):
        print "onActionPrint"

    def onActionSpeak(self):
        print "onActionSpeak"
        """Pronouce word using external software."""

    def closeEvent(self, event):
        self.writeWinSize()
        self.hide()
        event.ignore()

    def quit_app(self):
        self.writeWinSize()
        QtGui.qApp.quit()

    def __icon_activated(self, reason):
        if reason & (QtGui.QSystemTrayIcon.DoubleClick | QtGui.QSystemTrayIcon.Trigger\
                     & (~QtGui.QSystemTrayIcon.Context)):
            if  self.isVisible():
                self.writeWinSize()
                self.hide()
            else:
                self.recallWinSize()
                self.setVisible(True)

#        word = self.entry.GetValue().strip()
#        if word:
#            cmd = self.app.config.get('pronunciationCommand') or prefswin.PRON_COMMAND
#
#        if self.app.config.get('pronounceTrans') == 'True':
#            word = html2text(self.htmlCode)
#
#        import locale
#        localeCharset = locale.getpreferredencoding()
#
#        try:
#            word = word.replace('(', '').replace(')', '').replace('\n',
#                '').replace('\r', '').replace('"', '\\"')
#            cmd = (cmd % word).encode(localeCharset)
#            Process(os.system, cmd)
#        except Exception, e:
#            traceback.print_exc()
#            title = _("Error")
#            msg = _("Unable to decode text using your locale charset %s" \
#                % localeCharset)
#            errorwin.showErrorMessage(title, msg)

def main(options):
    log.debug("Building main dialog")

    window = Main(options)
    installErrorHandler(QErrorMessage(window))

    log.debug("Showing main dialog")

    return app.exec_()

