Invisible navigation fixes, URLPlayer volume fixes, shutdown fix

This commit is contained in:
Manuel Cortez 2015-01-20 22:07:13 -06:00
parent c25412bd32
commit 399de75d64
6 changed files with 130 additions and 110 deletions

112
README.md Normal file
View File

@ -0,0 +1,112 @@
TWBlue - Next generation
======
Note
======
Please note that this branch is a new generation of TWBlue, so the code is been written using the MVC design pattern and it is very unstable. This code does not works properly and it is not recommended its use, only you use this code for testing purposes. You may find some huge bugs, because we're written most of the source code from scratch.
TWBlue, an accessible, open source and multiplatform twitter application.
TW Blue is an app designed to use Twitter in a simple and fast way and avoiding, as far as possible, the consumtion of excessive resources of the machine where its running. With this app youll have access to twitter features such as:
* Create, reply to, retweet and delete tweets,
* Add and remove tweets from favourites,
* Send and delete direct messages,
* See your friends and followers,
* Follow, unfollow, block and report users as spam,
* Open a users timeline, which will allow you to get that users tweets separately,
* Open URL addresses when attached to a tweet or direct message,
* Play various file and URL types which contain audio
* and more!
See the [TWBlue's webpage](http://twblue.com.mx) for more details.
## Using TWBlue from sources
This document describes how to run tw blue from source, and, after that, how to build a binary version, which doesn't need Python and the other dependencies to run.
### Required dependencies.
Although most dependencies can be found in the windows-dependencies directory, we provide links to their official websites. If you are cloning with git, don't forget to initialize and update the submodules to get the windows-dependencies folder. You can use these two commands to perform this task from git bash:
git submodule init
git submodule update
All the dependencies provided in this folder are prebuilt. If you want to build them from source, you will need Microsoft visual Studio 2008.
#### Dependencies packaged in windows installers
* [Python,](http://python.org) version 2.7.9
If you want to build both x86 and x64 binaries, you can install python x86 to C:\python27 and python x64 to C:\python27x64, for example.
* [wxPython](http://www.wxpython.org) for Python 2.7, version 3.0.2
* [Python windows extensions (pywin32)](http://www.sourceforge.net/projects/pywin32/) for python 2.7, build 219
* [Pycurl](http://pycurl.sourceforge.net) 7.19.5 for Python 2.7: [32-bit downloads,](https://pypi.python.org/pypi/pycurl/7.19.3.1) [64-bit downloads](http://www.lfd.uci.edu/~gohlke/pythonlibs/)
* [PyEnchant,](http://pythonhosted.org/pyenchant/) version 1.6.6.
x64 version has been built by TW Blue developers, so you only will find it in windows-dependencies folder
The windows installers are available only in the windows-dependencies folder
To build a binary version:
* [Py2exe](http://www.sourceforge.net/projects/py2exe/) for Python 2.7, version 0.6.9
#### Dependencies that must be installed using easy_install
setuptools install a script, called easy_install. You can find it in the python scripts directory. To install packages using easy_install, you have to navigate to the scripts directory using a command prompt, for example:
cd C:\python27x64\scripts
You can also add the scripts folder to your path environment variable.
After that, run the following command to install a package, replacing packagename with the names listed below:
easy_install -Z package
The -z switch unzips the package, instead of installing it compressed. If you add the --upgrade switch, you can upgrade a package to its latest version. The following packages need to be installed:
* pubsub
* dropbox
* configobj
* requests-oauthlib
* future
* pygeocoder
* suds
* arrow
* markdown
easy_install will automatically get the additional libraries that these packages need to work properly.
#### Other dependencies
These dependencies are located in the windows-dependencies directory. You don't need to install or modify them.
* Bootstrap 1.2.1: included in dependencies directory.
This dependency has been built using pure basic 4.61. Its source can be found at http://hg.q-continuum.net/updater
* [oggenc2.exe,](http://www.rarewares.org/ogg-oggenc.php) version 2.87
* Microsoft Visual c++ 2008 redistributable dlls.
#### Dependencies required to build the installer
* [NSIS unicode,](http://www.scratchpaper.com/) version 2.46.5
### Running TW Blue from source
Now that you have installed all these packages, you can run TW Blue from source using a command prompt. Navigate to the src directory into the repo, and type the following command:
python main.py
If necesary, change the first part of the command to reflect where is your python executable. You can run TW Blue using python x86 and x64
### Building a binary version
A binary version doesn't need python and the other dependencies to run, it's the same version that you will find in TW Blue website if you download the zip files.
To build it, run the following command from the src folder:
python setup.py py2exe
You will find the binaries in the dist directory.
### How to generate a translation template
You must run the gen_pot.bat file, located in the tools directory. Your python installation should be in your path environment variable. The pot file will appear in the tools directory too.

View File

@ -49,8 +49,8 @@ class bufferController(object):
self.session.settings["sound"]["volume"] = 0.0 self.session.settings["sound"]["volume"] = 0.0
else: else:
self.session.settings["sound"]["volume"] -=0.05 self.session.settings["sound"]["volume"] -=0.05
if hasattr(sound.URLStream, "stream"): if hasattr(sound.URLPlayer, "stream"):
sound.URLStream.stream.volume = self.session.settings["sound"]["volume"] sound.URLPlayer.stream.volume = self.session.settings["sound"]["volume"]
self.session.sound.play("volume_changed.ogg") self.session.sound.play("volume_changed.ogg")
def volume_up(self): def volume_up(self):
@ -59,8 +59,8 @@ class bufferController(object):
self.session.settings["sound"]["volume"] = 1.0 self.session.settings["sound"]["volume"] = 1.0
else: else:
self.session.settings["sound"]["volume"] +=0.05 self.session.settings["sound"]["volume"] +=0.05
if hasattr(sound.URLStream, "stream"): if hasattr(sound.URLPlayer, "stream"):
sound.URLStream.stream.volume = self.session.settings["sound"]["volume"] sound.URLPlayer.stream.volume = self.session.settings["sound"]["volume"]
self.session.sound.play("volume_changed.ogg") self.session.sound.play("volume_changed.ogg")
def start_stream(self): def start_stream(self):

View File

@ -94,6 +94,8 @@ class Controller(object):
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close)
if widgetUtils.toolkit == "wx":
widgetUtils.connectExitFunction(self.exit)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_tweet, self.view.compose) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_tweet, self.view.compose)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_reply, self.view.reply) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_reply, self.view.reply)
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_retweet, self.view.retweet) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.post_retweet, self.view.retweet)
@ -359,6 +361,7 @@ class Controller(object):
if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False:
self.register_invisible_keyboard_shorcuts(km) self.register_invisible_keyboard_shorcuts(km)
self.view.Hide() self.view.Hide()
self.fix_wrong_buffer()
self.showing = False self.showing = False
else: else:
if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False:
@ -383,6 +386,11 @@ class Controller(object):
def buffer_changed(self, *args, **kwargs): def buffer_changed(self, *args, **kwargs):
if self.get_current_buffer().account != self.current_account: self.current_account = self.get_current_buffer().account if self.get_current_buffer().account != self.current_account: self.current_account = self.get_current_buffer().account
def fix_wrong_buffer(self):
buffer = self.get_current_buffer()
if buffer.session == None:
self.right()
def up(self, *args, **kwargs): def up(self, *args, **kwargs):
page = self.get_current_buffer() page = self.get_current_buffer()
position = page.buffer.list.get_selected() position = page.buffer.list.get_selected()

View File

@ -1,105 +0,0 @@
# Copyright (c) 2006, 2007, 2010 Alexander Belchenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""Helper for standard gettext.py on Windows.
Module obtains user language code on Windows to use with standard
Python gettext.py library.
The module provides 2 functions: setup_env and get_language.
You may use setup_env before initializing gettext functions.
Or you can use get_language to get the list of language codes suitable
to pass them to gettext.find or gettext.translation function.
Usage example #1:
import gettext, gettext_windows
gettext_windows.setup_env()
gettext.install('myapp')
Usage example #2:
import gettext, gettext_windows
lang = gettext_windows.get_language()
translation = gettext.translation('myapp', languages=lang)
_ = translation.gettext
"""
import locale
import os
import sys
OS_WINDOWS = (sys.platform == 'win32')
def setup_env_windows(system_lang=True):
"""Check environment variables used by gettext
and setup LANG if there is none.
"""
if _get_lang_env_var() is not None:
return
lang = get_language_windows(system_lang)
if lang:
os.environ['LANGUAGE'] = ':'.join(lang)
def get_language_windows(system_lang=True):
"""Get language code based on current Windows settings.
@return: list of languages.
"""
try:
import ctypes
except ImportError:
return [locale.getdefaultlocale()[0]]
# get all locales using windows API
lcid_user = ctypes.windll.kernel32.GetUserDefaultLCID()
lcid_system = ctypes.windll.kernel32.GetSystemDefaultLCID()
if system_lang and lcid_user != lcid_system:
lcids = [lcid_user, lcid_system]
else:
lcids = [lcid_user]
return filter(None, [locale.windows_locale.get(i) for i in lcids]) or None
def setup_env_other(system_lang=True):
pass
def get_language_other(system_lang=True):
lang = _get_lang_env_var()
if lang is not None:
return lang.split(':')
return None
def _get_lang_env_var():
for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
lang = os.environ.get(i)
if lang:
return lang
return None
if OS_WINDOWS:
setup_env = setup_env_windows
get_language = get_language_windows
else:
setup_env = setup_env_other
get_language = get_language_other

View File

@ -1,5 +1,6 @@
from gi.repository import Gtk, Gdk from gi.repository import Gtk, Gdk
toolkit = "gtk"
# Code responses for GTK +3 dialogs. # Code responses for GTK +3 dialogs.
# this is when an user presses OK on a dialogue. # this is when an user presses OK on a dialogue.
OK = Gtk.ResponseType.OK OK = Gtk.ResponseType.OK

View File

@ -1,5 +1,6 @@
import wx import wx
toolkit = "wx"
# Code responses for WX dialogs. # Code responses for WX dialogs.
# this is when an user presses OK on a dialogue. # this is when an user presses OK on a dialogue.
OK = wx.ID_OK OK = wx.ID_OK
@ -36,3 +37,6 @@ def connect_event(parent, event, func, menuitem=None, *args, **kwargs):
return getattr(parent, "Bind")(event, func, *args, **kwargs) return getattr(parent, "Bind")(event, func, *args, **kwargs)
else: else:
return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs) return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs)
def connectExitFunction(exitFunction):
wx.GetApp().Bind(wx.EVT_END_SESSION, exitFunction)