aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md30
-rw-r--r--scudcloud-1.0/debian/changelog12
-rw-r--r--scudcloud-1.0/debian/control1
-rw-r--r--scudcloud-1.0/lib/resources.py3
-rwxr-xr-xscudcloud-1.0/lib/scudcloud.py9
-rw-r--r--scudcloud-1.0/lib/speller.py90
-rw-r--r--scudcloud-1.0/lib/wrapper.py17
-rwxr-xr-xscudcloud-1.0/scudcloud2
-rw-r--r--scudcloud-1.0/scudcloud.spec9
9 files changed, 156 insertions, 17 deletions
diff --git a/README.md b/README.md
index 59da367..19dcc79 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
![ScudCloud Logo](/scudcloud-1.0/resources/scudcloud.png?raw=true "Scud clouds are low, ragged and wind-torn cloud fragments, usually not attached to the thunderstorm base. With the 'mother' cloud, the form of them together is like a chat balloon")
-ScudCloud is a **non official** open-source Linux (Debian, Ubuntu, Kubuntu, Mint, Arch, Fedora) desktop client for [Slack©](http://slack.com).
+ScudCloud is a **non official** open-source Linux (Debian, Ubuntu, Kubuntu, Mint, Arch, Fedora) desktop client for [Slack](http://slack.com).
ScudCloud uses the [QT](http://qt-project.org) library + [Webkit](http://www.webkit.org/) to render the web version of Slack, but using the [QWebkit-Native bridge](http://qt-project.org/doc/qt-4.8/qtwebkit-bridge.html) to improve desktop integration with:
@@ -27,7 +27,7 @@ sudo apt-get update
sudo apt-get install scudcloud
```
-If you want **spell checking** (it'll only mark wrong words in red, but no suggestions), add the `hunspell` dictionary for your language. For `en-us`:
+If you want **spell checking**, add the `hunspell` dictionary for your language. For `en-us`:
sudo apt-get install hunspell-en-us
@@ -76,9 +76,9 @@ First, you'll need to install at least packages for `python3`, `python-qt4` (`qt
Then run the below script: it'll download the code and install it:
```bash
-wget https://github.com/raelgc/scudcloud/archive/v1.0.67.tar.gz
-tar -xvf v1.0.67.tar.gz
-cd scudcloud-1.0.67
+wget https://github.com/raelgc/scudcloud/archive/v1.0.69.tar.gz
+tar -xvf v1.0.69.tar.gz
+cd scudcloud-1.0.69
SOURCE="scudcloud-1.0"
INSTALL="/opt/scudcloud"
sudo mkdir -p $INSTALL/lib
@@ -96,35 +96,43 @@ sudo ln -sf $INSTALL/scudcloud /usr/bin/scudcloud
# Troubleshooting
-## 1. Default domain
+#### 1. Default domain
You can change the default domain editing or just deleting the config file:
~/.config/scudcloud/scudcloud.cfg
-## 2. Where is the package for my distro?
+#### 2. Where is the package for my distro?
If not listed above, you're welcome [to contribute](/CONTRIBUTING.md). In this meanwhile, try the [Manual Install](#manual-install) instructions.
-## 3. `Keep me signed in` is not working
+#### 3. Spell checking is not working
+
+Make sure you have the following packages installed:
+
+* `libqtwebkit-qupzillaplugins`
+* `python3-hunspell`
+* `hunspell-en-us`
+
+#### 4. `Keep me signed in` is not working
For some reason, ScudCloud was not able to create the configuration folder. Please, manually create this folder:
~/.config/scudcloud/
-## 4. How to disable Flash?
+#### 5. How to disable Flash?
Flash is required to display embedded videos, but if you don't care, disable it starting with:
scudcloud --no_plugins=True
-## 5. How to start ScudCloud minimized?
+#### 6. How to start ScudCloud minimized?
You can start ScudCloud minized to tray with:
scudcloud --minimized=True
-## 6. High DPI Support
+#### 7. High DPI Support
ScudCloud offers zoom support. The zoom level will be persisted between sessions.
diff --git a/scudcloud-1.0/debian/changelog b/scudcloud-1.0/debian/changelog
index 64777ff..3fa6298 100644
--- a/scudcloud-1.0/debian/changelog
+++ b/scudcloud-1.0/debian/changelog
@@ -1,3 +1,15 @@
+scudcloud (1.0-69) trusty; urgency=medium
+
+ * Fixing crash when python3-hunspell is not present (#237)
+
+ -- Rael Gugelmin Cunha <rael.gc@gmail.com> Tue, 22 Sep 2015 19:54:47 -0300
+
+scudcloud (1.0-68) trusty; urgency=medium
+
+ * Adding HunSpell suggestions (#55)
+
+ -- Rael Gugelmin Cunha <rael.gc@gmail.com> Tue, 22 Sep 2015 16:30:14 -0300
+
scudcloud (1.0-67) trusty; urgency=medium
* Fixing QuickList
diff --git a/scudcloud-1.0/debian/control b/scudcloud-1.0/debian/control
index 9ae96d2..d25cae5 100644
--- a/scudcloud-1.0/debian/control
+++ b/scudcloud-1.0/debian/control
@@ -18,6 +18,7 @@ Recommends: sni-qt,
fonts-lato,
gir1.2-unity-5.0,
libqtwebkit-qupzillaplugins,
+ python3-hunspell,
python3-gi,
ttf-mscorefonts-installer
Description: ScudCloud is a non official desktop client for Slack
diff --git a/scudcloud-1.0/lib/resources.py b/scudcloud-1.0/lib/resources.py
index 6e60bd8..f9835d8 100644
--- a/scudcloud-1.0/lib/resources.py
+++ b/scudcloud-1.0/lib/resources.py
@@ -9,6 +9,9 @@ class Resources:
SSO_URL_RE = re.compile(r'^http[s]://[a-zA-Z0-9_\-]+.slack.com/sso/saml/start$')
SERVICES_URL_RE = re.compile(r'^http[s]://[a-zA-Z0-9_\-]+.slack.com/services/.*')
+ SPELL_DICT_PATH = "/usr/share/hunspell/"
+ SPELL_LIMIT = 6
+
# It's initialized in /scudcloud script
INSTALL_DIR = None
diff --git a/scudcloud-1.0/lib/scudcloud.py b/scudcloud-1.0/lib/scudcloud.py
index fcf98fe..debc808 100755
--- a/scudcloud-1.0/lib/scudcloud.py
+++ b/scudcloud-1.0/lib/scudcloud.py
@@ -4,6 +4,7 @@ from cookiejar import PersistentCookieJar
from leftpane import LeftPane
from notifier import Notifier
from resources import Resources
+from speller import Speller
from systray import Systray
from wrapper import Wrapper
from threading import Thread
@@ -19,7 +20,7 @@ try:
except ImportError:
Unity = None
Dbusmenu = None
- from launcher import DummyLauncher
+ from launcher import DummyLauncher
class ScudCloud(QtGui.QMainWindow):
@@ -27,6 +28,7 @@ class ScudCloud(QtGui.QMainWindow):
debug = False
forceClose = False
messages = 0
+ speller = Speller()
def __init__(self, parent = None, settings_path = ""):
super(ScudCloud, self).__init__(parent)
@@ -258,11 +260,10 @@ class ScudCloud(QtGui.QMainWindow):
for i in range(0, self.stackedWidget.count()):
if self.stackedWidget.widget(i).url().toString().startswith(url):
self.stackedWidget.setCurrentIndex(i)
+ self.quicklist(self.current().listChannels())
exists = True
break
- if exists:
- self.quicklist(self.current().listChannels())
- else:
+ if not exists:
self.addWrapper(url)
self.enableMenus(self.current().isConnected())
diff --git a/scudcloud-1.0/lib/speller.py b/scudcloud-1.0/lib/speller.py
new file mode 100644
index 0000000..6fd34df
--- /dev/null
+++ b/scudcloud-1.0/lib/speller.py
@@ -0,0 +1,90 @@
+import os
+from resources import Resources
+from PyQt4 import QtGui
+from PyQt4.QtCore import QObject
+from PyQt4.QtCore import QLocale, QFile, QTextBoundaryFinder
+
+# Checking if python-hunspell is present
+try:
+ import hunspell
+except ImportError:
+ class hunspell:
+ HunSpell = None
+
+# Simplified version of QupZilla Speller (https://github.com/QupZilla/qupzilla/blob/v1.8/src/lib/plugins/qtwebkit/spellcheck/speller.cpp)
+class Speller(QObject):
+
+ hunspell = None
+ initialized = False
+ startPos = 0
+
+ def __init__(self):
+ super(Speller, self).__init__()
+ if self.initialized or hunspell.HunSpell is None:
+ return
+ dictionaryPath = self.getDictionaryPath()
+ language = self.parseLanguage(dictionaryPath)
+ if dictionaryPath is None or language is None:
+ return
+ self.hunspell = hunspell.HunSpell(dictionaryPath + ".dic", dictionaryPath + ".aff")
+ self.initialized = True
+
+ def isMisspelled(self, s):
+ return not self.hunspell.spell(s)
+
+ def suggest(self, s):
+ return self.hunspell.suggest(s)
+
+ def parseLanguage(self, path):
+ if '/' in path:
+ pos = path.rfind('/')
+ return path[-int(pos + 1):]
+ return path
+
+ def dictionaryExists(self, path):
+ return QFile(path + ".dic").exists() and QFile(path + ".aff").exists();
+
+ def getDictionaryPath(self):
+ dicPath = Resources.SPELL_DICT_PATH + QLocale.system().name()
+ if self.dictionaryExists(dicPath):
+ return dicPath
+ return ''
+
+ def replaceWord(self, element, word):
+ action = self.sender()
+ new = action.data()
+ text = str(element.evaluateJavaScript("this.value"))
+ cursorPos = int(element.evaluateJavaScript("this.selectionStart"))
+ text = text[:self.startPos] + new + text[self.startPos+len(word):]
+ text = text.replace('\\', "\\\\")
+ text = text.replace('\n', "\\n")
+ text = text.replace('\'', "\\'")
+ element.evaluateJavaScript("this.value='{}'".format(text))
+ element.evaluateJavaScript("this.selectionStart=this.selectionEnd={}".format(cursorPos))
+
+ def getWord(self, element):
+ text = str(element.evaluateJavaScript("this.value"))
+ pos = int(int(element.evaluateJavaScript("this.selectionStart")) + int(1))
+ finder = QTextBoundaryFinder(QTextBoundaryFinder.Word, text)
+ finder.setPosition(pos)
+ self.startPos = finder.toPreviousBoundary()
+ return text[self.startPos:finder.toNextBoundary()].strip()
+
+ def populateContextMenu(self, menu, element):
+ word = self.getWord(element)
+ if self.isMisspelled(word):
+ suggests = self.suggest(word)
+ count = Resources.SPELL_LIMIT
+ if len(suggests) < count:
+ count = len(suggests)
+ boldFont = menu.font()
+ boldFont.setBold(True)
+ for i in range(0, count):
+ action = QtGui.QAction(suggests[i], self)
+ action.triggered.connect(lambda:self.replaceWord(element, word))
+ action.setData(suggests[i])
+ action.setFont(boldFont)
+ menu.addAction(action)
+ if count == 0:
+ menu.addAction(menu.tr("No suggestions")).setEnabled(False)
+ menu.addSeparator();
diff --git a/scudcloud-1.0/lib/wrapper.py b/scudcloud-1.0/lib/wrapper.py
index 994d0d7..44a8cda 100644
--- a/scudcloud-1.0/lib/wrapper.py
+++ b/scudcloud-1.0/lib/wrapper.py
@@ -49,6 +49,23 @@ class Wrapper(QWebView):
self.pageAction(QWebPage.Forward).setShortcuts(QKeySequence.Forward)
self.pageAction(QWebPage.Reload).setShortcuts(QKeySequence.Refresh)
+ def contextMenuEvent(self, event):
+ menu = QtGui.QMenu(self)
+ if self.window.speller.initialized:
+ hit = self.page().currentFrame().hitTestContent(event.pos())
+ element = hit.element()
+ if hit.isContentEditable() and not hit.isContentSelected() and element.attribute("type") != "password":
+ self.window.speller.populateContextMenu(menu, element)
+ pageMenu = self.page().createStandardContextMenu()
+ if pageMenu is not None:
+ for a in pageMenu.actions():
+ if a.isSeparator():
+ menu.addSeparator()
+ elif a.isVisible():
+ menu.addAction(a)
+ del pageMenu
+ menu.exec_(event.globalPos())
+
def call(self, function, arg=None):
if isinstance(arg, str):
arg = "'"+arg+"'"
diff --git a/scudcloud-1.0/scudcloud b/scudcloud-1.0/scudcloud
index 9af00db..919467c 100755
--- a/scudcloud-1.0/scudcloud
+++ b/scudcloud-1.0/scudcloud
@@ -14,7 +14,7 @@ from qsingleapplication import QSingleApplication
# The ScudCloud QMainWindow
win = None
-VERSION = '1.0.67'
+VERSION = '1.0.69'
def main():
global win;
diff --git a/scudcloud-1.0/scudcloud.spec b/scudcloud-1.0/scudcloud.spec
index 22b39a2..9042a36 100644
--- a/scudcloud-1.0/scudcloud.spec
+++ b/scudcloud-1.0/scudcloud.spec
@@ -1,7 +1,7 @@
#
# spec file for package scudcloud
#
-# Copyright (c) 2015 Marcin Trendota (moonwolf@techsterowniki.pl)
+# Copyright (c) 2015 Marcin Trendota (moonwolf@poczta.onet.pl)
# Copyright (c) 2015 Marcin Bajor (marcin.bajor@gmail.com)
#
# All modifications and additions to the file contributed by third parties
@@ -43,6 +43,11 @@ Url: https://github.com/raelgc/scudcloud/
Source: %{name}-%{version}.tar.gz
Requires: python3
Requires: python3-qt4
+%if 0%{?suse_version}
+Requires: google-lato-fonts
+%else
+Requires: lato-fonts
+%endif
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
@@ -142,6 +147,8 @@ fi
%{_bindir}/scudcloud
%changelog
+* Mon Sep 21 2015 Marcin Trendota <moonwolf@poczta.onet.pl>
+- Add lato-fonts dependency
* Mon Aug 10 2015 Marcin Bajor <marcin.bajor@gmail.com>
- Now build for CentOS, Red Hat Enterprise Linux, openSUSE, SUSE Linux Enterprise Server and others is possible
* Mon May 18 2015 Marcin Trendota <moonwolf@poczta.onet.pl>