def createConfigurationInterface(self, parent): ##The dictionary backend configuration self.backend_config = Dict_Backend_Config(self) p = parent.addPage(self.backend_config, "Backend") p.setIcon(kdeui.KIcon("accessories-dictionary")) ##The appearance configuration part self.appearance_config = Appearance_Config(self) p2 = parent.addPage(self.appearance_config, "Appearance") p2.setIcon(kdeui.KIcon("preferences-desktop-color")) ##Final bits self.connect(parent, SIGNAL("okClicked()"), self.configAccepted) self.connect(parent, SIGNAL("cancelClicked()"), self.configDenied)
class PythonDictionary(plasmascript.Applet): def __init__(self,parent,args=None): plasmascript.Applet.__init__(self, parent) self.determine_capabilities() self.definition = [] self.word = None self.engines = {} if self.has_engine: self.engines["dict-dataengine"] = self.define_via_dict_dataengine if self.has_dict_client: self.engines["dict-client"] = self.define_via_dict_client if self.has_python_dictclient: self.engines["python-dictclient"] = self.define_via_python_dict_client self.height = 60 def init(self): #configuration self.setHasConfigurationInterface(True) #open config file configuration = self.config() #configurations settings self.chosen_engine = unicode(configuration.readEntry("engine", self.engines.keys()[-1]).toString()) self.server = unicode(configuration.readEntry("server", "dict.org").toString()) self.width = int(configuration.readEntry("width", "200").toString()) self.text_color = unicode(configuration.readEntry("textColor", "#000000").toString()) self.force_bw_definition = configuration.readEntry("force_bw_definition", False).toBool() #configure non-configurable settings self.setAspectRatioMode(Plasma.IgnoreAspectRatio) self.theme = Plasma.Svg(self) self.theme.setImagePath("widgets/background") self.setBackgroundHints(Plasma.Applet.DefaultBackground) self.layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet) self.combobox = Plasma.ComboBox() self.combobox.nativeWidget().setEditable(True) self.combobox.setFocusPolicy(Qt.ClickFocus) self.combobox.nativeWidget().setContextMenuPolicy(Qt.NoContextMenu) self.update_text_color() self.lineEdit = self.combobox.nativeWidget().lineEdit() self.connect(self.combobox.nativeWidget(), SIGNAL("returnPressed()"), self.lookup_word) self.connect(self.combobox.nativeWidget(), SIGNAL("activated()"), self.focusWidget) self.lineEdit.installEventFilter(self) self.lineEdit.setFont(Plasma.Theme.defaultTheme().font(Plasma.Theme.DesktopFont)) self.layout.addItem(self.combobox) self.setLayout(self.layout) self.set_combo_width(self.width) ##END INIT METHOD### ###FOCUS FIX### # These methods fix the problem with getting a focus to the combobox # when there are active windows open. def focusWidget(self): #adapted from Run Command Applet. # thanks Michal Dutkiewicz aka Emdek <*****@*****.**> if self.scene(): parentView = None possibleParentView = None for view in self.scene().views(): if view.sceneRect().intersects(self.sceneBoundingRect()) or view.sceneRect().contains(self.scenePos()): if view.isActiveWindow(): parentView = view break else: possibleParentView = view if not parentView: parentView = possibleParentView if parentView: kdeui.KWindowSystem.forceActiveWindow(parentView.winId()) self.raise_() self.combobox.nativeWidget().setFocus() QTimer.singleShot(250, self.combobox.nativeWidget(), SLOT("setFocus()")) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.focusWidget() def eventFilter(self, myobject, event): if (event.type() ==QEvent.MouseButtonPress): self.focusWidget() return False ###END FOCUS FIX ### def determine_capabilities(self): ## Check to see if python-dictclient is an option: self.has_python_dictclient = has_python_dictclient ## Check to see if there is a local instance of dict client: self.has_dict_client = (subprocess.call(["which", "dict"]) == 0) ## Use the engine as a last resort (no offense...) self.has_engine = True def de_markup(self, text): regex = re.compile('<[^>]*>') return regex.sub('', text).strip().replace("\r", "\n") def ping(self): KMessageBox.information(None, "ping", "ping") ###WORD LOOKUP METHODS### def lookup_word(self, word=None): if word is None: self.word = unicode(self.combobox.text()) else: self.word = word self.combobox.nativeWidget().setCurrentItem("") #TODO: timeout this next call self.engines[self.chosen_engine]() ###show the messagebox def show_definitions(self, match=False): dialog_data = {} if len(self.definition) > 0: dialog_data["is_match"] = match dialog_data["summary"] = self.definition[0] dialog_data["definition"] = self.definition[1:] dialog_data["title"] = "Definition of %s" % self.word self.definition_dialog(dialog_data) self.definition = [] else: kdeui.KMessageBox.information(self.combobox.nativeWidget(), "There was some kind of weird problem, you shouldn't be seeing this. Please report to the author.", "Definition of %s" % self.word) def definition_dialog(self, data): self.def_dialog = kdeui.KDialog() self.def_dialog.force_bw_definition = self.force_bw_definition self.def_dialog.setWindowTitle(data["title"]) if not data["is_match"]: self.def_widget = Definition_View_Tabbed(self.def_dialog, data) else: self.def_widget = Match_View_Widget(self, data) self.def_dialog.setButtons(kdeui.KDialog.ButtonCode(kdeui.KDialog.Close)) self.def_dialog.setMainWidget(self.def_widget) self.def_dialog.show() def define_via_dict_client(self): #code for using the CLI dict command is_match = False if self.word.isalnum(): command = "dict -f" if self.server is not None: command += " -h %s" % self.server command += " %s" % self.word defs = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) defs = list(defs.stdout) + list(defs.stderr) #Reformat that rather ungainly dict output into distinct definitions #Unicode fix here and a few lines down from kozakmamay; thanks! self.definition = [unicode(defs.pop(0), "utf-8")] #the first line is the summary is_match = re.search('perhaps you mean', self.definition[0]) is not None if not is_match: a_def = "" while defs: line = unicode(defs.pop(0), "utf-8") if not re.match(" ", line): if a_def: #if it's not empty, add the current defintion to the list self.definition.append(a_def) a_def = line.split("\t")[-1] else: #two leading spaces indicate a definition line a_def += line self.definition.append(a_def) #get the last line. Yeah, this is ugly. else: #if it's a match while defs: self.definition.append(defs.pop(0).split("\t")[-1].strip()) else: self.definition = ["Invalid Word."] self.show_definitions(is_match) def define_via_python_dict_client(self): #code for using the python-dictclient library conn = dictclient.Connection(self.server) defs = conn.define("*", self.word) num_defs = len(defs) is_match = False if (num_defs==0): #no defs, matching defs = conn.match("*","soundex", self.word) defs = ["%s\n" % x.getword() for x in defs] perhaps = ", perhaps you mean:" is_match =True else: defs = ["%s:\n\n%s\n" % (x.getdb().getdescription() ,x.getdefstr()) for x in defs] perhaps = "." #Prepare the output s = (num_defs !=1) and "s" or "" self.definition.append("%d definition%s found%s\n"%(num_defs, s, perhaps)) self.definition += defs self.show_definitions(is_match) def define_via_dict_dataengine(self): #code for using the plasma dataengine (currently broken) self.dict_engine = self.dataEngine("dict") mydef = self.dict_engine.connectSource(QString(self.word), self) #Once connectSource is called, dataUpdated() will do the rest... @pyqtSignature("dataUpdated(const QString &, const Plasma::DataEngine::Data &)") def dataUpdated(self, sourceName, data): """ This implementation bears some explanation. When we call connectSource() in define_via_dict_dataengine(), the dataengine will immediately call dataUpdated() with bad data: our word as a source, and an empty set for results. Once it actually hears back from the server, we'll get back a single definition with markup, OR and empty set of markup tags if no definition was found. Ugh. So, first we filter for no definitions, and do nothing if there are none. Then, if we get one, we remove the tags and see if there's anything left. If not, we tell the user there was no definition found. Otherwise, we print the tag-stripped definition (since I don't know how to get the KMessageBox.informationList to use the tags). If there's a better way to implement this, I'm open to suggestion... """ if sourceName == self.word: num_defs = len(data) s = (num_defs != 1) and "s" or "" self.definition = ["%d definition%s found.\n" % (num_defs, s)] if num_defs > 0: text = self.de_markup(unicode(data[QString("text")].toString())) if text != "": self.definition += ["WordNet"] self.definition += [text] else: self.definition = ["No definitions found."] self.show_definitions() ### CONFIGURATION RELATED CODE ######## def createConfigurationInterface(self, parent): ##The dictionary backend configuration self.backend_config = Dict_Backend_Config(self) p = parent.addPage(self.backend_config, "Backend") p.setIcon(kdeui.KIcon("accessories-dictionary")) ##The appearance configuration part self.appearance_config = Appearance_Config(self) p2 = parent.addPage(self.appearance_config, "Appearance") p2.setIcon(kdeui.KIcon("preferences-desktop-color")) ##Final bits self.connect(parent, SIGNAL("okClicked()"), self.configAccepted) self.connect(parent, SIGNAL("cancelClicked()"), self.configDenied) def showConfigurationInterface(self): self.dialog = kdeui.KPageDialog() self.dialog.setFaceType(kdeui.KPageDialog.List) self.dialog.setButtons(kdeui.KDialog.ButtonCode(kdeui.KDialog.Ok | kdeui.KDialog.Cancel)) self.createConfigurationInterface(self.dialog) self.dialog.resize(640,480) self.dialog.show() def configDenied(self): configuration = self.config() self.width = int(configuration.readEntry("width", "200").toString()) self.set_combo_width(self.width) def configAccepted(self): self.chosen_engine = self.backend_config.get_backend() self.server = self.backend_config.get_server_url() self.text_color = self.appearance_config.get_text_color() self.update_text_color() self.width = self.appearance_config.get_width() self.set_combo_width(self.width) self.force_bw_definition = self.appearance_config.get_force_bw_defs() configuration = self.config() configuration.writeEntry("engine", QVariant(self.chosen_engine)) configuration.writeEntry("server", QVariant(self.server)) configuration.writeEntry("width", QVariant(self.width)) configuration.writeEntry("textColor", QVariant(self.text_color)) configuration.writeEntry("force_bw_definition", QVariant(self.force_bw_definition)) ##appearance related def set_combo_width(self, width): if self.containment().containmentType() == Plasma.Containment.PanelContainment: self.combobox.nativeWidget().setMinimumWidth(width) self.boundingRect().setWidth(width) else: self.resize(width, self.height) self.combobox.nativeWidget().setMinimumWidth(width-40) def update_text_color(self): self.combobox.setStyleSheet("color: %s;"% self.text_color)