mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-25 17:39:23 +00:00
Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
f9864a887d | |||
3d8519313e | |||
f4ecf10885 | |||
c67b415934 | |||
10511d3022 | |||
9ea36a26d2 | |||
97286496fc | |||
![]() |
6436af76f5 | ||
![]() |
576b5064c0 | ||
![]() |
342265b3c0 | ||
![]() |
54938ecb6c | ||
![]() |
7aff8252d2 | ||
![]() |
9c680130f7 | ||
24d1ad093d | |||
b2b9cd810f | |||
582be54dea | |||
ff0fbeafa3 | |||
e314cf0599 | |||
![]() |
e7b72112cf | ||
![]() |
70c095febe | ||
6119b029f8 | |||
b74cd9a73d | |||
8ff6809f08 | |||
39af9d8623 | |||
3688d7548c | |||
07f9afb14e | |||
de12dadac2 | |||
877c909482 | |||
![]() |
1206aba83b | ||
![]() |
fcd631b2de | ||
![]() |
86130954d7 | ||
![]() |
23a56c637d | ||
![]() |
d5ac0db67b | ||
bb4869b7be | |||
44b6e82183 | |||
![]() |
5268f166f8 | ||
![]() |
37ad6b5fbf | ||
![]() |
bcc72c932d |
@@ -17,7 +17,7 @@ snapshot32:
|
||||
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- choco install python --version 3.8.7 -y -ForceX86
|
||||
- choco install python --version 3.8.10 -y -ForceX86
|
||||
- '&$env:PYTHON -V'
|
||||
- '&$env:PYTHON -m pip install --upgrade pip'
|
||||
- '&$env:PYTHON -m pip install --upgrade -r requirements.txt'
|
||||
@@ -54,7 +54,7 @@ snapshot64:
|
||||
- Set-Variable -Name "time" -Value (date -Format "%H:%m")
|
||||
- echo ${time}
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
- choco install python --version 3.8.7 -y
|
||||
- choco install python --version 3.8.10 -y
|
||||
- '&$env:PYTHON -V'
|
||||
- '&$env:PYTHON -m pip install --upgrade pip'
|
||||
- '&$env:PYTHON -m pip install --upgrade -r requirements.txt'
|
||||
|
@@ -2,6 +2,14 @@
|
||||
|
||||
## changes in this version
|
||||
|
||||
* When reading a tweet, if the tweet contains more than 2 consecutive mentions, TWBlue will announce how many more users the tweet includes, as opposed to read every user in the conversation. You still can display the tweet to read all users.
|
||||
* In the tweet displayer, It is possible to copy a link to the current tweet or person by pressing a button called "copy link to clipboard".
|
||||
* Added a keymap capable to work under Windows 11. ([#391](https://github.com/manuelcortez/TWBlue/pull/391))
|
||||
* Added user aliases to TWBlue. This feature allows you to rename user's display names on Twitter, so the next time you'll read an user it will be announced as you configured. For adding an alias to an user, select the "add alias" option in the user menu, located in the menu bar. This feature works only if you have set display screen names unchecked. Users are displayed with their display name in people buffers only. This action is supported in all keymaps, although it is undefined by default. ([#389](https://github.com/manuelcortez/TWBlue/pull/389))
|
||||
* There are some changes to the autocomplete users feature:
|
||||
* Now users can search for twitter screen names or display names in the database.
|
||||
* It is possible to undefine keystrokes in the current keymap in TWBlue. This allows you, for example, to redefine keystrokes completely.
|
||||
* We have changed our Geocoding service to the Nominatim API from OpenStreetMap. Addresses present in tweets are going to be determined by this service, as the Google Maps API now requires an API key. ([#390](https://github.com/manuelcortez/TWBlue/issues/390))
|
||||
* Added a limited version of the Twitter's Streaming API: The Streaming API will work only for tweets, and will receive tweets only by people you follow. Protected users are not possible to be streamed. It is possible that during high tweet traffic, the Stream might get disconnected at times, but TWBlue should be capable of detecting this problem and reconnecting the stream again. ([#385](https://github.com/manuelcortez/TWBlue/pull/385))
|
||||
* Fixed an issue that made TWBlue to not show a dialog when attempting to show a profile for a suspended user. ([#387](https://github.com/manuelcortez/TWBlue/issues/387))
|
||||
* Added support for Twitter audio and videos: Tweets which contains audio or videos will be detected as audio items, and you can playback those with the regular command to play audios. ([#384,](https://github.com/manuelcortez/TWBlue/pull/384))
|
||||
|
@@ -9,7 +9,7 @@ oauthlib
|
||||
requests-oauthlib
|
||||
requests-toolbelt
|
||||
pypubsub
|
||||
pygeocoder
|
||||
geopy
|
||||
arrow
|
||||
python-dateutil
|
||||
futures
|
||||
@@ -25,6 +25,7 @@ urllib3
|
||||
youtube-dl
|
||||
python-vlc
|
||||
pypiwin32
|
||||
pywin32
|
||||
certifi
|
||||
backports.functools_lru_cache
|
||||
cx_freeze
|
||||
@@ -32,6 +33,20 @@ tweepy
|
||||
twitter-text-parser
|
||||
pyenchant
|
||||
sqlitedict
|
||||
cx-Logging
|
||||
h11
|
||||
h2
|
||||
hpack
|
||||
hstspreload
|
||||
httpcore
|
||||
httpx
|
||||
hyperframe
|
||||
rfc3986
|
||||
sniffio
|
||||
attrs
|
||||
importlib-metadata
|
||||
numpy
|
||||
pillow
|
||||
git+https://github.com/accessibleapps/libloader
|
||||
git+https://github.com/accessibleapps/platform_utils
|
||||
git+https://github.com/accessibleapps/accessible_output2
|
||||
|
@@ -15,10 +15,10 @@ SetCompressor /solid lzma
|
||||
SetDatablockOptimize on
|
||||
VIAddVersionKey ProductName "TWBlue Snapshot version"
|
||||
VIAddVersionKey LegalCopyright "Copyright 2014-2021 Manuel Cortéz."
|
||||
VIAddVersionKey ProductVersion "8"
|
||||
VIAddVersionKey FileVersion "8"
|
||||
VIProductVersion "8.0.0.0"
|
||||
VIFileVersion "8.0.0.0"
|
||||
VIAddVersionKey ProductVersion "9"
|
||||
VIAddVersionKey FileVersion "9"
|
||||
VIProductVersion "9.0.0.0"
|
||||
VIFileVersion "9.0.0.0"
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!define MUI_LICENSEPAGE_RADIOBUTTONS
|
||||
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
||||
@@ -72,7 +72,7 @@ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "D
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "InstallLocation" $INSTDIR
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall" "Publisher" "Manuel Cortéz"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "8"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "DisplayVersion" "9"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "https://twblue.es"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMajor" 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 0
|
||||
|
@@ -49,3 +49,5 @@ braille_reporting = boolean(default=True)
|
||||
speech_reporting = boolean(default=True)
|
||||
|
||||
[filters]
|
||||
|
||||
[user-aliases]
|
@@ -9,7 +9,7 @@ if snapshot == False:
|
||||
update_url = 'https://twblue.es/updates/stable.php'
|
||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json'
|
||||
else:
|
||||
version = "8"
|
||||
version = "9"
|
||||
update_url = 'https://twblue.es/updates/snapshot.php'
|
||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json'
|
||||
authors = ["Manuel Cortéz", "José Manuel Delicado"]
|
||||
|
@@ -237,7 +237,7 @@ class BaseBuffer(base.Buffer):
|
||||
items_db = self.session.db[self.name]
|
||||
self.session.add_users_from_results(items)
|
||||
for i in items:
|
||||
if utils.is_allowed(i, self.session.settings, self.name) == True and utils.find_item(i.id, self.session.db[self.name]) == None:
|
||||
if utils.is_allowed(i, self.session.settings, self.name) == True and utils.find_item(i, self.session.db[self.name]) == None:
|
||||
i = reduce.reduce_tweet(i)
|
||||
i = self.session.check_quoted_status(i)
|
||||
i = self.session.check_long_tweet(i)
|
||||
@@ -644,8 +644,12 @@ class BaseBuffer(base.Buffer):
|
||||
original_tweet.text = utils.find_urls_in_text(original_tweet.text, original_tweet.entities)
|
||||
return compose.compose_quoted_tweet(quoted_tweet, original_tweet, self.session.db, self.session.settings["general"]["relative_times"])
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
def get_item_url(self):
|
||||
tweet = self.get_tweet()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
url = "https://twitter.com/{screen_name}/status/{tweet_id}".format(screen_name=self.session.get_user(tweet.user).screen_name, tweet_id=tweet.id)
|
||||
return url
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
url = self.get_item_url()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
webbrowser.open(url)
|
@@ -252,8 +252,7 @@ class PeopleBuffer(base.BaseBuffer):
|
||||
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||
output.speak(_(u"{0} new followers.").format(number_of_items))
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
def get_item_url(self, *args, **kwargs):
|
||||
tweet = self.get_tweet()
|
||||
output.speak(_(u"Opening item in web browser..."))
|
||||
url = "https://twitter.com/{screen_name}".format(screen_name=tweet.screen_name)
|
||||
webbrowser.open(url)
|
||||
return url
|
@@ -35,17 +35,16 @@ from mysc.repeating_timer import RepeatingTimer
|
||||
from mysc import restart
|
||||
import config
|
||||
import widgetUtils
|
||||
import pygeocoder
|
||||
from pygeolib import GeocoderError
|
||||
import logging
|
||||
import webbrowser
|
||||
from geopy.geocoders import Nominatim
|
||||
from mysc import localization
|
||||
import os
|
||||
import languageHandler
|
||||
|
||||
log = logging.getLogger("mainController")
|
||||
|
||||
geocoder = pygeocoder.Geocoder()
|
||||
geocoder = Nominatim(user_agent="TWBlue")
|
||||
|
||||
class Controller(object):
|
||||
|
||||
@@ -185,6 +184,7 @@ class Controller(object):
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.report_error, self.view.reportError)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_documentation, self.view.doc)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_changelog, self.view.changelog)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_alias, self.view.addAlias)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_list, self.view.addToList)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_list, self.view.removeFromList)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_buffer, self.view.update_buffer)
|
||||
@@ -754,6 +754,26 @@ class Controller(object):
|
||||
users = utils.get_all_users(tweet, buff.session)
|
||||
u = userActionsController.userActionsController(buff, users, "report")
|
||||
|
||||
def add_alias(self, *args, **kwargs):
|
||||
buff = self.get_best_buffer()
|
||||
if not hasattr(buff, "get_right_tweet"): return
|
||||
tweet = buff.get_right_tweet()
|
||||
if buff.type == "people":
|
||||
users = [tweet.screen_name]
|
||||
elif buff.type == "dm":
|
||||
users = [buff.session.get_user(tweet.message_create["sender_id"]).screen_name]
|
||||
else:
|
||||
users = utils.get_all_users(tweet, buff.session)
|
||||
dlg = dialogs.utils.addAliasDialog(_("Add an user alias"), users)
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
user, alias = dlg.get_user()
|
||||
if user == "" or alias == "":
|
||||
return
|
||||
user_id = buff.session.get_user_by_screen_name(user)
|
||||
buff.session.settings["user-aliases"][str(user_id)] = alias
|
||||
buff.session.settings.write()
|
||||
output.speak(_("Alias has been set correctly for {}.").format(user))
|
||||
|
||||
def post_tweet(self, event=None):
|
||||
buffer = self.get_best_buffer()
|
||||
buffer.post_status()
|
||||
@@ -810,7 +830,7 @@ class Controller(object):
|
||||
return
|
||||
elif buffer.type == "baseBuffer" or buffer.type == "favourites_timeline" or buffer.type == "list" or buffer.type == "search":
|
||||
tweet, tweetsList = buffer.get_full_tweet()
|
||||
msg = messages.viewTweet(tweet, tweetsList, utc_offset=buffer.session.db["utc_offset"])
|
||||
msg = messages.viewTweet(tweet, tweetsList, utc_offset=buffer.session.db["utc_offset"], item_url=buffer.get_item_url())
|
||||
elif buffer.type == "dm":
|
||||
non_tweet = buffer.get_formatted_message()
|
||||
item = buffer.get_right_tweet()
|
||||
@@ -818,8 +838,11 @@ class Controller(object):
|
||||
date = original_date.shift(seconds=buffer.session.db["utc_offset"]).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
|
||||
msg = messages.viewTweet(non_tweet, [], False, date=date)
|
||||
else:
|
||||
item_url = ""
|
||||
if hasattr(buffer, "get_item_url"):
|
||||
item_url = buffer.get_item_url()
|
||||
non_tweet = buffer.get_formatted_message()
|
||||
msg = messages.viewTweet(non_tweet, [], False)
|
||||
msg = messages.viewTweet(non_tweet, [], False, item_url=item_url)
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
buffer = self.get_current_buffer()
|
||||
@@ -977,19 +1000,17 @@ class Controller(object):
|
||||
if tweet.coordinates != None:
|
||||
x = tweet.coordinates["coordinates"][0]
|
||||
y = tweet.coordinates["coordinates"][1]
|
||||
address = geocoder.reverse_geocode(y, x, language = languageHandler.curLang)
|
||||
if event == None: output.speak(address[0].__str__())
|
||||
else: self.view.show_address(address[0].__str__())
|
||||
address = geocoder.reverse("{}, {}".format(y, x), language = languageHandler.curLang)
|
||||
if event == None: output.speak(address.address)
|
||||
else: self.view.show_address(address.address)
|
||||
else:
|
||||
output.speak(_(u"There are no coordinates in this tweet"))
|
||||
except GeocoderError:
|
||||
output.speak(_(u"There are no results for the coordinates in this tweet"))
|
||||
except ValueError:
|
||||
output.speak(_(u"Error decoding coordinates. Try again later."))
|
||||
except KeyError:
|
||||
pass
|
||||
# except KeyError:
|
||||
# pass
|
||||
except AttributeError:
|
||||
pass
|
||||
output.speak(_("Unable to find address in OpenStreetMap."))
|
||||
|
||||
def view_reverse_geocode(self, event=None):
|
||||
try:
|
||||
@@ -1244,14 +1265,17 @@ class Controller(object):
|
||||
keymap = {}
|
||||
for i in config.keymap["keymap"]:
|
||||
if hasattr(self, i):
|
||||
keymap[config.keymap["keymap"][i]] = getattr(self, i)
|
||||
if config.keymap["keymap"][i] != "":
|
||||
keymap[config.keymap["keymap"][i]] = getattr(self, i)
|
||||
return keymap
|
||||
|
||||
def register_invisible_keyboard_shorcuts(self, keymap):
|
||||
if config.changed_keymap:
|
||||
commonMessageDialogs.changed_keymap()
|
||||
# Make sure we pass a keymap without undefined keystrokes.
|
||||
new_keymap = {key: keymap[key] for key in keymap.keys() if keymap[key] != ""}
|
||||
self.keyboard_handler = WXKeyboardHandler(self.view)
|
||||
self.keyboard_handler.register_keys(keymap)
|
||||
self.keyboard_handler.register_keys(new_keymap)
|
||||
|
||||
def unregister_invisible_keyboard_shorcuts(self, keymap):
|
||||
try:
|
||||
|
@@ -102,7 +102,7 @@ class basicTweet(object):
|
||||
else:
|
||||
self.message.disable_button("shortenButton")
|
||||
self.message.disable_button("unshortenButton")
|
||||
if self.message.get("long_tweet") == False:
|
||||
if self.message.get("long_tweet") == False and hasattr(self, "max"):
|
||||
text = self.message.get_text()
|
||||
results = parse_tweet(text)
|
||||
self.message.set_title(_(u"%s - %s of %d characters") % (self.title, results.weightedLength, self.max))
|
||||
@@ -205,7 +205,7 @@ class dm(basicTweet):
|
||||
c.show_menu("dm")
|
||||
|
||||
class viewTweet(basicTweet):
|
||||
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date=""):
|
||||
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date="", item_url=""):
|
||||
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
|
||||
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
|
||||
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
|
||||
@@ -273,6 +273,10 @@ class viewTweet(basicTweet):
|
||||
text = tweet
|
||||
self.message = message.viewNonTweet(text, date)
|
||||
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
||||
if item_url != "":
|
||||
self.message.enable_button("share")
|
||||
widgetUtils.connect_event(self.message.share, widgetUtils.BUTTON_PRESSED, self.share)
|
||||
self.item_url = item_url
|
||||
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
||||
if self.contain_urls() == True:
|
||||
self.message.enable_button("unshortenButton")
|
||||
@@ -290,3 +294,8 @@ class viewTweet(basicTweet):
|
||||
if "https://twitter.com/" in i:
|
||||
text = text.replace(i, "\n")
|
||||
return text
|
||||
|
||||
def share(self, *args, **kwargs):
|
||||
if hasattr(self, "item_url"):
|
||||
output.copy(self.item_url)
|
||||
output.speak(_("Link copied to clipboard."))
|
@@ -21,7 +21,7 @@ class storage(object):
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def get_users(self, term):
|
||||
self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),))
|
||||
self.cursor.execute("""SELECT * FROM users WHERE UPPER(user) LIKE :term OR UPPER(name) LIKE :term""", {"term": "%{}%".format(term.upper())})
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def set_user(self, screen_name, user_name, from_a_buffer):
|
||||
|
@@ -34,4 +34,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -53,4 +53,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -54,4 +54,5 @@ configuration = string(default="control+win+alt+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
58
src/keymaps/Windows11.keymap
Normal file
58
src/keymaps/Windows11.keymap
Normal file
@@ -0,0 +1,58 @@
|
||||
[info]
|
||||
name = string(default="Windows 11")
|
||||
desc = string(default="A keymap with remapped modifiers for Windows 11 compatibility.")
|
||||
author = string(default="Bill Jesús <galorasd@gmail.com>")
|
||||
|
||||
[keymap]
|
||||
up = string(default="control+alt+win+up")
|
||||
down = string(default="control+alt+win+down")
|
||||
left = string(default="control+alt+win+left")
|
||||
right = string(default="control+alt+win+right")
|
||||
next_account = string(default="control+alt+win+shift+right")
|
||||
previous_account = string(default="control+alt+win+shift+left")
|
||||
open_conversation = string(default="control+alt+win+c")
|
||||
show_hide = string(default="control+win+w")
|
||||
post_tweet = string(default="alt+win+n")
|
||||
post_reply = string(default="control+win+r")
|
||||
post_retweet = string(default="alt+win+shift+r")
|
||||
send_dm = string(default="alt+win+shift+d")
|
||||
toggle_like = string(default="control+alt+win+f")
|
||||
follow = string(default="alt+win+shift+s")
|
||||
user_details = string(default="alt+win+shift+n")
|
||||
view_item = string(default="alt+win+v")
|
||||
exit = string(default="alt+win+f4")
|
||||
open_timeline = string(default="alt+win+i")
|
||||
remove_buffer = string(default="alt+win+shift+i")
|
||||
url = string(default="alt+win+return")
|
||||
audio = string(default="alt+shift+win+return")
|
||||
volume_up = string(default="control+alt+win+shift+up")
|
||||
go_home = string(default="control+alt+win+home")
|
||||
volume_down = string(default="control+alt+win+shift+down")
|
||||
go_end = string(default="control+alt+win+end")
|
||||
go_page_up = string(default="control+win+pageup")
|
||||
go_page_down = string(default="control+win+pagedown")
|
||||
update_profile = string(default="alt+win+p")
|
||||
delete = string(default="alt+win+delete")
|
||||
clear_buffer = string(default="alt+win+shift+delete")
|
||||
repeat_item = string(default="control+alt+win+space")
|
||||
copy_to_clipboard = string(default="alt+win+shift+c")
|
||||
add_to_list = string(default="alt+win+a")
|
||||
remove_from_list = string(default="alt+win+shift+a")
|
||||
toggle_buffer_mute = string(default="alt+win+shift+m")
|
||||
toggle_session_mute = string(default="control+alt+win+m")
|
||||
toggle_autoread = string(default="alt+win+e")
|
||||
search = string(default="alt+win+-")
|
||||
edit_keystrokes = string(default="alt+win+k")
|
||||
view_user_lists = string(default="alt+win+l")
|
||||
get_more_items = string(default="alt+win+pageup")
|
||||
reverse_geocode = string(default="control+win+g")
|
||||
view_reverse_geocode = string(default="alt+win+shift+g")
|
||||
get_trending_topics = string(default="control+win+t")
|
||||
check_for_updates = string(default="alt+win+u")
|
||||
list_manager = string(default="alt+win+shift+l")
|
||||
configuration = string(default="control+win+alt+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+alt+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -55,4 +55,5 @@ list_manager = string(default="control+win+shift+l")
|
||||
configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -56,4 +56,5 @@ configuration = string(default="control+win+o")
|
||||
accountConfiguration = string(default="control+win+shift+o")
|
||||
update_buffer = string(default="control+win+shift+u")
|
||||
ocr_image = string(default="win+alt+o")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
open_in_browser = string(default="alt+control+win+return")
|
||||
add_alias=string(default="")
|
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
actions = {
|
||||
"up": _(u"Go up in the current buffer"),
|
||||
"down": _(u"Go down in the current buffer"),
|
||||
@@ -57,4 +56,6 @@ actions = {
|
||||
"audio": _(u"Try to play an audio file"),
|
||||
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
||||
"ocr_image": _(u"Extracts the text from a picture and displays the result in a dialog."),
|
||||
"add_alias": _("Adds an alias to an user"),
|
||||
}
|
||||
|
@@ -1,7 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
from builtins import object
|
||||
import widgetUtils
|
||||
import config
|
||||
from . import wx_ui
|
||||
@@ -18,6 +15,7 @@ class KeystrokeEditor(object):
|
||||
self.hold_map = self.map.copy()
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_keystroke)
|
||||
widgetUtils.connect_event(self.dialog.undefine, widgetUtils.BUTTON_PRESSED, self.undefine_keystroke)
|
||||
widgetUtils.connect_event(self.dialog.execute, widgetUtils.BUTTON_PRESSED, self.execute_action)
|
||||
self.dialog.get_response()
|
||||
|
||||
@@ -33,6 +31,17 @@ class KeystrokeEditor(object):
|
||||
self.map[action] = new_keystroke
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
|
||||
def undefine_keystroke(self, *args, **kwargs):
|
||||
action = self.dialog.actions[self.dialog.get_action()]
|
||||
keystroke = self.map.get(action)
|
||||
if keystroke == None:
|
||||
return
|
||||
answer = self.dialog.undefine_keystroke_confirmation()
|
||||
if answer == widgetUtils.YES:
|
||||
self.map[action] = ""
|
||||
self.changed = True
|
||||
self.dialog.put_keystrokes(constants.actions, self.map)
|
||||
|
||||
def set_keystroke(self, keystroke, dialog):
|
||||
for i in keystroke.split("+"):
|
||||
if hasattr(dialog, i):
|
||||
|
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
import wx
|
||||
from multiplatform_widgets import widgets
|
||||
from wxUI.dialogs import baseDialog
|
||||
@@ -18,6 +17,7 @@ class keystrokeEditorDialog(baseDialog.BaseWXDialog):
|
||||
firstSizer.Add(self.keys.list, 0, wx.ALL, 5)
|
||||
self.edit = wx.Button(panel, -1, _(u"Edit"))
|
||||
self.edit.SetDefault()
|
||||
self.undefine = wx.Button(panel, -1, _("Undefine keystroke"))
|
||||
self.execute = wx.Button(panel, -1, _(u"Execute action"))
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
secondSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
@@ -37,13 +37,18 @@ class keystrokeEditorDialog(baseDialog.BaseWXDialog):
|
||||
continue
|
||||
action = actions[i]
|
||||
self.actions.append(i)
|
||||
keystroke = keystrokes[i]
|
||||
keystroke = keystrokes.get(i)
|
||||
if keystroke == "":
|
||||
keystroke = _("Undefined")
|
||||
self.keys.insert_item(False, *[action, keystroke])
|
||||
self.keys.select_item(selection)
|
||||
|
||||
def get_action(self):
|
||||
return self.keys.get_selected()
|
||||
|
||||
def undefine_keystroke_confirmation(self):
|
||||
return wx.MessageDialog(self, _("Are you sure you want to undefine this keystroke?"), _("Undefine keystroke"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION).ShowModal()
|
||||
|
||||
class editKeystrokeDialog(baseDialog.BaseWXDialog):
|
||||
def __init__(self):
|
||||
super(editKeystrokeDialog, self).__init__(parent=None, id=-1, title=_(u"Editing keystroke"))
|
||||
|
Binary file not shown.
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: TW Blue 0.85\n"
|
||||
"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n"
|
||||
"PO-Revision-Date: 2020-10-23 14:30+0300\n"
|
||||
"PO-Revision-Date: 2021-07-05 16:03+0200\n"
|
||||
"Last-Translator: Artem Plaksin <admin@maniyax.ru>\n"
|
||||
"Language-Team: Alexander Jaszyn <a.jaszyn@ya.ru>\n"
|
||||
"Language: ru\n"
|
||||
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 1.8.8\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
@@ -208,14 +208,12 @@ msgstr ""
|
||||
"личных сообщений вместо этого."
|
||||
|
||||
#: ../src\controller\buffers\twitterBuffers.py:983
|
||||
#, fuzzy
|
||||
msgid "{0} new followers."
|
||||
msgstr "Новый читатель."
|
||||
msgstr "{0} новых читателей."
|
||||
|
||||
#: ../src\controller\buffers\twitterBuffers.py:1266
|
||||
#, fuzzy
|
||||
msgid "This action is not supported in the buffer, yet."
|
||||
msgstr "Это действие не поддерживается в данном буфере"
|
||||
msgstr "Это действие пока не поддерживается в буфере."
|
||||
|
||||
#: ../src\controller\mainController.py:273
|
||||
msgid "Ready"
|
||||
@@ -314,9 +312,8 @@ msgid "Select the user"
|
||||
msgstr "Выберите пользователя"
|
||||
|
||||
#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236
|
||||
#, fuzzy
|
||||
msgid "MMM D, YYYY. H:m"
|
||||
msgstr "dddd, MMMM D, YYYY H:m:s"
|
||||
msgstr "MMM D, YYYY. H:m"
|
||||
|
||||
#: ../src\controller\mainController.py:934
|
||||
msgid "Conversation with {0}"
|
||||
@@ -1702,9 +1699,8 @@ msgid "Opens the global settings dialogue"
|
||||
msgstr "Открыть основные настройки"
|
||||
|
||||
#: ../src\keystrokeEditor\constants.py:54
|
||||
#, fuzzy
|
||||
msgid "Opens the list manager"
|
||||
msgstr "Менеджер Списков"
|
||||
msgstr "Открывает менеджер списков"
|
||||
|
||||
#: ../src\keystrokeEditor\constants.py:55
|
||||
msgid "Opens the account settings dialogue"
|
||||
|
@@ -39,7 +39,7 @@ def logs_path():
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
||||
def data_path(app_name='socializer'):
|
||||
def data_path(app_name='TW Blue'):
|
||||
if platform.system() == "Windows":
|
||||
data_path = os.path.join(os.getenv("AppData"), app_name)
|
||||
else:
|
||||
|
@@ -45,9 +45,9 @@ def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=No
|
||||
else:
|
||||
value = "text"
|
||||
if hasattr(tweet, "retweeted_status") and value != "message":
|
||||
text = StripChars(getattr(tweet.retweeted_status, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(tweet.retweeted_status, value)))
|
||||
else:
|
||||
text = StripChars(getattr(tweet, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(tweet, value)))
|
||||
if show_screen_names:
|
||||
user = session.get_user(tweet.user).screen_name
|
||||
else:
|
||||
@@ -111,7 +111,7 @@ def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False,
|
||||
value = "full_text"
|
||||
else:
|
||||
value = "text"
|
||||
text = StripChars(getattr(quoted_tweet, value))
|
||||
text = utils.clean_mentions(StripChars(getattr(quoted_tweet, value)))
|
||||
if show_screen_names:
|
||||
quoting_user = session.get_user(quoted_tweet.user).screen_name
|
||||
else:
|
||||
@@ -124,9 +124,9 @@ def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False,
|
||||
if hasattr(original_tweet, "message"):
|
||||
original_text = original_tweet.message
|
||||
elif hasattr(original_tweet, "full_text"):
|
||||
original_text = StripChars(original_tweet.full_text)
|
||||
original_text = utils.clean_mentions(StripChars(original_tweet.full_text))
|
||||
else:
|
||||
original_text = StripChars(original_tweet.text)
|
||||
original_text = utils.clean_mentions(StripChars(original_tweet.text))
|
||||
quoted_tweet.message = _(u"{0}. Quoted tweet from @{1}: {2}").format( text, original_user, original_text)
|
||||
quoted_tweet = tweets.clear_url(quoted_tweet)
|
||||
if hasattr(original_tweet, "entities") and original_tweet.entities.get("urls"):
|
||||
|
@@ -51,7 +51,7 @@ class Session(base.baseSession):
|
||||
if i.id < last_id:
|
||||
log.error("Ignoring an older tweet... Last id: {0}, tweet id: {1}".format(last_id, i.id))
|
||||
continue
|
||||
if utils.find_item(i.id, self.db[name]) == None and utils.is_allowed(i, self.settings, name) == True:
|
||||
if utils.find_item(i, self.db[name]) == None and utils.is_allowed(i, self.settings, name) == True:
|
||||
if i == False: continue
|
||||
reduced_object = reduce.reduce_tweet(i)
|
||||
reduced_object = self.check_quoted_status(reduced_object)
|
||||
@@ -72,7 +72,7 @@ class Session(base.baseSession):
|
||||
self.db[name] = []
|
||||
objects = self.db[name]
|
||||
for i in data:
|
||||
if utils.find_item(i.id, self.db[name]) == None:
|
||||
if utils.find_item(i, self.db[name]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: objects.append(i)
|
||||
else: objects.insert(0, i)
|
||||
num = num+1
|
||||
@@ -94,12 +94,12 @@ class Session(base.baseSession):
|
||||
for i in data:
|
||||
# Twitter returns sender_id as str, which must be converted to int in order to match to our user_id object.
|
||||
if int(i.message_create["sender_id"]) == self.db["user_id"]:
|
||||
if "sent_direct_messages" in self.db and utils.find_item(i.id, self.db["sent_direct_messages"]) == None:
|
||||
if "sent_direct_messages" in self.db and utils.find_item(i, self.db["sent_direct_messages"]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: sent_objects.append(i)
|
||||
else: sent_objects.insert(0, i)
|
||||
sent = sent+1
|
||||
else:
|
||||
if utils.find_item(i.id, self.db["direct_messages"]) == None:
|
||||
if utils.find_item(i, self.db["direct_messages"]) == None:
|
||||
if self.settings["general"]["reverse_timelines"] == False: objects.append(i)
|
||||
else: objects.insert(0, i)
|
||||
incoming = incoming+1
|
||||
@@ -430,9 +430,25 @@ class Session(base.baseSession):
|
||||
users = self.db["users"]
|
||||
users[user.id_str] = user
|
||||
self.db["users"] = users
|
||||
user.name = self.get_user_alias(user)
|
||||
return user
|
||||
else:
|
||||
return self.db["users"][str(id)]
|
||||
user = self.db["users"][str(id)]
|
||||
user.name = self.get_user_alias(user)
|
||||
return user
|
||||
|
||||
def get_user_alias(self, user):
|
||||
""" Retrieves an alias for the passed user model, if exists.
|
||||
@ user Tweepy.models.user: An user object.
|
||||
"""
|
||||
aliases = self.settings.get("user-aliases")
|
||||
if aliases == None:
|
||||
log.error("Aliases are not defined for this config spec.")
|
||||
return user.name
|
||||
user_alias = aliases.get(user.id_str)
|
||||
if user_alias != None:
|
||||
return user_alias
|
||||
return user.name
|
||||
|
||||
def get_user_by_screen_name(self, screen_name):
|
||||
""" Returns an user identifier associated with a screen_name.
|
||||
|
@@ -60,9 +60,13 @@ def find_urls (tweet, twitter_media=False):
|
||||
urls.append(i)
|
||||
return urls
|
||||
|
||||
def find_item(id, listItem):
|
||||
for i in range(0, len(listItem)):
|
||||
if listItem[i].id == id: return i
|
||||
def find_item(item, listItems):
|
||||
for i in range(0, len(listItems)):
|
||||
if listItems[i].id == item.id:
|
||||
return i
|
||||
# Check also retweets.
|
||||
if hasattr(item, "retweeted_status") and item.retweeted_status.id == listItems[i].id:
|
||||
return i
|
||||
return None
|
||||
|
||||
def find_list(name, lists):
|
||||
@@ -121,9 +125,9 @@ def get_all_mentioned(tweet, conf, field="screen_name"):
|
||||
""" Gets all users that have been mentioned."""
|
||||
results = []
|
||||
if hasattr(tweet, "retweeted_status"):
|
||||
results.extend(get_all_mentionned(tweet.retweeted_status, conf, field))
|
||||
results.extend(get_all_mentioned(tweet.retweeted_status, conf, field))
|
||||
if hasattr(tweet, "quoted_status"):
|
||||
results.extend(tweet.quoted_status, conf, field)
|
||||
results.extend(get_all_mentioned(tweet.quoted_status, conf, field))
|
||||
if hasattr(tweet, "entities") and tweet.entities.get("user_mentions"):
|
||||
for i in tweet.entities["user_mentions"]:
|
||||
if i["screen_name"] != conf["user_name"] and i["id_str"] != tweet.user:
|
||||
@@ -240,3 +244,20 @@ def expand_urls(text, entities):
|
||||
if url["url"] in text:
|
||||
text = text.replace(url["url"], url["expanded_url"])
|
||||
return text
|
||||
|
||||
def clean_mentions(text):
|
||||
new_text = text
|
||||
mentionned_people = [u for u in re.finditer("(?<=^|(?<=[^a-zA-Z0-9-\.]))@([A-Za-z0-9_]+)", text)]
|
||||
if len(mentionned_people) <= 2:
|
||||
return text
|
||||
end = -2
|
||||
total_users = 0
|
||||
for user in mentionned_people:
|
||||
if abs(user.start()-end) < 3:
|
||||
new_text = new_text.replace(user.group(0), "")
|
||||
total_users = total_users+1
|
||||
end = user.end()
|
||||
if total_users < 1:
|
||||
return text
|
||||
new_text = _("{user_1}, {user_2} and {all_users} more: {text}").format(user_1=mentionned_people[0].group(0), user_2=mentionned_people[1].group(0), all_users=total_users-2, text=new_text)
|
||||
return new_text
|
@@ -3,7 +3,7 @@ import sys
|
||||
import application
|
||||
import platform
|
||||
import os
|
||||
from cx_Freeze import setup, Executable
|
||||
from cx_Freeze import setup, Executable, winmsvcr
|
||||
from requests import certs
|
||||
|
||||
def get_architecture_files():
|
||||
@@ -40,7 +40,7 @@ build_exe_options = dict(
|
||||
build_exe="dist",
|
||||
optimize=1,
|
||||
includes=["enchant.tokenize.en"], # This is not handled automatically by cx_freeze.
|
||||
include_msvcr=True,
|
||||
include_msvcr=False,
|
||||
replace_paths = [("*", "")],
|
||||
include_files=["icon.ico", "conf.defaults", "app-configuration.defaults", "keymaps", "locales", "sounds", "documentation", ("keys/lib", "keys/lib"), find_sound_lib_datafiles(), find_accessible_output2_datafiles()]+get_architecture_files(),
|
||||
packages=["wxUI"],
|
||||
@@ -50,6 +50,8 @@ executables = [
|
||||
Executable('main.py', base=base, targetName="twblue")
|
||||
]
|
||||
|
||||
winmsvcr.FILES = ()
|
||||
winmsvcr.FILES_TO_DUPLICATE = ()
|
||||
setup(name=application.name,
|
||||
version=application.version,
|
||||
description=application.description,
|
||||
|
@@ -1,6 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
from builtins import str
|
||||
import wx
|
||||
import widgetUtils
|
||||
|
||||
@@ -356,6 +354,8 @@ class viewTweet(widgetUtils.BaseDialog):
|
||||
infoBox.Add(sourceBox, 0, wx.ALL, 5)
|
||||
mainBox.Add(infoBox, 0, wx.ALL, 5)
|
||||
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||
self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard"))
|
||||
self.share.Enable(False)
|
||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Disable()
|
||||
@@ -363,6 +363,7 @@ class viewTweet(widgetUtils.BaseDialog):
|
||||
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize)
|
||||
cancelButton.SetDefault()
|
||||
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsBox.Add(self.share, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
@@ -429,6 +430,8 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
dateBox.Add(dateLabel, 0, wx.ALL, 5)
|
||||
dateBox.Add(date, 0, wx.ALL, 5)
|
||||
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||
self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard"))
|
||||
self.share.Enable(False)
|
||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||
self.unshortenButton.Disable()
|
||||
@@ -436,6 +439,7 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize)
|
||||
cancelButton.SetDefault()
|
||||
buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsBox.Add(self.share, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5)
|
||||
buttonsBox.Add(self.translateButton, 0, wx.ALL, 5)
|
||||
@@ -463,5 +467,5 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
||||
self.text.SetFocus()
|
||||
|
||||
def enable_button(self, buttonName):
|
||||
if getattr(self, buttonName):
|
||||
if hasattr(self, buttonName):
|
||||
return getattr(self, buttonName).Enable()
|
||||
|
@@ -48,3 +48,36 @@ class selectUserDialog(baseDialog.BaseWXDialog):
|
||||
def get_user(self):
|
||||
return self.cb.GetValue()
|
||||
|
||||
class addAliasDialog(baseDialog.BaseWXDialog):
|
||||
def __init__(self, title, users):
|
||||
super(addAliasDialog, self).__init__(parent=None, id=wx.ID_ANY, title=title)
|
||||
panel = wx.Panel(self)
|
||||
userSizer = wx.BoxSizer()
|
||||
self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0], size=wx.DefaultSize)
|
||||
self.cb.SetFocus()
|
||||
self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users"))
|
||||
userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5)
|
||||
userSizer.Add(self.cb, 0, wx.ALL, 5)
|
||||
userSizer.Add(self.autocompletion, 0, wx.ALL, 5)
|
||||
aliasSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
aliasLabel = wx.StaticText(panel, wx.ID_ANY, _("Alias"))
|
||||
self.alias = wx.TextCtrl(panel, wx.ID_ANY)
|
||||
aliasSizer.Add(aliasLabel, 0, wx.ALL, 5)
|
||||
aliasSizer.Add(self.alias, 0, wx.ALL, 5)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
ok = wx.Button(panel, wx.ID_OK, _(u"OK"))
|
||||
ok.SetDefault()
|
||||
# ok.Bind(wx.EVT_BUTTON, self.onok)
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close"))
|
||||
btnsizer = wx.BoxSizer()
|
||||
btnsizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnsizer.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(userSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(aliasSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(btnsizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def get_user(self):
|
||||
return (self.cb.GetValue(), self.alias.GetValue())
|
||||
|
||||
|
@@ -43,6 +43,7 @@ class mainFrame(wx.Frame):
|
||||
self.follow = user.Append(wx.ID_ANY, _(u"&Actions..."))
|
||||
self.timeline = user.Append(wx.ID_ANY, _(u"&View timeline..."))
|
||||
self.dm = user.Append(wx.ID_ANY, _(u"Direct me&ssage"))
|
||||
self.addAlias = user.Append(wx.ID_ANY, _("Add a&lias"))
|
||||
self.addToList = user.Append(wx.ID_ANY, _(u"&Add to list"))
|
||||
self.removeFromList = user.Append(wx.ID_ANY, _(u"R&emove from list"))
|
||||
self.viewLists = user.Append(wx.ID_ANY, _(u"&View lists"))
|
||||
|
Submodule windows-dependencies updated: 27d860885f...27a7c41983
Reference in New Issue
Block a user