diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..c3c846f4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,123 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + PYTHON: "C:\\python37\\python.exe" + NSIS: "C:\\program files (x86)\\nsis\\makensis.exe" + +stages: + - build + - make_installer + - upload + +twblue32: + tags: + - shared-windows + - windows + - windows-1809 + before_script: + - Set-Variable -Name "time" -Value (date -Format "%H:%m") + - echo ${time} + - echo "started by ${GITLAB_USER_NAME}" + - choco install python --version 3.7.9 -y -ForceX86 + - '&$env:PYTHON -V' + - '&$env:PYTHON -m pip install --upgrade pip' + - '&$env:PYTHON -m pip install --upgrade -r requirements.txt' + stage: build + interruptible: true + script: + # Create html documentation firstly. + - cd doc + - '&$env:PYTHON documentation_importer.py' + - cd ..\src + - '&$env:PYTHON ..\doc\generator.py' + - '&$env:PYTHON write_version_data.py' + - '&$env:PYTHON setup.py build' + - cd .. + - mkdir artifacts + - cd scripts + - '&$env:PYTHON make_archive.py' + - cd .. + - mv src/dist artifacts/TWBlue + - move src/twblue.zip artifacts/twblue_x86.zip + # Move the generated script nsis file to artifacts, so we won't need python when generating the installer. + - move scripts/twblue.nsi artifacts/twblue.nsi + only: + - tags + artifacts: + paths: + - artifacts + expire_in: 1 day + +twblue64: + tags: + - shared-windows + - windows + - windows-1809 + before_script: + - Set-Variable -Name "time" -Value (date -Format "%H:%m") + - echo ${time} + - echo "started by ${GITLAB_USER_NAME}" + - choco install python --version 3.7.9 -y + - '&$env:PYTHON -V' + - '&$env:PYTHON -m pip install --upgrade pip' + - '&$env:PYTHON -m pip install --upgrade -r requirements.txt' + stage: build + interruptible: true + script: + # Create html documentation firstly. + - cd doc + - '&$env:PYTHON documentation_importer.py' + - cd ..\src + - '&$env:PYTHON ..\doc\generator.py' + - '&$env:PYTHON write_version_data.py' + - '&$env:PYTHON setup.py build' + - cd .. + - mkdir artifacts + - cd scripts + - '&$env:PYTHON make_archive.py' + - cd .. + - mv src/dist artifacts/TWBlue64 + - move src/twblue.zip artifacts/twblue_x64.zip + only: + - tags + artifacts: + paths: + - artifacts + expire_in: 1 day + +generate_versions: + stage: make_installer + tags: + - shared-windows + - windows + - windows-1809 + before_script: + - Set-Variable -Name "time" -Value (date -Format "%H:%m") + - echo ${time} + - echo "started by ${GITLAB_USER_NAME}" + - choco install nsis -y -ForceX86 + script: + - move artifacts/TWBlue scripts/ + - move artifacts/TWBlue64 scripts/ + - move artifacts/twblue.nsi scripts/installer.nsi + - cd scripts + - '&$env:NSIS installer.nsi' + - move twblue_setup.exe ../artifacts + only: + - tags + artifacts: + paths: + - artifacts + expire_in: 1 day + +upload: + stage: upload + tags: + - linux + image: python + interruptible: true + script: + - cd artifacts + - python ../scripts/upload.py + only: + - tags + - schedules \ No newline at end of file diff --git a/README.md b/README.md index 4f871210..332f9a4b 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Although most dependencies can be found in the windows-dependencies directory, w #### Dependencies packaged in windows installers -* [Python,](https://python.org) version 3.8.7 +* [Python,](https://python.org) version 3.7.9 If you want to build both x86 and x64 binaries, you can install python x86 to C:\python38 and python x64 to C:\python38x64, for example. #### Dependencies that must be installed using pip diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index cfd3a2c2..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,84 +0,0 @@ -pull_requests: - # Avoid building after pull requests. Shall we disable this option? - do_not_increment_build_number: true - -# Only build whenever we add tags to the repo. -skip_non_tags: true - -environment: - - matrix: - - # List of python versions we want to work with. - - PYTHON: "C:\\Python37" - PYTHON_VERSION: "3.7.x" # currently 2.7.9 - PYTHON_ARCH: "32" - - # perhaps we may enable this one in future? -# - PYTHON: "C:\\Python37-x64" -# PYTHON_VERSION: "3.7.x" # currently 2.7.9 -# PYTHON_ARCH: "64" - -# This is important so we will retrieve everything in submodules as opposed to default method. -clone_script: - - cmd: >- - git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% - && cd %APPVEYOR_BUILD_FOLDER% - && git checkout -qf %APPVEYOR_REPO_COMMIT% - && git submodule update --init --recursive - -install: - # If there is a newer build queued for the same PR, cancel this one. - # The AppVeyor 'rollout builds' option is supposed to serve the same - # purpose but it is problematic because it tends to cancel builds pushed - # directly to master instead of just PR builds (or the converse). - # credits: JuliaLang developers. - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` - https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` - Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` - throw "There are newer queued builds for this pull request, failing early." } -# - ECHO "Filesystem root:" -# - ps: "ls \"C:/\"" - - # Check that we have the expected version and architecture for Python - - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - "python --version" - - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" - - # Upgrade to the latest version of pip to avoid it displaying warnings - # about it being out of date. - - "python -m pip install --upgrade pip setuptools" - - # Install the build dependencies of the project. If some dependencies contain - # compiled extensions and are not provided as pre-built wheel packages, - # pip will build them from source using the MSVC compiler matching the - # target Python version and architecture - - "%CMD_IN_ENV% pip install -r requirements.txt" - - "%CMD_IN_ENV% pip install pyenchant" - -build_script: - # Build documentation at first, so setup.py won't fail when copying everything. - - "cd doc" - # Import documentation before building, so strings.py will be created. - - "%CMD_IN_ENV% python documentation_importer.py" - # build doc from src folder so it will generate result files right there. - - "cd ..\\src" - - "%CMD_IN_ENV% python ..\\doc\\generator.py" - # Build distributable files. - - "%CMD_IN_ENV% python setup.py build" - - "cd dist" - # Zip it all. - - cmd: 7z a ..\..\snapshot.zip * - -artifacts: - - path: snapshot.zip - -deploy: -- provider: FTP - host: twblue.es - protocol: ftp - beta: true - username: twblue.es - password: - secure: lQZqpYRnHf4LLVOg0C42NQ== - folder: 'web/pubs' \ No newline at end of file diff --git a/contributors.txt b/contributors.txt index a94ce353..436c4ba8 100644 --- a/contributors.txt +++ b/contributors.txt @@ -39,5 +39,5 @@ florian Ionașcu Christian Leo Mameli Natalia Hedlund (Наталья Хедлунд) Valeria (Валерия) -Corentin Bacqué-Cazenave -Artem Plaksin (maniyax) \ No newline at end of file +Oreonan +Artem Plaksin (maniyax) diff --git a/doc/changelog.md b/doc/changelog.md index f299071e..13d35a74 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,7 +1,61 @@ -TWBlue Changelog +TWBlue Changelog ## changes in this version +* We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. +* Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. + +## Changes in version 2021.11.12 + +* Now it is possible to create a tweet from a trending topics buffer again. +* TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features. + * It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created. + * Now you can add a poll to tweets. Polls can have up to 4 different options and allow voting up to 7 days after being created. Take into account, though, that currently TWBlue does not support reading polls in tweets. + * TWBlue now support threads while creating a new tweet. There is a new button, called add tweet which will add the current tweet to the thread and will allow you to write another tweet in the thread. Every tweet might include media (up to 4 photos, or one GIF image or a video) or up to one poll. + * Some functionality was removed from tweet dialogs within TWBlue. Particularly, URL shorteners and long tweets via Twishort. You still can read long tweets posted via Twishort, though. + +## Changes in version 2021.11.07 + +* TWBlue should retrieve tweets from threads and conversations in a more reliable way. Tweets in the same thread (made by the same author) will be sorted correctly, although replies to the thread (made by different people) may not be ordered in the same way they are displayed in Twitter apps. ([#417](https://github.com/manuelcortez/TWBlue/issues/417)) +* When creating a filter, TWBlue will show an error if user has not provided a name for the filter. Before, unnamed filters were a cause of config breaks in the application. +* It is again possible to read the changelog for TWBlue from the help menu in the menu bar. +* fixed a bug when clearing the direct messages buffer. ([#418](https://github.com/manuelcortez/TWBlue/issues/418)) +* fixed an issue that was making TWBlue to show incorrectly titles for trending topic buffers upon startup. ([#421](https://github.com/manuelcortez/TWBlue/issues/421)) +* fixed an issue that was making users of the graphical user interface to delete a buffer if a trends buffer was opened in the same session. +* Updated Spanish, Japanese and french translations. + +## Changes in Version 2021.10.30 + +* Fixed many errors in the way we compile TWBlue, so users of 64 bits systems and particularly windows 7 users would be able to install TWBlue again. In case of issues with versions prior to 2021.10.30, please remove everything related to TWBlue (except configs) and reinstall the version 2021.10.30 to fix any possible error. This step won't be needed again in 23 months. ([#416,](https://github.com/manuelcortez/TWBlue/issues/416), [#415,](https://github.com/manuelcortez/TWBlue/issues/415)) +* fixed an issue that was making impossible to manually add an user to the autocomplete users database. +* Started to improve support to conversations by searching for conversation_id. + +## changes in version 2021.10.27 + +* Added an user alias manager, located in the application menu in the menu bar. From this dialog, it is possible to review, add, edit or remove user aliases for the current account. ([#401](https://github.com/manuelcortez/TWBlue/issues/401)) +* TWBlue now closes the VLC player window automatically when a video reaches its end. ([#399](https://github.com/manuelcortez/TWBlue/issues/399)) +* After a lot of time, TWBlue now uses a new default Soundpack, called FreakyBlue. This soundpack will be set by default in all new sessions created in the application. Thanks to [Andre Louis](https://twitter.com/FreakyFwoof) for the pack. ([#247](https://github.com/manuelcortez/TWBlue/issues/247)) +* 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)) +* We just implemented some changes in the way TWBlue handles tweets in order to reduce its RAM memory usage [#380](https://github.com/manuelcortez/TWBlue/pull/380): + * We reduced the tweets size by storing only the tweet fields we currently use. This should reduce tweet's size in memory for every object up to 75%. + * When using the cache database to store your tweets, there is a new setting present in the account settings dialog, in the general tab. This setting allows you to control whether TWBlue will load the whole database into memory (which is the current behaviour) or not. + * Loading the whole database into memory has the advantage of being extremely fast to access any element (for example when moving through tweets in a buffer), but it requires more memory as the tweet buffers grow up. This should, however, use less memory than before thanks to the optimizations performed in tweet objects. If you have a machine with enough memory, this should be a good option for your case. + * If you uncheck this setting, TWBlue will read the whole database from disk. This is significantly slower, but the advantage of this setting is that it will consume almost no extra memory, no matter how big is the tweets dataset. Be ware, though, that TWBlue might start to feel slower when accessing elements (for example when reading tweets) as the buffers grow up. This setting is suggested for computers with low memory or for those people not wanting to keep a really big amount of tweets stored. +* Changed the label in the direct message's text control so it will indicate that the user needs to write the text there, without referring to any username in particular. ([#366,](https://github.com/manuelcortez/TWBlue/issues/366)) +* TWBlue will take Shift+F10 again as the contextual menu key in the list of items in a buffer. This stopped working after we have migrated to WX 4.1. ([#353,](https://github.com/manuelcortez/TWBlue/issues/353)) +* TWBlue should render correctly retweets of quoted tweets. ([#365,](https://github.com/manuelcortez/TWBlue/issues/365)) +* Fixed an error that was causing TWBlue to be unable to output to screen readers at times. ([#369,](https://github.com/manuelcortez/TWBlue/issues/369)) +* Fixed autocomplete users feature. ([#367,](https://github.com/manuelcortez/TWBlue/issues/367)) * Fixed error when displaying an URL at the end of a line, when the tweet or direct message contained multiple lines. Now the URL should be displayed correctly. ([#305,](https://github.com/manuelcortez/TWBlue/issues/305) [#272,](https://github.com/manuelcortez/TWBlue/issues/272)) * TWBlue has been migrated completely to Python 3 (currently, the software builds with Python 3.8). * TWBlue should be restarted gracefully. Before, the application was alerting users of not being closed properly every time the application restarted by itself. @@ -12,6 +66,8 @@ * TWBlue can upload images in Tweets and replies again. ([#240,](https://github.com/manuelcortez/TWBlue/issues/240)) * Fixed the way we use to count characters in Twitter. The new methods in TWBlue take into account special characters and URLS as documented in Twitter. ([#199,](https://github.com/manuelcortez/TWBlue/issues/199) [#315](https://github.com/manuelcortez/TWBlue/issues/315)) * Proxy support now works as expected. +* Changed translation service from yandex.translate to Google Translator. ([#355,](https://github.com/manuelcortez/TWBlue/issues/355)) +* Improved method to load direct messages in the buffers. Now it should be faster due to less calls to Twitter API performed from the client. * And more. ([#352,](https://github.com/manuelcortez/TWBlue/issues/352)) ## Changes in version 0.95 @@ -213,4 +269,4 @@ * New followers and friends buffer for user timelines. --- -Copyright © 2014-2017, Manuel Cortez. \ No newline at end of file +Copyright © 2014-2021, Manuel Cortez. \ No newline at end of file diff --git a/doc/documentation_importer.py b/doc/documentation_importer.py index 7fc927aa..f9b42c6f 100644 --- a/doc/documentation_importer.py +++ b/doc/documentation_importer.py @@ -1,28 +1,27 @@ # -*- coding: utf-8 -*- -from codecs import open """ This script converts the hold documentation (saved in markdown files) in a python file with a list of strings to translate it using gettext.""" def prepare_documentation_in_file(fileSource, fileDest): - """ This takes documentation written in a markdown file and put all the contents in a python file, to create a translatable documentation. - @fileSource str: A markdown(.md) file. - @fileDest str: A file where this will put the new strings""" + """ This takes documentation written in a markdown file and put all the contents in a python file, to create a translatable documentation. + @fileSource str: A markdown(.md) file. + @fileDest str: A file where this will put the new strings""" - f1 = open(fileSource, "r", encoding="utf-8") - f2 = open(fileDest, "w", encoding="utf-8") - lns = f1.readlines() - f2.write("# -*- coding: utf-8 -*-\n") - f2.write("documentation = [\n") - for i in lns: - if "\n" == i: - newvar = "\"\"," - elif "\n" == i[-1]: - newvar = "_(u\"\"\"%s\"\"\"),\n" % (i[:-1]) - else: - newvar = "_(u\"\"\"%s\"\"\"),\n" % (i) - f2.write(newvar) - f1.close() - f2.write("]") - f2.close() + f1 = open(fileSource, "r", encoding="utf-8") + f2 = open(fileDest, "w", encoding="utf-8") + lns = f1.readlines() + f2.write("# -*- coding: utf-8 -*-\n") + f2.write("documentation = [\n") + for i in lns: + if "\n" == i: + newvar = "\"\",\n" + elif "\n" == i[-1]: + newvar = "_(\"\"\"%s\"\"\"),\n" % (i[:-1]) + else: + newvar = "_(\"\"\"%s\"\"\"),\n" % (i) + f2.write(newvar) + f1.close() + f2.write("]") + f2.close() prepare_documentation_in_file("manual.md", "strings.py") diff --git a/doc/generator.py b/doc/generator.py index e26f7b75..01b03432 100644 --- a/doc/generator.py +++ b/doc/generator.py @@ -5,62 +5,83 @@ import locale import paths import markdown import shutil -from codecs import open as _open from importlib import reload -def change_language(name, language): - global _ - os.environ["lang"] = language - _ = gettext.install(name, os.path.join(paths.app_path(), "locales")) +# Languages already translated or translating the documentation. +documentation_languages = ["en", "es", "fr", "de", "it", "gl", "ja", "ru", "ro", "eu", "ca", "da", "sr"] -# the list of supported language codes of TW Blue -languages = ["en", "es", "fr", "de", "it", "gl", "ja", "ru", "ro", "eu", "ca", "da"] -def generate_document(language, document_type="documentation"): - if document_type == "documentation": - translation_file = "twblue-documentation" - change_language(translation_file, language) - reload(strings) - markdown_file = markdown.markdown("\n".join(strings.documentation[1:]), extensions=["markdown.extensions.toc"]) - title = strings.documentation[0] - filename = "manual.html" - elif document_type == "changelog": - translation_file = "twblue-changelog" - change_language(translation_file, language) - reload(changelog) - markdown_file = markdown.markdown("\n".join(changelog.documentation[1:]), extensions=["markdown.extensions.toc"]) - title = changelog.documentation[0] - filename = "changelog.html" - first_html_block = """ - - - %s - - - -

%s

- """ % (language, title, title) - first_html_block = first_html_block+ markdown_file - first_html_block = first_html_block + "\n\n" - if not os.path.exists(os.path.join("documentation", language)): - os.mkdir(os.path.join("documentation", language)) - mdfile = _open(os.path.join("documentation", language, filename), "w", encoding="utf-8") - mdfile.write(first_html_block) - mdfile.close() +# Changelog translated languages. +changelog_languages = ["en", "ca", "de", "es", "eu", "fr", "gl", "ja", "ro", "ru", "sr"] + +# this function will help us to have both strings.py and changelog.py without issues by installing a global dummy translation function. +def install_null_translation(name): + _ = gettext.NullTranslations() + _.install() + return + +def get_translations(name): + """ Create translation instances for every language of the translated document. """ + translations = {} + if "documentation" in name: + langs = documentation_languages + else: + langs = changelog_languages + for l in langs: + if l != "en": + _ = gettext.translation(name, os.path.join(paths.app_path(), "locales"), languages=[l]) + translations[l] = _ + else: + _ = gettext.NullTranslations() + translations[l] = _ + return translations + +def generate_document(lang, lang_name, document_type="documentation"): + """ Generates a document by using the provided lang object, which should be a translation, and lang_name, which should be the two letter code representing the language. """ + if document_type == "documentation": + translation_file = "twblue-documentation" + markdown_file = markdown.markdown("\n".join([lang.gettext(s) if s != "" else s for s in strings.documentation[1:]]), extensions=["markdown.extensions.toc"]) + title = lang.gettext(strings.documentation[0]) + filename = "manual.html" + elif document_type == "changelog": + translation_file = "twblue-changelog" + markdown_file = markdown.markdown("\n".join([lang.gettext(s) if s != "" else s for s in changelog.documentation[1:]]), extensions=["markdown.extensions.toc"]) + title = lang.gettext(changelog.documentation[0]) + filename = "changelog.html" + first_html_block = """ + + + %s + + + +

%s

+ """ % (lang_name, title, title) + first_html_block = first_html_block+ markdown_file + first_html_block = first_html_block + "\n\n" + if not os.path.exists(os.path.join("documentation", lang_name)): + os.mkdir(os.path.join("documentation", lang_name)) + mdfile = open(os.path.join("documentation", lang_name, filename), "w", encoding="utf-8") + mdfile.write(first_html_block) + mdfile.close() def create_documentation(): - print("Creating documentation in the supported languages...\n") - if not os.path.exists("documentation"): - os.mkdir("documentation") - if os.path.exists(os.path.join("documentation", "license.txt")) == False: - shutil.copy(os.path.join("..", "license.txt"), os.path.join("documentation", "license.txt")) - for i in languages: - print("Creating documentation for: %s" % (i,)) - generate_document(i) - generate_document(i, "changelog") - print("Done") + changelog_translations = get_translations("twblue-changelog") + documentation_translations = get_translations("twblue-documentation") + print("Creating documentation in the supported languages...\n") + if not os.path.exists("documentation"): + os.mkdir("documentation") + if os.path.exists(os.path.join("documentation", "license.txt")) == False: + shutil.copy(os.path.join("..", "license.txt"), os.path.join("documentation", "license.txt")) + for i in documentation_languages: + print("Creating documentation for: %s" % (i,)) + generate_document(lang_name=i, lang=documentation_translations.get(i)) + for i in changelog_languages: + print("Creating changelog for: %s" % (i,)) + generate_document(lang_name=i, lang=changelog_translations.get(i), document_type="changelog") + print("Done") -change_language("twblue-documentation", "en") +install_null_translation("twblue-documentation") import strings import changelog create_documentation() \ No newline at end of file diff --git a/doc/locales/ar/lc_messages/twblue-changelog.mo b/doc/locales/ar/lc_messages/twblue-changelog.mo index e505c5df..a6c44b3d 100644 Binary files a/doc/locales/ar/lc_messages/twblue-changelog.mo and b/doc/locales/ar/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/ar/lc_messages/twblue-changelog.po b/doc/locales/ar/lc_messages/twblue-changelog.po index 0084cb4a..5532b127 100644 --- a/doc/locales/ar/lc_messages/twblue-changelog.po +++ b/doc/locales/ar/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-07 13:48-0500\n" "Last-Translator: Manuel Cortez \n" "Language-Team: \n" diff --git a/doc/locales/ar/lc_messages/twblue-documentation.mo b/doc/locales/ar/lc_messages/twblue-documentation.mo index 768a5caa..e832dc6c 100644 Binary files a/doc/locales/ar/lc_messages/twblue-documentation.mo and b/doc/locales/ar/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/ar/lc_messages/twblue-documentation.po b/doc/locales/ar/lc_messages/twblue-documentation.po index 69e02f6a..c775b35d 100644 --- a/doc/locales/ar/lc_messages/twblue-documentation.po +++ b/doc/locales/ar/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2015-11-27 08:32-0600\n" "Last-Translator: Manuel Cortéz \n" "Language-Team: Mohammed Al Shara \n" diff --git a/doc/locales/ca/lc_messages/twblue-changelog.mo b/doc/locales/ca/lc_messages/twblue-changelog.mo index f1f2e071..9ed6631f 100644 Binary files a/doc/locales/ca/lc_messages/twblue-changelog.mo and b/doc/locales/ca/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/ca/lc_messages/twblue-changelog.po b/doc/locales/ca/lc_messages/twblue-changelog.po index 76d183f8..a4a7c0fc 100644 --- a/doc/locales/ca/lc_messages/twblue-changelog.po +++ b/doc/locales/ca/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TWBlue-Changelog V0.93\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 11:46+0200\n" "Last-Translator: Manuel Cortez \n" "Language-Team: Fran Torres Gallego. \n" diff --git a/doc/locales/ca/lc_messages/twblue-documentation.mo b/doc/locales/ca/lc_messages/twblue-documentation.mo index c1be3f5d..451a0653 100644 Binary files a/doc/locales/ca/lc_messages/twblue-documentation.mo and b/doc/locales/ca/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/ca/lc_messages/twblue-documentation.po b/doc/locales/ca/lc_messages/twblue-documentation.po index b8de28d6..6a22ad32 100644 --- a/doc/locales/ca/lc_messages/twblue-documentation.po +++ b/doc/locales/ca/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.89\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-03-25 15:15+0100\n" "Last-Translator: Joan Rabat \n" "Language-Team: Francisco Torres Gallego \n" diff --git a/doc/locales/da/LC_MESSAGES/twblue-documentation.mo b/doc/locales/da/LC_MESSAGES/twblue-documentation.mo index 106a512b..b93f7796 100644 Binary files a/doc/locales/da/LC_MESSAGES/twblue-documentation.mo and b/doc/locales/da/LC_MESSAGES/twblue-documentation.mo differ diff --git a/doc/locales/da/LC_MESSAGES/twblue-documentation.po b/doc/locales/da/LC_MESSAGES/twblue-documentation.po index a302adee..143d3f96 100644 --- a/doc/locales/da/LC_MESSAGES/twblue-documentation.po +++ b/doc/locales/da/LC_MESSAGES/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-11-17 10:25+0100\n" "Last-Translator: Nicolai Svendsen \n" "Language-Team: \n" diff --git a/doc/locales/de/lc_messages/twblue-changelog.mo b/doc/locales/de/lc_messages/twblue-changelog.mo index 3e4fa9d9..fd58e5ca 100644 Binary files a/doc/locales/de/lc_messages/twblue-changelog.mo and b/doc/locales/de/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/de/lc_messages/twblue-changelog.po b/doc/locales/de/lc_messages/twblue-changelog.po index 38ccfbfe..e681dee5 100644 --- a/doc/locales/de/lc_messages/twblue-changelog.po +++ b/doc/locales/de/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2019-03-17 16:39+0100\n" "Last-Translator: Steffen Schultz \n" "Language-Team: \n" diff --git a/doc/locales/de/lc_messages/twblue-documentation.mo b/doc/locales/de/lc_messages/twblue-documentation.mo index 022ae862..9d6b3961 100644 Binary files a/doc/locales/de/lc_messages/twblue-documentation.mo and b/doc/locales/de/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/de/lc_messages/twblue-documentation.po b/doc/locales/de/lc_messages/twblue-documentation.po index 08a7fe42..fb754089 100644 --- a/doc/locales/de/lc_messages/twblue-documentation.po +++ b/doc/locales/de/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TWBlue Documentation\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 11:01+0200\n" "Last-Translator: Steffen Schultz \n" "Language-Team: Steffen Schultz \n" diff --git a/doc/locales/es/LC_MESSAGES/twblue-changelog.mo b/doc/locales/es/LC_MESSAGES/twblue-changelog.mo index f9b5957d..82dbe54f 100644 Binary files a/doc/locales/es/LC_MESSAGES/twblue-changelog.mo and b/doc/locales/es/LC_MESSAGES/twblue-changelog.mo differ diff --git a/doc/locales/es/LC_MESSAGES/twblue-changelog.po b/doc/locales/es/LC_MESSAGES/twblue-changelog.po index 06defef6..36d645ee 100644 --- a/doc/locales/es/LC_MESSAGES/twblue-changelog.po +++ b/doc/locales/es/LC_MESSAGES/twblue-changelog.po @@ -5,8 +5,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2019-05-22 19:14+0200\n" +"Report-Msgid-Bugs-To: manuel@manuelcortez.net\n" +"POT-Creation-Date: 2021-11-12 12:52-0600\n" +"PO-Revision-Date: 2021-11-12 13:08-0600\n" "Last-Translator: José Manuel Delicado \n" "Language-Team: \n" "Language: es\n" @@ -14,18 +15,611 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 3.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../doc/changelog.py:3 -msgid "TWBlue Changelog" -msgstr "Lista de cambios de TWBlue" +#: changelog.py:3 +msgid "TWBlue Changelog" +msgstr "Lista de cambios de TWBlue" -#: ../doc/changelog.py:4 +#: changelog.py:5 msgid "## changes in this version" msgstr "## Cambios en esta versión" -#: ../doc/changelog.py:5 +#: changelog.py:7 +msgid "" +"* Now it is possible to create a tweet from a trending topics buffer again." +msgstr "" +"* De nuevo es posible crear un tweet desde un buffer de Tendencias.* Es " +"posible añadir tuits al buffer de me gusta desde la barra de menú otra vez." + +#: changelog.py:8 +msgid "" +"* TWBlue now includes a completely new set of dialogs to handle tweeting, " +"replying and sending direct messages that takes advantage of more Twitter " +"features." +msgstr "" +"* TWBlue incluye ahora un conjunto completamente nuevo de diálogos para " +"gestionar los tweets, las respuestas y el envío de mensajes directos que " +"aprovechan más funciones de la API de Twitter." + +#: changelog.py:9 +msgid "" +" * It is possible to add videos in tweets and direct messages by using " +"the new \"add\" button, located in every dialog where media can be added. " +"Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 " +"format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not " +"check if the uploaded video complies with Twitter media requirements. You " +"can add only a video in a tweet or direct message. No other kind of media " +"can be added after a video is in a tweet. If the video was unable to be " +"uploaded successfully, the tweet or direct message won't be created." +msgstr "" +" * Ahora ya es posible añadir vídeos en los tweets y mensajes directos " +"utilizando el nuevo botón \"añadir\", situado en todos los diálogos donde se " +"pueden añadir medios. Twitter sugiere añadir vídeos de entre 5 segundos y 2 " +"minutos de duración, en formato mp4 (códec de vídeo H.264 y códec de audio " +"AAC). Actualmente, TWBlue no comprueba si el vídeo subido cumple con los " +"requisitos de los medios de comunicación de Twitter. Sólo se puede añadir un " +"vídeo en un tweet o mensaje directo. No se puede añadir ningún otro tipo de " +"medio después de que un vídeo esté en un tweet. Si el vídeo no se ha podido " +"subir con éxito, el tuit o el mensaje directo no se creará." + +#: changelog.py:10 +msgid "" +" * Now you can add a poll to tweets. Polls can have up to 4 different " +"options and allow voting up to 7 days after being created. Take into " +"account, though, that currently TWBlue does not support reading polls in " +"tweets." +msgstr "" +" * Ahora puedes añadir una encuesta a los tweets. Las encuestas pueden " +"tener hasta 4 opciones diferentes y permiten votar hasta 7 días después de " +"ser creadas. Ten en cuenta, sin embargo, que actualmente TWBlue no soporta " +"la lectura de encuestas en los tweets." + +#: changelog.py:11 +msgid "" +" * TWBlue now support threads while creating a new tweet. There is a new " +"button, called add tweet which will add the current tweet to the thread and " +"will allow you to write another tweet in the thread. Every tweet might " +"include media (up to 4 photos, or one GIF image or a video) or up to one " +"poll." +msgstr "" +" * TWBlue ahora soporta hilos mientras se crea un nuevo tweet. Hay un " +"nuevo botón, llamado añadir tweet, que añadirá el tweet actual al hilo y te " +"permitirá escribir otro tweet en el hilo. Cada tweet puede incluir medios " +"(hasta 4 fotos, o una imagen GIF o un video) y una encuesta." + +#: changelog.py:12 +msgid "" +" * Some functionality was removed from tweet dialogs within TWBlue. " +"Particularly, URL shorteners and long tweets via Twishort. You still can " +"read long tweets posted via Twishort, though." +msgstr "" +" * Se han eliminado algunas características de los diálogos de tweets en " +"TWBlue. En particular, los acortadores de URL y los tweets largos a través " +"de Twishort. Sin embargo, todavía se pueden leer los tweets largos " +"publicados a través de Twishort." + +#: changelog.py:14 +msgid "## Changes in version 2021.11.07" +msgstr "## Cambios en la versión 2021.11.07" + +#: changelog.py:16 +msgid "" +"* TWBlue should retrieve tweets from threads and conversations in a more " +"reliable way. Tweets in the same thread (made by the same author) will be " +"sorted correctly, although replies to the thread (made by different people) " +"may not be ordered in the same way they are displayed in Twitter apps. " +"([#417](https://github.com/manuelcortez/TWBlue/issues/417))" +msgstr "" +"* TWBlue debería mostrar los hilos y conversaciones de manera más eficiente. " +"Los hilos se mostrarán en el orden en el que fueron creados, mientras que " +"las respuestas a alguno de los tweets que componen el hilo se podrían " +"mostrar en un orden diferente al que se muestra en las aplicaciones de " +"Twitter. ([#417](https://github.com/manuelcortez/TWBlue/issues/417))" + +#: changelog.py:17 +msgid "" +"* When creating a filter, TWBlue will show an error if user has not provided " +"a name for the filter. Before, unnamed filters were a cause of config breaks " +"in the application." +msgstr "" +"* Al crear un filtro, TWBlue mostrará un error si el usuario no ha " +"proporcionado un nombre para el filtro. Antes, los filtros sin nombre se " +"guardaban en la configuración y causaban errores al iniciar la aplicación." + +#: changelog.py:18 +#, fuzzy +#| msgid "" +#| "* It is possible to add a tweet to the likes buffer from the menu bar " +#| "again." +msgid "" +"* It is again possible to read the changelog for TWBlue from the help menu " +"in the menu bar." +msgstr "" +"* Es posible añadir tuits al buffer de me gusta desde la barra de menú otra " +"vez." + +#: changelog.py:19 +msgid "" +"* fixed a bug when clearing the direct messages buffer. ([#418](https://" +"github.com/manuelcortez/TWBlue/issues/418))" +msgstr "" +"* Corregido un error que impedía vaciar el buffer de mensajes directos. " +"([#418](https://github.com/manuelcortez/TWBlue/issues/418))* solucionado un " +"problema en el Streaming API que causaba que TWBlue desconectara el " +"Streaming. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" + +#: changelog.py:20 +msgid "" +"* fixed an issue that was making TWBlue to show incorrectly titles for " +"trending topic buffers upon startup. ([#421](https://github.com/manuelcortez/" +"TWBlue/issues/421))" +msgstr "" +"* Se ha corregido un problema que hacía que TWBlue mostrara de forma " +"incorrecta los títulos de los buffers de trending topics al iniciarse. " +"([#421](https://github.com/manuelcortez/TWBlue/issues/421))" + +#: changelog.py:21 +msgid "" +"* fixed an issue that was making users of the graphical user interface to " +"delete a buffer if a trends buffer was opened in the same session." +msgstr "" +"* Se ha solucionado un problema que hacía que los usuarios de la interfaz " +"gráfica no pudieran borrar algunos buffers si se abría un buffer de " +"tendencias en la misma sesión." + +#: changelog.py:22 +#, fuzzy +#| msgid "* Updated romanian translation." +msgid "* Updated Spanish, Japanese and french translations." +msgstr "* Actualizada la traducción al rumano." + +#: changelog.py:24 +msgid "## Changes in Version 2021.10.30" +msgstr "## Cambios en la versión 2021.10.30" + +#: changelog.py:26 +msgid "" +"* Fixed many errors in the way we compile TWBlue, so users of 64 bits " +"systems and particularly windows 7 users would be able to install TWBlue " +"again. In case of issues with versions prior to 2021.10.30, please remove " +"everything related to TWBlue (except configs) and reinstall the version " +"2021.10.30 to fix any possible error. This step won't be needed again in 23 " +"months. ([#416,](https://github.com/manuelcortez/TWBlue/issues/416), [#415,]" +"(https://github.com/manuelcortez/TWBlue/issues/415))" +msgstr "" +"* Se han corregido algunos errores importantes en el proceso que utilizamos " +"para compilar las versiones de TWBlue. Gracias a estas correcciones, los " +"usuarios de sistemas de 64 bits, y en particular, los usuarios de Windows 7, " +"podrán volver a utilizar TWBlue con normalidad. En caso de presentar " +"problemas con versiones 2021.10.30 o anteriores, por favor elimina todo lo " +"relacionado con la aplicación (esta vez, sin incluir la configuración) e " +"intenta instalar desde cero. Esto no volverá a ser necesario por los " +"próximos 23 meses.([#416,](https://github.com/manuelcortez/TWBlue/" +"issues/416), [#415,](https://github.com/manuelcortez/TWBlue/issues/415))" + +#: changelog.py:27 +msgid "" +"* fixed an issue that was making impossible to manually add an user to the " +"autocomplete users database." +msgstr "" +"* Corregido un error que causaba que fuera imposible añadir manualmente un " +"usuario a la base de datos de autocompletado." + +#: changelog.py:28 +msgid "" +"* Started to improve support to conversations by searching for " +"conversation_id." +msgstr "" +"* Se ha comenzado a mejorar el soporte a las conversaciones e hilos buscando " +"por el parámetro conversation_id en Twitter." + +#: changelog.py:30 +msgid "## changes in version 2021.10.27" +msgstr "## Cambios en la versión 2021.10.27" + +#: changelog.py:32 +msgid "" +"* Added an user alias manager, located in the application menu in the menu " +"bar. From this dialog, it is possible to review, add, edit or remove user " +"aliases for the current account. ([#401](https://github.com/manuelcortez/" +"TWBlue/issues/401))" +msgstr "" +"* Agregado un administrador de alias de usuario, ubicado en la barra de " +"menú, dentro del menú de aplicación. Desde este apartado, es posible añadir, " +"editar y eliminar el alias para los usuarios de la cuenta seleccionada. " +"([#401](https://github.com/manuelcortez/TWBlue/issues/401))" + +#: changelog.py:33 +msgid "" +"* TWBlue now closes the VLC player window automatically when a video reaches " +"its end. ([#399](https://github.com/manuelcortez/TWBlue/issues/399))" +msgstr "" +"* TWBlue ahora cierra la ventana de reproducción de VLC al terminar la " +"reproducción de un video. ([#399](https://github.com/manuelcortez/TWBlue/" +"issues/399))" + +#: changelog.py:34 +msgid "" +"* After a lot of time, TWBlue now uses a new default Soundpack, called " +"FreakyBlue. This soundpack will be set by default in all new sessions " +"created in the application. Thanks to [Andre Louis](https://twitter.com/" +"FreakyFwoof) for the pack. ([#247](https://github.com/manuelcortez/TWBlue/" +"issues/247))" +msgstr "" +"* Después de mucho tiempo, TWBlue tiene un paquete de sonidos nuevo, llamado " +"FreakyBlue. Este paquete será el seleccionado por defecto al iniciar sesión " +"en la aplicación. Gracias a [Andre Louis](https://twitter.com/FreakyFwoof) " +"por tomarse el trabajo de diseñar el paquete de sonidos para TWBlue. ([#247]" +"(https://github.com/manuelcortez/TWBlue/issues/247))" + +#: changelog.py:35 +msgid "" +"* 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." +msgstr "" +"* Cuando se lea un tweet, si el elemento contiene muchos usuarios " +"mencionados, TWBlue indicará los primeros dos usuarios e indicará el número " +"de usuarios adicionales que tiene el tweet, en lugar de leer todos y cada " +"uno de los usuarios que han sido mencionados. Todavía puede verse el " +"conjunto de usuarios mencionados en el tweet utilizando el diálogo de ver " +"tweets." + +#: changelog.py:36 +msgid "" +"* 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\"." +msgstr "" +"* En el diálogo para mostrar tweets, es posible copiar el vínculo de acceso " +"directo al tweet o usuario seleccionando el botón llamado \"copiar vínculo " +"al portapapeles\"." + +#: changelog.py:37 +msgid "" +"* Added a keymap capable to work under Windows 11. ([#391](https://github." +"com/manuelcortez/TWBlue/pull/391))" +msgstr "" +"* Se ha añadido un mapa de teclado capaz de funcionar correctamente en " +"Windows 11. ([#391](https://github.com/manuelcortez/TWBlue/pull/391))" + +#: changelog.py:38 +msgid "" +"* 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))" +msgstr "" +"* Se han añadido alias de usuario a TWBlue. Esta función permite renombrar " +"los usuarios que se muestran en Twitter, de modo que la próxima vez que se " +"lea un usuario se anunciará tal y como esté configurado. Para añadir un " +"alias a un usuario, selecciona la opción \"añadir alias\" en el menú de " +"usuario, situado en la barra de menú. Esta opción sólo funciona si has " +"desmarcado la opción de mostrar nombres de pantalla. Los usuarios se " +"muestran con su nombre de pantalla sólo en los buffers de personas. Esta " +"acción es compatible con todos los mapas de teclado, aunque no está asignada " +"a ninguna combinación de teclado por defecto. ([#389](https://github.com/" +"manuelcortez/TWBlue/pull/389))" + +#: changelog.py:39 +msgid "* There are some changes to the autocomplete users feature:" +msgstr "* Hemos introducido algunos cambios al autocompletado de usuarios:" + +#: changelog.py:40 +msgid "" +" * Now users can search for twitter screen names or display names in the " +"database." +msgstr "" +" * Ahora, es posible buscar utilizando los nombres de pantalla o nombres " +"para mostrar de los usuarios de Twitter." + +#: changelog.py:41 +msgid "" +"* It is possible to undefine keystrokes in the current keymap in TWBlue. " +"This allows you, for example, to redefine keystrokes completely." +msgstr "" +"* Es posible desasignar combinaciones de teclado en el mapa de teclado en " +"uso en TWBlue. Esto permite, por ejemplo, desasignar combinaciones de " +"teclado para utilizarlas en otras funciones." + +#: changelog.py:42 +msgid "" +"* 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))" +msgstr "" +"* Hemos cambiado nuestro proveedor de servicio de geocodificación a la API " +"Nominatim de OpenStreetMap. Las direcciones presentes en los tweets van a " +"ser determinadas por este servicio, ya que la API de Google Maps requiere " +"ahora una clave API de pago. ([#390](https://github.com/manuelcortez/TWBlue/" +"issues/390))" + +#: changelog.py:43 +msgid "" +"* 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))" +msgstr "" +"* Se ha añadido una versión limitada de la Streaming API de Twitter: La " +"Streaming API funcionará sólo para los tweets, y recibirá los tweets sólo de " +"las personas que sigues. Los usuarios protegidos no serán incluidos en los " +"tweets que se reciben en la streaming API. Es posible que durante un alto " +"tráfico de tweets, el Stream pueda desconectarse a veces, pero TWBlue " +"debería ser capaz de detectar este problema y reconectar el stream de nuevo. " +"([#385](https://github.com/manuelcortez/TWBlue/pull/385))" + +#: changelog.py:44 +msgid "" +"* 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))" +msgstr "" +"* Se ha corregido un problema que causaba que TWBlue fuera incapaz de " +"mostrar nada al intentar ver el perfil de un usuario suspendido. ([#387]" +"(https://github.com/manuelcortez/TWBlue/issues/387))" + +#: changelog.py:45 +msgid "" +"* 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))" +msgstr "" +"* Se ha añadido soporte para audio y vídeos de Twitter: Los tweets que " +"contengan audio o vídeos serán detectados como elementos de audio, y podrás " +"reproducirlos con el comando habitual para reproducir audios. ([#384,]" +"(https://github.com/manuelcortez/TWBlue/pull/384))" + +#: changelog.py:46 +msgid "" +"* We just implemented some changes in the way TWBlue handles tweets in order " +"to reduce its RAM memory usage [#380](https://github.com/manuelcortez/TWBlue/" +"pull/380):" +msgstr "" +"* Hemos implementado una serie de cambios en la forma en que TWBlue almacena " +"los tweets, con el objetivo de mejorar el consumo de memoria y CPU. [#380]" +"(https://github.com/manuelcortez/TWBlue/pull/380):" + +#: changelog.py:47 +msgid "" +" * We reduced the tweets size by storing only the tweet fields we " +"currently use. This should reduce tweet's size in memory for every object up " +"to 75%." +msgstr "" +" * Hemos logrado reducir el tamaño de los tweets almacenando sólo los " +"campos de información que usamos actualmente. Esto debería reducir el tamaño " +"del tweet en la memoria para cada objeto hasta un 75%." + +#: changelog.py:48 +msgid "" +" * When using the cache database to store your tweets, there is a new " +"setting present in the account settings dialog, in the general tab. This " +"setting allows you to control whether TWBlue will load the whole database " +"into memory (which is the current behaviour) or not." +msgstr "" +" * Cuando se utiliza la base de datos de caché para almacenar tweets, hay " +"un nuevo ajuste presente en el diálogo de configuración de la cuenta, en la " +"pestaña general. Este ajuste te permite controlar si TWBlue cargará toda la " +"base de datos en la memoria RAM (Opción predeterminada) o no." + +#: changelog.py:49 +msgid "" +" * Loading the whole database into memory has the advantage of being " +"extremely fast to access any element (for example when moving through tweets " +"in a buffer), but it requires more memory as the tweet buffers grow up. This " +"should, however, use less memory than before thanks to the optimizations " +"performed in tweet objects. If you have a machine with enough memory, this " +"should be a good option for your case." +msgstr "" +" * Cargar toda la base de datos en la memoria tiene la ventaja de ser " +"extremadamente rápido para acceder a cualquier elemento (por ejemplo, al " +"desplazarse por los tweets en un buffer), pero requiere más memoria a medida " +"que los buffers de tweets se hacen más grandes. Sin embargo, debería " +"utilizar menos memoria que antes gracias a las optimizaciones realizadas en " +"los objetos de tweets. Si tienes una máquina con suficiente memoria, esta " +"debería ser una buena opción para ti." + +#: changelog.py:50 +msgid "" +" * If you uncheck this setting, TWBlue will read the whole database " +"from disk. This is significantly slower, but the advantage of this setting " +"is that it will consume almost no extra memory, no matter how big is the " +"tweets dataset. Be ware, though, that TWBlue might start to feel slower when " +"accessing elements (for example when reading tweets) as the buffers grow up. " +"This setting is suggested for computers with low memory or for those people " +"not wanting to keep a really big amount of tweets stored." +msgstr "" +" * Si desmarcas esta opción, TWBlue leerá toda la base de datos desde " +"el disco. Esto es significativamente más lento, pero la ventaja de esta " +"opción es que no consumirá casi nada de memoria extra, sin importar lo " +"grande que sea el buffer. Sin embargo, ten en cuenta que TWBlue puede " +"empezar a ser más lento al acceder a los elementos (por ejemplo, al leer " +"tweets) a medida que los buffers se hacen más grandes. Esta configuración se " +"sugiere para ordenadores con poca memoria o para aquellas personas que no " +"quieran mantener una cantidad realmente grande de tweets almacenados." + +#: changelog.py:51 +msgid "" +"* Changed the label in the direct message's text control so it will indicate " +"that the user needs to write the text there, without referring to any " +"username in particular. ([#366,](https://github.com/manuelcortez/TWBlue/" +"issues/366))" +msgstr "" +"* Se ha cambiado la etiqueta del campo de texto para escribir el recipiente " +"de un mensaje directo. Ahora en dicho campo no se especifica ningún nombre " +"de usuario. ([#366,](https://github.com/manuelcortez/TWBlue/issues/366))" + +#: changelog.py:52 +msgid "" +"* TWBlue will take Shift+F10 again as the contextual menu key in the list of " +"items in a buffer. This stopped working after we have migrated to WX 4.1. " +"([#353,](https://github.com/manuelcortez/TWBlue/issues/353))" +msgstr "" +"* TWBlue puede volver a usar la combinación de teclado Shift+F10 como la " +"tecla de menú contextual." + +#: changelog.py:53 +msgid "" +"* TWBlue should render correctly retweets of quoted tweets. ([#365,](https://" +"github.com/manuelcortez/TWBlue/issues/365))" +msgstr "" +"* TWBlue debería mostrar apropiadamente los retweets de un tweet citado. " +"([#365,](https://github.com/manuelcortez/TWBlue/issues/365))" + +#: changelog.py:54 +msgid "" +"* Fixed an error that was causing TWBlue to be unable to output to screen " +"readers at times. ([#369,](https://github.com/manuelcortez/TWBlue/" +"issues/369))" +msgstr "" +"* Corregido un error que causaba que en ocasiones, TWBlue fuera incapaz de " +"enviar texto a los lectores de pantalla. ([#369,](https://github.com/" +"manuelcortez/TWBlue/issues/369))" + +#: changelog.py:55 +msgid "" +"* Fixed autocomplete users feature. ([#367,](https://github.com/manuelcortez/" +"TWBlue/issues/367))" +msgstr "" +"* Corregida la característica de autocompletado de usuarios. ([#367,]" +"(https://github.com/manuelcortez/TWBlue/issues/367))" + +#: changelog.py:56 +msgid "" +"* Fixed error when displaying an URL at the end of a line, when the tweet or " +"direct message contained multiple lines. Now the URL should be displayed " +"correctly. ([#305,](https://github.com/manuelcortez/TWBlue/issues/305) " +"[#272,](https://github.com/manuelcortez/TWBlue/issues/272))" +msgstr "" +"* Corregido un error al intentar colocar direcciones URL en tweets o " +"mensajes directos con múltiples líneas. Ahora deberían verse correctamente " +"todas las direcciones. ([#305,](https://github.com/manuelcortez/TWBlue/" +"issues/305) [#272,](https://github.com/manuelcortez/TWBlue/issues/272))" + +#: changelog.py:57 +msgid "" +"* TWBlue has been migrated completely to Python 3 (currently, the software " +"builds with Python 3.8)." +msgstr "" +"* TWBlue ha sido migrado completamente a Python 3 (actualmente, el software " +"se construye con Python 3.8)." + +#: changelog.py:58 +msgid "" +"* TWBlue should be restarted gracefully. Before, the application was " +"alerting users of not being closed properly every time the application " +"restarted by itself." +msgstr "" +"* TWBlue debería reiniciarse apropiadamente. Antes, la aplicación alertaba a " +"los usuarios de que no se cerraba correctamente cada vez que debía efectuar " +"un reinicio." + +#: changelog.py:59 +msgid "" +"* If TWBlue attemps to load an account with invalid tokens (this happens " +"when reactivating a previously deactivated account, or when access to the ap " +"is revoqued), TWBlue will inform the user about this error and will skip the " +"account. Before, the app was unable to start due to a critical error. " +"([#328,](https://github.com/manuelcortez/TWBlue/issues/328))" +msgstr "" +"* Si TWBlue intenta cargar una cuenta con tokens no válidos (esto ocurre " +"cuando se reactiva una cuenta previamente desactivada, o cuando se revoca el " +"acceso a la ap), TWBlue informará al usuario sobre este error y omitirá la " +"sesión. Antes, la aplicación no podía iniciarse debido a un error crítico. " +"([#328,](https://github.com/manuelcortez/TWBlue/issues/328))" + +#: changelog.py:60 +msgid "" +"* When sending a direct message, the title of the window will change " +"appropiately when the recipient is edited. ([#276,](https://github.com/" +"manuelcortez/TWBlue/issues/276))" +msgstr "" +"* Al enviar un mensaje directo, el título de la ventana cambiará " +"apropiadamente cada vez que el recipiente es editado. ([#276,](https://" +"github.com/manuelcortez/TWBlue/issues/276))" + +#: changelog.py:61 +msgid "" +"* URL'S in user profiles are expanded automatically. ([#275,](https://github." +"com/manuelcortez/TWBlue/issues/275))" +msgstr "" +"* Las direcciones URL de los perfiles de usuario estarán expandidas " +"automáticamente. ([#275,](https://github.com/manuelcortez/TWBlue/issues/275))" + +#: changelog.py:62 +msgid "" +"* TWBlue now uses [Tweepy,](https://github.com/tweepy/tweepy) to connect " +"with Twitter. We have adopted this change in order to support Twitter'S API " +"V 2 in the very near future. ([#333,](https://github.com/manuelcortez/TWBlue/" +"issues/337) [#347](https://github.com/manuelcortez/TWBlue/pull/347))" +msgstr "" +"* TWBlue ahora utiliza la librería [Tweepy](https://github.com/tweepy/" +"tweepy) para conectar con Twitter. Hemos decidido adoptar este cambio para " +"así poder utilizar las características presentes en la versión 2 de la API " +"de Twitter en un futuro cercano. ([#333,](https://github.com/manuelcortez/" +"TWBlue/issues/337) [#347](https://github.com/manuelcortez/TWBlue/pull/347))" + +#: changelog.py:63 +msgid "" +"* TWBlue can upload images in Tweets and replies again. ([#240,](https://" +"github.com/manuelcortez/TWBlue/issues/240))" +msgstr "" +"* TWBlue puede subir imágenes en tweets y respuestas de nuevo. ([#240,]" +"(https://github.com/manuelcortez/TWBlue/issues/240))" + +#: changelog.py:64 +msgid "" +"* Fixed the way we use to count characters in Twitter. The new methods in " +"TWBlue take into account special characters and URLS as documented in " +"Twitter. ([#199,](https://github.com/manuelcortez/TWBlue/issues/199) [#315]" +"(https://github.com/manuelcortez/TWBlue/issues/315))" +msgstr "" +"* Hemos corregido la manera en la que TWBlue cuenta los caracteres en los " +"tweets y al escribir. Ahora los caracteres serán contados de acuerdo con las " +"especificaciones de Twitter. ([#199,](https://github.com/manuelcortez/TWBlue/" +"issues/199) [#315](https://github.com/manuelcortez/TWBlue/issues/315))" + +#: changelog.py:65 +msgid "* Proxy support now works as expected." +msgstr "* El soporte Proxy ahora debería funcionar como es debido." + +#: changelog.py:66 +msgid "" +"* Changed translation service from yandex.translate to Google Translator. " +"([#355,](https://github.com/manuelcortez/TWBlue/issues/355))" +msgstr "" +"* Hemos cambiado el servicio de traducción de yandex.translate a Google " +"Translate. ([#355,](https://github.com/manuelcortez/TWBlue/issues/355))" + +#: changelog.py:67 +msgid "" +"* Improved method to load direct messages in the buffers. Now it should be " +"faster due to less calls to Twitter API performed from the client." +msgstr "" +"* Se ha mejorado el método para cargar los mensajes directos en los buffers. " +"Ahora debería ser más rápido debido a que se realizan menos llamadas a la " +"API de Twitter desde el cliente." + +#: changelog.py:68 +msgid "" +"* And more. ([#352,](https://github.com/manuelcortez/TWBlue/issues/352))" +msgstr "* Y más ([#352,](https://github.com/manuelcortez/TWBlue/issues/352))" + +#: changelog.py:70 +msgid "## Changes in version 0.95" +msgstr "## Cambios en la versión 0.95" + +#: changelog.py:72 msgid "" "* TWBlue can open a Tweet or user directly in Twitter. There is a new option " "in the context menu for people and tweet buffers, and also, the shortcut " @@ -36,12 +630,12 @@ msgstr "" "también el atajo control+win+alt+enter para abrir en Twitter el elemento con " "el foco." -#: ../doc/changelog.py:6 +#: changelog.py:73 msgid "* Some keystrokes were remapped in the Windows 10 Keymap:" msgstr "" "* Cambiados algunos atajos de teclado en el mapa de teclado de Windows 10:" -#: ../doc/changelog.py:7 +#: changelog.py:74 msgid "" " * Read location of a tweet: Ctrl+Win+G. ([#177](https://github.com/" "manuelcortez/TWBlue/pull/177))" @@ -49,17 +643,17 @@ msgstr "" " * Leer ubicación de un tuit: CTRL+Win+G. ([#177](https://github.com/" "manuelcortez/TWBlue/pull/177))" -#: ../doc/changelog.py:8 +#: changelog.py:75 msgid " * Open global settings dialogue: Ctrl+Win+Alt+O." msgstr " * Abrir diálogo de configuración global: Ctrl+Win+Alt+O." -#: ../doc/changelog.py:9 +#: changelog.py:76 msgid " * Mute/unmute current session: Control + Windows + Alt + M." msgstr "" " * Silenciar / desactivar silencio en la sesión actual: Control + Windows " "+ Alt + M." -#: ../doc/changelog.py:10 +#: changelog.py:77 msgid "" "* Fixed an error that was preventing TWBlue to load the direct messages " "buffer if an user who sent a message has been deleted." @@ -67,7 +661,7 @@ msgstr "" "* Corregido un error que impedía a TWBlue cargar el buffer de mensajes " "directos si se ha eliminado un usuario que envió un mensaje." -#: ../doc/changelog.py:11 +#: changelog.py:78 msgid "" "* Added support for playing audios posted in [AnyAudio.net](http://anyaudio." "net) directly from TWBlue. Thanks to [Sam Tupy](http://www.samtupy.com/)" @@ -76,7 +670,7 @@ msgstr "" "(http://anyaudio.net) directamente desde TWBlue. Gracias a [Sam Tupy](http://" "www.samtupy.com/)" -#: ../doc/changelog.py:12 +#: changelog.py:79 msgid "" "* Custom buffer ordering will not be reset every time the application " "restarts after an account setting has been modified." @@ -84,7 +678,7 @@ msgstr "" "* El orden personalizado de buffers no se restablecerá cada vez que la " "aplicación se reinicie tras modificar un ajuste de la cuenta." -#: ../doc/changelog.py:13 +#: changelog.py:80 msgid "" "* When adding or removing an user from a list, it is possible to press enter " "in the focused list instead of having to search for the \"add\" or \"delete" @@ -94,7 +688,7 @@ msgstr "" "la lista con el foco en vez de tener que buscar los botones \"Añadir\" o " "\"Eliminar\"." -#: ../doc/changelog.py:14 +#: changelog.py:81 msgid "" "* Quoted and long tweets are displayed properly in the sent tweets buffer " "after being send. ([#253](https://github.com/manuelcortez/TWBlue/issues/253))" @@ -103,7 +697,7 @@ msgstr "" "enviados después de enviarse. ([#253](https://github.com/manuelcortez/TWBlue/" "issues/253))" -#: ../doc/changelog.py:15 +#: changelog.py:82 msgid "" "* Fixed an issue that was making the list manager keystroke unable to be " "shown in the keystroke editor. Now the keystroke is listed properly. ([#260]" @@ -114,7 +708,7 @@ msgstr "" "se lista adecuadamente. ([#260](https://github.com/manuelcortez/TWBlue/" "issues/260))" -#: ../doc/changelog.py:16 +#: changelog.py:83 msgid "" "* The volume slider, located in the account settings of TWBlue, now should " "decrease and increase value properly when up and down arrows are pressed. " @@ -126,7 +720,7 @@ msgstr "" "arriba y abajo. Antes lo hacía en orden inverso. ([#261](https://github.com/" "manuelcortez/TWBlue/issues/261))" -#: ../doc/changelog.py:17 +#: changelog.py:84 msgid "" "* autoreading has been redesigned to work in a similar way for almost all " "buffers. Needs testing. ([#221](https://github.com/manuelcortez/TWBlue/" @@ -136,7 +730,7 @@ msgstr "" "casi todos los buffers. Necesita pruebas. ([#221](https://github.com/" "manuelcortez/TWBlue/issues/221))" -#: ../doc/changelog.py:18 +#: changelog.py:85 msgid "" "* When displaying tweets or direct messages, a new field has been added to " "show the date when the item has been posted to Twitter." @@ -144,7 +738,7 @@ msgstr "" "* Al mostrar tuits o mensajes directos, ahora hay un nuevo campo que muestra " "la fecha en la que se publicó ese elemento en Twitter." -#: ../doc/changelog.py:19 +#: changelog.py:86 msgid "" "* Added support for deleting direct messages by using the new Twitter API " "methods." @@ -152,14 +746,14 @@ msgstr "" "* Se ha añadido soporte para eliminar mensajes directos usando los nuevos " "métodos de la API de Twitter." -#: ../doc/changelog.py:20 +#: changelog.py:87 msgid "" "* When quoting a retweet, the quote will be made to the original tweet " "instead of the retweet." msgstr "" "* Al citar un retuit, la cita apuntará al tuit original en vez del retuit." -#: ../doc/changelog.py:21 +#: changelog.py:88 msgid "" "* If the sent direct messages buffer is hidden, TWBlue should keep loading " "everything as expected. ([#246](https://github.com/manuelcortez/TWBlue/" @@ -169,7 +763,7 @@ msgstr "" "cargar todo como se espera. ([#246](https://github.com/manuelcortez/TWBlue/" "issues/246))" -#: ../doc/changelog.py:22 +#: changelog.py:89 msgid "" "* There is a new soundpack, called FreakyBlue (Thanks to [Andre Louis]" "(https://twitter.com/FreakyFwoof)) as a new option in TWBlue. This pack can " @@ -183,7 +777,7 @@ msgstr "" "que los usuarios deberían echar un vistazo y dar su opinión en las " "snapshots. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))" -#: ../doc/changelog.py:23 +#: changelog.py:90 msgid "" "* There is a new option in the help menu that allows you to visit the " "soundpacks section in the TWBlue website. ([#247](https://github.com/" @@ -193,7 +787,7 @@ msgstr "" "paquetes de sonidos en el sitio web de TWBlue. ([#247](https://github.com/" "manuelcortez/TWBlue/issues/247))" -#: ../doc/changelog.py:24 +#: changelog.py:91 msgid "" "* When reading location of a geotagged tweet, it will be translated for " "users of other languages. ([#251](https://github.com/manuelcortez/TWBlue/" @@ -203,7 +797,7 @@ msgstr "" "usuarios de otros idiomas. ([#251](https://github.com/manuelcortez/TWBlue/" "pull/251))" -#: ../doc/changelog.py:25 +#: changelog.py:92 msgid "" "* When there are no more items to retrieve in direct messages and people " "buffers, a message will announce it." @@ -211,7 +805,7 @@ msgstr "" "* Cuando no haya más elementos que recuperar en los buffers de mensajes " "directos y personas, un mensaje lo indicará." -#: ../doc/changelog.py:26 +#: changelog.py:93 msgid "" "* Fixed an issue reported by some users that was making them unable to load " "more items in their direct messages." @@ -219,14 +813,14 @@ msgstr "" "* Corregido un problema reportado por algunos usuarios que les impedía " "cargar más elementos en sus mensajes directos." -#: ../doc/changelog.py:27 +#: changelog.py:94 msgid "" "* It is possible to add a tweet to the likes buffer from the menu bar again." msgstr "" "* Es posible añadir tuits al buffer de me gusta desde la barra de menú otra " "vez." -#: ../doc/changelog.py:28 +#: changelog.py:95 msgid "" "* Tweets, replies and retweets will be added to sent tweets right after " "being posted in Twitter." @@ -234,16 +828,16 @@ msgstr "" "* Los tuits, respuestas y retuits se añadirán a los tuits enviados justo al " "publicarse en Twitter." -#: ../doc/changelog.py:29 +#: changelog.py:96 msgid "* Extended Tweets should be displayed properly in list buffers." msgstr "" "* Los tuits largos deberían mostrarse correctamente en los buffers de listas." -#: ../doc/changelog.py:30 +#: changelog.py:98 msgid "## Changes in version 0.94" msgstr "## Cambios en la versión 0.94" -#: ../doc/changelog.py:31 +#: changelog.py:100 msgid "" "* Added an option in the global settings dialog to disable the Streaming " "features of TWBlue. TWBlue will remove all Streaming features after August " @@ -257,7 +851,7 @@ msgstr "" "permite saber cómo se comportará la aplicación al llegar ese día. ([#219]" "(https://github.com/manuelcortez/TWBlue/issues/219))" -#: ../doc/changelog.py:32 +#: changelog.py:101 msgid "" "* Due to Twitter API changes, Switched authorisation method to Pin-code " "based authorisation. When you add new accounts to TWBlue, you will be " @@ -270,7 +864,7 @@ msgstr "" "autorizar recibirás un número que deberás pegar en la ventana de TWBlue para " "poder continuar. ([#216](https://github.com/manuelcortez/TWBlue/issues/216))" -#: ../doc/changelog.py:33 +#: changelog.py:102 msgid "" "* In order to comply with latest Twitter changes, TWBlue has switched to the " "new method used to send and receive direct messages, according to issue " @@ -281,7 +875,7 @@ msgstr "" "directos, de acuerdo con lo dispuesto en el issue [#215.](https://github.com/" "manuelcortez/twblue/issues/215)" -#: ../doc/changelog.py:34 +#: changelog.py:103 msgid "" " * The new method does not allow direct messages to be processed in real " "time. Direct messages will be updated periodically." @@ -290,7 +884,7 @@ msgstr "" "tiempo real. Los mensajes directos se actualizarán periódicamente, pero no " "en tiempo real." -#: ../doc/changelog.py:35 +#: changelog.py:104 msgid "" "* After august 16 or when streaming is disabled, the events buffer will no " "longer be created in TWBlue." @@ -298,7 +892,7 @@ msgstr "" "* Luego del 16 de agosto o si las características en tiempo real han sido " "desactivadas, el buffer de eventos dejará de ser utilizado en TWBlue." -#: ../doc/changelog.py:36 +#: changelog.py:105 msgid "" "* You can configure frequency for buffer updates in TWBlue. By default, " "TWBlue will update all buffers every 2 minutes, but you can change this " @@ -310,7 +904,7 @@ msgstr "" "esto puede cambiarse desde el diálogo de opciones globales. ([#223](https://" "github.com/manuelcortez/TWBlue/issues/223))" -#: ../doc/changelog.py:37 +#: changelog.py:106 msgid "" "* Added a new tab called feedback, in the account settings dialog. This tab " "allows you to control whether automatic speech or Braille feedbak in certain " @@ -327,7 +921,7 @@ msgstr "" "salida automática. ([#203](https://github.com/manuelcortez/TWBlue/" "issues/203))" -#: ../doc/changelog.py:38 +#: changelog.py:107 msgid "" "* The spell checking dialog now has access keys defined for the most " "important actions. ([#211](https://github.com/manuelcortez/TWBlue/" @@ -337,7 +931,7 @@ msgstr "" "para las acciones más importantes. ([#211](https://github.com/manuelcortez/" "TWBlue/issues/211))" -#: ../doc/changelog.py:39 +#: changelog.py:108 msgid "" "* TWBlue now Uses WXPython 4.0.1. This will allow us to migrate all " "important components to Python 3 in the future. ([#207](https://github.com/" @@ -347,7 +941,7 @@ msgstr "" "componentes importantes a Python 3 en el futuro. ([#207](https://github.com/" "manuelcortez/TWBlue/issues/207))" -#: ../doc/changelog.py:40 +#: changelog.py:109 msgid "" "* When you quote a Tweet, if the original tweet was posted with Twishort, " "TWBlue should display properly the quoted tweet. Before it was displaying " @@ -358,7 +952,7 @@ msgstr "" "debería mostrar correctamente el tuit citado. Antes sólo mostraba el tuit " "original. ([#206](https://github.com/manuelcortez/TWBlue/issues/206))" -#: ../doc/changelog.py:41 +#: changelog.py:110 msgid "" "* It is possible to filter by retweets, quotes and replies when creating a " "new filter." @@ -366,7 +960,7 @@ msgstr "" "* Es posible filtrar por retuits, tuits citados y respuestas al crear nuevos " "filtros." -#: ../doc/changelog.py:42 +#: changelog.py:111 msgid "" "* Added support for playing youtube Links directly from the client. ([#94]" "(https://github.com/manuelcortez/TWBlue/issues/94))" @@ -374,11 +968,11 @@ msgstr "" "* Se ha añadido soporte para reproducir enlaces de Youtube directamente " "desde el cliente. ([#94](https://github.com/manuelcortez/TWBlue/issues/94))" -#: ../doc/changelog.py:43 +#: changelog.py:112 msgid "* Replaced Bass with libVLC for playing URL streams." msgstr "* Se ha reemplazado bass por LibVlc para reproducir audio desde URLS." -#: ../doc/changelog.py:44 +#: changelog.py:113 msgid "" "* the checkbox for indicating whether TWBlue will include everyone in a " "reply or not, will be unchecked by default." @@ -386,7 +980,7 @@ msgstr "" "* La casilla que indica si TWBlue debe incluir a todos los participantes en " "una respuesta estará desmarcada por defecto." -#: ../doc/changelog.py:45 +#: changelog.py:114 msgid "" "* You can request TWBlue to save the state for two checkboxes: Long tweet " "and mention all, from the global settings dialogue." @@ -394,7 +988,7 @@ msgstr "" "* Puedes pedir a TWBlue que guarde el estado de dos casillas: tuit largo y " "mencionar a todos, desde el diálogo de opciones globales." -#: ../doc/changelog.py:46 +#: changelog.py:115 msgid "" "* For windows 10 users, some keystrokes in the invisible user interface have " "been changed or merged:" @@ -402,7 +996,7 @@ msgstr "" "* Para usuarios de Windows 10, algunas combinaciones de teclado en el modo " "invisible han sufrido cambios o han sido combinadas:" -#: ../doc/changelog.py:47 +#: changelog.py:116 msgid "" " * control+Windows+alt+F will be used for toggling between adding and " "removing a tweet to user's likes. This function will execute the needed " @@ -412,22 +1006,22 @@ msgstr "" "un tuit a los tuits que le gustan a un usuario. Esta función ejecutará la " "acción necesaria basándose en el estado actual del tuit con el foco." -#: ../doc/changelog.py:48 +#: changelog.py:117 msgid "* TWBlue will show an error if something goes wrong in an audio upload." msgstr "" "* TWBlue mostrará un error si algo sale mal durante la carga de un archivo " "de audio." -#: ../doc/changelog.py:49 +#: changelog.py:118 msgid "" "* And more. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " msgstr "* Y más. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " -#: ../doc/changelog.py:50 +#: changelog.py:120 msgid "## Changes in version 0.93" msgstr "## Cambios en la versión 0.93" -#: ../doc/changelog.py:51 +#: changelog.py:122 msgid "" "* A new soundpack has been added to TWBlue. Thanks to [@ValeriaK305](https://" "twitter.com/ValeriaK305)" @@ -435,7 +1029,7 @@ msgstr "" "* Se ha añadido un nuevo paquete de sonidos a la instalación predeterminada " "de TWBlue, gracias a [@ValeriaK305](https://twitter.com/ValeriaK305)" -#: ../doc/changelog.py:52 +#: changelog.py:123 msgid "" "* In the Windows 10 keymap, we have changed some default keystrokes as " "windows now uses some previously assigned shortcuts:" @@ -444,16 +1038,16 @@ msgstr "" "de teclado, ya que Windows ahora utiliza algunos de los atajos que utilizaba " "TWBlue:" -#: ../doc/changelog.py:53 +#: changelog.py:124 msgid " * For liking a tweet, press Control+Windows+alt+f" msgstr "" " * Para marcar como me gusta un tweet, presiona control+windows+alt+f" -#: ../doc/changelog.py:54 +#: changelog.py:125 msgid " * for opening a trends buffer, press control+Windows+T" msgstr " * Para abrir un buffer de tendencias, presiona Control+Windows+T" -#: ../doc/changelog.py:55 +#: changelog.py:126 msgid "" "* TWBlue has received improvements in some functions for handling extended " "tweets, long tweets and quoted retweets. It should render some tweets in a " @@ -463,7 +1057,7 @@ msgstr "" "extendidos y retuits citados. Debería ser capaz de mostrar mejor algunos " "tuits." -#: ../doc/changelog.py:56 +#: changelog.py:127 msgid "" "* In the spell checker module, there is a new button that will allow you to " "add your own words to your personal dictionary so the module won't mark them " @@ -473,7 +1067,7 @@ msgstr "" "la palabra a tu diccionario. De esta forma,en un futuro esa palabra no " "aparecerá marcada como mal escrita." -#: ../doc/changelog.py:57 +#: changelog.py:128 msgid "" "* Added filtering capabilities to TWBlue. ([#102](https://github.com/" "manuelcortez/TWBlue/issues/102))" @@ -481,7 +1075,7 @@ msgstr "" "* Se han añadido filtros a TWBlue. ([#102](https://github.com/manuelcortez/" "TWBlue/issues/102))" -#: ../doc/changelog.py:58 +#: changelog.py:129 msgid "" " * You can create a filter for the current buffer from the buffer menu in " "the menu bar. At this moment, invisible interface does not have any shorcut " @@ -491,11 +1085,11 @@ msgstr "" "ubicado en la barra de menú. Por el momento, la interfaz invisible no cuenta " "con un atajo para esta acción." -#: ../doc/changelog.py:59 +#: changelog.py:130 msgid " * You can create filters by word or languages." msgstr " * Puedes crear filtros de palabras o de idiomas en el tuit." -#: ../doc/changelog.py:60 +#: changelog.py:131 msgid "" " * For deleting already created filters, you can go to the filter manager " "in the buffer menu and delete the filters you won't need." @@ -503,7 +1097,7 @@ msgstr "" " * Para eliminar filtros previamente creados, puedes acceder al gestor de " "filtros en el menú buffer, y eliminar desde ahí los que ya no necesites." -#: ../doc/changelog.py:61 +#: changelog.py:132 msgid "" "* Links should be opened properly in quoted tweets ([#167,](https://github." "com/manuelcortez/TWBlue/issues/167) [#184](https://github.com/manuelcortez/" @@ -513,14 +1107,14 @@ msgstr "" "(https://github.com/manuelcortez/TWBlue/issues/167) [#184](https://github." "com/manuelcortez/TWBlue/issues/184))" -#: ../doc/changelog.py:62 +#: changelog.py:133 msgid "" "* Increased display name limit up to 50 characters in update profile dialog." msgstr "" "* Se ha aumentado el número de caracteres permitidos en los nombres para " "mostrar en Twitter a 50 caracteres." -#: ../doc/changelog.py:63 +#: changelog.py:134 msgid "" "* When authorising an account, you will see a dialogue with a cancel button, " "in case you want to abort the process. Also, NVDA will not be blocked when " @@ -532,7 +1126,7 @@ msgstr "" "autorización para la cuenta. ([#101](https://github.com/manuelcortez/TWBlue/" "issues/101))" -#: ../doc/changelog.py:64 +#: changelog.py:135 msgid "" "* In the translator module, the list of available languages is fetched " "automatically from the provider. That means all of these languages will work " @@ -547,7 +1141,7 @@ msgstr "" "determina de forma automática por el API de Yandex. ([#153](https://github." "com/manuelcortez/TWBlue/issues/153))" -#: ../doc/changelog.py:65 +#: changelog.py:136 msgid "" "* Trending topics, searches and conversation buffers will use mute settings " "set for the session in wich they were opened. ([#157](https://github.com/" @@ -557,7 +1151,7 @@ msgstr "" "opciones de silencio en la sesión de TWBlue donde fueron creados. ([#157]" "(https://github.com/manuelcortez/TWBlue/issues/157))" -#: ../doc/changelog.py:66 +#: changelog.py:137 msgid "" "* The Tweet limit is now 280 characters lenght instead 140. It means you can " "tweet longer tweets. ([#172](https://github.com/manuelcortez/TWBlue/" @@ -567,7 +1161,7 @@ msgstr "" "significa que se pueden escribir tuits más largos. [#172](https://github.com/" "manuelcortez/TWBlue/issues/172))" -#: ../doc/changelog.py:67 +#: changelog.py:138 msgid "" "* Per popular request, Status for mention to all and long tweet checkboxes " "will not be saved in settings. ([#170](https://github.com/manuelcortez/" @@ -577,7 +1171,7 @@ msgstr "" "escribir un tuit largo y responder a todos. ([#170](https://github.com/" "manuelcortez/TWBlue/issues/170))" -#: ../doc/changelog.py:68 +#: changelog.py:139 msgid "" "* Fixed a problem that was making TWBlue unable to start if it was being ran " "in Windows with Serbian language. ([#175](https://github.com/manuelcortez/" @@ -587,11 +1181,11 @@ msgstr "" "el equipo se detectaba el idioma serbio. ([#175](https://github.com/" "manuelcortez/TWBlue/issues/175))" -#: ../doc/changelog.py:69 +#: changelog.py:140 msgid "* Added Danish translation." msgstr "* Se ha añadido la traducción al Danés." -#: ../doc/changelog.py:70 +#: changelog.py:141 msgid "" "* And more. ([#156,](https://github.com/manuelcortez/TWBlue/issues/156) " "[#163,](https://github.com/manuelcortez/TWBlue/issues/163) [#159,](https://" @@ -606,11 +1200,11 @@ msgstr "" "TWBlue/issues/173) [#174,](https://github.com/manuelcortez/TWBlue/" "issues/174) [#176,](https://github.com/manuelcortez/TWBlue/issues/176))" -#: ../doc/changelog.py:71 +#: changelog.py:143 msgid "## changes in version 0.91 and 0.92" msgstr "## Cambios en las versiones 0.91 y 0.92" -#: ../doc/changelog.py:72 +#: changelog.py:145 msgid "" "* Fixed incorrect unicode handling when copying tweet to clipboard. ([#150]" "(https://github.com/manuelcortez/TWBlue/issues/150))" @@ -618,7 +1212,7 @@ msgstr "" "* Se ha corregido un error de Unicode al copiar tuits al portapapeles. " "([#150](https://github.com/manuelcortez/TWBlue/issues/150))" -#: ../doc/changelog.py:73 +#: changelog.py:146 msgid "" "* TWBlue will show an error when trying to open a timeline for a suspended " "user. ([#128](https://github.com/manuelcortez/TWBlue/issues/128))" @@ -627,7 +1221,7 @@ msgstr "" "usuario suspendido. ([#128](https://github.com/manuelcortez/TWBlue/" "issues/128))" -#: ../doc/changelog.py:74 +#: changelog.py:147 msgid "" "* Removed TwUp as service as it no longer exists. ([#112](https://github.com/" "manuelcortez/TWBlue/issues/112))" @@ -635,7 +1229,7 @@ msgstr "" "* Se ha removido el servicio de audio TWUp, debido a que ya no existe. " "([#112](https://github.com/manuelcortez/TWBlue/issues/112))" -#: ../doc/changelog.py:75 +#: changelog.py:148 msgid "" "* Release audio files after uploading them. ([#130](https://github.com/" "manuelcortez/TWBlue/issues/130))" @@ -644,7 +1238,7 @@ msgstr "" "luego de haber sido subidos a algún servicio de audio. ([#130](https://" "github.com/manuelcortez/TWBlue/issues/130))" -#: ../doc/changelog.py:76 +#: changelog.py:149 msgid "" "* Now TWBlue will use Yandex's translation services instead microsoft " "translator. ([#132](https://github.com/manuelcortez/TWBlue/issues/132))" @@ -653,7 +1247,7 @@ msgstr "" "Microsoft Translator. ([#132](https://github.com/manuelcortez/TWBlue/" "issues/132))" -#: ../doc/changelog.py:77 +#: changelog.py:150 msgid "" "* SndUp users will be able to upload audio in their account by using their " "API Key again. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" @@ -661,7 +1255,7 @@ msgstr "" "* Los usuarios con cuenta de SNDUp podrán subir audios utilizando su clave " "de API de nuevo. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" -#: ../doc/changelog.py:78 +#: changelog.py:151 msgid "" "* old tweets shouldn't be added as new items in buffers. ([#116,](https://" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" @@ -671,7 +1265,7 @@ msgstr "" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" "manuelcortez/TWBlue/issues/133))" -#: ../doc/changelog.py:79 +#: changelog.py:152 msgid "" "* All mentionned users should be displayed correctly in Twishort's long " "tweets. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#135]" @@ -681,7 +1275,7 @@ msgstr "" "hechos mediante Twishort. ([#116,](https://github.com/manuelcortez/TWBlue/" "issues/116)) ([#135](https://github.com/manuelcortez/TWBlue/issues/135))" -#: ../doc/changelog.py:80 +#: changelog.py:153 msgid "" "* It is possible to select a language for OCR service from the extras panel, " "in the account settings dialogue. You can, however, set this to detect " @@ -696,7 +1290,7 @@ msgstr "" "especiales o símbolos que no forman parte del alfabeto inglés. ([#107]" "(https://github.com/manuelcortez/TWBlue/issues/107))" -#: ../doc/changelog.py:81 +#: changelog.py:154 msgid "" "* Fixed a problem with JAWS for Windows and TWBlue. Now JAWS will work " "normally in this update. [#100](https://github.com/manuelcortez/twblue/" @@ -706,15 +1300,15 @@ msgstr "" "funcionar de forma correcta con este lector de pantalla. [#100](https://" "github.com/manuelcortez/twblue/issues/100)" -#: ../doc/changelog.py:82 +#: changelog.py:155 msgid "* And more ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" msgstr "* Y más ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" -#: ../doc/changelog.py:83 +#: changelog.py:157 msgid "## Changes in version 0.90" msgstr "## Cambios en la versión 0.90" -#: ../doc/changelog.py:84 +#: changelog.py:159 msgid "" "* Fixed a bug in long tweet parsing that was making TWBlue to disconnect the " "streaming API. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" @@ -723,7 +1317,7 @@ msgstr "" "desconectara el Streaming. ([#103](https://github.com/manuelcortez/TWBlue/" "issues/103))" -#: ../doc/changelog.py:85 +#: changelog.py:160 msgid "" "* Now OCR will work in images from retweets. It fixes a bug where TWBlue was " "detecting images but couldn't apply OCR on them. ([#105](https://github.com/" @@ -734,7 +1328,7 @@ msgstr "" "pudiera aplicar OCR en ellas. ([#105](https://github.com/manuelcortez/TWBlue/" "issues/105))" -#: ../doc/changelog.py:86 +#: changelog.py:161 msgid "" "* TWBlue won't try to load tweets already deleted, made with Twishort. " "Before, if someone posted a long tweet but deleted it in the Twishort's " @@ -747,7 +1341,7 @@ msgstr "" "problemas en todo el cliente. ([#113](https://github.com/manuelcortez/TWBlue/" "issues/113))" -#: ../doc/changelog.py:87 +#: changelog.py:162 msgid "" "* TWBlue shows an error message when you try to view the profile of an user " "that does not exist or has been suspended. ([#114,](https://github.com/" @@ -759,7 +1353,7 @@ msgstr "" "manuelcortez/TWBlue/issues/114) [#115](https://github.com/manuelcortez/" "TWBlue/issues/115))" -#: ../doc/changelog.py:88 +#: changelog.py:163 msgid "" "* The spellchecker module should select the right language when is set to " "\"user default\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" @@ -768,7 +1362,7 @@ msgstr "" "apropiado cuando el idioma del cliente se establece en \"Idioma " "predeterminado\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" -#: ../doc/changelog.py:89 +#: changelog.py:164 msgid "" "* Image description will be displayed in retweets too. ([#119](https://" "github.com/manuelcortez/TWBlue/issues/119))" @@ -776,7 +1370,7 @@ msgstr "" "* La descripción de imágenes se mostrará en retuits también. ([#119](https://" "github.com/manuelcortez/TWBlue/issues/119))" -#: ../doc/changelog.py:90 +#: changelog.py:165 msgid "" "* When reading a long tweet, you shouldn't read strange entities anymore. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" @@ -784,7 +1378,7 @@ msgstr "" "* cuando se lea un tuit largo, no deberían aparecer símbolos extraños. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" -#: ../doc/changelog.py:91 +#: changelog.py:166 msgid "" "* TWBlue will not try to load timelines if the user is blocking you. ([#125]" "(https://github.com/manuelcortez/twblue/issues/125))" @@ -793,28 +1387,28 @@ msgstr "" "a la cuenta actual. ([#125](https://github.com/manuelcortez/twblue/" "issues/125))" -#: ../doc/changelog.py:92 +#: changelog.py:168 msgid "## Changes in version 0.88 and 0.89" msgstr "## Cambios en las versiones 0.88 y 0.89" -#: ../doc/changelog.py:93 +#: changelog.py:170 msgid "* Fixed more issues with streams and reconnections." msgstr "* Corregidos más problemas con los streams y la reconexión." -#: ../doc/changelog.py:94 +#: changelog.py:171 msgid "* newer updates will indicate the release date in the updater." msgstr "" "* Las actualizaciones más nuevas indicarán la fecha de lanzamiento en el " "módulo de actualización." -#: ../doc/changelog.py:95 +#: changelog.py:172 msgid "" "* Changes to keystrokes are reflected in keystroke editor automatically." msgstr "" "* Los cambios en las combinaciones de teclado se reflejarán automáticamente " "en el editor de combinaciones de teclado." -#: ../doc/changelog.py:96 +#: changelog.py:173 msgid "" "* In replies with multiple users, if the mention to all checkbox is " "unchecked, you will see a checkbox per user so you will be able to control " @@ -824,7 +1418,7 @@ msgstr "" "todos no está marcada, verás una casilla para cada usuario, lo que te " "permitirá seleccionar a los usuarios que serán mencionados en la respuesta." -#: ../doc/changelog.py:97 +#: changelog.py:174 msgid "" "* Fixed a bug that caused duplicated user mentions in replies when the tweet " "was made with Twishort." @@ -832,7 +1426,7 @@ msgstr "" "* Corregido un error que causaba que TWBlue mostrara menciones duplicadas si " "el tuit había sido enviado mediante Twishort." -#: ../doc/changelog.py:98 +#: changelog.py:175 msgid "" "* Retweets should be displayed normally again when the originating tweet is " "a Twishort's long tweet." @@ -840,7 +1434,7 @@ msgstr "" "* Los Retuits deben mostrarse correctamente si el tuit original había sido " "enviado mediante Twishort." -#: ../doc/changelog.py:99 +#: changelog.py:176 msgid "" "* Changed the way TWBlue saves user timelines in configuration. Now it uses " "user IDS instead usernames. With user IDS, if an user changes the username, " @@ -853,7 +1447,7 @@ msgstr "" "cambia su nombre de usuario TWBlue todavía será capaz de crear la línea " "temporal. Esto no era posible anteriormente." -#: ../doc/changelog.py:100 +#: changelog.py:177 msgid "" "* Added a new setting in the account settings dialogue that makes TWBlue to " "show twitter usernames instead the full name." @@ -861,7 +1455,7 @@ msgstr "" "* Añadida una opción en el diálogo de opciones de cuenta que hace que TWBlue " "muestre el nombre de pantalla del usuario en lugar del nombre completo." -#: ../doc/changelog.py:101 +#: changelog.py:178 msgid "" "* Added OCR in twitter pictures. There is a new item in the tweet menu that " "allows you to extract and display text in images. Also the keystroke alt+Win" @@ -872,18 +1466,18 @@ msgstr "" "imagen del tuit seleccionado. También se ha añadido la combinación Alt + " "Windows +O para el mismo propósito en la interfaz invisible." -#: ../doc/changelog.py:102 +#: changelog.py:179 msgid "* Now TWBlue will play a sound when the focused tweet contains images." msgstr "" "* Ahora TWBlue reproducirá un sonido cuando el tuit seleccionado contenga " "imágenes." -#: ../doc/changelog.py:103 +#: changelog.py:180 msgid "" "* Your own quoted tweets will not appear in the mentions buffer anymore." msgstr "* Tus tuits citados dejarán de mostrarse en el buffer de menciones." -#: ../doc/changelog.py:104 +#: changelog.py:181 msgid "" "* The config file is saved in a different way, it should fix the bug where " "TWBlue needs to be restarted after the config folder is deleted." @@ -892,13 +1486,13 @@ msgstr "" "solucionar el error que requería borrar el directorio de configuraciones y " "reiniciar TWBlue." -#: ../doc/changelog.py:105 +#: changelog.py:182 msgid "* Mentioning people from friends or followers buffers works again." msgstr "" "* Es posible de nuevo mencionar usuarios desde los buffers de seguidores y " "amigos." -#: ../doc/changelog.py:106 +#: changelog.py:183 msgid "" "* Support for proxy servers has been improved. Now TWBlue supports http, " "https, socks4 and socks5 proxies, with and without autentication." @@ -906,15 +1500,15 @@ msgstr "" "* Se ha mejorado el soporte para servidores proxy. Ahora TWBlue soporta " "proxys http, https, socks4 y socks5, con o sin autenticación." -#: ../doc/changelog.py:107 +#: changelog.py:185 msgid "## Changes in version 0.87" msgstr "## Cambios en la versión 0.87" -#: ../doc/changelog.py:108 +#: changelog.py:187 msgid "* Fixed stream connection errors." msgstr "* Arreglados errores en la conexión de los streams." -#: ../doc/changelog.py:109 +#: changelog.py:188 msgid "" "* Now TWBlue can handle properly a reply to the sender without including all " "other mentioned users." @@ -922,11 +1516,11 @@ msgstr "" "* Ahora TWBlue puede manejar correctamente las respuestas sin incluir a " "todos los usuarios del tuit original." -#: ../doc/changelog.py:110 +#: changelog.py:189 msgid "* Updated translations." msgstr "* Traducciones actualizadas." -#: ../doc/changelog.py:111 +#: changelog.py:190 msgid "" "* The status of the mention to all checkbox will be remembered the next time " "you reply to multiple users." @@ -934,11 +1528,11 @@ msgstr "" "* El estado de la casilla para mencionar a todos se recordará la próxima vez " "que escribas una respuesta." -#: ../doc/changelog.py:112 +#: changelog.py:192 msgid "## Changes in version 0.86" msgstr "## Cambios en la versión 0.86" -#: ../doc/changelog.py:113 +#: changelog.py:194 msgid "" "* Fixed a very important security issue. Now TWBlue will send tweets to " "twishort without using any other server." @@ -946,7 +1540,7 @@ msgstr "" "* Arreglado un error de seguridad muy importante. Ahora TWBlue enviará tuits " "hacia Twishort sin utilizar un servidor intermedio." -#: ../doc/changelog.py:114 +#: changelog.py:195 msgid "" "* When you add a comment to a tweet, it will be sent as a quoted tweet, even " "if your reply plus the original tweet is not exceeding 140 characters." @@ -955,7 +1549,7 @@ msgstr "" "citado, incluso si el comentario más el tuit original no supera los 140 " "caracteres." -#: ../doc/changelog.py:115 +#: changelog.py:196 msgid "" "* Updated windows 10 keymap for reflecting changes made in the last windows " "10 build." @@ -963,11 +1557,11 @@ msgstr "" "* Actualizado el mapa de teclado de Windows 10 debido a los cambios de la " "última build." -#: ../doc/changelog.py:116 +#: changelog.py:197 msgid "* Added last changes in the twitter API." msgstr "* Añadidos los últimos cambios en el API de Twitter." -#: ../doc/changelog.py:117 +#: changelog.py:198 msgid "" "* When replying, it will not show the twitter username in the text box. When " "you send the tweet, the username will be added automatically." @@ -976,7 +1570,7 @@ msgstr "" "campo de texto. El nombre de usuario será añadido de forma automática al " "enviar el tuit." -#: ../doc/changelog.py:118 +#: changelog.py:199 msgid "" "* When replying to multiple users, you'll have a checkbox instead a button " "for mentioning all people. If this is checked, twitter usernames will be " @@ -986,44 +1580,44 @@ msgstr "" "lugar de un botón para mencionar a todos. Si es marcada, los nombres de " "usuario de Twitter se añadirán automáticamente al enviar el tuit." -#: ../doc/changelog.py:119 +#: changelog.py:201 msgid "## Changes in version 0.85" msgstr "## Cambios en la versión 0.85" -#: ../doc/changelog.py:120 +#: changelog.py:203 msgid "* Long and quoted tweets should be displayed properly In lists." msgstr "" "* Los tuits largos y citados deberían mostrarse correctamente en las listas." -#: ../doc/changelog.py:121 +#: changelog.py:204 msgid "* The connection should be more stable." msgstr "* La conexión debería ser más estable." -#: ../doc/changelog.py:122 +#: changelog.py:205 msgid "* Added an autostart option in the global settings dialogue." msgstr "" "* Se ha añadido la opción para iniciar después de iniciar sesión en Windows " "en el diálogo de opciones globales." -#: ../doc/changelog.py:123 +#: changelog.py:206 msgid "* Updated translation." msgstr "* Se han actualizado las traducciones." -#: ../doc/changelog.py:124 +#: changelog.py:207 msgid "* Updated russian documentation." msgstr "* Actualizada la documentación en ruso." -#: ../doc/changelog.py:125 +#: changelog.py:208 msgid "* Tweets in cached database should be loaded properly." msgstr "* Se deben cargar correctamente los tuits en la base de datos." -#: ../doc/changelog.py:126 +#: changelog.py:209 msgid "* Added some missed dictionaries for spelling correction." msgstr "" "* Se han añadido algunos nuevos diccionarios en el módulo de corrección " "ortográfica." -#: ../doc/changelog.py:127 +#: changelog.py:210 msgid "" "* Timelines, lists and other buffer should be created in the right order at " "startup." @@ -1031,15 +1625,15 @@ msgstr "" "* Líneas temporales, listas y otros buffers deberían ser creados en el orden " "correcto al iniciar TWBlue." -#: ../doc/changelog.py:128 +#: changelog.py:212 msgid "## Changes in version 0.84 " msgstr "## Cambios en la versión 0.84 " -#: ../doc/changelog.py:129 +#: changelog.py:214 msgid "* More improvements in quoted and long tweets." msgstr "* Más mejoras en los tuits largos y citados." -#: ../doc/changelog.py:130 +#: changelog.py:215 msgid "" "* Updated translations: Russian, Italian, French, Romanian, Galician and " "Finnish." @@ -1047,7 +1641,7 @@ msgstr "" "* Actualizadas las siguientes traducciones: Ruso, italiano, francés, rumano, " "gallego y finlandés." -#: ../doc/changelog.py:131 +#: changelog.py:216 msgid "" "* Improvements in the audio uploader module: Now it can handle audio with " "non-english characters." @@ -1055,7 +1649,7 @@ msgstr "" "* Mejoras en el módulo de carga de archivos de audio: Ahora es capaz de " "manejar archivos de audio con caracteres especiales." -#: ../doc/changelog.py:132 +#: changelog.py:217 msgid "" "* the title of the window should be updated properly when spellcheck, " "translate or shorten/unshorten URL buttons are pressed." @@ -1063,7 +1657,7 @@ msgstr "" "* El título de la ventana debe actualizarse correctamente cuando se utilizan " "funciones como corrección ortográfica, traducción o acortar / expandir URL." -#: ../doc/changelog.py:133 +#: changelog.py:218 msgid "" "* the bug that changes the selected tweet in the home timeline shouldn't be " "happening so often." @@ -1071,11 +1665,11 @@ msgstr "" "* El error que hacía que el tuit seleccionado cambiara en la interfaz " "visible debería estar parcialmente corregido." -#: ../doc/changelog.py:134 +#: changelog.py:220 msgid "## Changes in version 0.82 and 0.83" msgstr "## Cambios en las versiones 0.82 y 0.83" -#: ../doc/changelog.py:135 +#: changelog.py:222 msgid "" "* If the tweet source (client) is an application with unicode characters " "(example: российская газета) it will not break the tweet displayer." @@ -1084,7 +1678,7 @@ msgstr "" "caracteres Unicode en su nombre (por ejemplo: российская газета), el " "visualizador de tuits lo podrá mostrar adecuadamente." -#: ../doc/changelog.py:136 +#: changelog.py:223 msgid "" "* Added a new field for image description in tweet displayer. When " "available, it will show description for images posted in tweets." @@ -1093,7 +1687,7 @@ msgstr "" "tuits. Cuando estén disponibles, se mostrarán descripciones para las " "imágenes en el tuit." -#: ../doc/changelog.py:137 +#: changelog.py:224 msgid "" "* users can add image descriptions to their photos. When uploading an image, " "a dialog will show for asking a description." @@ -1101,15 +1695,15 @@ msgstr "" "* Los usuarios ahora pueden añadir descripción a sus fotos. Al subir la " "imagen, aparecerá un diálogo para que se proporcione una descripción." -#: ../doc/changelog.py:138 +#: changelog.py:225 msgid "* Redesigned upload image dialog." msgstr "* El diálogo para subir imágenes ha sido rediseñado." -#: ../doc/changelog.py:139 +#: changelog.py:226 msgid "* Fixed photo uploads when posting tweets." msgstr "* Se ha corregido la carga de imágenes al publicar tuits." -#: ../doc/changelog.py:140 +#: changelog.py:227 msgid "" "* When getting tweets for a conversation, ignores deleted tweets or some " "errors, now TWBlue will try to get as much tweets as possible, even if some " @@ -1119,23 +1713,23 @@ msgstr "" "los tuits eliminados y algunos errores comunes. TWBlue cargará la mayor " "cantidad de tuits posible." -#: ../doc/changelog.py:141 +#: changelog.py:228 msgid "* Added audio playback from soundcloud." msgstr "* Añadida la reproducción de audio desde Soundcloud." -#: ../doc/changelog.py:142 +#: changelog.py:229 msgid "* Now the session mute option don't makes the screen reader speaks." msgstr "" "* Al silenciar una sesión, el lector de pantalla ya no anunciará ningún " "contenido automáticamente." -#: ../doc/changelog.py:143 +#: changelog.py:230 msgid "* Fixed the direct message dialog. Now it should be displayed properly." msgstr "" "* Corregido el diálogo de mensaje directo. Ahora debería mostrarse " "correctamente." -#: ../doc/changelog.py:144 +#: changelog.py:231 msgid "" "* when a tweet is deleted in twitter, TWBlue should reflect this change and " "delete that tweet in every buffer it is displayed." @@ -1143,7 +1737,7 @@ msgstr "" "* Cuando se elimina un tuit, TWBlue debería reflejar el cambio y eliminar el " "tuit de todos los buffers donde se muestra." -#: ../doc/changelog.py:145 +#: changelog.py:232 msgid "" "* If your session is broken, TWBlue will be able to remove it automatically " "instead just crashing." @@ -1151,12 +1745,12 @@ msgstr "" "* Si la configuración de una sesión ha sido dañada, TWBlue debería ser capaz " "de eliminarla y continuar en lugar de no abrirse." -#: ../doc/changelog.py:146 +#: changelog.py:233 msgid "* audio uploader should display the current progress." msgstr "" "* El diálogo de carga de archivos de audio ahora muestra el progreso actual." -#: ../doc/changelog.py:147 +#: changelog.py:234 msgid "" "* users can disable the check for updates feature at startup from the " "general tab, in the global settings dialogue." @@ -1164,7 +1758,7 @@ msgstr "" "* Es posible desactivar la comprobación automática de actualizaciones en el " "diálogo de opciones globales, en la pestaña General." -#: ../doc/changelog.py:148 +#: changelog.py:235 msgid "" "* The invisible interface and the window should be synchronized when the " "client reconnects." @@ -1172,12 +1766,12 @@ msgstr "" "* La interfaz invisible y la ventana gráfica deben estar sincronizadas " "cuando el cliente se reconecta." -#: ../doc/changelog.py:149 +#: changelog.py:236 msgid "* The documentation option in the systray icon should be enabled." msgstr "" "* La opción de documentación en la bandeja del sistema se encuentra activa." -#: ../doc/changelog.py:150 +#: changelog.py:237 msgid "" "* In trending buffers, you can press enter for posting a tweet about the " "focused trend." @@ -1185,7 +1779,7 @@ msgstr "" "* En buffers de tendencias, puedes pulsar enter sobre cada tendencia para " "publicar un tuit acerca de ella." -#: ../doc/changelog.py:151 +#: changelog.py:238 msgid "" "* Updated russian documentation and main program interface (thanks to " "Natalia Hedlund (Наталья Хедлунд), [@lifestar_n](https://twitter.com/" @@ -1194,19 +1788,19 @@ msgstr "" "* Actualizada la documentación e interfaz en ruso (gracias a Natalia Hedlund " "(Наталья Хедлунд), [@lifestar_n](https://twitter.com/lifestar_n) en twitter)" -#: ../doc/changelog.py:152 +#: changelog.py:239 msgid "* updated translations." msgstr "* Actualizadas algunas traducciones." -#: ../doc/changelog.py:153 +#: changelog.py:241 msgid "## Changes in Version 0.81" msgstr "## Cambios en la versión 0.81" -#: ../doc/changelog.py:154 +#: changelog.py:243 msgid "* Updated translations" msgstr "* Traducciones actualizadas" -#: ../doc/changelog.py:155 +#: changelog.py:244 msgid "" "* The updater module has received some improvements. Now it includes a " "Mirror URL for checking updates if the main URL is not available at the " @@ -1217,24 +1811,24 @@ msgstr "" "una URL con información de actualizaciones de respaldo por si la dirección " "principal no funciona." -#: ../doc/changelog.py:156 +#: changelog.py:245 msgid "* some GUI elements now use keyboard shortcuts for common actions." msgstr "" "* Algunos elementos de la interfaz gráfica ahora utilizan atajos de teclado " "para acciones comunes." -#: ../doc/changelog.py:157 +#: changelog.py:246 msgid "* fixed a bug in the geolocation dialog." msgstr "" "* Corregido un error en el diálogo para mostrar la información geográfica en " "Tuits." -#: ../doc/changelog.py:158 +#: changelog.py:247 msgid "* the chicken nugget keymap should work properly." msgstr "" "* El mapa de teclado de chicken Nugget debería funcionar correctamente." -#: ../doc/changelog.py:159 +#: changelog.py:248 msgid "" "* Added a new soundpack to the default installation of TWBlue, thanks to " "[@Deng90](https://twitter.com/deng90)" @@ -1242,11 +1836,11 @@ msgstr "" "* Se ha añadido un nuevo paquete de sonidos a la instalación predeterminada " "de TWBlue, gracias a [@Deng90](https://twitter.com/deng90)" -#: ../doc/changelog.py:160 +#: changelog.py:249 msgid "* Now the changelog is written in an html File." msgstr "* La lista de cambios ahora está escrita en un archivo HTML." -#: ../doc/changelog.py:161 +#: changelog.py:250 msgid "" "* Added some missed dictionaries in last version for the spell checking " "feature." @@ -1254,7 +1848,7 @@ msgstr "" "* Se han añadido algunos diccionarios al módulo de corrección ortográfica " "que no habían sido añadidos en la última versión." -#: ../doc/changelog.py:162 +#: changelog.py:251 msgid "" "* Trimmed the beginnings of the sounds in the default soundpack. Thanks to " "[@masonasons](https://github.com/masonasons)" @@ -1263,7 +1857,7 @@ msgstr "" "de sonidos predeterminado. Gracias a [@masonasons](https://github.com/" "masonasons)" -#: ../doc/changelog.py:163 +#: changelog.py:252 msgid "" "* Added Opus support for sound playback in TWBlue. Thanks to [@masonasons]" "(https://github.com/masonasons)" @@ -1271,7 +1865,7 @@ msgstr "" "* Añadido soporte al códec Opus en TWBlue. Gracias a [@masonasons](https://" "github.com/masonasons)" -#: ../doc/changelog.py:164 +#: changelog.py:253 msgid "" "* Added a source field in view tweet dialogue. Thanks to [@masonasons]" "(https://github.com/masonasons)" @@ -1280,14 +1874,14 @@ msgstr "" "el visualizador de tuits. Gracias a [@masonasons](https://github.com/" "masonasons)" -#: ../doc/changelog.py:165 +#: changelog.py:254 msgid "" "* You can load previous items in followers and friend buffers for others." msgstr "" "* Se pueden cargar más elementos en los buffers de seguidores y amigos de " "otros usuarios." -#: ../doc/changelog.py:166 +#: changelog.py:255 msgid "" "* The Spell Checker dialogue should not display an error message when you " "have set \"default language\" in the global settings dialogue if your " @@ -1298,20 +1892,20 @@ msgstr "" "tu idioma se encuentra soportado. [#168](http://twblue.es/bugs/view.php?" "id=168)" -#: ../doc/changelog.py:167 +#: changelog.py:256 msgid "* Updated romanian translation." msgstr "* Actualizada la traducción al rumano." -#: ../doc/changelog.py:168 +#: changelog.py:257 msgid "* Some code cleanups." msgstr "* Limpieza del código." -#: ../doc/changelog.py:169 +#: changelog.py:258 msgid "* The bug reports feature is fully operational again." msgstr "" "* El sistema de reporte de errores es completamente operativo de nuevo." -#: ../doc/changelog.py:170 +#: changelog.py:259 msgid "" "* TWBlue should work again for users that contains special characters in " "windows usernames." @@ -1319,24 +1913,24 @@ msgstr "" "* TWBlue debería funcionar de nuevo para usuarios que contienen caracteres " "especiales en sus nombres de usuario de Windows." -#: ../doc/changelog.py:171 +#: changelog.py:260 msgid "* Added more options for the tweet searches." msgstr "* Añadidas más opciones para las búsquedas en Twitter." -#: ../doc/changelog.py:172 +#: changelog.py:261 msgid "* Added play_audio to the keymap editor." msgstr "* Añadida la función play_audio al editor de mapas de teclado." -#: ../doc/changelog.py:173 +#: changelog.py:262 msgid "* Windows key is no longer required in the keymap editor" msgstr "" "* La tecla Windows ya no es obligatoria en el editor de mapas de teclado" -#: ../doc/changelog.py:174 +#: changelog.py:263 msgid "* Switched to the Microsoft translator." msgstr "* hemos pasado a usar el servicio Microsoft translator." -#: ../doc/changelog.py:175 +#: changelog.py:264 msgid "" "* You can update the current buffer by pressing ctrl+win+shift+u in the " "default keymap or in the buffer menu." @@ -1344,21 +1938,23 @@ msgstr "" "* Puedes actualizar el buffer actual pulsando ctrl+win+shift+u en la " "interfaz invisible o desde el menú buffer." -#: ../doc/changelog.py:176 +#: changelog.py:265 msgid "* Changed some keystrokes in the windows 10 default keymap" msgstr "" "* Cambiados algunos atajos de teclado en el mapa de teclado de Windows 10" -#: ../doc/changelog.py:177 +#: changelog.py:266 msgid "* New followers and friends buffer for user timelines." msgstr "* Nuevos buffers de amigos y seguidores para otros usuarios." -#: ../doc/changelog.py:178 +#: changelog.py:268 msgid "---" msgstr "---" -#: ../doc/changelog.py:179 -msgid "Copyright © 2014-2017, Manuel Cortez." +#: changelog.py:269 +#, fuzzy +#| msgid "Copyright © 2014-2017, Manuel Cortez." +msgid "Copyright © 2014-2021, Manuel Cortez." msgstr "Copyright © 2014-2017, Manuel Cortéz." #~ msgid "" diff --git a/doc/locales/es/LC_MESSAGES/twblue-documentation.mo b/doc/locales/es/LC_MESSAGES/twblue-documentation.mo index 00ad1323..3e5effa9 100644 Binary files a/doc/locales/es/LC_MESSAGES/twblue-documentation.mo and b/doc/locales/es/LC_MESSAGES/twblue-documentation.mo differ diff --git a/doc/locales/es/LC_MESSAGES/twblue-documentation.po b/doc/locales/es/LC_MESSAGES/twblue-documentation.po index 792235a2..a511716a 100644 --- a/doc/locales/es/LC_MESSAGES/twblue-documentation.po +++ b/doc/locales/es/LC_MESSAGES/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: twblue-documentation 0.84\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2019-05-06 23:06+0200\n" "Last-Translator: José Manuel Delicado \n" "Language-Team: Spanish \n" diff --git a/doc/locales/eu/lc_messages/twblue-changelog.mo b/doc/locales/eu/lc_messages/twblue-changelog.mo index 9f6f9909..6f7e6c0e 100644 Binary files a/doc/locales/eu/lc_messages/twblue-changelog.mo and b/doc/locales/eu/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/eu/lc_messages/twblue-changelog.po b/doc/locales/eu/lc_messages/twblue-changelog.po index f2d88233..07be77c3 100644 --- a/doc/locales/eu/lc_messages/twblue-changelog.po +++ b/doc/locales/eu/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-07 13:51-0500\n" "Last-Translator: Manuel Cortez \n" "Language-Team: \n" diff --git a/doc/locales/eu/lc_messages/twblue-changelog.temp.temp.po b/doc/locales/eu/lc_messages/twblue-changelog.temp.temp.po deleted file mode 100644 index 51f9b73d..00000000 --- a/doc/locales/eu/lc_messages/twblue-changelog.temp.temp.po +++ /dev/null @@ -1,635 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2017-07-08 16:25+Hora de verano central (Mxico)\n" -"PO-Revision-Date: 2017-07-15 19:44+0200\n" -"Last-Translator: Sukil Etxenike \n" -"Language-Team: \n" -"Language: eu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.0.1\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: ../doc/changelog.py:3 -msgid "TWBlue Changelog" -msgstr "TwBlueren aldaketak" - -#: ../doc/changelog.py:4 -msgid "## changes in this version" -msgstr "## Aldaketak bertsio honetan" - -#: ../doc/changelog.py:5 -msgid "" -"* TWBlue will show an error when trying to open a timeline for a suspended " -"user. ([#128](https://github.com/manuelcortez/TWBlue/issues/128))" -msgstr "" -"* TWBluek errore bat erakutsiko du ezabatutako erabiltzaile batn denbora " -"lerro bat irekitzen saiatzean . ([#128](https://github.com/manuelcortez/" -"TWBlue/issues/128))" - -#: ../doc/changelog.py:6 -msgid "" -"* Removed TwUp as service as it no longer exists. ([#112](https://github.com/" -"manuelcortez/TWBlue/issues/112))" -msgstr "" -"* TwUp zerbitzua kendu da, jada ez delako existitzen. ([#112](https://github." -"com/manuelcortez/TWBlue/issues/112)) " - -#: ../doc/changelog.py:7 -msgid "" -"* Release audio files after uploading them. ([#130](https://github.com/" -"manuelcortez/TWBlue/issues/130))" -msgstr "" -"* Orain audio fitxategiak askatzen dira igo ondoren. ([#130](https://github." -"com/manuelcortez/TWBlue/issues/130))" - -#: ../doc/changelog.py:8 -msgid "" -"* Now TWBlue will use Yandex's translation services instead microsoft " -"translator. ([#132](https://github.com/manuelcortez/TWBlue/issues/132))" -msgstr "" -"* Orain TWBluek Yandexen itzultzailea erabiltzen du Microsoften " -"itzultzailearen ordez. ([#132](https://github.com/manuelcortez/TWBlue/" -"issues/132))" - -#: ../doc/changelog.py:9 -msgid "" -"* SndUp users will be able to upload audio in their account by using their " -"API Key again. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" -msgstr "" -"* SndUp-en erabiltzaileek orain audioak igo ditzakete haien API kodea " -"erabilita. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" - -#: ../doc/changelog.py:10 -msgid "" -"* old tweets shouldn't be added as new items in buffers. ([#116,](https://" -"github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" -"manuelcortez/TWBlue/issues/133))" -msgstr "" -"* Txio zaharrak ez lirateke buferretan elementu berri gisa agertu behar. " -"([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://" -"github.com/manuelcortez/TWBlue/issues/133))" - -#: ../doc/changelog.py:11 -msgid "" -"* All mentionned users should be displayed correctly in Twishort's long " -"tweets. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#135]" -"(https://github.com/manuelcortez/TWBlue/issues/135))" -msgstr "" -"* Aipatutako erabiltzaile guztiak ondo agertu beharko lirateke Tuishort-en " -"txio luzeetan. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) " -"([#135](https://github.com/manuelcortez/TWBlue/issues/135))" - -#: ../doc/changelog.py:12 -msgid "" -"* It is possible to select a language for OCR service from the extras panel, " -"in the account settings dialogue. You can, however, set this to detect " -"automatically. OCR should work better in languages with special characters " -"or non-english symbols. ([#107](https://github.com/manuelcortez/TWBlue/" -"issues/107))" -msgstr "" - -#: ../doc/changelog.py:13 -msgid "" -"* Fixed a problem with JAWS for Windows and TWBlue. Now JAWS will work " -"normally in this update. [#100](https://github.com/manuelcortez/twblue/" -"issues/100)" -msgstr "" - -#: ../doc/changelog.py:14 -msgid "* And more ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" -msgstr "" - -#: ../doc/changelog.py:15 -msgid "## Changes in version 0.90" -msgstr "" - -#: ../doc/changelog.py:16 -msgid "" -"* Fixed a bug in long tweet parsing that was making TWBlue to disconnect the " -"streaming API. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" -msgstr "" - -#: ../doc/changelog.py:17 -msgid "" -"* Now OCR will work in images from retweets. It fixes a bug where TWBlue was " -"detecting images but couldn't apply OCR on them. ([#105](https://github.com/" -"manuelcortez/TWBlue/issues/105))" -msgstr "" - -#: ../doc/changelog.py:18 -msgid "" -"* TWBlue won't try to load tweets already deleted, made with Twishort. " -"Before, if someone posted a long tweet but deleted it in the Twishort's " -"site, TWBlue was trying to load the tweet and it was causing problems in all " -"the client. ([#113](https://github.com/manuelcortez/TWBlue/issues/113))" -msgstr "" - -#: ../doc/changelog.py:19 -msgid "" -"* TWBlue shows an error message when you try to view the profile of an user " -"that does not exist or has been suspended. ([#114,](https://github.com/" -"manuelcortez/TWBlue/issues/114) [#115](https://github.com/manuelcortez/" -"TWBlue/issues/115))" -msgstr "" - -#: ../doc/changelog.py:20 -msgid "" -"* The spellchecker module should select the right language when is set to " -"\"user default\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" -msgstr "" - -#: ../doc/changelog.py:21 -msgid "" -"* Image description will be displayed in retweets too. ([#119](https://" -"github.com/manuelcortez/TWBlue/issues/119))" -msgstr "" - -#: ../doc/changelog.py:22 -msgid "" -"* When reading a long tweet, you shouldn't read strange entities anymore. " -"([#118](https://github.com/manuelcortez/twblue/issues/118))" -msgstr "" - -#: ../doc/changelog.py:23 -msgid "" -"* TWBlue will not try to load timelines if the user is blocking you. ([#125]" -"(https://github.com/manuelcortez/twblue/issues/125))" -msgstr "" - -#: ../doc/changelog.py:24 -msgid "## Changes in version 0.88 and 0.89" -msgstr "" - -#: ../doc/changelog.py:25 -msgid "* Fixed more issues with streams and reconnections." -msgstr "" - -#: ../doc/changelog.py:26 -msgid "* newer updates will indicate the release date in the updater." -msgstr "" - -#: ../doc/changelog.py:27 -msgid "" -"* Changes to keystrokes are reflected in keystroke editor automatically." -msgstr "" - -#: ../doc/changelog.py:28 -msgid "" -"* In replies with multiple users, if the mention to all checkbox is " -"unchecked, you will see a checkbox per user so you will be able to control " -"who will be mentioned in the reply." -msgstr "" - -#: ../doc/changelog.py:29 -msgid "" -"* Fixed a bug that caused duplicated user mentions in replies when the tweet " -"was made with Twishort." -msgstr "" - -#: ../doc/changelog.py:30 -msgid "" -"* Retweets should be displayed normally again when the originating tweet is " -"a Twishort's long tweet." -msgstr "" - -#: ../doc/changelog.py:31 -msgid "" -"* Changed the way TWBlue saves user timelines in configuration. Now it uses " -"user IDS instead usernames. With user IDS, if an user changes the username, " -"TWBlue still will create his/her timeline. This was not possible by using " -"usernames." -msgstr "" - -#: ../doc/changelog.py:32 -msgid "" -"* Added a new setting in the account settings dialogue that makes TWBlue to " -"show twitter usernames instead the full name." -msgstr "" - -#: ../doc/changelog.py:33 -msgid "" -"* Added OCR in twitter pictures. There is a new item in the tweet menu that " -"allows you to extract and display text in images. Also the keystroke alt+Win" -"+o has been added for the same purpose from the invisible interface." -msgstr "" - -#: ../doc/changelog.py:34 -msgid "* Now TWBlue will play a sound when the focused tweet contains images." -msgstr "" - -#: ../doc/changelog.py:35 -msgid "" -"* Your own quoted tweets will not appear in the mentions buffer anymore." -msgstr "" - -#: ../doc/changelog.py:36 -msgid "" -"* The config file is saved in a different way, it should fix the bug where " -"TWBlue needs to be restarted after the config folder is deleted." -msgstr "" - -#: ../doc/changelog.py:37 -msgid "* Mentioning people from friends or followers buffers works again." -msgstr "" - -#: ../doc/changelog.py:38 -msgid "" -"* Support for proxy servers has been improved. Now TWBlue supports http, " -"https, socks4 and socks5 proxies, with and without autentication." -msgstr "" - -#: ../doc/changelog.py:39 -msgid "## Changes in version 0.87" -msgstr "" - -#: ../doc/changelog.py:40 -msgid "* Fixed stream connection errors." -msgstr "" - -#: ../doc/changelog.py:41 -msgid "" -"* Now TWBlue can handle properly a reply to the sender without including all " -"other mentioned users." -msgstr "" - -#: ../doc/changelog.py:42 -msgid "* Updated translations." -msgstr "" - -#: ../doc/changelog.py:43 -msgid "" -"* The status of the mention to all checkbox will be remembered the next time " -"you reply to multiple users." -msgstr "" - -#: ../doc/changelog.py:44 -msgid "## Changes in version 0.86" -msgstr "" - -#: ../doc/changelog.py:45 -msgid "" -"* Fixed a very important security issue. Now TWBlue will send tweets to " -"twishort without using any other server." -msgstr "" - -#: ../doc/changelog.py:46 -msgid "" -"* When you add a comment to a tweet, it will be sent as a quoted tweet, even " -"if your reply plus the original tweet is not exceeding 140 characters." -msgstr "" - -#: ../doc/changelog.py:47 -msgid "" -"* Updated windows 10 keymap for reflecting changes made in the last windows " -"10 build." -msgstr "" - -#: ../doc/changelog.py:48 -msgid "* Added last changes in the twitter API." -msgstr "" - -#: ../doc/changelog.py:49 -msgid "" -"* When replying, it will not show the twitter username in the text box. When " -"you send the tweet, the username will be added automatically." -msgstr "" - -#: ../doc/changelog.py:50 -msgid "" -"* When replying to multiple users, you'll have a checkbox instead a button " -"for mentioning all people. If this is checked, twitter usernames will be " -"added automatically when you send your reply." -msgstr "" - -#: ../doc/changelog.py:51 -msgid "## Changes in version 0.85" -msgstr "" - -#: ../doc/changelog.py:52 -msgid "* Long and quoted tweets should be displayed properly In lists." -msgstr "" - -#: ../doc/changelog.py:53 -msgid "* The connection should be more stable." -msgstr "" - -#: ../doc/changelog.py:54 -msgid "* Added an autostart option in the global settings dialogue." -msgstr "" - -#: ../doc/changelog.py:55 -msgid "* Updated translation." -msgstr "" - -#: ../doc/changelog.py:56 -msgid "* Updated russian documentation." -msgstr "" - -#: ../doc/changelog.py:57 -msgid "* Tweets in cached database should be loaded properly." -msgstr "" - -#: ../doc/changelog.py:58 -msgid "* Added some missed dictionaries for spelling correction." -msgstr "" - -#: ../doc/changelog.py:59 -msgid "" -"* Timelines, lists and other buffer should be created in the right order at " -"startup." -msgstr "" - -#: ../doc/changelog.py:60 -msgid "## Changes in version 0.84 " -msgstr "" - -#: ../doc/changelog.py:61 -msgid "* More improvements in quoted and long tweets." -msgstr "" - -#: ../doc/changelog.py:62 -msgid "" -"* Updated translations: Russian, Italian, French, Romanian, Galician and " -"Finnish." -msgstr "" - -#: ../doc/changelog.py:63 -msgid "" -"* Improvements in the audio uploader module: Now it can handle audio with " -"non-english characters." -msgstr "" - -#: ../doc/changelog.py:64 -msgid "" -"* the title of the window should be updated properly when spellcheck, " -"translate or shorten/unshorten URL buttons are pressed." -msgstr "" - -#: ../doc/changelog.py:65 -msgid "" -"* the bug that changes the selected tweet in the home timeline shouldn't be " -"happening so often." -msgstr "" - -#: ../doc/changelog.py:66 -msgid "## Changes in version 0.82 and 0.83" -msgstr "" - -#: ../doc/changelog.py:67 -msgid "" -"* If the tweet source (client) is an application with unicode characters " -"(example: российская газета) it will not break the tweet displayer." -msgstr "" - -#: ../doc/changelog.py:68 -msgid "" -"* Added a new field for image description in tweet displayer. When " -"available, it will show description for images posted in tweets." -msgstr "" - -#: ../doc/changelog.py:69 -msgid "" -"* users can add image descriptions to their photos. When uploading an image, " -"a dialog will show for asking a description." -msgstr "" - -#: ../doc/changelog.py:70 -msgid "* Redesigned upload image dialog." -msgstr "" - -#: ../doc/changelog.py:71 -msgid "* Fixed photo uploads when posting tweets." -msgstr "" - -#: ../doc/changelog.py:72 -msgid "" -"* When getting tweets for a conversation, ignores deleted tweets or some " -"errors, now TWBlue will try to get as much tweets as possible, even if some " -"of these are no longer available." -msgstr "" - -#: ../doc/changelog.py:73 -msgid "* Added audio playback from soundcloud." -msgstr "" - -#: ../doc/changelog.py:74 -msgid "* Now the session mute option don't makes the screen reader speaks." -msgstr "" - -#: ../doc/changelog.py:75 -msgid "* Fixed the direct message dialog. Now it should be displayed properly." -msgstr "" - -#: ../doc/changelog.py:76 -msgid "" -"* when a tweet is deleted in twitter, TWBlue should reflect this change and " -"delete that tweet in every buffer it is displayed." -msgstr "" - -#: ../doc/changelog.py:77 -msgid "" -"* If your session is broken, TWBlue will be able to remove it automatically " -"instead just crashing." -msgstr "" - -#: ../doc/changelog.py:78 -msgid "* audio uploader should display the current progress." -msgstr "" - -#: ../doc/changelog.py:79 -msgid "" -"* users can disable the check for updates feature at startup from the " -"general tab, in the global settings dialogue." -msgstr "" - -#: ../doc/changelog.py:80 -msgid "" -"* The invisible interface and the window should be synchronized when the " -"client reconnects." -msgstr "" - -#: ../doc/changelog.py:81 -msgid "* The documentation option in the systray icon should be enabled." -msgstr "" -"* Sistemaren ikonoetako dokumentazioa ikusteko aukera erabilgarria egon " -"beharko litzateke." - -#: ../doc/changelog.py:82 -msgid "" -"* In trending buffers, you can press enter for posting a tweet about the " -"focused trend." -msgstr "" -"* Tendentzien buferretan, enter saka dezakezu enfokatutako tendentziari " -"buruz txio bat argitaratzeko." - -#: ../doc/changelog.py:83 -msgid "" -"* Updated russian documentation and main program interface (thanks to " -"Natalia Hedlund (Наталья Хедлунд), [@lifestar_n](https://twitter.com/" -"lifestar_n) in twitter)" -msgstr "" - -#: ../doc/changelog.py:84 -msgid "* updated translations." -msgstr "* Itzulpenak eguneratuak izan dira." - -#: ../doc/changelog.py:85 -msgid "## Changes in Version 0.81" -msgstr "## 0.81bertsioaren aldaketak" - -#: ../doc/changelog.py:86 -msgid "* Updated translations" -msgstr "* Itzulpenak eguneratuak izan dira" - -#: ../doc/changelog.py:87 -msgid "" -"* The updater module has received some improvements. Now it includes a " -"Mirror URL for checking updates if the main URL is not available at the " -"moment. If something is wrong and both locations don't work, the program " -"will start anyway." -msgstr "" - -#: ../doc/changelog.py:88 -msgid "* some GUI elements now use keyboard shortcuts for common actions." -msgstr "" -"* Interfaze grafikoko elementu batzuek lasterbide teklak dituzte ohiko " -"ekintzetarako." - -#: ../doc/changelog.py:89 -msgid "* fixed a bug in the geolocation dialog." -msgstr "* Errore bat konpondu da geottxioen elkarrizketa-koadroan." - -#: ../doc/changelog.py:90 -msgid "* the chicken nugget keymap should work properly." -msgstr "* Chicken Nuggetaren teklatu-mapak ondo funtzionatu beharko luke." - -#: ../doc/changelog.py:91 -msgid "" -"* Added a new soundpack to the default installation of TWBlue, thanks to " -"[@Deng90](https://twitter.com/deng90)" -msgstr "" -"* Soinu pakete berri bat gehitu zaio TWBlueren lehenetsitako instalazioari, " -"eskerrak [@Deng90](https://twitter.com/deng90)" - -#: ../doc/changelog.py:92 -msgid "* Now the changelog is written in an html File." -msgstr "* Orain aldaketen fitxategia html fitxategi bat da." - -#: ../doc/changelog.py:93 -msgid "" -"* Added some missed dictionaries in last version for the spell checking " -"feature." -msgstr "" -"* Aurreko bertsioan falta ziren hiztegi batzuk gehitu dira, zuzentzaleak " -"erabiltzen dituenak." - -#: ../doc/changelog.py:94 -msgid "" -"* Trimmed the beginnings of the sounds in the default soundpack. Thanks to " -"[@masonasons](https://github.com/masonasons)" -msgstr "" -"* ehenetsitako soiinu paketearen soinuen hasierak moztu dira. Eskerrak " -"[@masonasons-i.](https://github.com/masonasons)" - -#: ../doc/changelog.py:95 -msgid "" -"* Added Opus support for sound playback in TWBlue. Thanks to [@masonasons]" -"(https://github.com/masonasons)" -msgstr "" -"* Opus formatua erreproduzi daiteke, eskerrak [@masonasons-i.](https://" -"github.com/masonasons)." - -#: ../doc/changelog.py:96 -msgid "" -"* Added a source field in view tweet dialogue. Thanks to [@masonasons]" -"(https://github.com/masonasons)" -msgstr "" -"* \"Iturria\" gehitu zaio txioa erakusteko elkarrizketa koadroari. Eskerrak " -"[@masonasons-i.](https://github.com/masonasons)" - -#: ../doc/changelog.py:97 -msgid "" -"* You can load previous items in followers and friend buffers for others." -msgstr "" -"* Aurreko elementuak karga ditzakezu besteen jarraitzaile eta lagunen " -"buferretan." - -#: ../doc/changelog.py:98 -msgid "" -"* The Spell Checker dialogue should not display an error message when you " -"have set \"default language\" in the global settings dialogue if your " -"language is supported [#168](http://twblue.es/bugs/view.php?id=168)" -msgstr "" -"* Zuzentzailearen elkarrizketa-koadroak ez luke errorerik erakutsi behar " -"aukera globaletan \"Lehenetsitako hizkuntza\" aukeratua dagoenean eta zure " -"hizkuntza erabilgarria denean [#168](http://twblue.es/bugs/view.php?id=168)" - -#: ../doc/changelog.py:99 -msgid "* Updated romanian translation." -msgstr "* Errumaniera itzulpena eguneratua izan da." - -#: ../doc/changelog.py:100 -msgid "* Some code cleanups." -msgstr "* Kode garbiketa batzuk." - -#: ../doc/changelog.py:101 -msgid "* The bug reports feature is fully operational again." -msgstr "* Arazoez informatzeko ezaugarriak berriz funtzionaten du" - -#: ../doc/changelog.py:102 -msgid "" -"* TWBlue should work again for users that contains special characters in " -"windows usernames." -msgstr "" -"* TWBluek berriz funtzionatu beharko luke haien Windows erabiltzaile-" -"izenetan karaktere bereziak dituzten erabiltzaileentzat." - -#: ../doc/changelog.py:103 -msgid "* Added more options for the tweet searches." -msgstr "* Txioen bilaketarako aukera gehiago gehitu dira." - -#: ../doc/changelog.py:104 -msgid "* Added play_audio to the keymap editor." -msgstr "* play_audio teklatu-mapen editorera gehitua izan da." - -#: ../doc/changelog.py:105 -msgid "* Windows key is no longer required in the keymap editor" -msgstr "* Windows tekla ez da jada bearrezkoa teklatu-mapen editorean." - -#: ../doc/changelog.py:106 -msgid "* Switched to the Microsoft translator." -msgstr "* Microsoften itzultzailera aldatu gara." - -#: ../doc/changelog.py:107 -msgid "" -"* You can update the current buffer by pressing ctrl+win+shift+u in the " -"default keymap or in the buffer menu." -msgstr "" -"* Enfokatutako uferra ktrl+shift+win+u sakatuta (lehenetsitako teklatu-" -"mapak) edo menuan eguneratu daitezke." - -#: ../doc/changelog.py:108 -msgid "* Changed some keystrokes in the windows 10 default keymap" -msgstr "" -"* Lasterbide-tekla batzuk aldatuak izan dira Windows 10erako teklatu-mapan." - -#: ../doc/changelog.py:109 -msgid "* New followers and friends buffer for user timelines." -msgstr "" -"* Jarraitzaileen eta lagunen bufer berria erabiltzaileen denbora-lerroentzat." - -#: ../doc/changelog.py:110 -msgid "---" -msgstr "---" - -#: ../doc/changelog.py:111 -msgid "Copyright © 2014-2017, Manuel Cortez." -msgstr "Copyright © 2014-2017, Manuel Cortez." diff --git a/doc/locales/eu/lc_messages/twblue-documentation.mo b/doc/locales/eu/lc_messages/twblue-documentation.mo index 57c9414e..3abe64b6 100644 Binary files a/doc/locales/eu/lc_messages/twblue-documentation.mo and b/doc/locales/eu/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/eu/lc_messages/twblue-documentation.po b/doc/locales/eu/lc_messages/twblue-documentation.po index e29734ef..1e97fbf6 100644 --- a/doc/locales/eu/lc_messages/twblue-documentation.po +++ b/doc/locales/eu/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2015-11-27 08:33-0600\n" "Last-Translator: Manuel Cortéz \n" "Language-Team: Sukil Echenique \n" diff --git a/doc/locales/fi/lc_messages/twblue-changelog.mo b/doc/locales/fi/lc_messages/twblue-changelog.mo new file mode 100644 index 00000000..51402baa Binary files /dev/null and b/doc/locales/fi/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/fi/lc_messages/twblue-changelog.po b/doc/locales/fi/lc_messages/twblue-changelog.po index a6893693..4f4466de 100644 --- a/doc/locales/fi/lc_messages/twblue-changelog.po +++ b/doc/locales/fi/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-07 13:52-0500\n" "Last-Translator: Manuel Cortez \n" "Language-Team: \n" diff --git a/doc/locales/fi/lc_messages/twblue-documentation.mo b/doc/locales/fi/lc_messages/twblue-documentation.mo new file mode 100644 index 00000000..f38123e3 Binary files /dev/null and b/doc/locales/fi/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/fi/lc_messages/twblue-documentation.po b/doc/locales/fi/lc_messages/twblue-documentation.po index 1f39ef47..496a5d9a 100644 --- a/doc/locales/fi/lc_messages/twblue-documentation.po +++ b/doc/locales/fi/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-27 16:37+0200\n" "Last-Translator: Jani Kinnunen \n" "Language-Team: \n" diff --git a/doc/locales/fr/lc_messages/twblue-changelog.mo b/doc/locales/fr/lc_messages/twblue-changelog.mo index 6435cb92..83695c7f 100644 Binary files a/doc/locales/fr/lc_messages/twblue-changelog.mo and b/doc/locales/fr/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/fr/lc_messages/twblue-changelog.po b/doc/locales/fr/lc_messages/twblue-changelog.po index 6bcd6cf0..b63e5c4a 100644 --- a/doc/locales/fr/lc_messages/twblue-changelog.po +++ b/doc/locales/fr/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: twblue-changelog 0.93\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estándar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2019-07-22 16:16+0200\n" "Last-Translator: Corentin BACQUÉ-CAZENAVE \n" "Language-Team: Corentin BACQUÉ-CAZENAVE \n" diff --git a/doc/locales/fr/lc_messages/twblue-documentation.mo b/doc/locales/fr/lc_messages/twblue-documentation.mo index 8b3416db..3065b0af 100644 Binary files a/doc/locales/fr/lc_messages/twblue-documentation.mo and b/doc/locales/fr/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/fr/lc_messages/twblue-documentation.po b/doc/locales/fr/lc_messages/twblue-documentation.po index 6b92578b..db2c8548 100644 --- a/doc/locales/fr/lc_messages/twblue-documentation.po +++ b/doc/locales/fr/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.88\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-11 12:25+0200\n" "Last-Translator: Rémy Ruiz \n" "Language-Team: Rémy Ruiz \n" diff --git a/doc/locales/gl/lc_messages/twblue-changelog.mo b/doc/locales/gl/lc_messages/twblue-changelog.mo index c68704b2..57a0258a 100644 Binary files a/doc/locales/gl/lc_messages/twblue-changelog.mo and b/doc/locales/gl/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/gl/lc_messages/twblue-changelog.po b/doc/locales/gl/lc_messages/twblue-changelog.po index e7682561..16f38baf 100644 --- a/doc/locales/gl/lc_messages/twblue-changelog.po +++ b/doc/locales/gl/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2019-05-12 22:19+0100\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/gl/lc_messages/twblue-documentation.mo b/doc/locales/gl/lc_messages/twblue-documentation.mo index 34c42135..6b8c27a1 100644 Binary files a/doc/locales/gl/lc_messages/twblue-documentation.mo and b/doc/locales/gl/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/gl/lc_messages/twblue-documentation.po b/doc/locales/gl/lc_messages/twblue-documentation.po index 9712fbee..bfe34947 100644 --- a/doc/locales/gl/lc_messages/twblue-documentation.po +++ b/doc/locales/gl/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: tw blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 11:34+0100\n" "Last-Translator: Juan C. Buño \n" "Language-Team: Alba Quinteiro \n" diff --git a/doc/locales/hu/lc_messages/twblue-changelog.mo b/doc/locales/hu/lc_messages/twblue-changelog.mo index f53cb685..f9d41433 100644 Binary files a/doc/locales/hu/lc_messages/twblue-changelog.mo and b/doc/locales/hu/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/hu/lc_messages/twblue-changelog.po b/doc/locales/hu/lc_messages/twblue-changelog.po index cc86518d..63843755 100644 --- a/doc/locales/hu/lc_messages/twblue-changelog.po +++ b/doc/locales/hu/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-12-11 11:07-0600\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/hu/lc_messages/twblue-documentation.mo b/doc/locales/hu/lc_messages/twblue-documentation.mo index a2b23b1e..065ee2c6 100644 Binary files a/doc/locales/hu/lc_messages/twblue-documentation.mo and b/doc/locales/hu/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/hu/lc_messages/twblue-documentation.po b/doc/locales/hu/lc_messages/twblue-documentation.po index 99f405a7..57cd4f6a 100644 --- a/doc/locales/hu/lc_messages/twblue-documentation.po +++ b/doc/locales/hu/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2015-11-27 08:34-0600\n" "Last-Translator: Manuel Cortéz \n" "Language-Team: \n" diff --git a/doc/locales/it/lc_messages/twblue-changelog.mo b/doc/locales/it/lc_messages/twblue-changelog.mo index d8e985e3..ebf9145a 100644 Binary files a/doc/locales/it/lc_messages/twblue-changelog.mo and b/doc/locales/it/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/it/lc_messages/twblue-changelog.po b/doc/locales/it/lc_messages/twblue-changelog.po index 739b2c2f..d288faf9 100644 --- a/doc/locales/it/lc_messages/twblue-changelog.po +++ b/doc/locales/it/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-12-11 11:07-0600\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/it/lc_messages/twblue-documentation.mo b/doc/locales/it/lc_messages/twblue-documentation.mo index 5b98fffd..3da1c1b0 100644 Binary files a/doc/locales/it/lc_messages/twblue-documentation.mo and b/doc/locales/it/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/it/lc_messages/twblue-documentation.po b/doc/locales/it/lc_messages/twblue-documentation.po index b6b8db7e..210a1b1f 100644 --- a/doc/locales/it/lc_messages/twblue-documentation.po +++ b/doc/locales/it/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-09 11:51+0100\n" "Last-Translator: Chris Leo Mameli \n" "Language-Team: \n" diff --git a/doc/locales/ja/lc_messages/twblue-changelog.mo b/doc/locales/ja/lc_messages/twblue-changelog.mo index e3a5bd5b..96e197b7 100644 Binary files a/doc/locales/ja/lc_messages/twblue-changelog.mo and b/doc/locales/ja/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/ja/lc_messages/twblue-changelog.po b/doc/locales/ja/lc_messages/twblue-changelog.po index ff9fb59a..9e39121f 100644 --- a/doc/locales/ja/lc_messages/twblue-changelog.po +++ b/doc/locales/ja/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 19:52+0900\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/ja/lc_messages/twblue-documentation.mo b/doc/locales/ja/lc_messages/twblue-documentation.mo index c81f278c..dd9e9c9d 100644 Binary files a/doc/locales/ja/lc_messages/twblue-documentation.mo and b/doc/locales/ja/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/ja/lc_messages/twblue-documentation.po b/doc/locales/ja/lc_messages/twblue-documentation.po index 74a1b294..46d4399a 100644 --- a/doc/locales/ja/lc_messages/twblue-documentation.po +++ b/doc/locales/ja/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 19:09+0900\n" "Last-Translator: Masamitsu Misono \n" "Language-Team: NVDA Help Desk \n" diff --git a/doc/locales/pl/lc_messages/twblue-changelog.mo b/doc/locales/pl/lc_messages/twblue-changelog.mo index 23e79664..035db01e 100644 Binary files a/doc/locales/pl/lc_messages/twblue-changelog.mo and b/doc/locales/pl/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/pl/lc_messages/twblue-changelog.po b/doc/locales/pl/lc_messages/twblue-changelog.po index b4f375f6..ae4e991c 100644 --- a/doc/locales/pl/lc_messages/twblue-changelog.po +++ b/doc/locales/pl/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-12-11 11:08-0600\n" "Last-Translator: zvonimir stanecic \n" "Language-Team: \n" diff --git a/doc/locales/pl/lc_messages/twblue-documentation.mo b/doc/locales/pl/lc_messages/twblue-documentation.mo index c551c017..179c4bff 100644 Binary files a/doc/locales/pl/lc_messages/twblue-documentation.mo and b/doc/locales/pl/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/pl/lc_messages/twblue-documentation.po b/doc/locales/pl/lc_messages/twblue-documentation.po index c20e8c96..7c281a31 100644 --- a/doc/locales/pl/lc_messages/twblue-documentation.po +++ b/doc/locales/pl/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-01-22 21:42+0100\n" "Last-Translator: Zvonimir Stanečić \n" "Language-Team: \n" diff --git a/doc/locales/pt/lc_messages/twblue-changelog.mo b/doc/locales/pt/lc_messages/twblue-changelog.mo index 112641aa..f78ff581 100644 Binary files a/doc/locales/pt/lc_messages/twblue-changelog.mo and b/doc/locales/pt/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/pt/lc_messages/twblue-changelog.po b/doc/locales/pt/lc_messages/twblue-changelog.po index 44f69c6f..d8bab64b 100644 --- a/doc/locales/pt/lc_messages/twblue-changelog.po +++ b/doc/locales/pt/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2017-12-11 11:08-0600\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/pt/lc_messages/twblue-documentation.mo b/doc/locales/pt/lc_messages/twblue-documentation.mo index 53f3ddc7..526e4126 100644 Binary files a/doc/locales/pt/lc_messages/twblue-documentation.mo and b/doc/locales/pt/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/pt/lc_messages/twblue-documentation.po b/doc/locales/pt/lc_messages/twblue-documentation.po index 1dd21a0a..6f43b32f 100644 --- a/doc/locales/pt/lc_messages/twblue-documentation.po +++ b/doc/locales/pt/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2015-11-27 08:35-0600\n" "Last-Translator: Manuel Cortéz \n" "Language-Team: \n" diff --git a/doc/locales/pt/manual.md b/doc/locales/pt/manual.md deleted file mode 100644 index a3703c37..00000000 --- a/doc/locales/pt/manual.md +++ /dev/null @@ -1,285 +0,0 @@ -% Documentação do TW Blue 0.42 - -# Versão 0.42 (alpha) - -# ¡Perigro! - -Você está lendo um documento gerado para uma aplicação em fase de desenvolvimento. A intenção deste manual é esclarecer alguns detalhes sobre o funcionamento do programa. Note-se que sendo desenvolvido ativamente, o software pode mudar um pouco em relação a esta documentação num futuro próximo. Por isso é aconselhável dar uma olhada de vez em quando para não se perder muito. - -Si quieres ver lo que ha cambiado con respecto a la versión anterior, [lee la lista de novedades aquí.](changes.html) - -# TW Blue - -TW Blue é um aplicativo para utilizar o Twitter de forma simples e rápida, além de evitar tanto quanto possível consumir demasiados recursos do computador. Com ele é possível realizar ações do Twitter, tais como: - -* Crear, responder, reenviar y eliminar Tuits, -* Marcar como favorito, eliminar de tus favoritos un tuit, -* Enviar y eliminar mensajes directos, -* Ver tus amigos y seguidores, -* Seguir, dejar de seguir, reportar como spam y bloquear a un usuario, -* Abrir una línea temporal para un usuario, lo que permite obtener todos los Tuits de ese usuario únicamente, -* Abrir direcciones URL cuando vayan en un tuit o mensaje directo, -* Reproducir varios tipos de archivos o direcciones que contengan audio. -* Y más. - -# Tabla de contenidos - -Para poder utilizar una aplicación como TW Blue que te permita gestionar una cuenta de Twitter, primero tienes que estar registrado en esta red social. Esta documentación no tiene como objetivo explicar el procedimiento para hacerlo. Partiremos desde el punto que tienes una cuenta con su respectivo nombre de usuario y contraseña. La documentación cubrirá estas secciones. - -* [Autorizar la aplicación](#autorizar) -* [La interfaz del programa](#interfaz) -* [Controles](#controles) - * [La interfaz gráfica (GUI)](#gui) - * [Botones de la aplicación](#botones) - * [Menús](#menus) - * [Menú aplicación](#app) - * [Menú Tuit](#tuit) - * [Menú Usuario](#usuario) - * [Menú buffer](#buffer) - * [Menú ayuda](#ayuda) - * [La interfaz No Visible](#interfaz_no_visible) - * [Atajos de Teclado para la Interfaz Gráfica](#atajos) - * [Atajos de Teclado para la Interfaz no Visible](#atajos_invisibles) -* [Listas](#listas) -* [Reportando Errores desde la web](#reportar) -* [Contacto](#contacto) - -## Autorizando la aplicación {#autorizar} - -Antes de nada, lo primero que se necesita es autorizar al programa para que este pueda acceder a tu cuenta de Twitter, y desde ella realizar lo que le pidas. El proceso de autorización es bastante sencillo, y en ningún momento el programa podrá tener acceso a tus datos como usuario y contraseña. Para autorizar la aplicación, solo tienes que abrir el archivo principal del programa, llamado TW Blue.exe (en algunos PC, solo se muestra como TW Blue). - -Al hacerlo, si no has configurado ninguna vez el programa, se mostrará un cuadro de diálogo donde te informa que serás llevado a Twitter para autorizar la aplicación una vez pulses sobre "aceptar". Para empezar con el proceso de autorización presiona sobre el único botón de ese diálogo. - -A continuación, tu navegador predeterminado se abrirá con la página de Twitter solicitándote autorizar la aplicación. Escribe, si no estás autenticado ya, tu nombre de usuario y contraseña, luego busca el botón autorizar, y presiónalo. - -De la página a la que serás redirigido (si el proceso ha tenido éxito), busca las instrucciones que te proporciona Twitter. En resumen, te dará un código numérico de varios dígitos que deberás pegar en un cuadro de texto que la aplicación ha abierto en otra ventana. - -Pega el código de verificación, y pulsa la tecla Intro. - -Si todo ha salido bien, la aplicación empezará a reproducir un grupo de sonidos en señal que se están actualizando tus datos. - -Cuando termine, el programa reproducirá otro sonido, y el lector de pantalla dirá "listo". - -## La interfaz del programa {#interfaz} - -La forma más simple de describir la interfaz gráfica de la aplicación es la de una ventana con una barra de menú con cinco menús (aplicación, tuit, usuario, buffer y ayuda); una lista de varios elementos y en la mayoría de los casos tres botones. Tuit, retuit y responder. Las acciones para cada uno de estos elementos serán descritas más adelante. - -Los elementos que hay en las listas pueden ser Tuits, mensajes directos o usuarios. TW Blue crea diferentes pestañas para cada lista, pues estos elementos pueden ser Tuits enviados, Tuits recividos en la línea principal, favoritos, o mensajes directos, y cada pestaña tiene un solo tipo de Tuit. Estas pestañas se llaman listas o buffers. - -Para cambiar entre las listas se hace presionando Control+Tab si se desea avanzar, y Control+Shift+Tab para retroceder. En todo momento los lectores de pantalla anunciarán la lista hacia la que se cambie el foco de la aplicación. Aquí están las listas básicas de TW Blue, que aparecen si se usa la configuración por defecto. - -* Principal: Aquí van todos los Tuits que se muestran en la línea principal. Estos son los Tuits de los usuarios a los que sigues. -* Menciones: Si un usuario (lo sigas o no) te menciona en Twitter, lo verás en esta lista. -* Mensajes directos: Aquí están los mensajes directos (privados) que intercambias con los usuarios que sigues y te siguen. Esta lista solo muestra los mensajes recividos. -* Enviados: En esta lista se muestran todos los Tuits y mensajes directos que se han enviado desde tu cuenta. -* Favoritos: Aquí verás los Tuits que has marcado como favoritos. -* Seguidores: Cuando los usuarios sigan tu cuenta, podrás verlos en esta lista, junto con un poco de información de la cuenta. -* Amigos: Igual que la lista anterior, pero estos usuarios son a los que tú sigues. -* Eventos: Un evento en TW Blue es "algo" que pase en Twitter. En la línea de eventos, podrás ver registrados los eventos más comunes (p. Ej. Te han comenzado a seguir, han marcado o removido un tweet tuyo de los favoritos, te has suscrito a una lista). Son como pequeñas notificaciones que envía Twitter y TW Blue organiza para que no te pierdas lo que ha pasado con tu cuenta. -* Línea temporal de un usuario: Estas son listas que tú deberás crear. Es una lista que contiene únicamente los Tuits de un usuario. Se usan si algún día necesitas o quieres ver los Tuits que ha realizado solo una persona y no deseas buscar por todo tu timeline. Puedes crear tantas como usuarios necesites. -* Lista: Una lista es parecida a una línea temporal, pero compuesta por los tweets de cada usuario que forme parte de ella. De momento las listas son una característica experimental de TW Blue. Si experimentas problemas con ellas, por favor escríbenos para contárnoslo. -* Búsqueda: Un buffer de búsqueda contiene los resultados de una búsqueda hecha en TW Blue. Las búsquedas pueden ser por tuits, en cuyo caso buscas un término en los tuits relevantes de Twitter, o por usuarios, donde los resultados son nombres de usuario de Twitter. -* Favoritos de un usuario: Es posible pedirle a TW Blue que te muestre los tuits que un usuario ha marcado como favoritos. - -Nota: Únicamente para esta versión de TW Blue, los amigos y seguidores actualizarán hasta 400, o cerca a los 400. En la próxima versión proporcionaremos un método para ver los amigos y seguidores sin exponerse tanto a los errores causados por el uso de la API de Twitter, muy frecuente entre personas con más de 600 amigos o seguidores. - -Ten en cuenta que por defecto la configuración solo permite obtener los 200 últimos Tuits para las listas principal, menciones, mensajes directos y líneas temporales. Esto puedes cambiarlo desde el diálogo de configuración. Para los enviados se obtendrán los últimos 200 Tuits y 200 mensajes directos. En versiones futuras se permitirá ajustar este parámetro. - -Si hay una dirección URL en algún tuit, TW Blue intentará abrirla cuando presiones Intro sobre ella. Si hay más de una, te mostrará una lista con todas para que selecciones la que quieras abrir. Si estás en el cuadro de diálogo de los amigos o seguidores, la tecla intro te mostrará detalles del mismo. - -Si pulsas Control+Intro, TW Blue intentará reproducir el audio que tenga el tuit sobre el que está el foco del sistema, siempre que tenga una URL. Si el tuit lleva la etiqueta #audio, un sonido al pasar por él te alertará que es un audio y puedes intentar reproducirlo. No obstante, también puede que no esté etiquetado y que TW Blue pueda reproducirlo, siempre que lleve a una dirección URL donde exista audio. - -## Controles {#controles} - -A partir de la versión 0.36, existe soporte para una interfaz que no requiere de una ventana visible. Esta puede ser activada pulsando Control+m, o seleccionando desde el menú aplicación la opción "Esconder ventana". Esta interfaz se maneja completamente con atajos de teclado. Estos atajos son diferentes a los que se utilizan para la interfaz gráfica. Cada una de ellas podrá utilizar solo los atajos que le correspondan, lo que quiere decir que no se permitirá utilizar los atajos de la interfaz no visible si se tiene activada la interfaz gráfica. En esta sección se detallará tanto la interfaz gráfica como la no visible. - -### Interfaz gráfica (GUI) {#gui} - -Aquí una lista dividida en dos partes. Por un lado, los botones que encontrarás si presionas Tab o Shift+Tab en la interfaz del programa, y por otro, los diferentes elementos que hay en la barra de menú. - -#### Botones de la aplicación {#botones} - -* Twit: Este botón abre el diálogo para escribir un tuit. El mensaje solo debe tener 140 caracteres. Al escribir el caracter número 141, un sonido será reproducido para indicarte que te has pasado del límite permitido por Twitter. Puedes querer acortar o desacortar una URL si la incluye tu tuit a fin de ganar más espacio donde escribir, para eso están los botones con esos nombres. Pulsa Intro para enviar el tuit. Si todo sale bien, el mensaje se enviará y tú escucharás un sonido que te lo confirme, si no, el lector de pantalla te responderá con un error en inglés, que indica por qué no se ha podido enviar el mensaje. -* Retuit: Este botón se encarga de reenviar el tuit sobre el que estás leyendo. Al presionarlo se te preguntará si deseas añadirle un comentario al tuit original (citándolo) o simplemente enviarlo como se ha escrito sin añadir nada más. -* Responder: Cuando estés visualizando un Tuit, puedes responderle al usuario que lo escribió pulsando sobre este botón. Se abrirá el mismo diálogo de Tuit, pero con el nombre del usuario (por ejemplo @usuario) en el, para que solo escribas el mensaje que quieres responderle. Si en el tuit hay más de un usuario mencionado, pulsa Shift+Tab y pulsa el botón "Mencionar a todos los usuarios". Cuando estés en la lista de amigos o seguidores, este botón se llamará mencionar. -* mensaje directo: Exactamente igual que enviar un Tuit, pero es un mensaje privado que solo podrá ver el usuario al que se lo envías. Pulsa Shift+Tab para ver el destinatario de tu mensaje. Si en el Tuit donde estabas para enviar el mensaje había más de un usuario mencionado, puedes navegar con las flechas de arriba y abajo para seleccionar otro, o escribir tú mismo el usuario (sin el signo de arroba). - -Ten en cuenta que los botones aparecerán según las acciones que se puedan hacer en la lista donde estés. Por ejemplo, en la línea principal, menciones, enviados, favoritos y las líneas temporales de los usuarios podrás ver los cuatro botones; mientras que en la lista de mensajes directos solo estará disponible el botón de "Mensaje Directo" y "tuit", y en las listas de amigos y seguidores, se verá el botón para "Twit" y el de "Mensaje directo" junto a "mencionar". - -#### Menús {#menus} - -En la parte superior de la ventana del programa podrás encontrar una barra de menú que hace las mismas cosas, y algunas cuantas más. A la barra de menú se accede presionando la tecla ALT, y cuenta en este momento con cuatro menús para diferentes acciones: Aplicación, Tuit, usuario y Ayuda. En esta sección se describen las acciones para cada uno de ellos. - -##### Menú aplicación {#app} - -* Actualizar Perfil: Abre un diálogo desde donde se podrá actualizar parte de tu información en Twitter. Nombre, ubicación, dirección URL y descripción. Si ya tienes alguno de estos campos actualmente en el perfil se llenarán automáticamente con lo que tiene tu configuración de Twitter. También podrás subir una foto a tu perfil. -* Esconder Ventana: Desactiva la interfaz gráfica. Lee el apartado sobre la interfaz no visible para más detalles sobre este comportamiento. -* Búsqueda: Muestra un cuadro de diálogo desde donde puedes buscar por tuits o por usuarios en twitter. -* Gestor de listas: Para poder utilizar las listas de Twitter, primero necesitarás crearlas. Este diálogo permite ver tus listas, editarlas, crearlas, borrarlas y, opcionalmente, verlas en buffers tal como lo harías con las líneas temporales. -* Tutorial de sonidos: Abre un diálogo donde verás una lista de los sonidos de TW blue, para que puedas aprenderlos y no te cueste trabajo familiarizarte con TW Blue. -* Preferencias: Abre un diálogo de configuración desde donde se pueden controlar algunos aspectos del programa. Las opciones no necesitan de explicación. -* Salir: pregunta si quieres salir o no del programa. Si la respuesta es que sí, cierra la aplicación. - -##### Menú Tuit {#tuit} - -* Las primeras opciones del menú son Twit, responder y retuit, que corresponden a los botones del mismo nombre. -* Marcar como favorito: Marca el tuit que estés viendo como favorito. -* Quitar tuit de favoritos: Elimina el tuit de tus favoritos. Esto no significa que se borra de Twitter, solo deja de estar en tu lista de favoritos. -* Ver Tuit: Abre un diálogo donde puedes ver el Tuit, mensaje directo, amigo o seguidor sobre el que esté el foco de la aplicación. Puedes leer el texto con los cursores. El diálogo es el mismo que el que se usa para escribir un Tuit. -* Eliminar: Elimina el Tuit o mensaje directo sobre el que estés, borrándolo definitivamente de Twitter y qitándolo de tus listas. Ten en cuenta que en el caso de los Tuits, Twitter solo permite borrar los que tú mismo has escrito. - -##### Menú usuario {#usuario} - -Ten en cuenta que las primeras seis opciones de este menú abren un mismo diálogo. Este diálogo tiene un cuadro de edición donde puedes seleccionar el usuario sobre el que deseas actuar, bien con los cursores arriba y abajo o escribiendo tú mismo el nombre. Después, hay un grupo de botones de radio para seguir, dejar de seguir, silenciar, des-silenciar, reportar como Spam y bloquear. Si seleccionas desde el menú la opción seguir, el botón del cuadro de diálogo estará marcado con esa opción, así como sucederá respectivamente con dejar de seguir, reportar como Spam y bloquear. Pulsa el botón Aceptar para que el programa trate de hacer lo que le pides. Si no se ha podido, escucharás el error en inglés. - -A continuación se describen las opciones restantes para este menú: - -* Mensaje Directo: La misma acción que el botón. -* Añadir a lista: Para que puedas ver los tweets de un usuario en tus listas, primero hay que añadirlo. Esta opción abrirá un diálogo desde donde puedes seleccionar al usuario que deseas añadir, para después abrir otra ventana donde puedes seleccionar la lista a la cual añadir a ese usuario. Una vez hecho esto, la lista contendrá un nuevo usuario y podrás ver sus tweets. -* Ver Perfil del usuario: Abre un diálogo desde donde te permite seleccionar el usuario al que quieres ver el perfil. -* Línea temporal: Abre un diálogo desde donde puedes seleccionar el usuario para el que se creará la línea temporal. Al presionar intro, se creará. Si se hace una línea temporal de un usuario que no tenga Tuits, el programa fallará. Si se crea una línea que ya existe el programa te avisará y no permitirá crearla de nuevo. -* Ver favoritos: Abre un buffer para seguir los favoritos que marca el usuario seleccionado. - -##### Menú Buffer {#buffer} - -* Silenciar: Silencia completamente el buffer, con lo que no escucharás sonido alguno cuando nuevos elementos aparezcan. -* Leer automáticamente tuits para este buffer: Esta opción activa o desactiva la lectura automática de tuits. Si está activada, el lector de pantalla o la voz Sapi5 (si está activada una) leerá automáticamente los nuevos tuits conforme estos vayan llegando al buffer. -* Limpiar Buffer: Vacía los elementos de este buffer. -* Eliminar buffer: Borra la lista sobre la que te encuentras actualmente. - -##### Menú Ayuda {#ayuda} - -* Documentación: Abre este archivo, donde puedes leer algunos conceptos interesantes del programa. -* ¿Qué hay de nuevo en esta versión?: Abre un documento con la lista de cambios desde la versión actual, hasta la primera en existencia. -* Buscar actualizaciones: Cada que se abre el programa él mismo busca automáticamente si hay una nueva versión. Si lo hay, te preguntará si quieres descargarla; si aceptas, TW Blue descargará la actualización, la instalará y te pedirá reiniciarla (algo que hace automáticamente). Esta opción comprueba si hay actualizaciones sin tener que reiniciar la aplicación. -* Sitio web de TW Blue. Ve a nuestra [página principal](http://twblue.com.mx) donde podrás encontrar toda la información y descargas relativas a TW Blue, así como participar de la comunidad. -* Reportar un error: Lanza un diálogo desde donde puedes reportar un error solo llenando un par de campos. El título y una pequeña descripción de lo que pasó. Al pulsar en "enviar" el error se reportará. Si no se ha podido el programa te mostrará un mensaje informándolo. -* Sobre TW Blue: Muestra información de créditos del programa. - -### Interfaz no visible {#interfaz_no_visible} - -Si presionas Control+M, o si desde el menú aplicación seleccionas esconder ventana, estarás activando una interfaz a la que no se podrá acceder por la manera convencional, porque no se ve. - -En la interfaz no visible todo lo que hagas será mediante atajos de teclado, incluso para recorrer las listas. Eventualmente se abrirán diálogos y estos sí serán visibles, pero la ventana principal de la aplicación no. Ve a la sección de atajos de teclado de la interfaz no visible para saber cuales puedes usar de momento. - -### Atajos de teclado para la Interfaz Gráfica {#atajos} - -Además de los botones y menús, la mayoría de las acciones pueden hacerse presionando una combinación de teclado. Aquí están las existentes en este momento: - -* Intro: Abrir una dirección URL. Si hay más de una podrás ver una lista que te permitirá seleccionar la que quieras. Si estás en la lista de amigos o seguidores, mostrará detalles del seleccionado. -* Control+Intro: Intenta reproducir un audio si en el Tuit hay una dirección URL. -* F5: Baja un 5% el volumen de los sonidos. Esto afecta a los sonidos que reproduce el programa y al audio que puedas escuchar a través de él. -* F6: Sube un 5% el volumen de los sonidos de la aplicación. -* Control+N: Abre el diálogo para escribir un nuevo Tuit. -* Control+M: Oculta la ventana. -* Control+Q: Sale de la aplicación. -* Control+R: Abre el diálogo para responder. -* Control+Shift+R: Equivalente a la acción Retuit. -* Control+D: Enviar mensaje directo. -* Control+F: Marcar como favorito. -* Control+Shift+F: Quitar de favoritos. -* Control+Shift+V: Ver Tuit. -* Control+S: Seguir a un usuario. -* Control+Shift+S: Dejar de seguir a un usuario. -* Control+K: Bloquear a un usuario. -* Control+Shift+K: Reportar como Spam. -* Control+I: Abrir línea temporal a un usuario. -* Control+Shift+I: Eliminar línea temporal. -* Control+p: Editar tu perfil. -* Suprimir: Eliminar tuit o mensaje directo. -* Shift+suprimir: vacía el buffer, quitando todos los elementos hasta ese entonces. Esto ocurre sin borrar nada de Twitter. - -### Atajos de teclado para la Interfaz no Visible {#atajos_invisibles} - -Estos son los atajos de teclado que puedes usar desde la interfaz no visible. Ten en cuenta que cuando la vista de la interfaz gráfica esté activada ninguno de ellos podrá usarse. Al decir "windows", nos estamos refiriendo a la tecla de Windows izquierda. - -* Control+Windows+Flecha Arriba: Va arriba en la lista actual. -* Control+Windows+Flecha abajo: Va hacia abajo en la lista actual. -* Control+Windows+Izquierda: Se desplaza a la pestaña de la izquierda. -* Control+Windows+Derecha: Se desplaza hacia la pestaña de la derecha. -* Control+Windows+Inicio: Ir al primer elemento de la lista. -* Control+Windows+Fin: Ir al final de la lista. -* Control+Windows+Avance de página: Ir 20 elementos hacia abajo en la lista actual. -* Control+Windows+Retroceso de página: ir 20 elementos hacia arriba en la lista actual. -* Control+Windows+Alt+Flecha Arriba: Subir volumen un 5%. -* Control+Windows+Alt+Flecha Abajo: Bajar volumen un 5%. -* Control+Windows+Intro: Abrir URL en el tuit, o ver detalles del usuario si estás en la lista de amigos o seguidores. -* Control+Windows+Alt+Intro: Intentar reproducir un audio. -* Control+Windows+M: Muestra la interfaz gráfica, desactivando la no visible. -* Control+Windows+N: Hacer un nuevo Tuit. -* Control+Windows+R: Responder a un tuit. -* Control+Windows+Shift+R: Hacer un retuit. -* Control+Windows+D: Enviar un mensaje directo. -* Control+Windows+Suprimir: Eliminar un tuit o mensaje directo. -* control+win+Shift+suprimir: vacía el buffer, quitando todos los elementos hasta ese entonces. Esto ocurre sin borrar nada de Twitter. -* Windows+Alt+F: Marcar como favorito. -* Windows+Alt+Shift+F: Quitar de favoritos. -* Control+Windows+S: Seguir a un usuario. -* Control+Windows+Shift+S: Dejar de seguir a alguien. -* Control+Windows+Alt+N: Ver detalles de un usuario, -* Control+Windows+V: Ver tuit en un cuadro de texto. -* Control+Windows+I: Abrir línea temporal. -* Control+Windows+Shift+I: Eliminar línea temporal de un usuario. -* Alt+Windows+P: Editar tu perfil. -* Control+win+espacio: ver tweet actual. -* Control+win+c: Copiar tweet al portapapeles. -* Control+windows+a: Añadir a un usuario a la lista. -* Control+shift+windows+a: qitar de la lista. -* Control+Windows+Shift+Flecha arriba: Ir un tuit hacia arriba en la conversación. -* Control+Windows+Flecha Abajo: Ir un tuit hacia abajo en la conversación. -* Control+Windows+Shift+M: Activar o desactivar el sonido para el buffer actual. -* Windows+Alt+M: Activar o desactivar el silencio global de TW Blue. -* Control+Windows+E: Activar o desactivar la lectura automática de los tuits en el buffer actual. -* Control+windows+Guion: buscar en Twitter. -* Control+Windows+F4: Cerrar el programa. - -## Listas {#listas} - -Una de las características más interesantes de Twitter son las listas, ya que son una manera de mantenerse actualizado sin tener que leer los tweets de todos los usuarios a los que sigues. Con una lista de Twitter solo verás los tweets de sus miembros (la gente que está dentro de la lista). Es parecido a una línea temporal, pero para muchos más usuarios. - -En TW blue hemos empezado a dar soporte para esta característica. De momento vamos poco a poco, pero ya es posible usar esta función. Te presentamos los pasos que hay que dar para poder tener una lista abierta en TW Blue. - -* Primero necesitarás ir al gestor de listas, ubicado bajo el menú aplicación. -* en el gestor de listas podrás ver todas las listas a las que estás unido, empezando por las que tú has creado. Si no ves ninguna lista en este diálogo, significa que no has creado ni te has unido a ninguna lista. Está bien. -* Verás un grupo de botones que se explican por sí solos: Crear nueva lista, editar, eliminar, abrir en buffer (este quizá es el menos claro, se refiere a abrir un nuevo buffer para que TW Blue actualice los tweets de la lista, como cuando pasa con las líneas temporales). - -Una vez que hayas creado una nueva lista, no deberías abrirla en buffer. Al menos no de inmediato, porque en este momento no tiene miembro alguno y eso significa que cuando se carguen los tweets para empezar a actualizarla no verás nada. Es recomendable primero añadir a gente a la lista, tal como sigue: - -* Cuando hayas cerrado el gestor de listas y estés navegando por entre los tweets de los usuarios, busca el usuario al que quieres añadir a la lista. -* Una vez encontrado, presiona el atajo Ctrl+Win+A o ve al menú usuario y selecciona la opción "Añadir a lista". -* Lo siguiente que verás es un diálogo que te permitirá seleccionar el usuario, asegúrate que el que está como predeterminado es el que deseas, o cámbialo si es necesario, y presiona Aceptar. -* Ahora verás otro diálogo, pero aquí están todas tus listas. Selecciona una (simplemente lleva el cursor hacia ella), y presiona el botón añadir. -* Para qitar a un usuario de una lista repite el mismo proceso, pero presiona Control+Win+Shift+A o selecciona la opción "Quitar de lista", y en el diálogo de las listas presiona sobre el botón "remover". - -## Reportando Errores Desde la Web {#reportar} - -Nota: Si estás usando el programa también puedes reportar un error desde el mismo, usando para ello la opción del menú ayuda. Este proceso solo te pide llenar dos cuadros de edición, y se encarga del resto. Estos pasos están escritos para quienes no pueden abrir el programa, no lo tienen en uso en este momento o sencillamente quieran reportar desde la web en lugar del sistema integrado de reporte de errores. - -Las cosas en este mundo (sí, incluidos los programas informáticos) están muy lejos de ser perfectas, con lo que a menudo te encontrarás con errores no previstos en la aplicación. Pero como la intención es siempre mejorar, eres libre (es más, sería genial que lo hicieras) de reportar los errores que vayas encontrando del programa para que se puedan revisar y eventualmente corregir. - -Para entrar a la web de reporte de incidencias, sigue [Este enlace.](http://twblue.com.mx/errores/bug_report_page.php) Es una web con un formulario donde tienes que llenar varios campos. Solo tres de ellos son realmente obligatorios (los que tienen marcado un asterisco), pero entre más campos puedas llenar, será mejor. - -Aquí están los diferentes campos del formulario y lo que deberías introducir en cada uno de ellos. Recuerda que son obligatorios solamente los campos marcados con un asterisco (*): - -* Categoría: Este cuadro combinado permite seleccionar a qué categoría asignar el error. Puede ser a la categoría General, si es un error del programa, o a documentación, si has encontrado un error en este archivo o en la lista de cambios. Este campo es obligatorio. -* Reproducibilidad: Aquí deberías indicar qué tan fácil o no es de reproducir el error. Las opciones disponibles son Desconocido, No reproducible, No se ha intentado (por defecto), aleatorio, a veces o siempre. Dependiendo de si se puede reproducir el error o no, deberías indicar lo que se parezca más a tu caso. Si estás solicitando una nueva funcionalidad, no importa este cuadro combinado. -* Severidad: Aquí se selecciona que tanto afecta esto al programa. Las opciones disponibles son funcionalidad (selecciona esto para solicitar una nueva funcionalidad), Trivial, Texto, Ajuste, Menor, Mayor, fallo o bloqueo. Nota que las opciones aumentan de nivel. Selecciona lo que más creas. Si no estás seguro de que seleccionar puedes dejarlo como está. -* Prioridad: En este cuadro se selecciona la opción de acuerdo con la importancia del error o funcionalidad solicitada. Las opciones disponibles son Ninguna, baja, normal, alta, hurgente e inmediata. -* Seleccionar Perfil: Aquí puedes escojer entre la configuración de arquitectura (32 o 64 bits), y el sistema operativo (Windows siete de momento). Si no, puedes llenar los tres cuadros de edición que están en la siguiente tabla con tus datos en específico. -* Versión del producto: Selecciona la versión del programa que estás utilizando para poder averiguar donde se ha generado el error. Este cuadro combinado tendrá la lista de las versiones en orden. Si bien no es obligatorio, ayudaría mucho a resolver más rápidamente el error. -* Resumen: Un título para el error, que explique en pocas palabras qué ocurre. Es un cuadro de texto obligatorio. -* Descripción: Este campo también obligatorio, te pide que describas con más detalles qué fue lo que ha ocurrido con el programa. -* Pasos para reproducir: Este campo de texto te sirve si sabes como hacer que la aplicación genere el error. Esto no es obligatorio, pero ayudaría mucho conocer como hacer que el programa tenga este error para rastrearlo mejor. -* Información adicional: Si tienes un comentario o nota que añadir, aquí puede ir. No es obligatorio. -* Subir archivo: Puedes subir aquí el archivo TW Blue.exe.log que se creó con el error que el programa tuvo. No es obligatorio. -* Visibilidad: Selecciona si quieres que el error sea público o privado. Por defecto es público, y es recomendable que así continúe. -* Enviar reporte. Presiona aquí para publicar el error y que este sea atendido. - -Muchas gracias por participar reportando errores y probando las funciones nuevas. - -## Contacto {#contacto} - -Si lo que se expone en este documento no es suficiente, si deseas colaborar de alguna otra forma o si simplemente deseas mantenerte en contacto con quien hace esta aplicación, sigue a la cuenta [@tw_blue2](https://twitter.com/tw_blue2) o a [@manuelcortez00.](https://twitter.com/manuelcortez00) También puedes visitar nuestro [Sitio web](http://twblue.com.mx) - ---- -Copyright © 2013-2014. Manuel Cortéz. \ No newline at end of file diff --git a/doc/locales/ro/LC_MESSAGES/twblue-changelog.mo b/doc/locales/ro/LC_MESSAGES/twblue-changelog.mo index 4fc2e2ac..cb94a33d 100644 Binary files a/doc/locales/ro/LC_MESSAGES/twblue-changelog.mo and b/doc/locales/ro/LC_MESSAGES/twblue-changelog.mo differ diff --git a/doc/locales/ro/LC_MESSAGES/twblue-changelog.po b/doc/locales/ro/LC_MESSAGES/twblue-changelog.po index 21e89aea..7d660945 100644 --- a/doc/locales/ro/LC_MESSAGES/twblue-changelog.po +++ b/doc/locales/ro/LC_MESSAGES/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 10:27+0300\n" "Last-Translator: Florian Ionașcu \n" "Language-Team: \n" diff --git a/doc/locales/ro/LC_MESSAGES/twblue-documentation.mo b/doc/locales/ro/LC_MESSAGES/twblue-documentation.mo index ceb4a89b..c55a7dd5 100644 Binary files a/doc/locales/ro/LC_MESSAGES/twblue-documentation.mo and b/doc/locales/ro/LC_MESSAGES/twblue-documentation.mo differ diff --git a/doc/locales/ro/LC_MESSAGES/twblue-documentation.po b/doc/locales/ro/LC_MESSAGES/twblue-documentation.po index 9b28749d..9dadf1b8 100644 --- a/doc/locales/ro/LC_MESSAGES/twblue-documentation.po +++ b/doc/locales/ro/LC_MESSAGES/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: twblue-documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-08 10:32+0300\n" "Last-Translator: Florian Ionașcu \n" "Language-Team: Spanish \n" diff --git a/doc/locales/ru/lc_messages/twblue-changelog.mo b/doc/locales/ru/lc_messages/twblue-changelog.mo index f84dcfa3..722647bb 100644 Binary files a/doc/locales/ru/lc_messages/twblue-changelog.mo and b/doc/locales/ru/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/ru/lc_messages/twblue-changelog.po b/doc/locales/ru/lc_messages/twblue-changelog.po index ad092bb6..aa2c1950 100644 --- a/doc/locales/ru/lc_messages/twblue-changelog.po +++ b/doc/locales/ru/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-15 12:20+0400\n" "Last-Translator: Наталья Хедлунд \n" "Language-Team: \n" diff --git a/doc/locales/ru/lc_messages/twblue-documentation.mo b/doc/locales/ru/lc_messages/twblue-documentation.mo index 0e690af5..f3e178bd 100644 Binary files a/doc/locales/ru/lc_messages/twblue-documentation.mo and b/doc/locales/ru/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/ru/lc_messages/twblue-documentation.po b/doc/locales/ru/lc_messages/twblue-documentation.po index c4660bdb..de56bbe5 100644 --- a/doc/locales/ru/lc_messages/twblue-documentation.po +++ b/doc/locales/ru/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-08-14 21:44+0400\n" "Last-Translator: Valeria \n" "Language-Team: \n" diff --git a/doc/locales/sr/lc_messages/twblue-changelog.mo b/doc/locales/sr/lc_messages/twblue-changelog.mo new file mode 100644 index 00000000..d570b36f Binary files /dev/null and b/doc/locales/sr/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/gl/lc_messages/twblue-changelog (Jani Kinnunen's conflicted copy 2019-03-25).po b/doc/locales/sr/lc_messages/twblue-changelog.po similarity index 56% rename from doc/locales/gl/lc_messages/twblue-changelog (Jani Kinnunen's conflicted copy 2019-03-25).po rename to doc/locales/sr/lc_messages/twblue-changelog.po index 503e12c8..16f1e60f 100644 --- a/doc/locales/gl/lc_messages/twblue-changelog (Jani Kinnunen's conflicted copy 2019-03-25).po +++ b/doc/locales/sr/lc_messages/twblue-changelog.po @@ -5,25 +5,26 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2018-08-08 11:46+0100\n" -"Last-Translator: \n" +"POT-Creation-Date: 2019-03-17 13:34\n" +"PO-Revision-Date: 2021-06-27 04:17+0100\n" +"Last-Translator: Nikola Jović \n" "Language-Team: \n" -"Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 1.6.11\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.6.10\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" +"Language: sr\n" #: ../doc/changelog.py:3 msgid "TWBlue Changelog" -msgstr "TWBlue Changelog" +msgstr "TWBlue lista promena" #: ../doc/changelog.py:4 msgid "## changes in this version" -msgstr "## cambios nesta versión" +msgstr "## Promene u ovoj verziji" #: ../doc/changelog.py:5 msgid "" @@ -31,49 +32,56 @@ msgid "" "in the context menu for people and tweet buffers, and also, the shortcut " "control+win+alt+Enter will open the focused item in Twitter." msgstr "" +"* TWBlue može da otvori tvit ili korisnika direktno na Twitteru. Nova opcija " +"je u kontekstnom meniju za ljude i kanale, i takođe, prečica control+win+alt" +"+Enter otvara fokusiranu stavku na Twitteru." #: ../doc/changelog.py:6 -#, fuzzy msgid "* Some keystrokes were remapped in the Windows 10 Keymap:" -msgstr "" -"* Cambiados algúns atallos de teclado no mapa de teclado do Windows 10." +msgstr "* Neke prečice su promenjene u Windows 10 mapi tasterskih prečica:" #: ../doc/changelog.py:7 -#, fuzzy msgid "" " * Read location of a tweet: Ctrl+Win+G. ([#177](https://github.com/" "manuelcortez/TWBlue/pull/177))" msgstr "" -"* Arranxado un erro que facía que os arquivos de audio non se liberaran " -"despois de se subir a algún servizo de audio. ([#130](https://github.com/" -"manuelcortez/TWBlue/issues/130))" +" * Čitanje lokacije tvita: Ctrl+Win+G. ([#177](https://github.com/" +"manuelcortez/TWBlue/pull/177))" #: ../doc/changelog.py:8 msgid " * Open global settings dialogue: Ctrl+Win+Alt+O." -msgstr "" +msgstr " * Otvaranje dijaloga globalnih podešavanja: Ctrl+Win+Alt+O." #: ../doc/changelog.py:9 -#, fuzzy msgid " * Mute/unmute current session: Control + Windows + Alt + M." -msgstr " * Para marcar como góstame un chío, preme Control+Windows+alt+f" +msgstr "" +" * Utišavanje / uklanjanje utišavanja trenutne sesije: Control + Windows " +"+ Alt + M." #: ../doc/changelog.py:10 msgid "" "* Fixed an error that was preventing TWBlue to load the direct messages " "buffer if an user who sent a message has been deleted." msgstr "" +"* Ispravljena greška koja je sprečavala da TWBlue učita kanal sa direktnim " +"porukama ako je korisnik koji je poslao direktnu poruku obrisan." #: ../doc/changelog.py:11 msgid "" "* Added support for playing audios posted in [AnyAudio.net](http://anyaudio." "net) directly from TWBlue. Thanks to [Sam Tupy](http://www.samtupy.com/)" msgstr "" +"* Dodata podrška za reprodukciju zvučnih zapisa na servisu [AnyAudio.net]" +"(http://anyaudio.net) direktno iz programa TWBlue. Zahvalnost [Sam Tupy]" +"(http://www.samtupy.com/)" #: ../doc/changelog.py:12 msgid "" "* Custom buffer ordering will not be reset every time the application " "restarts after an account setting has been modified." msgstr "" +"* Prilagođen raspored kanala se neće resetovati svaki put kada se aplikacija " +"ponovo pokrene nakon izmenjenog podešavanja naloga." #: ../doc/changelog.py:13 msgid "" @@ -81,78 +89,84 @@ msgid "" "in the focused list instead of having to search for the \"add\" or \"delete" "\" button." msgstr "" +"* Kada dodajete ili uklanjate korisnike iz liste, moguće je da pritisnete " +"enter na fokusiranu listu umesto potrebe da tražite tastere \"dodaj\" ili " +"\"obriši\"." #: ../doc/changelog.py:14 -#, fuzzy msgid "" "* Quoted and long tweets are displayed properly in the sent tweets buffer " "after being send. ([#253](https://github.com/manuelcortez/TWBlue/issues/253))" msgstr "" -"* A descripción de imaxes amosarase tamén en rechíos. ([#119](https://github." -"com/manuelcortez/TWBlue/issues/119))" +"* Citirani i dugi tvitovi se ispravno prikazuju u kanalima za poslate " +"tvitove nakon što su poslati. ([#253](https://github.com/manuelcortez/TWBlue/" +"issues/253))" #: ../doc/changelog.py:15 -#, fuzzy msgid "" "* Fixed an issue that was making the list manager keystroke unable to be " "shown in the keystroke editor. Now the keystroke is listed properly. ([#260]" "(https://github.com/manuelcortez/TWBlue/issues/260))" msgstr "" -"* Arranxado un problema que facía que o TWBlue non poidese comezar se se " -"estaba a executar en Windows coa lingua Servia. ([#175](https://github.com/" -"manuelcortez/TWBlue/issues/175))" +"* Ispravljen problem koji je izazvao da se prečica za upravljanje listama ne " +"prikazuje u dijalogu za izmenu tasterskih prečica. Sada se prečica ispravno " +"prikazuje. ([#260](https://github.com/manuelcortez/TWBlue/issues/260))" #: ../doc/changelog.py:16 -#, fuzzy msgid "" "* The volume slider, located in the account settings of TWBlue, now should " "decrease and increase value properly when up and down arrows are pressed. " "Before it was doing it in inverted order. ([#261](https://github.com/" "manuelcortez/TWBlue/issues/261))" msgstr "" -"* Cando cites un chío, se o chío orixinal se publicou con Twishort, o TWBlue " -"amosará correctamente o chío citado. Antes só amosaba o chío orixinal. " -"([#206](https://github.com/manuelcortez/TWBlue/issues/206))" +"* Slajder za jačinu, koji se nalazi u podešavanjima naloga za TWBlue, trebao " +"bi da ispravno smanjuje i povećava vrednost kada se koriste strelice gore i " +"dole. Ranije je ovo bilo obrnuto. ([#261](https://github.com/manuelcortez/" +"TWBlue/issues/261))" #: ../doc/changelog.py:17 -#, fuzzy msgid "" "* autoreading has been redesigned to work in a similar way for almost all " "buffers. Needs testing. ([#221](https://github.com/manuelcortez/TWBlue/" "issues/221))" msgstr "" -"* O TWBlue amosará un erro se se intenta abrir una liña temporal para un " -"usuario suspendido. ([#128](https://github.com/manuelcortez/TWBlue/" -"issues/128))" +"* Automatsko čitanje je redizajnirano da radi na sličan način za sve kanale. " +"Neophodno je testiranje. ([#221](https://github.com/manuelcortez/TWBlue/" +"issues/221))" #: ../doc/changelog.py:18 msgid "" "* When displaying tweets or direct messages, a new field has been added to " "show the date when the item has been posted to Twitter." msgstr "" +"* Kada se prikazuju tvitovi ili direktne poruke, dodato je novo polje koje " +"će prikazati datum kada je stavka objavljena." #: ../doc/changelog.py:19 msgid "" "* Added support for deleting direct messages by using the new Twitter API " "methods." msgstr "" +"* Dodata podrška za brisanje direktnih poruka korišćenjem novog Twitter API " +"metoda." #: ../doc/changelog.py:20 msgid "" "* When quoting a retweet, the quote will be made to the original tweet " "instead of the retweet." msgstr "" +"* Kada citirate retvit, citiranje će biti izvršeno na izvornom tvitu umesto " +"na retvitu." #: ../doc/changelog.py:21 -#, fuzzy msgid "" "* If the sent direct messages buffer is hidden, TWBlue should keep loading " "everything as expected. ([#246](https://github.com/manuelcortez/TWBlue/" "issues/246))" msgstr "" -"* Arranxado un erro que facía que os arquivos de audio non se liberaran " -"despois de se subir a algún servizo de audio. ([#130](https://github.com/" -"manuelcortez/TWBlue/issues/130))" +"* Ako je kanal poslatih direktnih poruka skriven, TWBlue bi trebao da učita " +"sve ostalo kako treba. ([#246](https://github.com/manuelcortez/TWBlue/" +"issues/246))" #: ../doc/changelog.py:22 msgid "" @@ -162,61 +176,67 @@ msgid "" "opinion in snapshot versions. ([#247](https://github.com/manuelcortez/TWBlue/" "issues/247))" msgstr "" +"* Dostupan je novi zvučni paket, koji se zove FreakyBlue (zahvalnost [Andre " +"Louis](https://twitter.com/FreakyFwoof)) kao nova opcija u programu TWBlue. " +"Ovaj paket bi mogao da postane podrazumevani u sledećoj stabilnoj verziji, " +"tako da korisnici mogu da ga probaju i izraze svoje mišljenje u verzijama za " +"testiranje. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))" #: ../doc/changelog.py:23 -#, fuzzy msgid "" "* There is a new option in the help menu that allows you to visit the " "soundpacks section in the TWBlue website. ([#247](https://github.com/" "manuelcortez/TWBlue/issues/247))" msgstr "" -"* O TWBlue agora Usa WXPython 4.0.1. Esto permitiranos migrar todos os " -"compoñentes importantes a Python 3 no futuro. ([#207](https://github.com/" -"manuelcortez/TWBlue/issues/207))" +"* U meni pomoći je dodata nova opcija koja dozvoljava da posetite deo TWBlue " +"sajta vezan za zvučne pakete. ([#247](https://github.com/manuelcortez/TWBlue/" +"issues/247))" #: ../doc/changelog.py:24 -#, fuzzy msgid "" "* When reading location of a geotagged tweet, it will be translated for " "users of other languages. ([#251](https://github.com/manuelcortez/TWBlue/" "pull/251))" msgstr "" -"* cando se lea un chío longo, non deberían aparecer símbolos extranos. " -"([#118](https://github.com/manuelcortez/twblue/issues/118))" +"* Kada čitate lokaciju geografskog tvita, biće preveden za korisnike drugih " +"jezika. ([#251](https://github.com/manuelcortez/TWBlue/pull/251))" #: ../doc/changelog.py:25 msgid "" "* When there are no more items to retrieve in direct messages and people " "buffers, a message will announce it." msgstr "" +"* Kada više nema stavki koje se mogu preuzeti u kanalima sa korisnicima ili " +"sa direktnim porukama, poruka će to označiti." #: ../doc/changelog.py:26 msgid "" "* Fixed an issue reported by some users that was making them unable to load " "more items in their direct messages." msgstr "" +"* Ispravljen problem prijavljen od strane nekih korisnika koji je izazivao " +"nemogućnost preuzimanja dodatnih stavki u kanalu direktnih poruka." #: ../doc/changelog.py:27 msgid "" "* It is possible to add a tweet to the likes buffer from the menu bar again." -msgstr "" +msgstr "* Ponovo je moguće dodati tvit u kanal sviđanja iz trake sa menijima." #: ../doc/changelog.py:28 msgid "" "* Tweets, replies and retweets will be added to sent tweets right after " "being posted in Twitter." msgstr "" +"* Tvitovi, odgovori i retvitovi će biti odmah dodati u kanal poslatih " +"tvitova nakon što se objave na Twitter." #: ../doc/changelog.py:29 -#, fuzzy msgid "* Extended Tweets should be displayed properly in list buffers." -msgstr "" -"* Os chíos longos e citados deberían amosarse correctamente nas listas." +msgstr "* Dugi tvitovi bi trebalo da se ispravno prikazuju u kanalima lista." #: ../doc/changelog.py:30 -#, fuzzy msgid "## Changes in version 0.94" -msgstr "## Cambios na versión 0.93" +msgstr "## Promene u 0.94 (Engleski )" #: ../doc/changelog.py:31 msgid "" @@ -225,11 +245,10 @@ msgid "" "16, so this option will give people an idea about how it will be. ([#219]" "(https://github.com/manuelcortez/TWBlue/issues/219))" msgstr "" -"* Engadida una opción no diálogo opción globais para deshabilitar as " -"características de Streaming do TWBlue. TWBlue eliminará todas as " -"características de Streaming despois do 16 de agosto, así esta opción dará " -"una idea á xente de como será. ([#219](https://github.com/manuelcortez/" -"TWBlue/issues/219))" +"* Added an option in the global settings dialog to disable the Streaming " +"features of TWBlue. TWBlue will remove all Streaming features after August " +"16, so this option will give people an idea about how it will be. ([#219]" +"(https://github.com/manuelcortez/TWBlue/issues/219))" #: ../doc/changelog.py:32 msgid "" @@ -238,11 +257,10 @@ msgid "" "required to paste a code displayed in the Twitter website in order to grant " "access to TWBlue. ([#216](https://github.com/manuelcortez/TWBlue/issues/216))" msgstr "" -"* Debido aos cambios na API de Twitter, cambiou o método de autorización a " -"una autorización baseada nun código Pin. Cando engadas contas novas ao " -"TWBlue, pediráseche pegar un código amosado no sitio web do Twitter para " -"garantizar o aceso ao TWBlue. ([#216](https://github.com/manuelcortez/TWBlue/" -"issues/216))" +"* Due to Twitter API changes, Switched authorisation method to Pin-code " +"based authorisation. When you add new accounts to TWBlue, you will be " +"required to paste a code displayed in the Twitter website in order to grant " +"access to TWBlue. ([#216](https://github.com/manuelcortez/TWBlue/issues/216))" #: ../doc/changelog.py:33 msgid "" @@ -250,25 +268,25 @@ msgid "" "new method used to send and receive direct messages, according to issue " "[#215.](https://github.com/manuelcortez/twblue/issues/215)" msgstr "" -"* Para poder cumprir cos últimos cambios en Twitter, o TWBlue cambiou ao " -"novo método usado para enviar e recibir as mensaxes directas, de acordo co " -"arranxo [#215.](https://github.com/manuelcortez/twblue/issues/215)" +"* In order to comply with latest Twitter changes, TWBlue has switched to the " +"new method used to send and receive direct messages, according to issue " +"[#215.](https://github.com/manuelcortez/twblue/issues/215)" #: ../doc/changelog.py:34 msgid "" " * The new method does not allow direct messages to be processed in real " "time. Direct messages will be updated periodically." msgstr "" -" * O novo método non permite procesar as mensaxes directas en tempo real. " -"As mensaxes directas actualizaranse periódicamente." +" * The new method does not allow direct messages to be processed in real " +"time. Direct messages will be updated periodically." #: ../doc/changelog.py:35 msgid "" "* After august 16 or when streaming is disabled, the events buffer will no " "longer be created in TWBlue." msgstr "" -"* Despois do 16 de agosto ou cando se deshabilite o streaming, o búfer " -"eventos xa non se creará no TWBlue." +"* After august 16 or when streaming is disabled, the events buffer will no " +"longer be created in TWBlue." #: ../doc/changelog.py:36 msgid "" @@ -277,13 +295,12 @@ msgid "" "setting in the global settings dialog. ([#223](https://github.com/" "manuelcortez/TWBlue/issues/223))" msgstr "" -"* Podes configurar a frecuencia para as actualizacións do búfer no TWBlue. " -"De xeito predeterminado, o TWBlue actualizará todos os búferes cada 2 " -"minutos, pero podes cambiar esta opción no diálogo opcións globais. ([#223]" -"(https://github.com/manuelcortez/TWBlue/issues/223))" +"* You can configure frequency for buffer updates in TWBlue. By default, " +"TWBlue will update all buffers every 2 minutes, but you can change this " +"setting in the global settings dialog. ([#223](https://github.com/" +"manuelcortez/TWBlue/issues/223))" #: ../doc/changelog.py:37 -#, fuzzy msgid "" "* Added a new tab called feedback, in the account settings dialog. This tab " "allows you to control whether automatic speech or Braille feedbak in certain " @@ -292,12 +309,12 @@ msgid "" "any kind of automatic output. ([#203](https://github.com/manuelcortez/TWBlue/" "issues/203))" msgstr "" -"* Engadida una nova pestana chamada retroalimentación, no diálogo opcións da " -"conta. Esta pestana permíteche controlar a retroalimentación automática da " -"fala ou do braille en certos eventos (mencións e mensaxes directas " -"recibidas) está habilitado. Ten en conta que esta opción terá preferencia " -"sobre a lectura automática dos búferes e de calquer tipo de saída " -"automática. ([#203](https://github.com/manuelcortez/TWBlue/issues/203))" +"* Added a new tab called feedback, in the account settings dialog. This tab " +"allows you to control whether automatic speech or Braille feedbak in certain " +"events (mentions and direct messages received) is enabled. Take into account " +"that this option will take preference over automatic reading of buffers and " +"any kind of automatic output. ([#203](https://github.com/manuelcortez/TWBlue/" +"issues/203))" #: ../doc/changelog.py:38 msgid "" @@ -305,9 +322,9 @@ msgid "" "important actions. ([#211](https://github.com/manuelcortez/TWBlue/" "issues/211))" msgstr "" -"* O diálogo de correción de ortografía agora ten teclas de aceso definidas " -"para as acións máis importantes. ([#211](https://github.com/manuelcortez/" -"TWBlue/issues/211))" +"* The spell checking dialog now has access keys defined for the most " +"important actions. ([#211](https://github.com/manuelcortez/TWBlue/" +"issues/211))" #: ../doc/changelog.py:39 msgid "" @@ -315,8 +332,8 @@ msgid "" "important components to Python 3 in the future. ([#207](https://github.com/" "manuelcortez/TWBlue/issues/207))" msgstr "" -"* O TWBlue agora Usa WXPython 4.0.1. Esto permitiranos migrar todos os " -"compoñentes importantes a Python 3 no futuro. ([#207](https://github.com/" +"* TWBlue now Uses WXPython 4.0.1. This will allow us to migrate all " +"important components to Python 3 in the future. ([#207](https://github.com/" "manuelcortez/TWBlue/issues/207))" #: ../doc/changelog.py:40 @@ -326,54 +343,54 @@ msgid "" "the original tweet only. ([#206](https://github.com/manuelcortez/TWBlue/" "issues/206))" msgstr "" -"* Cando cites un chío, se o chío orixinal se publicou con Twishort, o TWBlue " -"amosará correctamente o chío citado. Antes só amosaba o chío orixinal. " -"([#206](https://github.com/manuelcortez/TWBlue/issues/206))" +"* When you quote a Tweet, if the original tweet was posted with Twishort, " +"TWBlue should display properly the quoted tweet. Before it was displaying " +"the original tweet only. ([#206](https://github.com/manuelcortez/TWBlue/" +"issues/206))" #: ../doc/changelog.py:41 msgid "" "* It is possible to filter by retweets, quotes and replies when creating a " "new filter." msgstr "" -"* É posible filtrar por rechíos, citados e respostas cando se cree un filtro " -"novo." +"* It is possible to filter by retweets, quotes and replies when creating a " +"new filter." #: ../doc/changelog.py:42 msgid "" "* Added support for playing youtube Links directly from the client. ([#94]" "(https://github.com/manuelcortez/TWBlue/issues/94))" msgstr "" -"* Engadido o soporte para reproducir ligas de youtube directamente dende o " -"cliente. ([#94](https://github.com/manuelcortez/TWBlue/issues/94))" +"* Added support for playing youtube Links directly from the client. ([#94]" +"(https://github.com/manuelcortez/TWBlue/issues/94))" #: ../doc/changelog.py:43 msgid "* Replaced Bass with libVLC for playing URL streams." -msgstr "* Remplazado Bass con libVLC para reproducir URL streams." +msgstr "* Replaced Bass with libVLC for playing URL streams." #: ../doc/changelog.py:44 -#, fuzzy msgid "" "* the checkbox for indicating whether TWBlue will include everyone in a " "reply or not, will be unchecked by default." msgstr "" -"* A caixa de verificación para indicar se o TWBlue incluirá a calquera nunha " -"resposta ou non, estará desmarcada por omisión." +"* the checkbox for indicating whether TWBlue will include everyone in a " +"reply or not, will be unchecked by default." #: ../doc/changelog.py:45 msgid "" "* You can request TWBlue to save the state for two checkboxes: Long tweet " "and mention all, from the global settings dialogue." msgstr "" -"* Podes pedir ao TWBlue que garde o estado para dúas caixas de verificación: " -"Chío longo e mencionar a todos, dende a Caixa de diálogo opcións globais." +"* You can request TWBlue to save the state for two checkboxes: Long tweet " +"and mention all, from the global settings dialogue." #: ../doc/changelog.py:46 msgid "" "* For windows 10 users, some keystrokes in the invisible user interface have " "been changed or merged:" msgstr "" -"* Para os usuarios do windows 10, cambiáronse ou fusionáronse algúns atallos " -"de teclado na interfaz invisible de usuario:" +"* For windows 10 users, some keystrokes in the invisible user interface have " +"been changed or merged:" #: ../doc/changelog.py:47 msgid "" @@ -381,29 +398,31 @@ msgid "" "removing a tweet to user's likes. This function will execute the needed " "action based in the current status for the focused tweet." msgstr "" -" * control+Windows+alt+F usarase para conmutar entre engadir ou borrar un " -"chío aos gústame do usuario. Esta función executará a acción necesaria " -"baseada no estado actual para o chío enfocado." +" * control+Windows+alt+F will be used for toggling between adding and " +"removing a tweet to user's likes. This function will execute the needed " +"action based in the current status for the focused tweet." #: ../doc/changelog.py:48 msgid "* TWBlue will show an error if something goes wrong in an audio upload." -msgstr "* O TWBlue amosará un erro se algo vai mal nunha subida dun audio." +msgstr "" +"* TWBlue will show an error if something goes wrong in an audio upload." #: ../doc/changelog.py:49 msgid "" "* And more. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " -msgstr "* E máis. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " +msgstr "" +"* And more. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " #: ../doc/changelog.py:50 msgid "## Changes in version 0.93" -msgstr "## Cambios na versión 0.93" +msgstr "## Changes in version 0.93" #: ../doc/changelog.py:51 msgid "" "* A new soundpack has been added to TWBlue. Thanks to [@ValeriaK305](https://" "twitter.com/ValeriaK305)" msgstr "" -"* Engadido un novo pack de sons ao TWBlue. Grazas a [@ValeriaK305](https://" +"* A new soundpack has been added to TWBlue. Thanks to [@ValeriaK305](https://" "twitter.com/ValeriaK305)" #: ../doc/changelog.py:52 @@ -411,17 +430,16 @@ msgid "" "* In the Windows 10 keymap, we have changed some default keystrokes as " "windows now uses some previously assigned shortcuts:" msgstr "" -"* No mapa de teclado para o Windows 10, cambiamos algún atallos de teclado " -"predeterminados xa que windows agora usa algúns atallos de teclado asignados " -"anteriormente:" +"* In the Windows 10 keymap, we have changed some default keystrokes as " +"windows now uses some previously assigned shortcuts:" #: ../doc/changelog.py:53 msgid " * For liking a tweet, press Control+Windows+alt+f" -msgstr " * Para marcar como góstame un chío, preme Control+Windows+alt+f" +msgstr " * For liking a tweet, press Control+Windows+alt+f" #: ../doc/changelog.py:54 msgid " * for opening a trends buffer, press control+Windows+T" -msgstr " * para abrir un búfer de tendencias, press control+Windows+T" +msgstr " * for opening a trends buffer, press control+Windows+T" #: ../doc/changelog.py:55 msgid "" @@ -429,8 +447,9 @@ msgid "" "tweets, long tweets and quoted retweets. It should render some tweets in a " "better way." msgstr "" -"* TWBlue recibíu algunhas melloras no manexo de chíos longos, extendidos e " -"rechíos citados. Debería ser capaz de amosar mellor algúns chíos." +"* TWBlue has received improvements in some functions for handling extended " +"tweets, long tweets and quoted retweets. It should render some tweets in a " +"better way." #: ../doc/changelog.py:56 msgid "" @@ -438,16 +457,16 @@ msgid "" "add your own words to your personal dictionary so the module won't mark them " "as mispelled the next time you will check spelling." msgstr "" -"* No módulo de revisión de ortografía, hai unha función que che permite " -"engadir a palabra ao teu diccionario. Deste xeito, nun futuro esa palabra " -"non aparecerá marcada como mal escrita." +"* In the spell checker module, there is a new button that will allow you to " +"add your own words to your personal dictionary so the module won't mark them " +"as mispelled the next time you will check spelling." #: ../doc/changelog.py:57 msgid "" "* Added filtering capabilities to TWBlue. ([#102](https://github.com/" "manuelcortez/TWBlue/issues/102))" msgstr "" -"* Engadidas capacidades de filtrar ao TWBlue. ([#102](https://github.com/" +"* Added filtering capabilities to TWBlue. ([#102](https://github.com/" "manuelcortez/TWBlue/issues/102))" #: ../doc/changelog.py:58 @@ -456,21 +475,21 @@ msgid "" "the menu bar. At this moment, invisible interface does not have any shorcut " "for this." msgstr "" -"* Podes crear filtros para o búfer actual dende o menú búfer, atopado na " -"barra de menú. Polo de agora, a interfaz invisible non conta cun atallo para " -"esta ación." +" * You can create a filter for the current buffer from the buffer menu in " +"the menu bar. At this moment, invisible interface does not have any shorcut " +"for this." #: ../doc/changelog.py:59 msgid " * You can create filters by word or languages." -msgstr " * Podes crear filtros de palabras ou de linguas no chío." +msgstr " * You can create filters by word or languages." #: ../doc/changelog.py:60 msgid "" " * For deleting already created filters, you can go to the filter manager " "in the buffer menu and delete the filters you won't need." msgstr "" -"* Para borrar os filtros, podes aceder ao xestor de filtros no menú búfer, e " -"borrar dende ahí os que xa non necesites." +" * For deleting already created filters, you can go to the filter manager " +"in the buffer menu and delete the filters you won't need." #: ../doc/changelog.py:61 msgid "" @@ -478,16 +497,15 @@ msgid "" "com/manuelcortez/TWBlue/issues/167) [#184](https://github.com/manuelcortez/" "TWBlue/issues/184))" msgstr "" -"* As ligas deberíanse abrir apropriadamente en chíos cidatos ([#167,]" -"(https://github.com/manuelcortez/TWBlue/issues/167) [#184](https://github." -"com/manuelcortez/TWBlue/issues/184))" +"* Links should be opened properly in quoted tweets ([#167,](https://github." +"com/manuelcortez/TWBlue/issues/167) [#184](https://github.com/manuelcortez/" +"TWBlue/issues/184))" #: ../doc/changelog.py:62 msgid "" "* Increased display name limit up to 50 characters in update profile dialog." msgstr "" -"* Incrementouse o número de caracteres permitidos nos nomes para amosar en " -"Twitter a 50 caracteres." +"* Increased display name limit up to 50 characters in update profile dialog." #: ../doc/changelog.py:63 msgid "" @@ -496,9 +514,9 @@ msgid "" "the process starts. ([#101](https://github.com/manuelcortez/TWBlue/" "issues/101))" msgstr "" -"* Ao autorizar unha conta nova, verás un botón para cancelar a acción, se " -"queres deter o proceso. Ademáis, o NVDA non se bloqueará ao se iniciar a " -"autorización para a conta. ([#101](https://github.com/manuelcortez/TWBlue/" +"* When authorising an account, you will see a dialogue with a cancel button, " +"in case you want to abort the process. Also, NVDA will not be blocked when " +"the process starts. ([#101](https://github.com/manuelcortez/TWBlue/" "issues/101))" #: ../doc/changelog.py:64 @@ -509,12 +527,11 @@ msgid "" "box, because the language is detected automatically by Yandex'S API. ([#153]" "(https://github.com/manuelcortez/TWBlue/issues/153))" msgstr "" -"* no módulo de tradución, a listaxe de linguas soportadas obtense " -"automáticamente dende a web do proveedor. Esto significa que todos as " -"linguas funcionarán correctamente e non haberá problemas ao se traducir. " -"Tamén borramos a primeira Caixa combinada, xa que a lingua de orixen " -"determínase de xeito automático pola API de Yandex. ([#153](https://github." -"com/manuelcortez/TWBlue/issues/153))" +"* In the translator module, the list of available languages is fetched " +"automatically from the provider. That means all of these languages will work " +"and there will not be inconsistencies. Also we've removed the first combo " +"box, because the language is detected automatically by Yandex'S API. ([#153]" +"(https://github.com/manuelcortez/TWBlue/issues/153))" #: ../doc/changelog.py:65 msgid "" @@ -522,9 +539,9 @@ msgid "" "set for the session in wich they were opened. ([#157](https://github.com/" "manuelcortez/TWBlue/issues/157))" msgstr "" -"* As tendencias, as procuras e os búferes de conversa usarán as opcións de " -"silenciado configuradas para a sesión na que fosen abertos. ([#157](https://" -"github.com/manuelcortez/TWBlue/issues/157))" +"* Trending topics, searches and conversation buffers will use mute settings " +"set for the session in wich they were opened. ([#157](https://github.com/" +"manuelcortez/TWBlue/issues/157))" #: ../doc/changelog.py:66 msgid "" @@ -532,9 +549,9 @@ msgid "" "tweet longer tweets. ([#172](https://github.com/manuelcortez/TWBlue/" "issues/172))" msgstr "" -"* O límite para o chío agora e´de 280 caracteres de longo en lugar de 140. " -"Significa podes facer chíos máis longos. ([#172](https://github.com/" -"manuelcortez/TWBlue/issues/172))" +"* The Tweet limit is now 280 characters lenght instead 140. It means you can " +"tweet longer tweets. ([#172](https://github.com/manuelcortez/TWBlue/" +"issues/172))" #: ../doc/changelog.py:67 msgid "" @@ -542,9 +559,9 @@ msgid "" "will not be saved in settings. ([#170](https://github.com/manuelcortez/" "TWBlue/issues/170))" msgstr "" -"* Por petición popular, as caixas de verificación Estado para mencionar a " -"todos e chíos longos non se gardarán nas opcións. ([#170](https://github.com/" -"manuelcortez/TWBlue/issues/170))" +"* Per popular request, Status for mention to all and long tweet checkboxes " +"will not be saved in settings. ([#170](https://github.com/manuelcortez/" +"TWBlue/issues/170))" #: ../doc/changelog.py:68 msgid "" @@ -552,13 +569,13 @@ msgid "" "in Windows with Serbian language. ([#175](https://github.com/manuelcortez/" "TWBlue/issues/175))" msgstr "" -"* Arranxado un problema que facía que o TWBlue non poidese comezar se se " -"estaba a executar en Windows coa lingua Servia. ([#175](https://github.com/" -"manuelcortez/TWBlue/issues/175))" +"* Fixed a problem that was making TWBlue unable to start if it was being ran " +"in Windows with Serbian language. ([#175](https://github.com/manuelcortez/" +"TWBlue/issues/175))" #: ../doc/changelog.py:69 msgid "* Added Danish translation." -msgstr "* Engadida a tradución ao danés." +msgstr "* Added Danish translation." #: ../doc/changelog.py:70 msgid "" @@ -569,52 +586,47 @@ msgid "" "TWBlue/issues/174) [#176,](https://github.com/manuelcortez/TWBlue/" "issues/176))" msgstr "" -"* E máis. ([#156,](https://github.com/manuelcortez/TWBlue/issues/156) [#163,]" -"(https://github.com/manuelcortez/TWBlue/issues/163) [#159,](https://github." -"com/manuelcortez/TWBlue/issues/159) [#173,](https://github.com/manuelcortez/" -"TWBlue/issues/173) [#174,]* And more. ([#156,](https://github.com/" -"manuelcortez/TWBlue/issues/156) [#163,](https://github.com/manuelcortez/" -"TWBlue/issues/163) [#159,](https://github.com/manuelcortez/TWBlue/" -"issues/159) [#173,](https://github.com/manuelcortez/TWBlue/issues/173) " -"[#174,](https://github.com/manuelcortez/TWBlue/issues/174) [#176,](https://" -"github.com/manuelcortez/TWBlue/issues/176))" +"* And more. ([#156,](https://github.com/manuelcortez/TWBlue/issues/156) " +"[#163,](https://github.com/manuelcortez/TWBlue/issues/163) [#159,](https://" +"github.com/manuelcortez/TWBlue/issues/159) [#173,](https://github.com/" +"manuelcortez/TWBlue/issues/173) [#174,](https://github.com/manuelcortez/" +"TWBlue/issues/174) [#176,](https://github.com/manuelcortez/TWBlue/" +"issues/176))" #: ../doc/changelog.py:71 msgid "## changes in version 0.91 and 0.92" -msgstr "## Cambios na versión 0.91 e 0.92" +msgstr "## changes in version 0.91 and 0.92" #: ../doc/changelog.py:72 msgid "" "* Fixed incorrect unicode handling when copying tweet to clipboard. ([#150]" "(https://github.com/manuelcortez/TWBlue/issues/150))" msgstr "" -"* Arranxado o manexo incorrecto do unicode ao se copiar chíos ao " -"portapapeis. ([#150](https://github.com/manuelcortez/TWBlue/issues/150))" +"* Fixed incorrect unicode handling when copying tweet to clipboard. ([#150]" +"(https://github.com/manuelcortez/TWBlue/issues/150))" #: ../doc/changelog.py:73 msgid "" "* TWBlue will show an error when trying to open a timeline for a suspended " "user. ([#128](https://github.com/manuelcortez/TWBlue/issues/128))" msgstr "" -"* O TWBlue amosará un erro se se intenta abrir una liña temporal para un " -"usuario suspendido. ([#128](https://github.com/manuelcortez/TWBlue/" -"issues/128))" +"* TWBlue will show an error when trying to open a timeline for a suspended " +"user. ([#128](https://github.com/manuelcortez/TWBlue/issues/128))" #: ../doc/changelog.py:74 msgid "" "* Removed TwUp as service as it no longer exists. ([#112](https://github.com/" "manuelcortez/TWBlue/issues/112))" msgstr "" -"* Eliminouse o servicio de audio TWUp, debido a que xa non existe. ([#112]" -"(https://github.com/manuelcortez/TWBlue/issues/112))" +"* Removed TwUp as service as it no longer exists. ([#112](https://github.com/" +"manuelcortez/TWBlue/issues/112))" #: ../doc/changelog.py:75 msgid "" "* Release audio files after uploading them. ([#130](https://github.com/" "manuelcortez/TWBlue/issues/130))" msgstr "" -"* Arranxado un erro que facía que os arquivos de audio non se liberaran " -"despois de se subir a algún servizo de audio. ([#130](https://github.com/" +"* Release audio files after uploading them. ([#130](https://github.com/" "manuelcortez/TWBlue/issues/130))" #: ../doc/changelog.py:76 @@ -622,17 +634,16 @@ msgid "" "* Now TWBlue will use Yandex's translation services instead microsoft " "translator. ([#132](https://github.com/manuelcortez/TWBlue/issues/132))" msgstr "" -"* Agora o TWBlue usará os servizos de traducción de Yandex en lugar de " -"Microsoft Translator. ([#132](https://github.com/manuelcortez/TWBlue/" -"issues/132))" +"* Now TWBlue will use Yandex's translation services instead microsoft " +"translator. ([#132](https://github.com/manuelcortez/TWBlue/issues/132))" #: ../doc/changelog.py:77 msgid "" "* SndUp users will be able to upload audio in their account by using their " "API Key again. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" msgstr "" -"* Os usuarios con conta de SNDUp poderán subir audios usando a súa clave de " -"API de novo. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" +"* SndUp users will be able to upload audio in their account by using their " +"API Key again. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" #: ../doc/changelog.py:78 msgid "" @@ -640,7 +651,7 @@ msgid "" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" "manuelcortez/TWBlue/issues/133))" msgstr "" -"* Xa non se engadirán tuits vellos coma se foran recentes. ([#116,](https://" +"* old tweets shouldn't be added as new items in buffers. ([#116,](https://" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" "manuelcortez/TWBlue/issues/133))" @@ -650,9 +661,9 @@ msgid "" "tweets. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#135]" "(https://github.com/manuelcortez/TWBlue/issues/135))" msgstr "" -"* Todos os usuarios mencionados deberán amosarse correctamente en tuits " -"feitos mediante Twishort. ([#116,](https://github.com/manuelcortez/TWBlue/" -"issues/116)) ([#135](https://github.com/manuelcortez/TWBlue/issues/135))" +"* All mentionned users should be displayed correctly in Twishort's long " +"tweets. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#135]" +"(https://github.com/manuelcortez/TWBlue/issues/135))" #: ../doc/changelog.py:80 msgid "" @@ -662,12 +673,11 @@ msgid "" "or non-english symbols. ([#107](https://github.com/manuelcortez/TWBlue/" "issues/107))" msgstr "" -"* É posible selecionar unha lingua para a función de OCR en imaxes, dende a " -"pestana extras, no diálogo de opcións da conta. Tamén podes, nembargantes, " -"estabrecer a opción en detectar automáticamente. A característica de OCR en " -"imaxes funcionará mellor en linguas que usen caracteres especiais ou " -"símbolos que non forman parte do alfabeto inglés. ([#107](https://github.com/" -"manuelcortez/TWBlue/issues/107))" +"* It is possible to select a language for OCR service from the extras panel, " +"in the account settings dialogue. You can, however, set this to detect " +"automatically. OCR should work better in languages with special characters " +"or non-english symbols. ([#107](https://github.com/manuelcortez/TWBlue/" +"issues/107))" #: ../doc/changelog.py:81 msgid "" @@ -675,26 +685,26 @@ msgid "" "normally in this update. [#100](https://github.com/manuelcortez/twblue/" "issues/100)" msgstr "" -"* Arranxado un problema entre JAWS for Windows e o TWBlue. Agora o TWBlue " -"debería funcionar de xeito correcto con este lector de pantalla. [#100]" -"(https://github.com/manuelcortez/twblue/issues/100)" +"* Fixed a problem with JAWS for Windows and TWBlue. Now JAWS will work " +"normally in this update. [#100](https://github.com/manuelcortez/twblue/" +"issues/100)" #: ../doc/changelog.py:82 msgid "* And more ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" -msgstr "* E máis ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" +msgstr "" +"* And more ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" #: ../doc/changelog.py:83 msgid "## Changes in version 0.90" -msgstr "## Cambios na versión 0.90" +msgstr "## Changes in version 0.90" #: ../doc/changelog.py:84 msgid "" "* Fixed a bug in long tweet parsing that was making TWBlue to disconnect the " "streaming API. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" msgstr "" -"* Arranxado un problema na Streaming API que causaba que o TWBlue " -"desconectara o Streaming. ([#103](https://github.com/manuelcortez/TWBlue/" -"issues/103))" +"* Fixed a bug in long tweet parsing that was making TWBlue to disconnect the " +"streaming API. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" #: ../doc/changelog.py:85 msgid "" @@ -702,10 +712,9 @@ msgid "" "detecting images but couldn't apply OCR on them. ([#105](https://github.com/" "manuelcortez/TWBlue/issues/105))" msgstr "" -"* Agora o OCR en imaxes funcionará nos Rechíos tamén. Esto soluciona un erro " -"que causaba que as imaxes se detectaran nos rechíos, pero non se poidera " -"aplicar o OCR nelas. ([#105](https://github.com/manuelcortez/TWBlue/" -"issues/105))" +"* Now OCR will work in images from retweets. It fixes a bug where TWBlue was " +"detecting images but couldn't apply OCR on them. ([#105](https://github.com/" +"manuelcortez/TWBlue/issues/105))" #: ../doc/changelog.py:86 msgid "" @@ -714,11 +723,10 @@ msgid "" "site, TWBlue was trying to load the tweet and it was causing problems in all " "the client. ([#113](https://github.com/manuelcortez/TWBlue/issues/113))" msgstr "" -"* Agora o TWBlue xa non intentará cargar chíos feitos co Twishort que xa " -"foron borrados. Antes, se alguén creaba un chío para despois borralo, dende " -"Twishort, o TWBlue de todos modos tentaba cargar o chío, causando problemas " -"en todo o cliente. ([#113](https://github.com/manuelcortez/TWBlue/" -"issues/113))" +"* TWBlue won't try to load tweets already deleted, made with Twishort. " +"Before, if someone posted a long tweet but deleted it in the Twishort's " +"site, TWBlue was trying to load the tweet and it was causing problems in all " +"the client. ([#113](https://github.com/manuelcortez/TWBlue/issues/113))" #: ../doc/changelog.py:87 msgid "" @@ -727,8 +735,8 @@ msgid "" "manuelcortez/TWBlue/issues/114) [#115](https://github.com/manuelcortez/" "TWBlue/issues/115))" msgstr "" -"* O TWBlue amosa unha mensaxe de erro se se tenta ver o perfil dunha conta " -"que non existe ou que foi suspendida. ([#114,](https://github.com/" +"* TWBlue shows an error message when you try to view the profile of an user " +"that does not exist or has been suspended. ([#114,](https://github.com/" "manuelcortez/TWBlue/issues/114) [#115](https://github.com/manuelcortez/" "TWBlue/issues/115))" @@ -737,24 +745,23 @@ msgid "" "* The spellchecker module should select the right language when is set to " "\"user default\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" msgstr "" -"* O módulo de correción ortográfica debería selecionar a lingua apropriada " -"cando a lingua do cliente se establece en \"Lingua predeterminada\". ([#117]" -"(https://github.com/manuelcortez/TWBlue/issues/117))" +"* The spellchecker module should select the right language when is set to " +"\"user default\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" #: ../doc/changelog.py:89 msgid "" "* Image description will be displayed in retweets too. ([#119](https://" "github.com/manuelcortez/TWBlue/issues/119))" msgstr "" -"* A descripción de imaxes amosarase tamén en rechíos. ([#119](https://github." -"com/manuelcortez/TWBlue/issues/119))" +"* Image description will be displayed in retweets too. ([#119](https://" +"github.com/manuelcortez/TWBlue/issues/119))" #: ../doc/changelog.py:90 msgid "" "* When reading a long tweet, you shouldn't read strange entities anymore. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" msgstr "" -"* cando se lea un chío longo, non deberían aparecer símbolos extranos. " +"* When reading a long tweet, you shouldn't read strange entities anymore. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" #: ../doc/changelog.py:91 @@ -762,29 +769,26 @@ msgid "" "* TWBlue will not try to load timelines if the user is blocking you. ([#125]" "(https://github.com/manuelcortez/twblue/issues/125))" msgstr "" -"* O TWBlue non tentará cargar liñas temporais de usuarios que bloquearon á " -"conta actual. ([#125](https://github.com/manuelcortez/twblue/issues/125))" +"* TWBlue will not try to load timelines if the user is blocking you. ([#125]" +"(https://github.com/manuelcortez/twblue/issues/125))" #: ../doc/changelog.py:92 msgid "## Changes in version 0.88 and 0.89" -msgstr "## Cambios na versión 0.88 e 0.89" +msgstr "## Changes in version 0.88 and 0.89" #: ../doc/changelog.py:93 msgid "* Fixed more issues with streams and reconnections." -msgstr "* Correxidos máis problemas cos streams e ca reconexión." +msgstr "* Fixed more issues with streams and reconnections." #: ../doc/changelog.py:94 msgid "* newer updates will indicate the release date in the updater." -msgstr "" -"* As actualizacións máis novas indicarán a data do lanzamento no módulo de " -"actualización." +msgstr "* newer updates will indicate the release date in the updater." #: ../doc/changelog.py:95 msgid "" "* Changes to keystrokes are reflected in keystroke editor automatically." msgstr "" -"* Os cambios nas combinacións de teclado refrictiranse automáticamente no " -"editor de combinacións de teclado." +"* Changes to keystrokes are reflected in keystroke editor automatically." #: ../doc/changelog.py:96 msgid "" @@ -792,25 +796,25 @@ msgid "" "unchecked, you will see a checkbox per user so you will be able to control " "who will be mentioned in the reply." msgstr "" -"* nas respostas onde hai varios usuarios, se a Caixa mencionar a todos non " -"está marcada, verás unha caixa para cada usuario, o que che permitirá " -"selecionar aos usuarios que serán mencionados na resposta." +"* In replies with multiple users, if the mention to all checkbox is " +"unchecked, you will see a checkbox per user so you will be able to control " +"who will be mentioned in the reply." #: ../doc/changelog.py:97 msgid "" "* Fixed a bug that caused duplicated user mentions in replies when the tweet " "was made with Twishort." msgstr "" -"* Correxido un erro que causaba que o TWBlue amosara mencións duplicadas se " -"o chío se enviara mediante Twishort." +"* Fixed a bug that caused duplicated user mentions in replies when the tweet " +"was made with Twishort." #: ../doc/changelog.py:98 msgid "" "* Retweets should be displayed normally again when the originating tweet is " "a Twishort's long tweet." msgstr "" -"* Os Rechíos deben amosarse correctamente se o chío orixinal fhabía se " -"enviara mediante Twishort." +"* Retweets should be displayed normally again when the originating tweet is " +"a Twishort's long tweet." #: ../doc/changelog.py:99 msgid "" @@ -819,19 +823,18 @@ msgid "" "TWBlue still will create his/her timeline. This was not possible by using " "usernames." msgstr "" -"* Cambiada a maneira na que TWBlue garda as liñas temporais na " -"configuración. Agora úsanse identificadores de usuario en lugar de nomes de " -"usuario. Usando os identificadores para cada usuario, se alguén cambia o seu " -"nome de usuario TWBlue aínda será capaz de crear a liña temporal. Esto non " -"era posible anteriormente." +"* Changed the way TWBlue saves user timelines in configuration. Now it uses " +"user IDS instead usernames. With user IDS, if an user changes the username, " +"TWBlue still will create his/her timeline. This was not possible by using " +"usernames." #: ../doc/changelog.py:100 msgid "" "* Added a new setting in the account settings dialogue that makes TWBlue to " "show twitter usernames instead the full name." msgstr "" -"* engadida unha opción no diálogo de opcións de conta que fai que o TWBlue " -"amose o nome de pantalla do usuario en lugar do nome completo." +"* Added a new setting in the account settings dialogue that makes TWBlue to " +"show twitter usernames instead the full name." #: ../doc/changelog.py:101 msgid "" @@ -839,111 +842,108 @@ msgid "" "allows you to extract and display text in images. Also the keystroke alt+Win" "+o has been added for the same purpose from the invisible interface." msgstr "" -"* Engadido o OCR nas imaxes de Twitter. Hai unha nova opción no menú chío " -"que permite extraer o texto á imaxen do tuit selecionado. Tamén se engadiu a " -"combinación Alt+Windows+O para o mesmo propósito na interfaz invisible." +"* Added OCR in twitter pictures. There is a new item in the tweet menu that " +"allows you to extract and display text in images. Also the keystroke alt+Win" +"+o has been added for the same purpose from the invisible interface." #: ../doc/changelog.py:102 msgid "* Now TWBlue will play a sound when the focused tweet contains images." msgstr "" -"* Agora o TWBlue reproducirá un son cando o chío selecionado conteña imaxes" +"* Now TWBlue will play a sound when the focused tweet contains images." #: ../doc/changelog.py:103 msgid "" "* Your own quoted tweets will not appear in the mentions buffer anymore." -msgstr "* Os teus chíos citados deixarán de amosarse no búfer de mencións." +msgstr "" +"* Your own quoted tweets will not appear in the mentions buffer anymore." #: ../doc/changelog.py:104 msgid "" "* The config file is saved in a different way, it should fix the bug where " "TWBlue needs to be restarted after the config folder is deleted." msgstr "" -"* O ficheiro de configuración gárdase de un xeito diferente. Esto debería " -"solucionar o erro que requería borrar o directorio de configuracións e " -"reiniciar o TWBlue." +"* The config file is saved in a different way, it should fix the bug where " +"TWBlue needs to be restarted after the config folder is deleted." #: ../doc/changelog.py:105 msgid "* Mentioning people from friends or followers buffers works again." -msgstr "" -"* funciona de novo mencionar usuarios dende os búferes de seguidores e " -"amigos." +msgstr "* Mentioning people from friends or followers buffers works again." #: ../doc/changelog.py:106 msgid "" "* Support for proxy servers has been improved. Now TWBlue supports http, " "https, socks4 and socks5 proxies, with and without autentication." msgstr "" -"* Mellorouse o soporte para servidores proxy. Agora o TWBlue soporta proxys " -"http, https, socks4 e socks5, con ou sen autenticación." +"* Support for proxy servers has been improved. Now TWBlue supports http, " +"https, socks4 and socks5 proxies, with and without autentication." #: ../doc/changelog.py:107 msgid "## Changes in version 0.87" -msgstr "## Cambios na versión 0.87" +msgstr "## Changes in version 0.87" #: ../doc/changelog.py:108 msgid "* Fixed stream connection errors." -msgstr "* Correxidos erros na conexión dos streams." +msgstr "* Fixed stream connection errors." #: ../doc/changelog.py:109 msgid "" "* Now TWBlue can handle properly a reply to the sender without including all " "other mentioned users." msgstr "" -"* Agora o TWBlue pode manexar correctamente as respostas sen incluir a todos " -"os usuarios do chío orixinal." +"* Now TWBlue can handle properly a reply to the sender without including all " +"other mentioned users." #: ../doc/changelog.py:110 msgid "* Updated translations." -msgstr "* Actualizáronse as traduccións." +msgstr "* Updated translations." #: ../doc/changelog.py:111 msgid "" "* The status of the mention to all checkbox will be remembered the next time " "you reply to multiple users." msgstr "" -"* O estado da caixa para mencionar a todos lembrarase a seguinte vez que " -"escrebas unha resposta." +"* The status of the mention to all checkbox will be remembered the next time " +"you reply to multiple users." #: ../doc/changelog.py:112 msgid "## Changes in version 0.86" -msgstr "## Cambios na versión 0.86" +msgstr "## Changes in version 0.86" #: ../doc/changelog.py:113 msgid "" "* Fixed a very important security issue. Now TWBlue will send tweets to " "twishort without using any other server." msgstr "" -"* Correxido un erro de seguridade moi importante. Agora o TWBlue enviará " -"chíos cara Twishort sen usar un servidor intermedio." +"* Fixed a very important security issue. Now TWBlue will send tweets to " +"twishort without using any other server." #: ../doc/changelog.py:114 msgid "" "* When you add a comment to a tweet, it will be sent as a quoted tweet, even " "if your reply plus the original tweet is not exceeding 140 characters." msgstr "" -"* Cando se engada un comentario a un chío, este enviarase coma un chío " -"citado, incluso se o comentario máis o chío orixinal non supera os 140 " -"caracteres." +"* When you add a comment to a tweet, it will be sent as a quoted tweet, even " +"if your reply plus the original tweet is not exceeding 140 characters." #: ../doc/changelog.py:115 msgid "" "* Updated windows 10 keymap for reflecting changes made in the last windows " "10 build." msgstr "" -"* Actualizado o mapa de teclado de Windows 10 debido aos cambios da última " -"build." +"* Updated windows 10 keymap for reflecting changes made in the last windows " +"10 build." #: ../doc/changelog.py:116 msgid "* Added last changes in the twitter API." -msgstr "* Engadidos os últimos cambios na API do Twitter." +msgstr "* Added last changes in the twitter API." #: ../doc/changelog.py:117 msgid "" "* When replying, it will not show the twitter username in the text box. When " "you send the tweet, the username will be added automatically." msgstr "" -"* Cando se resposte a un chío, non se amosará o nome do usuario no campo de " -"texto. O nome de usuario será engadido de forma automática ao enviar o chío." +"* When replying, it will not show the twitter username in the text box. When " +"you send the tweet, the username will be added automatically." #: ../doc/changelog.py:118 msgid "" @@ -951,132 +951,125 @@ msgid "" "for mentioning all people. If this is checked, twitter usernames will be " "added automatically when you send your reply." msgstr "" -"* Cando se resposte a un chío con varios usuarios, verás unha caixa en lugar " -"dun botón para mencionar a todos. Se é marcada, os nomes de usuario do " -"Twitter engadiranse automáticamente ao enviar o chío." +"* When replying to multiple users, you'll have a checkbox instead a button " +"for mentioning all people. If this is checked, twitter usernames will be " +"added automatically when you send your reply." #: ../doc/changelog.py:119 msgid "## Changes in version 0.85" -msgstr "## Cambios na versión 0.85" +msgstr "## Changes in version 0.85" #: ../doc/changelog.py:120 msgid "* Long and quoted tweets should be displayed properly In lists." -msgstr "" -"* Os chíos longos e citados deberían amosarse correctamente nas listas." +msgstr "* Long and quoted tweets should be displayed properly In lists." #: ../doc/changelog.py:121 msgid "* The connection should be more stable." -msgstr "* A conexión debería ser máis estable." +msgstr "* The connection should be more stable." #: ../doc/changelog.py:122 msgid "* Added an autostart option in the global settings dialogue." -msgstr "" -"* Engadiuse a opción para comezar despois de iniciar sesión en Windows no " -"diálogo de opcións globais." +msgstr "* Added an autostart option in the global settings dialogue." #: ../doc/changelog.py:123 msgid "* Updated translation." -msgstr "* Actualizadas as traduccións." +msgstr "* Updated translation." #: ../doc/changelog.py:124 msgid "* Updated russian documentation." -msgstr "* Actualizada a documentación en ruso." +msgstr "* Updated russian documentation." #: ../doc/changelog.py:125 msgid "* Tweets in cached database should be loaded properly." -msgstr "* Deberíanse cargar correctamente os chíos na base de datos." +msgstr "* Tweets in cached database should be loaded properly." #: ../doc/changelog.py:126 msgid "* Added some missed dictionaries for spelling correction." -msgstr "" -"* Engadíronse algúns diccionarios novos no módulo de corrección ortográfica." +msgstr "* Added some missed dictionaries for spelling correction." #: ../doc/changelog.py:127 msgid "" "* Timelines, lists and other buffer should be created in the right order at " "startup." msgstr "" -"* As liñas temporais, as listas e outros búferes deberíanse crear na orden " -"correcta ao iniciar o TWBlue." +"* Timelines, lists and other buffer should be created in the right order at " +"startup." #: ../doc/changelog.py:128 msgid "## Changes in version 0.84 " -msgstr "## Cambios na versión 0.84 " +msgstr "## Changes in version 0.84 " #: ../doc/changelog.py:129 msgid "* More improvements in quoted and long tweets." -msgstr "* Máis melloras nos chíos longos e citados." +msgstr "* More improvements in quoted and long tweets." #: ../doc/changelog.py:130 msgid "" "* Updated translations: Russian, Italian, French, Romanian, Galician and " "Finnish." msgstr "" -"* Actualizadas as traducións: Ruso, italiano, francés, rumano, galego e " -"finlandés." +"* Updated translations: Russian, Italian, French, Romanian, Galician and " +"Finnish." #: ../doc/changelog.py:131 msgid "" "* Improvements in the audio uploader module: Now it can handle audio with " "non-english characters." msgstr "" -"* Melloras no módulo de carga de ficheiros de audio: Agora é capaz de " -"manexar ficheiros de audio con caracteres especiais." +"* Improvements in the audio uploader module: Now it can handle audio with " +"non-english characters." #: ../doc/changelog.py:132 msgid "" "* the title of the window should be updated properly when spellcheck, " "translate or shorten/unshorten URL buttons are pressed." msgstr "" -"* O título da ventá debería actualizarse correctamente cando se utilizan " -"funcións coma corrección ortográfica, traducción ou acurtar / expandir URL." +"* the title of the window should be updated properly when spellcheck, " +"translate or shorten/unshorten URL buttons are pressed." #: ../doc/changelog.py:133 msgid "" "* the bug that changes the selected tweet in the home timeline shouldn't be " "happening so often." msgstr "" -"* O erro que facía que o chío selecionado cambiara na interfaz visible " -"debería estar parcialmente correxido." +"* the bug that changes the selected tweet in the home timeline shouldn't be " +"happening so often." #: ../doc/changelog.py:134 msgid "## Changes in version 0.82 and 0.83" -msgstr "## Cambios na versión 0.82 e 0.83" +msgstr "## Changes in version 0.82 and 0.83" #: ../doc/changelog.py:135 msgid "" "* If the tweet source (client) is an application with unicode characters " "(example: российская газета) it will not break the tweet displayer." msgstr "" -"* Se a fonte do chío (cliente) é una aplicación con caracteres unicode " -"(exempro: " -"\\321\\200\\320\\276\\321\\201\\321\\201\\320\\270\\320\\271\\321\\201\\320\\272\\320\\260\\321\\217 " -"\\320\\263\\320\\260\\320\\267\\320\\265\\321\\202\\320\\260) non se romperá " -"o visualizador do chío." +"* If the tweet source (client) is an application with unicode characters " +"(example: российская газета) it will not break the tweet displayer." #: ../doc/changelog.py:136 msgid "" "* Added a new field for image description in tweet displayer. When " "available, it will show description for images posted in tweets." msgstr "" -"* Engadido un campo para descripción de imaxes no visualizador de chíos, " -"Cando estean dispoñibles, amosaránse descripcións para as imaxes no chío." +"* Added a new field for image description in tweet displayer. When " +"available, it will show description for images posted in tweets." #: ../doc/changelog.py:137 msgid "" "* users can add image descriptions to their photos. When uploading an image, " "a dialog will show for asking a description." msgstr "" -"* Os usuarios agora poden engadir descripción ás súas fotos. Ao subir a " -"imaxen, aparecerá un diálogo para que se proporcione unha descripción." +"* users can add image descriptions to their photos. When uploading an image, " +"a dialog will show for asking a description." #: ../doc/changelog.py:138 msgid "* Redesigned upload image dialog." -msgstr "* Rediseñouse o diálogo para subir imaxes." +msgstr "* Redesigned upload image dialog." #: ../doc/changelog.py:139 msgid "* Fixed photo uploads when posting tweets." -msgstr "* Correxiuse a carga das imaxes ao se publicar chíos." +msgstr "* Fixed photo uploads when posting tweets." #: ../doc/changelog.py:140 msgid "" @@ -1084,74 +1077,70 @@ msgid "" "errors, now TWBlue will try to get as much tweets as possible, even if some " "of these are no longer available." msgstr "" -"* cando se obteñen chíos para amosar unha conversa, agora ignóranse os chíos " -"borrados e algúns erros comúns. TWBlue cargará a maior cantidade de chíos " -"posible." +"* When getting tweets for a conversation, ignores deleted tweets or some " +"errors, now TWBlue will try to get as much tweets as possible, even if some " +"of these are no longer available." #: ../doc/changelog.py:141 msgid "* Added audio playback from soundcloud." -msgstr "* Engadida a reprodución de audio dende Soundcloud." +msgstr "* Added audio playback from soundcloud." #: ../doc/changelog.py:142 msgid "* Now the session mute option don't makes the screen reader speaks." -msgstr "" -"* Ao se silenciar unha sesión, agora o lector de pantalla xa non anunciará " -"ningún contido automáticamente." +msgstr "* Now the session mute option don't makes the screen reader speaks." #: ../doc/changelog.py:143 msgid "* Fixed the direct message dialog. Now it should be displayed properly." msgstr "" -"* Correxido o diálogo de mensaxe directa. Agora debería amosarse " -"correctamente." +"* Fixed the direct message dialog. Now it should be displayed properly." #: ../doc/changelog.py:144 msgid "" "* when a tweet is deleted in twitter, TWBlue should reflect this change and " "delete that tweet in every buffer it is displayed." msgstr "" -"* Cando se borra un chío, o TWBlue debería amosar o cambio e borrar o chío " -"de todos os búferes onde se amosa." +"* when a tweet is deleted in twitter, TWBlue should reflect this change and " +"delete that tweet in every buffer it is displayed." #: ../doc/changelog.py:145 msgid "" "* If your session is broken, TWBlue will be able to remove it automatically " "instead just crashing." msgstr "" -"* Se a configuración dunha sesión foi dañada, o TWBlue debería ser capaz de " -"borrala e de continuar en lugar de non se abrir." +"* If your session is broken, TWBlue will be able to remove it automatically " +"instead just crashing." #: ../doc/changelog.py:146 msgid "* audio uploader should display the current progress." -msgstr "" -"* O diálogo de carga de ficheiros de audio agora amosa o progreso actual." +msgstr "* audio uploader should display the current progress." #: ../doc/changelog.py:147 msgid "" "* users can disable the check for updates feature at startup from the " "general tab, in the global settings dialogue." msgstr "" -"* Os usuarios poden desactivar a comprobación automática de actualizacións " -"no diálogo de opcións globais, na pestana Xeral." +"* users can disable the check for updates feature at startup from the " +"general tab, in the global settings dialogue." #: ../doc/changelog.py:148 msgid "" "* The invisible interface and the window should be synchronized when the " "client reconnects." msgstr "" -"* A interfaz invisible e a ventá gráfica deben estar sincronizadas cando o " -"cliente se reconecta." +"* The invisible interface and the window should be synchronized when the " +"client reconnects." #: ../doc/changelog.py:149 msgid "* The documentation option in the systray icon should be enabled." -msgstr "* A opción de documentación na bandexa do sistema atópase activa." +msgstr "* The documentation option in the systray icon should be enabled." #: ../doc/changelog.py:150 msgid "" "* In trending buffers, you can press enter for posting a tweet about the " "focused trend." msgstr "" -"* Nos búferes de tendencias, podes premer intro sobre cada tendencia para " -"publicar un chío acerca dela." +"* In trending buffers, you can press enter for posting a tweet about the " +"focused trend." #: ../doc/changelog.py:151 msgid "" @@ -1159,23 +1148,21 @@ msgid "" "Natalia Hedlund (Наталья Хедлунд), [@lifestar_n](https://twitter.com/" "lifestar_n) in twitter)" msgstr "" -"* Actualizada a documentación e a interfaz principal do programa ao ruso " -"(Grazas a Natalia Hedlund " -"(\\320\\235\\320\\260\\321\\202\\320\\260\\320\\273\\321\\214\\321\\217 " -"\\320\\245\\320\\265\\320\\264\\320\\273\\321\\203\\320\\275\\320\\264), " -"[@lifestar_n](https://twitter.com/lifestar_n) in twitter)" +"* Updated russian documentation and main program interface (thanks to " +"Natalia Hedlund (Наталья Хедлунд), [@lifestar_n](https://twitter.com/" +"lifestar_n) in twitter)" #: ../doc/changelog.py:152 msgid "* updated translations." -msgstr "* Actualizadas as traduccións." +msgstr "* updated translations." #: ../doc/changelog.py:153 msgid "## Changes in Version 0.81" -msgstr "## Cambios na Versión 0.81" +msgstr "## Changes in Version 0.81" #: ../doc/changelog.py:154 msgid "* Updated translations" -msgstr "* Actualizadas as traducións." +msgstr "* Updated translations" #: ../doc/changelog.py:155 msgid "" @@ -1184,59 +1171,57 @@ msgid "" "moment. If something is wrong and both locations don't work, the program " "will start anyway." msgstr "" -"* O módulo de actualizacións recibiu algunhas melloras. Agora inclúe unha " -"URL con información de actualizacións de copia de seguridade por se o " -"enderezo principal non funciona." +"* The updater module has received some improvements. Now it includes a " +"Mirror URL for checking updates if the main URL is not available at the " +"moment. If something is wrong and both locations don't work, the program " +"will start anyway." #: ../doc/changelog.py:156 msgid "* some GUI elements now use keyboard shortcuts for common actions." -msgstr "" -"* Algúns elementos da interfaz gráfica agora usan atallos de teclado para " -"accións comúns." +msgstr "* some GUI elements now use keyboard shortcuts for common actions." #: ../doc/changelog.py:157 msgid "* fixed a bug in the geolocation dialog." -msgstr "" -"* Correxido un erro no diálogo para amosar a información xeográfica en chíos." +msgstr "* fixed a bug in the geolocation dialog." #: ../doc/changelog.py:158 msgid "* the chicken nugget keymap should work properly." -msgstr "* O mapa de teclado de chicken Nugget debería funcionar correctamente." +msgstr "* the chicken nugget keymap should work properly." #: ../doc/changelog.py:159 msgid "" "* Added a new soundpack to the default installation of TWBlue, thanks to " "[@Deng90](https://twitter.com/deng90)" msgstr "" -"* Engadiuse un novo paquete de sons á instalación predeterminada do TWBlue, " -"gracias a [@Deng90](https://twitter.com/deng90)" +"* Added a new soundpack to the default installation of TWBlue, thanks to " +"[@Deng90](https://twitter.com/deng90)" #: ../doc/changelog.py:160 msgid "* Now the changelog is written in an html File." -msgstr "* Agora o changelog escrébese nun Ficheiro html." +msgstr "* Now the changelog is written in an html File." #: ../doc/changelog.py:161 msgid "" "* Added some missed dictionaries in last version for the spell checking " "feature." msgstr "" -"* Engadíronse algúns dicionarios ao módulo de corrección ortográfica que non " -"foran engadidos na última versión. " +"* Added some missed dictionaries in last version for the spell checking " +"feature." #: ../doc/changelog.py:162 msgid "" "* Trimmed the beginnings of the sounds in the default soundpack. Thanks to " "[@masonasons](https://github.com/masonasons)" msgstr "" -"* Borráronse os silenzos ao comezo dos sons no paquete de sons " -"predeterminado. Gracias a [@masonasons](https://github.com/masonasons)" +"* Trimmed the beginnings of the sounds in the default soundpack. Thanks to " +"[@masonasons](https://github.com/masonasons)" #: ../doc/changelog.py:163 msgid "" "* Added Opus support for sound playback in TWBlue. Thanks to [@masonasons]" "(https://github.com/masonasons)" msgstr "" -"* Engadido o soporte ao códec Opus no TWBlue. Gracias a [@masonasons]" +"* Added Opus support for sound playback in TWBlue. Thanks to [@masonasons]" "(https://github.com/masonasons)" #: ../doc/changelog.py:164 @@ -1244,15 +1229,14 @@ msgid "" "* Added a source field in view tweet dialogue. Thanks to [@masonasons]" "(https://github.com/masonasons)" msgstr "" -"* Engadido un campo para amosar o cliente dende o que se fai un chío no " -"visualizador de chíos. Gracias a [@masonasons](https://github.com/masonasons)" +"* Added a source field in view tweet dialogue. Thanks to [@masonasons]" +"(https://github.com/masonasons)" #: ../doc/changelog.py:165 msgid "" "* You can load previous items in followers and friend buffers for others." msgstr "" -"* Podes cargar máis elementos nos búferes de seguedores e amigos de outros " -"usuarios." +"* You can load previous items in followers and friend buffers for others." #: ../doc/changelog.py:166 msgid "" @@ -1260,63 +1244,61 @@ msgid "" "have set \"default language\" in the global settings dialogue if your " "language is supported [#168](http://twblue.es/bugs/view.php?id=168)" msgstr "" -"* O módulo de corrección ortográfica non amosará unha mensaxe de erro ao se " -"establecer \"Lingua predeterminada\" no diálogo de opcións globais se a túa " -"língua se atopa soportada. [#168](http://twblue.es/bugs/view.php?id=168)" +"* The Spell Checker dialogue should not display an error message when you " +"have set \"default language\" in the global settings dialogue if your " +"language is supported [#168](http://twblue.es/bugs/view.php?id=168)" #: ../doc/changelog.py:167 msgid "* Updated romanian translation." -msgstr "* Actualizada a tradución ao romanés." +msgstr "* Updated romanian translation." #: ../doc/changelog.py:168 msgid "* Some code cleanups." -msgstr "* Limpeza do código." +msgstr "* Some code cleanups." #: ../doc/changelog.py:169 msgid "* The bug reports feature is fully operational again." -msgstr "" -"* O sistema de información de erros está completamente operativo de novo." +msgstr "* The bug reports feature is fully operational again." #: ../doc/changelog.py:170 msgid "" "* TWBlue should work again for users that contains special characters in " "windows usernames." msgstr "" -"* O TWBlue debería funcionar de novo para usuarios que conteñan caracteres " -"especiais nos seus nomes de usuario do Windows." +"* TWBlue should work again for users that contains special characters in " +"windows usernames." #: ../doc/changelog.py:171 msgid "* Added more options for the tweet searches." -msgstr "* Engadidas máis opcións para as procuras no Twitter." +msgstr "* Added more options for the tweet searches." #: ../doc/changelog.py:172 msgid "* Added play_audio to the keymap editor." -msgstr "* Engadida a función play_audio ao editor de mapas de teclado." +msgstr "* Added play_audio to the keymap editor." #: ../doc/changelog.py:173 msgid "* Windows key is no longer required in the keymap editor" -msgstr "* A tecla Windows xa non é obrigatoria no editor de mapas de teclado." +msgstr "* Windows key is no longer required in the keymap editor" #: ../doc/changelog.py:174 msgid "* Switched to the Microsoft translator." -msgstr "* Cambiamos a usar o servicio Microsoft translator." +msgstr "* Switched to the Microsoft translator." #: ../doc/changelog.py:175 msgid "" "* You can update the current buffer by pressing ctrl+win+shift+u in the " "default keymap or in the buffer menu." msgstr "" -"* Podes actualizar o búfer actual premendo ctrl+win+shift+u na interfaz " -"invisible ou dende o menú búfer." +"* You can update the current buffer by pressing ctrl+win+shift+u in the " +"default keymap or in the buffer menu." #: ../doc/changelog.py:176 msgid "* Changed some keystrokes in the windows 10 default keymap" -msgstr "" -"* Cambiados algúns atallos de teclado no mapa de teclado do Windows 10." +msgstr "* Changed some keystrokes in the windows 10 default keymap" #: ../doc/changelog.py:177 msgid "* New followers and friends buffer for user timelines." -msgstr "* Novos búferes de amigos e seguedores para outros usuarios." +msgstr "* New followers and friends buffer for user timelines." #: ../doc/changelog.py:178 msgid "---" @@ -1324,20 +1306,4 @@ msgstr "---" #: ../doc/changelog.py:179 msgid "Copyright © 2014-2017, Manuel Cortez." -msgstr "Copyright 2014-2017, Manuel Cortez." - -#~ msgid "" -#~ " * The sent direct messages buffer has been removed. All direct " -#~ "messages will be placed in one buffer only. " -#~ msgstr "" -#~ " * Eliminouse o búfer de mensaxes directas enviadas. Todas as mensaxes " -#~ "directas colócanse nun único búfer. " - -#~ msgid "" -#~ " * When sending a direct message, you will hear a sound if the message " -#~ "has been sent properly, but the direct message will not be added to the " -#~ "buffer inmediately." -#~ msgstr "" -#~ " * Cando se envíe una mensaxe directa, escoitarás un son se a mensaxe " -#~ "se enviou apropriadamente, pero a mensaxe directa non se engadirá ao " -#~ "búfer inmediatamente." +msgstr "Copyright © 2014-2017, Manuel Cortez." diff --git a/doc/locales/sr/lc_messages/twblue-documentation.mo b/doc/locales/sr/lc_messages/twblue-documentation.mo new file mode 100644 index 00000000..9f87c728 Binary files /dev/null and b/doc/locales/sr/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/sr/lc_messages/twblue-documentation.po b/doc/locales/sr/lc_messages/twblue-documentation.po new file mode 100644 index 00000000..af46ec53 --- /dev/null +++ b/doc/locales/sr/lc_messages/twblue-documentation.po @@ -0,0 +1,1885 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2019-03-17 13:34\n" +"PO-Revision-Date: 2021-06-27 01:40+0100\n" +"Last-Translator: Nikola Jović \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 1.6.10\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" +"Language: sr\n" + +#: ../doc/strings.py:3 +msgid "Documentation for TWBlue - 0.88" +msgstr "Dokumentacija za TWBlue - 0.88" + +#: ../doc/strings.py:4 +msgid "## Table of contents" +msgstr "## Sadržaj" + +#: ../doc/strings.py:5 +msgid "[TOC]" +msgstr "[TOC]" + +#: ../doc/strings.py:6 +msgid "## Warning!" +msgstr "## Upozorenje!" + +#: ../doc/strings.py:7 +msgid "" +"You are reading documentation produced for a program still in development. " +"The object of this manual is to explain some details of the operation of the " +"program. Bear in mind that as the software is in the process of active " +"development, parts of this user guide may change in the near future, so it " +"is advisable to keep checking from time to time to avoid missing important " +"information." +msgstr "" +"Čitate dokumentaciju za program koji je još uvek u razvoju. Cilj ove " +"dokumentacije je da objasni neke detalje funkcionisanja i korišćenja " +"programa. Imajte na umu da je program još u aktivnoj fazi razvoja, pa se " +"zato delovi ovog uputstva mogu promeniti u bliskoj budućnosti, pa je s toga " +"preporučljivo da ga s vremena na vreme proveravate kako bi izbegli " +"propuštanje bitnih informacija." + +#: ../doc/strings.py:8 +msgid "" +"If you want to see what has changed from the previous version, [read the " +"list of updates here.](changes.html)" +msgstr "" +"Ako želite da proverite šta se promenilo od prethodne verzije, [ovde " +"pročitajte listu ažuriranja.](changes.html)" + +#: ../doc/strings.py:9 +msgid "## Introduction" +msgstr "## Uvod" + +#: ../doc/strings.py:10 +msgid "" +"TWBlue is an application to make Twitter simple and fast, while using as few " +"resources as possible. With TWBlue, you can do things like the following:" +msgstr "" +"TWBlue je aplikacija koja čini korišćenje Twittera brzim i jednostavnim, a " +"koristi što je manje moguće resursa. Uz TWBlue, možete raditi sledeće:" + +#: ../doc/strings.py:11 +msgid "* Tweet, reply to, retweet and delete tweets," +msgstr "* Twitovanje, odgovaranje na tvitove, retvitovanje i brisanje tvitova," + +#: ../doc/strings.py:12 +msgid "* Like and unlike a tweet," +msgstr "* označavanje tvita kao sviđa mi se / ne sviđa mi se," + +#: ../doc/strings.py:13 +msgid "* Send and delete direct messages," +msgstr "* slanje i primanje direktnih poruka," + +#: ../doc/strings.py:14 +msgid "* See your friends and followers," +msgstr "* Prikazivanje vaših prijatelja i pratilaca," + +#: ../doc/strings.py:15 +msgid "* Follow, unfollow, report and block a user," +msgstr "" +"* Praćenje, prestanak praćenja, prijavljivanje i blokiranje drugih korisnika," + +#: ../doc/strings.py:16 +msgid "* Open a user's timeline to see their tweets separately," +msgstr "" +"* Otvaranje vremenske linije korisnika kako biste gledali njihove tvitove " +"odvojeno," + +#: ../doc/strings.py:17 +msgid "* Open URLs from a tweet or direct message," +msgstr "* Otvaranje adresa iz tvitova ili direktnih poruka," + +#: ../doc/strings.py:18 +msgid "* Play several types of audio files from addresses," +msgstr "* reprodukcija različitih vrsta zvučnih datoteka sa adresa," + +#: ../doc/strings.py:19 +msgid "* And more." +msgstr "* i još toga." + +#: ../doc/strings.py:20 +msgid "## Usage" +msgstr "## Korišćenje" + +#: ../doc/strings.py:21 +msgid "" +"Twitter is a social networking or micro-blogging tool which allows you to " +"compose short status updates of your activities in 280 characters or less. " +"Twitter is a way for friends, family and co-workers to communicate and stay " +"connected through the exchange of quick, frequent messages. You can restrict " +"delivery of updates to those in your circle of friends or, by default, allow " +"anyone to access them." +msgstr "" +"Twitter je društvena mreža ili alat za mikro blog kojja vam dozvoljava da " +"pišete statuse do 280 znakova. Twitter je način za prijatelje, porodicu ili " +"zaposlene da ostanu u komunikaciji kroz brze, česte poruke. Možete " +"ograničiti ažuriranja na one koji su u vašem krugu prijatelja ili, kako je " +"podrazumevano, dozvoliti svima da im pristupe." + +#: ../doc/strings.py:22 +msgid "" +"You can monitor the status of updates from your friends, family or co-" +"workers (known as following), and they in turn can read any updates you " +"create, (known as followers). The updates are referred to as Tweets. The " +"Tweets are posted to your Twitter profile or Blog and are searchable using " +"Twitter Search." +msgstr "" +"Možete pratiti ažuriranja statusa vaših prijatelja, porodice ili kolega (što " +"je poznatije kao praćenje), i oni takođe mogu da čitaju ažuriranja koja vi " +"pišete, (što znači da su oni vaši pratioci). Ova ažuriranja se zovu tvitovi. " +"Tvitovi će biti postavljeni na vaš Twitter profil ili blog i mogu se pronaći " +"u Twitter pretrazi." + +#: ../doc/strings.py:23 +msgid "" +"In order to use TWBlue, you must first have created an account on the " +"Twitter website. The process for signing up for a Twitter account is very " +"accessible. During the account registration, you will need to choose a " +"Twitter username. This serves two purposes. This is the method through which " +"people will comunicate with you, but most importantly, your username and " +"password will be required to connect TWBlue to your Twitter account. We " +"suggest you choose a username which is memorable both to you and the people " +"you hope will follow you." +msgstr "" +"Da biste koristili TWBlue, prvo morate da napravite nalog na Twitter " +"websajtu. Proces pravljenja naloga je veoma pristupačan. U toku registracije " +"naloga, morate da izaberete Twitter korisničko ime. Ovo korisničko ime ima " +"dve svrhe. Ovo je metod koji će ljudi koristiti da bi komunicirali sa vama, " +"ali naj važnije, vaše korisničko ime i lozinka su neophodni da biste " +"povezali TWBlue sa vašim nalogom. Predlažemo vam da odaberete korisničko ime " +"koje se lako pamti, kako za vas tako i za ljude za koje se nadate da će vas " +"pratiti." + +#: ../doc/strings.py:24 +msgid "" +"We'll start from the premise that you have a Twitter account with its " +"corresponding username and password." +msgstr "" +"Počećemo uz pretpostavku da već imate Twitter nalog sa odgovarajućim " +"korisničkim imenom i lozinkom." + +#: ../doc/strings.py:25 +msgid "### Authorising the application" +msgstr "### Autorizacija aplikacije" + +#: ../doc/strings.py:26 +msgid "" +"First of all, it's necessary to authorise the program so it can access your " +"Twitter account and act on your behalf. The authorisation process is quite " +"simple, and the program never retains data such as your password. In order " +"to authorise the application, you just need to run the main executable file, " +"called TWBlue.exe (on some computers it may appear simply as TWBlue if " +"Windows Explorer is not set to display file extensions). We suggest you may " +"like to place a Windows shortcut on your Desktop pointing to this executable " +"file for quick and easy location." +msgstr "" +"Za početak, neophodno je da autorizujete program kako bi mogao da pristupi " +"vašem nalogu i izvršava radnje u vaše ime. Proces autorizacije je " +"jednostavan, i program nikada ne čuva podatke kao što je vaša lozinka. Kako " +"biste autorizovali aplikaciju, morate samo da pokrenete glavnu izvršnu " +"datoteku, koja se zove TWBlue.exe (na nekim računarima možda će se zvati " +"samo TWBlue ako Windows explorer nije podešen da prikazuje ekstenzije " +"datoteka). Predlažemo vam da podesite prečicu na radnoj površini ka ovoj " +"izvršnoj datoteci radi lakšeg pokretanja." + +#: ../doc/strings.py:27 +msgid "" +"You can log into several Twitter accounts simultaneously. The program refers " +"to each Twitter account you have configured as a \"Session\". If this is the " +"first time you have launched TWBlue, and if no Twitter session exists, you " +"will see the Session Manager. This dialogue box allows you to authorise as " +"many accounts as you wish. If you press the Tab key to reach the \"new " +"account\" button and activate it by pressing the Space Bar, a dialogue box " +"will advise you that your default internet browser will be opened in order " +"to authorise the application and you will be asked if you would like to " +"continue. Activate the \"yes\" Button by pressing the letter \"Y\" so the " +"process may start." +msgstr "" +"Možete da se prijavite na više Twitter naloga u isto vreme. Program će zvati " +"svaki nalog koji podesite kao \"sesija\". Ako je ovo prvi put da pokrećete " +"TWBlue, i ako ne postoji nijedna Twitter sesija, videćete dijalog za " +"upravljanje sesijama. Ovaj dijalog će vam dozvoliti da autorizujete onoliko " +"naloga koliko želite. Ako pritisnete tab dugme da pronađete opciju \"Novi " +"nalog\" i aktivirate je tasterom razmak, dijalog će vam reći da će vaš " +"podrazumevani Web pretraživač biti otvoren kako biste autorizovali " +"aplikaciju i bićete upitani da li želite da nastavite. Aktiviranjem opcije " +"\"Da\" slovom \"D\" proces će započeti." + +#: ../doc/strings.py:28 +msgid "" +"Your default browser will open on the Twitter page to request authorisation. " +"Enter your username and password into the appropriate edit fields if you're " +"not already logged in, select the authorise button, and press it." +msgstr "" +"Vaš podrazumevani Web pretraživač će biti otvoren na Twitter stranici kako " +"bi zahtevao autorizaciju. Upišite vaše korisničko ime i lozinku u " +"odgovarajuća polja ako već niste prijavljeni, izaberite dugme autorizuj, i " +"pritisnite ga." + +#: ../doc/strings.py:29 +msgid "" +"Once you've authorised your twitter account, the website will redirect you " +"to a page which will notify you that TWBlue has been authorised " +"successfully. Now you are able to close the page by pressing ALT+F4 which " +"will return you to the Session Manager. On the session list, you will see a " +"new item temporarily called \"Authorised account x\" -where x is a number. " +"The session name will change once you open that session." +msgstr "" +"Nakon što ste autorizovali vaš Twitter nalog, Websajt će vas preusmeriti na " +"stranicu koja će vas obavestiti da je TWBlue uspešno autorizovan. Sada " +"možete da zatvorite ovu stranicu pritiskanjem tastera ALT+F4 što će vas " +"vratiti na upravljanje sesijama. U listi sesija, videćete novu stavku koja " +"se privremeno zove \"Autorizovan nalog x\" -gde će x biti zamenjen brojem. " +"Ime sesije će se promeniti nakon što je otvorite." + +#: ../doc/strings.py:30 +msgid "" +"To start running TWBlue, press the Ok button in the Session Manager " +"dialogue. By default, the program starts all the configured sessions " +"automatically, however, you can change this behavior." +msgstr "" +"Da biste počeli sa korišćenjem aplikacije TWBlue, u dijalogu upravljanja " +"sesijama pritisnite dugme u redu. Podrazumevano, program automatski pokreće " +"sve podešene sesije, ali, ovo se može promeniti." + +#: ../doc/strings.py:31 +msgid "" +"If all went well, the application will start playing sounds, indicating your " +"data is being updated." +msgstr "" +"Ako je sve u redu, aplikacija će početi sa reprodukcijom zvukova, što znači " +"da se vaši podaci ažuriraju." + +#: ../doc/strings.py:32 +msgid "" +"When the process is finished, by default the program will play another " +"sound, and the screen reader will say \"ready\" (this behaviour can be " +"configured)." +msgstr "" +"Kada se proces završi, po podrazumevanim podešavanjima program će " +"reprodukovati još jedan zvuk, i čitač ekrana će izgovoriti\"spreman\" (ovo " +"se može podesiti )." + +#: ../doc/strings.py:33 +msgid "## General concepts" +msgstr "## Opšti koncepti" + +#: ../doc/strings.py:34 +msgid "" +"Before starting to describe TWBlue's usage, we'll explain some concepts that " +"will be used extensively throughout this manual." +msgstr "" +"Pre nego što počnemo da opisujemo opšte korišćenje programa TWBlue, " +"opisaćemo neke opšte koncepte koji će se često koristiti u ovom uputstvu." + +#: ../doc/strings.py:35 +msgid "### Buffer" +msgstr "### Kanal" + +#: ../doc/strings.py:36 +msgid "" +"A buffer is a list of items to manage the data which arrives from Twitter, " +"after being processed by the application. When you configure a new session " +"on TWBlue and start it, many buffers are created. Each of them may contain " +"some of the items which this program works with: Tweets, direct messages, " +"users, trends or events. According to the buffer you are focusing, you will " +"be able to do different actions with these items." +msgstr "" +"Kanal je lista stavki koja upravlja vrstom podataka koji stižu sa Twittera, " +"nakon što ih aplikacija obradi. Kada podesite novu sesiju u programu TWBlue " +"i pokrenete je, neki kanali su već napravljeni. Svaki može da sadrži neke " +"stavke sa kojima program radi: Tvitovi, direktne poruke, korisnici, teme u " +"trendu ili događaji. U zavisnosti od kanala kojeg fokusirate, možete da " +"izvršavate različite radnje na njemu." + +#: ../doc/strings.py:37 +msgid "" +"The following is a description for every one of TWBlue's buffers and the " +"kind of items they work with." +msgstr "Sledi opis za svaki TWBlue kanal i listu stavki sa kojom on radi." + +#: ../doc/strings.py:38 +msgid "" +"* Home: this shows all the tweets on the main timeline. These are the tweets " +"by users you follow." +msgstr "" +"* Početak: Ovaj kanal prikazuje sve tvitove na glavnoj vremenskoj liniji. " +"Ovo su tvitovi od strane korisnika koje pratite." + +#: ../doc/strings.py:39 +msgid "" +"* Mentions: if a user, whether you follow them or not, mentions you on " +"Twitter, you will find it in this list." +msgstr "" +"* Spominjanja: Ako vas korisnik, bez obzira da li ih pratite ili ne, spomene " +"na Twitteru, to ćete pronaći u ovoj listi." + +#: ../doc/strings.py:40 +msgid "" +"* Direct messages: here you will find the private direct messages you " +"exchange with users who follow you , or with any user, if you allow direct " +"messages from everyone (this setting is configurable from Twitter). This " +"list only shows received messages." +msgstr "" +"* Direktne poruke: Ovde ćete pronaći privatne poruke koje razmenjujete sa " +"korisnicima koji vas prate, ili sa bilo kojim korisnikom, ako dozvolite " +"direktne poruke od svih (ovo podešavanje se menja na Twitteru ). Ova lista " +"prikazuje samo primljene poruke." + +#: ../doc/strings.py:41 +msgid "" +"* Sent direct messages: this buffer shows all the direct messages sent from " +"your account." +msgstr "" +"* Poslate direktne poruke: Ovaj kanal prikazuje sve direktne poruke poslate " +"sa vašeg naloga." + +#: ../doc/strings.py:42 +msgid "* Sent tweets: this shows all the tweets sent from your account." +msgstr "" +"* Poslati tvitovi: Ovaj kanal prikazuje sve tvitove poslate sa vašeg naloga." + +#: ../doc/strings.py:43 +msgid "* Likes: here you will see all the tweets you have liked." +msgstr "* Sviđanja: Ovde ćete videti sve tvitove koje ste označili sviđanjem." + +#: ../doc/strings.py:44 +msgid "" +"* Followers: when users follow you, you'll be able to see them on this " +"buffer, with some of their account details." +msgstr "" +"* Pratioci: Kada vas korisnici prate, možete da ih vidite na ovom kanalu, uz " +"neke detalje o njihovim nalozima." + +#: ../doc/strings.py:45 +msgid "" +"* Friends: the same as the previous buffer, but these are the users you " +"follow." +msgstr "" +"* Prijatelji: Isto kao i prethodni kanal, ali ovo su korisnici koje vi " +"pratite." + +#: ../doc/strings.py:46 +msgid "" +"* User timelines: these are buffers you may create. They contain only the " +"tweets by a specific user. They're used so you can see the tweets by a " +"single person and you don't want to look all over your timeline. You may " +"create as many as you like." +msgstr "" +"* Korisničke vremenske linije: Ovo su kanali koje vi možete da napravite. " +"Oni sadrže tvitove samo određenog korisnika. Oni se koriste kako biste mogli " +"da vidite tvitove samo jedne osobe a ne želite da ih tražite po celoj " +"vremenskoj liniji. Možete da napravite ovakvih kanala onoliko koliko želite." + +#: ../doc/strings.py:47 +msgid "" +"* Events: An event is anything that happens on Twitter, such as when someone " +"follows you, when someone adds or removes one of your tweets from their " +"likes list, or when you subscribe to a list. There are many more, but the " +"program shows the most common ones in the events buffer so that you can " +"easily keep track of what is happening on your account." +msgstr "" +"* Događaji: Događaj je sve ono što se dogodi na Twitteru, na primer kada vas " +"neko prati, kada neko doda ili ukloni vaš tvit sa liste sviđanja, ili kada " +"se prijavite na listu. Ima ih još puno, ali program prikazuje najčešće u " +"ovom kanalu kako biste mogli da pratite šta se dešava na vašem nalogu." + +#: ../doc/strings.py:48 +msgid "" +"* Lists: A list is similar to a user timeline, except that you can configure " +"it to contain tweets from multiple users." +msgstr "" +"* Liste: Lista je slična korisničkoj vremenskoj liniji, osim što možete da " +"je podesite tako da sadrži tvitove više različitih korisnika." + +#: ../doc/strings.py:49 +msgid "* Search: A search buffer contains the results of a search operation." +msgstr "* Pretraga: Kanal pretrage sadrži rezultate izvršene pretrage." + +#: ../doc/strings.py:50 +msgid "" +"* User likes: You can have the program create a buffer containing tweets " +"liked by a particular user." +msgstr "" +"* Korisnička sviđanja: Možete da napravite kanal koji sadrži samo tvitove " +"koji se sviđaju određenom korisniku." + +#: ../doc/strings.py:51 +msgid "" +"* Trending Topics: a trend buffer shows the top ten most used terms in a " +"geographical region. This region may be a country or a city. Trends are " +"updated every five minutes." +msgstr "" +"* Teme u trendu: Kanal tema u trendu sadrži listu 10 termina koji se " +"najčešće koriste u određenoj geografskoj regiji. Ova regija može biti država " +"ili grad. Teme u trendu se ažuriraju na 5 minuta." + +#: ../doc/strings.py:52 +msgid "" +"If a tweet contains a URL, you can press enter in the GUI or Control + " +"Windows + Enter in the invisible interface to open it. If it contains audio, " +"you can press Control + Enter or Control + Windows + Alt + Enter to play it, " +"respectively. TWBlue will play a sound if the tweet contains the \\#audio " +"hashtag, but there may be tweets which contain audio without this. Finally, " +"if a tweet contains geographical information, you can press Control + " +"Windows + G in the invisible interface to retrieve it." +msgstr "" +"Ako tvit sadrži adresu, možete pritisnuti enter u grafičkom interfejsu ili " +"CTRL plus Windows plus enter u nevidljivom interfejsu da je otvorite. Ako " +"sadrži zvučni zapis, možete pritisnuti ctrl plus enter ili ctrl plus windows " +"plus alt plus enter da ga reprodukujete. TWBlue će zvukom označiti tvitove " +"koji sadrže \\#audio hashtag, ali tvitovi mogu imati zvučne zapise i bez " +"ovoga. Konačno, ako tvit sadrži geografske informacije, možete pritisnuti " +"ctrl plus windows plus g da ih preuzmete." + +#: ../doc/strings.py:53 +msgid "### Username fields" +msgstr "### Polja korisničkih imena" + +#: ../doc/strings.py:54 +msgid "" +"These fields accept a Twitter username (without the at sign) as the input. " +"They are present in the send direct message and the user actions dialogue " +"boxes. Those dialogues will be discussed later. The initial value of these " +"fields depends on where they were opened from. They are prepopulated with " +"the username of the sender of the focused tweet (if they were opened from " +"the home and sent timelines, from users' timelines or from lists), the " +"sender of the focused direct message (if from the received or sent direct " +"message buffers) or in the focused user (if from the followers' or friends' " +"buffer). If one of those dialogue boxes is opened from a tweet, and if there " +"are more users mentioned in it, you can use the arrow keys to switch between " +"them. Alternatively, you can also type a username." +msgstr "" +"Ova polja prihvataju Twitter korisnička imena (bez et znaka ) kao unos. Ona " +"se prikazuju u dijalozima za slanje direktnih poruka i za korisničke radnje. " +"Ovi dijalozi će biti opisani kasnije. Prvobitna vrednost ovih polja zavisi " +"od toga gde su otvorena. Podrazumevano je upisano korisničko ime pošiljaoca " +"fokusiranog tvita (ako su otvorena iz početnog kanala ili kanala poslatih " +"stavki, iz korisničkih vremenskih linija ili iz liste), pošiljaocem " +"direktne poruke(ako su otvorena iz kanala primljenih ili poslatih direktnih " +"poruka) ili fokusiranim korisnikom(ako su otvorena iz kanala pratioca ili " +"prijatelja). Ako se jedan od ovih dijaloga otvori iz tvita, i ako je više " +"korisnika spomenuto u njemu, možete koristiti strelice da se prebacujete " +"između njih. U suprotnom, možete takođe da upišete korisničko ime." + +#: ../doc/strings.py:55 +msgid "## The program's interfaces" +msgstr "## Interfejsi programa" + +#: ../doc/strings.py:56 +msgid "### The graphical user interface (GUI)" +msgstr "### Grafički interfejs(GUI)" + +#: ../doc/strings.py:57 +msgid "The graphical user interface of TWBlue consists of a window containing:" +msgstr "Grafički interfejs aplikacije TWBlue sadrži prozor u kojem se nalazi:" + +#: ../doc/strings.py:58 +msgid "" +"* a menu bar accomodating six menus (application, tweet, user, buffer, " +"audio and help);" +msgstr "" +"* Traka menija koja sadrži šest menija (Aplikacija, tvit, korisnik, kanal, " +"audio i pomoć);" + +#: ../doc/strings.py:59 +msgid "* One tree view," +msgstr "* Jedan prikaz stabla," + +#: ../doc/strings.py:60 +msgid "* One list of items" +msgstr "* Jedna lista stavki" + +#: ../doc/strings.py:61 +msgid "" +"* Four buttons in most dialogs: Tweet, retweet , reply and direct message." +msgstr "" +"* 4 dugmeta u većini dijaloga: Tvit, retvituj, odgovori i direktna poruka." + +#: ../doc/strings.py:62 +msgid "The actions that are available for every item will be described later." +msgstr "Radnje koje su dostupne za svaku stavku će kasnije biti opisane." + +#: ../doc/strings.py:63 +msgid "" +"In summary, the GUI contains two core components. These are the controls you " +"will find while pressing the Tab key within the program's interface, and the " +"different elements present on the menu bar." +msgstr "" +"Najkraće opisano, grafički interfejs sadrži dve glavne komponente. To su " +"kontrole koje ćete pronaći kada pritiskate taster Tab u interfejsu programa, " +"i različiti elementi koji se nalaze na traci menija." + +#: ../doc/strings.py:64 +msgid "#### Buttons in the application" +msgstr "#### Dugmići u aplikaciji" + +#: ../doc/strings.py:65 +msgid "" +"* Tweet: this button opens up a dialogue box to write your tweet. Normal " +"tweets must not exceed 280 characters. However you can press the long tweet " +"checkbox and your tweet will be posted throught Twishort, wich will allow " +"you to write longer tweets (10000 characters). If you write past this limit, " +"a sound will play to warn you. Note that the character count is displayed in " +"the title bar. You may use the shorten and expand URL buttons to comply with " +"the character limit. You can upload a picture, check spelling, attach audio " +"or translate your message by selecting one of the available buttons in the " +"dialogue box. In addition, you can autocomplete the entering of users by " +"pressing Alt + C or the button for that purpose if you have the database of " +"users configured. Press enter to send the tweet. If all goes well, you'll " +"hear a sound confirming it. Otherwise, the screen reader will speak an error " +"message in English describing the problem." +msgstr "" +"* Tvit: Ovo dugme otvara dijalog za pisanje vašeg tvita. Standardni tvitovi " +"ne smeju imati više od 280 znakova. Ali možete označiti izborno polje dug " +"tvit i vaš tvit će biti objavljen kroz servis Twishort, što vam dozvoljava " +"da pišete duže tvitove (10000 znakova ). Ako pišete duže od ovog " +"ograničenja, čućete zvuk koji će vas upozoriti. Napomena da se broj znakova " +"takođe prikazuje kao naziv prozora. Možete takođe da koristite tastere " +"skrati vezu i proširi vezu da biste ispoštovali ograničenje znakova. Možete " +"da otpremite sliku, proverite pravopis, priložite zvučnu datoteku ili " +"prevedete tekst korišćenjem dostupnih opcija u ovom dijalogu. Takođe, možete " +"da izvršite automatsko dovršavanje korisničkih imena pritiskanjem prečice " +"alt plus a ili odgovarajućeg dugmeta ako je baza korisnika za automatsko " +"dovršavanje podešena. Pritisnite enter da pošaljete tvit. Ako je sve u redu, " +"čućete zvuk koji ovo potvrđuje. U suprotnom, čitač ekrana će na Engleskom " +"izgovoriti grešku koja opisuje problem." + +#: ../doc/strings.py:66 +msgid "" +"* Retweet: this button retweets the message you're reading. After you press " +"it, if you haven't configured the application not to do so, you'll be asked " +"if you want to add a comment or simply send it as written. If you choose to " +"add a comment, it will post a quoted tweet, that is, the comment with a " +"link to the originating tweet." +msgstr "" +"* Retvituj: Ovo dugme retvituje poruku koju čitate. Nakon što ga pritisnete, " +"ako niste podesili aplikaciju da ovo ne radi, pitaće vas da li želite da " +"dodate komentar ili jednostavno pošaljete retvit onakav kakav je. Ako " +"izaberete da dodate komentar, objaviće citiran tvit, to jest, komentar uz " +"link ka izvornom tvitu." + +#: ../doc/strings.py:67 +msgid "" +"* Reply: when you're viewing a tweet, you can reply to the user who sent it " +"by pressing this button. A dialogue will open up similar to the one for " +"tweeting. If there are more users referred to in the tweet, you can press " +"tab and activate the mention to all checkbox, or enabling checkbox for the " +"users you want to mention separately. When you're on the friends or " +"followers lists, the button will be called mention instead." +msgstr "" +"* Odgovori: Kada gledate tvit, možete odgovoriti korisniku koji ga je poslao " +"aktiviranjem ovog dugmeta. Dijalog će se otvoriti sličan onom za tvitovanje. " +"Ako je više korisnika spomenuto u tvitu, možete pritisnuti tab i označiti " +"izborno polje spomeni sve, ili označiti posebno izborno polje za svakog " +"korisnika kojeg želite da spomenete. Kada ste na listi prijatelja ili " +"pratilaca, umesto ovoga dugme će se zvati spomeni." + +#: ../doc/strings.py:68 +msgid "" +"* Direct message: exactly like sending a tweet, but it's a private message " +"which can only be read by the user you send it to. Press shift-tab twice to " +"see the recipient. If there were other users mentioned in the tweet you were " +"reading, you can arrow up or down to choose which one to send it to, or " +"write the username yourself without the at sign. In addition, you can " +"autocomplete the entering of users by pressing Alt + C or the button for " +"that purpose if you have the database of users configured." +msgstr "" +"* Direktna poruka: Baš kao i slanje tvita, ali ovo je privatna poruka koju " +"može da pročita samo korisnik kome ste je poslali. Pritisnite dva puta šift " +"tab da biste videli primaoca. Ako su drugi korisnici spominjani u tvitu " +"kojeg ste čitali, možete koristiti strelice gore i dole da izaberete kome " +"šaljete poruku, ili sami da upišete korisničko ime bez et znaka. Takođe, " +"možete izvršiti automatsko dovršavanje korisnika prečicom alt plus a ili " +"odgovarajućim dugmetom ako ste podesili bazu podataka za automatsko " +"dovršavanje." + +#: ../doc/strings.py:69 +msgid "" +"Bear in mind that buttons will appear according to which actions are " +"possible on the list you are browsing. For example, on the home timeline, " +"mentions, sent, likes and user timelines you will see the four buttons, " +"while on the direct messages list you'll only get the direct message and " +"tweet buttons, and on friends and followers lists the direct message, tweet, " +"and mention buttons will be available." +msgstr "" +"Imajte na umu da će se dugmići pojavljivati u zavisnosti od toga koje radnje " +"su dostupne na fokusiranoj listi. Na primer, na početnoj vremenskoj liniji, " +"spominjanjima, poslatim tvitovima, sviđanjima i korisničkim vremenskim " +"linijama videćete 4 dugmeta, dok ćete u listama direktnih poruka videti samo " +"dugmiće za direktnu poruku i tvit, i na listama prijatelja i pratilaca biće " +"dostupni dugmići za direktnu poruku, tvitovanje, kao i spominjanje." + +#: ../doc/strings.py:70 +msgid "#### Menus" +msgstr "#### Meniji" + +#: ../doc/strings.py:71 +msgid "" +"Visually, Towards the top of the main application window, can be found a " +"menu bar which contains many of the same functions as listed in the previous " +"section, together with some additional items. To access the menu bar, press " +"the alt key. You will find six menus listed: application, tweet, user, " +"buffer, audio and help. This section describes the items on each one of them." +msgstr "" +"Vizuelno, ka vrhu prozora aplikacije, možete pronaći traku sa menijima koja " +"sadrži dosta funkcija već opisanih iznad, uz neke dodatne stavke. Da biste " +"pristupili traci menija, pritisnite taster alt. Možete primetiti šest " +"opisanih menija: Aplikacija, Tvit, Korisnik, kanal, audio i pomoć. Ova " +"sekcija opisuje stavke svakog od njih." + +#: ../doc/strings.py:72 +msgid "##### Application menu" +msgstr "##### Meni aplikacija" + +#: ../doc/strings.py:73 +msgid "" +"* Manage accounts: Opens a window with all the sessions configured in " +"TWBlue, where you can add new sessions or delete the ones you've already " +"created." +msgstr "" +"* Upravljaj nalozima: Otvara prozor sa svim podešenim sesijama za TWBlue, " +"gde možete da dodate nove sesije ili obrišete već kreirane." + +#: ../doc/strings.py:74 +msgid "" +"* Update profile: opens a dialogue where you can update your information on " +"Twitter: name, location, website and bio. If you have already set this up " +"the fields will be prefilled with the existing information. Also, you can " +"upload a photo to your profile." +msgstr "" +"* Ažuriraj profil: Otvara dijalog gde možete da ažurirate vaše informacije " +"na Twitteru: Ime, mesto, Websajt i biografiju. Ako ste ovo već podesili " +"polja će biti popunjena postojećim informacijama. Takođe, možete otpremiti " +"vašu fotografiju profila." + +#: ../doc/strings.py:75 +msgid "" +"* Hide window: turns off the Graphical User Interface. Read the section on " +"the invisible interface for further details." +msgstr "" +"* Sakrij prozor: Krije grafički interfejs. Pročitajte sekciju o nevidljivom " +"interfejsu za dodatne detalje." + +#: ../doc/strings.py:76 +msgid "" +"* Search: shows a dialogue box where you can search for tweets or users on " +"Twitter." +msgstr "" +"* Pretraži: Prikazuje dijalog u kome možete da pretražujete korisnike i " +"tvitove na Twitteru." + +#: ../doc/strings.py:77 +msgid "" +"* Lists Manager: This dialogue box allows you to manage your Twitter lists. " +"In order to use them, you must first create them. Here, you can view, edit, " +"create, delete or, optionally, open them in buffers similar to user " +"timelines." +msgstr "" +"* Upravljanje listama: Ovaj dijalog vam dozvoljava da upravljate vašim " +"Twitter listama. Da biste ih koristili, prvo morate da ih napravite. Ovde, " +"možete prikazati, urediti, napraviti, obrisati ili, ako to želite, otvorite " +"ih u kanalima slično vremenskim linijama korisnika." + +#: ../doc/strings.py:78 +msgid "" +"* Edit keystrokes: this opens a dialogue where you can see and edit the " +"shortcuts used in the invisible interface." +msgstr "" +"* Izmeni tasterske prečice: Ova opcija otvara dijalog u kome možete " +"pogledati kao i izmeniti prečice koje se koriste u nevidljivom interfejsu." + +#: ../doc/strings.py:79 +msgid "" +"* Account settings: Opens a dialogue box which lets you customize settings " +"for the current account." +msgstr "" +"* Postavke naloga: Otvara dijalog koji vam dozvoljava da podesite " +"podešavanja za trenutni nalog." + +#: ../doc/strings.py:80 +msgid "" +"* Global settings: Opens a dialogue which lets you configure settings for " +"the entire application." +msgstr "" +"* Globalna podešavanja: Otvara dijalog koji vam dozvoljava da podesite " +"podešavanja za celu aplikaciju." + +#: ../doc/strings.py:81 +msgid "" +"* Exit: asks whether you want to exit the program. If the answer is yes, it " +"closes the application. If you do not want to be asked for confirmation " +"before exiting, uncheck the checkbox from the global settings dialogue box." +msgstr "" +"* Izlaz: Upitaće vas da li želite da izađete iz programa. Ako je odgovor da, " +"zatvara aplikaciju. Ako ne želite da budete upitani za potvrdu pre izlaza, " +"Onemogućite ovu opciju u dijalogu globalnih podešavanja." + +#: ../doc/strings.py:82 +msgid "##### Tweet menu" +msgstr "##### Meni tvit" + +#: ../doc/strings.py:83 +msgid "" +"* You will first find the items to tweet, reply and retweet, which are " +"equivalent to the buttons with the same name." +msgstr "" +"* Prvo ćete pronaći stavke da pošaljete tvit, odgovor i retvit, koje imaju " +"istu funkciju kao i dugmići sa ovim imenima." + +#: ../doc/strings.py:84 +msgid "* Like: Adds the tweet you're viewing to your likes list." +msgstr "* Sviđa mi se: Dodaje tvit koji čitate u vašu listu sviđanja." + +#: ../doc/strings.py:85 +msgid "* Unlike: removes the tweet from your likes, but not from Twitter." +msgstr "* Ne sviđa mi se: Uklanja tvit iz vaših sviđanja, ali ne sa Twittera." + +#: ../doc/strings.py:86 +msgid "" +"* Show tweet: opens up a dialogue box where you can read the tweet, direct " +"message, friend or follower which has focus. You can read the text with the " +"arrow keys. It's a similar dialog box as used for composing tweets, without " +"the ability to send the tweet, file attachment and autocompleting " +"capabilities. It does however include a retweets and likes count. If you are " +"in the followers or the friends list, it will only contain a read-only edit " +"box with the information in the focused item and a close button." +msgstr "" +"* Prikaži tvit: Otvara dijalog gde možete da pročitate tvit, direktnu " +"poruku, prijatelja ili pratioca koji je fokusiran. Možete pročitati tekst " +"strelicama. Ovo je sličan dijalog kao onaj koji se koristi za pisanje novog " +"tvita, bez mogućnosti slanja tvita, prilaganja datoteka i mogućnosti " +"automatskog dovršavanja. On ipak uključuje broj retvitova i sviđanja. Ako " +"ste u listi pratilaca ili prijatelja, sadržaće samo polje za čitanje sa " +"informacijama o fokusiranoj stavci i dugme za zatvaranje." + +#: ../doc/strings.py:87 +msgid "" +"* View address: If the selected tweet has geographical information, TWBlue " +"may display a dialogue box where you can read the tweet address. This " +"address is retrieved by sending the geographical coordinates of the tweet to " +"Google maps." +msgstr "" +"* Vidi adresu: Ako odabran tvit ima geografske informacije, TWBlue može " +"prikazati dijalog u kome možete pročitati adresu. Ova adresa se preuzima " +"slanje geografskih koordinata u tvitu na Google mape." + +#: ../doc/strings.py:88 +msgid "" +"* View conversation: If you are focusing a tweet with a mention, it opens a " +"buffer where you can view the whole conversation." +msgstr "" +"* Vidi razgovor: Ako ste fokusirani na tvit sa spominjanjem, otvara kanal u " +"kojem možete da vidite čitav razgovor." + +#: ../doc/strings.py:89 +msgid "" +"* Read text in pictures: Attempt to apply OCR technology to the image " +"attached to the tweet. The result will be displayed in another dialog." +msgstr "" +"* Čitaj tekst u slici: Pokušava da primeni OCR tehnologije na sliku koja je " +"priložena u tvit. Rezultat će biti prikazan u drugom dijalogu." + +#: ../doc/strings.py:90 +msgid "" +"* Delete: permanently removes the tweet or direct message which has focus " +"from Twitter and from your lists. Bear in mind that Twitter only allows you " +"to delete tweets you have posted yourself." +msgstr "" +"* Izbriši: Trajno uklanja fokusiran tvit ili direktnu poruku sa Twittera i " +"iz vaših lista. Imajte na umu da vam Twitter dozvoljava brisanje samo " +"tvitova koje ste vi poslali." + +#: ../doc/strings.py:91 +msgid "##### User menu" +msgstr "##### Meni korisnik" + +#: ../doc/strings.py:92 +msgid "" +"* Actions: Opens a dialogue where you can interact with a user. This " +"dialogue box will be populated with the user who sent the tweet or direct " +"message in focus or the selected user in the friends or followers buffer. " +"You can edit it or leave it as is and choose one of the following actions:" +msgstr "" +"* Radnje: Otvara dijalog u kojem možete da vršite interakciju sa korisnikom. " +"Ovaj dijalog će imati već upisano ime korisnika koji je poslao tvit ili " +"direktnu poruku, ili sa imenom fokusiranog korisnika u kanalima prijatelja i " +"pratilaca. Možete ga izmeniti ili ga ostaviti i izabrati jednu od sledećih " +"radnji:" + +#: ../doc/strings.py:93 +msgid "" +" * Follow: Follows a user. This means you'll see his/her tweets on your home " +"timeline, and if he/she also follows you, you'll be able to exchange direct " +"messages. You may also send / receive direct messages from each other if you " +"have configured the option to allow direct messages from anyone." +msgstr "" +" * Prati: Prati korisnika. Ovo znači da ćete njihove tvitove videti na vašoj " +"početnoj vremenskoj liniji, i ako vas oni takođe prate, možete da " +"razmenjujete direktne poruke. Takođe možete da razmenjujete direktne poruke " +"ako ste dozvolili razmenu direktnih poruka sa svima u Twitter podešavanjima." + +#: ../doc/strings.py:94 +msgid "" +" * Unfollow: Stops following a user, which causes you not being able to see " +"his/her tweets on your main timeline neither exchanging direct messages, " +"unless they have enabled receiving direct messages from anyone." +msgstr "" +" * Otprati: Prestaje sa praćenjem korisnika, što će onemogućiti praćenje " +"njihovih tvitova na vašoj vremenskoj liniji kao i razmenu direktnih poruka, " +"osim ako su omogućili primanje direktnih poruka od svih." + +#: ../doc/strings.py:95 +msgid "" +" * Mute: While muting someone, TWBlue won't show you nor his/her tweets on " +"your main timeline; neither will you see that person's mentions. But you " +"both will be able to exchange direct messages. The muted user is not " +"informed of this action." +msgstr "" +" * Utišaj: Kada nekoga utišate, TWBlue vam neće prikazivati njihove tvitove " +"na vremenskoj liniji; niti ćete videti njihova spominjanja. Možete da " +"razmenjujete direktne poruke. Utišan korisnik neće dobiti informaciju o ovoj " +"radnji." + +#: ../doc/strings.py:96 +msgid "" +" * Unmute: this option allows TWBlue to display the user's tweets and " +"mentions again." +msgstr "" +" * Ukloni utišavanje: Ova opcija dozvoljava da TWBlue ponovo prikazuje " +"tvitove i spominjanja korisnika." + +#: ../doc/strings.py:97 +msgid " * Block: Blocks a user. This forces the user to unfollow you ." +msgstr "" +" * Blokiraj: Blokira korisnika. Ovo će naterati korisnika da prestane da vas " +"prati." + +#: ../doc/strings.py:98 +msgid " * Unblock: Stops blocking a user." +msgstr " * Odblokiraj: Prestaje sa blokiranjem korisnika." + +#: ../doc/strings.py:99 +msgid "" +" * Report as spam: this option sends a message to Twitter suggesting the " +"user is performing prohibited practices on the social network." +msgstr "" +" * Prijavi kao neželjeno: Ova opcija šalje poruku Twitteru koja obaveštava " +"da korisnik izvršava zabranjene radnje." + +#: ../doc/strings.py:100 +msgid "" +" * Ignore tweets from this client: Adds the client from which the focused " +"tweet was sent to the ignored clients list." +msgstr "" +" * Zanemari tvitove iz ovog klijenta: Dodaje klijent iz kog je tvit poslat u " +"listu klijenata iz kojih se tvitovi zanemaruju." + +#: ../doc/strings.py:101 +msgid "" +"* View timeline: Lets you open a user's timeline by choosing the user in a " +"dialog box. It is created when you press enter. If you invoke this option " +"relative to a user that has no tweets, the operation will fail. If you try " +"creating an existing timeline the program will warn you and will not create " +"it again." +msgstr "" +"* Vidi vremensku liniju: Dozvoljava vam da otvorite vremensku liniju " +"korisnikaizborom korisnika u dijalogu. Pravi se kada pritisnete enter. Ako " +"aktivirate ovu opciju za korisnika koji nema tvitove, radnja neće uspeti. " +"Ako pokušate da napravite vremensku liniju koja već postoji program će vas " +"upozoriti i ona neće ponovo biti napravljena." + +#: ../doc/strings.py:102 +msgid "* Direct message: same action as the button." +msgstr "* Direktna poruka: Ista radnja kao i već opisano dugme." + +#: ../doc/strings.py:103 +msgid "" +"* Add to List: In order to see someone's tweets in one or more of your " +"lists, you must add them first. In the dialogue box that opens after " +"selecting the user, you will be asked to select the list you wish to add the " +"user to. Thereafter, the list will contain a new member and their tweets " +"will be displayed there." +msgstr "" +"* Dodaj na listu: Kako biste videli nečije tvitove u jednoj ili više lista, " +"prvo ih morate dodati. U dijalogu koji se otvara nakon što izaberete " +"korisnika, bićete upitani da izaberete listu na koju će korisnik biti dodat. " +"Nakon toga, lista će imati novog člana i njihovi tvitovi će biti prikazani u " +"njoj." + +#: ../doc/strings.py:104 +msgid "* Remove from list: lets you remove a user from a list." +msgstr "* Ukloni sa liste: Dozvoljava vam da uklonite korisnika sa liste." + +#: ../doc/strings.py:105 +msgid "* View lists: Shows the lists created by a specified user." +msgstr "* Vidi liste: Prikazuje liste koje je izabrani korisnik napravio." + +#: ../doc/strings.py:106 +msgid "" +"* Show user profile: opens a dialogue with the profile of the specified user." +msgstr "" +"* Prikaži profil korisnika: Otvara dijalog sa profilom izabranog korisnika." + +#: ../doc/strings.py:107 +msgid "" +"* View likes: Opens a buffer where you can see the tweets which have been " +"liked by a particular user." +msgstr "" +"* Vidi sviđanja: Otvara kanal u kojem možete videti tvitove koje je izabrani " +"korisnik označio sviđanjem." + +#: ../doc/strings.py:108 +msgid "##### Buffer menu" +msgstr "##### Meni kanal" + +#: ../doc/strings.py:109 +msgid "" +"* New trending topics buffer: This opens a buffer to get the worlwide " +"trending topics or those of a country or a city. You'll be able to select " +"from a dialogue box if you wish to retrieve countries' trends, cities' " +"trends or worldwide trends (this option is in the cities' list) and choose " +"one from the selected list. The trending topics buffer will be created once " +"the \"OK\" button has been activated within the dialogue box. Remember this " +"kind of buffer will be updated every five minutes." +msgstr "" +"* Novi kanal sa temama u trendu: Ova opcija otvara kanal za preuzimanje tema " +"u trendu širom sveta, za određenu državu ili za određeni grad. Nakon " +"aktiviranja opcije možete da izaberete da li želite da vidite teme u trendu " +"za državu, teme u trendu za grad ili teme u trendu širom sveta (ova opcija " +"se nalazi u listi gradova) i možete da izaberete jedan iz izabrane liste. " +"Kanal sa temama u trendu će biti napravljen kada aktivirate dugme \"u redu\" " +"u dijalogu. Zapamtite da će se ovaj kanal ažurirati na 5 minuta." + +#: ../doc/strings.py:110 +msgid "" +"* Load previous items: This allows more items to be loaded for the specified " +"buffer." +msgstr "" +"* Učitaj prethodne stavke: Ova opcija dozvoljava da učitate dodatne stavke " +"za izabrani kanal." + +#: ../doc/strings.py:111 +msgid "" +"* Mute: Mutes notifications of a particular buffer so you will not hear when " +"new tweets arrive." +msgstr "" +"* Utišaj: Utišava obaveštenja za trenutni kanal tako da nećete čuti kada " +"stignu novi tvitovi." + +#: ../doc/strings.py:112 +msgid "" +"* autoread: When enabled, the screen reader or SAPI 5 Text to Speech voice " +"(if enabled) will read the text of incoming tweets. Please note that this " +"could get rather chatty if there are a lot of incoming tweets." +msgstr "" +"* Automatski čitaj: Kada je ova opcija omogućena, čitač ekrana ili SAPI 5 " +"glas (ako je omogućen ) pročitaće tekst dolaznih tvitova. Imajte na umu da " +"bi ovo moglo da bude prilično često ako ima puno novih tvitova." + +#: ../doc/strings.py:113 +msgid "* Clear buffer: Deletes all items from the buffer." +msgstr "* Očisti kanal: Briše sve stavke sa kanala." + +#: ../doc/strings.py:114 +msgid "* Destroy: dismisses the list you're on." +msgstr "* Izbriši: Briše kanal na kojem ste." + +#: ../doc/strings.py:115 +msgid "##### Audio menu" +msgstr "##### Meni audio" + +#: ../doc/strings.py:116 +msgid "" +"* Play/pause: try to play audio for the selected item (if available), or " +"stop the currently played audio." +msgstr "" +"* Reprodukuj / zaustavi: Pokušava da reprodukuje zvučni zapis za izabranu " +"stavku (ako je dostupan ), ili zaustavlja zapis koji se trenutno reprodukuje." + +#: ../doc/strings.py:117 +msgid "" +"* Seek back 5 seconds: If an audio is being played, seek 5 seconds back in " +"the playback. This will work only in audio files. This feature cannot be " +"used in radio stations or other streamed files." +msgstr "" +"* Premotaj unazad za 5 sekundi: Ako se zvučni zapis reprodukuje, premotava " +"reprodukciju nazad 5 sekundi. Ovo će raditi samo u zvučnim datotekama. Ova " +"opcija se ne može koristiti na radio stanicama ili drugim strimovima." + +#: ../doc/strings.py:118 +msgid "" +"* Seek forward 5 seconds: If an audio is being played, seek 5 seconds " +"forward in the playback. This feature cannot be used in radio stations or " +"other streamed files." +msgstr "" +"* Premotaj unapred za 5 sekundi: Ako se zvučni zapis reprodukuje, premotava " +"reprodukciju za 5 sekundi unapred. Ova opcija se ne može koristiti sa radio " +"stanicama ili drugim strimovima." + +#: ../doc/strings.py:119 +msgid "##### Help menu" +msgstr "##### Meni pomoć" + +#: ../doc/strings.py:120 +msgid "" +"* Documentation: opens up this file, where you can read some useful program " +"concepts." +msgstr "" +"* Dokumentacija: Otvara ovu datoteku, u kojoj možete pročitati neke korisne " +"koncepte programa." + +#: ../doc/strings.py:121 +msgid "" +"* Sounds tutorial: Opens a dialog box where you can familiarize yourself " +"with the different sounds of the program." +msgstr "" +"* Zvučna uputstva: Otvara dijalog u kojem se možete upoznati sa različitim " +"zvukovima programa." + +#: ../doc/strings.py:122 +msgid "" +"* What's new in this version?: opens up a document with the list of changes " +"from the current version to the earliest." +msgstr "" +"* Šta je novo u ovoj verziji?: Otvara dokument sa listom promena od trenutne " +"verzije do naj starije." + +#: ../doc/strings.py:123 +msgid "" +"* Check for updates: every time you open the program it automatically checks " +"for new versions. If an update is available, it will ask you if you want to " +"download the update. If you accept, the updating process will commence. When " +"complete, TWBlue will be restarted. This item checks for new updates without " +"having to restart the application." +msgstr "" +"* Proveri da li postoje nadogradnje: Svaki put kada otvorite program " +"automatski će proveriti dostupnost nove verzije. Ako je ažuriranje dostupno, " +"upitaće vas da li želite da preuzmete ažuriranje. Ako prihvatite, proces " +"ažuriranja će započeti. Kada se završi, TWBlue će biti ponovo pokrenut. Ova " +"opcija proverava dostupnost ažuriranja bez potrebe za ponovnim pokretanjem " +"aplikacije." + +#: ../doc/strings.py:124 +msgid "" +"* TWBlue's website: visit our [home page](http://twblue.es) where you can " +"find all relevant information and downloads for TWBlue and become a part of " +"the community." +msgstr "" +"* TWBlue's websajt: Posetite našu[početnu stranicu](http://twblue.es) gde " +"možete pronaći sve bitne TWBlue informacije i preuzimanja za TWBlue kao i " +"postati deo zajednice." + +#: ../doc/strings.py:125 +msgid "* About TWBlue: shows the credits of the program." +msgstr "* O TWBlue: Prikazuje zahvalnosti i informacije o programu." + +#: ../doc/strings.py:126 +msgid "### The invisible user interface" +msgstr "### Nevidljivi korisnički interfejs" + +#: ../doc/strings.py:127 +msgid "" +"The invisible interface, as its name suggests, has no graphical window and " +"works directly with screen readers such as JAWS for Windows, NVDA and System " +"Access. This interface is disabled by default, but you can enable it by " +"pressing Control + M. It works similarly to TheQube and Chicken Nugget. Its " +"shortcuts are similar to those found in these two clients. In addition, the " +"program has builtin support for the keymaps for these applications, " +"configurable through the global settings dialogue. By default, you cannot " +"use this interface's shortcuts in the GUI, but you can configure this in the " +"global settings dialogue." +msgstr "" +"Nevidljivi interfejs, kao što samo ime govori, nema grafičkog prozora i radi " +"direktno sa čitačima ekrana kao što su JAWS za Windows, NVDA i System " +"Access. Ovaj interfejs je podrazumevano onemogućen, ali možete ga omogućiti " +"pritiskanjem prečice Control + M. Radi slično klijentima TheQube i Chicken " +"Nugget. Njegove prečice su slične onima koje se nalaze u ova dva klijenta. " +"Takođe, program ima ugrađenu podršku za mape prečica za ove aplikacije, koje " +"se podešavaju u dijalogu globalnih podešavanja. Po podrazumevanim " +"podešavanjima, ne možete koristiti prečice ovog interfejsa dok je prikazan " +"grafički interfejs, ali možete ovo podesiti u dijalogu globalnih podešavanja." + +#: ../doc/strings.py:128 +msgid "" +"The next section contains a list of keyboard shortcuts for both interfaces. " +"Bear in mind that we will only describe the default keymap." +msgstr "" +"Sledeća lista sadrži listu prečica za oba interfejsa. Imajte na umu da ćemo " +"opisati samo podrazumevanu mapu prečica." + +#: ../doc/strings.py:129 +msgid "## Keyboard shortcuts" +msgstr "## Tasterske prečice" + +#: ../doc/strings.py:130 +msgid "### Shortcuts of the graphical user interface (GUI)" +msgstr "### prečice grafičkog interfejsa (GUI-a)" + +#: ../doc/strings.py:131 +msgid "* Enter: Open URL." +msgstr "* Enter: Otvara adresu." + +#: ../doc/strings.py:132 +msgid "* Control + Enter: Play audio." +msgstr "* Control + Enter: Reprodukuje zvučni zapis." + +#: ../doc/strings.py:133 +msgid "* Control + M: Hide the GUI." +msgstr "* Control + M: Krije grafički interfejs." + +#: ../doc/strings.py:134 +msgid "* Control + N: Compose a new tweet." +msgstr "* Control + N: Piše novi tvit." + +#: ../doc/strings.py:135 +msgid "* Control + R: Reply / mention." +msgstr "* Control + R: Odgovor / spominjanje." + +#: ../doc/strings.py:136 +msgid "* Control + Shift + R: Retweet." +msgstr "* Control + Shift + R: Retvit." + +#: ../doc/strings.py:137 +msgid "* Control + D: Send a direct message." +msgstr "* Control + D: Šalje direktnu poruku." + +#: ../doc/strings.py:138 +msgid "* control + F: Add tweet to likes." +msgstr "* control + F: Dodavanje tvita u sviđanja." + +#: ../doc/strings.py:139 +msgid "* Control + Shift + F: Remove a tweet from likes." +msgstr "* Control + Shift + F: Uklanja tvit iz sviđanja." + +#: ../doc/strings.py:140 +msgid "* Control + S: Open the user actions dialogue." +msgstr "* Control + S: Otvara dijalog korisničkih radnji." + +#: ../doc/strings.py:141 +msgid "* Control + Shift + V: Show tweet." +msgstr "* Control + Shift + V: Prikazuje tvit." + +#: ../doc/strings.py:142 +msgid "* Control + Q: Quit this program." +msgstr "* Control + Q: Izlazi iz ovog programa." + +#: ../doc/strings.py:143 +msgid "* Control + I: Open user timeline." +msgstr "* Control + I: Otvara vremensku liniju korisnika." + +#: ../doc/strings.py:144 +msgid "* Control + Shift + i: Destroy buffer." +msgstr "* Control + Shift + i: Briše kanal." + +#: ../doc/strings.py:145 +msgid "* F5: Increase volume by 5%." +msgstr "* F5: Pojačava jačinu za 5 %." + +#: ../doc/strings.py:146 +msgid "* F6: Decrease volume by 5%." +msgstr "* F6: Smanjuje jačinu za 5%." + +#: ../doc/strings.py:147 +msgid "* Control + P: Edit your profile." +msgstr "* Control + P: Uređivanje vašeg profila." + +#: ../doc/strings.py:148 +msgid "* Control + Delete: Delete a tweet or direct message." +msgstr "* Control + Delete: Briše tvit ili direktnu poruku." + +#: ../doc/strings.py:149 +msgid "* Control + Shift + Delete: Empty the current buffer." +msgstr "* Control + Shift + Delete: Prazni trenutni kanal." + +#: ../doc/strings.py:150 +msgid "### Shortcuts of the invisible interface (default keymap)" +msgstr "### Prečice nevidljivog interfejsa (podrazumevana mapa prečica )" + +#: ../doc/strings.py:151 +msgid "" +"The invisible interface of TWBlue can be customised by using a keymap. Every " +"keymap defines a set of keystrokes to be used along with the invisible " +"interface. You can change the keymap in the global settings dialogue, under " +"the application menu in the menu bar, and check or edit keystrokes for the " +"selected keymap in the keystroke editor, also available in the application " +"menu." +msgstr "" +"Nevidljivi interfejs programa TWBlue se može prilagoditi korišćenjem mape " +"prečica. Svaka mapa prečica definiše listu prečica koje će se koristiti u " +"nevidljivom interfejsu. Možete promeniti mapu prečica u dijalogu globalnih " +"podešavanja, u meniju aplikacija u traci sa menijima, kao i da proverite ili " +"izmenite prečice izabrane mape opcijom izmeni tasterske prečice, koja se " +"takođe nalazi u meniju aplikacija." + +#: ../doc/strings.py:152 +msgid "" +"* Control + Windows + Up Arrow: moves to the previous item in the buffer." +msgstr "" +"* Control + Windows + strelica gore: Prelazi na prethodnu stavku u kanalu." + +#: ../doc/strings.py:153 +msgid "* Control + Windows + Down Arrow: moves to the next item in the buffer." +msgstr "" +"* Control + Windows + strelica dole: Prelazi na sledeću stavku u kanalu." + +#: ../doc/strings.py:154 +msgid "* Control + Windows + Left Arrow: Move to the previous buffer." +msgstr "* Control + Windows + strelica levo: Prelazi na sledeći kanal." + +#: ../doc/strings.py:155 +msgid "* Control + Windows + Right Arrow: Move to the next buffer." +msgstr "* Control + Windows + strelica desno: Prelazi na sledeći kanal." + +#: ../doc/strings.py:156 +msgid "* Control + Windows + Shift + Left: Focus the previous session." +msgstr "" +"* Control + Windows + Shift + strelica levo: Fokusiranje prethodne sesije." + +#: ../doc/strings.py:157 +msgid "* Control + Windows + Shift + Right: Focus the next session." +msgstr "" +"* Control + Windows + Shift + strelica desno: Fokusiranje sledeće sesije." + +#: ../doc/strings.py:158 +msgid "* Control + Windows + C: View conversation." +msgstr "* Control + Windows + C: Prikazuje razgovor." + +#: ../doc/strings.py:159 +msgid "* Control + Windows + Enter: Open URL." +msgstr "* Control + Windows + Enter: Otvara adresu." + +#: ../doc/strings.py:160 +msgid "* Control + Windows + ALT + Enter: Play audio." +msgstr "* Control + Windows + ALT + Enter: Reprodukuje zvučni zapis." + +#: ../doc/strings.py:161 +msgid "* Control + Windows + M: Show or hide the GUI." +msgstr "* Control + Windows + M: Prikazuje ili krije grafički interfejs." + +#: ../doc/strings.py:162 +msgid "* Control + Windows + N: New tweet." +msgstr "* Control + Windows + N: Novi tvit." + +#: ../doc/strings.py:163 +msgid "* Control + Windows + R: Reply / Mention." +msgstr "* Control + Windows + R: Odgovor / spominjanje." + +#: ../doc/strings.py:164 +msgid "* Control + Windows + Shift + R: Retweet." +msgstr "* Control + Windows + Shift + R: Retvit." + +#: ../doc/strings.py:165 +msgid "* Control + Windows + D: Send direct message." +msgstr "* Control + Windows + D: Slanje direktne poruke." + +#: ../doc/strings.py:166 +msgid "* Windows+ Alt + F: Like a tweet." +msgstr "* Windows+ Alt + F: Označite da vam se tvit sviđa." + +#: ../doc/strings.py:167 +msgid "* Alt + Windows + Shift + F: Remove from likes." +msgstr "* Alt + Windows + Shift + F: Uklanjanje iz liste sviđanja." + +#: ../doc/strings.py:168 +msgid "* Control + Windows + S: Open the user actions dialogue." +msgstr "* Control + Windows + S: Otvara dijalog korisničkih radnji." + +#: ../doc/strings.py:169 +msgid "* Control + Windows + Alt + N: See user details." +msgstr "* Control + Windows + Alt + N: Prikazuje korisničke detalje." + +#: ../doc/strings.py:170 +msgid "* Control + Windows + V: Show tweet." +msgstr "* Control + Windows + V: Prikazuje tvit." + +#: ../doc/strings.py:171 +msgid "* Control + Windows + F4: Quit TWBlue." +msgstr "* Control + Windows + F4: Zatvara TWBlue." + +#: ../doc/strings.py:172 +msgid "* Control + Windows + I: Open user timeline." +msgstr "* Control + Windows + I: Otvara vremensku liniju korisnika." + +#: ../doc/strings.py:173 +msgid "* Control + Windows + Shift + I: Destroy buffer." +msgstr "* Control + Windows + Shift + I: Briše kanal." + +#: ../doc/strings.py:174 +msgid "* Control + Windows + Alt + Up: Increase volume by 5%." +msgstr "* Control + Windows + Alt + strelica gore: Pojačava jačinu za 5%." + +#: ../doc/strings.py:175 +msgid "* Control + Windows + Alt + Down: Decrease volume by 5%." +msgstr "* Control + Windows + Alt + strelica dole: smanjuje jačinu za 5%." + +#: ../doc/strings.py:176 +msgid "" +"* Control + Windows + Home: Jump to the first element of the current buffer." +msgstr "" +"* Control + Windows + Home: Prebacuje se na prvi element trenutnog kanala." + +#: ../doc/strings.py:177 +msgid "" +"* Control + Windows + End: Jump to the last element of the current buffer." +msgstr "" +"* Control + Windows + End: Prebacuje se na poslednji element trenutnog " +"kanala." + +#: ../doc/strings.py:178 +msgid "" +"* Control + Windows + PageUp: Jump 20 elements up in the current buffer." +msgstr "" +"* Control + Windows + PageUp: Skače 20 elemenata gore u trenutnom kanalu." + +#: ../doc/strings.py:179 +msgid "" +"* Control + Windows + PageDown: Jump 20 elements down in the current buffer." +msgstr "" +"* Control + Windows + PageDown: Skače 20 elemenata dole u trenutnom kanalu." + +#: ../doc/strings.py:180 +msgid "* Windows + Alt + P: Edit profile." +msgstr "* Windows + Alt + P: Uređivanje profila." + +#: ../doc/strings.py:181 +msgid "* Control + Windows + Delete: Delete a tweet or direct message." +msgstr "* Control + Windows + Delete: Briše tvit ili direktnu poruku." + +#: ../doc/strings.py:182 +msgid "* Control + Windows + Shift + Delete: Empty the current buffer." +msgstr "* Control + Windows + Shift + Delete: Prazni trenutni kanal." + +#: ../doc/strings.py:183 +msgid "* Control + Windows + Space: Repeat last item." +msgstr "* Control + Windows + razmak: Ponavlja poslednju stavku." + +#: ../doc/strings.py:184 +msgid "* Control + Windows + Shift + C: Copy to clipboard." +msgstr "* Control + Windows + Shift + C: Kopira u privremenu memoriju." + +#: ../doc/strings.py:185 +msgid "* Control + Windows+ A: Add user to list." +msgstr "* Control + Windows+ A: Dodaje korisnika na listu." + +#: ../doc/strings.py:186 +msgid "* Control + Windows + Shift + A: Remove user from list." +msgstr "* Control + Windows + Shift + A: Uklanja korisnika sa liste." + +#: ../doc/strings.py:187 +msgid "* Control + Windows + Shift + M: Mute / unmute the current buffer." +msgstr "" +"* Control + Windows + Shift + M: Utišava ili uklanja utišavanje trenutnog " +"kanala." + +#: ../doc/strings.py:188 +msgid "* Windows + Alt + M: Mute / unmute the current session." +msgstr "* Windows + Alt + M: Utišava ili uklanja utišavanje trenutne sesije." + +#: ../doc/strings.py:189 +msgid "" +"* Control + Windows + E: Toggle the automatic reading of incoming tweets in " +"the current buffer." +msgstr "" +"* Control + Windows + E: Uključuje ili isključuje automatsko čitanje tvitova " +"za trenutni kanal." + +#: ../doc/strings.py:190 +msgid "* Control + Windows + -: Search on Twitter." +msgstr "* Control + Windows + -: Pretraga Twittera." + +#: ../doc/strings.py:191 +msgid "* Control + Windows + K: Show the keystroke editor." +msgstr "" +"* Control + Windows + K: Prikazuje dijalog za menjanje tasterskih prečica." + +#: ../doc/strings.py:192 +msgid "* Control + Windows + L: Show lists for a specified user." +msgstr "* Control + Windows + L: Prikazuje liste za izabranog korisnika." + +#: ../doc/strings.py:193 +msgid "* Windows + Alt + PageUp: Load previous items for the current buffer." +msgstr "* Windows + Alt + PageUp: Učitava prethodne stavke za trenutni kanal." + +#: ../doc/strings.py:194 +msgid "* Control + Windows + G: Get geolocation." +msgstr "* Control + Windows + G: Preuzima geografske podatke." + +#: ../doc/strings.py:195 +msgid "" +"* Control + Windows + Shift + G: Display the tweet's geolocation in a " +"dialogue." +msgstr "" +"* Control + Windows + Shift + G: Prikazuje geografske podatke o lokaciji " +"tvita u dijalogu." + +#: ../doc/strings.py:196 +msgid "* Control + Windows + T: Create a trending topics' buffer." +msgstr "* Control + Windows + T: Pravi kanal tema u trendu." + +#: ../doc/strings.py:197 +msgid "* Control + Windows + {: Find a string in the current buffer." +msgstr "* Control + Windows + {: Pretraga teksta u trenutnom kanalu." + +#: ../doc/strings.py:198 +msgid "" +"* Alt + Windows + O: Extracts text from the picture and display the result " +"in a dialog." +msgstr "" +"* Alt + Windows + O: Izvlači tekst iz slike i prikazuje rezultat u dijalogu." + +#: ../doc/strings.py:199 +msgid "## Configuration" +msgstr "## Podešavanja" + +#: ../doc/strings.py:200 +msgid "" +"As described above, this application has two configuration dialogues, the " +"global settings dialogue and the account settings dialogue." +msgstr "" +"Kao što je iznad opisano, ova aplikacija ima dva dijaloga podešavanja, " +"dijalog globalnih podešavanja i dijalog postavki naloga." + +#: ../doc/strings.py:201 +msgid "### The account settings dialogue" +msgstr "### Dijalog podešavanja naloga" + +#: ../doc/strings.py:202 +msgid "#### General tab" +msgstr "#### Kartica opšte" + +#: ../doc/strings.py:203 +msgid "" +"* Autocompletion settings: Allows you to configure the autocompletion " +"database. You can add users manually or let TWBlue add your followers, " +"friends or both." +msgstr "" +"* Postavke automatskog dovršavanja: Dozvoljava vam da podesite bazu " +"automatskog dovršavanja. Možete ručno podesiti bazu ili dozvoliti da TWBlue " +"doda vaše pratioce, prijatelje ili i jedne i druge." + +#: ../doc/strings.py:204 +msgid "" +"* Relative timestamps: Allows you to configure whether the application will " +"calculate the time the tweet or direct message was sent or received based on " +"the current time, or simply say the time it was received or sent." +msgstr "" +"* Relativne vremenske oznake: Dozvoljava da podesite da li će aplikacija " +"računati vreme u koje je direktna poruka ili tvit poslat ili primljen u " +"zavisnosti od trenutnog vremena, ili jednostavno reći vreme kada je stavka " +"primljena ili poslata." + +#: ../doc/strings.py:205 +msgid "" +"* API calls: Allows you to adjust the number of API calls to be made to " +"Twitter by this program." +msgstr "" +"* API pozivi: Dozvoljava da promenite broj API poziva Twitteru od strane " +"programa." + +#: ../doc/strings.py:206 +msgid "" +"* Items on each API call: Allows you to specify how many items should be " +"retrieved from Twitter for each API call (default and maximum is 200)." +msgstr "" +"* Stavke po svakom API pozivu: Dozvoljava da odredite koliko stavki treba da " +"se preuzme sa Twittera za svaki API poziv (podrazumevano i maksimalno je " +"200)." + +#: ../doc/strings.py:207 +msgid "" +"* Inverted buffers: Allows you to specify whether the buffers should be " +"inverted, which means that the oldest items will show at the end of them and " +"the newest at the beginning." +msgstr "" +"* Okreni kanal: Dozvoljava da odredite da li će kanali biti obrnuti, što " +"znači da će se starije stavke prikazivati na dnu a novije na vrhu." + +#: ../doc/strings.py:208 +msgid "" +"* Retweet mode: Allows you to specify the behaviour when posting a retweet: " +"you can choose between retweeting with a comment, retweeting without comment " +"or being asked." +msgstr "" +"* Način retvitovanja: Dozvoljava vam da odredite ponašanje kada šaljete " +"retvit: Možete izabrati između opcija retvituj sa komentarima, retvituj bez " +"komentara ili da vas aplikacija uvek pita." + +#: ../doc/strings.py:209 +msgid "" +"* Number of items per buffer to cache in database: This allows you to " +"specify how many items TWBlue should cache in a database. You can type any " +"number, 0 to cache all items, or leave blank to disable caching entirely." +msgstr "" +"* Broj stavki po kanalu za čuvanje u bazi: Ova opcija vam dozvoljava da " +"odredite koliko stavki će TWBlue čuvati u svojoj bazi. Možete upisati bilo " +"koji broj, 0 da se sve stavke čuvaju, ili ostavite polje praznim da se " +"čuvanje u potpunosti onemogući." + +#: ../doc/strings.py:210 +msgid "#### buffers tab" +msgstr "#### Kartica kanali" + +#: ../doc/strings.py:211 +msgid "" +"This tab displays a list for each buffer you have available in TWBlue, " +"except for searches, timelines, likes' timelines and lists. You can show, " +"hide and move them." +msgstr "" +"Ova kartica prikazuje sve kanale koje imate u aplikaciji TWBlue, osim " +"pretraga, vremenskih linija, vremenskih linija sviđanja i listi. Možete ih " +"prikazati, sakriti i premeštati." + +#: ../doc/strings.py:212 +msgid "#### The ignored clients tab" +msgstr "#### Kartica zanemareni klijenti" + +#: ../doc/strings.py:213 +msgid "" +"In this tab, you can add and remove clients to be ignored by the program." +msgstr "" +"U ovoj kartici, možete dodati i ukloniti klijente koje će program zanemariti." + +#: ../doc/strings.py:214 +msgid "#### Sound tab" +msgstr "#### Kartica zvuk" + +#: ../doc/strings.py:215 +msgid "" +"In this tab, you can adjust the sound volume, select the input and output " +"device and set the soundpack used by the program." +msgstr "" +"U ovoj kartici, možete promeniti jačinu zvuka, izabrati ulazni i izlazni " +"uređaj kao i zvučni paket koji će program koristiti." + +#: ../doc/strings.py:216 +msgid "#### Audio service tab" +msgstr "#### Kartica audio servis" + +#: ../doc/strings.py:217 +msgid "" +"In this tab, you can enter your SndUp API key (if you have one) to upload " +"audio to SndUp with your account. Note that if account credentials are not " +"specified you will upload anonimously." +msgstr "" +"U ovoj kartici, možete upisati vaš SndUp API ključ (ako ga imate ) da biste " +"otpremili zvučne datoteke na servis SndUp vašim nalogom. Napomena da ako ne " +"odredite podatke naloga otpremaćete datoteke anonimno." + +#: ../doc/strings.py:218 +msgid "### Global settings" +msgstr "### Globalna podešavanja" + +#: ../doc/strings.py:219 +msgid "" +"This dialogue allows you to configure some settings which will affect the " +"entire application." +msgstr "" +"Ovaj dijalog vam dozvoljava da podesite određena podešavanja koja će uticati " +"na čitavu aplikaciju." + +#: ../doc/strings.py:220 +msgid "#### General tab {#general-tab_1}" +msgstr "#### Kartica opšte {#general-tab_1}" + +#: ../doc/strings.py:221 +msgid "" +"* Language: This allows you to change the language of this program. " +"Currently supported languages are arabic, Catalan, German, English, Spanish, " +"Basque, Finnish, French, Galician, Croatian, Hungarian, Italian, Polish, " +"Portuguese, Russian and Turkish." +msgstr "" +"* Jezik: Dozvoljava promenu jezika programa. Trenutno podržani jezici su " +"Arapski, Katalonski, Nemački, Engleski, Španski, Baskijski, Finski, " +"Francuski, Galski, Hrvatski, Mađarski, Italijanski, Poljski, Portugalski, " +"Ruski, Srpski i Turski." + +#: ../doc/strings.py:222 +msgid "" +"* Ask before exiting TWBlue: This checkbox allows you to control whetherthe " +"program will ask for confirmation before exiting." +msgstr "" +"* Pitaj pre zatvaranja TWBlue: Ovo izborno polje dozvoljava da podesite da " +"li će program zahtevati potvrdu pre izlaza." + +#: ../doc/strings.py:223 +msgid "" +"* Play a sound when TWBlue launches: This checkbox allows you to configure " +"whether the application will play a sound when it has finished loading the " +"buffers." +msgstr "" +"* Reprodukuj zvuk kada se TWBlue pokrene: Ovo izborno polje dozvoljava da " +"odredite da li će aplikacija reprodukovati zvuk nakon što završi učitavanje " +"kanala." + +#: ../doc/strings.py:224 +msgid "" +"* Speak a message when TWBlue launches: This is the same as the previous " +"option, but this checkbox configures whether the screen reader will say " +"\"ready\"." +msgstr "" +"* Izgovori poruku kada se TWBlue pokrene: Ova opcija je ista kao i " +"prethodna, ali ovo izborno polje kontroliše da li će čitač ekrana reći " +"\"spreman\"." + +#: ../doc/strings.py:225 +msgid "" +"* Use the invisible interface's shortcuts in the GUI: As the invisible " +"interface and the Graphical User Interface have their own shortcuts, you may " +"want to use the invisible interface's keystrokes all the time. If this " +"option is checked, the invisible interface's shortcuts will be usable in the " +"GUI." +msgstr "" +"* Koristi prečice nevidljivog okruženja dok je grafičko okruženje prikazano: " +"Budući da nevidljivi i grafički interfejs imaju svoje prečice, možda ćete " +"želeti da uvek koristite prečice nevidljivog interfejsa. Ako je ova opcija " +"označena, prečice nevidljivog interfejsa se mogu koristiti u grafičkom " +"interfejsu." + +#: ../doc/strings.py:226 +msgid "" +"* Activate SAPI5 when any other screen reader is not being run: This " +"checkbox allows to activate SAPI 5 TTS when no other screen reader is being " +"run." +msgstr "" +"* Aktiviraj SAPI5 u slučaju da nijedan čitač ekrana nije pokrenut: Ova " +"opcija dozvoljava da koristite SAPI 5 glasove kada nijedan čitač ekrana nije " +"pokrenut." + +#: ../doc/strings.py:227 +msgid "" +"* Hide GUI on launch: This allows you to configure whether TWBlue will start " +"with the GUI or the invisible interface." +msgstr "" +"* Sakrij grafičko okruženje prilikom pokretanja: Ovo izborno polje " +"dozvoljava da podesite da li će se TWBlue pokrenuti u grafičkom ili " +"nevidljivom interfejsu." + +#: ../doc/strings.py:228 +msgid "" +"* Keymap: This option allows you to change the keymap used by the program in " +"the invisible interface. The shipped keymaps are Default, Qwitter, Windows " +"10 and Chicken Nugget. The keymaps are in the \"keymaps\" folder, and you " +"can create new ones. Just create a new \".keymap\" file and change the " +"keystrokes associated with the actions, as it is done in the shipped keymaps." +msgstr "" +"* Tasterske prečice: Ovaj izborni okvir vam dozvoljava da promenite mapu " +"prečica koju koristi program u nevidljivom interfejsu. Podrazumevane mape " +"prečica su default - podrazumevana, Qwitter, Windows 10 i Chicken Nugget. " +"Mape prečica su u folderu \"keymaps\", i možete napraviti nove. Samo " +"napravite novu \".keymap\" datoteku i promenite prečice za radnje, kako je i " +"urađeno u već postojećim mapama." + +#: ../doc/strings.py:229 +msgid "#### Proxi tab" +msgstr "#### Kartica proksi" + +#: ../doc/strings.py:230 +msgid "" +"In this tab you can configure TWBlue to use a Proxy server by completing the " +"fields displayed (type, server, port, user and password)." +msgstr "" +"U ovoj kartici možete podesiti TWBlue da koristi proksi server popunjavanjem " +"prikazanih polja (vrsta, server, port, korisnik i lozinka)." + +#: ../doc/strings.py:231 +msgid "## License, source code and donations" +msgstr "## Licenca, izvorni kod i donacije" + +#: ../doc/strings.py:232 +msgid "" +"Tw Blue is free software, licensed under the GNU GPL license, either version " +"2 or, at your option, any later version. You can view the license in the " +"file named license.txt, or online at ." +msgstr "" +"Tw Blue je besplatan program, pod GNU GPL licencom, ili verzija 2 ili, u " +"zavisnosti od vaših mogućnosti, bilo koja novija verzija. Možete videti " +"licencu u datoteci license.txt, ili onlajn na lokaciji ." + +#: ../doc/strings.py:233 +msgid "" +"The source code of the program is available on GitHub at ." +msgstr "" +"Izvorni kod programa je dostupan na Githubu ." + +#: ../doc/strings.py:234 +msgid "" +"If you want to donate to the project, you can do so at . Thank you for your support!" +msgstr "" +"Ako želite da donirate za razvoj projekta, to možete uraditi na adresi " +". Hvala vam na podršci!" + +#: ../doc/strings.py:235 +msgid "## Contact" +msgstr "## Kontakt" + +#: ../doc/strings.py:236 +msgid "" +"If you still have questions after reading this document, if you wish to " +"collaborate to the project in some other way, or if you simply want to get " +"in touch with the application developer, follow the Twitter account [@tw" +"\\_blue2](https://twitter.com/tw_blue2) or [@manuelcortez00.](https://" +"twitter.com/manuelcortez00) You can also visit [our website](https://twblue." +"es)" +msgstr "" +"Ako imate još pitanja nakon što ste pročitali ovaj dokument, ako želite da " +"pomognete projektu na neki drugi način, ili ako jednostavno želite da se " +"obratite programeru aplikacije, pratite Twitter nalog [@tw\\_blue2](https://" +"twitter.com/tw_blue2) ili [@manuelcortez00.](https://twitter.com/" +"manuelcortez00) takođe možete da posetite [naš websajt](https://twblue.es)" + +#: ../doc/strings.py:237 +msgid "## Credits" +msgstr "## Zahvalnost" + +#: ../doc/strings.py:238 +msgid "" +"TWBlue is developed and maintained by [Manuel Cortéz](https://twitter.com/" +"manuelcortez00) and [José Manuel Delicado](https://twitter.com/jmdaweb)." +msgstr "" +"TWBlue programiraju i održavaju [Manuel Cortéz](https://twitter.com/" +"manuelcortez00) i [José Manuel Delicado](https://twitter.com/jmdaweb)." + +#: ../doc/strings.py:239 +msgid "" +"We would also like to thank the translators of TWBlue, who have allowed the " +"spreading of the application." +msgstr "" +"Takođe bismo želeli da se zahvalimo prevodiocima aplikacije TWBlue, koji su " +"dozvolili da se aplikacija proširi." + +#: ../doc/strings.py:240 +msgid "" +"* Arabic: [Mohammed Al Shara,](https://twitter.com/mohammed0204) [Hatoun " +"Felemban](https://twitter.com/HatounFelemban)" +msgstr "" +"* Arapski: [Mohammed Al Shara,](https://twitter.com/mohammed0204) [Hatoun " +"Felemban](https://twitter.com/HatounFelemban)" + +#: ../doc/strings.py:241 +msgid "* Basque: [Sukil Etxenike](https://twitter.com/sukil2011)." +msgstr "* Baskijski: [Sukil Etxenike](https://twitter.com/sukil2011)." + +#: ../doc/strings.py:242 +msgid "* Catalan: [Francisco Torres](https://twitter.com/ftgalleg)" +msgstr "* Katalonski: [Francisco Torres](https://twitter.com/ftgalleg)" + +#: ../doc/strings.py:243 +msgid "* Croatian: [Zvonimir Stanečić](https://twitter.com/zvonimirek222)." +msgstr "* Hrvatski: [Zvonimir Stanečić](https://twitter.com/zvonimirek222)." + +#: ../doc/strings.py:244 +msgid "* English: [Manuel Cortéz](https://twitter.com/manuelcortez00)." +msgstr "* Engleski: [Manuel Cortéz](https://twitter.com/manuelcortez00)." + +#: ../doc/strings.py:245 +msgid "* Finnish: [Jani Kinnunen](https://twitter.com/jani_kinnunen)." +msgstr "* Finski: [Jani Kinnunen](https://twitter.com/jani_kinnunen)." + +#: ../doc/strings.py:246 +msgid "* French: [Rémy Ruiz](https://twitter.com/blindhelp38)." +msgstr "* Francuski: [Rémy Ruiz](https://twitter.com/blindhelp38)." + +#: ../doc/strings.py:247 +msgid "* Galician: [Juan Buño](https://twitter.com/Quetzatl_)." +msgstr "* Galski: [Juan Buño](https://twitter.com/Quetzatl_)." + +#: ../doc/strings.py:248 +msgid "* German: [Steffen Schultz](https://twitter.com/schulle4u)." +msgstr "* Nemački: [Steffen Schultz](https://twitter.com/schulle4u)." + +#: ../doc/strings.py:249 +msgid "* Hungarian: Robert Osztolykan." +msgstr "* Mađarski: Robert Osztolykan." + +#: ../doc/strings.py:250 +msgid "* Italian: [Christian Leo Mameli](https://twitter.com/llajta2012)." +msgstr "* Italijanski: [Christian Leo Mameli](https://twitter.com/llajta2012)." + +#: ../doc/strings.py:251 +msgid "* Japanese: [Riku](https://twitter.com/_riku02)" +msgstr "* Japanski: [Riku](https://twitter.com/_riku02)" + +#: ../doc/strings.py:252 +msgid "* Polish: [Pawel Masarczyk.](https://twitter.com/Piciok)" +msgstr "* Poljski: [Pawel Masarczyk.](https://twitter.com/Piciok)" + +#: ../doc/strings.py:253 +msgid "* Portuguese: [Odenilton Júnior Santos.](https://twitter.com/romaleif)" +msgstr "" +"* Portugalski: [Odenilton Júnior Santos.](https://twitter.com/romaleif)" + +#: ../doc/strings.py:254 +msgid "" +"* Romanian: [Florian Ionașcu](https://twitter.com/florianionascu7) and " +"[Nicușor Untilă](https://twitter.com/dj_storm2001)" +msgstr "" +"* Rumunski: [Florian Ionașcu](https://twitter.com/florianionascu7) i " +"[Nicușor Untilă](https://twitter.com/dj_storm2001)" + +#: ../doc/strings.py:255 +msgid "" +"* Russian: [Наталья Хедлунд](https://twitter.com/Lifestar_n) and [Валерия " +"Кузнецова](https://twitter.com/ValeriaK305)." +msgstr "" +"* Ruski: [Наталья Хедлунд](https://twitter.com/Lifestar_n) i [Валерия " +"Кузнецова](https://twitter.com/ValeriaK305)." + +#: ../doc/strings.py:256 +msgid "* Serbian: [Aleksandar Đurić](https://twitter.com/sokodtreshnje)" +msgstr "* Srpski: [Aleksandar Đurić](https://twitter.com/sokodtreshnje)" + +#: ../doc/strings.py:257 +msgid "* Spanish: [Manuel Cortéz](https://twitter.com/manuelcortez00)." +msgstr "* Španski: [Manuel Cortéz](https://twitter.com/manuelcortez00)." + +#: ../doc/strings.py:258 +msgid "* Turkish: [Burak Yüksek](https://twitter.com/burakyuksek)." +msgstr "* Turski: [Burak Yüksek](https://twitter.com/burakyuksek)." + +#: ../doc/strings.py:259 +msgid "" +"Many thanks also to the people who worked on the documentation. Initially, " +"[Manuel Cortez](https://twitter.com/manuelcortez00) did the documentation in " +"Spanish, and translated to English by [Bryner Villalobos](https://twitter." +"com/Bry_StarkCR), [Robert Spangler](https://twitter.com/glasscity1837), " +"[Sussan Rey](https://twitter.com/sussanrey17), [Anibal Hernandez](https://" +"twitter.com/AnimalMetal), and [Holly Scott-Gardner](https://twitter.com/" +"CatchTheseWords). It was updated by [Sukil Etxenike](https://twitter.com/" +"sukil2011), with some valuable corrections by [Brian Hartgen](https://" +"twitter.com/brianhartgen) and [Bill Dengler](https://twitter.com/codeofdusk)." +msgstr "" +"Velika zahvalnost takođe svima koji su radili na dokumentaciji. Prvobitno, " +"[Manuel Cortez](https://twitter.com/manuelcortez00) je napisao dokumentaciju " +"na Španskom, i na Engleski su preveli [Bryner Villalobos](https://twitter." +"com/Bry_StarkCR), [Robert Spangler](https://twitter.com/glasscity1837), " +"[Sussan Rey](https://twitter.com/sussanrey17), [Anibal Hernandez](https://" +"twitter.com/AnimalMetal), i [Holly Scott-Gardner](https://twitter.com/" +"CatchTheseWords). Ažurirao ju je [Sukil Etxenike](https://twitter.com/" +"sukil2011), uz neke značajne ispravke od strane [Brian Hartgen](https://" +"twitter.com/brianhartgen) i [Bill Dengler](https://twitter.com/codeofdusk)." + +#: ../doc/strings.py:260 +msgid "------------------------------------------------------------------------" +msgstr "------------------------------------------------------------------------" + +#: ../doc/strings.py:261 +msgid "Copyright © 2013-2017. Manuel Cortéz" +msgstr "Autorsko pravo © 2013-2017. Manuel Cortéz" diff --git a/doc/locales/tr/lc_messages/twblue-changelog.mo b/doc/locales/tr/lc_messages/twblue-changelog.mo index 784f3392..e99f4917 100644 Binary files a/doc/locales/tr/lc_messages/twblue-changelog.mo and b/doc/locales/tr/lc_messages/twblue-changelog.mo differ diff --git a/doc/locales/tr/lc_messages/twblue-changelog.po b/doc/locales/tr/lc_messages/twblue-changelog.po index 34eb2b92..da26ff0d 100644 --- a/doc/locales/tr/lc_messages/twblue-changelog.po +++ b/doc/locales/tr/lc_messages/twblue-changelog.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2018-01-05 17:01+0300\n" "Last-Translator: \n" "Language-Team: \n" diff --git a/doc/locales/tr/lc_messages/twblue-documentation.mo b/doc/locales/tr/lc_messages/twblue-documentation.mo index d2dfd9ad..abe35fbd 100644 Binary files a/doc/locales/tr/lc_messages/twblue-documentation.mo and b/doc/locales/tr/lc_messages/twblue-documentation.mo differ diff --git a/doc/locales/tr/lc_messages/twblue-documentation.po b/doc/locales/tr/lc_messages/twblue-documentation.po index 5edfd06b..0d4c3d42 100644 --- a/doc/locales/tr/lc_messages/twblue-documentation.po +++ b/doc/locales/tr/lc_messages/twblue-documentation.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue documentation 0.46\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" +"POT-Creation-Date: 2019-03-17 13:34\n" "PO-Revision-Date: 2019-02-03 17:01+0300\n" "Last-Translator: Manuel Cortéz \n" "Language-Team: \n" diff --git a/doc/manual.md b/doc/manual.md index 57eb0cc0..32799859 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -1,4 +1,4 @@ -Documentation for TWBlue - 0.88 +Documentation for TWBlue ## Table of contents @@ -42,7 +42,7 @@ You can log into several Twitter accounts simultaneously. The program refers to Your default browser will open on the Twitter page to request authorisation. Enter your username and password into the appropriate edit fields if you're not already logged in, select the authorise button, and press it. -Once you've authorised your twitter account, the website will redirect you to a page which will notify you that TWBlue has been authorised successfully. Now you are able to close the page by pressing ALT+F4 which will return you to the Session Manager. On the session list, you will see a new item temporarily called "Authorised account x" -where x is a number. The session name will change once you open that session. +Once you've authorised your twitter account, the website will redirect you to a page which will notify you that TWBlue has been authorised successfully. On this page, you will be shown a code composed of several numbers that you must paste in the TWBlue authorization dialogue in order to allow the application to access your account. Once you have pasted the code in the corresponding text field, press enter to finish the account setup and go back to the session manager. On the session list, you will see a new item temporarily called "Authorised account x" -where x is a number. The session name will change once you open that session. To start running TWBlue, press the Ok button in the Session Manager dialogue. By default, the program starts all the configured sessions automatically, however, you can change this behavior. @@ -56,7 +56,7 @@ Before starting to describe TWBlue's usage, we'll explain some concepts that wil ### Buffer -A buffer is a list of items to manage the data which arrives from Twitter, after being processed by the application. When you configure a new session on TWBlue and start it, many buffers are created. Each of them may contain some of the items which this program works with: Tweets, direct messages, users, trends or events. According to the buffer you are focusing, you will be able to do different actions with these items. +A buffer is a list of items to manage the data which arrives from Twitter, after being processed by the application. When you configure a new session on TWBlue and start it, many buffers are created. Each of them may contain some of the items which this program works with: Tweets, direct messages, users, trends or. According to the buffer you are focusing, you will be able to do different actions with these items. The following is a description for every one of TWBlue's buffers and the kind of items they work with. @@ -69,17 +69,17 @@ The following is a description for every one of TWBlue's buffers and the kind of * Followers: when users follow you, you'll be able to see them on this buffer, with some of their account details. * Friends: the same as the previous buffer, but these are the users you follow. * User timelines: these are buffers you may create. They contain only the tweets by a specific user. They're used so you can see the tweets by a single person and you don't want to look all over your timeline. You may create as many as you like. -* Events: An event is anything that happens on Twitter, such as when someone follows you, when someone adds or removes one of your tweets from their likes list, or when you subscribe to a list. There are many more, but the program shows the most common ones in the events buffer so that you can easily keep track of what is happening on your account. * Lists: A list is similar to a user timeline, except that you can configure it to contain tweets from multiple users. * Search: A search buffer contains the results of a search operation. * User likes: You can have the program create a buffer containing tweets liked by a particular user. +* Followers or following timeline: You can have TWBlue create a buffer containing all users who follow, or are followed by a specific user. * Trending Topics: a trend buffer shows the top ten most used terms in a geographical region. This region may be a country or a city. Trends are updated every five minutes. -If a tweet contains a URL, you can press enter in the GUI or Control + Windows + Enter in the invisible interface to open it. If it contains audio, you can press Control + Enter or Control + Windows + Alt + Enter to play it, respectively. TWBlue will play a sound if the tweet contains the \#audio hashtag, but there may be tweets which contain audio without this. Finally, if a tweet contains geographical information, you can press Control + Windows + G in the invisible interface to retrieve it. +If a tweet contains a URL, you can press enter in the GUI or Control + Windows + Enter in the invisible interface to open it. If it contains video or audio, including live stream content, you can press Control + Enter or Control + Windows + Alt + Enter to play it, respectively. TWBlue will play a sound if the tweet contains video metadata or the \#audio hashtag, but there may be tweets which contain media without this. Finally, if a tweet contains geographical information, you can press Control + Windows + G in the invisible interface to retrieve it. ### Username fields -These fields accept a Twitter username (without the at sign) as the input. They are present in the send direct message and the user actions dialogue boxes. Those dialogues will be discussed later. The initial value of these fields depends on where they were opened from. They are prepopulated with the username of the sender of the focused tweet (if they were opened from the home and sent timelines, from users' timelines or from lists), the sender of the focused direct message (if from the received or sent direct message buffers) or in the focused user (if from the followers' or friends' buffer). If one of those dialogue boxes is opened from a tweet, and if there are more users mentioned in it, you can use the arrow keys to switch between them. Alternatively, you can also type a username. +These fields accept a Twitter username (without the at sign) as the input. They are present in the send direct message, the user actions dialogue and the user alias dialogue boxes, to name a few examples. Those dialogues will be discussed later. The initial value of these fields depends on where they were opened from. They are prepopulated with the username of the sender of the focused tweet (if they were opened from the home and sent timelines, from users' timelines or from lists), the sender of the focused direct message (if from the received or sent direct message buffers) or in the focused user (if from the followers' or friends' buffer). If one of those dialogue boxes is opened from a tweet, and if there are more users mentioned in it, you can use the arrow keys to switch between them. Alternatively, you can also type a username. ## The program's interfaces @@ -98,9 +98,9 @@ In summary, the GUI contains two core components. These are the controls you wil #### Buttons in the application -* Tweet: this button opens up a dialogue box to write your tweet. Normal tweets must not exceed 280 characters. However you can press the long tweet checkbox and your tweet will be posted throught Twishort, wich will allow you to write longer tweets (10000 characters). If you write past this limit, a sound will play to warn you. Note that the character count is displayed in the title bar. You may use the shorten and expand URL buttons to comply with the character limit. You can upload a picture, check spelling, attach audio or translate your message by selecting one of the available buttons in the dialogue box. In addition, you can autocomplete the entering of users by pressing Alt + C or the button for that purpose if you have the database of users configured. Press enter to send the tweet. If all goes well, you'll hear a sound confirming it. Otherwise, the screen reader will speak an error message in English describing the problem. +* Tweet: this button opens up a dialogue box to write your tweet. Normal tweets must not exceed 280 characters. However you can press the long tweet checkbox and your tweet will be posted throught Twishort, wich will allow you to write longer tweets (10000 characters). If you write past this limit, a sound will play to warn you. Note that the character count is displayed in the title bar. You can upload a picture, check spelling, attach audio or translate your message by selecting one of the available buttons in the dialogue box. In addition, you can autocomplete the entering of users by pressing Alt + C or the button for that purpose if you have the database of users configured. Press enter to send the tweet. If all goes well, you'll hear a sound confirming it. Otherwise, the screen reader will speak an error message in English describing the problem. * Retweet: this button retweets the message you're reading. After you press it, if you haven't configured the application not to do so, you'll be asked if you want to add a comment or simply send it as written. If you choose to add a comment, it will post a quoted tweet, that is, the comment with a link to the originating tweet. -* Reply: when you're viewing a tweet, you can reply to the user who sent it by pressing this button. A dialogue will open up similar to the one for tweeting. If there are more users referred to in the tweet, you can press tab and activate the mention to all checkbox, or enabling checkbox for the users you want to mention separately. When you're on the friends or followers lists, the button will be called mention instead. +* Reply: when you're viewing a tweet, you can reply to the user who sent it by pressing this button. A dialogue will open up similar to the one for tweeting. If there are more users referred to in the tweet, you can press tab and activate the mention to all checkbox, or enabling checkbox for the users you want to mention separately. Note, however, that sometimes -especially when replying to a retweet or quoted tweet, the user who made the retweet or quote may also be mentioned. This is done by Twitter automatically. When you're on the friends or followers lists, the button will be called mention instead. * Direct message: exactly like sending a tweet, but it's a private message which can only be read by the user you send it to. Press shift-tab twice to see the recipient. If there were other users mentioned in the tweet you were reading, you can arrow up or down to choose which one to send it to, or write the username yourself without the at sign. In addition, you can autocomplete the entering of users by pressing Alt + C or the button for that purpose if you have the database of users configured. Bear in mind that buttons will appear according to which actions are possible on the list you are browsing. For example, on the home timeline, mentions, sent, likes and user timelines you will see the four buttons, while on the direct messages list you'll only get the direct message and tweet buttons, and on friends and followers lists the direct message, tweet, and mention buttons will be available. @@ -116,6 +116,7 @@ Visually, Towards the top of the main application window, can be found a menu ba * Hide window: turns off the Graphical User Interface. Read the section on the invisible interface for further details. * Search: shows a dialogue box where you can search for tweets or users on Twitter. * Lists Manager: This dialogue box allows you to manage your Twitter lists. In order to use them, you must first create them. Here, you can view, edit, create, delete or, optionally, open them in buffers similar to user timelines. +* Manage user aliases: Opens up a dialogue where you can manage user aliases for the active session. In this dialog you can add new aliases, as well as edit and delete existing ones. * Edit keystrokes: this opens a dialogue where you can see and edit the shortcuts used in the invisible interface. * Account settings: Opens a dialogue box which lets you customize settings for the current account. * Global settings: Opens a dialogue which lets you configure settings for the entire application. @@ -145,6 +146,7 @@ Visually, Towards the top of the main application window, can be found a menu ba * Ignore tweets from this client: Adds the client from which the focused tweet was sent to the ignored clients list. * View timeline: Lets you open a user's timeline by choosing the user in a dialog box. It is created when you press enter. If you invoke this option relative to a user that has no tweets, the operation will fail. If you try creating an existing timeline the program will warn you and will not create it again. * Direct message: same action as the button. +* Add Alias: An user alias 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. This feature works only if you have set display screen names unchecked, in account settings. * Add to List: In order to see someone's tweets in one or more of your lists, you must add them first. In the dialogue box that opens after selecting the user, you will be asked to select the list you wish to add the user to. Thereafter, the list will contain a new member and their tweets will be displayed there. * Remove from list: lets you remove a user from a list. * View lists: Shows the lists created by a specified user. @@ -153,8 +155,12 @@ Visually, Towards the top of the main application window, can be found a menu ba ##### Buffer menu +* Update buffer: Retrieves the newest items for the focused buffer. Normally, every buffer gets updated every couple of minutes, however you can force a specific buffer to be updated inmediately. Take into account, however, that the usage of this option repeatedly might exceed your allowed Twitter's API usage, in which case you would have to wait until it gets reset, tipycally within the next 15 minutes. * New trending topics buffer: This opens a buffer to get the worlwide trending topics or those of a country or a city. You'll be able to select from a dialogue box if you wish to retrieve countries' trends, cities' trends or worldwide trends (this option is in the cities' list) and choose one from the selected list. The trending topics buffer will be created once the "OK" button has been activated within the dialogue box. Remember this kind of buffer will be updated every five minutes. * Load previous items: This allows more items to be loaded for the specified buffer. +* Create filter: Creates a filter in the current buffer. Filters allow loading or ignoring tweets that meet certain conditions into a buffer. You can, for example, set a filter in the "home" buffer that loads tweets that are in English language only. By default, the filter creation dialog will place the focus on the field to name the filter. Currently, you can filter by word, by language, or both. In the filter by word, you can make TWBlue allow or ignore tweets with the desired word. In the filter by language, you can make the program load tweets in the languages you want, or ignore tweets written in certain languages. Once created, every filter will be saved in the session config and will be kept across application restarts. +* Manage filters: Opens up a dialogue which allows you to delete filters for the current session. +* Find a string in the currently focused buffer: Opens a dialogue where you can search for items in the current buffer. * Mute: Mutes notifications of a particular buffer so you will not hear when new tweets arrive. * autoread: When enabled, the screen reader or SAPI 5 Text to Speech voice (if enabled) will read the text of incoming tweets. Please note that this could get rather chatty if there are a lot of incoming tweets. * Clear buffer: Deletes all items from the buffer. @@ -173,6 +179,8 @@ Visually, Towards the top of the main application window, can be found a menu ba * What's new in this version?: opens up a document with the list of changes from the current version to the earliest. * Check for updates: every time you open the program it automatically checks for new versions. If an update is available, it will ask you if you want to download the update. If you accept, the updating process will commence. When complete, TWBlue will be restarted. This item checks for new updates without having to restart the application. * TWBlue's website: visit our [home page](http://twblue.es) where you can find all relevant information and downloads for TWBlue and become a part of the community. +* Get soundpacks for TWBlue: +* Make a Donation: Opens a website from which you can donate to the TWBlue project. Donations are made through paypal and you don't need an account to donate. * About TWBlue: shows the credits of the program. ### The invisible user interface @@ -350,4 +358,4 @@ Many thanks also to the people who worked on the documentation. Initially, [Manu ------------------------------------------------------------------------ -Copyright © 2013-2017. Manuel Cortéz \ No newline at end of file +Copyright © 2013-2021. Manuel Cortéz \ No newline at end of file diff --git a/mysc/keys/api_keys.c b/mysc/keys/api_keys.c index a3c5ad09..f07628c9 100644 --- a/mysc/keys/api_keys.c +++ b/mysc/keys/api_keys.c @@ -5,19 +5,6 @@ return "key\0"; char *get_api_secret(){ return "secret_key\0"; } -char *get_dropbox_api_key(){ -return "key\0"; -} -char *get_dropbox_api_secret(){ -return "secret_key\0"; -} char *get_twishort_api_key(){ return "key\0"; } -char *get_bts_user(){ -return "user\0"; -} -char *get_bts_password(){ -return "pass\0"; -} - diff --git a/mysc/keys/api_keys.h b/mysc/keys/api_keys.h index 963403ce..9073733d 100644 --- a/mysc/keys/api_keys.h +++ b/mysc/keys/api_keys.h @@ -3,10 +3,6 @@ char *get_api_key(); char *get_api_secret(); -char *get_dropbox_api_key(); -char *get_dropbox_api_secret(); char *get_twishort_api_key(); -char *get_bts_user(); -char *get_bts_password(); #endif diff --git a/requirements.txt b/requirements.txt index 6bf36fff..576a6522 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,27 +9,46 @@ oauthlib requests-oauthlib requests-toolbelt pypubsub -pygeocoder +geopy arrow python-dateutil futures winpaths PySocks win_inet_pton -yandex.translate +# Install the latest RC of this lib +# see https://github.com/ssut/py-googletrans/issues/234 +googletrans==4.0.0-rc1 idna<3,>=2.5 chardet urllib3 youtube-dl python-vlc pypiwin32 +pywin32 certifi backports.functools_lru_cache cx_freeze tweepy twitter-text-parser pyenchant -git+https://github.com/manuelcortez/libloader -git+https://github.com/manuelcortez/platform_utils -git+https://github.com/manuelcortez/accessible_output2 -git+https://github.com/jmdaweb/sound_lib \ No newline at end of file +sqlitedict +cx-Logging +h11 +h2 +hpack +hstspreload +httpcore +httpx +hyperframe +rfc3986 +sniffio +attrs +importlib-metadata +numpy +pillow +charset-normalizer +git+https://github.com/accessibleapps/libloader +git+https://github.com/accessibleapps/platform_utils +git+https://github.com/accessibleapps/accessible_output2 +git+https://github.com/accessibleapps/sound_lib \ No newline at end of file diff --git a/scripts/make_archive.py b/scripts/make_archive.py new file mode 100644 index 00000000..4f967183 --- /dev/null +++ b/scripts/make_archive.py @@ -0,0 +1,12 @@ +import shutil +import os +import sys + +def create_archive(): + os.chdir("..\\src") + print("Creating zip archive...") + folder = "dist" + shutil.make_archive("twblue", "zip", folder) + os.chdir("..\\scripts") + +create_archive() \ No newline at end of file diff --git a/scripts/twblue.nsi b/scripts/twblue.nsi index eca410c0..9f1bfe95 100644 --- a/scripts/twblue.nsi +++ b/scripts/twblue.nsi @@ -14,11 +14,11 @@ SetCompress auto SetCompressor /solid lzma SetDatablockOptimize on VIAddVersionKey ProductName "TWBlue" -VIAddVersionKey LegalCopyright "Copyright 2018 Manuel Cortéz." -VIAddVersionKey ProductVersion "0.95" -VIAddVersionKey FileVersion "0.95" -VIProductVersion "0.95.0.0" -VIFileVersion "0.95.0.0" +VIAddVersionKey LegalCopyright "Copyright 2014-2021 Manuel Cortéz." +VIAddVersionKey ProductVersion "0.95.0" +VIAddVersionKey FileVersion "0.95.0" +VIProductVersion "0.95.0" +VIFileVersion "0.95.0" !insertmacro MUI_PAGE_WELCOME !define MUI_LICENSEPAGE_RADIOBUTTONS !insertmacro MUI_PAGE_LICENSE "license.txt" @@ -27,12 +27,12 @@ var StartMenuFolder !insertmacro MUI_PAGE_STARTMENU startmenu $StartMenuFolder !insertmacro MUI_PAGE_INSTFILES !define MUI_FINISHPAGE_LINK "Visit TWBlue website" -!define MUI_FINISHPAGE_LINK_LOCATION "http://twblue.es" +!define MUI_FINISHPAGE_LINK_LOCATION "https://twblue.es" !define MUI_FINISHPAGE_RUN "$INSTDIR\TWBlue.exe" !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "Spanish" !insertmacro MUI_LANGUAGE "Italian" @@ -73,9 +73,9 @@ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "U 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" "0.95" -WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "URLInfoAbout" "http://twblue.es" +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" 95 +WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "VersionMinor" 0 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\twblue" "NoRepair" 1 SectionEnd diff --git a/scripts/upload.py b/scripts/upload.py new file mode 100644 index 00000000..b3460158 --- /dev/null +++ b/scripts/upload.py @@ -0,0 +1,48 @@ +#! /usr/bin/env python +import sys +import os +import glob +import ftplib + +transferred=0 + +def convert_bytes(n): + K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 + if n >= P: + return '%.2fPb' % (float(n) / T) + elif n >= T: + return '%.2fTb' % (float(n) / T) + elif n >= G: + return '%.2fGb' % (float(n) / G) + elif n >= M: + return '%.2fMb' % (float(n) / M) + elif n >= K: + return '%.2fKb' % (float(n) / K) + else: + return '%d' % n + +def callback(progress): + global transferred + transferred = transferred+len(progress) + print("Uploaded {}".format(convert_bytes(transferred),)) + +ftp_server = os.environ.get("FTP_SERVER") or sys.argv[1] +ftp_username = os.environ.get("FTP_USERNAME") or sys.argv[2] +ftp_password = os.environ.get("FTP_PASSWORD") or sys.argv[3] + +print("Uploading files to the TWBlue server...") +print("Connecting to %s" % (ftp_server,)) +connection = ftplib.FTP(ftp_server) +print("Connected to FTP server {}".format(ftp_server,)) +connection.login(user=ftp_username, passwd=ftp_password) +print("Logged in successfully") +connection.cwd("web/pubs") +files = glob.glob("*.zip")+glob.glob("*.exe") +print("These files will be uploaded into the version folder: {}".format(files,)) +for file in files: + transferred = 0 + print("Uploading {}".format(file,)) + with open(file, "rb") as f: + connection.storbinary('STOR %s' % file, f, callback=callback, blocksize=1024*1024) +print("Upload completed. exiting...") +connection.quit() \ No newline at end of file diff --git a/src/Conf.defaults b/src/Conf.defaults index 4396e120..a2b3760a 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -12,6 +12,7 @@ reverse_timelines = boolean(default=False) announce_stream_status = boolean(default=True) retweet_mode = string(default="ask") persist_size = integer(default=0) +load_cache_in_memory=boolean(default=True) show_screen_names = boolean(default=False) buffer_order = list(default=list('home','mentions', 'dm', 'sent_dm', 'sent_tweets','favorites','followers','friends','blocks','muted','events')) @@ -20,7 +21,7 @@ volume = float(default=1.0) input_device = string(default="Default") output_device = string(default="Default") session_mute = boolean(default=False) -current_soundpack = string(default="default") +current_soundpack = string(default="FreakyBlue") indicate_audio = boolean(default=True) indicate_geo = boolean(default=True) indicate_img = boolean(default=True) @@ -48,3 +49,5 @@ braille_reporting = boolean(default=True) speech_reporting = boolean(default=True) [filters] + +[user-aliases] \ No newline at end of file diff --git a/src/appkeys.cp37-win32.pyd b/src/appkeys.cp37-win32.pyd new file mode 100644 index 00000000..46ae5afe Binary files /dev/null and b/src/appkeys.cp37-win32.pyd differ diff --git a/src/appkeys.cp37-win_amd64.pyd b/src/appkeys.cp37-win_amd64.pyd new file mode 100644 index 00000000..c19fc7d7 Binary files /dev/null and b/src/appkeys.cp37-win_amd64.pyd differ diff --git a/src/application.py b/src/application.py index 7e223ef6..07632f4c 100644 --- a/src/application.py +++ b/src/application.py @@ -3,20 +3,14 @@ import datetime name = 'TWBlue' short_name='twblue' -snapshot = True -if snapshot == False: - version = "0.95" - update_url = 'https://twblue.es/updates/stable.php' - mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json' -else: - version = "3" - update_url = 'https://twblue.es/updates/snapshot.php' - mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json' +update_url = 'https://twblue.es/updates/updates.php' +mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/updates.json' authors = ["Manuel Cortéz", "José Manuel Delicado"] authorEmail = "manuel@manuelcortez.net" -copyright = "Copyright (C) 2013-2018, Manuel cortéz." +copyright = "Copyright (C) 2013-2021, Manuel cortéz." description = name+" is an app designed to use Twitter simply and efficiently while using minimal system resources. This app provides access to most Twitter features." -translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (Arabic)", "Francisco Torres (Catalan)", "Manuel cortéz (Spanish)", "Sukil Etxenike Arizaleta (Basque)", "Jani Kinnunen (finnish)", "Rémy Ruiz (French)", "Juan Buño (Galician)", "Steffen Schultz (German)", "Zvonimir Stanečić (Croatian)", "Robert Osztolykan (Hungarian)", "Christian Leo Mameli (Italian)", "Riku (Japanese)", "Paweł Masarczyk (Polish)", "Odenilton Júnior Santos (Portuguese)", "Florian Ionașcu, Nicușor Untilă (Romanian)", "Natalia Hedlund, Valeria Kuznetsova (Russian)", "Aleksandar Đurić (Serbian)", "Burak Yüksek (Turkish)"] +translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (Arabic)", "Francisco Torres (Catalan)", "Manuel cortéz (Spanish)", "Sukil Etxenike Arizaleta (Basque)", "Jani Kinnunen (finnish)", "Oreonan (Français)", "Juan Buño (Galician)", "Steffen Schultz (German)", "Zvonimir Stanečić (Croatian)", "Robert Osztolykan (Hungarian)", "Christian Leo Mameli (Italian)", "Riku (Japanese)", "Paweł Masarczyk (Polish)", "Odenilton Júnior Santos (Portuguese)", "Florian Ionașcu, Nicușor Untilă (Romanian)", "Natalia Hedlund, Valeria Kuznetsova (Russian)", "Aleksandar Đurić (Serbian)", "Burak Yüksek (Turkish)"] url = u"https://twblue.es" report_bugs_url = "https://github.com/manuelcortez/twblue/issues" -supported_languages = [] \ No newline at end of file +supported_languages = [] +version = "11" diff --git a/src/audio_services/__init__.py b/src/audio_services/__init__.py index 4d092b4c..d33809cb 100644 --- a/src/audio_services/__init__.py +++ b/src/audio_services/__init__.py @@ -2,22 +2,22 @@ from __future__ import unicode_literals from functools import wraps def matches_url(url): - def url_setter(func): - @wraps(func) - def internal_url_setter(*args, **kwargs): - return func(*args, **kwargs) - internal_url_setter.url = url - return internal_url_setter - return url_setter + def url_setter(func): + @wraps(func) + def internal_url_setter(*args, **kwargs): + return func(*args, **kwargs) + internal_url_setter.url = url + return internal_url_setter + return url_setter def find_url_transformer(url): - from audio_services import services - funcs = [] - for i in dir(services): - possible = getattr(services, i) - if callable(possible) and hasattr(possible, 'url'): - funcs.append(possible) - for f in funcs: - if url.lower().startswith(f.url.lower()): - return f - return services.convert_generic_audio + from audio_services import services + funcs = [] + for i in dir(services): + possible = getattr(services, i) + if callable(possible) and hasattr(possible, 'url'): + funcs.append(possible) + for f in funcs: + if url.lower().startswith(f.url.lower()): + return f + return services.convert_generic_audio diff --git a/src/audio_services/services.py b/src/audio_services/services.py index eefde7d5..b19ab68d 100644 --- a/src/audio_services/services.py +++ b/src/audio_services/services.py @@ -5,37 +5,37 @@ from . import youtube_utils @matches_url('https://audioboom.com') def convert_audioboom(url): - if "audioboom.com" not in url.lower(): - raise TypeError('%r is not a valid URL' % url) - audio_id = url.split('.com/')[-1] - return 'https://audioboom.com/%s.mp3' % audio_id + if "audioboom.com" not in url.lower(): + raise TypeError('%r is not a valid URL' % url) + audio_id = url.split('.com/')[-1] + return 'https://audioboom.com/%s.mp3' % audio_id @matches_url ('https://soundcloud.com/') def convert_soundcloud (url): - client_id = "df8113ca95c157b6c9731f54b105b473" - with requests.get('http://api.soundcloud.com/resolve.json', client_id=client_id, url=url) as permalink: - if permalink.status_code==404: - raise TypeError('%r is not a valid URL' % permalink.url) - else: - resolved_url = permalink.url - with requests.get(resolved_url) as track_url: - track_data = track_url.json() + client_id = "df8113ca95c157b6c9731f54b105b473" + with requests.get('http://api.soundcloud.com/resolve.json', client_id=client_id, url=url) as permalink: + if permalink.status_code==404: + raise TypeError('%r is not a valid URL' % permalink.url) + else: + resolved_url = permalink.url + with requests.get(resolved_url) as track_url: + track_data = track_url.json() - if track_data ['streamable']: - return track_data ['stream_url'] + "?client_id=%s" %client_id - else: - raise TypeError('%r is not streamable' % url) + if track_data ['streamable']: + return track_data ['stream_url'] + "?client_id=%s" %client_id + else: + raise TypeError('%r is not streamable' % url) @matches_url ('https://www.youtube.com/watch') def convert_youtube_long (url): - return youtube_utils.get_video_url(url) + return youtube_utils.get_video_url(url) @matches_url ('http://anyaudio.net/listen') def convert_anyaudio(url): - values = url.split("audio=") - if len(values) != 2: - raise TypeError('%r is not streamable' % url) - return "http://anyaudio.net/audiodownload?audio=%s" % (values[1],) + values = url.split("audio=") + if len(values) != 2: + raise TypeError('%r is not streamable' % url) + return "http://anyaudio.net/audiodownload?audio=%s" % (values[1],) def convert_generic_audio(url): - return url + return url diff --git a/src/audio_services/youtube_utils.py b/src/audio_services/youtube_utils.py index 3c4430a9..7341cfbf 100644 --- a/src/audio_services/youtube_utils.py +++ b/src/audio_services/youtube_utils.py @@ -3,11 +3,11 @@ from __future__ import unicode_literals import youtube_dl def get_video_url(url): - ydl = youtube_dl.YoutubeDL({'quiet': True, 'format': 'bestaudio/best', 'outtmpl': u'%(id)s%(ext)s'}) - with ydl: - result = ydl.extract_info(url, download=False) - if 'entries' in result: - video = result['entries'][0] - else: - video = result - return video["formats"][0]["url"] + ydl = youtube_dl.YoutubeDL({'quiet': True, 'format': 'bestaudio/best', 'outtmpl': u'%(id)s%(ext)s'}) + with ydl: + result = ydl.extract_info(url, download=False) + if 'entries' in result: + video = result['entries'][0] + else: + video = result + return video["formats"][0]["url"] diff --git a/src/config.py b/src/config.py index a7e94eb6..1954c628 100644 --- a/src/config.py +++ b/src/config.py @@ -15,14 +15,14 @@ keymap=None changed_keymap = False def setup (): - global app - log.debug("Loading global app settings...") - app = config_utils.load_config(os.path.join(paths.config_path(), MAINFILE), os.path.join(paths.app_path(), MAINSPEC)) - log.debug("Loading keymap...") - global keymap - if float(platform.version()[:2]) >= 10 and app["app-settings"]["load_keymap"] == "default.keymap": - app["app-settings"]["load_keymap"] = "Windows 10.keymap" - app.write() - global changed_keymap - changed_keymap = True - keymap = config_utils.load_config(os.path.join(paths.config_path(), "keymap.keymap"), os.path.join(paths.app_path(), "keymaps/"+app['app-settings']['load_keymap']), copy=False) + global app + log.debug("Loading global app settings...") + app = config_utils.load_config(os.path.join(paths.config_path(), MAINFILE), os.path.join(paths.app_path(), MAINSPEC)) + log.debug("Loading keymap...") + global keymap + if float(platform.version()[:2]) >= 10 and app["app-settings"]["load_keymap"] == "default.keymap": + app["app-settings"]["load_keymap"] = "Windows 10.keymap" + app.write() + global changed_keymap + changed_keymap = True + keymap = config_utils.load_config(os.path.join(paths.config_path(), "keymap.keymap"), os.path.join(paths.app_path(), "keymaps/"+app['app-settings']['load_keymap']), copy=False) diff --git a/src/config_utils.py b/src/config_utils.py index a680e017..4861827c 100644 --- a/src/config_utils.py +++ b/src/config_utils.py @@ -10,70 +10,70 @@ log = getLogger("config_utils") class ConfigLoadError(Exception): pass def load_config(config_path, configspec_path=None, copy=True, *args, **kwargs): - spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True) - try: - config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs) - except ParseError: - raise ConfigLoadError("Unable to load %r" % config_path) - validator = Validator() - validated = config.validate(validator, preserve_errors=False, copy=copy) - if validated == True: - config.write() - return config - else: - log.exception("Error in config file: {0}".format(validated,)) - commonMessageDialogs.invalid_configration() + spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True) + try: + config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs) + except ParseError: + raise ConfigLoadError("Unable to load %r" % config_path) + validator = Validator() + validated = config.validate(validator, preserve_errors=False, copy=copy) + if validated == True: + config.write() + return config + else: + log.exception("Error in config file: {0}".format(validated,)) + commonMessageDialogs.invalid_configuration() def is_blank(arg): - "Check if a line is blank." - for c in arg: - if c not in string.whitespace: - return False - return True + "Check if a line is blank." + for c in arg: + if c not in string.whitespace: + return False + return True def get_keys(path): - "Gets the keys of a configobj config file." - res=[] - fin=open(path) - for line in fin: - if not is_blank(line): - res.append(line[0:line.find('=')].strip()) - fin.close() - return res + "Gets the keys of a configobj config file." + res=[] + fin=open(path) + for line in fin: + if not is_blank(line): + res.append(line[0:line.find('=')].strip()) + fin.close() + return res def hist(keys): - "Generates a histogram of an iterable." - res={} - for k in keys: - res[k]=res.setdefault(k,0)+1 - return res + "Generates a histogram of an iterable." + res={} + for k in keys: + res[k]=res.setdefault(k,0)+1 + return res def find_problems(hist): - "Takes a histogram and returns a list of items occurring more than once." - res=[] - for k,v in hist.items(): - if v>1: - res.append(k) - return res + "Takes a histogram and returns a list of items occurring more than once." + res=[] + for k,v in hist.items(): + if v>1: + res.append(k) + return res def clean_config(path): - "Cleans a config file. If duplicate values are found, delete all of them and just use the default." - orig=[] - cleaned=[] - fin=open(path) - for line in fin: - orig.append(line) - fin.close() - for p in find_problems(hist(get_keys(path))): - for o in orig: - o.strip() - if p not in o: - cleaned.append(o) - if len(cleaned) != 0: - cam=open(path,'w') - for c in cleaned: - cam.write(c) - cam.close() - return True - else: - return False \ No newline at end of file + "Cleans a config file. If duplicate values are found, delete all of them and just use the default." + orig=[] + cleaned=[] + fin=open(path) + for line in fin: + orig.append(line) + fin.close() + for p in find_problems(hist(get_keys(path))): + for o in orig: + o.strip() + if p not in o: + cleaned.append(o) + if len(cleaned) != 0: + cam=open(path,'w') + for c in cleaned: + cam.write(c) + cam.close() + return True + else: + return False diff --git a/src/controller/attach.py b/src/controller/attach.py deleted file mode 100644 index 666e55f3..00000000 --- a/src/controller/attach.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import object -import os -import widgetUtils -import logging -from wxUI.dialogs import attach as gui -log = logging.getLogger("controller.attach") - -class attach(object): - def __init__(self): - self.attachments = list() - self.dialog = gui.attachDialog() - widgetUtils.connect_event(self.dialog.photo, widgetUtils.BUTTON_PRESSED, self.upload_image) - widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment) - self.dialog.get_response() - log.debug("Attachments controller started.") - - def upload_image(self, *args, **kwargs): - image, description = self.dialog.get_image() - if image != None: - imageInfo = {"type": "photo", "file": image, "description": description} - log.debug("Image data to upload: %r" % (imageInfo,)) - self.attachments.append(imageInfo) - info = [_(u"Photo"), description] - self.dialog.attachments.insert_item(False, *info) - self.dialog.remove.Enable(True) - - def remove_attachment(self, *args, **kwargs): - current_item = self.dialog.attachments.get_selected() - log.debug("Removing item %d" % (current_item,)) - if current_item == -1: current_item = 0 - self.attachments.pop(current_item) - self.dialog.attachments.remove_item(current_item) - self.check_remove_status() - log.debug("Removed") - - def check_remove_status(self): - if len(self.attachments) == 0 and self.dialog.attachments.get_count() == 0: - self.dialog.remove.Enable(False) diff --git a/src/controller/buffers/__init__.py b/src/controller/buffers/__init__.py index 2900a6e9..10e8971c 100644 --- a/src/controller/buffers/__init__.py +++ b/src/controller/buffers/__init__.py @@ -1,8 +1,3 @@ # -*- coding: utf-8 -*- -""" this package contains logic related to buffers. A buffer is a virtual representation of a group of items retrieved through the Social network API'S. - Ideally, new social networks added to TWBlue will have its own "buffers", and these buffers should be defined within this package, following the Twitter example. - Currently, the package contains the following modules: - * baseBuffers: Define a set of functions and structure to be expected in all buffers. New buffers should inherit its classes from one of the classes present here. - * twitterBuffers: All other code, specific to Twitter. -""" -from __future__ import unicode_literals \ No newline at end of file +from . import base as base +from . import twitter as twitter \ No newline at end of file diff --git a/src/controller/buffers/base/__init__.py b/src/controller/buffers/base/__init__.py new file mode 100644 index 00000000..293bbdd8 --- /dev/null +++ b/src/controller/buffers/base/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from .account import AccountBuffer +from .base import Buffer +from .empty import EmptyBuffer \ No newline at end of file diff --git a/src/controller/buffers/base/account.py b/src/controller/buffers/base/account.py new file mode 100644 index 00000000..46ecbb6d --- /dev/null +++ b/src/controller/buffers/base/account.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +""" Common logic to all buffers in TWBlue.""" +import logging +import config +import widgetUtils +from pubsub import pub +from wxUI import buffers +from . import base + +log = logging.getLogger("controller.buffers.base.account") + +class AccountBuffer(base.Buffer): + def __init__(self, parent, name, account, account_id): + super(AccountBuffer, self).__init__(parent, None, name) + log.debug("Initializing buffer %s, account %s" % (name, account,)) + self.buffer = buffers.accountPanel(parent, name) + self.type = self.buffer.type + self.compose_function = None + self.session = None + self.needs_init = False + self.account = account + self.buffer.account = account + self.name = name + self.account_id = account_id + + def setup_account(self): + widgetUtils.connect_event(self.buffer, widgetUtils.CHECKBOX, self.autostart, menuitem=self.buffer.autostart_account) + if self.account_id in config.app["sessions"]["ignored_sessions"]: + self.buffer.change_autostart(False) + else: + self.buffer.change_autostart(True) + if not hasattr(self, "logged"): + self.buffer.change_login(login=False) + widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.logout) + else: + self.buffer.change_login(login=True) + widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.login) + + def login(self, *args, **kwargs): + del self.logged + self.setup_account() + pub.sendMessage("login", session_id=self.account_id) + + def logout(self, *args, **kwargs): + self.logged = False + self.setup_account() + pub.sendMessage("logout", session_id=self.account_id) + + def autostart(self, *args, **kwargs): + if self.account_id in config.app["sessions"]["ignored_sessions"]: + self.buffer.change_autostart(True) + config.app["sessions"]["ignored_sessions"].remove(self.account_id) + else: + self.buffer.change_autostart(False) + config.app["sessions"]["ignored_sessions"].append(self.account_id) + config.app.write() \ No newline at end of file diff --git a/src/controller/buffers/base/base.py b/src/controller/buffers/base/base.py new file mode 100644 index 00000000..41b31219 --- /dev/null +++ b/src/controller/buffers/base/base.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +""" Common logic to all buffers in TWBlue.""" +import logging +import wx +import output +import sound +import widgetUtils + +log = logging.getLogger("controller.buffers.base.base") + +class Buffer(object): + """ A basic buffer object. This should be the base class for all other derived buffers.""" + + def __init__(self, parent=None, function=None, session=None, *args, **kwargs): + """Inits the main controller for this buffer: + @ parent wx.Treebook object: Container where we will put this buffer. + @ function str or None: function to be called periodically and update items on this buffer. + @ session sessionmanager.session object or None: Session handler for settings, database and data access. + """ + super(Buffer, self).__init__() + self.function = function + # Compose_function will be used to render an object on this buffer. Normally, signature is as follows: + # compose_function(item, db, relative_times, show_screen_names=False, session=None) + # Read more about compose functions in sessions/twitter/compose.py. + self.compose_function = None + self.args = args + self.kwargs = kwargs + # This will be used as a reference to the wx.Panel object wich stores the buffer GUI. + self.buffer = None + # This should countains the account associated to this buffer. + self.account = "" + # This controls whether the start_stream function should be called when starting the program. + self.needs_init = True + # if this is set to False, the buffer will be ignored on the invisible interface. + self.invisible = False + # Control variable, used to track time of execution for calls to start_stream. + self.execution_time = 0 + + def clear_list(self): + pass + + def get_event(self, ev): + """ Catch key presses in the WX interface and generate the corresponding event names.""" + if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown(): event = "audio" + elif ev.GetKeyCode() == wx.WXK_RETURN: event = "url" + elif ev.GetKeyCode() == wx.WXK_F5: event = "volume_down" + elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up" + elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list" + elif ev.GetKeyCode() == wx.WXK_DELETE: event = "destroy_status" + # Raise a Special event when pressed Shift+F10 because Wx==4.1.x does not seems to trigger this by itself. + # See https://github.com/manuelcortez/TWBlue/issues/353 + elif ev.GetKeyCode() == wx.WXK_F10 and ev.ShiftDown(): event = "show_menu" + else: + event = None + ev.Skip() + if event != None: + try: + ### ToDo: Remove after WX fixes issue #353 in the widgets. + if event == "show_menu": + return self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition()) + getattr(self, event)() + except AttributeError: + pass + + def volume_down(self): + """ Decreases volume by 5%""" + if self.session.settings["sound"]["volume"] > 0.0: + if self.session.settings["sound"]["volume"] <= 0.05: + self.session.settings["sound"]["volume"] = 0.0 + else: + self.session.settings["sound"]["volume"] -=0.05 + sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100.0)) + self.session.sound.play("volume_changed.ogg") + self.session.settings.write() + + def volume_up(self): + """ Increases volume by 5%.""" + if self.session.settings["sound"]["volume"] < 1.0: + if self.session.settings["sound"]["volume"] >= 0.95: + self.session.settings["sound"]["volume"] = 1.0 + else: + self.session.settings["sound"]["volume"] +=0.05 + sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100)) + self.session.sound.play("volume_changed.ogg") + self.session.settings.write() + + def start_stream(self, mandatory=False, play_sound=True): + pass + + def get_more_items(self): + output.speak(_(u"This action is not supported for this buffer"), True) + + def put_items_on_list(self, items): + pass + + def remove_buffer(self): + return False + + def remove_item(self, item): + f = self.buffer.list.get_selected() + self.buffer.list.remove_item(item) + self.buffer.list.select_item(f) + + def bind_events(self): + pass + + def get_object(self): + return self.buffer + + def get_message(self): + pass + + def set_list_position(self, reversed=False): + if reversed == False: + self.buffer.list.select_item(-1) + else: + self.buffer.list.select_item(0) + + def reply(self): + pass + + def send_message(self): + pass + + def share_item(self): + pass + + def destroy_status(self): + pass + + def post_status(self, *args, **kwargs): + pass + + def save_positions(self): + try: + self.session.db[self.name+"_pos"]=self.buffer.list.get_selected() + except AttributeError: + pass \ No newline at end of file diff --git a/src/controller/buffers/base/empty.py b/src/controller/buffers/base/empty.py new file mode 100644 index 00000000..66373d7c --- /dev/null +++ b/src/controller/buffers/base/empty.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import logging +from wxUI import buffers +from . import base + +log = logging.getLogger("controller.buffers.base.empty") + +class EmptyBuffer(base.Buffer): + def __init__(self, parent, name, account): + super(EmptyBuffer, self).__init__(parent=parent) + log.debug("Initializing buffer %s, account %s" % (name, account,)) + self.buffer = buffers.emptyPanel(parent, name) + self.type = self.buffer.type + self.compose_function = None + self.account = account + self.buffer.account = account + self.name = name + self.session = None + self.needs_init = True diff --git a/src/controller/buffers/baseBuffers.py b/src/controller/buffers/baseBuffers.py deleted file mode 100644 index 728a5e62..00000000 --- a/src/controller/buffers/baseBuffers.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- -""" Common logic to all buffers in TWBlue.""" -from __future__ import unicode_literals -from builtins import object -import logging -import wx -import output -import config -import sound -import widgetUtils -from pubsub import pub -from wxUI import buffers - -log = logging.getLogger("controller.buffers.baseBuffers") - -def _items_exist(function): - """ A decorator to execute a function only if the selected buffer contains at least one item.""" - def function_(self, *args, **kwargs): - if self.buffer.list.get_count() > 0: - function(self, *args, **kwargs) - return function_ - -class buffer(object): - """ A basic buffer object. This should be the base class for all other derived buffers.""" - - def __init__(self, parent=None, function=None, session=None, *args, **kwargs): - """Inits the main controller for this buffer: - @ parent wx.Treebook object: Container where we will put this buffer. - @ function str or None: function to be called periodically and update items on this buffer. - @ session sessionmanager.session object or None: Session handler for settings, database and data access. - """ - super(buffer, self).__init__() - self.function = function - # Compose_function will be used to render an object on this buffer. Normally, signature is as follows: - # compose_function(item, db, relative_times, show_screen_names=False, session=None) - # Read more about compose functions in twitter/compose.py. - self.compose_function = None - self.args = args - self.kwargs = kwargs - # This will be used as a reference to the wx.Panel object wich stores the buffer GUI. - self.buffer = None - # This should countains the account associated to this buffer. - self.account = "" - # This controls whether the start_stream function should be called when starting the program. - self.needs_init = True - # if this is set to False, the buffer will be ignored on the invisible interface. - self.invisible = False - # Control variable, used to track time of execution for calls to start_stream. - self.execution_time = 0 - - def clear_list(self): - pass - - def get_event(self, ev): - """ Catch key presses in the WX interface and generate the corresponding event names.""" - if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown(): event = "audio" - elif ev.GetKeyCode() == wx.WXK_RETURN: event = "url" - elif ev.GetKeyCode() == wx.WXK_F5: event = "volume_down" - elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up" - elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list" - elif ev.GetKeyCode() == wx.WXK_DELETE: event = "destroy_status" - else: - event = None - ev.Skip() - if event != None: - try: - getattr(self, event)() - except AttributeError: - pass - - def volume_down(self): - """ Decreases volume by 5%""" - if self.session.settings["sound"]["volume"] > 0.0: - if self.session.settings["sound"]["volume"] <= 0.05: - self.session.settings["sound"]["volume"] = 0.0 - else: - self.session.settings["sound"]["volume"] -=0.05 - sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100.0)) - self.session.sound.play("volume_changed.ogg") - self.session.settings.write() - - def volume_up(self): - """ Increases volume by 5%.""" - if self.session.settings["sound"]["volume"] < 1.0: - if self.session.settings["sound"]["volume"] >= 0.95: - self.session.settings["sound"]["volume"] = 1.0 - else: - self.session.settings["sound"]["volume"] +=0.05 - sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100)) - self.session.sound.play("volume_changed.ogg") - self.session.settings.write() - - def start_stream(self, mandatory=False, play_sound=True): - pass - - def get_more_items(self): - output.speak(_(u"This action is not supported for this buffer"), True) - - def put_items_on_list(self, items): - pass - - def remove_buffer(self): - return False - - def remove_item(self, item): - f = self.buffer.list.get_selected() - self.buffer.list.remove_item(item) - self.buffer.list.select_item(f) - - def bind_events(self): - pass - - def get_object(self): - return self.buffer - - def get_message(self): - pass - - def set_list_position(self, reversed=False): - if reversed == False: - self.buffer.list.select_item(-1) - else: - self.buffer.list.select_item(0) - - def reply(self): - pass - - def send_message(self): - pass - - def share_item(self): - pass - - def destroy_status(self): - pass - - def post_status(self, *args, **kwargs): - pass - - def save_positions(self): - try: - self.session.db[self.name+"_pos"]=self.buffer.list.get_selected() - except AttributeError: - pass - -class accountPanel(buffer): - def __init__(self, parent, name, account, account_id): - super(accountPanel, self).__init__(parent, None, name) - log.debug("Initializing buffer %s, account %s" % (name, account,)) - self.buffer = buffers.accountPanel(parent, name) - self.type = self.buffer.type - self.compose_function = None - self.session = None - self.needs_init = False - self.account = account - self.buffer.account = account - self.name = name - self.account_id = account_id - - def setup_account(self): - widgetUtils.connect_event(self.buffer, widgetUtils.CHECKBOX, self.autostart, menuitem=self.buffer.autostart_account) - if self.account_id in config.app["sessions"]["ignored_sessions"]: - self.buffer.change_autostart(False) - else: - self.buffer.change_autostart(True) - if not hasattr(self, "logged"): - self.buffer.change_login(login=False) - widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.logout) - else: - self.buffer.change_login(login=True) - widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.login) - - def login(self, *args, **kwargs): - del self.logged - self.setup_account() - pub.sendMessage("login", session_id=self.account_id) - - def logout(self, *args, **kwargs): - self.logged = False - self.setup_account() - pub.sendMessage("logout", session_id=self.account_id) - - def autostart(self, *args, **kwargs): - if self.account_id in config.app["sessions"]["ignored_sessions"]: - self.buffer.change_autostart(True) - config.app["sessions"]["ignored_sessions"].remove(self.account_id) - else: - self.buffer.change_autostart(False) - config.app["sessions"]["ignored_sessions"].append(self.account_id) - config.app.write() - -class emptyPanel(buffer): - def __init__(self, parent, name, account): - super(emptyPanel, self).__init__(parent=parent) - log.debug("Initializing buffer %s, account %s" % (name, account,)) - self.buffer = buffers.emptyPanel(parent, name) - self.type = self.buffer.type - self.compose_function = None - self.account = account - self.buffer.account = account - self.name = name - self.session = None - self.needs_init = True diff --git a/src/controller/buffers/twitter/__init__.py b/src/controller/buffers/twitter/__init__.py new file mode 100644 index 00000000..c893f6ba --- /dev/null +++ b/src/controller/buffers/twitter/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from .base import BaseBuffer +from .directMessages import DirectMessagesBuffer, SentDirectMessagesBuffer +from .list import ListBuffer +from .people import PeopleBuffer +from .trends import TrendsBuffer +from .search import SearchBuffer, SearchPeopleBuffer, ConversationBuffer diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py new file mode 100644 index 00000000..3ad5b77c --- /dev/null +++ b/src/controller/buffers/twitter/base.py @@ -0,0 +1,579 @@ +# -*- coding: utf-8 -*- +import time +import platform +if platform.system() == "Windows": + import wx + from wxUI import buffers, dialogs, commonMessageDialogs, menus + from controller import user +elif platform.system() == "Linux": + from gi.repository import Gtk + from gtkUI import buffers, dialogs, commonMessageDialogs +from controller import messages +import widgetUtils +import arrow +import webbrowser +import output +import config +import sound +import languageHandler +import logging +from audio_services import youtube_utils +from controller.buffers.base import base +from sessions.twitter import compose, utils, reduce +from mysc.thread_utils import call_threaded +from tweepy.errors import TweepyException +from tweepy.cursor import Cursor +from pubsub import pub +from sessions.twitter.long_tweets import twishort, tweets + +log = logging.getLogger("controller.buffers") + +def _tweets_exist(function): + """ A decorator to execute a function only if the selected buffer contains at least one item.""" + def function_(self, *args, **kwargs): + if self.buffer.list.get_count() > 0: + function(self, *args, **kwargs) + return function_ + +class BaseBuffer(base.Buffer): + def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, compose_func="compose_tweet", *args, **kwargs): + super(BaseBuffer, self).__init__(parent, function, *args, **kwargs) + log.debug("Initializing buffer %s, account %s" % (name, account,)) + if bufferType != None: + self.buffer = getattr(buffers, bufferType)(parent, name) + else: + self.buffer = buffers.basePanel(parent, name) + self.invisible = True + self.name = name + self.type = self.buffer.type + self.session = sessionObject + self.compose_function = getattr(compose, compose_func) + log.debug("Compose_function: %s" % (self.compose_function,)) + self.account = account + self.buffer.account = account + self.bind_events() + self.sound = sound + if "-timeline" in self.name or "-favorite" in self.name: + self.finished_timeline = False + # Add a compatibility layer for username based timelines from config. + # ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory. + try: + int(self.kwargs["user_id"]) + except ValueError: + self.is_screen_name = True + self.kwargs["screen_name"] = self.kwargs["user_id"] + self.kwargs.pop("user_id") + + def get_buffer_name(self): + """ Get buffer name from a set of different techniques.""" + # firstly let's take the easier buffers. + basic_buffers = dict(home_timeline=_(u"Home"), mentions=_(u"Mentions"), direct_messages=_(u"Direct messages"), sent_direct_messages=_(u"Sent direct messages"), sent_tweets=_(u"Sent tweets"), favourites=_(u"Likes"), followers=_(u"Followers"), friends=_(u"Friends"), blocked=_(u"Blocked users"), muted=_(u"Muted users")) + if self.name in list(basic_buffers.keys()): + return basic_buffers[self.name] + # Check user timelines + elif hasattr(self, "username"): + if "-timeline" in self.name: + return _(u"{username}'s timeline").format(username=self.username,) + elif "-favorite" in self.name: + return _(u"{username}'s likes").format(username=self.username,) + elif "-followers" in self.name: + return _(u"{username}'s followers").format(username=self.username,) + elif "-friends" in self.name: + return _(u"{username}'s friends").format(username=self.username,) + log.error("Error getting name for buffer %s" % (self.name,)) + return _(u"Unknown buffer") + + def post_status(self, *args, **kwargs): + title = _("Tweet") + caption = _("Write the tweet here") + tweet = messages.tweet(self.session, title, caption, "") + response = tweet.message.ShowModal() + if response == wx.ID_OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) + if hasattr(tweet.message, "destroy"): + tweet.message.destroy() + + def get_formatted_message(self): + if self.type == "dm" or self.name == "direct_messages": + return self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)[1] + return self.get_message() + + def get_message(self): + tweet = self.get_right_tweet() + return " ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) + + def get_full_tweet(self): + tweet = self.get_right_tweet() + tweetsList = [] + tweet_id = tweet.id + message = None + if hasattr(tweet, "message"): + message = tweet.message + try: + tweet = self.session.twitter.get_status(id=tweet_id, include_ext_alt_text=True, tweet_mode="extended") + tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities) + except TweepyException as e: + utils.twitter_error(e) + return + if message != None: + tweet.message = message + l = tweets.is_long(tweet) + while l != False: + tweetsList.append(tweet) + try: + tweet = self.session.twitter.get_status(id=l, include_ext_alt_text=True, tweet_mode="extended") + tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities) + except TweepyException as e: + utils.twitter_error(e) + return + l = tweets.is_long(tweet) + if l == False: + tweetsList.append(tweet) + return (tweet, tweetsList) + + def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): + # starts stream every 3 minutes. + current_time = time.time() + if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: + self.execution_time = current_time + log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type)) + log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) + if self.name != "direct_messages": + val = self.session.call_paged(self.function, *self.args, **self.kwargs) + else: + # 50 results are allowed per API call, so let's assume max value can be 50. + # reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + if self.session.settings["general"]["max_tweets_per_call"] > 50: + count = 50 + else: + count = self.session.settings["general"]["max_tweets_per_call"] + # try to retrieve the cursor for the current buffer. + try: + val = getattr(self.session.twitter, self.function)(return_cursors=True, count=count, *self.args, **self.kwargs) + if type(val) == tuple: + val, cursor = val + if type(cursor) == tuple: + cursor = cursor[1] + cursors = self.session.db["cursors"] + cursors[self.name] = cursor + self.session.db["cursors"] = cursors + results = [i for i in val] + val = results + val.reverse() + log.debug("Retrieved %d items from the cursored search on function %s." %(len(val), self.function)) + user_ids = [item.message_create["sender_id"] for item in val] + self.session.save_users(user_ids) + except TweepyException as e: + log.exception("Error %s" % (str(e))) + return + number_of_items = self.session.order_buffer(self.name, val) + log.debug("Number of items retrieved: %d" % (number_of_items,)) + self.put_items_on_list(number_of_items) + if hasattr(self, "finished_timeline") and self.finished_timeline == False: + if "-timeline" in self.name: + self.username = val[0].user.screen_name + elif "-favorite" in self.name: + self.username = self.session.api_call("get_user", **self.kwargs).screen_name + self.finished_timeline = True + if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages" and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: + self.session.sound.play(self.sound) + # Autoread settings + if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: + self.auto_read(number_of_items) + return number_of_items + + def auto_read(self, number_of_items): + if 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: + if self.session.settings["general"]["reverse_timelines"] == False: + tweet = self.session.db[self.name][-1] + else: + tweet = self.session.db[self.name][0] + output.speak(_(u"New tweet in {0}").format(self.get_buffer_name())) + output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) + 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 tweets in {1}.").format(number_of_items, self.get_buffer_name())) + + def get_more_items(self): + elements = [] + if self.session.settings["general"]["reverse_timelines"] == False: + last_id = self.session.db[self.name][0].id + else: + last_id = self.session.db[self.name][-1].id + try: + items = getattr(self.session.twitter, self.function)(max_id=last_id, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs) + except TweepyException as e: + log.exception("Error %s" % (str(e))) + return + if items == None: + return + 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, 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) + elements.append(i) + if self.session.settings["general"]["reverse_timelines"] == False: + items_db.insert(0, i) + else: + items_db.append(i) + self.session.db[self.name] = items_db + selection = self.buffer.list.get_selected() + log.debug("Retrieved %d items from cursored search in function %s." % (len(elements), self.function)) + if self.session.settings["general"]["reverse_timelines"] == False: + for i in elements: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(True, *tweet) + else: + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(False, *tweet) + self.buffer.list.select_item(selection) + output.speak(_(u"%s items retrieved") % (str(len(elements))), True) + + def remove_buffer(self, force=False): + if "-timeline" in self.name: + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-9] in self.session.settings["other_buffers"]["timelines"]: + self.session.settings["other_buffers"]["timelines"].remove(self.name[:-9]) + self.session.settings.write() + if self.name in self.session.db: + self.session.db.pop(self.name) + return True + elif dlg == widgetUtils.NO: + return False + elif "favorite" in self.name: + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-9] in self.session.settings["other_buffers"]["favourites_timelines"]: + self.session.settings["other_buffers"]["favourites_timelines"].remove(self.name[:-9]) + if self.name in self.session.db: + self.session.db.pop(self.name) + self.session.settings.write() + return True + elif dlg == widgetUtils.NO: + return False + else: + output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True) + return False + + def remove_tweet(self, id): + if type(self.session.db[self.name]) == dict: return + items = self.session.db[self.name] + for i in range(0, len(items)): + if items[i].id == id: + items.pop(i) + self.remove_item(i) + self.session.db[self.name] = items + + def put_items_on_list(self, number_of_items): + list_to_use = self.session.db[self.name] + if number_of_items == 0 and self.session.settings["general"]["persist_size"] == 0: return + log.debug("The list contains %d items " % (self.buffer.list.get_count(),)) + log.debug("Putting %d items on the list" % (number_of_items,)) + if self.buffer.list.get_count() == 0: + for i in list_to_use: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(False, *tweet) + self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) + elif self.buffer.list.get_count() > 0 and number_of_items > 0: + if self.session.settings["general"]["reverse_timelines"] == False: + items = list_to_use[len(list_to_use)-number_of_items:] + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(False, *tweet) + else: + items = list_to_use[0:number_of_items] + items.reverse() + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(True, *tweet) + log.debug("Now the list contains %d items " % (self.buffer.list.get_count(),)) + + def add_new_item(self, item): + tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + if self.session.settings["general"]["reverse_timelines"] == False: + self.buffer.list.insert_item(False, *tweet) + else: + self.buffer.list.insert_item(True, *tweet) + if 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(" ".join(tweet[:2]), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"]) + #Improve performance on Windows +# if platform.system() == "Windows": +# call_threaded(utils.is_audio,item) + + def bind_events(self): + log.debug("Binding events...") + self.buffer.set_focus_function(self.onFocus) + widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet) +# if self.type == "baseBuffer": + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.share_item, self.buffer.retweet) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.send_message, self.buffer.dm) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply) + # Replace for the correct way in other platforms. + widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu) + widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key) + + def show_menu(self, ev, pos=0, *args, **kwargs): + if self.buffer.list.get_count() == 0: return + if self.name == "sent_tweets" or self.name == "direct_messages": + menu = menus.sentPanelMenu() + elif self.name == "direct_messages": + menu = menus.dmPanelMenu() + widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) + else: + menu = menus.basePanelMenu() + widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.share_item, menuitem=menu.retweet) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.audio, menuitem=menu.play) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove) + if hasattr(menu, "openInBrowser"): + widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser) + if pos != 0: + self.buffer.PopupMenu(menu, pos) + else: + self.buffer.PopupMenu(menu, ev.GetPosition()) + + def view(self, *args, **kwargs): + pub.sendMessage("execute-action", action="view_item") + + def copy(self, *args, **kwargs): + pub.sendMessage("execute-action", action="copy_to_clipboard") + + def user_actions(self, *args, **kwargs): + pub.sendMessage("execute-action", action="follow") + + def fav(self, *args, **kwargs): + pub.sendMessage("execute-action", action="add_to_favourites") + + def unfav(self, *args, **kwargs): + pub.sendMessage("execute-action", action="remove_from_favourites") + + def delete_item_(self, *args, **kwargs): + pub.sendMessage("execute-action", action="delete_item") + + def url_(self, *args, **kwargs): + self.url() + + def show_menu_by_key(self, ev): + if self.buffer.list.get_count() == 0: + return + if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU: + self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition()) + + def get_tweet(self): + if hasattr(self.session.db[self.name][self.buffer.list.get_selected()], "retweeted_status"): + tweet = self.session.db[self.name][self.buffer.list.get_selected()].retweeted_status + else: + tweet = self.session.db[self.name][self.buffer.list.get_selected()] + return tweet + + def get_right_tweet(self): + tweet = self.session.db[self.name][self.buffer.list.get_selected()] + return tweet + + @_tweets_exist + def reply(self, *args, **kwargs): + tweet = self.get_right_tweet() + user = self.session.get_user(tweet.user) + screen_name = user.screen_name + id = tweet.id + users = utils.get_all_mentioned(tweet, self.session.db, field="screen_name") + ids = utils.get_all_mentioned(tweet, self.session.db, field="id") + # Build the window title + if len(users) < 1: + title=_("Reply to {arg0}").format(arg0=screen_name) + else: + title=_("Reply") + message = messages.reply(self.session, title, _("Reply to %s") % (screen_name,), "", users=users, ids=ids) + if message.message.ShowModal() == widgetUtils.OK: + if config.app["app-settings"]["remember_mention_and_longtweet"]: + if len(users) > 0: + config.app["app-settings"]["mention_all"] = message.message.mention_all.GetValue() + config.app.write() + tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments, poll_options=message.poll_options, poll_period=message.poll_period) + call_threaded(self.session.reply, in_reply_to_status_id=id, text=message.message.text.GetValue(), attachments=message.attachments, exclude_reply_user_ids=message.get_ids()) + if hasattr(message.message, "destroy"): message.message.destroy() + self.session.settings.write() + + @_tweets_exist + def send_message(self, *args, **kwargs): + tweet = self.get_right_tweet() + if self.type == "dm": + screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name + users = [screen_name] + elif self.type == "people": + screen_name = tweet.screen_name + users = [screen_name] + else: + screen_name = self.session.get_user(tweet.user).screen_name + users = utils.get_all_users(tweet, self.session) + dm = messages.dm(self.session, _("Direct message to %s") % (screen_name,), _("New direct message"), users) + if dm.message.ShowModal() == widgetUtils.OK: + screen_name = dm.message.cb.GetValue() + user = self.session.get_user_by_screen_name(screen_name) + recipient_id = user + text = dm.message.text.GetValue() + if len(dm.attachments) > 0: + attachment = dm.attachments[0] + else: + attachment = None + call_threaded(self.session.direct_message, text=text, recipient=recipient_id, attachment=attachment) + if hasattr(dm.message, "destroy"): dm.message.destroy() + + @_tweets_exist + def share_item(self, *args, **kwargs): + tweet = self.get_right_tweet() + id = tweet.id + if self.session.settings["general"]["retweet_mode"] == "ask": + answer = commonMessageDialogs.retweet_question(self.buffer) + if answer == widgetUtils.YES: + self._retweet_with_comment(tweet, id) + elif answer == widgetUtils.NO: + self._direct_retweet(id) + elif self.session.settings["general"]["retweet_mode"] == "direct": + self._direct_retweet(id) + else: + self._retweet_with_comment(tweet, id) + + def _retweet_with_comment(self, tweet, id): + if hasattr(tweet, "retweeted_status"): + tweet = tweet.retweeted_status + retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) + if retweet.message.ShowModal() == widgetUtils.OK: + text = retweet.message.text.GetValue() + tweet_data = dict(text=text, attachments=retweet.attachments, poll_period=retweet.poll_period, poll_options=retweet.poll_options) + tweet_data.update(quote_tweet_id=id) + call_threaded(self.session.send_tweet, *[tweet_data]) + if hasattr(retweet.message, "destroy"): + retweet.message.Destroy() + + def _direct_retweet(self, id): + item = self.session.api_call(call_name="retweet", _sound="retweet_send.ogg", id=id) + + def onFocus(self, *args, **kwargs): + tweet = self.get_tweet() + if platform.system() == "Windows" and self.session.settings["general"]["relative_times"] == True: + # fix this: + original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en") + ts = original_date.humanize(locale=languageHandler.getLanguage()) + self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts) + if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet): + self.session.sound.play("audio.ogg") + if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet): + self.session.sound.play("geo.ogg") + if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet): + self.session.sound.play("image.ogg") + + def audio(self, url='', *args, **kwargs): + if sound.URLPlayer.player.is_playing(): + return sound.URLPlayer.stop_audio() + tweet = self.get_tweet() + if tweet == None: return + urls = utils.find_urls(tweet, twitter_media=True) + if len(urls) == 1: + url=urls[0] + elif len(urls) > 1: + urls_list = dialogs.urlList.urlList() + urls_list.populate_list(urls) + if urls_list.get_response() == widgetUtils.OK: + url=urls_list.get_string() + if hasattr(urls_list, "destroy"): urls_list.destroy() + if url != '': + # try: + sound.URLPlayer.play(url, self.session.settings["sound"]["volume"]) +# except: +# log.error("Exception while executing audio method.") + +# @_tweets_exist + def url(self, url='', announce=True, *args, **kwargs): + if url == '': + tweet = self.get_tweet() + urls = utils.find_urls(tweet) + if len(urls) == 1: + url=urls[0] + elif len(urls) > 1: + urls_list = dialogs.urlList.urlList() + urls_list.populate_list(urls) + if urls_list.get_response() == widgetUtils.OK: + url=urls_list.get_string() + if hasattr(urls_list, "destroy"): urls_list.destroy() + if url != '': + if announce: + output.speak(_(u"Opening URL..."), True) + webbrowser.open_new_tab(url) + + def clear_list(self): + dlg = commonMessageDialogs.clear_list() + if dlg == widgetUtils.YES: + self.session.db[self.name] = [] + self.buffer.list.clear() + + @_tweets_exist + def destroy_status(self, *args, **kwargs): + index = self.buffer.list.get_selected() + if self.type == "events" or self.type == "people" or self.type == "empty" or self.type == "account": return + answer = commonMessageDialogs.delete_tweet_dialog(None) + if answer == widgetUtils.YES: + items = self.session.db[self.name] + try: + if self.name == "direct_messages" or self.name == "sent_direct_messages": + self.session.twitter.delete_direct_message(id=self.get_right_tweet().id) + items.pop(index) + else: + self.session.twitter.destroy_status(id=self.get_right_tweet().id) + items.pop(index) + self.buffer.list.remove_item(index) + except TweepyException: + self.session.sound.play("error.ogg") + self.session.db[self.name] = items + + @_tweets_exist + def user_details(self): + tweet = self.get_right_tweet() + if self.type == "dm": + users = [self.session.get_user(tweet.message_create["sender_id"]).screen_name] + elif self.type == "people": + users = [tweet.screen_name] + else: + users = utils.get_all_users(tweet, self.session) + dlg = dialogs.utils.selectUserDialog(title=_(u"User details"), users=users) + if dlg.get_response() == widgetUtils.OK: + user.profileController(session=self.session, user=dlg.get_user()) + if hasattr(dlg, "destroy"): dlg.destroy() + + def get_quoted_tweet(self, tweet): + quoted_tweet = self.session.twitter.get_status(id=tweet.id) + quoted_tweet.text = utils.find_urls_in_text(quoted_tweet.text, quoted_tweet.entities) + l = tweets.is_long(quoted_tweet) + id = tweets.get_id(l) + original_tweet = self.session.twitter.get_status(id=id) + 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 get_item_url(self): + tweet = self.get_tweet() + 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) \ No newline at end of file diff --git a/src/controller/buffers/twitter/directMessages.py b/src/controller/buffers/twitter/directMessages.py new file mode 100644 index 00000000..06cbed9a --- /dev/null +++ b/src/controller/buffers/twitter/directMessages.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +import platform +import widgetUtils +import arrow +import webbrowser +import output +import config +import languageHandler +import logging +from controller import messages +from sessions.twitter import compose, utils +from mysc.thread_utils import call_threaded +from tweepy.errors import TweepyException +from pubsub import pub +from wxUI import commonMessageDialogs +from . import base + +log = logging.getLogger("controller.buffers.twitter.dmBuffer") + +class DirectMessagesBuffer(base.BaseBuffer): + + def get_more_items(self): + # 50 results are allowed per API call, so let's assume max value can be 50. + # reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events + if self.session.settings["general"]["max_tweets_per_call"] > 50: + count = 50 + else: + count = self.session.settings["general"]["max_tweets_per_call"] + total = 0 + # try to retrieve the cursor for the current buffer. + cursor = self.session.db["cursors"].get(self.name) + try: + items = getattr(self.session.twitter, self.function)(return_cursors=True, cursor=cursor, count=count, *self.args, **self.kwargs) + if type(items) == tuple: + items, cursor = items + if type(cursor) == tuple: + cursor = cursor[1] + cursors = self.session.db["cursors"] + cursors[self.name] = cursor + self.session.db["cursors"] = cursors + results = [i for i in items] + items = results + log.debug("Retrieved %d items for cursored search in function %s" % (len(items), self.function)) + except TweepyException as e: + log.exception("Error %s" % (str(e))) + return + if items == None: + return + sent = [] + received = [] + sent_dms = self.session.db["sent_direct_messages"] + received_dms = self.session.db["direct_messages"] + for i in items: + if int(i.message_create["sender_id"]) == self.session.db["user_id"]: + if self.session.settings["general"]["reverse_timelines"] == False: + sent_dms.insert(0, i) + sent.append(i) + else: + sent_dms.append(i) + sent.insert(0, i) + else: + if self.session.settings["general"]["reverse_timelines"] == False: + received_dms.insert(0, i) + received.append(i) + else: + received_dms.append(i) + received.insert(0, i) + total = total+1 + self.session.db["direct_messages"] = received_dms + self.session.db["sent_direct_messages"] = sent_dms + user_ids = [item.message_create["sender_id"] for item in items] + self.session.save_users(user_ids) + pub.sendMessage("more-sent-dms", data=sent, account=self.session.db["user_name"]) + selected = self.buffer.list.get_selected() + if self.session.settings["general"]["reverse_timelines"] == True: + for i in received: + if int(i.message_create["sender_id"]) == self.session.db["user_id"]: + continue + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(True, *tweet) + self.buffer.list.select_item(selected) + else: + for i in received: + if int(i.message_create["sender_id"]) == self.session.db["user_id"]: + continue + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(True, *tweet) + output.speak(_(u"%s items retrieved") % (total), True) + + def reply(self, *args, **kwargs): + tweet = self.get_right_tweet() + screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name + message = messages.reply(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False, users=[screen_name,]) + if message.message.ShowModal() == widgetUtils.OK: + tweet_data = message.get_tweet_data() + call_threaded(self.session.send_tweet, tweet_data) + if hasattr(message.message, "destroy"): + message.message.destroy() + + def onFocus(self, *args, **kwargs): + tweet = self.get_tweet() + if platform.system() == "Windows" and self.session.settings["general"]["relative_times"] == True: + # fix this: + original_date = arrow.get(int(tweet.created_timestamp)) + ts = original_date.humanize(locale=languageHandler.getLanguage()) + self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts) + if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet): + self.session.sound.play("audio.ogg") + if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet): + self.session.sound.play("image.ogg") + + def clear_list(self): + dlg = commonMessageDialogs.clear_list() + if dlg == widgetUtils.YES: + self.session.db[self.name] = [] + self.buffer.list.clear() + + def auto_read(self, number_of_items): + if 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: + if self.session.settings["general"]["reverse_timelines"] == False: + tweet = self.session.db[self.name][-1] + else: + tweet = self.session.db[self.name][0] + output.speak(_(u"New direct message")) + output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) + 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 direct messages.").format(number_of_items,)) + + def open_in_browser(self, *args, **kwargs): + output.speak(_(u"This action is not supported in the buffer yet.")) + +class SentDirectMessagesBuffer(DirectMessagesBuffer): + + def __init__(self, *args, **kwargs): + super(SentDirectMessagesBuffer, self).__init__(*args, **kwargs) + if ("sent_direct_messages" in self.session.db) == False: + self.session.db["sent_direct_messages"] = [] + + def get_more_items(self): + output.speak(_(u"Getting more items cannot be done in this buffer. Use the direct messages buffer instead.")) + + def start_stream(self, *args, **kwargs): + pass + + def put_more_items(self, items): + if self.session.settings["general"]["reverse_timelines"] == True: + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(False, *tweet) + else: + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) + self.buffer.list.insert_item(False, *tweet) \ No newline at end of file diff --git a/src/controller/buffers/twitter/list.py b/src/controller/buffers/twitter/list.py new file mode 100644 index 00000000..a1153e6a --- /dev/null +++ b/src/controller/buffers/twitter/list.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +import platform +if platform.system() == "Windows": + from wxUI import dialogs, commonMessageDialogs +elif platform.system() == "Linux": + from gi.repository import Gtk + from gtkUI import dialogs, commonMessageDialogs +import widgetUtils +import logging +from tweepy.cursor import Cursor +from . import base + +log = logging.getLogger("controller.buffers.twitter.listBuffer") + +class ListBuffer(base.BaseBuffer): + def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, list_id=None, *args, **kwargs): + super(ListBuffer, self).__init__(parent, function, name, sessionObject, account, sound=None, bufferType=None, *args, **kwargs) + self.users = [] + self.list_id = list_id + self.kwargs["list_id"] = list_id + + def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): + self.get_user_ids() + super(ListBuffer, self).start_stream(mandatory, play_sound, avoid_autoreading) + + def get_user_ids(self): + for i in Cursor(self.session.twitter.get_list_members, list_id=self.list_id, include_entities=False, skip_status=True, count=5000).items(): + if i.id not in self.users: + self.users.append(i.id) + + def remove_buffer(self, force=False): + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-5] in self.session.settings["other_buffers"]["lists"]: + self.session.settings["other_buffers"]["lists"].remove(self.name[:-5]) + if self.name in self.session.db: + self.session.db.pop(self.name) + self.session.settings.write() + return True + elif dlg == widgetUtils.NO: + return False diff --git a/src/controller/buffers/twitter/people.py b/src/controller/buffers/twitter/people.py new file mode 100644 index 00000000..d29a46dc --- /dev/null +++ b/src/controller/buffers/twitter/people.py @@ -0,0 +1,252 @@ +# -*- coding: utf-8 -*- +import time +import platform +if platform.system() == "Windows": + from wxUI import commonMessageDialogs, menus + from controller import user +elif platform.system() == "Linux": + from gi.repository import Gtk + from gtkUI import dialogs, commonMessageDialogs +from controller import messages +import widgetUtils +import webbrowser +import output +import config +import logging +from mysc.thread_utils import call_threaded +from tweepy.errors import TweepyException +from pubsub import pub +from sessions.twitter import compose +from . import base + +log = logging.getLogger("controller.buffers.twitter.peopleBuffer") + +def _tweets_exist(function): + """ A decorator to execute a function only if the selected buffer contains at least one item.""" + def function_(self, *args, **kwargs): + if self.buffer.list.get_count() > 0: + function(self, *args, **kwargs) + return function_ + +class PeopleBuffer(base.BaseBuffer): + def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs): + super(PeopleBuffer, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs) + log.debug("Initializing buffer %s, account %s" % (name, account,)) + self.compose_function = compose.compose_followers_list + log.debug("Compose_function: %s" % (self.compose_function,)) + self.get_tweet = self.get_right_tweet + self.url = self.interact + if "-followers" in self.name or "-friends" in self.name: + self.finished_timeline = False + # Add a compatibility layer for username based timelines from config. + # ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory. + try: + int(self.kwargs["user_id"]) + except ValueError: + self.is_screen_name = True + self.kwargs["screen_name"] = self.kwargs["user_id"] + self.kwargs.pop("user_id") + + def remove_buffer(self, force=True): + if "-followers" in self.name: + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-10] in self.session.settings["other_buffers"]["followers_timelines"]: + self.session.settings["other_buffers"]["followers_timelines"].remove(self.name[:-10]) + if self.name in self.session.db: + self.session.db.pop(self.name) + self.session.settings.write() + return True + elif dlg == widgetUtils.NO: + return False + elif "-friends" in self.name: + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-8] in self.session.settings["other_buffers"]["friends_timelines"]: + self.session.settings["other_buffers"]["friends_timelines"].remove(self.name[:-8]) + if self.name in self.session.db: + self.session.db.pop(self.name) + self.session.settings.write() + return True + elif dlg == widgetUtils.NO: + return False + else: + output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True) + return False + + def onFocus(self, ev): + pass + + def get_message(self): + return " ".join(self.compose_function(self.get_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) + + def delete_item(self): pass + + @_tweets_exist + def reply(self, *args, **kwargs): + tweet = self.get_right_tweet() + screen_name = tweet.screen_name + message = messages.tweet(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False) + if message.message.ShowModal() == widgetUtils.OK: + tweet_data = message.get_tweet_data() + call_threaded(self.session.send_tweet, tweet_data) + if hasattr(message.message, "destroy"): + message.message.destroy() + + def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): + # starts stream every 3 minutes. + current_time = time.time() + if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: + self.execution_time = current_time + log.debug("Starting stream for %s buffer, %s account" % (self.name, self.account,)) + log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) + try: + val = getattr(self.session.twitter, self.function)(return_cursors=True, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs) + if type(val) == tuple: + val, cursor = val + if type(cursor) == tuple: + cursor = cursor[1] + cursors = self.session.db["cursors"] + cursors[self.name] = cursor + self.session.db["cursors"] = cursors + results = [i for i in val] + val = results + val.reverse() + log.debug("Retrieved %d items from cursored search in function %s" % (len(val), self.function)) + except TweepyException as e: + log.exception("Error %s" % (str(e))) + return + number_of_items = self.session.order_people(self.name, val) + log.debug("Number of items retrieved: %d" % (number_of_items,)) + self.put_items_on_list(number_of_items) + if hasattr(self, "finished_timeline") and self.finished_timeline == False: + self.username = self.session.api_call("get_user", **self.kwargs).screen_name + self.finished_timeline = True + if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: + self.session.sound.play(self.sound) + # Autoread settings + if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: + self.auto_read(number_of_items) + return number_of_items + + def get_more_items(self): + try: + cursor = self.session.db["cursors"].get(self.name) + items = getattr(self.session.twitter, self.function)(return_cursors=True, users=True, cursor=cursor, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs) + if type(items) == tuple: + items, cursor = items + if type(cursor) == tuple: + cursor = cursor[1] + cursors = self.session.db["cursors"] + cursors[self.name] = cursor + self.session.db["cursors"] = cursors + results = [i for i in items] + items = results + log.debug("Retrieved %d items from cursored search in function %s" % (len(items), self.function)) + except TweepyException as e: + log.exception("Error %s" % (str(e))) + return + if items == None: + return + items_db = self.session.db[self.name] + for i in items: + if self.session.settings["general"]["reverse_timelines"] == False: + items_db.insert(0, i) + else: + items_db.append(i) + self.session.db[self.name] = items_db + selected = self.buffer.list.get_selected() + if self.session.settings["general"]["reverse_timelines"] == True: + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) + self.buffer.list.insert_item(True, *tweet) + self.buffer.list.select_item(selected) + else: + for i in items: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) + self.buffer.list.insert_item(True, *tweet) + output.speak(_(u"%s items retrieved") % (len(items)), True) + + def put_items_on_list(self, number_of_items): + log.debug("The list contains %d items" % (self.buffer.list.get_count(),)) +# log.debug("Putting %d items on the list..." % (number_of_items,)) + if self.buffer.list.get_count() == 0: + for i in self.session.db[self.name]: + tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) + self.buffer.list.insert_item(False, *tweet) + self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) +# self.buffer.set_list_position() + elif self.buffer.list.get_count() > 0: + if self.session.settings["general"]["reverse_timelines"] == False: + for i in self.session.db[self.name][len(self.session.db[self.name])-number_of_items:]: + tweet = self.compose_function(i, self.session.db) + self.buffer.list.insert_item(False, *tweet) + else: + items = self.session.db[self.name][0:number_of_items] + items.reverse() + for i in items: + tweet = self.compose_function(i, self.session.db) + self.buffer.list.insert_item(True, *tweet) + log.debug("now the list contains %d items" % (self.buffer.list.get_count(),)) + + def get_right_tweet(self): + tweet = self.session.db[self.name][self.buffer.list.get_selected()] + return tweet + + def add_new_item(self, item): + tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session) + if self.session.settings["general"]["reverse_timelines"] == False: + self.buffer.list.insert_item(False, *tweet) + else: + self.buffer.list.insert_item(True, *tweet) + if 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(" ".join(tweet)) + + def clear_list(self): + dlg = commonMessageDialogs.clear_list() + if dlg == widgetUtils.YES: + self.session.db[self.name] = [] + self.session.db["cursors"][self.name] = -1 + self.buffer.list.clear() + + def interact(self): + user.profileController(self.session, user=self.get_right_tweet().screen_name) + + def show_menu(self, ev, pos=0, *args, **kwargs): + menu = menus.peoplePanelMenu() + widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details) +# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) + if hasattr(menu, "openInBrowser"): + widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser) + if pos != 0: + self.buffer.PopupMenu(menu, pos) + else: + self.buffer.PopupMenu(menu, ev.GetPosition()) + + def details(self, *args, **kwargs): + pub.sendMessage("execute-action", action="user_details") + + def auto_read(self, number_of_items): + if 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: + if self.session.settings["general"]["reverse_timelines"] == False: + tweet = self.session.db[self.name][-1] + else: + tweet = self.session.db[self.name][0] + output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) + 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 get_item_url(self, *args, **kwargs): + tweet = self.get_tweet() + url = "https://twitter.com/{screen_name}".format(screen_name=tweet.screen_name) + return url \ No newline at end of file diff --git a/src/controller/buffers/twitter/search.py b/src/controller/buffers/twitter/search.py new file mode 100644 index 00000000..55205069 --- /dev/null +++ b/src/controller/buffers/twitter/search.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +import time +import platform +import locale +if platform.system() == "Windows": + from wxUI import commonMessageDialogs +elif platform.system() == "Linux": + from gi.repository import Gtk + from gtkUI import commonMessageDialogs +import widgetUtils +import logging +from tweepy.errors import TweepyException +from . import base, people + +log = logging.getLogger("controller.buffers.twitter.searchBuffer") + +class SearchBuffer(base.BaseBuffer): + + def remove_buffer(self, force=False): + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]: + self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11]) + self.session.settings.write() + if self.name in self.session.db: + self.session.db.pop(self.name) + return True + elif dlg == widgetUtils.NO: + return False + +class SearchPeopleBuffer(people.PeopleBuffer): + """ This is identical to a normal peopleBufferController, except that uses the page parameter instead of a cursor.""" + def __init__(self, parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs): + super(SearchPeopleBuffer, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs) + if ("page" in self.kwargs) == False: + self.page = 1 + else: + self.page = self.kwargs.pop("page") + + def get_more_items(self, *args, **kwargs): + # Add 1 to the page parameter, put it in kwargs and calls to get_more_items in the parent buffer. + self.page = self.page +1 + self.kwargs["page"] = self.page + super(SearchPeopleBuffer, self).get_more_items(*args, **kwargs) + # remove the parameter again to make sure start_stream won't fetch items for this page indefinitely. + self.kwargs.pop("page") + + def remove_buffer(self, force=False): + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]: + self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11]) + self.session.settings.write() + if self.name in self.session.db: + self.session.db.pop(self.name) + return True + elif dlg == widgetUtils.NO: + return False + +class ConversationBuffer(SearchBuffer): + last_thread_id = None + last_reply_id = None + + def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False): + current_time = time.time() + if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: + self.execution_time = current_time + log.debug("Retrieving conversation. Last thread ID is {}, last reply ID is {}".format(self.last_thread_id, self.last_reply_id)) + results = self.get_replies(self.tweet) + log.debug("Retrieved {} items before filters.".format(len(results))) + number_of_items = self.session.order_buffer(self.name, results) + log.debug("Number of items retrieved: %d" % (number_of_items,)) + self.put_items_on_list(number_of_items) + if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: + self.session.sound.play(self.sound) + # Autoread settings + if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: + self.auto_read(number_of_items) + return number_of_items + + def remove_buffer(self, force=False): + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name in self.session.db: + self.session.db.pop(self.name) + return True + elif dlg == widgetUtils.NO: + return False + + def get_replies(self, tweet): + """ Try to retrieve the whole conversation for the passed object by using a mix between calls to API V1.1 and V2 """ + # firstly we would try to retrieve the whole thread, then we will get replies. + # this makes us to waste two search API calls, but there's no better option to retrieve the whole thread including replies, unfortunately. + thread_results = [] + reply_results = [] + # try to fetch conversation_id of the tweet initiating the buffer. + try: + tweet = self.session.twitter_v2.get_tweet(id=self.tweet.id, user_auth=True, tweet_fields=["conversation_id", "author_id"]) + thread_results.append(tweet.data) + except TweepyException as e: + log.exception("Error attempting to retrieve tweet conversation ID") + thread_results.append(self.tweet) + # Return earlier cause we can't do anything if we cannot fetch the object from twitter. + return thread_results + # If tweet contains a conversation_id param, let's retrieve the original tweet which started the conversation so we will have the whole reference for later. + if hasattr(tweet.data, "conversation_id") and tweet.data.conversation_id != None: + conversation_id = tweet.data.conversation_id + original_tweet = self.session.twitter_v2.get_tweet(id=tweet.data.conversation_id, user_auth=True, tweet_fields=["conversation_id", "author_id"]) + thread_results.insert(0, original_tweet.data) + else: + conversation_id = tweet.data.id + # find all tweets replying to the original thread only. Those tweets are sent by the same author who originally posted the first tweet. + try: + term = "conversation_id:{} from:{} to:{}".format(conversation_id, original_tweet.data.author_id, original_tweet.data.author_id) + thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, since_id=self.last_thread_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) + if thread_tweets.data != None: + thread_results.extend(thread_tweets.data) + # Search only replies to conversation_id. + term = "conversation_id:{}".format(conversation_id, original_tweet.data.author_id) + reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, since_id=self.last_reply_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) + if reply_tweets.data != None: + reply_results.extend(reply_tweets.data) + except TweepyException as e: + log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name)) + # convert v2 tweets in normal, V1.1 tweets so we don't have to deal with those kind of objects in our infrastructure. + # ToDo: Remove this last step once we support natively all objects fetched via Twitter API V2. + results = [] + ids = [tweet.id for tweet in thread_results] + if len(ids) > 0: + try: + thread_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") + thread_results.sort(key=lambda x: x.id) + self.last_thread_id = thread_results[-1].id + results.extend(thread_results) + except TweepyException as e: + log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) + return [] + ids = [tweet.id for tweet in reply_results] + if len(ids) > 0: + try: + reply_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") + reply_results.sort(key=lambda x: x.id) + self.last_reply_id = reply_results[-1].id + results.extend(reply_results) + except TweepyException as e: + log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) + return results + + def get_replies_v1(self, tweet): + try: + tweet = self.session.twitter.get_status(id=tweet.id, tweet_mode="extended") + except: + log.exception("Error getting tweet for making a conversation buffer.") + return [] + results = [] + results.append(tweet) + if hasattr(tweet, "in_reply_to_status_id") and tweet.in_reply_to_status_id != None: + while tweet.in_reply_to_status_id != None: + original_tweet = self.session.twitter.get_status(id=tweet.in_reply_to_status_id, tweet_mode="extended") + results.insert(0, original_tweet) + tweet = original_tweet + try: + term = "from:{} to:{}".format(tweet.user.screen_name, tweet.user.screen_name) + thread_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended") + results.extend(thread_tweets) + except TweepyException as e: + log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name)) + + try: + term = "to:{}".format(tweet.user.screen_name) + reply_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended") + ids = [t.id for t in results] + reply_tweets = [t for t in reply_tweets if hasattr(t, "in_reply_to_status_id") and t.in_reply_to_status_id in ids] + results.extend(reply_tweets) + except TweepyException as e: + log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name)) + results.sort(key=lambda x: x.id) + return results \ No newline at end of file diff --git a/src/controller/buffers/twitter/trends.py b/src/controller/buffers/twitter/trends.py new file mode 100644 index 00000000..39809df1 --- /dev/null +++ b/src/controller/buffers/twitter/trends.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +import time +import platform +if platform.system() == "Windows": + import wx + from wxUI import buffers, commonMessageDialogs, menus + from controller import user, messages +elif platform.system() == "Linux": + from gi.repository import Gtk + from gtkUI import buffers, commonMessageDialogs +from controller import messages +import widgetUtils +import output +import logging +from mysc.thread_utils import call_threaded +from tweepy.errors import TweepyException +from pubsub import pub +from controller.buffers import base + +log = logging.getLogger("controller.buffers.twitter.trends") + +class TrendsBuffer(base.Buffer): + def __init__(self, parent, name, sessionObject, account, trendsFor, *args, **kwargs): + super(TrendsBuffer, self).__init__(parent=parent, sessionObject=sessionObject) + self.trendsFor = trendsFor + self.session = sessionObject + self.account = account + self.invisible = True + self.buffer = buffers.trendsPanel(parent, name) + self.buffer.account = account + self.type = self.buffer.type + self.bind_events() + self.sound = "trends_updated.ogg" + self.trends = [] + self.name = name + self.buffer.name = name + self.compose_function = self.compose_function_ + self.get_formatted_message = self.get_message + self.reply = self.search_topic + + + def post_status(self, *args, **kwargs): + title = _("Tweet") + caption = _("Write the tweet here") + tweet = messages.tweet(self.session, title, caption, "") + response = tweet.message.ShowModal() + if response == wx.ID_OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) + if hasattr(tweet.message, "destroy"): + tweet.message.destroy() + + def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): + # starts stream every 3 minutes. + current_time = time.time() + if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: + self.execution_time = current_time + try: + data = self.session.twitter.get_place_trends(id=self.trendsFor) + except TweepyException as err: + log.exception("Error %s" % (str(err))) + if not hasattr(self, "name_"): + self.name_ = data[0]["locations"][0]["name"] + pub.sendMessage("buffer-title-changed", buffer=self) + self.trends = data[0]["trends"] + self.put_items_on_the_list() + if self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: + self.session.sound.play(self.sound) + + def put_items_on_the_list(self): + selected_item = self.buffer.list.get_selected() + self.buffer.list.clear() + for i in self.trends: + tweet = self.compose_function(i) + self.buffer.list.insert_item(False, *tweet) + self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) + + def compose_function_(self, trend): + return [trend["name"]] + + def bind_events(self): + log.debug("Binding events...") + self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet) + widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu) + widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key) + widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic) + + def get_message(self): + return self.compose_function(self.trends[self.buffer.list.get_selected()])[0] + + def remove_buffer(self, force=False): + if force == False: + dlg = commonMessageDialogs.remove_buffer() + else: + dlg = widgetUtils.YES + if dlg == widgetUtils.YES: + if self.name[:-3] in self.session.settings["other_buffers"]["trending_topic_buffers"]: + self.session.settings["other_buffers"]["trending_topic_buffers"].remove(self.name[:-3]) + self.session.settings.write() + if self.name in self.session.db: + self.session.db.pop(self.name) + return True + elif dlg == widgetUtils.NO: + return False + + def url(self, *args, **kwargs): + self.tweet_about_this_trend() + + def search_topic(self, *args, **kwargs): + topic = self.trends[self.buffer.list.get_selected()]["name"] + pub.sendMessage("search", term=topic) + + def show_menu(self, ev, pos=0, *args, **kwargs): + menu = menus.trendsPanelMenu() + widgetUtils.connect_event(menu, widgetUtils.MENU, self.search_topic, menuitem=menu.search_topic) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.tweet_about_this_trend, menuitem=menu.tweetThisTrend) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) + widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) + if pos != 0: + self.buffer.PopupMenu(menu, pos) + else: + self.buffer.PopupMenu(menu, ev.GetPosition()) + + def view(self, *args, **kwargs): + pub.sendMessage("execute-action", action="view_item") + + def copy(self, *args, **kwargs): + pub.sendMessage("execute-action", action="copy_to_clipboard") + + def tweet_about_this_trend(self, *args, **kwargs): + if self.buffer.list.get_count() == 0: return + title = _("Tweet") + caption = _("Write the tweet here") + tweet = messages.tweet(session=self.session, title=title, caption=caption, text=self.get_message()+ " ") + tweet.message.SetInsertionPoint(len(tweet.message.GetValue())) + if tweet.message.ShowModal() == widgetUtils.OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) + if hasattr(tweet.message, "destroy"): tweet.message.destroy() + + def show_menu_by_key(self, ev): + if self.buffer.list.get_count() == 0: + return + if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU: + self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition()) + + def open_in_browser(self, *args, **kwargs): + output.speak(_(u"This action is not supported in the buffer, yet.")) \ No newline at end of file diff --git a/src/controller/buffers/twitterBuffers.py b/src/controller/buffers/twitterBuffers.py deleted file mode 100644 index bef1836c..00000000 --- a/src/controller/buffers/twitterBuffers.py +++ /dev/null @@ -1,1293 +0,0 @@ -# -*- coding: utf-8 -*- -import time -import platform -if platform.system() == "Windows": - import wx - from wxUI import buffers, dialogs, commonMessageDialogs, menus - from controller import user -elif platform.system() == "Linux": - from gi.repository import Gtk - from gtkUI import buffers, dialogs, commonMessageDialogs -from controller import messages -import widgetUtils -import arrow -import webbrowser -import output -import config -import sound -import languageHandler -import logging -from audio_services import youtube_utils -from controller.buffers import baseBuffers -from sessions.twitter import compose, utils -from mysc.thread_utils import call_threaded -from tweepy.error import TweepError -from tweepy.cursor import Cursor -from pubsub import pub -from sessions.twitter.long_tweets import twishort, tweets - -log = logging.getLogger("controller.buffers") - -def _tweets_exist(function): - """ A decorator to execute a function only if the selected buffer contains at least one item.""" - def function_(self, *args, **kwargs): - if self.buffer.list.get_count() > 0: - function(self, *args, **kwargs) - return function_ - -class baseBufferController(baseBuffers.buffer): - def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, compose_func="compose_tweet", *args, **kwargs): - super(baseBufferController, self).__init__(parent, function, *args, **kwargs) - log.debug("Initializing buffer %s, account %s" % (name, account,)) - if bufferType != None: - self.buffer = getattr(buffers, bufferType)(parent, name) - else: - self.buffer = buffers.basePanel(parent, name) - self.invisible = True - self.name = name - self.type = self.buffer.type - self.session = sessionObject - self.compose_function = getattr(compose, compose_func) - log.debug("Compose_function: %s" % (self.compose_function,)) - self.account = account - self.buffer.account = account - self.bind_events() - self.sound = sound - if "-timeline" in self.name or "-favorite" in self.name: - self.finished_timeline = False - # Add a compatibility layer for username based timelines from config. - # ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory. - try: - int(self.kwargs["user_id"]) - except ValueError: - self.is_screen_name = True - self.kwargs["screen_name"] = self.kwargs["user_id"] - self.kwargs.pop("user_id") - - def get_buffer_name(self): - """ Get buffer name from a set of different techniques.""" - # firstly let's take the easier buffers. - basic_buffers = dict(home_timeline=_(u"Home"), mentions=_(u"Mentions"), direct_messages=_(u"Direct messages"), sent_direct_messages=_(u"Sent direct messages"), sent_tweets=_(u"Sent tweets"), favourites=_(u"Likes"), followers=_(u"Followers"), friends=_(u"Friends"), blocked=_(u"Blocked users"), muted=_(u"Muted users")) - if self.name in list(basic_buffers.keys()): - return basic_buffers[self.name] - # Check user timelines - elif hasattr(self, "username"): - if "-timeline" in self.name: - return _(u"{username}'s timeline").format(username=self.username,) - elif "-favorite" in self.name: - return _(u"{username}'s likes").format(username=self.username,) - elif "-followers" in self.name: - return _(u"{username}'s followers").format(username=self.username,) - elif "-friends" in self.name: - return _(u"{username}'s friends").format(username=self.username,) - log.error("Error getting name for buffer %s" % (self.name,)) - return _(u"Unknown buffer") - - def post_status(self, *args, **kwargs): - item = None - title = _(u"Tweet") - caption = _(u"Write the tweet here") - tweet = messages.tweet(self.session, title, caption, "") - if tweet.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = tweet.message.long_tweet.GetValue() - config.app.write() - text = tweet.message.get_text() - if len(text) > 280 and tweet.message.get("long_tweet") == True: - if not hasattr(tweet, "attachments"): - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - if not hasattr(tweet, "attachments") or len(tweet.attachments) == 0: - item = self.session.api_call(call_name="update_status", status=text, _sound="tweet_send.ogg", tweet_mode="extended") - else: - call_threaded(self.post_with_media, text=text, attachments=tweet.attachments) - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - if hasattr(tweet.message, "destroy"): tweet.message.destroy() - self.session.settings.write() - - def post_with_media(self, text, attachments): - media_ids = [] - for i in attachments: - img = self.session.twitter.media_upload(i["file"]) - self.session.twitter.create_media_metadata(media_id=img.media_id, alt_text=i["description"]) - media_ids.append(img.media_id) - item = self.session.twitter.update_status(status=text, media_ids=media_ids) - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - - def get_formatted_message(self): - if self.type == "dm" or self.name == "direct_messages": - return self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)[1] - return self.get_message() - - def get_message(self): - tweet = self.get_right_tweet() - return " ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) - - def get_full_tweet(self): - tweet = self.get_right_tweet() - tweetsList = [] - tweet_id = tweet.id - message = None - if hasattr(tweet, "message"): - message = tweet.message - try: - tweet = self.session.twitter.get_status(id=tweet_id, include_ext_alt_text=True, tweet_mode="extended") - tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities) - except TweepError as e: - utils.twitter_error(e) - return - if message != None: - tweet.message = message - l = tweets.is_long(tweet) - while l != False: - tweetsList.append(tweet) - try: - tweet = self.session.twitter.get_status(id=l, include_ext_alt_text=True, tweet_mode="extended") - tweet.full_text = utils.expand_urls(tweet.full_text, tweet.entities) - except TweepError as e: - utils.twitter_error(e) - return - l = tweets.is_long(tweet) - if l == False: - tweetsList.append(tweet) - return (tweet, tweetsList) - - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: - self.execution_time = current_time - log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type)) - log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) - if self.name != "direct_messages": - val = self.session.call_paged(self.function, *self.args, **self.kwargs) - else: - # 50 results are allowed per API call, so let's assume max value can be 50. - # reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events - if self.session.settings["general"]["max_tweets_per_call"] > 50: - count = 50 - else: - count = self.session.settings["general"]["max_tweets_per_call"] - # try to retrieve the cursor for the current buffer. - cursor = self.session.db["cursors"].get(self.name) - try: - # We need to assign all results somewhere else so the cursor variable would b generated. - val = Cursor(getattr(self.session.twitter, self.function), *self.args, **self.kwargs).items(count) - results = [i for i in val] - self.session.db["cursors"][self.name] = val.page_iterator.next_cursor - val = results - val.reverse() - except TweepError as e: - log.error("Error %s: %s" % (e.api_code, e.reason)) - return - number_of_items = self.session.order_buffer(self.name, val) - log.debug("Number of items retrieved: %d" % (number_of_items,)) - self.put_items_on_list(number_of_items) - if hasattr(self, "finished_timeline") and self.finished_timeline == False: - if "-timeline" in self.name: - self.username = val[0].user.screen_name - elif "-favorite" in self.name: - self.username = self.session.api_call("get_user", **self.kwargs).screen_name - self.finished_timeline = True - if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages" and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - # Autoread settings - if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: - self.auto_read(number_of_items) - return number_of_items - - def auto_read(self, number_of_items): - if 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: - if self.session.settings["general"]["reverse_timelines"] == False: - tweet = self.session.db[self.name][-1] - else: - tweet = self.session.db[self.name][0] - output.speak(_(u"New tweet in {0}").format(self.get_buffer_name())) - output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) - 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 tweets in {1}.").format(number_of_items, self.get_buffer_name())) - - def get_more_items(self): - elements = [] - if self.session.settings["general"]["reverse_timelines"] == False: - last_id = self.session.db[self.name][0].id - else: - last_id = self.session.db[self.name][-1].id - try: - items = Cursor(getattr(self.session.twitter, self.function), max_id=last_id, *self.args, **self.kwargs).items(self.session.settings["general"]["max_tweets_per_call"]) - except TweepError as e: - log.error("Error %s: %s" % (e.api_code, e.reason)) - return - if items == None: - return - 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: - i = self.session.check_quoted_status(i) - i = self.session.check_long_tweet(i) - elements.append(i) - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db[self.name].insert(0, i) - else: - self.session.db[self.name].append(i) - selection = self.buffer.list.get_selected() - if self.session.settings["general"]["reverse_timelines"] == False: - for i in elements: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(True, *tweet) - else: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) - self.buffer.list.select_item(selection) - output.speak(_(u"%s items retrieved") % (str(len(elements))), True) - - def remove_buffer(self, force=False): - if "-timeline" in self.name: - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-9] in self.session.settings["other_buffers"]["timelines"]: - self.session.settings["other_buffers"]["timelines"].remove(self.name[:-9]) - self.session.settings.write() - if self.name in self.session.db: - self.session.db.pop(self.name) - return True - elif dlg == widgetUtils.NO: - return False - elif "favorite" in self.name: - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-9] in self.session.settings["other_buffers"]["favourites_timelines"]: - self.session.settings["other_buffers"]["favourites_timelines"].remove(self.name[:-9]) - if self.name in self.session.db: - self.session.db.pop(self.name) - self.session.settings.write() - return True - elif dlg == widgetUtils.NO: - return False - else: - output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True) - return False - - def remove_tweet(self, id): - if type(self.session.db[self.name]) == dict: return - for i in range(0, len(self.session.db[self.name])): - if self.session.db[self.name][i].id == id: - self.session.db[self.name].pop(i) - self.remove_item(i) - - def put_items_on_list(self, number_of_items): - list_to_use = self.session.db[self.name] - if number_of_items == 0 and self.session.settings["general"]["persist_size"] == 0: return - log.debug("The list contains %d items " % (self.buffer.list.get_count(),)) - log.debug("Putting %d items on the list" % (number_of_items,)) - if self.buffer.list.get_count() == 0: - for i in list_to_use: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) - self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) - elif self.buffer.list.get_count() > 0 and number_of_items > 0: - if self.session.settings["general"]["reverse_timelines"] == False: - items = list_to_use[len(list_to_use)-number_of_items:] - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) - else: - items = list_to_use[0:number_of_items] - items.reverse() - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(True, *tweet) - log.debug("Now the list contains %d items " % (self.buffer.list.get_count(),)) - - def add_new_item(self, item): - tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - if self.session.settings["general"]["reverse_timelines"] == False: - self.buffer.list.insert_item(False, *tweet) - else: - self.buffer.list.insert_item(True, *tweet) - if 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(" ".join(tweet[:2]), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"]) - #Improve performance on Windows -# if platform.system() == "Windows": -# call_threaded(utils.is_audio,item) - - def bind_events(self): - log.debug("Binding events...") - self.buffer.set_focus_function(self.onFocus) - widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet) -# if self.type == "baseBuffer": - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.share_item, self.buffer.retweet) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.send_message, self.buffer.dm) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply) - # Replace for the correct way in other platforms. - widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu) - widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key) - - def show_menu(self, ev, pos=0, *args, **kwargs): - if self.buffer.list.get_count() == 0: return - if self.name == "sent_tweets" or self.name == "direct_messages": - menu = menus.sentPanelMenu() - elif self.name == "direct_messages": - menu = menus.dmPanelMenu() - widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) - else: - menu = menus.basePanelMenu() - widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.share_item, menuitem=menu.retweet) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.audio, menuitem=menu.play) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove) - if hasattr(menu, "openInBrowser"): - widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser) - if pos != 0: - self.buffer.PopupMenu(menu, pos) - else: - self.buffer.PopupMenu(menu, ev.GetPosition()) - - def view(self, *args, **kwargs): - pub.sendMessage("execute-action", action="view_item") - - def copy(self, *args, **kwargs): - pub.sendMessage("execute-action", action="copy_to_clipboard") - - def user_actions(self, *args, **kwargs): - pub.sendMessage("execute-action", action="follow") - - def fav(self, *args, **kwargs): - pub.sendMessage("execute-action", action="add_to_favourites") - - def unfav(self, *args, **kwargs): - pub.sendMessage("execute-action", action="remove_from_favourites") - - def delete_item_(self, *args, **kwargs): - pub.sendMessage("execute-action", action="delete_item") - - def url_(self, *args, **kwargs): - self.url() - - def show_menu_by_key(self, ev): - if self.buffer.list.get_count() == 0: - return - if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU: - self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition()) - - def get_tweet(self): - if hasattr(self.session.db[self.name][self.buffer.list.get_selected()], "retweeted_status"): - tweet = self.session.db[self.name][self.buffer.list.get_selected()].retweeted_status - else: - tweet = self.session.db[self.name][self.buffer.list.get_selected()] - return tweet - - def get_right_tweet(self): - tweet = self.session.db[self.name][self.buffer.list.get_selected()] - return tweet - - @_tweets_exist - def reply(self, *args, **kwargs): - tweet = self.get_right_tweet() - screen_name = tweet.user.screen_name - id = tweet.id - twishort_enabled = hasattr(tweet, "twishort") - users = utils.get_all_mentioned(tweet, self.session.db, field="screen_name") - ids = utils.get_all_mentioned(tweet, self.session.db, field="id_str") - # Build the window title - if len(users) < 1: - title=_("Reply to {arg0}").format(arg0=screen_name) - else: - title=_("Reply") - message = messages.reply(self.session, title, _(u"Reply to %s") % (screen_name,), "", users=users, ids=ids) - if message.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() - if len(users) > 0: - config.app["app-settings"]["mention_all"] = message.message.mentionAll.GetValue() - config.app.write() - params = {"_sound": "reply_send.ogg", "in_reply_to_status_id": id, "tweet_mode": "extended"} - text = message.message.get_text() - if twishort_enabled == False: - excluded_ids = message.get_ids() - params["exclude_reply_user_ids"] =excluded_ids - params["auto_populate_reply_metadata"] =True - else: - mentioned_people = message.get_people() - text = "@"+screen_name+" "+mentioned_people+u" "+text - if len(text) > 280 and message.message.get("long_tweet") == True: - if message.image == None: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - params["status"] = text - if message.image == None: - params["call_name"] = "update_status" - else: - params["call_name"] = "update_status_with_media" - params["media"] = message.file - item = self.session.api_call(**params) - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - if hasattr(message.message, "destroy"): message.message.destroy() - self.session.settings.write() - - @_tweets_exist - def send_message(self, *args, **kwargs): - tweet = self.get_right_tweet() - if self.type == "dm": - screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name - users = [screen_name] - elif self.type == "people": - screen_name = tweet.screen_name - users = [screen_name] - else: - screen_name = tweet.user.screen_name - users = utils.get_all_users(tweet, self.session.db) - dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users) - if dm.message.get_response() == widgetUtils.OK: - screen_name = dm.message.get("cb") - user = self.session.get_user_by_screen_name(screen_name) - recipient_id = user - text = dm.message.get_text() - val = self.session.api_call(call_name="send_direct_message", recipient_id=recipient_id, text=text) - if val != None: - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db["sent_direct_messages"].append(val) - else: - self.session.db["sent_direct_messages"].insert(0, val) - pub.sendMessage("sent-dm", data=val, user=self.session.db["user_name"]) - if hasattr(dm.message, "destroy"): dm.message.destroy() - - @_tweets_exist - def share_item(self, *args, **kwargs): - tweet = self.get_right_tweet() - id = tweet.id - if self.session.settings["general"]["retweet_mode"] == "ask": - answer = commonMessageDialogs.retweet_question(self.buffer) - if answer == widgetUtils.YES: - self._retweet_with_comment(tweet, id) - elif answer == widgetUtils.NO: - self._direct_retweet(id) - elif self.session.settings["general"]["retweet_mode"] == "direct": - self._direct_retweet(id) - else: - self._retweet_with_comment(tweet, id) - - def _retweet_with_comment(self, tweet, id, comment=''): - # If quoting a retweet, let's quote the original tweet instead the retweet. - if hasattr(tweet, "retweeted_status"): - tweet = tweet.retweeted_status - if hasattr(tweet, "full_text"): - comments = tweet.full_text - else: - comments = tweet.text - retweet = messages.tweet(self.session, _(u"Quote"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (tweet.user.screen_name, comments), max=256, messageType="retweet") - if comment != '': - retweet.message.set_text(comment) - if retweet.message.get_response() == widgetUtils.OK: - text = retweet.message.get_text() - text = text+" https://twitter.com/{0}/status/{1}".format(tweet.user.screen_name, id) - if retweet.image == None: - item = self.session.api_call(call_name="update_status", _sound="retweet_send.ogg", status=text, in_reply_to_status_id=id, tweet_mode="extended") - if item != None: - new_item = self.session.twitter.get_status(id=item.id, include_ext_alt_text=True, tweet_mode="extended") - pub.sendMessage("sent-tweet", data=new_item, user=self.session.db["user_name"]) - else: - call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=text, media=retweet.image) - if hasattr(retweet.message, "destroy"): retweet.message.destroy() - - def _direct_retweet(self, id): - item = self.session.api_call(call_name="retweet", _sound="retweet_send.ogg", id=id) - if item != None: - # Retweets are returned as non-extended tweets, so let's get the object as extended - # just before sending the event message. See https://github.com/manuelcortez/TWBlue/issues/253 - item = self.session.twitter.get_status(id=item.id, include_ext_alt_text=True, tweet_mode="extended") - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - - def onFocus(self, *args, **kwargs): - tweet = self.get_tweet() - if platform.system() == "Windows" and self.session.settings["general"]["relative_times"] == True: - # fix this: - original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en") - ts = original_date.humanize(locale=languageHandler.getLanguage()) - self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts) - if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet): - self.session.sound.play("audio.ogg") - if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet): - self.session.sound.play("geo.ogg") - if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet): - self.session.sound.play("image.ogg") - - def audio(self, url='', *args, **kwargs): - if sound.URLPlayer.player.is_playing(): - return sound.URLPlayer.stop_audio() - tweet = self.get_tweet() - if tweet == None: return - urls = utils.find_urls(tweet) - if len(urls) == 1: - url=urls[0] - elif len(urls) > 1: - urls_list = dialogs.urlList.urlList() - urls_list.populate_list(urls) - if urls_list.get_response() == widgetUtils.OK: - url=urls_list.get_string() - if hasattr(urls_list, "destroy"): urls_list.destroy() - if url != '': -# try: - sound.URLPlayer.play(url, self.session.settings["sound"]["volume"]) -# except: -# log.error("Exception while executing audio method.") - -# @_tweets_exist - def url(self, url='', announce=True, *args, **kwargs): - if url == '': - tweet = self.get_tweet() - urls = utils.find_urls(tweet) - if len(urls) == 1: - url=urls[0] - elif len(urls) > 1: - urls_list = dialogs.urlList.urlList() - urls_list.populate_list(urls) - if urls_list.get_response() == widgetUtils.OK: - url=urls_list.get_string() - if hasattr(urls_list, "destroy"): urls_list.destroy() - if url != '': - if announce: - output.speak(_(u"Opening URL..."), True) - webbrowser.open_new_tab(url) - - def clear_list(self): - dlg = commonMessageDialogs.clear_list() - if dlg == widgetUtils.YES: - self.session.db[self.name] = [] - self.buffer.list.clear() - - @_tweets_exist - def destroy_status(self, *args, **kwargs): - index = self.buffer.list.get_selected() - if self.type == "events" or self.type == "people" or self.type == "empty" or self.type == "account": return - answer = commonMessageDialogs.delete_tweet_dialog(None) - if answer == widgetUtils.YES: - try: - if self.name == "direct_messages" or self.name == "sent_direct_messages": - self.session.twitter.destroy_direct_message(id=self.get_right_tweet().id) - self.session.db[self.name].pop(index) - else: - self.session.twitter.destroy_status(id=self.get_right_tweet().id) - self.session.db[self.name].pop(index) - self.buffer.list.remove_item(index) - except TweepError: - self.session.sound.play("error.ogg") - - @_tweets_exist - def user_details(self): - tweet = self.get_right_tweet() - if self.type == "dm": - users = [self.session.get_user(tweet.message_create["sender_id"]).screen_name] - elif self.type == "people": - users = [tweet.screen_name] - else: - users = utils.get_all_users(tweet, self.session.db) - dlg = dialogs.utils.selectUserDialog(title=_(u"User details"), users=users) - if dlg.get_response() == widgetUtils.OK: - user.profileController(session=self.session, user=dlg.get_user()) - if hasattr(dlg, "destroy"): dlg.destroy() - - def get_quoted_tweet(self, tweet): - quoted_tweet = self.session.twitter.get_status(id=tweet.id) - quoted_tweet.text = utils.find_urls_in_text(quoted_tweet.text, quoted_tweet.entities) - l = tweets.is_long(quoted_tweet) - id = tweets.get_id(l) - original_tweet = self.session.twitter.get_status(id=id) - 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): - tweet = self.get_tweet() - output.speak(_(u"Opening item in web browser...")) - url = "https://twitter.com/{screen_name}/status/{tweet_id}".format(screen_name=tweet.user.screen_name, tweet_id=tweet.id) - webbrowser.open(url) - -class directMessagesController(baseBufferController): - - def get_more_items(self): - # 50 results are allowed per API call, so let's assume max value can be 50. - # reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events - if self.session.settings["general"]["max_tweets_per_call"] > 50: - count = 50 - else: - count = self.session.settings["general"]["max_tweets_per_call"] - total = 0 - # try to retrieve the cursor for the current buffer. - cursor = self.session.db["cursors"].get(self.name) - try: - items = Cursor(getattr(self.session.twitter, self.function), cursor=cursor, *self.args, **self.kwargs).items(count) - results = [i for i in items] - self.session.db["cursors"][self.name] = items.page_iterator.next_cursor - items = results - except TweepError as e: - log.error("Error %s: %s" % (e.api_code, e.reason)) - return - if items == None: - return - sent = [] - received = [] - for i in items: - if int(i.message_create["sender_id"]) == self.session.db["user_id"]: - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db["sent_direct_messages"].insert(0, i) - sent.append(i) - else: - self.session.db["sent_direct_messages"].append(i) - sent.insert(0, i) - else: - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db[self.name].insert(0, i) - received.append(i) - else: - self.session.db[self.name].append(i) - received.insert(0, i) - total = total+1 - pub.sendMessage("more-sent-dms", data=sent, account=self.session.db["user_name"]) - selected = self.buffer.list.get_selected() - - if self.session.settings["general"]["reverse_timelines"] == True: - for i in received: - if int(i.message_create["sender_id"]) == self.session.db["user_id"]: - continue - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(True, *tweet) - self.buffer.list.select_item(selected) - else: - for i in received: - if int(i.message_create["sender_id"]) == self.session.db["user_id"]: - continue - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(True, *tweet) - output.speak(_(u"%s items retrieved") % (total), True) - - @_tweets_exist - def reply(self, *args, **kwargs): - tweet = self.get_right_tweet() - screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name - message = messages.reply(self.session, _(u"Mention"), _(u"Mention to %s") % (screen_name,), "@%s " % (screen_name,), [screen_name,]) - if message.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() - config.app.write() - if message.image == None: - item = self.session.api_call(call_name="update_status", _sound="reply_send.ogg", status=message.message.get_text(), tweet_mode="extended") - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - else: - call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file) - if hasattr(message.message, "destroy"): message.message.destroy() - - def onFocus(self, *args, **kwargs): - tweet = self.get_tweet() - if platform.system() == "Windows" and self.session.settings["general"]["relative_times"] == True: - # fix this: - original_date = arrow.get(int(tweet.created_timestamp)) - ts = original_date.humanize(locale=languageHandler.getLanguage()) - self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts) - if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet): - self.session.sound.play("audio.ogg") - if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet): - self.session.sound.play("image.ogg") - - def clear_list(self): - dlg = commonMessageDialogs.clear_list() - if dlg == widgetUtils.YES: - self.session.db[self.name] = [] - self.buffer.list.clear() - - def auto_read(self, number_of_items): - if 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: - if self.session.settings["general"]["reverse_timelines"] == False: - tweet = self.session.db[self.name][-1] - else: - tweet = self.session.db[self.name][0] - output.speak(_(u"New direct message")) - output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) - 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 direct messages.").format(number_of_items,)) - - def open_in_browser(self, *args, **kwargs): - output.speak(_(u"This action is not supported in the buffer yet.")) - -class sentDirectMessagesController(directMessagesController): - - def __init__(self, *args, **kwargs): - super(sentDirectMessagesController, self).__init__(*args, **kwargs) - if ("sent_direct_messages" in self.session.db) == False: - self.session.db["sent_direct_messages"] = [] - - def get_more_items(self): - output.speak(_(u"Getting more items cannot be done in this buffer. Use the direct messages buffer instead.")) - - def start_stream(self, *args, **kwargs): - pass - - def put_more_items(self, items): - if self.session.settings["general"]["reverse_timelines"] == True: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) - else: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) - -class listBufferController(baseBufferController): - def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, list_id=None, *args, **kwargs): - super(listBufferController, self).__init__(parent, function, name, sessionObject, account, sound=None, bufferType=None, *args, **kwargs) - self.users = [] - self.list_id = list_id - self.kwargs["list_id"] = list_id - - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): - self.get_user_ids() - super(listBufferController, self).start_stream(mandatory, play_sound, avoid_autoreading) - - def get_user_ids(self): - for i in Cursor(self.session.twitter.list_members, list_id=self.list_id, include_entities=False, skip_status=True).items(): - if i.id not in self.users: - self.users.append(i.id) - - def remove_buffer(self, force=False): - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-5] in self.session.settings["other_buffers"]["lists"]: - self.session.settings["other_buffers"]["lists"].remove(self.name[:-5]) - if self.name in self.session.db: - self.session.db.pop(self.name) - self.session.settings.write() - return True - elif dlg == widgetUtils.NO: - return False - -class peopleBufferController(baseBufferController): - def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs): - super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs) - log.debug("Initializing buffer %s, account %s" % (name, account,)) - self.compose_function = compose.compose_followers_list - log.debug("Compose_function: %s" % (self.compose_function,)) - self.get_tweet = self.get_right_tweet - self.url = self.interact - if "-followers" in self.name or "-friends" in self.name: - self.finished_timeline = False - # Add a compatibility layer for username based timelines from config. - # ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory. - try: - int(self.kwargs["user_id"]) - except ValueError: - self.is_screen_name = True - self.kwargs["screen_name"] = self.kwargs["user_id"] - self.kwargs.pop("user_id") - - def remove_buffer(self, force=True): - if "-followers" in self.name: - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-10] in self.session.settings["other_buffers"]["followers_timelines"]: - self.session.settings["other_buffers"]["followers_timelines"].remove(self.name[:-10]) - if self.name in self.session.db: - self.session.db.pop(self.name) - self.session.settings.write() - return True - elif dlg == widgetUtils.NO: - return False - elif "-friends" in self.name: - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-8] in self.session.settings["other_buffers"]["friends_timelines"]: - self.session.settings["other_buffers"]["friends_timelines"].remove(self.name[:-8]) - if self.name in self.session.db: - self.session.db.pop(self.name) - self.session.settings.write() - return True - elif dlg == widgetUtils.NO: - return False - else: - output.speak(_(u"This buffer is not a timeline; it can't be deleted."), True) - return False - - def onFocus(self, ev): - pass - - def get_message(self): - return " ".join(self.compose_function(self.get_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) - - def delete_item(self): pass - - @_tweets_exist - def reply(self, *args, **kwargs): - tweet = self.get_right_tweet() - screen_name = tweet.screen_name - message = messages.reply(self.session, _(u"Mention"), _(u"Mention to %s") % (screen_name,), "@%s " % (screen_name,), [screen_name,]) - if message.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() - config.app.write() - if message.image == None: - item = self.session.api_call(call_name="update_status", _sound="reply_send.ogg", status=message.message.get_text(), tweet_mode="extended") - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - else: - call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file) - if hasattr(message.message, "destroy"): message.message.destroy() - - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: - self.execution_time = current_time - log.debug("Starting stream for %s buffer, %s account" % (self.name, self.account,)) - log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) - # try to retrieve the cursor for the current buffer. - cursor = self.session.db["cursors"].get(self.name) - try: - # We need to assign all results somewhere else so the cursor variable would b generated. - val = Cursor(getattr(self.session.twitter, self.function), *self.args, **self.kwargs).items(self.session.settings["general"]["max_tweets_per_call"]) - results = [i for i in val] - self.session.db["cursors"][self.name] = val.page_iterator.next_cursor - val = results - val.reverse() - except TweepError as e: - log.error("Error %s: %s" % (e.api_code, e.reason)) - return - number_of_items = self.session.order_people(self.name, val) - log.debug("Number of items retrieved: %d" % (number_of_items,)) - self.put_items_on_list(number_of_items) - if hasattr(self, "finished_timeline") and self.finished_timeline == False: - self.username = self.session.api_call("get_user", **self.kwargs).screen_name - self.finished_timeline = True - if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - # Autoread settings - if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: - self.auto_read(number_of_items) - return number_of_items - - def get_more_items(self): - try: - cursor = self.session.db["cursors"].get(self.name) - items = Cursor(getattr(self.session.twitter, self.function), users=True, cursor=cursor, *self.args, **self.kwargs).items(self.session.settings["general"]["max_tweets_per_call"]) - results = [i for i in items] - self.session.db["cursors"][self.name] = items.page_iterator.next_cursor - items = results - except TweepError as e: - log.error("Error %s: %s" % (e.api_code, e.reason)) - return - if items == None: - return - for i in items: - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db[self.name].insert(0, i) - else: - self.session.db[self.name].append(i) - selected = self.buffer.list.get_selected() - if self.session.settings["general"]["reverse_timelines"] == True: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) - self.buffer.list.insert_item(True, *tweet) - self.buffer.list.select_item(selected) - else: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) - self.buffer.list.insert_item(True, *tweet) - output.speak(_(u"%s items retrieved") % (len(items)), True) - - def put_items_on_list(self, number_of_items): - log.debug("The list contains %d items" % (self.buffer.list.get_count(),)) -# log.debug("Putting %d items on the list..." % (number_of_items,)) - if self.buffer.list.get_count() == 0: - for i in self.session.db[self.name]: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) - self.buffer.list.insert_item(False, *tweet) - self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) -# self.buffer.set_list_position() - elif self.buffer.list.get_count() > 0: - if self.session.settings["general"]["reverse_timelines"] == False: - for i in self.session.db[self.name][len(self.session.db[self.name])-number_of_items:]: - tweet = self.compose_function(i, self.session.db) - self.buffer.list.insert_item(False, *tweet) - else: - items = self.session.db[self.name][0:number_of_items] - items.reverse() - for i in items: - tweet = self.compose_function(i, self.session.db) - self.buffer.list.insert_item(True, *tweet) - log.debug("now the list contains %d items" % (self.buffer.list.get_count(),)) - - def get_right_tweet(self): - tweet = self.session.db[self.name][self.buffer.list.get_selected()] - return tweet - - def add_new_item(self, item): - tweet = self.compose_function(item, self.session.db, self.session.settings["general"]["relative_times"], self.session) - if self.session.settings["general"]["reverse_timelines"] == False: - self.buffer.list.insert_item(False, *tweet) - else: - self.buffer.list.insert_item(True, *tweet) - if 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(" ".join(tweet)) - - def clear_list(self): - dlg = commonMessageDialogs.clear_list() - if dlg == widgetUtils.YES: - self.session.db[self.name] = [] - self.session.db["cursors"][self.name] = -1 - self.buffer.list.clear() - - def interact(self): - user.profileController(self.session, user=self.get_right_tweet().screen_name) - - def show_menu(self, ev, pos=0, *args, **kwargs): - menu = menus.peoplePanelMenu() - widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details) -# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) - if hasattr(menu, "openInBrowser"): - widgetUtils.connect_event(menu, widgetUtils.MENU, self.open_in_browser, menuitem=menu.openInBrowser) - if pos != 0: - self.buffer.PopupMenu(menu, pos) - else: - self.buffer.PopupMenu(menu, ev.GetPosition()) - - def details(self, *args, **kwargs): - pub.sendMessage("execute-action", action="user_details") - - def auto_read(self, number_of_items): - if 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: - if self.session.settings["general"]["reverse_timelines"] == False: - tweet = self.session.db[self.name][-1] - else: - tweet = self.session.db[self.name][0] - output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session))) - 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): - 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) - -class searchBufferController(baseBufferController): - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: - self.execution_time = current_time - log.debug("Starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type)) - log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) - log.debug("Function: %s" % (self.function,)) -# try: - val = self.session.search(self.name, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs) -# except: -# return None - num = self.session.order_buffer(self.name, val) - self.put_items_on_list(num) - if num > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - # Autoread settings - if avoid_autoreading == False and mandatory == True and num > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: - self.auto_read(num) - return num - - def remove_buffer(self, force=False): - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]: - self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11]) - self.session.settings.write() - if self.name in self.session.db: - self.session.db.pop(self.name) - return True - elif dlg == widgetUtils.NO: - return False - -class searchPeopleBufferController(peopleBufferController): - - def __init__(self, parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs): - super(searchPeopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs) - log.debug("Initializing buffer %s, account %s" % (name, account,)) -# self.compose_function = compose.compose_followers_list - log.debug("Compose_function: %s" % (self.compose_function,)) - self.args = args - self.kwargs = kwargs - self.function = function - if ("page" in self.kwargs) == False: - self.kwargs["page"] = 1 - - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=True): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True: - self.execution_time = current_time - log.debug("starting stream for %s buffer, %s account and %s type" % (self.name, self.account, self.type)) - log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) - log.debug("Function: %s" % (self.function,)) -# try: - val = self.session.call_paged(self.function, *self.args, **self.kwargs) -# except: -# return - number_of_items = self.session.order_cursored_buffer(self.name, val) - log.debug("Number of items retrieved: %d" % (number_of_items,)) - self.put_items_on_list(number_of_items) - if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - # Autoread settings - if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: - self.auto_read(number_of_items) - return number_of_items - - def get_more_items(self, *args, **kwargs): - self.kwargs["page"] += 1 - try: - items = self.session.get_more_items(self.function, users=True, name=self.name, count=self.session.settings["general"]["max_tweets_per_call"], *self.args, **self.kwargs) - except TweepError as e: - output.speak(e.reason, True) - return - if items == None: - return - for i in items: - if self.session.settings["general"]["reverse_timelines"] == False: - self.session.db[self.name].insert(0, i) - else: - self.session.db[self.name].append(i) - selected = self.buffer.list.get_selected() -# self.put_items_on_list(len(items)) - if self.session.settings["general"]["reverse_timelines"] == True: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) - self.buffer.list.insert_item(True, *tweet) - self.buffer.list.select_item(selected) - else: - for i in items: - tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session) - self.buffer.list.insert_item(True, *tweet) -# self.buffer.list.select_item(selection) -# else: -# self.buffer.list.select_item(selection-elements) - output.speak(_(u"%s items retrieved") % (len(items)), True) - - def remove_buffer(self, force=False): - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-11] in self.session.settings["other_buffers"]["tweet_searches"]: - self.session.settings["other_buffers"]["tweet_searches"].remove(self.name[:-11]) - self.session.settings.write() - if self.name in self.session.db: - self.session.db.pop(self.name) - return True - elif dlg == widgetUtils.NO: - return False - -class trendsBufferController(baseBuffers.buffer): - def __init__(self, parent, name, session, account, trendsFor, *args, **kwargs): - super(trendsBufferController, self).__init__(parent=parent, session=session) - self.trendsFor = trendsFor - self.session = session - self.account = account - self.invisible = True - self.buffer = buffers.trendsPanel(parent, name) - self.buffer.account = account - self.type = self.buffer.type - self.bind_events() - self.sound = "trends_updated.ogg" - self.trends = [] - self.name = name - self.buffer.name = name - self.compose_function = self.compose_function_ - self.get_formatted_message = self.get_message - self.reply = self.search_topic - - def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: - self.execution_time = current_time - try: - data = self.session.twitter.trends_place(id=self.trendsFor) - except TweepError as err: - log.error("Error %s: %s" % (err.api_code, err.reason)) - if not hasattr(self, "name_"): - self.name_ = data[0]["locations"][0]["name"] - self.trends = data[0]["trends"] - self.put_items_on_the_list() - if self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - - def put_items_on_the_list(self): - selected_item = self.buffer.list.get_selected() - self.buffer.list.clear() - for i in self.trends: - tweet = self.compose_function(i) - self.buffer.list.insert_item(False, *tweet) - self.buffer.set_position(self.session.settings["general"]["reverse_timelines"]) - - def compose_function_(self, trend): - return [trend["name"]] - - def bind_events(self): - log.debug("Binding events...") - self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet) - widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu) - widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key) - widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic) - - def get_message(self): - return self.compose_function(self.trends[self.buffer.list.get_selected()])[0] - - def remove_buffer(self, force=False): - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name[:-3] in self.session.settings["other_buffers"]["trending_topic_buffers"]: - self.session.settings["other_buffers"]["trending_topic_buffers"].remove(self.name[:-3]) - self.session.settings.write() - if self.name in self.session.db: - self.session.db.pop(self.name) - return True - elif dlg == widgetUtils.NO: - return False - - def url(self, *args, **kwargs): - self.tweet_about_this_trend() - - def search_topic(self, *args, **kwargs): - topic = self.trends[self.buffer.list.get_selected()]["name"] - pub.sendMessage("search", term=topic) - - def show_menu(self, ev, pos=0, *args, **kwargs): - menu = menus.trendsPanelMenu() - widgetUtils.connect_event(menu, widgetUtils.MENU, self.search_topic, menuitem=menu.search_topic) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.tweet_about_this_trend, menuitem=menu.tweetThisTrend) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view) - widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy) - if pos != 0: - self.buffer.PopupMenu(menu, pos) - else: - self.buffer.PopupMenu(menu, ev.GetPosition()) - - def view(self, *args, **kwargs): - pub.sendMessage("execute-action", action="view_item") - - def copy(self, *args, **kwargs): - pub.sendMessage("execute-action", action="copy_to_clipboard") - - def tweet_about_this_trend(self, *args, **kwargs): - if self.buffer.list.get_count() == 0: return - title = _(u"Tweet") - caption = _(u"Write the tweet here") - tweet = messages.tweet(self.session, title, caption, self.get_message()+ " ") - tweet.message.set_cursor_at_end() - if tweet.message.get_response() == widgetUtils.OK: - text = tweet.message.get_text() - if len(text) > 280 and tweet.message.get("long_tweet") == True: - if tweet.image == None: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - if tweet.image == None: - call_threaded(self.session.api_call, call_name="update_status", status=text) - else: - call_threaded(self.session.api_call, call_name="update_status_with_media", status=text, media=tweet.image) - if hasattr(tweet.message, "destroy"): tweet.message.destroy() - - def show_menu_by_key(self, ev): - if self.buffer.list.get_count() == 0: - return - if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU: - self.show_menu(widgetUtils.MENU, pos=self.buffer.list.list.GetPosition()) - - def open_in_browser(self, *args, **kwargs): - output.speak(_(u"This action is not supported in the buffer, yet.")) - -class conversationBufferController(searchBufferController): - - def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False): - # starts stream every 3 minutes. - current_time = time.time() - if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: - self.execution_time = current_time - if start == True: - self.statuses = [] - self.ids = [] - self.statuses.append(self.tweet) - self.ids.append(self.tweet.id) - tweet = self.tweet - while tweet.in_reply_to_status_id != None: - try: - tweet = self.session.twitter.get_status(id=tweet.in_reply_to_status_id, tweet_mode="extended") - except TweepError as err: - break - self.statuses.insert(0, tweet) - self.ids.append(tweet.id) - if tweet.in_reply_to_status_id == None: - self.kwargs["since_id"] = tweet.id - self.ids.append(tweet.id) - val2 = self.session.search(self.name, tweet_mode="extended", *self.args, **self.kwargs) - for i in val2: - if i.in_reply_to_status_id in self.ids: - self.statuses.append(i) - self.ids.append(i.id) - tweet = i - number_of_items = self.session.order_buffer(self.name, self.statuses) - log.debug("Number of items retrieved: %d" % (number_of_items,)) - self.put_items_on_list(number_of_items) - if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True: - self.session.sound.play(self.sound) - # Autoread settings - if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]: - self.auto_read(number_of_items) - return number_of_items - - def remove_buffer(self, force=False): - if force == False: - dlg = commonMessageDialogs.remove_buffer() - else: - dlg = widgetUtils.YES - if dlg == widgetUtils.YES: - if self.name in self.session.db: - self.session.db.pop(self.name) - return True - elif dlg == widgetUtils.NO: - return False diff --git a/src/controller/filterController.py b/src/controller/filterController.py index 5f6fa6ed..79684801 100644 --- a/src/controller/filterController.py +++ b/src/controller/filterController.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import object import time import widgetUtils import application @@ -8,71 +6,71 @@ from wxUI.dialogs import filterDialogs from wxUI import commonMessageDialogs class filter(object): - def __init__(self, buffer, filter_title=None, if_word_exists=None, in_lang=None, regexp=None, word=None, in_buffer=None): - self.buffer = buffer - self.dialog = filterDialogs.filterDialog(languages=[i["name"] for i in application.supported_languages]) - if self.dialog.get_response() == widgetUtils.OK: - title = self.dialog.get("title") - contains = self.dialog.get("contains") - term = self.dialog.get("term") - regexp = self.dialog.get("regexp") - allow_rts = self.dialog.get("allow_rts") - allow_quotes = self.dialog.get("allow_quotes") - allow_replies = self.dialog.get("allow_replies") - load_language = self.dialog.get("load_language") - ignore_language = self.dialog.get("ignore_language") - lang_option = None - if ignore_language: - lang_option = False - elif load_language: - lang_option = True - langs = self.dialog.get_selected_langs() - langcodes = [] - for i in application.supported_languages: - if i["name"] in langs: - langcodes.append(i["code"]) - d = dict(in_buffer=self.buffer.name, word=term, regexp=regexp, in_lang=lang_option, languages=langcodes, if_word_exists=contains, allow_rts=allow_rts, allow_quotes=allow_quotes, allow_replies=allow_replies) - if title in self.buffer.session.settings["filters"]: - return commonMessageDialogs.existing_filter() - self.buffer.session.settings["filters"][title] = d - self.buffer.session.settings.write() + def __init__(self, buffer, filter_title=None, if_word_exists=None, in_lang=None, regexp=None, word=None, in_buffer=None): + self.buffer = buffer + self.dialog = filterDialogs.filterDialog(languages=[i["name"] for i in application.supported_languages]) + if self.dialog.get_response() == widgetUtils.OK: + title = self.dialog.get("title") + contains = self.dialog.get("contains") + term = self.dialog.get("term") + regexp = self.dialog.get("regexp") + allow_rts = self.dialog.get("allow_rts") + allow_quotes = self.dialog.get("allow_quotes") + allow_replies = self.dialog.get("allow_replies") + load_language = self.dialog.get("load_language") + ignore_language = self.dialog.get("ignore_language") + lang_option = None + if ignore_language: + lang_option = False + elif load_language: + lang_option = True + langs = self.dialog.get_selected_langs() + langcodes = [] + for i in application.supported_languages: + if i["name"] in langs: + langcodes.append(i["code"]) + d = dict(in_buffer=self.buffer.name, word=term, regexp=regexp, in_lang=lang_option, languages=langcodes, if_word_exists=contains, allow_rts=allow_rts, allow_quotes=allow_quotes, allow_replies=allow_replies) + if title in self.buffer.session.settings["filters"]: + return commonMessageDialogs.existing_filter() + self.buffer.session.settings["filters"][title] = d + self.buffer.session.settings.write() class filterManager(object): - def __init__(self, session): - self.session = session - self.dialog = filterDialogs.filterManagerDialog() - self.insert_filters(self.session.settings["filters"]) - if self.dialog.filters.get_count() == 0: - self.dialog.edit.Enable(False) - self.dialog.delete.Enable(False) - else: - widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_filter) - widgetUtils.connect_event(self.dialog.delete, widgetUtils.BUTTON_PRESSED, self.delete_filter) - response = self.dialog.get_response() + def __init__(self, session): + self.session = session + self.dialog = filterDialogs.filterManagerDialog() + self.insert_filters(self.session.settings["filters"]) + if self.dialog.filters.get_count() == 0: + self.dialog.edit.Enable(False) + self.dialog.delete.Enable(False) + else: + widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.edit_filter) + widgetUtils.connect_event(self.dialog.delete, widgetUtils.BUTTON_PRESSED, self.delete_filter) + response = self.dialog.get_response() - def insert_filters(self, filters): - self.dialog.filters.clear() - for f in list(filters.keys()): - filterName = f - buffer = filters[f]["in_buffer"] - if filters[f]["if_word_exists"] == "True" and filters[f]["word"] != "": - filter_by_word = "True" - else: - filter_by_word = "False" - filter_by_lang = "" - if filters[f]["in_lang"] != "None": - filter_by_lang = "True" - b = [f, buffer, filter_by_word, filter_by_lang] - self.dialog.filters.insert_item(False, *b) + def insert_filters(self, filters): + self.dialog.filters.clear() + for f in list(filters.keys()): + filterName = f + buffer = filters[f]["in_buffer"] + if filters[f]["if_word_exists"] == "True" and filters[f]["word"] != "": + filter_by_word = "True" + else: + filter_by_word = "False" + filter_by_lang = "" + if filters[f]["in_lang"] != "None": + filter_by_lang = "True" + b = [f, buffer, filter_by_word, filter_by_lang] + self.dialog.filters.insert_item(False, *b) - def edit_filter(self, *args, **kwargs): - pass + def edit_filter(self, *args, **kwargs): + pass - def delete_filter(self, *args, **kwargs): - filter_title = self.dialog.filters.get_text_column(self.dialog.filters.get_selected(), 0) - response = commonMessageDialogs.delete_filter() - if response == widgetUtils.YES: - self.session.settings["filters"].pop(filter_title) - self.session.settings.write() - self.insert_filters(self.session.settings["filters"]) \ No newline at end of file + def delete_filter(self, *args, **kwargs): + filter_title = self.dialog.filters.get_text_column(self.dialog.filters.get_selected(), 0) + response = commonMessageDialogs.delete_filter() + if response == widgetUtils.YES: + self.session.settings["filters"].pop(filter_title) + self.session.settings.write() + self.insert_filters(self.session.settings["filters"]) diff --git a/src/controller/listsController.py b/src/controller/listsController.py index 776b0604..ca861c31 100644 --- a/src/controller/listsController.py +++ b/src/controller/listsController.py @@ -3,108 +3,112 @@ import widgetUtils import output import logging from wxUI.dialogs import lists -from tweepy.error import TweepError +from tweepy.errors import TweepyException from sessions.twitter import compose, utils from pubsub import pub log = logging.getLogger("controller.listsController") class listsController(object): - def __init__(self, session, user=None): - super(listsController, self).__init__() - self.session = session - if user == None: - self.dialog = lists.listViewer() - self.dialog.populate_list(self.get_all_lists()) - widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list) - widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) - widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) - else: - self.dialog = lists.userListViewer(user) - self.dialog.populate_list(self.get_user_lists(user)) - widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe) - widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe) - self.dialog.get_response() + def __init__(self, session, user=None): + super(listsController, self).__init__() + self.session = session + if user == None: + self.dialog = lists.listViewer() + self.dialog.populate_list(self.get_all_lists()) + widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.create_list) + widgetUtils.connect_event(self.dialog.editBtn, widgetUtils.BUTTON_PRESSED, self.edit_list) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) + widgetUtils.connect_event(self.dialog.view, widgetUtils.BUTTON_PRESSED, self.open_list_as_buffer) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.remove_list) + else: + self.dialog = lists.userListViewer(user) + self.dialog.populate_list(self.get_user_lists(user)) + widgetUtils.connect_event(self.dialog.createBtn, widgetUtils.BUTTON_PRESSED, self.subscribe) + widgetUtils.connect_event(self.dialog.deleteBtn, widgetUtils.BUTTON_PRESSED, self.unsubscribe) + self.dialog.get_response() - def get_all_lists(self): - return [compose.compose_list(item) for item in self.session.db["lists"]] + def get_all_lists(self): + return [compose.compose_list(item) for item in self.session.db["lists"]] - def get_user_lists(self, user): - self.lists = self.session.twitter.lists_all(reverse=True, screen_name=user) - return [compose.compose_list(item) for item in self.lists] + def get_user_lists(self, user): + self.lists = self.session.twitter.lists_all(reverse=True, screen_name=user) + return [compose.compose_list(item) for item in self.lists] - def create_list(self, *args, **kwargs): - dialog = lists.createListDialog() - if dialog.get_response() == widgetUtils.OK: - name = dialog.get("name") - description = dialog.get("description") - p = dialog.get("public") - if p == True: - mode = "public" - else: - mode = "private" - try: - new_list = self.session.twitter.create_list(name=name, description=description, mode=mode) - self.session.db["lists"].append(new_list) - self.dialog.lista.insert_item(False, *compose.compose_list(new_list)) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) - log.exception("error %s: %s" % (e.api_code, e.reason)) - dialog.destroy() + def create_list(self, *args, **kwargs): + dialog = lists.createListDialog() + if dialog.get_response() == widgetUtils.OK: + name = dialog.get("name") + description = dialog.get("description") + p = dialog.get("public") + if p == True: + mode = "public" + else: + mode = "private" + try: + new_list = self.session.twitter.create_list(name=name, description=description, mode=mode) + self.session.db["lists"].append(new_list) + self.dialog.lista.insert_item(False, *compose.compose_list(new_list)) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) + dialog.destroy() - def edit_list(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()] - dialog = lists.editListDialog(list) - if dialog.get_response() == widgetUtils.OK: - name = dialog.get("name") - description = dialog.get("description") - p = dialog.get("public") - if p == True: - mode = "public" - else: - mode = "private" - try: - self.session.twitter.update_list(list_id=list.id, name=name, description=description, mode=mode) - self.session.get_lists() - self.dialog.populate_list(self.get_all_lists(), True) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) - dialog.destroy() + def edit_list(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()] + dialog = lists.editListDialog(list) + if dialog.get_response() == widgetUtils.OK: + name = dialog.get("name") + description = dialog.get("description") + p = dialog.get("public") + if p == True: + mode = "public" + else: + mode = "private" + try: + self.session.twitter.update_list(list_id=list.id, name=name, description=description, mode=mode) + self.session.get_lists() + self.dialog.populate_list(self.get_all_lists(), True) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) + dialog.destroy() - def remove_list(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()].id - if lists.remove_list() == widgetUtils.YES: - try: - self.session.twitter.destroy_list(list_id=list) - self.session.db["lists"].pop(self.dialog.get_item()) - self.dialog.lista.remove_item(self.dialog.get_item()) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) + def remove_list(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()].id + if lists.remove_list() == widgetUtils.YES: + try: + self.session.twitter.destroy_list(list_id=list) + self.session.db["lists"].pop(self.dialog.get_item()) + self.dialog.lista.remove_item(self.dialog.get_item()) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) - def open_list_as_buffer(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list = self.session.db["lists"][self.dialog.get_item()] - pub.sendMessage("create-new-buffer", buffer="list", account=self.session.db["user_name"], create=list.name) + def open_list_as_buffer(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list = self.session.db["lists"][self.dialog.get_item()] + pub.sendMessage("create-new-buffer", buffer="list", account=self.session.db["user_name"], create=list.name) - def subscribe(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list_id = self.lists[self.dialog.get_item()].id - try: - list = self.session.twitter.subscribe_list(list_id=list_id) - item = utils.find_item(list.id, self.session.db["lists"]) - self.session.db["lists"].append(list) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) + def subscribe(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list_id = self.lists[self.dialog.get_item()].id + try: + list = self.session.twitter.subscribe_list(list_id=list_id) + item = utils.find_item(list.id, self.session.db["lists"]) + self.session.db["lists"].append(list) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) - def unsubscribe(self, *args, **kwargs): - if self.dialog.lista.get_count() == 0: return - list_id = self.lists[self.dialog.get_item()].id - try: - list = self.session.twitter.unsubscribe_list(list_id=list_id) - self.session.db["lists"].remove(list) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) + def unsubscribe(self, *args, **kwargs): + if self.dialog.lista.get_count() == 0: return + list_id = self.lists[self.dialog.get_item()].id + try: + list = self.session.twitter.unsubscribe_list(list_id=list_id) + self.session.db["lists"].remove(list) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) diff --git a/src/controller/mainController.py b/src/controller/mainController.py index 608dc900..ddedb068 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -2,1617 +2,1667 @@ import platform system = platform.system() import application +import wx import requests from audio_services import youtube_utils import arrow if system == "Windows": - from update import updater - from wxUI import (view, dialogs, commonMessageDialogs, sysTrayIcon) - from . import settings - from extra import SoundsTutorial, ocr - import keystrokeEditor - from keyboard_handler.wx_handler import WXKeyboardHandler - from . import userActionsController - from . import trendingTopics - from . import user - from . import listsController - from . import filterController + from update import updater + from wxUI import (view, dialogs, commonMessageDialogs, sysTrayIcon) + from . import settings + from extra import SoundsTutorial, ocr + import keystrokeEditor + from keyboard_handler.wx_handler import WXKeyboardHandler + from . import userActionsController + from . import trendingTopics + from . import user + from . import listsController + from . import filterController # from issueReporter import issueReporter elif system == "Linux": - from gtkUI import (view, commonMessageDialogs) + from gtkUI import (view, commonMessageDialogs) from sessions.twitter import utils, compose from sessionmanager import manager, sessionManager - -from controller.buffers import baseBuffers, twitterBuffers +from controller import buffers from . import messages +from . import userAliasController import sessions from sessions.twitter import session as session_ from pubsub import pub import sound import output -from tweepy.error import TweepError +from tweepy.errors import TweepyException, Forbidden from mysc.thread_utils import call_threaded 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): - """ Main Controller for TWBlue. It manages the main window and sessions.""" - - def search_buffer(self, name_, user): - - """ Searches a buffer. - name_ str: The name for the buffer - user str: The account for the buffer. - for example you may want to search the home_timeline buffer for the tw_blue2 user. - Return type: buffers.buffer object.""" - for i in self.buffers: - if i.name == name_ and i.account == user: return i - - def get_current_buffer(self): - """ Get the current focused bufferObject. - Return type: buffers.buffer object.""" - buffer = self.view.get_current_buffer() - if hasattr(buffer, "account"): - buffer = self.search_buffer(buffer.name, buffer.account) - return buffer - - def get_best_buffer(self): - """ Get the best buffer for doing something using the session object. - This function is useful when you need to open a timeline or post a tweet, and the user is in a buffer without a session, for example the events buffer. - Return type: twitterBuffers.buffer object.""" - # Gets the parent buffer to know what account is doing an action - view_buffer = self.view.get_current_buffer() - # If the account has no session attached, we will need to search the first available non-empty buffer for that account to use its session. - if view_buffer.type == "account" or view_buffer.type == "empty": - buffer = self.get_first_buffer(view_buffer.account) - else: - buffer = self.search_buffer(view_buffer.name, view_buffer.account) - if buffer != None: return buffer - - def get_first_buffer(self, account): - """ Gets the first valid buffer for an account. - account str: A twitter username. - The first valid buffer is the home timeline.""" - for i in self.buffers: - if i.account == account and i.invisible == True and i.session != None: - return i - - def get_last_buffer(self, account): - """ Gets the last valid buffer for an account. - account str: A twitter username. - The last valid buffer is the last buffer that contains a session object assigned.""" - results = self.get_buffers_for_account(account) - return results[-1] - - def get_first_buffer_index(self, account): - buff = self.get_first_buffer(account) - return self.view.search(buff.name, buff.account) - - def get_last_buffer_index(self, account): - buff = self.get_last_buffer(account) - return self.view.search(buff.name, buff.account) - - def get_buffers_for_account(self, account): - results = [] - buffers = self.view.get_buffers() - [results.append(self.search_buffer(i.name, i.account)) for i in buffers if i.account == account and (i.type != "account")] - return results - - def bind_other_events(self): - """ Binds the local application events with their functions.""" - log.debug("Binding other application events...") - pub.subscribe(self.buffer_title_changed, "buffer-title-changed") - pub.subscribe(self.manage_sent_dm, "sent-dm") - widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_) - pub.subscribe(self.logout_account, "logout") - pub.subscribe(self.login_account, "login") - pub.subscribe(self.create_new_buffer, "create-new-buffer") - pub.subscribe(self.execute_action, "execute-action") - pub.subscribe(self.search_topic, "search") - pub.subscribe(self.update_sent_dms, "sent-dms-updated") - pub.subscribe(self.more_dms, "more-sent-dms") - pub.subscribe(self.manage_sent_tweets, "sent-tweet") - pub.subscribe(self.manage_friend, "friend") - pub.subscribe(self.manage_unfollowing, "unfollowing") - pub.subscribe(self.manage_favourite, "favourite") - pub.subscribe(self.manage_unfavourite, "unfavourite") - pub.subscribe(self.manage_blocked_user, "blocked-user") - pub.subscribe(self.manage_unblocked_user, "unblocked-user") - if system == "Windows": - pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed") - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_trending_topics, menuitem=self.view.trends) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.filter, menuitem=self.view.filter) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_filters, menuitem=self.view.manage_filters) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.accountConfiguration, menuitem=self.view.account_settings) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.ocr_image, menuitem=self.view.ocr) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close) - widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit) - if widgetUtils.toolkit == "wx": - log.debug("Binding the exit function...") - widgetUtils.connectExitFunction(self.exit_) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.edit_keystrokes, menuitem=self.view.keystroke_editor) - 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_retweet, self.view.retweet) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_favourites, self.view.fav) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_favourites, self.view.unfav) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_item, self.view.view) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.reverse_geocode, menuitem=self.view.view_coordinates) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.delete, self.view.delete) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.follow, menuitem=self.view.follow) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.send_dm, self.view.dm) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_more_items, menuitem=self.view.load_previous_items) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.clear_buffer, menuitem=self.view.clear) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_buffer, self.view.deleteTl) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.check_for_updates, self.view.check_for_updates) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.about, menuitem=self.view.about) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.visit_website, menuitem=self.view.visit_website) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_soundpacks, menuitem=self.view.get_soundpacks) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_accounts, self.view.manage_accounts) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_profile, menuitem=self.view.updateProfile) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.user_details, menuitem=self.view.details) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_autoread, menuitem=self.view.autoread) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_buffer_mute, self.view.mute_buffer) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_timeline, self.view.timeline) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_favs_timeline, self.view.favs) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_conversation, menuitem=self.view.view_conversation) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.seekLeft, menuitem=self.view.seekLeft) - widgetUtils.connect_event(self.view, widgetUtils.MENU, self.seekRight, menuitem=self.view.seekRight) - if widgetUtils.toolkit == "wx": - widgetUtils.connect_event(self.view.nb, widgetUtils.NOTEBOOK_PAGE_CHANGED, self.buffer_changed) - 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_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) - - def set_systray_icon(self): - self.systrayIcon = sysTrayIcon.SysTrayIcon() - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.post_tweet, menuitem=self.systrayIcon.tweet) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.configuration, menuitem=self.systrayIcon.global_settings) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.accountConfiguration, menuitem=self.systrayIcon.account_settings) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.update_profile, menuitem=self.systrayIcon.update_profile) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.show_hide, menuitem=self.systrayIcon.show_hide) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.check_for_updates, menuitem=self.systrayIcon.check_for_updates) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.view_documentation, menuitem=self.systrayIcon.doc) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.exit, menuitem=self.systrayIcon.exit) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.TASKBAR_LEFT_CLICK, self.taskbar_left_click) - widgetUtils.connect_event(self.systrayIcon, widgetUtils.TASKBAR_RIGHT_CLICK, self.taskbar_right_click) - - def taskbar_left_click(self, *args, **kwargs): - if self.showing == True: - self.view.set_focus() - else: - self.show_hide() - - def taskbar_right_click(self, *args, **kwargs): - self.systrayIcon.show_menu() - - def __init__(self): - super(Controller, self).__init__() - # Visibility state. - self.showing = True - # main window - self.view = view.mainFrame() - # buffers list. - self.buffers = [] - self.started = False - # accounts list. - self.accounts = [] - # This saves the current account (important in invisible mode) - self.current_account = "" - self.view.prepare() - self.bind_other_events() - if system == "Windows": - self.set_systray_icon() - - def check_invisible_at_startup(self): - # Visibility check. It does only work for windows. - if system != "Windows": return - if config.app["app-settings"]["hide_gui"] == True: - self.show_hide() - self.view.Show() - self.view.Hide() - # Invisible keyboard Shorcuts check. - if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == True: - km = self.create_invisible_keyboard_shorcuts() - self.register_invisible_keyboard_shorcuts(km) - - def do_work(self): - """ Creates the buffer objects for all accounts. This does not starts the buffer streams, only creates the objects.""" - log.debug("Creating buffers for all sessions...") - for i in sessions.sessions: - log.debug("Working on session %s" % (i,)) - if sessions.sessions[i].is_logged == False: - self.create_ignored_session_buffer(sessions.sessions[i]) - continue - self.create_buffers(sessions.sessions[i]) - - # Connection checker executed each minute. - self.checker_function = RepeatingTimer(60, self.check_connection) - self.checker_function.start() - self.save_db = RepeatingTimer(300, self.save_data_in_db) - self.save_db.start() - log.debug("Setting updates to buffers every %d seconds..." % (60*config.app["app-settings"]["update_period"],)) - self.update_buffers_function = RepeatingTimer(60*config.app["app-settings"]["update_period"], self.update_buffers) - self.update_buffers_function.start() - - def start(self): - """ Starts all buffer objects. Loads their items.""" - for i in sessions.sessions: - if sessions.sessions[i].is_logged == False: continue - self.start_buffers(sessions.sessions[i]) - self.set_buffer_positions(sessions.sessions[i]) - if config.app["app-settings"]["play_ready_sound"] == True: - sessions.sessions[list(sessions.sessions.keys())[0]].sound.play("ready.ogg") - if config.app["app-settings"]["speak_ready_msg"] == True: - output.speak(_(u"Ready")) - self.started = True - - def create_ignored_session_buffer(self, session): - self.accounts.append(session.settings["twitter"]["user_name"]) - account = baseBuffers.accountPanel(self.view.nb, session.settings["twitter"]["user_name"], session.settings["twitter"]["user_name"], session.session_id) - account.logged = False - account.setup_account() - self.buffers.append(account) - self.view.add_buffer(account.buffer , name=session.settings["twitter"]["user_name"]) - - def login_account(self, session_id): - for i in sessions.sessions: - if sessions.sessions[i].session_id == session_id: session = sessions.sessions[i] - session.login() - session.db = dict() - self.create_buffers(session, False) - self.start_buffers(session) - - def create_buffers(self, session, createAccounts=True): - """ Generates buffer objects for an user account. - session SessionObject: a sessionmanager.session.Session Object""" - session.get_user_info() - if createAccounts == True: - self.accounts.append(session.db["user_name"]) - account = baseBuffers.accountPanel(self.view.nb, session.db["user_name"], session.db["user_name"], session.session_id) - account.setup_account() - self.buffers.append(account) - self.view.add_buffer(account.buffer , name=session.db["user_name"]) - for i in session.settings['general']['buffer_order']: - if i == 'home': - home = twitterBuffers.baseBufferController(self.view.nb, "home_timeline", "home_timeline", session, session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended") - self.buffers.append(home) - self.view.insert_buffer(home.buffer, name=_(u"Home"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'mentions': - mentions = twitterBuffers.baseBufferController(self.view.nb, "mentions_timeline", "mentions", session, session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended") - self.buffers.append(mentions) - self.view.insert_buffer(mentions.buffer, name=_(u"Mentions"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'dm': - dm = twitterBuffers.directMessagesController(self.view.nb, "list_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg", full_text=True, items="events") - self.buffers.append(dm) - self.view.insert_buffer(dm.buffer, name=_(u"Direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'sent_dm': - sent_dm = twitterBuffers.sentDirectMessagesController(self.view.nb, "", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message") - self.buffers.append(sent_dm) - self.view.insert_buffer(sent_dm.buffer, name=_(u"Sent direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'sent_tweets': - sent_tweets = twitterBuffers.baseBufferController(self.view.nb, "user_timeline", "sent_tweets", session, session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended") - self.buffers.append(sent_tweets) - self.view.insert_buffer(sent_tweets.buffer, name=_(u"Sent tweets"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'favorites': - favourites = twitterBuffers.baseBufferController(self.view.nb, "favorites", "favourites", session, session.db["user_name"], sound="favourite.ogg", tweet_mode="extended") - self.buffers.append(favourites) - self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'followers': - followers = twitterBuffers.peopleBufferController(self.view.nb, "followers", "followers", session, session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"]) - self.buffers.append(followers) - self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'friends': - friends = twitterBuffers.peopleBufferController(self.view.nb, "friends", "friends", session, session.db["user_name"], screen_name=session.db["user_name"]) - self.buffers.append(friends) - self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'blocks': - blocks = twitterBuffers.peopleBufferController(self.view.nb, "blocks", "blocked", session, session.db["user_name"]) - self.buffers.append(blocks) - self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - elif i == 'muted': - muted = twitterBuffers.peopleBufferController(self.view.nb, "mutes", "muted", session, session.db["user_name"]) - self.buffers.append(muted) - self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - timelines = baseBuffers.emptyPanel(self.view.nb, "timelines", session.db["user_name"]) - self.buffers.append(timelines) - self.view.insert_buffer(timelines.buffer , name=_(u"Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["timelines"]: - tl = twitterBuffers.baseBufferController(self.view.nb, "user_timeline", "%s-timeline" % (i,), session, session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended") - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(i,), pos=self.view.search("timelines", session.db["user_name"])) - favs_timelines = baseBuffers.emptyPanel(self.view.nb, "favs_timelines", session.db["user_name"]) - self.buffers.append(favs_timelines) - self.view.insert_buffer(favs_timelines.buffer , name=_(u"Likes timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["favourites_timelines"]: - tl = twitterBuffers.baseBufferController(self.view.nb, "favorites", "%s-favorite" % (i,), session, session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended") - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"])) - followers_timelines = baseBuffers.emptyPanel(self.view.nb, "followers_timelines", session.db["user_name"]) - self.buffers.append(followers_timelines) - self.view.insert_buffer(followers_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["followers_timelines"]: - tl = twitterBuffers.peopleBufferController(self.view.nb, "followers", "%s-followers" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i) - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"Followers for {}").format(i,), pos=self.view.search("followers_timelines", session.db["user_name"])) - friends_timelines = baseBuffers.emptyPanel(self.view.nb, "friends_timelines", session.db["user_name"]) - self.buffers.append(friends_timelines) - self.view.insert_buffer(friends_timelines.buffer , name=_(u"Friends' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["friends_timelines"]: - tl = twitterBuffers.peopleBufferController(self.view.nb, "friends", "%s-friends" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i) - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"Friends for {}").format(i,), pos=self.view.search("friends_timelines", session.db["user_name"])) - lists = baseBuffers.emptyPanel(self.view.nb, "lists", session.db["user_name"]) - self.buffers.append(lists) - self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["lists"]: - tl = twitterBuffers.listBufferController(self.view.nb, "list_timeline", "%s-list" % (i,), session, session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended") - session.lists.append(tl) - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(i), pos=self.view.search("lists", session.db["user_name"])) - searches = baseBuffers.emptyPanel(self.view.nb, "searches", session.db["user_name"]) - self.buffers.append(searches) - self.view.insert_buffer(searches.buffer , name=_(u"Searches"), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - for i in session.settings["other_buffers"]["tweet_searches"]: - tl = twitterBuffers.searchBufferController(self.view.nb, "search", "%s-searchterm" % (i,), session, session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended") - self.buffers.append(tl) - self.view.insert_buffer(tl.buffer, name=_(u"Search for {}").format(i), pos=self.view.search("searches", session.db["user_name"])) - for i in session.settings["other_buffers"]["trending_topic_buffers"]: - buffer = twitterBuffers.trendsBufferController(self.view.nb, "%s_tt" % (i,), session, session.db["user_name"], i, sound="trends_updated.ogg") - buffer.start_stream(play_sound=False) - buffer.searchfunction = self.search - self.buffers.append(buffer) - self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (buffer.name_), pos=self.view.search(session.db["user_name"], session.db["user_name"])) - - def set_buffer_positions(self, session): - "Sets positions for buffers if values exist in the database." - for i in self.buffers: - if i.account == session.db["user_name"] and i.name+"_pos" in session.db and hasattr(i.buffer,'list'): - i.buffer.list.select_item(session.db[str(i.name+"_pos")]) - - def logout_account(self, session_id): - for i in sessions.sessions: - if sessions.sessions[i].session_id == session_id: session = sessions.sessions[i] - user = session.db["user_name"] - delete_buffers = [] - for i in self.buffers: - if i.account == user and i.name != user: - delete_buffers.append(i.name) - for i in delete_buffers: - self.destroy_buffer(i, user) - session.db = None - - def destroy_buffer(self, buffer_name, account): - buffer = self.search_buffer(buffer_name, account) - if buffer == None: return - buff = self.view.search(buffer.name, buffer.account) - if buff == None: return - self.view.delete_buffer(buff) - self.buffers.remove(buffer) - del buffer - - def search_topic(self, term): - self.search(value=term) - - def search(self, event=None, value="", *args, **kwargs): - """ Searches words or users in twitter. This creates a new buffer containing the search results.""" - log.debug("Creating a new search...") - dlg = dialogs.search.searchDialog(value) - if dlg.get_response() == widgetUtils.OK and dlg.get("term") != "": - term = dlg.get("term") - buffer = self.get_best_buffer() - if dlg.get("tweets") == True: - if term not in buffer.session.settings["other_buffers"]["tweet_searches"]: - buffer.session.settings["other_buffers"]["tweet_searches"].append(term) - buffer.session.settings.write() - args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()} - search = twitterBuffers.searchBufferController(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args) - else: - log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,)) - return - elif dlg.get("users") == True: - search = twitterBuffers.searchPeopleBufferController(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term) - search.start_stream(mandatory=True) - pos=self.view.search("searches", buffer.session.db["user_name"]) - self.insert_buffer(search, pos) - self.view.insert_buffer(search.buffer, name=_(u"Search for {}").format(term), pos=pos) - dlg.Destroy() - - def find(self, *args, **kwargs): - if 'string' in kwargs: - string=kwargs['string'] - else: - string='' - dlg = dialogs.find.findDialog(string) - if dlg.get_response() == widgetUtils.OK and dlg.get("string") != "": - string = dlg.get("string") - #If we still have an empty string for some reason (I.E. user clicked cancel, etc), return here. - if string == '': - log.debug("Find canceled.") - return - page = self.get_current_buffer() - if not hasattr(page.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - count = page.buffer.list.get_count() - if count < 1: - output.speak(_(u"Empty buffer."), True) - return - start = page.buffer.list.get_selected() - for i in range(start, count): - if string.lower() in page.buffer.list.get_text_column(i, 1).lower(): - page.buffer.list.select_item(i) - return output.speak(page.get_message(), True) - output.speak(_(u"{0} not found.").format(string,), True) - - def filter(self, *args, **kwargs): - page = self.get_current_buffer() - if not hasattr(page.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - # Let's prevent filtering of some buffers (people buffers, direct messages, events and sent items). - # ToDo: Remove events from here after August 16. - if (page.name == "direct_messages" or page.name == "sent_tweets" or page.name == "events") or page.type == "people": - output.speak(_(u"Filters cannot be applied on this buffer")) - return - new_filter = filterController.filter(page) - - def manage_filters(self, *args, **kwargs): - page = self.get_best_buffer() - manage_filters = filterController.filterManager(page.session) - - def seekLeft(self, *args, **kwargs): - try: - sound.URLPlayer.seek(-5000) - except: - output.speak("Unable to seek.",True) - - def seekRight(self, *args, **kwargs): - try: - sound.URLPlayer.seek(5000) - except: - output.speak("Unable to seek.",True) - - def edit_keystrokes(self, *args, **kwargs): - editor = keystrokeEditor.KeystrokeEditor() - if editor.changed == True: - config.keymap.write() - register = False - # determines if we need to reassign the keymap. - if self.showing == False: - register = True - elif config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == True: - register = True - # If there is a keyboard handler instance we need unregister all old keystrokes before register the new ones. - if hasattr(self, "keyboard_handler"): - keymap = {} - for i in editor.hold_map: - if hasattr(self, i): keymap[editor.hold_map[i]] = getattr(self, i) - self.unregister_invisible_keyboard_shorcuts(keymap) - self.invisible_shorcuts_changed(registered=register) - - def learn_sounds(self, *args, **kwargs): - """ Opens the sounds tutorial for the current account.""" - buffer = self.get_best_buffer() - SoundsTutorial.soundsTutorial(buffer.session) - - def view_user_lists(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.db) - dlg = dialogs.utils.selectUserDialog(_(u"Select the user"), users) - if dlg.get_response() == widgetUtils.OK: - user = dlg.get_user() - else: - return - l = listsController.listsController(buff.session, user=user) - - def add_to_list(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.db) - dlg = dialogs.utils.selectUserDialog(_(u"Select the user"), users) - if dlg.get_response() == widgetUtils.OK: - user = dlg.get_user() - else: - return - dlg = dialogs.lists.addUserListDialog() - dlg.populate_list([compose.compose_list(item) for item in buff.session.db["lists"]]) - if dlg.get_response() == widgetUtils.OK: - try: - list = buff.session.twitter.add_list_member(list_id=buff.session.db["lists"][dlg.get_item()].id, screen_name=user) - older_list = utils.find_item(buff.session.db["lists"][dlg.get_item()].id, buff.session.db["lists"]) - listBuffer = self.search_buffer("%s-list" % (buff.session.db["lists"][dlg.get_item()].name.lower()), buff.session.db["user_name"]) - if listBuffer != None: listBuffer.get_user_ids() - buff.session.db["lists"].pop(older_list) - buff.session.db["lists"].append(list) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) - - def remove_from_list(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.db) - dlg = dialogs.utils.selectUserDialog(_(u"Select the user"), users) - if dlg.get_response() == widgetUtils.OK: - user = dlg.get_user() - else: - return - dlg = dialogs.lists.removeUserListDialog() - dlg.populate_list([compose.compose_list(item) for item in buff.session.db["lists"]]) - if dlg.get_response() == widgetUtils.OK: - try: - list = buff.session.twitter.remove_list_member(list_id=buff.session.db["lists"][dlg.get_item()].id, screen_name=user) - older_list = utils.find_item(buff.session.db["lists"][dlg.get_item()].id, buff.session.db["lists"]) - listBuffer = self.search_buffer("%s-list" % (buff.session.db["lists"][dlg.get_item()].name.lower()), buff.session.db["user_name"]) - if listBuffer != None: listBuffer.get_user_ids() - buff.session.db["lists"].pop(older_list) - buff.session.db["lists"].append(list) - except TweepError as e: - output.speak("error %s: %s" % (e.api_code, e.reason)) - - def list_manager(self, *args, **kwargs): - s = self.get_best_buffer().session - l = listsController.listsController(s) - - def configuration(self, *args, **kwargs): - """ Opens the global settings dialogue.""" - d = settings.globalSettingsController() - if d.response == widgetUtils.OK: - d.save_configuration() - if d.needs_restart == True: - commonMessageDialogs.needs_restart() - restart.restart_program() - - def accountConfiguration(self, *args, **kwargs): - """ Opens the account settings dialogue for the current account.""" - buff = self.get_best_buffer() - manager.manager.set_current_session(buff.session.session_id) - d = settings.accountSettingsController(buff, self) - if d.response == widgetUtils.OK: - d.save_configuration() - if d.needs_restart == True: - commonMessageDialogs.needs_restart() - buff.session.settings.write() - restart.restart_program() - - def report_error(self, *args, **kwargs): - r = issueReporter.reportBug(self.get_best_buffer().session.db["user_name"]) - - def check_for_updates(self, *args, **kwargs): - update = updater.do_update() - if update == False: - view.no_update_available() - - def delete(self, *args, **kwargs): - """ Deletes an item in the current buffer. - Users can only remove their tweets and direct messages, other users' tweets and people (followers, friends, blocked, etc) can not be removed using this method.""" - buffer = self.view.get_current_buffer() - if hasattr(buffer, "account"): - buffer = self.search_buffer(buffer.name, buffer.account) - buffer.destroy_status() - - def exit(self, *args, **kwargs): - if config.app["app-settings"]["ask_at_exit"] == True: - answer = commonMessageDialogs.exit_dialog(self.view) - if answer == widgetUtils.YES: - self.exit_() - else: - self.exit_() - - def exit_(self, *args, **kwargs): - for i in self.buffers: i.save_positions() - log.debug("Exiting...") - log.debug("Saving global configuration...") - for item in sessions.sessions: - if sessions.sessions[item].logged == False: continue - log.debug("Disconnecting streams for %s session" % (sessions.sessions[item].session_id,)) - sessions.sessions[item].sound.cleaner.cancel() - log.debug("Shelving database for " + sessions.sessions[item].session_id) - sessions.sessions[item].shelve() - if system == "Windows": - self.systrayIcon.RemoveIcon() - pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) - if os.path.exists(pidpath): - os.remove(pidpath) - widgetUtils.exit_application() - - def follow(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users) - - def unfollow(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "unfollow") - - def mute(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "mute") - - def unmute(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "unmute") - - def block(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "block") - - def unblock(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "unblock") - - def report(self, *args, **kwargs): - buff = self.get_current_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.db) - u = userActionsController.userActionsController(buff, users, "report") - - def post_tweet(self, event=None): - buffer = self.get_best_buffer() - buffer.post_status() - - def post_reply(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.name == "direct_messages": - buffer.send_message() - else: - buffer.reply() - - def send_dm(self, *args, **kwargs): - buffer = self.get_current_buffer() - buffer.send_message() - - def post_retweet(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": - return - else: - buffer.share_item() - - def add_to_favourites(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": - return - else: - id = buffer.get_tweet().id - call_threaded(buffer.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id) - - def remove_from_favourites(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": - return - else: - id = buffer.get_tweet().id - call_threaded(buffer.session.api_call, call_name="destroy_favorite", id=id) - - def toggle_like(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": - return - else: - id = buffer.get_tweet().id - tweet = buffer.session.twitter.get_status(id=id, include_ext_alt_text=True, tweet_mode="extended") - if tweet.favorited == False: - call_threaded(buffer.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id) - else: - call_threaded(buffer.session.api_call, call_name="destroy_favorite", id=id) - - def view_item(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.type == "account" or buffer.type == "empty": - 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"]) - elif buffer.type == "dm": - non_tweet = buffer.get_formatted_message() - item = buffer.get_right_tweet() - original_date = arrow.get(int(item.created_timestamp)) - 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: - non_tweet = buffer.get_formatted_message() - msg = messages.viewTweet(non_tweet, [], False) - - def open_in_browser(self, *args, **kwargs): - buffer = self.get_current_buffer() - if hasattr(buffer, "open_in_browser"): - buffer.open_in_browser() - - def open_favs_timeline(self, *args, **kwargs): - self.open_timeline(default="favourites") - - def open_timeline(self, default="tweets", *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.db) - dlg = dialogs.userSelection.selectUserDialog(users=users, default=default) - if dlg.get_response() == widgetUtils.OK: - usr = utils.if_user_exists(buff.session.twitter, dlg.get_user()) - if usr != None: - if usr == dlg.get_user(): - commonMessageDialogs.suspended_user() - return - if usr.protected == True: - if usr.following == False: - commonMessageDialogs.no_following() - return - tl_type = dlg.get_action() - if tl_type == "tweets": - if usr.statuses_count == 0: - commonMessageDialogs.no_tweets() - return - if usr.id_str in buff.session.settings["other_buffers"]["timelines"]: - commonMessageDialogs.timeline_exist() - return - tl = twitterBuffers.baseBufferController(self.view.nb, "user_timeline", "%s-timeline" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="tweet_timeline.ogg", user_id=usr.id_str, tweet_mode="extended") - try: - tl.start_stream(play_sound=False) - except ValueError: - commonMessageDialogs.unauthorized() - return - pos=self.view.search("timelines", buff.session.db["user_name"]) - self.insert_buffer(tl, pos+1) - self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(dlg.get_user()), pos=pos) - buff.session.settings["other_buffers"]["timelines"].append(usr.id_str) - pub.sendMessage("buffer-title-changed", buffer=tl) - buff.session.sound.play("create_timeline.ogg") - elif tl_type == "favourites": - if usr.favourites_count == 0: - commonMessageDialogs.no_favs() - return - if usr.id_str in buff.session.settings["other_buffers"]["favourites_timelines"]: - commonMessageDialogs.timeline_exist() - return - tl = twitterBuffers.baseBufferController(self.view.nb, "favorites", "%s-favorite" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr.id_str, tweet_mode="extended") - try: - tl.start_stream(play_sound=False) - except ValueError: - commonMessageDialogs.unauthorized() - return - pos=self.view.search("favs_timelines", buff.session.db["user_name"]) - self.insert_buffer(tl, pos+1) - self.view.insert_buffer(buffer=tl.buffer, name=_(u"Likes for {}").format(dlg.get_user()), pos=pos) - buff.session.settings["other_buffers"]["favourites_timelines"].append(usr.id_str) - pub.sendMessage("buffer-title-changed", buffer=buff) - buff.session.sound.play("create_timeline.ogg") - elif tl_type == "followers": - if usr.followers_count == 0: - commonMessageDialogs.no_followers() - return - if usr.id_str in buff.session.settings["other_buffers"]["followers_timelines"]: - commonMessageDialogs.timeline_exist() - return - tl = twitterBuffers.peopleBufferController(self.view.nb, "followers", "%s-followers" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str) - try: - tl.start_stream(play_sound=False) - except ValueError: - commonMessageDialogs.unauthorized() - return - pos=self.view.search("followers_timelines", buff.session.db["user_name"]) - self.insert_buffer(tl, pos+1) - self.view.insert_buffer(buffer=tl.buffer, name=_(u"Followers for {}").format(dlg.get_user()), pos=pos) - buff.session.settings["other_buffers"]["followers_timelines"].append(usr.id_str) - buff.session.sound.play("create_timeline.ogg") - pub.sendMessage("buffer-title-changed", buffer=i) - elif tl_type == "friends": - if usr.friends_count == 0: - commonMessageDialogs.no_friends() - return - if usr.id_str in buff.session.settings["other_buffers"]["friends_timelines"]: - commonMessageDialogs.timeline_exist() - return - tl = twitterBuffers.peopleBufferController(self.view.nb, "friends", "%s-friends" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str) - try: - tl.start_stream(play_sound=False) - except ValueError: - commonMessageDialogs.unauthorized() - return - pos=self.view.search("friends_timelines", buff.session.db["user_name"]) - self.insert_buffer(tl, pos+1) - self.view.insert_buffer(buffer=tl.buffer, name=_(u"Friends for {}").format(dlg.get_user()), pos=pos) - buff.session.settings["other_buffers"]["friends_timelines"].append(usr.id_str) - buff.session.sound.play("create_timeline.ogg") - pub.sendMessage("buffer-title-changed", buffer=i) - else: - commonMessageDialogs.user_not_exist() - buff.session.settings.write() - - def open_conversation(self, *args, **kwargs): - buffer = self.get_current_buffer() - id = buffer.get_right_tweet().id_str - user = buffer.get_right_tweet().user.screen_name - search = twitterBuffers.conversationBufferController(self.view.nb, "search", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,)) - search.tweet = buffer.get_right_tweet() - search.start_stream(start=True) - pos=self.view.search("searches", buffer.session.db["user_name"]) - self.insert_buffer(search, pos) - self.view.insert_buffer(search.buffer, name=_(u"Conversation with {0}").format(user), pos=pos) - - def show_hide(self, *args, **kwargs): - km = self.create_invisible_keyboard_shorcuts() - if self.showing == True: - if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: - self.register_invisible_keyboard_shorcuts(km) - self.view.Hide() - self.fix_wrong_buffer() - self.showing = False - else: - if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: - self.unregister_invisible_keyboard_shorcuts(km) - self.view.Show() - self.showing = True - - def get_trending_topics(self, *args, **kwargs): - buff = self.get_best_buffer() - trends = trendingTopics.trendingTopicsController(buff.session) - if trends.dialog.get_response() == widgetUtils.OK: - woeid = trends.get_woeid() - if woeid in buff.session.settings["other_buffers"]["trending_topic_buffers"]: return - buffer = twitterBuffers.trendsBufferController(self.view.nb, "%s_tt" % (woeid,), buff.session, buff.account, woeid, sound="trends_updated.ogg") - buffer.searchfunction = self.search - pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]) - self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (trends.get_string()), pos=pos) - self.buffers.append(buffer) - buffer.start_stream() - buffer.session.settings["other_buffers"]["trending_topic_buffers"].append(woeid) - buffer.session.settings.write() - - def reverse_geocode(self, event=None): - try: - tweet = self.get_current_buffer().get_tweet() - 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__()) - 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 AttributeError: - pass - - def view_reverse_geocode(self, event=None): - try: - tweet = self.get_current_buffer().get_right_tweet() - if tweet.coordinates != None: - x = tweet.coordinates["coordinates"][0] - y = tweet.coordinates["coordinates"][1] - address = geocoder.reverse_geocode(y, x, language = languageHandler.curLang) - dlg = commonMessageDialogs.view_geodata(address[0].__str__()) - 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 AttributeError: - pass - - def get_more_items(self, *args, **kwargs): - self.get_current_buffer().get_more_items() - - def clear_buffer(self, *args, **kwargs): - self.get_current_buffer().clear_list() - - def remove_buffer(self, *args, **kwargs): - buffer = self.get_current_buffer() - if not hasattr(buffer, "account"): return - buff = self.view.search(buffer.name, buffer.account) - answer = buffer.remove_buffer() - if answer == False: return - log.debug("destroying buffer...") - if hasattr(buffer, "timer"): - log.debug("Stopping timer...") - buffer.timer.cancel() - log.debug("Timer cancelled.") - self.right() - self.view.delete_buffer(buff) - buffer.session.sound.play("delete_timeline.ogg") - self.buffers.remove(buffer) - del buffer - - def skip_buffer(self, forward=True): - buff = self.get_current_buffer() - if buff.invisible == False: - self.view.advance_selection(forward) - - def buffer_changed(self, *args, **kwargs): - buffer = self.get_current_buffer() - if buffer.account != self.current_account: - self.current_account = buffer.account - if not hasattr(buffer, "session") or buffer.session == None: return - muted = autoread = False - if buffer.name in buffer.session.settings["other_buffers"]["muted_buffers"]: - muted = True - elif buffer.name in buffer.session.settings["other_buffers"]["autoread_buffers"]: - autoread = True - self.view.check_menuitem("mute_buffer", muted) - self.view.check_menuitem("autoread", autoread) - - def fix_wrong_buffer(self): - buf = self.get_best_buffer() - if buf == None: - for i in self.accounts: - buffer = self.view.search("home_timeline", i) - if buffer != None: break - else: - buffer = self.view.search("home_timeline", buf.session.db["user_name"]) - if buffer!=None: - self.view.change_buffer(buffer) - - def up(self, *args, **kwargs): - page = self.get_current_buffer() - if not hasattr(page.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - position = page.buffer.list.get_selected() - index = position-1 - try: - page.buffer.list.select_item(index) - except: - pass - if position == page.buffer.list.get_selected(): - page.session.sound.play("limit.ogg") - - try: - output.speak(page.get_message(), True) - except: - pass - - def down(self, *args, **kwargs): - page = self.get_current_buffer() - if not hasattr(page.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - position = page.buffer.list.get_selected() - index = position+1 - try: - page.buffer.list.select_item(index) - except: - pass - if position == page.buffer.list.get_selected(): - page.session.sound.play("limit.ogg") - try: - output.speak(page.get_message(), True) - except: - pass - - def left(self, *args, **kwargs): - buff = self.view.get_current_buffer_pos() - buffer = self.get_current_buffer() - if not hasattr(buffer.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - if buff == self.get_first_buffer_index(buffer.account) or buff == 0: - self.view.change_buffer(self.get_last_buffer_index(buffer.account)) - else: - self.view.change_buffer(buff-1) - while self.get_current_buffer().invisible == False: self.skip_buffer(False) - buffer = self.get_current_buffer() - if self.showing == True: buffer.buffer.set_focus_in_list() - try: - msg = _(u"%s, %s of %s") % (self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) - except: - msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) - output.speak(msg, True) - - def right(self, *args, **kwargs): - buff = self.view.get_current_buffer_pos() - buffer = self.get_current_buffer() - if not hasattr(buffer.buffer, "list"): - output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) - return - if buff == self.get_last_buffer_index(buffer.account) or buff+1 == self.view.get_buffer_count(): - self.view.change_buffer(self.get_first_buffer_index(buffer.account)) - else: - self.view.change_buffer(buff+1) - while self.get_current_buffer().invisible == False: self.skip_buffer(True) - buffer = self.get_current_buffer() - if self.showing == True: buffer.buffer.set_focus_in_list() - try: - msg = _(u"%s, %s of %s") % (self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) - except: - msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) - output.speak(msg, True) - - def next_account(self, *args, **kwargs): - index = self.accounts.index(self.current_account) - if index+1 == len(self.accounts): - index = 0 - else: - index = index+1 - account = self.accounts[index] - self.current_account = account - buffer_object = self.get_first_buffer(account) - if buffer_object == None: - output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) - return - buff = self.view.search(buffer_object.name, account) - if buff == None: - output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) - return - self.view.change_buffer(buff) - buffer = self.get_current_buffer() - if self.showing == True: buffer.buffer.set_focus_in_list() - try: - msg = _(u"%s. %s, %s of %s") % (buffer.account, self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) - except: - msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) - output.speak(msg, True) - - def previous_account(self, *args, **kwargs): - index = self.accounts.index(self.current_account) - if index-1 < 0: - index = len(self.accounts)-1 - else: - index = index-1 - account = self.accounts[index] - self.current_account = account - buffer_object = self.get_first_buffer(account) - if buffer_object == None: - output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) - return - buff = self.view.search(buffer_object.name, account) - if buff == None: - output.speak(_(u"{0}: This account is not logged into twitter.").format(account), True) - return - self.view.change_buffer(buff) - buffer = self.get_current_buffer() - if self.showing == True: buffer.buffer.set_focus_in_list() - try: - msg = _(u"%s. %s, %s of %s") % (buffer.account, self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) - except: - msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) - output.speak(msg, True) - - def go_home(self): - buffer = self.get_current_buffer() - buffer.buffer.list.select_item(0) - try: - output.speak(buffer.get_message(), True) - except: - pass - - def go_end(self): - buffer = self.get_current_buffer() - buffer.buffer.list.select_item(buffer.buffer.list.get_count()-1) - try: - output.speak(buffer.get_message(), True) - except: - pass - - def go_page_up(self): - buffer = self.get_current_buffer() - if buffer.buffer.list.get_selected() <= 20: - index = 0 - else: - index = buffer.buffer.list.get_selected() - 20 - buffer.buffer.list.select_item(index) - try: - output.speak(buffer.get_message(), True) - except: - pass - - def go_page_down(self): - buffer = self.get_current_buffer() - if buffer.buffer.list.get_selected() >= buffer.buffer.list.get_count() - 20: - index = buffer.buffer.list.get_count()-1 - else: - index = buffer.buffer.list.get_selected() + 20 - buffer.buffer.list.select_item(index) - try: - output.speak(buffer.get_message(), True) - except: - pass - - def url(self, *args, **kwargs): - buffer = self.get_current_buffer() - buffer.url() - - def audio(self, *args, **kwargs): - self.get_current_buffer().audio() - - def volume_down(self, *args, **kwargs): - self.get_current_buffer().volume_down() - - def volume_up(self, *args, **kwargs): - self.get_current_buffer().volume_up() - - def create_invisible_keyboard_shorcuts(self): - keymap = {} - for i in config.keymap["keymap"]: - if hasattr(self, 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() - self.keyboard_handler = WXKeyboardHandler(self.view) - self.keyboard_handler.register_keys(keymap) - - def unregister_invisible_keyboard_shorcuts(self, keymap): - try: - self.keyboard_handler.unregister_keys(keymap) - del self.keyboard_handler - except AttributeError: - pass - - def notify(self, session, play_sound=None, message=None, notification=False): - if session.settings["sound"]["session_mute"] == True: return - if play_sound != None: - session.sound.play(play_sound) - if message != None: - output.speak(message, speech=session.settings["reporting"]["speech_reporting"], braille=session.settings["reporting"]["braille_reporting"]) - - def manage_sent_dm(self, data, user): - buffer = self.search_buffer("sent_direct_messages", user) - if buffer == None: return - play_sound = "dm_sent.ogg" - if "sent_direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]: - self.notify(buffer.session, play_sound=play_sound) - buffer.add_new_item(data) - - def manage_sent_tweets(self, data, user): - buffer = self.search_buffer("sent_tweets", user) - if buffer == None: return -# if "sent_tweets" not in buffer.session.settings["other_buffers"]["muted_buffers"]: -# self.notify(buffer.session, play_sound=play_sound) - data = buffer.session.check_quoted_status(data) - data = buffer.session.check_long_tweet(data) - if data == False: # Long tweet deleted from twishort. - return - if buffer.session.settings["general"]["reverse_timelines"] == False: - buffer.session.db[buffer.name].append(data) - else: - buffer.session.db[buffer.name].insert(0, data) - buffer.add_new_item(data) - - def manage_friend(self, data, user): - buffer = self.search_buffer("friends", user) - if buffer == None: return - buffer.add_new_item(data) - - def manage_unfollowing(self, item, user): - buffer = self.search_buffer("friends", user) - if buffer == None: return - buffer.remove_item(item) - - def manage_favourite(self, data, user): - buffer = self.search_buffer("favourites", user) - if buffer == None: return - play_sound = "favourite.ogg" - if "favourites" not in buffer.session.settings["other_buffers"]["muted_buffers"]: - self.notify(buffer.session, play_sound=play_sound) - buffer.add_new_item(data) - - def manage_unfavourite(self, item, user): - buffer = self.search_buffer("favourites", user) - if buffer == None: return - buffer.remove_item(item) - - def manage_blocked_user(self, data, user): - buffer = self.search_buffer("blocked", user) - if buffer == None: return - buffer.add_new_item(data) - - def manage_unblocked_user(self, item, user): - buffer = self.search_buffer("blocked", user) - if buffer == None: return - buffer.remove_item(item) - - def start_buffers(self, session): - log.debug("starting buffers... Session %s" % (session.session_id,)) - for i in self.buffers: - if i.session == session and i.needs_init == True: - if hasattr(i, "finished_timeline") and i.finished_timeline == False: - change_title = True - else: - change_title = False - try: - if "mentions" in i.name or "direct_messages" in i.name: - i.start_stream() - else: - i.start_stream(play_sound=False) - except TweepError: - buff = self.view.search(i.name, i.account) - i.remove_buffer(force=True) - commonMessageDialogs.blocked_timeline() - if self.get_current_buffer() == i: - self.right() - self.view.delete_buffer(buff) - self.buffers.remove(i) - del i - continue - if change_title: - pub.sendMessage("buffer-title-changed", buffer=i) - - def set_positions(self): - for i in sessions.sessions: - self.set_buffer_positions(i) - - def check_connection(self): - if self.started == False: - return - for i in sessions.sessions: - try: - if sessions.sessions[i].is_logged == False: continue - sessions.sessions[i].check_connection() - except TweepError: # We shouldn't allow this function to die. - pass - - def create_new_buffer(self, buffer, account, create): - buff = self.search_buffer("home_timeline", account) - if create == True: - if buffer == "favourites": - favourites = twitterBuffers.baseBufferController(self.view.nb, "favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended") - self.buffers.append(favourites) - self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - favourites.start_stream(play_sound=False) - if buffer == "followers": - followers = twitterBuffers.peopleBufferController(self.view.nb, "followers", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"]) - self.buffers.append(followers) - self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - followers.start_stream(play_sound=False) - elif buffer == "friends": - friends = twitterBuffers.peopleBufferController(self.view.nb, "friends", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"]) - self.buffers.append(friends) - self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - friends.start_stream(play_sound=False) - elif buffer == "blocked": - blocks = twitterBuffers.peopleBufferController(self.view.nb, "blocks", "blocked", buff.session, buff.session.db["user_name"]) - self.buffers.append(blocks) - self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - blocks.start_stream(play_sound=False) - elif buffer == "muted": - muted = twitterBuffers.peopleBufferController(self.view.nb, "mutes", "muted", buff.session, buff.session.db["user_name"]) - self.buffers.append(muted) - self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - muted.start_stream(play_sound=False) - elif buffer == "events": - events = twitterBuffers.eventsBufferController(self.view.nb, "events", buff.session, buff.session.db["user_name"], bufferType="dmPanel", screen_name=buff.session.db["user_name"]) - self.buffers.append(events) - self.view.insert_buffer(events.buffer, name=_(u"Events"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) - elif create == False: - self.destroy_buffer(buffer, buff.session.db["user_name"]) - elif buffer == "list": - if create in buff.session.settings["other_buffers"]["lists"]: - output.speak(_(u"This list is already opened"), True) - return - tl = twitterBuffers.listBufferController(self.view.nb, "list_timeline", create+"-list", buff.session, buff.session.db["user_name"], bufferType=None, list_id=utils.find_list(create, buff.session.db["lists"]), tweet_mode="extended") - buff.session.lists.append(tl) - pos=self.view.search("lists", buff.session.db["user_name"]) - self.insert_buffer(tl, pos) - self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(create), pos=self.view.search("lists", buff.session.db["user_name"])) - tl.start_stream(play_sound=False) - buff.session.settings["other_buffers"]["lists"].append(create) - buff.session.settings.write() - - def invisible_shorcuts_changed(self, registered): - if registered == True: - km = self.create_invisible_keyboard_shorcuts() - self.register_invisible_keyboard_shorcuts(km) - elif registered == False: - km = self.create_invisible_keyboard_shorcuts() - self.unregister_invisible_keyboard_shorcuts(km) - - def about(self, *args, **kwargs): - self.view.about_dialog() - - def get_soundpacks(self, *args, **kwargs): - # This should redirect users of other languages to the right version of the TWBlue website. - lang = languageHandler.curLang[:2] - url = application.url - final_url = "{0}/{1}/soundpacks".format(url, lang) - try: - response = requests.get(final_url) - except: - output.speak(_(u"An error happened while trying to connect to the server. Please try later.")) - return - # There is no twblue.es/en, so if English is the language used this should be False anyway. - if response.status_code == 200 and lang != "en": - webbrowser.open_new_tab(final_url) - else: - webbrowser.open_new_tab(application.url+"/soundpacks") - - def visit_website(self, *args, **kwargs): - # This should redirect users of other languages to the right version of the TWBlue website. - lang = languageHandler.curLang[:2] - url = application.url - final_url = "{0}/{1}".format(url, lang) - try: - response = requests.get(final_url) - except: - output.speak(_(u"An error happened while trying to connect to the server. Please try later.")) - return - # There is no twblue.es/en, so if English is the language used this should be False anyway. - if response.status_code == 200 and lang != "en": - webbrowser.open_new_tab(final_url) - else: - webbrowser.open_new_tab(application.url) - - def manage_accounts(self, *args, **kwargs): - sm = sessionManager.sessionManagerController(started=True) - sm.fill_list() - sm.show() - for i in sm.new_sessions: - self.create_buffers(sessions.sessions[i]) - call_threaded(self.start_buffers, sessions.sessions[i]) - for i in sm.removed_sessions: - if sessions.sessions[i].logged == True: - self.logout_account(sessions.sessions[i].session_id) - self.destroy_buffer(sessions.sessions[i].settings["twitter"]["user_name"], sessions.sessions[i].settings["twitter"]["user_name"]) - self.accounts.remove(sessions.sessions[i].settings["twitter"]["user_name"]) - sessions.sessions.pop(i) - - def update_profile(self, *args, **kwargs): - r = user.profileController(self.get_best_buffer().session) - - def user_details(self, *args, **kwargs): - buffer = self.get_current_buffer() - if not hasattr(buffer, "session") or buffer.session == None: return - if hasattr(buffer, "user_details"): - buffer.user_details() - - def toggle_autoread(self, *args, **kwargs): - buffer = self.get_current_buffer() - if hasattr(buffer, "session") and buffer.session == None: return - if buffer.name not in buffer.session.settings["other_buffers"]["autoread_buffers"]: - buffer.session.settings["other_buffers"]["autoread_buffers"].append(buffer.name) - output.speak(_(u"The auto-reading of new tweets is enabled for this buffer"), True) - elif buffer.name in buffer.session.settings["other_buffers"]["autoread_buffers"]: - buffer.session.settings["other_buffers"]["autoread_buffers"].remove(buffer.name) - output.speak(_(u"The auto-reading of new tweets is disabled for this buffer"), True) - buffer.session.settings.write() - - def toggle_session_mute(self, *args, **kwargs): - buffer = self.get_best_buffer() - if buffer.session.settings["sound"]["session_mute"] == False: - buffer.session.settings["sound"]["session_mute"] = True - output.speak(_(u"Session mute on"), True) - elif buffer.session.settings["sound"]["session_mute"] == True: - buffer.session.settings["sound"]["session_mute"] = False - output.speak(_(u"Session mute off"), True) - buffer.session.settings.write() - - def toggle_buffer_mute(self, *args, **kwargs): - buffer = self.get_current_buffer() - if hasattr(buffer, "session") and buffer.session == None: return - if buffer.name not in buffer.session.settings["other_buffers"]["muted_buffers"]: - buffer.session.settings["other_buffers"]["muted_buffers"].append(buffer.name) - output.speak(_(u"Buffer mute on"), True) - elif buffer.name in buffer.session.settings["other_buffers"]["muted_buffers"]: - buffer.session.settings["other_buffers"]["muted_buffers"].remove(buffer.name) - output.speak(_(u"Buffer mute off"), True) - buffer.session.settings.write() - - def view_documentation(self, *args, **kwargs): - lang = localization.get("documentation") - os.chdir("documentation/%s" % (lang,)) - webbrowser.open("manual.html") - os.chdir("../../") - - def view_changelog(self, *args, **kwargs): - if application.snapshot == True: - webbrowser.open("https://github.com/manuelcortez/twblue/blob/next-gen/doc/changelog.md") - else: - lang = localization.get("documentation") - os.chdir("documentation/%s" % (lang,)) - webbrowser.open("changelog.html") - os.chdir("../../") - - def insert_buffer(self, buffer, position): - self.buffers.insert(position, buffer) - - def copy_to_clipboard(self, *args, **kwargs): - output.copy(self.get_current_buffer().get_message()) - output.speak(_(u"Copied")) - - def repeat_item(self, *args, **kwargs): - output.speak(self.get_current_buffer().get_message()) - - def execute_action(self, action): - if hasattr(self, action): - getattr(self, action)() - - def update_buffers(self): - for i in self.buffers[:]: - if i.session != None and i.session.is_logged == True: - try: - i.start_stream(mandatory=True) - except TweepError: - buff = self.view.search(i.name, i.account) - i.remove_buffer(force=True) - commonMessageDialogs.blocked_timeline() - if self.get_current_buffer() == i: - self.right() - self.view.delete_buffer(buff) - self.buffers.remove(i) - del i - - def update_buffer(self, *args, **kwargs): - bf = self.get_current_buffer() - if not hasattr(bf, "start_stream"): - output.speak(_(u"Unable to update this buffer.")) - return - else: - output.speak(_(u"Updating buffer...")) - n = bf.start_stream(mandatory=True, avoid_autoreading=True) - if n != None: - output.speak(_(u"{0} items retrieved").format(n,)) - - def buffer_title_changed(self, buffer): - if "-timeline" in buffer.name: - title = _(u"Timeline for {}").format(buffer.username,) - elif "-favorite" in buffer.name: - title = _(u"Likes for {}").format(buffer.username,) - elif "-followers" in buffer.name: - title = _(u"Followers for {}").format(buffer.username,) - elif "-friends" in buffer.name: - title = _(u"Friends for {}").format(buffer.username,) - buffer_index = self.view.search(buffer.name, buffer.account) - self.view.set_page_title(buffer_index, title) - - def ocr_image(self, *args, **kwargs): - buffer = self.get_current_buffer() - if hasattr(buffer, "get_right_tweet") == False: - output.speak(_(u"Invalid buffer")) - return - tweet = buffer.get_tweet() - media_list = [] - if ("entities" in tweet) and ("media" in tweet["entities"]): - [media_list.append(i) for i in tweet["entities"]["media"] if i not in media_list] - elif "retweeted_status" in tweet and "media" in tweet["retweeted_status"]["entities"]: - [media_list.append(i) for i in tweet["retweeted_status"]["entities"]["media"] if i not in media_list] - elif "quoted_status" in tweet and "media" in tweet["quoted_status"]["entities"]: - [media_list.append(i) for i in tweet["quoted_status"]["entities"]["media"] if i not in media_list] - if len(media_list) > 1: - image_list = [_(u"Picture {0}").format(i,) for i in range(0, len(media_list))] - dialog = dialogs.urlList.urlList(title=_(u"Select the picture")) - if dialog.get_response() == widgetUtils.OK: - img = media_list[dialog.get_item()] - else: - return - elif len(media_list) == 1: - img = media_list[0] - else: - output.speak(_(u"Invalid buffer")) - return - if buffer.session.settings["mysc"]["ocr_language"] != "": - ocr_lang = buffer.session.settings["mysc"]["ocr_language"] - else: - ocr_lang = ocr.OCRSpace.short_langs.index(tweet["lang"]) - ocr_lang = ocr.OCRSpace.OcrLangs[ocr_lang] - api = ocr.OCRSpace.OCRSpaceAPI() - try: - text = api.OCR_URL(img["media_url"], lang=ocr_lang) - except ocr.OCRSpace.APIError as er: - output.speak(_(u"Unable to extract text")) - return - msg = messages.viewTweet(text["ParsedText"], [], False) - - def update_sent_dms(self, total, account): - sent_dms = self.search_buffer("sent_direct_messages", account) - if sent_dms != None: - sent_dms.put_items_on_list(total) - - def more_dms(self, data, account): - sent_dms = self.search_buffer("sent_direct_messages", account) - if sent_dms != None: - sent_dms.put_more_items(data) - - def save_data_in_db(self): - for i in sessions.sessions: - sessions.sessions[i].shelve() + """ Main Controller for TWBlue. It manages the main window and sessions.""" + + def search_buffer(self, name_, user): + + """ Searches a buffer. + name_ str: The name for the buffer + user str: The account for the buffer. + for example you may want to search the home_timeline buffer for the tw_blue2 user. + Return type: buffers.buffer object.""" + for i in self.buffers: + if i.name == name_ and i.account == user: return i + + def get_current_buffer(self): + """ Get the current focused bufferObject. + Return type: buffers.buffer object.""" + buffer = self.view.get_current_buffer() + if hasattr(buffer, "account"): + buffer = self.search_buffer(buffer.name, buffer.account) + return buffer + + def get_best_buffer(self): + """ Get the best buffer for doing something using the session object. + This function is useful when you need to open a timeline or post a tweet, and the user is in a buffer without a session, for example the events buffer. + Return type: twitterBuffers.buffer object.""" + # Gets the parent buffer to know what account is doing an action + view_buffer = self.view.get_current_buffer() + # If the account has no session attached, we will need to search the first available non-empty buffer for that account to use its session. + if view_buffer.type == "account" or view_buffer.type == "empty": + buffer = self.get_first_buffer(view_buffer.account) + else: + buffer = self.search_buffer(view_buffer.name, view_buffer.account) + if buffer != None: return buffer + + def get_first_buffer(self, account): + """ Gets the first valid buffer for an account. + account str: A twitter username. + The first valid buffer is the home timeline.""" + for i in self.buffers: + if i.account == account and i.invisible == True and i.session != None: + return i + + def get_last_buffer(self, account): + """ Gets the last valid buffer for an account. + account str: A twitter username. + The last valid buffer is the last buffer that contains a session object assigned.""" + results = self.get_buffers_for_account(account) + return results[-1] + + def get_first_buffer_index(self, account): + buff = self.get_first_buffer(account) + return self.view.search(buff.name, buff.account) + + def get_last_buffer_index(self, account): + buff = self.get_last_buffer(account) + return self.view.search(buff.name, buff.account) + + def get_buffers_for_account(self, account): + results = [] + buffers = self.view.get_buffers() + [results.append(self.search_buffer(i.name, i.account)) for i in buffers if i.account == account and (i.type != "account")] + return results + + def bind_other_events(self): + """ Binds the local application events with their functions.""" + log.debug("Binding other application events...") + pub.subscribe(self.buffer_title_changed, "buffer-title-changed") + pub.subscribe(self.manage_sent_dm, "sent-dm") + widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_) + pub.subscribe(self.logout_account, "logout") + pub.subscribe(self.login_account, "login") + pub.subscribe(self.create_new_buffer, "create-new-buffer") + pub.subscribe(self.execute_action, "execute-action") + pub.subscribe(self.search_topic, "search") + pub.subscribe(self.update_sent_dms, "sent-dms-updated") + pub.subscribe(self.more_dms, "more-sent-dms") + pub.subscribe(self.manage_sent_tweets, "sent-tweet") + pub.subscribe(self.manage_new_tweet, "newTweet") + pub.subscribe(self.manage_friend, "friend") + pub.subscribe(self.manage_unfollowing, "unfollowing") + pub.subscribe(self.manage_favourite, "favourite") + pub.subscribe(self.manage_unfavourite, "unfavourite") + pub.subscribe(self.manage_blocked_user, "blocked-user") + pub.subscribe(self.manage_unblocked_user, "unblocked-user") + pub.subscribe(self.create_buffer, "createBuffer") + if system == "Windows": + pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed") + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_trending_topics, menuitem=self.view.trends) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.filter, menuitem=self.view.filter) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_filters, menuitem=self.view.manage_filters) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.accountConfiguration, menuitem=self.view.account_settings) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.configuration, menuitem=self.view.prefs) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.ocr_image, menuitem=self.view.ocr) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.learn_sounds, menuitem=self.view.sounds_tutorial) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.exit, menuitem=self.view.close) + widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit) + if widgetUtils.toolkit == "wx": + log.debug("Binding the exit function...") + widgetUtils.connectExitFunction(self.exit_) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.edit_keystrokes, menuitem=self.view.keystroke_editor) + 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_retweet, self.view.retweet) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.add_to_favourites, self.view.fav) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_from_favourites, self.view.unfav) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_item, self.view.view) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.reverse_geocode, menuitem=self.view.view_coordinates) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.delete, self.view.delete) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.follow, menuitem=self.view.follow) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.send_dm, self.view.dm) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_more_items, menuitem=self.view.load_previous_items) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.view_user_lists, menuitem=self.view.viewLists) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.clear_buffer, menuitem=self.view.clear) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.remove_buffer, self.view.deleteTl) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.check_for_updates, self.view.check_for_updates) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.about, menuitem=self.view.about) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.visit_website, menuitem=self.view.visit_website) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.get_soundpacks, menuitem=self.view.get_soundpacks) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_accounts, self.view.manage_accounts) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_profile, menuitem=self.view.updateProfile) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.user_details, menuitem=self.view.details) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_autoread, menuitem=self.view.autoread) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.toggle_buffer_mute, self.view.mute_buffer) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_timeline, self.view.timeline) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_favs_timeline, self.view.favs) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.open_conversation, menuitem=self.view.view_conversation) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.seekLeft, menuitem=self.view.seekLeft) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.seekRight, menuitem=self.view.seekRight) + if widgetUtils.toolkit == "wx": + widgetUtils.connect_event(self.view.nb, widgetUtils.NOTEBOOK_PAGE_CHANGED, self.buffer_changed) + 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) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_aliases, self.view.manageAliases) + + def set_systray_icon(self): + self.systrayIcon = sysTrayIcon.SysTrayIcon() + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.post_tweet, menuitem=self.systrayIcon.tweet) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.configuration, menuitem=self.systrayIcon.global_settings) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.accountConfiguration, menuitem=self.systrayIcon.account_settings) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.update_profile, menuitem=self.systrayIcon.update_profile) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.show_hide, menuitem=self.systrayIcon.show_hide) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.check_for_updates, menuitem=self.systrayIcon.check_for_updates) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.view_documentation, menuitem=self.systrayIcon.doc) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.MENU, self.exit, menuitem=self.systrayIcon.exit) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.TASKBAR_LEFT_CLICK, self.taskbar_left_click) + widgetUtils.connect_event(self.systrayIcon, widgetUtils.TASKBAR_RIGHT_CLICK, self.taskbar_right_click) + + def taskbar_left_click(self, *args, **kwargs): + if self.showing == True: + self.view.set_focus() + else: + self.show_hide() + + def taskbar_right_click(self, *args, **kwargs): + self.systrayIcon.show_menu() + + def __init__(self): + super(Controller, self).__init__() + # Visibility state. + self.showing = True + # main window + self.view = view.mainFrame() + # buffers list. + self.buffers = [] + self.started = False + # accounts list. + self.accounts = [] + # This saves the current account (important in invisible mode) + self.current_account = "" + self.view.prepare() + self.bind_other_events() + if system == "Windows": + self.set_systray_icon() + + def check_invisible_at_startup(self): + # Visibility check. It does only work for windows. + if system != "Windows": return + if config.app["app-settings"]["hide_gui"] == True: + self.show_hide() + self.view.Show() + self.view.Hide() + # Invisible keyboard Shorcuts check. + if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == True: + km = self.create_invisible_keyboard_shorcuts() + self.register_invisible_keyboard_shorcuts(km) + + def do_work(self): + """ Creates the buffer objects for all accounts. This does not starts the buffer streams, only creates the objects.""" + log.debug("Creating buffers for all sessions...") + for i in sessions.sessions: + log.debug("Working on session %s" % (i,)) + if sessions.sessions[i].is_logged == False: + self.create_ignored_session_buffer(sessions.sessions[i]) + continue + self.create_buffers(sessions.sessions[i]) + + # Connection checker executed each minute. + self.checker_function = RepeatingTimer(60, self.check_connection) +# self.checker_function.start() +# self.save_db = RepeatingTimer(300, self.save_data_in_db) +# self.save_db.start() + log.debug("Setting updates to buffers every %d seconds..." % (60*config.app["app-settings"]["update_period"],)) + self.update_buffers_function = RepeatingTimer(60*config.app["app-settings"]["update_period"], self.update_buffers) + self.update_buffers_function.start() + + def start(self): + """ Starts all buffer objects. Loads their items.""" + for i in sessions.sessions: + if sessions.sessions[i].is_logged == False: continue + self.start_buffers(sessions.sessions[i]) + self.set_buffer_positions(sessions.sessions[i]) + sessions.sessions[i].start_streaming() + if config.app["app-settings"]["play_ready_sound"] == True: + sessions.sessions[list(sessions.sessions.keys())[0]].sound.play("ready.ogg") + if config.app["app-settings"]["speak_ready_msg"] == True: + output.speak(_(u"Ready")) + self.started = True + self.streams_checker_function = RepeatingTimer(60, self.check_streams) + self.streams_checker_function.start() + + + def create_ignored_session_buffer(self, session): + self.accounts.append(session.settings["twitter"]["user_name"]) + account = buffers.base.AccountBuffer(self.view.nb, session.settings["twitter"]["user_name"], session.settings["twitter"]["user_name"], session.session_id) + account.logged = False + account.setup_account() + self.buffers.append(account) + self.view.add_buffer(account.buffer , name=session.settings["twitter"]["user_name"]) + + def login_account(self, session_id): + for i in sessions.sessions: + if sessions.sessions[i].session_id == session_id: session = sessions.sessions[i] + session.login() + session.db = dict() + self.create_buffers(session, False) + self.start_buffers(session) + + def create_buffer(self, buffer_type="baseBuffer", session_type="twitter", buffer_title="", parent_tab=None, start=False, kwargs={}): + log.debug("Creating buffer of type {0} with parent_tab of {2} arguments {1}".format(buffer_type, kwargs, parent_tab)) + if not hasattr(buffers, session_type): + raise AttributeError("Session type %s does not exist yet." % (session_type)) + available_buffers = getattr(buffers, session_type) + if not hasattr(available_buffers, buffer_type): + raise AttributeError("Specified buffer type does not exist: %s" % (buffer_type,)) + buffer = getattr(available_buffers, buffer_type)(**kwargs) + if start: + if kwargs.get("function") == "user_timeline": + try: + buffer.start_stream(play_sound=False) + except ValueError: + commonMessageDialogs.unauthorized() + return + else: + call_threaded(buffer.start_stream) + self.buffers.append(buffer) + if parent_tab == None: + log.debug("Appending buffer {}...".format(buffer,)) + self.view.add_buffer(buffer.buffer, buffer_title) + else: + self.view.insert_buffer(buffer.buffer, buffer_title, parent_tab) + log.debug("Inserting buffer {0} into control {1}".format(buffer, parent_tab)) + + def create_buffers(self, session, createAccounts=True): + """ Generates buffer objects for an user account. + session SessionObject: a sessionmanager.session.Session Object""" + session.get_user_info() + if createAccounts == True: + self.accounts.append(session.db["user_name"]) + account = buffers.base.AccountBuffer(self.view.nb, session.db["user_name"], session.db["user_name"], session.session_id) + account.setup_account() + self.buffers.append(account) + self.view.add_buffer(account.buffer , name=session.db["user_name"]) + root_position =self.view.search(session.db["user_name"], session.db["user_name"]) + for i in session.settings['general']['buffer_order']: + if i == 'home': + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Home"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="home_timeline", name="home_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended")) + elif i == 'mentions': + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="mentions_timeline", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended")) + elif i == 'dm': + pub.sendMessage("createBuffer", buffer_type="DirectMessagesBuffer", session_type=session.type, buffer_title=_("Direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_direct_messages", name="direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg")) + elif i == 'sent_dm': + pub.sendMessage("createBuffer", buffer_type="SentDirectMessagesBuffer", session_type=session.type, buffer_title=_("Sent direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function=None, name="sent_direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message")) + elif i == 'sent_tweets': + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent tweets"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="sent_tweets", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended")) + elif i == 'favorites': + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="favourites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg", tweet_mode="extended")) + elif i == 'followers': + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_followers", name="followers", sessionObject=session, account=session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])) + elif i == 'friends': + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Following"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_friends", name="friends", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"])) + elif i == 'blocks': + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Blocked users"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_blocks", name="blocked", sessionObject=session, account=session.db["user_name"])) + elif i == 'muted': + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Muted users"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_mutes", name="muted", sessionObject=session, account=session.db["user_name"])) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="timelines", account=session.db["user_name"])) + timelines_position =self.view.search("timelines", session.db["user_name"]) + for i in session.settings["other_buffers"]["timelines"]: + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_(u"Timeline for {}").format(i,), parent_tab=timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="%s-timeline" % (i,), sessionObject=session, account=session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Likes timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="favs_timelines", account=session.db["user_name"])) + favs_timelines_position =self.view.search("favs_timelines", session.db["user_name"]) + for i in session.settings["other_buffers"]["favourites_timelines"]: + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes for {}").format(i,), parent_tab=favs_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="%s-favorite" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Followers timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="followers_timelines", account=session.db["user_name"])) + followers_timelines_position =self.view.search("followers_timelines", session.db["user_name"]) + for i in session.settings["other_buffers"]["followers_timelines"]: + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers for {}").format(i,), parent_tab=followers_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_followers", name="%s-followers" % (i,), sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", user_id=i)) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Following timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="friends_timelines", account=session.db["user_name"])) + friends_timelines_position =self.view.search("friends_timelines", session.db["user_name"]) + for i in session.settings["other_buffers"]["friends_timelines"]: + pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_(u"Friends for {}").format(i,), parent_tab=friends_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_friends", name="%s-friends" % (i,), sessionObject=session, account=session.db["user_name"], sound="new_event.ogg", user_id=i)) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Lists"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="lists", account=session.db["user_name"])) + lists_position =self.view.search("lists", session.db["user_name"]) + for i in session.settings["other_buffers"]["lists"]: + pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=session.type, buffer_title=_(u"List for {}").format(i), parent_tab=lists_position, start=False, kwargs=dict(parent=self.view.nb, function="list_timeline", name="%s-list" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Searches"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="searches", account=session.db["user_name"])) + searches_position =self.view.search("searches", session.db["user_name"]) + for i in session.settings["other_buffers"]["tweet_searches"]: + pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_(u"Search for {}").format(i), parent_tab=searches_position, start=False, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (i,), sessionObject=session, account=session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended")) + for i in session.settings["other_buffers"]["trending_topic_buffers"]: + pub.sendMessage("createBuffer", buffer_type="TrendsBuffer", session_type=session.type, buffer_title=_("Trending topics for %s") % (i), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="%s_tt" % (i,), sessionObject=session, account=session.db["user_name"], trendsFor=i, sound="trends_updated.ogg")) + + def set_buffer_positions(self, session): + "Sets positions for buffers if values exist in the database." + for i in self.buffers: + if i.account == session.db["user_name"] and i.name+"_pos" in session.db and hasattr(i.buffer,'list'): + i.buffer.list.select_item(session.db[str(i.name+"_pos")]) + + def logout_account(self, session_id): + for i in sessions.sessions: + if sessions.sessions[i].session_id == session_id: session = sessions.sessions[i] + user = session.db["user_name"] + delete_buffers = [] + for i in self.buffers: + if i.account == user and i.name != user: + delete_buffers.append(i.name) + for i in delete_buffers: + self.destroy_buffer(i, user) + session.db = None + + def destroy_buffer(self, buffer_name, account): + buffer = self.search_buffer(buffer_name, account) + if buffer == None: return + buff = self.view.search(buffer.name, buffer.account) + if buff == None: return + self.view.delete_buffer(buff) + self.buffers.remove(buffer) + del buffer + + def search_topic(self, term): + self.search(value=term) + + def search(self, event=None, value="", *args, **kwargs): + """ Searches words or users in twitter. This creates a new buffer containing the search results.""" + log.debug("Creating a new search...") + dlg = dialogs.search.searchDialog(value) + if dlg.get_response() == widgetUtils.OK and dlg.get("term") != "": + term = dlg.get("term") + buffer = self.get_best_buffer() + searches_position =self.view.search("searches", buffer.session.db["user_name"]) + if dlg.get("tweets") == True: + if term not in buffer.session.settings["other_buffers"]["tweet_searches"]: + buffer.session.settings["other_buffers"]["tweet_searches"].append(term) + buffer.session.settings.write() + args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()} + pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args)) + else: + log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,)) + return + elif dlg.get("users") == True: + pub.sendMessage("createBuffer", buffer_type="SearchPeopleBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_users", name="%s-searchUser" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term)) + dlg.Destroy() + + def find(self, *args, **kwargs): + if 'string' in kwargs: + string=kwargs['string'] + else: + string='' + dlg = dialogs.find.findDialog(string) + if dlg.get_response() == widgetUtils.OK and dlg.get("string") != "": + string = dlg.get("string") + #If we still have an empty string for some reason (I.E. user clicked cancel, etc), return here. + if string == '': + log.debug("Find canceled.") + return + page = self.get_current_buffer() + if not hasattr(page.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + count = page.buffer.list.get_count() + if count < 1: + output.speak(_(u"Empty buffer."), True) + return + start = page.buffer.list.get_selected() + for i in range(start, count): + if string.lower() in page.buffer.list.get_text_column(i, 1).lower(): + page.buffer.list.select_item(i) + return output.speak(page.get_message(), True) + output.speak(_(u"{0} not found.").format(string,), True) + + def filter(self, *args, **kwargs): + page = self.get_current_buffer() + if not hasattr(page.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + # Let's prevent filtering of some buffers (people buffers, direct messages, events and sent items). + # ToDo: Remove events from here after August 16. + if (page.name == "direct_messages" or page.name == "sent_tweets" or page.name == "events") or page.type == "people": + output.speak(_(u"Filters cannot be applied on this buffer")) + return + new_filter = filterController.filter(page) + + def manage_filters(self, *args, **kwargs): + page = self.get_best_buffer() + manage_filters = filterController.filterManager(page.session) + + def seekLeft(self, *args, **kwargs): + try: + sound.URLPlayer.seek(-5000) + except: + output.speak("Unable to seek.",True) + + def seekRight(self, *args, **kwargs): + try: + sound.URLPlayer.seek(5000) + except: + output.speak("Unable to seek.",True) + + def edit_keystrokes(self, *args, **kwargs): + editor = keystrokeEditor.KeystrokeEditor() + if editor.changed == True: + config.keymap.write() + register = False + # determines if we need to reassign the keymap. + if self.showing == False: + register = True + elif config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == True: + register = True + # If there is a keyboard handler instance we need unregister all old keystrokes before register the new ones. + if hasattr(self, "keyboard_handler"): + keymap = {} + for i in editor.hold_map: + if hasattr(self, i): keymap[editor.hold_map[i]] = getattr(self, i) + self.unregister_invisible_keyboard_shorcuts(keymap) + self.invisible_shorcuts_changed(registered=register) + + def learn_sounds(self, *args, **kwargs): + """ Opens the sounds tutorial for the current account.""" + buffer = self.get_best_buffer() + SoundsTutorial.soundsTutorial(buffer.session) + + def view_user_lists(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.selectUserDialog(_(u"Select the user"), users) + if dlg.get_response() == widgetUtils.OK: + user = dlg.get_user() + else: + return + l = listsController.listsController(buff.session, user=user) + + def add_to_list(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.selectUserDialog(_(u"Select the user"), users) + if dlg.get_response() == widgetUtils.OK: + user = dlg.get_user() + else: + return + dlg = dialogs.lists.addUserListDialog() + dlg.populate_list([compose.compose_list(item) for item in buff.session.db["lists"]]) + if dlg.get_response() == widgetUtils.OK: + try: + list = buff.session.twitter.add_list_member(list_id=buff.session.db["lists"][dlg.get_item()].id, screen_name=user) + older_list = utils.find_item(buff.session.db["lists"][dlg.get_item()].id, buff.session.db["lists"]) + listBuffer = self.search_buffer("%s-list" % (buff.session.db["lists"][dlg.get_item()].name.lower()), buff.session.db["user_name"]) + if listBuffer != None: listBuffer.get_user_ids() + buff.session.db["lists"].pop(older_list) + buff.session.db["lists"].append(list) + except TweepyException as e: + log.exception("error %s" % (str(e))) + output.speak("error %s" % (str(e))) + + def remove_from_list(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.selectUserDialog(_(u"Select the user"), users) + if dlg.get_response() == widgetUtils.OK: + user = dlg.get_user() + else: + return + dlg = dialogs.lists.removeUserListDialog() + dlg.populate_list([compose.compose_list(item) for item in buff.session.db["lists"]]) + if dlg.get_response() == widgetUtils.OK: + try: + list = buff.session.twitter.remove_list_member(list_id=buff.session.db["lists"][dlg.get_item()].id, screen_name=user) + older_list = utils.find_item(buff.session.db["lists"][dlg.get_item()].id, buff.session.db["lists"]) + listBuffer = self.search_buffer("%s-list" % (buff.session.db["lists"][dlg.get_item()].name.lower()), buff.session.db["user_name"]) + if listBuffer != None: listBuffer.get_user_ids() + buff.session.db["lists"].pop(older_list) + buff.session.db["lists"].append(list) + except TweepyException as e: + output.speak("error %s" % (str(e))) + log.exception("error %s" % (str(e))) + + def list_manager(self, *args, **kwargs): + s = self.get_best_buffer().session + l = listsController.listsController(s) + + def configuration(self, *args, **kwargs): + """ Opens the global settings dialogue.""" + d = settings.globalSettingsController() + if d.response == widgetUtils.OK: + d.save_configuration() + if d.needs_restart == True: + commonMessageDialogs.needs_restart() + restart.restart_program() + + def accountConfiguration(self, *args, **kwargs): + """ Opens the account settings dialogue for the current account.""" + buff = self.get_best_buffer() + manager.manager.set_current_session(buff.session.session_id) + d = settings.accountSettingsController(buff, self) + if d.response == widgetUtils.OK: + d.save_configuration() + if d.needs_restart == True: + commonMessageDialogs.needs_restart() + buff.session.settings.write() + buff.session.save_persistent_data() + restart.restart_program() + + def report_error(self, *args, **kwargs): + r = issueReporter.reportBug(self.get_best_buffer().session.db["user_name"]) + + def check_for_updates(self, *args, **kwargs): + update = updater.do_update() + if update == False: + view.no_update_available() + + def delete(self, *args, **kwargs): + """ Deletes an item in the current buffer. + Users can only remove their tweets and direct messages, other users' tweets and people (followers, friends, blocked, etc) can not be removed using this method.""" + buffer = self.view.get_current_buffer() + if hasattr(buffer, "account"): + buffer = self.search_buffer(buffer.name, buffer.account) + buffer.destroy_status() + + def exit(self, *args, **kwargs): + if config.app["app-settings"]["ask_at_exit"] == True: + answer = commonMessageDialogs.exit_dialog(self.view) + if answer == widgetUtils.YES: + self.exit_() + else: + self.exit_() + + def exit_(self, *args, **kwargs): + for i in self.buffers: i.save_positions() + log.debug("Exiting...") + log.debug("Saving global configuration...") + for item in sessions.sessions: + if sessions.sessions[item].logged == False: continue + log.debug("Disconnecting streaming endpoint for session" + sessions.sessions[item].session_id) + sessions.sessions[item].stop_streaming() + log.debug("Disconnecting streams for %s session" % (sessions.sessions[item].session_id,)) + sessions.sessions[item].sound.cleaner.cancel() + log.debug("Saving database for " + sessions.sessions[item].session_id) + sessions.sessions[item].save_persistent_data() + if system == "Windows": + self.systrayIcon.RemoveIcon() + pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) + if os.path.exists(pidpath): + os.remove(pidpath) + if hasattr(self, "streams_checker_function"): + log.debug("Stopping stream checker...") + self.streams_checker_function.cancel() + widgetUtils.exit_application() + + def follow(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users) + + def unfollow(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users, "unfollow") + + def mute(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users, "mute") + + def unmute(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users, "unmute") + + def block(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users, "block") + + def unblock(self, *args, **kwargs): + buff = self.get_current_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) + u = userActionsController.userActionsController(buff, users, "unblock") + + def report(self, *args, **kwargs): + buff = self.get_current_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) + 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.userAliasDialogs.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)) + pub.sendMessage("alias-added") + + def manage_aliases(self, *args, **kwargs): + buff = self.get_best_buffer() + alias_controller = userAliasController.userAliasController(buff.session.settings) + + def post_tweet(self, event=None): + buffer = self.get_best_buffer() + buffer.post_status() + + def post_reply(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.name == "direct_messages": + buffer.send_message() + else: + buffer.reply() + + def send_dm(self, *args, **kwargs): + buffer = self.get_current_buffer() + buffer.send_message() + + def post_retweet(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": + return + else: + buffer.share_item() + + def add_to_favourites(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": + return + else: + id = buffer.get_tweet().id + call_threaded(buffer.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id) + + def remove_from_favourites(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": + return + else: + id = buffer.get_tweet().id + call_threaded(buffer.session.api_call, call_name="destroy_favorite", id=id) + + def toggle_like(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events": + return + else: + id = buffer.get_tweet().id + tweet = buffer.session.twitter.get_status(id=id, include_ext_alt_text=True, tweet_mode="extended") + if tweet.favorited == False: + call_threaded(buffer.session.api_call, call_name="create_favorite", _sound="favourite.ogg", id=id) + else: + call_threaded(buffer.session.api_call, call_name="destroy_favorite", id=id) + + def view_item(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.type == "account" or buffer.type == "empty": + 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"], item_url=buffer.get_item_url()) + elif buffer.type == "dm": + non_tweet = buffer.get_formatted_message() + item = buffer.get_right_tweet() + original_date = arrow.get(int(item.created_timestamp)) + 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, item_url=item_url) + + def open_in_browser(self, *args, **kwargs): + buffer = self.get_current_buffer() + if hasattr(buffer, "open_in_browser"): + buffer.open_in_browser() + + def open_favs_timeline(self, *args, **kwargs): + self.open_timeline(default="favourites") + + def open_timeline(self, default="tweets", *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.userSelection.selectUserDialog(users=users, default=default) + if dlg.get_response() == widgetUtils.OK: + usr = utils.if_user_exists(buff.session.twitter, dlg.get_user()) + if usr != None: + if usr == dlg.get_user(): + commonMessageDialogs.suspended_user() + return + if usr.protected == True: + if usr.following == False: + commonMessageDialogs.no_following() + return + tl_type = dlg.get_action() + if tl_type == "tweets": + if usr.statuses_count == 0: + commonMessageDialogs.no_tweets() + return + if usr.id_str in buff.session.settings["other_buffers"]["timelines"]: + commonMessageDialogs.timeline_exist() + return + tl = buffers.twitter.BaseBuffer(self.view.nb, "user_timeline", "%s-timeline" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="tweet_timeline.ogg", user_id=usr.id_str, tweet_mode="extended") + try: + tl.start_stream(play_sound=False) + except ValueError: + commonMessageDialogs.unauthorized() + return + pos=self.view.search("timelines", buff.session.db["user_name"]) + self.insert_buffer(tl, pos+1) + self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(dlg.get_user()), pos=pos) + buff.session.settings["other_buffers"]["timelines"].append(usr.id_str) + pub.sendMessage("buffer-title-changed", buffer=tl) + buff.session.sound.play("create_timeline.ogg") + elif tl_type == "favourites": + if usr.favourites_count == 0: + commonMessageDialogs.no_favs() + return + if usr.id_str in buff.session.settings["other_buffers"]["favourites_timelines"]: + commonMessageDialogs.timeline_exist() + return + tl = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "%s-favorite" % (usr.id_str,), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr.id_str, tweet_mode="extended") + try: + tl.start_stream(play_sound=False) + except ValueError: + commonMessageDialogs.unauthorized() + return + pos=self.view.search("favs_timelines", buff.session.db["user_name"]) + self.insert_buffer(tl, pos+1) + self.view.insert_buffer(buffer=tl.buffer, name=_(u"Likes for {}").format(dlg.get_user()), pos=pos) + buff.session.settings["other_buffers"]["favourites_timelines"].append(usr.id_str) + pub.sendMessage("buffer-title-changed", buffer=buff) + buff.session.sound.play("create_timeline.ogg") + elif tl_type == "followers": + if usr.followers_count == 0: + commonMessageDialogs.no_followers() + return + if usr.id_str in buff.session.settings["other_buffers"]["followers_timelines"]: + commonMessageDialogs.timeline_exist() + return + tl = buffers.twitter.PeopleBuffer(self.view.nb, "get_followers", "%s-followers" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str) + try: + tl.start_stream(play_sound=False) + except ValueError: + commonMessageDialogs.unauthorized() + return + pos=self.view.search("followers_timelines", buff.session.db["user_name"]) + self.insert_buffer(tl, pos+1) + self.view.insert_buffer(buffer=tl.buffer, name=_(u"Followers for {}").format(dlg.get_user()), pos=pos) + buff.session.settings["other_buffers"]["followers_timelines"].append(usr.id_str) + buff.session.sound.play("create_timeline.ogg") + pub.sendMessage("buffer-title-changed", buffer=i) + elif tl_type == "friends": + if usr.friends_count == 0: + commonMessageDialogs.no_friends() + return + if usr.id_str in buff.session.settings["other_buffers"]["friends_timelines"]: + commonMessageDialogs.timeline_exist() + return + tl = buffers.twitter.PeopleBuffer(self.view.nb, "get_friends", "%s-friends" % (usr.id_str,), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr.id_str) + try: + tl.start_stream(play_sound=False) + except ValueError: + commonMessageDialogs.unauthorized() + return + pos=self.view.search("friends_timelines", buff.session.db["user_name"]) + self.insert_buffer(tl, pos+1) + self.view.insert_buffer(buffer=tl.buffer, name=_(u"Friends for {}").format(dlg.get_user()), pos=pos) + buff.session.settings["other_buffers"]["friends_timelines"].append(usr.id_str) + buff.session.sound.play("create_timeline.ogg") + pub.sendMessage("buffer-title-changed", buffer=i) + else: + commonMessageDialogs.user_not_exist() + buff.session.settings.write() + + def open_conversation(self, *args, **kwargs): + buffer = self.get_current_buffer() + id = buffer.get_right_tweet().id + user = buffer.session.get_user(buffer.get_right_tweet().user).screen_name + search = buffers.twitter.ConversationBuffer(self.view.nb, "search_tweets", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,)) + search.tweet = buffer.get_right_tweet() + search.start_stream(start=True) + pos=self.view.search("searches", buffer.session.db["user_name"]) + self.insert_buffer(search, pos) + self.view.insert_buffer(search.buffer, name=_(u"Conversation with {0}").format(user), pos=pos) + + def show_hide(self, *args, **kwargs): + km = self.create_invisible_keyboard_shorcuts() + if self.showing == True: + if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: + self.register_invisible_keyboard_shorcuts(km) + self.view.Hide() + self.fix_wrong_buffer() + self.showing = False + else: + if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] == False: + self.unregister_invisible_keyboard_shorcuts(km) + self.view.Show() + self.showing = True + + def get_trending_topics(self, *args, **kwargs): + buff = self.get_best_buffer() + trends = trendingTopics.trendingTopicsController(buff.session) + if trends.dialog.get_response() == widgetUtils.OK: + woeid = trends.get_woeid() + if woeid in buff.session.settings["other_buffers"]["trending_topic_buffers"]: return + buffer = buffers.twitter.TrendsBuffer(self.view.nb, "%s_tt" % (woeid,), buff.session, buff.account, woeid, sound="trends_updated.ogg") + buffer.searchfunction = self.search + pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]) + self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (trends.get_string()), pos=pos) + self.buffers.append(buffer) + buffer.start_stream() + buffer.session.settings["other_buffers"]["trending_topic_buffers"].append(woeid) + buffer.session.settings.write() + + def reverse_geocode(self, event=None): + try: + tweet = self.get_current_buffer().get_tweet() + if tweet.coordinates != None: + x = tweet.coordinates["coordinates"][0] + y = tweet.coordinates["coordinates"][1] + 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 ValueError: + output.speak(_(u"Error decoding coordinates. Try again later.")) +# except KeyError: +# pass + except AttributeError: + output.speak(_("Unable to find address in OpenStreetMap.")) + + def view_reverse_geocode(self, event=None): + try: + tweet = self.get_current_buffer().get_right_tweet() + if tweet.coordinates != None: + x = tweet.coordinates["coordinates"][0] + y = tweet.coordinates["coordinates"][1] + address = geocoder.reverse_geocode(y, x, language = languageHandler.curLang) + dlg = commonMessageDialogs.view_geodata(address[0].__str__()) + 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 AttributeError: + pass + + def get_more_items(self, *args, **kwargs): + self.get_current_buffer().get_more_items() + + def clear_buffer(self, *args, **kwargs): + self.get_current_buffer().clear_list() + + def remove_buffer(self, *args, **kwargs): + buffer = self.get_current_buffer() + if not hasattr(buffer, "account"): return + buff = self.view.search(buffer.name, buffer.account) + answer = buffer.remove_buffer() + if answer == False: return + log.debug("destroying buffer...") + if hasattr(buffer, "timer"): + log.debug("Stopping timer...") + buffer.timer.cancel() + log.debug("Timer cancelled.") + self.right() + self.view.delete_buffer(buff) + buffer.session.sound.play("delete_timeline.ogg") + self.buffers.remove(buffer) + del buffer + + def skip_buffer(self, forward=True): + buff = self.get_current_buffer() + if buff.invisible == False: + self.view.advance_selection(forward) + + def buffer_changed(self, *args, **kwargs): + buffer = self.get_current_buffer() + if buffer.account != self.current_account: + self.current_account = buffer.account + if not hasattr(buffer, "session") or buffer.session == None: return + muted = autoread = False + if buffer.name in buffer.session.settings["other_buffers"]["muted_buffers"]: + muted = True + elif buffer.name in buffer.session.settings["other_buffers"]["autoread_buffers"]: + autoread = True + self.view.check_menuitem("mute_buffer", muted) + self.view.check_menuitem("autoread", autoread) + + def fix_wrong_buffer(self): + buf = self.get_best_buffer() + if buf == None: + for i in self.accounts: + buffer = self.view.search("home_timeline", i) + if buffer != None: break + else: + buffer = self.view.search("home_timeline", buf.session.db["user_name"]) + if buffer!=None: + self.view.change_buffer(buffer) + + def up(self, *args, **kwargs): + page = self.get_current_buffer() + if not hasattr(page.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + position = page.buffer.list.get_selected() + index = position-1 + try: + page.buffer.list.select_item(index) + except: + pass + if position == page.buffer.list.get_selected(): + page.session.sound.play("limit.ogg") + + try: + output.speak(page.get_message(), True) + except: + pass + + def down(self, *args, **kwargs): + page = self.get_current_buffer() + if not hasattr(page.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + position = page.buffer.list.get_selected() + index = position+1 + try: + page.buffer.list.select_item(index) + except: + pass + if position == page.buffer.list.get_selected(): + page.session.sound.play("limit.ogg") + try: + output.speak(page.get_message(), True) + except: + pass + + def left(self, *args, **kwargs): + buff = self.view.get_current_buffer_pos() + buffer = self.get_current_buffer() + if not hasattr(buffer.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + if buff == self.get_first_buffer_index(buffer.account) or buff == 0: + self.view.change_buffer(self.get_last_buffer_index(buffer.account)) + else: + self.view.change_buffer(buff-1) + while self.get_current_buffer().invisible == False: self.skip_buffer(False) + buffer = self.get_current_buffer() + if self.showing == True: buffer.buffer.set_focus_in_list() + try: + msg = _(u"%s, %s of %s") % (self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) + except: + msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) + output.speak(msg, True) + + def right(self, *args, **kwargs): + buff = self.view.get_current_buffer_pos() + buffer = self.get_current_buffer() + if not hasattr(buffer.buffer, "list"): + output.speak(_(u"No session is currently in focus. Focus a session with the next or previous session shortcut."), True) + return + if buff == self.get_last_buffer_index(buffer.account) or buff+1 == self.view.get_buffer_count(): + self.view.change_buffer(self.get_first_buffer_index(buffer.account)) + else: + self.view.change_buffer(buff+1) + while self.get_current_buffer().invisible == False: self.skip_buffer(True) + buffer = self.get_current_buffer() + if self.showing == True: buffer.buffer.set_focus_in_list() + try: + msg = _(u"%s, %s of %s") % (self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) + except: + msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) + output.speak(msg, True) + + def next_account(self, *args, **kwargs): + index = self.accounts.index(self.current_account) + if index+1 == len(self.accounts): + index = 0 + else: + index = index+1 + account = self.accounts[index] + self.current_account = account + buffer_object = self.get_first_buffer(account) + if buffer_object == None: + output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) + return + buff = self.view.search(buffer_object.name, account) + if buff == None: + output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) + return + self.view.change_buffer(buff) + buffer = self.get_current_buffer() + if self.showing == True: buffer.buffer.set_focus_in_list() + try: + msg = _(u"%s. %s, %s of %s") % (buffer.account, self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) + except: + msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) + output.speak(msg, True) + + def previous_account(self, *args, **kwargs): + index = self.accounts.index(self.current_account) + if index-1 < 0: + index = len(self.accounts)-1 + else: + index = index-1 + account = self.accounts[index] + self.current_account = account + buffer_object = self.get_first_buffer(account) + if buffer_object == None: + output.speak(_(u"{0}: This account is not logged into Twitter.").format(account), True) + return + buff = self.view.search(buffer_object.name, account) + if buff == None: + output.speak(_(u"{0}: This account is not logged into twitter.").format(account), True) + return + self.view.change_buffer(buff) + buffer = self.get_current_buffer() + if self.showing == True: buffer.buffer.set_focus_in_list() + try: + msg = _(u"%s. %s, %s of %s") % (buffer.account, self.view.get_buffer_text(), buffer.buffer.list.get_selected()+1, buffer.buffer.list.get_count()) + except: + msg = _(u"%s. Empty") % (self.view.get_buffer_text(),) + output.speak(msg, True) + + def go_home(self): + buffer = self.get_current_buffer() + buffer.buffer.list.select_item(0) + try: + output.speak(buffer.get_message(), True) + except: + pass + + def go_end(self): + buffer = self.get_current_buffer() + buffer.buffer.list.select_item(buffer.buffer.list.get_count()-1) + try: + output.speak(buffer.get_message(), True) + except: + pass + + def go_page_up(self): + buffer = self.get_current_buffer() + if buffer.buffer.list.get_selected() <= 20: + index = 0 + else: + index = buffer.buffer.list.get_selected() - 20 + buffer.buffer.list.select_item(index) + try: + output.speak(buffer.get_message(), True) + except: + pass + + def go_page_down(self): + buffer = self.get_current_buffer() + if buffer.buffer.list.get_selected() >= buffer.buffer.list.get_count() - 20: + index = buffer.buffer.list.get_count()-1 + else: + index = buffer.buffer.list.get_selected() + 20 + buffer.buffer.list.select_item(index) + try: + output.speak(buffer.get_message(), True) + except: + pass + + def url(self, *args, **kwargs): + buffer = self.get_current_buffer() + buffer.url() + + def audio(self, *args, **kwargs): + self.get_current_buffer().audio() + + def volume_down(self, *args, **kwargs): + self.get_current_buffer().volume_down() + + def volume_up(self, *args, **kwargs): + self.get_current_buffer().volume_up() + + def create_invisible_keyboard_shorcuts(self): + keymap = {} + for i in config.keymap["keymap"]: + if hasattr(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(new_keymap) + + def unregister_invisible_keyboard_shorcuts(self, keymap): + try: + self.keyboard_handler.unregister_keys(keymap) + del self.keyboard_handler + except AttributeError: + pass + + def notify(self, session, play_sound=None, message=None, notification=False): + if session.settings["sound"]["session_mute"] == True: return + if play_sound != None: + session.sound.play(play_sound) + if message != None: + output.speak(message, speech=session.settings["reporting"]["speech_reporting"], braille=session.settings["reporting"]["braille_reporting"]) + + def manage_sent_dm(self, data, user): + buffer = self.search_buffer("sent_direct_messages", user) + if buffer == None: return + play_sound = "dm_sent.ogg" + if "sent_direct_messages" not in buffer.session.settings["other_buffers"]["muted_buffers"]: + self.notify(buffer.session, play_sound=play_sound) + buffer.add_new_item(data) + + def manage_sent_tweets(self, data, user): + buffer = self.search_buffer("sent_tweets", user) + if buffer == None: return + data = buffer.session.check_quoted_status(data) + data = buffer.session.check_long_tweet(data) + if data == False: # Long tweet deleted from twishort. + return + items = buffer.session.db[buffer.name] + if buffer.session.settings["general"]["reverse_timelines"] == False: + items.append(data) + else: + items.insert(0, data) + buffer.session.db[buffer.name] = items + buffer.add_new_item(data) + + def manage_friend(self, data, user): + buffer = self.search_buffer("friends", user) + if buffer == None: return + buffer.add_new_item(data) + + def manage_unfollowing(self, item, user): + buffer = self.search_buffer("friends", user) + if buffer == None: return + buffer.remove_item(item) + + def manage_favourite(self, data, user): + buffer = self.search_buffer("favourites", user) + if buffer == None: return + play_sound = "favourite.ogg" + if "favourites" not in buffer.session.settings["other_buffers"]["muted_buffers"]: + self.notify(buffer.session, play_sound=play_sound) + buffer.add_new_item(data) + + def manage_unfavourite(self, item, user): + buffer = self.search_buffer("favourites", user) + if buffer == None: return + buffer.remove_item(item) + + def manage_blocked_user(self, data, user): + buffer = self.search_buffer("blocked", user) + if buffer == None: return + buffer.add_new_item(data) + + def manage_unblocked_user(self, item, user): + buffer = self.search_buffer("blocked", user) + if buffer == None: return + buffer.remove_item(item) + + def start_buffers(self, session): + log.debug("starting buffers... Session %s" % (session.session_id,)) + for i in self.buffers: + if i.session == session and i.needs_init == True: + if hasattr(i, "finished_timeline") and i.finished_timeline == False: + change_title = True + else: + change_title = False + try: + if "mentions" in i.name or "direct_messages" in i.name: + i.start_stream() + else: + i.start_stream(play_sound=False) + except TweepyException as err: + log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), i.name, i.account, i.args, i.kwargs)) + # Determine if this error was caused by a block applied to the current user (IE permission errors). + if type(err) == Forbidden: + buff = self.view.search(i.name, i.account) + i.remove_buffer(force=True) + commonMessageDialogs.blocked_timeline() + if self.get_current_buffer() == i: + self.right() + self.view.delete_buffer(buff) + self.buffers.remove(i) + del i + continue + if change_title: + pub.sendMessage("buffer-title-changed", buffer=i) + + def set_positions(self): + for i in sessions.sessions: + self.set_buffer_positions(i) + + def check_connection(self): + if self.started == False: + return + for i in sessions.sessions: + try: + if sessions.sessions[i].is_logged == False: continue + sessions.sessions[i].check_connection() + except TweepyException: # We shouldn't allow this function to die. + pass + + def create_new_buffer(self, buffer, account, create): + buff = self.search_buffer("home_timeline", account) + if create == True: + if buffer == "favourites": + favourites = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended") + self.buffers.append(favourites) + self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) + favourites.start_stream(play_sound=False) + if buffer == "followers": + followers = buffers.twitter.PeopleBuffer(self.view.nb, "get_followers", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"]) + self.buffers.append(followers) + self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) + followers.start_stream(play_sound=False) + elif buffer == "friends": + friends = buffers.twitter.PeopleBuffer(self.view.nb, "get_friends", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"]) + self.buffers.append(friends) + self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) + friends.start_stream(play_sound=False) + elif buffer == "blocked": + blocks = buffers.twitter.PeopleBuffer(self.view.nb, "get_blocks", "blocked", buff.session, buff.session.db["user_name"]) + self.buffers.append(blocks) + self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) + blocks.start_stream(play_sound=False) + elif buffer == "muted": + muted = buffers.twitter.PeopleBuffer(self.view.nb, "get_mutes", "muted", buff.session, buff.session.db["user_name"]) + self.buffers.append(muted) + self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])) + muted.start_stream(play_sound=False) + elif create == False: + self.destroy_buffer(buffer, buff.session.db["user_name"]) + elif buffer == "list": + if create in buff.session.settings["other_buffers"]["lists"]: + output.speak(_(u"This list is already opened"), True) + return + tl = buffers.twitter.ListBuffer(self.view.nb, "list_timeline", create+"-list", buff.session, buff.session.db["user_name"], bufferType=None, list_id=utils.find_list(create, buff.session.db["lists"]), tweet_mode="extended") + buff.session.lists.append(tl) + pos=self.view.search("lists", buff.session.db["user_name"]) + self.insert_buffer(tl, pos) + self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(create), pos=self.view.search("lists", buff.session.db["user_name"])) + tl.start_stream(play_sound=False) + buff.session.settings["other_buffers"]["lists"].append(create) + buff.session.settings.write() + + def invisible_shorcuts_changed(self, registered): + if registered == True: + km = self.create_invisible_keyboard_shorcuts() + self.register_invisible_keyboard_shorcuts(km) + elif registered == False: + km = self.create_invisible_keyboard_shorcuts() + self.unregister_invisible_keyboard_shorcuts(km) + + def about(self, *args, **kwargs): + self.view.about_dialog() + + def get_soundpacks(self, *args, **kwargs): + # This should redirect users of other languages to the right version of the TWBlue website. + lang = languageHandler.curLang[:2] + url = application.url + final_url = "{0}/{1}/soundpacks".format(url, lang) + try: + response = requests.get(final_url) + except: + output.speak(_(u"An error happened while trying to connect to the server. Please try later.")) + return + # There is no twblue.es/en, so if English is the language used this should be False anyway. + if response.status_code == 200 and lang != "en": + webbrowser.open_new_tab(final_url) + else: + webbrowser.open_new_tab(application.url+"/soundpacks") + + def visit_website(self, *args, **kwargs): + # This should redirect users of other languages to the right version of the TWBlue website. + lang = languageHandler.curLang[:2] + url = application.url + final_url = "{0}/{1}".format(url, lang) + try: + response = requests.get(final_url) + except: + output.speak(_(u"An error happened while trying to connect to the server. Please try later.")) + return + # There is no twblue.es/en, so if English is the language used this should be False anyway. + if response.status_code == 200 and lang != "en": + webbrowser.open_new_tab(final_url) + else: + webbrowser.open_new_tab(application.url) + + def manage_accounts(self, *args, **kwargs): + sm = sessionManager.sessionManagerController(started=True) + sm.fill_list() + sm.show() + for i in sm.new_sessions: + self.create_buffers(sessions.sessions[i]) + call_threaded(self.start_buffers, sessions.sessions[i]) + for i in sm.removed_sessions: + if sessions.sessions[i].logged == True: + self.logout_account(sessions.sessions[i].session_id) + self.destroy_buffer(sessions.sessions[i].settings["twitter"]["user_name"], sessions.sessions[i].settings["twitter"]["user_name"]) + self.accounts.remove(sessions.sessions[i].settings["twitter"]["user_name"]) + sessions.sessions.pop(i) + + def update_profile(self, *args, **kwargs): + r = user.profileController(self.get_best_buffer().session) + + def user_details(self, *args, **kwargs): + buffer = self.get_current_buffer() + if not hasattr(buffer, "session") or buffer.session == None: return + if hasattr(buffer, "user_details"): + buffer.user_details() + + def toggle_autoread(self, *args, **kwargs): + buffer = self.get_current_buffer() + if hasattr(buffer, "session") and buffer.session == None: return + if buffer.name not in buffer.session.settings["other_buffers"]["autoread_buffers"]: + buffer.session.settings["other_buffers"]["autoread_buffers"].append(buffer.name) + output.speak(_(u"The auto-reading of new tweets is enabled for this buffer"), True) + elif buffer.name in buffer.session.settings["other_buffers"]["autoread_buffers"]: + buffer.session.settings["other_buffers"]["autoread_buffers"].remove(buffer.name) + output.speak(_(u"The auto-reading of new tweets is disabled for this buffer"), True) + buffer.session.settings.write() + + def toggle_session_mute(self, *args, **kwargs): + buffer = self.get_best_buffer() + if buffer.session.settings["sound"]["session_mute"] == False: + buffer.session.settings["sound"]["session_mute"] = True + output.speak(_(u"Session mute on"), True) + elif buffer.session.settings["sound"]["session_mute"] == True: + buffer.session.settings["sound"]["session_mute"] = False + output.speak(_(u"Session mute off"), True) + buffer.session.settings.write() + + def toggle_buffer_mute(self, *args, **kwargs): + buffer = self.get_current_buffer() + if hasattr(buffer, "session") and buffer.session == None: return + if buffer.name not in buffer.session.settings["other_buffers"]["muted_buffers"]: + buffer.session.settings["other_buffers"]["muted_buffers"].append(buffer.name) + output.speak(_(u"Buffer mute on"), True) + elif buffer.name in buffer.session.settings["other_buffers"]["muted_buffers"]: + buffer.session.settings["other_buffers"]["muted_buffers"].remove(buffer.name) + output.speak(_(u"Buffer mute off"), True) + buffer.session.settings.write() + + def view_documentation(self, *args, **kwargs): + lang = localization.get("documentation") + os.chdir("documentation/%s" % (lang,)) + webbrowser.open("manual.html") + os.chdir("../../") + + def view_changelog(self, *args, **kwargs): + lang = localization.get("documentation") + os.chdir("documentation/%s" % (lang,)) + webbrowser.open("changelog.html") + os.chdir("../../") + + def insert_buffer(self, buffer, position): + self.buffers.insert(position, buffer) + + def copy_to_clipboard(self, *args, **kwargs): + output.copy(self.get_current_buffer().get_message()) + output.speak(_(u"Copied")) + + def repeat_item(self, *args, **kwargs): + output.speak(self.get_current_buffer().get_message()) + + def execute_action(self, action): + if hasattr(self, action): + getattr(self, action)() + + def update_buffers(self): + for i in self.buffers[:]: + if i.session != None and i.session.is_logged == True: + try: + i.start_stream(mandatory=True) + except TweepyException as err: + log.exception("Error %s starting buffer %s on account %s, with args %r and kwargs %r." % (str(err), i.name, i.account, i.args, i.kwargs)) + # Determine if this error was caused by a block applied to the current user (IE permission errors). + if type(err) == Forbidden: + buff = self.view.search(i.name, i.account) + i.remove_buffer(force=True) + commonMessageDialogs.blocked_timeline() + if self.get_current_buffer() == i: + self.right() + self.view.delete_buffer(buff) + self.buffers.remove(i) + del i + + def update_buffer(self, *args, **kwargs): + bf = self.get_current_buffer() + if not hasattr(bf, "start_stream"): + output.speak(_(u"Unable to update this buffer.")) + return + else: + output.speak(_(u"Updating buffer...")) + n = bf.start_stream(mandatory=True, avoid_autoreading=True) + if n != None: + output.speak(_(u"{0} items retrieved").format(n,)) + + def buffer_title_changed(self, buffer): + if buffer.name.endswith("-timeline"): + title = _(u"Timeline for {}").format(buffer.username,) + elif buffer.name.endswith("-favorite"): + title = _(u"Likes for {}").format(buffer.username,) + elif buffer.name.endswith("-followers"): + title = _(u"Followers for {}").format(buffer.username,) + elif buffer.name.endswith("-friends"): + title = _(u"Friends for {}").format(buffer.username,) + elif buffer.name.endswith("_tt"): + title = _("Trending topics for %s") % (buffer.name_) + buffer_index = self.view.search(buffer.name, buffer.account) + self.view.set_page_title(buffer_index, title) + + def ocr_image(self, *args, **kwargs): + buffer = self.get_current_buffer() + if hasattr(buffer, "get_right_tweet") == False: + output.speak(_(u"Invalid buffer")) + return + tweet = buffer.get_tweet() + media_list = [] + if hasattr(tweet, "entities") and tweet.entities.get("media") != None: + [media_list.append(i) for i in tweet.entities["media"] if i not in media_list] + elif hasattr(tweet, "retweeted_status") and tweet.retweeted_status.get("media") != None: + [media_list.append(i) for i in tweet.retweeted_status.entities["media"] if i not in media_list] + elif hasattr(tweet, "quoted_status") and tweet.quoted_status.entities.get("media") != None: + [media_list.append(i) for i in tweet.quoted_status.entities["media"] if i not in media_list] + if len(media_list) > 1: + image_list = [_(u"Picture {0}").format(i,) for i in range(0, len(media_list))] + dialog = dialogs.urlList.urlList(title=_(u"Select the picture")) + if dialog.get_response() == widgetUtils.OK: + img = media_list[dialog.get_item()] + else: + return + elif len(media_list) == 1: + img = media_list[0] + else: + output.speak(_(u"Invalid buffer")) + return + if buffer.session.settings["mysc"]["ocr_language"] != "": + ocr_lang = buffer.session.settings["mysc"]["ocr_language"] + else: + ocr_lang = ocr.OCRSpace.short_langs.index(tweet.lang) + ocr_lang = ocr.OCRSpace.OcrLangs[ocr_lang] + api = ocr.OCRSpace.OCRSpaceAPI() + try: + text = api.OCR_URL(img["media_url"], lang=ocr_lang) + except ocr.OCRSpace.APIError as er: + output.speak(_(u"Unable to extract text")) + return + msg = messages.viewTweet(text["ParsedText"], [], False) + + def update_sent_dms(self, total, account): + sent_dms = self.search_buffer("sent_direct_messages", account) + if sent_dms != None: + sent_dms.put_items_on_list(total) + + def more_dms(self, data, account): + sent_dms = self.search_buffer("sent_direct_messages", account) + if sent_dms != None: + sent_dms.put_more_items(data) + + def save_data_in_db(self): + for i in sessions.sessions: + sessions.sessions[i].save_persistent_data() + + def manage_new_tweet(self, data, user, _buffers): + sound_to_play = None + for buff in _buffers: + buffer = self.search_buffer(buff, user) + if buffer == None or buffer.session.db["user_name"] != user: return + buffer.add_new_item(data) + if buff == "home_timeline": sound_to_play = "tweet_received.ogg" + elif buff == "mentions": sound_to_play = "mention_received.ogg" + elif buff == "sent_tweets": sound_to_play = "tweet_send.ogg" + elif "timeline" in buff: sound_to_play = "tweet_timeline.ogg" + else: sound_to_play = None + if sound_to_play != None and buff not in buffer.session.settings["other_buffers"]["muted_buffers"]: + self.notify(buffer.session, sound_to_play) + + def check_streams(self): + if self.started == False: + return + for i in sessions.sessions: + try: + if sessions.sessions[i].is_logged == False: continue + sessions.sessions[i].check_streams() + except TweepyException: # We shouldn't allow this function to die. + pass diff --git a/src/controller/messages.py b/src/controller/messages.py index 880ec4a2..421be6d7 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -1,289 +1,379 @@ # -*- coding: utf-8 -*- -import re -import platform +import os import arrow import languageHandler -system = platform.system() +import wx import widgetUtils import output -import url_shortener import sound import config from pubsub import pub from twitter_text import parse_tweet -if system == "Windows": - from wxUI.dialogs import message, urlList - from wxUI import commonMessageDialogs - from extra import translator, SpellChecker, autocompletionUsers - from extra.AudioUploader import audioUploader -elif system == "Linux": - from gtkUI.dialogs import message +from wxUI.dialogs import twitterDialogs, urlList +from wxUI import commonMessageDialogs +from extra import translator, SpellChecker, autocompletionUsers +from extra.AudioUploader import audioUploader from sessions.twitter import utils -from . import attach class basicTweet(object): - """ This class handles the tweet main features. Other classes should derive from this class.""" - def __init__(self, session, title, caption, text, messageType="tweet", max=280, *args, **kwargs): - super(basicTweet, self).__init__() - self.max = max - self.title = title - self.session = session - self.message = getattr(message, messageType)(title, caption, text, *args, **kwargs) - widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) - widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) - widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) - widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten) - widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) - widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) - if hasattr(self.message, "long_tweet"): - widgetUtils.connect_event(self.message.long_tweet, widgetUtils.CHECKBOX, self.text_processor) - if config.app["app-settings"]["remember_mention_and_longtweet"]: - self.message.long_tweet.SetValue(config.app["app-settings"]["longtweet"]) - self.attachments = [] + """ This class handles the tweet main features. Other classes should derive from this class.""" + def __init__(self, session, title, caption, text="", messageType="tweet", max=280, *args, **kwargs): + super(basicTweet, self).__init__() + self.max = max + self.title = title + self.session = session + self.message = getattr(twitterDialogs, messageType)(title=title, caption=caption, message=text, *args, **kwargs) + self.message.text.SetValue(text) + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) + widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) + widgetUtils.connect_event(self.message.add_audio, widgetUtils.BUTTON_PRESSED, self.attach) + widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) + widgetUtils.connect_event(self.message.translate, widgetUtils.BUTTON_PRESSED, self.translate) + if hasattr(self.message, "add"): + widgetUtils.connect_event(self.message.add, widgetUtils.BUTTON_PRESSED, self.on_attach) + self.attachments = [] - def translate(self, event=None): - dlg = translator.gui.translateDialog() - if dlg.get_response() == widgetUtils.OK: - text_to_translate = self.message.get_text() - dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")] - msg = translator.translator.translate(text=text_to_translate, target=dest) - self.message.set_text(msg) - self.text_processor() - self.message.text_focus() - output.speak(_(u"Translated")) - else: - return + def translate(self, event=None): + dlg = translator.gui.translateDialog() + if dlg.get_response() == widgetUtils.OK: + text_to_translate = self.message.text.GetValue() + language_dict = translator.translator.available_languages() + for k in language_dict: + if language_dict[k] == dlg.dest_lang.GetStringSelection(): + dst = k + msg = translator.translator.translate(text=text_to_translate, target=dst) + self.message.text.ChangeValue(msg) + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) + self.text_processor() + self.message.text.SetFocus() + output.speak(_(u"Translated")) + else: + return - def shorten(self, event=None): - urls = utils.find_urls_in_text(self.message.get_text()) - if len(urls) == 0: - output.speak(_(u"There's no URL to be shortened")) - self.message.text_focus() - elif len(urls) == 1: - self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.shorten(urls[0]))) - output.speak(_(u"URL shortened")) - self.text_processor() - self.message.text_focus() - elif len(urls) > 1: - list_urls = urlList.urlList() - list_urls.populate_list(urls) - if list_urls.get_response() == widgetUtils.OK: - self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.shorten(list_urls.get_string()))) - output.speak(_(u"URL shortened")) - self.text_processor() - self.message.text_focus() + def text_processor(self, *args, **kwargs): + text = self.message.text.GetValue() + results = parse_tweet(text) + self.message.SetTitle(_("%s - %s of %d characters") % (self.title, results.weightedLength, self.max)) + if results.weightedLength > self.max: + self.session.sound.play("max_length.ogg") - def unshorten(self, event=None): - urls = utils.find_urls_in_text(self.message.get_text()) - if len(urls) == 0: - output.speak(_(u"There's no URL to be expanded")) - self.message.text_focus() - elif len(urls) == 1: - self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.unshorten(urls[0]))) - output.speak(_(u"URL expanded")) - self.text_processor() - self.message.text_focus() - elif len(urls) > 1: - list_urls = urlList.urlList() - list_urls.populate_list(urls) - if list_urls.get_response() == widgetUtils.OK: - self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string()))) - output.speak(_(u"URL expanded")) - self.text_processor() - self.message.text_focus() + def spellcheck(self, event=None): + text = self.message.text.GetValue() + checker = SpellChecker.spellchecker.spellChecker(text, "") + if hasattr(checker, "fixed_text"): + self.message.text.ChangeValue(checker.fixed_text) + self.text_processor() + self.message.text.SetFocus() - def text_processor(self, *args, **kwargs): - if len(self.message.get_text()) > 1: - self.message.enable_button("shortenButton") - self.message.enable_button("unshortenButton") - else: - self.message.disable_button("shortenButton") - self.message.disable_button("unshortenButton") - if self.message.get("long_tweet") == False: - 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)) - if results.weightedLength > self.max: - self.session.sound.play("max_length.ogg") - else: - self.message.set_title(_(u"%s - %s characters") % (self.title, results.weightedLength)) + def attach(self, *args, **kwargs): + def completed_callback(dlg): + url = dlg.uploaderFunction.get_url() + pub.unsubscribe(dlg.uploaderDialog.update, "uploading") + dlg.uploaderDialog.destroy() + if "sndup.net/" in url: + self.message.text.ChangeValue(self.message.text.GetValue()+url+" #audio") + self.text_processor() + else: + commonMessageDialogs.common_error(url) + dlg.cleanup() + dlg = audioUploader.audioUploader(self.session.settings, completed_callback) + self.message.text.SetFocus() - def spellcheck(self, event=None): - text = self.message.get_text() - checker = SpellChecker.spellchecker.spellChecker(text, "") - if hasattr(checker, "fixed_text"): - self.message.set_text(checker.fixed_text) - self.text_processor() - self.message.text_focus() + def can_attach(self): + if len(self.attachments) == 0: + return True + elif len(self.attachments) == 1 and (self.attachments[0]["type"] == "video" or self.attachments[0]["type"] == "gif"): + return False + elif len(self.attachments) < 4: + return True + return False - def attach(self, *args, **kwargs): - def completed_callback(dlg): - url = dlg.uploaderFunction.get_url() - pub.unsubscribe(dlg.uploaderDialog.update, "uploading") - dlg.uploaderDialog.destroy() - if "sndup.net/" in url: - self.message.set_text(self.message.get_text()+url+" #audio") - self.text_processor() - else: - commonMessageDialogs.common_error(url) + def on_attach(self, *args, **kwargs): + can_attach = self.can_attach() + menu = self.message.attach_menu(can_attach) + self.message.Bind(wx.EVT_MENU, self.on_attach_image, self.message.add_image) + self.message.Bind(wx.EVT_MENU, self.on_attach_video, self.message.add_video) + if hasattr(self.message, "add_poll"): + self.message.Bind(wx.EVT_MENU, self.on_attach_poll, self.message.add_poll) + self.message.PopupMenu(menu, self.message.add.GetPosition()) - dlg.cleanup() - dlg = audioUploader.audioUploader(self.session.settings, completed_callback) - self.message.text_focus() + def on_attach_image(self, *args, **kwargs): + can_attach = self.can_attach() + video_or_gif_present = False + for a in self.attachments: + if a["type"] == "video" or a["type"] == "gif": + video_or_gif = True + break + if can_attach == False or video_or_gif_present == True: + return self.message.unable_to_attach_file() + image, description = self.message.get_image() + if image != None: + if image.endswith("gif"): + image_type = "gif" + else: + image_type = "photo" + imageInfo = {"type": image_type, "file": image, "description": description} + if len(self.attachments) > 0 and image_type == "gif": + return self.message.unable_to_attach_file() + self.attachments.append(imageInfo) + self.message.add_item(item=[os.path.basename(imageInfo["file"]), imageInfo["type"], imageInfo["description"]]) + self.text_processor() + + def on_attach_video(self, *args, **kwargs): + if len(self.attachments) > 0: + return self.message.unable_to_attach_file() + video = self.message.get_video() + if video != None: + videoInfo = {"type": "video", "file": video, "description": ""} + if len(self.attachments) > 0: + return self.message.unable_to_attach_file() + self.attachments.append(videoInfo) + self.message.add_item(item=[os.path.basename(videoInfo["file"]), videoInfo["type"], videoInfo["description"]]) + self.text_processor() + + def on_attach_poll(self, *args, **kwargs): + dlg = twitterDialogs.poll() + if dlg.ShowModal() == wx.ID_OK: + self.poll_options = dlg.get_options() + self.poll_period = 60*24*dlg.period.GetValue() + dlg.Destroy() + + def remove_attachment(self, *args, **kwargs): + attachment = self.message.attachments.GetFocusedItem() + if attachment > -1 and len(self.attachments) > attachment: + self.attachments.pop(attachment) + self.message.remove_item(list_type="attachment") + self.text_processor() + self.message.text.SetFocus() class tweet(basicTweet): - def __init__(self, session, title, caption, text, max=280, messageType="tweet", *args, **kwargs): - super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) - self.image = None - widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) - widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) - self.text_processor() + def __init__(self, session, title, caption, text="", max=280, messageType="tweet", *args, **kwargs): + self.thread = [] + self.poll_options = None + self.poll_period = None + super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) + widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + if hasattr(self.message, "add_tweet"): + widgetUtils.connect_event(self.message.add_tweet, widgetUtils.BUTTON_PRESSED, self.add_tweet) + widgetUtils.connect_event(self.message.remove_tweet, widgetUtils.BUTTON_PRESSED, self.remove_tweet) + widgetUtils.connect_event(self.message.remove_attachment, widgetUtils.BUTTON_PRESSED, self.remove_attachment) + self.text_processor() - def upload_image(self, *args, **kwargs): - a = attach.attach() - if len(a.attachments) != 0: - self.attachments = a.attachments + def autocomplete_users(self, *args, **kwargs): + c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) + c.show_menu() + + def add_tweet(self, event, update_gui=True, *args, **kwargs): + text = self.message.text.GetValue() + attachments = self.attachments[::] + tweetdata = dict(text=text, attachments=attachments, poll_options=self.poll_options, poll_period=self.poll_period) + self.thread.append(tweetdata) + self.attachments = [] + self.poll_options = None + self.poll_period = None + if update_gui: + self.message.reset_controls() + self.message.add_item(item=[text, len(attachments)], list_type="tweet") + self.message.text.SetFocus() + self.text_processor() + + def get_tweet_data(self): + self.add_tweet(event=None, update_gui=False) + return self.thread + + def text_processor(self, *args, **kwargs): + super(tweet, self).text_processor(*args, **kwargs) + if len(self.thread) > 0: + self.message.tweets.Enable(True) + self.message.remove_tweet.Enable(True) + else: + self.message.tweets.Enable(False) + self.message.remove_tweet.Enable(False) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) + if hasattr(self.message, "add_tweet"): + if len(self.message.text.GetValue()) > 0 or len(self.attachments) > 0: + self.message.add_tweet.Enable(True) + else: + self.message.add_tweet.Enable(False) + + def remove_tweet(self, *args, **kwargs): + tweet = self.message.tweets.GetFocusedItem() + if tweet > -1 and len(self.thread) > tweet: + self.thread.pop(tweet) + self.message.remove_item(list_type="tweet") + self.text_processor() + self.message.text.SetFocus() - def autocomplete_users(self, *args, **kwargs): - c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) - c.show_menu() class reply(tweet): - def __init__(self, session, title, caption, text, users=[], ids=[]): - super(reply, self).__init__(session, title, caption, text, messageType="reply", users=users) - self.ids = ids - self.users = users - if len(users) > 0: - widgetUtils.connect_event(self.message.mentionAll, widgetUtils.CHECKBOX, self.mention_all) - self.message.enable_button("mentionAll") - if config.app["app-settings"]["remember_mention_and_longtweet"]: - self.message.mentionAll.SetValue(config.app["app-settings"]["mention_all"]) - self.mention_all() - self.message.set_cursor_at_end() - self.text_processor() + def __init__(self, session, title, caption, text, users=[], ids=[]): + super(reply, self).__init__(session, title, caption, text, messageType="reply", users=users) + self.ids = ids + self.users = users + if len(users) > 0: + widgetUtils.connect_event(self.message.mention_all, widgetUtils.CHECKBOX, self.mention_all) + self.message.mention_all.Enable(True) + if config.app["app-settings"]["remember_mention_and_longtweet"]: + self.message.mention_all.SetValue(config.app["app-settings"]["mention_all"]) + self.mention_all() + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) + self.text_processor() - def mention_all(self, *args, **kwargs): - if self.message.mentionAll.GetValue() == True: - for i in self.message.checkboxes: - i.SetValue(True) - i.Hide() - else: - for i in self.message.checkboxes: - i.SetValue(False) - i.Show() + def text_processor(self, *args, **kwargs): + super(tweet, self).text_processor(*args, **kwargs) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) - def get_ids(self): - excluded_ids = "" - for i in range(0, len(self.message.checkboxes)): - if self.message.checkboxes[i].GetValue() == False: - excluded_ids = excluded_ids + "{0},".format(self.ids[i],) - return excluded_ids + def mention_all(self, *args, **kwargs): + if self.message.mention_all.GetValue() == True: + for i in self.message.checkboxes: + i.SetValue(True) + i.Hide() + else: + for i in self.message.checkboxes: + i.SetValue(False) + i.Show() - def get_people(self): - people = "" - for i in range(0, len(self.message.checkboxes)): - if self.message.checkboxes[i].GetValue() == True: - people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),) - return people + def get_ids(self): + excluded_ids = [] + for i in range(0, len(self.message.checkboxes)): + if self.message.checkboxes[i].GetValue() == False: + excluded_ids.append(self.ids[i]) + return excluded_ids + + def get_people(self): + people = "" + for i in range(0, len(self.message.checkboxes)): + if self.message.checkboxes[i].GetValue() == True: + people = people + "{0} ".format(self.message.checkboxes[i].GetLabel(),) + return people class dm(basicTweet): - def __init__(self, session, title, caption, text): - super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000) - widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) - self.text_processor() - widgetUtils.connect_event(self.message.cb, widgetUtils.ENTERED_TEXT, self.user_changed) + def __init__(self, session, title, caption, users): + super(dm, self).__init__(session, title, caption, messageType="dm", max=10000, users=users) + widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + self.text_processor() + widgetUtils.connect_event(self.message.cb, widgetUtils.ENTERED_TEXT, self.user_changed) - def user_changed(self, *args, **kwargs): - self.title = _("Direct message to %s") % (self.message.get_user()) - self.text_processor() + def user_changed(self, *args, **kwargs): + self.title = _("Direct message to %s") % (self.message.cb.GetValue()) + self.text_processor() - def autocomplete_users(self, *args, **kwargs): - c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) - c.show_menu("dm") + def autocomplete_users(self, *args, **kwargs): + c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) + c.show_menu("dm") + + def text_processor(self, *args, **kwargs): + super(dm, self).text_processor(*args, **kwargs) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) + + def can_attach(self): + if len(self.attachments) == 0: + return True + return False class viewTweet(basicTweet): - def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date=""): - """ 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. - param is_tweet: True or false, depending wether the passed object is a tweet or not.""" - if is_tweet == True: - self.title = _(u"Tweet") - image_description = [] - text = "" - for i in range(0, len(tweetList)): - # tweets with message keys are longer tweets, the message value is the full messaje taken from twishort. - if hasattr(tweetList[i], "message") and tweetList[i].is_quote_status == False: - value = "message" - else: - value = "full_text" - if hasattr(tweetList[i], "retweeted_status") and tweetList[i].is_quote_status == False: - if not hasattr(tweetList[i], "message"): - text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, tweetList[i].retweeted_status.full_text) - else: - text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, getattr(tweetList[i], value)) - else: - text = text + " @%s: %s\n" % (tweetList[i].user.screen_name, getattr(tweetList[i], value)) - # tweets with extended_entities could include image descriptions. - if hasattr(tweetList[i], "extended_entities") and "media" in tweetList[i].extended_entities: - for z in tweetList[i].extended_entities["media"]: - if "ext_alt_text" in z and z["ext_alt_text"] != None: - image_description.append(z["ext_alt_text"]) - if hasattr(tweetList[i], "retweeted_status") and hasattr(tweetList[i].retweeted_status, "extended_entities") and "media" in tweetList[i].retweeted_status["extended_entities"]: - for z in tweetList[i].retweeted_status.extended_entities["media"]: - if "ext_alt_text" in z and z["ext_alt_text"] != None: - image_description.append(z["ext_alt_text"]) - # set rt and likes counters. - rt_count = str(tweet.retweet_count) - favs_count = str(tweet.favorite_count) - # Gets the client from where this tweet was made. - source = tweet.source - original_date = arrow.get(tweet.created_at, locale="en") - date = original_date.shift(seconds=utc_offset).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage()) - if text == "": - if hasattr(tweet, "message"): - value = "message" - else: - value = "full_text" - if hasattr(tweet, "retweeted_status"): - if not hasattr(tweet, "message"): - text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, tweet.retweeted_status.full_text) - else: - text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, getattr(tweet, value)) - else: - text = getattr(tweet, value) - text = self.clear_text(text) - if hasattr(tweet, "extended_entities") and "media" in tweet.extended_entities: - for z in tweet.extended_entities["media"]: - if "ext_alt_text" in z and z["ext_alt_text"] != None: - image_description.append(z["ext_alt_text"]) - if hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "extended_entities") and "media" in tweet.retweeted_status.extended_entities: - for z in tweet.retweeted_status.extended_entities["media"]: - if "ext_alt_text" in z and z["ext_alt_text"] != None: - image_description.append(z["ext_alt_text"]) - self.message = message.viewTweet(text, rt_count, favs_count, source, date) - results = parse_tweet(text) - self.message.set_title(results.weightedLength) - [self.message.set_image_description(i) for i in image_description] - else: - self.title = _(u"View item") - text = tweet - self.message = message.viewNonTweet(text, date) - widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) - widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) - if self.contain_urls() == True: - self.message.enable_button("unshortenButton") - widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) - self.message.get_response() + 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. + param is_tweet: True or false, depending wether the passed object is a tweet or not.""" + if is_tweet == True: + self.title = _(u"Tweet") + image_description = [] + text = "" + for i in range(0, len(tweetList)): + # tweets with message keys are longer tweets, the message value is the full messaje taken from twishort. + if hasattr(tweetList[i], "message") and tweetList[i].is_quote_status == False: + value = "message" + else: + value = "full_text" + if hasattr(tweetList[i], "retweeted_status") and tweetList[i].is_quote_status == False: + if not hasattr(tweetList[i], "message"): + text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, tweetList[i].retweeted_status.full_text) + else: + text = text + "rt @%s: %s\n" % (tweetList[i].retweeted_status.user.screen_name, getattr(tweetList[i], value)) + else: + text = text + " @%s: %s\n" % (tweetList[i].user.screen_name, getattr(tweetList[i], value)) + # tweets with extended_entities could include image descriptions. + if hasattr(tweetList[i], "extended_entities") and "media" in tweetList[i].extended_entities: + for z in tweetList[i].extended_entities["media"]: + if "ext_alt_text" in z and z["ext_alt_text"] != None: + image_description.append(z["ext_alt_text"]) + if hasattr(tweetList[i], "retweeted_status") and hasattr(tweetList[i].retweeted_status, "extended_entities") and "media" in tweetList[i].retweeted_status["extended_entities"]: + for z in tweetList[i].retweeted_status.extended_entities["media"]: + if "ext_alt_text" in z and z["ext_alt_text"] != None: + image_description.append(z["ext_alt_text"]) + # set rt and likes counters. + rt_count = str(tweet.retweet_count) + favs_count = str(tweet.favorite_count) + # Gets the client from where this tweet was made. + source = tweet.source + original_date = arrow.get(tweet.created_at, locale="en") + date = original_date.shift(seconds=utc_offset).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage()) + if text == "": + if hasattr(tweet, "message"): + value = "message" + else: + value = "full_text" + if hasattr(tweet, "retweeted_status"): + if not hasattr(tweet, "message"): + text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, tweet.retweeted_status.full_text) + else: + text = "rt @%s: %s" % (tweet.retweeted_status.user.screen_name, getattr(tweet, value)) + else: + text = getattr(tweet, value) + text = self.clear_text(text) + if hasattr(tweet, "extended_entities") and "media" in tweet.extended_entities: + for z in tweet.extended_entities["media"]: + if "ext_alt_text" in z and z["ext_alt_text"] != None: + image_description.append(z["ext_alt_text"]) + if hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "extended_entities") and "media" in tweet.retweeted_status.extended_entities: + for z in tweet.retweeted_status.extended_entities["media"]: + if "ext_alt_text" in z and z["ext_alt_text"] != None: + image_description.append(z["ext_alt_text"]) + self.message = twitterDialogs.viewTweet(text, rt_count, favs_count, source, date) + results = parse_tweet(text) + self.message.set_title(results.weightedLength) + [self.message.set_image_description(i) for i in image_description] + else: + self.title = _(u"View item") + text = tweet + self.message = twitterDialogs.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) + self.message.ShowModal() - def contain_urls(self): - if len(utils.find_urls_in_text(self.message.get_text())) > 0: - return True - return False + # We won't need text_processor in this dialog, so let's avoid it. + def text_processor(self): + pass - def clear_text(self, text): - urls = utils.find_urls_in_text(text) - for i in urls: - if "https://twitter.com/" in i: - text = text.replace(i, "\n") - return text + def clear_text(self, text): + urls = utils.find_urls_in_text(text) + for i in urls: + 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.")) \ No newline at end of file diff --git a/src/controller/settings.py b/src/controller/settings.py index f1a3e728..84040d2e 100644 --- a/src/controller/settings.py +++ b/src/controller/settings.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import str -from builtins import object import os import webbrowser import sound_lib @@ -24,202 +21,206 @@ from collections import OrderedDict from mysc import autostart as autostart_windows class globalSettingsController(object): - def __init__(self): - super(globalSettingsController, self).__init__() - self.dialog = configuration.configurationDialog() - self.create_config() - self.needs_restart = False - self.is_started = True + def __init__(self): + super(globalSettingsController, self).__init__() + self.dialog = configuration.configurationDialog() + self.create_config() + self.needs_restart = False + self.is_started = True - def make_kmmap(self): - res={} - for i in os.listdir(os.path.join(paths.app_path(), 'keymaps')): - if ".keymap" not in i: - continue - try: - res[i[:-7]] =i - except: - log.exception("Exception while loading keymap " + i) - return res + def make_kmmap(self): + res={} + for i in os.listdir(os.path.join(paths.app_path(), 'keymaps')): + if ".keymap" not in i: + continue + try: + res[i[:-7]] =i + except: + log.exception("Exception while loading keymap " + i) + return res - def create_config(self): - self.kmmap=self.make_kmmap() - self.langs = languageHandler.getAvailableLanguages() - langs = [] - [langs.append(i[1]) for i in self.langs] - self.codes = [] - [self.codes.append(i[0]) for i in self.langs] - id = self.codes.index(config.app["app-settings"]["language"]) - self.kmfriendlies=[] - self.kmnames=[] - for k,v in list(self.kmmap.items()): - self.kmfriendlies.append(k) - self.kmnames.append(v) - self.kmid=self.kmnames.index(config.app['app-settings']['load_keymap']) - self.dialog.create_general(langs,self.kmfriendlies) - self.dialog.general.language.SetSelection(id) - self.dialog.general.km.SetSelection(self.kmid) - if paths.mode == "installed": - self.dialog.set_value("general", "autostart", config.app["app-settings"]["autostart"]) - else: - self.dialog.general.autostart.Enable(False) - self.dialog.set_value("general", "ask_at_exit", config.app["app-settings"]["ask_at_exit"]) - self.dialog.set_value("general", "no_streaming", config.app["app-settings"]["no_streaming"]) - self.dialog.set_value("general", "play_ready_sound", config.app["app-settings"]["play_ready_sound"]) - self.dialog.set_value("general", "speak_ready_msg", config.app["app-settings"]["speak_ready_msg"]) - self.dialog.set_value("general", "handle_longtweets", config.app["app-settings"]["handle_longtweets"]) - self.dialog.set_value("general", "use_invisible_shorcuts", config.app["app-settings"]["use_invisible_keyboard_shorcuts"]) - self.dialog.set_value("general", "disable_sapi5", config.app["app-settings"]["voice_enabled"]) - self.dialog.set_value("general", "hide_gui", config.app["app-settings"]["hide_gui"]) - self.dialog.set_value("general", "update_period", config.app["app-settings"]["update_period"]) - self.dialog.set_value("general", "check_for_updates", config.app["app-settings"]["check_for_updates"]) - self.dialog.set_value("general", "remember_mention_and_longtweet", config.app["app-settings"]["remember_mention_and_longtweet"]) - proxyTypes = [_("System default"), _("HTTP"), _("SOCKS v4"), _("SOCKS v4 with DNS support"), _("SOCKS v5"), _("SOCKS v5 with DNS support")] - self.dialog.create_proxy(proxyTypes) - try: - self.dialog.proxy.type.SetSelection(config.app["proxy"]["type"]) - except: - self.dialog.proxy.type.SetSelection(0) - self.dialog.set_value("proxy", "server", config.app["proxy"]["server"]) - self.dialog.set_value("proxy", "port", config.app["proxy"]["port"]) - self.dialog.set_value("proxy", "user", config.app["proxy"]["user"]) - self.dialog.set_value("proxy", "password", config.app["proxy"]["password"]) + def create_config(self): + self.kmmap=self.make_kmmap() + self.langs = languageHandler.getAvailableLanguages() + langs = [] + [langs.append(i[1]) for i in self.langs] + self.codes = [] + [self.codes.append(i[0]) for i in self.langs] + id = self.codes.index(config.app["app-settings"]["language"]) + self.kmfriendlies=[] + self.kmnames=[] + for k,v in list(self.kmmap.items()): + self.kmfriendlies.append(k) + self.kmnames.append(v) + self.kmid=self.kmnames.index(config.app['app-settings']['load_keymap']) + self.dialog.create_general(langs,self.kmfriendlies) + self.dialog.general.language.SetSelection(id) + self.dialog.general.km.SetSelection(self.kmid) + if paths.mode == "installed": + self.dialog.set_value("general", "autostart", config.app["app-settings"]["autostart"]) + else: + self.dialog.general.autostart.Enable(False) + self.dialog.set_value("general", "ask_at_exit", config.app["app-settings"]["ask_at_exit"]) + self.dialog.set_value("general", "no_streaming", config.app["app-settings"]["no_streaming"]) + self.dialog.set_value("general", "play_ready_sound", config.app["app-settings"]["play_ready_sound"]) + self.dialog.set_value("general", "speak_ready_msg", config.app["app-settings"]["speak_ready_msg"]) + self.dialog.set_value("general", "handle_longtweets", config.app["app-settings"]["handle_longtweets"]) + self.dialog.set_value("general", "use_invisible_shorcuts", config.app["app-settings"]["use_invisible_keyboard_shorcuts"]) + self.dialog.set_value("general", "disable_sapi5", config.app["app-settings"]["voice_enabled"]) + self.dialog.set_value("general", "hide_gui", config.app["app-settings"]["hide_gui"]) + self.dialog.set_value("general", "update_period", config.app["app-settings"]["update_period"]) + self.dialog.set_value("general", "check_for_updates", config.app["app-settings"]["check_for_updates"]) + self.dialog.set_value("general", "remember_mention_and_longtweet", config.app["app-settings"]["remember_mention_and_longtweet"]) + proxyTypes = [_("System default"), _("HTTP"), _("SOCKS v4"), _("SOCKS v4 with DNS support"), _("SOCKS v5"), _("SOCKS v5 with DNS support")] + self.dialog.create_proxy(proxyTypes) + try: + self.dialog.proxy.type.SetSelection(config.app["proxy"]["type"]) + except: + self.dialog.proxy.type.SetSelection(0) + self.dialog.set_value("proxy", "server", config.app["proxy"]["server"]) + self.dialog.set_value("proxy", "port", config.app["proxy"]["port"]) + self.dialog.set_value("proxy", "user", config.app["proxy"]["user"]) + self.dialog.set_value("proxy", "password", config.app["proxy"]["password"]) - self.dialog.realize() - self.response = self.dialog.get_response() + self.dialog.realize() + self.response = self.dialog.get_response() - def save_configuration(self): - if self.codes[self.dialog.general.language.GetSelection()] != config.app["app-settings"]["language"]: - config.app["app-settings"]["language"] = self.codes[self.dialog.general.language.GetSelection()] - languageHandler.setLanguage(config.app["app-settings"]["language"]) - self.needs_restart = True - if self.kmnames[self.dialog.general.km.GetSelection()] != config.app["app-settings"]["load_keymap"]: - config.app["app-settings"]["load_keymap"] =self.kmnames[self.dialog.general.km.GetSelection()] - kmFile = open(os.path.join(paths.config_path(), "keymap.keymap"), "w") - kmFile.close() - self.needs_restart = True - if config.app["app-settings"]["autostart"] != self.dialog.get_value("general", "autostart") and paths.mode == "installed": - config.app["app-settings"]["autostart"] = self.dialog.get_value("general", "autostart") - autostart_windows.setAutoStart(application.name, enable=self.dialog.get_value("general", "autostart")) - if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] != self.dialog.get_value("general", "use_invisible_shorcuts"): - config.app["app-settings"]["use_invisible_keyboard_shorcuts"] = self.dialog.get_value("general", "use_invisible_shorcuts") - pub.sendMessage("invisible-shorcuts-changed", registered=self.dialog.get_value("general", "use_invisible_shorcuts")) - if config.app["app-settings"]["no_streaming"] != self.dialog.get_value("general", "no_streaming"): - config.app["app-settings"]["no_streaming"] = self.dialog.get_value("general", "no_streaming") - self.needs_restart = True - if config.app["app-settings"]["update_period"] != self.dialog.get_value("general", "update_period"): - config.app["app-settings"]["update_period"] = self.dialog.get_value("general", "update_period") - self.needs_restart = True - config.app["app-settings"]["voice_enabled"] = self.dialog.get_value("general", "disable_sapi5") - config.app["app-settings"]["hide_gui"] = self.dialog.get_value("general", "hide_gui") - config.app["app-settings"]["ask_at_exit"] = self.dialog.get_value("general", "ask_at_exit") - config.app["app-settings"]["handle_longtweets"] = self.dialog.get_value("general", "handle_longtweets") - config.app["app-settings"]["play_ready_sound"] = self.dialog.get_value("general", "play_ready_sound") - config.app["app-settings"]["speak_ready_msg"] = self.dialog.get_value("general", "speak_ready_msg") - config.app["app-settings"]["check_for_updates"] = self.dialog.get_value("general", "check_for_updates") - config.app["app-settings"]["remember_mention_and_longtweet"] = self.dialog.get_value("general", "remember_mention_and_longtweet") - if config.app["proxy"]["type"]!=self.dialog.get_value("proxy", "type") or config.app["proxy"]["server"] != self.dialog.get_value("proxy", "server") or config.app["proxy"]["port"] != self.dialog.get_value("proxy", "port") or config.app["proxy"]["user"] != self.dialog.get_value("proxy", "user") or config.app["proxy"]["password"] != self.dialog.get_value("proxy", "password"): - if self.is_started == True: - self.needs_restart = True - config.app["proxy"]["type"] = self.dialog.proxy.type.Selection - config.app["proxy"]["server"] = self.dialog.get_value("proxy", "server") - config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") - config.app["proxy"]["user"] = self.dialog.get_value("proxy", "user") - config.app["proxy"]["password"] = self.dialog.get_value("proxy", "password") - config.app.write() + def save_configuration(self): + if self.codes[self.dialog.general.language.GetSelection()] != config.app["app-settings"]["language"]: + config.app["app-settings"]["language"] = self.codes[self.dialog.general.language.GetSelection()] + languageHandler.setLanguage(config.app["app-settings"]["language"]) + self.needs_restart = True + if self.kmnames[self.dialog.general.km.GetSelection()] != config.app["app-settings"]["load_keymap"]: + config.app["app-settings"]["load_keymap"] =self.kmnames[self.dialog.general.km.GetSelection()] + kmFile = open(os.path.join(paths.config_path(), "keymap.keymap"), "w") + kmFile.close() + self.needs_restart = True + if config.app["app-settings"]["autostart"] != self.dialog.get_value("general", "autostart") and paths.mode == "installed": + config.app["app-settings"]["autostart"] = self.dialog.get_value("general", "autostart") + autostart_windows.setAutoStart(application.name, enable=self.dialog.get_value("general", "autostart")) + if config.app["app-settings"]["use_invisible_keyboard_shorcuts"] != self.dialog.get_value("general", "use_invisible_shorcuts"): + config.app["app-settings"]["use_invisible_keyboard_shorcuts"] = self.dialog.get_value("general", "use_invisible_shorcuts") + pub.sendMessage("invisible-shorcuts-changed", registered=self.dialog.get_value("general", "use_invisible_shorcuts")) + if config.app["app-settings"]["no_streaming"] != self.dialog.get_value("general", "no_streaming"): + config.app["app-settings"]["no_streaming"] = self.dialog.get_value("general", "no_streaming") + self.needs_restart = True + if config.app["app-settings"]["update_period"] != self.dialog.get_value("general", "update_period"): + config.app["app-settings"]["update_period"] = self.dialog.get_value("general", "update_period") + self.needs_restart = True + config.app["app-settings"]["voice_enabled"] = self.dialog.get_value("general", "disable_sapi5") + config.app["app-settings"]["hide_gui"] = self.dialog.get_value("general", "hide_gui") + config.app["app-settings"]["ask_at_exit"] = self.dialog.get_value("general", "ask_at_exit") + config.app["app-settings"]["handle_longtweets"] = self.dialog.get_value("general", "handle_longtweets") + config.app["app-settings"]["play_ready_sound"] = self.dialog.get_value("general", "play_ready_sound") + config.app["app-settings"]["speak_ready_msg"] = self.dialog.get_value("general", "speak_ready_msg") + config.app["app-settings"]["check_for_updates"] = self.dialog.get_value("general", "check_for_updates") + config.app["app-settings"]["remember_mention_and_longtweet"] = self.dialog.get_value("general", "remember_mention_and_longtweet") + if config.app["proxy"]["type"]!=self.dialog.get_value("proxy", "type") or config.app["proxy"]["server"] != self.dialog.get_value("proxy", "server") or config.app["proxy"]["port"] != self.dialog.get_value("proxy", "port") or config.app["proxy"]["user"] != self.dialog.get_value("proxy", "user") or config.app["proxy"]["password"] != self.dialog.get_value("proxy", "password"): + if self.is_started == True: + self.needs_restart = True + config.app["proxy"]["type"] = self.dialog.proxy.type.Selection + config.app["proxy"]["server"] = self.dialog.get_value("proxy", "server") + config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") + config.app["proxy"]["user"] = self.dialog.get_value("proxy", "user") + config.app["proxy"]["password"] = self.dialog.get_value("proxy", "password") + config.app.write() class accountSettingsController(globalSettingsController): - def __init__(self, buffer, window): - self.user = buffer.session.db["user_name"] - self.buffer = buffer - self.window = window - self.config = buffer.session.settings - super(accountSettingsController, self).__init__() + def __init__(self, buffer, window): + self.user = buffer.session.db["user_name"] + self.buffer = buffer + self.window = window + self.config = buffer.session.settings + super(accountSettingsController, self).__init__() - def create_config(self): - self.dialog.create_general_account() - widgetUtils.connect_event(self.dialog.general.au, widgetUtils.BUTTON_PRESSED, self.manage_autocomplete) - self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"]) - self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"]) - self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_tweets_per_call"]) - self.dialog.set_value("general", "reverse_timelines", self.config["general"]["reverse_timelines"]) - rt = self.config["general"]["retweet_mode"] - if rt == "ask": - self.dialog.set_value("general", "retweet_mode", _(u"Ask")) - elif rt == "direct": - self.dialog.set_value("general", "retweet_mode", _(u"Retweet without comments")) - else: - self.dialog.set_value("general", "retweet_mode", _(u"Retweet with comments")) - self.dialog.set_value("general", "persist_size", str(self.config["general"]["persist_size"])) - self.dialog.create_reporting() - self.dialog.set_value("reporting", "speech_reporting", self.config["reporting"]["speech_reporting"]) - self.dialog.set_value("reporting", "braille_reporting", self.config["reporting"]["braille_reporting"]) - self.dialog.create_other_buffers() - buffer_values = self.get_buffers_list() - self.dialog.buffers.insert_buffers(buffer_values) - self.dialog.buffers.connect_hook_func(self.toggle_buffer_active) - widgetUtils.connect_event(self.dialog.buffers.toggle_state, widgetUtils.BUTTON_PRESSED, self.toggle_state) - widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up) - widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down) + def create_config(self): + self.dialog.create_general_account() + widgetUtils.connect_event(self.dialog.general.au, widgetUtils.BUTTON_PRESSED, self.manage_autocomplete) + self.dialog.set_value("general", "relative_time", self.config["general"]["relative_times"]) + self.dialog.set_value("general", "show_screen_names", self.config["general"]["show_screen_names"]) + self.dialog.set_value("general", "itemsPerApiCall", self.config["general"]["max_tweets_per_call"]) + self.dialog.set_value("general", "reverse_timelines", self.config["general"]["reverse_timelines"]) + rt = self.config["general"]["retweet_mode"] + if rt == "ask": + self.dialog.set_value("general", "retweet_mode", _(u"Ask")) + elif rt == "direct": + self.dialog.set_value("general", "retweet_mode", _(u"Retweet without comments")) + else: + self.dialog.set_value("general", "retweet_mode", _(u"Retweet with comments")) + self.dialog.set_value("general", "persist_size", str(self.config["general"]["persist_size"])) + self.dialog.set_value("general", "load_cache_in_memory", self.config["general"]["load_cache_in_memory"]) + self.dialog.create_reporting() + self.dialog.set_value("reporting", "speech_reporting", self.config["reporting"]["speech_reporting"]) + self.dialog.set_value("reporting", "braille_reporting", self.config["reporting"]["braille_reporting"]) + self.dialog.create_other_buffers() + buffer_values = self.get_buffers_list() + self.dialog.buffers.insert_buffers(buffer_values) + self.dialog.buffers.connect_hook_func(self.toggle_buffer_active) + widgetUtils.connect_event(self.dialog.buffers.toggle_state, widgetUtils.BUTTON_PRESSED, self.toggle_state) + widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up) + widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down) - self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"]) - widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client) - widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client) - self.input_devices = sound_lib.input.Input.get_device_names() - self.output_devices = sound_lib.output.Output.get_device_names() - self.soundpacks = [] - [self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(os.path.join(paths.sound_path(), i)) == True ] - self.dialog.create_sound(self.input_devices, self.output_devices, self.soundpacks) - self.dialog.set_value("sound", "volumeCtrl", self.config["sound"]["volume"]*100) - self.dialog.set_value("sound", "input", self.config["sound"]["input_device"]) - self.dialog.set_value("sound", "output", self.config["sound"]["output_device"]) - self.dialog.set_value("sound", "session_mute", self.config["sound"]["session_mute"]) - self.dialog.set_value("sound", "soundpack", self.config["sound"]["current_soundpack"]) - self.dialog.set_value("sound", "indicate_audio", self.config["sound"]["indicate_audio"]) - self.dialog.set_value("sound", "indicate_geo", self.config["sound"]["indicate_geo"]) - self.dialog.set_value("sound", "indicate_img", self.config["sound"]["indicate_img"]) - self.dialog.create_extras(OCRSpace.translatable_langs) - self.dialog.set_value("extras", "sndup_apiKey", self.config["sound"]["sndup_api_key"]) - language_index = OCRSpace.OcrLangs.index(self.config["mysc"]["ocr_language"]) - self.dialog.extras.ocr_lang.SetSelection(language_index) - self.dialog.realize() - self.dialog.set_title(_(u"Account settings for %s") % (self.user,)) - self.response = self.dialog.get_response() + self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"]) + widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client) + widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client) + self.input_devices = sound_lib.input.Input.get_device_names() + self.output_devices = sound_lib.output.Output.get_device_names() + self.soundpacks = [] + [self.soundpacks.append(i) for i in os.listdir(paths.sound_path()) if os.path.isdir(os.path.join(paths.sound_path(), i)) == True ] + self.dialog.create_sound(self.input_devices, self.output_devices, self.soundpacks) + self.dialog.set_value("sound", "volumeCtrl", self.config["sound"]["volume"]*100) + self.dialog.set_value("sound", "input", self.config["sound"]["input_device"]) + self.dialog.set_value("sound", "output", self.config["sound"]["output_device"]) + self.dialog.set_value("sound", "session_mute", self.config["sound"]["session_mute"]) + self.dialog.set_value("sound", "soundpack", self.config["sound"]["current_soundpack"]) + self.dialog.set_value("sound", "indicate_audio", self.config["sound"]["indicate_audio"]) + self.dialog.set_value("sound", "indicate_geo", self.config["sound"]["indicate_geo"]) + self.dialog.set_value("sound", "indicate_img", self.config["sound"]["indicate_img"]) + self.dialog.create_extras(OCRSpace.translatable_langs) + self.dialog.set_value("extras", "sndup_apiKey", self.config["sound"]["sndup_api_key"]) + language_index = OCRSpace.OcrLangs.index(self.config["mysc"]["ocr_language"]) + self.dialog.extras.ocr_lang.SetSelection(language_index) + self.dialog.realize() + self.dialog.set_title(_(u"Account settings for %s") % (self.user,)) + self.response = self.dialog.get_response() - def save_configuration(self): - if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): - self.needs_restart = True - self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") - self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") - self.config["general"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") - if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"): - if self.dialog.get_value("general", "persist_size") == '': - self.config["general"]["persist_size"] =-1 - else: - try: - self.config["general"]["persist_size"] = int(self.dialog.get_value("general", "persist_size")) - except ValueError: - output.speak("Invalid cache size, setting to default.",True) - self.config["general"]["persist_size"] =1764 + def save_configuration(self): + if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): + self.needs_restart = True + self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") + self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") + self.config["general"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") + if self.config["general"]["load_cache_in_memory"] != self.dialog.get_value("general", "load_cache_in_memory"): + self.config["general"]["load_cache_in_memory"] = self.dialog.get_value("general", "load_cache_in_memory") + self.needs_restart = True + if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"): + if self.dialog.get_value("general", "persist_size") == '': + self.config["general"]["persist_size"] =-1 + else: + try: + self.config["general"]["persist_size"] = int(self.dialog.get_value("general", "persist_size")) + except ValueError: + output.speak("Invalid cache size, setting to default.",True) + self.config["general"]["persist_size"] =1764 - if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"): - self.needs_restart = True - self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines") - rt = self.dialog.get_value("general", "retweet_mode") - if rt == _(u"Ask"): - self.config["general"]["retweet_mode"] = "ask" - elif rt == _(u"Retweet without comments"): - self.config["general"]["retweet_mode"] = "direct" - else: - self.config["general"]["retweet_mode"] = "comment" - buffers_list = self.dialog.buffers.get_list() - if buffers_list != self.config["general"]["buffer_order"]: - self.needs_restart = True - self.config["general"]["buffer_order"] = buffers_list - self.config["reporting"]["speech_reporting"] = self.dialog.get_value("reporting", "speech_reporting") - self.config["reporting"]["braille_reporting"] = self.dialog.get_value("reporting", "braille_reporting") - self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()] + if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"): + self.needs_restart = True + self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines") + rt = self.dialog.get_value("general", "retweet_mode") + if rt == _(u"Ask"): + self.config["general"]["retweet_mode"] = "ask" + elif rt == _(u"Retweet without comments"): + self.config["general"]["retweet_mode"] = "direct" + else: + self.config["general"]["retweet_mode"] = "comment" + buffers_list = self.dialog.buffers.get_list() + if buffers_list != self.config["general"]["buffer_order"]: + self.needs_restart = True + self.config["general"]["buffer_order"] = buffers_list + self.config["reporting"]["speech_reporting"] = self.dialog.get_value("reporting", "speech_reporting") + self.config["reporting"]["braille_reporting"] = self.dialog.get_value("reporting", "braille_reporting") + self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()] # if self.config["other_buffers"]["show_followers"] != self.dialog.get_value("buffers", "followers"): # self.config["other_buffers"]["show_followers"] = self.dialog.get_value("buffers", "followers") # pub.sendMessage("create-new-buffer", buffer="followers", account=self.user, create=self.config["other_buffers"]["show_followers"]) @@ -238,75 +239,75 @@ class accountSettingsController(globalSettingsController): # if self.config["other_buffers"]["show_events"] != self.dialog.get_value("buffers", "events"): # self.config["other_buffers"]["show_events"] = self.dialog.get_value("buffers", "events") # pub.sendMessage("create-new-buffer", buffer="events", account=self.user, create=self.config["other_buffers"]["show_events"]) - if self.config["sound"]["input_device"] != self.dialog.sound.get("input"): - self.config["sound"]["input_device"] = self.dialog.sound.get("input") - try: - self.buffer.session.sound.input.set_device(self.buffer.session.sound.input.find_device_by_name(self.config["sound"]["input_device"])) - except: - self.config["sound"]["input_device"] = "default" - if self.config["sound"]["output_device"] != self.dialog.sound.get("output"): - self.config["sound"]["output_device"] = self.dialog.sound.get("output") - try: - self.buffer.session.sound.output.set_device(self.buffer.session.sound.output.find_device_by_name(self.config["sound"]["output_device"])) - except: - self.config["sound"]["output_device"] = "default" - self.config["sound"]["volume"] = self.dialog.get_value("sound", "volumeCtrl")/100.0 - self.config["sound"]["session_mute"] = self.dialog.get_value("sound", "session_mute") - self.config["sound"]["current_soundpack"] = self.dialog.sound.get("soundpack") - self.config["sound"]["indicate_audio"] = self.dialog.get_value("sound", "indicate_audio") - self.config["sound"]["indicate_geo"] = self.dialog.get_value("sound", "indicate_geo") - self.config["sound"]["indicate_img"] = self.dialog.get_value("sound", "indicate_img") - self.config["sound"]["sndup_api_key"] = self.dialog.get_value("extras", "sndup_apiKey") - self.buffer.session.sound.config = self.config["sound"] - self.buffer.session.sound.check_soundpack() - self.config.write() + if self.config["sound"]["input_device"] != self.dialog.sound.get("input"): + self.config["sound"]["input_device"] = self.dialog.sound.get("input") + try: + self.buffer.session.sound.input.set_device(self.buffer.session.sound.input.find_device_by_name(self.config["sound"]["input_device"])) + except: + self.config["sound"]["input_device"] = "default" + if self.config["sound"]["output_device"] != self.dialog.sound.get("output"): + self.config["sound"]["output_device"] = self.dialog.sound.get("output") + try: + self.buffer.session.sound.output.set_device(self.buffer.session.sound.output.find_device_by_name(self.config["sound"]["output_device"])) + except: + self.config["sound"]["output_device"] = "default" + self.config["sound"]["volume"] = self.dialog.get_value("sound", "volumeCtrl")/100.0 + self.config["sound"]["session_mute"] = self.dialog.get_value("sound", "session_mute") + self.config["sound"]["current_soundpack"] = self.dialog.sound.get("soundpack") + self.config["sound"]["indicate_audio"] = self.dialog.get_value("sound", "indicate_audio") + self.config["sound"]["indicate_geo"] = self.dialog.get_value("sound", "indicate_geo") + self.config["sound"]["indicate_img"] = self.dialog.get_value("sound", "indicate_img") + self.config["sound"]["sndup_api_key"] = self.dialog.get_value("extras", "sndup_apiKey") + self.buffer.session.sound.config = self.config["sound"] + self.buffer.session.sound.check_soundpack() + self.config.write() - def toggle_state(self,*args,**kwargs): - return self.dialog.buffers.change_selected_item() + def toggle_state(self,*args,**kwargs): + return self.dialog.buffers.change_selected_item() - def manage_autocomplete(self, *args, **kwargs): - configuration = settings.autocompletionSettings(self.buffer.session.settings, self.buffer, self.window) + def manage_autocomplete(self, *args, **kwargs): + configuration = settings.autocompletionSettings(self.buffer.session.settings, self.buffer, self.window) - def add_ignored_client(self, *args, **kwargs): - client = commonMessageDialogs.get_ignored_client() - if client == None: return - if client not in self.config["twitter"]["ignored_clients"]: - self.config["twitter"]["ignored_clients"].append(client) - self.dialog.ignored_clients.append(client) + def add_ignored_client(self, *args, **kwargs): + client = commonMessageDialogs.get_ignored_client() + if client == None: return + if client not in self.config["twitter"]["ignored_clients"]: + self.config["twitter"]["ignored_clients"].append(client) + self.dialog.ignored_clients.append(client) - def remove_ignored_client(self, *args, **kwargs): - if self.dialog.ignored_clients.get_clients() == 0: return - id = self.dialog.ignored_clients.get_client_id() - self.config["twitter"]["ignored_clients"].pop(id) - self.dialog.ignored_clients.remove_(id) + def remove_ignored_client(self, *args, **kwargs): + if self.dialog.ignored_clients.get_clients() == 0: return + id = self.dialog.ignored_clients.get_client_id() + self.config["twitter"]["ignored_clients"].pop(id) + self.dialog.ignored_clients.remove_(id) - def get_buffers_list(self): - all_buffers=OrderedDict() - all_buffers['home']=_(u"Home") - all_buffers['mentions']=_(u"Mentions") - all_buffers['dm']=_(u"Direct Messages") - all_buffers['sent_dm']=_(u"Sent direct messages") - all_buffers['sent_tweets']=_(u"Sent tweets") - all_buffers['favorites']=_(u"Likes") - all_buffers['followers']=_(u"Followers") - all_buffers['friends']=_(u"Friends") - all_buffers['blocks']=_(u"Blocked users") - all_buffers['muted']=_(u"Muted users") - list_buffers = [] - hidden_buffers=[] - all_buffers_keys = list(all_buffers.keys()) - # Check buffers shown first. - for i in self.config["general"]["buffer_order"]: - if i in all_buffers_keys: - list_buffers.append((i, all_buffers[i], True)) - # This second pass will retrieve all hidden buffers. - for i in all_buffers_keys: - if i not in self.config["general"]["buffer_order"]: - hidden_buffers.append((i, all_buffers[i], False)) - list_buffers.extend(hidden_buffers) - return list_buffers + def get_buffers_list(self): + all_buffers=OrderedDict() + all_buffers['home']=_(u"Home") + all_buffers['mentions']=_(u"Mentions") + all_buffers['dm']=_(u"Direct Messages") + all_buffers['sent_dm']=_(u"Sent direct messages") + all_buffers['sent_tweets']=_(u"Sent tweets") + all_buffers['favorites']=_(u"Likes") + all_buffers['followers']=_(u"Followers") + all_buffers['friends']=_(u"Friends") + all_buffers['blocks']=_(u"Blocked users") + all_buffers['muted']=_(u"Muted users") + list_buffers = [] + hidden_buffers=[] + all_buffers_keys = list(all_buffers.keys()) + # Check buffers shown first. + for i in self.config["general"]["buffer_order"]: + if i in all_buffers_keys: + list_buffers.append((i, all_buffers[i], True)) + # This second pass will retrieve all hidden buffers. + for i in all_buffers_keys: + if i not in self.config["general"]["buffer_order"]: + hidden_buffers.append((i, all_buffers[i], False)) + list_buffers.extend(hidden_buffers) + return list_buffers - def toggle_buffer_active(self, ev): - change = self.dialog.buffers.get_event(ev) - if change == True: - self.dialog.buffers.change_selected_item() \ No newline at end of file + def toggle_buffer_active(self, ev): + change = self.dialog.buffers.get_event(ev) + if change == True: + self.dialog.buffers.change_selected_item() diff --git a/src/controller/trendingTopics.py b/src/controller/trendingTopics.py index 5b6bd270..e61032b8 100644 --- a/src/controller/trendingTopics.py +++ b/src/controller/trendingTopics.py @@ -3,43 +3,43 @@ from wxUI.dialogs import trends import widgetUtils class trendingTopicsController(object): - def __init__(self, session): - super(trendingTopicsController, self).__init__() - self.countries = {} - self.cities = {} - self.dialog = trends.trendingTopicsDialog() - self.information = session.twitter.trends_available() - self.split_information() - widgetUtils.connect_event(self.dialog.country, widgetUtils.RADIOBUTTON, self.get_places) - widgetUtils.connect_event(self.dialog.city, widgetUtils.RADIOBUTTON, self.get_places) - self.get_places() + def __init__(self, session): + super(trendingTopicsController, self).__init__() + self.countries = {} + self.cities = {} + self.dialog = trends.trendingTopicsDialog() + self.information = session.twitter.available_trends() + self.split_information() + widgetUtils.connect_event(self.dialog.country, widgetUtils.RADIOBUTTON, self.get_places) + widgetUtils.connect_event(self.dialog.city, widgetUtils.RADIOBUTTON, self.get_places) + self.get_places() - def split_information(self): - for i in self.information: - if i["placeType"]["name"] == "Country": - self.countries[i["name"]] = i["woeid"] - else: - self.cities[i["name"]] = i["woeid"] + def split_information(self): + for i in self.information: + if i["placeType"]["name"] == "Country": + self.countries[i["name"]] = i["woeid"] + else: + self.cities[i["name"]] = i["woeid"] - def get_places(self, event=None): - values = [] - if self.dialog.get_active() == "country": - for i in self.information: - if i["placeType"]["name"] == "Country": - values.append(i["name"]) - elif self.dialog.get_active() == "city": - for i in self.information: - if i["placeType"]["name"] != "Country": - values.append(i["name"]) - self.dialog.set(values) + def get_places(self, event=None): + values = [] + if self.dialog.get_active() == "country": + for i in self.information: + if i["placeType"]["name"] == "Country": + values.append(i["name"]) + elif self.dialog.get_active() == "city": + for i in self.information: + if i["placeType"]["name"] != "Country": + values.append(i["name"]) + self.dialog.set(values) - def get_woeid(self): - selected = self.dialog.get_item() - if self.dialog.get_active() == "country": - woeid = self.countries[selected] - else: - woeid = self.cities[selected] - return woeid + def get_woeid(self): + selected = self.dialog.get_item() + if self.dialog.get_active() == "country": + woeid = self.countries[selected] + else: + woeid = self.cities[selected] + return woeid - def get_string(self): - return self.dialog.get_item() \ No newline at end of file + def get_string(self): + return self.dialog.get_item() diff --git a/src/controller/user.py b/src/controller/user.py index 9293b5c7..7bd1fb21 100644 --- a/src/controller/user.py +++ b/src/controller/user.py @@ -6,123 +6,123 @@ import output from wxUI.dialogs import update_profile, show_user import logging log = logging.getLogger("controller.user") -from tweepy.error import TweepError +from tweepy.errors import TweepyException, Forbidden, NotFound from sessions.twitter import utils class profileController(object): - def __init__(self, session, user=None): - super(profileController, self).__init__() - self.file = None - self.session = session - self.user = user - if user == None: - self.get_data(screen_name=self.session.db["user_name"]) - self.dialog = update_profile.updateProfileDialog() - self.fill_profile_fields() - self.uploaded = False - widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) - else: - try: - self.get_data(screen_name=self.user) - except TweepError as err: - if err.api_code == 50: - wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() - if err.api_code == 403: - wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal() - log.error("error %d: %s" % (err.api_code, err.reason)) - return - self.dialog = show_user.showUserProfile() - string = self.get_user_info() - self.dialog.set("text", string) - self.dialog.set_title(_(u"Information for %s") % (self.data.screen_name)) - if self.data.url != None: - self.dialog.enable_url() - widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url) - if self.dialog.get_response() == widgetUtils.OK and self.user == None: - self.do_update() + def __init__(self, session, user=None): + super(profileController, self).__init__() + self.file = None + self.session = session + self.user = user + if user == None: + self.get_data(screen_name=self.session.db["user_name"]) + self.dialog = update_profile.updateProfileDialog() + self.fill_profile_fields() + self.uploaded = False + widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) + else: + try: + self.get_data(screen_name=self.user) + except TweepyException as err: + if type(err) == NotFound: + wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() + if type(err) == Forbidden: + wx.MessageDialog(None, _(u"User has been suspended"), _(u"Error"), wx.ICON_ERROR).ShowModal() + log.error("error %s" % (str(err))) + return + self.dialog = show_user.showUserProfile() + string = self.get_user_info() + self.dialog.set("text", string) + self.dialog.set_title(_(u"Information for %s") % (self.data.screen_name)) + if self.data.url != None: + self.dialog.enable_url() + widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url) + if self.dialog.get_response() == widgetUtils.OK and self.user == None: + self.do_update() - def get_data(self, screen_name): - self.data = self.session.twitter.get_user(screen_name=screen_name) - if screen_name != self.session.db["user_name"]: - self.friendship_status = self.session.twitter.show_friendship(source_screen_name=self.session.db["user_name"], target_screen_name=screen_name) + def get_data(self, screen_name): + self.data = self.session.twitter.get_user(screen_name=screen_name) + if screen_name != self.session.db["user_name"]: + self.friendship_status = self.session.twitter.get_friendship(source_screen_name=self.session.db["user_name"], target_screen_name=screen_name) - def fill_profile_fields(self): - self.dialog.set_name(self.data.name) - if self.data.url != None: - self.dialog.set_url(self.data.url) - if len(self.data.location) > 0: - self.dialog.set_location(self.data.location) - if len(self.data.description) > 0: - self.dialog.set_description(self.data.description) + def fill_profile_fields(self): + self.dialog.set_name(self.data.name) + if self.data.url != None: + self.dialog.set_url(self.data.url) + if len(self.data.location) > 0: + self.dialog.set_location(self.data.location) + if len(self.data.description) > 0: + self.dialog.set_description(self.data.description) - def get_image(self): - file = self.dialog.upload_picture() - if file != None: - self.file = open(file, "rb") - self.uploaded = True - self.dialog.change_upload_button(self.uploaded) + def get_image(self): + file = self.dialog.upload_picture() + if file != None: + self.file = open(file, "rb") + self.uploaded = True + self.dialog.change_upload_button(self.uploaded) - def discard_image(self): - self.file = None - output.speak(_(u"Discarded")) - self.uploaded = False - self.dialog.change_upload_button(self.uploaded) + def discard_image(self): + self.file = None + output.speak(_(u"Discarded")) + self.uploaded = False + self.dialog.change_upload_button(self.uploaded) - def upload_image(self, *args, **kwargs): - if self.uploaded == False: - self.get_image() - elif self.uploaded == True: - self.discard_image() + def upload_image(self, *args, **kwargs): + if self.uploaded == False: + self.get_image() + elif self.uploaded == True: + self.discard_image() - def do_update(self): - if self.user != None: return - name = self.dialog.get("name") - description = self.dialog.get("description") - location = self.dialog.get("location") - url = self.dialog.get("url") - if self.file != None: - try: - self.session.twitter.update_profile_image(image=self.file) - except TweepError as e: - output.speak(u"Error %s. %s" % (e.api_code, e.reason)) - try: - self.session.twitter.update_profile(name=name, description=description, location=location, url=url) - except TweepError as e: - output.speak(u"Error %s. %s" % (e.api_code, e.reason)) + def do_update(self): + if self.user != None: return + name = self.dialog.get("name") + description = self.dialog.get("description") + location = self.dialog.get("location") + url = self.dialog.get("url") + if self.file != None: + try: + self.session.twitter.update_profile_image(image=self.file) + except TweepyException as e: + output.speak(u"Error %s" % (str(e))) + try: + self.session.twitter.update_profile(name=name, description=description, location=location, url=url) + except TweepyException as e: + output.speak(u"Error %s." % (str(e))) - def get_user_info(self): - string = u"" - string = string + _(u"Username: @%s\n") % (self.data.screen_name) - string = string + _(u"Name: %s\n") % (self.data.name) - if self.data.location != "": - string = string + _(u"Location: %s\n") % (self.data.location) - if self.data.url != None: - string = string+ _(u"URL: %s\n") % (self.data.entities["url"]["urls"][0]["expanded_url"]) - if self.data.description != "": - if self.data.entities.get("description") != None and self.data.entities["description"].get("urls"): - self.data.description = utils.expand_urls(self.data.description, self.data.entities["description"]) - string = string+ _(u"Bio: %s\n") % (self.data.description) - if self.data.protected == True: protected = _(u"Yes") - else: protected = _(u"No") - string = string+ _(u"Protected: %s\n") % (protected) - if hasattr(self, "friendship_status"): - relation = False - friendship = "Relationship: " - if self.friendship_status[0].following: - friendship += _(u"You follow {0}. ").format(self.data.name,) - relation = True - if self.friendship_status[1].following: - friendship += _(u"{0} is following you.").format(self.data.name,) - relation = True - if relation == True: - string = string+friendship+"\n" - string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data.followers_count, self.data.friends_count) - if self.data.verified == True: verified = _(u"Yes") - else: verified = _(u"No") - string = string+ _(u"Verified: %s\n") % (verified) - string = string+ _(u"Tweets: %s\n") % (self.data.statuses_count) - string = string+ _(u"Likes: %s") % (self.data.favourites_count) - return string + def get_user_info(self): + string = u"" + string = string + _(u"Username: @%s\n") % (self.data.screen_name) + string = string + _(u"Name: %s\n") % (self.data.name) + if self.data.location != "": + string = string + _(u"Location: %s\n") % (self.data.location) + if self.data.url != None: + string = string+ _(u"URL: %s\n") % (self.data.entities["url"]["urls"][0]["expanded_url"]) + if self.data.description != "": + if self.data.entities.get("description") != None and self.data.entities["description"].get("urls"): + self.data.description = utils.expand_urls(self.data.description, self.data.entities["description"]) + string = string+ _(u"Bio: %s\n") % (self.data.description) + if self.data.protected == True: protected = _(u"Yes") + else: protected = _(u"No") + string = string+ _(u"Protected: %s\n") % (protected) + if hasattr(self, "friendship_status"): + relation = False + friendship = "Relationship: " + if self.friendship_status[0].following: + friendship += _(u"You follow {0}. ").format(self.data.name,) + relation = True + if self.friendship_status[1].following: + friendship += _(u"{0} is following you.").format(self.data.name,) + relation = True + if relation == True: + string = string+friendship+"\n" + string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data.followers_count, self.data.friends_count) + if self.data.verified == True: verified = _(u"Yes") + else: verified = _(u"No") + string = string+ _(u"Verified: %s\n") % (verified) + string = string+ _(u"Tweets: %s\n") % (self.data.statuses_count) + string = string+ _(u"Likes: %s") % (self.data.favourites_count) + return string - def visit_url(self, *args, **kwargs): - webbrowser.open_new_tab(self.data.url) \ No newline at end of file + def visit_url(self, *args, **kwargs): + webbrowser.open_new_tab(self.data.url) diff --git a/src/controller/userActionsController.py b/src/controller/userActionsController.py index 54f4ba16..e9cbcd45 100644 --- a/src/controller/userActionsController.py +++ b/src/controller/userActionsController.py @@ -3,77 +3,77 @@ import widgetUtils import output from wxUI.dialogs import userActions from pubsub import pub -from tweepy.error import TweepError +from tweepy.errors import TweepyException from extra import autocompletionUsers class userActionsController(object): - def __init__(self, buffer, users=[], default="follow"): - super(userActionsController, self).__init__() - self.buffer = buffer - self.session = buffer.session - self.dialog = userActions.UserActionsDialog(users, default) - widgetUtils.connect_event(self.dialog.autocompletion, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) - if self.dialog.get_response() == widgetUtils.OK: - self.process_action() + def __init__(self, buffer, users=[], default="follow"): + super(userActionsController, self).__init__() + self.buffer = buffer + self.session = buffer.session + self.dialog = userActions.UserActionsDialog(users, default) + widgetUtils.connect_event(self.dialog.autocompletion, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + if self.dialog.get_response() == widgetUtils.OK: + self.process_action() - def autocomplete_users(self, *args, **kwargs): - c = autocompletionUsers.completion.autocompletionUsers(self.dialog, self.session.session_id) - c.show_menu("dm") + def autocomplete_users(self, *args, **kwargs): + c = autocompletionUsers.completion.autocompletionUsers(self.dialog, self.session.session_id) + c.show_menu("dm") - def process_action(self): - action = self.dialog.get_action() - user = self.dialog.get_user() - if user == "": return - getattr(self, action)(user) + def process_action(self): + action = self.dialog.get_action() + user = self.dialog.get_user() + if user == "": return + getattr(self, action)(user) - def follow(self, user): - try: - self.session.twitter.create_friendship(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def follow(self, user): + try: + self.session.twitter.create_friendship(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def unfollow(self, user): - try: - id = self.session.twitter.destroy_friendship(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def unfollow(self, user): + try: + id = self.session.twitter.destroy_friendship(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def mute(self, user): - try: - id = self.session.twitter.create_mute(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def mute(self, user): + try: + id = self.session.twitter.create_mute(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def unmute(self, user): - try: - id = self.session.twitter.destroy_mute(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def unmute(self, user): + try: + id = self.session.twitter.destroy_mute(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def report(self, user): - try: - id = self.session.twitter.report_spam(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def report(self, user): + try: + id = self.session.twitter.report_spam(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def block(self, user): - try: - id = self.session.twitter.create_block(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def block(self, user): + try: + id = self.session.twitter.create_block(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def unblock(self, user): - try: - id = self.session.twitter.destroy_block(screen_name=user ) - except TweepError as err: - output.speak("Error %s: %s" % (err.api_code, err.reason), True) + def unblock(self, user): + try: + id = self.session.twitter.destroy_block(screen_name=user ) + except TweepyException as err: + output.speak("Error %s" % (str(err)), True) - def ignore_client(self, user): - tweet = self.buffer.get_right_tweet() - if hasattr(tweet, "sender"): - output.speak(_(u"You can't ignore direct messages")) - return - client = tweet.source - if client not in self.session.settings["twitter"]["ignored_clients"]: - self.session.settings["twitter"]["ignored_clients"].append(client) - self.session.settings.write() \ No newline at end of file + def ignore_client(self, user): + tweet = self.buffer.get_right_tweet() + if hasattr(tweet, "sender"): + output.speak(_(u"You can't ignore direct messages")) + return + client = tweet.source + if client not in self.session.settings["twitter"]["ignored_clients"]: + self.session.settings["twitter"]["ignored_clients"].append(client) + self.session.settings.write() diff --git a/src/controller/userAliasController.py b/src/controller/userAliasController.py new file mode 100644 index 00000000..69a4fa8f --- /dev/null +++ b/src/controller/userAliasController.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +import widgetUtils +from pubsub import pub +from wxUI.dialogs import userAliasDialogs +from extra import autocompletionUsers + +class userAliasController(object): + def __init__(self, settings): + super(userAliasController, self).__init__() + self.settings = settings + self.dialog = userAliasDialogs.userAliasEditorDialog() + self.update_aliases_manager() + widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.on_add) + widgetUtils.connect_event(self.dialog.edit, widgetUtils.BUTTON_PRESSED, self.on_edit) + widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.on_remove) + pub.subscribe(self.update_aliases_manager, "alias-added") + self.dialog.ShowModal() + + def update_aliases_manager(self): + self.dialog.users.Clear() + aliases = [self.settings["user-aliases"].get(k) for k in self.settings["user-aliases"].keys()] + if len(aliases) > 0: + self.dialog.users.InsertItems(aliases, 0) + self.dialog.on_selection_changes() + + def on_add(self, *args, **kwargs): + pub.sendMessage("execute-action", action="add_alias") + + def on_edit(self, *args, **kwargs): + selection = self.dialog.get_selected_user() + if selection != "": + edited = self.dialog.edit_alias_dialog(_("Edit alias for {}").format(selection)) + if edited == None or edited == "": + return + for user_key in self.settings["user-aliases"].keys(): + if self.settings["user-aliases"][user_key] == selection: + self.settings["user-aliases"][user_key] = edited + self.settings.write() + self.update_aliases_manager() + break + + def on_remove(self, *args, **kwargs): + selection = self.dialog.get_selected_user() + if selection == None or selection == "": + return + should_remove = self.dialog.remove_alias_dialog() + if should_remove: + for user_key in self.settings["user-aliases"].keys(): + if self.settings["user-aliases"][user_key] == selection: + self.settings["user-aliases"].pop(user_key) + self.settings.write() + self.update_aliases_manager() + break diff --git a/src/extra/AudioUploader/audioUploader.py b/src/extra/AudioUploader/audioUploader.py index 7f23fbbd..0ba6f82e 100644 --- a/src/extra/AudioUploader/audioUploader.py +++ b/src/extra/AudioUploader/audioUploader.py @@ -37,146 +37,146 @@ import logging log = logging.getLogger("extra.AudioUploader.audioUploader") class audioUploader(object): - def __init__(self, configFile, completed_callback): - self.config = configFile - super(audioUploader, self).__init__() - self.dialog = wx_ui.audioDialog(services=self.get_available_services()) - self.file = None - self.recorded = False - self.recording = None - self.playing = None - widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) - widgetUtils.connect_event(self.dialog.pause, widgetUtils.BUTTON_PRESSED, self.on_pause) - widgetUtils.connect_event(self.dialog.record, widgetUtils.BUTTON_PRESSED, self.on_record) - widgetUtils.connect_event(self.dialog.attach_exists, widgetUtils.BUTTON_PRESSED, self.on_attach_exists) - widgetUtils.connect_event(self.dialog.discard, widgetUtils.BUTTON_PRESSED, self.on_discard) - if self.dialog.get_response() == widgetUtils.OK: - self.postprocess() - log.debug("Uploading file %s to %s..." % (self.file, self.dialog.get("services"))) - self.uploaderDialog = wx_transfer_dialogs.UploadDialog(self.file) - output.speak(_(u"Attaching...")) - if self.dialog.get("services") == "SNDUp": - base_url = "https://sndup.net/post.php" - if len(self.config["sound"]["sndup_api_key"]) > 0: - url = base_url + '?apikey=' + self.config['sound']['sndup_api_key'] - else: - url = base_url - self.uploaderFunction = transfer.Upload(obj=self, field='file', url=url, filename=self.file, completed_callback=completed_callback) - pub.subscribe(self.uploaderDialog.update, "uploading") - self.uploaderDialog.get_response(self.uploaderFunction.perform_threaded) + def __init__(self, configFile, completed_callback): + self.config = configFile + super(audioUploader, self).__init__() + self.dialog = wx_ui.audioDialog(services=self.get_available_services()) + self.file = None + self.recorded = False + self.recording = None + self.playing = None + widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) + widgetUtils.connect_event(self.dialog.pause, widgetUtils.BUTTON_PRESSED, self.on_pause) + widgetUtils.connect_event(self.dialog.record, widgetUtils.BUTTON_PRESSED, self.on_record) + widgetUtils.connect_event(self.dialog.attach_exists, widgetUtils.BUTTON_PRESSED, self.on_attach_exists) + widgetUtils.connect_event(self.dialog.discard, widgetUtils.BUTTON_PRESSED, self.on_discard) + if self.dialog.get_response() == widgetUtils.OK: + self.postprocess() + log.debug("Uploading file %s to %s..." % (self.file, self.dialog.get("services"))) + self.uploaderDialog = wx_transfer_dialogs.UploadDialog(self.file) + output.speak(_(u"Attaching...")) + if self.dialog.get("services") == "SNDUp": + base_url = "https://sndup.net/post.php" + if len(self.config["sound"]["sndup_api_key"]) > 0: + url = base_url + '?apikey=' + self.config['sound']['sndup_api_key'] + else: + url = base_url + self.uploaderFunction = transfer.Upload(obj=self, field='file', url=url, filename=self.file, completed_callback=completed_callback) + pub.subscribe(self.uploaderDialog.update, "uploading") + self.uploaderDialog.get_response(self.uploaderFunction.perform_threaded) - def get_available_services(self): - services = [] - services.append("SNDUp") - return services + def get_available_services(self): + services = [] + services.append("SNDUp") + return services - def on_pause(self, *args, **kwargs): - if self.dialog.get("pause") == _(u"Pause"): - self.recording.pause() - self.dialog.set("pause", _(u"&Resume")) - elif self.dialog.get("pause") == _(u"Resume"): - self.recording.play() - self.dialog.set("pause", _(U"&Pause")) + def on_pause(self, *args, **kwargs): + if self.dialog.get("pause") == _(u"Pause"): + self.recording.pause() + self.dialog.set("pause", _(u"&Resume")) + elif self.dialog.get("pause") == _(u"Resume"): + self.recording.play() + self.dialog.set("pause", _(U"&Pause")) - def on_record(self, *args, **kwargs): - if self.recording != None: - self.stop_recording() - self.dialog.disable_control("pause") - else: - self.start_recording() - self.dialog.enable_control("pause") + def on_record(self, *args, **kwargs): + if self.recording != None: + self.stop_recording() + self.dialog.disable_control("pause") + else: + self.start_recording() + self.dialog.enable_control("pause") - def start_recording(self): - self.dialog.disable_control("attach_exists") - self.file = tempfile.mktemp(suffix='.wav') - self.recording = sound.recording(self.file) - self.recording.play() - self.dialog.set("record", _(u"&Stop")) - output.speak(_(u"Recording")) + def start_recording(self): + self.dialog.disable_control("attach_exists") + self.file = tempfile.mktemp(suffix='.wav') + self.recording = sound.recording(self.file) + self.recording.play() + self.dialog.set("record", _(u"&Stop")) + output.speak(_(u"Recording")) - def stop_recording(self): - self.recording.stop() - self.recording.free() - output.speak(_(u"Stopped")) - self.recorded = True - self.dialog.set("record", _(u"&Record")) - self.file_attached() + def stop_recording(self): + self.recording.stop() + self.recording.free() + output.speak(_(u"Stopped")) + self.recorded = True + self.dialog.set("record", _(u"&Record")) + self.file_attached() - def file_attached(self): - self.dialog.set("pause", _(u"&Pause")) - self.dialog.disable_control("record") - self.dialog.enable_control("play") - self.dialog.enable_control("discard") - self.dialog.disable_control("attach_exists") - self.dialog.enable_control("attach") - self.dialog.play.SetFocus() + def file_attached(self): + self.dialog.set("pause", _(u"&Pause")) + self.dialog.disable_control("record") + self.dialog.enable_control("play") + self.dialog.enable_control("discard") + self.dialog.disable_control("attach_exists") + self.dialog.enable_control("attach") + self.dialog.play.SetFocus() - def on_discard(self, *args, **kwargs): - if self.playing: - self._stop() - if self.recording != None: - self.cleanup() - self.dialog.disable_control("attach") - self.dialog.disable_control("play") - self.file = None - self.dialog.enable_control("record") - self.dialog.enable_control("attach_exists") - self.dialog.record.SetFocus() - self.dialog.disable_control("discard") - self.recording = None - output.speak(_(u"Discarded")) + def on_discard(self, *args, **kwargs): + if self.playing: + self._stop() + if self.recording != None: + self.cleanup() + self.dialog.disable_control("attach") + self.dialog.disable_control("play") + self.file = None + self.dialog.enable_control("record") + self.dialog.enable_control("attach_exists") + self.dialog.record.SetFocus() + self.dialog.disable_control("discard") + self.recording = None + output.speak(_(u"Discarded")) - def on_play(self, *args, **kwargs): - if not self.playing: - call_threaded(self._play) - else: - self._stop() + def on_play(self, *args, **kwargs): + if not self.playing: + call_threaded(self._play) + else: + self._stop() - def _play(self): - output.speak(_(u"Playing...")) + def _play(self): + output.speak(_(u"Playing...")) # try: - self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE) - self.playing.play() - self.dialog.set("play", _(u"&Stop")) - try: - while self.playing.is_playing: - pass - self.dialog.set("play", _(u"&Play")) - self.playing.free() - self.playing = None - except: - pass + self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE) + self.playing.play() + self.dialog.set("play", _(u"&Stop")) + try: + while self.playing.is_playing: + pass + self.dialog.set("play", _(u"&Play")) + self.playing.free() + self.playing = None + except: + pass - def _stop(self): - output.speak(_(u"Stopped")) - self.playing.stop() - self.playing.free() - self.dialog.set("play", _(u"&Play")) - self.playing = None + def _stop(self): + output.speak(_(u"Stopped")) + self.playing.stop() + self.playing.free() + self.dialog.set("play", _(u"&Play")) + self.playing = None - def postprocess(self): - if self.file.lower().endswith('.wav'): - output.speak(_(u"Recoding audio...")) - sound.recode_audio(self.file) - self.wav_file = self.file - self.file = '%s.ogg' % self.file[:-4] + def postprocess(self): + if self.file.lower().endswith('.wav'): + output.speak(_(u"Recoding audio...")) + sound.recode_audio(self.file) + self.wav_file = self.file + self.file = '%s.ogg' % self.file[:-4] - def cleanup(self): - if self.playing and self.playing.is_playing: - self.playing.stop() - if self.recording != None: - if self.recording.is_playing: - self.recording.stop() - try: - self.recording.free() - except: - pass - os.remove(self.file) - if hasattr(self, 'wav_file'): - os.remove(self.wav_file) + def cleanup(self): + if self.playing and self.playing.is_playing: + self.playing.stop() + if self.recording != None: + if self.recording.is_playing: + self.recording.stop() + try: + self.recording.free() + except: + pass + os.remove(self.file) + if hasattr(self, 'wav_file'): + os.remove(self.wav_file) - def on_attach_exists(self, *args, **kwargs): - self.file = self.dialog.get_file() - if self.file != False: - self.file_attached() + def on_attach_exists(self, *args, **kwargs): + self.file = self.dialog.get_file() + if self.file != False: + self.file_attached() diff --git a/src/extra/AudioUploader/transfer.py b/src/extra/AudioUploader/transfer.py index a567f753..8c6bc670 100644 --- a/src/extra/AudioUploader/transfer.py +++ b/src/extra/AudioUploader/transfer.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import -from __future__ import division -from __future__ import unicode_literals -from builtins import object -from past.utils import old_div +from __future__ import division +from __future__ import unicode_literals +from builtins import object +from past.utils import old_div import sys import threading import time @@ -15,74 +15,74 @@ from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncod import requests import os class Upload(object): - def __init__(self, field=None, obj=None, url=None, filename=None, follow_location=True, completed_callback=None, verbose=False, *args, **kwargs): - super(Upload, self).__init__(*args, **kwargs) - self.url=url - self.filename=filename - log.debug("Uploading audio to %s, filename %s" % (url, filename)) - self.start_time = None - self.completed_callback = completed_callback - self.background_thread = None - self.transfer_rate = 0 - self.local_filename=os.path.basename(self.filename) - if isinstance(self.local_filename, str): - self.local_filename=self.local_filename.encode(sys.getfilesystemencoding()) - self.fin=open(self.filename, 'rb') - self.m = MultipartEncoder(fields={field:(self.local_filename, self.fin, "application/octet-stream")}) - self.monitor = MultipartEncoderMonitor(self.m, self.progress_callback) - self.response=None - self.obj=obj - self.follow_location=follow_location - #the verbose parameter is deprecated and will be removed soon + def __init__(self, field=None, obj=None, url=None, filename=None, follow_location=True, completed_callback=None, verbose=False, *args, **kwargs): + super(Upload, self).__init__(*args, **kwargs) + self.url=url + self.filename=filename + log.debug("Uploading audio to %s, filename %s" % (url, filename)) + self.start_time = None + self.completed_callback = completed_callback + self.background_thread = None + self.transfer_rate = 0 + self.local_filename=os.path.basename(self.filename) + if isinstance(self.local_filename, str): + self.local_filename=self.local_filename.encode(sys.getfilesystemencoding()) + self.fin=open(self.filename, 'rb') + self.m = MultipartEncoder(fields={field:(self.local_filename, self.fin, "application/octet-stream")}) + self.monitor = MultipartEncoderMonitor(self.m, self.progress_callback) + self.response=None + self.obj=obj + self.follow_location=follow_location + #the verbose parameter is deprecated and will be removed soon - def elapsed_time(self): - if not self.start_time: - return 0 - return time.time() - self.start_time + def elapsed_time(self): + if not self.start_time: + return 0 + return time.time() - self.start_time - def progress_callback(self, monitor): - progress = {} - progress["total"] = monitor.len - progress["current"] = monitor.bytes_read - if progress["current"] == 0: - progress["percent"] = 0 - self.transfer_rate = 0 - else: - progress["percent"] = int((float(progress["current"]) / progress["total"]) * 100) - self.transfer_rate = old_div(progress["current"], self.elapsed_time()) - progress["speed"] = '%s/s' % convert_bytes(self.transfer_rate) - if self.transfer_rate: - progress["eta"] = old_div((progress["total"] - progress["current"]), self.transfer_rate) - else: - progress["eta"] = 0 - pub.sendMessage("uploading", data=progress) + def progress_callback(self, monitor): + progress = {} + progress["total"] = monitor.len + progress["current"] = monitor.bytes_read + if progress["current"] == 0: + progress["percent"] = 0 + self.transfer_rate = 0 + else: + progress["percent"] = int((float(progress["current"]) / progress["total"]) * 100) + self.transfer_rate = old_div(progress["current"], self.elapsed_time()) + progress["speed"] = '%s/s' % convert_bytes(self.transfer_rate) + if self.transfer_rate: + progress["eta"] = old_div((progress["total"] - progress["current"]), self.transfer_rate) + else: + progress["eta"] = 0 + pub.sendMessage("uploading", data=progress) - def perform_transfer(self): - log.debug("starting upload...") - self.start_time = time.time() - self.response=requests.post(url=self.url, data=self.monitor, headers={"Content-Type":self.m.content_type}, allow_redirects=self.follow_location, stream=True) - log.debug("Upload finished.") - self.complete_transfer() + def perform_transfer(self): + log.debug("starting upload...") + self.start_time = time.time() + self.response=requests.post(url=self.url, data=self.monitor, headers={"Content-Type":self.m.content_type}, allow_redirects=self.follow_location, stream=True) + log.debug("Upload finished.") + self.complete_transfer() - def perform_threaded(self, *args, **kwargs): - self.background_thread = threading.Thread(target=self.perform_transfer) - self.background_thread.daemon = True - self.background_thread.start() + def perform_threaded(self, *args, **kwargs): + self.background_thread = threading.Thread(target=self.perform_transfer) + self.background_thread.daemon = True + self.background_thread.start() - def complete_transfer(self): - if callable(self.completed_callback): - self.completed_callback(self.obj) - if hasattr(self,'fin') and callable(self.fin.close): - self.fin.close() + def complete_transfer(self): + if callable(self.completed_callback): + self.completed_callback(self.obj) + if hasattr(self,'fin') and callable(self.fin.close): + self.fin.close() - def get_url(self): - try: - data = self.response.json() - except: - return _("Error in file upload: {0}").format(self.data.content,) - if "url" in data and data["url"] != "0": - return data["url"] - elif "error" in data and data["error"] != "0": - return data["error"] - else: - return _("Error in file upload: {0}").format(self.data.content,) \ No newline at end of file + def get_url(self): + try: + data = self.response.json() + except: + return _("Error in file upload: {0}").format(self.data.content,) + if "url" in data and data["url"] != "0": + return data["url"] + elif "error" in data and data["error"] != "0": + return data["error"] + else: + return _("Error in file upload: {0}").format(self.data.content,) diff --git a/src/extra/AudioUploader/utils.py b/src/extra/AudioUploader/utils.py index 9ec89156..c9bbdc9a 100644 --- a/src/extra/AudioUploader/utils.py +++ b/src/extra/AudioUploader/utils.py @@ -3,42 +3,42 @@ from __future__ import unicode_literals from builtins import str def convert_bytes(n): - K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 - if n >= P: - return '%.2fPb' % (float(n) / T) - elif n >= T: - return '%.2fTb' % (float(n) / T) - elif n >= G: - return '%.2fGb' % (float(n) / G) - elif n >= M: - return '%.2fMb' % (float(n) / M) - elif n >= K: - return '%.2fKb' % (float(n) / K) - else: - return '%d' % n + K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 + if n >= P: + return '%.2fPb' % (float(n) / T) + elif n >= T: + return '%.2fTb' % (float(n) / T) + elif n >= G: + return '%.2fGb' % (float(n) / G) + elif n >= M: + return '%.2fMb' % (float(n) / M) + elif n >= K: + return '%.2fKb' % (float(n) / K) + else: + return '%d' % n def seconds_to_string(seconds, precision=0): - day = seconds // 86400 - hour = seconds // 3600 - min = (seconds // 60) % 60 - sec = seconds - (hour * 3600) - (min * 60) - sec_spec = "." + str(precision) + "f" - sec_string = sec.__format__(sec_spec) - string = "" - if day == 1: - string += _(u"%d day, ") % day - elif day >= 2: - string += _(u"%d days, ") % day - if (hour == 1): - string += _(u"%d hour, ") % hour - elif (hour >= 2): - string += _("%d hours, ") % hour - if (min == 1): - string += _(u"%d minute, ") % min - elif (min >= 2): - string += _(u"%d minutes, ") % min - if sec >= 0 and sec <= 2: - string += _(u"%s second") % sec_string - else: - string += _(u"%s seconds") % sec_string - return string \ No newline at end of file + day = seconds // 86400 + hour = seconds // 3600 + min = (seconds // 60) % 60 + sec = seconds - (hour * 3600) - (min * 60) + sec_spec = "." + str(precision) + "f" + sec_string = sec.__format__(sec_spec) + string = "" + if day == 1: + string += _(u"%d day, ") % day + elif day >= 2: + string += _(u"%d days, ") % day + if (hour == 1): + string += _(u"%d hour, ") % hour + elif (hour >= 2): + string += _("%d hours, ") % hour + if (min == 1): + string += _(u"%d minute, ") % min + elif (min >= 2): + string += _(u"%d minutes, ") % min + if sec >= 0 and sec <= 2: + string += _(u"%s second") % sec_string + else: + string += _(u"%s seconds") % sec_string + return string diff --git a/src/extra/AudioUploader/wx_transfer_dialogs.py b/src/extra/AudioUploader/wx_transfer_dialogs.py index b70d343e..fc14b201 100644 --- a/src/extra/AudioUploader/wx_transfer_dialogs.py +++ b/src/extra/AudioUploader/wx_transfer_dialogs.py @@ -7,57 +7,57 @@ import widgetUtils class UploadDialog(widgetUtils.BaseDialog): - def __init__(self, filename, *args, **kwargs): - super(UploadDialog, self).__init__(parent=None, id=wx.ID_ANY, *args, **kwargs) - self.pane = wx.Panel(self) - self.progress_bar = wx.Gauge(parent=self.pane) - fileBox = wx.BoxSizer(wx.HORIZONTAL) - fileLabel = wx.StaticText(self.pane, -1, _(u"File")) - self.file = wx.TextCtrl(self.pane, -1, value=filename, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(200, 100)) - self.file.SetFocus() - fileBox.Add(fileLabel) - fileBox.Add(self.file) - currentAmountBox = wx.BoxSizer(wx.HORIZONTAL) - current_amount_label = wx.StaticText(self.pane, -1, _(u"Transferred")) - self.current_amount = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) - currentAmountBox.Add(current_amount_label) - currentAmountBox.Add(self.current_amount) - totalSizeBox = wx.BoxSizer(wx.HORIZONTAL) - total_size_label = wx.StaticText(self.pane, -1, _(u"Total file size")) - self.total_size = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) - totalSizeBox.Add(total_size_label) - totalSizeBox.Add(self.total_size) - speedBox = wx.BoxSizer(wx.HORIZONTAL) - speedLabel = wx.StaticText(self.pane, -1, _(u"Transfer rate")) - self.speed = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="0 Kb/s") - speedBox.Add(speedLabel) - speedBox.Add(self.speed) - etaBox = wx.BoxSizer(wx.HORIZONTAL) - etaLabel = wx.StaticText(self.pane, -1, _(u"Time left")) - self.eta = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="Unknown", size=(200, 100)) - etaBox.Add(etaLabel) - etaBox.Add(self.eta) - self.create_buttons() - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(fileBox) - sizer.Add(currentAmountBox) - sizer.Add(totalSizeBox) - sizer.Add(speedBox) - sizer.Add(etaBox) - sizer.Add(self.progress_bar) - self.pane.SetSizerAndFit(sizer) + def __init__(self, filename, *args, **kwargs): + super(UploadDialog, self).__init__(parent=None, id=wx.ID_ANY, *args, **kwargs) + self.pane = wx.Panel(self) + self.progress_bar = wx.Gauge(parent=self.pane) + fileBox = wx.BoxSizer(wx.HORIZONTAL) + fileLabel = wx.StaticText(self.pane, -1, _(u"File")) + self.file = wx.TextCtrl(self.pane, -1, value=filename, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(200, 100)) + self.file.SetFocus() + fileBox.Add(fileLabel) + fileBox.Add(self.file) + currentAmountBox = wx.BoxSizer(wx.HORIZONTAL) + current_amount_label = wx.StaticText(self.pane, -1, _(u"Transferred")) + self.current_amount = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) + currentAmountBox.Add(current_amount_label) + currentAmountBox.Add(self.current_amount) + totalSizeBox = wx.BoxSizer(wx.HORIZONTAL) + total_size_label = wx.StaticText(self.pane, -1, _(u"Total file size")) + self.total_size = wx.TextCtrl(self.pane, -1, value='0', style=wx.TE_READONLY|wx.TE_MULTILINE) + totalSizeBox.Add(total_size_label) + totalSizeBox.Add(self.total_size) + speedBox = wx.BoxSizer(wx.HORIZONTAL) + speedLabel = wx.StaticText(self.pane, -1, _(u"Transfer rate")) + self.speed = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="0 Kb/s") + speedBox.Add(speedLabel) + speedBox.Add(self.speed) + etaBox = wx.BoxSizer(wx.HORIZONTAL) + etaLabel = wx.StaticText(self.pane, -1, _(u"Time left")) + self.eta = wx.TextCtrl(self.pane, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, value="Unknown", size=(200, 100)) + etaBox.Add(etaLabel) + etaBox.Add(self.eta) + self.create_buttons() + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(fileBox) + sizer.Add(currentAmountBox) + sizer.Add(totalSizeBox) + sizer.Add(speedBox) + sizer.Add(etaBox) + sizer.Add(self.progress_bar) + self.pane.SetSizerAndFit(sizer) - def update(self, data): - wx.CallAfter(self.progress_bar.SetValue, data["percent"]) - wx.CallAfter(self.current_amount.SetValue, '%s (%d%%)' % (convert_bytes(data["current"]), data["percent"])) - wx.CallAfter(self.total_size.SetValue, convert_bytes(data["total"])) - wx.CallAfter(self.speed.SetValue, data["speed"]) - if data["eta"]: - wx.CallAfter(self.eta.SetValue, seconds_to_string(data["eta"])) + def update(self, data): + wx.CallAfter(self.progress_bar.SetValue, data["percent"]) + wx.CallAfter(self.current_amount.SetValue, '%s (%d%%)' % (convert_bytes(data["current"]), data["percent"])) + wx.CallAfter(self.total_size.SetValue, convert_bytes(data["total"])) + wx.CallAfter(self.speed.SetValue, data["speed"]) + if data["eta"]: + wx.CallAfter(self.eta.SetValue, seconds_to_string(data["eta"])) - def create_buttons(self): - self.cancel_button = wx.Button(parent=self.pane, id=wx.ID_CANCEL) + def create_buttons(self): + self.cancel_button = wx.Button(parent=self.pane, id=wx.ID_CANCEL) - def get_response(self, fn): - wx.CallAfter(fn, 0.01) - self.ShowModal() + def get_response(self, fn): + wx.CallAfter(fn, 0.01) + self.ShowModal() diff --git a/src/extra/AudioUploader/wx_ui.py b/src/extra/AudioUploader/wx_ui.py index 05fdbcc7..dc64dab4 100644 --- a/src/extra/AudioUploader/wx_ui.py +++ b/src/extra/AudioUploader/wx_ui.py @@ -24,56 +24,56 @@ import logging log = logging.getLogger("extra.AudioUploader.wx_UI") class audioDialog(widgetUtils.BaseDialog): - def __init__(self, services): - log.debug("creating audio dialog.") - super(audioDialog, self).__init__(None, -1, _(u"Attach audio")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - btnSizer = wx.BoxSizer(wx.HORIZONTAL) - btnSizer2 = wx.BoxSizer(wx.HORIZONTAL) + def __init__(self, services): + log.debug("creating audio dialog.") + super(audioDialog, self).__init__(None, -1, _(u"Attach audio")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer2 = wx.BoxSizer(wx.HORIZONTAL) - self.play = wx.Button(panel, -1, _(u"&Play")) - self.play.Disable() - self.pause = wx.Button(panel, -1, _(u"&Pause")) - self.pause.Disable() - self.record = wx.Button(panel, -1, _(u"&Record")) - self.record.SetFocus() - self.attach_exists = wx.Button(panel, -1, _(u"&Add an existing file")) - self.discard = wx.Button(panel, -1, _(u"&Discard")) - self.discard.Disable() - label = wx.StaticText(panel, -1, _(u"Upload to")) - self.services = wx.ComboBox(panel, -1, choices=services, value=services[0], style=wx.CB_READONLY) - servicesBox = wx.BoxSizer(wx.HORIZONTAL) - servicesBox.Add(label, 0, wx.ALL, 5) - servicesBox.Add(self.services, 0, wx.ALL, 5) - self.attach = wx.Button(panel, wx.ID_OK, _(u"Attach")) - self.attach.Disable() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Cancel")) - btnSizer.Add(self.play, 0, wx.ALL, 5) - btnSizer.Add(self.pause, 0, wx.ALL, 5) - btnSizer.Add(self.record, 0, wx.ALL, 5) - btnSizer2.Add(self.attach_exists, 0, wx.ALL, 5) - btnSizer2.Add(self.discard, 0, wx.ALL, 5) - btnSizer2.Add(self.attach, 0, wx.ALL, 5) - btnSizer2.Add(cancel, 0, wx.ALL, 5) - sizer.Add(servicesBox, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - sizer.Add(btnSizer2, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + self.play = wx.Button(panel, -1, _(u"&Play")) + self.play.Disable() + self.pause = wx.Button(panel, -1, _(u"&Pause")) + self.pause.Disable() + self.record = wx.Button(panel, -1, _(u"&Record")) + self.record.SetFocus() + self.attach_exists = wx.Button(panel, -1, _(u"&Add an existing file")) + self.discard = wx.Button(panel, -1, _(u"&Discard")) + self.discard.Disable() + label = wx.StaticText(panel, -1, _(u"Upload to")) + self.services = wx.ComboBox(panel, -1, choices=services, value=services[0], style=wx.CB_READONLY) + servicesBox = wx.BoxSizer(wx.HORIZONTAL) + servicesBox.Add(label, 0, wx.ALL, 5) + servicesBox.Add(self.services, 0, wx.ALL, 5) + self.attach = wx.Button(panel, wx.ID_OK, _(u"Attach")) + self.attach.Disable() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Cancel")) + btnSizer.Add(self.play, 0, wx.ALL, 5) + btnSizer.Add(self.pause, 0, wx.ALL, 5) + btnSizer.Add(self.record, 0, wx.ALL, 5) + btnSizer2.Add(self.attach_exists, 0, wx.ALL, 5) + btnSizer2.Add(self.discard, 0, wx.ALL, 5) + btnSizer2.Add(self.attach, 0, wx.ALL, 5) + btnSizer2.Add(cancel, 0, wx.ALL, 5) + sizer.Add(servicesBox, 0, wx.ALL, 5) + sizer.Add(btnSizer, 0, wx.ALL, 5) + sizer.Add(btnSizer2, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def enable_control(self, control): - log.debug("Enabling control %s" % (control,)) - if hasattr(self, control): - getattr(self, control).Enable() + def enable_control(self, control): + log.debug("Enabling control %s" % (control,)) + if hasattr(self, control): + getattr(self, control).Enable() - def disable_control(self, control): - log.debug("Disabling control %s" % (control,)) - if hasattr(self, control): - getattr(self, control).Disable() + def disable_control(self, control): + log.debug("Disabling control %s" % (control,)) + if hasattr(self, control): + getattr(self, control).Disable() - def get_file(self): - openFileDialog = wx.FileDialog(self, _(u"Select the audio file to be uploaded"), "", "", _("Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return False - return openFileDialog.GetPath() + def get_file(self): + openFileDialog = wx.FileDialog(self, _(u"Select the audio file to be uploaded"), "", "", _("Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return False + return openFileDialog.GetPath() diff --git a/src/extra/SoundsTutorial/gtk_ui.py b/src/extra/SoundsTutorial/gtk_ui.py index 450498a5..a5ffab02 100644 --- a/src/extra/SoundsTutorial/gtk_ui.py +++ b/src/extra/SoundsTutorial/gtk_ui.py @@ -4,23 +4,23 @@ from gi.repository import Gtk import widgetUtils class soundsTutorialDialog(Gtk.Dialog): - def __init__(self, actions): - super(soundsTutorialDialog, self).__init__("Sounds tutorial", None, 0, (Gtk.STOCK_CANCEL, widgetUtils.CANCEL)) - box = self.get_content_area() - label = Gtk.Label("Press enter for listen the sound") - self.list = widgetUtils.list("Action") - self.populate_actions(actions) - lBox = Gtk.Box(spacing=6) - lBox.add(label) - lBox.add(self.list.list) - box.add(lBox) - self.play = Gtk.Button("Play") - box.add(self.play) - self.show_all() + def __init__(self, actions): + super(soundsTutorialDialog, self).__init__("Sounds tutorial", None, 0, (Gtk.STOCK_CANCEL, widgetUtils.CANCEL)) + box = self.get_content_area() + label = Gtk.Label("Press enter for listen the sound") + self.list = widgetUtils.list("Action") + self.populate_actions(actions) + lBox = Gtk.Box(spacing=6) + lBox.add(label) + lBox.add(self.list.list) + box.add(lBox) + self.play = Gtk.Button("Play") + box.add(self.play) + self.show_all() - def populate_actions(self, actions): - for i in actions: - self.list.insert_item(i) + def populate_actions(self, actions): + for i in actions: + self.list.insert_item(i) - def get_selected(self): - return self.list.get_selected() \ No newline at end of file + def get_selected(self): + return self.list.get_selected() diff --git a/src/extra/SoundsTutorial/reverse_sort.py b/src/extra/SoundsTutorial/reverse_sort.py index 1094113e..27711174 100644 --- a/src/extra/SoundsTutorial/reverse_sort.py +++ b/src/extra/SoundsTutorial/reverse_sort.py @@ -1,4 +1,4 @@ -from __future__ import unicode_literals +from __future__ import unicode_literals #Reverse sort, by Bill Dengler for use in TWBlue http://twblue.es def invert_tuples(t): "Invert a list of tuples, so that the 0th element becomes the -1th, and the -1th becomes the 0th." @@ -9,4 +9,4 @@ def invert_tuples(t): def reverse_sort(t): "Sorts a list of tuples/lists by their last elements, not their first." - return invert_tuples(sorted(invert_tuples(t))) \ No newline at end of file + return invert_tuples(sorted(invert_tuples(t))) diff --git a/src/extra/SoundsTutorial/soundsTutorial.py b/src/extra/SoundsTutorial/soundsTutorial.py index 58b23590..4e679b1c 100644 --- a/src/extra/SoundsTutorial/soundsTutorial.py +++ b/src/extra/SoundsTutorial/soundsTutorial.py @@ -10,28 +10,28 @@ import logging log = logging.getLogger("extra.SoundsTutorial.soundsTutorial") from . import soundsTutorial_constants if platform.system() == "Windows": - from . import wx_ui as UI + from . import wx_ui as UI elif platform.system() == "Linux": - from . import gtk_ui as UI + from . import gtk_ui as UI class soundsTutorial(object): - def __init__(self, sessionObject): - log.debug("Creating sounds tutorial object...") - super(soundsTutorial, self).__init__() - self.session = sessionObject - self.actions = [] - log.debug("Loading actions for sounds tutorial...") - [self.actions.append(i[1]) for i in soundsTutorial_constants.actions] - self.files = [] - log.debug("Searching sound files...") - [self.files.append(i[0]) for i in soundsTutorial_constants.actions] - log.debug("Creating dialog...") - self.dialog = UI.soundsTutorialDialog(self.actions) - widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) - self.dialog.get_response() + def __init__(self, sessionObject): + log.debug("Creating sounds tutorial object...") + super(soundsTutorial, self).__init__() + self.session = sessionObject + self.actions = [] + log.debug("Loading actions for sounds tutorial...") + [self.actions.append(i[1]) for i in soundsTutorial_constants.actions] + self.files = [] + log.debug("Searching sound files...") + [self.files.append(i[0]) for i in soundsTutorial_constants.actions] + log.debug("Creating dialog...") + self.dialog = UI.soundsTutorialDialog(self.actions) + widgetUtils.connect_event(self.dialog.play, widgetUtils.BUTTON_PRESSED, self.on_play) + self.dialog.get_response() - def on_play(self, *args, **kwargs): - try: - self.session.sound.play(self.files[self.dialog.get_selection()]+".ogg") - except: - log.exception("Error playing the %s sound" % (self.files[self.dialog.items.GetSelection()],)) \ No newline at end of file + def on_play(self, *args, **kwargs): + try: + self.session.sound.play(self.files[self.dialog.get_selection()]+".ogg") + except: + log.exception("Error playing the %s sound" % (self.files[self.dialog.items.GetSelection()],)) diff --git a/src/extra/SoundsTutorial/soundsTutorial_constants.py b/src/extra/SoundsTutorial/soundsTutorial_constants.py index e28612dc..536add4d 100644 --- a/src/extra/SoundsTutorial/soundsTutorial_constants.py +++ b/src/extra/SoundsTutorial/soundsTutorial_constants.py @@ -5,27 +5,27 @@ from __future__ import unicode_literals from . import reverse_sort import application actions = reverse_sort.reverse_sort([ ("audio", _(u"Audio tweet.")), - ("create_timeline", _(u"User timeline buffer created.")), - ("delete_timeline", _(u"Buffer destroied.")), - ("dm_received", _(u"Direct message received.")), - ("dm_sent", _(u"Direct message sent.")), - ("error", _(u"Error.")), - ("favourite", _(u"Tweet liked.")), - ("favourites_timeline_updated", _(u"Likes buffer updated.")), - ("geo", _(u"Geotweet.")), -("image", _("Tweet contains one or more images")), -("limit", _(u"Boundary reached.")), - ("list_tweet", _(u"List updated.")), - ("max_length", _(u"Too many characters.")), - ("mention_received", _(u"Mention received.")), - ("new_event", _(u"New event.")), - ("ready", _(u"{0} is ready.").format(application.name,)), - ("reply_send", _(u"Mention sent.")), - ("retweet_send", _(u"Tweet retweeted.")), - ("search_updated", _(u"Search buffer updated.")), - ("tweet_received", _(u"Tweet received.")), - ("tweet_send", _(u"Tweet sent.")), - ("trends_updated", _(u"Trending topics buffer updated.")), - ("tweet_timeline", _(u"New tweet in user timeline buffer.")), - ("update_followers", _(u"New follower.")), - ("volume_changed", _(u"Volume changed."))]) + ("create_timeline", _(u"User timeline buffer created.")), + ("delete_timeline", _(u"Buffer destroied.")), + ("dm_received", _(u"Direct message received.")), + ("dm_sent", _(u"Direct message sent.")), + ("error", _(u"Error.")), + ("favourite", _(u"Tweet liked.")), + ("favourites_timeline_updated", _(u"Likes buffer updated.")), + ("geo", _(u"Geotweet.")), + ("image", _("Tweet contains one or more images")), + ("limit", _(u"Boundary reached.")), + ("list_tweet", _(u"List updated.")), + ("max_length", _(u"Too many characters.")), + ("mention_received", _(u"Mention received.")), + ("new_event", _(u"New event.")), + ("ready", _(u"{0} is ready.").format(application.name,)), + ("reply_send", _(u"Mention sent.")), + ("retweet_send", _(u"Tweet retweeted.")), + ("search_updated", _(u"Search buffer updated.")), + ("tweet_received", _(u"Tweet received.")), + ("tweet_send", _(u"Tweet sent.")), + ("trends_updated", _(u"Trending topics buffer updated.")), + ("tweet_timeline", _(u"New tweet in user timeline buffer.")), + ("update_followers", _(u"New follower.")), + ("volume_changed", _(u"Volume changed."))]) diff --git a/src/extra/SoundsTutorial/wx_ui.py b/src/extra/SoundsTutorial/wx_ui.py index ac2b0373..ebb6caf9 100644 --- a/src/extra/SoundsTutorial/wx_ui.py +++ b/src/extra/SoundsTutorial/wx_ui.py @@ -4,27 +4,27 @@ import wx import widgetUtils class soundsTutorialDialog(widgetUtils.BaseDialog): - def __init__(self, actions): - super(soundsTutorialDialog, self).__init__(None, -1) - self.SetTitle(_(u"Sounds tutorial")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(panel, -1, _(u"Press enter to listen to the sound for the selected event")) - self.items = wx.ListBox(panel, 1, choices=actions, style=wx.LB_SINGLE) - self.items.SetSelection(0) - listBox = wx.BoxSizer(wx.HORIZONTAL) - listBox.Add(label) - listBox.Add(self.items) - self.play = wx.Button(panel, 1, (u"Play")) - self.play.SetDefault() - close = wx.Button(panel, wx.ID_CANCEL) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(self.play) - btnBox.Add(close) - sizer.Add(listBox) - sizer.Add(btnBox) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self, actions): + super(soundsTutorialDialog, self).__init__(None, -1) + self.SetTitle(_(u"Sounds tutorial")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(panel, -1, _(u"Press enter to listen to the sound for the selected event")) + self.items = wx.ListBox(panel, 1, choices=actions, style=wx.LB_SINGLE) + self.items.SetSelection(0) + listBox = wx.BoxSizer(wx.HORIZONTAL) + listBox.Add(label) + listBox.Add(self.items) + self.play = wx.Button(panel, 1, (u"Play")) + self.play.SetDefault() + close = wx.Button(panel, wx.ID_CANCEL) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.play) + btnBox.Add(close) + sizer.Add(listBox) + sizer.Add(btnBox) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def get_selection(self): - return self.items.GetSelection() \ No newline at end of file + def get_selection(self): + return self.items.GetSelection() diff --git a/src/extra/SpellChecker/__init__.py b/src/extra/SpellChecker/__init__.py index f1eb69de..cf120537 100644 --- a/src/extra/SpellChecker/__init__.py +++ b/src/extra/SpellChecker/__init__.py @@ -3,4 +3,4 @@ from __future__ import unicode_literals from . import spellchecker import platform if platform.system() == "Windows": - from .wx_ui import * \ No newline at end of file + from .wx_ui import * diff --git a/src/extra/SpellChecker/spellchecker.py b/src/extra/SpellChecker/spellchecker.py index f8b1bec4..29bf2512 100644 --- a/src/extra/SpellChecker/spellchecker.py +++ b/src/extra/SpellChecker/spellchecker.py @@ -19,69 +19,69 @@ from enchant import tokenize log = logging.getLogger("extra.SpellChecker.spellChecker") class spellChecker(object): - def __init__(self, text, dictionary): - super(spellChecker, self).__init__() - # Set Dictionary path if not set in a previous call to this method. - # Dictionary path will be located in user config, see https://github.com/manuelcortez/twblue/issues/208 + def __init__(self, text, dictionary): + super(spellChecker, self).__init__() + # Set Dictionary path if not set in a previous call to this method. + # Dictionary path will be located in user config, see https://github.com/manuelcortez/twblue/issues/208 # dict_path = enchant.get_param("enchant.myspell.dictionary.path") # if dict_path == None: # enchant.set_param("enchant.myspell.dictionary.path", os.path.join(paths.config_path(), "dicts")) # log.debug("Dictionary path set to %s" % (os.path.join(paths.config_path(), "dicts"),)) - log.debug("Creating the SpellChecker object. Dictionary: %s" % (dictionary,)) - self.active = True - try: - if config.app["app-settings"]["language"] == "system": - log.debug("Using the system language") - self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict")) - else: - log.debug("Using language: %s" % (languageHandler.getLanguage(),)) - self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict")) - except DictNotFoundError: - log.exception("Dictionary for language %s not found." % (dictionary,)) - wx_ui.dict_not_found_error() - self.active = False - self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter]) - self.checker.set_text(text) - if self.active == True: - log.debug("Creating dialog...") - self.dialog = wx_ui.spellCheckerDialog() - widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore) - widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll) - widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace) - widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll) - widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add) - self.check() - self.dialog.get_response() - self.fixed_text = self.checker.get_text() + log.debug("Creating the SpellChecker object. Dictionary: %s" % (dictionary,)) + self.active = True + try: + if config.app["app-settings"]["language"] == "system": + log.debug("Using the system language") + self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict")) + else: + log.debug("Using language: %s" % (languageHandler.getLanguage(),)) + self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict")) + except DictNotFoundError: + log.exception("Dictionary for language %s not found." % (dictionary,)) + wx_ui.dict_not_found_error() + self.active = False + self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter]) + self.checker.set_text(text) + if self.active == True: + log.debug("Creating dialog...") + self.dialog = wx_ui.spellCheckerDialog() + widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore) + widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll) + widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace) + widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll) + widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add) + self.check() + self.dialog.get_response() + self.fixed_text = self.checker.get_text() - def check(self): - try: - next(self.checker) - textToSay = _(u"Misspelled word: %s") % (self.checker.word,) - context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10)) - self.dialog.set_title(textToSay) - output.speak(textToSay) - self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest()) - except StopIteration: - log.debug("Process finished.") - wx_ui.finished() - self.dialog.Destroy() + def check(self): + try: + next(self.checker) + textToSay = _(u"Misspelled word: %s") % (self.checker.word,) + context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10)) + self.dialog.set_title(textToSay) + output.speak(textToSay) + self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest()) + except StopIteration: + log.debug("Process finished.") + wx_ui.finished() + self.dialog.Destroy() - def ignore(self, ev): - self.check() + def ignore(self, ev): + self.check() - def ignoreAll(self, ev): - self.checker.ignore_always(word=self.checker.word) - self.check() + def ignoreAll(self, ev): + self.checker.ignore_always(word=self.checker.word) + self.check() - def replace(self, ev): - self.checker.replace(self.dialog.get_selected_suggestion()) - self.check() + def replace(self, ev): + self.checker.replace(self.dialog.get_selected_suggestion()) + self.check() - def replaceAll(self, ev): - self.checker.replace_always(self.dialog.get_selected_suggestion()) - self.check() + def replaceAll(self, ev): + self.checker.replace_always(self.dialog.get_selected_suggestion()) + self.check() - def add(self, ev): - self.checker.add() - self.check() + def add(self, ev): + self.checker.add() + self.check() diff --git a/src/extra/SpellChecker/wx_ui.py b/src/extra/SpellChecker/wx_ui.py index 3a13e9f1..9c7159fd 100644 --- a/src/extra/SpellChecker/wx_ui.py +++ b/src/extra/SpellChecker/wx_ui.py @@ -21,63 +21,63 @@ import wx import application class spellCheckerDialog(wx.Dialog): - def __init__(self): - super(spellCheckerDialog, self).__init__(None, 1) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - word = wx.StaticText(panel, -1, _(u"Misspelled word")) - self.word = wx.TextCtrl(panel, -1) - wordBox = wx.BoxSizer(wx.HORIZONTAL) - wordBox.Add(word, 0, wx.ALL, 5) - wordBox.Add(self.word, 0, wx.ALL, 5) - context = wx.StaticText(panel, -1, _(u"Context")) - self.context = wx.TextCtrl(panel, -1) - contextBox = wx.BoxSizer(wx.HORIZONTAL) - contextBox.Add(context, 0, wx.ALL, 5) - contextBox.Add(self.context, 0, wx.ALL, 5) - suggest = wx.StaticText(panel, -1, _(u"Suggestions")) - self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE) - suggestionsBox = wx.BoxSizer(wx.HORIZONTAL) - suggestionsBox.Add(suggest, 0, wx.ALL, 5) - suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5) - self.ignore = wx.Button(panel, -1, _(u"&Ignore")) - self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all")) - self.replace = wx.Button(panel, -1, _(u"&Replace")) - self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all")) - self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary")) - close = wx.Button(panel, wx.ID_CANCEL) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(self.ignore, 0, wx.ALL, 5) - btnBox.Add(self.ignoreAll, 0, wx.ALL, 5) - btnBox.Add(self.replace, 0, wx.ALL, 5) - btnBox.Add(self.replaceAll, 0, wx.ALL, 5) - btnBox.Add(self.add, 0, wx.ALL, 5) - btnBox.Add(close, 0, wx.ALL, 5) - sizer.Add(wordBox, 0, wx.ALL, 5) - sizer.Add(contextBox, 0, wx.ALL, 5) - sizer.Add(suggestionsBox, 0, wx.ALL, 5) - sizer.Add(btnBox, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(spellCheckerDialog, self).__init__(None, 1) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + word = wx.StaticText(panel, -1, _(u"Misspelled word")) + self.word = wx.TextCtrl(panel, -1) + wordBox = wx.BoxSizer(wx.HORIZONTAL) + wordBox.Add(word, 0, wx.ALL, 5) + wordBox.Add(self.word, 0, wx.ALL, 5) + context = wx.StaticText(panel, -1, _(u"Context")) + self.context = wx.TextCtrl(panel, -1) + contextBox = wx.BoxSizer(wx.HORIZONTAL) + contextBox.Add(context, 0, wx.ALL, 5) + contextBox.Add(self.context, 0, wx.ALL, 5) + suggest = wx.StaticText(panel, -1, _(u"Suggestions")) + self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE) + suggestionsBox = wx.BoxSizer(wx.HORIZONTAL) + suggestionsBox.Add(suggest, 0, wx.ALL, 5) + suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5) + self.ignore = wx.Button(panel, -1, _(u"&Ignore")) + self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all")) + self.replace = wx.Button(panel, -1, _(u"&Replace")) + self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all")) + self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary")) + close = wx.Button(panel, wx.ID_CANCEL) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.ignore, 0, wx.ALL, 5) + btnBox.Add(self.ignoreAll, 0, wx.ALL, 5) + btnBox.Add(self.replace, 0, wx.ALL, 5) + btnBox.Add(self.replaceAll, 0, wx.ALL, 5) + btnBox.Add(self.add, 0, wx.ALL, 5) + btnBox.Add(close, 0, wx.ALL, 5) + sizer.Add(wordBox, 0, wx.ALL, 5) + sizer.Add(contextBox, 0, wx.ALL, 5) + sizer.Add(suggestionsBox, 0, wx.ALL, 5) + sizer.Add(btnBox, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def set_title(self, title): - return self.SetTitle(title) + def set_title(self, title): + return self.SetTitle(title) - def set_word_and_suggestions(self, word, context, suggestions): - self.word.SetValue(word) - self.context.ChangeValue(context) - self.suggestions.Set(suggestions) - self.suggestions.SetFocus() + def set_word_and_suggestions(self, word, context, suggestions): + self.word.SetValue(word) + self.context.ChangeValue(context) + self.suggestions.Set(suggestions) + self.suggestions.SetFocus() - def get_selected_suggestion(self): - return self.suggestions.GetStringSelection() + def get_selected_suggestion(self): + return self.suggestions.GetStringSelection() def dict_not_found_error(): - wx.MessageDialog(None, _(u"An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _(u"Error"), wx.ICON_ERROR).ShowModal() + wx.MessageDialog(None, _(u"An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _(u"Error"), wx.ICON_ERROR).ShowModal() def finished(): - wx.MessageDialog(None, _(u"Spell check complete."), application.name, style=wx.OK).ShowModal() + wx.MessageDialog(None, _(u"Spell check complete."), application.name, style=wx.OK).ShowModal() diff --git a/src/extra/autocompletionUsers/__init__.py b/src/extra/autocompletionUsers/__init__.py index cceb68cc..7a307a5e 100644 --- a/src/extra/autocompletionUsers/__init__.py +++ b/src/extra/autocompletionUsers/__init__.py @@ -2,4 +2,4 @@ from __future__ import absolute_import from __future__ import unicode_literals # -*- coding: utf-8 -*- -from . import completion, settings \ No newline at end of file +from . import completion, settings diff --git a/src/extra/autocompletionUsers/completion.py b/src/extra/autocompletionUsers/completion.py index 562788cb..9fa8c8ec 100644 --- a/src/extra/autocompletionUsers/completion.py +++ b/src/extra/autocompletionUsers/completion.py @@ -1,50 +1,47 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -from builtins import object import output from . import storage from . import wx_menu class autocompletionUsers(object): - def __init__(self, window, session_id): - super(autocompletionUsers, self).__init__() - self.window = window - self.db = storage.storage(session_id) + def __init__(self, window, session_id): + super(autocompletionUsers, self).__init__() + self.window = window + self.db = storage.storage(session_id) - def show_menu(self, mode="tweet"): - position = self.window.get_position() - if mode == "tweet": - text = self.window.get_text() - text = text[:position] - try: - pattern = text.split()[-1] - except IndexError: - output.speak(_(u"You have to start writing")) - return - if pattern.startswith("@") == True: - menu = wx_menu.menu(self.window.text, pattern[1:], mode=mode) - users = self.db.get_users(pattern[1:]) - if len(users) > 0: - menu.append_options(users) - self.window.popup_menu(menu) - menu.destroy() - else: - output.speak(_(u"There are no results in your users database")) - else: - output.speak(_(u"Autocompletion only works for users.")) - elif mode == "dm": - text = self.window.get_user() - try: - pattern = text.split()[-1] - except IndexError: - output.speak(_(u"You have to start writing")) - return - menu = wx_menu.menu(self.window.cb, pattern, mode=mode) - users = self.db.get_users(pattern) - if len(users) > 0: - menu.append_options(users) - self.window.popup_menu(menu) - menu.destroy() - else: - output.speak(_(u"There are no results in your users database")) \ No newline at end of file + def show_menu(self, mode="tweet"): + position = self.window.text.GetInsertionPoint() + if mode == "tweet": + text = self.window.text.GetValue() + text = text[:position] + try: + pattern = text.split()[-1] + except IndexError: + output.speak(_(u"You have to start writing")) + return + if pattern.startswith("@") == True: + menu = wx_menu.menu(self.window.text, pattern[1:], mode=mode) + users = self.db.get_users(pattern[1:]) + if len(users) > 0: + menu.append_options(users) + self.window.PopupMenu(menu, self.window.text.GetPosition()) + menu.destroy() + else: + output.speak(_(u"There are no results in your users database")) + else: + output.speak(_(u"Autocompletion only works for users.")) + elif mode == "dm": + text = self.window.cb.GetValue() + try: + pattern = text.split()[-1] + except IndexError: + output.speak(_(u"You have to start writing")) + return + menu = wx_menu.menu(self.window.cb, pattern, mode=mode) + users = self.db.get_users(pattern) + if len(users) > 0: + menu.append_options(users) + self.window.PopupMenu(menu, self.window.text.GetPosition()) + menu.destroy() + else: + output.speak(_(u"There are no results in your users database")) diff --git a/src/extra/autocompletionUsers/manage.py b/src/extra/autocompletionUsers/manage.py index ba3a224c..a1acd603 100644 --- a/src/extra/autocompletionUsers/manage.py +++ b/src/extra/autocompletionUsers/manage.py @@ -1,47 +1,44 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -# -*- coding: utf-8 -*- -from builtins import object -from . import storage import widgetUtils -from . import wx_manage +from tweepy.errors import TweepyException +from . import storage, wx_manage from wxUI import commonMessageDialogs class autocompletionManage(object): - def __init__(self, session): - super(autocompletionManage, self).__init__() - self.session = session - self.dialog = wx_manage.autocompletionManageDialog() - self.database = storage.storage(self.session.session_id) - self.users = self.database.get_all_users() - self.dialog.put_users(self.users) - widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add_user) - widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_user) - self.dialog.get_response() + def __init__(self, session): + super(autocompletionManage, self).__init__() + self.session = session + self.dialog = wx_manage.autocompletionManageDialog() + self.database = storage.storage(self.session.session_id) + self.users = self.database.get_all_users() + self.dialog.put_users(self.users) + widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add_user) + widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_user) + self.dialog.get_response() - def update_list(self): - item = self.dialog.users.get_selected() - self.dialog.users.clear() - self.users = self.database.get_all_users() - self.dialog.put_users(self.users) - self.dialog.users.select_item(item) + def update_list(self): + item = self.dialog.users.get_selected() + self.dialog.users.clear() + self.users = self.database.get_all_users() + self.dialog.put_users(self.users) + self.dialog.users.select_item(item) - def add_user(self, *args, **kwargs): - usr = self.dialog.get_user() - if usr == False: - return - try: - data = self.session.twitter.twitter.show_user(screen_name=usr) - except: - self.dialog.show_invalid_user_error() - return - self.database.set_user(data["screen_name"], data["name"], 0) - self.update_list() + def add_user(self, *args, **kwargs): + usr = self.dialog.get_user() + if usr == False: + return + try: + data = self.session.twitter.get_user(screen_name=usr) + except TweepyException as e: + log.exception("Exception raised when attempting to add an user to the autocomplete database manually.") + self.dialog.show_invalid_user_error() + return + self.database.set_user(data.screen_name, data.name, 0) + self.update_list() - def remove_user(self, ev): - if commonMessageDialogs.delete_user_from_db() == widgetUtils.YES: - item = self.dialog.users.get_selected() - user = self.users[item] - self.database.remove_user(user[0]) - self.update_list() \ No newline at end of file + def remove_user(self, ev): + if commonMessageDialogs.delete_user_from_db() == widgetUtils.YES: + item = self.dialog.users.get_selected() + user = self.users[item] + self.database.remove_user(user[0]) + self.update_list() diff --git a/src/extra/autocompletionUsers/settings.py b/src/extra/autocompletionUsers/settings.py index d14ba62b..d875fb0d 100644 --- a/src/extra/autocompletionUsers/settings.py +++ b/src/extra/autocompletionUsers/settings.py @@ -1,63 +1,59 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -# -*- coding: utf-8 -*- -from builtins import object -from . import storage import widgetUtils +import output from . import wx_settings from . import manage -import output +from . import storage from mysc.thread_utils import call_threaded class autocompletionSettings(object): - def __init__(self, config, buffer, window): - super(autocompletionSettings, self).__init__() - self.config = config - self.buffer = buffer - self.window = window - self.dialog = wx_settings.autocompletionSettingsDialog() - self.dialog.set("friends_buffer", self.config["mysc"]["save_friends_in_autocompletion_db"]) - self.dialog.set("followers_buffer", self.config["mysc"]["save_followers_in_autocompletion_db"]) - widgetUtils.connect_event(self.dialog.viewList, widgetUtils.BUTTON_PRESSED, self.view_list) - if self.dialog.get_response() == widgetUtils.OK: - call_threaded(self.add_users_to_database) + def __init__(self, config, buffer, window): + super(autocompletionSettings, self).__init__() + self.config = config + self.buffer = buffer + self.window = window + self.dialog = wx_settings.autocompletionSettingsDialog() + self.dialog.set("friends_buffer", self.config["mysc"]["save_friends_in_autocompletion_db"]) + self.dialog.set("followers_buffer", self.config["mysc"]["save_followers_in_autocompletion_db"]) + widgetUtils.connect_event(self.dialog.viewList, widgetUtils.BUTTON_PRESSED, self.view_list) + if self.dialog.get_response() == widgetUtils.OK: + call_threaded(self.add_users_to_database) - def add_users_to_database(self): - self.config["mysc"]["save_friends_in_autocompletion_db"] = self.dialog.get("friends_buffer") - self.config["mysc"]["save_followers_in_autocompletion_db"] = self.dialog.get("followers_buffer") - output.speak(_(u"Updating database... You can close this window now. A message will tell you when the process finishes.")) - database = storage.storage(self.buffer.session.session_id) - if self.dialog.get("followers_buffer") == True: - buffer = self.window.search_buffer("followers", self.config["twitter"]["user_name"]) - for i in buffer.session.db[buffer.name]["items"]: - database.set_user(i["screen_name"], i["name"], 1) - else: - database.remove_by_buffer(1) - if self.dialog.get("friends_buffer") == True: - buffer = self.window.search_buffer("friends", self.config["twitter"]["user_name"]) - for i in buffer.session.db[buffer.name]["items"]: - database.set_user(i["screen_name"], i["name"], 2) - else: - database.remove_by_buffer(2) - wx_settings.show_success_dialog() - self.dialog.destroy() - - def view_list(self, ev): - q = manage.autocompletionManage(self.buffer.session) + def add_users_to_database(self): + self.config["mysc"]["save_friends_in_autocompletion_db"] = self.dialog.get("friends_buffer") + self.config["mysc"]["save_followers_in_autocompletion_db"] = self.dialog.get("followers_buffer") + output.speak(_(u"Updating database... You can close this window now. A message will tell you when the process finishes.")) + database = storage.storage(self.buffer.session.session_id) + if self.dialog.get("followers_buffer") == True: + buffer = self.window.search_buffer("followers", self.config["twitter"]["user_name"]) + for i in buffer.session.db[buffer.name]: + database.set_user(i.screen_name, i.name, 1) + else: + database.remove_by_buffer(1) + if self.dialog.get("friends_buffer") == True: + buffer = self.window.search_buffer("friends", self.config["twitter"]["user_name"]) + for i in buffer.session.db[buffer.name]: + database.set_user(i.screen_name, i.name, 2) + else: + database.remove_by_buffer(2) + wx_settings.show_success_dialog() + self.dialog.destroy() + + def view_list(self, ev): + q = manage.autocompletionManage(self.buffer.session) def execute_at_startup(window, buffer, config): - database = storage.storage(buffer.session.session_id) - if config["mysc"]["save_followers_in_autocompletion_db"] == True and config["other_buffers"]["show_followers"] == True: - buffer = window.search_buffer("followers", config["twitter"]["user_name"]) - for i in buffer.session.db[buffer.name]: - database.set_user(i["screen_name"], i["name"], 1) - else: - database.remove_by_buffer(1) - if config["mysc"]["save_friends_in_autocompletion_db"] == True and config["other_buffers"]["show_friends"] == True: - buffer = window.search_buffer("friends", config["twitter"]["user_name"]) - for i in buffer.session.db[buffer.name]: - database.set_user(i["screen_name"], i["name"], 2) - else: - database.remove_by_buffer(2) \ No newline at end of file + database = storage.storage(buffer.session.session_id) + if config["mysc"]["save_followers_in_autocompletion_db"] == True and config["other_buffers"]["show_followers"] == True: + buffer = window.search_buffer("followers", config["twitter"]["user_name"]) + for i in buffer.session.db[buffer.name]: + database.set_user(i.screen_name, i.name, 1) + else: + database.remove_by_buffer(1) + if config["mysc"]["save_friends_in_autocompletion_db"] == True and config["other_buffers"]["show_friends"] == True: + buffer = window.search_buffer("friends", config["twitter"]["user_name"]) + for i in buffer.session.db[buffer.name]: + database.set_user(i.screen_name, i.name, 2) + else: + database.remove_by_buffer(2) diff --git a/src/extra/autocompletionUsers/storage.py b/src/extra/autocompletionUsers/storage.py index 9a34ef68..4ac80ebf 100644 --- a/src/extra/autocompletionUsers/storage.py +++ b/src/extra/autocompletionUsers/storage.py @@ -1,54 +1,52 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import object import os, sqlite3, paths class storage(object): - def __init__(self, session_id): - self.connection = sqlite3.connect(os.path.join(paths.config_path(), "%s/autocompletionUsers.dat" % (session_id))) - self.cursor = self.connection.cursor() - if self.table_exist("users") == False: - self.create_table() + def __init__(self, session_id): + self.connection = sqlite3.connect(os.path.join(paths.config_path(), "%s/autocompletionUsers.dat" % (session_id))) + self.cursor = self.connection.cursor() + if self.table_exist("users") == False: + self.create_table() - def table_exist(self, table): - ask = self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % (table)) - answer = ask.fetchone() - if answer == None: - return False - else: - return True + def table_exist(self, table): + ask = self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'" % (table)) + answer = ask.fetchone() + if answer == None: + return False + else: + return True - def get_all_users(self): - self.cursor.execute("""select * from users""") - return self.cursor.fetchall() + def get_all_users(self): + self.cursor.execute("""select * from users""") + return self.cursor.fetchall() - def get_users(self, term): - self.cursor.execute("""SELECT * FROM users WHERE user LIKE ?""", ('{}%'.format(term),)) - return self.cursor.fetchall() + def get_users(self, 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): - self.cursor.execute("""insert or ignore into users values(?, ?, ?)""", (screen_name, user_name, from_a_buffer)) - self.connection.commit() + def set_user(self, screen_name, user_name, from_a_buffer): + self.cursor.execute("""insert or ignore into users values(?, ?, ?)""", (screen_name, user_name, from_a_buffer)) + self.connection.commit() - def remove_user(self, user): - self.cursor.execute("""DELETE FROM users WHERE user = ?""", (user,)) - self.connection.commit() - return self.cursor.fetchone() + def remove_user(self, user): + self.cursor.execute("""DELETE FROM users WHERE user = ?""", (user,)) + self.connection.commit() + return self.cursor.fetchone() - def remove_by_buffer(self, bufferType): - """ Removes all users saved on a buffer. BufferType is 0 for no buffer, 1 for friends and 2 for followers""" - self.cursor.execute("""DELETE FROM users WHERE from_a_buffer = ?""", (bufferType,)) - self.connection.commit() - return self.cursor.fetchone() + def remove_by_buffer(self, bufferType): + """ Removes all users saved on a buffer. BufferType is 0 for no buffer, 1 for friends and 2 for followers""" + self.cursor.execute("""DELETE FROM users WHERE from_a_buffer = ?""", (bufferType,)) + self.connection.commit() + return self.cursor.fetchone() - def create_table(self): - self.cursor.execute(""" + def create_table(self): + self.cursor.execute(""" create table users( user TEXT UNIQUE, name TEXT, from_a_buffer INTEGER )""") - def __del__(self): - self.cursor.close() - self.connection.close() \ No newline at end of file + def __del__(self): + self.cursor.close() + self.connection.close() diff --git a/src/extra/autocompletionUsers/wx_manage.py b/src/extra/autocompletionUsers/wx_manage.py index dad0d0dd..6f34a681 100644 --- a/src/extra/autocompletionUsers/wx_manage.py +++ b/src/extra/autocompletionUsers/wx_manage.py @@ -1,44 +1,44 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals import wx import widgetUtils from multiplatform_widgets import widgets import application + class autocompletionManageDialog(widgetUtils.BaseDialog): - def __init__(self): - super(autocompletionManageDialog, self).__init__(parent=None, id=-1, title=_(u"Manage Autocompletion database")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(panel, -1, _(u"Editing {0} users database").format(application.name,)) - self.users = widgets.list(panel, _(u"Username"), _(u"Name"), style=wx.LC_REPORT) - sizer.Add(label, 0, wx.ALL, 5) - sizer.Add(self.users.list, 0, wx.ALL, 5) - self.add = wx.Button(panel, -1, _(u"Add user")) - self.remove = wx.Button(panel, -1, _(u"Remove user")) - optionsBox = wx.BoxSizer(wx.HORIZONTAL) - optionsBox.Add(self.add, 0, wx.ALL, 5) - optionsBox.Add(self.remove, 0, wx.ALL, 5) - sizer.Add(optionsBox, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK) - cancel = wx.Button(panel, wx.ID_CANCEL) - sizerBtn = wx.BoxSizer(wx.HORIZONTAL) - sizerBtn.Add(ok, 0, wx.ALL, 5) - sizer.Add(cancel, 0, wx.ALL, 5) - sizer.Add(sizerBtn, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(autocompletionManageDialog, self).__init__(parent=None, id=-1, title=_(u"Manage Autocompletion database")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(panel, -1, _(u"Editing {0} users database").format(application.name,)) + self.users = widgets.list(panel, _(u"Username"), _(u"Name"), style=wx.LC_REPORT) + sizer.Add(label, 0, wx.ALL, 5) + sizer.Add(self.users.list, 0, wx.ALL, 5) + self.add = wx.Button(panel, -1, _(u"Add user")) + self.remove = wx.Button(panel, -1, _(u"Remove user")) + optionsBox = wx.BoxSizer(wx.HORIZONTAL) + optionsBox.Add(self.add, 0, wx.ALL, 5) + optionsBox.Add(self.remove, 0, wx.ALL, 5) + sizer.Add(optionsBox, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK) + cancel = wx.Button(panel, wx.ID_CANCEL) + sizerBtn = wx.BoxSizer(wx.HORIZONTAL) + sizerBtn.Add(ok, 0, wx.ALL, 5) + sizer.Add(cancel, 0, wx.ALL, 5) + sizer.Add(sizerBtn, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def put_users(self, users): - for i in users: - j = [i[0], i[1]] - self.users.insert_item(False, *j) + def put_users(self, users): + for i in users: + j = [i[0], i[1]] + self.users.insert_item(False, *j) - def get_user(self): - usr = False - userDlg = wx.TextEntryDialog(None, _(u"Twitter username"), _(u"Add user to database")) - if userDlg.ShowModal() == wx.ID_OK: - usr = userDlg.GetValue() - return usr + def get_user(self): + usr = False + userDlg = wx.TextEntryDialog(None, _(u"Twitter username"), _(u"Add user to database")) + if userDlg.ShowModal() == wx.ID_OK: + usr = userDlg.GetValue() + return usr - def show_invalid_user_error(self): - wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error!"), wx.ICON_ERROR).ShowModal() \ No newline at end of file + def show_invalid_user_error(self): + wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error!"), wx.ICON_ERROR).ShowModal() diff --git a/src/extra/autocompletionUsers/wx_menu.py b/src/extra/autocompletionUsers/wx_menu.py index bf94e7f0..065ff2a1 100644 --- a/src/extra/autocompletionUsers/wx_menu.py +++ b/src/extra/autocompletionUsers/wx_menu.py @@ -1,26 +1,25 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals import wx class menu(wx.Menu): - def __init__(self, window, pattern, mode): - super(menu, self).__init__() - self.window = window - self.pattern = pattern - self.mode = mode + def __init__(self, window, pattern, mode): + super(menu, self).__init__() + self.window = window + self.pattern = pattern + self.mode = mode - def append_options(self, options): - for i in options: - item = wx.MenuItem(self, wx.ID_ANY, "%s (@%s)" % (i[1], i[0])) - self.AppendItem(item) - self.Bind(wx.EVT_MENU, lambda evt, temp=i[0]: self.select_text(evt, temp), item) + def append_options(self, options): + for i in options: + item = wx.MenuItem(self, wx.ID_ANY, "%s (@%s)" % (i[1], i[0])) + self.AppendItem(item) + self.Bind(wx.EVT_MENU, lambda evt, temp=i[0]: self.select_text(evt, temp), item) - def select_text(self, ev, text): - if self.mode == "tweet": - self.window.ChangeValue(self.window.GetValue().replace("@"+self.pattern, "@"+text+" ")) - elif self.mode == "dm": - self.window.SetValue(self.window.GetValue().replace(self.pattern, text)) - self.window.SetInsertionPointEnd() + def select_text(self, ev, text): + if self.mode == "tweet": + self.window.ChangeValue(self.window.GetValue().replace("@"+self.pattern, "@"+text+" ")) + elif self.mode == "dm": + self.window.SetValue(self.window.GetValue().replace(self.pattern, text)) + self.window.SetInsertionPointEnd() - def destroy(self): - self.Destroy() \ No newline at end of file + def destroy(self): + self.Destroy() diff --git a/src/extra/autocompletionUsers/wx_settings.py b/src/extra/autocompletionUsers/wx_settings.py index e5520d4f..3d635935 100644 --- a/src/extra/autocompletionUsers/wx_settings.py +++ b/src/extra/autocompletionUsers/wx_settings.py @@ -1,28 +1,27 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals import wx import widgetUtils import application class autocompletionSettingsDialog(widgetUtils.BaseDialog): - def __init__(self): - super(autocompletionSettingsDialog, self).__init__(parent=None, id=-1, title=_(u"Autocomplete users' settings")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.followers_buffer = wx.CheckBox(panel, -1, _(u"Add users from followers buffer")) - self.friends_buffer = wx.CheckBox(panel, -1, _(u"Add users from friends buffer")) - sizer.Add(self.followers_buffer, 0, wx.ALL, 5) - sizer.Add(self.friends_buffer, 0, wx.ALL, 5) - self.viewList = wx.Button(panel, -1, _(u"Manage database...")) - sizer.Add(self.viewList, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK) - cancel = wx.Button(panel, wx.ID_CANCEL) - sizerBtn = wx.BoxSizer(wx.HORIZONTAL) - sizerBtn.Add(ok, 0, wx.ALL, 5) - sizer.Add(cancel, 0, wx.ALL, 5) - sizer.Add(sizerBtn, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(autocompletionSettingsDialog, self).__init__(parent=None, id=-1, title=_(u"Autocomplete users' settings")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.followers_buffer = wx.CheckBox(panel, -1, _(u"Add users from followers buffer")) + self.friends_buffer = wx.CheckBox(panel, -1, _(u"Add users from friends buffer")) + sizer.Add(self.followers_buffer, 0, wx.ALL, 5) + sizer.Add(self.friends_buffer, 0, wx.ALL, 5) + self.viewList = wx.Button(panel, -1, _(u"Manage database...")) + sizer.Add(self.viewList, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK) + cancel = wx.Button(panel, wx.ID_CANCEL) + sizerBtn = wx.BoxSizer(wx.HORIZONTAL) + sizerBtn.Add(ok, 0, wx.ALL, 5) + sizer.Add(cancel, 0, wx.ALL, 5) + sizer.Add(sizerBtn, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) def show_success_dialog(): - wx.MessageDialog(None, _(u"{0}'s database of users has been updated.").format(application.name,), _(u"Done"), wx.OK).ShowModal() \ No newline at end of file + wx.MessageDialog(None, _(u"{0}'s database of users has been updated.").format(application.name,), _(u"Done"), wx.OK).ShowModal() diff --git a/src/extra/ocr/OCRSpace.py b/src/extra/ocr/OCRSpace.py index ec7e21a1..cee5e7c3 100644 --- a/src/extra/ocr/OCRSpace.py +++ b/src/extra/ocr/OCRSpace.py @@ -9,37 +9,37 @@ short_langs = ["", "da", "du", "en", "fi", "fr", "de", "hu", "ko", "it", "ja", " OcrLangs = ["", "dan", "dut", "eng", "fin", "fre", "ger", "hun", "kor", "ita", "jpn", "pol", "por", "rus", "spa", "tur"] class APIError(Exception): - pass + pass class OCRSpaceAPI(object): - def __init__(self, key="4e72ae996f88957", url='https://api.ocr.space/parse/image'): - self.key = key - self.url = url + def __init__(self, key="4e72ae996f88957", url='https://api.ocr.space/parse/image'): + self.key = key + self.url = url - def OCR_URL(self, url, overlay=False, lang=None): - payload = { - 'url': url, - 'isOverlayRequired': overlay, - 'apikey': self.key, - } - if lang != None: - payload.update(language=lang) - r = requests.post(self.url, data=payload) - result = r.json()['ParsedResults'][0] - if result['ErrorMessage']: - raise APIError(result['ErrorMessage']) - return result + def OCR_URL(self, url, overlay=False, lang=None): + payload = { + 'url': url, + 'isOverlayRequired': overlay, + 'apikey': self.key, + } + if lang != None: + payload.update(language=lang) + r = requests.post(self.url, data=payload) + result = r.json()['ParsedResults'][0] + if result['ErrorMessage']: + raise APIError(result['ErrorMessage']) + return result - def OCR_file(self, fileobj, overlay=False): - payload = { - 'isOverlayRequired': overlay, - 'apikey': self.key, - 'lang': 'es', - } - r = requests.post(self.url, data=payload, files={'file': fileobj}) - results = r.json()['ParsedResults'] - if results[0]['ErrorMessage']: - raise APIError(results[0]['ErrorMessage']) - return results + def OCR_file(self, fileobj, overlay=False): + payload = { + 'isOverlayRequired': overlay, + 'apikey': self.key, + 'lang': 'es', + } + r = requests.post(self.url, data=payload, files={'file': fileobj}) + results = r.json()['ParsedResults'] + if results[0]['ErrorMessage']: + raise APIError(results[0]['ErrorMessage']) + return results diff --git a/src/extra/ocr/__init__.py b/src/extra/ocr/__init__.py index 48e76b1a..5617235f 100644 --- a/src/extra/ocr/__init__.py +++ b/src/extra/ocr/__init__.py @@ -2,4 +2,4 @@ from __future__ import absolute_import from __future__ import unicode_literals # -*- coding: utf-8 -*- -from . import OCRSpace \ No newline at end of file +from . import OCRSpace diff --git a/src/extra/translator/__init__.py b/src/extra/translator/__init__.py index 4b1845ea..07b41a1e 100644 --- a/src/extra/translator/__init__.py +++ b/src/extra/translator/__init__.py @@ -4,5 +4,5 @@ from __future__ import unicode_literals from . import translator import platform if platform.system() == "Windows": - from . import wx_ui as gui - \ No newline at end of file + from . import wx_ui as gui + diff --git a/src/extra/translator/translator.py b/src/extra/translator/translator.py index f390fbf2..d9bc99dc 100644 --- a/src/extra/translator/translator.py +++ b/src/extra/translator/translator.py @@ -1,115 +1,116 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import zip -from yandex_translate import YandexTranslate +import logging +from googletrans import Translator, LANGUAGES + +log = logging.getLogger("extras.translator") + +# create a single translator instance +# see https://github.com/ssut/py-googletrans/issues/234 +t = None def translate(text="", target="en"): - t = YandexTranslate("trnsl.1.1.20161012T134532Z.d01b9c75fc39aa74.7d1be75a5166a80583eeb020e10f584168da6bf7") - vars = dict(text=text, lang=target) - return t.translate(**vars)["text"][0] + global t + log.debug("Received translation request for language %s, text=%s" % (target, text)) + if t == None: + t = Translator() + vars = dict(text=text, dest=target) + return t.translate(**vars).text supported_langs = None -d = None + languages = { - "af": _(u"Afrikaans"), - "sq": _(u"Albanian"), - "am": _(u"Amharic"), - "ar": _(u"Arabic"), - "hy": _(u"Armenian"), - "az": _(u"Azerbaijani"), - "eu": _(u"Basque"), - "be": _(u"Belarusian"), - "bn": _(u"Bengali"), - "bh": _(u"Bihari"), - "bg": _(u"Bulgarian"), - "my": _(u"Burmese"), - "ca": _(u"Catalan"), - "chr": _(u"Cherokee"), - "zh": _(u"Chinese"), - "zh-CN": _(u"Chinese_simplified"), - "zh-TW": _(u"Chinese_traditional"), - "hr": _(u"Croatian"), - "cs": _(u"Czech"), - "da": _(u"Danish"), - "dv": _(u"Dhivehi"), - "nl": _(u"Dutch"), - "en": _(u"English"), - "eo": _(u"Esperanto"), - "et": _(u"Estonian"), - "tl": _(u"Filipino"), - "fi": _(u"Finnish"), - "fr": _(u"French"), - "gl": _(u"Galician"), - "ka": _(u"Georgian"), - "de": _(u"German"), - "el": _(u"Greek"), - "gn": _(u"Guarani"), - "gu": _(u"Gujarati"), - "iw": _(u"Hebrew"), - "hi": _(u"Hindi"), - "hu": _(u"Hungarian"), - "is": _(u"Icelandic"), - "id": _(u"Indonesian"), - "iu": _(u"Inuktitut"), - "ga": _(u"Irish"), - "it": _(u"Italian"), - "ja": _(u"Japanese"), - "kn": _(u"Kannada"), - "kk": _(u"Kazakh"), - "km": _(u"Khmer"), - "ko": _(u"Korean"), - "ku": _(u"Kurdish"), - "ky": _(u"Kyrgyz"), - "lo": _(u"Laothian"), - "lv": _(u"Latvian"), - "lt": _(u"Lithuanian"), - "mk": _(u"Macedonian"), - "ms": _(u"Malay"), - "ml": _(u"Malayalam"), - "mt": _(u"Maltese"), - "mr": _(u"Marathi"), - "mn": _(u"Mongolian"), - "ne": _(u"Nepali"), - "no": _(u"Norwegian"), - "or": _(u"Oriya"), - "ps": _(u"Pashto"), - "fa": _(u"Persian"), - "pl": _(u"Polish"), - "pt": _(u"Portuguese"), - "pa": _(u"Punjabi"), - "ro": _(u"Romanian"), - "ru": _(u"Russian"), - "sa": _(u"Sanskrit"), - "sr": _(u"Serbian"), - "sd": _(u"Sindhi"), - "si": _(u"Sinhalese"), - "sk": _(u"Slovak"), - "sl": _(u"Slovenian"), - "es": _(u"Spanish"), - "sw": _(u"Swahili"), - "sv": _(u"Swedish"), - "tg": _(u"Tajik"), - "ta": _(u"Tamil"), - "tl": _(u"Tagalog"), - "te": _(u"Telugu"), - "th": _(u"Thai"), - "bo": _(u"Tibetan"), - "tr": _(u"Turkish"), - "uk": _(u"Ukrainian"), - "ur": _(u"Urdu"), - "uz": _(u"Uzbek"), - "ug": _(u"Uighur"), - "vi": _(u"Vietnamese"), - "cy": _(u"Welsh"), - "yi": _(u"Yiddish") + "af": _(u"Afrikaans"), + "sq": _(u"Albanian"), + "am": _(u"Amharic"), + "ar": _(u"Arabic"), + "hy": _(u"Armenian"), + "az": _(u"Azerbaijani"), + "eu": _(u"Basque"), + "be": _(u"Belarusian"), + "bn": _(u"Bengali"), + "bh": _(u"Bihari"), + "bg": _(u"Bulgarian"), + "my": _(u"Burmese"), + "ca": _(u"Catalan"), + "chr": _(u"Cherokee"), + "zh": _(u"Chinese"), + "zh-CN": _(u"Chinese_simplified"), + "zh-TW": _(u"Chinese_traditional"), + "hr": _(u"Croatian"), + "cs": _(u"Czech"), + "da": _(u"Danish"), + "dv": _(u"Dhivehi"), + "nl": _(u"Dutch"), + "en": _(u"English"), + "eo": _(u"Esperanto"), + "et": _(u"Estonian"), + "tl": _(u"Filipino"), + "fi": _(u"Finnish"), + "fr": _(u"French"), + "gl": _(u"Galician"), + "ka": _(u"Georgian"), + "de": _(u"German"), + "el": _(u"Greek"), + "gn": _(u"Guarani"), + "gu": _(u"Gujarati"), + "iw": _(u"Hebrew"), + "hi": _(u"Hindi"), + "hu": _(u"Hungarian"), + "is": _(u"Icelandic"), + "id": _(u"Indonesian"), + "iu": _(u"Inuktitut"), + "ga": _(u"Irish"), + "it": _(u"Italian"), + "ja": _(u"Japanese"), + "kn": _(u"Kannada"), + "kk": _(u"Kazakh"), + "km": _(u"Khmer"), + "ko": _(u"Korean"), + "ku": _(u"Kurdish"), + "ky": _(u"Kyrgyz"), + "lo": _(u"Laothian"), + "lv": _(u"Latvian"), + "lt": _(u"Lithuanian"), + "mk": _(u"Macedonian"), + "ms": _(u"Malay"), + "ml": _(u"Malayalam"), + "mt": _(u"Maltese"), + "mr": _(u"Marathi"), + "mn": _(u"Mongolian"), + "ne": _(u"Nepali"), + "no": _(u"Norwegian"), + "or": _(u"Oriya"), + "ps": _(u"Pashto"), + "fa": _(u"Persian"), + "pl": _(u"Polish"), + "pt": _(u"Portuguese"), + "pa": _(u"Punjabi"), + "ro": _(u"Romanian"), + "ru": _(u"Russian"), + "sa": _(u"Sanskrit"), + "sr": _(u"Serbian"), + "sd": _(u"Sindhi"), + "si": _(u"Sinhalese"), + "sk": _(u"Slovak"), + "sl": _(u"Slovenian"), + "es": _(u"Spanish"), + "sw": _(u"Swahili"), + "sv": _(u"Swedish"), + "tg": _(u"Tajik"), + "ta": _(u"Tamil"), + "tl": _(u"Tagalog"), + "te": _(u"Telugu"), + "th": _(u"Thai"), + "bo": _(u"Tibetan"), + "tr": _(u"Turkish"), + "uk": _(u"Ukrainian"), + "ur": _(u"Urdu"), + "uz": _(u"Uzbek"), + "ug": _(u"Uighur"), + "vi": _(u"Vietnamese"), + "cy": _(u"Welsh"), + "yi": _(u"Yiddish") } def available_languages(): - global supported_langs, d - if supported_langs == None and d == None: - t = YandexTranslate("trnsl.1.1.20161012T134532Z.d01b9c75fc39aa74.7d1be75a5166a80583eeb020e10f584168da6bf7") - supported_langs = t.langs - d = [] - for i in supported_langs: - d.append(languages[i]) - return sorted(zip(supported_langs, d)) + return dict(sorted(languages.items(), key=lambda x: x[1])) diff --git a/src/extra/translator/wx_ui.py b/src/extra/translator/wx_ui.py index 14d2a88e..e05af488 100644 --- a/src/extra/translator/wx_ui.py +++ b/src/extra/translator/wx_ui.py @@ -16,46 +16,30 @@ # along with this program. If not, see . # ############################################################ -from __future__ import absolute_import -from __future__ import unicode_literals -# -*- coding: utf-8 -*- -############################################################ -# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo -# -# 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 2 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, see . -# -############################################################ from . import translator import wx from wxUI.dialogs import baseDialog class translateDialog(baseDialog.BaseWXDialog): - def __init__(self): - super(translateDialog, self).__init__(None, -1, title=_(u"Translate message")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - staticDest = wx.StaticText(panel, -1, _(u"Target language")) - self.dest_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY) - self.dest_lang.SetFocus() - self.dest_lang.SetSelection(0) - listSizer = wx.BoxSizer(wx.HORIZONTAL) - listSizer.Add(staticDest) - listSizer.Add(self.dest_lang) - ok = wx.Button(panel, wx.ID_OK) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL) - self.SetEscapeId(wx.ID_CANCEL) + def __init__(self): + languages = [] + language_dict = translator.available_languages() + for k in language_dict: + languages.append(language_dict[k]) + super(translateDialog, self).__init__(None, -1, title=_(u"Translate message")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + staticDest = wx.StaticText(panel, -1, _(u"Target language")) + self.dest_lang = wx.ComboBox(panel, -1, choices=languages, style = wx.CB_READONLY) + self.dest_lang.SetFocus() + self.dest_lang.SetSelection(0) + listSizer = wx.BoxSizer(wx.HORIZONTAL) + listSizer.Add(staticDest) + listSizer.Add(self.dest_lang) + ok = wx.Button(panel, wx.ID_OK) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL) + self.SetEscapeId(wx.ID_CANCEL) - def get(self, control): - return getattr(self, control).GetSelection() \ No newline at end of file + def get(self, control): + return getattr(self, control).GetSelection() diff --git a/src/fixes/__init__.py b/src/fixes/__init__.py index 70834b1a..6f256431 100644 --- a/src/fixes/__init__.py +++ b/src/fixes/__init__.py @@ -9,11 +9,11 @@ from . import fix_urllib3_warnings # Avoiding some SSL warnings related to Twyth from . import fix_win32com #from . import fix_requests #fix cacert.pem location for TWBlue binary copies def setup(): - fix_arrow.fix() - if hasattr(sys, "frozen"): - fix_libloader.fix() - fix_win32com.fix() + fix_arrow.fix() + if hasattr(sys, "frozen"): + fix_libloader.fix() + fix_win32com.fix() # fix_requests.fix() # else: # fix_requests.fix(False) - fix_urllib3_warnings.fix() \ No newline at end of file + fix_urllib3_warnings.fix() diff --git a/src/fixes/fix_arrow.py b/src/fixes/fix_arrow.py index aef8581e..322c9af7 100644 --- a/src/fixes/fix_arrow.py +++ b/src/fixes/fix_arrow.py @@ -1,95 +1,49 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals from arrow import locales from arrow.locales import Locale def fix(): - # insert a modified function so if there is no language available in arrow, returns English locale. - locales.get_locale = get_locale + # insert a modified function so if there is no language available in arrow, returns English locale. + locales.get_locale = get_locale def get_locale(name): - locale_cls = locales._locales.get(name.lower()) - if locale_cls is None: - name = name[:2] - locale_cls = locales._locales.get(name.lower()) - if locale_cls == None: - return locales.EnglishLocale() - return locale_cls() + locale_cls = locales._locale_map.get(name.lower()) + if locale_cls is None: + name = name[:2] + locale_cls = locales._locale_map.get(name.lower()) + if locale_cls == None: + return locales.EnglishLocale() + return locale_cls() -class CatalaLocale(Locale): - names = ['ca', 'ca_es', 'ca_ca'] - past = 'Fa {0}' - future = '{0}' # I don't know what's the right phrase in catala for the future. +class GalicianLocale(object): + names = ['gl', 'gl_es', 'gl_gl'] + past = 'Hai {0}' + future = 'En {0}' + and_word = "e" - timeframes = { - 'now': 'Ara mateix', - 'seconds': 'segons', - 'minute': '1 minut', - 'minutes': '{0} minuts', - 'hour': 'una hora', - 'hours': '{0} hores', - 'day': 'un dia', - 'days': '{0} dies', - 'month': 'un mes', - 'months': '{0} messos', - 'year': 'un any', - 'years': '{0} anys', - } + timeframes = { + 'now': 'Agora', + "second": "un segundo", + 'seconds': '{0} segundos', + 'minute': 'un minuto', + 'minutes': '{0} minutos', + 'hour': 'unha hora', + 'hours': '{0} horas', + 'day': 'un día', + 'days': '{0} días', + "week": "unha semana", + "weeks": "{0} semanas", + 'month': 'un mes', + 'months': '{0} meses', + 'year': 'un ano', + 'years': '{0} anos', + } - month_names = ['', 'Jener', 'Febrer', 'Març', 'Abril', 'Maig', 'Juny', 'Juliol', 'Agost', 'Setembre', 'Octubre', 'Novembre', 'Decembre'] - month_abbreviations = ['', 'Jener', 'Febrer', 'Març', 'Abril', 'Maig', 'Juny', 'Juliol', 'Agost', 'Setembre', 'Octubre', 'Novembre', 'Decembre'] - day_names = ['', 'Dilluns', 'Dimars', 'Dimecres', 'Dijous', 'Divendres', 'Disabte', 'Diumenge'] - day_abbreviations = ['', 'Dilluns', 'Dimars', 'Dimecres', 'Dijous', 'Divendres', 'Disabte', 'Diumenge'] + meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"} -class GalicianLocale(Locale): - names = ['gl', 'gl_es', 'gl_gl'] - past = 'Fai {0}' - future = 'En {0}' - - timeframes = { - 'now': 'Agora mesmo', - 'seconds': 'segundos', - 'minute': 'un minuto', - 'minutes': '{0} minutos', - 'hour': 'una hora', - 'hours': '{0} horas', - 'day': 'un día', - 'days': '{0} días', - 'month': 'un mes', - 'months': '{0} meses', - 'year': 'un ano', - 'years': '{0} anos', - } - - month_names = ['', 'Xaneiro', 'Febreiro', 'Marzo', 'Abril', 'Maio', 'Xuño', 'Xullo', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Decembro'] - month_abbreviations = ['', 'Xan', 'Feb', 'Mar', 'Abr', 'Mai', 'Xun', 'Xul', 'Ago', 'Set', 'Out', 'Nov', 'Dec'] - day_names = ['', 'Luns', 'Martes', 'Mércores', 'Xoves', 'Venres', 'Sábado', 'Domingo'] - day_abbreviations = ['', 'Lun', 'Mar', 'Mer', 'xov', 'Ven' 'Sab', 'Dom'] - -class BasqueLocale(Locale): - names = ['eu', 'eu_es', 'eu_eu'] - past = 'duela {0}' - future = '{0} igarota' - - timeframes = { - 'now': 'Orain', - # 'second': 'segundu bat', - 'seconds': 'segundu batzuk', # without specifying a number. - #'seconds': '{0} segundu', # specifying a number - 'minute': 'minutu bat', - 'minutes': '{0} minutu', - 'hour': 'ordu bat', - 'hours': '{0} ordu', - 'day': 'egun bat', - 'days': '{0} egun', - 'month': 'hilabete bat', - 'months': '{0} hilabete', - 'year': 'urte bat', - 'years': '{0} urte', - } - - month_names = ['', 'Urtarrilak', 'Otsailak', 'Martxoak', 'Apirilak', 'Maiatzak', 'Ekainak', 'Uztailak', 'Abuztuak', 'Irailak', 'Urriak', 'Azaroak', 'Abenduak'] - month_abbreviations = ['', 'urt', 'ots', 'mar', 'api', 'mai', 'eka', 'uzt', 'abu', 'ira', 'urr', 'aza', 'abe'] - day_names = ['', 'Asteleehna', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata', 'Igandea'] - day_abbreviations = ['', 'al', 'ar', 'az', 'og', 'ol', 'lr', 'ig'] + month_names = ['', 'xaneiro', 'febreiro', 'marzo', 'abril', 'maio', 'xuño', 'xullo', 'agosto', 'setembro', 'outubro', 'novembro', 'decembro'] + month_abbreviations = ['', 'xan', 'feb', 'mar', 'abr', 'mai', 'xun', 'xul', 'ago', 'set', 'out', 'nov', 'dec'] + day_names = ['', 'luns', 'martes', 'mércores', 'xoves', 'venres', 'sábado', 'domingo'] + day_abbreviations = ['', 'lun', 'mar', 'mer', 'xov', 'ven', 'sab', 'dom'] + ordinal_day_re = r"((?P[1-3]?[0-9](?=[ºª]))[ºª])" diff --git a/src/fixes/fix_libloader.py b/src/fixes/fix_libloader.py index db214ed4..064440f7 100644 --- a/src/fixes/fix_libloader.py +++ b/src/fixes/fix_libloader.py @@ -16,27 +16,27 @@ log = logging.getLogger("fixes.fix_libloader") fixed=False def patched_getmodule(modname): - mod=__import__(modname) - return sys.modules[modname] + mod=__import__(modname) + return sys.modules[modname] def load_com(*names): - global fixed - if fixed==False: - gencache._GetModule=patched_getmodule - com.prepare_gencache() - fixed=True - result = None - for name in names: - try: - result = gencache.EnsureDispatch(name) - break - except com_error: - continue - if result is None: - raise com_error("Unable to load any of the provided com objects.") - return result + global fixed + if fixed==False: + gencache._GetModule=patched_getmodule + com.prepare_gencache() + fixed=True + result = None + for name in names: + try: + result = gencache.EnsureDispatch(name) + break + except com_error: + continue + if result is None: + raise com_error("Unable to load any of the provided com objects.") + return result def fix(): - log.debug("Applying fix for Libloader...") - com.load_com = load_com - log.debug("Load_com has been mapped correctly.") \ No newline at end of file + log.debug("Applying fix for Libloader...") + com.load_com = load_com + log.debug("Load_com has been mapped correctly.") diff --git a/src/fixes/fix_requests.py b/src/fixes/fix_requests.py index 49ff12e3..a1d88585 100644 --- a/src/fixes/fix_requests.py +++ b/src/fixes/fix_requests.py @@ -7,6 +7,6 @@ import logging log = logging.getLogger("fixes.fix_requests") def fix(): - log.debug("Applying fix for requests...") - os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path(), "certifi", "cacert.pem")#.encode(paths.fsencoding) -# log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"]))#.decode(paths.fsencoding))) \ No newline at end of file + log.debug("Applying fix for requests...") + os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path(), "certifi", "cacert.pem")#.encode(paths.fsencoding) +# log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"]))#.decode(paths.fsencoding))) diff --git a/src/fixes/fix_urllib3_warnings.py b/src/fixes/fix_urllib3_warnings.py index 63ca2615..67c6d9ad 100644 --- a/src/fixes/fix_urllib3_warnings.py +++ b/src/fixes/fix_urllib3_warnings.py @@ -8,8 +8,8 @@ import six import urllib.request, urllib.parse, urllib.error def fix(): - urllib3.disable_warnings() - fields.format_header_param=patched_format_header_param + urllib3.disable_warnings() + fields.format_header_param=patched_format_header_param def patched_format_header_param(name, value): if not any(ch in value for ch in '"\\\r\n'): diff --git a/src/fixes/fix_win32com.py b/src/fixes/fix_win32com.py index a135c90a..bce06112 100644 --- a/src/fixes/fix_win32com.py +++ b/src/fixes/fix_win32com.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals import win32com.client def fix(): - if win32com.client.gencache.is_readonly == True: - win32com.client.gencache.is_readonly = False - win32com.client.gencache.Rebuild() \ No newline at end of file + if win32com.client.gencache.is_readonly == True: + win32com.client.gencache.is_readonly = False + win32com.client.gencache.Rebuild() diff --git a/src/issueReporter/issueReporter.py b/src/issueReporter/issueReporter.py index a4d074eb..db261b5e 100644 --- a/src/issueReporter/issueReporter.py +++ b/src/issueReporter/issueReporter.py @@ -27,40 +27,40 @@ from suds.client import Client import constants class reportBug(object): - def __init__(self, user_name): - self.user_name = user_name - self.categories = [_(u"General")] - self.reproducibilities = [_(u"always"), _(u"sometimes"), _(u"random"), _(u"have not tried"), _(u"unable to duplicate")] - self.severities = [_(u"block"), _(u"crash"), _(u"major"), _(u"minor"), _(u"tweak"), _(u"text"), _(u"trivial"), _(u"feature")] - self.dialog = wx_ui.reportBugDialog(self.categories, self.reproducibilities, self.severities) - widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send) - self.dialog.get_response() + def __init__(self, user_name): + self.user_name = user_name + self.categories = [_(u"General")] + self.reproducibilities = [_(u"always"), _(u"sometimes"), _(u"random"), _(u"have not tried"), _(u"unable to duplicate")] + self.severities = [_(u"block"), _(u"crash"), _(u"major"), _(u"minor"), _(u"tweak"), _(u"text"), _(u"trivial"), _(u"feature")] + self.dialog = wx_ui.reportBugDialog(self.categories, self.reproducibilities, self.severities) + widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send) + self.dialog.get_response() - def send(self, *args, **kwargs): - if self.dialog.get("summary") == "" or self.dialog.get("description") == "": - self.dialog.no_filled() - return - if self.dialog.get("agree") == False: - self.dialog.no_checkbox() - return - try: - client = Client(application.report_bugs_url) - issue = client.factory.create('IssueData') - issue.project.name = application.name - issue.project.id = 0 - issue.summary = self.dialog.get("summary"), - issue.description = "Reported by @%s on version %s (snapshot = %s)\n\n" % (self.user_name, application.version, application.snapshot) + self.dialog.get("description") - # to do: Create getters for category, severity and reproducibility in wx_UI. - issue.category = constants.categories[self.dialog.category.GetSelection()] - issue.reproducibility.name = constants.reproducibilities[self.dialog.reproducibility.GetSelection()] - issue.severity.name = constants.severities[self.dialog.severity.GetSelection()] - issue.priority.name = "normal" - issue.view_state.name = "public" - issue.resolution.name = "open" - issue.projection.name = "none" - issue.eta.name = "eta" - issue.status.name = "new" - id = client.service.mc_issue_add(keys.keyring.get("bts_user"), keys.keyring.get("bts_password"), issue) - self.dialog.success(id) - except: - self.dialog.error() + def send(self, *args, **kwargs): + if self.dialog.get("summary") == "" or self.dialog.get("description") == "": + self.dialog.no_filled() + return + if self.dialog.get("agree") == False: + self.dialog.no_checkbox() + return + try: + client = Client(application.report_bugs_url) + issue = client.factory.create('IssueData') + issue.project.name = application.name + issue.project.id = 0 + issue.summary = self.dialog.get("summary"), + issue.description = "Reported by @%s on version %s (snapshot = %s)\n\n" % (self.user_name, application.version, application.snapshot) + self.dialog.get("description") + # to do: Create getters for category, severity and reproducibility in wx_UI. + issue.category = constants.categories[self.dialog.category.GetSelection()] + issue.reproducibility.name = constants.reproducibilities[self.dialog.reproducibility.GetSelection()] + issue.severity.name = constants.severities[self.dialog.severity.GetSelection()] + issue.priority.name = "normal" + issue.view_state.name = "public" + issue.resolution.name = "open" + issue.projection.name = "none" + issue.eta.name = "eta" + issue.status.name = "new" + id = client.service.mc_issue_add(keys.keyring.get("bts_user"), keys.keyring.get("bts_password"), issue) + self.dialog.success(id) + except: + self.dialog.error() diff --git a/src/issueReporter/wx_ui.py b/src/issueReporter/wx_ui.py index 46ee715c..82d0c51c 100644 --- a/src/issueReporter/wx_ui.py +++ b/src/issueReporter/wx_ui.py @@ -21,75 +21,75 @@ import wx import widgetUtils import application class reportBugDialog(widgetUtils.BaseDialog): - def __init__(self, categories, reproducibilities, severities): - super(reportBugDialog, self).__init__(parent=None, id=wx.NewId()) - self.SetTitle(_(u"Report an error")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - categoryLabel = wx.StaticText(panel, -1, _(u"Select a category"), size=wx.DefaultSize) - self.category = wx.ComboBox(panel, -1, choices=categories, style=wx.CB_READONLY) - self.category.SetSelection(0) - categoryB = wx.BoxSizer(wx.HORIZONTAL) - categoryB.Add(categoryLabel, 0, wx.ALL, 5) - categoryB.Add(self.category, 0, wx.ALL, 5) - self.category.SetFocus() - sizer.Add(categoryB, 0, wx.ALL, 5) - summaryLabel = wx.StaticText(panel, -1, _(u"Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize) - self.summary = wx.TextCtrl(panel, -1) - dc = wx.WindowDC(self.summary) - dc.SetFont(self.summary.GetFont()) - self.summary.SetSize(dc.GetTextExtent("a"*80)) - summaryB = wx.BoxSizer(wx.HORIZONTAL) - summaryB.Add(summaryLabel, 0, wx.ALL, 5) - summaryB.Add(self.summary, 0, wx.ALL, 5) - sizer.Add(summaryB, 0, wx.ALL, 5) - descriptionLabel = wx.StaticText(panel, -1, _(u"Here, you can describe the bug in detail"), size=wx.DefaultSize) - self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE) - dc = wx.WindowDC(self.description) - dc.SetFont(self.description.GetFont()) - (x, y, z) = dc.GetMultiLineTextExtent("0"*2000) - self.description.SetSize((x, y)) - descBox = wx.BoxSizer(wx.HORIZONTAL) - descBox.Add(descriptionLabel, 0, wx.ALL, 5) - descBox.Add(self.description, 0, wx.ALL, 5) - sizer.Add(descBox, 0, wx.ALL, 5) - reproducibilityLabel = wx.StaticText(panel, -1, _(u"how often does this bug happen?"), size=wx.DefaultSize) - self.reproducibility = wx.ComboBox(panel, -1, choices=reproducibilities, style=wx.CB_READONLY) - self.reproducibility.SetSelection(3) - reprB = wx.BoxSizer(wx.HORIZONTAL) - reprB.Add(reproducibilityLabel, 0, wx.ALL, 5) - reprB.Add(self.reproducibility, 0, wx.ALL, 5) - sizer.Add(reprB, 0, wx.ALL, 5) - severityLabel = wx.StaticText(panel, -1, _(u"Select the importance that you think this bug has")) - self.severity = wx.ComboBox(panel, -1, choices=severities, style=wx.CB_READONLY) - self.severity.SetSelection(3) - severityB = wx.BoxSizer(wx.HORIZONTAL) - severityB.Add(severityLabel, 0, wx.ALL, 5) - severityB.Add(self.severity, 0, wx.ALL, 5) - sizer.Add(severityB, 0, wx.ALL, 5) - self.agree = wx.CheckBox(panel, -1, _(u"I know that the {0} bug system will get my Twitter username to contact me and fix the bug quickly").format(application.name,)) - self.agree.SetValue(False) - sizer.Add(self.agree, 0, wx.ALL, 5) - self.ok = wx.Button(panel, wx.ID_OK, _(u"Send report")) - self.ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(self.ok, 0, wx.ALL, 5) - btnBox.Add(cancel, 0, wx.ALL, 5) - sizer.Add(btnBox, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self, categories, reproducibilities, severities): + super(reportBugDialog, self).__init__(parent=None, id=wx.NewId()) + self.SetTitle(_(u"Report an error")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + categoryLabel = wx.StaticText(panel, -1, _(u"Select a category"), size=wx.DefaultSize) + self.category = wx.ComboBox(panel, -1, choices=categories, style=wx.CB_READONLY) + self.category.SetSelection(0) + categoryB = wx.BoxSizer(wx.HORIZONTAL) + categoryB.Add(categoryLabel, 0, wx.ALL, 5) + categoryB.Add(self.category, 0, wx.ALL, 5) + self.category.SetFocus() + sizer.Add(categoryB, 0, wx.ALL, 5) + summaryLabel = wx.StaticText(panel, -1, _(u"Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize) + self.summary = wx.TextCtrl(panel, -1) + dc = wx.WindowDC(self.summary) + dc.SetFont(self.summary.GetFont()) + self.summary.SetSize(dc.GetTextExtent("a"*80)) + summaryB = wx.BoxSizer(wx.HORIZONTAL) + summaryB.Add(summaryLabel, 0, wx.ALL, 5) + summaryB.Add(self.summary, 0, wx.ALL, 5) + sizer.Add(summaryB, 0, wx.ALL, 5) + descriptionLabel = wx.StaticText(panel, -1, _(u"Here, you can describe the bug in detail"), size=wx.DefaultSize) + self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE) + dc = wx.WindowDC(self.description) + dc.SetFont(self.description.GetFont()) + (x, y, z) = dc.GetMultiLineTextExtent("0"*2000) + self.description.SetSize((x, y)) + descBox = wx.BoxSizer(wx.HORIZONTAL) + descBox.Add(descriptionLabel, 0, wx.ALL, 5) + descBox.Add(self.description, 0, wx.ALL, 5) + sizer.Add(descBox, 0, wx.ALL, 5) + reproducibilityLabel = wx.StaticText(panel, -1, _(u"how often does this bug happen?"), size=wx.DefaultSize) + self.reproducibility = wx.ComboBox(panel, -1, choices=reproducibilities, style=wx.CB_READONLY) + self.reproducibility.SetSelection(3) + reprB = wx.BoxSizer(wx.HORIZONTAL) + reprB.Add(reproducibilityLabel, 0, wx.ALL, 5) + reprB.Add(self.reproducibility, 0, wx.ALL, 5) + sizer.Add(reprB, 0, wx.ALL, 5) + severityLabel = wx.StaticText(panel, -1, _(u"Select the importance that you think this bug has")) + self.severity = wx.ComboBox(panel, -1, choices=severities, style=wx.CB_READONLY) + self.severity.SetSelection(3) + severityB = wx.BoxSizer(wx.HORIZONTAL) + severityB.Add(severityLabel, 0, wx.ALL, 5) + severityB.Add(self.severity, 0, wx.ALL, 5) + sizer.Add(severityB, 0, wx.ALL, 5) + self.agree = wx.CheckBox(panel, -1, _(u"I know that the {0} bug system will get my Twitter username to contact me and fix the bug quickly").format(application.name,)) + self.agree.SetValue(False) + sizer.Add(self.agree, 0, wx.ALL, 5) + self.ok = wx.Button(panel, wx.ID_OK, _(u"Send report")) + self.ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.ok, 0, wx.ALL, 5) + btnBox.Add(cancel, 0, wx.ALL, 5) + sizer.Add(btnBox, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def no_filled(self): - wx.MessageDialog(self, _(u"You must fill out both fields"), _(u"Error"), wx.OK|wx.ICON_ERROR).ShowModal() + def no_filled(self): + wx.MessageDialog(self, _(u"You must fill out both fields"), _(u"Error"), wx.OK|wx.ICON_ERROR).ShowModal() - def no_checkbox(self): - wx.MessageDialog(self, _(u"You need to mark the checkbox to provide us your twitter username to contact you if it is necessary."), _(u"Error"), wx.ICON_ERROR).ShowModal() + def no_checkbox(self): + wx.MessageDialog(self, _(u"You need to mark the checkbox to provide us your twitter username to contact you if it is necessary."), _(u"Error"), wx.ICON_ERROR).ShowModal() - def success(self, id): - wx.MessageDialog(self, _(u"Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You've reported the bug number %i") % (id), _(u"reported"), wx.OK).ShowModal() - self.EndModal(wx.ID_OK) + def success(self, id): + wx.MessageDialog(self, _(u"Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You've reported the bug number %i") % (id), _(u"reported"), wx.OK).ShowModal() + self.EndModal(wx.ID_OK) - def error(self): - wx.MessageDialog(self, _(u"Something unexpected occurred while trying to report the bug. Please, try again later"), _(u"Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal() - self.EndModal(wx.ID_CANCEL) \ No newline at end of file + def error(self): + wx.MessageDialog(self, _(u"Something unexpected occurred while trying to report the bug. Please, try again later"), _(u"Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal() + self.EndModal(wx.ID_CANCEL) diff --git a/src/keyboard_handler/global_handler.py b/src/keyboard_handler/global_handler.py index d07062ac..b50e082e 100644 --- a/src/keyboard_handler/global_handler.py +++ b/src/keyboard_handler/global_handler.py @@ -1,8 +1,8 @@ from __future__ import absolute_import import platform if platform.system() == 'Linux': - from .linux import LinuxKeyboardHandler as GlobalKeyboardHandler + from .linux import LinuxKeyboardHandler as GlobalKeyboardHandler else: - from .wx_handler import WXKeyboardHandler as GlobalKeyboardHandler + from .wx_handler import WXKeyboardHandler as GlobalKeyboardHandler #elif platform.system() == 'Darwin': - #from osx import OSXKeyboardHandler as GlobalKeyboardHandler + #from osx import OSXKeyboardHandler as GlobalKeyboardHandler diff --git a/src/keyboard_handler/key_constants.py b/src/keyboard_handler/key_constants.py index c40491d4..6d88ffe9 100644 --- a/src/keyboard_handler/key_constants.py +++ b/src/keyboard_handler/key_constants.py @@ -1,127 +1,127 @@ keys = { - 'accept': 30, - 'add': 107, - 'apps': 93, - 'attn': 246, - 'back': 8, - 'browser_back': 166, - 'browser_forward': 167, - 'cancel': 3, - 'capital': 20, - 'clear': 12, - 'control': 17, - 'convert': 28, - 'crsel': 247, - 'decimal': 110, - 'delete': 46, - 'divide': 111, - 'down': 40, - 'end': 35, - 'ereof': 249, - 'escape': 27, - 'execute': 43, - 'exsel': 248, - 'f1': 112, - 'f10': 121, - 'f11': 122, - 'f12': 123, - 'f13': 124, - 'f14': 125, - 'f15': 126, - 'f16': 127, - 'f17': 128, - 'f18': 129, - 'f19': 130, - 'f2': 113, - 'f20': 131, - 'f21': 132, - 'f22': 133, - 'f23': 134, - 'f24': 135, - 'f3': 114, - 'f4': 115, - 'f5': 116, - 'f6': 117, - 'f7': 118, - 'f8': 119, - 'f9': 120, - 'final': 24, - 'hangeul': 21, - 'hangul': 21, - 'hanja': 25, - 'help': 47, - 'home': 36, - 'insert': 45, - 'junja': 23, - 'kana': 21, - 'kanji': 25, - 'lbutton': 1, - 'lcontrol': 162, - 'left': 37, - 'lmenu': 164, - 'lshift': 160, - 'lwin': 91, - 'mbutton': 4, - 'media_next_track': 176, - 'media_play_pause': 179, - 'media_prev_track': 177, - 'menu': 18, - 'modechange': 31, - 'multiply': 106, - 'next': 34, - 'noname': 252, - 'nonconvert': 29, - 'numlock': 144, - 'numpad0': 96, - 'numpad1': 97, - 'numpad2': 98, - 'numpad3': 99, - 'numpad4': 100, - 'numpad5': 101, - 'numpad6': 102, - 'numpad7': 103, - 'numpad8': 104, - 'numpad9': 105, - 'oem_clear': 254, - 'pa1': 253, - 'pagedown': 34, - 'pageup': 33, - 'pause': 19, - 'play': 250, - 'print': 42, - 'prior': 33, - 'processkey': 229, - 'rbutton': 2, - 'rcontrol': 163, - 'return': 13, - 'right': 39, - 'rmenu': 165, - 'rshift': 161, - 'rwin': 92, - 'scroll': 145, - 'select': 41, - 'separator': 108, - 'shift': 16, - 'snapshot': 44, - 'space': 32, - 'subtract': 109, - 'tab': 9, - 'up': 38, - 'volume_down': 174, - 'volume_mute': 173, - 'volume_up': 175, - 'xbutton1': 5, - 'xbutton2': 6, - 'zoom': 251, - '/': 191, - ';': 218, - '[': 219, - '\\': 220, - ']': 221, - '\'': 222, - '=': 187, - '-': 189, - ';': 186, + 'accept': 30, + 'add': 107, + 'apps': 93, + 'attn': 246, + 'back': 8, + 'browser_back': 166, + 'browser_forward': 167, + 'cancel': 3, + 'capital': 20, + 'clear': 12, + 'control': 17, + 'convert': 28, + 'crsel': 247, + 'decimal': 110, + 'delete': 46, + 'divide': 111, + 'down': 40, + 'end': 35, + 'ereof': 249, + 'escape': 27, + 'execute': 43, + 'exsel': 248, + 'f1': 112, + 'f10': 121, + 'f11': 122, + 'f12': 123, + 'f13': 124, + 'f14': 125, + 'f15': 126, + 'f16': 127, + 'f17': 128, + 'f18': 129, + 'f19': 130, + 'f2': 113, + 'f20': 131, + 'f21': 132, + 'f22': 133, + 'f23': 134, + 'f24': 135, + 'f3': 114, + 'f4': 115, + 'f5': 116, + 'f6': 117, + 'f7': 118, + 'f8': 119, + 'f9': 120, + 'final': 24, + 'hangeul': 21, + 'hangul': 21, + 'hanja': 25, + 'help': 47, + 'home': 36, + 'insert': 45, + 'junja': 23, + 'kana': 21, + 'kanji': 25, + 'lbutton': 1, + 'lcontrol': 162, + 'left': 37, + 'lmenu': 164, + 'lshift': 160, + 'lwin': 91, + 'mbutton': 4, + 'media_next_track': 176, + 'media_play_pause': 179, + 'media_prev_track': 177, + 'menu': 18, + 'modechange': 31, + 'multiply': 106, + 'next': 34, + 'noname': 252, + 'nonconvert': 29, + 'numlock': 144, + 'numpad0': 96, + 'numpad1': 97, + 'numpad2': 98, + 'numpad3': 99, + 'numpad4': 100, + 'numpad5': 101, + 'numpad6': 102, + 'numpad7': 103, + 'numpad8': 104, + 'numpad9': 105, + 'oem_clear': 254, + 'pa1': 253, + 'pagedown': 34, + 'pageup': 33, + 'pause': 19, + 'play': 250, + 'print': 42, + 'prior': 33, + 'processkey': 229, + 'rbutton': 2, + 'rcontrol': 163, + 'return': 13, + 'right': 39, + 'rmenu': 165, + 'rshift': 161, + 'rwin': 92, + 'scroll': 145, + 'select': 41, + 'separator': 108, + 'shift': 16, + 'snapshot': 44, + 'space': 32, + 'subtract': 109, + 'tab': 9, + 'up': 38, + 'volume_down': 174, + 'volume_mute': 173, + 'volume_up': 175, + 'xbutton1': 5, + 'xbutton2': 6, + 'zoom': 251, + '/': 191, + ';': 218, + '[': 219, + '\\': 220, + ']': 221, + '\'': 222, + '=': 187, + '-': 189, + ';': 186, } modifiers = {'alt': 1, 'control': 2, 'shift': 4, 'win': 8} diff --git a/src/keyboard_handler/linux.py b/src/keyboard_handler/linux.py index ba69d7ff..15f6ff7b 100644 --- a/src/keyboard_handler/linux.py +++ b/src/keyboard_handler/linux.py @@ -3,56 +3,56 @@ import threading import thread import pyatspi def parse(s): - """parse a string like control+f into (modifier, key). -Unknown modifiers will return ValueError.""" - m = 0 - lst = s.split('+') - if not len(lst): return (0, s) + """parse a string like control+f into (modifier, key). + Unknown modifiers will return ValueError.""" + m = 0 + lst = s.split('+') + if not len(lst): return (0, s) #Are these right? - d = { - "shift": 1< 1: #more than one key, parse error - raise ValueError, 'unknown modifier %s' % lst[0] - return (m, lst[0].lower()) + if len(lst) > 1: #more than one key, parse error + raise ValueError, 'unknown modifier %s' % lst[0] + return (m, lst[0].lower()) class AtspiThread(threading.Thread): - def run(self): - pyatspi.Registry.registerKeystrokeListener(handler, kind=(pyatspi.KEY_PRESSED_EVENT,), - mask=pyatspi.allModifiers()) - pyatspi.Registry.start() + def run(self): + pyatspi.Registry.registerKeystrokeListener(handler, kind=(pyatspi.KEY_PRESSED_EVENT,), + mask=pyatspi.allModifiers()) + pyatspi.Registry.start() #the keys we registered keys = {} def handler(e): - m,k = e.modifiers,e.event_string.lower() + m,k = e.modifiers,e.event_string.lower() #not sure why we can't catch control+f. Try to fix it. - if (not e.is_text) and e.id >= 97 <= 126: - k = chr(e.id) - if (m,k) not in keys: return False - thread.start_new(keys[(m,k)], ()) - return True #don't pass it on + if (not e.is_text) and e.id >= 97 <= 126: + k = chr(e.id) + if (m,k) not in keys: return False + thread.start_new(keys[(m,k)], ()) + return True #don't pass it on class LinuxKeyboardHandler(KeyboardHandler): - def __init__(self, *args, **kwargs): - KeyboardHandler.__init__(self, *args, **kwargs) - t = AtspiThread() - t.start() - def register_key(self, key, function): - """key will be a string, such as control+shift+f. -We need to convert that, using parse_key, -into modifier and key to put into our dictionary.""" + def __init__(self, *args, **kwargs): + KeyboardHandler.__init__(self, *args, **kwargs) + t = AtspiThread() + t.start() + def register_key(self, key, function): + """key will be a string, such as control+shift+f. + We need to convert that, using parse_key, + into modifier and key to put into our dictionary.""" #register key so we know if we have it on event receive. - t = parse(key) - keys[t] = function + t = parse(key) + keys[t] = function #if we got this far, the key is valid. - KeyboardHandler.register_key(self, key, function) + KeyboardHandler.register_key(self, key, function) - def unregister_key (self, key, function): - KeyboardHandler.unregister_key(self, key, function) - del keys[parse(key)] + def unregister_key (self, key, function): + KeyboardHandler.unregister_key(self, key, function) + del keys[parse(key)] diff --git a/src/keyboard_handler/main.py b/src/keyboard_handler/main.py index 000ee65d..0020bf7d 100644 --- a/src/keyboard_handler/main.py +++ b/src/keyboard_handler/main.py @@ -5,84 +5,84 @@ class KeyboardHandlerError (Exception): pass class KeyboardHandler(object): - def __init__(self, repeat_rate=0.0, *args, **kwargs): - self.repeat_rate = repeat_rate #How long between accepting the same keystroke? - self._last_key = None - self._last_keypress_time = 0 - super(KeyboardHandler, self).__init__(*args, **kwargs) - self.active_keys = {} - if not hasattr(self, 'replacement_mods'): - self.replacement_mods = {} - if not hasattr(self, 'replacement_keys'): - self.replacement_keys = {} + def __init__(self, repeat_rate=0.0, *args, **kwargs): + self.repeat_rate = repeat_rate #How long between accepting the same keystroke? + self._last_key = None + self._last_keypress_time = 0 + super(KeyboardHandler, self).__init__(*args, **kwargs) + self.active_keys = {} + if not hasattr(self, 'replacement_mods'): + self.replacement_mods = {} + if not hasattr(self, 'replacement_keys'): + self.replacement_keys = {} - def register_key (self, key, function): - if key in self.active_keys: - raise KeyboardHandlerError("Key %s is already registered to a function" % key) - if not callable(function): - raise TypeError("Must provide a callable to be invoked upon keypress") - self.active_keys[key] = function + def register_key (self, key, function): + if key in self.active_keys: + raise KeyboardHandlerError("Key %s is already registered to a function" % key) + if not callable(function): + raise TypeError("Must provide a callable to be invoked upon keypress") + self.active_keys[key] = function - def unregister_key (self, key, function): - try: - if self.active_keys[key] != function: - raise KeyboardHandlerError("key %s is not registered to that function" % key) - except KeyError: - raise KeyboardHandlerError("Key %s not currently registered" % key) - del(self.active_keys[key]) + def unregister_key (self, key, function): + try: + if self.active_keys[key] != function: + raise KeyboardHandlerError("key %s is not registered to that function" % key) + except KeyError: + raise KeyboardHandlerError("Key %s not currently registered" % key) + del(self.active_keys[key]) - def unregister_all_keys(self): - for key in list(self.active_keys): - self.unregister_key(key, self.active_keys[key]) + def unregister_all_keys(self): + for key in list(self.active_keys): + self.unregister_key(key, self.active_keys[key]) - def handle_key (self, key): - if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate: - return - try: - function = self.active_keys[key] - except KeyError: - return - self._last_key = key - self._last_keypress_time = time.time() - return function() + def handle_key (self, key): + if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate: + return + try: + function = self.active_keys[key] + except KeyError: + return + self._last_key = key + self._last_keypress_time = time.time() + return function() - def register_keys(self, keys): - """Given a mapping of keystrokes to functions, registers all keystrokes""" - for k in keys: - self.register_key(k, keys[k]) + def register_keys(self, keys): + """Given a mapping of keystrokes to functions, registers all keystrokes""" + for k in keys: + self.register_key(k, keys[k]) - def unregister_keys(self, keys): - """Given a mapping of keys to their functions, unregisters all provided keys.""" - for k in keys: - self.unregister_key(k, keys[k]) + def unregister_keys(self, keys): + """Given a mapping of keys to their functions, unregisters all provided keys.""" + for k in keys: + self.unregister_key(k, keys[k]) - def standardize_key(self, key): - """Takes a keystroke and places it in a standard case and order in a list.""" - working = key.split('+') - working = [i.lower() for i in working] - answer = [] - if "control" in working: - answer.append("control") - if "win" in working: - answer.append("win") - if "alt" in working: - answer.append("alt") - if "shift" in working: - answer.append("shift") - if working[-1] not in answer: - answer.append(working[-1]) - return answer + def standardize_key(self, key): + """Takes a keystroke and places it in a standard case and order in a list.""" + working = key.split('+') + working = [i.lower() for i in working] + answer = [] + if "control" in working: + answer.append("control") + if "win" in working: + answer.append("win") + if "alt" in working: + answer.append("alt") + if "shift" in working: + answer.append("shift") + if working[-1] not in answer: + answer.append(working[-1]) + return answer - def standardize_keymap(self, keymap): - """Given a keymap, returns the keymap standardized.""" - full = {} - for i in keymap: - answer = "" - new = self.standardize_key(keymap[i]) - for (c, j) in enumerate(new): - if c < len(new)-1: - answer = "%s%s+" % (answer, j) - else: - answer = "%s%s" % (answer, j) - full[i] = answer - return full + def standardize_keymap(self, keymap): + """Given a keymap, returns the keymap standardized.""" + full = {} + for i in keymap: + answer = "" + new = self.standardize_key(keymap[i]) + for (c, j) in enumerate(new): + if c < len(new)-1: + answer = "%s%s+" % (answer, j) + else: + answer = "%s%s" % (answer, j) + full[i] = answer + return full diff --git a/src/keyboard_handler/osx.py b/src/keyboard_handler/osx.py index 12884859..f63e85ad 100644 --- a/src/keyboard_handler/osx.py +++ b/src/keyboard_handler/osx.py @@ -12,45 +12,45 @@ kEventHotKeyReleasedSubtype = 9 class OSXKeyboardHandler(KeyboardHandler): - def __init__(self): - super(OSXKeyboardHandler, self).__init__() - self.replacement_keys = dict() - self.app = KeyboardCapturingNSApplication.alloc().init() - self._event_thread = Thread(target=AppHelper.runEventLoop) - self._event_thread.start() + def __init__(self): + super(OSXKeyboardHandler, self).__init__() + self.replacement_keys = dict() + self.app = KeyboardCapturingNSApplication.alloc().init() + self._event_thread = Thread(target=AppHelper.runEventLoop) + self._event_thread.start() - def register_key (self, key, function): - super(OSXKeyboardHandler, self).register_key(key, function) - k, m = self.parse_key(key) - key_id = RegisterEventHotKey(k, m, (0, 0), GetApplicationEventTarget(), 0) - self.key_ids[key] = key_id + def register_key (self, key, function): + super(OSXKeyboardHandler, self).register_key(key, function) + k, m = self.parse_key(key) + key_id = RegisterEventHotKey(k, m, (0, 0), GetApplicationEventTarget(), 0) + self.key_ids[key] = key_id - def unregister_key (self, key, function): - super(OSXKeyboardHandler, self).unregister_key(key, function) - key_id = self.key_ids[key] - raise NotImplementedError + def unregister_key (self, key, function): + super(OSXKeyboardHandler, self).unregister_key(key, function) + key_id = self.key_ids[key] + raise NotImplementedError - def parse_key (self, key): - key=key.split("+") - #replacements - #Modifier keys: - for index, item in enumerate(key[0:-1]): - if self.replacement_mods.has_key(item): - key[index] = self.replacement_mods[item] - if self.replacement_keys.has_key(key[-1]): - key[-1] = self.replacement_keys[key[-1]] - elif len(key[-1])==1: - key[-1] = ord(str(key[-1]))-36 - mods = 0 - for i in key[:-1]: - mods = mods|i - return [key[-1], mods] + def parse_key (self, key): + key=key.split("+") + #replacements + #Modifier keys: + for index, item in enumerate(key[0:-1]): + if self.replacement_mods.has_key(item): + key[index] = self.replacement_mods[item] + if self.replacement_keys.has_key(key[-1]): + key[-1] = self.replacement_keys[key[-1]] + elif len(key[-1])==1: + key[-1] = ord(str(key[-1]))-36 + mods = 0 + for i in key[:-1]: + mods = mods|i + return [key[-1], mods] class KeyboardCapturingNSApplication(NSApplication): - def sendEvent_(self, theEvent): - if theEvent.type() == NSSystemDefined and theEvent.subtype() == kEventHotKeyPressedSubtype: - self.activateIgnoringOtherApps_(True) - NSRunAlertPanel(u'Hot Key Pressed', u'Hot Key Pressed', None, None, None) - super(NSApplication, self).sendEvent_(theEvent) + def sendEvent_(self, theEvent): + if theEvent.type() == NSSystemDefined and theEvent.subtype() == kEventHotKeyPressedSubtype: + self.activateIgnoringOtherApps_(True) + NSRunAlertPanel(u'Hot Key Pressed', u'Hot Key Pressed', None, None, None) + super(NSApplication, self).sendEvent_(theEvent) diff --git a/src/keyboard_handler/windows.py b/src/keyboard_handler/windows.py index 4197400b..2411c38c 100644 --- a/src/keyboard_handler/windows.py +++ b/src/keyboard_handler/windows.py @@ -5,36 +5,36 @@ from main import KeyboardHandler class WindowsKeyboardHandler(KeyboardHandler): - def __init__ (self, *args, **kwargs): - super(WindowsKeyboardHandler, self).__init__(*args, **kwargs) - #Setup the replacement dictionaries. - for i in dir(win32con): - if i.startswith("VK_"): - key = i[3:].lower() - self.replacement_keys[key] = getattr(win32con, i) - elif i.startswith("MOD_"): - key = i[4:].lower() - self.replacement_mods[key] = getattr(win32con, i) - self.replacement_keys .update(dict(pageup=win32con.VK_PRIOR, pagedown=win32con.VK_NEXT)) + def __init__ (self, *args, **kwargs): + super(WindowsKeyboardHandler, self).__init__(*args, **kwargs) + #Setup the replacement dictionaries. + for i in dir(win32con): + if i.startswith("VK_"): + key = i[3:].lower() + self.replacement_keys[key] = getattr(win32con, i) + elif i.startswith("MOD_"): + key = i[4:].lower() + self.replacement_mods[key] = getattr(win32con, i) + self.replacement_keys .update(dict(pageup=win32con.VK_PRIOR, pagedown=win32con.VK_NEXT)) - def parse_key (self, keystroke, separator="+"): - keystroke = str(keystroke) #We don't want unicode - keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] - mods = 0 - for i in keystroke[:-1]: - mods = mods | i #or everything together - return (mods, keystroke[-1]) + def parse_key (self, keystroke, separator="+"): + keystroke = str(keystroke) #We don't want unicode + keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] + mods = 0 + for i in keystroke[:-1]: + mods = mods | i #or everything together + return (mods, keystroke[-1]) - def keycode_from_key(self, key): - if key in self.replacement_mods: - return self.replacement_mods[key] - if key in self.replacement_keys: - return self.replacement_keys[key] - if len(key) == 1: - return win32api.VkKeyScanEx(key, win32api.GetKeyboardLayout()) + def keycode_from_key(self, key): + if key in self.replacement_mods: + return self.replacement_mods[key] + if key in self.replacement_keys: + return self.replacement_keys[key] + if len(key) == 1: + return win32api.VkKeyScanEx(key, win32api.GetKeyboardLayout()) - def is_key_pressed(self, key): - """Returns if the given key was pressed. Requires an active message loop or will simply give if the key was pressed recently.""" - key = self.keycode_from_key(key) - return win32api.GetAsyncKeyState(key) + def is_key_pressed(self, key): + """Returns if the given key was pressed. Requires an active message loop or will simply give if the key was pressed recently.""" + key = self.keycode_from_key(key) + return win32api.GetAsyncKeyState(key) diff --git a/src/keyboard_handler/wx_handler.py b/src/keyboard_handler/wx_handler.py index 80609116..ff16db3d 100644 --- a/src/keyboard_handler/wx_handler.py +++ b/src/keyboard_handler/wx_handler.py @@ -10,121 +10,121 @@ from . import key_constants __all__ = ['WXKeyboardHandler', 'WXControlKeyboardHandler'] def call_after(func): - def wrapper(*args, **kwargs): - wx.CallAfter(func, *args, **kwargs) - functools.update_wrapper(wrapper, func) - return wrapper + def wrapper(*args, **kwargs): + wx.CallAfter(func, *args, **kwargs) + functools.update_wrapper(wrapper, func) + return wrapper class BaseWXKeyboardHandler(KeyboardHandler): - def __init__(self, *args, **kwargs): - super(BaseWXKeyboardHandler, self).__init__(*args, **kwargs) - #Setup the replacement dictionaries. - for i in dir(wx): - if i.startswith('WXK_'): - key = i[4:].lower() - self.replacement_keys[key] = getattr(wx, i) - elif i.startswith('MOD_'): - key = i[4:].lower() - self.replacement_mods[key] = getattr(wx, i) + def __init__(self, *args, **kwargs): + super(BaseWXKeyboardHandler, self).__init__(*args, **kwargs) + #Setup the replacement dictionaries. + for i in dir(wx): + if i.startswith('WXK_'): + key = i[4:].lower() + self.replacement_keys[key] = getattr(wx, i) + elif i.startswith('MOD_'): + key = i[4:].lower() + self.replacement_mods[key] = getattr(wx, i) - def parse_key (self, keystroke, separator="+"): - keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] - mods = 0 - for i in keystroke[:-1]: - mods = mods | i #or everything together - return (mods, keystroke[-1]) + def parse_key (self, keystroke, separator="+"): + keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] + mods = 0 + for i in keystroke[:-1]: + mods = mods | i #or everything together + return (mods, keystroke[-1]) + + def keycode_from_key(self, key): + result = None + if key in self.replacement_mods: + result = self.replacement_mods[key] + elif key in self.replacement_keys: + result = self.replacement_keys[key] + if result >= 277: + result -= 277 + elif len(key) == 1: + result = ord(key.upper()) + if result is None: + raise KeyboardHandlerError("Could not translate key %r into a valid keycode." % key) + return result - def keycode_from_key(self, key): - result = None - if key in self.replacement_mods: - result = self.replacement_mods[key] - elif key in self.replacement_keys: - result = self.replacement_keys[key] - if result >= 277: - result -= 277 - elif len(key) == 1: - result = ord(key.upper()) - if result is None: - raise KeyboardHandlerError("Could not translate key %r into a valid keycode." % key) - return result - class WXKeyboardHandler(BaseWXKeyboardHandler): - def __init__ (self, parent, *args, **kwargs): - super(WXKeyboardHandler, self).__init__(*args, **kwargs) - self.parent = parent - self.key_ids = {} - self.replacement_keys = key_constants.keys - self.replacement_mods = key_constants.modifiers + def __init__ (self, parent, *args, **kwargs): + super(WXKeyboardHandler, self).__init__(*args, **kwargs) + self.parent = parent + self.key_ids = {} + self.replacement_keys = key_constants.keys + self.replacement_mods = key_constants.modifiers - @call_after - def register_key(self, key, function): - super(WXKeyboardHandler, self).register_key(key, function) - key_id = wx.NewId() - parsed = self.parse_key(key) - res = self.parent.RegisterHotKey(key_id, *parsed) - if not res: - logger.warn("Failed to register hotkey: %s for function %r", key, function) - self.parent.Bind(wx.EVT_HOTKEY, lambda evt: self.process_key(evt, key_id), id=key_id) - self.key_ids[key] = key_id - return res + @call_after + def register_key(self, key, function): + super(WXKeyboardHandler, self).register_key(key, function) + key_id = wx.NewId() + parsed = self.parse_key(key) + res = self.parent.RegisterHotKey(key_id, *parsed) + if not res: + logger.warn("Failed to register hotkey: %s for function %r", key, function) + self.parent.Bind(wx.EVT_HOTKEY, lambda evt: self.process_key(evt, key_id), id=key_id) + self.key_ids[key] = key_id + return res - def parse_key (self, keystroke, separator="+"): - keystroke = str(keystroke) #We don't want unicode - keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] - mods = 0 - for i in keystroke[:-1]: - mods = mods | i #or everything together - return (mods, keystroke[-1]) + def parse_key (self, keystroke, separator="+"): + keystroke = str(keystroke) #We don't want unicode + keystroke = [self.keycode_from_key(i) for i in keystroke.split(separator)] + mods = 0 + for i in keystroke[:-1]: + mods = mods | i #or everything together + return (mods, keystroke[-1]) - @call_after - def unregister_key (self, key, function): - super(WXKeyboardHandler, self).unregister_key(key, function) - if key not in self.key_ids: - return #there's nothing we can do. - key_id = self.key_ids[key] - self.parent.UnregisterHotKey(key_id) - self.parent.Unbind( wx.EVT_HOTKEY, id=key_id) - self.key_ids.pop(key) + @call_after + def unregister_key (self, key, function): + super(WXKeyboardHandler, self).unregister_key(key, function) + if key not in self.key_ids: + return #there's nothing we can do. + key_id = self.key_ids[key] + self.parent.UnregisterHotKey(key_id) + self.parent.Unbind( wx.EVT_HOTKEY, id=key_id) + self.key_ids.pop(key) - def process_key (self, evt, id): - evt.Skip() - key_ids = self.key_ids.keys() - for i in key_ids: - if self.key_ids.get(i) == id: - self.handle_key(i) + def process_key (self, evt, id): + evt.Skip() + key_ids = self.key_ids.keys() + for i in key_ids: + if self.key_ids.get(i) == id: + self.handle_key(i) class WXControlKeyboardHandler(wx.StaticText, KeyboardHandler): - def __init__(self, parent=None, *a, **k): - wx.StaticText.__init__(self, parent=parent) - KeyboardHandler.__init__(self, *a, **k) - self.wx_replacements = {} - for i in [d for d in dir(wx) if d.startswith('WXK_')]: - self.wx_replacements[getattr(wx, i)] = i[4:].lower() - self.Bind(wx.EVT_KEY_DOWN, self.process_key, self) - self.SetFocus() + def __init__(self, parent=None, *a, **k): + wx.StaticText.__init__(self, parent=parent) + KeyboardHandler.__init__(self, *a, **k) + self.wx_replacements = {} + for i in [d for d in dir(wx) if d.startswith('WXK_')]: + self.wx_replacements[getattr(wx, i)] = i[4:].lower() + self.Bind(wx.EVT_KEY_DOWN, self.process_key, self) + self.SetFocus() - def process_key(self, evt): - keycode = evt.GetKeyCode() - keyname = self.wx_replacements.get(keycode, None) - modifiers = "" - replacements = ( (evt.ControlDown(), 'control+'), - (evt.AltDown(), 'alt+'), - (evt.ShiftDown(), 'shift+'), - (evt.MetaDown(), 'win+') - ) - for mod, ch in (replacements): - if mod: - modifiers += ch - if keyname is None: - if 27 < keycode < 256: - keyname = chr(keycode).lower() - else: - keyname = "(%s)unknown" % keycode - key = modifiers + keyname - self.handle_key(key) + def process_key(self, evt): + keycode = evt.GetKeyCode() + keyname = self.wx_replacements.get(keycode, None) + modifiers = "" + replacements = ( (evt.ControlDown(), 'control+'), + (evt.AltDown(), 'alt+'), + (evt.ShiftDown(), 'shift+'), + (evt.MetaDown(), 'win+') + ) + for mod, ch in (replacements): + if mod: + modifiers += ch + if keyname is None: + if 27 < keycode < 256: + keyname = chr(keycode).lower() + else: + keyname = "(%s)unknown" % keycode + key = modifiers + keyname + self.handle_key(key) diff --git a/src/keymaps/Chicken Nugget.keymap b/src/keymaps/Chicken Nugget.keymap index c741ba5a..2f1888b0 100644 --- a/src/keymaps/Chicken Nugget.keymap +++ b/src/keymaps/Chicken Nugget.keymap @@ -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") \ No newline at end of file +open_in_browser = string(default="alt+control+win+return") +add_alias=string(default="") \ No newline at end of file diff --git a/src/keymaps/Qwitter.keymap b/src/keymaps/Qwitter.keymap index 21ae6160..e9736a5b 100644 --- a/src/keymaps/Qwitter.keymap +++ b/src/keymaps/Qwitter.keymap @@ -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") \ No newline at end of file +open_in_browser = string(default="alt+control+win+return") +add_alias=string(default="") \ No newline at end of file diff --git a/src/keymaps/Windows 10.keymap b/src/keymaps/Windows 10.keymap index e02e6278..70e79664 100644 --- a/src/keymaps/Windows 10.keymap +++ b/src/keymaps/Windows 10.keymap @@ -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") \ No newline at end of file +open_in_browser = string(default="alt+control+win+return") +add_alias=string(default="") \ No newline at end of file diff --git a/src/keymaps/Windows11.keymap b/src/keymaps/Windows11.keymap new file mode 100644 index 00000000..57ca311e --- /dev/null +++ b/src/keymaps/Windows11.keymap @@ -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 ") + +[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="") \ No newline at end of file diff --git a/src/keymaps/base.template b/src/keymaps/base.template index 31784e42..f95ffcc1 100644 --- a/src/keymaps/base.template +++ b/src/keymaps/base.template @@ -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") \ No newline at end of file +open_in_browser = string(default="alt+control+win+return") +add_alias=string(default="") \ No newline at end of file diff --git a/src/keymaps/default.keymap b/src/keymaps/default.keymap index f4dbb190..fa5157e0 100644 --- a/src/keymaps/default.keymap +++ b/src/keymaps/default.keymap @@ -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") \ No newline at end of file +open_in_browser = string(default="alt+control+win+return") +add_alias=string(default="") \ No newline at end of file diff --git a/src/keys/__init__.py b/src/keys/__init__.py index aa08bfc8..6c0a4990 100644 --- a/src/keys/__init__.py +++ b/src/keys/__init__.py @@ -14,9 +14,9 @@ import paths # lib = load_library("snapshot_api_keys64", x64_path=paths.app_path("keys/lib")) #else: if platform.architecture()[0][:2] == "32": - lib = load_library("stable_api_keys32", x86_path=os.path.join(paths.app_path(), "keys", "lib")) + lib = load_library("stable_api_keys32", x86_path=os.path.join(paths.app_path(), "keys", "lib")) else: - lib = load_library("stable_api_keys64", x64_path=os.path.join(paths.app_path(), "keys", "lib")) + lib = load_library("stable_api_keys64", x64_path=os.path.join(paths.app_path(), "keys", "lib")) # import linuxKeys # lib = linuxKeys @@ -24,20 +24,20 @@ else: keyring = None def setup(): - global keyring - if keyring == None: - keyring = Keyring() + global keyring + if keyring == None: + keyring = Keyring() class Keyring(object): - def __init__(self): - super(Keyring, self).__init__() + def __init__(self): + super(Keyring, self).__init__() - def _call_method(self, function): - result = getattr(lib, function) - result = c_char_p(result.__call__()) - return result.value + def _call_method(self, function): + result = getattr(lib, function) + result = c_char_p(result.__call__()) + return result.value - def get(self, func): - if hasattr(application,func+"_override"): - return getattr(application,func+'_override') - return getattr(self, "_call_method")("get_"+func) + def get(self, func): + if hasattr(application,func+"_override"): + return getattr(application,func+'_override') + return getattr(self, "_call_method")("get_"+func) diff --git a/src/keys/linuxKeys.py b/src/keys/linuxKeys.py index 0baef390..4b6bb8d4 100644 --- a/src/keys/linuxKeys.py +++ b/src/keys/linuxKeys.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals def get_api_key(): - return "8pDLbyOW3saYnvSZ4uLFg\0" + return "8pDLbyOW3saYnvSZ4uLFg\0" def get_api_secret(): - return "YsgdrzY9B4yyYvYsyee78rKI3GshjHpenVS9LnFJXY\0"; + return "YsgdrzY9B4yyYvYsyee78rKI3GshjHpenVS9LnFJXY\0"; #char *get_dropbox_api_key(){ #return "key\0"; diff --git a/src/keystrokeEditor/__init__.py b/src/keystrokeEditor/__init__.py index b8cf7680..10ba64c2 100644 --- a/src/keystrokeEditor/__init__.py +++ b/src/keystrokeEditor/__init__.py @@ -1,3 +1,3 @@ from __future__ import absolute_import from __future__ import unicode_literals -from .keystrokeEditor import KeystrokeEditor \ No newline at end of file +from .keystrokeEditor import KeystrokeEditor diff --git a/src/keystrokeEditor/constants.py b/src/keystrokeEditor/constants.py index 47cc0e97..2d176ac1 100644 --- a/src/keystrokeEditor/constants.py +++ b/src/keystrokeEditor/constants.py @@ -1,60 +1,61 @@ # -*- 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"), -"left": _(u"Go to the previous buffer"), -"right": _(u"Go to the next buffer"), -"next_account": _(u"Focus the next session"), -"previous_account": _(u"Focus the previous session"), -"show_hide": _(u"Show or hide the GUI"), -"post_tweet": _(u"New tweet"), -"post_reply": _(u"Reply"), -"post_retweet": _(u"Retweet"), -"send_dm": _(u"Send direct message"), -"add_to_favourites": _(u"Like a tweet"), -"toggle_like": _(u"Like/unlike a tweet"), -"remove_from_favourites": _(u"Unlike a tweet"), -"follow": _(u"Open the user actions dialogue"), -"user_details": _(u"See user details"), -"view_item": _(u"Show tweet"), -"exit": _(u"Quit"), -"open_timeline": _(u"Open user timeline"), -"remove_buffer": _(u"Destroy buffer"), -"interact": _(u"Interact with the currently focused tweet."), -"url": _(u"Open URL"), -"open_in_browser": _(u"View in Twitter"), -"volume_up": _(u"Increase volume by 5%"), -"volume_down": _(u"Decrease volume by 5%"), -"go_home": _(u"Jump to the first element of a buffer"), -"go_end": _(u"Jump to the last element of the current buffer"), -"go_page_up": _(u"Jump 20 elements up in the current buffer"), -"go_page_down": _(u"Jump 20 elements down in the current buffer"), -"update_profile": _(u"Edit profile"), -"delete": _(u"Delete a tweet or direct message"), -"clear_buffer": _(u"Empty the current buffer"), -"repeat_item": _(u"Repeat last item"), -"copy_to_clipboard": _(u"Copy to clipboard"), -"add_to_list": _(u"Add to list"), -"remove_from_list": _(u"Remove from list"), -"toggle_buffer_mute": _(u"Mute/unmute the active buffer"), -"toggle_session_mute": _(u"Mute/unmute the current session"), -"toggle_autoread": _(u"toggle the automatic reading of incoming tweets in the active buffer"), -"search": _(u"Search on twitter"), -"find": _(u"Find a string in the currently focused buffer"), -"edit_keystrokes": _(u"Show the keystroke editor"), -"view_user_lists": _(u"Show lists for a specified user"), -"get_more_items": _(u"load previous items"), -"reverse_geocode": _(u"Get geolocation"), -"view_reverse_geocode": _(u"Display the tweet's geolocation in a dialog"), -"get_trending_topics": _(u"Create a trending topics buffer"), -"open_conversation": _(u"View conversation"), -"check_for_updates": _(u"Check and download updates"), -"lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."), -"configuration": _(u"Opens the global settings dialogue"), -"list_manager": _(u"Opens the list manager"), -"accountConfiguration": _(u"Opens the account settings dialogue"), -"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."), -} \ No newline at end of file + "up": _(u"Go up in the current buffer"), + "down": _(u"Go down in the current buffer"), + "left": _(u"Go to the previous buffer"), + "right": _(u"Go to the next buffer"), + "next_account": _(u"Focus the next session"), + "previous_account": _(u"Focus the previous session"), + "show_hide": _(u"Show or hide the GUI"), + "post_tweet": _(u"New tweet"), + "post_reply": _(u"Reply"), + "post_retweet": _(u"Retweet"), + "send_dm": _(u"Send direct message"), + "add_to_favourites": _(u"Like a tweet"), + "toggle_like": _(u"Like/unlike a tweet"), + "remove_from_favourites": _(u"Unlike a tweet"), + "follow": _(u"Open the user actions dialogue"), + "user_details": _(u"See user details"), + "view_item": _(u"Show tweet"), + "exit": _(u"Quit"), + "open_timeline": _(u"Open user timeline"), + "remove_buffer": _(u"Destroy buffer"), + "interact": _(u"Interact with the currently focused tweet."), + "url": _(u"Open URL"), + "open_in_browser": _(u"View in Twitter"), + "volume_up": _(u"Increase volume by 5%"), + "volume_down": _(u"Decrease volume by 5%"), + "go_home": _(u"Jump to the first element of a buffer"), + "go_end": _(u"Jump to the last element of the current buffer"), + "go_page_up": _(u"Jump 20 elements up in the current buffer"), + "go_page_down": _(u"Jump 20 elements down in the current buffer"), + "update_profile": _(u"Edit profile"), + "delete": _(u"Delete a tweet or direct message"), + "clear_buffer": _(u"Empty the current buffer"), + "repeat_item": _(u"Repeat last item"), + "copy_to_clipboard": _(u"Copy to clipboard"), + "add_to_list": _(u"Add to list"), + "remove_from_list": _(u"Remove from list"), + "toggle_buffer_mute": _(u"Mute/unmute the active buffer"), + "toggle_session_mute": _(u"Mute/unmute the current session"), + "toggle_autoread": _(u"toggle the automatic reading of incoming tweets in the active buffer"), + "search": _(u"Search on twitter"), + "find": _(u"Find a string in the currently focused buffer"), + "edit_keystrokes": _(u"Show the keystroke editor"), + "view_user_lists": _(u"Show lists for a specified user"), + "get_more_items": _(u"load previous items"), + "reverse_geocode": _(u"Get geolocation"), + "view_reverse_geocode": _(u"Display the tweet's geolocation in a dialog"), + "get_trending_topics": _(u"Create a trending topics buffer"), + "open_conversation": _(u"View conversation"), + "check_for_updates": _(u"Check and download updates"), + "lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."), + "configuration": _(u"Opens the global settings dialogue"), + "list_manager": _(u"Opens the list manager"), + "accountConfiguration": _(u"Opens the account settings dialogue"), + "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"), +} + \ No newline at end of file diff --git a/src/keystrokeEditor/keystrokeEditor.py b/src/keystrokeEditor/keystrokeEditor.py index 215ed404..1af14b23 100644 --- a/src/keystrokeEditor/keystrokeEditor.py +++ b/src/keystrokeEditor/keystrokeEditor.py @@ -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 @@ -9,53 +6,65 @@ from . import constants from pubsub import pub class KeystrokeEditor(object): - def __init__(self): - super(KeystrokeEditor, self).__init__() - self.changed = False # Change it if the keyboard shorcuts are reassigned. - self.dialog = wx_ui.keystrokeEditorDialog() - self.map = config.keymap["keymap"] - # we need to copy the keymap before modify it, for unregistering the old keystrokes if is needed. - 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.execute, widgetUtils.BUTTON_PRESSED, self.execute_action) - self.dialog.get_response() + def __init__(self): + super(KeystrokeEditor, self).__init__() + self.changed = False # Change it if the keyboard shorcuts are reassigned. + self.dialog = wx_ui.keystrokeEditorDialog() + self.map = config.keymap["keymap"] + # we need to copy the keymap before modify it, for unregistering the old keystrokes if is needed. + 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() - def edit_keystroke(self, *args, **kwargs): - action = self.dialog.actions[self.dialog.get_action()] - edit_dialog = wx_ui.editKeystrokeDialog() - self.set_keystroke(self.map[action], edit_dialog) - answer = edit_dialog.get_response() - if answer == widgetUtils.OK: - new_keystroke = self.get_edited_keystroke(edit_dialog) - if new_keystroke != self.map[action]: - self.changed = True - self.map[action] = new_keystroke - self.dialog.put_keystrokes(constants.actions, self.map) + def edit_keystroke(self, *args, **kwargs): + action = self.dialog.actions[self.dialog.get_action()] + edit_dialog = wx_ui.editKeystrokeDialog() + self.set_keystroke(self.map[action], edit_dialog) + answer = edit_dialog.get_response() + if answer == widgetUtils.OK: + new_keystroke = self.get_edited_keystroke(edit_dialog) + if new_keystroke != self.map[action]: + self.changed = True + self.map[action] = new_keystroke + self.dialog.put_keystrokes(constants.actions, self.map) - def set_keystroke(self, keystroke, dialog): - for i in keystroke.split("+"): - if hasattr(dialog, i): - dialog.set(i, True) - dialog.set("key", keystroke.split("+")[-1]) + 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 get_edited_keystroke(self, dialog): - keys = [] - if dialog.get("control") == True: - keys.append("control") - if dialog.get("win") == True: - keys.append("win") - if dialog.get("alt") == True: - keys.append("alt") - if dialog.get("shift") == True: - keys.append("shift") - if dialog.get("key") != "": - keys.append(dialog.get("key")) - else: - wx_ui.no_key() - return - return "+".join(keys) + def set_keystroke(self, keystroke, dialog): + for i in keystroke.split("+"): + if hasattr(dialog, i): + dialog.set(i, True) + dialog.set("key", keystroke.split("+")[-1]) - def execute_action(self, *args, **kwargs): - action = self.dialog.actions[self.dialog.get_action()] - pub.sendMessage("execute-action", action=action) \ No newline at end of file + def get_edited_keystroke(self, dialog): + keys = [] + if dialog.get("control") == True: + keys.append("control") + if dialog.get("win") == True: + keys.append("win") + if dialog.get("alt") == True: + keys.append("alt") + if dialog.get("shift") == True: + keys.append("shift") + if dialog.get("key") != "": + keys.append(dialog.get("key")) + else: + wx_ui.no_key() + return + return "+".join(keys) + + def execute_action(self, *args, **kwargs): + action = self.dialog.actions[self.dialog.get_action()] + pub.sendMessage("execute-action", action=action) diff --git a/src/keystrokeEditor/wx_ui.py b/src/keystrokeEditor/wx_ui.py index 7fd7c5c0..ddb2e6a5 100644 --- a/src/keystrokeEditor/wx_ui.py +++ b/src/keystrokeEditor/wx_ui.py @@ -1,82 +1,87 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals import wx from multiplatform_widgets import widgets from wxUI.dialogs import baseDialog class keystrokeEditorDialog(baseDialog.BaseWXDialog): - def __init__(self): - super(keystrokeEditorDialog, self).__init__(parent=None, id=-1, title=_(u"Keystroke editor")) - panel = wx.Panel(self) - self.actions = [] - sizer = wx.BoxSizer(wx.VERTICAL) - keysText = wx.StaticText(panel, -1, _(u"Select a keystroke to edit")) - self.keys = widgets.list(self, _(u"Action"), _(u"Keystroke"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(400, 450)) - self.keys.list.SetFocus() - firstSizer = wx.BoxSizer(wx.HORIZONTAL) - firstSizer.Add(keysText, 0, wx.ALL, 5) - firstSizer.Add(self.keys.list, 0, wx.ALL, 5) - self.edit = wx.Button(panel, -1, _(u"Edit")) - self.edit.SetDefault() - self.execute = wx.Button(panel, -1, _(u"Execute action")) - close = wx.Button(panel, wx.ID_CANCEL, _(u"Close")) - secondSizer = wx.BoxSizer(wx.HORIZONTAL) - secondSizer.Add(self.edit, 0, wx.ALL, 5) - secondSizer.Add(self.execute, 0, wx.ALL, 5) - secondSizer.Add(close, 0, wx.ALL, 5) - sizer.Add(firstSizer, 0, wx.ALL, 5) - sizer.Add(secondSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(keystrokeEditorDialog, self).__init__(parent=None, id=-1, title=_(u"Keystroke editor")) + panel = wx.Panel(self) + self.actions = [] + sizer = wx.BoxSizer(wx.VERTICAL) + keysText = wx.StaticText(panel, -1, _(u"Select a keystroke to edit")) + self.keys = widgets.list(self, _(u"Action"), _(u"Keystroke"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(400, 450)) + self.keys.list.SetFocus() + firstSizer = wx.BoxSizer(wx.HORIZONTAL) + firstSizer.Add(keysText, 0, wx.ALL, 5) + 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) + secondSizer.Add(self.edit, 0, wx.ALL, 5) + secondSizer.Add(self.execute, 0, wx.ALL, 5) + secondSizer.Add(close, 0, wx.ALL, 5) + sizer.Add(firstSizer, 0, wx.ALL, 5) + sizer.Add(secondSizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def put_keystrokes(self, actions, keystrokes): - selection = self.keys.get_selected() - self.keys.clear() - for i in keystrokes: - if (i in actions) == False: - continue - action = actions[i] - self.actions.append(i) - keystroke = keystrokes[i] - self.keys.insert_item(False, *[action, keystroke]) - self.keys.select_item(selection) + def put_keystrokes(self, actions, keystrokes): + selection = self.keys.get_selected() + self.keys.clear() + for i in keystrokes: + if (i in actions) == False: + continue + action = actions[i] + self.actions.append(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 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")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.control = wx.CheckBox(panel, -1, _(u"Control")) - self.alt = wx.CheckBox(panel, -1, _(u"Alt")) - self.shift = wx.CheckBox(panel, -1, _(u"Shift")) - self.win = wx.CheckBox(panel, -1, _(u"Windows")) - sizer1 = wx.BoxSizer(wx.HORIZONTAL) - sizer1.Add(self.control) - sizer1.Add(self.alt) - sizer1.Add(self.shift) - sizer1.Add(self.win) - charLabel = wx.StaticText(panel, -1, _(u"Key")) - self.key = wx.TextCtrl(panel, -1) - sizer2 = wx.BoxSizer(wx.HORIZONTAL) - sizer2.Add(charLabel) - sizer2.Add(self.key) - ok = wx.Button(panel, wx.ID_OK, _(u"OK")) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL) - sizer3 = wx.BoxSizer(wx.HORIZONTAL) - sizer3.Add(ok) - sizer3.Add(cancel) - sizer.Add(sizer1) - sizer.Add(sizer2) - sizer.Add(sizer3) - panel.SetSizerAndFit(sizer) + def __init__(self): + super(editKeystrokeDialog, self).__init__(parent=None, id=-1, title=_(u"Editing keystroke")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.control = wx.CheckBox(panel, -1, _(u"Control")) + self.alt = wx.CheckBox(panel, -1, _(u"Alt")) + self.shift = wx.CheckBox(panel, -1, _(u"Shift")) + self.win = wx.CheckBox(panel, -1, _(u"Windows")) + sizer1 = wx.BoxSizer(wx.HORIZONTAL) + sizer1.Add(self.control) + sizer1.Add(self.alt) + sizer1.Add(self.shift) + sizer1.Add(self.win) + charLabel = wx.StaticText(panel, -1, _(u"Key")) + self.key = wx.TextCtrl(panel, -1) + sizer2 = wx.BoxSizer(wx.HORIZONTAL) + sizer2.Add(charLabel) + sizer2.Add(self.key) + ok = wx.Button(panel, wx.ID_OK, _(u"OK")) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL) + sizer3 = wx.BoxSizer(wx.HORIZONTAL) + sizer3.Add(ok) + sizer3.Add(cancel) + sizer.Add(sizer1) + sizer.Add(sizer2) + sizer.Add(sizer3) + panel.SetSizerAndFit(sizer) def no_win_message(): - return wx.MessageDialog(None, _(u"You need to use the Windows key"), _(u"Invalid keystroke"), wx.OK|wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"You need to use the Windows key"), _(u"Invalid keystroke"), wx.OK|wx.ICON_ERROR).ShowModal() def no_key(): - return wx.MessageDialog(None, _(u"You must provide a character for the keystroke"), _(u"Invalid keystroke"), wx.ICON_ERROR).ShowModal() \ No newline at end of file + return wx.MessageDialog(None, _(u"You must provide a character for the keystroke"), _(u"Invalid keystroke"), wx.ICON_ERROR).ShowModal() diff --git a/src/languageHandler.py b/src/languageHandler.py index d17aa61b..b0ea7fb5 100644 --- a/src/languageHandler.py +++ b/src/languageHandler.py @@ -12,7 +12,7 @@ import gettext import paths import platform import application - + #a few Windows locale constants LOCALE_SLANGUAGE=0x2 LOCALE_SLANGDISPLAYNAME=0x6f @@ -20,195 +20,195 @@ LOCALE_SLANGDISPLAYNAME=0x6f curLang="en" def localeNameToWindowsLCID(localeName): - """Retreave the Windows locale identifier (LCID) for the given locale name - @param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage - @type localeName: string - @returns: a Windows LCID - @rtype: integer - """ - #Windows Vista is able to convert locale names to LCIDs - func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None) - if func_LocaleNameToLCID is not None: - localeName=localeName.replace('_','-') - LCID=func_LocaleNameToLCID(str(localeName),0) - else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID - localeName=locale.normalize(localeName) - if '.' in localeName: - localeName=localeName.split('.')[0] - LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName] - if len(LCList)>0: - LCID=LCList[0] - else: - LCID=0 - return LCID + """Retreave the Windows locale identifier (LCID) for the given locale name + @param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage + @type localeName: string + @returns: a Windows LCID + @rtype: integer + """ + #Windows Vista is able to convert locale names to LCIDs + func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None) + if func_LocaleNameToLCID is not None: + localeName=localeName.replace('_','-') + LCID=func_LocaleNameToLCID(str(localeName),0) + else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID + localeName=locale.normalize(localeName) + if '.' in localeName: + localeName=localeName.split('.')[0] + LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName] + if len(LCList)>0: + LCID=LCList[0] + else: + LCID=0 + return LCID def getLanguageDescription(language): - """Finds out the description (localized full name) of a given local name""" - desc=None - if platform.system() == "Windows": - LCID=localeNameToWindowsLCID(language) - if LCID!=0: - buf=ctypes.create_unicode_buffer(1024) - if '_' not in language: - res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024) - else: - res=0 - if res==0: - res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024) - desc=buf.value - elif platform.system() == "Linux" or not desc: - desc={ - "am":pgettext("languageName","Amharic"), - "an":pgettext("languageName","Aragonese"), - "es":pgettext("languageName","Spanish"), - "pt":pgettext("languageName","Portuguese"), - "ru":pgettext("languageName","Russian"), - "it":pgettext("languageName","italian"), - "tr":pgettext("languageName","Turkey"), - "gl":pgettext("languageName","Galician"), - "ca":pgettext("languageName","Catala"), - "eu":pgettext("languageName","Vasque"), - "pl":pgettext("languageName","polish"), - "ar":pgettext("languageName","Arabic"), - "ne":pgettext("languageName","Nepali"), - "sr":pgettext("languageName","Serbian (Latin)"), - "ja":pgettext("languageName","Japanese"), - }.get(language,None) - return desc + """Finds out the description (localized full name) of a given local name""" + desc=None + if platform.system() == "Windows": + LCID=localeNameToWindowsLCID(language) + if LCID!=0: + buf=ctypes.create_unicode_buffer(1024) + if '_' not in language: + res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024) + else: + res=0 + if res==0: + res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024) + desc=buf.value + elif platform.system() == "Linux" or not desc: + desc={ + "am":pgettext("languageName","Amharic"), + "an":pgettext("languageName","Aragonese"), + "es":pgettext("languageName","Spanish"), + "pt":pgettext("languageName","Portuguese"), + "ru":pgettext("languageName","Russian"), + "it":pgettext("languageName","italian"), + "tr":pgettext("languageName","Turkey"), + "gl":pgettext("languageName","Galician"), + "ca":pgettext("languageName","Catala"), + "eu":pgettext("languageName","Vasque"), + "pl":pgettext("languageName","polish"), + "ar":pgettext("languageName","Arabic"), + "ne":pgettext("languageName","Nepali"), + "sr":pgettext("languageName","Serbian (Latin)"), + "ja":pgettext("languageName","Japanese"), + }.get(language,None) + return desc def getAvailableLanguages(): - """generates a list of locale names, plus their full localized language and country names. - @rtype: list of tuples - """ - #Make a list of all the locales found in NVDA's locale dir - l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')] - l=[x for x in l if os.path.isfile(os.path.join(paths.locale_path(), '%s/LC_MESSAGES/%s.po' % (x, application.short_name)))] - #Make sure that en (english) is in the list as it may not have any locale files, but is default - if 'en' not in l: - l.append('en') - l.sort() - #For each locale, ask Windows for its human readable display name - d=[] - for i in l: - desc=getLanguageDescription(i) - label="%s, %s"%(desc,i) if desc else i - d.append(label) - #include a 'user default, windows' language, which just represents the default language for this user account - l.append("system") - # Translators: the label for the Windows default NVDA interface language. - d.append(_("User default")) - #return a zipped up version of both the lists (a list with tuples of locale,label) - return list(zip(l,d)) + """generates a list of locale names, plus their full localized language and country names. + @rtype: list of tuples + """ + #Make a list of all the locales found in NVDA's locale dir + l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')] + l=[x for x in l if os.path.isfile(os.path.join(paths.locale_path(), '%s/LC_MESSAGES/%s.po' % (x, application.short_name)))] + #Make sure that en (english) is in the list as it may not have any locale files, but is default + if 'en' not in l: + l.append('en') + l.sort() + #For each locale, ask Windows for its human readable display name + d=[] + for i in l: + desc=getLanguageDescription(i) + label="%s, %s"%(desc,i) if desc else i + d.append(label) + #include a 'user default, windows' language, which just represents the default language for this user account + l.append("system") + # Translators: the label for the Windows default NVDA interface language. + d.append(_("User default")) + #return a zipped up version of both the lists (a list with tuples of locale,label) + return list(zip(l,d)) def makePgettext(translations): - """Obtaina pgettext function for use with a gettext translations instance. - pgettext is used to support message contexts, - but Python 2.7's gettext module doesn't support this, - so NVDA must provide its own implementation. - """ - if isinstance(translations, gettext.GNUTranslations): - def pgettext(context, message): - message = str(message) - try: - # Look up the message with its context. - return translations._catalog["%s\x04%s" % (context, message)] - except KeyError: - return message - else: - def pgettext(context, message): - return str(message) - return pgettext + """Obtaina pgettext function for use with a gettext translations instance. + pgettext is used to support message contexts, + but Python 2.7's gettext module doesn't support this, + so NVDA must provide its own implementation. + """ + if isinstance(translations, gettext.GNUTranslations): + def pgettext(context, message): + message = str(message) + try: + # Look up the message with its context. + return translations._catalog["%s\x04%s" % (context, message)] + except KeyError: + return message + else: + def pgettext(context, message): + return str(message) + return pgettext def setLanguage(lang): - system = platform.system() - global curLang - try: - if lang=="system": - if system == "Windows": - windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage() - localeName=locale.windows_locale[windowsLCID] - elif system == "Darwin": - import Foundation - localeName = Foundation.NSLocale.currentLocale().identifier() - elif system == "Linux": - localeName = locale.getdefaultlocale()[0] - trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName]) - curLang=localeName + system = platform.system() + global curLang + try: + if lang=="system": + if system == "Windows": + windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage() + localeName=locale.windows_locale[windowsLCID] + elif system == "Darwin": + import Foundation + localeName = Foundation.NSLocale.currentLocale().identifier() + elif system == "Linux": + localeName = locale.getdefaultlocale()[0] + trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName]) + curLang=localeName # else: # localeName=locale.getdefaultlocale()[0] # trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName]) # curLang=localeName - else: - trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang]) - curLang=lang - localeChanged=False - #Try setting Python's locale to lang + else: + trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang]) + curLang=lang + localeChanged=False + #Try setting Python's locale to lang # try: - if system == "Windows": - locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang)) - localeChanged=True - else: - locale.setlocale(locale.LC_ALL, lang) - localeChanged=True + if system == "Windows": + locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang)) + localeChanged=True + else: + locale.setlocale(locale.LC_ALL, lang) + localeChanged=True # except: # pass - if not localeChanged and '_' in lang: - #Python couldn'tsupport the language_country locale, just try language. - try: - locale.setlocale(locale.LC_ALL, lang.split('_')[0]) - except: - pass - #Set the windows locale for this thread (NVDA core) to this locale. - if system == "Windows": - LCID=localeNameToWindowsLCID(lang) - ctypes.windll.kernel32.SetThreadLocale(LCID) - except IOError: - trans=gettext.translation(application.short_name, fallback=True) - curLang="en" - if sys.version[0] == "3": - trans.install() - else: - trans.install(unicode=True) - # Install our pgettext function. + if not localeChanged and '_' in lang: + #Python couldn'tsupport the language_country locale, just try language. + try: + locale.setlocale(locale.LC_ALL, lang.split('_')[0]) + except: + pass + #Set the windows locale for this thread (NVDA core) to this locale. + if system == "Windows": + LCID=localeNameToWindowsLCID(lang) + ctypes.windll.kernel32.SetThreadLocale(LCID) + except IOError: + trans=gettext.translation(application.short_name, fallback=True) + curLang="en" + if sys.version[0] == "3": + trans.install() + else: + trans.install(unicode=True) + # Install our pgettext function. # __builtin__.__dict__["pgettext"] = makePgettext(trans) def getLanguage(): - return curLang + return curLang def normalizeLanguage(lang): - """ - Normalizes a language-dialect string in to a standard form we can deal with. - Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase. - """ - lang=lang.replace('-','_') - ld=lang.split('_') - ld[0]=ld[0].lower() - #Filter out meta languages such as x-western - if ld[0]=='x': - return None - if len(ld)>=2: - ld[1]=ld[1].upper() - return "_".join(ld) + """ + Normalizes a language-dialect string in to a standard form we can deal with. + Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase. + """ + lang=lang.replace('-','_') + ld=lang.split('_') + ld[0]=ld[0].lower() + #Filter out meta languages such as x-western + if ld[0]=='x': + return None + if len(ld)>=2: + ld[1]=ld[1].upper() + return "_".join(ld) def langToWindowsLocale(lang): - languages = {"en": "eng", - "ar": "ara", - "ca": "cat", -"de": "deu", - "es": "esp", - "fi": "fin", - "fr": "fre_FRA", - "gl": "glc", - "eu": "euq", - "hu": "hun", - "hr": "hrv", - "it": "ita", - "ja": "jpn", - "pl": "plk", - "pt": "ptb", - "ru": "rus", - "tr": "trk", - "sr": "eng", - } - return languages[lang] + languages = {"en": "eng", + "ar": "ara", + "ca": "cat", + "de": "deu", + "es": "esp", + "fi": "fin", + "fr": "fre_FRA", + "gl": "glc", + "eu": "euq", + "hu": "hun", + "hr": "hrv", + "it": "ita", + "ja": "jpn", + "pl": "plk", + "pt": "ptb", + "ru": "rus", + "tr": "trk", + "sr": "eng", + } + return languages[lang] diff --git a/src/locales/ca/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po b/src/locales/ca/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po deleted file mode 100644 index 00ed6817..00000000 --- a/src/locales/ca/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po +++ /dev/null @@ -1,4187 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2018-08-08 18:22+0200\n" -"Last-Translator: Manuel Cortez \n" -"Language-Team: Fran Torres Gallego \n" -"Language: ca\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.1.1\n" -"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-SourceCharset: UTF-8\n" - -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Foto" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "El buffer actual no suporta aquesta acció" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "Principal" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "Mencions" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "Missatges directes" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "Missatges directes enviats" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "Tuits enviats" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "Tuits que m'agraden." - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "Seguidors" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Amics" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "Usuaris bloquejats" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "Usuaris silenciats" - -#: ../src\controller\buffers\twitterBuffers.py:75 -#, fuzzy -msgid "{username}'s timeline" -msgstr "Obrir línia temporal" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:83 -#, fuzzy -msgid "Unknown buffer" -msgstr "Desconegut" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "Tuit" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "Escriu el tuit aquí" - -#: ../src\controller\buffers\twitterBuffers.py:194 -#, fuzzy -msgid "New tweet in {0}" -msgstr "Tuit nou" - -#: ../src\controller\buffers\twitterBuffers.py:197 -#, fuzzy -msgid "{0} new tweets in {1}." -msgstr "@{0} Ha citat el teu tuit: {1}" - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s elements descarregats" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Aquest buffer no es una liniatemporal; no es pot eliminar." - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "Respondre a {arg0}" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "Respondre" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "Respondre a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Missatge directe a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "Nou missatge directe" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "Afegeix el teu comentari al tuit" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "citar" - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "Obrint URL..." - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "Detalls de l'usuari" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "Mencionar a %s" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "Menció" - -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy -msgid "{0} new direct messages." -msgstr "Nou missatge directe" - -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy -msgid "This action is not supported in the buffer yet." -msgstr "El buffer actual no suporta aquesta acció" - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy -msgid "{0} new followers." -msgstr "Nou seguidor." - -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy -msgid "This action is not supported in the buffer, yet." -msgstr "El buffer actual no suporta aquesta acció" - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "Llest." - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "Línies temporals" - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "Línia temporal per a {}" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "Línies temporals de tuits que m'agraden" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "Tuits que agraden a {}" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Línies temporals de seguidors." - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "Seguidors de {}" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Línies temporals d'amics" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "Amics de {}" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "Llistes" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "Llista per {}" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "Recerques" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "Cercar per {}" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "Tendències de %s" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "" -"No hi ha cap sessió en el focus. Focalitza una sessió amb les dreceres " -"d'anterior o següent sessió." - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "Buidar buffer." - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0} no s'ha trobat." - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "No es poden aplicar filtres a aquest bufer" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "Selecciona l'usuari" - -#: ../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" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "Conversa amb {0}" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "En aquest tuit no hi ha coordenades." - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "No hi ha resultats per a les coordenades d'aquest tuit." - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "Error decodificant les coordenades. Si et plau, prova-ho més tard." - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s, %s de %s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%s. buit" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: No s'ha iniciat sessió a Twitter amb aquest compte" - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s de %s" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: No s'ha iniciat sessió a Twitter amb aquest compte" - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Esdeveniments" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "Aquesta llista ja està oberta." - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"Alguna cosa inesperada ha passat quan s'intentaba reportar el teu problema. " -"Si et plau, prova-ho de nou més tard." - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "La lectura automàtica de tuits per a aquest buffer està activada." - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "La lectura automàtica de tuits per a aquest buffer està desactivada." - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "Silenci de sessió activat" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "Silenci de sessió desactivat." - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "Silenci de buffer activat" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "Silenci de buffer desactivat" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "Copiat" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "No es pot actualitzar aquest buffer." - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "Actualitzant buffer..." - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0} elements descarregats." - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "Bufer invàlid." - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Aquest twit no contè imatges." - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "Imatge de {0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "Selecciona una imatge." - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "No es pot extreure el text." - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "Traduït" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "No hi ha cap adreça per escurçar." - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "Adreça escurçada." - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "No hi ha cap adreça per expandir." - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "Adreça expandida" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s de %d caracters" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s caracters" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "&Veure Element" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Conexió directa." - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "Pregunta" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "Retuiteja sense comentaris" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "Retuiteja amb comentaris" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "Configuració del compte per a %s" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "missatges directes" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "Error" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "Aquest 'usuari no existeix" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "L'usuari ha estat suspès" - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "Detalls per a %s" - -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "Descartat" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Nom d'usuari: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Nom: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Localització: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "Descripció: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "Sí" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "No" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "Protegit: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "Ja segueixes a {0}. " - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr "{0} et segueix" - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Seguidors: %s\n" -" Amics: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "Verificat: %s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "Tuits: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "m'agraden" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "No pots ignorar els missatges directes." - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "Adjuntant..." - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "&Continúa" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "Continúa" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "&Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "&Aturar" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "Grabant" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "Aturat" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "&Grabar" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "Reproduïnt..." - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "&Reproduir" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "Recodificant audio..." - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "Error al carregar el fitxer: {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "%d dia, " - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%d dies, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "%d hora, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d hores, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "%d minut, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d minuts, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "%s segon" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s segons" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "Fitxer" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "Transferit" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "Mida total del fitxer" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "Velocitat de transferencia" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "Temps restant" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "Adjuntar audio" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "&Afegir un fitxer existent" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "&Descartar" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "Enviar a:" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "Adjuntar" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "&Cancel·lar" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Arxius d'audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "Selecciona el fitxer d'audio que vols carregar" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "Tuit d'audio" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "S'ha creat el buffer de la linia temporal de l'usuari" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "Buffer eliminat" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Missatge directe rebut." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Missatge directe enviat." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "Error." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "Tuit marcat com m'agrada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "Buffer de tuits que m'agraden actualitzat" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "Geotuit" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "El twit contè una o més imatges." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "No hi ha més elements" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "Llista actualitzada" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "Massa caracters" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "Menció rebuda" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "Esdeveniment nou." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0} és a punt." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "Menció enviada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "Tuit retuitejat." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "Buffer de recerca actualitzat" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "Tuit rebut." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "Tuit enviat." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "Búfer de tendències actualitzat" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "Tuit nou a la línia temporal de l'usuari." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "Nou seguidor." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "Volum canviat" - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "Tutorial de sons" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "Prem enter per escoltar el so per al esdeveniment seleccionat." - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "Paraula mal escrita: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "Paraula mal escrita" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "Context" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "Sugeriments" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "&Ignorar" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "I&gnorar tot" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "R&eemplaçar" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "Reemplaçar t&ots." - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "A&fegir al diccionari personal" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"Hi ha hagut un problema. No hi ha diccionaris disponibles per a l'idioma " -"seleccionat a {0}." - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "Comprovació d'ortografia finalitzada" - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "Has de començar a escriure." - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "No hi ha resultats a la teva base de dades d'usuaris." - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "l'autocompletat només funciona per a usuaris." - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Actualitzant la base de dades... Pots tancar aquesta finestra, un nissatge " -"t'avisarà quan el procés hagi acabat." - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "Gestionar la base de dades d'autocompletar." - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "Editant la base de dades d'usuaris de {0}." - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "Nom d'usuari." - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Nom." - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "Afegir usuari." - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "Esborrar usuari." - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "Afegir usuari a la base de dades." - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "Nom d'usuari de Twitter." - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "L'usuari no existeix" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "Error!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Configuració d'autocompletar usuaris" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Afegir usuaris des del buffer de seguidors." - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Afegir usuaris des del buffer d'amics" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Gestionar base de dades..." - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "Fet" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "La base de dades d'usuaris de {0} s'ha actualitzat" - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "Detecció automàtica" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "Danès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "olandès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "Anglès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "Finès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "Francès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "Alemany" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "Hongarès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "Italià" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "Japonès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "Coreà" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "Polac" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "Portuguès" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "Rus" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "Espanyol" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "Turc" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "Africà" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "Albanès" - -#: ../src\extra\translator\translator.py:14 -msgid "Amharic" -msgstr "Amharic" - -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "Àrab" - -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "Armeni" - -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "Acerbajà" - -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "vasc" - -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "Bielorús" - -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "Bengali" - -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "Bùlgar" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "Birmà" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "Català" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "Cheroqui" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "xinès" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "xinèss simplificat" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "xinés tradicional" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "Croat" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "Txec" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "Esperanto" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "Estonià" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "Filipí" - -#: ../src\extra\translator\translator.py:40 -msgid "Galician" -msgstr "Gallec" - -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "Georgià" - -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "Grec" - -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "Guaraní" - -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "Guiaratí" - -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "Hebreu" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "Hindi" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "Islandès" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "Indonesi" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "Irlandès" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "Canarès" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "Kazakh" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "Camboià" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "Kurd" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "Kirguís" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "Lao" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "Letó" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "Lituà" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "Macedoni" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "Malai" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "Malayalam" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "Maltès" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "Maratí" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "Mongol" - -#: ../src\extra\translator\translator.py:70 -msgid "Nepali" -msgstr "Nepalí" - -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "Noruec" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr "Oriia" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "Pastú" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "Persa" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "Paniabí" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "Romanè" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "Sànstrit" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" -msgstr "Serbi" - -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "Sindhi" - -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "Cingalès" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "Eslovac" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "Esloveni" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "Suahili" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "Suec" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "Tajik" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "Tamil" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "Tagal" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "Telugú" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "Tailandès" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "tibetà" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "Ucraïnès" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "Uzbec" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "Uigur" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "Vietnamita" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "Galès" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "Yiddish" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "Traduir missatge" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "Llengua de destinació" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "General" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "Sempre" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "No s'ha provat." - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "aleatori" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "a vegades" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "Impossible duplicar." - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "bloquejar" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "error" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "característica" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "major" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "menor" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "text" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "Trivial" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "configuració" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "Reportar un problema" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "selecciona una categoria" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "" -"Descriu en poques paraules el que ha passat. Desprès podràs explicar-ho més " -"profundament" - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "Aquí pots descriure amb detall el problema" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "Amb quina freqüència té lloc aquest error?" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "Selecciona la importància que creus que té aquest bug del programa" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Entenc que el sistema de bugs de {0} obtindrà el meu nom d'usuari per " -"contactar-me i solucionar el bug ràpidament." - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "Enviar report" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "Cancel·lar" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "Has d'omplir els dos camps" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Cal que marquis la casella per facilitar-nos el teu nom d'usuari de Twitter, " -"per poder-te contactar si és necessari." - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"Gracies per reportar aquest problema! Tant de bó puguis veure'l entre la " -"llista de millores de pròximes versions. Has reportat el problema nombre %i" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "Reportat" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "Error reportant" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Alguna cosa inesperada ha passat quan s'intentaba reportar el teu problema. " -"Si et plau, prova-ho de nou més tard." - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Va amunt en el bufer actual" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "Va avall en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Anar al buffer anterior" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Anar al bufer següent" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Focalitza la sessió següent." - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Focalitza la sessió anterior." - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Veure o amagar la GUI" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Tuit nou" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Retuit" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Enviar Missatge Directe" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "t'agrada el tuit." - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "t'agrada/ja no t'agrada el twit" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Ja no t'agrada el tuit." - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Obrir el diàleg d'accions d'usuari" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Veure detalls de l'usuari" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Mostra el tuit" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "Sortir" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Obrir línia temporal" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Elimina el bufer." - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interactua amb el tuit seleccionat." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Obre adreça." - -#: ../src\keystrokeEditor\constants.py:25 -#, fuzzy -msgid "View in Twitter" -msgstr "Cerca a Twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Augmentar Volum 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Baixar Volum 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Vés al primer element del bufer actual." - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Vés a l'últim element del buffer actual." - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Vés 20 elements amunt en el buffer actual." - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Vés 20 elements avall en el bufer actual." - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Editar perfil" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Elimina un tuit o missatge directe." - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Buidar el buffer actual" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Repeteix l'últim ítem" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Copiar al portapapers" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Afegir a llista" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Eliminar de llista" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Activar o desactivar el silenci al buffer actual" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Activa o desactiva el silenci de la sessió actual" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "Commutar la lectura automàtica de tuits nous per a aquest buffer" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "Cerca a Twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Troba una cadena en el buffer focalitzat." - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Mostrar l'editor de combinacions de teclat" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Veure llistes de l'usuari específic" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "Carrega elements anteriors" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Obtenir la geolocalització" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Mostra en un diàleg la localització geográfica del tuit." - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Crear un buffer de tendències" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Veure conversa." - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "Cerca i descarrega actualitzacions" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Obre el gestor de llistes, que et permetrà crear, editar, eliminar i obrir " -"llistes en buffers." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Obre el diàleg de configuració global." - -#: ../src\keystrokeEditor\constants.py:54 -#, fuzzy -msgid "Opens the list manager" -msgstr "Gestor de llistes" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Obre el diàleg de configuració del compte." - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Provar de reproduir un arxiu d'audio" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Actualitza el buffer i carrega possibles elements perduts." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "Extreure el text d'una imatge i mostra'l en un diàleg." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Editor de combinacions de teclat" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Selecciona una combinació de teclat per editar-la" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "Combinació de teclat" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "Acció" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "Editar" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "Executar acció" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "Tancar" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "Editant combinació de tecles" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "Control" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "Shift" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "Finestres" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "Tecla" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "Acceptar" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "Necessites utilitzar la tecla Windows" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "Combinació de teclat invàlida" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "Has de triar una lletra per a la cominació ràpida de teclat" - -#: ../src\languageHandler.py:99 -msgid "User default" -msgstr "Usuari per defecte" - -#: ../src\main.py:105 -msgid "https://twblue.es/donate" -msgstr "https://twblue.es/donate" - -#: ../src\main.py:122 -msgid "" -"{0} is already running. Close the other instance before starting this one. " -"If you're sure that {0} isn't running, try deleting the file at {1}. If " -"you're unsure of how to do this, contact the {0} developers." -msgstr "" - -#: ../src\sessionmanager\wxUI.py:8 -msgid "Session manager" -msgstr "Gestor de sessions" - -#: ../src\sessionmanager\wxUI.py:11 -msgid "Accounts list" -msgstr "Llista de comptes" - -#: ../src\sessionmanager\wxUI.py:13 -msgid "Account" -msgstr "Compte" - -#: ../src\sessionmanager\wxUI.py:17 -msgid "New account" -msgstr "Compte nou." - -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 -msgid "Remove account" -msgstr "Esborrar compte." - -#: ../src\sessionmanager\wxUI.py:19 -msgid "Global Settings" -msgstr "Configuració global" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "Problema de compte" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "You need to configure an account." -msgstr "Necessites configurar un compte" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "Autorització" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "" -"The request to authorize your Twitter account will be opened in your " -"browser. You only need to do this once. Would you like to continue?" -msgstr "" -"La sol·licitud per autoritzar el teu compte de twitter sobrirà en el teu " -"navegador. Només has de fer això una vegada. Vols continuar?" - -#: ../src\sessionmanager\wxUI.py:52 -msgid "Authorized account %d" -msgstr "Compte autoritzat %d" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "Token d'usuari invàlid" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "" -"Your access token is invalid or the authorization has failed. Please try " -"again." -msgstr "" -"El codi d'autorització no és vàlid o el procés d'atorització ha fallat. Si " -"et plau, prova-ho més tard." - -#: ../src\sessionmanager\wxUI.py:64 -msgid "Do you really want to delete this account?" -msgstr "Realment vols eliminar aquest compte?" - -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 -msgid "dddd, MMMM D, YYYY H:m:s" -msgstr "dddd, MMMM D, YYYY H:m:s" - -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 -msgid "Dm to %s " -msgstr "dm a %s" - -#: ../src\sessions\twitter\compose.py:141 -msgid "{0}. Quoted tweet from @{1}: {2}" -msgstr "{0}. Tuit citat de @{1}: {2}" - -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 -msgid "Unavailable" -msgstr "No disponible" - -#: ../src\sessions\twitter\compose.py:166 -msgid "" -"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " -"Twitter %s" -msgstr "" -"%s (@%s). %s seguidors, %s amics, %s tuits. Últim tuit %s. Es va unir a " -"Twitter %s" - -#: ../src\sessions\twitter\compose.py:170 -msgid "No description available" -msgstr "No hi ha descripció disponible" - -#: ../src\sessions\twitter\compose.py:174 -msgid "private" -msgstr "Privat" - -#: ../src\sessions\twitter\compose.py:175 -msgid "public" -msgstr "Públic" - -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "En aquest tuit no hi ha coordenades." - -#: ../src\sessions\twitter\session.py:215 -msgid "%s failed. Reason: %s" -msgstr "%s ha fallat. Raó: %s" - -#: ../src\sessions\twitter\session.py:221 -msgid "%s succeeded." -msgstr "%s amb èxit" - -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "Ho sentim, no estas autoritzat per veure aquest estat" - -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "No s'ha trobat cap estat amb aquest ID" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "Codi d'error {0}" - -#: ../src\sessions\twitter\wxUI.py:6 -msgid "Authorising account..." -msgstr "Autoritzant el compte..." - -#: ../src\sessions\twitter\wxUI.py:9 -msgid "Enter your PIN code here" -msgstr "Introdueix el PIN aqui" - -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "Aturat." - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "Nova versió de %s" - -#: ../src\update\wxUpdater.py:10 -msgid "" -"There's a new %s version available, released on %s. Would you like to " -"download it now?\n" -"\n" -" %s version: %s\n" -"\n" -"Changes:\n" -"%s" -msgstr "" -"Hi ha una nova versió de %s disponible. T'agradaria descaregar-la ara?\n" -"\n" -" %s versió: %s\n" -"\n" -"Canvis:\n" -"%s" - -#: ../src\update\wxUpdater.py:18 -msgid "Download in Progress" -msgstr "Descàrrega en progrés" - -#: ../src\update\wxUpdater.py:18 -msgid "Downloading the new version..." -msgstr "Descarregant la nova versió" - -#: ../src\update\wxUpdater.py:28 -msgid "Updating... %s of %s" -msgstr "Actualitzant... %s of %s" - -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "Fet!" - -#: ../src\update\wxUpdater.py:31 -msgid "" -"The update has been downloaded and installed successfully. Press OK to " -"continue." -msgstr "" -"L'actualització s'ha descarregat i instal·lat correctament. Prem Acceptar " -"per continuar." - -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "Client" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Text" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "data" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "Usuari" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Missatge directe" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "Esdeveniment" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "Eliminar esdeveniment" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "connectar-se" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "Iniciar sessió automàticament" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "Desconnectar-se" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "Trending topic" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "Tuit sobre aquesta tendència" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "Cerca missatge" - -#: ../src\wxUI\commonMessageDialogs.py:6 -msgid "" -"This retweet is over 140 characters. Would you like to post it as a mention " -"to the poster with your comments and a link to the original tweet?" -msgstr "" -"Aquest tuit excedeix els 140 caracters. Vols publicar-lo com una menció a " -"l'usuari original amb els teus comentaris i un enllaç al twit original?" - -#: ../src\wxUI\commonMessageDialogs.py:9 -msgid "Would you like to add a comment to this tweet?" -msgstr "T'agradaria afegirun comentari a aquest tuit?" - -#: ../src\wxUI\commonMessageDialogs.py:12 -msgid "" -"Do you really want to delete this tweet? It will be deleted from Twitter as " -"well." -msgstr "" -"Estàs segur que vols eliminar aquest tuit? també s'eliminarà de Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 -msgid "Delete" -msgstr "Eliminar" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Do you really want to close {0}?" -msgstr "Estàs segur que vols tancar {0}?" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Exit" -msgstr "Sortir" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid " {0} must be restarted for these changes to take effect." -msgstr " {0} S'ha de reiniciar perquè els canvis facin efecte." - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid "Restart {0} " -msgstr "Reiniciar {0} " - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "" -"Are you sure you want to delete this user from the database? This user will " -"not appear in autocomplete results anymore." -msgstr "" -"Estàs segur de que vols eliminar aquest usuari de la base de dades? l'usuari " -"no apareixerà més als resultats d'autocompletar." - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "Confirm" -msgstr "Confirma" - -#: ../src\wxUI\commonMessageDialogs.py:25 -msgid "Enter the name of the client : " -msgstr "Introdueix el nom del client : " - -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 -msgid "Add client" -msgstr "Afegir client" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "" -"Do you really want to empty this buffer? It's items will be removed from " -"the list but not from Twitter" -msgstr "" -"Estàs segur de que vols buidar aquest buffer? Els tuits seràn eliminats de " -"la llista, però no de Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "Empty buffer" -msgstr "Buidar buffer" - -#: ../src\wxUI\commonMessageDialogs.py:35 -msgid "Do you really want to destroy this buffer?" -msgstr "Realment vols eliminar aquest buffer?" - -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Attention" -msgstr "Alerta" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "A timeline for this user already exists. You can't open another" -msgstr "" -"Ja hi ha una línia temporal per aquest usuari. No pots obrirne una altra." - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "Existing timeline" -msgstr "Linea temporal existent" - -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "This user has no tweets, so you can't open a timeline for them." -msgstr "" -"Aquest usuari no té tuits, per tant no pots obrir-ne una línia temporal." - -#: ../src\wxUI\commonMessageDialogs.py:47 -msgid "" -"This is a protected Twitter user, which means you can't open a timeline " -"using the Streaming API. The user's tweets will not update due to a twitter " -"policy. Do you want to continue?" -msgstr "" -"Aquest usuari està protegit, per tant no es pot obrir la seva línia temporal " -"utilitant la API de streaming. Els tuits de l'usuari no s'actualitzaran " -"degut a la política de Twitter. Vols continuar?" - -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "Warning" -msgstr "Avís" - -#: ../src\wxUI\commonMessageDialogs.py:50 -msgid "" -"This is a protected user account, you need to follow this user to view their " -"tweets or likes." -msgstr "" -"El compte d'aquest usuari està protegit, necessites seguir-lo per veure els " -"seus tuits o els tuits que li agraden." - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "" -"If you like {0} we need your help to keep it going. Help us by donating to " -"the project. This will help us pay for the server, the domain and some other " -"things to ensure that {0} will be actively maintained. Your donation will " -"give us the means to continue the development of {0}, and to keep {0} free. " -"Would you like to donate now?" -msgstr "" -"Si t'agrada {0}, necessitem la teva col·laboració perquè continui " -"funcionant, ens pots ajudar donant una quantitat al projecte. Això ens " -"ajudarà a pagar el servidor, el domini i altres aspectes que asseguraran un " -"manteniment més actiu de {0}. La teva donació ens empeny a continuar el " -"desenvolupament de {0}, i per fent que {0} sigui gratuit. Vols fer una " -"donació ara?" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "We need your help" -msgstr "Necessitem la teva ajuda" - -#: ../src\wxUI\commonMessageDialogs.py:57 -msgid "This user has no tweets. {0} can't create a timeline." -msgstr "Aquest usuari no té tuits. {0} no pot obrir la seva línia temporal." - -#: ../src\wxUI\commonMessageDialogs.py:60 -msgid "This user has no favorited tweets. {0} can't create a timeline." -msgstr "" -"Aquest usuari no té tuits favorits. {0} no pot obrir la seva línia temporal." - -#: ../src\wxUI\commonMessageDialogs.py:63 -msgid "This user has no followers. {0} can't create a timeline." -msgstr "Aquest usuari no té seguidors, {0} no pot obrir la línia temporal." - -#: ../src\wxUI\commonMessageDialogs.py:66 -msgid "This user has no friends. {0} can't create a timeline." -msgstr "Aquest usuari no té amics, {0} no pot obrir la línia temporal." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "Dades geogràfiques en aquest tuit." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geolocation data: {0}" -msgstr "Dades geográfiques: {0}. " - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "Informació" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "" -"TWBlue has detected that you're running windows 10 and has changed the " -"default keymap to the Windows 10 keymap. It means that some keyboard " -"shorcuts could be different. Please check the keystroke editor by pressing " -"Alt+Win+K to see all available keystrokes for this keymap." -msgstr "" -"TWBlue ha detectat que s'està executant Windows 10 i ha cambiat el mapa de " -"tecles per defecte al mapa de tecles Windows 10." - -#: ../src\wxUI\commonMessageDialogs.py:76 -msgid "You have been blocked from viewing this content" -msgstr "Vosté ha estat bloquejat per veure aquest contingut." - -#: ../src\wxUI\commonMessageDialogs.py:79 -msgid "" -"You have been blocked from viewing someone's content. In order to avoid " -"conflicts with the full session, TWBlue will remove the affected timeline." -msgstr "" -"Vostè ha estat bloquejat per veure alguns continguts. A la petició hi ha " -"confictes que afecten completament a la sessió. TWBlue eliminarà el fil " -"temporal afectat." - -#: ../src\wxUI\commonMessageDialogs.py:82 -msgid "" -"TWBlue cannot load this timeline because the user has been suspended from " -"Twitter." -msgstr "" -"TWBlue no pot carregar aquest time-line ja que l'usuari ha estat suspès de " -"twitter." - -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Do you really want to delete this filter?" -msgstr "Realment vols eliminar aquest filtre?" - -#: ../src\wxUI\commonMessageDialogs.py:88 -msgid "This filter already exists. Please use a different title" -msgstr "Aquest filtre ja existeix. Si us plau, utilitzeu un altre titol." - -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "" -"{0} quit unexpectedly the last time it was run. If the problem persists, " -"please report it to the {0} developers." -msgstr "" - -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Afegir adjunts" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Adjunts" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Titol" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Tipus" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Afegir un adjunt" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Foto" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "esborrar l'adjunt" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Fitxers d'imatge (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Selecciona la fotografia per carregar." - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Si et plau, proveeix d'una descripció" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Descripció" - -#: ../src\wxUI\dialogs\configuration.py:16 -msgid "Language" -msgstr "Idioma" - -#: ../src\wxUI\dialogs\configuration.py:23 -msgid "Run {0} at Windows startup" -msgstr "executar {0} quan Windows inicii" - -#: ../src\wxUI\dialogs\configuration.py:24 -msgid "ask before exiting {0}" -msgstr "Preguntar abans de sortir de {0}" - -#: ../src\wxUI\dialogs\configuration.py:27 -msgid "Disable Streaming functions" -msgstr "Desactivar les funcions de streaming" - -#: ../src\wxUI\dialogs\configuration.py:30 -msgid "Buffer update interval, in minutes" -msgstr "actualització del bufer, en minuts" - -#: ../src\wxUI\dialogs\configuration.py:36 -msgid "Play a sound when {0} launches" -msgstr "Reprodueix un so quan {0} s'inicii." - -#: ../src\wxUI\dialogs\configuration.py:38 -msgid "Speak a message when {0} launches" -msgstr "verbalitza un missatge quan {0} s'inicii." - -#: ../src\wxUI\dialogs\configuration.py:40 -msgid "Use invisible interface's keyboard shortcuts while GUI is visible" -msgstr "" -"Utilitzar les combinacions de tecles de la interfície invisible mentre la " -"guia està visible." - -#: ../src\wxUI\dialogs\configuration.py:42 -msgid "Activate Sapi5 when any other screen reader is not being run" -msgstr "Activar Sapi5 quan no hi ha un altre lector de pantalla funcionant" - -#: ../src\wxUI\dialogs\configuration.py:44 -msgid "Hide GUI on launch" -msgstr "Amagar guia al iniciar" - -#: ../src\wxUI\dialogs\configuration.py:46 -msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" -msgstr "" -"Lectura completa de tuits llargs (Pot disminuir la velocitat del " -"funcionament del client)." - -#: ../src\wxUI\dialogs\configuration.py:48 -msgid "Remember state for mention all and long tweet" -msgstr "Recordar l'estat de menció a tots en els twits llargs" - -#: ../src\wxUI\dialogs\configuration.py:51 -msgid "Keymap" -msgstr "Mapa de teclat" - -#: ../src\wxUI\dialogs\configuration.py:56 -msgid "Check for updates when {0} launches" -msgstr "Comprobar actualitzacións quan {0} s'inicii" - -#: ../src\wxUI\dialogs\configuration.py:66 -msgid "Proxy type: " -msgstr "Tipus de proxi." - -#: ../src\wxUI\dialogs\configuration.py:73 -msgid "Proxy server: " -msgstr "Servidor proxi: " - -#: ../src\wxUI\dialogs\configuration.py:79 -msgid "Port: " -msgstr "Port: " - -#: ../src\wxUI\dialogs\configuration.py:85 -msgid "User: " -msgstr "Usuari: " - -#: ../src\wxUI\dialogs\configuration.py:91 -msgid "Password: " -msgstr "Contrasenya: " - -#: ../src\wxUI\dialogs\configuration.py:103 -msgid "Autocompletion settings..." -msgstr "Configuració d'autocompletat..." - -#: ../src\wxUI\dialogs\configuration.py:105 -msgid "Relative timestamps" -msgstr "Temps relatius" - -#: ../src\wxUI\dialogs\configuration.py:108 -msgid "Items on each API call" -msgstr "Elements per cada trucada a la API" - -#: ../src\wxUI\dialogs\configuration.py:114 -msgid "" -"Inverted buffers: The newest tweets will be shown at the beginning while the " -"oldest at the end" -msgstr "" -"Buffers invertits: els nous tuits es mostraràn al inici de les llistes y els " -"antics al final" - -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet mode" -msgstr "Mode de Retuit" - -#: ../src\wxUI\dialogs\configuration.py:122 -msgid "Show screen names instead of full names" -msgstr "Mostrar el nom de pantalla dins del nom complert." - -#: ../src\wxUI\dialogs\configuration.py:124 -msgid "" -"Number of items per buffer to cache in database (0 to disable caching, blank " -"for unlimited)" -msgstr "" -"Nombre d'elements per bufer que s'emmagatzemaran a la base de dades (0 per " -"deshabilitar l'emagatzematge, en blanc per a ilimitat)." - -#: ../src\wxUI\dialogs\configuration.py:134 -msgid "Enable automatic speech feedback" -msgstr "Activar missatges parlats" - -#: ../src\wxUI\dialogs\configuration.py:136 -msgid "Enable automatic Braille feedback" -msgstr "Activar missatges en braille" - -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Estat" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Buffer" -msgstr "Bufer" - -#: ../src\wxUI\dialogs\configuration.py:147 -msgid "Show/hide" -msgstr "Mostra/amaga" - -#: ../src\wxUI\dialogs\configuration.py:148 -msgid "Move up" -msgstr "Moure amunt" - -#: ../src\wxUI\dialogs\configuration.py:149 -msgid "Move down" -msgstr "Moure avall" - -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 -msgid "Show" -msgstr "Mostra" - -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 -msgid "Hide" -msgstr "Amaga" - -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 -msgid "Select a buffer first." -msgstr "Primer has de seleccionar un buffer." - -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 -msgid "The buffer is hidden, show it first." -msgstr "El buffer està amagat, primer l'has de mostrar." - -#: ../src\wxUI\dialogs\configuration.py:175 -msgid "The buffer is already at the top of the list." -msgstr "El buffer ja és al capdamunt de la llista." - -#: ../src\wxUI\dialogs\configuration.py:199 -msgid "The buffer is already at the bottom of the list." -msgstr "El buffer ja es al capdavall de la llista." - -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 -msgid "Ignored clients" -msgstr "Clients ignorats" - -#: ../src\wxUI\dialogs\configuration.py:247 -msgid "Remove client" -msgstr "Esborrar client" - -#: ../src\wxUI\dialogs\configuration.py:271 -msgid "Volume" -msgstr "Volum." - -#: ../src\wxUI\dialogs\configuration.py:282 -msgid "Session mute" -msgstr "Silenci de sessió" - -#: ../src\wxUI\dialogs\configuration.py:284 -msgid "Output device" -msgstr "Dispositiu de sortida" - -#: ../src\wxUI\dialogs\configuration.py:291 -msgid "Input device" -msgstr "Dispositiu d'entrada" - -#: ../src\wxUI\dialogs\configuration.py:299 -msgid "Sound pack" -msgstr "Paquet de sons" - -#: ../src\wxUI\dialogs\configuration.py:305 -msgid "Indicate audio tweets with sound" -msgstr "Indica un twit d'audio mitjançant un só." - -#: ../src\wxUI\dialogs\configuration.py:307 -msgid "Indicate geotweets with sound" -msgstr "Indica un GeoTwit amb un só." - -#: ../src\wxUI\dialogs\configuration.py:309 -msgid "Indicate tweets containing images with sound" -msgstr "Indica els twits que continguin imatges amb un só." - -#: ../src\wxUI\dialogs\configuration.py:332 -msgid "Language for OCR" -msgstr "Idioma de l'OCR" - -#: ../src\wxUI\dialogs\configuration.py:338 -msgid "API Key for SndUp" -msgstr "Clau API per SndUp." - -#: ../src\wxUI\dialogs\configuration.py:353 -msgid "{0} preferences" -msgstr "Preferències de {0} " - -#: ../src\wxUI\dialogs\configuration.py:364 -msgid "Proxy" -msgstr "Proxi" - -#: ../src\wxUI\dialogs\configuration.py:373 -msgid "Feedback" -msgstr "Retroalimentació" - -#: ../src\wxUI\dialogs\configuration.py:377 -msgid "Buffers" -msgstr "Buffers" - -#: ../src\wxUI\dialogs\configuration.py:385 -msgid "Sound" -msgstr "So" - -#: ../src\wxUI\dialogs\configuration.py:389 -msgid "Extras" -msgstr "Extres." - -#: ../src\wxUI\dialogs\configuration.py:394 -msgid "Save" -msgstr "Desar" - -#: ../src\wxUI\dialogs\filterDialogs.py:15 -msgid "Create a filter for this buffer" -msgstr "Crear un filtre per aquest bufer" - -#: ../src\wxUI\dialogs\filterDialogs.py:16 -msgid "Filter title" -msgstr "Titol del filtre." - -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "Filtrar per paraula" - -#: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "Ignorar els twits amb la següent paraula" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -msgid "Ignore tweets without the following word" -msgstr "Ignorar els twits que no contenguin la següent paraula" - -#: ../src\wxUI\dialogs\filterDialogs.py:32 -msgid "word" -msgstr "paraula" - -#: ../src\wxUI\dialogs\filterDialogs.py:37 -msgid "Allow retweets" -msgstr "Permetre retwits" - -#: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "Permetre twits citats" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -msgid "Allow replies" -msgstr "Permetre respostes" - -#: ../src\wxUI\dialogs\filterDialogs.py:47 -msgid "Use this term as a regular expression" -msgstr "utilizar aquest termini com una expresió regular." - -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by language" -msgstr "filtrar per idioma" - -#: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "carregar els twits amb els següents idiomes" - -#: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "Ignorar els twits amb els següents idiomes" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 -msgid "Don't filter by language" -msgstr "No filtrar per idioma" - -#: ../src\wxUI\dialogs\filterDialogs.py:63 -msgid "Supported languages" -msgstr "Idiomes soporrtats" - -#: ../src\wxUI\dialogs\filterDialogs.py:68 -msgid "Add selected language to filter" -msgstr "Afegir l'idioma seleccionat a filtrar" - -#: ../src\wxUI\dialogs\filterDialogs.py:72 -msgid "Selected languages" -msgstr "Idiomes seleccionats" - -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 -msgid "Remove" -msgstr "Esborrar" - -#: ../src\wxUI\dialogs\filterDialogs.py:122 -msgid "Manage filters" -msgstr "Gestionar filtresGestionar compte" - -#: ../src\wxUI\dialogs\filterDialogs.py:124 -msgid "Filters" -msgstr "Filtres" - -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter" -msgstr "Filtre" - -#: ../src\wxUI\dialogs\find.py:12 -msgid "Find in current buffer" -msgstr "Troba en el buffer actual." - -#: ../src\wxUI\dialogs\find.py:13 -msgid "String" -msgstr "cadena" - -#: ../src\wxUI\dialogs\lists.py:10 -msgid "Lists manager" -msgstr "Gestor de llistes" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "List" -msgstr "Llista" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "Membres" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Owner" -msgstr "Propietari" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "mode" -msgstr "Manera" - -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 -msgid "Create a new list" -msgstr "Crear una nova llista" - -#: ../src\wxUI\dialogs\lists.py:21 -msgid "Open in buffer" -msgstr "Obrir en buffer" - -#: ../src\wxUI\dialogs\lists.py:51 -msgid "Viewing lists for %s" -msgstr "Veient les llistes de %s" - -#: ../src\wxUI\dialogs\lists.py:52 -msgid "Subscribe" -msgstr "Donar-se d'alta" - -#: ../src\wxUI\dialogs\lists.py:53 -msgid "Unsubscribe" -msgstr "Donar-se de baixa" - -#: ../src\wxUI\dialogs\lists.py:64 -msgid "Name (20 characters maximun)" -msgstr "Nom (màxim vint caràcters)" - -#: ../src\wxUI\dialogs\lists.py:74 -msgid "Mode" -msgstr "Manera" - -#: ../src\wxUI\dialogs\lists.py:75 -msgid "Public" -msgstr "Públic" - -#: ../src\wxUI\dialogs\lists.py:76 -msgid "Private" -msgstr "Privat" - -#: ../src\wxUI\dialogs\lists.py:96 -msgid "Editing the list %s" -msgstr "Editant la llista %s" - -#: ../src\wxUI\dialogs\lists.py:107 -msgid "Select a list to add the user" -msgstr "Selecciona una llista per a afegir a l'usuari" - -#: ../src\wxUI\dialogs\lists.py:108 -msgid "Add" -msgstr "Afegir" - -#: ../src\wxUI\dialogs\lists.py:130 -msgid "Select a list to remove the user" -msgstr "Selecciona una llista per esborrar a l'usuari" - -#: ../src\wxUI\dialogs\lists.py:148 -msgid "Do you really want to delete this list?" -msgstr "Realment vols eliminar aquesta llista?" - -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "&Tuit llarg" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Carregar imatge..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Comprova &l'ortografia." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Adjuntar audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "&Escurçar adreça" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Expandir adreça" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Traduir..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "&Autocompletar usuaris" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "&enviar" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "&Tancar" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinatari" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Mencionar a tothom" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tuit - %i caràcters" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Descripció de la imatge" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retuit." - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Tuits que m'agraden: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Font: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "data" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "veure" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Element" - -#: ../src\wxUI\dialogs\search.py:13 -msgid "Search on Twitter" -msgstr "Cerca a Twitter" - -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "&Cerca" - -#: ../src\wxUI\dialogs\search.py:21 -msgid "Tweets" -msgstr "Tuits" - -#: ../src\wxUI\dialogs\search.py:22 -msgid "Users" -msgstr "Usuaris" - -#: ../src\wxUI\dialogs\search.py:29 -msgid "&Language for results: " -msgstr "&idioma dels resultats: " - -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 -msgid "any" -msgstr "Cap" - -#: ../src\wxUI\dialogs\search.py:37 -msgid "Results &type: " -msgstr "&Tipus de resultats: " - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 -msgid "Mixed" -msgstr "Barrejat" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 -msgid "Recent" -msgstr "Recent" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 -msgid "Popular" -msgstr "Popular" - -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 -msgid "&OK" -msgstr "&Acceptar" - -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 -msgid "&Close" -msgstr "&Tancar" - -#: ../src\wxUI\dialogs\show_user.py:11 -msgid "Details" -msgstr "Detalls" - -#: ../src\wxUI\dialogs\show_user.py:16 -msgid "&Go to URL" -msgstr "&Anar a l'adreça" - -#: ../src\wxUI\dialogs\trends.py:12 -msgid "View trending topics" -msgstr "Noves tendències." - -#: ../src\wxUI\dialogs\trends.py:13 -msgid "Trending topics by" -msgstr "Trending topics per" - -#: ../src\wxUI\dialogs\trends.py:15 -msgid "Country" -msgstr "País" - -#: ../src\wxUI\dialogs\trends.py:16 -msgid "City" -msgstr "Ciutat" - -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 -msgid "&Location" -msgstr "&Localització" - -#: ../src\wxUI\dialogs\update_profile.py:9 -msgid "Update your profile" -msgstr "Actualitzar el teu perfil" - -#: ../src\wxUI\dialogs\update_profile.py:11 -msgid "&Name (50 characters maximum)" -msgstr "&Nom (màxim 50 caràcters)" - -#: ../src\wxUI\dialogs\update_profile.py:22 -msgid "&Website" -msgstr "&Lloc web" - -#: ../src\wxUI\dialogs\update_profile.py:27 -msgid "&Bio (160 characters maximum)" -msgstr "&Biografia (màxim 160 caràcters)" - -#: ../src\wxUI\dialogs\update_profile.py:33 -msgid "Upload a &picture" -msgstr "Carregar una &fotografia" - -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "&Actualitzar perfil" - -#: ../src\wxUI\dialogs\update_profile.py:76 -msgid "Upload a picture" -msgstr "Carregar una fotografia" - -#: ../src\wxUI\dialogs\update_profile.py:78 -msgid "Discard image" -msgstr "Descartar imatge" - -#: ../src\wxUI\dialogs\urlList.py:5 -msgid "Select URL" -msgstr "Selecciona adreça" - -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "&Usuari" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 -msgid "&Autocomplete users" -msgstr "&Autocompletar usuaris." - -#: ../src\wxUI\dialogs\userActions.py:19 -msgid "&Follow" -msgstr "&Seguir" - -#: ../src\wxUI\dialogs\userActions.py:20 -msgid "U&nfollow" -msgstr "&Deixar de seguir" - -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "&Silenciar" - -#: ../src\wxUI\dialogs\userActions.py:22 -msgid "Unmu&te" -msgstr "&Dessilenciar" - -#: ../src\wxUI\dialogs\userActions.py:23 -msgid "&Block" -msgstr "&Bloquejar" - -#: ../src\wxUI\dialogs\userActions.py:24 -msgid "Unbl&ock" -msgstr "&Desbloquejar" - -#: ../src\wxUI\dialogs\userActions.py:25 -msgid "&Report as spam" -msgstr "&Reportar com a spam" - -#: ../src\wxUI\dialogs\userActions.py:26 -msgid "&Ignore tweets from this client" -msgstr "&Ignorar tuits d'aquest client" - -#: ../src\wxUI\dialogs\userSelection.py:9 -msgid "Timeline for %s" -msgstr "Línia temporal de %s" - -#: ../src\wxUI\dialogs\userSelection.py:18 -msgid "Buffer type" -msgstr "Tipus de bufer." - -#: ../src\wxUI\dialogs\userSelection.py:19 -msgid "&Tweets" -msgstr "&Tuits" - -#: ../src\wxUI\dialogs\userSelection.py:20 -msgid "&Likes" -msgstr "&Tuits que m'agraden." - -#: ../src\wxUI\dialogs\userSelection.py:21 -msgid "&Followers" -msgstr "&Seguidors" - -#: ../src\wxUI\dialogs\userSelection.py:22 -msgid "F&riends" -msgstr "&Amics" - -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "&Retuit" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "&Respondre" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "&m'agrada" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "&Ja no m'agrada" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "&Obrir URL..." - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy -msgid "&Open in Twitter" -msgstr "Cerca a Twitter" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "&Reproduir audio" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "&Veure tuit" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "&Copiar al portapapers" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "&Eliminar" - -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "&accions d'usuari..." - -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "&Mostrar missatge directe" - -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "&Veure esdeveniment." - -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "Missatge &directe" - -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "&Veure llistes" - -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "&Veure perfil de l'usuari" - -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "&Veure usuari." - -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "Tuit sobre aquesta tendència." - -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "Mostrar item." - -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "&Configuració global" - -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "&Configuració del compte" - -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "&Actualitzar perfil" - -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "&Veure/ amagar" - -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "&Documentació" - -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "&Cercar actualitzacions" - -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "&Sortir" - -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "&gestionar compte" - -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "&Amagar finestra" - -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "&Gestor de llistes" - -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "&Editar combinacions de tecles" - -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "&Sortir" - -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "&Tuit" - -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "Veure &Adreça" - -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "Veure &conversa" - -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "Llegir el text dintre d'una imatge." - -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "&Accions..." - -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "&Veure línia temporal..." - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "Missatge directe" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "&Afegir a llista" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "&Eliminar de llista" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "&Veure tuits que agraden" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "&Actualitzar buffer" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "Nou &bufer de tendències" - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "Crear un nou &filtreCrear una nova llista" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "&gestionar filtres" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "Troba una cadena en el buffer focalitzat..." - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "&carregar twits més antics" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "&lectura automàtica" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "&Netejar buffer" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "&elimina" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "enrere 5 se&gons" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "avan&çar 5 segons" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "&Tutorial de sons" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "&Què hi ha de nou en aquesta versió?" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "&Cercar actualitzacions" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "&Reportar un problema" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "&Pàgina web de {0} " - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "Sobre &{0}" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "&Aplicació" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "&Bufer" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "&Audio" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "&Ajuda" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "Adreça" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "Actualitzat" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "La teva {0} versió ja està actualitzada." - -#~ msgid "Empty" -#~ msgstr "Buit" - -#~ msgid "One mention from %s " -#~ msgstr "Una menció de %s" - -#~ msgid "One tweet from %s" -#~ msgstr "Un tuit de %s" - -#~ msgid "You've blocked %s" -#~ msgstr "Has bloquejat a %s" - -#~ msgid "You've unblocked %s" -#~ msgstr "has desbloquejat %s" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "%s(@%s) ha començat a seguirte" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "Has seguit a %s(@%s)" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "Has deixat de seguir a %s(@%s)" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "Has marcat que t'agrada: %s, %s" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s) ha marcat que li agrada: %s" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "Has marcat que ja no t'agrada: %s, %s" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s) ha marcat que ja no li agrada: %s" - -#~ msgid "You've created the list %s" -#~ msgstr "Has creat la llista %s" - -#~ msgid "You've deleted the list %s" -#~ msgstr "Has esborrat la llista %s" - -#~ msgid "You've updated the list %s" -#~ msgstr "Has actualitzat la lista %s" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "Has afegit a %s(@%s) a la llista %s" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "%s(@%s) t'a afegit a la llista %s" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "Has esborrat a %s(@%s) de la llista %s" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "%s(@%s) t'ha eliminat de la llista %s" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "T'has subscrit a la llista %s, propietat de %s(@%s)" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "%s - %s caracters." - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "T'has donat de baixa de la llista %s, propietat de %s(@%s)" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Has sigut donat de baixa de la llista %s, propietat de %s(@%s)" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "Has retuitat un tuit de %s(@%s): %s" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "%s(@%s) ha retuitat el teu retuit: %s" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "Trucades a la API (una trucada equival a 200 tuits, 2 a 400 tuits, etc):" - -#~ msgid "Unable to upload the audio" -#~ msgstr "Impossible carregar l'audio" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "Esperant per l'autorització..." - -#~ msgid "autodetect" -#~ msgstr "Autodetectar" - -#~ msgid "" -#~ "There's a new %s version available. Would you like to download it now?\n" -#~ "\n" -#~ " %s version: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" -#~ msgstr "" -#~ "Hi ha una nova versió de %s disponible. T'agradaria descaregar-la ara?\n" -#~ "\n" -#~ " %s versió: %s\n" -#~ "\n" -#~ "Canvis:\n" -#~ "%s" - -#~ msgid "Start {0} after logging in windows" -#~ msgstr "Iniciar {0} després d'iniciar Windows." - -#~ msgid "" -#~ "If you have a SndUp account, enter your API Key here. If your API Key is " -#~ "invalid, {0} will fail to upload. If there is no API Key here, {0} will " -#~ "upload annonymously." -#~ msgstr "" -#~ "Si tens un compte a SndUp, introdueix el teu API Key aquí. Si l'API Key " -#~ "és incorrecte, {0} no podrá enviar res al servidor. Si no hi ha API Key " -#~ "aqí, {0} carregarà de manera anònima" - -#~ msgid "Disconnect your Pocket account" -#~ msgstr "Desconnectar el teu compte de Pocket" - -#~ msgid "Connect your Pocket account" -#~ msgstr "Connectar compte de pocket" - -#~ msgid "Pocket Authorization" -#~ msgstr "Autorització de Pocket" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. You only need " -#~ "to do this once. Do you want to continue?" -#~ msgstr "" -#~ "La sol·licitud s'obrirà en el teu navegador. Només necessites fer això " -#~ "una vegada. Vols continuar?" - -#~ msgid "Error during authorization. Try again later." -#~ msgstr "Error durant l'autorització. Si et plau, prova-ho més tard." - -#~ msgid "Services" -#~ msgstr "Serveis" - -#~ msgid "Contains" -#~ msgstr "conté" - -#~ msgid "Doesn't contain" -#~ msgstr "no conté" - -#~ msgid "" -#~ "You have successfully logged into Twitter with {0}. You can close this " -#~ "window now." -#~ msgstr "" -#~ "S'ha iniciat correctament la sessió a twitter amb {0}. Ara ja es pot " -#~ "tancar aquesta finestra." - -#~ msgid "&Send" -#~ msgstr "&Enviar" - -#~ msgid "Spelling correction" -#~ msgstr "Correcció d'escriptura." - -#~ msgid "Shorten URL" -#~ msgstr "Escurçar adreça" - -#~ msgid "Expand URL" -#~ msgstr "Expandir adreça" - -#~ msgid "Send" -#~ msgstr "Enviar" - -#~ msgid "unavailable" -#~ msgstr "No disponible." - -#~ msgid "Search" -#~ msgstr "Cerca" - -#~ msgid "Update profile" -#~ msgstr "Actualitzar perfil" - -#~ msgid "Follow" -#~ msgstr "Seguir" - -#~ msgid "Mute" -#~ msgstr "Silenciar" - -#~ msgid "Block" -#~ msgstr "Bloquejar" - -#~ msgid "Report as spam" -#~ msgstr "Reportar com a spam" - -#~ msgid "Favourites" -#~ msgstr "Favorits" - -#~ msgid "Favourites timeline for {}" -#~ msgstr "Línies temporals dels favorits de " - -#~ msgid "Tweet favourited." -#~ msgstr "Tuit marcat com a favorit." - -#~ msgid "Mark as favourite" -#~ msgstr "Marcar com a favorit" - -#~ msgid "Remove from favourites" -#~ msgstr "Esborrar de favorits" - -#~ msgid "You've added to favourites: %s, %s" -#~ msgstr "Has afegit a favorits: %s, %s" - -#~ msgid "%s(@%s) has marked as favourite: %s" -#~ msgstr "%s(@%s) ha marcat com a favorit: %s" - -#~ msgid "You've removed from favourites: %s, %s" -#~ msgstr "Has esborrat delsteus favorits: %s, %s" - -#~ msgid "%s(@%s) has removed from favourites: %s" -#~ msgstr "%s(@%s) ha esborrat dels seus favorits: %s" - -#~ msgid "Favourites: " -#~ msgstr "Favorits: " - -#~ msgid "Add to &favourites" -#~ msgstr "&Afegir a favorit" - -#~ msgid "Remove from favo&urites" -#~ msgstr "&Esborrar de favorits" - -#~ msgid "V&iew favourites" -#~ msgstr "&Veure favorits" - -#~ msgid "Opening media..." -#~ msgstr "Obrint media..." - -#~ msgid "Add a new ignored client" -#~ msgstr "Afegir un nou client ignorat " - -#~ msgid "Do you really want to delete this timeline?" -#~ msgstr "Realment vols eliminar aquesta línia temporal?" - -#~ msgid "Autocomplete users\\342\\200\\231 settings" -#~ msgstr "Autocompletar usuaris\\342\\200\\231 configuració" - -#~ msgid "Set the autocomplete function" -#~ msgstr "Configurar la funció d'autocompletat" - -#~ msgid "Relative times" -#~ msgstr "Temps relatius" - -#~ msgid "" -#~ "API calls when the stream is started (One API call equals to 200 tweetts, " -#~ "two API calls equals 400 tweets, etc):" -#~ msgstr "" -#~ "Trucades a la API quan el stream s'inicïi (una trucada equival a 200 " -#~ "tuits, 2 a 400 tuits, etc):" - -#~ msgid "" -#~ "Inverted buffers: The newest tweets will be shown at the beginning of the " -#~ "lists while the oldest at the end" -#~ msgstr "" -#~ "Buffers invertits: els nous tuits es mostraràn al inici de les llistes y " -#~ "els antics al final" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. Copy the code " -#~ "from Dropbox and paste it into the text box which will appear. You only " -#~ "need to do this once." -#~ msgstr "" -#~ "La sol·licitud d'autorització s'obrirà en el teu navegador. Copia i " -#~ "enganxa el codi al quadre de text que apareixerà tot seguit. Només has de " -#~ "fer això una vegada." - -#~ msgid "Verification code" -#~ msgstr "Codi de verificació" - -#~ msgid "Error during authorisation. Try again later." -#~ msgstr "Error durant l'autorització. Si et plau, prova-ho més tard." - -#~ msgid "TW Blue preferences" -#~ msgstr "Preferències de TW Blue" - -#~ msgid "Show other buffers" -#~ msgstr "Mostrar altres buffers" - -#~ msgid "JPG images" -#~ msgstr "Imatges JPG" - -#~ msgid "GIF images" -#~ msgstr "Imatges Gif" - -#~ msgid "PNG Images" -#~ msgstr "Imatges PNG" - -#~ msgid "Select an URL" -#~ msgstr "Selecciona una adreça" - -#~ msgid "Not actionable." -#~ msgstr "No hi ha accions associades a aquest tuit" - -#~ msgid "This account is not logged in twitter." -#~ msgstr "No s'ha iniciat sessió a Twitter amb aquest compte" - -#~ msgid "{0}: This account is not logged in twitter." -#~ msgstr "{0}: No s'ha iniciat sessió a twitter amb aquest comte" - -#~ msgid "Global mute off" -#~ msgstr "Silenci global desactivat" - -#~ msgid "User-defined buffer created." -#~ msgstr "Creat el buffer de l'usuari definit" - -#~ msgid "User-defined buffer destroied." -#~ msgstr "Esborrat el buffer de l'usuari definit" - -#, fuzzy -#~ msgid "Someone's favourites have been updated." -#~ msgstr "Els favorits d'algú s'han actualitzat." - -#~ msgid "A trending topic buffer has been updated." -#~ msgstr "Un buffer de tendències s'ha actualitzat." - -#~ msgid "New tweet in user-defined buffer." -#~ msgstr "Un tuit nou al buffer de l'usuari definit" - -#~ msgid "Mis-spelled word: %s" -#~ msgstr "Paraula mal escrita: %s" - -#~ msgid "Mis-spelled word" -#~ msgstr "Paraula mal escrita" - -#~ msgid "Finished" -#~ msgstr "Finalitzat" - -#~ msgid "The spelling review has finished." -#~ msgstr "La revisió d'escriptura s'ha finalitzat." - -#~ msgid "" -#~ "Do you really want to delete this message? It will be eliminated from " -#~ "Twitter as well." -#~ msgstr "" -#~ "Estàs segur de que vols esborrar aquest missatge? Tambè s'esborrarà de " -#~ "Twitter." - -#~ msgid "Show followers" -#~ msgstr "Veure seguidors" - -#~ msgid "Show friends" -#~ msgstr "Veure amics" - -#~ msgid "Show favourites" -#~ msgstr "Veure favorits" - -#~ msgid "Show blocked users" -#~ msgstr "Veure usuaris bloquejats" - -#~ msgid "Show muted users" -#~ msgstr "Veure usuaris silenciats" - -#~ msgid "Show events" -#~ msgstr "Veure esdeveniments." - -#~ msgid "" -#~ "The authorisation request will be shown on your browser. Copy the code " -#~ "tat Dropbox will provide and, in the text box that will appear on TW " -#~ "Blue, paste it. This code is necessary to continue. You only need to do " -#~ "it once." -#~ msgstr "" -#~ "La sol·licitud d'autorització apareixerà al teu navegador. Copia el codi " -#~ "que dropbox et facilitarà i, en el camp de text que apareixerà a TW Blue, " -#~ "enganxa'l. Aquest codi es necessari per continuar. Només ho has de fer " -#~ "una vegada." - -#~ msgid "Authorisation" -#~ msgstr "Autorització" - -#, fuzzy -#~ msgid "Change to the next account" -#~ msgstr "Anar a la pestanya següent" - -#, fuzzy -#~ msgid "Change to the previous account" -#~ msgstr "Anar a la pestanya anterior" - -#~ msgid "Remove buffer" -#~ msgstr "Esborrar buffer" - -#~ msgid "" -#~ "Open URL on the current tweet, or further information for a friend or " -#~ "follower" -#~ msgstr "" -#~ "Obrir adreça al twit actual, o sol·licitar més informació a buffers " -#~ "d'usuaris" - -#~ msgid "Go to the first element on the list" -#~ msgstr "Anar al primer element DE LA LLISTA" - -#~ msgid "Go to the last element on the list" -#~ msgstr "Anar al darrer element de la llista" - -#~ msgid "Move 20 elements up on the current list" -#~ msgstr "Moure's 20 elements cap amunt en la llista actual" - -#~ msgid "Move 20 elements down on the current list" -#~ msgstr "Moure's 20 elements cap avall en la llista actual" - -#~ msgid "Remove a tweet or direct message" -#~ msgstr "Esborrar un tuit o missatge directe" - -#, fuzzy -#~ msgid "Globally mute/unmute the current account" -#~ msgstr "Activar o desactivar el silenci global de TW Blue" - -#, fuzzy -#~ msgid "load previous items to any buffer" -#~ msgstr "&carregar twits més antics a qualsevol buffer" - -#, fuzzy -#~ msgid "" -#~ "The request for the required Twitter authorisation to continue will be " -#~ "opened on your browser. You only need to do it once. Would you like to " -#~ "autorhise a new account now?" -#~ msgstr "" -#~ "La Sol·licitud per a l'autorització del teu compte de Twitter s'obrirá al " -#~ "navigador. Només has de fer això una vegada. Vols autoritzar un compte de " -#~ "Twitter ara?" - -#~ msgid "" -#~ "Your access token is invalid or the authorisation has failed. Please try " -#~ "again." -#~ msgstr "" -#~ "El teu token d'accés és invàlid o l'autorització ha fallat. Si et plau, " -#~ "prova-ho de nou." - -#~ msgid "" -#~ "%s (@%s). %s followers, %s friends, %s tweets. Last tweet on %s. Joined " -#~ "Twitter on %s" -#~ msgstr "" -#~ "%s (@%s). %s seguidors, %s amics, %s tuits. Últim tuit el %s. Es va unir " -#~ "a Twitter el %s" - -#~ msgid "" -#~ "The application requires to be restarted to save these changes. Press OK " -#~ "to do it now." -#~ msgstr "" -#~ "El programa necessita reiniciar perquè els canvis facin efecte. Prem " -#~ "acceptar per fer-ho ara." - -#~ msgid "" -#~ "Dropbox will open in your browser. After you log into Dropbox, an " -#~ "authorization code will be generated. Please paste it into the field " -#~ "which will appear. You only need to do this once." -#~ msgstr "" -#~ "Dropbox s'obrirà en el teu navegador. Una vegada hagis iniciat sessió a " -#~ "Dropox, apareixerà un codi d'autorització que hauràs d'enganxar. Només " -#~ "hauràs de fer això una vegada." - -#~ msgid "View &trending topics" -#~ msgstr "Veure &Trending topics" - -#~ msgid "&Unfollow" -#~ msgstr "&Deixar de seguir" - -#~ msgid "U&nmute" -#~ msgstr "&Dessilenciar" - -#~ msgid "Unb&lock" -#~ msgstr "&Desbloquejar" - -#~ msgid "&Timeline" -#~ msgstr "&Línia temporal" - -#~ msgid "&Autoread tweets for this buffer" -#~ msgstr "&Llegir automàticament els tuits d'aquest buffer." - -#~ msgid "&Remove buffer" -#~ msgstr "&Esborrar buffer" - -#~ msgid "Stop recording" -#~ msgstr "Aturar grabació" - -#~ msgid "The tweet may contain a playable audio" -#~ msgstr "El tuit pot contenir un audio reproduible." - -#~ msgid "A timeline has been created" -#~ msgstr "La línia temporal s'ha creat" - -#~ msgid "A timeline has been deleted" -#~ msgstr "La línia temporal s'ha esborrat" - -#~ msgid "You've received a direct message" -#~ msgstr "Has rebut un missatge directe" - -#~ msgid "You've sent a direct message" -#~ msgstr "Has enviat un missatge directe." - -#~ msgid "A bug has happened" -#~ msgstr "Hi ha hagut un problema." - -#~ msgid "You've added a tweet to your favourites" -#~ msgstr "Has afegit un tuit als favorits." - -#~ msgid "The tweet has coordinates to determine its location" -#~ msgstr "El tuit té coordenades per determinar la seva localització." - -#~ msgid "There are no more tweets to read" -#~ msgstr "No hi ha més twits per llegir" - -#~ msgid "A list has a new tweet" -#~ msgstr "Una llista té un nou twit" - -#~ msgid "You can't add any more characters on the tweet" -#~ msgstr "No pots afegir més caràcters al tuit." - -#~ msgid "You've been mentioned " -#~ msgstr "Has sigut mencionat" - -#~ msgid "A new event has happened" -#~ msgstr "hi ha hagut un nou esdeveniment." - -#~ msgid "You've replied" -#~ msgstr "Has contestat" - -#~ msgid "You've sent a tweet" -#~ msgstr "Has enviat un tuit" - -#~ msgid "There's a new tweet in a timeline" -#~ msgstr "Hi ha un nou tuit a una línia temporal." - -#~ msgid "You have a new follower" -#~ msgstr "Tens un nou seguidor." - -#~ msgid "You've turned the volume up or down" -#~ msgstr "Has apujat o abaixat el volum." - -#~ msgid "" -#~ "It seems as though the currently used sound pack needs an update. %i " -#~ "fails are still be required to use this function. Make sure to obtain the " -#~ "needed lacking sounds or to contact with the sound pack developer." -#~ msgstr "" -#~ "Sembla que el paquet de sons actualment utilitzat necessita una " -#~ "actualització. %i fitxers son necesaris per a fer aquesta funció. " -#~ "Asegurat de aconseguir els sons necessaris o contacta amb el creador del " -#~ "paquet." - -#~ msgid "See the users list" -#~ msgstr "Veure la llista d'usuaris." - -#~ msgid "Do you really want to delete this message?" -#~ msgstr "Realment vols eliminar aquest missatge?" - -#~ msgid "Unable to play audio." -#~ msgstr "Impossible reproduir audio" - -#~ msgid "Do you really want to delete this favourites timeline?" -#~ msgstr "Realment vols eliminar aquesta líniade favorits?" - -#~ msgid "&Mention" -#~ msgstr "&Menció" - -#~ msgid "Announce" -#~ msgstr "Anuncia" - -#~ msgid "" -#~ "Do you really want to empty this buffer? It's items will be removed from " -#~ "the list" -#~ msgstr "" -#~ "Estàs segur de que vols buidar aquest buffer? Els tuits seràn eliminats " -#~ "de la llista." - -#~ msgid "Do you really want to delete this search term?" -#~ msgstr "Segur que vols esborrar aquest terme de cerca?" - -#~ msgid "ask before exiting TwBlue?" -#~ msgstr "Preguntar abans de sortir de Tw Blue?" - -#~ msgid "Activate the auto-start of the invisible interface" -#~ msgstr "Activar l'inici automàtic de la interfície invisible" - -#~ msgid "Global mute" -#~ msgstr "Silenci global" - -#~ msgid "friends" -#~ msgstr "Amics" - -#~ msgid "Favorites" -#~ msgstr "Favorits" - -#~ msgid "You've muted to %s" -#~ msgstr "Has silenciat a %s" - -#~ msgid "You've unmuted to %s" -#~ msgstr "Has dessilenciat a %s" - -#~ msgid "This list is arready opened." -#~ msgstr "Aquesta llista ja està oberta" - -#~ msgid "List for %s" -#~ msgstr "Llista %s" - -#~ msgid "Uploading..." -#~ msgstr "Carregant..." - -#~ msgid "Men&tion all" -#~ msgstr "Men&cionar a tots" - -#~ msgid "This user does not exist on Twitter" -#~ msgstr "Aquest usuari no existeix a Twitter." - -#~ msgid "S&witch account" -#~ msgstr "&Canviar de compte" - -#~ msgid "&Preferences" -#~ msgstr "&Preferències" - -#~ msgid "About &TW Blue" -#~ msgstr "&Sobre TW Blue" - -#~ msgid "" -#~ "An error occurred while looking for an update. It may be due to any " -#~ "problem either on our server or on your DNS servers. Please, try again " -#~ "later." -#~ msgstr "" -#~ "Hi ha hagut un error cercant actualitzacions. Pot ser per un problema amb " -#~ "el nostre servidor o en el teu servidor DNS. Si et plau, prova-ho més " -#~ "tard." - -#~ msgid "Sent" -#~ msgstr "Enviats" - -#~ msgid "%s favourites from %s" -#~ msgstr "%s favorits de %s" - -#~ msgid "Streams disconnected. TW Blue will try to reconnect in a minute." -#~ msgstr "Streams desconnectats. TW Blue provarà de connectar-se en un minut." - -#~ msgid "Reconnecting streams..." -#~ msgstr "Reconectant els streams..." - -#~ msgid "search users for %s" -#~ msgstr "Cercar usuaris per %s" - -#~ msgid "Do you really want to close TW Blue?" -#~ msgstr "Estàs segur de que vols sortir de TW Blue?" - -#~ msgid "Exiting..." -#~ msgstr "Sortint..." - -#~ msgid "Error while adding to favourites." -#~ msgstr "Error afegint a favorit" - -#~ msgid "Error while removing from favourites." -#~ msgstr "Error esborrant de favorits" - -#~ msgid "Individual timeline" -#~ msgstr "Línia temporal individual" - -#~ msgid "List of favourites" -#~ msgstr "Llista de favorits" - -#~ msgid "Existing list" -#~ msgstr "Llista existent" - -#~ msgid "" -#~ "There's already a list of favourites for this user. You can't create " -#~ "another." -#~ msgstr "" -#~ "Ja hi ha una llista de favorits d'aquest usuari. No pots crear-ne una " -#~ "altra." - -#~ msgid "" -#~ "This user has no favourites. You can't create a list of favourites for " -#~ "this user." -#~ msgstr "" -#~ "Aquest usuari no té tuits favorits. No pots obrir una llista dels seus " -#~ "tuits favorits." - -#~ msgid "%s" -#~ msgstr "%s" - -#~ msgid "Documentation" -#~ msgstr "Documentació" - -#~ msgid "Translation" -#~ msgstr "Traducció." - -#~ msgid "Move up one tweet in the conversation" -#~ msgstr "Anar un tuit amunt a la conversa" - -#~ msgid "Move down one tweet in the conversation" -#~ msgstr "Anar un tuit avall a la conversa" - -#~ msgid "Show the graphical interface" -#~ msgstr "Activar la visualització gràfica" - -#~ msgid "Reply to a tweet" -#~ msgstr "Respondre un twit." - -#~ msgid "Empty the buffer removing all the elements" -#~ msgstr "Buidar buffer, eliminant tos els elements" - -#~ msgid "Listen the current message" -#~ msgstr "Escoltar el missatge actual" - -#~ msgid "Get location of any tweet" -#~ msgstr "Esbrinar la localització de qualsevol tuit." - -#~ msgid "Creates a buffer for displaying trends for a desired place" -#~ msgstr "Crea un buffer per mostrar tendències d'un lloc concret." - -#~ msgid "Select a twitter account to start TW Blue" -#~ msgstr "Selecciona un compte de Twitter per començar a TWBlue" - -#~ msgid "Remove session" -#~ msgstr "Eliminar sessió." - -#~ msgid "One tweet from %s in the list %s" -#~ msgstr "Un tuit de %s en la llista %s" - -#~ msgid "One direct message" -#~ msgstr "Un missatge directe" - -#~ msgid "About a week ago" -#~ msgstr "Fa una setmana" - -#~ msgid "About {} weeks ago" -#~ msgstr "Fa {} setmanes" - -#~ msgid "A month ago" -#~ msgstr "Fa un mes" - -#~ msgid "About {} months ago" -#~ msgstr "Fa {} messos" - -#~ msgid "About a year ago" -#~ msgstr "Fa un any" - -#~ msgid "About {} years ago" -#~ msgstr "Fa {} anys" - -#~ msgid "About 1 day ago" -#~ msgstr "Fa un dia" - -#~ msgid "About {} days ago" -#~ msgstr "Fa {} dies" - -#~ msgid "just now" -#~ msgstr "Ara mateix" - -#~ msgid "{} seconds ago" -#~ msgstr "Fa {} segons" - -#~ msgid "1 minute ago" -#~ msgstr "Fa 1 minut" - -#~ msgid "{} minutes ago" -#~ msgstr "Fa {} minuts" - -#~ msgid "About 1 hour ago" -#~ msgstr "Fa una hora" - -#~ msgid "About {} hours ago" -#~ msgstr "Fa {} hores" - -#~ msgid "January" -#~ msgstr "Jener" - -#~ msgid "February" -#~ msgstr "Febrer" - -#~ msgid "March" -#~ msgstr "Març" - -#~ msgid "April" -#~ msgstr "Abril" - -#~ msgid "June" -#~ msgstr "Juny" - -#~ msgid "July" -#~ msgstr "Juliol" - -#~ msgid "August" -#~ msgstr "Agost" - -#~ msgid "September" -#~ msgstr "Setembre" - -#~ msgid "October" -#~ msgstr "Octubre" - -#~ msgid "November" -#~ msgstr "Novembre" - -#~ msgid "December" -#~ msgstr "Decembre" - -#~ msgid "Sunday" -#~ msgstr "Diumenge" - -#~ msgid "Monday" -#~ msgstr "Dilluns" - -#~ msgid "Tuesday" -#~ msgstr "Dimars" - -#~ msgid "Wednesday" -#~ msgstr "Dimecres" - -#~ msgid "Thursday" -#~ msgstr "Dijous" - -#~ msgid "Friday" -#~ msgstr "Divendres" - -#~ msgid "Saturday" -#~ msgstr "Disabte" - -#~ msgid "sun" -#~ msgstr "Diumenge" - -#~ msgid "mon" -#~ msgstr "Dilluns" - -#~ msgid "tue" -#~ msgstr "Dimarts" - -#~ msgid "wed" -#~ msgstr "Dimecres" - -#~ msgid "thu" -#~ msgstr "Dijous" - -#~ msgid "fri" -#~ msgstr "Divendres" - -#~ msgid "sat" -#~ msgstr "Dissabte" - -#~ msgid "jan" -#~ msgstr "Jener" - -#~ msgid "feb" -#~ msgstr "Febrer" - -#~ msgid "mar" -#~ msgstr "Març" - -#~ msgid "apr" -#~ msgstr "Abril" - -#~ msgid "may" -#~ msgstr "Maig" - -#~ msgid "jun" -#~ msgstr "Juny" - -#~ msgid "jul" -#~ msgstr "Juliol" - -#~ msgid "aug" -#~ msgstr "Agost" - -#~ msgid "sep" -#~ msgstr "Setembre" - -#~ msgid "oct" -#~ msgstr "Octubre" - -#~ msgid "nov" -#~ msgstr "Novembre" - -#~ msgid "dec" -#~ msgstr "Decembre" - -#~ msgid "%A, %B %d, %Y at %I:%M:%S %p" -#~ msgstr "%A, %d de %B del %Y a les %I:%M:%S %p" - -#~ msgid "Your TW Blue version is up to date" -#~ msgstr "La teva versió de TWBlue està actualitzada" - -#~ msgid "Connection error. Try again later." -#~ msgstr "Error de connexió. Si et plau, prova-ho més tard." - -#~ msgid "View members" -#~ msgstr "¿¿¿Veure membres" - -#~ msgid "View subscribers" -#~ msgstr "Veure subscriptors" - -#~ msgid "Ouner" -#~ msgstr "propietari" - -#~ msgid "Successfully following %s" -#~ msgstr "Èxit seguint a %s" - -#~ msgid "%s has been reported as spam" -#~ msgstr "%s ha sigut reportat com spam" - -#~ msgid "%s has been blocked" -#~ msgstr "%s ha sigut bloquejat" - -#~ msgid "User's information" -#~ msgstr "Detalls de l'usuari" - -#~ msgid "You've unblock %s" -#~ msgstr "Has desbloquejat a %s" - -#~ msgid "Clear" -#~ msgstr "Limpiar" diff --git a/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).mo b/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).mo deleted file mode 100644 index b7b41c9f..00000000 Binary files a/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).mo and /dev/null differ diff --git a/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po b/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po deleted file mode 100644 index d3113de0..00000000 --- a/src/locales/da/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po +++ /dev/null @@ -1,3371 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2019-03-09 23:36+0100\n" -"Last-Translator: Nicolai Svendsen \n" -"Language-Team: \n" -"Language: da\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.2\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Billede" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "Denne handling understøttes ikke for denne buffer" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "Hjem" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "Omtale" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "Direkte beskeder" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "Sendte direkte beskeder" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "Sendte tweets" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "Synes godt om" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "Følgere" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Venner" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "Blokerede brugere" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "Dæmpede brugere" - -#: ../src\controller\buffers\twitterBuffers.py:75 -#, fuzzy -msgid "{username}'s timeline" -msgstr "Åbn brugerens tidslinje" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:83 -#, fuzzy -msgid "Unknown buffer" -msgstr "Ukendt" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "Tweet" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "Skriv et tweet her" - -#: ../src\controller\buffers\twitterBuffers.py:194 -#, fuzzy -msgid "New tweet in {0}" -msgstr "Nyt Tweet" - -#: ../src\controller\buffers\twitterBuffers.py:197 -#, fuzzy -msgid "{0} new tweets in {1}." -msgstr "@{0} citerede dit tweet: {1}" - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s elementer hentet" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Denne buffer er ikke en tidslinje; Den kan ikke slettes." - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "Svare {arg0}" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "Svar" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "Svar %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Direkte besked til %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "Ny direkte besked" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "tilføj din kommentar til dette tweet" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "Citat" - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "Åbner URL…" - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "Brugerdetaljer" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "Omtale til %s" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "Omtale" - -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy -msgid "{0} new direct messages." -msgstr "Ny direkte besked" - -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy -msgid "This action is not supported in the buffer yet." -msgstr "Denne handling understøttes ikke for denne buffer" - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy -msgid "{0} new followers." -msgstr "Ny følger." - -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy -msgid "This action is not supported in the buffer, yet." -msgstr "Denne handling understøttes ikke for denne buffer" - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "Klar" - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "Tidslinjer" - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "Tidslinje for {}" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "Tidslinjer for synes godt om" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "Synes godt om for {}" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Tidslinjer for følgere" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "Følgere for {}" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Venners tidslinjer" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "Venner for {}" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "Lister" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "Liste for {}" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "Søgninger" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "Søg efter {}" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "Trends for {}" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "" -"Ingen session er på nuværende tidspunkt i fokus. Skift fokus til en aktiv " -"session ved brug af tastaturgenvejen der skifter mellem forrige og næste " -"session" - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "Tøm buffer" - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0} ikke fundet." - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "Filtre understøttes ikke for denne buffer" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "Vælg bruger" - -#: ../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" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "Samtale med {0}" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "Der er ingen koordinater i denne tweet" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "Der er ingen resultater for koordinaterne i denne tweet" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "Fejl under afkodning af koordinater. Prøv igen senere." - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s, %s af %s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%s. Tom" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: Denne konto er ikke logget ind på Twitter." - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s af %s" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: Denne konto er ikke logget ind på Twitter." - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Begivenheder" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "Denne liste er allerede åbnet" - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"Noget uventet opstod under forsøg på at rapportere fejlen. Prøv igen senere." - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "Auto-læsning af ny tweets er aktiveret for denne buffer" - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "Auto-læsning af ny tweets er deaktiveret for denne buffer" - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "Session dæmpning slået til" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "Session dæmpning slået fra" - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "Buffer dæmpning slået til" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "Buffer dæmpning slået fra" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "Kopieret" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "Ikke i stand til at opdatere denne buffer." - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "Opdaterer buffer…" - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0} emner hentet" - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "Ugyldig buffer" - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Dette tweet indeholder ingen billeder." - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "Billede {0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "Vælg billedet" - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "Ikke i stand til at genkende tekst" - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "Oversat" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "Der er ingen URL der kan forkortes" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URL forkortet" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "Der er ingen URL der kan udvides" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URL udvidet" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s af %d tegn" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s tegn" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "Vis element" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Direkte forbindelse" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "Spørg" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "Retweet uden kommentar" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "Retweet med en kommentar" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "Kontoindstillinger for %s" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "Direkte Beskeder" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "Fejl" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "Denne bruger eksisterer ikke" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "Brugeren er suspenderet" - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "Information om %s" - -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "Kasseret" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Brugernavn: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Navn: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Lokalitet: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "Bio: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "Ja" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "Nej" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "Beskyttet: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "Du følger {0}. " - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr "{0} følger dig." - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Følgere: %s\n" -" Venner: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "Verificeret:%s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "Tweets: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "Synes godt om: %s" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "Du kan ikke ignorere direkte beskeder" - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "Vedhæfter…" - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "Pause" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "&Genoptag" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "Genoptag" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "&Pause" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "&Stop" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "Optager" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "Stoppet" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "&Optag" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "Afspiller." - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "&Afspil" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "Genkoder lyd..." - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "Fejl under upload af fil: {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "%d dag, " - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%d dage, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "%d time, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d timer, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "%d minut, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d minutter, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "%s sekund" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s sekunder" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "Fil" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "Overført" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "Total filstørrelse" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "Overførselshastighed" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "Tid tilbage" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "Vedhæft lyd" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "&Tilføj en eksisterende fil" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "&Kassér" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "Overfør til" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "Vedhæft" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "&Annuller" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Lydfiler (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "Vælg den lydfil, der skal uploades" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "Lyd tweet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "Bruger tidslinjebuffer oprettet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "Buffer slettet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Direkte besked modtaget." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Direkte besked sendt." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "Fejl." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "Synes godt om tweet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "Buffer synes godt om opdateret." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "Geotweet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "Tweet indeholder et eller flere billeder" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "Grænse nået." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "Liste opdateret." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "For mange tegn." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "Omtale modtaget." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "Nyt begivenhed." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0} er klar." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "Omtale sendt." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "Tweet retweetet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "Søgebuffer opdateret." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "Tweet modtaget." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "Tweet sendt." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "Trending emner buffer opdateret." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "Ny tweet i bruger tidslinje buffer." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "Ny følger." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "Lydstyrke ændret." - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "Hør lyde" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "Tryk på enter for at lytte til lyden for den valgte begivenhed" - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "Fejlstavede ord: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "Fejlstavet ord" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "Kontekst" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "Forslag" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "&Ignorér" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "&Ignorér alle" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "&Erstat" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "E&rstat alle" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "&Tilføj til personlig ordbog" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"Der opstod en fejl. Der findes ingen ordbøger til det valgte sprog på {0}" - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "Stavekontrol gennemført." - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "Du skal begynde at skrive" - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "Der er ingen resultater i din bruger database" - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "Autofuldførelse fungerer kun for brugere." - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Opdaterer database... Du kan lukke dette vindue nu. En meddelelse vil " -"fortælle dig, hvornår processen er færdig." - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "Administrer autofuldførelsesdatabase" - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "Redigerer {0} brugers database" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "Brugernavn" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Navn" - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "Tilføj bruger" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "Fjern bruger" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "Tilføj bruger til database" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "Twitter brugernavn" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "Denne bruger eksisterer ikke" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "Fejl!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Indstillinger for autofuldførelse af brugere" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Tilføj brugere fra bufferen følgere" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Tilføj brugere fra bufferen venner" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Administrer database…" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "Færdig" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "{0}s database over brugere er blevet opdateret." - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "Opdag automatisk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "Dansk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "Hollandsk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "Engelsk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "Finsk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "Fransk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "Tysk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "Ungarsk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "Italiensk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "Japansk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "Koreansk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "Polsk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "Portugisisk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "Russisk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "Spansk" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "Tyrkisk" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "Afrikaans" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "Albansk" - -#: ../src\extra\translator\translator.py:14 -msgid "Amharic" -msgstr "Amharisk" - -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "Arabisk" - -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "Armensk" - -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "Azerbaijansk" - -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "Baskisk " - -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "Hviderussisk " - -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "Bengali" - -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "Bulgarsk" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "Burmesisk" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "Catalansk" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "Cherokee" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "Kinesisk" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "Kinesisk (Forenklet)" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "Kinesisk (Traditionelt)" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "Kroatisk" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "Tjekkisk" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "Esperanto" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "Estisk" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "Filippinsk" - -#: ../src\extra\translator\translator.py:40 -msgid "Galician" -msgstr "Galicisk" - -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "Georgisk" - -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "Græsk" - -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "Guaraní" - -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "Gujarati" - -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "Hebraisk" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "Hindi" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "Islandsk" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "Indonesisk" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "Irsk" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "Kannada" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "Kasakhisk" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "Khmer" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "Kurdisk" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "Kirgisisk" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "Laotisk" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "Lettisk" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "Litauisk" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "Makedonsk" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "Malaysisk" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "Malayalam" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "Maltesisk" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "Marathi" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "Mongolsk" - -#: ../src\extra\translator\translator.py:70 -msgid "Nepali" -msgstr "Nepalesisk" - -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "Norsk" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr "Oriya" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "Pashto" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "Persisk" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "Panjabi" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "Rumænsk" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "Sanskrit" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" -msgstr "Serbisk" - -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "Sindhi" - -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "Sinhalesisk" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "Slovakisk" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "Slovensk" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "Swahili" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "Svensk" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "Tadsjikisk" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "Tamil" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "Tagalog" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "Telugu" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "Thaisk" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "Tibetansk" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "Ukrainsk" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "Usbekisk" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "Uighur" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "Vietnamesisk" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "Walisisk" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "Jiddisch" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "Oversæt besked" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "Målsprog" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "Generelt" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "altid" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "Har ikke prøvet" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "tilfældigt" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "somme tider" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "Kan ikke duplikere" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "blokér" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "sammenbrud" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "funktion" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "stor" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "mindre" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "tekst" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "trivielt" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "tweak" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "Rapportér en fejl" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "Vælg en katogori" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "" -"Beskriv kort, hvad der skete. Du vil blive i stand til at forklare det " -"grundigt senere" - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "Her kan du beskrive fejlen i detaljer" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "Hvor ofte sker denne fejl?" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "Vælg den betydning, du mener, at denne fejl har" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Jeg ved at {0} fejlsystemet vil modtage mit Twitter brugernavn til at " -"kontakte mig og rette fejlen hurtigt" - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "Send rapport" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "Annuller" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "Du skal udfylde begge felter" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Du skal markere checkboksen for at give os dit twitter brugernavn så vi kan " -"kontakte dig, hvis det er nødvendigt." - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"Tak for at du rapporterede denne fejl! I fremtidige versioner kan du " -"muligvis finde denne fejlrettelse i listen over ændringer. Din rapport har " -"fejlnummeret %i" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "rapporteret" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "Fejl under rapportering" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Noget uventet opstod under forsøg på at rapportere fejlen. Prøv igen senere." - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Gå op i den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "Gå ned i den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Gå til den forrige buffer" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Gå til den næste buffer" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Bring fokus til næste session" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Bring fokus til forrige session" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Vis eller skjul brugergrænsefladen" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Nyt Tweet" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Retweet" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Send direkte besked" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "Synes godt om en tweet" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "Synes godt om/synes ikke godt om en tweet" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Synes ikke godt om en tweet" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Åbn dialogboksen Brugerhandlinger" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Se brugerdetaljer" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Vis tweet" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "Afslut" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Åbn brugerens tidslinje" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Ødelæg buffer" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interager med den aktuelt fokuserede tweet." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Åbn URL" - -#: ../src\keystrokeEditor\constants.py:25 -#, fuzzy -msgid "View in Twitter" -msgstr "Søg på Twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Forøg lydstyrke med 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Formindsk lydstyrke med 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Hop til det første element i en buffer" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Hop til det sidste element i den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Spring 20 elementer op i den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Spring 20 elementer ned i den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Redigér profil" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Slet et tweet eller en direkte besked" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Tøm den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Gentag sidste emne" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Kopiér til udklipsholder" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Tilføj til liste" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Fjern fra liste" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Slå dæmpning til eller fra på den aktuelle buffer" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Slå dæmpning til eller fra på den aktuelle session" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "" -"Slå automatisk læsning af indkommende tweets til og fra for den aktive buffer" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "Søg på twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Find en streng i den aktuelt fokuserede buffer" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Vis tastetrykredigering" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Vis tilhørende lister for en bestemt bruger" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "Indlæs tidligere elementer" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Få geolokalitet" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Vis tweetens geolokalitet i en dialog" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Opret en buffer med trending emner" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Se samtale" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "Tjek og download opdateringer" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Åbner listemanageren, som giver dig mulighed for at oprette, redigere, " -"slette og åbne lister i buffere." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Åbner dialogen med globale indstillinger" - -#: ../src\keystrokeEditor\constants.py:54 -#, fuzzy -msgid "Opens the list manager" -msgstr "Listemanager" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Åbner dialogen med kontoindstillinger" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Forsøg at afspille en lydfil" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Opdaterer bufferen og henter mulige tabte emner der." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "Uddrager teksten fra et billede og viser resultatet i en dialog." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Tastetrykredigering" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Vælg et tastetryk for at redigere" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "tastetryk" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "Handling" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "Rediger" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "Kør handling" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "Luk" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "Redigerer tastetryk" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "Kontrol" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "Skift" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "Windows" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "Tast" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "OK" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "Du skal bruge Windows-tasten" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "Ugyldigt tastetryk" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "Du skal angive et tegn til tastetrykket" - -#: ../src\languageHandler.py:99 -msgid "User default" -msgstr "Brugerstandard" - -#: ../src\main.py:105 -msgid "https://twblue.es/donate" -msgstr "https://twblue.es/donate" - -#: ../src\main.py:122 -msgid "" -"{0} is already running. Close the other instance before starting this one. " -"If you're sure that {0} isn't running, try deleting the file at {1}. If " -"you're unsure of how to do this, contact the {0} developers." -msgstr "" - -#: ../src\sessionmanager\wxUI.py:8 -msgid "Session manager" -msgstr "Sessionmanager" - -#: ../src\sessionmanager\wxUI.py:11 -msgid "Accounts list" -msgstr "Konti liste" - -#: ../src\sessionmanager\wxUI.py:13 -msgid "Account" -msgstr "Konto" - -#: ../src\sessionmanager\wxUI.py:17 -msgid "New account" -msgstr "Ny konto" - -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 -msgid "Remove account" -msgstr "Fjern konto" - -#: ../src\sessionmanager\wxUI.py:19 -msgid "Global Settings" -msgstr "Globale Indstillinger" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "Kontofejl" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "You need to configure an account." -msgstr "Du skal konfigurere en konto." - -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "Godkendelse" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "" -"The request to authorize your Twitter account will be opened in your " -"browser. You only need to do this once. Would you like to continue?" -msgstr "" -"Anmodningen om at godkende din Twitter-konto åbnes i din browser. Du behøver " -"kun at gøre dette en gang. Vil du fortsætte?" - -#: ../src\sessionmanager\wxUI.py:52 -msgid "Authorized account %d" -msgstr "Autoriseret konto %d" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "Ugyldigt brugertoken" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "" -"Your access token is invalid or the authorization has failed. Please try " -"again." -msgstr "" -"Dit adgangstoken er ugyldigt, eller godkendelsen er mislykket. Prøv igen." - -#: ../src\sessionmanager\wxUI.py:64 -msgid "Do you really want to delete this account?" -msgstr "Vil du slette denne konto?" - -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 -msgid "dddd, MMMM D, YYYY H:m:s" -msgstr "dddd, MMMM D, YYYY H:m:s" - -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 -msgid "Dm to %s " -msgstr "DB til %s " - -#: ../src\sessions\twitter\compose.py:141 -msgid "{0}. Quoted tweet from @{1}: {2}" -msgstr "{0}. Citeret tweet fra @{1}: {2}" - -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 -msgid "Unavailable" -msgstr "Utilgængelig" - -#: ../src\sessions\twitter\compose.py:166 -msgid "" -"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " -"Twitter %s" -msgstr "" -"%s (@%s). %s følgere, %s venner, %s tweets. Sidst tweetedt %s. Tilmeldt " -"Twitter %s" - -#: ../src\sessions\twitter\compose.py:170 -msgid "No description available" -msgstr "Ingen beskrivelse tilgængelig" - -#: ../src\sessions\twitter\compose.py:174 -msgid "private" -msgstr "privat" - -#: ../src\sessions\twitter\compose.py:175 -msgid "public" -msgstr "offentlig" - -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "Der er ingen koordinater i denne tweet" - -#: ../src\sessions\twitter\session.py:215 -msgid "%s failed. Reason: %s" -msgstr "%s mislykkedes. Grund: %s" - -#: ../src\sessions\twitter\session.py:221 -msgid "%s succeeded." -msgstr "%s lykkedes." - -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "Beklager, du har ikke tilladelse til at se denne status." - -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "Ingen status fundet med det ID" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "Fejlkode {0}" - -#: ../src\sessions\twitter\wxUI.py:6 -msgid "Authorising account..." -msgstr "Godkender konto..." - -#: ../src\sessions\twitter\wxUI.py:9 -msgid "Enter your PIN code here" -msgstr "Indtast din PIN-kode her" - -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "Stoppet." - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "Ny version for %s" - -#: ../src\update\wxUpdater.py:10 -msgid "" -"There's a new %s version available, released on %s. Would you like to " -"download it now?\n" -"\n" -" %s version: %s\n" -"\n" -"Changes:\n" -"%s" -msgstr "" -"Der er en ny %s version tilgængelig, udgivet den %s. Vil du hente den nu?\n" -"\n" -" %s version: %s\n" -"\n" -"Ændringer:\n" -"%s" - -#: ../src\update\wxUpdater.py:18 -msgid "Download in Progress" -msgstr "Download i gang" - -#: ../src\update\wxUpdater.py:18 -msgid "Downloading the new version..." -msgstr "Henter den nye version..." - -#: ../src\update\wxUpdater.py:28 -msgid "Updating... %s of %s" -msgstr "Opdaterer... %s af %s" - -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "Færdig!" - -#: ../src\update\wxUpdater.py:31 -msgid "" -"The update has been downloaded and installed successfully. Press OK to " -"continue." -msgstr "" -"Opdateringen er blevet downloadet og installeret med succes. Tryk på OK for " -"at fortsætte." - -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "Klient" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Tekst" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "Dato" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "Bruger" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Direkte besked" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "Begivenhed" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "Fjern Begivenhed" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "Log ind" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "Log ind automatisk" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "Log ud" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "Trending emne" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "Tweet om denne trend" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "Søg emne" - -#: ../src\wxUI\commonMessageDialogs.py:6 -msgid "" -"This retweet is over 140 characters. Would you like to post it as a mention " -"to the poster with your comments and a link to the original tweet?" -msgstr "" -"Dette retweet er over 140 tegn. Vil du sende det som en omtale til den " -"oprindelige sender med dine kommentarer og et link til det oprindelige tweet?" - -#: ../src\wxUI\commonMessageDialogs.py:9 -msgid "Would you like to add a comment to this tweet?" -msgstr "Vil du gerne tilføje en kommentar til dette tweet?" - -#: ../src\wxUI\commonMessageDialogs.py:12 -msgid "" -"Do you really want to delete this tweet? It will be deleted from Twitter as " -"well." -msgstr "" -"Vil du virkelig slette dette tweet? Den bliver også slettet fra Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 -msgid "Delete" -msgstr "Slet" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Do you really want to close {0}?" -msgstr "Vil du virkelig lukke {0}?" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Exit" -msgstr "Afslut" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid " {0} must be restarted for these changes to take effect." -msgstr "{0} skal genstartes for at disse ændringer træder i kraft." - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid "Restart {0} " -msgstr "Genstart {0}" - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "" -"Are you sure you want to delete this user from the database? This user will " -"not appear in autocomplete results anymore." -msgstr "" -"Er du sikker på, at du vil slette denne bruger fra databasen? Denne bruger " -"vil ikke længere blive vist i autofuldførende resultater." - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "Confirm" -msgstr "Bekræft" - -#: ../src\wxUI\commonMessageDialogs.py:25 -msgid "Enter the name of the client : " -msgstr "Indtast klientens navn:" - -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 -msgid "Add client" -msgstr "Tilføj klient" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "" -"Do you really want to empty this buffer? It's items will be removed from " -"the list but not from Twitter" -msgstr "" -"Vil du virkelig tømme denne buffer? Bufferens emner vil blive fjernet fra " -"listen, men ikke fra Twitter" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "Empty buffer" -msgstr "Tøm buffer" - -#: ../src\wxUI\commonMessageDialogs.py:35 -msgid "Do you really want to destroy this buffer?" -msgstr "Vil du virkelig ødelægge denne buffer?" - -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Attention" -msgstr "Bemærk" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "A timeline for this user already exists. You can't open another" -msgstr "" -"En tidslinje for denne bruger eksisterer allerede. Du kan ikke åbne en anden." - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "Existing timeline" -msgstr "Eksisterende tidslinje" - -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "This user has no tweets, so you can't open a timeline for them." -msgstr "" -"Denne bruger har ingen tweets, så du kan ikke åbne en tidslinje for dem." - -#: ../src\wxUI\commonMessageDialogs.py:47 -msgid "" -"This is a protected Twitter user, which means you can't open a timeline " -"using the Streaming API. The user's tweets will not update due to a twitter " -"policy. Do you want to continue?" -msgstr "" -"Dette er en beskyttet Twitter-bruger, hvilket betyder, at du ikke kan åbne " -"en tidslinje ved hjælp af Streaming API. Brugerens tweets opdateres ikke på " -"grund af en Twitter-politik. Vil du fortsætte?" - -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "Warning" -msgstr "Advarsel" - -#: ../src\wxUI\commonMessageDialogs.py:50 -msgid "" -"This is a protected user account, you need to follow this user to view their " -"tweets or likes." -msgstr "" -"Dette er en beskyttet brugerkonto, du skal følge denne bruger for at se " -"deres tweets eller synes godt om." - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "" -"If you like {0} we need your help to keep it going. Help us by donating to " -"the project. This will help us pay for the server, the domain and some other " -"things to ensure that {0} will be actively maintained. Your donation will " -"give us the means to continue the development of {0}, and to keep {0} free. " -"Would you like to donate now?" -msgstr "" -"Hvis du kan lide {0}, har vi brug for din hjælp til at holde projektet i " -"gang. Hjælp os ved at donere til projektet. Dette vil hjælpe os med at " -"betale for serveren, domænet og nogle andre ting for at sikre, at {0} bliver " -"aktivt vedligeholdt. Din donation vil give os midler til at fortsætte " -"udviklingen af {0} og sikre, at {0} forbliver gratis. Vil du gerne donere nu?" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "We need your help" -msgstr "Vi har brug for din hjælp" - -#: ../src\wxUI\commonMessageDialogs.py:57 -msgid "This user has no tweets. {0} can't create a timeline." -msgstr "Denne bruger har ingen tweets. {0} kan ikke oprette en tidslinje." - -#: ../src\wxUI\commonMessageDialogs.py:60 -msgid "This user has no favorited tweets. {0} can't create a timeline." -msgstr "" -"Denne bruger har ingen foretrukne tweets. {0} kan ikke oprette en tidslinje." - -#: ../src\wxUI\commonMessageDialogs.py:63 -msgid "This user has no followers. {0} can't create a timeline." -msgstr "Denne bruger har ingen følgere. {0} kan ikke oprette en tidslinje." - -#: ../src\wxUI\commonMessageDialogs.py:66 -msgid "This user has no friends. {0} can't create a timeline." -msgstr "Denne bruger har ingen venner. {0} kan ikke oprette en tidslinje." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "Geo data for denne tweet" - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geolocation data: {0}" -msgstr "Data for geolokalitet: {0}" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "Information" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "" -"TWBlue has detected that you're running windows 10 and has changed the " -"default keymap to the Windows 10 keymap. It means that some keyboard " -"shorcuts could be different. Please check the keystroke editor by pressing " -"Alt+Win+K to see all available keystrokes for this keymap." -msgstr "" -"TWBlue har opdaget, at du kører Windows 10 og har skiftet " -"standardtastaturkommandoerne til Windows 10 keymap. Det betyder, at nogle " -"tastaturgenveje kan være forskellige. Tjek venligst de tilgængelige " -"tastetryk ved at trykke på ALT+WIN+K for at se alle tilgængelige tastetryk " -"for dette sæt af tastaturgenveje." - -#: ../src\wxUI\commonMessageDialogs.py:76 -msgid "You have been blocked from viewing this content" -msgstr "Du er blevet blokeret for at se dette indhold" - -#: ../src\wxUI\commonMessageDialogs.py:79 -msgid "" -"You have been blocked from viewing someone's content. In order to avoid " -"conflicts with the full session, TWBlue will remove the affected timeline." -msgstr "" -"Du er blevet blokeret fra at se en persons indhold. For at undgå konflikter " -"med den fulde session fjerner TWBlue den berørte tidslinje." - -#: ../src\wxUI\commonMessageDialogs.py:82 -msgid "" -"TWBlue cannot load this timeline because the user has been suspended from " -"Twitter." -msgstr "" -"TWBlue kan ikke indlæse denne tidslinje, fordi brugeren er blevet " -"suspenderet fra Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Do you really want to delete this filter?" -msgstr "Er du sikker på, at du vil slette dette filter?" - -#: ../src\wxUI\commonMessageDialogs.py:88 -msgid "This filter already exists. Please use a different title" -msgstr "Dette filter findes allerede. Benyt venligst en anden titel." - -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "" -"{0} quit unexpectedly the last time it was run. If the problem persists, " -"please report it to the {0} developers." -msgstr "" - -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Tilføj et bilag" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Bilag" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Titel" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Type" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Tilføj bilag" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Billede" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Fjern bilag" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Billedfiler (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Vælg det billede, der skal uploades" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Giv en kort beskrivelse" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "beskrivelse" - -#: ../src\wxUI\dialogs\configuration.py:16 -msgid "Language" -msgstr "Sprog" - -#: ../src\wxUI\dialogs\configuration.py:23 -msgid "Run {0} at Windows startup" -msgstr "Kør {0} når Windows starter" - -#: ../src\wxUI\dialogs\configuration.py:24 -msgid "ask before exiting {0}" -msgstr "Spørg før du afslutter {0}" - -#: ../src\wxUI\dialogs\configuration.py:27 -msgid "Disable Streaming functions" -msgstr "Deaktivér streaming-funktionalitet" - -#: ../src\wxUI\dialogs\configuration.py:30 -msgid "Buffer update interval, in minutes" -msgstr "Buffer-opdateringsinterval, i minutter" - -#: ../src\wxUI\dialogs\configuration.py:36 -msgid "Play a sound when {0} launches" -msgstr "Afspil en lyd, når {0} starter" - -#: ../src\wxUI\dialogs\configuration.py:38 -msgid "Speak a message when {0} launches" -msgstr "Sig en besked, når {0} starter" - -#: ../src\wxUI\dialogs\configuration.py:40 -msgid "Use invisible interface's keyboard shortcuts while GUI is visible" -msgstr "" -"Brug tastaturgenveje for den usynlige grænseflade, mens brugergrænsefladen " -"er synlig" - -#: ../src\wxUI\dialogs\configuration.py:42 -msgid "Activate Sapi5 when any other screen reader is not being run" -msgstr "Aktivér Sapi5, når en anden skærmlæser ikke køres" - -#: ../src\wxUI\dialogs\configuration.py:44 -msgid "Hide GUI on launch" -msgstr "Skjul brugergrænsefladen ved opstart" - -#: ../src\wxUI\dialogs\configuration.py:46 -msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" -msgstr "Brug Codeofdusks longtweet handlers (kan reducere klientens ydeevne)" - -#: ../src\wxUI\dialogs\configuration.py:48 -msgid "Remember state for mention all and long tweet" -msgstr "Husk indstilling for \"omtal alle\" og \"lang tweet\"" - -#: ../src\wxUI\dialogs\configuration.py:51 -msgid "Keymap" -msgstr "Sæt af tastaturkommandoer" - -#: ../src\wxUI\dialogs\configuration.py:56 -msgid "Check for updates when {0} launches" -msgstr "Søg efter opdateringer, når {0} starter" - -#: ../src\wxUI\dialogs\configuration.py:66 -msgid "Proxy type: " -msgstr "Proxy- type:" - -#: ../src\wxUI\dialogs\configuration.py:73 -msgid "Proxy server: " -msgstr "Proxyserver:" - -#: ../src\wxUI\dialogs\configuration.py:79 -msgid "Port: " -msgstr "Port:" - -#: ../src\wxUI\dialogs\configuration.py:85 -msgid "User: " -msgstr "Bruger:" - -#: ../src\wxUI\dialogs\configuration.py:91 -msgid "Password: " -msgstr "Adgangskode:" - -#: ../src\wxUI\dialogs\configuration.py:103 -msgid "Autocompletion settings..." -msgstr "Autofuldførelsesindstillinger..." - -#: ../src\wxUI\dialogs\configuration.py:105 -msgid "Relative timestamps" -msgstr "Relative tidsstempler" - -#: ../src\wxUI\dialogs\configuration.py:108 -msgid "Items on each API call" -msgstr "Emner ved hvert API-opkald" - -#: ../src\wxUI\dialogs\configuration.py:114 -msgid "" -"Inverted buffers: The newest tweets will be shown at the beginning while the " -"oldest at the end" -msgstr "" -"Inverterede buffere: De nyeste tweets vil blive vist i toppen, mens de " -"ældste vises i bunden" - -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet mode" -msgstr "Retweet-tilstand" - -#: ../src\wxUI\dialogs\configuration.py:122 -msgid "Show screen names instead of full names" -msgstr "Vis skærmnavne i stedet for fulde navne" - -#: ../src\wxUI\dialogs\configuration.py:124 -msgid "" -"Number of items per buffer to cache in database (0 to disable caching, blank " -"for unlimited)" -msgstr "" -"Antal emner pr. Buffer til cache i databasen (0 for at deaktivere caching, " -"blank for ubegrænset)" - -#: ../src\wxUI\dialogs\configuration.py:134 -msgid "Enable automatic speech feedback" -msgstr "Aktivér automatisk talefeedback" - -#: ../src\wxUI\dialogs\configuration.py:136 -msgid "Enable automatic Braille feedback" -msgstr "Aktiver automatisk punktfeedback" - -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Status" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Buffer" -msgstr "Buffer" - -#: ../src\wxUI\dialogs\configuration.py:147 -msgid "Show/hide" -msgstr "Vis/skjul" - -#: ../src\wxUI\dialogs\configuration.py:148 -msgid "Move up" -msgstr "Flyt op" - -#: ../src\wxUI\dialogs\configuration.py:149 -msgid "Move down" -msgstr "Flyt ned" - -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 -msgid "Show" -msgstr "Vis" - -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 -msgid "Hide" -msgstr "Skjul" - -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 -msgid "Select a buffer first." -msgstr "Vælg først en buffer." - -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 -msgid "The buffer is hidden, show it first." -msgstr "Bufferen er skjult, vis den først." - -#: ../src\wxUI\dialogs\configuration.py:175 -msgid "The buffer is already at the top of the list." -msgstr "Bufferen er allerede øverst på listen." - -#: ../src\wxUI\dialogs\configuration.py:199 -msgid "The buffer is already at the bottom of the list." -msgstr "Bufferen er allerede nederst på listen." - -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 -msgid "Ignored clients" -msgstr "Ignorerede klienter" - -#: ../src\wxUI\dialogs\configuration.py:247 -msgid "Remove client" -msgstr "Fjern klient" - -#: ../src\wxUI\dialogs\configuration.py:271 -msgid "Volume" -msgstr "Lydstyrke" - -#: ../src\wxUI\dialogs\configuration.py:282 -msgid "Session mute" -msgstr "Sessiondæmpning" - -#: ../src\wxUI\dialogs\configuration.py:284 -msgid "Output device" -msgstr "Output- enhed" - -#: ../src\wxUI\dialogs\configuration.py:291 -msgid "Input device" -msgstr "Input- enhed" - -#: ../src\wxUI\dialogs\configuration.py:299 -msgid "Sound pack" -msgstr "Lydpakke" - -#: ../src\wxUI\dialogs\configuration.py:305 -msgid "Indicate audio tweets with sound" -msgstr "Angiv lydtweets med en lyd" - -#: ../src\wxUI\dialogs\configuration.py:307 -msgid "Indicate geotweets with sound" -msgstr "Angiv geotweets med en lyd" - -#: ../src\wxUI\dialogs\configuration.py:309 -msgid "Indicate tweets containing images with sound" -msgstr "Angiv tweets der indeholder billeder med en lyd" - -#: ../src\wxUI\dialogs\configuration.py:332 -msgid "Language for OCR" -msgstr "Sprog til tekstgenkendelse" - -#: ../src\wxUI\dialogs\configuration.py:338 -msgid "API Key for SndUp" -msgstr "API-nøgle til SndUp" - -#: ../src\wxUI\dialogs\configuration.py:353 -msgid "{0} preferences" -msgstr "{0} indstillinger" - -#: ../src\wxUI\dialogs\configuration.py:364 -msgid "Proxy" -msgstr "Proxy" - -#: ../src\wxUI\dialogs\configuration.py:373 -msgid "Feedback" -msgstr "Feedback" - -#: ../src\wxUI\dialogs\configuration.py:377 -msgid "Buffers" -msgstr "Buffere" - -#: ../src\wxUI\dialogs\configuration.py:385 -msgid "Sound" -msgstr "Lyd" - -#: ../src\wxUI\dialogs\configuration.py:389 -msgid "Extras" -msgstr "Ekstra" - -#: ../src\wxUI\dialogs\configuration.py:394 -msgid "Save" -msgstr "Gem" - -#: ../src\wxUI\dialogs\filterDialogs.py:15 -msgid "Create a filter for this buffer" -msgstr "Opret et filter for denne buffer" - -#: ../src\wxUI\dialogs\filterDialogs.py:16 -msgid "Filter title" -msgstr "Filtrér titel" - -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "Filtrér efter ord" - -#: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "Ignorer tweets der indeholder følgende ord" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -msgid "Ignore tweets without the following word" -msgstr "Ignorer tweets uden følgende ord" - -#: ../src\wxUI\dialogs\filterDialogs.py:32 -msgid "word" -msgstr "ord" - -#: ../src\wxUI\dialogs\filterDialogs.py:37 -msgid "Allow retweets" -msgstr "Tillad retweets" - -#: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "Tillad citerede tweets" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -msgid "Allow replies" -msgstr "Tillad svar" - -#: ../src\wxUI\dialogs\filterDialogs.py:47 -msgid "Use this term as a regular expression" -msgstr "Brug dette udtryk som et regulært udtryk" - -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by language" -msgstr "Filtrer efter sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "Indlæs tweets i de følgende sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "Ignorer tweets i de følgende sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 -msgid "Don't filter by language" -msgstr "Filtrér ikke efter sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:63 -msgid "Supported languages" -msgstr "Understøttede sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:68 -msgid "Add selected language to filter" -msgstr "Tilføj valge sprog til filter" - -#: ../src\wxUI\dialogs\filterDialogs.py:72 -msgid "Selected languages" -msgstr "Valgte sprog" - -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 -msgid "Remove" -msgstr "Fjern" - -#: ../src\wxUI\dialogs\filterDialogs.py:122 -msgid "Manage filters" -msgstr "Administrer filtre" - -#: ../src\wxUI\dialogs\filterDialogs.py:124 -msgid "Filters" -msgstr "Filtre" - -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter" -msgstr "Filter" - -#: ../src\wxUI\dialogs\find.py:12 -msgid "Find in current buffer" -msgstr "Find i den aktuelle buffer" - -#: ../src\wxUI\dialogs\find.py:13 -msgid "String" -msgstr "Streng" - -#: ../src\wxUI\dialogs\lists.py:10 -msgid "Lists manager" -msgstr "Listemanager" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "List" -msgstr "Liste" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "Medlemmer" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Owner" -msgstr "Ejer" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "mode" -msgstr "tilstand" - -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 -msgid "Create a new list" -msgstr "Opret en ny liste" - -#: ../src\wxUI\dialogs\lists.py:21 -msgid "Open in buffer" -msgstr "Åbn i buffer" - -#: ../src\wxUI\dialogs\lists.py:51 -msgid "Viewing lists for %s" -msgstr "Viser lister for %s" - -#: ../src\wxUI\dialogs\lists.py:52 -msgid "Subscribe" -msgstr "Tilmeld" - -#: ../src\wxUI\dialogs\lists.py:53 -msgid "Unsubscribe" -msgstr "Afmeld" - -#: ../src\wxUI\dialogs\lists.py:64 -msgid "Name (20 characters maximun)" -msgstr "Navn (maks. 20 tegn)" - -#: ../src\wxUI\dialogs\lists.py:74 -msgid "Mode" -msgstr "Tilstand" - -#: ../src\wxUI\dialogs\lists.py:75 -msgid "Public" -msgstr "Offentlig" - -#: ../src\wxUI\dialogs\lists.py:76 -msgid "Private" -msgstr "Privat" - -#: ../src\wxUI\dialogs\lists.py:96 -msgid "Editing the list %s" -msgstr "Redigerer listen %s" - -#: ../src\wxUI\dialogs\lists.py:107 -msgid "Select a list to add the user" -msgstr "Vælg en liste for at tilføje brugeren" - -#: ../src\wxUI\dialogs\lists.py:108 -msgid "Add" -msgstr "Tilføj" - -#: ../src\wxUI\dialogs\lists.py:130 -msgid "Select a list to remove the user" -msgstr "Vælg en liste for at fjerne brugeren" - -#: ../src\wxUI\dialogs\lists.py:148 -msgid "Do you really want to delete this list?" -msgstr "Er du sikker på, at du vil slette denne liste ?" - -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "&Lang tweet" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Upload billede" - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Kontroller &stavning…" - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Vedhæft lyd..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Fork&ort URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Udvid URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Oversæt…" - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Auto&fuldfør brugere" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "Sen&d" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "&Luk" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Modtager" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Omtal alle" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tweet - %i tegn" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Billedbeskrivelse" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "retweets:" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Synes godt om:" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Kilde:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "Dato" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Vis" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Emne" - -#: ../src\wxUI\dialogs\search.py:13 -msgid "Search on Twitter" -msgstr "Søg på Twitter" - -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "&Søg" - -#: ../src\wxUI\dialogs\search.py:21 -msgid "Tweets" -msgstr "Tweets" - -#: ../src\wxUI\dialogs\search.py:22 -msgid "Users" -msgstr "Brugere" - -#: ../src\wxUI\dialogs\search.py:29 -msgid "&Language for results: " -msgstr "&Sprog for resultater:" - -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 -msgid "any" -msgstr "alle" - -#: ../src\wxUI\dialogs\search.py:37 -msgid "Results &type: " -msgstr "Resultat&typer: " - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 -msgid "Mixed" -msgstr "Blandet" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 -msgid "Recent" -msgstr "Seneste" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 -msgid "Popular" -msgstr "Populær" - -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 -msgid "&OK" -msgstr "&OK" - -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 -msgid "&Close" -msgstr "&Luk" - -#: ../src\wxUI\dialogs\show_user.py:11 -msgid "Details" -msgstr "Detaljer" - -#: ../src\wxUI\dialogs\show_user.py:16 -msgid "&Go to URL" -msgstr "&Gå til URL" - -#: ../src\wxUI\dialogs\trends.py:12 -msgid "View trending topics" -msgstr "Se trending emner" - -#: ../src\wxUI\dialogs\trends.py:13 -msgid "Trending topics by" -msgstr "Trends for" - -#: ../src\wxUI\dialogs\trends.py:15 -msgid "Country" -msgstr "Land" - -#: ../src\wxUI\dialogs\trends.py:16 -msgid "City" -msgstr "By" - -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 -msgid "&Location" -msgstr "&Lokalitet" - -#: ../src\wxUI\dialogs\update_profile.py:9 -msgid "Update your profile" -msgstr "Opdater din profil" - -#: ../src\wxUI\dialogs\update_profile.py:11 -msgid "&Name (50 characters maximum)" -msgstr "&Navn (50 tegn max)" - -#: ../src\wxUI\dialogs\update_profile.py:22 -msgid "&Website" -msgstr "&Webside" - -#: ../src\wxUI\dialogs\update_profile.py:27 -msgid "&Bio (160 characters maximum)" -msgstr "&Bio (maks. 160 tegn)" - -#: ../src\wxUI\dialogs\update_profile.py:33 -msgid "Upload a &picture" -msgstr "Upload et &billede" - -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "&Opdater profil" - -#: ../src\wxUI\dialogs\update_profile.py:76 -msgid "Upload a picture" -msgstr "Upload et billede" - -#: ../src\wxUI\dialogs\update_profile.py:78 -msgid "Discard image" -msgstr "Kassér billede" - -#: ../src\wxUI\dialogs\urlList.py:5 -msgid "Select URL" -msgstr "Vælg URL" - -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "&Bruger" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 -msgid "&Autocomplete users" -msgstr "&Autofuldfør brugere" - -#: ../src\wxUI\dialogs\userActions.py:19 -msgid "&Follow" -msgstr "&Følg" - -#: ../src\wxUI\dialogs\userActions.py:20 -msgid "U&nfollow" -msgstr "&Stop med at følge" - -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "&Dæmp" - -#: ../src\wxUI\dialogs\userActions.py:22 -msgid "Unmu&te" -msgstr "&Dæmp ikke" - -#: ../src\wxUI\dialogs\userActions.py:23 -msgid "&Block" -msgstr "&Blokér" - -#: ../src\wxUI\dialogs\userActions.py:24 -msgid "Unbl&ock" -msgstr "&Fjern blokering" - -#: ../src\wxUI\dialogs\userActions.py:25 -msgid "&Report as spam" -msgstr "&Rapporter som spam" - -#: ../src\wxUI\dialogs\userActions.py:26 -msgid "&Ignore tweets from this client" -msgstr "&Ignorer tweets fra denne klient" - -#: ../src\wxUI\dialogs\userSelection.py:9 -msgid "Timeline for %s" -msgstr "Tidslinje for %s" - -#: ../src\wxUI\dialogs\userSelection.py:18 -msgid "Buffer type" -msgstr "Buffertype" - -#: ../src\wxUI\dialogs\userSelection.py:19 -msgid "&Tweets" -msgstr "&Tweets" - -#: ../src\wxUI\dialogs\userSelection.py:20 -msgid "&Likes" -msgstr "&Synes godt om" - -#: ../src\wxUI\dialogs\userSelection.py:21 -msgid "&Followers" -msgstr "&Følgere" - -#: ../src\wxUI\dialogs\userSelection.py:22 -msgid "F&riends" -msgstr "&Venner" - -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "&Retweet" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "&Svar" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "S&ynes godt om" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "Fjern Synes &godt om" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "Åbn &URL" - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy -msgid "&Open in Twitter" -msgstr "Søg på Twitter" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "&Afspil lyd" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "&Vis tweet" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "&Kopiér til udklipsholder" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "&Slet" - -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "&Brugerhandlinger…" - -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "&Vis direkte besked" - -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "&Vis begivenhed" - -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "Direkte &besked" - -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "&Vis lister" - -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "Vis bruger&profil" - -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "Vis &bruger" - -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "&Tweet om denne trend" - -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "&Vis emne" - -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "&Globale indstillinger" - -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "&Kontoindstillinger" - -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "Opdater &profil" - -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "vis/skjul" - -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "&Dokumentation" - -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "&Søg efter opdateringer" - -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "&Afslut" - -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "&Kontihåndtering" - -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "&Skjul vindue" - -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "&Listemanager" - -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "&Rediger tastetryk" - -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "&Afslut" - -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "&Tweet" - -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "Vis &adresse" - -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "Vis sa&&tale" - -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "Læs tekst på billedet" - -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "&Handlinger..." - -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "&Vis tidslinje..." - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "Direkte &besked" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "&Tilføj til liste" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "&Fjern fra liste" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "V&is synes godt om" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "&Opdater buffer" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "Ny &trending emner buffer..." - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "Opret et nyt &filter" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "&Administrer filtre" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "Find en streng i den aktuelt fokuserede buffer..." - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "&Indlæs tidligere emner" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "&Automatisk læsning" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "&Ryd buffer" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "&Ødelæg" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "&Søg tilbage 5 sekunder" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "&Søg fremad 5 sekunder" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "&Hør lyde" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "&Hvad er nyt i denne version?" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "&Søg efter opdateringer" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "&Rapporter en fejl" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "{0}s &websted" - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "&Om {0}" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "&Applikation" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "&Buffer" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "&Lyd" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "&Hjælp" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "Adresse" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "Opdatér" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "Din {0} version er opdateret" - -#~ msgid "Empty" -#~ msgstr "Tom" - -#~ msgid "One mention from %s " -#~ msgstr "En omtale fra %s" - -#~ msgid "One tweet from %s" -#~ msgstr "Et tweet fra %s" - -#~ msgid "You've blocked %s" -#~ msgstr "Du har blokeret %s" - -#~ msgid "You've unblocked %s" -#~ msgstr "Du har fjernet blokeringen af %s" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "%s (@%s) har fulgt dig" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "Du har fulgt %s (@%s)" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "Du følger ikke længere %s (@%s)" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "Du synes godt om: %s, %s" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s) synes godt om: %s" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "Du synes ikke længere om: %s, %s" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s) synes ikke længere om: %s" - -#~ msgid "You've created the list %s" -#~ msgstr "Du har oprettet listen %s" - -#~ msgid "You've deleted the list %s" -#~ msgstr "Du har slettet listen %s" - -#~ msgid "You've updated the list %s" -#~ msgstr "Du har opdateret listen %s" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "Du har tilføjet %s(@%s) til listen %s" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "%s(@%s) har tilføjet dig til listen %s" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "Du er fjernet %s(@%s) fra listen %s" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "%s(@%s) har fjernet dig fra listen %s" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "Du har abonneret på listen %s, som ejes af %s(@%s)" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "%s(@%s) har tilmeldt dig til listen %s" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Du har afmeldt dig fra listen %s, som ejes af %s(@%s)" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Du er blevet afmeldt fra listen %s, som ejes af %s(@%s)" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "Du har retweetet et retweet fra %s(@%s): %s" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "%s(@%s) har retweetet dit retweet: %s" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "API-opkald (Et API-opkald = 200 tweets, to API-opkald = 400 tweets osv.):" - -#~ msgid "Unable to upload the audio" -#~ msgstr "Ikke i stand til at uploade lyd" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "Venter på kontogodkendelse..." - -#~ msgid "autodetect" -#~ msgstr "opdag automatisk" diff --git a/src/locales/es/LC_MESSAGES/twblue.mo b/src/locales/es/LC_MESSAGES/twblue.mo index 72cc7b91..41660d8d 100644 Binary files a/src/locales/es/LC_MESSAGES/twblue.mo and b/src/locales/es/LC_MESSAGES/twblue.mo differ diff --git a/src/locales/es/LC_MESSAGES/twblue.po b/src/locales/es/LC_MESSAGES/twblue.po index 1b41db22..55b892fd 100644 --- a/src/locales/es/LC_MESSAGES/twblue.po +++ b/src/locales/es/LC_MESSAGES/twblue.po @@ -1,1801 +1,105 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.84\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2019-05-06 23:03+0200\n" -"Last-Translator: José Manuel Delicado \n" +"Report-Msgid-Bugs-To: manuel@manuelcortez.net\n" +"POT-Creation-Date: 2021-11-12 13:22-0600\n" +"PO-Revision-Date: 2021-11-12 13:29-0600\n" +"Last-Translator: Manuel Cortez \n" "Language-Team: Manuel Cortez \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.1\n" +"X-Generator: Poedit 3.0\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: UTF-8\n" -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Imagen" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "Esta acción no se encuentra soportada para este buffer" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "Principal" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "Menciones" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "Mensajes directos" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "Mensajes directos enviados" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "Tuits enviados" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "Tuits marcados como me gusta" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "Seguidores" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Amigos" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "Usuarios bloqueados" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "Usuarios silenciados" - -#: ../src\controller\buffers\twitterBuffers.py:75 -msgid "{username}'s timeline" -msgstr "Línea temporal de {username}" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "Tuits que le gustan a {username}" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "Seguidores de {username}" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "Amigos de {username}" - -#: ../src\controller\buffers\twitterBuffers.py:83 -msgid "Unknown buffer" -msgstr "Buffer desconocido" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "Tuit" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "Escribe el tuit aquí" - -#: ../src\controller\buffers\twitterBuffers.py:194 -msgid "New tweet in {0}" -msgstr "Nuevo tuit en {0}" - -#: ../src\controller\buffers\twitterBuffers.py:197 -msgid "{0} new tweets in {1}." -msgstr "{0} nuevos tuits en {1}." - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s elementos recuperados" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Este buffer no es una línea temporal. No se puede eliminar." - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "Responder a {arg0}" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "Responder" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "Responder a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Mensaje directo a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "Nuevo mensaje directo" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "Añade tu comentario al tuit" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "Citar" - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "Abriendo URL..." - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "Detalles del usuario" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "Abriendo elemento en el navegador..." - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "Mencionar a %s" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "Mención" - -#: ../src\controller\buffers\twitterBuffers.py:728 -msgid "{0} new direct messages." -msgstr "{0} mensajes directos nuevos." - -#: ../src\controller\buffers\twitterBuffers.py:731 -msgid "This action is not supported in the buffer yet." -msgstr "Esta acción todavía no se soporta en este buffer." - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" -"No se pueden obtener más elementos en este buffer. Usa el buffer de mensajes " -"directos en su lugar." - -#: ../src\controller\buffers\twitterBuffers.py:983 -msgid "{0} new followers." -msgstr "{0} nuevos seguidores." - -#: ../src\controller\buffers\twitterBuffers.py:1266 -msgid "This action is not supported in the buffer, yet." -msgstr "Esta acción todavía no se soporta en este buffer." - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "Listo" - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "Líneas temporales" - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "Línea temporal de {0}" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "Líneas temporales de tuits marcados con me gusta" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "Tuits que le gustan a {0}" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Líneas temporales de seguidores" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "Seguidores de {0}" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Líneas temporales de amigos" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "Amigos de {0}" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "Listas" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "Lista {0}" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "Búsquedas" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "Buscar {0}" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "Tendencias para %s" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "No estás en ninguna sesión. Cambia a una sesión activa." - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "Buffer vacío." - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0} no encontrado." - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "No pueden aplicarse filtros sobre este buffer" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "Selecciona un usuario" - -#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236 -msgid "MMM D, YYYY. H:m" -msgstr "D MMM, YYYY. H:m" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "Conversación con {0}" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "No hay coordenadas en este tuit" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "No hay resultados para las coordenadas en este tuit" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "Error decodificando las coordenadas. Inténtalo nuevamente más tarde." - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s, %s de %s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%s. Vacío" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s de %s" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Eventos" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "Esta lista ya ha sido abierta" - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"Ha ocurrido un error al intentar conectarse al servidor. Por favor, " -"inténtalo más tarde." - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "La lectura automática de nuevos tuits para este buffer está activada" - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "" -"La lectura automática de nuevos tuits para este buffer está desactivada" - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "Silencio de sesión activo" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "Silencio de sesión desactivado" - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "Silenciar buffer, activado" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "Silenciar buffer, desactivado" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "Copiado" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "Imposible actualizar este buffer." - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "Actualizando buffer..." - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0} elementos descargados" - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "Buffer inválido" - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "El tuit no contiene imágenes" - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "Foto {0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "Selecciona la foto" - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "Imposible extraer texto" - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "Traducido" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "No hay ninguna URL para acortar" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URL Acortada" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "No hay ninguna URL para expandir" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URL expandida" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s de %d caracteres" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s caracteres" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "Ver elemento" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Conexión directa" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "Preguntar" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "Retuitear sin comentario" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "Retuitear añadiendo un comentario" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "Opciones de la cuenta de %s" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "Mensajes directos" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "Error" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "El usuario no existe" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "El usuario ha sido suspendido" - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "Detalles para %s" - -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "Descartado" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Nombre de usuario: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Nombre: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Ubicación: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "Descripción: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "Sí" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "No" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "Protegido: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "Sigues a {0}. " - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr "{0} te sigue." - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Seguidores: %s\n" -" Amigos: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "Verificado: %s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "Tuits: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "Me gusta: %s" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "No puedes ignorar los mensajes directos" - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "Adjuntando..." - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "&Reanudar" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "Reanudar" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "&Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "&Detener" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "Grabando" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "Stopped" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "&Grabar" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "Reproduciendo..." - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "&Reproducir" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "Recodificando audio..." - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "Error al subir el archivo: {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "%d día, " - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%d días, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "%d hora, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d horas, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "%d minuto, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d minutos, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "%s segundo" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s segundos" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "Archivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "Transferido" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "Tamaño total del archivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "Velocidad de transferencia" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "Tiempo restante" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "Adjuntar audio" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "&Añadir un archivo existente" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "&Descartar" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "Subir a" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "Adjuntar" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "&Cancelar" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Archivos de audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "Selecciona el archivo de audio que deseas subir" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "Tuit con audio." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "Línea temporal de un usuario creada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "Buffer eliminado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Mensaje directo recibido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Mensaje directo enviado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "Error." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "Tuit marcado como me gusta." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "Un Buffer de tuits marcados como me gusta se ha actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "Tuit con información geográfica." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "El tuit contiene una o más imágenes" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "No hay más elementos en el buffer." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "Lista actualizada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "Demasiados caracteres." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "Mención recibida." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "Nuevo evento." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0} está listo." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "Mención enviada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "Tuit retuiteado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "Buffer de búsqueda actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "Tuit recibido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "Tuit enviado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "Buffer de trending topics actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "Nuevo tuit en línea temporal de un usuario." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "Nuevo seguidor." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "Volumen modificado." - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "Tutorial de sonidos" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "Pulsa enter para escuchar el sonido para el evento seleccionado" - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "Palabra mal escrita: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "Palabra mal escrita" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "Contexto" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "Sugerencias" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "&Ignorar" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "Ignorar &todo" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "&Reemplazar" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "R&eemplazar todo" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "Añadir al &diccionario" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"Ha ocurrido un error. No se encuentran diccionarios disponibles para el " -"idioma seleccionado en {0}." - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "Corrección ortográfica finalizada." - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "Tienes que empezar a escribir" - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "No hay resultados en tu base de datos de usuarios" - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "El autocompletado solo funciona con usuarios." - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Actualizando base de datos... Puedes cerrar esta ventana ahora. Un mensaje " -"te informará cuando el proceso haya terminado." - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "Gestionar la base de datos del autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "Editando la base de datos de usuarios de {0}" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "Nombre de usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Nombre" - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "Añadir usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "Quitar usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "Añadir usuario a la base de datos" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "Nombre de usuario de Twitter" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "El usuario no existe" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "¡Error!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Opciones de autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Añadir usuarios desde el buffer de seguidores" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Añadir usuarios desde el buffer de amigos" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Administrar base de datos..." - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "¡Hecho" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "La base de datos de usuarios de {0} ha sido actualizada." - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "Detectar automáticamente" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "Danés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "Holandés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "Inglés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "Finés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "Francés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "Alemán" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "Húngaro" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "Italiano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "Japonés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "Coreano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "Polaco" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "Portugués" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "Ruso" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "Español" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "Turco" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "Africano" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "Albanés" - -#: ../src\extra\translator\translator.py:14 +#: languageHandler.py:61 +msgctxt "languageName" msgid "Amharic" msgstr "Amárico" -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "Árabe" +#: languageHandler.py:62 +msgctxt "languageName" +msgid "Aragonese" +msgstr "Aragonés" -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "Armenio" +#: languageHandler.py:63 +msgctxt "languageName" +msgid "Spanish" +msgstr "Español" -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "Acerí" +#: languageHandler.py:64 +msgctxt "languageName" +msgid "Portuguese" +msgstr "Portugués" -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "Vasco" +#: languageHandler.py:65 +msgctxt "languageName" +msgid "Russian" +msgstr "Ruso" -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "Bielorruso" +#: languageHandler.py:66 +msgctxt "languageName" +msgid "italian" +msgstr "Italiano" -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "Bengalí" +#: languageHandler.py:67 +msgctxt "languageName" +msgid "Turkey" +msgstr "Turco" -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "Búlgaro" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "Birmano" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "Catalán" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "Cheroqui" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "Chino" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "Chino simplificado" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "Chino tradicional" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "Croata" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "Checo" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "Esperanto" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "Estonio" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "Filipino" - -#: ../src\extra\translator\translator.py:40 +#: languageHandler.py:68 +msgctxt "languageName" msgid "Galician" msgstr "Gallego" -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "Georgiano" +#: languageHandler.py:69 +msgctxt "languageName" +msgid "Catala" +msgstr "Catalán" -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "Griego" +#: languageHandler.py:70 +msgctxt "languageName" +msgid "Vasque" +msgstr "Vasco" -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "Guaraní" +#: languageHandler.py:71 +msgctxt "languageName" +msgid "polish" +msgstr "Polaco" -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "Guyaratí" +#: languageHandler.py:72 +msgctxt "languageName" +msgid "Arabic" +msgstr "Árabe" -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "Hebreo" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "Hindi" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "Islandés" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "Indonesio" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "Irlandés" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "Canarés" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "Kazajo" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "Camboyano" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "Kurdo" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "Kirguís" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "Lao" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "Letón" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "Lituano" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "Macedonio" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "Malayo" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "Malayalam" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "Maltés" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "Maratí" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "Mongol" - -#: ../src\extra\translator\translator.py:70 +#: languageHandler.py:73 +msgctxt "languageName" msgid "Nepali" msgstr "Nepalí" -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "Noruego" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr "Oriya" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "Pastú" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "Persa" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "Panyabí" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "Rumano" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "Sánscrito" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" +#: languageHandler.py:74 +msgctxt "languageName" +msgid "Serbian (Latin)" msgstr "Serbio" -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "Sindhi" +#: languageHandler.py:75 +msgctxt "languageName" +msgid "Japanese" +msgstr "Japonés" -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "Cingalés" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "Eslovaco" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "Esloveno" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "Suajili" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "Sueco" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "Tayiko" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "Tamil" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "Tagalo" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "Telugú" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "Tailandés" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "Tibetano" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "Ucraniano" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "Uzbeco" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "Uigur" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "Vietnamita" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "Galés" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "Yídish" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "Traducir mensaje" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "Idioma de destino" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "General" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "siempre" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "no se ha intentado" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "aleatoriamente" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "a veces" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "imposible de reproducir" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "bloqueo" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "fallo" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "característica" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "mayor" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "menor" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "texto" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "trivial" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "ajuste" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "Reportar un error" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "Selecciona una categoría" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "" -"Describe en pocas palabras lo que ha pasado (después podrás profundizar)" - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "Aquí puedes describir el error en detalle" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "¿Qué tan a menudo ocurre este error?" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "Selecciona la importancia que consideras que tiene este error" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Sé que el sistema de errores de {0} obtendrá mi nombre de usuario de Twitter " -"para contactarme y resolver el error rápidamente" - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "Enviar reporte" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "Cancelar" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "Debes llenar ambos campos" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Debes marcar la casilla para proporcionarnos tu nombre de usuario de Twitter " -"para poder contactarte si es necesario." - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"¡Gracias por reportar este error! Quizá puedas verlo entre la lista de " -"cambios de próximas versiones. Has reportado el error número %i" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "reportado" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "Error al reportar" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Algo inesperado ocurrió mientras intentábamos reportar tu error. Por favor, " -"vuelve a intentarlo más tarde" - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Va arriba en la lista actual" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "Va abajo en la lista actual" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Va al buffer anterior" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Va al buffer siguiente" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Ir a la siguiente sesión" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Va a la sesión anterior" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Muestra o esconde la interfaz gráfica" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Nuevo tuit" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Retuit" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Enviar mensaje directo" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "Marcar tuit como me gusta" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "Marcar o remover tuit como me gusta" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Marcar tuit como ya no me gusta" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Abrir el diálogo de acciones" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Ver detalles del usuario" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Ver tuit" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "Salir" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Abrir línea temporal" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Eliminar buffer" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interactuar con el tuit que tiene el foco." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Abrir URL" - -#: ../src\keystrokeEditor\constants.py:25 -msgid "View in Twitter" -msgstr "Ver en Twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Subir volumen en un 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Bajar volumen en un 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Ir al primer elemento del buffer" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Ir al último elemento del buffer" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Moverse 20 elementos hacia arriba en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Moverse 20 elementos hacia abajo en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Editar perfil" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Eliminar tuit o mensaje directo" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Vaciar buffer" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Repetir último elemento" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Copiar al portapapeles" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Añadir a lista" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Quitar de lista" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Silenciar o des-silenciar el buffer activo" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Activar o desactivar el silencio para la sesión activa" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "" -"conmutar entre la lectura automática de nuevos tuits para el buffer actual" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "Buscar en Twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Buscar un término en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Mostrar el editor de combinaciones de teclado" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Mostrar listas para un usuario específico" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "cargar elementos anteriores" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Obtener ubicación" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Mostrar la ubicación del tuit en un diálogo" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Crear un buffer de tendencias" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Ver conversación" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "&Comprobar y descargar actualizaciones" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Abre el gestor de listas, que permite crear, editar, eliminar y abrir listas " -"como buffers." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Abre el diálogo de opciones globales" - -#: ../src\keystrokeEditor\constants.py:54 -msgid "Opens the list manager" -msgstr "Abre el gestor de listas" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Abre el diálogo de opciones de cuenta" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Intentar reproducir audio" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Actualiza el buffer e intenta descargar los elementos perdidos." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "Extrae el texto de una foto y muestra el resultado en un diálogo." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Editor de combinaciones de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Selecciona una combinación de teclado para editarla" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "Combinación de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "Acción" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "Editar" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "Ejecutar acción" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "Cerrar" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "Editando combinación de teclas" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "Control" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "Shift" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "Windows" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "Tecla" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "Aceptar" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "Necesitas usar la tecla de windows" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "Combinación de teclado inválida" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "Debes proporcionar una letra para el atajo de teclado" - -#: ../src\languageHandler.py:99 +#: languageHandler.py:99 msgid "User default" msgstr "Idioma predeterminado" -#: ../src\main.py:105 +#: main.py:120 msgid "https://twblue.es/donate" msgstr "https://twblue.es/donate" -#: ../src\main.py:122 +#: main.py:137 msgid "" "{0} is already running. Close the other instance before starting this one. " "If you're sure that {0} isn't running, try deleting the file at {1}. If " @@ -1806,43 +110,1839 @@ msgstr "" "archivo que se encuentra en {1}. Si no sabes cómo hacerlo con seguridad, " "contacta con los desarrolladores de {0}." -#: ../src\sessionmanager\wxUI.py:8 +#: extra/AudioUploader/audioUploader.py:136 sound.py:147 +msgid "Playing..." +msgstr "Reproduciendo..." + +#: sound.py:160 +msgid "Stopped." +msgstr "Detenido." + +#: controller/mainController.py:277 +msgid "Ready" +msgstr "Listo" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:337 +#: controller/settings.py:286 +msgid "Home" +msgstr "Inicio" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:339 +#: controller/settings.py:287 +msgid "Mentions" +msgstr "Menciones" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:341 +msgid "Direct messages" +msgstr "Mensajes directos" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:343 +#: controller/settings.py:289 +msgid "Sent direct messages" +msgstr "Mensajes directos enviados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:345 +#: controller/settings.py:290 +msgid "Sent tweets" +msgstr "Tuits enviados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:347 +#: controller/mainController.py:1390 controller/settings.py:291 +msgid "Likes" +msgstr "Tuits marcados como me gusta" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:349 +#: controller/mainController.py:1395 controller/settings.py:292 +msgid "Followers" +msgstr "Seguidores" + +#: controller/mainController.py:351 +msgid "Following" +msgstr "Siguiendo" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:353 +#: controller/mainController.py:1405 controller/settings.py:294 +msgid "Blocked users" +msgstr "Usuarios bloqueados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:355 +#: controller/mainController.py:1410 controller/settings.py:295 +msgid "Muted users" +msgstr "Usuarios silenciados" + +#: controller/mainController.py:356 +msgid "Timelines" +msgstr "Líneas temporales" + +#: controller/mainController.py:359 controller/mainController.py:883 +#: controller/mainController.py:1582 +msgid "Timeline for {}" +msgstr "Línea temporal de {0}" + +#: controller/mainController.py:360 +msgid "Likes timelines" +msgstr "Líneas temporales de tuits marcados con me gusta" + +#: controller/mainController.py:363 controller/mainController.py:902 +#: controller/mainController.py:1584 +msgid "Likes for {}" +msgstr "Tuits que le gustan a {0}" + +#: controller/mainController.py:364 +msgid "Followers timelines" +msgstr "Líneas temporales de seguidores" + +#: controller/mainController.py:367 controller/mainController.py:921 +#: controller/mainController.py:1586 +msgid "Followers for {}" +msgstr "Seguidores de {0}" + +#: controller/mainController.py:368 +msgid "Following timelines" +msgstr "Líneas temporales de siguiendo" + +#: controller/mainController.py:371 controller/mainController.py:940 +#: controller/mainController.py:1588 +msgid "Friends for {}" +msgstr "Amigos de {0}" + +#: controller/mainController.py:372 wxUI/dialogs/lists.py:13 +msgid "Lists" +msgstr "Listas" + +#: controller/mainController.py:375 controller/mainController.py:1422 +msgid "List for {}" +msgstr "Lista {0}" + +#: controller/mainController.py:376 +msgid "Searches" +msgstr "Búsquedas" + +#: controller/mainController.py:379 controller/mainController.py:426 +#: controller/mainController.py:431 +msgid "Search for {}" +msgstr "Buscar {0}" + +#: controller/mainController.py:381 controller/mainController.py:982 +#: controller/mainController.py:1590 +#, python-format +msgid "Trending topics for %s" +msgstr "Tendencias para %s" + +#: controller/mainController.py:448 controller/mainController.py:464 +#: controller/mainController.py:1080 controller/mainController.py:1099 +#: controller/mainController.py:1118 controller/mainController.py:1137 +msgid "" +"No session is currently in focus. Focus a session with the next or previous " +"session shortcut." +msgstr "No estás en ninguna sesión. Cambia a una sesión activa." + +#: controller/mainController.py:452 +msgid "Empty buffer." +msgstr "Buffer vacío." + +#: controller/mainController.py:459 +msgid "{0} not found." +msgstr "{0} no encontrado." + +#: controller/mainController.py:469 +msgid "Filters cannot be applied on this buffer" +msgstr "No pueden aplicarse filtros sobre este buffer" + +#: controller/mainController.py:522 controller/mainController.py:539 +#: controller/mainController.py:568 +msgid "Select the user" +msgstr "Selecciona un usuario" + +#: controller/mainController.py:753 +msgid "Add an user alias" +msgstr "Añadir alias de usuario" + +#: controller/mainController.py:761 +msgid "Alias has been set correctly for {}." +msgstr "Añadido el alias para {}" + +#: controller/mainController.py:829 controller/messages.py:327 +msgid "MMM D, YYYY. H:m" +msgstr "D MMM, YYYY. H:m" + +#: controller/mainController.py:957 +msgid "Conversation with {0}" +msgstr "Conversación con {0}" + +#: controller/mainController.py:998 controller/mainController.py:1015 +msgid "There are no coordinates in this tweet" +msgstr "No hay coordenadas en este tuit" + +#: controller/mainController.py:1000 controller/mainController.py:1019 +msgid "Error decoding coordinates. Try again later." +msgstr "Error decodificando las coordenadas. Inténtalo nuevamente más tarde." + +#: controller/mainController.py:1004 +msgid "Unable to find address in OpenStreetMap." +msgstr "Imposible encontrar dirección en Open Street Map." + +#: controller/mainController.py:1017 +msgid "There are no results for the coordinates in this tweet" +msgstr "No hay resultados para las coordenadas en este tuit" + +#: controller/mainController.py:1128 controller/mainController.py:1147 +#, python-format +msgid "%s, %s of %s" +msgstr "%s, %s de %s" + +#: controller/mainController.py:1130 controller/mainController.py:1149 +#: controller/mainController.py:1174 controller/mainController.py:1199 +#, python-format +msgid "%s. Empty" +msgstr "%s. Vacío" + +#: controller/mainController.py:1162 controller/mainController.py:1166 +#: controller/mainController.py:1187 +msgid "{0}: This account is not logged into Twitter." +msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." + +#: controller/mainController.py:1172 controller/mainController.py:1197 +#, python-format +msgid "%s. %s, %s of %s" +msgstr "%s. %s, %s de %s" + +#: controller/mainController.py:1191 +msgid "{0}: This account is not logged into twitter." +msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:1400 +#: controller/settings.py:293 +msgid "Friends" +msgstr "Amigos" + +#: controller/mainController.py:1416 +msgid "This list is already opened" +msgstr "Esta lista ya ha sido abierta" + +#: controller/mainController.py:1446 controller/mainController.py:1462 +msgid "" +"An error happened while trying to connect to the server. Please try later." +msgstr "" +"Ha ocurrido un error al intentar conectarse al servidor. Por favor, " +"inténtalo más tarde." + +#: controller/mainController.py:1498 +msgid "The auto-reading of new tweets is enabled for this buffer" +msgstr "La lectura automática de nuevos tuits para este buffer está activada" + +#: controller/mainController.py:1501 +msgid "The auto-reading of new tweets is disabled for this buffer" +msgstr "" +"La lectura automática de nuevos tuits para este buffer está desactivada" + +#: controller/mainController.py:1508 +msgid "Session mute on" +msgstr "Silencio de sesión activo" + +#: controller/mainController.py:1511 +msgid "Session mute off" +msgstr "Silencio de sesión desactivado" + +#: controller/mainController.py:1519 +msgid "Buffer mute on" +msgstr "Silenciar buffer, activado" + +#: controller/mainController.py:1522 +msgid "Buffer mute off" +msgstr "Silenciar buffer, desactivado" + +#: controller/mainController.py:1542 +msgid "Copied" +msgstr "Copiado" + +#: controller/mainController.py:1572 +msgid "Unable to update this buffer." +msgstr "Imposible actualizar este buffer." + +#: controller/mainController.py:1575 +msgid "Updating buffer..." +msgstr "Actualizando buffer..." + +#: controller/mainController.py:1578 +msgid "{0} items retrieved" +msgstr "{0} elementos descargados" + +#: controller/mainController.py:1597 controller/mainController.py:1617 +msgid "Invalid buffer" +msgstr "Buffer inválido" + +#: controller/mainController.py:1608 +msgid "Picture {0}" +msgstr "Foto {0}" + +#: controller/mainController.py:1609 +msgid "Select the picture" +msgstr "Selecciona la foto" + +#: controller/mainController.py:1628 +msgid "Unable to extract text" +msgstr "Imposible extraer texto" + +#: controller/messages.py:49 +msgid "Translated" +msgstr "Traducido" + +#: controller/messages.py:56 +#, python-format +msgid "%s - %s of %d characters" +msgstr "%s - %s de %d caracteres" + +#: controller/buffers/twitter/base.py:428 controller/messages.py:268 +#, python-format +msgid "Direct message to %s" +msgstr "Mensaje directo a %s" + +#: controller/buffers/twitter/base.py:87 +#: controller/buffers/twitter/trends.py:43 +#: controller/buffers/twitter/trends.py:134 controller/messages.py:296 +#: wxUI/buffers/base.py:25 wxUI/buffers/events.py:15 wxUI/buffers/trends.py:18 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:309 wxUI/sysTrayIcon.py:35 +msgid "Tweet" +msgstr "Tuit" + +#: controller/messages.py:354 +msgid "View item" +msgstr "Ver elemento" + +#: controller/messages.py:379 +msgid "Link copied to clipboard." +msgstr "Enlace copiado al portapapeles" + +#: controller/settings.py:74 +msgid "System default" +msgstr "Predeterminado del sistema" + +#: controller/settings.py:74 +msgid "HTTP" +msgstr "HTTP" + +#: controller/settings.py:74 +msgid "SOCKS v4" +msgstr "SOCKS v4" + +#: controller/settings.py:74 +msgid "SOCKS v4 with DNS support" +msgstr "SOCKS v4 con soporte DNS" + +#: controller/settings.py:74 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: controller/settings.py:74 +msgid "SOCKS v5 with DNS support" +msgstr "SOCKS v5 con soporte DNS" + +#: controller/settings.py:145 controller/settings.py:211 +#: wxUI/dialogs/configuration.py:116 +msgid "Ask" +msgstr "Preguntar" + +#: controller/settings.py:147 controller/settings.py:213 +#: wxUI/dialogs/configuration.py:116 +msgid "Retweet without comments" +msgstr "Retuitear sin comentario" + +#: controller/settings.py:149 wxUI/dialogs/configuration.py:116 +msgid "Retweet with comments" +msgstr "Retuitear añadiendo un comentario" + +#: controller/settings.py:185 +#, python-format +msgid "Account settings for %s" +msgstr "Opciones de la cuenta de %s" + +#: controller/settings.py:288 +msgid "Direct Messages" +msgstr "Mensajes directos" + +#: controller/user.py:29 wxUI/commonMessageDialogs.py:39 +msgid "That user does not exist" +msgstr "El usuario no existe" + +#: controller/user.py:29 controller/user.py:31 extra/SpellChecker/wx_ui.py:80 +#: issueReporter/wx_ui.py:84 issueReporter/wx_ui.py:87 +#: wxUI/commonMessageDialogs.py:39 wxUI/commonMessageDialogs.py:51 +#: wxUI/commonMessageDialogs.py:58 wxUI/commonMessageDialogs.py:61 +#: wxUI/commonMessageDialogs.py:64 wxUI/commonMessageDialogs.py:67 +#: wxUI/commonMessageDialogs.py:77 wxUI/commonMessageDialogs.py:80 +#: wxUI/commonMessageDialogs.py:83 wxUI/commonMessageDialogs.py:89 +#: wxUI/commonMessageDialogs.py:92 +msgid "Error" +msgstr "Error" + +#: controller/user.py:31 +msgid "User has been suspended" +msgstr "El usuario ha sido suspendido" + +#: controller/user.py:37 +#, python-format +msgid "Information for %s" +msgstr "Detalles para %s" + +#: controller/user.py:67 extra/AudioUploader/audioUploader.py:127 +msgid "Discarded" +msgstr "Descartado" + +#: controller/user.py:95 +#, python-format +msgid "Username: @%s\n" +msgstr "Nombre de usuario: @%s\n" + +#: controller/user.py:96 +#, python-format +msgid "Name: %s\n" +msgstr "Nombre: %s\n" + +#: controller/user.py:98 +#, python-format +msgid "Location: %s\n" +msgstr "Ubicación: %s\n" + +#: controller/user.py:100 +#, python-format +msgid "URL: %s\n" +msgstr "URL: %s\n" + +#: controller/user.py:104 +#, python-format +msgid "Bio: %s\n" +msgstr "Descripción: %s\n" + +#: controller/user.py:105 controller/user.py:120 +msgid "Yes" +msgstr "Sí" + +#: controller/user.py:106 controller/user.py:121 +msgid "No" +msgstr "No" + +#: controller/user.py:107 +#, python-format +msgid "Protected: %s\n" +msgstr "Protegido: %s\n" + +#: controller/user.py:112 +msgid "You follow {0}. " +msgstr "Sigues a {0}. " + +#: controller/user.py:115 +msgid "{0} is following you." +msgstr "{0} te sigue." + +#: controller/user.py:119 +#, python-format +msgid "" +"Followers: %s\n" +" Friends: %s\n" +msgstr "" +"Seguidores: %s\n" +" Amigos: %s\n" + +#: controller/user.py:122 +#, python-format +msgid "Verified: %s\n" +msgstr "Verificado: %s\n" + +#: controller/user.py:123 +#, python-format +msgid "Tweets: %s\n" +msgstr "Tuits: %s\n" + +#: controller/user.py:124 +#, python-format +msgid "Likes: %s" +msgstr "Me gusta: %s" + +#: controller/userActionsController.py:74 +msgid "You can't ignore direct messages" +msgstr "No puedes ignorar los mensajes directos" + +#: controller/userAliasController.py:32 +msgid "Edit alias for {}" +msgstr "Editar alias para {}" + +#: controller/buffers/base/base.py:91 +msgid "This action is not supported for this buffer" +msgstr "Esta acción no se encuentra soportada para este buffer" + +#: controller/buffers/twitter/base.py:76 +msgid "{username}'s timeline" +msgstr "Línea temporal de {username}" + +#: controller/buffers/twitter/base.py:78 +msgid "{username}'s likes" +msgstr "Tuits que le gustan a {username}" + +#: controller/buffers/twitter/base.py:80 +msgid "{username}'s followers" +msgstr "Seguidores de {username}" + +#: controller/buffers/twitter/base.py:82 +msgid "{username}'s friends" +msgstr "Amigos de {username}" + +#: controller/buffers/twitter/base.py:84 +msgid "Unknown buffer" +msgstr "Buffer desconocido" + +#: controller/buffers/twitter/base.py:88 +#: controller/buffers/twitter/trends.py:44 +#: controller/buffers/twitter/trends.py:135 +msgid "Write the tweet here" +msgstr "Escribe el tuit aquí" + +#: controller/buffers/twitter/base.py:192 +msgid "New tweet in {0}" +msgstr "Nuevo tuit en {0}" + +#: controller/buffers/twitter/base.py:195 +msgid "{0} new tweets in {1}." +msgstr "{0} nuevos tuits en {1}." + +#: controller/buffers/twitter/base.py:234 +#: controller/buffers/twitter/directMessages.py:88 +#: controller/buffers/twitter/people.py:174 +#, python-format +msgid "%s items retrieved" +msgstr "%s elementos recuperados" + +#: controller/buffers/twitter/base.py:266 +#: controller/buffers/twitter/people.py:80 +msgid "This buffer is not a timeline; it can't be deleted." +msgstr "Este buffer no es una línea temporal. No se puede eliminar." + +#: controller/buffers/twitter/base.py:402 +msgid "Reply to {arg0}" +msgstr "Responder a {arg0}" + +#: controller/buffers/twitter/base.py:404 keystrokeEditor/constants.py:11 +#: wxUI/buffers/base.py:27 +msgid "Reply" +msgstr "Responder" + +#: controller/buffers/twitter/base.py:405 +#, python-format +msgid "Reply to %s" +msgstr "Responder a %s" + +#: controller/buffers/twitter/base.py:428 +#: controller/buffers/twitter/directMessages.py:124 +msgid "New direct message" +msgstr "Nuevo mensaje directo" + +#: controller/buffers/twitter/base.py:459 +msgid "Quote" +msgstr "Citar" + +#: controller/buffers/twitter/base.py:459 +msgid "Add your comment to the tweet" +msgstr "Añade tu comentario al tuit" + +#: controller/buffers/twitter/base.py:520 +msgid "Opening URL..." +msgstr "Abriendo URL..." + +#: controller/buffers/twitter/base.py:557 +msgid "User details" +msgstr "Detalles del usuario" + +#: controller/buffers/twitter/base.py:578 +msgid "Opening item in web browser..." +msgstr "Abriendo elemento en el navegador..." + +#: controller/buffers/twitter/directMessages.py:93 +#: controller/buffers/twitter/people.py:95 wxUI/buffers/people.py:17 +msgid "Mention" +msgstr "Mención" + +#: controller/buffers/twitter/directMessages.py:93 +#: controller/buffers/twitter/people.py:95 +#, python-format +msgid "Mention to %s" +msgstr "Mencionar a %s" + +#: controller/buffers/twitter/directMessages.py:127 +msgid "{0} new direct messages." +msgstr "{0} mensajes directos nuevos." + +#: controller/buffers/twitter/directMessages.py:130 +msgid "This action is not supported in the buffer yet." +msgstr "Esta acción todavía no se soporta en este buffer." + +#: controller/buffers/twitter/directMessages.py:140 +msgid "" +"Getting more items cannot be done in this buffer. Use the direct messages " +"buffer instead." +msgstr "" +"No se pueden obtener más elementos en este buffer. Usa el buffer de mensajes " +"directos en su lugar." + +#: controller/buffers/twitter/people.py:247 +msgid "{0} new followers." +msgstr "{0} nuevos seguidores." + +#: controller/buffers/twitter/trends.py:150 +msgid "This action is not supported in the buffer, yet." +msgstr "Esta acción todavía no se soporta en este buffer." + +#: extra/AudioUploader/audioUploader.py:57 +msgid "Attaching..." +msgstr "Adjuntando..." + +#: extra/AudioUploader/audioUploader.py:74 +msgid "Pause" +msgstr "Pausa" + +#: extra/AudioUploader/audioUploader.py:76 +msgid "&Resume" +msgstr "&Reanudar" + +#: extra/AudioUploader/audioUploader.py:77 +msgid "Resume" +msgstr "Reanudar" + +#: extra/AudioUploader/audioUploader.py:79 +#: extra/AudioUploader/audioUploader.py:106 extra/AudioUploader/wx_ui.py:37 +msgid "&Pause" +msgstr "&Pausa" + +#: extra/AudioUploader/audioUploader.py:94 +#: extra/AudioUploader/audioUploader.py:140 +msgid "&Stop" +msgstr "&Detener" + +#: extra/AudioUploader/audioUploader.py:95 +msgid "Recording" +msgstr "Grabando" + +#: extra/AudioUploader/audioUploader.py:100 +#: extra/AudioUploader/audioUploader.py:151 +msgid "Stopped" +msgstr "Stopped" + +#: extra/AudioUploader/audioUploader.py:102 extra/AudioUploader/wx_ui.py:39 +msgid "&Record" +msgstr "&Grabar" + +#: extra/AudioUploader/audioUploader.py:144 +#: extra/AudioUploader/audioUploader.py:154 extra/AudioUploader/wx_ui.py:35 +msgid "&Play" +msgstr "&Reproducir" + +#: extra/AudioUploader/audioUploader.py:159 +msgid "Recoding audio..." +msgstr "Recodificando audio..." + +#: extra/AudioUploader/transfer.py:82 extra/AudioUploader/transfer.py:88 +msgid "Error in file upload: {0}" +msgstr "Error al subir el archivo: {0}" + +#: extra/AudioUploader/utils.py:29 update/utils.py:29 +#, python-format +msgid "%d day, " +msgstr "%d día, " + +#: extra/AudioUploader/utils.py:31 update/utils.py:31 +#, python-format +msgid "%d days, " +msgstr "%d días, " + +#: extra/AudioUploader/utils.py:33 update/utils.py:33 +#, python-format +msgid "%d hour, " +msgstr "%d hora, " + +#: extra/AudioUploader/utils.py:35 update/utils.py:35 +#, python-format +msgid "%d hours, " +msgstr "%d horas, " + +#: extra/AudioUploader/utils.py:37 update/utils.py:37 +#, python-format +msgid "%d minute, " +msgstr "%d minuto, " + +#: extra/AudioUploader/utils.py:39 update/utils.py:39 +#, python-format +msgid "%d minutes, " +msgstr "%d minutos, " + +#: extra/AudioUploader/utils.py:41 update/utils.py:41 +#, python-format +msgid "%s second" +msgstr "%s segundo" + +#: extra/AudioUploader/utils.py:43 update/utils.py:43 +#, python-format +msgid "%s seconds" +msgstr "%s segundos" + +#: extra/AudioUploader/wx_transfer_dialogs.py:15 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:35 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:171 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:255 +msgid "File" +msgstr "Archivo" + +#: extra/AudioUploader/wx_transfer_dialogs.py:21 +msgid "Transferred" +msgstr "Transferido" + +#: extra/AudioUploader/wx_transfer_dialogs.py:26 +msgid "Total file size" +msgstr "Tamaño total del archivo" + +#: extra/AudioUploader/wx_transfer_dialogs.py:31 +msgid "Transfer rate" +msgstr "Velocidad de transferencia" + +#: extra/AudioUploader/wx_transfer_dialogs.py:36 +msgid "Time left" +msgstr "Tiempo restante" + +#: extra/AudioUploader/wx_ui.py:29 +msgid "Attach audio" +msgstr "Adjuntar audio" + +#: extra/AudioUploader/wx_ui.py:41 +msgid "&Add an existing file" +msgstr "&Añadir un archivo existente" + +#: extra/AudioUploader/wx_ui.py:42 +msgid "&Discard" +msgstr "&Descartar" + +#: extra/AudioUploader/wx_ui.py:44 +msgid "Upload to" +msgstr "Subir a" + +#: extra/AudioUploader/wx_ui.py:49 +msgid "Attach" +msgstr "Adjuntar" + +#: extra/AudioUploader/wx_ui.py:51 +msgid "&Cancel" +msgstr "&Cancelar" + +#: extra/AudioUploader/wx_ui.py:76 +msgid "Select the audio file to be uploaded" +msgstr "Selecciona el archivo de audio que deseas subir" + +#: extra/AudioUploader/wx_ui.py:76 +msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" +msgstr "Archivos de audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" + +#: extra/SoundsTutorial/soundsTutorial_constants.py:7 +msgid "Audio tweet." +msgstr "Tuit con audio." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:8 +msgid "User timeline buffer created." +msgstr "Línea temporal de un usuario creada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:9 +msgid "Buffer destroied." +msgstr "Buffer eliminado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:10 +msgid "Direct message received." +msgstr "Mensaje directo recibido." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:11 +msgid "Direct message sent." +msgstr "Mensaje directo enviado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:12 +msgid "Error." +msgstr "Error." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:13 +msgid "Tweet liked." +msgstr "Tuit marcado como me gusta." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:14 +msgid "Likes buffer updated." +msgstr "Un Buffer de tuits marcados como me gusta se ha actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:15 +msgid "Geotweet." +msgstr "Tuit con información geográfica." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:16 +msgid "Tweet contains one or more images" +msgstr "El tuit contiene una o más imágenes" + +#: extra/SoundsTutorial/soundsTutorial_constants.py:17 +msgid "Boundary reached." +msgstr "No hay más elementos en el buffer." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:18 +msgid "List updated." +msgstr "Lista actualizada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:19 +msgid "Too many characters." +msgstr "Demasiados caracteres." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:20 +msgid "Mention received." +msgstr "Mención recibida." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:21 +msgid "New event." +msgstr "Nuevo evento." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:22 +msgid "{0} is ready." +msgstr "{0} está listo." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:23 +msgid "Mention sent." +msgstr "Mención enviada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:24 +msgid "Tweet retweeted." +msgstr "Tuit retuiteado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:25 +msgid "Search buffer updated." +msgstr "Buffer de búsqueda actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:26 +msgid "Tweet received." +msgstr "Tuit recibido." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:27 +msgid "Tweet sent." +msgstr "Tuit enviado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:28 +msgid "Trending topics buffer updated." +msgstr "Buffer de trending topics actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:29 +msgid "New tweet in user timeline buffer." +msgstr "Nuevo tuit en línea temporal de un usuario." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:30 +msgid "New follower." +msgstr "Nuevo seguidor." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:31 +msgid "Volume changed." +msgstr "Volumen modificado." + +#: extra/SoundsTutorial/wx_ui.py:9 +msgid "Sounds tutorial" +msgstr "Tutorial de sonidos" + +#: extra/SoundsTutorial/wx_ui.py:12 +msgid "Press enter to listen to the sound for the selected event" +msgstr "Pulsa enter para escuchar el sonido para el evento seleccionado" + +#: extra/SpellChecker/spellchecker.py:60 +#, python-format +msgid "Misspelled word: %s" +msgstr "Palabra mal escrita: %s" + +#: extra/SpellChecker/wx_ui.py:28 +msgid "Misspelled word" +msgstr "Palabra mal escrita" + +#: extra/SpellChecker/wx_ui.py:33 +msgid "Context" +msgstr "Contexto" + +#: extra/SpellChecker/wx_ui.py:38 +msgid "Suggestions" +msgstr "Sugerencias" + +#: extra/SpellChecker/wx_ui.py:43 +msgid "&Ignore" +msgstr "&Ignorar" + +#: extra/SpellChecker/wx_ui.py:44 +msgid "I&gnore all" +msgstr "Ignorar &todo" + +#: extra/SpellChecker/wx_ui.py:45 +msgid "&Replace" +msgstr "&Reemplazar" + +#: extra/SpellChecker/wx_ui.py:46 +msgid "R&eplace all" +msgstr "R&eemplazar todo" + +#: extra/SpellChecker/wx_ui.py:47 +msgid "&Add to personal dictionary" +msgstr "Añadir al &diccionario" + +#: extra/SpellChecker/wx_ui.py:80 +msgid "" +"An error has occurred. There are no dictionaries available for the selected " +"language in {0}" +msgstr "" +"Ha ocurrido un error. No se encuentran diccionarios disponibles para el " +"idioma seleccionado en {0}." + +#: extra/SpellChecker/wx_ui.py:83 +msgid "Spell check complete." +msgstr "Corrección ortográfica finalizada." + +#: extra/autocompletionUsers/completion.py:20 +#: extra/autocompletionUsers/completion.py:38 +msgid "You have to start writing" +msgstr "Tienes que empezar a escribir" + +#: extra/autocompletionUsers/completion.py:30 +#: extra/autocompletionUsers/completion.py:47 +msgid "There are no results in your users database" +msgstr "No hay resultados en tu base de datos de usuarios" + +#: extra/autocompletionUsers/completion.py:32 +msgid "Autocompletion only works for users." +msgstr "El autocompletado solo funciona con usuarios." + +#: extra/autocompletionUsers/settings.py:25 +msgid "" +"Updating database... You can close this window now. A message will tell you " +"when the process finishes." +msgstr "" +"Actualizando base de datos... Puedes cerrar esta ventana ahora. Un mensaje " +"te informará cuando el proceso haya terminado." + +#: extra/autocompletionUsers/wx_manage.py:9 +msgid "Manage Autocompletion database" +msgstr "Gestionar la base de datos del autocompletado de usuarios" + +#: extra/autocompletionUsers/wx_manage.py:12 +msgid "Editing {0} users database" +msgstr "Editando la base de datos de usuarios de {0}" + +#: extra/autocompletionUsers/wx_manage.py:13 +msgid "Username" +msgstr "Nombre de usuario" + +#: extra/autocompletionUsers/wx_manage.py:13 wxUI/dialogs/configuration.py:144 +msgid "Name" +msgstr "Nombre" + +#: extra/autocompletionUsers/wx_manage.py:16 +msgid "Add user" +msgstr "Añadir usuario" + +#: extra/autocompletionUsers/wx_manage.py:17 +msgid "Remove user" +msgstr "Quitar usuario" + +#: extra/autocompletionUsers/wx_manage.py:38 +msgid "Twitter username" +msgstr "Nombre de usuario de Twitter" + +#: extra/autocompletionUsers/wx_manage.py:38 +msgid "Add user to database" +msgstr "Añadir usuario a la base de datos" + +#: extra/autocompletionUsers/wx_manage.py:44 +msgid "The user does not exist" +msgstr "El usuario no existe" + +#: extra/autocompletionUsers/wx_manage.py:44 wxUI/commonMessageDialogs.py:45 +msgid "Error!" +msgstr "¡Error!" + +#: extra/autocompletionUsers/wx_settings.py:8 +msgid "Autocomplete users' settings" +msgstr "Opciones de autocompletado de usuarios" + +#: extra/autocompletionUsers/wx_settings.py:11 +msgid "Add users from followers buffer" +msgstr "Añadir usuarios desde el buffer de seguidores" + +#: extra/autocompletionUsers/wx_settings.py:12 +msgid "Add users from friends buffer" +msgstr "Añadir usuarios desde el buffer de amigos" + +#: extra/autocompletionUsers/wx_settings.py:15 +msgid "Manage database..." +msgstr "Administrar base de datos..." + +#: extra/autocompletionUsers/wx_settings.py:27 +msgid "{0}'s database of users has been updated." +msgstr "La base de datos de usuarios de {0} ha sido actualizada." + +#: extra/autocompletionUsers/wx_settings.py:27 +msgid "Done" +msgstr "¡Hecho" + +#: extra/ocr/OCRSpace.py:7 +msgid "Detect automatically" +msgstr "Detectar automáticamente" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:41 +msgid "Danish" +msgstr "Danés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:43 +msgid "Dutch" +msgstr "Holandés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:44 +msgid "English" +msgstr "Inglés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:48 +msgid "Finnish" +msgstr "Finés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:49 +msgid "French" +msgstr "Francés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:52 +msgid "German" +msgstr "Alemán" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:58 +msgid "Hungarian" +msgstr "Húngaro" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:68 +msgid "Korean" +msgstr "Coreano" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:63 +msgid "Italian" +msgstr "Italiano" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:64 +msgid "Japanese" +msgstr "Japonés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:85 +msgid "Polish" +msgstr "Polaco" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:86 +msgid "Portuguese" +msgstr "Portugués" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:89 +msgid "Russian" +msgstr "Ruso" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:96 +msgid "Spanish" +msgstr "Español" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:105 +msgid "Turkish" +msgstr "Turco" + +#: extra/translator/translator.py:22 +msgid "Afrikaans" +msgstr "Africano" + +#: extra/translator/translator.py:23 +msgid "Albanian" +msgstr "Albanés" + +#: extra/translator/translator.py:24 +msgid "Amharic" +msgstr "Amárico" + +#: extra/translator/translator.py:25 +msgid "Arabic" +msgstr "Árabe" + +#: extra/translator/translator.py:26 +msgid "Armenian" +msgstr "Armenio" + +#: extra/translator/translator.py:27 +msgid "Azerbaijani" +msgstr "Acerí" + +#: extra/translator/translator.py:28 +msgid "Basque" +msgstr "Vasco" + +#: extra/translator/translator.py:29 +msgid "Belarusian" +msgstr "Bielorruso" + +#: extra/translator/translator.py:30 +msgid "Bengali" +msgstr "Bengalí" + +#: extra/translator/translator.py:31 +msgid "Bihari" +msgstr "Bihari" + +#: extra/translator/translator.py:32 +msgid "Bulgarian" +msgstr "Búlgaro" + +#: extra/translator/translator.py:33 +msgid "Burmese" +msgstr "Birmano" + +#: extra/translator/translator.py:34 +msgid "Catalan" +msgstr "Catalán" + +#: extra/translator/translator.py:35 +msgid "Cherokee" +msgstr "Cheroqui" + +#: extra/translator/translator.py:36 +msgid "Chinese" +msgstr "Chino" + +#: extra/translator/translator.py:37 +msgid "Chinese_simplified" +msgstr "Chino simplificado" + +#: extra/translator/translator.py:38 +msgid "Chinese_traditional" +msgstr "Chino tradicional" + +#: extra/translator/translator.py:39 +msgid "Croatian" +msgstr "Croata" + +#: extra/translator/translator.py:40 +msgid "Czech" +msgstr "Checo" + +#: extra/translator/translator.py:42 +msgid "Dhivehi" +msgstr "Dhivehi" + +#: extra/translator/translator.py:45 +msgid "Esperanto" +msgstr "Esperanto" + +#: extra/translator/translator.py:46 +msgid "Estonian" +msgstr "Estonio" + +#: extra/translator/translator.py:47 +msgid "Filipino" +msgstr "Filipino" + +#: extra/translator/translator.py:50 +msgid "Galician" +msgstr "Gallego" + +#: extra/translator/translator.py:51 +msgid "Georgian" +msgstr "Georgiano" + +#: extra/translator/translator.py:53 +msgid "Greek" +msgstr "Griego" + +#: extra/translator/translator.py:54 +msgid "Guarani" +msgstr "Guaraní" + +#: extra/translator/translator.py:55 +msgid "Gujarati" +msgstr "Guyaratí" + +#: extra/translator/translator.py:56 +msgid "Hebrew" +msgstr "Hebreo" + +#: extra/translator/translator.py:57 +msgid "Hindi" +msgstr "Hindi" + +#: extra/translator/translator.py:59 +msgid "Icelandic" +msgstr "Islandés" + +#: extra/translator/translator.py:60 +msgid "Indonesian" +msgstr "Indonesio" + +#: extra/translator/translator.py:61 +msgid "Inuktitut" +msgstr "Inuktitut" + +#: extra/translator/translator.py:62 +msgid "Irish" +msgstr "Irlandés" + +#: extra/translator/translator.py:65 +msgid "Kannada" +msgstr "Canarés" + +#: extra/translator/translator.py:66 +msgid "Kazakh" +msgstr "Kazajo" + +#: extra/translator/translator.py:67 +msgid "Khmer" +msgstr "Camboyano" + +#: extra/translator/translator.py:69 +msgid "Kurdish" +msgstr "Kurdo" + +#: extra/translator/translator.py:70 +msgid "Kyrgyz" +msgstr "Kirguís" + +#: extra/translator/translator.py:71 +msgid "Laothian" +msgstr "Lao" + +#: extra/translator/translator.py:72 +msgid "Latvian" +msgstr "Letón" + +#: extra/translator/translator.py:73 +msgid "Lithuanian" +msgstr "Lituano" + +#: extra/translator/translator.py:74 +msgid "Macedonian" +msgstr "Macedonio" + +#: extra/translator/translator.py:75 +msgid "Malay" +msgstr "Malayo" + +#: extra/translator/translator.py:76 +msgid "Malayalam" +msgstr "Malayalam" + +#: extra/translator/translator.py:77 +msgid "Maltese" +msgstr "Maltés" + +#: extra/translator/translator.py:78 +msgid "Marathi" +msgstr "Maratí" + +#: extra/translator/translator.py:79 +msgid "Mongolian" +msgstr "Mongol" + +#: extra/translator/translator.py:80 +msgid "Nepali" +msgstr "Nepalí" + +#: extra/translator/translator.py:81 +msgid "Norwegian" +msgstr "Noruego" + +#: extra/translator/translator.py:82 +msgid "Oriya" +msgstr "Oriya" + +#: extra/translator/translator.py:83 +msgid "Pashto" +msgstr "Pastú" + +#: extra/translator/translator.py:84 +msgid "Persian" +msgstr "Persa" + +#: extra/translator/translator.py:87 +msgid "Punjabi" +msgstr "Panyabí" + +#: extra/translator/translator.py:88 +msgid "Romanian" +msgstr "Rumano" + +#: extra/translator/translator.py:90 +msgid "Sanskrit" +msgstr "Sánscrito" + +#: extra/translator/translator.py:91 +msgid "Serbian" +msgstr "Serbio" + +#: extra/translator/translator.py:92 +msgid "Sindhi" +msgstr "Sindhi" + +#: extra/translator/translator.py:93 +msgid "Sinhalese" +msgstr "Cingalés" + +#: extra/translator/translator.py:94 +msgid "Slovak" +msgstr "Eslovaco" + +#: extra/translator/translator.py:95 +msgid "Slovenian" +msgstr "Esloveno" + +#: extra/translator/translator.py:97 +msgid "Swahili" +msgstr "Suajili" + +#: extra/translator/translator.py:98 +msgid "Swedish" +msgstr "Sueco" + +#: extra/translator/translator.py:99 +msgid "Tajik" +msgstr "Tayiko" + +#: extra/translator/translator.py:100 +msgid "Tamil" +msgstr "Tamil" + +#: extra/translator/translator.py:101 +msgid "Tagalog" +msgstr "Tagalo" + +#: extra/translator/translator.py:102 +msgid "Telugu" +msgstr "Telugú" + +#: extra/translator/translator.py:103 +msgid "Thai" +msgstr "Tailandés" + +#: extra/translator/translator.py:104 +msgid "Tibetan" +msgstr "Tibetano" + +#: extra/translator/translator.py:106 +msgid "Ukrainian" +msgstr "Ucraniano" + +#: extra/translator/translator.py:107 +msgid "Urdu" +msgstr "Urdu" + +#: extra/translator/translator.py:108 +msgid "Uzbek" +msgstr "Uzbeco" + +#: extra/translator/translator.py:109 +msgid "Uighur" +msgstr "Uigur" + +#: extra/translator/translator.py:110 +msgid "Vietnamese" +msgstr "Vietnamita" + +#: extra/translator/translator.py:111 +msgid "Welsh" +msgstr "Galés" + +#: extra/translator/translator.py:112 +msgid "Yiddish" +msgstr "Yídish" + +#: extra/translator/wx_ui.py:29 +msgid "Translate message" +msgstr "Traducir mensaje" + +#: extra/translator/wx_ui.py:32 +msgid "Target language" +msgstr "Idioma de destino" + +#: issueReporter/issueReporter.py:32 wxUI/dialogs/configuration.py:359 +#: wxUI/dialogs/configuration.py:368 +msgid "General" +msgstr "General" + +#: issueReporter/issueReporter.py:33 +msgid "always" +msgstr "siempre" + +#: issueReporter/issueReporter.py:33 +msgid "sometimes" +msgstr "a veces" + +#: issueReporter/issueReporter.py:33 +msgid "random" +msgstr "aleatoriamente" + +#: issueReporter/issueReporter.py:33 +msgid "have not tried" +msgstr "no se ha intentado" + +#: issueReporter/issueReporter.py:33 +msgid "unable to duplicate" +msgstr "imposible de reproducir" + +#: issueReporter/issueReporter.py:34 +msgid "block" +msgstr "bloqueo" + +#: issueReporter/issueReporter.py:34 +msgid "crash" +msgstr "fallo" + +#: issueReporter/issueReporter.py:34 +msgid "major" +msgstr "mayor" + +#: issueReporter/issueReporter.py:34 +msgid "minor" +msgstr "menor" + +#: issueReporter/issueReporter.py:34 +msgid "tweak" +msgstr "ajuste" + +#: issueReporter/issueReporter.py:34 +msgid "text" +msgstr "texto" + +#: issueReporter/issueReporter.py:34 +msgid "trivial" +msgstr "trivial" + +#: issueReporter/issueReporter.py:34 +msgid "feature" +msgstr "característica" + +#: issueReporter/wx_ui.py:26 +msgid "Report an error" +msgstr "Reportar un error" + +#: issueReporter/wx_ui.py:29 +msgid "Select a category" +msgstr "Selecciona una categoría" + +#: issueReporter/wx_ui.py:37 +msgid "" +"Briefly describe what happened. You will be able to thoroughly explain it " +"later" +msgstr "" +"Describe en pocas palabras lo que ha pasado (después podrás profundizar)" + +#: issueReporter/wx_ui.py:46 +msgid "Here, you can describe the bug in detail" +msgstr "Aquí puedes describir el error en detalle" + +#: issueReporter/wx_ui.py:56 +msgid "how often does this bug happen?" +msgstr "¿Qué tan a menudo ocurre este error?" + +#: issueReporter/wx_ui.py:63 +msgid "Select the importance that you think this bug has" +msgstr "Selecciona la importancia que consideras que tiene este error" + +#: issueReporter/wx_ui.py:70 +msgid "" +"I know that the {0} bug system will get my Twitter username to contact me " +"and fix the bug quickly" +msgstr "" +"Sé que el sistema de errores de {0} obtendrá mi nombre de usuario de Twitter " +"para contactarme y resolver el error rápidamente" + +#: issueReporter/wx_ui.py:73 +msgid "Send report" +msgstr "Enviar reporte" + +#: issueReporter/wx_ui.py:75 wxUI/dialogs/filterDialogs.py:83 +#: wxUI/dialogs/find.py:23 +msgid "Cancel" +msgstr "Cancelar" + +#: issueReporter/wx_ui.py:84 +msgid "You must fill out both fields" +msgstr "Debes llenar ambos campos" + +#: issueReporter/wx_ui.py:87 +msgid "" +"You need to mark the checkbox to provide us your twitter username to contact " +"you if it is necessary." +msgstr "" +"Debes marcar la casilla para proporcionarnos tu nombre de usuario de Twitter " +"para poder contactarte si es necesario." + +#: issueReporter/wx_ui.py:90 +#, python-format +msgid "" +"Thanks for reporting this bug! In future versions, you may be able to find " +"it in the changes list. You've reported the bug number %i" +msgstr "" +"¡Gracias por reportar este error! Quizá puedas verlo entre la lista de " +"cambios de próximas versiones. Has reportado el error número %i" + +#: issueReporter/wx_ui.py:90 +msgid "reported" +msgstr "reportado" + +#: issueReporter/wx_ui.py:94 +msgid "" +"Something unexpected occurred while trying to report the bug. Please, try " +"again later" +msgstr "" +"Algo inesperado ocurrió mientras intentábamos reportar tu error. Por favor, " +"vuelve a intentarlo más tarde" + +#: issueReporter/wx_ui.py:94 +msgid "Error while reporting" +msgstr "Error al reportar" + +#: keystrokeEditor/constants.py:3 +msgid "Go up in the current buffer" +msgstr "Va arriba en la lista actual" + +#: keystrokeEditor/constants.py:4 +msgid "Go down in the current buffer" +msgstr "Va abajo en la lista actual" + +#: keystrokeEditor/constants.py:5 +msgid "Go to the previous buffer" +msgstr "Va al buffer anterior" + +#: keystrokeEditor/constants.py:6 +msgid "Go to the next buffer" +msgstr "Va al buffer siguiente" + +#: keystrokeEditor/constants.py:7 +msgid "Focus the next session" +msgstr "Ir a la siguiente sesión" + +#: keystrokeEditor/constants.py:8 +msgid "Focus the previous session" +msgstr "Va a la sesión anterior" + +#: keystrokeEditor/constants.py:9 +msgid "Show or hide the GUI" +msgstr "Muestra o esconde la interfaz gráfica" + +#: keystrokeEditor/constants.py:10 +msgid "New tweet" +msgstr "Nuevo tuit" + +#: keystrokeEditor/constants.py:12 wxUI/buffers/base.py:26 +#: wxUI/commonMessageDialogs.py:10 +msgid "Retweet" +msgstr "Retuit" + +#: keystrokeEditor/constants.py:13 +msgid "Send direct message" +msgstr "Enviar mensaje directo" + +#: keystrokeEditor/constants.py:14 +msgid "Like a tweet" +msgstr "Marcar tuit como me gusta" + +#: keystrokeEditor/constants.py:15 +msgid "Like/unlike a tweet" +msgstr "Marcar o remover tuit como me gusta" + +#: keystrokeEditor/constants.py:16 +msgid "Unlike a tweet" +msgstr "Marcar tuit como ya no me gusta" + +#: keystrokeEditor/constants.py:17 +msgid "Open the user actions dialogue" +msgstr "Abrir el diálogo de acciones" + +#: keystrokeEditor/constants.py:18 +msgid "See user details" +msgstr "Ver detalles del usuario" + +#: keystrokeEditor/constants.py:19 +msgid "Show tweet" +msgstr "Ver tuit" + +#: keystrokeEditor/constants.py:20 +msgid "Quit" +msgstr "Salir" + +#: keystrokeEditor/constants.py:21 +msgid "Open user timeline" +msgstr "Abrir línea temporal" + +#: keystrokeEditor/constants.py:22 +msgid "Destroy buffer" +msgstr "Eliminar buffer" + +#: keystrokeEditor/constants.py:23 +msgid "Interact with the currently focused tweet." +msgstr "Interactuar con el tuit que tiene el foco." + +#: keystrokeEditor/constants.py:24 +msgid "Open URL" +msgstr "Abrir URL" + +#: keystrokeEditor/constants.py:25 +msgid "View in Twitter" +msgstr "Ver en Twitter" + +#: keystrokeEditor/constants.py:26 +msgid "Increase volume by 5%" +msgstr "Subir volumen en un 5%" + +#: keystrokeEditor/constants.py:27 +msgid "Decrease volume by 5%" +msgstr "Bajar volumen en un 5%" + +#: keystrokeEditor/constants.py:28 +msgid "Jump to the first element of a buffer" +msgstr "Ir al primer elemento del buffer" + +#: keystrokeEditor/constants.py:29 +msgid "Jump to the last element of the current buffer" +msgstr "Ir al último elemento del buffer" + +#: keystrokeEditor/constants.py:30 +msgid "Jump 20 elements up in the current buffer" +msgstr "Moverse 20 elementos hacia arriba en el buffer actual" + +#: keystrokeEditor/constants.py:31 +msgid "Jump 20 elements down in the current buffer" +msgstr "Moverse 20 elementos hacia abajo en el buffer actual" + +#: keystrokeEditor/constants.py:32 +msgid "Edit profile" +msgstr "Editar perfil" + +#: keystrokeEditor/constants.py:33 +msgid "Delete a tweet or direct message" +msgstr "Eliminar tuit o mensaje directo" + +#: keystrokeEditor/constants.py:34 +msgid "Empty the current buffer" +msgstr "Vaciar buffer" + +#: keystrokeEditor/constants.py:35 +msgid "Repeat last item" +msgstr "Repetir último elemento" + +#: keystrokeEditor/constants.py:36 +msgid "Copy to clipboard" +msgstr "Copiar al portapapeles" + +#: keystrokeEditor/constants.py:37 +msgid "Add to list" +msgstr "Añadir a lista" + +#: keystrokeEditor/constants.py:38 +msgid "Remove from list" +msgstr "Quitar de lista" + +#: keystrokeEditor/constants.py:39 +msgid "Mute/unmute the active buffer" +msgstr "Silenciar o des-silenciar el buffer activo" + +#: keystrokeEditor/constants.py:40 +msgid "Mute/unmute the current session" +msgstr "Activar o desactivar el silencio para la sesión activa" + +#: keystrokeEditor/constants.py:41 +msgid "toggle the automatic reading of incoming tweets in the active buffer" +msgstr "" +"conmutar entre la lectura automática de nuevos tuits para el buffer actual" + +#: keystrokeEditor/constants.py:42 +msgid "Search on twitter" +msgstr "Buscar en Twitter" + +#: keystrokeEditor/constants.py:43 +msgid "Find a string in the currently focused buffer" +msgstr "Buscar un término en el buffer actual" + +#: keystrokeEditor/constants.py:44 +msgid "Show the keystroke editor" +msgstr "Mostrar el editor de combinaciones de teclado" + +#: keystrokeEditor/constants.py:45 +msgid "Show lists for a specified user" +msgstr "Mostrar listas para un usuario específico" + +#: keystrokeEditor/constants.py:46 +msgid "load previous items" +msgstr "cargar elementos anteriores" + +#: keystrokeEditor/constants.py:47 +msgid "Get geolocation" +msgstr "Obtener ubicación" + +#: keystrokeEditor/constants.py:48 +msgid "Display the tweet's geolocation in a dialog" +msgstr "Mostrar la ubicación del tuit en un diálogo" + +#: keystrokeEditor/constants.py:49 +msgid "Create a trending topics buffer" +msgstr "Crear un buffer de tendencias" + +#: keystrokeEditor/constants.py:50 +msgid "View conversation" +msgstr "Ver conversación" + +#: keystrokeEditor/constants.py:51 +msgid "Check and download updates" +msgstr "&Comprobar y descargar actualizaciones" + +#: keystrokeEditor/constants.py:52 +msgid "" +"Opens the list manager, which allows you to create, edit, delete and open " +"lists in buffers." +msgstr "" +"Abre el gestor de listas, que permite crear, editar, eliminar y abrir listas " +"como buffers." + +#: keystrokeEditor/constants.py:53 +msgid "Opens the global settings dialogue" +msgstr "Abre el diálogo de opciones globales" + +#: keystrokeEditor/constants.py:54 +msgid "Opens the list manager" +msgstr "Abre el gestor de listas" + +#: keystrokeEditor/constants.py:55 +msgid "Opens the account settings dialogue" +msgstr "Abre el diálogo de opciones de cuenta" + +#: keystrokeEditor/constants.py:56 +msgid "Try to play an audio file" +msgstr "Intentar reproducir audio" + +#: keystrokeEditor/constants.py:57 +msgid "Updates the buffer and retrieves possible lost items there." +msgstr "Actualiza el buffer e intenta descargar los elementos perdidos." + +#: keystrokeEditor/constants.py:58 +msgid "Extracts the text from a picture and displays the result in a dialog." +msgstr "Extrae el texto de una foto y muestra el resultado en un diálogo." + +#: keystrokeEditor/constants.py:59 +msgid "Adds an alias to an user" +msgstr "Añade un alias a un usuario específico." + +#: keystrokeEditor/wx_ui.py:8 +msgid "Keystroke editor" +msgstr "Editor de combinaciones de teclado" + +#: keystrokeEditor/wx_ui.py:12 +msgid "Select a keystroke to edit" +msgstr "Selecciona una combinación de teclado para editarla" + +#: keystrokeEditor/wx_ui.py:13 wxUI/dialogs/userActions.py:10 +#: wxUI/dialogs/userActions.py:19 wxUI/dialogs/userActions.py:20 +msgid "Action" +msgstr "Acción" + +#: keystrokeEditor/wx_ui.py:13 +msgid "Keystroke" +msgstr "Combinación de teclado" + +#: keystrokeEditor/wx_ui.py:18 wxUI/dialogs/filterDialogs.py:135 +#: wxUI/dialogs/lists.py:20 wxUI/dialogs/userAliasDialogs.py:53 +msgid "Edit" +msgstr "Editar" + +#: keystrokeEditor/wx_ui.py:20 keystrokeEditor/wx_ui.py:50 +msgid "Undefine keystroke" +msgstr "Desasignar combinación de teclas" + +#: keystrokeEditor/wx_ui.py:21 +msgid "Execute action" +msgstr "Ejecutar acción" + +#: keystrokeEditor/wx_ui.py:22 wxUI/dialogs/configuration.py:396 +#: wxUI/dialogs/userAliasDialogs.py:25 wxUI/dialogs/utils.py:39 +msgid "Close" +msgstr "Cerrar" + +#: keystrokeEditor/wx_ui.py:42 +msgid "Undefined" +msgstr "Sin definir" + +#: keystrokeEditor/wx_ui.py:50 +msgid "Are you sure you want to undefine this keystroke?" +msgstr "¿Seguro que deseas desasignar esta combinación de teclado?" + +#: keystrokeEditor/wx_ui.py:54 +msgid "Editing keystroke" +msgstr "Editando combinación de teclas" + +#: keystrokeEditor/wx_ui.py:57 +msgid "Control" +msgstr "Control" + +#: keystrokeEditor/wx_ui.py:58 +msgid "Alt" +msgstr "Alt" + +#: keystrokeEditor/wx_ui.py:59 +msgid "Shift" +msgstr "Shift" + +#: keystrokeEditor/wx_ui.py:60 +msgid "Windows" +msgstr "Windows" + +#: keystrokeEditor/wx_ui.py:66 +msgid "Key" +msgstr "Tecla" + +#: keystrokeEditor/wx_ui.py:71 wxUI/dialogs/filterDialogs.py:80 +#: wxUI/dialogs/find.py:21 wxUI/dialogs/userAliasDialogs.py:23 +#: wxUI/dialogs/utils.py:36 +msgid "OK" +msgstr "Aceptar" + +#: keystrokeEditor/wx_ui.py:84 +msgid "You need to use the Windows key" +msgstr "Necesitas usar la tecla de windows" + +#: keystrokeEditor/wx_ui.py:84 keystrokeEditor/wx_ui.py:87 +msgid "Invalid keystroke" +msgstr "Combinación de teclado inválida" + +#: keystrokeEditor/wx_ui.py:87 +msgid "You must provide a character for the keystroke" +msgstr "Debes proporcionar una letra para el atajo de teclado" + +#: sessionmanager/wxUI.py:9 msgid "Session manager" msgstr "Gestor de sesiones" -#: ../src\sessionmanager\wxUI.py:11 +#: sessionmanager/wxUI.py:12 msgid "Accounts list" msgstr "Lista de cuentas" -#: ../src\sessionmanager\wxUI.py:13 +#: sessionmanager/wxUI.py:14 msgid "Account" msgstr "Cuenta" -#: ../src\sessionmanager\wxUI.py:17 +#: sessionmanager/wxUI.py:18 msgid "New account" msgstr "Nueva cuenta" -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 +#: sessionmanager/wxUI.py:19 sessionmanager/wxUI.py:65 msgid "Remove account" msgstr "Eliminar cuenta" -#: ../src\sessionmanager\wxUI.py:19 +#: sessionmanager/wxUI.py:20 msgid "Global Settings" msgstr "Opciones globales" -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "Error en la cuenta" - -#: ../src\sessionmanager\wxUI.py:42 +#: sessionmanager/wxUI.py:43 msgid "You need to configure an account." msgstr "Necesitas configurar una cuenta." -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "Autorización" +#: sessionmanager/wxUI.py:43 +msgid "Account Error" +msgstr "Error en la cuenta" -#: ../src\sessionmanager\wxUI.py:48 +#: sessionmanager/wxUI.py:49 msgid "" "The request to authorize your Twitter account will be opened in your " "browser. You only need to do this once. Would you like to continue?" @@ -1850,15 +1950,16 @@ msgstr "" "La solicitud de autorización de Twitter será abierta en tu navegador. Esto " "es necesario hacerlo solo una vez. ¿Quieres continuar?" -#: ../src\sessionmanager\wxUI.py:52 +#: sessionmanager/wxUI.py:49 +msgid "Authorization" +msgstr "Autorización" + +#: sessionmanager/wxUI.py:53 +#, python-format msgid "Authorized account %d" msgstr "Cuenta autorizada %d" -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "Código de acceso inválido" - -#: ../src\sessionmanager\wxUI.py:58 +#: sessionmanager/wxUI.py:59 msgid "" "Your access token is invalid or the authorization has failed. Please try " "again." @@ -1866,30 +1967,91 @@ msgstr "" "El código de autorización es inválido o el proceso ha fallado. Por favor " "inténtalo de nuevo más tarde." -#: ../src\sessionmanager\wxUI.py:64 +#: sessionmanager/wxUI.py:59 +msgid "Invalid user token" +msgstr "Código de acceso inválido" + +#: sessionmanager/wxUI.py:65 msgid "Do you really want to delete this account?" msgstr "¿Realmente deseas eliminar esta cuenta?" -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 +#: sessionmanager/wxUI.py:81 +msgid "" +"TWBlue is unable to authenticate the account for {} in Twitter. It might be " +"due to an invalid or expired token, revoqued access to the application, or " +"after an account reactivation. Please remove the account manually from your " +"Twitter sessions in order to stop seeing this message." +msgstr "" +"TWBlue es incapaz de autenticar los datos para la cuenta {}. Esto puede " +"deberse a un token incorrecto o que ya ha expirado; a haber revocado acceso " +"a la aplicación, o luego de reactivar una cuenta previamente suspendida. Por " +"favor, elimina esta cuenta manualmente desde tus sesiones de Twitter en la " +"aplicación para dejar de ver este mensaje." + +#: sessionmanager/wxUI.py:81 +msgid "Authentication error for session {}" +msgstr "Error de autenticación en la sesión {}" + +#: sessions/base.py:113 +msgid "" +"An exception occurred while saving the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Ha ocurrido un error al guardar la base de datos de {app}. La base de datos " +"será creada desde cero automáticamente. Si este error persiste, contacta con " +"los desarrolladores de {app} para obtener ayuda." + +#: sessions/base.py:153 +msgid "" +"An exception occurred while loading the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Ocurrió un error al cargar la base de datos de {app}. {app} creará una base " +"de datos nueva automáticamente. Si este error persiste, contacta con los " +"desarrolladores de {app} para obtener ayuda." + +#: sessions/session_utils.py:231 sessions/twitter/utils.py:231 +msgid "Sorry, you are not authorised to see this status." +msgstr "Lo sentimos, no estás autorizado para ver este tuit." + +#: sessions/session_utils.py:233 sessions/twitter/utils.py:233 +msgid "No status found with that ID" +msgstr "No existe un tuit con este ID" + +#: sessions/session_utils.py:235 +msgid "Error code {0}" +msgstr "Código de error {0}" + +#: sessions/session_utils.py:262 sessions/twitter/utils.py:262 +msgid "{user_1}, {user_2} and {all_users} more: {text}" +msgstr "{user_1}, {user_2} y {all_users} más: {text}" + +#: sessions/twitter/compose.py:38 sessions/twitter/compose.py:81 +#: sessions/twitter/compose.py:146 sessions/twitter/compose.py:155 +#: sessions/twitter/templates.py:38 sessions/twitter/templates.py:81 +#: sessions/twitter/templates.py:146 sessions/twitter/templates.py:155 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd, MMMM D, YYYY H:m:s" -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 +#: sessions/twitter/compose.py:89 sessions/twitter/compose.py:91 +#: sessions/twitter/templates.py:89 sessions/twitter/templates.py:91 +#, python-format msgid "Dm to %s " msgstr "Dm a %s " -#: ../src\sessions\twitter\compose.py:141 +#: sessions/twitter/compose.py:130 sessions/twitter/templates.py:130 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0} citó el tuit de {1}: {2}" -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 +#: sessions/twitter/compose.py:157 sessions/twitter/compose.py:159 +#: sessions/twitter/templates.py:157 sessions/twitter/templates.py:159 msgid "Unavailable" msgstr "No disponible" -#: ../src\sessions\twitter\compose.py:166 +#: sessions/twitter/compose.py:160 sessions/twitter/templates.py:160 +#, python-format msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1897,59 +2059,46 @@ msgstr "" "%s (@%s). %s seguidores, %s amigos, %s tuits. Último tuit %s. Se unió a " "Twitter %s" -#: ../src\sessions\twitter\compose.py:170 +#: sessions/twitter/compose.py:164 sessions/twitter/templates.py:164 msgid "No description available" msgstr "No hay una descripción disponible" -#: ../src\sessions\twitter\compose.py:174 +#: sessions/twitter/compose.py:168 sessions/twitter/templates.py:168 msgid "private" msgstr "privado" -#: ../src\sessions\twitter\compose.py:175 +#: sessions/twitter/compose.py:169 sessions/twitter/templates.py:169 msgid "public" msgstr "público" -#: ../src\sessions\twitter\session.py:169 -msgid "There are no more items to retrieve in this buffer." -msgstr "No hay más elementos que recuperar en este buffer." - -#: ../src\sessions\twitter\session.py:215 +#: sessions/twitter/session.py:211 sessions/twitter/session.py:238 +#, python-format msgid "%s failed. Reason: %s" msgstr "%s falló. Razón: %s" -#: ../src\sessions\twitter\session.py:221 +#: sessions/twitter/session.py:217 sessions/twitter/session.py:241 +#, python-format msgid "%s succeeded." msgstr "%s con éxito." -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "Lo sentimos, no estás autorizado para ver este tuit." +#: sessions/twitter/session.py:450 sessions/twitter/session.py:528 +msgid "Deleted account" +msgstr "Cuenta eliminada" -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "No existe un tuit con este ID" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" +#: sessions/twitter/utils.py:235 +msgid "Error {0}" msgstr "Código de error {0}" -#: ../src\sessions\twitter\wxUI.py:6 +#: sessions/twitter/wxUI.py:7 msgid "Authorising account..." msgstr "Autorizando cuenta..." -#: ../src\sessions\twitter\wxUI.py:9 +#: sessions/twitter/wxUI.py:10 msgid "Enter your PIN code here" msgstr "Introduce el código PIN aquí" -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "Detenido." - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "Nueva versión de %s" - -#: ../src\update\wxUpdater.py:10 +#: update/wxUpdater.py:14 +#, python-format msgid "" "There's a new %s version available, released on %s. Would you like to " "download it now?\n" @@ -1966,23 +2115,25 @@ msgstr "" "Novedades:\n" "%s" -#: ../src\update\wxUpdater.py:18 +#: update/wxUpdater.py:14 +#, python-format +msgid "New version for %s" +msgstr "Nueva versión de %s" + +#: update/wxUpdater.py:22 msgid "Download in Progress" msgstr "Descarga en progreso" -#: ../src\update\wxUpdater.py:18 +#: update/wxUpdater.py:22 msgid "Downloading the new version..." msgstr "Descargando la nueva versión..." -#: ../src\update\wxUpdater.py:28 +#: update/wxUpdater.py:32 +#, python-format msgid "Updating... %s of %s" msgstr "Actualizando... %s de %s" -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "¡Hecho!" - -#: ../src\update\wxUpdater.py:31 +#: update/wxUpdater.py:35 msgid "" "The update has been downloaded and installed successfully. Press OK to " "continue." @@ -1990,61 +2141,11 @@ msgstr "" "La actualización ha sido descargada e instalada. Presiona aceptar para " "iniciar la aplicación." -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "Cliente" +#: update/wxUpdater.py:35 +msgid "Done!" +msgstr "¡Hecho!" -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Texto" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "Fecha" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "Usuario" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Mensaje directo" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "Evento" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "Eliminar evento" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "Iniciar sesión" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "Iniciar sesión automáticamente" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "Cerrar sesión" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "Tendencia" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "Tuitear sobre esta tendencia" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "Buscar tema" - -#: ../src\wxUI\commonMessageDialogs.py:6 +#: wxUI/commonMessageDialogs.py:7 msgid "" "This retweet is over 140 characters. Would you like to post it as a mention " "to the poster with your comments and a link to the original tweet?" @@ -2053,38 +2154,38 @@ msgstr "" "comentarios con una mención al usuario que publicó el tuit original y un " "enlace al mismo?" -#: ../src\wxUI\commonMessageDialogs.py:9 +#: wxUI/commonMessageDialogs.py:10 msgid "Would you like to add a comment to this tweet?" msgstr "¿Te gustaría añadir un comentario a este tuit?" -#: ../src\wxUI\commonMessageDialogs.py:12 +#: wxUI/commonMessageDialogs.py:13 msgid "" "Do you really want to delete this tweet? It will be deleted from Twitter as " "well." msgstr "" "¿Realmente quieres borrar este mensaje? También se eliminará de Twitter." -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 +#: wxUI/commonMessageDialogs.py:13 wxUI/dialogs/lists.py:149 msgid "Delete" msgstr "Eliminar" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: wxUI/commonMessageDialogs.py:16 msgid "Do you really want to close {0}?" msgstr "¿Realmente deseas salir de {0}?" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: wxUI/commonMessageDialogs.py:16 msgid "Exit" msgstr "Salir" -#: ../src\wxUI\commonMessageDialogs.py:19 +#: wxUI/commonMessageDialogs.py:20 msgid " {0} must be restarted for these changes to take effect." msgstr " Debes reiniciar {0} para que estos cambios tengan efecto." -#: ../src\wxUI\commonMessageDialogs.py:19 +#: wxUI/commonMessageDialogs.py:20 msgid "Restart {0} " msgstr "Reiniciar {0} " -#: ../src\wxUI\commonMessageDialogs.py:22 +#: wxUI/commonMessageDialogs.py:23 msgid "" "Are you sure you want to delete this user from the database? This user will " "not appear in autocomplete results anymore." @@ -2092,20 +2193,19 @@ msgstr "" "¿Estás seguro de querer eliminar este usuario de la base de datos? Este ya " "no aparecerá en los resultados del autocompletado." -#: ../src\wxUI\commonMessageDialogs.py:22 +#: wxUI/commonMessageDialogs.py:23 msgid "Confirm" msgstr "Confirmar" -#: ../src\wxUI\commonMessageDialogs.py:25 +#: wxUI/commonMessageDialogs.py:26 msgid "Enter the name of the client : " msgstr "Introduce el nombre del cliente: " -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 +#: wxUI/commonMessageDialogs.py:26 wxUI/dialogs/configuration.py:246 msgid "Add client" msgstr "Añadir cliente" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: wxUI/commonMessageDialogs.py:32 msgid "" "Do you really want to empty this buffer? It's items will be removed from " "the list but not from Twitter" @@ -2113,32 +2213,31 @@ msgstr "" "¿Realmente quieres vaciar el contenido de este buffer? Los tweets serán " "eliminados de la lista, pero no de Twitter" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: wxUI/commonMessageDialogs.py:32 msgid "Empty buffer" msgstr "Vaciar buffer" -#: ../src\wxUI\commonMessageDialogs.py:35 +#: wxUI/commonMessageDialogs.py:36 msgid "Do you really want to destroy this buffer?" msgstr "¿Realmente deseas eliminar este buffer?" -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 +#: wxUI/commonMessageDialogs.py:36 wxUI/commonMessageDialogs.py:86 msgid "Attention" msgstr "Atención" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: wxUI/commonMessageDialogs.py:42 msgid "A timeline for this user already exists. You can't open another" msgstr "Ya hay una línea temporal para este usuario. No se puede abrir otra" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: wxUI/commonMessageDialogs.py:42 msgid "Existing timeline" msgstr "Línea temporal existente" -#: ../src\wxUI\commonMessageDialogs.py:44 +#: wxUI/commonMessageDialogs.py:45 msgid "This user has no tweets, so you can't open a timeline for them." msgstr "Este usuario no tiene tuits. No puedes abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:47 +#: wxUI/commonMessageDialogs.py:48 msgid "" "This is a protected Twitter user, which means you can't open a timeline " "using the Streaming API. The user's tweets will not update due to a twitter " @@ -2149,12 +2248,11 @@ msgstr "" "este usuario no se actualizarán debido a una política de Twitter. ¿Deseas " "continuar?" -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 +#: wxUI/commonMessageDialogs.py:48 wxUI/commonMessageDialogs.py:95 msgid "Warning" msgstr "Atención" -#: ../src\wxUI\commonMessageDialogs.py:50 +#: wxUI/commonMessageDialogs.py:51 msgid "" "This is a protected user account, you need to follow this user to view their " "tweets or likes." @@ -2162,7 +2260,7 @@ msgstr "" "Esta es una cuenta protegida, debes seguir al usuario para poder ver sus " "tuits y los tuits marcados con me gusta." -#: ../src\wxUI\commonMessageDialogs.py:53 +#: wxUI/commonMessageDialogs.py:54 msgid "" "If you like {0} we need your help to keep it going. Help us by donating to " "the project. This will help us pay for the server, the domain and some other " @@ -2177,42 +2275,38 @@ msgstr "" "permitirá seguir escribiendo características para {0} y que estas sean " "libres en {0}. ¿Te gustaría donar ahora?" -#: ../src\wxUI\commonMessageDialogs.py:53 +#: wxUI/commonMessageDialogs.py:54 msgid "We need your help" msgstr "Necesitamos tu ayuda" -#: ../src\wxUI\commonMessageDialogs.py:57 +#: wxUI/commonMessageDialogs.py:58 msgid "This user has no tweets. {0} can't create a timeline." msgstr "Este usuario no tiene tuits. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:60 +#: wxUI/commonMessageDialogs.py:61 msgid "This user has no favorited tweets. {0} can't create a timeline." msgstr "" "Este usuario no tiene tuits favoritos. {0} no puede abrirle una línea " "temporal." -#: ../src\wxUI\commonMessageDialogs.py:63 +#: wxUI/commonMessageDialogs.py:64 msgid "This user has no followers. {0} can't create a timeline." msgstr "" "Este usuario no tiene seguidores. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:66 +#: wxUI/commonMessageDialogs.py:67 msgid "This user has no friends. {0} can't create a timeline." msgstr "Este usuario no tiene amigos. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "Información geográfica para este tweet" - -#: ../src\wxUI\commonMessageDialogs.py:70 +#: wxUI/commonMessageDialogs.py:71 msgid "Geolocation data: {0}" msgstr "Datos de ubicación: {0}" -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "Información" +#: wxUI/commonMessageDialogs.py:71 +msgid "Geo data for this tweet" +msgstr "Información geográfica para este tweet" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: wxUI/commonMessageDialogs.py:74 msgid "" "TWBlue has detected that you're running windows 10 and has changed the " "default keymap to the Windows 10 keymap. It means that some keyboard " @@ -2225,11 +2319,15 @@ msgstr "" "el editor de combinaciones de teclado y ver todas las combinaciones " "disponibles en este mapa de teclado." -#: ../src\wxUI\commonMessageDialogs.py:76 +#: wxUI/commonMessageDialogs.py:74 +msgid "Information" +msgstr "Información" + +#: wxUI/commonMessageDialogs.py:77 msgid "You have been blocked from viewing this content" msgstr "Te han bloqueado y no puedes ver este contenido" -#: ../src\wxUI\commonMessageDialogs.py:79 +#: wxUI/commonMessageDialogs.py:80 msgid "" "You have been blocked from viewing someone's content. In order to avoid " "conflicts with the full session, TWBlue will remove the affected timeline." @@ -2237,7 +2335,7 @@ msgstr "" "Alguien te ha bloqueado y no puedes ver su contenido. Para evitar conflictos " "en la sesión entera, TWBlue quitará el hilo temporal afectado." -#: ../src\wxUI\commonMessageDialogs.py:82 +#: wxUI/commonMessageDialogs.py:83 msgid "" "TWBlue cannot load this timeline because the user has been suspended from " "Twitter." @@ -2245,15 +2343,15 @@ msgstr "" "TWBlue no puede cargar este hilo temporal porque el usuario ha sido " "suspendido por Twitter." -#: ../src\wxUI\commonMessageDialogs.py:85 +#: wxUI/commonMessageDialogs.py:86 msgid "Do you really want to delete this filter?" msgstr "¿Realmente deseas eliminar este filtro?" -#: ../src\wxUI\commonMessageDialogs.py:88 +#: wxUI/commonMessageDialogs.py:89 msgid "This filter already exists. Please use a different title" msgstr "Este filtro ya existe, por favor utiliza un título diferente" -#: ../src\wxUI\commonMessageDialogs.py:94 +#: wxUI/commonMessageDialogs.py:95 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." @@ -2261,146 +2359,441 @@ msgstr "" "{0} se cerró de forma inesperada la última vez que se usó. Si el problema " "persiste, por favor informa de él a los desarrolladores de {0}." -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Adjuntar un archivo" +#: wxUI/menus.py:8 wxUI/view.py:33 +msgid "&Retweet" +msgstr "&Retuit" -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Adjuntos" +#: wxUI/menus.py:10 wxUI/menus.py:34 wxUI/view.py:32 +msgid "Re&ply" +msgstr "Res&ponder" -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Título" +#: wxUI/menus.py:12 wxUI/view.py:34 +msgid "&Like" +msgstr "Me &gusta" -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Tipo" +#: wxUI/menus.py:14 wxUI/view.py:35 +msgid "&Unlike" +msgstr "&Ya no me gusta" -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Añadir adjuntos" +#: wxUI/menus.py:16 wxUI/menus.py:36 wxUI/menus.py:52 +msgid "&Open URL" +msgstr "&Abrir URL" -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Foto" +#: wxUI/menus.py:18 wxUI/menus.py:54 wxUI/menus.py:87 +msgid "&Open in Twitter" +msgstr "&Abrir en Twitter" -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Remover archivo" +#: wxUI/menus.py:20 wxUI/menus.py:38 wxUI/menus.py:56 +msgid "&Play audio" +msgstr "&Reproducir audio" -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Archivos de imagen (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +#: wxUI/menus.py:22 wxUI/menus.py:58 wxUI/view.py:36 +msgid "&Show tweet" +msgstr "&Ver tuit" -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Selecciona una foto para subir" +#: wxUI/menus.py:24 wxUI/menus.py:42 wxUI/menus.py:60 wxUI/menus.py:70 +#: wxUI/menus.py:89 wxUI/menus.py:103 +msgid "&Copy to clipboard" +msgstr "&Copiar al portapapeles" -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "por favor proporciona una descripción" +#: wxUI/menus.py:26 wxUI/menus.py:44 wxUI/menus.py:62 wxUI/menus.py:72 +#: wxUI/view.py:40 +msgid "&Delete" +msgstr "&Eliminar" -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Descripción" +#: wxUI/menus.py:28 wxUI/menus.py:46 wxUI/menus.py:91 +msgid "&User actions..." +msgstr "&Acciones de usuario..." -#: ../src\wxUI\dialogs\configuration.py:16 +#: wxUI/menus.py:40 +msgid "&Show direct message" +msgstr "&Mostrar mensaje directo" + +#: wxUI/menus.py:68 +msgid "&Show event" +msgstr "&Mostrar evento" + +#: wxUI/menus.py:78 +msgid "Direct &message" +msgstr "Mensaje &directo" + +#: wxUI/menus.py:80 wxUI/view.py:50 +msgid "&View lists" +msgstr "&Ver listas" + +#: wxUI/menus.py:83 wxUI/view.py:51 +msgid "Show user &profile" +msgstr "Ve&r perfil del usuario" + +#: wxUI/menus.py:85 +msgid "&Show user" +msgstr "&Mostrar usuario" + +#: wxUI/buffers/trends.py:20 wxUI/menus.py:97 +msgid "Search topic" +msgstr "Buscar tema" + +#: wxUI/menus.py:99 +msgid "&Tweet about this trend" +msgstr "&Tuitear sobre esta tendencia" + +#: wxUI/menus.py:101 +msgid "&Show item" +msgstr "&Ver tuit" + +#: wxUI/sysTrayIcon.py:36 wxUI/view.py:26 +msgid "&Global settings" +msgstr "Opciones &globales" + +#: wxUI/sysTrayIcon.py:37 wxUI/view.py:25 +msgid "Account se&ttings" +msgstr "Opciones de &cuenta" + +#: wxUI/sysTrayIcon.py:38 +msgid "Update &profile" +msgstr "Actualizar &perfil" + +#: wxUI/sysTrayIcon.py:39 +msgid "&Show / hide" +msgstr "&Mostrar / esconder" + +#: wxUI/sysTrayIcon.py:40 wxUI/view.py:75 +msgid "&Documentation" +msgstr "&Documentación" + +#: wxUI/sysTrayIcon.py:41 +msgid "Check for &updates" +msgstr "Comprobar &actualizaciones" + +#: wxUI/sysTrayIcon.py:42 +msgid "&Exit" +msgstr "&Salir" + +#: wxUI/view.py:18 +msgid "&Manage accounts" +msgstr "Gestionar &cuentas" + +#: wxUI/dialogs/update_profile.py:35 wxUI/view.py:19 +msgid "&Update profile" +msgstr "Actuali&zar perfil" + +#: wxUI/view.py:20 +msgid "&Hide window" +msgstr "Esconder &ventana" + +#: wxUI/dialogs/search.py:13 wxUI/view.py:21 +msgid "&Search" +msgstr "&Buscar" + +#: wxUI/view.py:22 +msgid "&Lists manager" +msgstr "Gestor de &listas" + +#: wxUI/view.py:23 +msgid "Manage user aliases" +msgstr "Gestionar alias de usuario" + +#: wxUI/view.py:24 +msgid "&Edit keystrokes" +msgstr "Editar combinaciones de &teclas" + +#: wxUI/view.py:27 +msgid "E&xit" +msgstr "S&alir" + +#: wxUI/view.py:31 wxUI/view.py:86 +msgid "&Tweet" +msgstr "&Tuit" + +#: wxUI/view.py:37 +msgid "View &address" +msgstr "Ver &dirección" + +#: wxUI/view.py:38 +msgid "View conversa&tion" +msgstr "Ver conversa&ción" + +#: wxUI/view.py:39 +msgid "Read text in picture" +msgstr "Leer texto en imágenes" + +#: wxUI/view.py:44 +msgid "&Actions..." +msgstr "&Acciones..." + +#: wxUI/view.py:45 +msgid "&View timeline..." +msgstr "&Ver línea temporal..." + +#: wxUI/view.py:46 +msgid "Direct me&ssage" +msgstr "&Mensaje directo" + +#: wxUI/view.py:47 +msgid "Add a&lias" +msgstr "Añadir alias" + +#: wxUI/view.py:48 +msgid "&Add to list" +msgstr "&Añadir a lista" + +#: wxUI/view.py:49 +msgid "R&emove from list" +msgstr "&Quitar de lista" + +#: wxUI/view.py:52 +msgid "V&iew likes" +msgstr "&Ver tuits marcados con me gusta" + +#: wxUI/view.py:56 +msgid "&Update buffer" +msgstr "&actualizar buffer" + +#: wxUI/view.py:57 +msgid "New &trending topics buffer..." +msgstr "Nuevo buffer de &tendencias..." + +#: wxUI/view.py:58 +msgid "Create a &filter" +msgstr "Crear &filtro" + +#: wxUI/view.py:59 +msgid "&Manage filters" +msgstr "Gestionar &filtros" + +#: wxUI/view.py:60 +msgid "Find a string in the currently focused buffer..." +msgstr "Buscar término en el buffer actual..." + +#: wxUI/view.py:61 +msgid "&Load previous items" +msgstr "&Cargar elementos anteriores" + +#: wxUI/dialogs/userActions.py:22 wxUI/view.py:63 +msgid "&Mute" +msgstr "S&ilenciar" + +#: wxUI/view.py:64 +msgid "&Autoread" +msgstr "&lectura automática" + +#: wxUI/view.py:65 +msgid "&Clear buffer" +msgstr "&Vaciar buffer" + +#: wxUI/view.py:66 +msgid "&Destroy" +msgstr "&Eliminar" + +#: wxUI/view.py:70 +msgid "&Seek back 5 seconds" +msgstr "&Retroceder 5 segundos" + +#: wxUI/view.py:71 +msgid "&Seek forward 5 seconds" +msgstr "A&vanzar 5 segundos" + +#: wxUI/view.py:76 +msgid "Sounds &tutorial" +msgstr "Tutorial de &sonidos" + +#: wxUI/view.py:77 +msgid "&What's new in this version?" +msgstr "¿&Qué hay de nuevo en esta versión?" + +#: wxUI/view.py:78 +msgid "&Check for updates" +msgstr "&Comprobar actualizaciones" + +#: wxUI/view.py:79 +msgid "&Report an error" +msgstr "&Reportar un error" + +#: wxUI/view.py:80 +msgid "{0}'s &website" +msgstr "Sitio &web de {0}" + +#: wxUI/view.py:81 +msgid "Get soundpacks for TWBlue" +msgstr "Obtener paquetes de sonidos para TWBlue" + +#: wxUI/view.py:82 +msgid "About &{0}" +msgstr "Sobre &{0}" + +#: wxUI/view.py:85 +msgid "&Application" +msgstr "&Aplicación" + +#: wxUI/dialogs/userActions.py:11 wxUI/view.py:87 +msgid "&User" +msgstr "&Usuario" + +#: wxUI/view.py:88 +msgid "&Buffer" +msgstr "&Buffer" + +#: wxUI/view.py:89 +msgid "&Audio" +msgstr "&Audio" + +#: wxUI/view.py:90 +msgid "&Help" +msgstr "Ay&uda" + +#: wxUI/view.py:176 +msgid "Address" +msgstr "Dirección" + +#: wxUI/view.py:207 +msgid "Your {0} version is up to date" +msgstr "Tu versión de {0} está actualizada" + +#: wxUI/view.py:207 +msgid "Update" +msgstr "Actualización" + +#: wxUI/buffers/base.py:12 wxUI/buffers/people.py:12 +#: wxUI/buffers/user_searches.py:11 wxUI/dialogs/userAliasDialogs.py:14 +#: wxUI/dialogs/userSelection.py:11 wxUI/dialogs/utils.py:32 +msgid "User" +msgstr "Usuario" + +#: wxUI/buffers/base.py:12 wxUI/dialogs/twitterDialogs/tweetDialogs.py:47 +msgid "Text" +msgstr "Texto" + +#: wxUI/buffers/base.py:12 wxUI/buffers/events.py:14 +msgid "Date" +msgstr "Fecha" + +#: wxUI/buffers/base.py:12 +msgid "Client" +msgstr "Cliente" + +#: wxUI/buffers/base.py:28 +msgid "Direct message" +msgstr "Mensaje directo" + +#: wxUI/buffers/events.py:14 +msgid "Event" +msgstr "Evento" + +#: wxUI/buffers/events.py:16 +msgid "Remove event" +msgstr "Eliminar evento" + +#: wxUI/buffers/panels.py:12 wxUI/buffers/panels.py:20 +msgid "Login" +msgstr "Iniciar sesión" + +#: wxUI/buffers/panels.py:14 +msgid "Log in automatically" +msgstr "Iniciar sesión automáticamente" + +#: wxUI/buffers/panels.py:22 +msgid "Logout" +msgstr "Cerrar sesión" + +#: wxUI/buffers/trends.py:9 +msgid "Trending topic" +msgstr "Tendencia" + +#: wxUI/buffers/trends.py:19 +msgid "Tweet about this trend" +msgstr "Tuitear sobre esta tendencia" + +#: wxUI/dialogs/configuration.py:15 msgid "Language" msgstr "Idioma" -#: ../src\wxUI\dialogs\configuration.py:23 +#: wxUI/dialogs/configuration.py:22 msgid "Run {0} at Windows startup" msgstr "Ejecutar {0} al iniciar Windows" -#: ../src\wxUI\dialogs\configuration.py:24 +#: wxUI/dialogs/configuration.py:23 msgid "ask before exiting {0}" msgstr "preguntar antes de salir de {0}" -#: ../src\wxUI\dialogs\configuration.py:27 +#: wxUI/dialogs/configuration.py:26 msgid "Disable Streaming functions" msgstr "Desactivar funciones en tiempo real" -#: ../src\wxUI\dialogs\configuration.py:30 +#: wxUI/dialogs/configuration.py:29 msgid "Buffer update interval, in minutes" msgstr "Intervalo de actualización de los buffers, en minutos" -#: ../src\wxUI\dialogs\configuration.py:36 +#: wxUI/dialogs/configuration.py:35 msgid "Play a sound when {0} launches" msgstr "Reproducir un sonido cuando inicia {0}" -#: ../src\wxUI\dialogs\configuration.py:38 +#: wxUI/dialogs/configuration.py:37 msgid "Speak a message when {0} launches" msgstr "Hablar un mensaje cuando {0} inicie" -#: ../src\wxUI\dialogs\configuration.py:40 +#: wxUI/dialogs/configuration.py:39 msgid "Use invisible interface's keyboard shortcuts while GUI is visible" msgstr "" "Usar los atajos de teclado de la interfaz invisible en la ventana gráfica" -#: ../src\wxUI\dialogs\configuration.py:42 +#: wxUI/dialogs/configuration.py:41 msgid "Activate Sapi5 when any other screen reader is not being run" msgstr "Activar Sapi5 cuando no hay ningún lector de pantalla ejecutándose" -#: ../src\wxUI\dialogs\configuration.py:44 +#: wxUI/dialogs/configuration.py:43 msgid "Hide GUI on launch" msgstr "Esconder interfaz gráfica al iniciar" -#: ../src\wxUI\dialogs\configuration.py:46 +#: wxUI/dialogs/configuration.py:45 msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" msgstr "" "Lectura completa de Tuits largos (puede disminuir el rendimiento del cliente)" -#: ../src\wxUI\dialogs\configuration.py:48 +#: wxUI/dialogs/configuration.py:47 msgid "Remember state for mention all and long tweet" msgstr "Recordar estado para casillas de mencionar a todos y tweet largos" -#: ../src\wxUI\dialogs\configuration.py:51 +#: wxUI/dialogs/configuration.py:50 msgid "Keymap" msgstr "Mapa de teclado" -#: ../src\wxUI\dialogs\configuration.py:56 +#: wxUI/dialogs/configuration.py:55 msgid "Check for updates when {0} launches" msgstr "Comprobar actualizaciones cuando {0} inicie" -#: ../src\wxUI\dialogs\configuration.py:66 +#: wxUI/dialogs/configuration.py:65 msgid "Proxy type: " msgstr "Tipo de proxy: " -#: ../src\wxUI\dialogs\configuration.py:73 +#: wxUI/dialogs/configuration.py:72 msgid "Proxy server: " msgstr "Servidor proxy: " -#: ../src\wxUI\dialogs\configuration.py:79 +#: wxUI/dialogs/configuration.py:78 msgid "Port: " msgstr "Puerto: " -#: ../src\wxUI\dialogs\configuration.py:85 +#: wxUI/dialogs/configuration.py:84 msgid "User: " msgstr "Usuario: " -#: ../src\wxUI\dialogs\configuration.py:91 +#: wxUI/dialogs/configuration.py:90 msgid "Password: " msgstr "Contraseña: " -#: ../src\wxUI\dialogs\configuration.py:103 +#: wxUI/dialogs/configuration.py:102 msgid "Autocompletion settings..." msgstr "Opciones de autocompletado de usuarios..." -#: ../src\wxUI\dialogs\configuration.py:105 +#: wxUI/dialogs/configuration.py:104 msgid "Relative timestamps" msgstr "Tiempos relativos" -#: ../src\wxUI\dialogs\configuration.py:108 +#: wxUI/dialogs/configuration.py:107 msgid "Items on each API call" msgstr "Elementos por cada llamada a la API" -#: ../src\wxUI\dialogs\configuration.py:114 +#: wxUI/dialogs/configuration.py:113 msgid "" "Inverted buffers: The newest tweets will be shown at the beginning while the " "oldest at the end" @@ -2408,15 +2801,15 @@ msgstr "" "Buffers invertidos: los nuevos tweets se mostrarán al principio de las " "listas y los viejos al final" -#: ../src\wxUI\dialogs\configuration.py:116 +#: wxUI/dialogs/configuration.py:115 msgid "Retweet mode" msgstr "Modo de retuit" -#: ../src\wxUI\dialogs\configuration.py:122 +#: wxUI/dialogs/configuration.py:121 msgid "Show screen names instead of full names" msgstr "Mostrar nombres de pantalla en lugar de nombres completos" -#: ../src\wxUI\dialogs\configuration.py:124 +#: wxUI/dialogs/configuration.py:123 msgid "" "Number of items per buffer to cache in database (0 to disable caching, blank " "for unlimited)" @@ -2425,856 +2818,809 @@ msgstr "" "blanco para guardarlos de forma ilimitada, 0 para desactivar la base de " "datos)" -#: ../src\wxUI\dialogs\configuration.py:134 +#: wxUI/dialogs/configuration.py:127 +msgid "" +"Load cache for tweets in memory (much faster in big datasets but requires " +"more RAM)" +msgstr "" +"Cargar cache para Tweets en RAM (es más rápido para listas muy grandes de " +"elementos, pero requiere más memoria)" + +#: wxUI/dialogs/configuration.py:134 msgid "Enable automatic speech feedback" msgstr "Activar mensajes automáticos hablados" -#: ../src\wxUI\dialogs\configuration.py:136 +#: wxUI/dialogs/configuration.py:136 msgid "Enable automatic Braille feedback" msgstr "Activar mensajes automáticos en Braille" -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Estado" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: wxUI/dialogs/configuration.py:144 wxUI/dialogs/filterDialogs.py:130 msgid "Buffer" msgstr "Buffer" -#: ../src\wxUI\dialogs\configuration.py:147 +#: wxUI/dialogs/configuration.py:144 +msgid "Status" +msgstr "Estado" + +#: wxUI/dialogs/configuration.py:147 msgid "Show/hide" msgstr "Mostrar/ocultar" -#: ../src\wxUI\dialogs\configuration.py:148 +#: wxUI/dialogs/configuration.py:148 msgid "Move up" msgstr "Mover arriba" -#: ../src\wxUI\dialogs\configuration.py:149 +#: wxUI/dialogs/configuration.py:149 msgid "Move down" msgstr "Mover abajo" -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 +#: wxUI/dialogs/configuration.py:159 wxUI/dialogs/configuration.py:224 +#: wxUI/dialogs/configuration.py:227 wxUI/dialogs/configuration.py:232 msgid "Show" msgstr "Mostrar" -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 +#: wxUI/dialogs/configuration.py:161 wxUI/dialogs/configuration.py:171 +#: wxUI/dialogs/configuration.py:195 wxUI/dialogs/configuration.py:225 msgid "Hide" msgstr "Ocultar" -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 +#: wxUI/dialogs/configuration.py:169 wxUI/dialogs/configuration.py:193 msgid "Select a buffer first." msgstr "Primero selecciona un buffer." -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 +#: wxUI/dialogs/configuration.py:172 wxUI/dialogs/configuration.py:196 msgid "The buffer is hidden, show it first." msgstr "El buffer está oculto, muéstralo primero." -#: ../src\wxUI\dialogs\configuration.py:175 +#: wxUI/dialogs/configuration.py:175 msgid "The buffer is already at the top of the list." msgstr "El buffer ya se encuentra al principio de la lista." -#: ../src\wxUI\dialogs\configuration.py:199 +#: wxUI/dialogs/configuration.py:199 msgid "The buffer is already at the bottom of the list." msgstr "El buffer ya se encuentra al final de la lista." -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 +#: wxUI/dialogs/configuration.py:240 wxUI/dialogs/configuration.py:381 msgid "Ignored clients" msgstr "Clientes ignorados" -#: ../src\wxUI\dialogs\configuration.py:247 +#: wxUI/dialogs/configuration.py:247 msgid "Remove client" msgstr "Quitar cliente" -#: ../src\wxUI\dialogs\configuration.py:271 +#: wxUI/dialogs/configuration.py:271 msgid "Volume" msgstr "Volumen" -#: ../src\wxUI\dialogs\configuration.py:282 +#: wxUI/dialogs/configuration.py:282 msgid "Session mute" msgstr "Silencio de sesión" -#: ../src\wxUI\dialogs\configuration.py:284 +#: wxUI/dialogs/configuration.py:284 msgid "Output device" msgstr "Dispositivo de salida" -#: ../src\wxUI\dialogs\configuration.py:291 +#: wxUI/dialogs/configuration.py:291 msgid "Input device" msgstr "Dispositivo de entrada" -#: ../src\wxUI\dialogs\configuration.py:299 +#: wxUI/dialogs/configuration.py:299 msgid "Sound pack" msgstr "Paquete de sonidos" -#: ../src\wxUI\dialogs\configuration.py:305 +#: wxUI/dialogs/configuration.py:305 msgid "Indicate audio tweets with sound" msgstr "Reproducir sonido en tuits con audio" -#: ../src\wxUI\dialogs\configuration.py:307 +#: wxUI/dialogs/configuration.py:307 msgid "Indicate geotweets with sound" msgstr "Reproducir sonido en tuits con información geográfica" -#: ../src\wxUI\dialogs\configuration.py:309 +#: wxUI/dialogs/configuration.py:309 msgid "Indicate tweets containing images with sound" msgstr "Reproducir sonido en tuits con imágenes" -#: ../src\wxUI\dialogs\configuration.py:332 +#: wxUI/dialogs/configuration.py:332 msgid "Language for OCR" msgstr "Idioma para el OCR" -#: ../src\wxUI\dialogs\configuration.py:338 +#: wxUI/dialogs/configuration.py:338 msgid "API Key for SndUp" msgstr "Clave de api para SNDUp" -#: ../src\wxUI\dialogs\configuration.py:353 +#: wxUI/dialogs/configuration.py:353 msgid "{0} preferences" msgstr "Preferencias de {0}" -#: ../src\wxUI\dialogs\configuration.py:364 +#: wxUI/dialogs/configuration.py:364 msgid "Proxy" msgstr "Proxy" -#: ../src\wxUI\dialogs\configuration.py:373 +#: wxUI/dialogs/configuration.py:373 msgid "Feedback" msgstr "Retroalimentación" -#: ../src\wxUI\dialogs\configuration.py:377 +#: wxUI/dialogs/configuration.py:377 msgid "Buffers" msgstr "Buffers" -#: ../src\wxUI\dialogs\configuration.py:385 +#: wxUI/dialogs/configuration.py:385 msgid "Sound" msgstr "Sonido" -#: ../src\wxUI\dialogs\configuration.py:389 +#: wxUI/dialogs/configuration.py:389 msgid "Extras" msgstr "Extras" -#: ../src\wxUI\dialogs\configuration.py:394 +#: wxUI/dialogs/configuration.py:394 msgid "Save" msgstr "Guardar" -#: ../src\wxUI\dialogs\filterDialogs.py:15 +#: wxUI/dialogs/filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "Crear filtro para este buffer" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: wxUI/dialogs/filterDialogs.py:14 msgid "Filter title" msgstr "Nombre del filtro" -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: wxUI/dialogs/filterDialogs.py:24 wxUI/dialogs/filterDialogs.py:130 msgid "Filter by word" msgstr "Filtrar por palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:26 +#: wxUI/dialogs/filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "Ignorar tuits que contengan la siguiente palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: wxUI/dialogs/filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "Ignorar tuits que no contengan la siguiente palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:32 +#: wxUI/dialogs/filterDialogs.py:31 msgid "word" msgstr "palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:37 +#: wxUI/dialogs/filterDialogs.py:36 msgid "Allow retweets" msgstr "Permitir retuits" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: wxUI/dialogs/filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "Permitir tweets citados" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: wxUI/dialogs/filterDialogs.py:38 msgid "Allow replies" msgstr "Permitir respuestas" -#: ../src\wxUI\dialogs\filterDialogs.py:47 +#: wxUI/dialogs/filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "Usar término como expresión regular" -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: wxUI/dialogs/filterDialogs.py:48 wxUI/dialogs/filterDialogs.py:130 msgid "Filter by language" msgstr "Filtrar por idioma" -#: ../src\wxUI\dialogs\filterDialogs.py:50 +#: wxUI/dialogs/filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "Cargar tuits en los siguientes idiomas" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: wxUI/dialogs/filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "Ignorar tuits en los siguientes idiomas" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: wxUI/dialogs/filterDialogs.py:51 msgid "Don't filter by language" msgstr "No filtrar por idioma" -#: ../src\wxUI\dialogs\filterDialogs.py:63 +#: wxUI/dialogs/filterDialogs.py:62 msgid "Supported languages" msgstr "Idiomas soportados" -#: ../src\wxUI\dialogs\filterDialogs.py:68 +#: wxUI/dialogs/filterDialogs.py:67 msgid "Add selected language to filter" msgstr "Añadir idioma seleccionado al filtro" -#: ../src\wxUI\dialogs\filterDialogs.py:72 +#: wxUI/dialogs/filterDialogs.py:71 msgid "Selected languages" msgstr "Idiomas seleccionados" -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 +#: wxUI/dialogs/filterDialogs.py:73 wxUI/dialogs/filterDialogs.py:137 +#: wxUI/dialogs/lists.py:21 wxUI/dialogs/lists.py:132 +#: wxUI/dialogs/userAliasDialogs.py:57 msgid "Remove" msgstr "Borrar" -#: ../src\wxUI\dialogs\filterDialogs.py:122 +#: wxUI/dialogs/filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Debes definir un título ppara el filtro antes de poder guardarlo." + +#: wxUI/dialogs/filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Título del filtro faltante" + +#: wxUI/dialogs/filterDialogs.py:127 msgid "Manage filters" msgstr "Gestionar filtros" -#: ../src\wxUI\dialogs\filterDialogs.py:124 +#: wxUI/dialogs/filterDialogs.py:129 msgid "Filters" msgstr "Filtros" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: wxUI/dialogs/filterDialogs.py:130 msgid "Filter" msgstr "Filtro" -#: ../src\wxUI\dialogs\find.py:12 +#: wxUI/dialogs/find.py:13 msgid "Find in current buffer" msgstr "Buscar en el buffer actual" -#: ../src\wxUI\dialogs\find.py:13 +#: wxUI/dialogs/find.py:14 msgid "String" msgstr "Término" -#: ../src\wxUI\dialogs\lists.py:10 +#: wxUI/dialogs/lists.py:11 msgid "Lists manager" msgstr "Gestor de listas" -#: ../src\wxUI\dialogs\lists.py:13 +#: wxUI/dialogs/lists.py:14 msgid "List" msgstr "Lista" -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "Miembros" +#: wxUI/dialogs/lists.py:14 wxUI/dialogs/lists.py:70 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:37 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:126 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:173 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:257 +msgid "Description" +msgstr "Descripción" -#: ../src\wxUI\dialogs\lists.py:13 +#: wxUI/dialogs/lists.py:14 msgid "Owner" msgstr "Propietario" -#: ../src\wxUI\dialogs\lists.py:13 +#: wxUI/dialogs/lists.py:14 +msgid "Members" +msgstr "Miembros" + +#: wxUI/dialogs/lists.py:14 msgid "mode" msgstr "modo" -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 +#: wxUI/dialogs/lists.py:19 wxUI/dialogs/lists.py:62 msgid "Create a new list" msgstr "Crear nueva lista" -#: ../src\wxUI\dialogs\lists.py:21 +#: wxUI/dialogs/lists.py:22 msgid "Open in buffer" msgstr "Abrir en buffer" -#: ../src\wxUI\dialogs\lists.py:51 +#: wxUI/dialogs/lists.py:52 +#, python-format msgid "Viewing lists for %s" msgstr "Viendo las listas de %s" -#: ../src\wxUI\dialogs\lists.py:52 +#: wxUI/dialogs/lists.py:53 msgid "Subscribe" msgstr "Darte de alta" -#: ../src\wxUI\dialogs\lists.py:53 +#: wxUI/dialogs/lists.py:54 msgid "Unsubscribe" msgstr "Darse de baja" -#: ../src\wxUI\dialogs\lists.py:64 +#: wxUI/dialogs/lists.py:65 msgid "Name (20 characters maximun)" msgstr "Nombre (máximo 20 caracteres)" -#: ../src\wxUI\dialogs\lists.py:74 +#: wxUI/dialogs/lists.py:75 msgid "Mode" msgstr "Modo" -#: ../src\wxUI\dialogs\lists.py:75 +#: wxUI/dialogs/lists.py:76 msgid "Public" msgstr "Público" -#: ../src\wxUI\dialogs\lists.py:76 +#: wxUI/dialogs/lists.py:77 msgid "Private" msgstr "Privado" -#: ../src\wxUI\dialogs\lists.py:96 +#: wxUI/dialogs/lists.py:97 +#, python-format msgid "Editing the list %s" msgstr "Editando la lista %s" -#: ../src\wxUI\dialogs\lists.py:107 +#: wxUI/dialogs/lists.py:108 msgid "Select a list to add the user" msgstr "Selecciona una lista para añadir al usuario" -#: ../src\wxUI\dialogs\lists.py:108 +#: wxUI/dialogs/lists.py:109 msgid "Add" msgstr "Añadir" -#: ../src\wxUI\dialogs\lists.py:130 +#: wxUI/dialogs/lists.py:131 msgid "Select a list to remove the user" msgstr "Selecciona una lista para quitar al usuario" -#: ../src\wxUI\dialogs\lists.py:148 +#: wxUI/dialogs/lists.py:149 msgid "Do you really want to delete this list?" msgstr "¿Realmente deseas eliminar esta lista?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "Tuit &largo" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Subir imagen..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Revisar &ortografía..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Adjuntar audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Acortar &URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Expandir URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Traducir..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Auto&completar usuarios" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "En&viar" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "Ce&rrar" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinatario" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Mencionar a todos" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tuit - %i caracteres " - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Descripción de la imagen" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retuits: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Me gusta: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Desde: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -msgid "Date: " -msgstr "Fecha: " - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Ver" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Elemento" - -#: ../src\wxUI\dialogs\search.py:13 +#: wxUI/dialogs/search.py:12 msgid "Search on Twitter" msgstr "Buscar en Twitter" -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "&Buscar" - -#: ../src\wxUI\dialogs\search.py:21 +#: wxUI/dialogs/search.py:21 msgid "Tweets" msgstr "Tuits" -#: ../src\wxUI\dialogs\search.py:22 +#: wxUI/dialogs/search.py:22 wxUI/dialogs/userAliasDialogs.py:43 msgid "Users" msgstr "Usuarios" -#: ../src\wxUI\dialogs\search.py:29 +#: wxUI/dialogs/search.py:29 msgid "&Language for results: " msgstr "&Idioma para los resultados: " -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 +#: wxUI/dialogs/search.py:31 wxUI/dialogs/search.py:55 msgid "any" msgstr "cualquiera" -#: ../src\wxUI\dialogs\search.py:37 +#: wxUI/dialogs/search.py:37 msgid "Results &type: " msgstr "&Tipo de resultados: " -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:63 msgid "Mixed" msgstr "Mixtos" -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:64 msgid "Recent" msgstr "Recientes" -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:65 msgid "Popular" msgstr "Populares" -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 +#: wxUI/dialogs/search.py:43 wxUI/dialogs/trends.py:25 +#: wxUI/dialogs/userActions.py:41 wxUI/dialogs/userSelection.py:33 msgid "&OK" msgstr "&Aceptar" -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 +#: wxUI/dialogs/search.py:45 wxUI/dialogs/show_user.py:19 +#: wxUI/dialogs/trends.py:27 wxUI/dialogs/update_profile.py:37 +#: wxUI/dialogs/userActions.py:43 wxUI/dialogs/userSelection.py:35 msgid "&Close" msgstr "Ce&rrar" -#: ../src\wxUI\dialogs\show_user.py:11 +#: wxUI/dialogs/show_user.py:12 msgid "Details" msgstr "Detalles" -#: ../src\wxUI\dialogs\show_user.py:16 +#: wxUI/dialogs/show_user.py:17 msgid "&Go to URL" msgstr "&Ir a URL" -#: ../src\wxUI\dialogs\trends.py:12 +#: wxUI/dialogs/trends.py:10 msgid "View trending topics" msgstr "Ver tendencias" -#: ../src\wxUI\dialogs\trends.py:13 +#: wxUI/dialogs/trends.py:11 msgid "Trending topics by" msgstr "Tendencias por" -#: ../src\wxUI\dialogs\trends.py:15 +#: wxUI/dialogs/trends.py:12 msgid "Country" msgstr "País" -#: ../src\wxUI\dialogs\trends.py:16 +#: wxUI/dialogs/trends.py:13 msgid "City" msgstr "Ciudad" -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 +#: wxUI/dialogs/trends.py:19 wxUI/dialogs/update_profile.py:18 msgid "&Location" msgstr "&Ubicación" -#: ../src\wxUI\dialogs\update_profile.py:9 +#: wxUI/dialogs/update_profile.py:10 msgid "Update your profile" msgstr "Actualizar tu perfil" -#: ../src\wxUI\dialogs\update_profile.py:11 +#: wxUI/dialogs/update_profile.py:12 msgid "&Name (50 characters maximum)" msgstr "&Nombre (máximo 50 caracteres)" -#: ../src\wxUI\dialogs\update_profile.py:22 +#: wxUI/dialogs/update_profile.py:23 msgid "&Website" msgstr "Sitio &web" -#: ../src\wxUI\dialogs\update_profile.py:27 +#: wxUI/dialogs/update_profile.py:28 msgid "&Bio (160 characters maximum)" msgstr "&Descripción (máximo 160 caracteres)" -#: ../src\wxUI\dialogs\update_profile.py:33 +#: wxUI/dialogs/update_profile.py:34 msgid "Upload a &picture" msgstr "Subir una &foto" -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "Actuali&zar perfil" - -#: ../src\wxUI\dialogs\update_profile.py:76 +#: wxUI/dialogs/update_profile.py:77 msgid "Upload a picture" msgstr "Subir una foto" -#: ../src\wxUI\dialogs\update_profile.py:78 +#: wxUI/dialogs/update_profile.py:79 msgid "Discard image" msgstr "Descartar foto" -#: ../src\wxUI\dialogs\urlList.py:5 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:133 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:289 +#: wxUI/dialogs/update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Selecciona una foto para subir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:133 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:289 +#: wxUI/dialogs/update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Archivos de imagen (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: wxUI/dialogs/urlList.py:6 msgid "Select URL" msgstr "Selecciona la URL" -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "&Usuario" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 +#: wxUI/dialogs/userActions.py:14 wxUI/dialogs/userAliasDialogs.py:13 +#: wxUI/dialogs/userSelection.py:14 wxUI/dialogs/utils.py:31 msgid "&Autocomplete users" msgstr "&Autocompletar usuarios" -#: ../src\wxUI\dialogs\userActions.py:19 +#: wxUI/dialogs/userActions.py:20 msgid "&Follow" msgstr "&Seguir" -#: ../src\wxUI\dialogs\userActions.py:20 +#: wxUI/dialogs/userActions.py:21 msgid "U&nfollow" msgstr "&Dejar de seguir" -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "S&ilenciar" - -#: ../src\wxUI\dialogs\userActions.py:22 +#: wxUI/dialogs/userActions.py:23 msgid "Unmu&te" msgstr "D&esactivar silencio" -#: ../src\wxUI\dialogs\userActions.py:23 +#: wxUI/dialogs/userActions.py:24 msgid "&Block" msgstr "&Bloquear" -#: ../src\wxUI\dialogs\userActions.py:24 +#: wxUI/dialogs/userActions.py:25 msgid "Unbl&ock" msgstr "Desb&loquear" -#: ../src\wxUI\dialogs\userActions.py:25 +#: wxUI/dialogs/userActions.py:26 msgid "&Report as spam" msgstr "&Reportar como spam" -#: ../src\wxUI\dialogs\userActions.py:26 +#: wxUI/dialogs/userActions.py:27 msgid "&Ignore tweets from this client" msgstr "&Ignorar tuits de este cliente" -#: ../src\wxUI\dialogs\userSelection.py:9 +#: wxUI/dialogs/userAliasDialogs.py:18 +msgid "Alias" +msgstr "Alias" + +#: wxUI/dialogs/userAliasDialogs.py:41 +msgid "Edit user aliases" +msgstr "Editar alias de usuarios" + +#: wxUI/dialogs/userAliasDialogs.py:48 +msgid "Actions" +msgstr "Acciones" + +#: wxUI/dialogs/userAliasDialogs.py:50 +msgid "Add alias" +msgstr "Añadir alias" + +#: wxUI/dialogs/userAliasDialogs.py:51 +msgid "Adds a new user alias" +msgstr "Añadir un nuevo alias" + +#: wxUI/dialogs/userAliasDialogs.py:54 +msgid "Edit the currently focused user Alias." +msgstr "Editar alias del usuario seleccionado" + +#: wxUI/dialogs/userAliasDialogs.py:58 +msgid "Remove the currently focused user alias." +msgstr "Eliminar alias del usuario seleccionado." + +#: wxUI/dialogs/userAliasDialogs.py:82 +msgid "Are you sure you want to delete this user alias?" +msgstr "¿Estás seguro que deseas eliminar este alias de usuario?" + +#: wxUI/dialogs/userAliasDialogs.py:82 +msgid "Remove user alias" +msgstr "Eliminar alias de usuario" + +#: wxUI/dialogs/userAliasDialogs.py:93 +msgid "User alias" +msgstr "Alias de usuario" + +#: wxUI/dialogs/userSelection.py:10 +#, python-format msgid "Timeline for %s" msgstr "Línea temporal de %s" -#: ../src\wxUI\dialogs\userSelection.py:18 +#: wxUI/dialogs/userSelection.py:19 msgid "Buffer type" msgstr "Tipo de buffer" -#: ../src\wxUI\dialogs\userSelection.py:19 +#: wxUI/dialogs/userSelection.py:20 msgid "&Tweets" msgstr "&Tuits" -#: ../src\wxUI\dialogs\userSelection.py:20 +#: wxUI/dialogs/userSelection.py:21 msgid "&Likes" msgstr "Tuits marcados como &me gusta" -#: ../src\wxUI\dialogs\userSelection.py:21 +#: wxUI/dialogs/userSelection.py:22 msgid "&Followers" msgstr "&Seguidores" -#: ../src\wxUI\dialogs\userSelection.py:22 +#: wxUI/dialogs/userSelection.py:23 msgid "F&riends" msgstr "&Amigos" -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "&Retuit" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "Res&ponder" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "Me &gusta" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "&Ya no me gusta" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "&Abrir URL" - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -msgid "&Open in Twitter" -msgstr "&Abrir en Twitter" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "&Reproducir audio" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "&Ver tuit" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "&Copiar al portapapeles" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "&Eliminar" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:32 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:48 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:168 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:252 +msgid "Attachments" +msgstr "Adjuntos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:36 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:172 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:256 +msgid "Type" +msgstr "Tipo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:39 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:175 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:259 +msgid "Delete attachment" +msgstr "Quitar archivo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:44 +msgid "Added Tweets" +msgstr "Tuits añadidos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:51 +msgid "Delete tweet" +msgstr "Quitar tuit" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:56 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:190 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:264 +msgid "A&dd..." +msgstr "Añadir..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:58 +msgid "Add t&weet" +msgstr "Añadir Tuit" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:61 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:192 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:266 +msgid "&Attach audio..." +msgstr "&Adjuntar audio..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:65 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:196 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:235 +msgid "Auto&complete users" +msgstr "Auto&completar usuarios" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:67 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:198 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:270 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:364 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:437 +msgid "Check &spelling..." +msgstr "Revisar &ortografía..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:69 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:200 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:272 +msgid "&Translate" +msgstr "&Traducir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:73 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:204 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:276 +msgid "Sen&d" +msgstr "En&viar" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:117 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:218 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:296 +msgid "Image" +msgstr "Imagen" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:119 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:220 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:298 +msgid "Video" +msgstr "Vídeo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:121 +msgid "Poll" +msgstr "Encuesta" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:126 +msgid "please provide a description" +msgstr "por favor proporciona una descripción" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:140 +msgid "Select the video to be uploaded" +msgstr "Selecciona un vídeo para subir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:140 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Archivos de video (*.mp4)|*.mp4" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:146 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"No es posible añadir más archivos multimedia. Por favor asegúrate que " +"cumples con los requisitos de archivos de Twitter. Solo se puede añadir un " +"video o un GIF en cada tweet, o un máximo de hasta 4 imágenes." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:146 +msgid "Error adding attachment" +msgstr "Error añadiendo un archivo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:180 +msgid "&Mention to all" +msgstr "&Mencionar a todos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:233 +msgid "&Recipient" +msgstr "&Destinatario" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:304 +#, python-format +msgid "Tweet - %i characters " +msgstr "Tuit - %i caracteres " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:321 +msgid "Image description" +msgstr "Descripción de la imagen" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:332 +msgid "Retweets: " +msgstr "Retuits: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:337 +msgid "Likes: " +msgstr "Me gusta: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:342 +msgid "Source: " +msgstr "Desde: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:347 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:425 +msgid "Date: " +msgstr "Fecha: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:362 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:435 +msgid "Copy link to clipboard" +msgstr "Copiar enlace al portapapeles" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:365 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:440 +msgid "&Translate..." +msgstr "&Traducir..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:366 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:441 +msgid "C&lose" +msgstr "Ce&rrar" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:410 +msgid "View" +msgstr "Ver" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:412 +msgid "Item" +msgstr "Elemento" -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "&Acciones de usuario..." +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:438 +msgid "&Expand URL" +msgstr "&Expandir URL" -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "&Mostrar mensaje directo" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:477 +msgid "Add a poll" +msgstr "Añadir encuesta" -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "&Mostrar evento" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:481 +msgid "Participation time (in days)" +msgstr "Tiempo para participar (en días)" -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "Mensaje &directo" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:488 +msgid "Choices" +msgstr "Opciones" -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "&Ver listas" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:492 +msgid "Option 1" +msgstr "Opción 1" -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "Ve&r perfil del usuario" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:499 +msgid "Option 2" +msgstr "Opción 2" -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "&Mostrar usuario" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:506 +msgid "Option 3" +msgstr "Opción 3" -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "&Tuitear sobre esta tendencia" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:513 +msgid "Option 4" +msgstr "Opción 4" -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "&Ver tuit" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:541 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "" +"Por favor asegúrate de haber proporcionado, al menos, dos opciones para la " +"encuesta." -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "Opciones &globales" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:541 +msgid "Not enough information" +msgstr "Información insuficiente" -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "Opciones de &cuenta" +#~ msgid "Photo" +#~ msgstr "Imagen" -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "Actualizar &perfil" +#~ msgid "There's no URL to be shortened" +#~ msgstr "No hay ninguna URL para acortar" -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "&Mostrar / esconder" +#~ msgid "URL shortened" +#~ msgstr "URL Acortada" -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "&Documentación" +#~ msgid "There's no URL to be expanded" +#~ msgstr "No hay ninguna URL para expandir" -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "Comprobar &actualizaciones" +#~ msgid "URL expanded" +#~ msgstr "URL expandida" -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "&Salir" +#~ msgid "%s - %s characters" +#~ msgstr "%s - %s caracteres" -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "Gestionar &cuentas" +#~ msgid "Title" +#~ msgstr "Título" -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "Esconder &ventana" +#~ msgid "Add attachments" +#~ msgstr "Añadir adjuntos" -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "Gestor de &listas" +#~ msgid "&Photo" +#~ msgstr "&Foto" -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "Editar combinaciones de &teclas" +#~ msgid "&Long tweet" +#~ msgstr "Tuit &largo" -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "S&alir" +#~ msgid "&Upload image..." +#~ msgstr "&Subir imagen..." -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "&Tuit" +#~ msgid "Sh&orten URL" +#~ msgstr "Acortar &URL" -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "Ver &dirección" +#~ msgid "Friends' Timelines" +#~ msgstr "Líneas temporales de amigos" -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "Ver conversa&ción" +#~ msgid "Events" +#~ msgstr "Eventos" -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "Leer texto en imágenes" +#~ msgid "This tweet doesn't contain images" +#~ msgstr "El tuit no contiene imágenes" -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "&Acciones..." +#~ msgid "Direct connection" +#~ msgstr "Conexión directa" -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "&Ver línea temporal..." - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "&Mensaje directo" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "&Añadir a lista" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "&Quitar de lista" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "&Ver tuits marcados con me gusta" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "&actualizar buffer" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "Nuevo buffer de &tendencias..." - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "Crear &filtro" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "Gestionar &filtros" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "Buscar término en el buffer actual..." - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "&Cargar elementos anteriores" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "&lectura automática" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "&Vaciar buffer" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "&Eliminar" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "&Retroceder 5 segundos" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "A&vanzar 5 segundos" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "Tutorial de &sonidos" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "¿&Qué hay de nuevo en esta versión?" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "&Comprobar actualizaciones" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "&Reportar un error" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "Sitio &web de {0}" - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "Obtener paquetes de sonidos para TWBlue" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "Sobre &{0}" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "&Aplicación" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "&Buffer" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "&Audio" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "Ay&uda" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "Dirección" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "Actualización" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "Tu versión de {0} está actualizada" +#~ msgid "There are no more items to retrieve in this buffer." +#~ msgstr "No hay más elementos que recuperar en este buffer." #~ msgid "Empty" #~ msgstr "Vacío" @@ -3451,9 +3797,6 @@ msgstr "Tu versión de {0} está actualizada" #~ msgid "Update profile" #~ msgstr "Actualizar perfil" -#~ msgid "Follow" -#~ msgstr "Seguir" - #~ msgid "Mute" #~ msgstr "Silenciar" @@ -3505,9 +3848,6 @@ msgstr "Tu versión de {0} está actualizada" #~ msgid "Opening media..." #~ msgstr "Abriendo medio..." -#~ msgid "Add a new ignored client" -#~ msgstr "Añadir un nuevo clienteClientes ignorados" - #~ msgid "Do you really want to delete this timeline?" #~ msgstr "¿Realmente deseas eliminar esta línea temporal?" @@ -3517,9 +3857,6 @@ msgstr "Tu versión de {0} está actualizada" #~ msgid "GIF images" #~ msgstr "Imágenes GIF" -#~ msgid "PNG Images" -#~ msgstr "Imágenes PNG" - #~ msgid "Select an URL" #~ msgstr "Selecciona una URL" @@ -3785,9 +4122,6 @@ msgstr "Tu versión de {0} está actualizada" #~ msgid "See the users list" #~ msgstr "Ver lista de usuarios" -#~ msgid "Do you really want to delete this message?" -#~ msgstr "¿Realmente quieres eliminar este mensaje?" - #~ msgid "Unable to play audio." #~ msgstr "Imposible reproducir audio" diff --git a/src/locales/fr/LC_MESSAGES/twblue.mo b/src/locales/fr/LC_MESSAGES/twblue.mo index 03e45525..a6de8403 100644 Binary files a/src/locales/fr/LC_MESSAGES/twblue.mo and b/src/locales/fr/LC_MESSAGES/twblue.mo differ diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index 9eb03e89..f9587d45 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -1,289 +1,291 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estándar romance\n" -"PO-Revision-Date: 2019-07-22 16:16+0200\n" -"Last-Translator: Corentin BACQUÉ-CAZENAVE \n" -"Language-Team: Corentin BACQUÉ-CAZENAVE \n" +"POT-Creation-Date: 2021-11-11 01:00+0100\n" +"PO-Revision-Date: 2021-11-12 13:32-0600\n" +"Last-Translator: Oreonan \n" +"Language-Team: Oreonan \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 3.0\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,384,-1,-1,-1,-1\n" -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Photo" - -#: ../src\controller\buffers\baseBuffers.py:95 +#: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "Cette action n'est pas supportée pour ce tampon" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 msgid "Home" msgstr "Accueil" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 msgid "Mentions" msgstr "Mentions" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:341 msgid "Direct messages" -msgstr "Messages privés" +msgstr "Messages" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 msgid "Sent direct messages" -msgstr "Messages privés envoyés" +msgstr "Messages envoyés" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 msgid "Sent tweets" msgstr "Tweets envoyés" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:347 +#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 msgid "Likes" msgstr "Favoris" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:349 +#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 msgid "Followers" msgstr "Abonnés" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Abonnements" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:353 +#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 msgid "Blocked users" msgstr "Utilisateurs bloqués" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:355 +#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 msgid "Muted users" msgstr "Utilisateurs masqués" -#: ../src\controller\buffers\twitterBuffers.py:75 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 +msgid "Friends" +msgstr "Abonnements" + +#: ../src\controller\buffers\twitter\base.py:76 msgid "{username}'s timeline" msgstr "Chronologie de {username}" -#: ../src\controller\buffers\twitterBuffers.py:77 +#: ../src\controller\buffers\twitter\base.py:78 msgid "{username}'s likes" msgstr "Favoris de {username}" -#: ../src\controller\buffers\twitterBuffers.py:79 +#: ../src\controller\buffers\twitter\base.py:80 msgid "{username}'s followers" msgstr "Abonnés de {username}" -#: ../src\controller\buffers\twitterBuffers.py:81 +#: ../src\controller\buffers\twitter\base.py:82 msgid "{username}'s friends" msgstr "Abonnements de {username}" -#: ../src\controller\buffers\twitterBuffers.py:83 +#: ../src\controller\buffers\twitter\base.py:84 msgid "Unknown buffer" msgstr "Tampon inconnu" -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 +#: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "Tweet" -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "Écrivez le tweet ici" -#: ../src\controller\buffers\twitterBuffers.py:194 +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" msgstr "Nouveau tweet dans {0}" -#: ../src\controller\buffers\twitterBuffers.py:197 +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." msgstr "{0} nouveau tweet dans {1}" -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 +#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\directMessages.py:88 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s éléments récupérés" -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 +#: ../src\controller\buffers\twitter\base.py:266 +#: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ce tampon n'est pas une chronologie ; Impossible de le supprimé." -#: ../src\controller\buffers\twitterBuffers.py:402 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "Répondre à {arg0}" -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 +#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Répondre" -#: ../src\controller\buffers\twitterBuffers.py:405 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "Répondre à %s" -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Message privé à %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" -msgstr "Nouveau message privé" +msgstr "Nouveau message" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 +msgid "Direct message to %s" +msgstr "Message à %s" + +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "Ajoutez votre commentaire pour le tweet" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "Citer" -#: ../src\controller\buffers\twitterBuffers.py:572 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." msgstr "Ouverture de l'URL..." -#: ../src\controller\buffers\twitterBuffers.py:607 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "Détails de l'utilisateur" -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." msgstr "Ouverture de l'élément dans le navigateur Web..." -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "Mention pour %s" -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "Mention" -#: ../src\controller\buffers\twitterBuffers.py:728 +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." -msgstr "{0} nouveau message privé" +msgstr "{0} nouveau message" -#: ../src\controller\buffers\twitterBuffers.py:731 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." msgstr "Cette action n'est pas supportée dans le tampon actuel" -#: ../src\controller\buffers\twitterBuffers.py:741 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." msgstr "" "Récupérer plus d'élément est impossible dans ce tampon, utilisez le tampon " -"des messages privés à la place." +"des messages à la place." -#: ../src\controller\buffers\twitterBuffers.py:983 +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." msgstr "{0} nouvel abonné" -#: ../src\controller\buffers\twitterBuffers.py:1266 +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." msgstr "Cette action n'est pas supportée pour le tampon actuel" -#: ../src\controller\mainController.py:273 +#: ../src\controller\mainController.py:277 msgid "Ready" msgstr "Prêt" -#: ../src\controller\mainController.py:345 +#: ../src\controller\mainController.py:351 +msgid "Following" +msgstr "Abonnements" + +#: ../src\controller\mainController.py:356 msgid "Timelines" msgstr "Chronologies" -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 +#: ../src\controller\mainController.py:359 +#: ../src\controller\mainController.py:883 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "Chronologie de {}" -#: ../src\controller\mainController.py:352 +#: ../src\controller\mainController.py:360 msgid "Likes timelines" msgstr "Chronologies des favoris" -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 +#: ../src\controller\mainController.py:363 +#: ../src\controller\mainController.py:902 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "Favoris de {}" -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" +#: ../src\controller\mainController.py:364 +msgid "Followers timelines" msgstr "Chronologies des abonnés" -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 +#: ../src\controller\mainController.py:367 +#: ../src\controller\mainController.py:921 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "Abonnés de {}" -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" +#: ../src\controller\mainController.py:368 +msgid "Following timelines" msgstr "Chronologies des abonnements" -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 +#: ../src\controller\mainController.py:371 +#: ../src\controller\mainController.py:940 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "Abonnements de {}" -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 +#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 msgid "Lists" msgstr "Listes" -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 +#: ../src\controller\mainController.py:375 +#: ../src\controller\mainController.py:1422 msgid "List for {}" -msgstr "Liste de {}" +msgstr "Liste {}" -#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:376 msgid "Searches" msgstr "Recherches" -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 +#: ../src\controller\mainController.py:379 +#: ../src\controller\mainController.py:426 +#: ../src\controller\mainController.py:431 msgid "Search for {}" msgstr "Recherche de {}" -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 +#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" msgstr "Tendances pour %s" -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 +#: ../src\controller\mainController.py:448 +#: ../src\controller\mainController.py:464 +#: ../src\controller\mainController.py:1080 +#: ../src\controller\mainController.py:1099 +#: ../src\controller\mainController.py:1118 +#: ../src\controller\mainController.py:1137 msgid "" "No session is currently in focus. Focus a session with the next or previous " "session shortcut." @@ -291,238 +293,246 @@ msgstr "" "Aucune session n'a actuellement le focus. Sélectionnez-en une avec le " "raccourci pour la session précédente ou suivante." -#: ../src\controller\mainController.py:465 +#: ../src\controller\mainController.py:452 msgid "Empty buffer." msgstr "Tampon vide." -#: ../src\controller\mainController.py:472 +#: ../src\controller\mainController.py:459 msgid "{0} not found." msgstr "{0} introuvable." -#: ../src\controller\mainController.py:482 +#: ../src\controller\mainController.py:469 msgid "Filters cannot be applied on this buffer" msgstr "Les filtres ne peuvent pas s'appliquer à ce tampon" -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 +#: ../src\controller\mainController.py:522 +#: ../src\controller\mainController.py:539 +#: ../src\controller\mainController.py:568 msgid "Select the user" msgstr "Sélectionnez l'utilisateur" -#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236 +#: ../src\controller\mainController.py:753 +msgid "Add an user alias" +msgstr "Ajoute un alias pour l'utilisateur" + +#: ../src\controller\mainController.py:761 +msgid "Alias has been set correctly for {}." +msgstr "L'alias pour {} a correctement été définie" + +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "D MMM YYYY à H:m" -#: ../src\controller\mainController.py:934 +#: ../src\controller\mainController.py:957 msgid "Conversation with {0}" msgstr "Conversation avec {0}" -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 +#: ../src\controller\mainController.py:998 +#: ../src\controller\mainController.py:1015 msgid "There are no coordinates in this tweet" msgstr "Il n'y a aucune coordonnée dans ce tweet" -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "Il n'y a aucun résultat pour les coordonnées dans ce tweet" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 +#: ../src\controller\mainController.py:1000 +#: ../src\controller\mainController.py:1019 msgid "Error decoding coordinates. Try again later." msgstr "Erreur pendant le décodage des coordonnées. Réessayez plus tard." -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 +#: ../src\controller\mainController.py:1004 +msgid "Unable to find address in OpenStreetMap." +msgstr "Impossible de trouver l'adresse dans OpenStreetMap" + +#: ../src\controller\mainController.py:1017 +msgid "There are no results for the coordinates in this tweet" +msgstr "Il n'y a aucun résultat pour les coordonnées dans ce tweet" + +#: ../src\controller\mainController.py:1128 +#: ../src\controller\mainController.py:1147 msgid "%s, %s of %s" msgstr "%s, %s de %s" -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 +#: ../src\controller\mainController.py:1130 +#: ../src\controller\mainController.py:1149 +#: ../src\controller\mainController.py:1174 +#: ../src\controller\mainController.py:1199 msgid "%s. Empty" msgstr "%s. Vide" -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 +#: ../src\controller\mainController.py:1162 #: ../src\controller\mainController.py:1166 +#: ../src\controller\mainController.py:1187 msgid "{0}: This account is not logged into Twitter." msgstr "{0}: Ce compte n'est pas connecté à twitter." -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 +#: ../src\controller\mainController.py:1172 +#: ../src\controller\mainController.py:1197 msgid "%s. %s, %s of %s" msgstr "%s. %s, %s de %s" -#: ../src\controller\mainController.py:1170 +#: ../src\controller\mainController.py:1191 msgid "{0}: This account is not logged into twitter." msgstr "{0}: Ce compte n'est pas connecté à twitter." -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Événements" - -#: ../src\controller\mainController.py:1393 +#: ../src\controller\mainController.py:1416 msgid "This list is already opened" msgstr "Cette liste est déjà ouverte" -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 +#: ../src\controller\mainController.py:1446 +#: ../src\controller\mainController.py:1462 msgid "" "An error happened while trying to connect to the server. Please try later." msgstr "" "Une erreur s'est produite en essayant de se connecter au serveur. Veuillez " "réessayer plus tard." -#: ../src\controller\mainController.py:1475 +#: ../src\controller\mainController.py:1498 msgid "The auto-reading of new tweets is enabled for this buffer" msgstr "La lecture automatique des nouveaux tweets est activée pour ce tampon" -#: ../src\controller\mainController.py:1478 +#: ../src\controller\mainController.py:1501 msgid "The auto-reading of new tweets is disabled for this buffer" msgstr "" "La lecture automatique des nouveaux tweets est désactivée pour ce tampon" -#: ../src\controller\mainController.py:1485 +#: ../src\controller\mainController.py:1508 msgid "Session mute on" msgstr "Session muet" -#: ../src\controller\mainController.py:1488 +#: ../src\controller\mainController.py:1511 msgid "Session mute off" msgstr "Session non muet" -#: ../src\controller\mainController.py:1496 +#: ../src\controller\mainController.py:1519 msgid "Buffer mute on" msgstr "Tampon muet" -#: ../src\controller\mainController.py:1499 +#: ../src\controller\mainController.py:1522 msgid "Buffer mute off" msgstr "Tampon non muet" -#: ../src\controller\mainController.py:1522 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "Copié" -#: ../src\controller\mainController.py:1549 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "Impossible de mettre à jour ce tampon." -#: ../src\controller\mainController.py:1552 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "Actualisation..." -#: ../src\controller\mainController.py:1555 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0} éléments récupérés" -#: ../src\controller\mainController.py:1572 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" msgstr "Tampon invalide" -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Ce tweet ne contient pas d'images" - -#: ../src\controller\mainController.py:1579 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "Photo {0}" -#: ../src\controller\mainController.py:1580 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "Sélectionner la photo" -#: ../src\controller\mainController.py:1596 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "Impossible d'extraire le texte" -#: ../src\controller\messages.py:54 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "Traduit" -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "Aucune URL à réduire" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URL réduite" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "Aucune URL à élargir" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URL élargi" - -#: ../src\controller\messages.py:104 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s/%d caractères" -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s caractères" - -#: ../src\controller\messages.py:262 +#: ../src\controller\messages.py:354 msgid "View item" msgstr "Voir l'élément" -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Connexion directe" +#: ../src\controller\messages.py:379 +msgid "Link copied to clipboard." +msgstr "Lien copié dans le Presse-papiers" -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:74 +msgid "HTTP" +msgstr "HTTP" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4" +msgstr "SOCKS v4" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4 with DNS support" +msgstr "SOCKS v4 avec support DNS" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5 with DNS support" +msgstr "SOCKS v5 avec support DNS" + +#: ../src\controller\settings.py:74 +msgid "System default" +msgstr "Système par défaut" + +#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Ask" msgstr "Demander" -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet without comments" msgstr "Retweet sans commentaires" -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet with comments" msgstr "Retweet avec commentaires" -#: ../src\controller\settings.py:184 +#: ../src\controller\settings.py:185 msgid "Account settings for %s" msgstr "Paramètres du compte de %s" -#: ../src\controller\settings.py:284 +#: ../src\controller\settings.py:288 msgid "Direct Messages" -msgstr "Messages privés" +msgstr "Messages" -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 +#: ../src\controller\user.py:29 ../src\controller\user.py:31 +#: ../src\extra\SpellChecker\wx_ui.py:80 ../src\issueReporter\wx_ui.py:84 +#: ../src\issueReporter\wx_ui.py:87 ../src\wxUI\commonMessageDialogs.py:39 +#: ../src\wxUI\commonMessageDialogs.py:51 +#: ../src\wxUI\commonMessageDialogs.py:58 +#: ../src\wxUI\commonMessageDialogs.py:61 +#: ../src\wxUI\commonMessageDialogs.py:64 +#: ../src\wxUI\commonMessageDialogs.py:67 +#: ../src\wxUI\commonMessageDialogs.py:77 +#: ../src\wxUI\commonMessageDialogs.py:80 +#: ../src\wxUI\commonMessageDialogs.py:83 +#: ../src\wxUI\commonMessageDialogs.py:89 +#: ../src\wxUI\commonMessageDialogs.py:92 msgid "Error" msgstr "Erreur" -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 +#: ../src\controller\user.py:29 ../src\wxUI\commonMessageDialogs.py:39 msgid "That user does not exist" msgstr "Cet utilisateur n'existe pas" -#: ../src\controller\user.py:30 +#: ../src\controller\user.py:31 msgid "User has been suspended" msgstr "L'utilisateur a été suspendu" -#: ../src\controller\user.py:36 +#: ../src\controller\user.py:37 msgid "Information for %s" msgstr "Détails de %s" -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 +#: ../src\controller\user.py:67 ../src\extra\AudioUploader\audioUploader.py:127 msgid "Discarded" msgstr "Ignoré" @@ -542,31 +552,31 @@ msgstr "Localisation: %s\n" msgid "URL: %s\n" msgstr "Site Web: %s\n" -#: ../src\controller\user.py:102 +#: ../src\controller\user.py:104 msgid "Bio: %s\n" msgstr "Biographie: %s\n" -#: ../src\controller\user.py:103 ../src\controller\user.py:118 +#: ../src\controller\user.py:105 ../src\controller\user.py:120 msgid "Yes" msgstr "Oui" -#: ../src\controller\user.py:104 ../src\controller\user.py:119 +#: ../src\controller\user.py:106 ../src\controller\user.py:121 msgid "No" msgstr "Non" -#: ../src\controller\user.py:105 +#: ../src\controller\user.py:107 msgid "Protected: %s\n" msgstr "Protégé: %s\n" -#: ../src\controller\user.py:110 +#: ../src\controller\user.py:112 msgid "You follow {0}. " msgstr "Vous suivez {0}. " -#: ../src\controller\user.py:113 +#: ../src\controller\user.py:115 msgid "{0} is following you." msgstr "{0} vous suit." -#: ../src\controller\user.py:117 +#: ../src\controller\user.py:119 msgid "" "Followers: %s\n" " Friends: %s\n" @@ -574,311 +584,318 @@ msgstr "" "Abonnés: %s\n" " Abonnements: %s\n" -#: ../src\controller\user.py:120 +#: ../src\controller\user.py:122 msgid "Verified: %s\n" msgstr "Vérifié : %s\n" -#: ../src\controller\user.py:121 +#: ../src\controller\user.py:123 msgid "Tweets: %s\n" msgstr "Tweets: %s\n" -#: ../src\controller\user.py:122 +#: ../src\controller\user.py:124 msgid "Likes: %s" msgstr "Favoris: %s" -#: ../src\controller\userActionsController.py:75 +#: ../src\controller\userActionsController.py:74 msgid "You can't ignore direct messages" -msgstr "Vous ne pouvez pas ignorer les messages privés" +msgstr "Vous ne pouvez pas ignorer les messages" -#: ../src\extra\AudioUploader\audioUploader.py:54 +#: ../src\controller\userAliasController.py:32 +msgid "Edit alias for {}" +msgstr "Éditer l'alias pour {}" + +#: ../src\extra\AudioUploader\audioUploader.py:57 msgid "Attaching..." msgstr "Ajout en cours..." -#: ../src\extra\AudioUploader\audioUploader.py:71 +#: ../src\extra\AudioUploader\audioUploader.py:74 msgid "Pause" msgstr "Pause" -#: ../src\extra\AudioUploader\audioUploader.py:73 +#: ../src\extra\AudioUploader\audioUploader.py:76 msgid "&Resume" msgstr "&Reprendre" -#: ../src\extra\AudioUploader\audioUploader.py:74 +#: ../src\extra\AudioUploader\audioUploader.py:77 msgid "Resume" msgstr "Reprendre" -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 +#: ../src\extra\AudioUploader\audioUploader.py:79 +#: ../src\extra\AudioUploader\audioUploader.py:106 +#: ../src\extra\AudioUploader\wx_ui.py:37 msgid "&Pause" msgstr "&Pause" -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 +#: ../src\extra\AudioUploader\audioUploader.py:94 +#: ../src\extra\AudioUploader\audioUploader.py:140 msgid "&Stop" msgstr "&Arrêter" -#: ../src\extra\AudioUploader\audioUploader.py:92 +#: ../src\extra\AudioUploader\audioUploader.py:95 msgid "Recording" msgstr "Enregistrement en cours" -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:100 +#: ../src\extra\AudioUploader\audioUploader.py:151 msgid "Stopped" msgstr "Arrêté" -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 +#: ../src\extra\AudioUploader\audioUploader.py:102 +#: ../src\extra\AudioUploader\wx_ui.py:39 msgid "&Record" msgstr "&Enregistrer" -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." msgstr "Lecture..." -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 +#: ../src\extra\AudioUploader\audioUploader.py:144 +#: ../src\extra\AudioUploader\audioUploader.py:154 +#: ../src\extra\AudioUploader\wx_ui.py:35 msgid "&Play" msgstr "&Lire" -#: ../src\extra\AudioUploader\audioUploader.py:156 +#: ../src\extra\AudioUploader\audioUploader.py:159 msgid "Recoding audio..." msgstr "Recodage audio..." -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 +#: ../src\extra\AudioUploader\transfer.py:82 +#: ../src\extra\AudioUploader\transfer.py:88 msgid "Error in file upload: {0}" msgstr "Erreur lors du chargement du fichier: {0}" -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 +#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 msgid "%d day, " msgstr "%d jour, " -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 +#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 msgid "%d days, " msgstr "%d jours, " -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 +#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 msgid "%d hour, " msgstr "%d heure, " -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 +#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 msgid "%d hours, " msgstr "%d heures, " -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 +#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 msgid "%d minute, " msgstr "%d minute, " -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 +#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 msgid "%d minutes, " msgstr "%d minutes, " -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 +#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 msgid "%s second" msgstr "%s seconde" -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 +#: ../src\extra\AudioUploader\utils.py:43 ../src\update\utils.py:43 msgid "%s seconds" msgstr "%s secondes" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "Fichier" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:21 msgid "Transferred" msgstr "Transféré" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:26 msgid "Total file size" msgstr "Taille totale du fichier" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:31 msgid "Transfer rate" msgstr "Vitesse du transfert" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:36 msgid "Time left" msgstr "Temps restant" -#: ../src\extra\AudioUploader\wx_ui.py:28 +#: ../src\extra\AudioUploader\wx_ui.py:29 msgid "Attach audio" msgstr "Joindre un audio" -#: ../src\extra\AudioUploader\wx_ui.py:40 +#: ../src\extra\AudioUploader\wx_ui.py:41 msgid "&Add an existing file" msgstr "&Ajouter un fichier existant" -#: ../src\extra\AudioUploader\wx_ui.py:41 +#: ../src\extra\AudioUploader\wx_ui.py:42 msgid "&Discard" msgstr "&Ignorer" -#: ../src\extra\AudioUploader\wx_ui.py:43 +#: ../src\extra\AudioUploader\wx_ui.py:44 msgid "Upload to" msgstr "Charger" -#: ../src\extra\AudioUploader\wx_ui.py:48 +#: ../src\extra\AudioUploader\wx_ui.py:49 msgid "Attach" msgstr "Joindre " -#: ../src\extra\AudioUploader\wx_ui.py:50 +#: ../src\extra\AudioUploader\wx_ui.py:51 msgid "&Cancel" msgstr "&Annuler" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" msgstr "Fichiers audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Select the audio file to be uploaded" msgstr "Sélectionnez le fichier audio que vous souhaitez charger" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 msgid "Audio tweet." msgstr "Tweet audio." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 msgid "User timeline buffer created." msgstr "Tampon de chronologie utilisateur créé." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 msgid "Buffer destroied." msgstr "Tampon détruit." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Message privé reçu." - #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Message privé envoyé." +msgid "Direct message received." +msgstr "Message reçu." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 +msgid "Direct message sent." +msgstr "Message envoyé." + +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 msgid "Error." msgstr "Erreur." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 msgid "Tweet liked." msgstr "Tweet aimé." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 msgid "Likes buffer updated." msgstr "Tampon des favoris mis à jour." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 msgid "Geotweet." msgstr "Tweet avec localisation géographique." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 msgid "Tweet contains one or more images" msgstr "Ce tweet contient une ou plusieurs images" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 msgid "Boundary reached." msgstr "Limite atteinte." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 msgid "List updated." msgstr "Liste mise à jour." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 msgid "Too many characters." msgstr "Trop de caractères." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 msgid "Mention received." msgstr "Mention reçue." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 msgid "New event." msgstr "Nouvel événement." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 msgid "{0} is ready." msgstr "{0} est prêt." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 msgid "Mention sent." msgstr "Mention envoyée." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 msgid "Tweet retweeted." msgstr "Tweet retweeté." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 msgid "Search buffer updated." msgstr "Tampon de recherche mis à jour." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 msgid "Tweet received." msgstr "Tweet reçu." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 msgid "Tweet sent." msgstr "Tweet envoyé." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 msgid "Trending topics buffer updated." msgstr "Tampon de tendances mis à jour." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 msgid "New tweet in user timeline buffer." msgstr "Nouveau tweet dans un tampon de chronologie utilisateur." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 msgid "New follower." msgstr "Nouvel abonné." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:31 msgid "Volume changed." msgstr "Volume changé." -#: ../src\extra\SoundsTutorial\wx_ui.py:8 +#: ../src\extra\SoundsTutorial\wx_ui.py:9 msgid "Sounds tutorial" msgstr "Apprentissage des sons" -#: ../src\extra\SoundsTutorial\wx_ui.py:11 +#: ../src\extra\SoundsTutorial\wx_ui.py:12 msgid "Press enter to listen to the sound for the selected event" msgstr "Pressez sur entrée pour entendre le son lié à l'événement sélectionné" -#: ../src\extra\SpellChecker\spellchecker.py:57 +#: ../src\extra\SpellChecker\spellchecker.py:60 msgid "Misspelled word: %s" msgstr "Mot mal orthographié: %s" -#: ../src\extra\SpellChecker\wx_ui.py:27 +#: ../src\extra\SpellChecker\wx_ui.py:28 msgid "Misspelled word" msgstr "Mot mal orthographié" -#: ../src\extra\SpellChecker\wx_ui.py:32 +#: ../src\extra\SpellChecker\wx_ui.py:33 msgid "Context" msgstr "Contexte" -#: ../src\extra\SpellChecker\wx_ui.py:37 +#: ../src\extra\SpellChecker\wx_ui.py:38 msgid "Suggestions" msgstr "Suggestions" -#: ../src\extra\SpellChecker\wx_ui.py:42 +#: ../src\extra\SpellChecker\wx_ui.py:43 msgid "&Ignore" msgstr "&Ignorer" -#: ../src\extra\SpellChecker\wx_ui.py:43 +#: ../src\extra\SpellChecker\wx_ui.py:44 msgid "I&gnore all" msgstr "I&gnorer tout" -#: ../src\extra\SpellChecker\wx_ui.py:44 +#: ../src\extra\SpellChecker\wx_ui.py:45 msgid "&Replace" msgstr "&Remplacer" -#: ../src\extra\SpellChecker\wx_ui.py:45 +#: ../src\extra\SpellChecker\wx_ui.py:46 msgid "R&eplace all" msgstr "R&emplacer tout" -#: ../src\extra\SpellChecker\wx_ui.py:46 +#: ../src\extra\SpellChecker\wx_ui.py:47 msgid "&Add to personal dictionary" msgstr "&Ajouter au dictionnaire personnel" -#: ../src\extra\SpellChecker\wx_ui.py:79 +#: ../src\extra\SpellChecker\wx_ui.py:80 msgid "" "An error has occurred. There are no dictionaries available for the selected " "language in {0}" @@ -886,25 +903,25 @@ msgstr "" "Une erreur s'est produite. Il n'existe aucun dictionnaires disponibles pour " "la langue sélectionnée dans {0}" -#: ../src\extra\SpellChecker\wx_ui.py:82 +#: ../src\extra\SpellChecker\wx_ui.py:83 msgid "Spell check complete." msgstr "Vérification orthographique terminée." -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 +#: ../src\extra\autocompletionUsers\completion.py:20 +#: ../src\extra\autocompletionUsers\completion.py:38 msgid "You have to start writing" msgstr "Vous devez commencer à écrire" -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 +#: ../src\extra\autocompletionUsers\completion.py:30 +#: ../src\extra\autocompletionUsers\completion.py:47 msgid "There are no results in your users database" msgstr "Il n'y a aucun résultat dans votre base de données des utilisateurs" -#: ../src\extra\autocompletionUsers\completion.py:33 +#: ../src\extra\autocompletionUsers\completion.py:32 msgid "Autocompletion only works for users." msgstr "La saisie automatique fonctionne uniquement pour les utilisateurs." -#: ../src\extra\autocompletionUsers\settings.py:27 +#: ../src\extra\autocompletionUsers\settings.py:25 msgid "" "Updating database... You can close this window now. A message will tell you " "when the process finishes." @@ -913,45 +930,45 @@ msgstr "" "fenêtre maintenant. Un message vous avertira lorsque le processus est " "terminé." -#: ../src\extra\autocompletionUsers\wx_manage.py:8 +#: ../src\extra\autocompletionUsers\wx_manage.py:9 msgid "Manage Autocompletion database" msgstr "Gérer la base de données pour la saisie automatique" -#: ../src\extra\autocompletionUsers\wx_manage.py:11 +#: ../src\extra\autocompletionUsers\wx_manage.py:12 msgid "Editing {0} users database" msgstr "Modification de la base de données des utilisateurs de {0}" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 msgid "Username" msgstr "Nom d'utilisateur" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 #: ../src\wxUI\dialogs\configuration.py:144 msgid "Name" msgstr "Nom" -#: ../src\extra\autocompletionUsers\wx_manage.py:15 +#: ../src\extra\autocompletionUsers\wx_manage.py:16 msgid "Add user" msgstr "Ajouter l'utilisateur" -#: ../src\extra\autocompletionUsers\wx_manage.py:16 +#: ../src\extra\autocompletionUsers\wx_manage.py:17 msgid "Remove user" msgstr "Supprimer l'utilisateur" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Add user to database" msgstr "Ajouter l'utilisateur à la base de données" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Twitter username" msgstr "Nom d'utilisateur de Twitter" -#: ../src\extra\autocompletionUsers\wx_manage.py:43 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 msgid "The user does not exist" msgstr "Cet utilisateur n'existe pas sur Twitter" -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "Error!" msgstr "Erreur !" @@ -979,449 +996,449 @@ msgstr "Terminé" msgid "{0}'s database of users has been updated." msgstr "La base de données des utilisateurs de {0} a été mis à jour." -#: ../src\extra\ocr\OCRSpace.py:5 +#: ../src\extra\ocr\OCRSpace.py:7 msgid "Detect automatically" msgstr "Détecter automatiquement" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:41 msgid "Danish" msgstr "Danois" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:43 msgid "Dutch" msgstr "Néerlandais" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:44 msgid "English" msgstr "Anglais" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:48 msgid "Finnish" msgstr "Finnois" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:49 msgid "French" msgstr "Français" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:52 msgid "German" msgstr "Allemand" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:58 msgid "Hungarian" msgstr "Hongrois" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:63 msgid "Italian" msgstr "Italien" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:64 msgid "Japanese" msgstr "Japonais" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:68 msgid "Korean" msgstr "Coréen" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:85 msgid "Polish" msgstr "Polonais" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:86 msgid "Portuguese" msgstr "Portugais" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:89 msgid "Russian" msgstr "Russe" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:96 msgid "Spanish" msgstr "Espagnol" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:105 msgid "Turkish" msgstr "Turc" -#: ../src\extra\translator\translator.py:12 +#: ../src\extra\translator\translator.py:22 msgid "Afrikaans" msgstr "Africain" -#: ../src\extra\translator\translator.py:13 +#: ../src\extra\translator\translator.py:23 msgid "Albanian" msgstr "Albanais" -#: ../src\extra\translator\translator.py:14 +#: ../src\extra\translator\translator.py:24 msgid "Amharic" msgstr "Amharique" -#: ../src\extra\translator\translator.py:15 +#: ../src\extra\translator\translator.py:25 msgid "Arabic" msgstr "Arabe" -#: ../src\extra\translator\translator.py:16 +#: ../src\extra\translator\translator.py:26 msgid "Armenian" msgstr "Arménien" -#: ../src\extra\translator\translator.py:17 +#: ../src\extra\translator\translator.py:27 msgid "Azerbaijani" msgstr "Azerbaïdjanais" -#: ../src\extra\translator\translator.py:18 +#: ../src\extra\translator\translator.py:28 msgid "Basque" msgstr "Basque" -#: ../src\extra\translator\translator.py:19 +#: ../src\extra\translator\translator.py:29 msgid "Belarusian" msgstr "Biélorusse" -#: ../src\extra\translator\translator.py:20 +#: ../src\extra\translator\translator.py:30 msgid "Bengali" msgstr "Bengali" -#: ../src\extra\translator\translator.py:21 +#: ../src\extra\translator\translator.py:31 msgid "Bihari" msgstr "Bihari" -#: ../src\extra\translator\translator.py:22 +#: ../src\extra\translator\translator.py:32 msgid "Bulgarian" msgstr "Bulgare" -#: ../src\extra\translator\translator.py:23 +#: ../src\extra\translator\translator.py:33 msgid "Burmese" msgstr "Birman" -#: ../src\extra\translator\translator.py:24 +#: ../src\extra\translator\translator.py:34 msgid "Catalan" msgstr "Catalan" -#: ../src\extra\translator\translator.py:25 +#: ../src\extra\translator\translator.py:35 msgid "Cherokee" msgstr "Cherokee" -#: ../src\extra\translator\translator.py:26 +#: ../src\extra\translator\translator.py:36 msgid "Chinese" msgstr "Chinois" -#: ../src\extra\translator\translator.py:27 +#: ../src\extra\translator\translator.py:37 msgid "Chinese_simplified" msgstr "Chinois simplifié" -#: ../src\extra\translator\translator.py:28 +#: ../src\extra\translator\translator.py:38 msgid "Chinese_traditional" msgstr "Chinois traditionnel" -#: ../src\extra\translator\translator.py:29 +#: ../src\extra\translator\translator.py:39 msgid "Croatian" msgstr "Croate" -#: ../src\extra\translator\translator.py:30 +#: ../src\extra\translator\translator.py:40 msgid "Czech" msgstr "Tchèque" -#: ../src\extra\translator\translator.py:32 +#: ../src\extra\translator\translator.py:42 msgid "Dhivehi" msgstr "Dhivehi" -#: ../src\extra\translator\translator.py:35 +#: ../src\extra\translator\translator.py:45 msgid "Esperanto" msgstr "Esperanto" -#: ../src\extra\translator\translator.py:36 +#: ../src\extra\translator\translator.py:46 msgid "Estonian" msgstr "Estonien" -#: ../src\extra\translator\translator.py:37 +#: ../src\extra\translator\translator.py:47 msgid "Filipino" msgstr "Filipino" -#: ../src\extra\translator\translator.py:40 +#: ../src\extra\translator\translator.py:50 msgid "Galician" msgstr "Galicien" -#: ../src\extra\translator\translator.py:41 +#: ../src\extra\translator\translator.py:51 msgid "Georgian" msgstr "Géorgien" -#: ../src\extra\translator\translator.py:43 +#: ../src\extra\translator\translator.py:53 msgid "Greek" msgstr "Grec" -#: ../src\extra\translator\translator.py:44 +#: ../src\extra\translator\translator.py:54 msgid "Guarani" msgstr "Guarani" -#: ../src\extra\translator\translator.py:45 +#: ../src\extra\translator\translator.py:55 msgid "Gujarati" msgstr "Gujarâtî" -#: ../src\extra\translator\translator.py:46 +#: ../src\extra\translator\translator.py:56 msgid "Hebrew" msgstr "Hébreu" -#: ../src\extra\translator\translator.py:47 +#: ../src\extra\translator\translator.py:57 msgid "Hindi" msgstr "Hindi" -#: ../src\extra\translator\translator.py:49 +#: ../src\extra\translator\translator.py:59 msgid "Icelandic" msgstr "Islandais" -#: ../src\extra\translator\translator.py:50 +#: ../src\extra\translator\translator.py:60 msgid "Indonesian" msgstr "Indonésien" -#: ../src\extra\translator\translator.py:51 +#: ../src\extra\translator\translator.py:61 msgid "Inuktitut" msgstr "Inuktitut" -#: ../src\extra\translator\translator.py:52 +#: ../src\extra\translator\translator.py:62 msgid "Irish" msgstr "Irlandais" -#: ../src\extra\translator\translator.py:55 +#: ../src\extra\translator\translator.py:65 msgid "Kannada" msgstr "Canara" -#: ../src\extra\translator\translator.py:56 +#: ../src\extra\translator\translator.py:66 msgid "Kazakh" msgstr "Kazakh" -#: ../src\extra\translator\translator.py:57 +#: ../src\extra\translator\translator.py:67 msgid "Khmer" msgstr "Cambodgien" -#: ../src\extra\translator\translator.py:59 +#: ../src\extra\translator\translator.py:69 msgid "Kurdish" msgstr "Kurde" -#: ../src\extra\translator\translator.py:60 +#: ../src\extra\translator\translator.py:70 msgid "Kyrgyz" msgstr "Kirghiz" -#: ../src\extra\translator\translator.py:61 +#: ../src\extra\translator\translator.py:71 msgid "Laothian" msgstr "Laotien" -#: ../src\extra\translator\translator.py:62 +#: ../src\extra\translator\translator.py:72 msgid "Latvian" msgstr "Letton" -#: ../src\extra\translator\translator.py:63 +#: ../src\extra\translator\translator.py:73 msgid "Lithuanian" msgstr "Lituanien" -#: ../src\extra\translator\translator.py:64 +#: ../src\extra\translator\translator.py:74 msgid "Macedonian" msgstr "Macédonien" -#: ../src\extra\translator\translator.py:65 +#: ../src\extra\translator\translator.py:75 msgid "Malay" msgstr "Malaisien" -#: ../src\extra\translator\translator.py:66 +#: ../src\extra\translator\translator.py:76 msgid "Malayalam" msgstr "Malayalam" -#: ../src\extra\translator\translator.py:67 +#: ../src\extra\translator\translator.py:77 msgid "Maltese" msgstr "Maltais" -#: ../src\extra\translator\translator.py:68 +#: ../src\extra\translator\translator.py:78 msgid "Marathi" msgstr "Marathi" -#: ../src\extra\translator\translator.py:69 +#: ../src\extra\translator\translator.py:79 msgid "Mongolian" msgstr "Mongol" -#: ../src\extra\translator\translator.py:70 +#: ../src\extra\translator\translator.py:80 msgid "Nepali" msgstr "Népali" -#: ../src\extra\translator\translator.py:71 +#: ../src\extra\translator\translator.py:81 msgid "Norwegian" msgstr "Norvégien" -#: ../src\extra\translator\translator.py:72 +#: ../src\extra\translator\translator.py:82 msgid "Oriya" msgstr "Oriya" -#: ../src\extra\translator\translator.py:73 +#: ../src\extra\translator\translator.py:83 msgid "Pashto" msgstr "Pashto" -#: ../src\extra\translator\translator.py:74 +#: ../src\extra\translator\translator.py:84 msgid "Persian" msgstr "Perse" -#: ../src\extra\translator\translator.py:77 +#: ../src\extra\translator\translator.py:87 msgid "Punjabi" msgstr "Punjabi" -#: ../src\extra\translator\translator.py:78 +#: ../src\extra\translator\translator.py:88 msgid "Romanian" msgstr "Roumain" -#: ../src\extra\translator\translator.py:80 +#: ../src\extra\translator\translator.py:90 msgid "Sanskrit" msgstr "Sanscrit" -#: ../src\extra\translator\translator.py:81 +#: ../src\extra\translator\translator.py:91 msgid "Serbian" msgstr "Serbe" -#: ../src\extra\translator\translator.py:82 +#: ../src\extra\translator\translator.py:92 msgid "Sindhi" msgstr "Sindhi" -#: ../src\extra\translator\translator.py:83 +#: ../src\extra\translator\translator.py:93 msgid "Sinhalese" msgstr "Cinghalais" -#: ../src\extra\translator\translator.py:84 +#: ../src\extra\translator\translator.py:94 msgid "Slovak" msgstr "Slovaque" -#: ../src\extra\translator\translator.py:85 +#: ../src\extra\translator\translator.py:95 msgid "Slovenian" msgstr "Slovène" -#: ../src\extra\translator\translator.py:87 +#: ../src\extra\translator\translator.py:97 msgid "Swahili" msgstr "Swahili" -#: ../src\extra\translator\translator.py:88 +#: ../src\extra\translator\translator.py:98 msgid "Swedish" msgstr "Suédois" -#: ../src\extra\translator\translator.py:89 +#: ../src\extra\translator\translator.py:99 msgid "Tajik" msgstr "Tadjik" -#: ../src\extra\translator\translator.py:90 +#: ../src\extra\translator\translator.py:100 msgid "Tamil" msgstr "Tamil" -#: ../src\extra\translator\translator.py:91 +#: ../src\extra\translator\translator.py:101 msgid "Tagalog" msgstr "Tagalog" -#: ../src\extra\translator\translator.py:92 +#: ../src\extra\translator\translator.py:102 msgid "Telugu" msgstr "Telugu" -#: ../src\extra\translator\translator.py:93 +#: ../src\extra\translator\translator.py:103 msgid "Thai" msgstr "Thaï" -#: ../src\extra\translator\translator.py:94 +#: ../src\extra\translator\translator.py:104 msgid "Tibetan" msgstr "Tibétain" -#: ../src\extra\translator\translator.py:96 +#: ../src\extra\translator\translator.py:106 msgid "Ukrainian" msgstr "Ukrainien" -#: ../src\extra\translator\translator.py:97 +#: ../src\extra\translator\translator.py:107 msgid "Urdu" msgstr "Urdu" -#: ../src\extra\translator\translator.py:98 +#: ../src\extra\translator\translator.py:108 msgid "Uzbek" msgstr "Ouzbek" -#: ../src\extra\translator\translator.py:99 +#: ../src\extra\translator\translator.py:109 msgid "Uighur" msgstr "Uighur" -#: ../src\extra\translator\translator.py:100 +#: ../src\extra\translator\translator.py:110 msgid "Vietnamese" msgstr "Vietnamien" -#: ../src\extra\translator\translator.py:101 +#: ../src\extra\translator\translator.py:111 msgid "Welsh" msgstr "Gallois" -#: ../src\extra\translator\translator.py:102 +#: ../src\extra\translator\translator.py:112 msgid "Yiddish" msgstr "Yiddish" -#: ../src\extra\translator\wx_ui.py:44 +#: ../src\extra\translator\wx_ui.py:29 msgid "Translate message" msgstr "Traduire le message" -#: ../src\extra\translator\wx_ui.py:47 +#: ../src\extra\translator\wx_ui.py:32 msgid "Target language" msgstr "Langue cible" -#: ../src\issueReporter\issueReporter.py:30 +#: ../src\issueReporter\issueReporter.py:32 #: ../src\wxUI\dialogs\configuration.py:359 #: ../src\wxUI\dialogs\configuration.py:368 msgid "General" msgstr "Général" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "always" msgstr "Toujours" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "have not tried" msgstr "Vous n'avez pas essayé" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "random" msgstr "Aléatoire" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "sometimes" msgstr "Parfois" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "unable to duplicate" msgstr "Impossible de reproduire" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "block" msgstr "Bloquer" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "crash" msgstr "Problème" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "feature" msgstr "Fonctionnalité" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "major" msgstr "Majeur" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "minor" msgstr "Mineur" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "text" msgstr "Texte" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "trivial" msgstr "Trivial" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "tweak" msgstr "Réglage" -#: ../src\issueReporter\wx_ui.py:25 +#: ../src\issueReporter\wx_ui.py:26 msgid "Report an error" msgstr "Signaler une erreur" -#: ../src\issueReporter\wx_ui.py:28 +#: ../src\issueReporter\wx_ui.py:29 msgid "Select a category" msgstr "Sélectionnez une catégorie" -#: ../src\issueReporter\wx_ui.py:36 +#: ../src\issueReporter\wx_ui.py:37 msgid "" "Briefly describe what happened. You will be able to thoroughly explain it " "later" @@ -1429,19 +1446,19 @@ msgstr "" "Décrivez brièvement ce qui s'est passé. Vous serez en mesure d'expliquer en " "profondeur par la suite." -#: ../src\issueReporter\wx_ui.py:45 +#: ../src\issueReporter\wx_ui.py:46 msgid "Here, you can describe the bug in detail" msgstr "Ici, vous pouvez décrire le problème en détail" -#: ../src\issueReporter\wx_ui.py:55 +#: ../src\issueReporter\wx_ui.py:56 msgid "how often does this bug happen?" msgstr "Combien de fois s'est produit ce problème ?" -#: ../src\issueReporter\wx_ui.py:62 +#: ../src\issueReporter\wx_ui.py:63 msgid "Select the importance that you think this bug has" msgstr "Sélectionnez l'importance que vous pensez que ce problème a" -#: ../src\issueReporter\wx_ui.py:69 +#: ../src\issueReporter\wx_ui.py:70 msgid "" "I know that the {0} bug system will get my Twitter username to contact me " "and fix the bug quickly" @@ -1449,20 +1466,20 @@ msgstr "" "Je sais que le système d'erreurs de {0} obtiendra mon nom d'utilisateur de " "Twitter afin de me contacter et corriger l'erreur rapidement" -#: ../src\issueReporter\wx_ui.py:72 +#: ../src\issueReporter\wx_ui.py:73 msgid "Send report" msgstr "Envoyer le rapport" -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 +#: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "Annuler" -#: ../src\issueReporter\wx_ui.py:83 +#: ../src\issueReporter\wx_ui.py:84 msgid "You must fill out both fields" msgstr "Vous devez remplir les deux champs" -#: ../src\issueReporter\wx_ui.py:86 +#: ../src\issueReporter\wx_ui.py:87 msgid "" "You need to mark the checkbox to provide us your twitter username to contact " "you if it is necessary." @@ -1470,7 +1487,7 @@ msgstr "" "Vous devez cocher la case à cocher afin de nous fournir votre nom " "d'utilisateur de Twitter pour communiquer avec vous si c'est nécessaire." -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "" "Thanks for reporting this bug! In future versions, you may be able to find " "it in the changes list. You've reported the bug number %i" @@ -1479,15 +1496,15 @@ msgstr "" "pourrez le trouver dans la liste des changements. Vous avez signalé le " "numéro d'erreur %i" -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "reported" msgstr "signalé" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "Error while reporting" msgstr "Erreur lors du signalement du rapport" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "" "Something unexpected occurred while trying to report the bug. Please, try " "again later" @@ -1527,14 +1544,14 @@ msgstr "Afficher ou masquer l'interface graphique" msgid "New tweet" msgstr "Nouveau tweet" -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 +#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "Retweet" #: ../src\keystrokeEditor\constants.py:13 msgid "Send direct message" -msgstr "Envoyer un message privé" +msgstr "Envoyer un message" #: ../src\keystrokeEditor\constants.py:14 msgid "Like a tweet" @@ -1614,7 +1631,7 @@ msgstr "Modifier le profil" #: ../src\keystrokeEditor\constants.py:33 msgid "Delete a tweet or direct message" -msgstr "Supprimer un tweet ou un message privé" +msgstr "Supprimer un tweet ou un message" #: ../src\keystrokeEditor\constants.py:34 msgid "Empty the current buffer" @@ -1725,6 +1742,10 @@ msgstr "" "Extraire le texte d'une photo et afficher le résultat dans une boîte de " "dialogue." +#: ../src\keystrokeEditor\constants.py:59 +msgid "Adds an alias to an user" +msgstr "Ajouter un alias à un utilisateur" + #: ../src\keystrokeEditor\wx_ui.py:8 msgid "Keystroke editor" msgstr "Modificateur de raccourci" @@ -1737,63 +1758,76 @@ msgstr "Sélectionnez un raccourci à modifier" msgid "Keystroke" msgstr "Raccourci" -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 +#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:10 +#: ../src\wxUI\dialogs\userActions.py:19 ../src\wxUI\dialogs\userActions.py:20 msgid "Action" msgstr "Action" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 +#: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "Modifier" -#: ../src\keystrokeEditor\wx_ui.py:20 +#: ../src\keystrokeEditor\wx_ui.py:20 ../src\keystrokeEditor\wx_ui.py:50 +msgid "Undefine keystroke" +msgstr "Indéfinir le raccourcis clavier" + +#: ../src\keystrokeEditor\wx_ui.py:21 msgid "Execute action" msgstr "Exécuter une action" -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 +#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 +#: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 msgid "Close" msgstr "Fermer" -#: ../src\keystrokeEditor\wx_ui.py:48 +#: ../src\keystrokeEditor\wx_ui.py:42 +msgid "Undefined" +msgstr "Non défini" + +#: ../src\keystrokeEditor\wx_ui.py:50 +msgid "Are you sure you want to undefine this keystroke?" +msgstr "Êtes-vous sûr de vouloir indéfinir ce raccourcis ?" + +#: ../src\keystrokeEditor\wx_ui.py:54 msgid "Editing keystroke" msgstr "Modification en cours d'un raccourci" -#: ../src\keystrokeEditor\wx_ui.py:51 +#: ../src\keystrokeEditor\wx_ui.py:57 msgid "Control" msgstr "Contrôle" -#: ../src\keystrokeEditor\wx_ui.py:52 +#: ../src\keystrokeEditor\wx_ui.py:58 msgid "Alt" msgstr "Alt" -#: ../src\keystrokeEditor\wx_ui.py:53 +#: ../src\keystrokeEditor\wx_ui.py:59 msgid "Shift" msgstr "Maj" -#: ../src\keystrokeEditor\wx_ui.py:54 +#: ../src\keystrokeEditor\wx_ui.py:60 msgid "Windows" msgstr "Windows" -#: ../src\keystrokeEditor\wx_ui.py:60 +#: ../src\keystrokeEditor\wx_ui.py:66 msgid "Key" msgstr "Touche" -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 +#: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 +#: ../src\wxUI\dialogs\utils.py:36 msgid "OK" msgstr "OK" -#: ../src\keystrokeEditor\wx_ui.py:78 +#: ../src\keystrokeEditor\wx_ui.py:84 msgid "You need to use the Windows key" msgstr "Vous devez utiliser la touche Windows" -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:84 ../src\keystrokeEditor\wx_ui.py:87 msgid "Invalid keystroke" msgstr "Raccourci invalide" -#: ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:87 msgid "You must provide a character for the keystroke" msgstr "Vous devez fournir une lettre pour le raccourci" @@ -1801,11 +1835,11 @@ msgstr "Vous devez fournir une lettre pour le raccourci" msgid "User default" msgstr "Utilisateur par défaut" -#: ../src\main.py:105 +#: ../src\main.py:120 msgid "https://twblue.es/donate" msgstr "https://twblue.es/donate" -#: ../src\main.py:122 +#: ../src\main.py:137 msgid "" "{0} is already running. Close the other instance before starting this one. " "If you're sure that {0} isn't running, try deleting the file at {1}. If " @@ -1816,43 +1850,43 @@ msgstr "" "de supprimer le fichier {1}. Si vous ne savez pas comment faire cela, " "contactez les développeurs de {0}." -#: ../src\sessionmanager\wxUI.py:8 +#: ../src\sessionmanager\wxUI.py:9 msgid "Session manager" msgstr "Gestion des comptes" -#: ../src\sessionmanager\wxUI.py:11 +#: ../src\sessionmanager\wxUI.py:12 msgid "Accounts list" msgstr "Liste des comptes" -#: ../src\sessionmanager\wxUI.py:13 +#: ../src\sessionmanager\wxUI.py:14 msgid "Account" msgstr "Compte" -#: ../src\sessionmanager\wxUI.py:17 +#: ../src\sessionmanager\wxUI.py:18 msgid "New account" msgstr "Nouveau compte" -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:19 ../src\sessionmanager\wxUI.py:65 msgid "Remove account" msgstr "Supprimer le compte" -#: ../src\sessionmanager\wxUI.py:19 +#: ../src\sessionmanager\wxUI.py:20 msgid "Global Settings" msgstr "Paramètres Globaux" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "Account Error" msgstr "Erreur dans le Compte" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "You need to configure an account." msgstr "Vous devez configurer un compte." -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "Authorization" msgstr "Autorisation" -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "" "The request to authorize your Twitter account will be opened in your " "browser. You only need to do this once. Would you like to continue?" @@ -1861,15 +1895,15 @@ msgstr "" "navigateur. Vous devrez seulement réaliser ceci une fois. Souhaitez-vous " "continuer ?" -#: ../src\sessionmanager\wxUI.py:52 +#: ../src\sessionmanager\wxUI.py:53 msgid "Authorized account %d" msgstr "Compte autorisé %d" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "Invalid user token" msgstr "Code d'accès invalide" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "" "Your access token is invalid or the authorization has failed. Please try " "again." @@ -1877,30 +1911,66 @@ msgstr "" "Votre code d'accès est incorrect ou l'autorisation a échoué. S'il vous plaît " "essayer de nouveau." -#: ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:65 msgid "Do you really want to delete this account?" msgstr "Voulez-vous vraiment supprimer ce compte ?" -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 +#: ../src\sessionmanager\wxUI.py:81 +msgid "Authentication error for session {}" +msgstr "Erreur d'authentification pour la session {}" + +#: ../src\sessionmanager\wxUI.py:81 +msgid "" +"TWBlue is unable to authenticate the account for {} in Twitter. It might be " +"due to an invalid or expired token, revoqued access to the application, or " +"after an account reactivation. Please remove the account manually from your " +"Twitter sessions in order to stop seeing this message." +msgstr "" +"TWBlue ne parvient pas à authentifier le compte pour {} sur Twitter. Cela " +"peut être dû à un jeton d'accès incorrect, un accès d'application révoqué, " +"ou après la réactivation d'un compte. Veuillez supprimer manuellement ce " +"compte depuis votre session Twitter pour ne plus voir ce message." + +#: ../src\sessions\base.py:113 +msgid "" +"An exception occurred while saving the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Une erreur est survenue lors de l'enregistrement de la base de données de " +"{app}, elle va être détruite et recréée automatiquement. Si ce problème " +"perciste, veuillez envoyer le journal d'erreur aux développeurs de {app}." + +#: ../src\sessions\base.py:153 +msgid "" +"An exception occurred while loading the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Une erreur est survenue lors du chargement de la base de données de {app}, " +"elle va être détruite et recréée automatiquement. Si ce problème perciste, " +"veuillez envoyer le journal d'erreur aux développeurs de {app}." + +#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 +#: ../src\sessions\twitter\compose.py:146 +#: ../src\sessions\twitter\compose.py:155 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd D MMMM YYYY à H:m:s" -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 +#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 msgid "Dm to %s " msgstr "Mp à %s" -#: ../src\sessions\twitter\compose.py:141 +#: ../src\sessions\twitter\compose.py:130 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0}. Tweet de @{1} cité : {2}" -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 +#: ../src\sessions\twitter\compose.py:157 +#: ../src\sessions\twitter\compose.py:159 msgid "Unavailable" msgstr "Indisponible" -#: ../src\sessions\twitter\compose.py:166 +#: ../src\sessions\twitter\compose.py:160 msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1908,59 +1978,66 @@ msgstr "" "%s (@%s). %s abonnés, %s abonnements, %s tweets. Dernier tweet envoyé %s. À " "rejoint Twitter %s" -#: ../src\sessions\twitter\compose.py:170 +#: ../src\sessions\twitter\compose.py:164 msgid "No description available" msgstr "Aucune description disponible" -#: ../src\sessions\twitter\compose.py:174 +#: ../src\sessions\twitter\compose.py:168 msgid "private" msgstr "privé" -#: ../src\sessions\twitter\compose.py:175 +#: ../src\sessions\twitter\compose.py:169 msgid "public" msgstr "public" -#: ../src\sessions\twitter\session.py:169 -msgid "There are no more items to retrieve in this buffer." -msgstr "Il n'y a aucun nouvel élément a récupéré dans ce tampon" - -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" msgstr "%s erreur. Raison: %s" -#: ../src\sessions\twitter\session.py:221 +#: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%s réussi." -#: ../src\sessions\twitter\utils.py:225 +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 +msgid "Deleted account" +msgstr "Compte supprimé" + +#: ../src\sessions\twitter\utils.py:231 msgid "Sorry, you are not authorised to see this status." msgstr "Désolé, vous n'êtes pas autorisé à voir ce Tweet." -#: ../src\sessions\twitter\utils.py:227 +#: ../src\sessions\twitter\utils.py:233 msgid "No status found with that ID" msgstr "Aucun Tweet trouvée avec cet ID" -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "Code d'erreur {0}" +#: ../src\sessions\twitter\utils.py:235 +msgid "Error {0}" +msgstr "Erreur {0}" -#: ../src\sessions\twitter\wxUI.py:6 +#: ../src\sessions\twitter\utils.py:262 +msgid "{user_1}, {user_2} and {all_users} more: {text}" +msgstr "{user_1}, {user_2} et {all_users} de plus : {text}" + +#: ../src\sessions\twitter\wxUI.py:7 msgid "Authorising account..." msgstr "Compte en cours d'autorisation..." -#: ../src\sessions\twitter\wxUI.py:9 +#: ../src\sessions\twitter\wxUI.py:10 msgid "Enter your PIN code here" msgstr "Entrer votre code PIN ici" -#: ../src\sound.py:159 +#: ../src\sound.py:160 msgid "Stopped." msgstr "Arrêté." -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "New version for %s" msgstr "Nouvelle version de %s" -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "" "There's a new %s version available, released on %s. Would you like to " "download it now?\n" @@ -1978,23 +2055,23 @@ msgstr "" "Modifications:\n" "%s" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Download in Progress" msgstr "Téléchargement en cours" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Downloading the new version..." msgstr "Téléchargement de la nouvelle version en cours..." -#: ../src\update\wxUpdater.py:28 +#: ../src\update\wxUpdater.py:32 msgid "Updating... %s of %s" -msgstr "Mise à jour en cours... %s de %s" +msgstr "Mise à jour en cours... %s sur %s" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "Done!" msgstr "Terminé !" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "" "The update has been downloaded and installed successfully. Press OK to " "continue." @@ -2002,61 +2079,63 @@ msgstr "" "La mise à jour a été téléchargé et installé avec succès. Appuyez sur OK pour " "continuer." -#: ../src\wxUI\buffers\base.py:11 +#: ../src\wxUI\buffers\base.py:12 msgid "Client" msgstr "Client" -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Texte" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "Date" -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\people.py:12 +#: ../src\wxUI\buffers\user_searches.py:11 +#: ../src\wxUI\dialogs\userAliasDialogs.py:14 +#: ../src\wxUI\dialogs\userSelection.py:11 ../src\wxUI\dialogs\utils.py:32 msgid "User" msgstr "Utilisateur" -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Message privé" +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "Texte" -#: ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\base.py:28 +msgid "Direct message" +msgstr "Message" + +#: ../src\wxUI\buffers\events.py:14 msgid "Event" msgstr "Événement" -#: ../src\wxUI\buffers\events.py:15 +#: ../src\wxUI\buffers\events.py:16 msgid "Remove event" msgstr "Supprimer l'événement" -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 +#: ../src\wxUI\buffers\panels.py:12 ../src\wxUI\buffers\panels.py:20 msgid "Login" msgstr "Connexion" -#: ../src\wxUI\buffers\panels.py:13 +#: ../src\wxUI\buffers\panels.py:14 msgid "Log in automatically" msgstr "Connexion automatique" -#: ../src\wxUI\buffers\panels.py:21 +#: ../src\wxUI\buffers\panels.py:22 msgid "Logout" msgstr "Déconnexion" -#: ../src\wxUI\buffers\trends.py:8 +#: ../src\wxUI\buffers\trends.py:9 msgid "Trending topic" msgstr "Tendance" -#: ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\buffers\trends.py:19 msgid "Tweet about this trend" msgstr "Tweet sur cette tendance" -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 +#: ../src\wxUI\buffers\trends.py:20 ../src\wxUI\menus.py:97 msgid "Search topic" msgstr "Recherche tendance" -#: ../src\wxUI\commonMessageDialogs.py:6 +#: ../src\wxUI\commonMessageDialogs.py:7 msgid "" "This retweet is over 140 characters. Would you like to post it as a mention " "to the poster with your comments and a link to the original tweet?" @@ -2065,11 +2144,11 @@ msgstr "" "commentaires avec en mentionnant l'utilisateur qui a publié le tweet " "original et un lien vers celui-ci ?" -#: ../src\wxUI\commonMessageDialogs.py:9 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Would you like to add a comment to this tweet?" msgstr "Souhaitez-vous ajouter un commentaire à ce tweet ?" -#: ../src\wxUI\commonMessageDialogs.py:12 +#: ../src\wxUI\commonMessageDialogs.py:13 msgid "" "Do you really want to delete this tweet? It will be deleted from Twitter as " "well." @@ -2077,27 +2156,27 @@ msgstr "" "Voulez-vous vraiment supprimer ce tweet ? Il sera également supprimé de " "Twitter." -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\commonMessageDialogs.py:13 ../src\wxUI\dialogs\lists.py:149 msgid "Delete" msgstr "Supprimer Tweet" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Do you really want to close {0}?" msgstr "Voulez-vous vraiment quitter {0} ?" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Exit" msgstr "Quitter" -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid " {0} must be restarted for these changes to take effect." msgstr " {0} doit être redémarré pour que ces modifications prennent effet." -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid "Restart {0} " msgstr "Redémarrez {0} " -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "" "Are you sure you want to delete this user from the database? This user will " "not appear in autocomplete results anymore." @@ -2106,20 +2185,20 @@ msgstr "" "Cet utilisateur n'apparaîtra plus dans les résultats lors de La saisie " "automatique." -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "Confirm" msgstr "Confirmer" -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 msgid "Enter the name of the client : " msgstr "Entrez le nom du client: " -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 #: ../src\wxUI\dialogs\configuration.py:246 msgid "Add client" msgstr "Ajouter un client" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "" "Do you really want to empty this buffer? It's items will be removed from " "the list but not from Twitter" @@ -2127,36 +2206,36 @@ msgstr "" "Voulez-vous vraiment vider ce tampon ? Ces éléments seront supprimés de la " "liste, mais pas de Twitter" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "Empty buffer" msgstr "Tampon Vide" -#: ../src\wxUI\commonMessageDialogs.py:35 +#: ../src\wxUI\commonMessageDialogs.py:36 msgid "Do you really want to destroy this buffer?" msgstr "Voulez-vous vraiment détruire ce tampon ?" -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 +#: ../src\wxUI\commonMessageDialogs.py:36 +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Attention" msgstr "Attention" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "A timeline for this user already exists. You can't open another" msgstr "" "Une chronologie pour cet utilisateur existe déjà. Vous ne pouvez pas ouvrir " "une autre" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "Existing timeline" msgstr "Chronologie existante" -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "This user has no tweets, so you can't open a timeline for them." msgstr "" "Cet utilisateur n'a aucun tweets, donc vous ne pouvez pas ouvrir une " "chronologie pour lui." -#: ../src\wxUI\commonMessageDialogs.py:47 +#: ../src\wxUI\commonMessageDialogs.py:48 msgid "" "This is a protected Twitter user, which means you can't open a timeline " "using the Streaming API. The user's tweets will not update due to a twitter " @@ -2167,12 +2246,12 @@ msgstr "" "tweets ne mettra pas à jour en raison d'une politique de twitter. Voulez-" "vous continuer ?" -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:48 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "Warning" msgstr "Attention" -#: ../src\wxUI\commonMessageDialogs.py:50 +#: ../src\wxUI\commonMessageDialogs.py:51 msgid "" "This is a protected user account, you need to follow this user to view their " "tweets or likes." @@ -2180,7 +2259,7 @@ msgstr "" "Ce compte utilisateur est protégé, vous devez suivre cet utilisateur pour " "afficher ces tweets ou favoris." -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "" "If you like {0} we need your help to keep it going. Help us by donating to " "the project. This will help us pay for the server, the domain and some other " @@ -2195,44 +2274,44 @@ msgstr "" "poursuivre le développement de {0}, et de garder {0} gratuit. Vous souhaitez " "faire un don maintenant ?" -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "We need your help" msgstr "Nous avons besoin de votre aide" -#: ../src\wxUI\commonMessageDialogs.py:57 +#: ../src\wxUI\commonMessageDialogs.py:58 msgid "This user has no tweets. {0} can't create a timeline." msgstr "" "Cet utilisateur n'a aucun tweets. {0} ne peut pas créer une chronologie." -#: ../src\wxUI\commonMessageDialogs.py:60 +#: ../src\wxUI\commonMessageDialogs.py:61 msgid "This user has no favorited tweets. {0} can't create a timeline." msgstr "" "Cet utilisateur n'a aucun tweets marqué comme favori. {0} ne peut pas créer " "une chronologie." -#: ../src\wxUI\commonMessageDialogs.py:63 +#: ../src\wxUI\commonMessageDialogs.py:64 msgid "This user has no followers. {0} can't create a timeline." msgstr "" "Cet utilisateur n'a aucun abonnés. {0} ne peut pas créer une chronologie." -#: ../src\wxUI\commonMessageDialogs.py:66 +#: ../src\wxUI\commonMessageDialogs.py:67 msgid "This user has no friends. {0} can't create a timeline." msgstr "" "Cet utilisateur n'a aucun abonnements. {0} ne peut pas créer une chronologie." -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geo data for this tweet" msgstr "Données de localisation géographique pour ce tweet" -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geolocation data: {0}" msgstr "Données de localisation géographique: {0}" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "Information" msgstr "Information" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "" "TWBlue has detected that you're running windows 10 and has changed the " "default keymap to the Windows 10 keymap. It means that some keyboard " @@ -2245,11 +2324,11 @@ msgstr "" "vérifier le Modificateur de raccourci en appuyant sur Alt+Win+K pour voir " "tous les raccourcis disponibles pour cette configuration clavier." -#: ../src\wxUI\commonMessageDialogs.py:76 +#: ../src\wxUI\commonMessageDialogs.py:77 msgid "You have been blocked from viewing this content" msgstr "Vous avez été bloqué de voir ce contenu" -#: ../src\wxUI\commonMessageDialogs.py:79 +#: ../src\wxUI\commonMessageDialogs.py:80 msgid "" "You have been blocked from viewing someone's content. In order to avoid " "conflicts with the full session, TWBlue will remove the affected timeline." @@ -2257,7 +2336,7 @@ msgstr "" "Vous avez été bloqué de voir le contenu de quelqu'un. Afin d'éviter les " "conflits avec la session complète, TWBlue supprime la chronologie affecté." -#: ../src\wxUI\commonMessageDialogs.py:82 +#: ../src\wxUI\commonMessageDialogs.py:83 msgid "" "TWBlue cannot load this timeline because the user has been suspended from " "Twitter." @@ -2265,15 +2344,15 @@ msgstr "" "TWBlue ne peut pas charger cette chronologie car l'utilisateur a été " "suspendu de Twitter." -#: ../src\wxUI\commonMessageDialogs.py:85 +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Do you really want to delete this filter?" msgstr "Voulez-vous vraiment supprimer ce filtre ?" -#: ../src\wxUI\commonMessageDialogs.py:88 +#: ../src\wxUI\commonMessageDialogs.py:89 msgid "This filter already exists. Please use a different title" msgstr "Ce filtre existe déjà. Veuillez utiliser un titre différent" -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." @@ -2281,149 +2360,100 @@ msgstr "" "{0} a été quitté inopinément lors de sa dernière exécution. Si ce problème " "perciste, veuillez le signaler aux développeurs de {0}." -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Ajouter un fichier" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Fichiers joints" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Titre" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Type" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Joindre des fichiers" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Image" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Supprimer le fichier joint" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Fichiers image (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Sélectionnez la photo à charger" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Veuillez fournir une description" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Description" - -#: ../src\wxUI\dialogs\configuration.py:16 +#: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "Langue" -#: ../src\wxUI\dialogs\configuration.py:23 +#: ../src\wxUI\dialogs\configuration.py:22 msgid "Run {0} at Windows startup" msgstr "Démarrer {0} en même temps que Windows" -#: ../src\wxUI\dialogs\configuration.py:24 +#: ../src\wxUI\dialogs\configuration.py:23 msgid "ask before exiting {0}" msgstr "Demander avant de quitter {0}" -#: ../src\wxUI\dialogs\configuration.py:27 +#: ../src\wxUI\dialogs\configuration.py:26 msgid "Disable Streaming functions" msgstr "Désactiver les fonctions de streaming" -#: ../src\wxUI\dialogs\configuration.py:30 +#: ../src\wxUI\dialogs\configuration.py:29 msgid "Buffer update interval, in minutes" msgstr "Intervalle de mise à jour des tampons, en minutes" -#: ../src\wxUI\dialogs\configuration.py:36 +#: ../src\wxUI\dialogs\configuration.py:35 msgid "Play a sound when {0} launches" msgstr "Jouer un son lorsque {0} démarre" -#: ../src\wxUI\dialogs\configuration.py:38 +#: ../src\wxUI\dialogs\configuration.py:37 msgid "Speak a message when {0} launches" msgstr "Dire un message lorsque {0} démarre" -#: ../src\wxUI\dialogs\configuration.py:40 +#: ../src\wxUI\dialogs\configuration.py:39 msgid "Use invisible interface's keyboard shortcuts while GUI is visible" msgstr "" "Utilisez les raccourcis clavier de l'interface invisible alors que " "l'interface graphique est affichée" -#: ../src\wxUI\dialogs\configuration.py:42 +#: ../src\wxUI\dialogs\configuration.py:41 msgid "Activate Sapi5 when any other screen reader is not being run" msgstr "" "Activer Sapi5 lorsqu'il n'y a aucun autre lecteur d'écran en cours " "d'exécution" -#: ../src\wxUI\dialogs\configuration.py:44 +#: ../src\wxUI\dialogs\configuration.py:43 msgid "Hide GUI on launch" msgstr "Masquer l'interface graphique au démarrage" -#: ../src\wxUI\dialogs\configuration.py:46 +#: ../src\wxUI\dialogs\configuration.py:45 msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" msgstr "" "Lecture complète de tweets longs (peut diminuer les performances du client)" -#: ../src\wxUI\dialogs\configuration.py:48 +#: ../src\wxUI\dialogs\configuration.py:47 msgid "Remember state for mention all and long tweet" msgstr "Se souvenir de l'état pour \"Répondre à tous\" et \"Tweet long\"" -#: ../src\wxUI\dialogs\configuration.py:51 +#: ../src\wxUI\dialogs\configuration.py:50 msgid "Keymap" msgstr "Configuration clavier" -#: ../src\wxUI\dialogs\configuration.py:56 +#: ../src\wxUI\dialogs\configuration.py:55 msgid "Check for updates when {0} launches" msgstr "Vérifier les mises à jour lorsque {0} démarre" -#: ../src\wxUI\dialogs\configuration.py:66 +#: ../src\wxUI\dialogs\configuration.py:65 msgid "Proxy type: " msgstr "Type de proxy: " -#: ../src\wxUI\dialogs\configuration.py:73 +#: ../src\wxUI\dialogs\configuration.py:72 msgid "Proxy server: " msgstr "Serveur proxy: " -#: ../src\wxUI\dialogs\configuration.py:79 +#: ../src\wxUI\dialogs\configuration.py:78 msgid "Port: " msgstr "Port: " -#: ../src\wxUI\dialogs\configuration.py:85 +#: ../src\wxUI\dialogs\configuration.py:84 msgid "User: " msgstr "Utilisateur: " -#: ../src\wxUI\dialogs\configuration.py:91 +#: ../src\wxUI\dialogs\configuration.py:90 msgid "Password: " msgstr "Mot de passe: " -#: ../src\wxUI\dialogs\configuration.py:103 +#: ../src\wxUI\dialogs\configuration.py:102 msgid "Autocompletion settings..." msgstr "Paramètres pour la saisie automatique..." -#: ../src\wxUI\dialogs\configuration.py:105 +#: ../src\wxUI\dialogs\configuration.py:104 msgid "Relative timestamps" msgstr "Temps relatifs" -#: ../src\wxUI\dialogs\configuration.py:108 +#: ../src\wxUI\dialogs\configuration.py:107 msgid "Items on each API call" msgstr "Éléments pour chaque appel à l'API" -#: ../src\wxUI\dialogs\configuration.py:114 +#: ../src\wxUI\dialogs\configuration.py:113 msgid "" "Inverted buffers: The newest tweets will be shown at the beginning while the " "oldest at the end" @@ -2431,15 +2461,15 @@ msgstr "" "Tampons inversés: les tweets plus récents seront affichées en haut alors que " "les plus ancien à la fin" -#: ../src\wxUI\dialogs\configuration.py:116 +#: ../src\wxUI\dialogs\configuration.py:115 msgid "Retweet mode" msgstr "Mode retweet" -#: ../src\wxUI\dialogs\configuration.py:122 +#: ../src\wxUI\dialogs\configuration.py:121 msgid "Show screen names instead of full names" msgstr "Afficher les noms d'écran au lieu des noms complets" -#: ../src\wxUI\dialogs\configuration.py:124 +#: ../src\wxUI\dialogs\configuration.py:123 msgid "" "Number of items per buffer to cache in database (0 to disable caching, blank " "for unlimited)" @@ -2447,6 +2477,14 @@ msgstr "" "Nombre d'éléments par tampon en cache dans la base de données (0 pour " "désactiver la mise en cache, laissez en blanc pour illimité)" +#: ../src\wxUI\dialogs\configuration.py:127 +msgid "" +"Load cache for tweets in memory (much faster in big datasets but requires " +"more RAM)" +msgstr "" +"Charger le cache des tweets en mémoire (plus rapide pour les gros ensembles " +"de données mais nécessite plus de RAM)" + #: ../src\wxUI\dialogs\configuration.py:134 msgid "Enable automatic speech feedback" msgstr "Activer le retour automatique de la parole" @@ -2460,7 +2498,7 @@ msgid "Status" msgstr "Statut" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "Tampon" @@ -2585,276 +2623,199 @@ msgstr "Supplémentaires" msgid "Save" msgstr "Enregistrer" -#: ../src\wxUI\dialogs\filterDialogs.py:15 +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "Créer un filtre pour ce tampon" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" msgstr "Titre du filtre" -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by word" msgstr "Filtrer par mot" -#: ../src\wxUI\dialogs\filterDialogs.py:26 +#: ../src\wxUI\dialogs\filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "Ignorer les tweets contenant le mot suivant" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: ../src\wxUI\dialogs\filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "Ignorer les tweets ne contenant pas le mot suivant" -#: ../src\wxUI\dialogs\filterDialogs.py:32 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" msgstr "Mot" -#: ../src\wxUI\dialogs\filterDialogs.py:37 +#: ../src\wxUI\dialogs\filterDialogs.py:36 msgid "Allow retweets" msgstr "Permettre les retweets" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: ../src\wxUI\dialogs\filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "Permettre les tweets cités" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: ../src\wxUI\dialogs\filterDialogs.py:38 msgid "Allow replies" msgstr "Permettre les réponses" -#: ../src\wxUI\dialogs\filterDialogs.py:47 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "Utiliser ce terme comme une expression régulière" -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by language" msgstr "Filtrer par langue" -#: ../src\wxUI\dialogs\filterDialogs.py:50 +#: ../src\wxUI\dialogs\filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "Charger tweets dans les suivantes langues" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: ../src\wxUI\dialogs\filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "Ignorer tweets dans les suivantes langues" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: ../src\wxUI\dialogs\filterDialogs.py:51 msgid "Don't filter by language" msgstr "Ne pas filtrer par langue" -#: ../src\wxUI\dialogs\filterDialogs.py:63 +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" msgstr "Langues supportées" -#: ../src\wxUI\dialogs\filterDialogs.py:68 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" msgstr "Ajouter la langue sélectionnée au filtre" -#: ../src\wxUI\dialogs\filterDialogs.py:72 +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" msgstr "Langue sélectionnée" -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "Effacer" -#: ../src\wxUI\dialogs\filterDialogs.py:122 +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Nom de filtre manquant" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Vous devez définir un nom pour le filtre avant de le créer." + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" msgstr "Gérer les filtres" -#: ../src\wxUI\dialogs\filterDialogs.py:124 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" msgstr "Filtres" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" msgstr "Filtre" -#: ../src\wxUI\dialogs\find.py:12 +#: ../src\wxUI\dialogs\find.py:13 msgid "Find in current buffer" msgstr "Trouver dans le tampon actuel" -#: ../src\wxUI\dialogs\find.py:13 +#: ../src\wxUI\dialogs\find.py:14 msgid "String" msgstr "Chaîne" -#: ../src\wxUI\dialogs\lists.py:10 +#: ../src\wxUI\dialogs\lists.py:11 msgid "Lists manager" msgstr "Gestionnaire de listes" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "List" msgstr "Liste" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Members" msgstr "Membres" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Owner" msgstr "Propriétaire" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "mode" msgstr "mode" -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "Description" + +#: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "Créer une nouvelle liste" -#: ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:22 msgid "Open in buffer" msgstr "Ouvrir dans un tampon" -#: ../src\wxUI\dialogs\lists.py:51 +#: ../src\wxUI\dialogs\lists.py:52 msgid "Viewing lists for %s" msgstr "Affichage des listes pour %s" -#: ../src\wxUI\dialogs\lists.py:52 +#: ../src\wxUI\dialogs\lists.py:53 msgid "Subscribe" msgstr "S'abonner" -#: ../src\wxUI\dialogs\lists.py:53 +#: ../src\wxUI\dialogs\lists.py:54 msgid "Unsubscribe" msgstr "Se désabonner" -#: ../src\wxUI\dialogs\lists.py:64 +#: ../src\wxUI\dialogs\lists.py:65 msgid "Name (20 characters maximun)" msgstr "Nom (maximum 20 caractères)" -#: ../src\wxUI\dialogs\lists.py:74 +#: ../src\wxUI\dialogs\lists.py:75 msgid "Mode" msgstr "Mode" -#: ../src\wxUI\dialogs\lists.py:75 +#: ../src\wxUI\dialogs\lists.py:76 msgid "Public" msgstr "Public" -#: ../src\wxUI\dialogs\lists.py:76 +#: ../src\wxUI\dialogs\lists.py:77 msgid "Private" msgstr "Privé" -#: ../src\wxUI\dialogs\lists.py:96 +#: ../src\wxUI\dialogs\lists.py:97 msgid "Editing the list %s" msgstr "Modification de la liste %s" -#: ../src\wxUI\dialogs\lists.py:107 +#: ../src\wxUI\dialogs\lists.py:108 msgid "Select a list to add the user" msgstr "Sélectionnez une liste pour ajouter l'utilisateur" -#: ../src\wxUI\dialogs\lists.py:108 +#: ../src\wxUI\dialogs\lists.py:109 msgid "Add" msgstr "Ajouter" -#: ../src\wxUI\dialogs\lists.py:130 +#: ../src\wxUI\dialogs\lists.py:131 msgid "Select a list to remove the user" msgstr "Sélectionnez une liste pour supprimer l'utilisateur" -#: ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\dialogs\lists.py:149 msgid "Do you really want to delete this list?" msgstr "Voulez-vous vraiment supprimer cette liste ?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "&Tweet long" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Joindre une image..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Correction &orthographique..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Joindre un audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "&Réduire URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Élargir URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Traduire..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Sai&sie automatique utilisateurs" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "Envoye&r" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "F&ermer" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinataire" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Répondre à tout le monde" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tweet - %i caractères " - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Description de l'image" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retweets: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Favoris: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Source: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -msgid "Date: " -msgstr "Date: " - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Voir" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Élément" - -#: ../src\wxUI\dialogs\search.py:13 +#: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "Rechercher sur Twitter" -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 +#: ../src\wxUI\dialogs\search.py:13 ../src\wxUI\view.py:21 msgid "&Search" msgstr "&Rechercher" @@ -2862,7 +2823,7 @@ msgstr "&Rechercher" msgid "Tweets" msgstr "Tweets" -#: ../src\wxUI\dialogs\search.py:22 +#: ../src\wxUI\dialogs\search.py:22 ../src\wxUI\dialogs\userAliasDialogs.py:43 msgid "Users" msgstr "Utilisateurs" @@ -2890,510 +2851,678 @@ msgstr "Récents" msgid "Popular" msgstr "Populaire" -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 +#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:25 +#: ../src\wxUI\dialogs\userActions.py:41 +#: ../src\wxUI\dialogs\userSelection.py:33 msgid "&OK" msgstr "&OK" -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 +#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:19 +#: ../src\wxUI\dialogs\trends.py:27 ../src\wxUI\dialogs\update_profile.py:37 +#: ../src\wxUI\dialogs\userActions.py:43 +#: ../src\wxUI\dialogs\userSelection.py:35 msgid "&Close" msgstr "&Fermer" -#: ../src\wxUI\dialogs\show_user.py:11 +#: ../src\wxUI\dialogs\show_user.py:12 msgid "Details" msgstr "Détails" -#: ../src\wxUI\dialogs\show_user.py:16 +#: ../src\wxUI\dialogs\show_user.py:17 msgid "&Go to URL" msgstr "&Aller à l'URL" -#: ../src\wxUI\dialogs\trends.py:12 +#: ../src\wxUI\dialogs\trends.py:10 msgid "View trending topics" msgstr "Afficher les tendances" -#: ../src\wxUI\dialogs\trends.py:13 +#: ../src\wxUI\dialogs\trends.py:11 msgid "Trending topics by" msgstr "Tendances par" -#: ../src\wxUI\dialogs\trends.py:15 +#: ../src\wxUI\dialogs\trends.py:12 msgid "Country" msgstr "Pays" -#: ../src\wxUI\dialogs\trends.py:16 +#: ../src\wxUI\dialogs\trends.py:13 msgid "City" msgstr "Ville" -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 +#: ../src\wxUI\dialogs\trends.py:19 ../src\wxUI\dialogs\update_profile.py:18 msgid "&Location" msgstr "&Localisation" -#: ../src\wxUI\dialogs\update_profile.py:9 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "Fichiers joints" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "Type" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "Supprimer la pièce jointe" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "Tweets ajoutés" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "Supprimer le tweet" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "&Ajouter" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "A&jouter un tweet" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "&Joindre un audio..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "Sai&sie automatique utilisateurs" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "Correction &orthographique..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "&Traduire" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "Envoye&r" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "Image" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "Vidéo" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "Sondage" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "Veuillez fournir une description" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Fichiers image (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Sélectionnez la photo à charger" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "Sélectionnez la vidéo à téléverser" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Fichiers vidéo (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "Erreur à l'ajout de la pièce jointe" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"Il est impossible de joindre plus de contenu. Assurez-vous que votre tweet " +"respecte les règles d'attachement de Twitter. Vous pouvez seulement inclure " +"une vidéo ou un GIF par tweet, et 4 photos au maximum." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "&Répondre à tout le monde" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "&Destinataire" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "Tweet - %i caractères " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "Description de l'image" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "Retweets: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "Favoris: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "Source: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "Date: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "Copier le lien dans le Presse-papiers" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "&Traduire..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "F&ermer" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "Voir" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "Élément" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "&Élargir URL" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "Ajouter un sondage" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "Temps de participation (en jours)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "Choix" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "Option 1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "Option 2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "Option 3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "Option 4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "Pas assez d'informations" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "Assurez-vous d'avoir spécifier au moins 2 options pour le sondage." + +#: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "Actualiser votre profil" -#: ../src\wxUI\dialogs\update_profile.py:11 +#: ../src\wxUI\dialogs\update_profile.py:12 msgid "&Name (50 characters maximum)" msgstr "&Nom (50 caractères maximum)" -#: ../src\wxUI\dialogs\update_profile.py:22 +#: ../src\wxUI\dialogs\update_profile.py:23 msgid "&Website" msgstr "Site &Web" -#: ../src\wxUI\dialogs\update_profile.py:27 +#: ../src\wxUI\dialogs\update_profile.py:28 msgid "&Bio (160 characters maximum)" msgstr "&Biographie (maximum 160 caractères)" -#: ../src\wxUI\dialogs\update_profile.py:33 +#: ../src\wxUI\dialogs\update_profile.py:34 msgid "Upload a &picture" msgstr "Charger une &photo" -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 +#: ../src\wxUI\dialogs\update_profile.py:35 ../src\wxUI\view.py:19 msgid "&Update profile" msgstr "Actualiser le &profil" -#: ../src\wxUI\dialogs\update_profile.py:76 +#: ../src\wxUI\dialogs\update_profile.py:77 msgid "Upload a picture" msgstr "Charger une photo" -#: ../src\wxUI\dialogs\update_profile.py:78 +#: ../src\wxUI\dialogs\update_profile.py:79 msgid "Discard image" msgstr "Ignorer la photo" -#: ../src\wxUI\dialogs\urlList.py:5 +#: ../src\wxUI\dialogs\urlList.py:6 msgid "Select URL" msgstr "Sélectionnez l'URL" -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 +#: ../src\wxUI\dialogs\userActions.py:11 ../src\wxUI\view.py:87 msgid "&User" msgstr "&Utilisateur" -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 +#: ../src\wxUI\dialogs\userActions.py:14 +#: ../src\wxUI\dialogs\userAliasDialogs.py:13 +#: ../src\wxUI\dialogs\userSelection.py:14 ../src\wxUI\dialogs\utils.py:31 msgid "&Autocomplete users" msgstr "&Saisie automatique utilisateurs" -#: ../src\wxUI\dialogs\userActions.py:19 +#: ../src\wxUI\dialogs\userActions.py:20 msgid "&Follow" msgstr "&Suivre" -#: ../src\wxUI\dialogs\userActions.py:20 +#: ../src\wxUI\dialogs\userActions.py:21 msgid "U&nfollow" msgstr "Ne pas su&ivre" -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 +#: ../src\wxUI\dialogs\userActions.py:22 ../src\wxUI\view.py:63 msgid "&Mute" msgstr "&Masquer" -#: ../src\wxUI\dialogs\userActions.py:22 +#: ../src\wxUI\dialogs\userActions.py:23 msgid "Unmu&te" msgstr "&Démasquer" -#: ../src\wxUI\dialogs\userActions.py:23 +#: ../src\wxUI\dialogs\userActions.py:24 msgid "&Block" msgstr "&Bloquer" -#: ../src\wxUI\dialogs\userActions.py:24 +#: ../src\wxUI\dialogs\userActions.py:25 msgid "Unbl&ock" msgstr "Débl&oquer" -#: ../src\wxUI\dialogs\userActions.py:25 +#: ../src\wxUI\dialogs\userActions.py:26 msgid "&Report as spam" msgstr "&Signaler comme spam" -#: ../src\wxUI\dialogs\userActions.py:26 +#: ../src\wxUI\dialogs\userActions.py:27 msgid "&Ignore tweets from this client" msgstr "&Ignorer les tweets de ce client" -#: ../src\wxUI\dialogs\userSelection.py:9 +#: ../src\wxUI\dialogs\userAliasDialogs.py:18 +msgid "Alias" +msgstr "Alias" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:41 +msgid "Edit user aliases" +msgstr "Éditer les alias utilisateur" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:48 +msgid "Actions" +msgstr "Actions" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:50 +msgid "Add alias" +msgstr "Ajouter un alias" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:51 +msgid "Adds a new user alias" +msgstr "Ajoute un nouvel alias utilisateur" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:54 +msgid "Edit the currently focused user Alias." +msgstr "Éditer l'alias utilisateur ayant actuellement le focus." + +#: ../src\wxUI\dialogs\userAliasDialogs.py:58 +msgid "Remove the currently focused user alias." +msgstr "Supprimer l'alias utilisateur ayant actuellement le focus." + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Are you sure you want to delete this user alias?" +msgstr "Êtes-vous sûr de vouloir supprimer cet alias utilisateur ?" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Remove user alias" +msgstr "Supprimer l'alias utilisateur" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:93 +msgid "User alias" +msgstr "Alias utilisateur" + +#: ../src\wxUI\dialogs\userSelection.py:10 msgid "Timeline for %s" msgstr "Chronologie pour %s" -#: ../src\wxUI\dialogs\userSelection.py:18 +#: ../src\wxUI\dialogs\userSelection.py:19 msgid "Buffer type" msgstr "Type de tampon" -#: ../src\wxUI\dialogs\userSelection.py:19 +#: ../src\wxUI\dialogs\userSelection.py:20 msgid "&Tweets" msgstr "&Tweets" -#: ../src\wxUI\dialogs\userSelection.py:20 +#: ../src\wxUI\dialogs\userSelection.py:21 msgid "&Likes" msgstr "&Favoris" -#: ../src\wxUI\dialogs\userSelection.py:21 +#: ../src\wxUI\dialogs\userSelection.py:22 msgid "&Followers" msgstr "&Abonnés" -#: ../src\wxUI\dialogs\userSelection.py:22 +#: ../src\wxUI\dialogs\userSelection.py:23 msgid "F&riends" msgstr "A&bonnements" -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 +#: ../src\wxUI\menus.py:8 ../src\wxUI\view.py:33 msgid "&Retweet" msgstr "&Retweet" -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 +#: ../src\wxUI\menus.py:10 ../src\wxUI\menus.py:34 ../src\wxUI\view.py:32 msgid "Re&ply" msgstr "Ré&pondre" -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 +#: ../src\wxUI\menus.py:12 ../src\wxUI\view.py:34 msgid "&Like" msgstr "A&jouter aux favoris" -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 +#: ../src\wxUI\menus.py:14 ../src\wxUI\view.py:35 msgid "&Unlike" msgstr "S&upprimer des favoris" -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 +#: ../src\wxUI\menus.py:16 ../src\wxUI\menus.py:36 ../src\wxUI\menus.py:52 msgid "&Open URL" msgstr "&Ouvrir l'URL" -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 +#: ../src\wxUI\menus.py:18 ../src\wxUI\menus.py:54 ../src\wxUI\menus.py:87 msgid "&Open in Twitter" msgstr "Ou&vrir dans Twitter" -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 +#: ../src\wxUI\menus.py:20 ../src\wxUI\menus.py:38 ../src\wxUI\menus.py:56 msgid "&Play audio" msgstr "&Lire audio" -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 +#: ../src\wxUI\menus.py:22 ../src\wxUI\menus.py:58 ../src\wxUI\view.py:36 msgid "&Show tweet" msgstr "A&fficher tweet" -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 +#: ../src\wxUI\menus.py:24 ../src\wxUI\menus.py:42 ../src\wxUI\menus.py:60 +#: ../src\wxUI\menus.py:70 ../src\wxUI\menus.py:89 ../src\wxUI\menus.py:103 msgid "&Copy to clipboard" msgstr "&Copier dans le Presse-papiers" -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 +#: ../src\wxUI\menus.py:26 ../src\wxUI\menus.py:44 ../src\wxUI\menus.py:62 +#: ../src\wxUI\menus.py:72 ../src\wxUI\view.py:40 msgid "&Delete" msgstr "&Supprimer Tweet" -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 +#: ../src\wxUI\menus.py:28 ../src\wxUI\menus.py:46 ../src\wxUI\menus.py:91 msgid "&User actions..." msgstr "&Actions de l'utilisateur..." -#: ../src\wxUI\menus.py:39 +#: ../src\wxUI\menus.py:40 msgid "&Show direct message" -msgstr "&Afficher le message privé" +msgstr "&Afficher le message" -#: ../src\wxUI\menus.py:67 +#: ../src\wxUI\menus.py:68 msgid "&Show event" msgstr "&Afficher l'événement" -#: ../src\wxUI\menus.py:77 +#: ../src\wxUI\menus.py:78 msgid "Direct &message" -msgstr "&Message privé" +msgstr "&Message" -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 +#: ../src\wxUI\menus.py:80 ../src\wxUI\view.py:50 msgid "&View lists" msgstr "&Voir listes" -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 +#: ../src\wxUI\menus.py:83 ../src\wxUI\view.py:51 msgid "Show user &profile" msgstr "Voir le &profil de l'utilisateur" -#: ../src\wxUI\menus.py:84 +#: ../src\wxUI\menus.py:85 msgid "&Show user" msgstr "&Afficher l'utilisateur" -#: ../src\wxUI\menus.py:98 +#: ../src\wxUI\menus.py:99 msgid "&Tweet about this trend" msgstr "&Tweet sur cette tendance" -#: ../src\wxUI\menus.py:100 +#: ../src\wxUI\menus.py:101 msgid "&Show item" msgstr "&Afficher l'élément" -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 +#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:26 msgid "&Global settings" msgstr "Paramètres &globaux" -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 +#: ../src\wxUI\sysTrayIcon.py:37 ../src\wxUI\view.py:25 msgid "Account se&ttings" msgstr "Paramètres du c&ompte" -#: ../src\wxUI\sysTrayIcon.py:37 +#: ../src\wxUI\sysTrayIcon.py:38 msgid "Update &profile" msgstr "&Actualiser le profil" -#: ../src\wxUI\sysTrayIcon.py:38 +#: ../src\wxUI\sysTrayIcon.py:39 msgid "&Show / hide" msgstr "&Afficher / masquer" -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 +#: ../src\wxUI\sysTrayIcon.py:40 ../src\wxUI\view.py:75 msgid "&Documentation" msgstr "&Documentation" -#: ../src\wxUI\sysTrayIcon.py:40 +#: ../src\wxUI\sysTrayIcon.py:41 msgid "Check for &updates" msgstr "Vérifier les &mises à jour" -#: ../src\wxUI\sysTrayIcon.py:41 +#: ../src\wxUI\sysTrayIcon.py:42 msgid "&Exit" msgstr "&Quitter" -#: ../src\wxUI\view.py:16 +#: ../src\wxUI\view.py:18 msgid "&Manage accounts" msgstr "Gérer les &comptes" -#: ../src\wxUI\view.py:18 +#: ../src\wxUI\view.py:20 msgid "&Hide window" msgstr "Masquer la &fenêtre" -#: ../src\wxUI\view.py:20 +#: ../src\wxUI\view.py:22 msgid "&Lists manager" msgstr "Gérer les &listes" -#: ../src\wxUI\view.py:21 +#: ../src\wxUI\view.py:23 +msgid "Manage user aliases" +msgstr "Gérer les alias utilisateur" + +#: ../src\wxUI\view.py:24 msgid "&Edit keystrokes" msgstr "&Éditer les raccourcis clavier" -#: ../src\wxUI\view.py:24 +#: ../src\wxUI\view.py:27 msgid "E&xit" msgstr "&Quitter" -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 +#: ../src\wxUI\view.py:31 ../src\wxUI\view.py:86 msgid "&Tweet" msgstr "&Tweet" -#: ../src\wxUI\view.py:34 +#: ../src\wxUI\view.py:37 msgid "View &address" msgstr "Voir &adresse" -#: ../src\wxUI\view.py:35 +#: ../src\wxUI\view.py:38 msgid "View conversa&tion" msgstr "Voir &conversation" -#: ../src\wxUI\view.py:36 +#: ../src\wxUI\view.py:39 msgid "Read text in picture" msgstr "Lire le texte dans l'&image" -#: ../src\wxUI\view.py:41 +#: ../src\wxUI\view.py:44 msgid "&Actions..." msgstr "&Actions..." -#: ../src\wxUI\view.py:42 +#: ../src\wxUI\view.py:45 msgid "&View timeline..." msgstr "Voir &chronologie..." -#: ../src\wxUI\view.py:43 +#: ../src\wxUI\view.py:46 msgid "Direct me&ssage" -msgstr "&Message privé" +msgstr "&Message" -#: ../src\wxUI\view.py:44 +#: ../src\wxUI\view.py:47 +msgid "Add a&lias" +msgstr "Ajouter un a&lias" + +#: ../src\wxUI\view.py:48 msgid "&Add to list" msgstr "A&jouter à la liste" -#: ../src\wxUI\view.py:45 +#: ../src\wxUI\view.py:49 msgid "R&emove from list" msgstr "S&upprimer de la liste" -#: ../src\wxUI\view.py:48 +#: ../src\wxUI\view.py:52 msgid "V&iew likes" msgstr "Voir &favoris" -#: ../src\wxUI\view.py:52 +#: ../src\wxUI\view.py:56 msgid "&Update buffer" msgstr "&Mise à jour du tampon" -#: ../src\wxUI\view.py:53 +#: ../src\wxUI\view.py:57 msgid "New &trending topics buffer..." msgstr "Nouveau tampon de &tendances..." -#: ../src\wxUI\view.py:54 +#: ../src\wxUI\view.py:58 msgid "Create a &filter" msgstr "Créer un &filtre" -#: ../src\wxUI\view.py:55 +#: ../src\wxUI\view.py:59 msgid "&Manage filters" msgstr "&Gérer les filtres" -#: ../src\wxUI\view.py:56 +#: ../src\wxUI\view.py:60 msgid "Find a string in the currently focused buffer..." msgstr "Trouver une chaîne dans le tampon ayant actuellement le f&ocus..." -#: ../src\wxUI\view.py:57 +#: ../src\wxUI\view.py:61 msgid "&Load previous items" msgstr "&Charger des éléments plus anciens" -#: ../src\wxUI\view.py:60 +#: ../src\wxUI\view.py:64 msgid "&Autoread" msgstr "&Lecture automatique" -#: ../src\wxUI\view.py:61 +#: ../src\wxUI\view.py:65 msgid "&Clear buffer" msgstr "&Effacer le tampon" -#: ../src\wxUI\view.py:62 +#: ../src\wxUI\view.py:66 msgid "&Destroy" msgstr "&Détruire" -#: ../src\wxUI\view.py:66 +#: ../src\wxUI\view.py:70 msgid "&Seek back 5 seconds" msgstr "&Reculer de 5 secondes" -#: ../src\wxUI\view.py:67 +#: ../src\wxUI\view.py:71 msgid "&Seek forward 5 seconds" msgstr "&Avancer de 5 secondes" -#: ../src\wxUI\view.py:72 +#: ../src\wxUI\view.py:76 msgid "Sounds &tutorial" msgstr "&Apprentissage des sons" -#: ../src\wxUI\view.py:73 +#: ../src\wxUI\view.py:77 msgid "&What's new in this version?" msgstr "&Quoi de neuf dans cette version ?" -#: ../src\wxUI\view.py:74 +#: ../src\wxUI\view.py:78 msgid "&Check for updates" msgstr "&Vérifier les mises à jour" -#: ../src\wxUI\view.py:75 +#: ../src\wxUI\view.py:79 msgid "&Report an error" msgstr "&Signaler une erreur" -#: ../src\wxUI\view.py:76 +#: ../src\wxUI\view.py:80 msgid "{0}'s &website" msgstr "Site &Web de {0}" -#: ../src\wxUI\view.py:77 +#: ../src\wxUI\view.py:81 msgid "Get soundpacks for TWBlue" msgstr "Obtenir des packs de son pour TWBlue" -#: ../src\wxUI\view.py:78 +#: ../src\wxUI\view.py:82 msgid "About &{0}" msgstr "À propos de &{0}" -#: ../src\wxUI\view.py:81 +#: ../src\wxUI\view.py:85 msgid "&Application" msgstr "&Application" -#: ../src\wxUI\view.py:84 +#: ../src\wxUI\view.py:88 msgid "&Buffer" msgstr "Ta&mpon" -#: ../src\wxUI\view.py:85 +#: ../src\wxUI\view.py:89 msgid "&Audio" msgstr "Au&dio" -#: ../src\wxUI\view.py:86 +#: ../src\wxUI\view.py:90 msgid "&Help" msgstr "A&ide" -#: ../src\wxUI\view.py:172 +#: ../src\wxUI\view.py:176 msgid "Address" msgstr "Adresse" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Update" msgstr "Mise à jour" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Your {0} version is up to date" msgstr "Votre version de {0} est à jour" - -#~ msgid "Empty" -#~ msgstr "Vide" - -#~ msgid "One mention from %s " -#~ msgstr "Une mention de %s" - -#~ msgid "One tweet from %s" -#~ msgstr "Un tweet de %s" - -#~ msgid "You've blocked %s" -#~ msgstr "Vous avez bloqué à %s" - -#~ msgid "You've unblocked %s" -#~ msgstr "Vous avez débloqué à %s" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "%s(@%s) vous suit" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "Vous suivez %s(@%s)" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "Vous ne suivez plus %s(@%s)" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "Vous avez ajouté aux favoris: %s, %s" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s) a ajouté aux favoris: %s" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "Vous avez retiré des favoris: %s, %s" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s) a retiré des favoris: %s" - -#~ msgid "You've created the list %s" -#~ msgstr "Vous avez créé la liste %s" - -#~ msgid "You've deleted the list %s" -#~ msgstr "Vous avez supprimé la liste %s" - -#~ msgid "You've updated the list %s" -#~ msgstr "Vous avez mis à jour la liste %s" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "Vous avez ajouté %s(@%s) à la liste %s" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "%s(@%s) vous a ajouté à la liste %s" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "Vous avez supprimé à %s(@%s) de la liste %s" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "%s(@%s) vous a supprimé de la liste %s" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "Vous êtes abonné à la liste %s, qui est la propriété de %s(@%s)" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "%s(@%s) vous a abonné à la liste %s" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Vous êtes désabonné de la liste %s, qui est la propriété de %s(@%s)" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "" -#~ "Vous avez été désabonné de la liste %s, qui est la propriété de %s(@%s)" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "Vous avez retweeté un retweet de %s(@%s): %s" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "%s(@%s) a retweeté votre retweet: %s" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "Appels à l'API (un appel à l'API équivaut à 200 tweets, 2 appels à l'API " -#~ "équivaut à 400 tweets, etc.):" - -#~ msgid "Unable to upload the audio" -#~ msgstr "Impossible de charger l'audio" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "En attente d'autorisation du compte..." - -#~ msgid "Contains" -#~ msgstr "Contient" - -#~ msgid "Doesn't contain" -#~ msgstr "Ne contient pas" - -#~ msgid "Create a filter" -#~ msgstr "Créer un filtre" - -#~ msgid "&Name (20 characters maximum)" -#~ msgstr "&Nom (maximum 20 caractères)" diff --git a/src/locales/gl/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po b/src/locales/gl/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po deleted file mode 100644 index a814fb3e..00000000 --- a/src/locales/gl/LC_MESSAGES/twblue (Jani Kinnunen's conflicted copy 2019-03-25).po +++ /dev/null @@ -1,4190 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: TW Blue 0.80\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2018-08-08 10:44+0100\n" -"Last-Translator: Manuel Cortez \n" -"Language-Team: Juan Buño \n" -"Language: gl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.6.11\n" -"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-SourceCharset: UTF-8\n" - -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Imaxe" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "Esta acción non se atopa soportada para este buffer" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "Principal" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "Mencións" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "Mensaxes directas" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "Enviar mensaxes directas" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "Enviar chíos" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "Marcados como Gústame" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "Seguidores" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Amigos" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "Usuarios bloqueados" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "Usuarios silenciados" - -#: ../src\controller\buffers\twitterBuffers.py:75 -#, fuzzy -msgid "{username}'s timeline" -msgstr "Abrir líña temporal" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:83 -#, fuzzy -msgid "Unknown buffer" -msgstr "Descoñecido" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "Chío" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "Escribe o chío aquí" - -#: ../src\controller\buffers\twitterBuffers.py:194 -#, fuzzy -msgid "New tweet in {0}" -msgstr "Novo chío" - -#: ../src\controller\buffers\twitterBuffers.py:197 -#, fuzzy -msgid "{0} new tweets in {1}." -msgstr "@{0} citou o teu chío: {1}" - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s elementos recuperados" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Este buffer non é unha liña temporal. Non pode ser eliminado." - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "Respostar a {arg0}" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "Respostar" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "Respostar a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Mensaxe directa a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "Nova mensaxe directa" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "Engade o teu comentario ao chío" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "Cita" - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "Abrindo URL..." - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "Detalles de usuario" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "Mencionar a %s" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "Mención" - -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy -msgid "{0} new direct messages." -msgstr "Nova mensaxe directa" - -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy -msgid "This action is not supported in the buffer yet." -msgstr "Esta acción non se atopa soportada para este buffer" - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy -msgid "{0} new followers." -msgstr "Novo seguidor." - -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy -msgid "This action is not supported in the buffer, yet." -msgstr "Esta acción non se atopa soportada para este buffer" - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "Listo" - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "Liñas temporais" - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "Liña temporal para {0}" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "Liñas temporais de marcados como gústame" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "Chíos que me gustan para {}" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Liñas temporais de seguidores" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "Seguidores para {}" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Liñas temporais de amigos" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "Amigos para {}" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "Listas" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "Lista para {}" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "Procuras" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "Procurar {0}" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "Tendencias para %s" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "" -"Non hai unha sesión actualmente no foco. Enfoca unha sesión co atallo de " -"teclado para sesión seguinte ou anterior." - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "Valdeirar búffer." - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0} non atopado." - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "Os filtros non se poden aplicar neste búfer" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "Seleciona un usuario" - -#: ../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" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "Conversa con {0}" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "Non hai coordinadas neste chío" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "Non hai resultados para as coordenadas neste chío" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "Erro decodificando as coordenadas. Téntao de novo máis tarde." - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s, %s de %s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%s. Valeiro" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: Esta conta non está autentificada en Twitter." - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s de %s" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: Esta conta non está autentificada en twitter." - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Eventos" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "Esta lista xa está aberta" - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"Algo inesperado aconteceu cando tentabamos reportar o teu erro. Por favor, " -"volve intentalo máis tarde" - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "a autolectura de novos chíos está activada neste bufer" - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "a autolectura de novos chíos está desactivada neste buffer" - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "Sesión silenciada" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "Silenciar Sesión desactivado" - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "silencio de buffer activo" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "silencio de buffer inactivo" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "Copiado" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "Imposible actualizar este búfer." - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "Actualizando búfer..." - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0} elementos recuperados" - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "Búfer inválido" - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Este chío non contén imaxes" - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "Foto {0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "Seleciona a foto" - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "Imposible extraer texto" - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "Traducido" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "Non hai ningunha URL para acortar" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URL Acortada" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "Non hai ningunha URL para expandir" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URL expandida" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s de %d caracteres" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s carácteres" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "Ver elemento" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Conexión directa" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "Preguntar" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "Rechiar sen comentarios" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "Rechiar con comentarios" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "Opcions da conta para %s" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "Mensaxes directas" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "Erro" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "Ese usuario non existe" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "O usuario foi suspendido" - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "Detalles para %s" - -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "Descartado" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Nome de usuario: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Nome: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Ubicación: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "Descrición: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "Sí" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "Non" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "Protexido: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "Segues a {0}. " - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr "{0} estache a seguir." - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Seguidores: %s\n" -" Amigos: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "Verificado: %s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "Chíos: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "Marcados como gústame: %s" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "Non podes ignorar as mensaxes directas" - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "Adxuntando..." - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "PAUSAR" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "&RETOMAR" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "RETOMAR" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "&PAUSAR" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "&Deter" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "Grabando" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "Detido" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "&Grabar" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "Reproducindo..." - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "&Reproducir" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "Recodificando audio..." - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "Erro subindo o ficheiro: {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "%d día, " - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%d días, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "%d hora, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d horas, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "%d minuto, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d minutos, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "%s segundo" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s segundos" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "Arquivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "Transferido" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "Tamaño total do arquivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "Velocidade de transferencia" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "Tempo restante" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "Adxuntar audio" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "&Engadir un arquivo existente" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "&Descartar" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "Subir a" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "Adxuntar" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "&Cancelar" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Arquivos de audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "Seleciona o arquivo de audio que desexas subir" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "Chío de Audio." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "Búfer de Liña temporal de usuario creado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "Búfer destruido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Mensaxe directa recibida" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Mensaxe directa enviada" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "Erro" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "Chío marcado como gústame." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "Búfer de marcados como gústame actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "chío xeolocalizable" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "O chío contén una ou máis imaxes" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "Límite alcanzado" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "Lista actualizada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "Demasiados carácteres." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "Mención recibida." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "Novo evento" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0} está listo" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "Mención enviada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "Chío rechiado" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "Búfer Procuras actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "Chío recibido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "Chío enviado" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "Búfer Tendencias actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "Novo chío no búfer liñas temporais de usuario." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "Novo seguidor." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "Volume cambiado." - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "tutorial de sons" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "" -"preme enter para escoitar o sonido correspondente ao evento selecionado" - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "Falta de ortografía: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "Falta de ortografía" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "contexto" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "suxerencias" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "&Ignorar" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "I&gnorar todo" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "&Reemplazar" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "R&eemplazar todo" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "&Engadir ao dicionario persoal" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"ocorreu un erro. Non hai diccionarios dispoñibles para a lingua selecionada " -"no {0}" - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "Corrección ortográfica completada." - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "Tes que comezar a escribir" - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "Non hai resultados na túa base de datos de usuario" - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "O autocompletado soamente funciona para usuarios" - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Actualizando base de datos... Podes pechar esta ventá agora. Unha mensaxe " -"avisarache cando este proceso remate." - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "Xestionar a base de datos do autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "Editando a base de dados de usuarios do {0} " - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "Nome de usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Nome" - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "Engadir usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "Quitar usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "Engadir usuario á base de datos" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "Nome de usuario de twitter" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "O usuario non existe" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "Erro!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Opcións de autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Engadir usuarios dende o buffer de seguidores" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Engadir usuarios dende o buffer de amigos" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Xestionar base de datos..." - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "Feito!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "Actualizouse a base de dados de usuarios do {0}'" - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "Detectar automáticamente" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "dinamarqués" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "holandés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "inglés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "finés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "francés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "alemán" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "húngaro" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "italiano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "xaponés" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "coreano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "polaco" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "portugués" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "ruso" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "castelán" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "Turco" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "Africano" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "albanés" - -#: ../src\extra\translator\translator.py:14 -msgid "Amharic" -msgstr "amárico" - -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "árabe" - -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "armenio" - -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "acerí" - -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "eusquera" - -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "bielorruso" - -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "bengalí" - -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "búlgaro" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "virmano" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "catalán" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "cheroqui" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "chinés" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "chinés simplificado" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "chinés tradicional" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "croata" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "checo" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "esperanto" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "estonio" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "filipino" - -#: ../src\extra\translator\translator.py:40 -msgid "Galician" -msgstr "galego" - -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "Xeorxiano" - -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "grego" - -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "guaraní" - -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "Gujarati" - -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "hebreo" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "indi" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "islandés" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "indonesio" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "irlandés (gaélico)" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "Canarés" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "cazaxo" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "Cambodia" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "curdo" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "Quirguiz" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "Lao" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "letón" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "lituano" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "macedonio" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "malaio" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "Malaialam" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "maltés" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "maratí" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "mongol" - -#: ../src\extra\translator\translator.py:70 -msgid "Nepali" -msgstr "nepalí" - -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "noruegués" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr "Oriya" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "Pastú" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "persa" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "Punjabi" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "rumano" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "sánscrito" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" -msgstr "serbio" - -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "Sindhi" - -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "Cingalés" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "eslovaco" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "esloveno" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "swahili" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "sueco" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "Tajik" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "tamil" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "Tagalo" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "Telugú" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "tailandés" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "tibetano" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "Ucraíno" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "uzbeco" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "Uighur" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "vietnamita" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "galés" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "Yiddish" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "Traducir mensaxe" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "Idioma de destino" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "Xeral" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "Sempre" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "Non se intentou" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "Aleatoriamente" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "As veces" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "Imposible reproducir" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "Bloqueo" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "Fallo" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "Característica" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "Maior" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "Menor" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "Texto" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "trivial" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "Axuste" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "Reportar un erro" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "Seleciona unha categoría" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "Describe en poucas palabras o que ocorreu, logo poderás profundizar." - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "Aquí podes describir o erro en detalle" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "Qué tan a miúdo ocorre este erro?" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "Selecciona a importancia que consideras que ten este erro" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Coñezo que o sistema de erros de {0} obterá o meu nome de usuario de " -"Twitter para contactarme e resolver o erro rapidamente" - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "Enviar reporte" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "Cancelar" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "Debes encher ambos campos" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Necesitas marcar a caixa para proporcionarnos o teu nome de usuario de " -"Twitter para poder contactarte se é preciso" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"Grazas por reportar o teu erro!. Quizais poderás velo en próximas versións " -"na listaxe de trocos. Reportaches o erro número %i." - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "Reportado" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "Erro ao reportar" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Algo inesperado aconteceu cando tentabamos reportar o teu erro. Por favor, " -"volve intentalo máis tarde" - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Vai arriba no búfer actual" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "vai abaixo no búfer actual" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Vai ó anterior búfer" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Vai ó seguinte búfer" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Enfocar a seguinte sesión" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Enfocar a anterior sesión" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Amosar ou agochar a Interface gráfica" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Novo chío" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Rechío" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Enviar mensaxe directa" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "Gústame un chío" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "Marcar o non marcar un chío como gússtame" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Non me gusta un chío" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Abrir o diálogo de accións do Usuario" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Ver detalles do usuario" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Ver chío" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "saír" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Abrir líña temporal" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Destruir o búfer" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interactuar co chío enfocado actualmente." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Abrir URL" - -#: ../src\keystrokeEditor\constants.py:25 -#, fuzzy -msgid "View in Twitter" -msgstr "procurar en twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Subir o volumen nun 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Baixar o volume nun 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Saltar ó primeiro elemento do búfer actual" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Saltar ó derradeiro elemento do búfer actual" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Saltar 20 elementos cara arriba no búfer actual" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Saltar 20 elementos cara abaixo no búfer actual" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Editar perfil" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Eliminar un chío ou unha mensaxe direita" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Vaciar buffer actual" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Repetir último elemento" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Copiar ao portapapeis" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Engadir á listaxe" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Quitar de listaxe" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Silenciar ou desilenciar o buffer activo" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Silenciar/activbar o son na sesión actual" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "" -"Conmutar entre a lectura automática de novos chíos para o buffer actual" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "procurar en twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Atopar unha cadea no búfer enfocado actualmente" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Mostrar o editor de combinacións de teclado" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Mostrar listaxes para un usuario específico" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "cargar elementos anteriores" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Obter a xeolocalización" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Amosar a xeolocazación dos chíos nun diálogo" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Crear un búfer de tendencias" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Ver conversación" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "Comprobar e descargar actualizacións" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Abre o xestor de listas, o que che permite crear, editar, eliminar e abrir " -"listas nos búferes." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Abre o diálogo de opcións blobais" - -#: ../src\keystrokeEditor\constants.py:54 -#, fuzzy -msgid "Opens the list manager" -msgstr "Xestor de listaxes" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Abre o diálogo de opcións da conta" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Tentar reproducir un ficheiro de audio" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Actualiza o búfer e recupera posibles elementos perdidos ahí." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "Extrae o texto dende una foto e amosa o resultado nun diálogo." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Editor de combinacións de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Seleciona unha combinación de teclado para editala" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "Combinacións de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "Acción" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "Editar" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "Executar acción" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "Pechar" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "Editando combinación de teclas" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "Control" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "Shift" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "Windows" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "Tecla" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "Aceptar" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "Precisas empregar a tecla de Windows" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "Combinación de teclado inválida" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "Debes proporcionar unha tecla para o atallo do teclado" - -#: ../src\languageHandler.py:99 -msgid "User default" -msgstr "usuario por defecto" - -#: ../src\main.py:105 -msgid "https://twblue.es/donate" -msgstr "https://twblue.es/donate" - -#: ../src\main.py:122 -msgid "" -"{0} is already running. Close the other instance before starting this one. " -"If you're sure that {0} isn't running, try deleting the file at {1}. If " -"you're unsure of how to do this, contact the {0} developers." -msgstr "" - -#: ../src\sessionmanager\wxUI.py:8 -msgid "Session manager" -msgstr "Xestor de sesión" - -#: ../src\sessionmanager\wxUI.py:11 -msgid "Accounts list" -msgstr "Lista de contas" - -#: ../src\sessionmanager\wxUI.py:13 -msgid "Account" -msgstr "Conta" - -#: ../src\sessionmanager\wxUI.py:17 -msgid "New account" -msgstr "Nova conta" - -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 -msgid "Remove account" -msgstr "Quitar conta" - -#: ../src\sessionmanager\wxUI.py:19 -msgid "Global Settings" -msgstr "Opcións Globais" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "Erro na conta" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "You need to configure an account." -msgstr "Precisas configurar unha conta" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "Autorización" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "" -"The request to authorize your Twitter account will be opened in your " -"browser. You only need to do this once. Would you like to continue?" -msgstr "" -"A petición para se autorizar na túa conta de Twitter abrirase no navegador. " -"Só necesitas facer isto unha vez. ¿Gostaríache continuar?" - -#: ../src\sessionmanager\wxUI.py:52 -msgid "Authorized account %d" -msgstr "Conta autorizada %d" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "Código de acceso inválido" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "" -"Your access token is invalid or the authorization has failed. Please try " -"again." -msgstr "" -"O teu token de aceso é inválido ou fallou a autorización. Por favor téntao " -"de novo." - -#: ../src\sessionmanager\wxUI.py:64 -msgid "Do you really want to delete this account?" -msgstr "Estás seguro de que desexas eliminar esta conta?" - -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 -msgid "dddd, MMMM D, YYYY H:m:s" -msgstr "dddd, MMMM D, YYYY H:m:s" - -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 -msgid "Dm to %s " -msgstr "dm a %s" - -#: ../src\sessions\twitter\compose.py:141 -msgid "{0}. Quoted tweet from @{1}: {2}" -msgstr "{0}. chío citado dende @{1}: {2}" - -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 -msgid "Unavailable" -msgstr "Non dispoñible" - -#: ../src\sessions\twitter\compose.py:166 -msgid "" -"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " -"Twitter %s" -msgstr "" -"%s (@%s). %s seguidores, %s amigos, %s chíos. último chío %s. Unido a " -"Twitter %s" - -#: ../src\sessions\twitter\compose.py:170 -msgid "No description available" -msgstr "Non hai unha descrición dispoñible" - -#: ../src\sessions\twitter\compose.py:174 -msgid "private" -msgstr "Privado" - -#: ../src\sessions\twitter\compose.py:175 -msgid "public" -msgstr "público" - -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "Non hai coordinadas neste chío" - -#: ../src\sessions\twitter\session.py:215 -msgid "%s failed. Reason: %s" -msgstr "%s fallou. Razón: %s" - -#: ../src\sessions\twitter\session.py:221 -msgid "%s succeeded." -msgstr "%s con éxito" - -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "Síntoo, non estás autorizado para ver este estado." - -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "Non se atopou o estado con ese ID" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "Código de erro {0}" - -#: ../src\sessions\twitter\wxUI.py:6 -msgid "Authorising account..." -msgstr "Autorizando conta..." - -#: ../src\sessions\twitter\wxUI.py:9 -msgid "Enter your PIN code here" -msgstr "Introduce o código PIN aquí" - -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "Detido." - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "Nova versión de %s" - -#: ../src\update\wxUpdater.py:10 -msgid "" -"There's a new %s version available, released on %s. Would you like to " -"download it now?\n" -"\n" -" %s version: %s\n" -"\n" -"Changes:\n" -"%s" -msgstr "" -"Hai unha versión %s nova dispoñible, publicada en %s. ¿Gostaríache " -"descargala agora?\n" -"\n" -" %s versión: %s\n" -"\n" -"Cambios:\n" -"%s" - -#: ../src\update\wxUpdater.py:18 -msgid "Download in Progress" -msgstr "Descarga en progreso" - -#: ../src\update\wxUpdater.py:18 -msgid "Downloading the new version..." -msgstr "Descargando a nova versión..." - -#: ../src\update\wxUpdater.py:28 -msgid "Updating... %s of %s" -msgstr "Actualizando... %s de %s" - -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "¡Feito!" - -#: ../src\update\wxUpdater.py:31 -msgid "" -"The update has been downloaded and installed successfully. Press OK to " -"continue." -msgstr "" -"A nova versión de TW blue foi descargada e instalada con éxito. Preme " -"aceptar para iniciar a aplicación" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "Cliente" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Texto" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "Data" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "Usuario" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Mensaxe directa" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "Evento" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "Eliminar evento" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "Iniciar sesión" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "Comezar sesión automáticamente" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "Pechar sesión" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "Tendencia" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "Chiar sobre esta tendencia" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "Procurar tema" - -#: ../src\wxUI\commonMessageDialogs.py:6 -msgid "" -"This retweet is over 140 characters. Would you like to post it as a mention " -"to the poster with your comments and a link to the original tweet?" -msgstr "" -"Este rechouchío ten máis de 140 carácteres. ¿Gostaríache publicalo como unha " -"mención ó remitente cos teus comentarios e unha liga ó chío orixinal?" - -#: ../src\wxUI\commonMessageDialogs.py:9 -msgid "Would you like to add a comment to this tweet?" -msgstr "¿gustaríache engadir un comentario a este chío?" - -#: ../src\wxUI\commonMessageDialogs.py:12 -msgid "" -"Do you really want to delete this tweet? It will be deleted from Twitter as " -"well." -msgstr "¿Queres de certo eliminar esta mensaxe? Eliminarase tamén de Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 -msgid "Delete" -msgstr "Eliminar" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Do you really want to close {0}?" -msgstr "Queres pechar de certo {0}?" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Exit" -msgstr "Saír" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid " {0} must be restarted for these changes to take effect." -msgstr " débese reiniciar {0} para que estos cambios teñan lugar." - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid "Restart {0} " -msgstr "Reiniciar {0} " - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "" -"Are you sure you want to delete this user from the database? This user will " -"not appear in autocomplete results anymore." -msgstr "" -"Estás seguro de querer eliminar este usuario da base de datos? Este xa non " -"aparecerá nos resultados do autocompletado." - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "Confirm" -msgstr "Confirmar" - -#: ../src\wxUI\commonMessageDialogs.py:25 -msgid "Enter the name of the client : " -msgstr "Introduce o nome do cliente" - -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 -msgid "Add client" -msgstr "Endadir cliente" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "" -"Do you really want to empty this buffer? It's items will be removed from " -"the list but not from Twitter" -msgstr "" -"¿realmente queres borrar o contido deste buffer? Estes chíos borraranse da " -"listaxe, mais non de twitter" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "Empty buffer" -msgstr "Vaciar buffer" - -#: ../src\wxUI\commonMessageDialogs.py:35 -msgid "Do you really want to destroy this buffer?" -msgstr "Realmente queres eliminar este buffer?" - -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Attention" -msgstr "Atención" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "A timeline for this user already exists. You can't open another" -msgstr "Xa hai unha liña temporal para este usuario. Non podes abrir outra" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "Existing timeline" -msgstr "Liña temporal existente" - -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "This user has no tweets, so you can't open a timeline for them." -msgstr "" -"Este usuario non ten chíos, así que non podes abrirlle unha liña temporal" - -#: ../src\wxUI\commonMessageDialogs.py:47 -msgid "" -"This is a protected Twitter user, which means you can't open a timeline " -"using the Streaming API. The user's tweets will not update due to a twitter " -"policy. Do you want to continue?" -msgstr "" -"Este é un usuario protexido de Twitter. Significa que non podes abrir un " -"timeline utilizando a Streaming API. Os chíos dos usuario non se " -"actualizarán debido a unha política de twitter. ¿Queres continuar?" - -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "Warning" -msgstr "Precaución" - -#: ../src\wxUI\commonMessageDialogs.py:50 -msgid "" -"This is a protected user account, you need to follow this user to view their " -"tweets or likes." -msgstr "" -"Esta é unha conta de usuario protexida, necesitas seguir a este usuario para " -"ver os seus chíos ou marcados como gústame." - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "" -"If you like {0} we need your help to keep it going. Help us by donating to " -"the project. This will help us pay for the server, the domain and some other " -"things to ensure that {0} will be actively maintained. Your donation will " -"give us the means to continue the development of {0}, and to keep {0} free. " -"Would you like to donate now?" -msgstr "" -"Se che gosta {0} necesitamos da túa axuda para mantelo en camiño. Axúdanos " -"donando ó proxecto. Esto axudaranos a pagar o servidor, o dominio e algunhas " -"outras cousas para asegurarmos de que {0} se manterá activo. A túa donación " -"daranos unha razón para continuar o desenvolvemento do {0}, e para manter a " -"{0} libre. ¿Gostaríache donar agora?" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "We need your help" -msgstr "Necesitamos da túa axuda" - -#: ../src\wxUI\commonMessageDialogs.py:57 -msgid "This user has no tweets. {0} can't create a timeline." -msgstr "Este usuario non ten chíos. {0} non podo crear unha liña temporal." - -#: ../src\wxUI\commonMessageDialogs.py:60 -msgid "This user has no favorited tweets. {0} can't create a timeline." -msgstr "" -"Este usuario non ten chíos favoritos. {0} non podo crear unha liña temporal." - -#: ../src\wxUI\commonMessageDialogs.py:63 -msgid "This user has no followers. {0} can't create a timeline." -msgstr "" -"Este usuario non ten seguedores. {0} non podo crear unha liña temporal." - -#: ../src\wxUI\commonMessageDialogs.py:66 -msgid "This user has no friends. {0} can't create a timeline." -msgstr "Este usuario non ten amigos. {0} non podo crear unha liña temporal." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "datos de xeolocalización para este chío" - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geolocation data: {0}" -msgstr "Obter a xeolocalización: {0}" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "Información" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "" -"TWBlue has detected that you're running windows 10 and has changed the " -"default keymap to the Windows 10 keymap. It means that some keyboard " -"shorcuts could be different. Please check the keystroke editor by pressing " -"Alt+Win+K to see all available keystrokes for this keymap." -msgstr "" -"TWBlue detectou que usas o Windows 10 e cambiou o mapa dò teclado " -"predeterminado ao mapa de teclado do Windows 10. Esto significa que algunhas " -"combinacións de teclas poderían ser iferentes. Preme alt+win+k para abrir o " -"editor de combinacións de teclado e ver todas as combinacións dispoñibles " -"neste mapa de teclado." - -#: ../src\wxUI\commonMessageDialogs.py:76 -msgid "You have been blocked from viewing this content" -msgstr "Bloqueáronte e non podes ver este contido" - -#: ../src\wxUI\commonMessageDialogs.py:79 -msgid "" -"You have been blocked from viewing someone's content. In order to avoid " -"conflicts with the full session, TWBlue will remove the affected timeline." -msgstr "" -"Alguén bloqueoute e non podes ver o seu contido. Para evitar confrictos en " -"toda a sesión, TWBlue quitará o fío temporal afectado." - -#: ../src\wxUI\commonMessageDialogs.py:82 -msgid "" -"TWBlue cannot load this timeline because the user has been suspended from " -"Twitter." -msgstr "" -"O TWBlue non pode cargar este fío temporal porque o usuario foi suspendido " -"por Twitter" - -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Do you really want to delete this filter?" -msgstr "¿Realmente queres borrar este filtro?" - -#: ../src\wxUI\commonMessageDialogs.py:88 -msgid "This filter already exists. Please use a different title" -msgstr "Este filtro xa existe. Por favor usa un título diferente " - -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "" -"{0} quit unexpectedly the last time it was run. If the problem persists, " -"please report it to the {0} developers." -msgstr "" - -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Engadir un adxunto" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Adxuntos" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Título" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Tipo" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Endadir adxuntos" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Imaxe" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Quitar adxuntos" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Arquivos de imaxe (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Seleciona unha foto para subir" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Por favor proporciona una descrición" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Descrición" - -#: ../src\wxUI\dialogs\configuration.py:16 -msgid "Language" -msgstr "Idioma" - -#: ../src\wxUI\dialogs\configuration.py:23 -msgid "Run {0} at Windows startup" -msgstr "Executar {0} no arranque do Windows" - -#: ../src\wxUI\dialogs\configuration.py:24 -msgid "ask before exiting {0}" -msgstr "Preguntar antes de saír do {0}" - -#: ../src\wxUI\dialogs\configuration.py:27 -msgid "Disable Streaming functions" -msgstr "Desactivar funcións de Streaming" - -#: ../src\wxUI\dialogs\configuration.py:30 -msgid "Buffer update interval, in minutes" -msgstr "Intervalo de actualización do búfer, en minutos" - -#: ../src\wxUI\dialogs\configuration.py:36 -msgid "Play a sound when {0} launches" -msgstr "Reproducir un son ó se lanzar {0}" - -#: ../src\wxUI\dialogs\configuration.py:38 -msgid "Speak a message when {0} launches" -msgstr "Falar unha mensaxe ó se lanzar {0}" - -#: ../src\wxUI\dialogs\configuration.py:40 -msgid "Use invisible interface's keyboard shortcuts while GUI is visible" -msgstr "" -"Empregar os atallos de teclado da interfaz invisible na xanela gráfica." - -#: ../src\wxUI\dialogs\configuration.py:42 -msgid "Activate Sapi5 when any other screen reader is not being run" -msgstr "activar sappy 5 cando ningún outro lector se estea a executar" - -#: ../src\wxUI\dialogs\configuration.py:44 -msgid "Hide GUI on launch" -msgstr "Agochar interfaz gráfica no lanzador" - -#: ../src\wxUI\dialogs\configuration.py:46 -msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" -msgstr "" -"Utilizar lectura completa de chíos longos (pode disminuir o rendemento do " -"cliente)" - -#: ../src\wxUI\dialogs\configuration.py:48 -msgid "Remember state for mention all and long tweet" -msgstr "Lembrar estado para mencionar a todos e chío longo" - -#: ../src\wxUI\dialogs\configuration.py:51 -msgid "Keymap" -msgstr "Mapa de teclado" - -#: ../src\wxUI\dialogs\configuration.py:56 -msgid "Check for updates when {0} launches" -msgstr "Procurar actualizacións cando se lance {0}" - -#: ../src\wxUI\dialogs\configuration.py:66 -msgid "Proxy type: " -msgstr "Typo de proxy: " - -#: ../src\wxUI\dialogs\configuration.py:73 -msgid "Proxy server: " -msgstr "Servidor Proxy: " - -#: ../src\wxUI\dialogs\configuration.py:79 -msgid "Port: " -msgstr "Porto: " - -#: ../src\wxUI\dialogs\configuration.py:85 -msgid "User: " -msgstr "Usuario" - -#: ../src\wxUI\dialogs\configuration.py:91 -msgid "Password: " -msgstr "Contrasinal" - -#: ../src\wxUI\dialogs\configuration.py:103 -msgid "Autocompletion settings..." -msgstr "Opcións de autocompletado" - -#: ../src\wxUI\dialogs\configuration.py:105 -msgid "Relative timestamps" -msgstr "Tempos relativos" - -#: ../src\wxUI\dialogs\configuration.py:108 -msgid "Items on each API call" -msgstr "Elementos por cada chamada á API" - -#: ../src\wxUI\dialogs\configuration.py:114 -msgid "" -"Inverted buffers: The newest tweets will be shown at the beginning while the " -"oldest at the end" -msgstr "" -"Buffers invertidos. Os novos chíos mostraranse ao comezo da listaxe e os " -"máis vellos ao final." - -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet mode" -msgstr "Modo de rechouchío" - -#: ../src\wxUI\dialogs\configuration.py:122 -msgid "Show screen names instead of full names" -msgstr "Amosar nomes de pantalla en lugar de nomes enteiros" - -#: ../src\wxUI\dialogs\configuration.py:124 -msgid "" -"Number of items per buffer to cache in database (0 to disable caching, blank " -"for unlimited)" -msgstr "" -"Número de elementos por búfer para gardar na caché da base de dados (0 para " -"desactivar o gardado na caché, en branco para ilimitado)" - -#: ../src\wxUI\dialogs\configuration.py:134 -msgid "Enable automatic speech feedback" -msgstr "Activar a retroalimentación automática da fala" - -#: ../src\wxUI\dialogs\configuration.py:136 -msgid "Enable automatic Braille feedback" -msgstr "Activar a retroalimentación automática do braille" - -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Estado" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Buffer" -msgstr "Búfer" - -#: ../src\wxUI\dialogs\configuration.py:147 -msgid "Show/hide" -msgstr "Amosar/agochar" - -#: ../src\wxUI\dialogs\configuration.py:148 -msgid "Move up" -msgstr "Mover arriba" - -#: ../src\wxUI\dialogs\configuration.py:149 -msgid "Move down" -msgstr "Mover abaixo" - -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 -msgid "Show" -msgstr "Amosar" - -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 -msgid "Hide" -msgstr "Agochar" - -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 -msgid "Select a buffer first." -msgstr "Selecciona un búfer primeiro." - -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 -msgid "The buffer is hidden, show it first." -msgstr "O búffer está agochado, amósao primeiro." - -#: ../src\wxUI\dialogs\configuration.py:175 -msgid "The buffer is already at the top of the list." -msgstr "O búfer xa está enriba na lista." - -#: ../src\wxUI\dialogs\configuration.py:199 -msgid "The buffer is already at the bottom of the list." -msgstr "O búfer xa está no fondo da lista." - -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 -msgid "Ignored clients" -msgstr "Clientes rexeitados" - -#: ../src\wxUI\dialogs\configuration.py:247 -msgid "Remove client" -msgstr "Quitar cliente" - -#: ../src\wxUI\dialogs\configuration.py:271 -msgid "Volume" -msgstr "volume" - -#: ../src\wxUI\dialogs\configuration.py:282 -msgid "Session mute" -msgstr "Silenciar sesión" - -#: ../src\wxUI\dialogs\configuration.py:284 -msgid "Output device" -msgstr "dispositivo de saída" - -#: ../src\wxUI\dialogs\configuration.py:291 -msgid "Input device" -msgstr "dispositivo de entrada" - -#: ../src\wxUI\dialogs\configuration.py:299 -msgid "Sound pack" -msgstr "Paquete de sons" - -#: ../src\wxUI\dialogs\configuration.py:305 -msgid "Indicate audio tweets with sound" -msgstr "Indicar chíos de audio con son" - -#: ../src\wxUI\dialogs\configuration.py:307 -msgid "Indicate geotweets with sound" -msgstr "Indicar chíos xeolocalizados con son" - -#: ../src\wxUI\dialogs\configuration.py:309 -msgid "Indicate tweets containing images with sound" -msgstr "Indicar chíos que conteñan imaxes con son" - -#: ../src\wxUI\dialogs\configuration.py:332 -msgid "Language for OCR" -msgstr "Lingua para o OCR" - -#: ../src\wxUI\dialogs\configuration.py:338 -msgid "API Key for SndUp" -msgstr "Clave da api para SNDUp" - -#: ../src\wxUI\dialogs\configuration.py:353 -msgid "{0} preferences" -msgstr "Preferencias do {0}" - -#: ../src\wxUI\dialogs\configuration.py:364 -msgid "Proxy" -msgstr "Proxy" - -#: ../src\wxUI\dialogs\configuration.py:373 -msgid "Feedback" -msgstr "Retroalimentación" - -#: ../src\wxUI\dialogs\configuration.py:377 -msgid "Buffers" -msgstr "Búferes" - -#: ../src\wxUI\dialogs\configuration.py:385 -msgid "Sound" -msgstr "son" - -#: ../src\wxUI\dialogs\configuration.py:389 -msgid "Extras" -msgstr "Extras" - -#: ../src\wxUI\dialogs\configuration.py:394 -msgid "Save" -msgstr "Gardar" - -#: ../src\wxUI\dialogs\filterDialogs.py:15 -msgid "Create a filter for this buffer" -msgstr "Crear un filtro para este búfer" - -#: ../src\wxUI\dialogs\filterDialogs.py:16 -msgid "Filter title" -msgstr "Título do filtro" - -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "Filtrar por palabra" - -#: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "Ignorar chíos que conteñan a seguinte palabra" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -msgid "Ignore tweets without the following word" -msgstr "Ignorar chíos sen a seguinte palabra" - -#: ../src\wxUI\dialogs\filterDialogs.py:32 -msgid "word" -msgstr "palabra" - -#: ../src\wxUI\dialogs\filterDialogs.py:37 -msgid "Allow retweets" -msgstr "Permitir rechíos" - -#: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "Permitir chíos citados" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -msgid "Allow replies" -msgstr "Permitir respostas" - -#: ../src\wxUI\dialogs\filterDialogs.py:47 -msgid "Use this term as a regular expression" -msgstr "Usa este termo coma expresión regular" - -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by language" -msgstr "Filtrar por lingua" - -#: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "Cargar chíos nas seguintes linguas" - -#: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "Ignorar chíos nas seguintes linguas" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 -msgid "Don't filter by language" -msgstr "Non filtrar por lingua" - -#: ../src\wxUI\dialogs\filterDialogs.py:63 -msgid "Supported languages" -msgstr "Linguas soportadas" - -#: ../src\wxUI\dialogs\filterDialogs.py:68 -msgid "Add selected language to filter" -msgstr "Engadir lingua selecionada para filtrar" - -#: ../src\wxUI\dialogs\filterDialogs.py:72 -msgid "Selected languages" -msgstr "Linguas selecionadas" - -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 -msgid "Remove" -msgstr "Borrar" - -#: ../src\wxUI\dialogs\filterDialogs.py:122 -msgid "Manage filters" -msgstr "Xestionar filtros" - -#: ../src\wxUI\dialogs\filterDialogs.py:124 -msgid "Filters" -msgstr "Filtros" - -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter" -msgstr "Filtro" - -#: ../src\wxUI\dialogs\find.py:12 -msgid "Find in current buffer" -msgstr "Atopar no búfer actual" - -#: ../src\wxUI\dialogs\find.py:13 -msgid "String" -msgstr "Cadea" - -#: ../src\wxUI\dialogs\lists.py:10 -msgid "Lists manager" -msgstr "Xestor de listaxes" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "List" -msgstr "Listaxe" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "Membros" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Owner" -msgstr "propietario" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "mode" -msgstr "Modo" - -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 -msgid "Create a new list" -msgstr "Crear nova listaxe" - -#: ../src\wxUI\dialogs\lists.py:21 -msgid "Open in buffer" -msgstr "Abrir en buffer" - -#: ../src\wxUI\dialogs\lists.py:51 -msgid "Viewing lists for %s" -msgstr "Vendo as listaxes de %s" - -#: ../src\wxUI\dialogs\lists.py:52 -msgid "Subscribe" -msgstr "Darse de alta" - -#: ../src\wxUI\dialogs\lists.py:53 -msgid "Unsubscribe" -msgstr "Darse de baixa" - -#: ../src\wxUI\dialogs\lists.py:64 -msgid "Name (20 characters maximun)" -msgstr "Nome (máximo 20 caracteres)" - -#: ../src\wxUI\dialogs\lists.py:74 -msgid "Mode" -msgstr "Modo" - -#: ../src\wxUI\dialogs\lists.py:75 -msgid "Public" -msgstr "Público" - -#: ../src\wxUI\dialogs\lists.py:76 -msgid "Private" -msgstr "Privado" - -#: ../src\wxUI\dialogs\lists.py:96 -msgid "Editing the list %s" -msgstr "Editando a listaxe %s" - -#: ../src\wxUI\dialogs\lists.py:107 -msgid "Select a list to add the user" -msgstr "Seleciona unha listaxe para engadir o usuario" - -#: ../src\wxUI\dialogs\lists.py:108 -msgid "Add" -msgstr "Engadir" - -#: ../src\wxUI\dialogs\lists.py:130 -msgid "Select a list to remove the user" -msgstr "Seleciona unha listaxe para quitar o usuario" - -#: ../src\wxUI\dialogs\lists.py:148 -msgid "Do you really want to delete this list?" -msgstr "¿Realmente desexas eliminar esta listaxe?" - -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "Chío &longo" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "Subir &imaxen..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Corrección de &ortografía..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Engadir audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "A&curtar URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Expandir URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Traducir..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Auto&completar usuarios" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "En&viar" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "&Pechar" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinatario" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Mencionar a todos" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Chío - %i caracteres" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Descrición de imaxe" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Rechouchíos: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Marcados como gústame:" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Orixe:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "Data" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Ver" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Elemento" - -#: ../src\wxUI\dialogs\search.py:13 -msgid "Search on Twitter" -msgstr "procurar en twitter" - -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "&Procurar" - -#: ../src\wxUI\dialogs\search.py:21 -msgid "Tweets" -msgstr "Chíos" - -#: ../src\wxUI\dialogs\search.py:22 -msgid "Users" -msgstr "Usuarios" - -#: ../src\wxUI\dialogs\search.py:29 -msgid "&Language for results: " -msgstr "&Lingua para os resultados: " - -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 -msgid "any" -msgstr "calquera" - -#: ../src\wxUI\dialogs\search.py:37 -msgid "Results &type: " -msgstr "&Tipo de resultados: " - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 -msgid "Mixed" -msgstr "Misturado" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 -msgid "Recent" -msgstr "Recente" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 -msgid "Popular" -msgstr "Popular" - -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 -msgid "&OK" -msgstr "&Aceptar" - -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 -msgid "&Close" -msgstr "&Pechar" - -#: ../src\wxUI\dialogs\show_user.py:11 -msgid "Details" -msgstr "Detalles" - -#: ../src\wxUI\dialogs\show_user.py:16 -msgid "&Go to URL" -msgstr "&Ir á URL" - -#: ../src\wxUI\dialogs\trends.py:12 -msgid "View trending topics" -msgstr "Ver tendencias" - -#: ../src\wxUI\dialogs\trends.py:13 -msgid "Trending topics by" -msgstr "Tendencias por..." - -#: ../src\wxUI\dialogs\trends.py:15 -msgid "Country" -msgstr "País" - -#: ../src\wxUI\dialogs\trends.py:16 -msgid "City" -msgstr "Cidade" - -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 -msgid "&Location" -msgstr "&Ubicación" - -#: ../src\wxUI\dialogs\update_profile.py:9 -msgid "Update your profile" -msgstr "Actualizar o teu perfil" - -#: ../src\wxUI\dialogs\update_profile.py:11 -msgid "&Name (50 characters maximum)" -msgstr "&Nome (máximo 50 caracteres)" - -#: ../src\wxUI\dialogs\update_profile.py:22 -msgid "&Website" -msgstr "Sitio &web" - -#: ../src\wxUI\dialogs\update_profile.py:27 -msgid "&Bio (160 characters maximum)" -msgstr "&Biografía (máximo 160 caracteres)" - -#: ../src\wxUI\dialogs\update_profile.py:33 -msgid "Upload a &picture" -msgstr "Subir unha &foto" - -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "A&ctualizar perfil" - -#: ../src\wxUI\dialogs\update_profile.py:76 -msgid "Upload a picture" -msgstr "Subir unha foto" - -#: ../src\wxUI\dialogs\update_profile.py:78 -msgid "Discard image" -msgstr "Descartar foto" - -#: ../src\wxUI\dialogs\urlList.py:5 -msgid "Select URL" -msgstr "Seleccionar URL" - -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "&Usuario" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 -msgid "&Autocomplete users" -msgstr "&Autocompletar usuarios" - -#: ../src\wxUI\dialogs\userActions.py:19 -msgid "&Follow" -msgstr "&Seguir" - -#: ../src\wxUI\dialogs\userActions.py:20 -msgid "U&nfollow" -msgstr "Dei&xar de seguir" - -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "si&lenciar" - -#: ../src\wxUI\dialogs\userActions.py:22 -msgid "Unmu&te" -msgstr "Desactivar &silenzo" - -#: ../src\wxUI\dialogs\userActions.py:23 -msgid "&Block" -msgstr "&Bloquear" - -#: ../src\wxUI\dialogs\userActions.py:24 -msgid "Unbl&ock" -msgstr "&Desbloquear" - -#: ../src\wxUI\dialogs\userActions.py:25 -msgid "&Report as spam" -msgstr "Reportar coma s&pam" - -#: ../src\wxUI\dialogs\userActions.py:26 -msgid "&Ignore tweets from this client" -msgstr "&Ignorar chíos deste cliente" - -#: ../src\wxUI\dialogs\userSelection.py:9 -msgid "Timeline for %s" -msgstr "Liña temporal de %s" - -#: ../src\wxUI\dialogs\userSelection.py:18 -msgid "Buffer type" -msgstr "Tipo de Búfer" - -#: ../src\wxUI\dialogs\userSelection.py:19 -msgid "&Tweets" -msgstr "&Chíos" - -#: ../src\wxUI\dialogs\userSelection.py:20 -msgid "&Likes" -msgstr "&Gústame" - -#: ../src\wxUI\dialogs\userSelection.py:21 -msgid "&Followers" -msgstr "&Seguidores" - -#: ../src\wxUI\dialogs\userSelection.py:22 -msgid "F&riends" -msgstr "&Amigos" - -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "&Rechouchío" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "&Responder" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "&´Gústame" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "&Non me gusta" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "&Abrir URL..." - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy -msgid "&Open in Twitter" -msgstr "procurar en twitter" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "re&producir audio" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "&Ver chío" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "&Copiar ao portapapeis" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "&Eliminar" - -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "&Accións de usuario..." - -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "&ver mensaxe directa" - -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "&ver evento" - -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "Mensaxe &directa" - -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "&Ver listaxes" - -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "Ver &perfil do usuario" - -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "&ver usuarios silenciados" - -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "&twittear sobre esta tendencia" - -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "&Ver chío" - -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "Opcións &Globais" - -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "&opcións de conta" - -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "Actualizar &perfil" - -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "A&Mosar / agochar" - -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "&Documentación" - -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "Comprobar &actualizacións" - -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "&Saír" - -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "&Xestionar contas" - -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "Agochar &xanela" - -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "&Xestor de listaxes" - -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "Editar combinacións de &teclas" - -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "&Saír" - -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "&Chío" - -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "Ver &enderezo" - -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "Ver conversa&ción" - -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "Ler texto en foto" - -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "&Accións..." - -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "&Ver principal..." - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "&Mensaxe directa" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "&Engadir á listaxe" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "&Quitar de listaxe" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "&Ver marcados como gústame" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "&Actualizar buffer" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "Novo búfer &tendencias..." - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "Crear un &filtro" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "&Xestionar filtros" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "Atopar unha cadea no búfer enfocado actualmente..." - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "&Cargar elementos anteriores" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "&Autoleer" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "&Limpar buffer" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "&Destruir" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "&buscar 5 segudnos cara atrás" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "&Buscar 5 segundos cara adiante" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "tutorial de &sons" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "Qué hai de novo nesta &versión?" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "Comprobar &actualizacións" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "Reportar un &erro" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "Sitio &web do {0}" - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "Acerca do &{0}" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "&Aplicación" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "&Buffer" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "&Audio" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "A&xuda" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "Enderezo" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "Actualización" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "A túa versión {0} está ó día" - -#~ msgid "Empty" -#~ msgstr "Valeiro" - -#~ msgid "One mention from %s " -#~ msgstr "Una mención de %s" - -#~ msgid "One tweet from %s" -#~ msgstr "Un chío de %s" - -#~ msgid "You've blocked %s" -#~ msgstr "Bloqueaches a %s" - -#~ msgid "You've unblocked %s" -#~ msgstr "Desbloqueaches a %s" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "%s(@%s) comezou a seguirte" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "Agora segues a %s(@%s)" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "deixaches de seguir a %s(@%s)" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "Marcaches como gústame: %s, %s" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s) marcouse como gústame: %s" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "Marcaches como non me gusta: %s, %s" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s) marcouse como non me gusta: %s" - -#~ msgid "You've created the list %s" -#~ msgstr "Creaches a listaxe %s" - -#~ msgid "You've deleted the list %s" -#~ msgstr "Eliminaches a listaxe %s" - -#~ msgid "You've updated the list %s" -#~ msgstr "actualizaches a listaxe %s" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "Engadiches a %s(@%s) á listaxe %s" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "%s(@%s) engadiute á listaxe %s" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "Quitaches a %s(@%s) da listaxe %s" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "%s(@%s) quitouche da listaxe %s" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "décheste de alta na listaxe %s, propiedade de %s(@%s)" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "%s(@%s) subscribíute á listaxe %s" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "décheste de baixa da listaxe %s, propiedade de %s(@%s)" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Fuches dado de baixa da listaxe %s, propiedade de %s(@%s)" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "Rechouchiaches un rechouchío de %s(@%s): %s" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "%s(@%s) rechouchiou o teu rechouchío %s" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "Chamadas á API cando o stream inicie, unha chamada é igual a 200 tuits, " -#~ "dúas a 400 etc" - -#~ msgid "Unable to upload the audio" -#~ msgstr "Imposible subir o audio" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "Agardando pola autorización da conta..." - -#~ msgid "autodetect" -#~ msgstr "Autodetectar" - -#~ msgid "" -#~ "There's a new %s version available. Would you like to download it now?\n" -#~ "\n" -#~ " %s version: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" -#~ msgstr "" -#~ "Hai dispoñible unha nova versión %s. ¿Gostaríache descargala agora?\n" -#~ "\n" -#~ " %s versión: %s\n" -#~ "\n" -#~ "Cambios:\n" -#~ "%s" - -#~ msgid "Start {0} after logging in windows" -#~ msgstr "Comezar {0} despois de autentificarte no windows" - -#~ msgid "" -#~ "If you have a SndUp account, enter your API Key here. If your API Key is " -#~ "invalid, {0} will fail to upload. If there is no API Key here, {0} will " -#~ "upload annonymously." -#~ msgstr "" -#~ "Se tes unha conta en SndUp, introduce a túa clave API aquí. Se a clave " -#~ "API non é correcta, o {0} non poderá subir nada. Se non pos ningunha " -#~ "clave api aquí, os audios subiranse de forma anónima ó {0}" - -#~ msgid "Disconnect your Pocket account" -#~ msgstr "Desconectar a túa conta de Pocket" - -#~ msgid "Connect your Pocket account" -#~ msgstr "Conectar a túa conta de Pocket" - -#~ msgid "Pocket Authorization" -#~ msgstr "Autorización de Pocket" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. You only need " -#~ "to do this once. Do you want to continue?" -#~ msgstr "" -#~ "A petición para se autorizar na túa conta de Twitter abrirase no " -#~ "navegador. Só necesitas facer isto unha vez. ¿Gostaríache continuar?" - -#~ msgid "Error during authorization. Try again later." -#~ msgstr "Erro durante a autorización. Téntao de novo máis tarde" - -#~ msgid "Services" -#~ msgstr "Servizos" - -#~ msgid "Contains" -#~ msgstr "Contén" - -#~ msgid "Doesn't contain" -#~ msgstr "Non contén" - -#~ msgid "" -#~ "You have successfully logged into Twitter with {0}. You can close this " -#~ "window now." -#~ msgstr "" -#~ "Autentificácheste con éxito no Twitter con {0}. Agora podes pechar esta " -#~ "ventá." - -#~ msgid "&Send" -#~ msgstr "&Enviar" - -#~ msgid "Spelling correction" -#~ msgstr "correción hortográfica" - -#~ msgid "Shorten URL" -#~ msgstr "Acortar URL" - -#~ msgid "Expand URL" -#~ msgstr "Expandir URL" - -#~ msgid "Send" -#~ msgstr "Enviar" - -#~ msgid "unavailable" -#~ msgstr "Non dispoñible" - -#~ msgid "Search" -#~ msgstr "procurar" - -#~ msgid "Update profile" -#~ msgstr "Actualizar perfil" - -#~ msgid "Follow" -#~ msgstr "Seguir" - -#~ msgid "Mute" -#~ msgstr "silenciar" - -#~ msgid "Block" -#~ msgstr "Bloquear" - -#~ msgid "Report as spam" -#~ msgstr "Reportar coma spam" - -#~ msgid "Favourites" -#~ msgstr "Favoritos" - -#~ msgid "Favourites timeline for {}" -#~ msgstr "Liñas temporais de favoritos para {0}" - -#~ msgid "Tweet favourited." -#~ msgstr "Chío posto en favoritos." - -#~ msgid "Mark as favourite" -#~ msgstr "Marcar coma favorito" - -#~ msgid "Remove from favourites" -#~ msgstr "Quitar de favoritos" - -#~ msgid "You've added to favourites: %s, %s" -#~ msgstr "Marcaches coma favorito: %s, %s" - -#~ msgid "%s(@%s) has marked as favourite: %s" -#~ msgstr "%s(@%s) marcou coma favorito: %s" - -#~ msgid "You've removed from favourites: %s, %s" -#~ msgstr "Eliminaches dos teus favoritos: %s, %s" - -#~ msgid "%s(@%s) has removed from favourites: %s" -#~ msgstr "%s(@%s) quitou dos seus favoritos: %s" - -#~ msgid "Favourites: " -#~ msgstr "Favoritos: " - -#~ msgid "Add to &favourites" -#~ msgstr "&Marcar coma favorito" - -#~ msgid "Remove from favo&urites" -#~ msgstr "&Quitar de favoritos" - -#~ msgid "V&iew favourites" -#~ msgstr "Mostrar &favoritos" - -#~ msgid "Opening media..." -#~ msgstr "Abrindo medios..." - -#~ msgid "Add a new ignored client" -#~ msgstr "Engadir un novo cliente rexeitado" - -#~ msgid "Do you really want to delete this timeline?" -#~ msgstr "¿Realmente desexas eliminar esta liña temporal?" - -#~ msgid "Autocomplete users\\342\\200\\231 settings" -#~ msgstr "Autocompletar usuarios\\342\\200\\231 settings" - -#~ msgid "Set the autocomplete function" -#~ msgstr "Configurar a función de autocompletado" - -#~ msgid "Relative times" -#~ msgstr "Tempos relativos" - -#~ msgid "" -#~ "API calls when the stream is started (One API call equals to 200 tweetts, " -#~ "two API calls equals 400 tweets, etc):" -#~ msgstr "" -#~ "Chamadas á API cando o stream inicie, unha chamada é igual a 200 tuits, " -#~ "dúas a 400 etc" - -#~ msgid "" -#~ "Inverted buffers: The newest tweets will be shown at the beginning of the " -#~ "lists while the oldest at the end" -#~ msgstr "" -#~ "Buffers invertidos. Os novos chíos mostraranse ao comezo da listaxe e os " -#~ "máis vellos ao final." - -#~ msgid "" -#~ "The authorization request will be opened in your browser. Copy the code " -#~ "from Dropbox and paste it into the text box which will appear. You only " -#~ "need to do this once." -#~ msgstr "" -#~ "A petición de autorización abrirase no teu navegador. Copia o código " -#~ "dende Dropbox e pégao na caixa de texto que aparecerá. Só necesitas facer " -#~ "isto unha vez." - -#~ msgid "Verification code" -#~ msgstr "Código de verificación" - -#~ msgid "Error during authorisation. Try again later." -#~ msgstr "Erro durante a autorización. Téntao de novo máis tarde" - -#~ msgid "TW Blue preferences" -#~ msgstr "Preferencias do TW Blue" - -#~ msgid "Show other buffers" -#~ msgstr "Mostrar outros buffers" - -#~ msgid "JPG images" -#~ msgstr "Imaxes JPG" - -#~ msgid "GIF images" -#~ msgstr "Imaxes GIF" - -#~ msgid "PNG Images" -#~ msgstr "Imaxes PNG" - -#~ msgid "Select an URL" -#~ msgstr "Seleciona unha URL" - -#~ msgid "Not actionable." -#~ msgstr "Non accionable." - -#, fuzzy -#~ msgid "" -#~ "Perform secondary interact action (open URL in browser if Codeofdusk's " -#~ "intelegent audio tweet handlers enabled, play audio if disabled." -#~ msgstr "" -#~ "Perform secondary interact action (open URL in browser if Codeofdusk's " -#~ "intelegent audio tweet handlers enabled, play audio if disabled." - -#~ msgid "This account is not logged in twitter." -#~ msgstr "Esta conta non está autentificada en twitter." - -#~ msgid "{0}: This account is not logged in twitter." -#~ msgstr "{0}: Esta conta non está rexistrada en twitter." - -#~ msgid "Global mute off" -#~ msgstr "silencio xeral inactivo" - -#~ msgid "User-defined buffer created." -#~ msgstr "Creouse un novo búfer" - -#~ msgid "User-defined buffer destroied." -#~ msgstr "Eliminouse un novo búfer" - -#~ msgid "Someone's favourites have been updated." -#~ msgstr "os favoritos de alguén actualizáronse" - -#~ msgid "Mension received." -#~ msgstr "Mención recibida" - -#~ msgid "A trending topic buffer has been updated." -#~ msgstr "Actualizouse o búfer de tendencias." - -#~ msgid "New tweet in user-defined buffer." -#~ msgstr "hai un novo chío no buffer definido do usuario" - -#~ msgid "Mis-spelled word: %s" -#~ msgstr "palabra mal escrita: %s" - -#~ msgid "Mis-spelled word" -#~ msgstr "palabra mal escrita" - -#~ msgid "Finished" -#~ msgstr "Rematado" - -#~ msgid "The spelling review has finished." -#~ msgstr "a revisión ortográfica rematou" - -#~ msgid "" -#~ "Do you really want to delete this message? It will be eliminated from " -#~ "Twitter as well." -#~ msgstr "" -#~ "Realmente queres eliminar esta mensaxe? Eliminarase tamén de twitter" - -#~ msgid "Show followers" -#~ msgstr "Mostrar seguidores" - -#~ msgid "Show friends" -#~ msgstr "Mostrar amigos" - -#~ msgid "Show favourites" -#~ msgstr "Mostrar favoritos" - -#~ msgid "Show blocked users" -#~ msgstr "Mostrar usuarios bloqueados" - -#~ msgid "Show muted users" -#~ msgstr "Mostrar usuarios silenciados" - -#~ msgid "Show events" -#~ msgstr "Mostrar eventos" - -#~ msgid "" -#~ "The authorisation request will be shown on your browser. Copy the code " -#~ "tat Dropbox will provide and, in the text box that will appear on TW " -#~ "Blue, paste it. This code is necessary to continue. You only need to do " -#~ "it once." -#~ msgstr "" -#~ "Abrirase o teu navegador web coa solicitude que precisas a fin de iniciar " -#~ "sesión. Copia e pega no cadro de edición o código que dropbox vaiche " -#~ "proporcionar para poder iniciar sesión. Isto só terás que facelo unha vez" - -#~ msgid "Authorisation" -#~ msgstr "Autorización" - -#~ msgid "Change to the next account" -#~ msgstr "Cambiar a seguinte conta" - -#~ msgid "Change to the previous account" -#~ msgstr "Cambiar á conta anterior" - -#~ msgid "Remove buffer" -#~ msgstr "Borrar buffer" - -#~ msgid "" -#~ "Open URL on the current tweet, or further information for a friend or " -#~ "follower" -#~ msgstr "" -#~ "Abrir URL no chío anterior ou solicitar máis información en buffers de " -#~ "usuarios" - -#~ msgid "Go to the first element on the list" -#~ msgstr "Ir ao primeiro elemento da listaxe" - -#~ msgid "Go to the last element on the list" -#~ msgstr "Ir ao derradeiro elemento da listaxe" - -#~ msgid "Move 20 elements up on the current list" -#~ msgstr "Moverse 20 elementos hacia arriba na listaxe actual" - -#~ msgid "Move 20 elements down on the current list" -#~ msgstr "moverse 20 elementos hacia abaixo na listaxe actual" - -#~ msgid "Remove a tweet or direct message" -#~ msgstr "Eliminar chío ou mensaxe directa" - -#~ msgid "Globally mute/unmute the current account" -#~ msgstr "Activar ou desactivar o silencio global do tw blue" - -#~ msgid "load previous items to any buffer" -#~ msgstr "Cargar elementos anteriores para un bufer" - -#~ msgid "" -#~ "The request for the required Twitter authorisation to continue will be " -#~ "opened on your browser. You only need to do it once. Would you like to " -#~ "autorhise a new account now?" -#~ msgstr "" -#~ "Abrirase o navegador web coa solicitude de autorización de twitter que " -#~ "precisas para continuar. Só precisas facer isto unha vez. Queres " -#~ "actualizar unha nova conta agora?" - -#~ msgid "" -#~ "Your access token is invalid or the authorisation has failed. Please try " -#~ "again." -#~ msgstr "" -#~ "O código de acceso é incorrecto ou a autorización fallou. Por favor, " -#~ "inténtao de novo." - -#~ msgid "" -#~ "%s (@%s). %s followers, %s friends, %s tweets. Last tweet on %s. Joined " -#~ "Twitter on %s" -#~ msgstr "" -#~ "%s (@%s). %s seguidores, %s amigos, %s chíos. Último chío o %s. Uniuse a " -#~ "Twitter o %s" - -#~ msgid "" -#~ "The application requires to be restarted to save these changes. Press OK " -#~ "to do it now." -#~ msgstr "" -#~ "Para que estes cambios teñan efecto, a aplicación debe ser reiniciada. " -#~ "Preme aceptar para facelo agora." - -#~ msgid "" -#~ "Dropbox will open in your browser. After you log into Dropbox, an " -#~ "authorization code will be generated. Please paste it into the field " -#~ "which will appear. You only need to do this once." -#~ msgstr "" -#~ "Abriráse Dropbox no teu navegador. Despois de que te autentifiques no " -#~ "Dropbox, xenerarase un código de autorización. Por favor pégao no campo " -#~ "que aparecerá. Só necesitas facer esto unha vez." - -#~ msgid "View &trending topics" -#~ msgstr "Ver &tendencias" - -#~ msgid "&Unfollow" -#~ msgstr "&Deixar de seguir" - -#~ msgid "U&nmute" -#~ msgstr "Desactivar si&lencio" - -#~ msgid "Unb&lock" -#~ msgstr "Des&bloquear" - -#~ msgid "&Timeline" -#~ msgstr "Li&ña temporal" - -#~ msgid "&Autoread tweets for this buffer" -#~ msgstr "&Ler automáticamente chíos para este buffer" - -#~ msgid "&Remove buffer" -#~ msgstr "&Borrar buffer" - -#~ msgid "Stop recording" -#~ msgstr "Deter grabación" - -#~ msgid "The tweet may contain a playable audio" -#~ msgstr "O chío TEN QUE CONTER UN AUDIO VÁLIDO" - -#~ msgid "A timeline has been created" -#~ msgstr "creouse unha liña temporal" - -#~ msgid "A timeline has been deleted" -#~ msgstr "borrouse unha liña temporal" - -#~ msgid "You've received a direct message" -#~ msgstr "Recibiches unha mensaxe directa" - -#~ msgid "You've sent a direct message" -#~ msgstr "Enviaches unha mensaxe directa" - -#~ msgid "A bug has happened" -#~ msgstr "ocorreu un erro" - -#~ msgid "You've added a tweet to your favourites" -#~ msgstr "Engadiches un chío aos teus favoritos" - -#~ msgid "The tweet has coordinates to determine its location" -#~ msgstr "O chío contén coordenadas para determinar a súa ubicación" - -#~ msgid "There are no more tweets to read" -#~ msgstr "non hai máis chíos para ler" - -#~ msgid "A list has a new tweet" -#~ msgstr "unha listaxe ten un twit novo" - -#~ msgid "You can't add any more characters on the tweet" -#~ msgstr "non podes engadir máis caracteres ao chío" - -#~ msgid "You've been mentioned " -#~ msgstr "fuches mencionado" - -#~ msgid "A new event has happened" -#~ msgstr "ocorreu un novo evento" - -#~ msgid "You've replied" -#~ msgstr "respondiches" - -#~ msgid "You've sent a tweet" -#~ msgstr "enviaches un chío" - -#~ msgid "There's a new tweet in a timeline" -#~ msgstr "hai un novo chío nunha liña temporal" - -#~ msgid "You have a new follower" -#~ msgstr "tes un novo seguidor" - -#~ msgid "You've turned the volume up or down" -#~ msgstr "cambiaches o volume" - -#~ msgid "" -#~ "It seems as though the currently used sound pack needs an update. %i " -#~ "fails are still be required to use this function. Make sure to obtain the " -#~ "needed lacking sounds or to contact with the sound pack developer." -#~ msgstr "" -#~ "parece que o paquete de sons utilizado precisa de ser actualizado. Os " -#~ "arquivos %i son necesarios para esta función. Asegúrate de ter os sons " -#~ "necesarios ou contacta co creador do paquete" - -#~ msgid "See the users list" -#~ msgstr "Ver listaxe de usuarios" - -#~ msgid "Do you really want to delete this message?" -#~ msgstr "¿Realmente queres eliminar esta mensaxe?" - -#~ msgid "Unable to play audio." -#~ msgstr "Imposible reproducir audio" - -#~ msgid "Do you really want to delete this favourites timeline?" -#~ msgstr "Realmente desexas eliminar esta liña temporal de favoritos?" - -#~ msgid "&Mention" -#~ msgstr "M&ención" - -#~ msgid "Announce" -#~ msgstr "Anuncio" - -#~ msgid "" -#~ "Do you really want to empty this buffer? It's items will be removed from " -#~ "the list" -#~ msgstr "" -#~ "Realmente queres borrar o contido deste buffer? Os elementos eliminaranse " -#~ "da listaxe" - -#~ msgid "Do you really want to delete this search term?" -#~ msgstr "Realmente queres borrar este termo de procura?" - -#~ msgid "ask before exiting TwBlue?" -#~ msgstr "Preguntar ao saír de TWBlue" - -#~ msgid "Activate the auto-start of the invisible interface" -#~ msgstr "activar xanela invisible ao iniciar" - -#~ msgid "Global mute" -#~ msgstr "silencio xeral" - -#~ msgid "friends" -#~ msgstr "Amigos" - -#~ msgid "Favorites" -#~ msgstr "Favoritos" - -#~ msgid "You've muted to %s" -#~ msgstr "Silenciaches a %s" - -#~ msgid "You've unmuted to %s" -#~ msgstr "Desactivaches o silencio a %s" - -#~ msgid "This list is arready opened." -#~ msgstr "Esta listaxe xa está aberta." - -#~ msgid "List for %s" -#~ msgstr "Listaxe %s" - -#~ msgid "Uploading..." -#~ msgstr "Subindo..." - -#~ msgid "Men&tion all" -#~ msgstr "Mencionar &a todos" - -#~ msgid "This user does not exist on Twitter" -#~ msgstr "Ese usuario non existe en Twitter" - -#~ msgid "S&witch account" -#~ msgstr "Cambiar &conta" - -#~ msgid "&Preferences" -#~ msgstr "&Preferencias" - -#~ msgid "About &TW Blue" -#~ msgstr "Sobre &TW Blue" - -#~ msgid "" -#~ "An error occurred while looking for an update. It may be due to any " -#~ "problem either on our server or on your DNS servers. Please, try again " -#~ "later." -#~ msgstr "" -#~ "Ocorreu un erro ao buscar unha actualización. Isto pode deberse a un erro " -#~ "no noso servidor ou nos teus servidores DNS. Por favor, inténtao de novo " -#~ "máis tarde." - -#~ msgid "Sent" -#~ msgstr "Enviados" - -#~ msgid "%s favourites from %s" -#~ msgstr "%s favoritos de %s" - -#~ msgid "Streams disconnected. TW Blue will try to reconnect in a minute." -#~ msgstr "Streams desconectados. TW blue tentará conectarse nun minuto" - -#~ msgid "Reconnecting streams..." -#~ msgstr "Conectando os streams..." - -#~ msgid "search users for %s" -#~ msgstr "Procurar usuarios para %s" - -#~ msgid "Do you really want to close TW Blue?" -#~ msgstr "¿Realmente desexas saír de TW Blue?" - -#~ msgid "Exiting..." -#~ msgstr "Saíndo..." - -#~ msgid "Error while adding to favourites." -#~ msgstr "Erro ao marcar coma favorito" - -#~ msgid "Error while removing from favourites." -#~ msgstr "Erro ao quitar de favoritos" - -#~ msgid "Individual timeline" -#~ msgstr "Liña temporal individual" - -#~ msgid "List of favourites" -#~ msgstr "Listaxe de favoritos" - -#~ msgid "Existing list" -#~ msgstr "Listaxe existente " - -#~ msgid "" -#~ "There's already a list of favourites for this user. You can't create " -#~ "another." -#~ msgstr "" -#~ "Xa hai unha listaxe de favoritos aberta de este usuario. Non se pode " -#~ "abrir outra" - -#~ msgid "" -#~ "This user has no favourites. You can't create a list of favourites for " -#~ "this user." -#~ msgstr "" -#~ "Este usuario non ten favoritos. Non é posible crear unha listaxe de " -#~ "favoritos para el" - -#~ msgid "%s" -#~ msgstr "%s" - -#~ msgid "Documentation" -#~ msgstr "Documentación" - -#~ msgid "Translation" -#~ msgstr "Tradución" - -#~ msgid "Move up one tweet in the conversation" -#~ msgstr "Ir un chío hacia arriba na conversa" - -#~ msgid "Move down one tweet in the conversation" -#~ msgstr "ir un chío hacia abaixo na conversa" - -#~ msgid "Show the graphical interface" -#~ msgstr "Mostrar a interfaz gráfica" - -#~ msgid "Reply to a tweet" -#~ msgstr "Responder a un chío" - -#~ msgid "Empty the buffer removing all the elements" -#~ msgstr "Vaciar buffer quitando todos os elementos" - -#~ msgid "Listen the current message" -#~ msgstr "Escoitar a mensaxe actual" - -#~ msgid "Get location of any tweet" -#~ msgstr "Obter ubicación dun chío" - -#~ msgid "Creates a buffer for displaying trends for a desired place" -#~ msgstr "Crear un buffer para mostrar tendencias dun lugar elixido." - -#~ msgid "Select a twitter account to start TW Blue" -#~ msgstr "Seleciona unha conta de twitter para iniciar o TW Blue" - -#~ msgid "Remove session" -#~ msgstr "Eliminar sesión" - -#~ msgid "One tweet from %s in the list %s" -#~ msgstr "Un chío de %s na listaxe %s" - -#~ msgid "One direct message" -#~ msgstr "Unha mensaxe directa" - -#~ msgid "About a week ago" -#~ msgstr "Fai unha semana" - -#~ msgid "About {} weeks ago" -#~ msgstr "Fai {} semanas" - -#~ msgid "A month ago" -#~ msgstr "Fai un mes" - -#~ msgid "About {} months ago" -#~ msgstr "Fai {} meses" - -#~ msgid "About a year ago" -#~ msgstr "Fai un ano" - -#~ msgid "About {} years ago" -#~ msgstr "Fai {} anos" - -#~ msgid "About 1 day ago" -#~ msgstr "Fai un día" - -#~ msgid "About {} days ago" -#~ msgstr "Fai {} días" - -#~ msgid "just now" -#~ msgstr "Agora mesmo" - -#~ msgid "{} seconds ago" -#~ msgstr "Fai {} segundos" - -#~ msgid "1 minute ago" -#~ msgstr "Fai un minuto" - -#~ msgid "{} minutes ago" -#~ msgstr "fai {} minutos" - -#~ msgid "About 1 hour ago" -#~ msgstr "Fai unha hora" - -#~ msgid "About {} hours ago" -#~ msgstr "Fai {} horas" - -#~ msgid "January" -#~ msgstr "Xaneiro" - -#~ msgid "February" -#~ msgstr "Febreiro" - -#~ msgid "March" -#~ msgstr "Marzo" - -#~ msgid "April" -#~ msgstr "Abril" - -#~ msgid "June" -#~ msgstr "Xuño" - -#~ msgid "July" -#~ msgstr "Xullo" - -#~ msgid "August" -#~ msgstr "Agosto" - -#~ msgid "September" -#~ msgstr "Setembro" - -#~ msgid "October" -#~ msgstr "Outubro" - -#~ msgid "November" -#~ msgstr "Novembro" - -#~ msgid "December" -#~ msgstr "Decembro" - -#~ msgid "Sunday" -#~ msgstr "Domingo" - -#~ msgid "Monday" -#~ msgstr "Luns" - -#~ msgid "Tuesday" -#~ msgstr "Martes" - -#~ msgid "Wednesday" -#~ msgstr "Mércores" - -#~ msgid "Thursday" -#~ msgstr "Xoves" - -#~ msgid "Friday" -#~ msgstr "Venres" - -#~ msgid "Saturday" -#~ msgstr "Sábado" - -#~ msgid "sun" -#~ msgstr "Dom" - -#~ msgid "mon" -#~ msgstr "Lun" - -#~ msgid "tue" -#~ msgstr "Mar" - -#~ msgid "wed" -#~ msgstr "Mer" - -#~ msgid "thu" -#~ msgstr "Xov" - -#~ msgid "fri" -#~ msgstr "Ven" - -#~ msgid "sat" -#~ msgstr "Sab" - -#~ msgid "jan" -#~ msgstr "Xan" - -#~ msgid "feb" -#~ msgstr "Feb" - -#~ msgid "mar" -#~ msgstr "Mar" - -#~ msgid "apr" -#~ msgstr "Abr" - -#~ msgid "may" -#~ msgstr "Mai" - -#~ msgid "jun" -#~ msgstr "Xun" - -#~ msgid "jul" -#~ msgstr "Xul" - -#~ msgid "aug" -#~ msgstr "Ago" - -#~ msgid "sep" -#~ msgstr "Set" - -#~ msgid "oct" -#~ msgstr "Out" - -#~ msgid "nov" -#~ msgstr "Nov" - -#~ msgid "dec" -#~ msgstr "Dec" - -#~ msgid "%A, %B %d, %Y at %I:%M:%S %p" -#~ msgstr "%A, %d de %B do %Y ás %I:%M:%S %p" - -#~ msgid "Your TW Blue version is up to date" -#~ msgstr "A túa versión de TW Blue está actualizada" - -#~ msgid "Connection error. Try again later." -#~ msgstr "Erro de conexión. Téntao de novo máis tarde" - -#~ msgid "View members" -#~ msgstr "Ver membros" - -#~ msgid "View subscribers" -#~ msgstr "Ver suscritores" - -#~ msgid "Ouner" -#~ msgstr "propietario" - -#~ msgid "Successfully following %s" -#~ msgstr "Éxito seguindo a %s" - -#~ msgid "%s has been reported as spam" -#~ msgstr "%s foi reportado coma spam" - -#~ msgid "%s has been blocked" -#~ msgstr "%s foi bloqueado" - -#~ msgid "User's information" -#~ msgstr "Detalles do usuario" - -#~ msgid "You've unblock %s" -#~ msgstr "Desbloqueaches a %s" - -#~ msgid "Clear" -#~ msgstr "Limpiar" diff --git a/src/locales/it/LC_MESSAGES/twblue.po b/src/locales/it/LC_MESSAGES/twblue.po deleted file mode 100644 index bcde10fc..00000000 --- a/src/locales/it/LC_MESSAGES/twblue.po +++ /dev/null @@ -1,4157 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: TW Blue 0.80\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2019-03-23 01:38+0100\n" -"Last-Translator: Chris Leo Mameli \n" -"Language-Team: Christian Leo Mameli\n" -"Language: it\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" -"X-Poedit-Basepath: .\n" -"X-Poedit-SourceCharset: UTF-8\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.6.3\n" - -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Foto" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "Questa azione non è supportata per questo buffer" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "Cronologia Principale" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "Menzioni" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "Messaggi Ricevuti" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "Messaggi inviati" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "Tweet inviati" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "Mi piace" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "Followers" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Following" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "Utenti bloccati" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "Utenti silenziati" - -#: ../src\controller\buffers\twitterBuffers.py:75 -msgid "{username}'s timeline" -msgstr "Cronologia di {username}" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "Like di {username}" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "Follower di {username}" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "Amici di {username}" - -#: ../src\controller\buffers\twitterBuffers.py:83 -msgid "Unknown buffer" -msgstr "Buffer sconosciuto" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "Tweet" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "Scrivi il tweet qui" - -#: ../src\controller\buffers\twitterBuffers.py:194 -msgid "New tweet in {0}" -msgstr "Nuovo tweet in {0}" - -#: ../src\controller\buffers\twitterBuffers.py:197 -msgid "{0} new tweets in {1}." -msgstr "{0} nuovi tweet in {1}." - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s Elementi recuperati" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Impossivile eliminare. Questo buffer non è una Cronologia;" - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "Rispondi a {arg0}" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "Rispondi" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "Rispondi a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Messaggio diretto a %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "Nuovo messaggio diretto" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "Aggiungi il tuo commento al tweet" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "Citazione..." - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "Collegamento alla pagina..." - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "Dettagli utente" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "Apertura dell'articolo nel browser..." - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "Menziona a %s" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "Menziona" - -#: ../src\controller\buffers\twitterBuffers.py:728 -msgid "{0} new direct messages." -msgstr "{0} Nuovo messaggio diretto" - -#: ../src\controller\buffers\twitterBuffers.py:731 -msgid "This action is not supported in the buffer yet." -msgstr "Questa azione non è supportata per questo buffer" - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" -"Non si possono aggiungere ulteriori elementi in questo buffer. Utilizzare il " -"buffer per i messaggi diretti." - -#: ../src\controller\buffers\twitterBuffers.py:983 -msgid "{0} new followers." -msgstr "{0} Nuovo follower." - -#: ../src\controller\buffers\twitterBuffers.py:1266 -msgid "This action is not supported in the buffer, yet." -msgstr "Questa azione non è supportata per questo buffer" - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "Pronto" - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "Cronologie di..." - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "Cronologia di {}" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "Cronologie Favorite" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "A {} Piace" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Cronologie dei followers" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "Followers di {}" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Cronologie degli amici" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "Amici di {}" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "Liste" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "Lista per {}" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "Ricerca" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "Cerca per {0}" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "Argomenti di tendenza per %s" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "" -"Nessuna sessione focalizzata attualmente. Focalizzare una sessione con " -"l'apposito comando." - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "Svuota Elenco" - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0} Non trovato." - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "Il filtro non è supportato in questo buffer" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "Seleziona l'utente" - -#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236 -msgid "MMM D, YYYY. H:m" -msgstr "MMM D, YYYY. H:m" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "Conversazione con {0}" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "Non ci sono coordinate in questo Tweet" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "Nessun risultato per la ricerca in questo tweet" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "Errore durante l'autorizzazione. Riprovare più tardi." - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s, %s di %s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%s. Vuoto" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: Questo account non è connesso a Twitter." - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s di %s" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: Questo account non è connesso a Twitter." - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Notifiche" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "Questa lista è già aperta" - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "Errore durante la connessione al server. Per favore, riprova più tardi" - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "Attivata la lettura automatica per i nuovi tweet in questo buffer;" - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "Disattivata la lettura automatica per questo buffer;" - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "Sessione mute on" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "Sessione mute off" - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "Disattivato" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "Attivato" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "Copiato" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "Impossibile aggiornare questo buffer:" - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "Buffer aggiornato..." - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0} Elementi recuperati" - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "Buffer non valido " - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Questo tweet non contiene immagini" - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "Immagine {0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "Seleziona immagine" - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "Impossibile estrarre il testo" - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "Tradotto" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "Nessun URL da accorciare." - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URL accorciato." - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "Nessun URL da espandere" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URL espanso" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s di %d caratteri" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s Caratteri" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "Visualizza elemento" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Collegamento diretto" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "Richiesta" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "Retweet senza commenti" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "Retweet con commenti" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "Impostazioni Account per %s" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "Messaggi diretti" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "Errore" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "Questo utente non esiste su Twitter" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "L'utente è stato sospeso." - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "Informazioni per %s" - -#: ../src\controller\user.py:66 -#: ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "Scartato" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Nome utente: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Nome: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Localizzazione: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "Descrizione: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "Sì" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "No" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "Protetta: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "Stai seguendo {0}. " - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr "{0} ti sta seguendo." - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Followers: %s\n" -" Following: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "Verificato: %s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "Tweets: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "Mi Piace: %s" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "Non è possibile ignorare i messaggi diretti" - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "Allegando..." - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "&Riassumi" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "Riassumi" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "&Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "&Stop" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "Registrazione" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "Stoppato" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "&Registra" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "Riproduzione" - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "Ri&produci" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "Ricodifica audio ..." - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "Errore nel file in caricamento {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "%d giorno, " - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%d giorni, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "%d ora, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d ore, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "%d minuto, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d minuti, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "%s secondo" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s secondi" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "File" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "Trasferito" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "Dimensioni totali del file" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "Velocità di trasferimento" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "Tempo rimasto" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "Allega audio" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "&Allega un file esistente" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "&Scarta" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "Carica" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "Allega" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "&annulla" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "Selezionare il file audio da caricare" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "Audio tweet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "Il Buffer per la Cronologia dell'utente specifico è stato creato." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "Buffer eliminato." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "Messaggio diretto ricevuto" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "Messaggi diretto inviato" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "Errore" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "Tweet marcati con Mi Piace." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "Un Buffer segnato come Mi Piace è stato aggiornato." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "GeoTweet." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "Il Tweet contiene una o più immagini" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "Boundary reached." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "Lista aggiornata." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "Troppi caratteri" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "Menzione ricevuta." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "Nuovo evento" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0} TwBlue è pronto." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "Menzione Inviata" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "Tweet retweettati." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "Buffer della Ricerca aggiornato." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "Tweet ricevuto." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "Tweet inviato" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "Il buffer degli argomenti di tendenza è stato aggiornato." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "Nuovo tweet nel buffer della Cronologia utente specifico." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "Nuovo follower." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "Volume modificato." - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "Tutorial dei suoni" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "Premi Invio per ascoltare il suono dell'evento selezionato" - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "parola errata: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "Parola errata" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "Contesto" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "Suggerimenti" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "&Ignora" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "I&gnora tutto" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "S&ostituisci" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "Sost&ituisci tutto" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "&Aggiungi al dizionario personale" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"Errore. Non ci sono i dizionari disponibili per la lingua selezionata in {0}" - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "Controllo ortografico completato." - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "Inizia a scrivere" - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "Nessun risultato nel tuo Database utenti" - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "Il completamento automatico funziona solo per gli utenti." - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Aggiornamento del database... Si può ora chiudere questa finestra. Un " -"messaggio vi informerà Quando il processo termina." - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "Gestisci autocompletamento per gli utenti nel database" - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "Modificazione del {0} database degli utenti" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "Nome utente" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Nome" - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "Aggiungi utente" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "Rimuovi utente" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "Aggiungi utente al database" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "Nome utente Twitter" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "Questo utente non esiste su Twitter" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "Errore" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Impostazioni autocompletamento utenti" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Aggiungi utenti dall'elenco followers" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Aggiungi utenti dall'elenco dei following" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Gestisci database..." - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "Fatto!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "Il {0} database di TWBlue per gli utenti è stato aggiornato." - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "Rileva automaticamente" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "Danese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "Olandese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "Inglese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "Finlandese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "Francese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "Tedesco" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "Ungherese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "Italiano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "Giapponese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "Coreano" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "Polacco" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "Portoghese" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "Russo" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "Spagnolo" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "Turco" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "Africano" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "Albanese" - -#: ../src\extra\translator\translator.py:14 -msgid "Amharic" -msgstr "Amarico" - -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "Arabo" - -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "Armeno\"" - -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "Azerbaijano" - -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "Basco" - -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "BieloRusso" - -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "Bengalese" - -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "Bulgaro" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "Birmano" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "Catalano" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "Cherokee" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "Cinese" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "Cinese semplificato" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "Cinese tradizionale" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "Croato" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "Ceco" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "Esperanto" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "Estonian" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "Filippino" - -#: ../src\extra\translator\translator.py:40 -msgid "Galician" -msgstr "Galiziano" - -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "Georgiano" - -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "Greco" - -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "Guarani" - -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "Gujarati" - -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "Ebraico" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "Hindi" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "Islandese" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "Indonesiano" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "Irlandese" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "Kannada" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "Kazako" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "Khmer" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "Curdo" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "Kirghizistan" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "Laothian" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "Léttone" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "Lituano" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "Macedone" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "Malese" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "Malayalam" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "Maltese" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "Marathi" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "Mongolo" - -#: ../src\extra\translator\translator.py:70 -msgid "Nepali" -msgstr "Nepali" - -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "Norvegese" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr " Oriya" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "Pashto" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "Persiano" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "Punjabi" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "Romeno" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "Sanskrit" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" -msgstr "Serbo" - -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "Sindhi" - -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "Singalese" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "Slovacco" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "Sloveno" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "Swahili" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "Svedese" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "Tagiko" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "Tamil" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "Tagalog" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "Telugu" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "Thai" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "Tibetano" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "Ucraino" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "Uzbeko" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "Uighur" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "Vietnamese" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "Gallese" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "Yiddish" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "Traduci messaggio" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "Lingua di destinazione" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "Generale" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "Sempre" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "Nessun tentativo" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "Casualmente" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "Qualche volta" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "Impossibile duplicare" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "Blocca" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "Crash" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "caratteristica" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "Maggiore" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "Minore" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "Testo" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "Trivial" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "tweak" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "Riporta un errore" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "Seleziona una categoria" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "" -"Descrivi brevemente ciò che è accaduto. Sarete in grado di spiegare a fondo " -"in un secondo momento" - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "È possibile descrivere il bug in dettaglio quì:" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "Quante volte si verifica questo bug?" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "Selezionare il livello di importanza del bug" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Sono a conoscenza che il {0} sistema di bug otterrà il mio nome utente " -"Twitter per contattarmi e fissare il bug rapidamente" - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "Invia rapporto" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "annulla" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "È necessario compilare entrambi i campi" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Contrassegnare la casella di controllo per fornirci il tuo nome utente " -"Twitter per contattarvi se necessario." - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"Grazie per aver segnalato il bug! ;Nelle future versioni, si può essere in " -"grado di trovare nella lista delle modifiche. ;Hai segnalato il numero bug%i" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "segnalato" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "Errore nel segnalare" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Qualcosa di inaspettato si è verificato durante il tentativo di riportare il " -"bug. ;Per favore, riprova più tardi" - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Scorri verso l'alto" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "Scorri verso il basso " - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Vai al buffer precedente" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Vai al buffer successivo" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Focalizza la sessione successiva" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Focalizza la sessione precedente" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Mostra o nascondi GUI" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Nuovo tweet" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Retweet" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Invia un messaggio diretto" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "Mi Piace il tweet" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "Mi piace / Non Mi piace il tweet" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Non Mi piace il tweet" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Apri una finestra per selezionare un'azione" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Dettagli utente" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Visualizza Tweet" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "Esci" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Apri una specifica Cronologia per l'utente" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Elimina buffer" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interagisci con il tweet attualmente focalizzato." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Apri URL" - -#: ../src\keystrokeEditor\constants.py:25 -msgid "View in Twitter" -msgstr "Visualizza in Twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Aumenta Volume 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Diminuisce Volume 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Vai alla prima voce nel buffer attuale" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Vai all'ultima voce nel buffer attuale" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Salta 20 voci in alto nel buffer attuale" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Salta 20 voci in basso nel buffer attuale" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Modifica Profilo" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Elimina un tweet o un messaggio diretto" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Svuota Elenco" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Ripeti l'ultima voce" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Copia negli appunti" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Aggiungi alla lista" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Rimuovi dalla lista" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Mutes/unmutes il buffer corrente" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Mute/unmute la sessione corrente" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "" -"Attiva o disattiva la Lettura automatica per i nuovi tweet nel buffer " -"selezionato" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "Ricerca in Twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Trova del testo nel buffer attualmente focalizzato" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Visualizza il modificatore comandi" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Mostra le liste di un utente" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "Carica gli elementi precedenti" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Localizzazione" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Visualizza la localizzazione del Tweet in una finestra" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Crea un buffer per gli argomenti di tendenza" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Visualizza conversazione" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "Controlla e scarica aggiornamenti" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Apre il gestore lista, che consente di creare, modificare, eliminare e " -"aprire liste nei buffer." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Apri le impostazioni generali" - -#: ../src\keystrokeEditor\constants.py:54 -msgid "Opens the list manager" -msgstr "Apri il gestore liste" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Apri le impostazioni Account" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Prova ad avviare un audio." - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Aggiorna il buffer e recupera i possibili elementi persi." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "" -"Estrae il testo da un'immagine e visualizza il risultato in una finestra di " -"dialogo." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Modifica comando" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Seleziona il comando da modificare:" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "Comando" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "Azione" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "Modifica" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "Esegui" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "Chiudi" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "Modifica comando" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "Control" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "Shift" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "Windows" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "Key" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "OK" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "È necessario utilizzare il tasto Windows" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "Comando non valido" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "You must provide a character for the keystroke" - -#: ../src\languageHandler.py:99 -msgid "User default" -msgstr "Utente predefinito" - -#: ../src\main.py:105 -msgid "https://twblue.es/donate" -msgstr "https://twblue.es/donate" - -#: ../src\main.py:122 -msgid "" -"{0} is already running. Close the other instance before starting this one. " -"If you're sure that {0} isn't running, try deleting the file at {1}. If " -"you're unsure of how to do this, contact the {0} developers." -msgstr "" -"{0} è già in esecuzione. Chiudere altre istanze prima di avviare. Se sei " -"sicuro che {0} non è in esecuzione, provare a cancellare il file in {1}. Se " -"non sei sicuro di come si può fare, contattare gli sviluppatori {0}." - -#: ../src\sessionmanager\wxUI.py:8 -msgid "Session manager" -msgstr "Gestisci sessione." - -#: ../src\sessionmanager\wxUI.py:11 -msgid "Accounts list" -msgstr "Elenco Account" - -#: ../src\sessionmanager\wxUI.py:13 -msgid "Account" -msgstr "Account" - -#: ../src\sessionmanager\wxUI.py:17 -msgid "New account" -msgstr "Nuovo Account" - -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 -msgid "Remove account" -msgstr "Rimuovi account" - -#: ../src\sessionmanager\wxUI.py:19 -msgid "Global Settings" -msgstr "Impostazioni generali" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "Errore!" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "You need to configure an account." -msgstr "È necessario configurare un account." - -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "Autorizzazione" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "" -"The request to authorize your Twitter account will be opened in your " -"browser. You only need to do this once. Would you like to continue?" -msgstr "" -"La richiesta di autorizzazione per l'account di Twitter verrà aperto nel " -"browser. Questa operazione verrà richiesta solo una volta. Vuoi continuare?" - -#: ../src\sessionmanager\wxUI.py:52 -msgid "Authorized account %d" -msgstr "Account autorizzato %d" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "Chiave di autorizzazione utente non valido" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "" -"Your access token is invalid or the authorization has failed. Please try " -"again." -msgstr "" -"Il tuo token di accesso non è valido o l'autorizzazione non è riuscita. " -"Riprova." - -#: ../src\sessionmanager\wxUI.py:64 -msgid "Do you really want to delete this account?" -msgstr "Sei sicuro di voler eliminare questo account?" - -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 -msgid "dddd, MMMM D, YYYY H:m:s" -msgstr "dddd, MMMM D, YYYY H:m:s" - -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 -msgid "Dm to %s " -msgstr "Dm a %s " - -#: ../src\sessions\twitter\compose.py:141 -msgid "{0}. Quoted tweet from @{1}: {2}" -msgstr "{0}. Tweet citato da @{1}: {2}" - -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 -msgid "Unavailable" -msgstr "Non disponibile" - -#: ../src\sessions\twitter\compose.py:166 -msgid "" -"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " -"Twitter %s" -msgstr "" -"%s (@%s). %s followers, %s following, %s tweets. Ultimo tweet %s. Iscritto " -"a Twitter %s" - -#: ../src\sessions\twitter\compose.py:170 -msgid "No description available" -msgstr "Nessuna descrizione disponibile" - -#: ../src\sessions\twitter\compose.py:174 -msgid "private" -msgstr "Privato" - -#: ../src\sessions\twitter\compose.py:175 -msgid "public" -msgstr "Pubblico" - -#: ../src\sessions\twitter\session.py:169 -msgid "There are no more items to retrieve in this buffer." -msgstr "Non ci sono più elementi da recuperare in questo buffer." - -#: ../src\sessions\twitter\session.py:215 -msgid "%s failed. Reason: %s" -msgstr "%s Errore. Motivo: %s" - -#: ../src\sessions\twitter\session.py:221 -msgid "%s succeeded." -msgstr "%s Operazione riuscita." - -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "Spiacente, non sei autorizzato a visualizzare questo stato." - -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "Nessuno stato trovato per quel ID" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "codice di errore {0}" - -#: ../src\sessions\twitter\wxUI.py:6 -msgid "Authorising account..." -msgstr "Autorizzazione dell'Account..." - -#: ../src\sessions\twitter\wxUI.py:9 -msgid "Enter your PIN code here" -msgstr "Inserire il codice PIN quì" - -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "Arrestato." - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "Nuova versione di %s" - -#: ../src\update\wxUpdater.py:10 -msgid "" -"There's a new %s version available, released on %s. Would you like to " -"download it now?\n" -"\n" -" %s version: %s\n" -"\n" -"Changes:\n" -"%s" -msgstr "" -"È disponibile una nuova versione %s, rilasciata il %s. Scaricarla ora?\n" -"\n" -" %s versione: %s\n" -"\n" -"Change:\n" -"%s" - -#: ../src\update\wxUpdater.py:18 -msgid "Download in Progress" -msgstr "Download in corso" - -#: ../src\update\wxUpdater.py:18 -msgid "Downloading the new version..." -msgstr "Download della nuova versione..." - -#: ../src\update\wxUpdater.py:28 -msgid "Updating... %s of %s" -msgstr "Aggiornamento... %s di %s" - -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "Fatto!" - -#: ../src\update\wxUpdater.py:31 -msgid "" -"The update has been downloaded and installed successfully. Press OK to " -"continue." -msgstr "" -"La nuova versione TW blu è stata scaricata e installata. Premere OK per " -"avviare l'applicazione." - -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "Client" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Testo" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "Data" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "Utente" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "Messaggio diretto" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "Evento" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "Rimuovere evento" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "Connetti" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "Login automatico" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "Disconnetti" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "Tendenze" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "Tweet riguardo questa tendenza" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "Cerca argomento" - -#: ../src\wxUI\commonMessageDialogs.py:6 -msgid "" -"This retweet is over 140 characters. Would you like to post it as a mention " -"to the poster with your comments and a link to the original tweet?" -msgstr "" -"Questo retweet ha superato i 140 caratteri. Preferisci pubblicarlo come una " -"menzione all'autore del post con i vostri commenti e un link per il tweet " -"originale?" - -#: ../src\wxUI\commonMessageDialogs.py:9 -msgid "Would you like to add a comment to this tweet?" -msgstr "Vuoi aggiungere un commento a questo tweet?" - -#: ../src\wxUI\commonMessageDialogs.py:12 -msgid "" -"Do you really want to delete this tweet? It will be deleted from Twitter as " -"well." -msgstr "Vuoi eliminare il tweet? Questo sarà cancellato anche da Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 -msgid "Delete" -msgstr "Elimina Tweet" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Do you really want to close {0}?" -msgstr "Sei sicuro di voler chiudere {0}?" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Exit" -msgstr "Esci" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid " {0} must be restarted for these changes to take effect." -msgstr " {0} Riavviare perché le modifiche abbiano effetto." - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid "Restart {0} " -msgstr "Riavvia {0}" - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "" -"Are you sure you want to delete this user from the database? This user will " -"not appear in autocomplete results anymore." -msgstr "" -"Sei sicuro di voler eliminare questo utente dal database? Questo utente non " -"apparirà nei risultati di completamento automatico." - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "Confirm" -msgstr "Conferma" - -#: ../src\wxUI\commonMessageDialogs.py:25 -msgid "Enter the name of the client : " -msgstr "Inserire il nome del cliente" - -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 -msgid "Add client" -msgstr "Aggiungi client" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "" -"Do you really want to empty this buffer? It's items will be removed from " -"the list but not from Twitter" -msgstr "" -"Svuotare questo buffer? I tweet saranno rimossi dall'elenco, ma non da " -"Twitter" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "Empty buffer" -msgstr "Svuota Elenco" - -#: ../src\wxUI\commonMessageDialogs.py:35 -msgid "Do you really want to destroy this buffer?" -msgstr "Sei sicuro di voler eliminare questo buffer?" - -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Attention" -msgstr "Attenzione" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "A timeline for this user already exists. You can't open another" -msgstr "Una Cronologia per questo utente è già presente." - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "Existing timeline" -msgstr "Cronologia già esistente" - -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "This user has no tweets, so you can't open a timeline for them." -msgstr "" -"Questo utente non ha tweets. Non è possibile aprire una Cronologia per " -"questo utente" - -#: ../src\wxUI\commonMessageDialogs.py:47 -msgid "" -"This is a protected Twitter user, which means you can't open a timeline " -"using the Streaming API. The user's tweets will not update due to a twitter " -"policy. Do you want to continue?" -msgstr "" -"Questo è un account twitter protetto. Non è possibile aprire una Cronologia " -"utilizzando l'API Streaming. I Tweet dell'utente non verranno aggiornati a " -"causa di una politica di Twitter. Vuoi continuare?" - -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "Warning" -msgstr "Avviso" - -#: ../src\wxUI\commonMessageDialogs.py:50 -msgid "" -"This is a protected user account, you need to follow this user to view their " -"tweets or likes." -msgstr "" -"Questo è un account utente protetto, è necessario seguire l'utente per " -"visualizzare i suoi tweet o preferiti." - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "" -"If you like {0} we need your help to keep it going. Help us by donating to " -"the project. This will help us pay for the server, the domain and some other " -"things to ensure that {0} will be actively maintained. Your donation will " -"give us the means to continue the development of {0}, and to keep {0} free. " -"Would you like to donate now?" -msgstr "" -"Se ti piace {0} ricorda che abbiamo bisogno del vostro aiuto per andare " -"avanti. Aiutaci facendo una donazione per il progetto. Questo ci aiuterà a " -"pagare il server, il dominio e alcune altre cose per garantire che {0} Sarà " -"attivamente sostenuto. La vostra donazione ci darà i mezzi per continuare lo " -"sviluppo di {0}, e mantenere {0} free. Vuoi fare una donazione adesso?" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "We need your help" -msgstr "Abbiamo bisogno del tuo aiuto" - -#: ../src\wxUI\commonMessageDialogs.py:57 -msgid "This user has no tweets. {0} can't create a timeline." -msgstr "" -"Questo utente non ha tweets. {0} non può creare una Cronologia per questo " -"utente" - -#: ../src\wxUI\commonMessageDialogs.py:60 -msgid "This user has no favorited tweets. {0} can't create a timeline." -msgstr "" -"Questo utente non ha tweets preferiti. {0} non può creare una Cronologia per " -"questo utente" - -#: ../src\wxUI\commonMessageDialogs.py:63 -msgid "This user has no followers. {0} can't create a timeline." -msgstr "" -"Non stai seguendo questo utente . {0} non è possibile creare una Cronologia." - -#: ../src\wxUI\commonMessageDialogs.py:66 -msgid "This user has no friends. {0} can't create a timeline." -msgstr "" -"Questo utente non è tra gli amici. {0} non è possibile creare una Cronologia." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "Informazioni geografiche per questo tweet." - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geolocation data: {0}" -msgstr "Geolocalizzazione data: {0}" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "Informazioni:" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "" -"TWBlue has detected that you're running windows 10 and has changed the " -"default keymap to the Windows 10 keymap. It means that some keyboard " -"shorcuts could be different. Please check the keystroke editor by pressing " -"Alt+Win+K to see all available keystrokes for this keymap." -msgstr "" -"TWBlue ha rilevato che si sta eseguendo windows 10 ed ha cambiato la " -"mappatura dei tasti di default per Windows 10. Ciò significa che alcuni " -"tasti di scelta rapida della tastiera potrèbbero essere diversi. Si " -"consiglia di controllare l'editor dei tasti rapidi premendo Alt+Win+K per " -"visualizzare tutti i tasti rapidi disponibili per questa mappatura di " -"tasti. " - -#: ../src\wxUI\commonMessageDialogs.py:76 -msgid "You have been blocked from viewing this content" -msgstr "Impossibile visualizzare il contenuto perché sei stato bloccato." - -#: ../src\wxUI\commonMessageDialogs.py:79 -msgid "" -"You have been blocked from viewing someone's content. In order to avoid " -"conflicts with the full session, TWBlue will remove the affected timeline." -msgstr "" -"Sei stato bloccato e non puoi visualizzare alcun contenuto. Al fine di " -"evitare conflitti con l'intera sezione, TWblue rimuoverà la relativa " -"cronologia. " - -#: ../src\wxUI\commonMessageDialogs.py:82 -msgid "" -"TWBlue cannot load this timeline because the user has been suspended from " -"Twitter." -msgstr "" -"TWBlue non può caricare la cronologia perché l'utente è stato sospeso da " -"Twitter." - -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Do you really want to delete this filter?" -msgstr "Sei sicuro di voler eliminare questo filtro??" - -#: ../src\wxUI\commonMessageDialogs.py:88 -msgid "This filter already exists. Please use a different title" -msgstr "Questo filtro è già esistente. Utilizzare un altro titolo" - -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "" -"{0} quit unexpectedly the last time it was run. If the problem persists, " -"please report it to the {0} developers." -msgstr "" -"Si è verificato un errore nell'ultima chiusura di {0}. Se il problema " -"persiste, segnalare l'errore agli sviluppatori di {0}." - -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Aggiungi allegato" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Allegati" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Titolo" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Tipo" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Aggiungi allegato" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "&Foto" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Rimuovi allegato" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "File di immagine (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Seleziona l'immagine da caricare" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Aggiungi una descrizione" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Descrizione" - -#: ../src\wxUI\dialogs\configuration.py:16 -msgid "Language" -msgstr "Lingua" - -#: ../src\wxUI\dialogs\configuration.py:23 -msgid "Run {0} at Windows startup" -msgstr "Avvia {0} all'avvio di Windows." - -#: ../src\wxUI\dialogs\configuration.py:24 -msgid "ask before exiting {0}" -msgstr "Conferma prima di uscire da {0}" - -#: ../src\wxUI\dialogs\configuration.py:27 -msgid "Disable Streaming functions" -msgstr "Disattiva le funzioni di Streaming" - -#: ../src\wxUI\dialogs\configuration.py:30 -msgid "Buffer update interval, in minutes" -msgstr "Intervallo d aggiornamento del buffer, in minuti" - -#: ../src\wxUI\dialogs\configuration.py:36 -msgid "Play a sound when {0} launches" -msgstr "Riproduci un suono {0} all'avvio" - -#: ../src\wxUI\dialogs\configuration.py:38 -msgid "Speak a message when {0} launches" -msgstr "Avvisa con un messaggio {0} all'avvio" - -#: ../src\wxUI\dialogs\configuration.py:40 -msgid "Use invisible interface's keyboard shortcuts while GUI is visible" -msgstr "" -"Utilizza i comandi per l'interfaccia invisibile nell'interfaccia grafica" - -#: ../src\wxUI\dialogs\configuration.py:42 -msgid "Activate Sapi5 when any other screen reader is not being run" -msgstr "Attiva SAPI5 quando non viene eseguito un altro lettore di schermo" - -#: ../src\wxUI\dialogs\configuration.py:44 -msgid "Hide GUI on launch" -msgstr "Nascondi Interfaccia grafica all'avvio" - -#: ../src\wxUI\dialogs\configuration.py:46 -msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" -msgstr "Lettura completa dei tweet (Può ridurre le prestazioni del client)" - -#: ../src\wxUI\dialogs\configuration.py:48 -msgid "Remember state for mention all and long tweet" -msgstr "Riporta stato per i tweet lunghi e l'opzione Menziona tutti." - -#: ../src\wxUI\dialogs\configuration.py:51 -msgid "Keymap" -msgstr "Keymap" - -#: ../src\wxUI\dialogs\configuration.py:56 -msgid "Check for updates when {0} launches" -msgstr "Controlla aggiornamenti all'avvio di {0} " - -#: ../src\wxUI\dialogs\configuration.py:66 -msgid "Proxy type: " -msgstr "Servizio Proxy: " - -#: ../src\wxUI\dialogs\configuration.py:73 -msgid "Proxy server: " -msgstr "Proxy server: " - -#: ../src\wxUI\dialogs\configuration.py:79 -msgid "Port: " -msgstr "Port: " - -#: ../src\wxUI\dialogs\configuration.py:85 -msgid "User: " -msgstr "Utente" - -#: ../src\wxUI\dialogs\configuration.py:91 -msgid "Password: " -msgstr "Password: " - -#: ../src\wxUI\dialogs\configuration.py:103 -msgid "Autocompletion settings..." -msgstr "impostazioni di autocompletamento..." - -#: ../src\wxUI\dialogs\configuration.py:105 -msgid "Relative timestamps" -msgstr "Mostra tempo di ricezione trascorso" - -#: ../src\wxUI\dialogs\configuration.py:108 -msgid "Items on each API call" -msgstr "Elementi per ogni chiamata API " - -#: ../src\wxUI\dialogs\configuration.py:114 -msgid "" -"Inverted buffers: The newest tweets will be shown at the beginning while the " -"oldest at the end" -msgstr "" -"Inverti elenco: I nuovi tweets verranno mostrate in cima all'elenco, i " -"precedenti alla fine" - -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet mode" -msgstr "Retweet mode" - -#: ../src\wxUI\dialogs\configuration.py:122 -msgid "Show screen names instead of full names" -msgstr "Visualizza nome del riquadro al posto del nome completo" - -#: ../src\wxUI\dialogs\configuration.py:124 -msgid "" -"Number of items per buffer to cache in database (0 to disable caching, blank " -"for unlimited)" -msgstr "" -"Numero di voci per buffer per la cache nel database (0 per disabilitare " -"caching, vuoto per un numero illimitato)" - -#: ../src\wxUI\dialogs\configuration.py:134 -msgid "Enable automatic speech feedback" -msgstr "Attiva automaticamente il feedback vocale" - -#: ../src\wxUI\dialogs\configuration.py:136 -msgid "Enable automatic Braille feedback" -msgstr "Attiva automaticamente il feedback braille." - -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Stato" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Buffer" -msgstr "Buffer" - -#: ../src\wxUI\dialogs\configuration.py:147 -msgid "Show/hide" -msgstr "Mostra/Nascondi" - -#: ../src\wxUI\dialogs\configuration.py:148 -msgid "Move up" -msgstr "Sposta su" - -#: ../src\wxUI\dialogs\configuration.py:149 -msgid "Move down" -msgstr "Sposta Giù" - -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 -msgid "Show" -msgstr "Mostra" - -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 -msgid "Hide" -msgstr "Nascondi" - -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 -msgid "Select a buffer first." -msgstr "Selezionare un buffer." - -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 -msgid "The buffer is hidden, show it first." -msgstr "Il buffer è nascosto." - -#: ../src\wxUI\dialogs\configuration.py:175 -msgid "The buffer is already at the top of the list." -msgstr "Il buffer è già in cima alla lista." - -#: ../src\wxUI\dialogs\configuration.py:199 -msgid "The buffer is already at the bottom of the list." -msgstr "Il buffer è già in fondo all'elenco." - -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 -msgid "Ignored clients" -msgstr "Ignora clients" - -#: ../src\wxUI\dialogs\configuration.py:247 -msgid "Remove client" -msgstr "Rimuovi client" - -#: ../src\wxUI\dialogs\configuration.py:271 -msgid "Volume" -msgstr "Volume" - -#: ../src\wxUI\dialogs\configuration.py:282 -msgid "Session mute" -msgstr "sessione mute" - -#: ../src\wxUI\dialogs\configuration.py:284 -msgid "Output device" -msgstr "Dispositivo di uscita" - -#: ../src\wxUI\dialogs\configuration.py:291 -msgid "Input device" -msgstr "Dispositivo di input" - -#: ../src\wxUI\dialogs\configuration.py:299 -msgid "Sound pack" -msgstr "Pacchetto audio" - -#: ../src\wxUI\dialogs\configuration.py:305 -msgid "Indicate audio tweets with sound" -msgstr "Avvisa con un suono per i tweet audio:" - -#: ../src\wxUI\dialogs\configuration.py:307 -msgid "Indicate geotweets with sound" -msgstr "Avvisa con un suono la geolocalizzazione dei tweet" - -#: ../src\wxUI\dialogs\configuration.py:309 -msgid "Indicate tweets containing images with sound" -msgstr "Avvisa con un suono i tweet con immagini" - -#: ../src\wxUI\dialogs\configuration.py:332 -msgid "Language for OCR" -msgstr "Lingua per l'OCR" - -#: ../src\wxUI\dialogs\configuration.py:338 -msgid "API Key for SndUp" -msgstr "API Key per SndUp" - -#: ../src\wxUI\dialogs\configuration.py:353 -msgid "{0} preferences" -msgstr "{0} Preferenze" - -#: ../src\wxUI\dialogs\configuration.py:364 -msgid "Proxy" -msgstr "Proxy" - -#: ../src\wxUI\dialogs\configuration.py:373 -msgid "Feedback" -msgstr "Feedback " - -#: ../src\wxUI\dialogs\configuration.py:377 -msgid "Buffers" -msgstr "Buffers" - -#: ../src\wxUI\dialogs\configuration.py:385 -msgid "Sound" -msgstr "Audio" - -#: ../src\wxUI\dialogs\configuration.py:389 -msgid "Extras" -msgstr "Extra" - -#: ../src\wxUI\dialogs\configuration.py:394 -msgid "Save" -msgstr "Salva" - -#: ../src\wxUI\dialogs\filterDialogs.py:15 -msgid "Create a filter for this buffer" -msgstr "Crea un filtro per questo buffer" - -#: ../src\wxUI\dialogs\filterDialogs.py:16 -msgid "Filter title" -msgstr "Titolo del filtro" - -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "Filtra per parola" - -#: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "Ignora i tweet che contengono questa parola" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -msgid "Ignore tweets without the following word" -msgstr "Ignora i tweet che non contengono questa parola" - -#: ../src\wxUI\dialogs\filterDialogs.py:32 -msgid "word" -msgstr "Parola" - -#: ../src\wxUI\dialogs\filterDialogs.py:37 -msgid "Allow retweets" -msgstr "Consenti retweet" - -#: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "Consenti i tweet con citazione" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -msgid "Allow replies" -msgstr "Consenti risposte" - -#: ../src\wxUI\dialogs\filterDialogs.py:47 -msgid "Use this term as a regular expression" -msgstr "Usa questo elemento come espressione regolare" - -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by language" -msgstr "Filtra per lingua" - -#: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "Carica i tweet nelle seguenti lingue" - -#: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "Ignora i tweet nelle seguenti lingue" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 -msgid "Don't filter by language" -msgstr "Non filtrare per lingua" - -#: ../src\wxUI\dialogs\filterDialogs.py:63 -msgid "Supported languages" -msgstr "Lingue supportate" - -#: ../src\wxUI\dialogs\filterDialogs.py:68 -msgid "Add selected language to filter" -msgstr "Aggiungi la lingua selezionata per il filtro" - -#: ../src\wxUI\dialogs\filterDialogs.py:72 -msgid "Selected languages" -msgstr "Lingue selezionate" - -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 -msgid "Remove" -msgstr "Elimina" - -#: ../src\wxUI\dialogs\filterDialogs.py:122 -msgid "Manage filters" -msgstr "Gestione filtri" - -#: ../src\wxUI\dialogs\filterDialogs.py:124 -msgid "Filters" -msgstr "Filtri" - -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter" -msgstr "Firltro" - -#: ../src\wxUI\dialogs\find.py:12 -msgid "Find in current buffer" -msgstr "Trova nel buffer corrente" - -#: ../src\wxUI\dialogs\find.py:13 -msgid "String" -msgstr "Stringa" - -#: ../src\wxUI\dialogs\lists.py:10 -msgid "Lists manager" -msgstr "Gestione liste" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "List" -msgstr "Lista" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "Membri" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Owner" -msgstr "Proprietario" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "mode" -msgstr "Modalità" - -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 -msgid "Create a new list" -msgstr "Crea nuova lista" - -#: ../src\wxUI\dialogs\lists.py:21 -msgid "Open in buffer" -msgstr "Apri nel buffer" - -#: ../src\wxUI\dialogs\lists.py:51 -msgid "Viewing lists for %s" -msgstr "Visualizzazione delle liste per %s" - -#: ../src\wxUI\dialogs\lists.py:52 -msgid "Subscribe" -msgstr "Iscriviti" - -#: ../src\wxUI\dialogs\lists.py:53 -msgid "Unsubscribe" -msgstr "Disiscriviti" - -#: ../src\wxUI\dialogs\lists.py:64 -msgid "Name (20 characters maximun)" -msgstr "Nome (massimo 20 caratteri)" - -#: ../src\wxUI\dialogs\lists.py:74 -msgid "Mode" -msgstr "Modalità" - -#: ../src\wxUI\dialogs\lists.py:75 -msgid "Public" -msgstr "Pubblico" - -#: ../src\wxUI\dialogs\lists.py:76 -msgid "Private" -msgstr "Privato" - -#: ../src\wxUI\dialogs\lists.py:96 -msgid "Editing the list %s" -msgstr "Modifica elenco %s" - -#: ../src\wxUI\dialogs\lists.py:107 -msgid "Select a list to add the user" -msgstr "Seleziona una lista per aggiungere l'utente" - -#: ../src\wxUI\dialogs\lists.py:108 -msgid "Add" -msgstr "Aggiungi" - -#: ../src\wxUI\dialogs\lists.py:130 -msgid "Select a list to remove the user" -msgstr "Seleziona una lista per rimuovere l'utente" - -#: ../src\wxUI\dialogs\lists.py:148 -msgid "Do you really want to delete this list?" -msgstr "Sei sicuro di voler eliminare questa lista?" - -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "&Long tweet" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Carica immagine..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Controllo &ortografico..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "A&llega audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Accorcia &URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "&Espandi URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "&Traduci..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "&completamento automatico per gli utenti" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "In&via" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "&Chiudi" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "Destinata&rio" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "Menziona a &tutti" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tweet -% i caratteri " - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Descrizione Immagine" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retweet" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Mi piace: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Lingua d'origine" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -msgid "Date: " -msgstr "Data:" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Visualizza" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Elemento" - -#: ../src\wxUI\dialogs\search.py:13 -msgid "Search on Twitter" -msgstr "Ricerca in Twitter" - -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "&Ricerca" - -#: ../src\wxUI\dialogs\search.py:21 -msgid "Tweets" -msgstr "Tweet" - -#: ../src\wxUI\dialogs\search.py:22 -msgid "Users" -msgstr "Utente" - -#: ../src\wxUI\dialogs\search.py:29 -msgid "&Language for results: " -msgstr "&Lingua per i risultati:" - -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 -msgid "any" -msgstr "Qualsiasi" - -#: ../src\wxUI\dialogs\search.py:37 -msgid "Results &type: " -msgstr "Results &type: " - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 -msgid "Mixed" -msgstr "Misto" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 -msgid "Recent" -msgstr "Recenti" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 -msgid "Popular" -msgstr "Popolari" - -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 -msgid "&OK" -msgstr "&Ok" - -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 -msgid "&Close" -msgstr "&Chiudi" - -#: ../src\wxUI\dialogs\show_user.py:11 -msgid "Details" -msgstr "Dettagli" - -#: ../src\wxUI\dialogs\show_user.py:16 -msgid "&Go to URL" -msgstr "&Vai all'URL" - -#: ../src\wxUI\dialogs\trends.py:12 -msgid "View trending topics" -msgstr "Visualizza tendenze" - -#: ../src\wxUI\dialogs\trends.py:13 -msgid "Trending topics by" -msgstr "Tendenze per" - -#: ../src\wxUI\dialogs\trends.py:15 -msgid "Country" -msgstr "Paese" - -#: ../src\wxUI\dialogs\trends.py:16 -msgid "City" -msgstr "Città" - -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 -msgid "&Location" -msgstr "&Localizzazione, esterno" - -#: ../src\wxUI\dialogs\update_profile.py:9 -msgid "Update your profile" -msgstr "Aggiorna il tuo profilo" - -#: ../src\wxUI\dialogs\update_profile.py:11 -msgid "&Name (50 characters maximum)" -msgstr "&Nome (massimo 50 caratteri)" - -#: ../src\wxUI\dialogs\update_profile.py:22 -msgid "&Website" -msgstr "Sito &web" - -#: ../src\wxUI\dialogs\update_profile.py:27 -msgid "&Bio (160 characters maximum)" -msgstr "&Descrizione (massimo 160 caratteri)" - -#: ../src\wxUI\dialogs\update_profile.py:33 -msgid "Upload a &picture" -msgstr "Carica una &foto" - -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "Aggiorna il &profilo" - -#: ../src\wxUI\dialogs\update_profile.py:76 -msgid "Upload a picture" -msgstr "Carica una foto" - -#: ../src\wxUI\dialogs\update_profile.py:78 -msgid "Discard image" -msgstr "Scartare immagine" - -#: ../src\wxUI\dialogs\urlList.py:5 -msgid "Select URL" -msgstr "Selezionare URL" - -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "&Utente" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 -msgid "&Autocomplete users" -msgstr "&completamento automatico per gli utenti" - -#: ../src\wxUI\dialogs\userActions.py:19 -msgid "&Follow" -msgstr "&Segui" - -#: ../src\wxUI\dialogs\userActions.py:20 -msgid "U&nfollow" -msgstr "&Non seguire" - -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "&Mute" - -#: ../src\wxUI\dialogs\userActions.py:22 -msgid "Unmu&te" -msgstr "U&nmute" - -#: ../src\wxUI\dialogs\userActions.py:23 -msgid "&Block" -msgstr "&Blocca" - -#: ../src\wxUI\dialogs\userActions.py:24 -msgid "Unbl&ock" -msgstr "&Sblocca" - -#: ../src\wxUI\dialogs\userActions.py:25 -msgid "&Report as spam" -msgstr "Segnala come spa&m" - -#: ../src\wxUI\dialogs\userActions.py:26 -msgid "&Ignore tweets from this client" -msgstr "&Ignora tweet da questo client" - -#: ../src\wxUI\dialogs\userSelection.py:9 -msgid "Timeline for %s" -msgstr "Cronologia di %s" - -#: ../src\wxUI\dialogs\userSelection.py:18 -msgid "Buffer type" -msgstr "Tipo di Buffer" - -#: ../src\wxUI\dialogs\userSelection.py:19 -msgid "&Tweets" -msgstr "&Tweet" - -#: ../src\wxUI\dialogs\userSelection.py:20 -msgid "&Likes" -msgstr "Mi &piace" - -#: ../src\wxUI\dialogs\userSelection.py:21 -msgid "&Followers" -msgstr "&Followers" - -#: ../src\wxUI\dialogs\userSelection.py:22 -msgid "F&riends" -msgstr "Followin&g" - -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "&Retweet" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "&Rispondi" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "&Mi Piace" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "&Non Mi Piace" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "C&ollegamento alla pagina..." - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -msgid "&Open in Twitter" -msgstr "&Apri in Twitter" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "A&vvia audio" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "&Visualizza Tweet" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "&Copia negli appunti" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "&Elimina Tweet" - -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "&Azioni utente..." - -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "Visualizza me&ssaggio diretto" - -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "&Mostra evento" - -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "&Messaggio diretto" - -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "&Visualizza liste" - -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "Visualizza il profilo &utente" - -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "&Visualizza utente" - -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "&Tweet su questa tendenza" - -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "&Visualizza voci" - -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "Impostazioni &generali" - -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "Impos&tazioni Account " - -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "Aggiorna il &profilo" - -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "&Mostra/ Nascondi" - -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "&Documentazione" - -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "Controlla &aggiornamenti" - -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "&Esci" - -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "Gestisci &accounts" - -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "&Nascondi la finestra" - -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "Gestione &liste" - -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "&Modifica comandi" - -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "&Esci" - -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "&Tweet" - -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "Visualizza &indirizzo" - -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "Visualizza &conversazione" - -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "Lettura testo da un immagine" - -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "Scegli &Azione..." - -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "&Visualizza la Cronologia..." - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "Messaggio &diretto" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "Aggiungi alla &lista" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "&Rimuovi dalla lista" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "&Visualizza tweet marcati con Mi Piace" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "&aggiorna buffer" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "Nuovo buffer per argomenti di &tendenza..." - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "Crea &filtro" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "Gestisci fi<ri" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "Trova del testo nel buffer attualmente focalizzato" - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "&Carica le voci precedenti" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "Lettu&ra automatica" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "Ripulisci l'elen&co" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "&Elimina" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "Indietro 5 &secondi" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "Avanti 5 &secondi" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "&Tutorial dei suoni" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "Cosa c'è di &nuovo in questa versione?" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "Controlla &aggiornamenti" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "Riporta un &errore" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "{0} Sito &Web di TW Blue" - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "Ottieni soundpacks per TWBlue" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "A proposito di &{0}" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "&Applicazione" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "&Buffer" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "&Audio" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "A&iuto" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "Indirizzo" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "Aggiorna" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "La tua versione di {0} è aggiornata" - -#~ msgid "Empty" -#~ msgstr "Vuoto" - -#~ msgid "One mention from %s " -#~ msgstr "Una menzione da %s " - -#~ msgid "One tweet from %s" -#~ msgstr "Un tweet da %s" - -#~ msgid "You've blocked %s" -#~ msgstr "Hai bloccato %s" - -#~ msgid "You've unblocked %s" -#~ msgstr "Hai sbloccato %s" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "%s(@%s) ti sta seguendo" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "Stai seguendo %s(@%s)" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "Non stai più seguendo %s (@%s)" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "Ti Piace questo tweet: %s, %s" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "A %s(@%s) gli piace: %s" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "Non ti piace %s, %s" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "A %s(@%s) non gli piace: %s" - -#~ msgid "You've created the list %s" -#~ msgstr "Hai creato la lista %s" - -#~ msgid "You've deleted the list %s" -#~ msgstr "Hai eliminato la lista %s" - -#~ msgid "You've updated the list %s" -#~ msgstr "Hai aggiornato la lista %s" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "Hai aggiunto %s(@%s) alla lista %s" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "%s(@%s) ti ha aggiunto alla lista%s" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "Hai rimosso %s(@%s) dalla lista %s" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "%s(@%s) ti ha rimosso dalla lista %s" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "Ti sei iscritto alla lista %s, creata da %s(@%s)" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "%s(@%s) ti ha aggiunto alla lista %s" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Hai annullato l'iscrizione dalla lista %s, creata da %s(@%s)" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "Sei stato cancellato dalla lista %s, creata da %s(@%s)" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "Hai retweettato con un retweet da %s(@%s): %s" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "%s(@%s) Ha rituittato un tuo retweet: %s" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "Chiamate API quando viene avviato il flusso (Una chiamata API equivale a " -#~ "200 tweetts, due chiamate API equivale a 400 tweets," - -#~ msgid "Unable to upload the audio" -#~ msgstr "Impossibile caricare l'audio" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "Attendere per l'autorizzazione..." - -#~ msgid "autodetect" -#~ msgstr "Rilevamento automatico" - -#~ msgid "" -#~ "There's a new %s version available. Would you like to download it now?\n" -#~ "\n" -#~ " %s version: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" -#~ msgstr "" -#~ "La nuova versione %s è disponibile. Desìderi scaricarla ora?\n" -#~ "\n" -#~ " %s versione: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" - -#~ msgid "Start {0} after logging in windows" -#~ msgstr "Avvia {0} dopo l'accesso a Windows" - -#~ msgid "" -#~ "If you have a SndUp account, enter your API Key here. If your API Key is " -#~ "invalid, {0} will fail to upload. If there is no API Key here, {0} will " -#~ "upload annonymously." -#~ msgstr "" -#~ "Se avete un account SndUp, inserisci la tua API Key quì. Se l'API Key è " -#~ "sbagliata, {0} non si carica. Se non è presente una API key, {0} si " -#~ "caricherà anonimamente" - -#~ msgid "Disconnect your Pocket account" -#~ msgstr "Scollegare il tuo account Pocket" - -#~ msgid "Connect your Pocket account" -#~ msgstr "Collega il tuo account di Pocket" - -#~ msgid "Pocket Authorization" -#~ msgstr "Autorizzazione Pocket" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. You only need " -#~ "to do this once. Do you want to continue?" -#~ msgstr "" -#~ "La richiesta di autorizzazione si aprirà nel browser. Questa operazione " -#~ "verrà richiesta solo una volta. Vuoi continuare?" - -#~ msgid "Error during authorization. Try again later." -#~ msgstr "Errore durante l'autorizzazione. Riprovare più tardi." - -#~ msgid "Services" -#~ msgstr "Servizi" - -#~ msgid "Contains" -#~ msgstr "Contenuto" - -#~ msgid "Doesn't contain" -#~ msgstr "Senza contenuto" - -#~ msgid "" -#~ "You have successfully logged into Twitter with {0}. You can close this " -#~ "window now." -#~ msgstr "" -#~ "Connessione a Twitter con {0} riuscita. È possibile chiudere questa " -#~ "finestra." - -#~ msgid "&Send" -#~ msgstr "&Invia" - -#~ msgid "Spelling correction" -#~ msgstr "Correzione ortografica" - -#~ msgid "Shorten URL" -#~ msgstr "Accorcia URL" - -#~ msgid "Expand URL" -#~ msgstr "Espandi URL" - -#~ msgid "Send" -#~ msgstr "Invia" - -#~ msgid "unavailable" -#~ msgstr "Non disponibile" - -#~ msgid "Search" -#~ msgstr "Ricerca" - -#~ msgid "Update profile" -#~ msgstr "Aggiorna il profilo" - -#~ msgid "Follow" -#~ msgstr "Segui" - -#~ msgid "Mute" -#~ msgstr "Mute" - -#~ msgid "Block" -#~ msgstr "Blocca" - -#~ msgid "Report as spam" -#~ msgstr "Segnala come spam" - -#~ msgid "Favourites" -#~ msgstr "Favoriti" - -#~ msgid "Favourites timeline for {}" -#~ msgstr "Cronologia Favoriti di {0}" - -#~ msgid "Tweet favourited." -#~ msgstr "Tweet preferiti." - -#~ msgid "Mark as favourite" -#~ msgstr "Aggiungi ai preferiti" - -#~ msgid "Remove from favourites" -#~ msgstr "Rimuovi dai favoriti" - -#~ msgid "You've added to favourites: %s, %s" -#~ msgstr "Hai aggiunto ai preferiti: %s, %s" - -#~ msgid "%s(@%s) has marked as favourite: %s" -#~ msgstr "%s(@%s) ha segnato come preferito: %s" - -#~ msgid "You've removed from favourites: %s, %s" -#~ msgstr " Hai rimosso dai preferiti: %s, %s" - -#~ msgid "%s(@%s) has removed from favourites: %s" -#~ msgstr "%s(@%s) è stato rimosso dai preferiti: %s" - -#~ msgid "Favourites: " -#~ msgstr "Preferiti: " - -#~ msgid "Add to &favourites" -#~ msgstr "&Aggiungi ai preferiti" - -#~ msgid "Remove from favo&urites" -#~ msgstr "&Rimuovi dai favoriti" - -#~ msgid "V&iew favourites" -#~ msgstr "Visualizza &preferiti" - -#~ msgid "Opening media..." -#~ msgstr "Apertura contenuto multimediale..." - -#~ msgid "Add a new ignored client" -#~ msgstr "Aggiunto un nuovo client ignorato" - -#~ msgid "Do you really want to delete this timeline?" -#~ msgstr "Eliminare la Cronologia?" - -#~ msgid "Autocomplete users\\342\\200\\231 settings" -#~ msgstr "Autocomplete users\\342\\200\\231 Impostazioni" - -#~ msgid "Set the autocomplete function" -#~ msgstr "Imposta la funzione di completamento automatico" - -#~ msgid "Relative times" -#~ msgstr "Mostra tempo di ricezione trascorso" - -#~ msgid "" -#~ "API calls when the stream is started (One API call equals to 200 tweetts, " -#~ "two API calls equals 400 tweets, etc):" -#~ msgstr "" -#~ "Chiamate API quando viene avviato il flusso (Una chiamata API equivale a " -#~ "200 tweetts, due chiamate API equivale a 400 tweets," - -#~ msgid "" -#~ "Inverted buffers: The newest tweets will be shown at the beginning of the " -#~ "lists while the oldest at the end" -#~ msgstr "" -#~ "Inverti elenco: I nuovi tweets verranno mostrate in cima all'elenco, i " -#~ "precedenti alla fine" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. Copy the code " -#~ "from Dropbox and paste it into the text box which will appear. You only " -#~ "need to do this once." -#~ msgstr "" -#~ "La richiesta di autorizzazione verrà aperta nel browser. Copia il codice " -#~ "da Dropbox ed incolla nel campo editazione che apparirà. Questa " -#~ "operazione verrà richiesta solo una volta." - -#~ msgid "Verification code" -#~ msgstr "Codice di verifica" - -#~ msgid "Error during authorisation. Try again later." -#~ msgstr "Errore durante l'autorizzazione. Riprovare più tardi." - -#~ msgid "TW Blue preferences" -#~ msgstr "Preferenze" - -#~ msgid "Show other buffers" -#~ msgstr "Visualizza" - -#~ msgid "JPG images" -#~ msgstr "Immagini JPG" - -#~ msgid "GIF images" -#~ msgstr "Immagini GIF" - -#~ msgid "PNG Images" -#~ msgstr "Immagini PNG" - -#~ msgid "Select an URL" -#~ msgstr "Seleziona un indirizzo" - -#~ msgid "This account is not logged in twitter." -#~ msgstr "Questo account non è registrato in twitter." - -#~ msgid "{0}: This account is not logged in twitter." -#~ msgstr "{0}: Questo account non è connesso a twitter." - -#~ msgid "Global mute off" -#~ msgstr "Silenzia tutto off" - -#~ msgid "User-defined buffer created." -#~ msgstr "Buffer per l'utente definito creato." - -#~ msgid "User-defined buffer destroied." -#~ msgstr "Buffer per l'utente definito è stato eliminato" - -#~ msgid "Someone's favourites have been updated." -#~ msgstr "I preferiti di qualcuno son stati aggiornati" - -#~ msgid "Mension received." -#~ msgstr "Menzione ricevuta." - -#~ msgid "A trending topic buffer has been updated." -#~ msgstr "Aggiornamento nel buffer argomenti di tendenza" - -#~ msgid "New tweet in user-defined buffer." -#~ msgstr "Nuovo tweet nella linea temporale di un utente definito" - -#~ msgid "Mis-spelled word: %s" -#~ msgstr "Mis-spelled word: %s" - -#~ msgid "Mis-spelled word" -#~ msgstr "Mis-spelled word" - -#~ msgid "Finished" -#~ msgstr "Finito" - -#~ msgid "The spelling review has finished." -#~ msgstr "Correzione di ortografia terminata" - -#~ msgid "" -#~ "Do you really want to delete this message? It will be eliminated from " -#~ "Twitter as well." -#~ msgstr "" -#~ "Sei sicuro di voler eliminare questo messaggio? Verrà eliminato anche da " -#~ "Twitter." - -#~ msgid "Show followers" -#~ msgstr "Visualizza followers" - -#~ msgid "Show friends" -#~ msgstr "Visualizza following" - -#~ msgid "Show favourites" -#~ msgstr "Visualizza preferiti" - -#~ msgid "Show blocked users" -#~ msgstr "Mostra gli utenti bloccati" - -#~ msgid "Show muted users" -#~ msgstr "Mostra utenti silenziati" - -#~ msgid "Show events" -#~ msgstr "Visualizza notifiche" - -#~ msgid "" -#~ "The authorisation request will be shown on your browser. Copy the code " -#~ "tat Dropbox will provide and, in the text box that will appear on TW " -#~ "Blue, paste it. This code is necessary to continue. You only need to do " -#~ "it once." -#~ msgstr "" -#~ "Una richiesta di autorizzazione verrà visualizzata nel tuo browser. " -#~ "Copiare il codice fornito da Dropbox nella casella di testo che " -#~ "apparirà ed incolla su TW Blue. Questo codice è necessario per continuare." - -#~ msgid "Authorisation" -#~ msgstr "Autorizzazione" - -#~ msgid "Change to the next account" -#~ msgstr "Passa al successivo account" - -#~ msgid "Change to the previous account" -#~ msgstr "Passa al precedente account" - -#~ msgid "Remove buffer" -#~ msgstr "Elimina Elenco" - -#~ msgid "" -#~ "Open URL on the current tweet, or further information for a friend or " -#~ "follower" -#~ msgstr "Apri il link nel tweet corrente, o ulteriori informazioni" - -#~ msgid "Go to the first element on the list" -#~ msgstr "Vai al primo elemento dell'elenco" - -#~ msgid "Go to the last element on the list" -#~ msgstr "Vai all'ultimo elemento dell'elenco" - -#~ msgid "Move 20 elements up on the current list" -#~ msgstr "Salta 20 elementi in alto nell'elenco corrente" - -#~ msgid "Move 20 elements down on the current list" -#~ msgstr "Salta 20 elementi in basso nell'elenco corrente" - -#~ msgid "Remove a tweet or direct message" -#~ msgstr "Rimuovi un tweet o un messaggio diretto" - -#~ msgid "Globally mute/unmute the current account" -#~ msgstr "mute/unmute l'account corrente" - -#~ msgid "load previous items to any buffer" -#~ msgstr "Carica voci precedenti per tutti i buffer" - -#~ msgid "" -#~ "The request for the required Twitter authorisation to continue will be " -#~ "opened on your browser. You only need to do it once. Would you like to " -#~ "autorhise a new account now?" -#~ msgstr "" -#~ "La richiesta per l'autorizzazione a Twitter necessaria per continuare " -#~ "sarà aperto sul tuo browser. Desìderi autorizzare un nuovo account?" - -#~ msgid "" -#~ "Your access token is invalid or the authorisation has failed. Please try " -#~ "again." -#~ msgstr "" -#~ "La tua chiave di accesso non è valido o l'autorizzazione non è riuscita. " -#~ "Riprova." - -#~ msgid "" -#~ "%s (@%s). %s followers, %s friends, %s tweets. Last tweet on %s. Joined " -#~ "Twitter on %s" -#~ msgstr "" -#~ "%s (@%s). %s followers, %s Amici, %s tweets. Ultimo tweet %s. Iscritto a " -#~ "Twitter da %s" - -#~ msgid "" -#~ "The application requires to be restarted to save these changes. Press OK " -#~ "to do it now." -#~ msgstr "" -#~ "L'applicazione richiede di essere riavviata per salvare le modifiche. " -#~ "Premi OK per farlo ora." - -#~ msgid "" -#~ "Dropbox will open in your browser. After you log into Dropbox, an " -#~ "authorization code will be generated. Please paste it into the field " -#~ "which will appear. You only need to do this once." -#~ msgstr "" -#~ "Dropbox si aprirà nel tuo browser. Dopo la connessione a Dropbox viene " -#~ "generato un codice di autorizzazione. Incollare nell'apposito campo " -#~ "editazione. Questa operazione verrà eseguita una volta sola." - -#~ msgid "View &trending topics" -#~ msgstr "Visualizza &tendenze" - -#~ msgid "&Unfollow" -#~ msgstr "Non seg&uire" - -#~ msgid "U&nmute" -#~ msgstr "&Unmute" - -#~ msgid "Unb&lock" -#~ msgstr "Sb&locca" - -#~ msgid "&Timeline" -#~ msgstr "Linea &temporale" - -#~ msgid "&Autoread tweets for this buffer" -#~ msgstr "Leggi &automaticamente tweets per questo buffer" - -#~ msgid "&Remove buffer" -#~ msgstr "&Elimina Elenco" - -#~ msgid "Stop recording" -#~ msgstr "Ferma la registrazione" - -#~ msgid "The tweet may contain a playable audio" -#~ msgstr "Il tweet contiene un audio riproducibile" - -#~ msgid "A timeline has been created" -#~ msgstr "Creata nuova Linea temporale" - -#~ msgid "A timeline has been deleted" -#~ msgstr "Linea temporale cancellata" - -#~ msgid "You've received a direct message" -#~ msgstr "Hai ricevuto un messaggio diretto" - -#~ msgid "You've sent a direct message" -#~ msgstr "Hai inviato un messaggio diretto" - -#~ msgid "A bug has happened" -#~ msgstr "Segnalazione errore" - -#~ msgid "You've added a tweet to your favourites" -#~ msgstr "Hai aggiunto un tweet ai tuoi preferiti" - -#~ msgid "The tweet has coordinates to determine its location" -#~ msgstr "Il tweet contiene coordinate per determinare la localizzazione" - -#~ msgid "There are no more tweets to read" -#~ msgstr "Non ci sono altri tweet da leggere" - -#~ msgid "A list has a new tweet" -#~ msgstr "Una lista ha un nuovo tweet" - -#~ msgid "You can't add any more characters on the tweet" -#~ msgstr "Non è possibile aggiungere altri caratteri al tweet" - -#~ msgid "You've been mentioned " -#~ msgstr "Sei stato menzionato" - -#~ msgid "A new event has happened" -#~ msgstr "Nuovo evento " - -#~ msgid "You've replied" -#~ msgstr "Hai risposto" - -#~ msgid "You've sent a tweet" -#~ msgstr "Hai inviato un tweet" - -#~ msgid "There's a new tweet in a timeline" -#~ msgstr "Nuovo tweet nella linea temporale" - -#~ msgid "You have a new follower" -#~ msgstr "Hai un nuovo seguitore" - -#~ msgid "You've turned the volume up or down" -#~ msgstr "Volume regolato" - -#~ msgid "" -#~ "It seems as though the currently used sound pack needs an update. %i " -#~ "fails are still be required to use this function. Make sure to obtain the " -#~ "needed lacking sounds or to contact with the sound pack developer." -#~ msgstr "" -#~ "Sembra che attualmente il pacchetto dei suoni usato richiede un " -#~ "aggiornamento. %i I fail sono ancora necessari per utilizzare questa " -#~ "funzione. Assicurati di ottenere i suoni mancanti necessari o contatta lo " -#~ "sviluppatore per il pacchetto." - -#~ msgid "See the users list" -#~ msgstr "Visualizza la lista degli utenti" - -#~ msgid "Do you really want to delete this message?" -#~ msgstr "Sei sicuro di voler eliminare questo messaggio?" - -#~ msgid "Unable to play audio." -#~ msgstr "Impossibile riprodurre audio." - -#~ msgid "Do you really want to delete this favourites timeline?" -#~ msgstr "Sei sicuro di voler eliminare questa Linea temporale?" - -#~ msgid "&Mention" -#~ msgstr "&Menziona" - -#~ msgid "Announce" -#~ msgstr "Notifica" - -#~ msgid "" -#~ "Do you really want to empty this buffer? It's items will be removed from " -#~ "the list" -#~ msgstr "" -#~ "Sei sicuro di voler svuotare questo buffer? It's items will be removed " -#~ "from the list" - -#~ msgid "Do you really want to delete this search term?" -#~ msgstr "Eliminare la ricerca? " - -#~ msgid "ask before exiting TwBlue?" -#~ msgstr "Richiedere conferma prima di uscire da TwBlue?" - -#~ msgid "Activate the auto-start of the invisible interface" -#~ msgstr "Attiva automaticamente all'avvio l'interfaccia invisibile" - -#~ msgid "Global mute" -#~ msgstr "Silenzia tutto" - -#~ msgid "friends" -#~ msgstr "Following" - -#~ msgid "Favorites" -#~ msgstr "Favoriti" - -#~ msgid "You've muted to %s" -#~ msgstr "Silenziato a %s" - -#~ msgid "You've unmuted to %s" -#~ msgstr "Hai de-silenziato %s" - -#~ msgid "This list is arready opened." -#~ msgstr "Questa lista è già aperta." - -#~ msgid "List for %s" -#~ msgstr "Modifica elenco %s" - -#~ msgid "Uploading..." -#~ msgstr "Caricando..." - -#~ msgid "Men&tion all" -#~ msgstr "Menziona &Tutti" - -#~ msgid "This user does not exist on Twitter" -#~ msgstr "Questo utente non esiste su Twitter" - -#~ msgid "S&witch account" -#~ msgstr "&Passa a un altro account" - -#~ msgid "&Preferences" -#~ msgstr "Preferen&ze" - -#~ msgid "About &TW Blue" -#~ msgstr "&Informazioni su TW Blue" - -#~ msgid "" -#~ "An error occurred while looking for an update. It may be due to any " -#~ "problem either on our server or on your DNS servers. Please, try again " -#~ "later." -#~ msgstr "" -#~ "Si è verificato un errore durante il tentativo di aggiornare. Probabili " -#~ "problemi Sia sul nostro server o sui server DNS. Provare più tardi." - -#~ msgid "Sent" -#~ msgstr "Inviati" - -#~ msgid "%s favourites from %s" -#~ msgstr "%s preferiti da %s" - -#~ msgid "Streams disconnected. TW Blue will try to reconnect in a minute." -#~ msgstr "Streams scollegati. TW Blu tenterà di riconnettersi immediatamente." - -#~ msgid "Reconnecting streams..." -#~ msgstr "Riconnessione streams..." - -#~ msgid "search users for %s" -#~ msgstr "Cerca utente per %s" - -#~ msgid "Do you really want to close TW Blue?" -#~ msgstr "Sei sicuro di voler uscire daTW Blue?" - -#~ msgid "Exiting..." -#~ msgstr "Chiusura in corso..." - -#~ msgid "Error while adding to favourites." -#~ msgstr "Errore durante l'aggiunta ai preferiti." - -#~ msgid "Error while removing from favourites." -#~ msgstr "Errore durante la rimozione dai preferiti." - -#~ msgid "Individual timeline" -#~ msgstr "Linea Temporale individuale" - -#~ msgid "List of favourites" -#~ msgstr "Lista dei favoriti" - -#~ msgid "Existing list" -#~ msgstr "Elenco esistente" - -#~ msgid "" -#~ "There's already a list of favourites for this user. You can't create " -#~ "another." -#~ msgstr "C'è già una lista di preferiti per questo utente." - -#~ msgid "" -#~ "This user has no favourites. You can't create a list of favourites for " -#~ "this user." -#~ msgstr "" -#~ "Questo utente non ha preferenze. Non è possibile creare una lista di " -#~ "preferiti per questo utente." - -#~ msgid "%s" -#~ msgstr "%s" - -#~ msgid "Documentation" -#~ msgstr "Documentazione" - -#~ msgid "Translation" -#~ msgstr "Traduzione" - -#~ msgid "Move up one tweet in the conversation" -#~ msgstr "Vai al tweet precedente" - -#~ msgid "Move down one tweet in the conversation" -#~ msgstr "Vai al tweet successivo" - -#~ msgid "Show the graphical interface" -#~ msgstr "Mostra l'interfaccia grafica" - -#~ msgid "Reply to a tweet" -#~ msgstr "Rispondi" - -#~ msgid "Empty the buffer removing all the elements" -#~ msgstr "Svuota il buffer rimuovendo tutti gli elementi" - -#~ msgid "Listen the current message" -#~ msgstr "Ascolta il messaggio corrente" - -#~ msgid "Get location of any tweet" -#~ msgstr "Localizza tutti i tweet" - -#~ msgid "Creates a buffer for displaying trends for a desired place" -#~ msgstr "" -#~ "Crea un buffer per la visualizzazione di tendenze per un luogo desiderato" - -#~ msgid "Select a twitter account to start TW Blue" -#~ msgstr "Selezionare un account twitter per avviare TW Blue" - -#~ msgid "Remove session" -#~ msgstr "Rimuovi sessione" - -#~ msgid "One tweet from %s in the list %s" -#~ msgstr " Un tweet da %s nella lista %s" - -#~ msgid "One direct message" -#~ msgstr "Un messaggio diretto" - -#~ msgid "About a week ago" -#~ msgstr "Circa una settimana fa" - -#~ msgid "About {} weeks ago" -#~ msgstr "Circa {} settimane fa" - -#~ msgid "A month ago" -#~ msgstr "Un mese fa" - -#~ msgid "About {} months ago" -#~ msgstr "Circa {} mesi fa" - -#~ msgid "About a year ago" -#~ msgstr "Circa un anno fa" - -#~ msgid "About {} years ago" -#~ msgstr "Circa {} anni fa" - -#~ msgid "About 1 day ago" -#~ msgstr "Un giorno fa" - -#~ msgid "About {} days ago" -#~ msgstr "Circa {} giorni fa" - -#~ msgid "just now" -#~ msgstr "Adesso" - -#~ msgid "{} seconds ago" -#~ msgstr "{} secondi fa" - -#~ msgid "1 minute ago" -#~ msgstr "Un minuto fa" - -#~ msgid "{} minutes ago" -#~ msgstr "{} minuti fa" - -#~ msgid "About 1 hour ago" -#~ msgstr "Un'ora fa" - -#~ msgid "About {} hours ago" -#~ msgstr "Circa {} ore fa" - -#~ msgid "January" -#~ msgstr "Gennaio" - -#~ msgid "February" -#~ msgstr "Febbraio" - -#~ msgid "March" -#~ msgstr "Marzo" - -#~ msgid "April" -#~ msgstr "Aprile" - -#~ msgid "June" -#~ msgstr "Giugno" - -#~ msgid "July" -#~ msgstr "Luglio" - -#~ msgid "August" -#~ msgstr "Agosto" - -#~ msgid "September" -#~ msgstr "Settembre" - -#~ msgid "October" -#~ msgstr "Ottobre" - -#~ msgid "November" -#~ msgstr "Novembre" - -#~ msgid "December" -#~ msgstr "Dicembre" - -#~ msgid "Sunday" -#~ msgstr "Domenica" - -#~ msgid "Monday" -#~ msgstr "Lunedì" - -#~ msgid "Tuesday" -#~ msgstr "Martedì" - -#~ msgid "Wednesday" -#~ msgstr "Mercoledì" - -#~ msgid "Thursday" -#~ msgstr "Giovedì" - -#~ msgid "Friday" -#~ msgstr "Venerdì" - -#~ msgid "Saturday" -#~ msgstr "Sabato" - -#~ msgid "sun" -#~ msgstr "Dom" - -#~ msgid "mon" -#~ msgstr "Lu" - -#~ msgid "tue" -#~ msgstr "Ma" - -#~ msgid "wed" -#~ msgstr "Me" - -#~ msgid "thu" -#~ msgstr "Gio" - -#~ msgid "fri" -#~ msgstr "Ve" - -#~ msgid "sat" -#~ msgstr "Sab" - -#~ msgid "jan" -#~ msgstr "Gen" - -#~ msgid "feb" -#~ msgstr "feb" - -#~ msgid "mar" -#~ msgstr "Mar" - -#~ msgid "apr" -#~ msgstr "Apr" - -#~ msgid "may" -#~ msgstr "Mag" - -#~ msgid "jun" -#~ msgstr "Giu" - -#~ msgid "jul" -#~ msgstr "Lug" - -#~ msgid "aug" -#~ msgstr "Ago" - -#~ msgid "sep" -#~ msgstr "Set" - -#~ msgid "oct" -#~ msgstr "Ott" - -#~ msgid "nov" -#~ msgstr "Nov" - -#~ msgid "dec" -#~ msgstr "dic" - -#~ msgid "%A, %B %d, %Y at %I:%M:%S %p" -#~ msgstr "%A, %B %d, %Y at %I:%M:%S %p" - -#~ msgid "Your TW Blue version is up to date" -#~ msgstr "La tua versione di TW Blue è aggiornata" - -#~ msgid "Connection error. Try again later." -#~ msgstr "Errore durante la connessione. Riprovare più tardi." - -#~ msgid "Ouner" -#~ msgstr "Ouner" - -#~ msgid "View members" -#~ msgstr "Visualizza membri" - -#~ msgid "View subscribers" -#~ msgstr "Visualizza gli Iscritti" diff --git a/src/locales/ja/lc_messages/twblue (Jani Kinnunen's conflicted copy 2019-04-03).po b/src/locales/ja/lc_messages/twblue (Jani Kinnunen's conflicted copy 2019-04-03).po deleted file mode 100644 index ef6cf70d..00000000 --- a/src/locales/ja/lc_messages/twblue (Jani Kinnunen's conflicted copy 2019-04-03).po +++ /dev/null @@ -1,3441 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2018-08-08 18:23+0900\n" -"Last-Translator: Manuel Cortez \n" -"Language-Team: \n" -"Language: ja_JP\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.1.1\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "画像" - -#: ../src\controller\buffers\baseBuffers.py:95 -msgid "This action is not supported for this buffer" -msgstr "この動作は、現在のバッファではサポートされていません。" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 -msgid "Home" -msgstr "ホーム" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 -msgid "Mentions" -msgstr "メンション" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 -msgid "Direct messages" -msgstr "ダイレクトメッセージ" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 -msgid "Sent direct messages" -msgstr "送信済みのダイレクトメッセージ" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 -msgid "Sent tweets" -msgstr "送信済みのツイート" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 -msgid "Likes" -msgstr "いいね" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 -msgid "Followers" -msgstr "フォロワー" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "フォロー" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 -msgid "Blocked users" -msgstr "ブロックしたユーザー" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 -msgid "Muted users" -msgstr "ミューとしたユーザー" - -#: ../src\controller\buffers\twitterBuffers.py:75 -#, fuzzy -msgid "{username}'s timeline" -msgstr "特定のユーザーのタイムラインを開く" - -#: ../src\controller\buffers\twitterBuffers.py:77 -msgid "{username}'s likes" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:79 -msgid "{username}'s followers" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:81 -msgid "{username}'s friends" -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:83 -#, fuzzy -msgid "Unknown buffer" -msgstr "不明" - -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 -msgid "Tweet" -msgstr "ツイート" - -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 -msgid "Write the tweet here" -msgstr "ツイートを入力:" - -#: ../src\controller\buffers\twitterBuffers.py:194 -#, fuzzy -msgid "New tweet in {0}" -msgstr "新規ツイート" - -#: ../src\controller\buffers\twitterBuffers.py:197 -#, fuzzy -msgid "{0} new tweets in {1}." -msgstr "@{0} 引用付きツイート: {1}" - -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 -msgid "%s items retrieved" -msgstr "%s個のアイテムを取得しました" - -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "このバッファは、タイムラインではないため、削除できません" - -#: ../src\controller\buffers\twitterBuffers.py:402 -msgid "Reply to {arg0}" -msgstr "「{arg0}」への返信:" - -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 -msgid "Reply" -msgstr "返信" - -#: ../src\controller\buffers\twitterBuffers.py:405 -msgid "Reply to %s" -msgstr "「%s」への返信:" - -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "「%s」へのダイレクトメッセージ" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 -msgid "New direct message" -msgstr "新しいダイレクトメッセージ " - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Add your comment to the tweet" -msgstr "ツイートにコメントを追加" - -#: ../src\controller\buffers\twitterBuffers.py:500 -msgid "Quote" -msgstr "引用" - -#: ../src\controller\buffers\twitterBuffers.py:572 -msgid "Opening URL..." -msgstr "URLを開いています" - -#: ../src\controller\buffers\twitterBuffers.py:607 -msgid "User details" -msgstr "ユーザーの詳細" - -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 -msgid "Opening item in web browser..." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -msgid "Mention to %s" -msgstr "%sへのメンション" - -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 -msgid "Mention" -msgstr "メンション" - -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy -msgid "{0} new direct messages." -msgstr "新しいダイレクトメッセージ " - -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy -msgid "This action is not supported in the buffer yet." -msgstr "この動作は、現在のバッファではサポートされていません。" - -#: ../src\controller\buffers\twitterBuffers.py:741 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" - -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy -msgid "{0} new followers." -msgstr "新しいフォロワー" - -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy -msgid "This action is not supported in the buffer, yet." -msgstr "この動作は、現在のバッファではサポートされていません。" - -#: ../src\controller\mainController.py:273 -msgid "Ready" -msgstr "準備完了" - -#: ../src\controller\mainController.py:345 -msgid "Timelines" -msgstr "タイムライン" - -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 -msgid "Timeline for {}" -msgstr "「{}」のタイムライン" - -#: ../src\controller\mainController.py:352 -msgid "Likes timelines" -msgstr "ほかのユーザーのいいね一覧" - -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 -msgid "Likes for {}" -msgstr "{}のいいね一覧" - -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "フォロワー一覧" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 -msgid "Followers for {}" -msgstr "{}をフォローしているユーザー" - -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "フォロー一覧" - -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 -msgid "Friends for {}" -msgstr "{}がフォローしているユーザー" - -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 -msgid "Lists" -msgstr "リスト" - -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 -msgid "List for {}" -msgstr "{}のリスト" - -#: ../src\controller\mainController.py:381 -msgid "Searches" -msgstr "検索" - -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 -msgid "Search for {}" -msgstr "「{}」の検索結果" - -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 -msgid "Trending topics for %s" -msgstr "{}の話題のトピック" - -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "" -"セッションが選択されていません。「次のセッション」または「前のセッション」の" -"ショートカットを利用して、セッションを選択してください。" - -#: ../src\controller\mainController.py:465 -msgid "Empty buffer." -msgstr "バッファをクリア" - -#: ../src\controller\mainController.py:472 -msgid "{0} not found." -msgstr "{0}が見つかりませんでした。" - -#: ../src\controller\mainController.py:482 -msgid "Filters cannot be applied on this buffer" -msgstr "" -"このバッファにフィルターは適応できません。その動作は、現在のバッファでは利用" -"できません。" - -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 -msgid "Select the user" -msgstr "ユーザーを選択" - -#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236 -#, fuzzy -msgid "MMM D, YYYY. H:m" -msgstr "YYYY年MMMMD日(dddd) H時m分s秒" - -#: ../src\controller\mainController.py:934 -msgid "Conversation with {0}" -msgstr "{0}との会話" - -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "このツイートには、ジェオタグは存在しません" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "このツイートのジェオタグには、なにも含まれていません" - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "ジェオタグの取得に失敗しました" - -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 -msgid "%s, %s of %s" -msgstr "%s %s/%s" - -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 -msgid "%s. Empty" -msgstr "%sは、からです。" - -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 -#: ../src\controller\mainController.py:1166 -msgid "{0}: This account is not logged into Twitter." -msgstr "このアカウント{0}は、まだツイッターにログインしていません" - -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 -msgid "%s. %s, %s of %s" -msgstr "セッション:%s %s %s/%s/" - -#: ../src\controller\mainController.py:1170 -msgid "{0}: This account is not logged into twitter." -msgstr "このアカウント{0}は、まだツイッターにログインしていません" - -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "イベント" - -#: ../src\controller\mainController.py:1393 -msgid "This list is already opened" -msgstr "既に開かれています" - -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"バグを報告しようとしているときに、予期しないエラーが発生しました。後でやり直" -"してください" - -#: ../src\controller\mainController.py:1475 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "自動読み上げ 有効" - -#: ../src\controller\mainController.py:1478 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "自動読み上げ 無効" - -#: ../src\controller\mainController.py:1485 -msgid "Session mute on" -msgstr "このセッションのミュートを設定" - -#: ../src\controller\mainController.py:1488 -msgid "Session mute off" -msgstr "このセッションのミュートを解除" - -#: ../src\controller\mainController.py:1496 -msgid "Buffer mute on" -msgstr "このバッファのミュートを設定" - -#: ../src\controller\mainController.py:1499 -msgid "Buffer mute off" -msgstr "このバッファのミュートを解除" - -#: ../src\controller\mainController.py:1522 -msgid "Copied" -msgstr "コピーしました" - -#: ../src\controller\mainController.py:1549 -msgid "Unable to update this buffer." -msgstr "このバッファを更新できません。" - -#: ../src\controller\mainController.py:1552 -msgid "Updating buffer..." -msgstr "バッファを更新中…" - -#: ../src\controller\mainController.py:1555 -msgid "{0} items retrieved" -msgstr "{0}個のアイテムを取得しました" - -#: ../src\controller\mainController.py:1572 -msgid "Invalid buffer" -msgstr "無効なバッファ無効なユーザートークンです。" - -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "このツイートは、画像を含んでいません" - -#: ../src\controller\mainController.py:1579 -msgid "Picture {0}" -msgstr "画像{0}" - -#: ../src\controller\mainController.py:1580 -msgid "Select the picture" -msgstr "画像を選択" - -#: ../src\controller\mainController.py:1596 -msgid "Unable to extract text" -msgstr "テキストを抽出できません" - -#: ../src\controller\messages.py:54 -msgid "Translated" -msgstr "翻訳完了" - -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "短縮されたURLは、ありません" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URLを短縮しました" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "短縮を解除するURLはありません" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URLの短縮を解除しました" - -#: ../src\controller\messages.py:104 -msgid "%s - %s of %d characters" -msgstr "%s - %s/%d" - -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s文字" - -#: ../src\controller\messages.py:262 -msgid "View item" -msgstr "アイテムを見る" - -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "直接接続" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Ask" -msgstr "その都度、質問する" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet without comments" -msgstr "コメントを付けずにリツイート(公式RT)" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 -msgid "Retweet with comments" -msgstr "コメントをつけてリツイート(非公式RT)" - -#: ../src\controller\settings.py:184 -msgid "Account settings for %s" -msgstr "%sのアカウント設定" - -#: ../src\controller\settings.py:284 -msgid "Direct Messages" -msgstr "ダイレクトメッセージ" - -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 -msgid "Error" -msgstr "エラー" - -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 -msgid "That user does not exist" -msgstr "そのユーザーは存在しません。" - -#: ../src\controller\user.py:30 -msgid "User has been suspended" -msgstr "ユーザーが凍結されています。" - -#: ../src\controller\user.py:36 -msgid "Information for %s" -msgstr "%sの情報" - -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 -msgid "Discarded" -msgstr "拒否されました" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "ユーザー名: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "名前: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "居住地: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:102 -msgid "Bio: %s\n" -msgstr "自己紹介: %s\n" - -#: ../src\controller\user.py:103 ../src\controller\user.py:118 -msgid "Yes" -msgstr "はい" - -#: ../src\controller\user.py:104 ../src\controller\user.py:119 -msgid "No" -msgstr "いいえ" - -#: ../src\controller\user.py:105 -msgid "Protected: %s\n" -msgstr "保護設定: %s\n" - -#: ../src\controller\user.py:110 -msgid "You follow {0}. " -msgstr "{0}をフォロー" - -#: ../src\controller\user.py:113 -msgid "{0} is following you." -msgstr " {0}がフォロー" - -#: ../src\controller\user.py:117 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"フォロワー: %s\n" -"フォロー: %s\n" - -#: ../src\controller\user.py:120 -msgid "Verified: %s\n" -msgstr "認証済み: %s\n" - -#: ../src\controller\user.py:121 -msgid "Tweets: %s\n" -msgstr "ツイート数: %s\n" - -#: ../src\controller\user.py:122 -msgid "Likes: %s" -msgstr "いいね数: %s" - -#: ../src\controller\userActionsController.py:75 -msgid "You can't ignore direct messages" -msgstr "ダイレクトメッセージを無視することはできません" - -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "添付中" - -#: ../src\extra\AudioUploader\audioUploader.py:71 -msgid "Pause" -msgstr "一時停止" - -#: ../src\extra\AudioUploader\audioUploader.py:73 -msgid "&Resume" -msgstr "再開(&R)" - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Resume" -msgstr "再開" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 -msgid "&Pause" -msgstr "一時停止(&P)" - -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 -msgid "&Stop" -msgstr "停止(&S)" - -#: ../src\extra\AudioUploader\audioUploader.py:92 -msgid "Recording" -msgstr "録音中" - -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 -msgid "Stopped" -msgstr "停止" - -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 -msgid "&Record" -msgstr "録音(&R)" - -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 -msgid "Playing..." -msgstr "再生中" - -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 -msgid "&Play" -msgstr "再生(&P)" - -#: ../src\extra\AudioUploader\audioUploader.py:156 -msgid "Recoding audio..." -msgstr "音声を録音中" - -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -msgid "Error in file upload: {0}" -msgstr "ファイルアップロードエラー: {0}" - -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "1日前" - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%s日" - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "1時間前" - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d時間" - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "1分前" - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d分" - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "1秒前" - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s seconds" -msgstr "%s秒" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 -msgid "File" -msgstr "ファイル" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 -msgid "Transferred" -msgstr "転送済み" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 -msgid "Total file size" -msgstr "合計サイズ" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 -msgid "Transfer rate" -msgstr "転送速度" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 -msgid "Time left" -msgstr "残り時間" - -#: ../src\extra\AudioUploader\wx_ui.py:28 -msgid "Attach audio" -msgstr "音声を添付" - -#: ../src\extra\AudioUploader\wx_ui.py:40 -msgid "&Add an existing file" -msgstr "既存のファイルを追加(&A)" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Discard" -msgstr "拒否(&D)" - -#: ../src\extra\AudioUploader\wx_ui.py:43 -msgid "Upload to" -msgstr "アップロード先:" - -#: ../src\extra\AudioUploader\wx_ui.py:48 -msgid "Attach" -msgstr "添付" - -#: ../src\extra\AudioUploader\wx_ui.py:50 -msgid "&Cancel" -msgstr "キャンセル(&C)" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "音声ファイル (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:75 -msgid "Select the audio file to be uploaded" -msgstr "アップロードする音声ファイルを選択" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "音声付きツイート" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "ユーザーのタイムラインのバッファを作成" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "バッファを削除" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "ダイレクトメッセージを受信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "ダイレクトメッセージを送信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "エラー" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "ツイートがいいねされた" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "いいねバッファが更新された" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "位置情報付きのツイート" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Tweet contains one or more images" -msgstr "ツイートに1つ以上の画像が含まれています" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "先頭または最後のツイート" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "リストが更新された" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "文字数オーバー" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "リプライを受信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "新しいイベント" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0}の準備完了" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "リプライを送信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "ツイートをリツイート" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "検索バッファが更新された" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "ツイートを受信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "ツイートを送信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "トレンドの話題のバッファが更新された" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "ユーザーのタイムラインに新しいツイートを受信" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "新しいフォロワー" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "ボリュームを変更" - -#: ../src\extra\SoundsTutorial\wx_ui.py:8 -msgid "Sounds tutorial" -msgstr "サウンドの確認" - -#: ../src\extra\SoundsTutorial\wx_ui.py:11 -msgid "Press enter to listen to the sound for the selected event" -msgstr "選択されたイベントのサウンドを再生するには、Enterキーを押してください" - -#: ../src\extra\SpellChecker\spellchecker.py:57 -msgid "Misspelled word: %s" -msgstr "「%s」はスペルが間違っています" - -#: ../src\extra\SpellChecker\wx_ui.py:27 -msgid "Misspelled word" -msgstr "スペルミスの単語" - -#: ../src\extra\SpellChecker\wx_ui.py:32 -msgid "Context" -msgstr "コンテキスト" - -#: ../src\extra\SpellChecker\wx_ui.py:37 -msgid "Suggestions" -msgstr "提案" - -#: ../src\extra\SpellChecker\wx_ui.py:42 -msgid "&Ignore" -msgstr "無視(&I)" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "I&gnore all" -msgstr "すべて無視(&G)" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "&Replace" -msgstr "置き換え(&R)" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "R&eplace all" -msgstr "すべて置き換え(&E)" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "個人辞書に追加(&A)" - -#: ../src\extra\SpellChecker\wx_ui.py:79 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "エラーが発生しました。{0}で選択した言語用の辞書がありません" - -#: ../src\extra\SpellChecker\wx_ui.py:82 -msgid "Spell check complete." -msgstr "スペルチェックが完了しました" - -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 -msgid "You have to start writing" -msgstr "あなたは、書き込みを開始しなければなりません" - -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 -msgid "There are no results in your users database" -msgstr "あなたのユーザーのデータベースには、見つかりませんでした" - -#: ../src\extra\autocompletionUsers\completion.py:33 -msgid "Autocompletion only works for users." -msgstr "自動補完はユーザーのみで動作します" - -#: ../src\extra\autocompletionUsers\settings.py:27 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"データベースの更新中...あなたは今、このウィンドウを閉じることができます。 プ" -"ロセスが終了するとメッセージが表示されます" - -#: ../src\extra\autocompletionUsers\wx_manage.py:8 -msgid "Manage Autocompletion database" -msgstr "オートコンプリートのデータベースを管理" - -#: ../src\extra\autocompletionUsers\wx_manage.py:11 -msgid "Editing {0} users database" -msgstr "{0}のユーザーデータベースを編集中" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Username" -msgstr "ユーザー名" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "名前" - -#: ../src\extra\autocompletionUsers\wx_manage.py:15 -msgid "Add user" -msgstr "ユーザーを追加" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Remove user" -msgstr "ユーザーを削除" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Add user to database" -msgstr "データベースにユーザーを追加" - -#: ../src\extra\autocompletionUsers\wx_manage.py:37 -msgid "Twitter username" -msgstr "ツイッターのユーザー名" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -msgid "The user does not exist" -msgstr "そのユーザーは存在しません" - -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "Error!" -msgstr "エラー" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "オートコンプリートユーザーの設定" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "フォロワーからユーザーを追加" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "フォロー中のユーザーからユーザーを追加" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "データベースの管理" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "完了" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "{0}のユーザーのデータベースが更新されました" - -#: ../src\extra\ocr\OCRSpace.py:5 -msgid "Detect automatically" -msgstr "自動検出" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 -msgid "Danish" -msgstr "デンマーク語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 -msgid "Dutch" -msgstr "オランダ語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 -msgid "English" -msgstr "英語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 -msgid "Finnish" -msgstr "フィンランド語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 -msgid "French" -msgstr "フランス語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 -msgid "German" -msgstr "ドイツ語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 -msgid "Hungarian" -msgstr "ハンガリー語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 -msgid "Italian" -msgstr "イタリア語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 -msgid "Japanese" -msgstr "日本語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 -msgid "Korean" -msgstr "韓国語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 -msgid "Polish" -msgstr "ポーランド語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 -msgid "Portuguese" -msgstr "ポルトガル語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 -msgid "Russian" -msgstr "ロシア語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 -msgid "Spanish" -msgstr "スペイン語" - -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 -msgid "Turkish" -msgstr "トルコ語" - -#: ../src\extra\translator\translator.py:12 -msgid "Afrikaans" -msgstr "アフリカ語" - -#: ../src\extra\translator\translator.py:13 -msgid "Albanian" -msgstr "アルバニア語" - -#: ../src\extra\translator\translator.py:14 -msgid "Amharic" -msgstr "アムハラ語" - -#: ../src\extra\translator\translator.py:15 -msgid "Arabic" -msgstr "アラビア語" - -#: ../src\extra\translator\translator.py:16 -msgid "Armenian" -msgstr "アルメニア語" - -#: ../src\extra\translator\translator.py:17 -msgid "Azerbaijani" -msgstr "アゼルバイジャン語" - -#: ../src\extra\translator\translator.py:18 -msgid "Basque" -msgstr "バスク語" - -#: ../src\extra\translator\translator.py:19 -msgid "Belarusian" -msgstr "ベラルーシ語" - -#: ../src\extra\translator\translator.py:20 -msgid "Bengali" -msgstr "ベンガル語" - -#: ../src\extra\translator\translator.py:21 -msgid "Bihari" -msgstr "ビハール語" - -#: ../src\extra\translator\translator.py:22 -msgid "Bulgarian" -msgstr "ブルガリア語" - -#: ../src\extra\translator\translator.py:23 -msgid "Burmese" -msgstr "ビルマ語" - -#: ../src\extra\translator\translator.py:24 -msgid "Catalan" -msgstr "カタロニア語" - -#: ../src\extra\translator\translator.py:25 -msgid "Cherokee" -msgstr "チェロキー語" - -#: ../src\extra\translator\translator.py:26 -msgid "Chinese" -msgstr "中国語" - -#: ../src\extra\translator\translator.py:27 -msgid "Chinese_simplified" -msgstr "簡体字中国語" - -#: ../src\extra\translator\translator.py:28 -msgid "Chinese_traditional" -msgstr "繁体字中国語" - -#: ../src\extra\translator\translator.py:29 -msgid "Croatian" -msgstr "クロアチア語" - -#: ../src\extra\translator\translator.py:30 -msgid "Czech" -msgstr "チェコ語" - -#: ../src\extra\translator\translator.py:32 -msgid "Dhivehi" -msgstr "ディベヒ語" - -#: ../src\extra\translator\translator.py:35 -msgid "Esperanto" -msgstr "エスペラント語" - -#: ../src\extra\translator\translator.py:36 -msgid "Estonian" -msgstr "エストニア語" - -#: ../src\extra\translator\translator.py:37 -msgid "Filipino" -msgstr "フィリピン語" - -#: ../src\extra\translator\translator.py:40 -msgid "Galician" -msgstr "ガリシア語" - -#: ../src\extra\translator\translator.py:41 -msgid "Georgian" -msgstr "ジョージア語" - -#: ../src\extra\translator\translator.py:43 -msgid "Greek" -msgstr "ギリシャ語" - -#: ../src\extra\translator\translator.py:44 -msgid "Guarani" -msgstr "グアラニ語" - -#: ../src\extra\translator\translator.py:45 -msgid "Gujarati" -msgstr "グジャラート語" - -#: ../src\extra\translator\translator.py:46 -msgid "Hebrew" -msgstr "ヘブライ語" - -#: ../src\extra\translator\translator.py:47 -msgid "Hindi" -msgstr "ヒンディー語" - -#: ../src\extra\translator\translator.py:49 -msgid "Icelandic" -msgstr "アイスランド語" - -#: ../src\extra\translator\translator.py:50 -msgid "Indonesian" -msgstr "インドネシア語" - -#: ../src\extra\translator\translator.py:51 -msgid "Inuktitut" -msgstr "イヌクティトゥト語" - -#: ../src\extra\translator\translator.py:52 -msgid "Irish" -msgstr "アイリス語" - -#: ../src\extra\translator\translator.py:55 -msgid "Kannada" -msgstr "カンナダ語" - -#: ../src\extra\translator\translator.py:56 -msgid "Kazakh" -msgstr "カザフ語" - -#: ../src\extra\translator\translator.py:57 -msgid "Khmer" -msgstr "クメール語" - -#: ../src\extra\translator\translator.py:59 -msgid "Kurdish" -msgstr "クルド語" - -#: ../src\extra\translator\translator.py:60 -msgid "Kyrgyz" -msgstr "キルギス語" - -#: ../src\extra\translator\translator.py:61 -msgid "Laothian" -msgstr "ラオス語" - -#: ../src\extra\translator\translator.py:62 -msgid "Latvian" -msgstr "ラトビア語" - -#: ../src\extra\translator\translator.py:63 -msgid "Lithuanian" -msgstr "リトアニア語" - -#: ../src\extra\translator\translator.py:64 -msgid "Macedonian" -msgstr "マケドニア語" - -#: ../src\extra\translator\translator.py:65 -msgid "Malay" -msgstr "マレー語" - -#: ../src\extra\translator\translator.py:66 -msgid "Malayalam" -msgstr "マラヤーラム語" - -#: ../src\extra\translator\translator.py:67 -msgid "Maltese" -msgstr "マルタ語" - -#: ../src\extra\translator\translator.py:68 -msgid "Marathi" -msgstr "マラーティー語" - -#: ../src\extra\translator\translator.py:69 -msgid "Mongolian" -msgstr "モンゴル語" - -#: ../src\extra\translator\translator.py:70 -msgid "Nepali" -msgstr "ネパール語" - -#: ../src\extra\translator\translator.py:71 -msgid "Norwegian" -msgstr "ノルウェー語" - -#: ../src\extra\translator\translator.py:72 -msgid "Oriya" -msgstr "オリヤー語" - -#: ../src\extra\translator\translator.py:73 -msgid "Pashto" -msgstr "パシュトウ語" - -#: ../src\extra\translator\translator.py:74 -msgid "Persian" -msgstr "ペルシア語" - -#: ../src\extra\translator\translator.py:77 -msgid "Punjabi" -msgstr "パンジャブ語" - -#: ../src\extra\translator\translator.py:78 -msgid "Romanian" -msgstr "ルーマニア語" - -#: ../src\extra\translator\translator.py:80 -msgid "Sanskrit" -msgstr "サンスクリット語" - -#: ../src\extra\translator\translator.py:81 -msgid "Serbian" -msgstr "セルビア語" - -#: ../src\extra\translator\translator.py:82 -msgid "Sindhi" -msgstr "シンド語" - -#: ../src\extra\translator\translator.py:83 -msgid "Sinhalese" -msgstr "シンハラ語" - -#: ../src\extra\translator\translator.py:84 -msgid "Slovak" -msgstr "スロバキア語" - -#: ../src\extra\translator\translator.py:85 -msgid "Slovenian" -msgstr "スロベニア語" - -#: ../src\extra\translator\translator.py:87 -msgid "Swahili" -msgstr "スワヒリ語" - -#: ../src\extra\translator\translator.py:88 -msgid "Swedish" -msgstr "スウェーデン語" - -#: ../src\extra\translator\translator.py:89 -msgid "Tajik" -msgstr "タジク語" - -#: ../src\extra\translator\translator.py:90 -msgid "Tamil" -msgstr "タミル語" - -#: ../src\extra\translator\translator.py:91 -msgid "Tagalog" -msgstr "タガログ語" - -#: ../src\extra\translator\translator.py:92 -msgid "Telugu" -msgstr "テルグ語" - -#: ../src\extra\translator\translator.py:93 -msgid "Thai" -msgstr "タイ語" - -#: ../src\extra\translator\translator.py:94 -msgid "Tibetan" -msgstr "チベット語" - -#: ../src\extra\translator\translator.py:96 -msgid "Ukrainian" -msgstr "ウクライナ語" - -#: ../src\extra\translator\translator.py:97 -msgid "Urdu" -msgstr "ウルドゥー語" - -#: ../src\extra\translator\translator.py:98 -msgid "Uzbek" -msgstr "ウズベク語" - -#: ../src\extra\translator\translator.py:99 -msgid "Uighur" -msgstr "ウイグル語" - -#: ../src\extra\translator\translator.py:100 -msgid "Vietnamese" -msgstr "ベトナム語" - -#: ../src\extra\translator\translator.py:101 -msgid "Welsh" -msgstr "ウェールズ語" - -#: ../src\extra\translator\translator.py:102 -msgid "Yiddish" -msgstr "イディッシュ語" - -#: ../src\extra\translator\wx_ui.py:44 -msgid "Translate message" -msgstr "メッセージを翻訳" - -#: ../src\extra\translator\wx_ui.py:47 -msgid "Target language" -msgstr "翻訳先の言語" - -#: ../src\issueReporter\issueReporter.py:30 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "一般" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "always" -msgstr "常に" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "have not tried" -msgstr "試したことがない" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "random" -msgstr "ランダム" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "sometimes" -msgstr "時々" - -#: ../src\issueReporter\issueReporter.py:31 -msgid "unable to duplicate" -msgstr "複製できません" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "block" -msgstr "ブロック" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "crash" -msgstr "クラッシュ" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "feature" -msgstr "特徴" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "major" -msgstr "メジャー" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "minor" -msgstr "マイナー" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "text" -msgstr "内容" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "trivial" -msgstr "些細な" - -#: ../src\issueReporter\issueReporter.py:32 -msgid "tweak" -msgstr "微調整" - -#: ../src\issueReporter\wx_ui.py:25 -msgid "Report an error" -msgstr "エラーを報告" - -#: ../src\issueReporter\wx_ui.py:28 -msgid "Select a category" -msgstr "カテゴリを選択" - -#: ../src\issueReporter\wx_ui.py:36 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "簡単な説明" - -#: ../src\issueReporter\wx_ui.py:45 -msgid "Here, you can describe the bug in detail" -msgstr "バグの詳細な説明" - -#: ../src\issueReporter\wx_ui.py:55 -msgid "how often does this bug happen?" -msgstr "このバグが起こる頻度" - -#: ../src\issueReporter\wx_ui.py:62 -msgid "Select the importance that you think this bug has" -msgstr "このバグの重要性を選択" - -#: ../src\issueReporter\wx_ui.py:69 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"私は、{0}のバグシステムが私に連絡して、すぐにバグを修正するために、ツイッター" -"のユーザー名を取得することを理解しています" - -#: ../src\issueReporter\wx_ui.py:72 -msgid "Send report" -msgstr "レポートを送信" - -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 -msgid "Cancel" -msgstr "キャンセル" - -#: ../src\issueReporter\wx_ui.py:83 -msgid "You must fill out both fields" -msgstr "あなたは、両方のフィールドに記入しなければなりません" - -#: ../src\issueReporter\wx_ui.py:86 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"必要な場合に連絡するため、ツイッターのユーザー名を私たちに送信するために、" -"チェックボックスにチェックをつける必要があります" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"このバグを報告していただき、ありがとうございます!将来のバージョンでは、変更" -"のリストでそれを見つけることができるかもしれません。あなたは、バグ番号%iを報" -"しました" - -#: ../src\issueReporter\wx_ui.py:89 -msgid "reported" -msgstr "レポート完了" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "Error while reporting" -msgstr "エラー" - -#: ../src\issueReporter\wx_ui.py:93 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"バグを報告しようとしているときに、予期しないエラーが発生しました。後でやり直" -"してください" - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "現在のバッファで、前のツイートに移動" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "現在のバッファで、次のツイートに移動" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "前のバッファに移動" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "次のバッファに移動" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "次のセッションにフォーカス" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "前のセッションにフォーカス" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "GUIの表示と非表示を切り替え" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "新規ツイート" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "リツイート" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "ダイレクトメッセージを作成" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "ツイートをいいねする" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "ツイートをいいね・いいね解除" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "ツイートのいいねを解除" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "ユーザーのアクションを選択する画面を表示" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "ユーザーの詳細を表示" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "ツイートを表示" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "終了" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "特定のユーザーのタイムラインを開く" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "現在のバッファを削除" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "現在フォーカス中のツイートを相呼応する" - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "URLを開く" - -#: ../src\keystrokeEditor\constants.py:25 -#, fuzzy -msgid "View in Twitter" -msgstr "ツイッターを検索" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "音量を5パーセント上げる" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "音量を5パーセント下げる" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "現在のバッファの先頭に移動" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "現在のバッファの最後に移動" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "20個前の要素に移動" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "20個先の要素に移動" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "プロフィールを編集" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "ツイートまたはダイレクトメッセージを削除" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "現在のバッファをクリア" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "現在のアイテムをもう一度読み上げ" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "クリップボードにコピー" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "リストに追加" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "リストから削除" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "現在のバッファのミュートを切り替え" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "現在のセッションのミュートを切り替え" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "新着のツイートを自動で読み上げるかどうかを設定" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "ツイッターを検索" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "現在のバッファ内の文字列を検索" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "キーストロークエディタを表示" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "特定のユーザーのリストを表示" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "以前のアイテムを取得" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "位置情報を取得" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "位置情報を表示" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "トレンドの話題のバッファを作成" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "会話を見る" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "アップデートをチェックしてダウンロード" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"リストを作成したり、編集したり、削除したりするために「リストの管理」を開く" - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "「全般設定」ダイアログを開く" - -#: ../src\keystrokeEditor\constants.py:54 -#, fuzzy -msgid "Opens the list manager" -msgstr "リストの管理" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "「アカウント設定」ダイアログを開く" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "音声ファイルの再生" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "バッファを更新して、取得に失敗したアイテムを取得" - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "画像からテキストを抽出して、結果をダイアログで表示。" - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "キーストロークエディタ" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "編集するキーストロークを選択" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "キーストローク" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 -msgid "Action" -msgstr "操作" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 -msgid "Edit" -msgstr "編集" - -#: ../src\keystrokeEditor\wx_ui.py:20 -msgid "Execute action" -msgstr "現在の動作を実行" - -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 -msgid "Close" -msgstr "閉じる" - -#: ../src\keystrokeEditor\wx_ui.py:48 -msgid "Editing keystroke" -msgstr "キーストロークを編集" - -#: ../src\keystrokeEditor\wx_ui.py:51 -msgid "Control" -msgstr "コントロール" - -#: ../src\keystrokeEditor\wx_ui.py:52 -msgid "Alt" -msgstr "オルト" - -#: ../src\keystrokeEditor\wx_ui.py:53 -msgid "Shift" -msgstr "シフト" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Windows" -msgstr "ウィンドウズ" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Key" -msgstr "キー名" - -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 -msgid "OK" -msgstr "OK" - -#: ../src\keystrokeEditor\wx_ui.py:78 -msgid "You need to use the Windows key" -msgstr "ウィンドウズキーを使用する必要があります" - -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 -msgid "Invalid keystroke" -msgstr "無効なキーストローク" - -#: ../src\keystrokeEditor\wx_ui.py:81 -msgid "You must provide a character for the keystroke" -msgstr "キー名が入力されていません" - -#: ../src\languageHandler.py:99 -msgid "User default" -msgstr "ユーザーのデフォルト" - -#: ../src\main.py:105 -msgid "https://twblue.es/donate" -msgstr "https://twblue.es/donate" - -#: ../src\main.py:122 -msgid "" -"{0} is already running. Close the other instance before starting this one. " -"If you're sure that {0} isn't running, try deleting the file at {1}. If " -"you're unsure of how to do this, contact the {0} developers." -msgstr "" - -#: ../src\sessionmanager\wxUI.py:8 -msgid "Session manager" -msgstr "セッションの管理" - -#: ../src\sessionmanager\wxUI.py:11 -msgid "Accounts list" -msgstr "アカウントリスト" - -#: ../src\sessionmanager\wxUI.py:13 -msgid "Account" -msgstr "アカウント" - -#: ../src\sessionmanager\wxUI.py:17 -msgid "New account" -msgstr "新しいアカウントを連携" - -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 -msgid "Remove account" -msgstr "このアカウントを削除" - -#: ../src\sessionmanager\wxUI.py:19 -msgid "Global Settings" -msgstr "全体の設定" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "Account Error" -msgstr "アカウントエラー" - -#: ../src\sessionmanager\wxUI.py:42 -msgid "You need to configure an account." -msgstr "アカウントを設定する必要があります" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "Authorization" -msgstr "認証" - -#: ../src\sessionmanager\wxUI.py:48 -msgid "" -"The request to authorize your Twitter account will be opened in your " -"browser. You only need to do this once. Would you like to continue?" -msgstr "" -"アカウントを認証するために、ブラウザを開きます。あなたは、一度だけ、これを実" -"行する必要があります。続行しますか?" - -#: ../src\sessionmanager\wxUI.py:52 -msgid "Authorized account %d" -msgstr "認証したアカウント%d" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "Invalid user token" -msgstr "無効なユーザートークンです。" - -#: ../src\sessionmanager\wxUI.py:58 -msgid "" -"Your access token is invalid or the authorization has failed. Please try " -"again." -msgstr "" -"あなたのアクセストークンが無効であるか、または許可が失敗しました。もう一度や" -"り直してください。" - -#: ../src\sessionmanager\wxUI.py:64 -msgid "Do you really want to delete this account?" -msgstr "本当にこのアカウントを削除しますか?" - -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 -msgid "dddd, MMMM D, YYYY H:m:s" -msgstr "YYYY年MMMMD日(dddd) H時m分s秒" - -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 -msgid "Dm to %s " -msgstr "「%s」へのDM" - -#: ../src\sessions\twitter\compose.py:141 -msgid "{0}. Quoted tweet from @{1}: {2}" -msgstr "{0} 引用:@{1}:{2}" - -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 -msgid "Unavailable" -msgstr "無効" - -#: ../src\sessions\twitter\compose.py:166 -msgid "" -"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " -"Twitter %s" -msgstr "" -"%s: @%s フォロワー: %s フォロー: %s ツイート数: %s 最後のツイート: %s ツイッ" -"ターへの参加: %s" - -#: ../src\sessions\twitter\compose.py:170 -msgid "No description available" -msgstr "説明はありません" - -#: ../src\sessions\twitter\compose.py:174 -msgid "private" -msgstr "プライベート" - -#: ../src\sessions\twitter\compose.py:175 -msgid "public" -msgstr "公式" - -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "このツイートには、ジェオタグは存在しません" - -#: ../src\sessions\twitter\session.py:215 -msgid "%s failed. Reason: %s" -msgstr "%s" - -#: ../src\sessions\twitter\session.py:221 -msgid "%s succeeded." -msgstr "%sに成功しました。" - -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "申し訳ありませんが、あなたはこのステータスを表示する権限がありません" - -#: ../src\sessions\twitter\utils.py:227 -msgid "No status found with that ID" -msgstr "そのIDのステータスが見つかりませんでした" - -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "エラーコード {0}" - -#: ../src\sessions\twitter\wxUI.py:6 -msgid "Authorising account..." -msgstr "アカウントを連携中…" - -#: ../src\sessions\twitter\wxUI.py:9 -msgid "Enter your PIN code here" -msgstr "PINコードを入力" - -#: ../src\sound.py:159 -msgid "Stopped." -msgstr "停止" - -#: ../src\update\wxUpdater.py:10 -msgid "New version for %s" -msgstr "「%s」の新しいバージョン" - -#: ../src\update\wxUpdater.py:10 -msgid "" -"There's a new %s version available, released on %s. Would you like to " -"download it now?\n" -"\n" -" %s version: %s\n" -"\n" -"Changes:\n" -"%s" -msgstr "" -"%sの新しいバージョンが%sにリリースされています。今すぐダウンロードします" -"か?\n" -"\n" -"%sバージョン:%s\n" -"\n" -"更新履歴:\n" -"%s" - -#: ../src\update\wxUpdater.py:18 -msgid "Download in Progress" -msgstr "ダウンロード中" - -#: ../src\update\wxUpdater.py:18 -msgid "Downloading the new version..." -msgstr "新しいバージョンをダウンロードしています" - -#: ../src\update\wxUpdater.py:28 -msgid "Updating... %s of %s" -msgstr "アップデート中… %s/%s" - -#: ../src\update\wxUpdater.py:31 -msgid "Done!" -msgstr "完了" - -#: ../src\update\wxUpdater.py:31 -msgid "" -"The update has been downloaded and installed successfully. Press OK to " -"continue." -msgstr "" -"アップデートは正常にインストールされました。続行する場合は、「OK」を押してく" -"ださい" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Client" -msgstr "クライアント" - -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "内容" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 -msgid "Date" -msgstr "日時" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 -msgid "User" -msgstr "ユーザー" - -#: ../src\wxUI\buffers\base.py:27 -msgid "Direct message" -msgstr "ダイレクトメッセージ" - -#: ../src\wxUI\buffers\events.py:13 -msgid "Event" -msgstr "イベント" - -#: ../src\wxUI\buffers\events.py:15 -msgid "Remove event" -msgstr "イベントを削除" - -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 -msgid "Login" -msgstr "ログイン" - -#: ../src\wxUI\buffers\panels.py:13 -msgid "Log in automatically" -msgstr "自動的にログインする" - -#: ../src\wxUI\buffers\panels.py:21 -msgid "Logout" -msgstr "ログアウト" - -#: ../src\wxUI\buffers\trends.py:8 -msgid "Trending topic" -msgstr "トレンドの話題" - -#: ../src\wxUI\buffers\trends.py:18 -msgid "Tweet about this trend" -msgstr "このトレンドのツイート" - -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 -msgid "Search topic" -msgstr "トピックを検索" - -#: ../src\wxUI\commonMessageDialogs.py:6 -msgid "" -"This retweet is over 140 characters. Would you like to post it as a mention " -"to the poster with your comments and a link to the original tweet?" -msgstr "" -"このリツイートは、140文字を超えています。投稿者へのリプライとコメント、お" -"よび元のツイートへのリンクで登校しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:9 -msgid "Would you like to add a comment to this tweet?" -msgstr "このツイートにコメントをつけますか?" - -#: ../src\wxUI\commonMessageDialogs.py:12 -msgid "" -"Do you really want to delete this tweet? It will be deleted from Twitter as " -"well." -msgstr "" -"本当にこのツイートを削除しますか?このツイートは、ツイッターから削除されま" -"す。" - -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 -msgid "Delete" -msgstr "削除" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Do you really want to close {0}?" -msgstr "本当に「{0}」を終了しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:15 -msgid "Exit" -msgstr "終了確認" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid " {0} must be restarted for these changes to take effect." -msgstr "これらの変更を有効にするには、「{0}」を再起動する必要があります。" - -#: ../src\wxUI\commonMessageDialogs.py:19 -msgid "Restart {0} " -msgstr "「{0}」を再起動" - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "" -"Are you sure you want to delete this user from the database? This user will " -"not appear in autocomplete results anymore." -msgstr "" -"データベースからこのユーザーを削除してもよろしいですか?このユーザーは、自動" -"補完結果には表示されません。" - -#: ../src\wxUI\commonMessageDialogs.py:22 -msgid "Confirm" -msgstr "確認" - -#: ../src\wxUI\commonMessageDialogs.py:25 -msgid "Enter the name of the client : " -msgstr "クライアントの名前:" - -#: ../src\wxUI\commonMessageDialogs.py:25 -#: ../src\wxUI\dialogs\configuration.py:246 -msgid "Add client" -msgstr "クライアントを追加" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "" -"Do you really want to empty this buffer? It's items will be removed from " -"the list but not from Twitter" -msgstr "" -"本当にこのバッファをクリアしますか?これは、ツイッターからは削除されません。" - -#: ../src\wxUI\commonMessageDialogs.py:31 -msgid "Empty buffer" -msgstr "バッファをクリア" - -#: ../src\wxUI\commonMessageDialogs.py:35 -msgid "Do you really want to destroy this buffer?" -msgstr "本当にこのバッファを削除しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Attention" -msgstr "確認" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "A timeline for this user already exists. You can't open another" -msgstr "" -"そのユーザーのタイムラインは、既に開かれています。他のユーザーを開いてくださ" -"い。" - -#: ../src\wxUI\commonMessageDialogs.py:41 -msgid "Existing timeline" -msgstr "既存のタイムライン" - -#: ../src\wxUI\commonMessageDialogs.py:44 -msgid "This user has no tweets, so you can't open a timeline for them." -msgstr "" -"このユーザーは、何もツイートしていないため、タイムラインを開くことができませ" -"ん。" - -#: ../src\wxUI\commonMessageDialogs.py:47 -msgid "" -"This is a protected Twitter user, which means you can't open a timeline " -"using the Streaming API. The user's tweets will not update due to a twitter " -"policy. Do you want to continue?" -msgstr "" -"このアカウントは、保護されています。これは、ストリーミングAPIを利用して、タイ" -"ムラインを開くことができないことを意味します。ユーザーのツイートはTwitterのポ" -"リシーにより更新されません。続行しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "Warning" -msgstr "警告" - -#: ../src\wxUI\commonMessageDialogs.py:50 -msgid "" -"This is a protected user account, you need to follow this user to view their " -"tweets or likes." -msgstr "" -"このユーザーは保護されています。このユーザーのツイートやお気に入り一覧を見る" -"には、このユーザーをフォローする必要があります。" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "" -"If you like {0} we need your help to keep it going. Help us by donating to " -"the project. This will help us pay for the server, the domain and some other " -"things to ensure that {0} will be actively maintained. Your donation will " -"give us the means to continue the development of {0}, and to keep {0} free. " -"Would you like to donate now?" -msgstr "" -"「{0}」が好きなら、私たちは、それを続けるために、助けを必要としています。プロ" -"ジェクトに寄付することで、私たちを助けてください。これは、私たちは{0}が積極的" -"に維持されることを保証するために、サーバー、ドメイン、およびいくつかの他のも" -"ののために支払うのに役立ちます。あなたの寄付は私たちに「{0}」の開発を継続する" -"ための手段を与え、自由な「{0}」を維持します。今すぐ寄付しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:53 -msgid "We need your help" -msgstr "寄付のお願い" - -#: ../src\wxUI\commonMessageDialogs.py:57 -msgid "This user has no tweets. {0} can't create a timeline." -msgstr "" -"このユーザーにはツイートがないため、「{0}」のタイムラインを作成することはでき" -"ません。" - -#: ../src\wxUI\commonMessageDialogs.py:60 -msgid "This user has no favorited tweets. {0} can't create a timeline." -msgstr "" -"このユーザーには、お気に入り登録されたツイートがないため、「{0}」のタイムライ" -"ンを作成することはできません。" - -#: ../src\wxUI\commonMessageDialogs.py:63 -msgid "This user has no followers. {0} can't create a timeline." -msgstr "" -"このユーザーのフォロワーがいないため、「{0}」でタイムラインを作ることはできま" -"せん。" - -#: ../src\wxUI\commonMessageDialogs.py:66 -msgid "This user has no friends. {0} can't create a timeline." -msgstr "" -"このユーザーは、誰もフォローしていないため、「{0}」でタイムラインを作ることは" -"できません。" - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geo data for this tweet" -msgstr "このツイートの位置情報" - -#: ../src\wxUI\commonMessageDialogs.py:70 -msgid "Geolocation data: {0}" -msgstr "位置情報: {0}" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "Information" -msgstr "情報" - -#: ../src\wxUI\commonMessageDialogs.py:73 -msgid "" -"TWBlue has detected that you're running windows 10 and has changed the " -"default keymap to the Windows 10 keymap. It means that some keyboard " -"shorcuts could be different. Please check the keystroke editor by pressing " -"Alt+Win+K to see all available keystrokes for this keymap." -msgstr "" -"TWBlueは、Windows10で動作していることを検出したため、デフォルトのキーマップを" -"Windows10のキーマップに変更しました。これは、一部のキーボードショートカットが" -"違うことを意味します。このキーマップで使用できる全てのショートカットを見るに" -"は、Alt+Win+Kで、キーストロークエディタを開いて確認してください。" - -#: ../src\wxUI\commonMessageDialogs.py:76 -msgid "You have been blocked from viewing this content" -msgstr "このコンテンツの表示がブロックされています" - -#: ../src\wxUI\commonMessageDialogs.py:79 -msgid "" -"You have been blocked from viewing someone's content. In order to avoid " -"conflicts with the full session, TWBlue will remove the affected timeline." -msgstr "" -"他のユーザーのコンテンツを表示できないようになっています。フルセッションとの" -"競合を避けるため、TWBlueは影響を受けるタイムラインを削除します。" - -#: ../src\wxUI\commonMessageDialogs.py:82 -msgid "" -"TWBlue cannot load this timeline because the user has been suspended from " -"Twitter." -msgstr "" -"ユーザーがTwitterから凍結されているため、このタイムラインをロードできません。" - -#: ../src\wxUI\commonMessageDialogs.py:85 -msgid "Do you really want to delete this filter?" -msgstr "本当に、このフィルターを削除しますか?" - -#: ../src\wxUI\commonMessageDialogs.py:88 -msgid "This filter already exists. Please use a different title" -msgstr "このフィルターはすでに利用されています。別の名前を利用してください" - -#: ../src\wxUI\commonMessageDialogs.py:94 -msgid "" -"{0} quit unexpectedly the last time it was run. If the problem persists, " -"please report it to the {0} developers." -msgstr "" - -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "添付ファイル" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "タイトル" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "形式" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "画像(&P)" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "添付ファイルを削除" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "アップロードする画像を選択" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "説明を入力" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "説明" - -#: ../src\wxUI\dialogs\configuration.py:16 -msgid "Language" -msgstr "言語" - -#: ../src\wxUI\dialogs\configuration.py:23 -msgid "Run {0} at Windows startup" -msgstr "Windows起動時に{0}を実行" - -#: ../src\wxUI\dialogs\configuration.py:24 -msgid "ask before exiting {0}" -msgstr "{0}を終了する前に確認" - -#: ../src\wxUI\dialogs\configuration.py:27 -msgid "Disable Streaming functions" -msgstr "ストリーミング機能を無効化する" - -#: ../src\wxUI\dialogs\configuration.py:30 -msgid "Buffer update interval, in minutes" -msgstr "バッファの更新間隔(分)" - -#: ../src\wxUI\dialogs\configuration.py:36 -msgid "Play a sound when {0} launches" -msgstr "{0}が起動したときに、音声を再生" - -#: ../src\wxUI\dialogs\configuration.py:38 -msgid "Speak a message when {0} launches" -msgstr "{0}が起動した際に、メッセージを読み上げ" - -#: ../src\wxUI\dialogs\configuration.py:40 -msgid "Use invisible interface's keyboard shortcuts while GUI is visible" -msgstr "GUI表示中でもGUI非表示時に利用できるショートカットを利用する" - -#: ../src\wxUI\dialogs\configuration.py:42 -msgid "Activate Sapi5 when any other screen reader is not being run" -msgstr "他のスクリーンリーダーが起動していないときは、Sapi5を利用する" - -#: ../src\wxUI\dialogs\configuration.py:44 -msgid "Hide GUI on launch" -msgstr "起動時にGUIを隠す" - -#: ../src\wxUI\dialogs\configuration.py:46 -msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" -msgstr "" -"Codeofduskを利用して長いツイートをできるようにする(パフォーマンスが低下する" -"場合があります)" - -#: ../src\wxUI\dialogs\configuration.py:48 -msgid "Remember state for mention all and long tweet" -msgstr "" -"「全員にリプライ」および「ツイートを短縮して投稿」のチェック状態を保持する" - -#: ../src\wxUI\dialogs\configuration.py:51 -msgid "Keymap" -msgstr "キーマップ" - -#: ../src\wxUI\dialogs\configuration.py:56 -msgid "Check for updates when {0} launches" -msgstr "{0}の起動時にアップデートを確認" - -#: ../src\wxUI\dialogs\configuration.py:66 -msgid "Proxy type: " -msgstr "プロキシタイプ: " - -#: ../src\wxUI\dialogs\configuration.py:73 -msgid "Proxy server: " -msgstr "プロキシサーバー:" - -#: ../src\wxUI\dialogs\configuration.py:79 -msgid "Port: " -msgstr "ポート:" - -#: ../src\wxUI\dialogs\configuration.py:85 -msgid "User: " -msgstr "ユーザー名:" - -#: ../src\wxUI\dialogs\configuration.py:91 -msgid "Password: " -msgstr "パスワード:" - -#: ../src\wxUI\dialogs\configuration.py:103 -msgid "Autocompletion settings..." -msgstr "自動保管の設定" - -#: ../src\wxUI\dialogs\configuration.py:105 -msgid "Relative timestamps" -msgstr "相対的な時刻を利用する" - -#: ../src\wxUI\dialogs\configuration.py:108 -msgid "Items on each API call" -msgstr "各API呼び出しの回数" - -#: ../src\wxUI\dialogs\configuration.py:114 -msgid "" -"Inverted buffers: The newest tweets will be shown at the beginning while the " -"oldest at the end" -msgstr "" -"バッファの並び順を入れ替える(新しいツイートを先頭に、古いツイートを最後に表" -"示)" - -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet mode" -msgstr "リツイートのモード" - -#: ../src\wxUI\dialogs\configuration.py:122 -msgid "Show screen names instead of full names" -msgstr "表示名の代わりに、ユーザー名を表示する" - -#: ../src\wxUI\dialogs\configuration.py:124 -msgid "" -"Number of items per buffer to cache in database (0 to disable caching, blank " -"for unlimited)" -msgstr "" -"バッファごとにデータベースにキャッシュする項目数(0はキャッシュしない、空欄の" -"場合は無制限)" - -#: ../src\wxUI\dialogs\configuration.py:134 -msgid "Enable automatic speech feedback" -msgstr "自動音声フィードバックを有効化" - -#: ../src\wxUI\dialogs\configuration.py:136 -msgid "Enable automatic Braille feedback" -msgstr "自動点字フィードバックを有効化" - -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "ステータス" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Buffer" -msgstr "バッファ" - -#: ../src\wxUI\dialogs\configuration.py:147 -msgid "Show/hide" -msgstr "表示または非表示" - -#: ../src\wxUI\dialogs\configuration.py:148 -msgid "Move up" -msgstr "上へ" - -#: ../src\wxUI\dialogs\configuration.py:149 -msgid "Move down" -msgstr "下へ" - -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 -msgid "Show" -msgstr "表示" - -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 -msgid "Hide" -msgstr "非表示" - -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 -msgid "Select a buffer first." -msgstr "最初にバッファを選んでください" - -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 -msgid "The buffer is hidden, show it first." -msgstr "そのバッファは非表示状態です。まず最初に、表示してください" - -#: ../src\wxUI\dialogs\configuration.py:175 -msgid "The buffer is already at the top of the list." -msgstr "既にそのバッファは、リストの先頭です" - -#: ../src\wxUI\dialogs\configuration.py:199 -msgid "The buffer is already at the bottom of the list." -msgstr "既にそのバッファは、リストの最後です" - -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 -msgid "Ignored clients" -msgstr "無視するクライアント" - -#: ../src\wxUI\dialogs\configuration.py:247 -msgid "Remove client" -msgstr "クライアントを削除" - -#: ../src\wxUI\dialogs\configuration.py:271 -msgid "Volume" -msgstr "ボリューム" - -#: ../src\wxUI\dialogs\configuration.py:282 -msgid "Session mute" -msgstr "セッションのミュート" - -#: ../src\wxUI\dialogs\configuration.py:284 -msgid "Output device" -msgstr "出力先デバイス" - -#: ../src\wxUI\dialogs\configuration.py:291 -msgid "Input device" -msgstr "入力デバイス" - -#: ../src\wxUI\dialogs\configuration.py:299 -msgid "Sound pack" -msgstr "サウンドパック" - -#: ../src\wxUI\dialogs\configuration.py:305 -msgid "Indicate audio tweets with sound" -msgstr "音声付きツイートを音で報告" - -#: ../src\wxUI\dialogs\configuration.py:307 -msgid "Indicate geotweets with sound" -msgstr "位置情報付きツイートを音で報告" - -#: ../src\wxUI\dialogs\configuration.py:309 -msgid "Indicate tweets containing images with sound" -msgstr "画像付きツイートを音で報告" - -#: ../src\wxUI\dialogs\configuration.py:332 -msgid "Language for OCR" -msgstr "OCRの言語" - -#: ../src\wxUI\dialogs\configuration.py:338 -msgid "API Key for SndUp" -msgstr "SndUpのAPIキー" - -#: ../src\wxUI\dialogs\configuration.py:353 -msgid "{0} preferences" -msgstr "{0}の設定" - -#: ../src\wxUI\dialogs\configuration.py:364 -msgid "Proxy" -msgstr "プロキシ" - -#: ../src\wxUI\dialogs\configuration.py:373 -msgid "Feedback" -msgstr "フィードバック" - -#: ../src\wxUI\dialogs\configuration.py:377 -msgid "Buffers" -msgstr "バッファ" - -#: ../src\wxUI\dialogs\configuration.py:385 -msgid "Sound" -msgstr "サウンド" - -#: ../src\wxUI\dialogs\configuration.py:389 -msgid "Extras" -msgstr "その他" - -#: ../src\wxUI\dialogs\configuration.py:394 -msgid "Save" -msgstr "保存" - -#: ../src\wxUI\dialogs\filterDialogs.py:15 -msgid "Create a filter for this buffer" -msgstr "このバッファのフィルタを作成" - -#: ../src\wxUI\dialogs\filterDialogs.py:16 -msgid "Filter title" -msgstr "フィルター名" - -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "単語でフィルター" - -#: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "次の単語が含まれるツイートを無視する" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -msgid "Ignore tweets without the following word" -msgstr "次の単語が含まれないツイートを無視する" - -#: ../src\wxUI\dialogs\filterDialogs.py:32 -msgid "word" -msgstr "単語" - -#: ../src\wxUI\dialogs\filterDialogs.py:37 -msgid "Allow retweets" -msgstr "リツイートを許可する" - -#: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "引用ツイートを許可する" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -msgid "Allow replies" -msgstr "リプライを許可するフォロワー一覧" - -#: ../src\wxUI\dialogs\filterDialogs.py:47 -msgid "Use this term as a regular expression" -msgstr "正規表現を利用" - -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by language" -msgstr "言語でフィルター" - -#: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "下記の言語のツイートを表示" - -#: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "下記の言語のツイートを無視する" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 -msgid "Don't filter by language" -msgstr "言語でフィルタしない" - -#: ../src\wxUI\dialogs\filterDialogs.py:63 -msgid "Supported languages" -msgstr "サポートしている言語" - -#: ../src\wxUI\dialogs\filterDialogs.py:68 -msgid "Add selected language to filter" -msgstr "選択した言語をフィルターに追加" - -#: ../src\wxUI\dialogs\filterDialogs.py:72 -msgid "Selected languages" -msgstr "選択した言語" - -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 -msgid "Remove" -msgstr "削除" - -#: ../src\wxUI\dialogs\filterDialogs.py:122 -msgid "Manage filters" -msgstr "フィルターの管理" - -#: ../src\wxUI\dialogs\filterDialogs.py:124 -msgid "Filters" -msgstr "フィルター" - -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter" -msgstr "フィルター" - -#: ../src\wxUI\dialogs\find.py:12 -msgid "Find in current buffer" -msgstr "現在のバッファ内を検索" - -#: ../src\wxUI\dialogs\find.py:13 -msgid "String" -msgstr "検索文字" - -#: ../src\wxUI\dialogs\lists.py:10 -msgid "Lists manager" -msgstr "リストの管理" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "List" -msgstr "リスト" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Members" -msgstr "メンバー" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "Owner" -msgstr "所有者" - -#: ../src\wxUI\dialogs\lists.py:13 -msgid "mode" -msgstr "モード" - -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 -msgid "Create a new list" -msgstr "新しいリストを作成" - -#: ../src\wxUI\dialogs\lists.py:21 -msgid "Open in buffer" -msgstr "バッファで開く" - -#: ../src\wxUI\dialogs\lists.py:51 -msgid "Viewing lists for %s" -msgstr "「%s」のリストを閲覧中" - -#: ../src\wxUI\dialogs\lists.py:52 -msgid "Subscribe" -msgstr "登録" - -#: ../src\wxUI\dialogs\lists.py:53 -msgid "Unsubscribe" -msgstr "登録解除" - -#: ../src\wxUI\dialogs\lists.py:64 -msgid "Name (20 characters maximun)" -msgstr "名前(二〇文字以内)" - -#: ../src\wxUI\dialogs\lists.py:74 -msgid "Mode" -msgstr "モード" - -#: ../src\wxUI\dialogs\lists.py:75 -msgid "Public" -msgstr "公開" - -#: ../src\wxUI\dialogs\lists.py:76 -msgid "Private" -msgstr "プライベート" - -#: ../src\wxUI\dialogs\lists.py:96 -msgid "Editing the list %s" -msgstr "リスト「%s」を編集中" - -#: ../src\wxUI\dialogs\lists.py:107 -msgid "Select a list to add the user" -msgstr "ユーザーを追加するリストを選択" - -#: ../src\wxUI\dialogs\lists.py:108 -msgid "Add" -msgstr "追加" - -#: ../src\wxUI\dialogs\lists.py:130 -msgid "Select a list to remove the user" -msgstr "ユーザーを削除するには、リストを選択" - -#: ../src\wxUI\dialogs\lists.py:148 -msgid "Do you really want to delete this list?" -msgstr "本当に、このリストを削除しますか?" - -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "ツイートを短縮して投稿(&L)" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "画像をアップロード(&U)" - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "スペルチェック(&S)" - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "音声を添付(&A)" - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "URLを短縮(&O)" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "URLを元に戻す(&E)" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "翻訳(&T)..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "ユーザーを自動保管(&C)" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "送信(&D)" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "閉じる(&C)" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "送信先(&R)" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "全員にリプライ(&M)" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "ツイート - %i文字" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "画像の説明" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "リツイート:" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "いいね" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "ソース:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "日時" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "ツイート" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "アイテム" - -#: ../src\wxUI\dialogs\search.py:13 -msgid "Search on Twitter" -msgstr "ツイッターを検索" - -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 -msgid "&Search" -msgstr "検索(&S)" - -#: ../src\wxUI\dialogs\search.py:21 -msgid "Tweets" -msgstr "ツイート" - -#: ../src\wxUI\dialogs\search.py:22 -msgid "Users" -msgstr "ユーザー" - -#: ../src\wxUI\dialogs\search.py:29 -msgid "&Language for results: " -msgstr "結果の言語(&L):" - -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 -msgid "any" -msgstr "指定しない" - -#: ../src\wxUI\dialogs\search.py:37 -msgid "Results &type: " -msgstr "結果のタイプ(&T):" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 -msgid "Mixed" -msgstr "混合" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 -msgid "Recent" -msgstr "最近" - -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 -msgid "Popular" -msgstr "人気" - -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 -msgid "&OK" -msgstr "OK(&O)" - -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 -msgid "&Close" -msgstr "閉じる(&C)" - -#: ../src\wxUI\dialogs\show_user.py:11 -msgid "Details" -msgstr "詳細" - -#: ../src\wxUI\dialogs\show_user.py:16 -msgid "&Go to URL" -msgstr "URLへ移動(&G)" - -#: ../src\wxUI\dialogs\trends.py:12 -msgid "View trending topics" -msgstr "トレンドの話題を表示" - -#: ../src\wxUI\dialogs\trends.py:13 -msgid "Trending topics by" -msgstr "トレンドの話題" - -#: ../src\wxUI\dialogs\trends.py:15 -msgid "Country" -msgstr "国" - -#: ../src\wxUI\dialogs\trends.py:16 -msgid "City" -msgstr "都市" - -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 -msgid "&Location" -msgstr "場所(&L)" - -#: ../src\wxUI\dialogs\update_profile.py:9 -msgid "Update your profile" -msgstr "プロフィールを更新" - -#: ../src\wxUI\dialogs\update_profile.py:11 -msgid "&Name (50 characters maximum)" -msgstr "名前(50文字以内)(&N)" - -#: ../src\wxUI\dialogs\update_profile.py:22 -msgid "&Website" -msgstr "ウェブサイト(&W)" - -#: ../src\wxUI\dialogs\update_profile.py:27 -msgid "&Bio (160 characters maximum)" -msgstr "自己紹介(160文字以内)(&B)" - -#: ../src\wxUI\dialogs\update_profile.py:33 -msgid "Upload a &picture" -msgstr "画像をアップロード(&P)" - -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 -msgid "&Update profile" -msgstr "プロフィールを更新(&U)" - -#: ../src\wxUI\dialogs\update_profile.py:76 -msgid "Upload a picture" -msgstr "画像をアップロード" - -#: ../src\wxUI\dialogs\update_profile.py:78 -msgid "Discard image" -msgstr "画像をアップロードできません" - -#: ../src\wxUI\dialogs\urlList.py:5 -msgid "Select URL" -msgstr "URLを選択" - -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 -msgid "&User" -msgstr "ユーザー(&U)" - -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 -msgid "&Autocomplete users" -msgstr "自動保管されたユーザー" - -#: ../src\wxUI\dialogs\userActions.py:19 -msgid "&Follow" -msgstr "フォロー(&F)" - -#: ../src\wxUI\dialogs\userActions.py:20 -msgid "U&nfollow" -msgstr "フォロー解除(&N)" - -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 -msgid "&Mute" -msgstr "ミュート(&M)" - -#: ../src\wxUI\dialogs\userActions.py:22 -msgid "Unmu&te" -msgstr "ミュート解除(&T)" - -#: ../src\wxUI\dialogs\userActions.py:23 -msgid "&Block" -msgstr "ブロック(&B)" - -#: ../src\wxUI\dialogs\userActions.py:24 -msgid "Unbl&ock" -msgstr "ブロック解除(&O)" - -#: ../src\wxUI\dialogs\userActions.py:25 -msgid "&Report as spam" -msgstr "スパムとして報告(&R)" - -#: ../src\wxUI\dialogs\userActions.py:26 -msgid "&Ignore tweets from this client" -msgstr "このクライアントからのツイートを無視(&I)" - -#: ../src\wxUI\dialogs\userSelection.py:9 -msgid "Timeline for %s" -msgstr "「%s」のタイムライン" - -#: ../src\wxUI\dialogs\userSelection.py:18 -msgid "Buffer type" -msgstr "バッファのタイプ" - -#: ../src\wxUI\dialogs\userSelection.py:19 -msgid "&Tweets" -msgstr "ツイート(&T)" - -#: ../src\wxUI\dialogs\userSelection.py:20 -msgid "&Likes" -msgstr "いいね(&L)" - -#: ../src\wxUI\dialogs\userSelection.py:21 -msgid "&Followers" -msgstr "フォロワー(&F)" - -#: ../src\wxUI\dialogs\userSelection.py:22 -msgid "F&riends" -msgstr "フォロー(&R)" - -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 -msgid "&Retweet" -msgstr "リツイート(&R)" - -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 -msgid "Re&ply" -msgstr "リプライ(&P)" - -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 -msgid "&Like" -msgstr "いいね(&L)" - -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 -msgid "&Unlike" -msgstr "いいねを解除(&U)" - -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 -msgid "&Open URL" -msgstr "URLを開く(&O)" - -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy -msgid "&Open in Twitter" -msgstr "ツイッターを検索" - -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 -msgid "&Play audio" -msgstr "音声を再生(&P)" - -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 -msgid "&Show tweet" -msgstr "ツイートを表示(&S)" - -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 -msgid "&Copy to clipboard" -msgstr "クリップボードにコピー(&C)" - -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 -msgid "&Delete" -msgstr "削除(&D)" - -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 -msgid "&User actions..." -msgstr "ユーザーのアクション(&U)" - -#: ../src\wxUI\menus.py:39 -msgid "&Show direct message" -msgstr "ダイレクトメッセージを表示(&S)" - -#: ../src\wxUI\menus.py:67 -msgid "&Show event" -msgstr "イベントを表示(&S)" - -#: ../src\wxUI\menus.py:77 -msgid "Direct &message" -msgstr "ダイレクトメッセージ(&M)" - -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 -msgid "&View lists" -msgstr "リストを見る(&V)" - -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 -msgid "Show user &profile" -msgstr "ユーザーのプロフィールを表示(&P)" - -#: ../src\wxUI\menus.py:84 -msgid "&Show user" -msgstr "ユーザーを表示(&S)" - -#: ../src\wxUI\menus.py:98 -msgid "&Tweet about this trend" -msgstr "このトレンドのツイート(&T)" - -#: ../src\wxUI\menus.py:100 -msgid "&Show item" -msgstr "アイテムを表示(&S)" - -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 -msgid "&Global settings" -msgstr "全般設定(&G)" - -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 -msgid "Account se&ttings" -msgstr "アカウント設定(&T(" - -#: ../src\wxUI\sysTrayIcon.py:37 -msgid "Update &profile" -msgstr "プロフィールを更新(&P)" - -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "&Show / hide" -msgstr "表示または非表示(&S)" - -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 -msgid "&Documentation" -msgstr "取扱説明書(&D)" - -#: ../src\wxUI\sysTrayIcon.py:40 -msgid "Check for &updates" -msgstr "アップデートを確認(&U)" - -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "&Exit" -msgstr "終了(&E)" - -#: ../src\wxUI\view.py:16 -msgid "&Manage accounts" -msgstr "アカウントの管理(&M)" - -#: ../src\wxUI\view.py:18 -msgid "&Hide window" -msgstr "ウィンドウを隠す(&H)" - -#: ../src\wxUI\view.py:20 -msgid "&Lists manager" -msgstr "リストの管理(&L)" - -#: ../src\wxUI\view.py:21 -msgid "&Edit keystrokes" -msgstr "キーストロークを編集(&E)" - -#: ../src\wxUI\view.py:24 -msgid "E&xit" -msgstr "終了(&X)" - -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 -msgid "&Tweet" -msgstr "ツイート(&T)" - -#: ../src\wxUI\view.py:34 -msgid "View &address" -msgstr "位置情報を表示(&A)" - -#: ../src\wxUI\view.py:35 -msgid "View conversa&tion" -msgstr "会話を見る(&T)" - -#: ../src\wxUI\view.py:36 -msgid "Read text in picture" -msgstr "画像からテキストを読み取り" - -#: ../src\wxUI\view.py:41 -msgid "&Actions..." -msgstr "操作(&A)" - -#: ../src\wxUI\view.py:42 -msgid "&View timeline..." -msgstr "タイムラインを表示(&V)" - -#: ../src\wxUI\view.py:43 -msgid "Direct me&ssage" -msgstr "ダイレクトメッセージ(&S)" - -#: ../src\wxUI\view.py:44 -msgid "&Add to list" -msgstr "リストに追加(&A)" - -#: ../src\wxUI\view.py:45 -msgid "R&emove from list" -msgstr "リストから削除(&E)" - -#: ../src\wxUI\view.py:48 -msgid "V&iew likes" -msgstr "いいね一覧を見る(&I)" - -#: ../src\wxUI\view.py:52 -msgid "&Update buffer" -msgstr "バッファを更新(&U)" - -#: ../src\wxUI\view.py:53 -msgid "New &trending topics buffer..." -msgstr "新しいトレンドの話題のバッファ(&T)" - -#: ../src\wxUI\view.py:54 -msgid "Create a &filter" -msgstr "新しいフィルターを作成(&F)" - -#: ../src\wxUI\view.py:55 -msgid "&Manage filters" -msgstr "フィルターの管理(&M)" - -#: ../src\wxUI\view.py:56 -msgid "Find a string in the currently focused buffer..." -msgstr "現在フォーカス中のバッファ内の文字列を検索" - -#: ../src\wxUI\view.py:57 -msgid "&Load previous items" -msgstr "以前のアイテムを取得(&L)" - -#: ../src\wxUI\view.py:60 -msgid "&Autoread" -msgstr "自動読み上げ(&A)" - -#: ../src\wxUI\view.py:61 -msgid "&Clear buffer" -msgstr "バッファをクリア(&C)" - -#: ../src\wxUI\view.py:62 -msgid "&Destroy" -msgstr "バッファを削除(&D)" - -#: ../src\wxUI\view.py:66 -msgid "&Seek back 5 seconds" -msgstr "5秒戻る(&S)" - -#: ../src\wxUI\view.py:67 -msgid "&Seek forward 5 seconds" -msgstr "5秒進む(&S)" - -#: ../src\wxUI\view.py:72 -msgid "Sounds &tutorial" -msgstr "サウンドの確認(&T)" - -#: ../src\wxUI\view.py:73 -msgid "&What's new in this version?" -msgstr "更新履歴(&W)" - -#: ../src\wxUI\view.py:74 -msgid "&Check for updates" -msgstr "アップデートを確認(&C)" - -#: ../src\wxUI\view.py:75 -msgid "&Report an error" -msgstr "エラーを報告(&R)" - -#: ../src\wxUI\view.py:76 -msgid "{0}'s &website" -msgstr "「{0}」のウェブサイト(&W)" - -#: ../src\wxUI\view.py:77 -msgid "Get soundpacks for TWBlue" -msgstr "" - -#: ../src\wxUI\view.py:78 -msgid "About &{0}" -msgstr "{0}について(&A)" - -#: ../src\wxUI\view.py:81 -msgid "&Application" -msgstr "アプリケーション(&A)" - -#: ../src\wxUI\view.py:84 -msgid "&Buffer" -msgstr "バッファ(&B)" - -#: ../src\wxUI\view.py:85 -msgid "&Audio" -msgstr "音声(&A)" - -#: ../src\wxUI\view.py:86 -msgid "&Help" -msgstr "ヘルプ(&H)" - -#: ../src\wxUI\view.py:172 -msgid "Address" -msgstr "アドレス" - -#: ../src\wxUI\view.py:203 -msgid "Update" -msgstr "アップデート" - -#: ../src\wxUI\view.py:203 -msgid "Your {0} version is up to date" -msgstr "「{0}」のバージョンは最新です" - -#~ msgid "Empty" -#~ msgstr "何もありません" - -#~ msgid "One mention from %s " -#~ msgstr "%sからの返信" - -#~ msgid "One tweet from %s" -#~ msgstr "「%s」からのツイート" - -#~ msgid "You've blocked %s" -#~ msgstr "「%s」をブロックしました。" - -#~ msgid "You've unblocked %s" -#~ msgstr "「%s」のブロックを解除しました" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "「%s: @%s」がフォローしました" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "「%s: @%s」をフォローしました" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "「%s: @%s」のフォローを解除しました" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "%s %sをいいねしました" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s)が「%s」をいいねしました" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "%s %sのいいねを解除しました" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s)が%sのいいねを解除しました" - -#~ msgid "You've created the list %s" -#~ msgstr "リスト「%s」を作成しました" - -#~ msgid "You've deleted the list %s" -#~ msgstr "リスト「%s」を削除しました" - -#~ msgid "You've updated the list %s" -#~ msgstr "リスト「%s」をアップデートしました" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "「%s: @%s」をリスト「%s」に追加しました" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "「%s: @%s」がリスト「%s」にあなたを追加しました" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "「%s: @%s」をリスト「%s」から削除しました" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "「%s: @%s」がリスト「%s」からあなたを削除しました" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」に加入しました" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "「%s(@%s)」があなたのリスト「%s」を購読しました" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」から退会しました" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」から退会してきました" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "「%s: @%s」がリツイートした「%s」をリツイートしました" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "「%s: @%s」があなたのリツイート「%s」をリツイートしました" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "APIの呼び出し数(1回のAPIの呼び出し=200、2回のAPIの呼び出し=400、など)" - -#~ msgid "Unable to upload the audio" -#~ msgstr "音声をアップロードできません" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "アカウント連携を待機しています…" - -#~ msgid "autodetect" -#~ msgstr "自動検出" - -#~ msgid "" -#~ "There's a new %s version available. Would you like to download it now?\n" -#~ "\n" -#~ " %s version: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" -#~ msgstr "" -#~ "「%s」の新しいバージョンが利用可能です。今すぐダウンロードしますか?\n" -#~ "\n" -#~ "%sバージョン: %s\n" -#~ "\n" -#~ "更新履歴\n" -#~ "%s" - -#~ msgid "Start {0} after logging in windows" -#~ msgstr "Windowsログオン後に{0}を起動" - -#~ msgid "" -#~ "If you have a SndUp account, enter your API Key here. If your API Key is " -#~ "invalid, {0} will fail to upload. If there is no API Key here, {0} will " -#~ "upload annonymously." -#~ msgstr "" -#~ "SndUpアカウントをお持ちの場合は、ここにAPIキーを入力してください。APIキー" -#~ "が無効である場合、{0}のアップロードに失敗します。APIキーが存在しない場合" -#~ "は、{0}は、匿名でアップロードされます。" - -#~ msgid "Disconnect your Pocket account" -#~ msgstr "Poketとの連携を解除" - -#~ msgid "Connect your Pocket account" -#~ msgstr "Pocketアカウントと連携" - -#~ msgid "Pocket Authorization" -#~ msgstr "Pocketの認証" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. You only need " -#~ "to do this once. Do you want to continue?" -#~ msgstr "" -#~ "認証要求をブラウザで開きます。一度だけこれを実行する必要があります。続行し" -#~ "ますか?" - -#~ msgid "Error during authorization. Try again later." -#~ msgstr "認証中にエラーが発生しました。後でやり直してください。" - -#~ msgid "Services" -#~ msgstr "サービス" - -#~ msgid "Contains" -#~ msgstr "含む" - -#~ msgid "Doesn't contain" -#~ msgstr "含まない" - -#~ msgid "" -#~ "You have successfully logged into Twitter with {0}. You can close this " -#~ "window now." -#~ msgstr "" -#~ "{0}でのTwitterのログインに成功しました。今すぐこのウィンドウを閉じることが" -#~ "できます。" diff --git a/src/locales/ja/lc_messages/twblue.mo b/src/locales/ja/lc_messages/twblue.mo index 57e20370..aab8b3f0 100644 Binary files a/src/locales/ja/lc_messages/twblue.mo and b/src/locales/ja/lc_messages/twblue.mo differ diff --git a/src/locales/ja/lc_messages/twblue.po b/src/locales/ja/lc_messages/twblue.po index cb3a697e..1354cdac 100644 --- a/src/locales/ja/lc_messages/twblue.po +++ b/src/locales/ja/lc_messages/twblue.po @@ -5,290 +5,289 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2019-07-06 23:53+0900\n" -"Last-Translator: Manuel Cortez \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2021-11-12 08:18+0900\n" +"Last-Translator: 陸 \n" "Language-Team: \n" "Language: ja_JP\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 3.0\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "画像" - -#: ../src\controller\buffers\baseBuffers.py:95 +#: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" -msgstr "この動作は、現在のバッファではサポートされていません。" +msgstr "この動作は、現在のバッファではサポートされていません" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 msgid "Home" msgstr "ホーム" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 msgid "Mentions" msgstr "メンション" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:341 msgid "Direct messages" msgstr "ダイレクトメッセージ" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 msgid "Sent direct messages" msgstr "送信済みのダイレクトメッセージ" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 msgid "Sent tweets" msgstr "送信済みのツイート" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:347 +#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 msgid "Likes" msgstr "いいね" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:349 +#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 msgid "Followers" msgstr "フォロワー" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "フォロー" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:353 +#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 msgid "Blocked users" msgstr "ブロックしたユーザー" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:355 +#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 msgid "Muted users" msgstr "ミューとしたユーザー" -#: ../src\controller\buffers\twitterBuffers.py:75 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 +msgid "Friends" +msgstr "フォロー" + +#: ../src\controller\buffers\twitter\base.py:76 msgid "{username}'s timeline" msgstr "「{username}」のタイムライン" -#: ../src\controller\buffers\twitterBuffers.py:77 +#: ../src\controller\buffers\twitter\base.py:78 msgid "{username}'s likes" msgstr "「{username}」のいいね一覧" -#: ../src\controller\buffers\twitterBuffers.py:79 +#: ../src\controller\buffers\twitter\base.py:80 msgid "{username}'s followers" msgstr "「{username}」のフォロワー" -#: ../src\controller\buffers\twitterBuffers.py:81 +#: ../src\controller\buffers\twitter\base.py:82 msgid "{username}'s friends" msgstr "「{username}」のフォロー" -#: ../src\controller\buffers\twitterBuffers.py:83 +#: ../src\controller\buffers\twitter\base.py:84 msgid "Unknown buffer" msgstr "不明なバッファ" -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 +#: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "ツイート" -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "ツイートを入力" -#: ../src\controller\buffers\twitterBuffers.py:194 +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" msgstr "「{0}」への新規ツイート" -#: ../src\controller\buffers\twitterBuffers.py:197 +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." -msgstr "「{1}」への{0}個の新規ツイート" +msgstr "「{1}」への{0}個の新規ツイート。" -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 +#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\directMessages.py:88 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s個のアイテムを取得しました" -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 +#: ../src\controller\buffers\twitter\base.py:266 +#: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." -msgstr "このバッファは、タイムラインではないため、削除できません" +msgstr "このバッファは、タイムラインではないため、削除できません。" -#: ../src\controller\buffers\twitterBuffers.py:402 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "「{arg0}」への返信:" -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 +#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "返信" -#: ../src\controller\buffers\twitterBuffers.py:405 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "「%s」への返信" -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "「%s」へのダイレクトメッセージ" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "新しいダイレクトメッセージ" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 +msgid "Direct message to %s" +msgstr "「%s」へのダイレクトメッセージ" + +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "ツイートにコメントを追加" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "引用" -#: ../src\controller\buffers\twitterBuffers.py:572 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." -msgstr "URLを開いています" +msgstr "URLを開いています…" -#: ../src\controller\buffers\twitterBuffers.py:607 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "ユーザーの詳細" -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." -msgstr "アイテムをブラウザで開いています…" +msgstr "ブラウザでアイテムを開いています…" -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "%sへのメンション" -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "メンション" -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." -msgstr "新しいダイレクトメッセージ " +msgstr "{0}件の新しいダイレクトメッセージ。" -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\buffers\twitterBuffers.py:741 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." msgstr "" -"このバッファでは、これ以上のアイテムを取得することはできません。代わりに、" -"「ダイレクトメッセージ」バッファを使用してください。" +"このバッファでは、さらにアイテムを取得することはできません。代わりにダイレク" +"トメッセージバッファを使用してください。" -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." -msgstr "新しいフォロワー" +msgstr "{0}人の新しいフォロワー。" -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\mainController.py:273 +#: ../src\controller\mainController.py:277 msgid "Ready" msgstr "準備完了" -#: ../src\controller\mainController.py:345 +#: ../src\controller\mainController.py:351 +msgid "Following" +msgstr "フォロー中" + +#: ../src\controller\mainController.py:356 msgid "Timelines" msgstr "タイムライン" -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 +#: ../src\controller\mainController.py:359 +#: ../src\controller\mainController.py:883 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "「{}」のタイムライン" -#: ../src\controller\mainController.py:352 +#: ../src\controller\mainController.py:360 msgid "Likes timelines" msgstr "ほかのユーザーのいいね一覧" -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 +#: ../src\controller\mainController.py:363 +#: ../src\controller\mainController.py:902 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "{}のいいね一覧" -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" +#: ../src\controller\mainController.py:364 +msgid "Followers timelines" msgstr "フォロワー一覧" -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 +#: ../src\controller\mainController.py:367 +#: ../src\controller\mainController.py:921 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "{}をフォローしているユーザー" -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" +#: ../src\controller\mainController.py:368 +msgid "Following timelines" msgstr "フォロー一覧" -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 +#: ../src\controller\mainController.py:371 +#: ../src\controller\mainController.py:940 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "{}がフォローしているユーザー" -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 +#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 msgid "Lists" msgstr "リスト" -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 +#: ../src\controller\mainController.py:375 +#: ../src\controller\mainController.py:1422 msgid "List for {}" msgstr "{}のリスト" -#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:376 msgid "Searches" msgstr "検索" -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 +#: ../src\controller\mainController.py:379 +#: ../src\controller\mainController.py:426 +#: ../src\controller\mainController.py:431 msgid "Search for {}" msgstr "「{}」の検索結果" -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 +#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" -msgstr "{}の話題のトピック" +msgstr "%s のトレンド" -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 +#: ../src\controller\mainController.py:448 +#: ../src\controller\mainController.py:464 +#: ../src\controller\mainController.py:1080 +#: ../src\controller\mainController.py:1099 +#: ../src\controller\mainController.py:1118 +#: ../src\controller\mainController.py:1137 msgid "" "No session is currently in focus. Focus a session with the next or previous " "session shortcut." @@ -296,241 +295,245 @@ msgstr "" "セッションが選択されていません。「次のセッション」または「前のセッション」の" "ショートカットを利用して、セッションを選択してください。" -#: ../src\controller\mainController.py:465 +#: ../src\controller\mainController.py:452 msgid "Empty buffer." -msgstr "バッファをクリア" +msgstr "からのバッファ。" -#: ../src\controller\mainController.py:472 +#: ../src\controller\mainController.py:459 msgid "{0} not found." msgstr "{0}が見つかりませんでした。" -#: ../src\controller\mainController.py:482 +#: ../src\controller\mainController.py:469 msgid "Filters cannot be applied on this buffer" -msgstr "" -"このバッファにフィルターは適応できません。その動作は、現在のバッファでは利用" -"できません。" +msgstr "このバッファにはフィルターを適応できません" -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 +#: ../src\controller\mainController.py:522 +#: ../src\controller\mainController.py:539 +#: ../src\controller\mainController.py:568 msgid "Select the user" msgstr "ユーザーを選択" -#: ../src\controller\mainController.py:809 ../src\controller\messages.py:236 -#, fuzzy -msgid "MMM D, YYYY. H:m" -msgstr "YYYY年MMMMD日(dddd) H時m分s秒" +#: ../src\controller\mainController.py:753 +msgid "Add an user alias" +msgstr "ユーザーエイリアスを追加" -#: ../src\controller\mainController.py:934 +#: ../src\controller\mainController.py:761 +msgid "Alias has been set correctly for {}." +msgstr "{}のエイリアスが正しく設定されています。" + +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 +msgid "MMM D, YYYY. H:m" +msgstr "YYYY年MMMMD日 H時m分" + +#: ../src\controller\mainController.py:957 msgid "Conversation with {0}" msgstr "{0}との会話" -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 -msgid "There are no coordinates in this tweet" -msgstr "このツイートには、ジェオタグは存在しません" - -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "このツイートのジェオタグには、なにも含まれていません" - -#: ../src\controller\mainController.py:979 #: ../src\controller\mainController.py:998 -msgid "Error decoding coordinates. Try again later." -msgstr "ジェオタグの取得に失敗しました" +#: ../src\controller\mainController.py:1015 +msgid "There are no coordinates in this tweet" +msgstr "このツイートに位置情報は存在しません" -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 +#: ../src\controller\mainController.py:1000 +#: ../src\controller\mainController.py:1019 +msgid "Error decoding coordinates. Try again later." +msgstr "位置情報の取得に失敗しました。あとで再試行してください。" + +#: ../src\controller\mainController.py:1004 +msgid "Unable to find address in OpenStreetMap." +msgstr "OpenStreetMapでアドレスが見つかりません。" + +#: ../src\controller\mainController.py:1017 +msgid "There are no results for the coordinates in this tweet" +msgstr "このツイートの位置情報には、なにも含まれていません" + +#: ../src\controller\mainController.py:1128 +#: ../src\controller\mainController.py:1147 msgid "%s, %s of %s" msgstr "%s %s/%s" -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 +#: ../src\controller\mainController.py:1130 +#: ../src\controller\mainController.py:1149 +#: ../src\controller\mainController.py:1174 +#: ../src\controller\mainController.py:1199 msgid "%s. Empty" -msgstr "%sは、からです。" +msgstr "%sは、からです" -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 +#: ../src\controller\mainController.py:1162 #: ../src\controller\mainController.py:1166 +#: ../src\controller\mainController.py:1187 msgid "{0}: This account is not logged into Twitter." -msgstr "このアカウント{0}は、まだツイッターにログインしていません" +msgstr "{0}: このアカウントは、まだTwitterにログインしていません。" -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 +#: ../src\controller\mainController.py:1172 +#: ../src\controller\mainController.py:1197 msgid "%s. %s, %s of %s" -msgstr "セッション:%s %s %s/%s/" +msgstr "セッション:%s %s %s/%s" -#: ../src\controller\mainController.py:1170 +#: ../src\controller\mainController.py:1191 msgid "{0}: This account is not logged into twitter." -msgstr "このアカウント{0}は、まだツイッターにログインしていません" +msgstr "{0}: このアカウントは、まだTwitterにログインしていません。" -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "イベント" - -#: ../src\controller\mainController.py:1393 +#: ../src\controller\mainController.py:1416 msgid "This list is already opened" msgstr "既に開かれています" -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy +#: ../src\controller\mainController.py:1446 +#: ../src\controller\mainController.py:1462 msgid "" "An error happened while trying to connect to the server. Please try later." msgstr "" -"バグを報告しようとしているときに、予期しないエラーが発生しました。後でやり直" -"してください" +"サーバーへの接続中に、予期しないエラーが発生しました。あとで再試行してくださ" +"い。" -#: ../src\controller\mainController.py:1475 +#: ../src\controller\mainController.py:1498 msgid "The auto-reading of new tweets is enabled for this buffer" msgstr "自動読み上げ 有効" -#: ../src\controller\mainController.py:1478 +#: ../src\controller\mainController.py:1501 msgid "The auto-reading of new tweets is disabled for this buffer" msgstr "自動読み上げ 無効" -#: ../src\controller\mainController.py:1485 +#: ../src\controller\mainController.py:1508 msgid "Session mute on" msgstr "このセッションのミュートを設定" -#: ../src\controller\mainController.py:1488 +#: ../src\controller\mainController.py:1511 msgid "Session mute off" msgstr "このセッションのミュートを解除" -#: ../src\controller\mainController.py:1496 +#: ../src\controller\mainController.py:1519 msgid "Buffer mute on" msgstr "このバッファのミュートを設定" -#: ../src\controller\mainController.py:1499 +#: ../src\controller\mainController.py:1522 msgid "Buffer mute off" msgstr "このバッファのミュートを解除" -#: ../src\controller\mainController.py:1522 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "コピーしました" -#: ../src\controller\mainController.py:1549 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "このバッファを更新できません。" -#: ../src\controller\mainController.py:1552 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "バッファを更新中…" -#: ../src\controller\mainController.py:1555 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0}個のアイテムを取得しました" -#: ../src\controller\mainController.py:1572 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" -msgstr "無効なバッファ無効なユーザートークンです。" +msgstr "無効なバッファ" -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "このツイートは、画像を含んでいません" - -#: ../src\controller\mainController.py:1579 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "画像{0}" -#: ../src\controller\mainController.py:1580 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "画像を選択" -#: ../src\controller\mainController.py:1596 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "テキストを抽出できません" -#: ../src\controller\messages.py:54 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "翻訳完了" -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "短縮されたURLは、ありません" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "URLを短縮しました" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "短縮を解除するURLはありません" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "URLの短縮を解除しました" - -#: ../src\controller\messages.py:104 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s/%d" -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s文字" - -#: ../src\controller\messages.py:262 +#: ../src\controller\messages.py:354 msgid "View item" msgstr "アイテムを見る" -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "直接接続" +#: ../src\controller\messages.py:379 +msgid "Link copied to clipboard." +msgstr "リンクをクリップボードへコピーしました。" -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:74 +msgid "HTTP" +msgstr "HTTP" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4" +msgstr "SOCKS v4" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4 with DNS support" +msgstr "DNSをサポートする SOCKS v4" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5 with DNS support" +msgstr "DNSをサポートする SOCKS v5" + +#: ../src\controller\settings.py:74 +msgid "System default" +msgstr "システムのデフォルト" + +#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Ask" msgstr "その都度、質問する" -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet without comments" msgstr "コメントを付けずにリツイート(公式RT)" -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet with comments" msgstr "コメントをつけてリツイート(非公式RT)" -#: ../src\controller\settings.py:184 +#: ../src\controller\settings.py:185 msgid "Account settings for %s" msgstr "%sのアカウント設定" -#: ../src\controller\settings.py:284 +#: ../src\controller\settings.py:288 msgid "Direct Messages" msgstr "ダイレクトメッセージ" -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 +#: ../src\controller\user.py:29 ../src\controller\user.py:31 +#: ../src\extra\SpellChecker\wx_ui.py:80 ../src\issueReporter\wx_ui.py:84 +#: ../src\issueReporter\wx_ui.py:87 ../src\wxUI\commonMessageDialogs.py:39 +#: ../src\wxUI\commonMessageDialogs.py:51 +#: ../src\wxUI\commonMessageDialogs.py:58 +#: ../src\wxUI\commonMessageDialogs.py:61 +#: ../src\wxUI\commonMessageDialogs.py:64 +#: ../src\wxUI\commonMessageDialogs.py:67 +#: ../src\wxUI\commonMessageDialogs.py:77 +#: ../src\wxUI\commonMessageDialogs.py:80 +#: ../src\wxUI\commonMessageDialogs.py:83 +#: ../src\wxUI\commonMessageDialogs.py:89 +#: ../src\wxUI\commonMessageDialogs.py:92 msgid "Error" msgstr "エラー" -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 +#: ../src\controller\user.py:29 ../src\wxUI\commonMessageDialogs.py:39 msgid "That user does not exist" -msgstr "そのユーザーは存在しません。" +msgstr "そのユーザーは存在しません" -#: ../src\controller\user.py:30 +#: ../src\controller\user.py:31 msgid "User has been suspended" -msgstr "ユーザーが凍結されています。" +msgstr "ユーザーが凍結されています" -#: ../src\controller\user.py:36 +#: ../src\controller\user.py:37 msgid "Information for %s" msgstr "%sの情報" -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 +#: ../src\controller\user.py:67 ../src\extra\AudioUploader\audioUploader.py:127 msgid "Discarded" msgstr "拒否されました" @@ -550,31 +553,31 @@ msgstr "居住地: %s\n" msgid "URL: %s\n" msgstr "URL: %s\n" -#: ../src\controller\user.py:102 +#: ../src\controller\user.py:104 msgid "Bio: %s\n" msgstr "自己紹介: %s\n" -#: ../src\controller\user.py:103 ../src\controller\user.py:118 +#: ../src\controller\user.py:105 ../src\controller\user.py:120 msgid "Yes" msgstr "はい" -#: ../src\controller\user.py:104 ../src\controller\user.py:119 +#: ../src\controller\user.py:106 ../src\controller\user.py:121 msgid "No" msgstr "いいえ" -#: ../src\controller\user.py:105 +#: ../src\controller\user.py:107 msgid "Protected: %s\n" msgstr "保護設定: %s\n" -#: ../src\controller\user.py:110 +#: ../src\controller\user.py:112 msgid "You follow {0}. " -msgstr "{0}をフォロー" +msgstr "{0}をフォロー。 " -#: ../src\controller\user.py:113 +#: ../src\controller\user.py:115 msgid "{0} is following you." -msgstr " {0}がフォロー" +msgstr "{0}がフォロー。" -#: ../src\controller\user.py:117 +#: ../src\controller\user.py:119 msgid "" "Followers: %s\n" " Friends: %s\n" @@ -582,383 +585,390 @@ msgstr "" "フォロワー: %s\n" "フォロー: %s\n" -#: ../src\controller\user.py:120 +#: ../src\controller\user.py:122 msgid "Verified: %s\n" msgstr "認証済み: %s\n" -#: ../src\controller\user.py:121 +#: ../src\controller\user.py:123 msgid "Tweets: %s\n" msgstr "ツイート数: %s\n" -#: ../src\controller\user.py:122 +#: ../src\controller\user.py:124 msgid "Likes: %s" msgstr "いいね数: %s" -#: ../src\controller\userActionsController.py:75 +#: ../src\controller\userActionsController.py:74 msgid "You can't ignore direct messages" msgstr "ダイレクトメッセージを無視することはできません" -#: ../src\extra\AudioUploader\audioUploader.py:54 -msgid "Attaching..." -msgstr "添付中" +#: ../src\controller\userAliasController.py:32 +msgid "Edit alias for {}" +msgstr "{}のエイリアスを編集" -#: ../src\extra\AudioUploader\audioUploader.py:71 +#: ../src\extra\AudioUploader\audioUploader.py:57 +msgid "Attaching..." +msgstr "添付中…" + +#: ../src\extra\AudioUploader\audioUploader.py:74 msgid "Pause" msgstr "一時停止" -#: ../src\extra\AudioUploader\audioUploader.py:73 +#: ../src\extra\AudioUploader\audioUploader.py:76 msgid "&Resume" msgstr "再開(&R)" -#: ../src\extra\AudioUploader\audioUploader.py:74 +#: ../src\extra\AudioUploader\audioUploader.py:77 msgid "Resume" msgstr "再開" -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 +#: ../src\extra\AudioUploader\audioUploader.py:79 +#: ../src\extra\AudioUploader\audioUploader.py:106 +#: ../src\extra\AudioUploader\wx_ui.py:37 msgid "&Pause" msgstr "一時停止(&P)" -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 +#: ../src\extra\AudioUploader\audioUploader.py:94 +#: ../src\extra\AudioUploader\audioUploader.py:140 msgid "&Stop" msgstr "停止(&S)" -#: ../src\extra\AudioUploader\audioUploader.py:92 +#: ../src\extra\AudioUploader\audioUploader.py:95 msgid "Recording" msgstr "録音中" -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:100 +#: ../src\extra\AudioUploader\audioUploader.py:151 msgid "Stopped" msgstr "停止" -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 +#: ../src\extra\AudioUploader\audioUploader.py:102 +#: ../src\extra\AudioUploader\wx_ui.py:39 msgid "&Record" msgstr "録音(&R)" -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." -msgstr "再生中" +msgstr "再生中…" -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 +#: ../src\extra\AudioUploader\audioUploader.py:144 +#: ../src\extra\AudioUploader\audioUploader.py:154 +#: ../src\extra\AudioUploader\wx_ui.py:35 msgid "&Play" msgstr "再生(&P)" -#: ../src\extra\AudioUploader\audioUploader.py:156 +#: ../src\extra\AudioUploader\audioUploader.py:159 msgid "Recoding audio..." -msgstr "音声を録音中" +msgstr "音声を録音中…" -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 +#: ../src\extra\AudioUploader\transfer.py:82 +#: ../src\extra\AudioUploader\transfer.py:88 msgid "Error in file upload: {0}" msgstr "ファイルアップロードエラー: {0}" -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 -msgid "%d day, " -msgstr "1日前" - #: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d days, " -msgstr "%s日" +msgid "%d day, " +msgstr "%d日 " #: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d hour, " -msgstr "1時間前" +msgid "%d days, " +msgstr "%d日 " #: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hours, " -msgstr "%d時間" +msgid "%d hour, " +msgstr "%d時間 " #: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d minute, " -msgstr "1分前" +msgid "%d hours, " +msgstr "%d時間 " #: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minutes, " -msgstr "%d分" +msgid "%d minute, " +msgstr "%d分 " #: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%s second" -msgstr "1秒前" +msgid "%d minutes, " +msgstr "%d分 " #: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 +msgid "%s second" +msgstr "%s秒" + +#: ../src\extra\AudioUploader\utils.py:43 ../src\update\utils.py:43 msgid "%s seconds" msgstr "%s秒" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "ファイル" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:21 msgid "Transferred" msgstr "転送済み" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:26 msgid "Total file size" msgstr "合計サイズ" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:31 msgid "Transfer rate" msgstr "転送速度" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:36 msgid "Time left" msgstr "残り時間" -#: ../src\extra\AudioUploader\wx_ui.py:28 +#: ../src\extra\AudioUploader\wx_ui.py:29 msgid "Attach audio" msgstr "音声を添付" -#: ../src\extra\AudioUploader\wx_ui.py:40 +#: ../src\extra\AudioUploader\wx_ui.py:41 msgid "&Add an existing file" msgstr "既存のファイルを追加(&A)" -#: ../src\extra\AudioUploader\wx_ui.py:41 +#: ../src\extra\AudioUploader\wx_ui.py:42 msgid "&Discard" msgstr "拒否(&D)" -#: ../src\extra\AudioUploader\wx_ui.py:43 +#: ../src\extra\AudioUploader\wx_ui.py:44 msgid "Upload to" -msgstr "アップロード先:" +msgstr "アップロード先" -#: ../src\extra\AudioUploader\wx_ui.py:48 +#: ../src\extra\AudioUploader\wx_ui.py:49 msgid "Attach" msgstr "添付" -#: ../src\extra\AudioUploader\wx_ui.py:50 +#: ../src\extra\AudioUploader\wx_ui.py:51 msgid "&Cancel" msgstr "キャンセル(&C)" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" msgstr "音声ファイル (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Select the audio file to be uploaded" msgstr "アップロードする音声ファイルを選択" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 -msgid "Audio tweet." -msgstr "音声付きツイート" - #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "User timeline buffer created." -msgstr "ユーザーのタイムラインのバッファを作成" +msgid "Audio tweet." +msgstr "音声付きツイート。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "Buffer destroied." -msgstr "バッファを削除" +msgid "User timeline buffer created." +msgstr "ユーザーのタイムラインのバッファを作成。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Direct message received." -msgstr "ダイレクトメッセージを受信" +msgid "Buffer destroied." +msgstr "バッファを削除。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message sent." -msgstr "ダイレクトメッセージを送信" +msgid "Direct message received." +msgstr "ダイレクトメッセージを受信。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Error." -msgstr "エラー" +msgid "Direct message sent." +msgstr "ダイレクトメッセージを送信。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Tweet liked." -msgstr "ツイートがいいねされた" +msgid "Error." +msgstr "エラー。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Likes buffer updated." -msgstr "いいねバッファが更新された" +msgid "Tweet liked." +msgstr "ツイートがいいねされた。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Geotweet." -msgstr "位置情報付きのツイート" +msgid "Likes buffer updated." +msgstr "いいねバッファが更新された。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 +msgid "Geotweet." +msgstr "位置情報付きのツイート。" + +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 msgid "Tweet contains one or more images" msgstr "ツイートに1つ以上の画像が含まれています" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Boundary reached." -msgstr "先頭または最後のツイート" - #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "List updated." -msgstr "リストが更新された" +msgid "Boundary reached." +msgstr "先頭または最後のツイート。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "Too many characters." -msgstr "文字数オーバー" +msgid "List updated." +msgstr "リストが更新された。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Mention received." -msgstr "リプライを受信" +msgid "Too many characters." +msgstr "文字数オーバー。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "New event." -msgstr "新しいイベント" +msgid "Mention received." +msgstr "リプライを受信した。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "{0} is ready." -msgstr "{0}の準備完了" +msgid "New event." +msgstr "新しいイベント。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "Mention sent." -msgstr "リプライを送信" +msgid "{0} is ready." +msgstr "{0}の準備完了。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Tweet retweeted." -msgstr "ツイートをリツイート" +msgid "Mention sent." +msgstr "リプライを送信した。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Search buffer updated." -msgstr "検索バッファが更新された" +msgid "Tweet retweeted." +msgstr "ツイートをリツイートした。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Tweet received." -msgstr "ツイートを受信" +msgid "Search buffer updated." +msgstr "検索バッファが更新された。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet sent." -msgstr "ツイートを送信" +msgid "Tweet received." +msgstr "ツイートを受信した。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Trending topics buffer updated." -msgstr "トレンドの話題のバッファが更新された" +msgid "Tweet sent." +msgstr "ツイートを送信した。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "New tweet in user timeline buffer." -msgstr "ユーザーのタイムラインに新しいツイートを受信" +msgid "Trending topics buffer updated." +msgstr "トレンドのバッファが更新された。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New follower." -msgstr "新しいフォロワー" +msgid "New tweet in user timeline buffer." +msgstr "ユーザーのタイムラインに新しいツイートを受信した。" #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "Volume changed." -msgstr "ボリュームを変更" +msgid "New follower." +msgstr "新しいフォロワー。" -#: ../src\extra\SoundsTutorial\wx_ui.py:8 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:31 +msgid "Volume changed." +msgstr "ボリュームを変更した。" + +#: ../src\extra\SoundsTutorial\wx_ui.py:9 msgid "Sounds tutorial" msgstr "サウンドの確認" -#: ../src\extra\SoundsTutorial\wx_ui.py:11 +#: ../src\extra\SoundsTutorial\wx_ui.py:12 msgid "Press enter to listen to the sound for the selected event" msgstr "選択されたイベントのサウンドを再生するには、Enterキーを押してください" -#: ../src\extra\SpellChecker\spellchecker.py:57 +#: ../src\extra\SpellChecker\spellchecker.py:60 msgid "Misspelled word: %s" msgstr "「%s」はスペルが間違っています" -#: ../src\extra\SpellChecker\wx_ui.py:27 +#: ../src\extra\SpellChecker\wx_ui.py:28 msgid "Misspelled word" msgstr "スペルミスの単語" -#: ../src\extra\SpellChecker\wx_ui.py:32 +#: ../src\extra\SpellChecker\wx_ui.py:33 msgid "Context" msgstr "コンテキスト" -#: ../src\extra\SpellChecker\wx_ui.py:37 +#: ../src\extra\SpellChecker\wx_ui.py:38 msgid "Suggestions" msgstr "提案" -#: ../src\extra\SpellChecker\wx_ui.py:42 +#: ../src\extra\SpellChecker\wx_ui.py:43 msgid "&Ignore" msgstr "無視(&I)" -#: ../src\extra\SpellChecker\wx_ui.py:43 +#: ../src\extra\SpellChecker\wx_ui.py:44 msgid "I&gnore all" msgstr "すべて無視(&G)" -#: ../src\extra\SpellChecker\wx_ui.py:44 +#: ../src\extra\SpellChecker\wx_ui.py:45 msgid "&Replace" msgstr "置き換え(&R)" -#: ../src\extra\SpellChecker\wx_ui.py:45 +#: ../src\extra\SpellChecker\wx_ui.py:46 msgid "R&eplace all" msgstr "すべて置き換え(&E)" -#: ../src\extra\SpellChecker\wx_ui.py:46 +#: ../src\extra\SpellChecker\wx_ui.py:47 msgid "&Add to personal dictionary" msgstr "個人辞書に追加(&A)" -#: ../src\extra\SpellChecker\wx_ui.py:79 +#: ../src\extra\SpellChecker\wx_ui.py:80 msgid "" "An error has occurred. There are no dictionaries available for the selected " "language in {0}" msgstr "エラーが発生しました。{0}で選択した言語用の辞書がありません" -#: ../src\extra\SpellChecker\wx_ui.py:82 +#: ../src\extra\SpellChecker\wx_ui.py:83 msgid "Spell check complete." -msgstr "スペルチェックが完了しました" +msgstr "スペルチェックが完了しました。" -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 +#: ../src\extra\autocompletionUsers\completion.py:20 +#: ../src\extra\autocompletionUsers\completion.py:38 msgid "You have to start writing" msgstr "あなたは、書き込みを開始しなければなりません" -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 +#: ../src\extra\autocompletionUsers\completion.py:30 +#: ../src\extra\autocompletionUsers\completion.py:47 msgid "There are no results in your users database" msgstr "あなたのユーザーのデータベースには、見つかりませんでした" -#: ../src\extra\autocompletionUsers\completion.py:33 +#: ../src\extra\autocompletionUsers\completion.py:32 msgid "Autocompletion only works for users." -msgstr "自動補完はユーザーのみで動作します" +msgstr "自動補完はユーザーのみで動作します。" -#: ../src\extra\autocompletionUsers\settings.py:27 +#: ../src\extra\autocompletionUsers\settings.py:25 msgid "" "Updating database... You can close this window now. A message will tell you " "when the process finishes." msgstr "" -"データベースの更新中...あなたは今、このウィンドウを閉じることができます。 プ" -"ロセスが終了するとメッセージが表示されます" +"データベースの更新中… なお、このウィンドウを閉じることができます。処理が終了" +"すると、メッセージが表示されます。" -#: ../src\extra\autocompletionUsers\wx_manage.py:8 +#: ../src\extra\autocompletionUsers\wx_manage.py:9 msgid "Manage Autocompletion database" msgstr "オートコンプリートのデータベースを管理" -#: ../src\extra\autocompletionUsers\wx_manage.py:11 +#: ../src\extra\autocompletionUsers\wx_manage.py:12 msgid "Editing {0} users database" msgstr "{0}のユーザーデータベースを編集中" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 msgid "Username" msgstr "ユーザー名" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 #: ../src\wxUI\dialogs\configuration.py:144 msgid "Name" msgstr "名前" -#: ../src\extra\autocompletionUsers\wx_manage.py:15 +#: ../src\extra\autocompletionUsers\wx_manage.py:16 msgid "Add user" msgstr "ユーザーを追加" -#: ../src\extra\autocompletionUsers\wx_manage.py:16 +#: ../src\extra\autocompletionUsers\wx_manage.py:17 msgid "Remove user" msgstr "ユーザーを削除" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Add user to database" msgstr "データベースにユーザーを追加" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Twitter username" -msgstr "ツイッターのユーザー名" +msgstr "Twitterのユーザー名" -#: ../src\extra\autocompletionUsers\wx_manage.py:43 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 msgid "The user does not exist" msgstr "そのユーザーは存在しません" -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "Error!" -msgstr "エラー" +msgstr "エラー!" #: ../src\extra\autocompletionUsers\wx_settings.py:8 msgid "Autocomplete users' settings" @@ -974,7 +984,7 @@ msgstr "フォロー中のユーザーからユーザーを追加" #: ../src\extra\autocompletionUsers\wx_settings.py:15 msgid "Manage database..." -msgstr "データベースの管理" +msgstr "データベースの管理..." #: ../src\extra\autocompletionUsers\wx_settings.py:27 msgid "Done" @@ -982,498 +992,498 @@ msgstr "完了" #: ../src\extra\autocompletionUsers\wx_settings.py:27 msgid "{0}'s database of users has been updated." -msgstr "{0}のユーザーのデータベースが更新されました" +msgstr "{0}のユーザーのデータベースが更新されました。" -#: ../src\extra\ocr\OCRSpace.py:5 +#: ../src\extra\ocr\OCRSpace.py:7 msgid "Detect automatically" msgstr "自動検出" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:41 msgid "Danish" msgstr "デンマーク語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:43 msgid "Dutch" msgstr "オランダ語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:44 msgid "English" msgstr "英語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:48 msgid "Finnish" msgstr "フィンランド語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:49 msgid "French" msgstr "フランス語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:52 msgid "German" msgstr "ドイツ語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:58 msgid "Hungarian" msgstr "ハンガリー語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:63 msgid "Italian" msgstr "イタリア語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:64 msgid "Japanese" msgstr "日本語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:68 msgid "Korean" msgstr "韓国語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:85 msgid "Polish" msgstr "ポーランド語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:86 msgid "Portuguese" msgstr "ポルトガル語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:89 msgid "Russian" msgstr "ロシア語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:96 msgid "Spanish" msgstr "スペイン語" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:105 msgid "Turkish" msgstr "トルコ語" -#: ../src\extra\translator\translator.py:12 +#: ../src\extra\translator\translator.py:22 msgid "Afrikaans" msgstr "アフリカ語" -#: ../src\extra\translator\translator.py:13 +#: ../src\extra\translator\translator.py:23 msgid "Albanian" msgstr "アルバニア語" -#: ../src\extra\translator\translator.py:14 +#: ../src\extra\translator\translator.py:24 msgid "Amharic" msgstr "アムハラ語" -#: ../src\extra\translator\translator.py:15 +#: ../src\extra\translator\translator.py:25 msgid "Arabic" msgstr "アラビア語" -#: ../src\extra\translator\translator.py:16 +#: ../src\extra\translator\translator.py:26 msgid "Armenian" msgstr "アルメニア語" -#: ../src\extra\translator\translator.py:17 +#: ../src\extra\translator\translator.py:27 msgid "Azerbaijani" msgstr "アゼルバイジャン語" -#: ../src\extra\translator\translator.py:18 +#: ../src\extra\translator\translator.py:28 msgid "Basque" msgstr "バスク語" -#: ../src\extra\translator\translator.py:19 +#: ../src\extra\translator\translator.py:29 msgid "Belarusian" msgstr "ベラルーシ語" -#: ../src\extra\translator\translator.py:20 +#: ../src\extra\translator\translator.py:30 msgid "Bengali" msgstr "ベンガル語" -#: ../src\extra\translator\translator.py:21 +#: ../src\extra\translator\translator.py:31 msgid "Bihari" msgstr "ビハール語" -#: ../src\extra\translator\translator.py:22 +#: ../src\extra\translator\translator.py:32 msgid "Bulgarian" msgstr "ブルガリア語" -#: ../src\extra\translator\translator.py:23 +#: ../src\extra\translator\translator.py:33 msgid "Burmese" msgstr "ビルマ語" -#: ../src\extra\translator\translator.py:24 +#: ../src\extra\translator\translator.py:34 msgid "Catalan" msgstr "カタロニア語" -#: ../src\extra\translator\translator.py:25 +#: ../src\extra\translator\translator.py:35 msgid "Cherokee" msgstr "チェロキー語" -#: ../src\extra\translator\translator.py:26 +#: ../src\extra\translator\translator.py:36 msgid "Chinese" msgstr "中国語" -#: ../src\extra\translator\translator.py:27 +#: ../src\extra\translator\translator.py:37 msgid "Chinese_simplified" msgstr "簡体字中国語" -#: ../src\extra\translator\translator.py:28 +#: ../src\extra\translator\translator.py:38 msgid "Chinese_traditional" msgstr "繁体字中国語" -#: ../src\extra\translator\translator.py:29 +#: ../src\extra\translator\translator.py:39 msgid "Croatian" msgstr "クロアチア語" -#: ../src\extra\translator\translator.py:30 +#: ../src\extra\translator\translator.py:40 msgid "Czech" msgstr "チェコ語" -#: ../src\extra\translator\translator.py:32 +#: ../src\extra\translator\translator.py:42 msgid "Dhivehi" msgstr "ディベヒ語" -#: ../src\extra\translator\translator.py:35 +#: ../src\extra\translator\translator.py:45 msgid "Esperanto" msgstr "エスペラント語" -#: ../src\extra\translator\translator.py:36 +#: ../src\extra\translator\translator.py:46 msgid "Estonian" msgstr "エストニア語" -#: ../src\extra\translator\translator.py:37 +#: ../src\extra\translator\translator.py:47 msgid "Filipino" msgstr "フィリピン語" -#: ../src\extra\translator\translator.py:40 +#: ../src\extra\translator\translator.py:50 msgid "Galician" msgstr "ガリシア語" -#: ../src\extra\translator\translator.py:41 +#: ../src\extra\translator\translator.py:51 msgid "Georgian" msgstr "ジョージア語" -#: ../src\extra\translator\translator.py:43 +#: ../src\extra\translator\translator.py:53 msgid "Greek" msgstr "ギリシャ語" -#: ../src\extra\translator\translator.py:44 +#: ../src\extra\translator\translator.py:54 msgid "Guarani" msgstr "グアラニ語" -#: ../src\extra\translator\translator.py:45 +#: ../src\extra\translator\translator.py:55 msgid "Gujarati" msgstr "グジャラート語" -#: ../src\extra\translator\translator.py:46 +#: ../src\extra\translator\translator.py:56 msgid "Hebrew" msgstr "ヘブライ語" -#: ../src\extra\translator\translator.py:47 +#: ../src\extra\translator\translator.py:57 msgid "Hindi" msgstr "ヒンディー語" -#: ../src\extra\translator\translator.py:49 +#: ../src\extra\translator\translator.py:59 msgid "Icelandic" msgstr "アイスランド語" -#: ../src\extra\translator\translator.py:50 +#: ../src\extra\translator\translator.py:60 msgid "Indonesian" msgstr "インドネシア語" -#: ../src\extra\translator\translator.py:51 +#: ../src\extra\translator\translator.py:61 msgid "Inuktitut" msgstr "イヌクティトゥト語" -#: ../src\extra\translator\translator.py:52 +#: ../src\extra\translator\translator.py:62 msgid "Irish" msgstr "アイリス語" -#: ../src\extra\translator\translator.py:55 +#: ../src\extra\translator\translator.py:65 msgid "Kannada" msgstr "カンナダ語" -#: ../src\extra\translator\translator.py:56 +#: ../src\extra\translator\translator.py:66 msgid "Kazakh" msgstr "カザフ語" -#: ../src\extra\translator\translator.py:57 +#: ../src\extra\translator\translator.py:67 msgid "Khmer" msgstr "クメール語" -#: ../src\extra\translator\translator.py:59 +#: ../src\extra\translator\translator.py:69 msgid "Kurdish" msgstr "クルド語" -#: ../src\extra\translator\translator.py:60 +#: ../src\extra\translator\translator.py:70 msgid "Kyrgyz" msgstr "キルギス語" -#: ../src\extra\translator\translator.py:61 +#: ../src\extra\translator\translator.py:71 msgid "Laothian" msgstr "ラオス語" -#: ../src\extra\translator\translator.py:62 +#: ../src\extra\translator\translator.py:72 msgid "Latvian" msgstr "ラトビア語" -#: ../src\extra\translator\translator.py:63 +#: ../src\extra\translator\translator.py:73 msgid "Lithuanian" msgstr "リトアニア語" -#: ../src\extra\translator\translator.py:64 +#: ../src\extra\translator\translator.py:74 msgid "Macedonian" msgstr "マケドニア語" -#: ../src\extra\translator\translator.py:65 +#: ../src\extra\translator\translator.py:75 msgid "Malay" msgstr "マレー語" -#: ../src\extra\translator\translator.py:66 +#: ../src\extra\translator\translator.py:76 msgid "Malayalam" msgstr "マラヤーラム語" -#: ../src\extra\translator\translator.py:67 +#: ../src\extra\translator\translator.py:77 msgid "Maltese" msgstr "マルタ語" -#: ../src\extra\translator\translator.py:68 +#: ../src\extra\translator\translator.py:78 msgid "Marathi" msgstr "マラーティー語" -#: ../src\extra\translator\translator.py:69 +#: ../src\extra\translator\translator.py:79 msgid "Mongolian" msgstr "モンゴル語" -#: ../src\extra\translator\translator.py:70 +#: ../src\extra\translator\translator.py:80 msgid "Nepali" msgstr "ネパール語" -#: ../src\extra\translator\translator.py:71 +#: ../src\extra\translator\translator.py:81 msgid "Norwegian" msgstr "ノルウェー語" -#: ../src\extra\translator\translator.py:72 +#: ../src\extra\translator\translator.py:82 msgid "Oriya" msgstr "オリヤー語" -#: ../src\extra\translator\translator.py:73 +#: ../src\extra\translator\translator.py:83 msgid "Pashto" msgstr "パシュトウ語" -#: ../src\extra\translator\translator.py:74 +#: ../src\extra\translator\translator.py:84 msgid "Persian" msgstr "ペルシア語" -#: ../src\extra\translator\translator.py:77 +#: ../src\extra\translator\translator.py:87 msgid "Punjabi" msgstr "パンジャブ語" -#: ../src\extra\translator\translator.py:78 +#: ../src\extra\translator\translator.py:88 msgid "Romanian" msgstr "ルーマニア語" -#: ../src\extra\translator\translator.py:80 +#: ../src\extra\translator\translator.py:90 msgid "Sanskrit" msgstr "サンスクリット語" -#: ../src\extra\translator\translator.py:81 +#: ../src\extra\translator\translator.py:91 msgid "Serbian" msgstr "セルビア語" -#: ../src\extra\translator\translator.py:82 +#: ../src\extra\translator\translator.py:92 msgid "Sindhi" msgstr "シンド語" -#: ../src\extra\translator\translator.py:83 +#: ../src\extra\translator\translator.py:93 msgid "Sinhalese" msgstr "シンハラ語" -#: ../src\extra\translator\translator.py:84 +#: ../src\extra\translator\translator.py:94 msgid "Slovak" msgstr "スロバキア語" -#: ../src\extra\translator\translator.py:85 +#: ../src\extra\translator\translator.py:95 msgid "Slovenian" msgstr "スロベニア語" -#: ../src\extra\translator\translator.py:87 +#: ../src\extra\translator\translator.py:97 msgid "Swahili" msgstr "スワヒリ語" -#: ../src\extra\translator\translator.py:88 +#: ../src\extra\translator\translator.py:98 msgid "Swedish" msgstr "スウェーデン語" -#: ../src\extra\translator\translator.py:89 +#: ../src\extra\translator\translator.py:99 msgid "Tajik" msgstr "タジク語" -#: ../src\extra\translator\translator.py:90 +#: ../src\extra\translator\translator.py:100 msgid "Tamil" msgstr "タミル語" -#: ../src\extra\translator\translator.py:91 +#: ../src\extra\translator\translator.py:101 msgid "Tagalog" msgstr "タガログ語" -#: ../src\extra\translator\translator.py:92 +#: ../src\extra\translator\translator.py:102 msgid "Telugu" msgstr "テルグ語" -#: ../src\extra\translator\translator.py:93 +#: ../src\extra\translator\translator.py:103 msgid "Thai" msgstr "タイ語" -#: ../src\extra\translator\translator.py:94 +#: ../src\extra\translator\translator.py:104 msgid "Tibetan" msgstr "チベット語" -#: ../src\extra\translator\translator.py:96 +#: ../src\extra\translator\translator.py:106 msgid "Ukrainian" msgstr "ウクライナ語" -#: ../src\extra\translator\translator.py:97 +#: ../src\extra\translator\translator.py:107 msgid "Urdu" msgstr "ウルドゥー語" -#: ../src\extra\translator\translator.py:98 +#: ../src\extra\translator\translator.py:108 msgid "Uzbek" msgstr "ウズベク語" -#: ../src\extra\translator\translator.py:99 +#: ../src\extra\translator\translator.py:109 msgid "Uighur" msgstr "ウイグル語" -#: ../src\extra\translator\translator.py:100 +#: ../src\extra\translator\translator.py:110 msgid "Vietnamese" msgstr "ベトナム語" -#: ../src\extra\translator\translator.py:101 +#: ../src\extra\translator\translator.py:111 msgid "Welsh" msgstr "ウェールズ語" -#: ../src\extra\translator\translator.py:102 +#: ../src\extra\translator\translator.py:112 msgid "Yiddish" msgstr "イディッシュ語" -#: ../src\extra\translator\wx_ui.py:44 +#: ../src\extra\translator\wx_ui.py:29 msgid "Translate message" msgstr "メッセージを翻訳" -#: ../src\extra\translator\wx_ui.py:47 +#: ../src\extra\translator\wx_ui.py:32 msgid "Target language" msgstr "翻訳先の言語" -#: ../src\issueReporter\issueReporter.py:30 +#: ../src\issueReporter\issueReporter.py:32 #: ../src\wxUI\dialogs\configuration.py:359 #: ../src\wxUI\dialogs\configuration.py:368 msgid "General" msgstr "一般" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "always" msgstr "常に" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "have not tried" msgstr "試したことがない" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "random" msgstr "ランダム" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "sometimes" msgstr "時々" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "unable to duplicate" msgstr "複製できません" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "block" msgstr "ブロック" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "crash" msgstr "クラッシュ" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "feature" msgstr "特徴" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "major" msgstr "メジャー" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "minor" msgstr "マイナー" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "text" msgstr "内容" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "trivial" msgstr "些細な" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "tweak" msgstr "微調整" -#: ../src\issueReporter\wx_ui.py:25 +#: ../src\issueReporter\wx_ui.py:26 msgid "Report an error" msgstr "エラーを報告" -#: ../src\issueReporter\wx_ui.py:28 +#: ../src\issueReporter\wx_ui.py:29 msgid "Select a category" msgstr "カテゴリを選択" -#: ../src\issueReporter\wx_ui.py:36 +#: ../src\issueReporter\wx_ui.py:37 msgid "" "Briefly describe what happened. You will be able to thoroughly explain it " "later" msgstr "簡単な説明" -#: ../src\issueReporter\wx_ui.py:45 +#: ../src\issueReporter\wx_ui.py:46 msgid "Here, you can describe the bug in detail" msgstr "バグの詳細な説明" -#: ../src\issueReporter\wx_ui.py:55 +#: ../src\issueReporter\wx_ui.py:56 msgid "how often does this bug happen?" msgstr "このバグが起こる頻度" -#: ../src\issueReporter\wx_ui.py:62 +#: ../src\issueReporter\wx_ui.py:63 msgid "Select the importance that you think this bug has" msgstr "このバグの重要性を選択" -#: ../src\issueReporter\wx_ui.py:69 +#: ../src\issueReporter\wx_ui.py:70 msgid "" "I know that the {0} bug system will get my Twitter username to contact me " "and fix the bug quickly" msgstr "" -"私は、{0}のバグシステムが私に連絡して、すぐにバグを修正するために、ツイッター" -"のユーザー名を取得することを理解しています" +"私は、{0}のバグシステムが私に連絡して、すぐにバグを修正するために、Twitterの" +"ユーザー名を取得することを理解しています" -#: ../src\issueReporter\wx_ui.py:72 +#: ../src\issueReporter\wx_ui.py:73 msgid "Send report" msgstr "レポートを送信" -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 +#: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "キャンセル" -#: ../src\issueReporter\wx_ui.py:83 +#: ../src\issueReporter\wx_ui.py:84 msgid "You must fill out both fields" msgstr "あなたは、両方のフィールドに記入しなければなりません" -#: ../src\issueReporter\wx_ui.py:86 +#: ../src\issueReporter\wx_ui.py:87 msgid "" "You need to mark the checkbox to provide us your twitter username to contact " "you if it is necessary." msgstr "" -"必要な場合に連絡するため、ツイッターのユーザー名を私たちに送信するために、" -"チェックボックスにチェックをつける必要があります" +"必要な場合に連絡するため、Twitterのユーザー名を私たちに送信するために、チェッ" +"クボックスにチェックをつける必要があります。" -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "" "Thanks for reporting this bug! In future versions, you may be able to find " "it in the changes list. You've reported the bug number %i" @@ -1482,21 +1492,20 @@ msgstr "" "のリストでそれを見つけることができるかもしれません。あなたは、バグ番号%iを報" "しました" -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "reported" msgstr "レポート完了" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "Error while reporting" msgstr "エラー" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "" "Something unexpected occurred while trying to report the bug. Please, try " "again later" msgstr "" -"バグを報告しようとしているときに、予期しないエラーが発生しました。後でやり直" -"してください" +"バグの報告中に、予期しないエラーが発生しました。あとで再試行してください" #: ../src\keystrokeEditor\constants.py:3 msgid "Go up in the current buffer" @@ -1530,8 +1539,8 @@ msgstr "GUIの表示と非表示を切り替え" msgid "New tweet" msgstr "新規ツイート" -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 +#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "リツイート" @@ -1577,7 +1586,7 @@ msgstr "現在のバッファを削除" #: ../src\keystrokeEditor\constants.py:23 msgid "Interact with the currently focused tweet." -msgstr "現在フォーカス中のツイートを相呼応する" +msgstr "現在フォーカス中のツイートを相呼応する。" #: ../src\keystrokeEditor\constants.py:24 msgid "Open URL" @@ -1585,7 +1594,7 @@ msgstr "URLを開く" #: ../src\keystrokeEditor\constants.py:25 msgid "View in Twitter" -msgstr "ツイッターで見る" +msgstr "Twitterで見る" #: ../src\keystrokeEditor\constants.py:26 msgid "Increase volume by 5%" @@ -1653,7 +1662,7 @@ msgstr "新着のツイートを自動で読み上げるかどうかを設定" #: ../src\keystrokeEditor\constants.py:42 msgid "Search on twitter" -msgstr "ツイッターを検索" +msgstr "Twitterを検索" #: ../src\keystrokeEditor\constants.py:43 msgid "Find a string in the currently focused buffer" @@ -1681,7 +1690,7 @@ msgstr "位置情報を表示" #: ../src\keystrokeEditor\constants.py:49 msgid "Create a trending topics buffer" -msgstr "トレンドの話題のバッファを作成" +msgstr "トレンドのバッファを作成" #: ../src\keystrokeEditor\constants.py:50 msgid "View conversation" @@ -1696,14 +1705,13 @@ msgid "" "Opens the list manager, which allows you to create, edit, delete and open " "lists in buffers." msgstr "" -"リストを作成したり、編集したり、削除したりするために「リストの管理」を開く" +"リストを作成したり、編集したり、削除したりするために「リストの管理」を開く。" #: ../src\keystrokeEditor\constants.py:53 msgid "Opens the global settings dialogue" msgstr "「全般設定」ダイアログを開く" #: ../src\keystrokeEditor\constants.py:54 -#, fuzzy msgid "Opens the list manager" msgstr "リストの管理" @@ -1717,12 +1725,16 @@ msgstr "音声ファイルの再生" #: ../src\keystrokeEditor\constants.py:57 msgid "Updates the buffer and retrieves possible lost items there." -msgstr "バッファを更新して、取得に失敗したアイテムを取得" +msgstr "バッファを更新して、取得に失敗したアイテムを取得。" #: ../src\keystrokeEditor\constants.py:58 msgid "Extracts the text from a picture and displays the result in a dialog." msgstr "画像からテキストを抽出して、結果をダイアログで表示。" +#: ../src\keystrokeEditor\constants.py:59 +msgid "Adds an alias to an user" +msgstr "ユーザーにエイリアスを追加" + #: ../src\keystrokeEditor\wx_ui.py:8 msgid "Keystroke editor" msgstr "キーストロークエディタ" @@ -1735,63 +1747,76 @@ msgstr "編集するキーストロークを選択" msgid "Keystroke" msgstr "キーストローク" -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 +#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:10 +#: ../src\wxUI\dialogs\userActions.py:19 ../src\wxUI\dialogs\userActions.py:20 msgid "Action" msgstr "操作" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 +#: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "編集" -#: ../src\keystrokeEditor\wx_ui.py:20 +#: ../src\keystrokeEditor\wx_ui.py:20 ../src\keystrokeEditor\wx_ui.py:50 +msgid "Undefine keystroke" +msgstr "キーストロークの定義を解除" + +#: ../src\keystrokeEditor\wx_ui.py:21 msgid "Execute action" msgstr "現在の動作を実行" -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 +#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 +#: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 msgid "Close" msgstr "閉じる" -#: ../src\keystrokeEditor\wx_ui.py:48 +#: ../src\keystrokeEditor\wx_ui.py:42 +msgid "Undefined" +msgstr "未定義" + +#: ../src\keystrokeEditor\wx_ui.py:50 +msgid "Are you sure you want to undefine this keystroke?" +msgstr "このキーストロークの定義を解除してもよろしいですか?" + +#: ../src\keystrokeEditor\wx_ui.py:54 msgid "Editing keystroke" msgstr "キーストロークを編集" -#: ../src\keystrokeEditor\wx_ui.py:51 +#: ../src\keystrokeEditor\wx_ui.py:57 msgid "Control" msgstr "コントロール" -#: ../src\keystrokeEditor\wx_ui.py:52 +#: ../src\keystrokeEditor\wx_ui.py:58 msgid "Alt" msgstr "オルト" -#: ../src\keystrokeEditor\wx_ui.py:53 +#: ../src\keystrokeEditor\wx_ui.py:59 msgid "Shift" msgstr "シフト" -#: ../src\keystrokeEditor\wx_ui.py:54 +#: ../src\keystrokeEditor\wx_ui.py:60 msgid "Windows" msgstr "ウィンドウズ" -#: ../src\keystrokeEditor\wx_ui.py:60 +#: ../src\keystrokeEditor\wx_ui.py:66 msgid "Key" msgstr "キー名" -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 +#: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 +#: ../src\wxUI\dialogs\utils.py:36 msgid "OK" msgstr "OK" -#: ../src\keystrokeEditor\wx_ui.py:78 +#: ../src\keystrokeEditor\wx_ui.py:84 msgid "You need to use the Windows key" msgstr "ウィンドウズキーを使用する必要があります" -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:84 ../src\keystrokeEditor\wx_ui.py:87 msgid "Invalid keystroke" msgstr "無効なキーストローク" -#: ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:87 msgid "You must provide a character for the keystroke" msgstr "キー名が入力されていません" @@ -1799,57 +1824,58 @@ msgstr "キー名が入力されていません" msgid "User default" msgstr "ユーザーのデフォルト" -#: ../src\main.py:105 +#: ../src\main.py:120 msgid "https://twblue.es/donate" msgstr "https://twblue.es/donate" -#: ../src\main.py:122 +#: ../src\main.py:137 msgid "" "{0} is already running. Close the other instance before starting this one. " "If you're sure that {0} isn't running, try deleting the file at {1}. If " "you're unsure of how to do this, contact the {0} developers." msgstr "" -"{0} は、すでに起動しています。実行する前に、以前に起動しているものを終了させ" -"てください。{0} が起動していないことが確実な場合は、 {1} にあるファイルを削除" -"してみてください.削除方法が不明の場合は、 {0} の開発者までご連絡ください。" +"{0}は、すでに実行されています。このインスタンスを開始する前に、他のインスタン" +"スを閉じてください。{0}が実行されていないことが確実な場合は、{1}でファイルを" +"削除してみてください。これを行う方法がわからない場合は、{0}開発者に連絡してく" +"ださい。" -#: ../src\sessionmanager\wxUI.py:8 +#: ../src\sessionmanager\wxUI.py:9 msgid "Session manager" msgstr "セッションの管理" -#: ../src\sessionmanager\wxUI.py:11 +#: ../src\sessionmanager\wxUI.py:12 msgid "Accounts list" msgstr "アカウントリスト" -#: ../src\sessionmanager\wxUI.py:13 +#: ../src\sessionmanager\wxUI.py:14 msgid "Account" msgstr "アカウント" -#: ../src\sessionmanager\wxUI.py:17 +#: ../src\sessionmanager\wxUI.py:18 msgid "New account" msgstr "新しいアカウントを連携" -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:19 ../src\sessionmanager\wxUI.py:65 msgid "Remove account" msgstr "このアカウントを削除" -#: ../src\sessionmanager\wxUI.py:19 +#: ../src\sessionmanager\wxUI.py:20 msgid "Global Settings" msgstr "全体の設定" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "Account Error" msgstr "アカウントエラー" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "You need to configure an account." -msgstr "アカウントを設定する必要があります" +msgstr "アカウントを設定する必要があります。" -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "Authorization" msgstr "認証" -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "" "The request to authorize your Twitter account will be opened in your " "browser. You only need to do this once. Would you like to continue?" @@ -1857,15 +1883,15 @@ msgstr "" "アカウントを認証するために、ブラウザを開きます。あなたは、一度だけ、これを実" "行する必要があります。続行しますか?" -#: ../src\sessionmanager\wxUI.py:52 +#: ../src\sessionmanager\wxUI.py:53 msgid "Authorized account %d" msgstr "認証したアカウント%d" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "Invalid user token" -msgstr "無効なユーザートークンです。" +msgstr "無効なユーザートークン" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "" "Your access token is invalid or the authorization has failed. Please try " "again." @@ -1873,30 +1899,65 @@ msgstr "" "あなたのアクセストークンが無効であるか、または許可が失敗しました。もう一度や" "り直してください。" -#: ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:65 msgid "Do you really want to delete this account?" msgstr "本当にこのアカウントを削除しますか?" -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 +#: ../src\sessionmanager\wxUI.py:81 +msgid "Authentication error for session {}" +msgstr "セッション {} の認証エラー" + +#: ../src\sessionmanager\wxUI.py:81 +msgid "" +"TWBlue is unable to authenticate the account for {} in Twitter. It might be " +"due to an invalid or expired token, revoqued access to the application, or " +"after an account reactivation. Please remove the account manually from your " +"Twitter sessions in order to stop seeing this message." +msgstr "" +"TWBlueはTwitterで {} のアカウントを認証できません。トークンが無効または期限切" +"れであるか、アプリケーションへのアクセスが取り消されているか、アカウントの再" +"アクティブ化が原因である可能性があります。このメッセージの表示を停止するに" +"は、Twitterセッションからアカウントを手動で削除してください。" + +#: ../src\sessions\base.py:113 +msgid "" +"An exception occurred while saving the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"{app} データベースの保存中に例外が発生しました。自動的に削除され、再構築され" +"ます。このエラーが続く場合は、エラーログを {app} 開発者に送信してください。" + +#: ../src\sessions\base.py:153 +msgid "" +"An exception occurred while loading the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"{app} データベースの読み込み中に例外が発生しました。自動的に削除され、再構築" +"されます。このエラーが続く場合は、エラーログを {app} 開発者に送信してくださ" +"い。" + +#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 +#: ../src\sessions\twitter\compose.py:146 +#: ../src\sessions\twitter\compose.py:155 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "YYYY年MMMMD日(dddd) H時m分s秒" -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 +#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 msgid "Dm to %s " -msgstr "「%s」へのDM" +msgstr "「%s」へのDM " -#: ../src\sessions\twitter\compose.py:141 +#: ../src\sessions\twitter\compose.py:130 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0} 引用:@{1}:{2}" -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 +#: ../src\sessions\twitter\compose.py:157 +#: ../src\sessions\twitter\compose.py:159 msgid "Unavailable" msgstr "無効" -#: ../src\sessions\twitter\compose.py:166 +#: ../src\sessions\twitter\compose.py:160 msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1904,60 +1965,66 @@ msgstr "" "%s: @%s フォロワー: %s フォロー: %s ツイート数: %s 最後のツイート: %s ツイッ" "ターへの参加: %s" -#: ../src\sessions\twitter\compose.py:170 +#: ../src\sessions\twitter\compose.py:164 msgid "No description available" msgstr "説明はありません" -#: ../src\sessions\twitter\compose.py:174 +#: ../src\sessions\twitter\compose.py:168 msgid "private" msgstr "プライベート" -#: ../src\sessions\twitter\compose.py:175 +#: ../src\sessions\twitter\compose.py:169 msgid "public" msgstr "公式" -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "このツイートには、ジェオタグは存在しません" - -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" -msgstr "%s" +msgstr "%s が失敗しました。理由: %s" -#: ../src\sessions\twitter\session.py:221 +#: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%sに成功しました。" -#: ../src\sessions\twitter\utils.py:225 -msgid "Sorry, you are not authorised to see this status." -msgstr "申し訳ありませんが、あなたはこのステータスを表示する権限がありません" +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 +msgid "Deleted account" +msgstr "削除されたアカウント" -#: ../src\sessions\twitter\utils.py:227 +#: ../src\sessions\twitter\utils.py:231 +msgid "Sorry, you are not authorised to see this status." +msgstr "申し訳ありませんが、あなたはこのステータスを表示する権限がありません。" + +#: ../src\sessions\twitter\utils.py:233 msgid "No status found with that ID" msgstr "そのIDのステータスが見つかりませんでした" -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "エラーコード {0}" +#: ../src\sessions\twitter\utils.py:235 +msgid "Error {0}" +msgstr "エラー {0}" -#: ../src\sessions\twitter\wxUI.py:6 +#: ../src\sessions\twitter\utils.py:262 +msgid "{user_1}, {user_2} and {all_users} more: {text}" +msgstr "{user_1}、{user_2}、ほか{all_users}ユーザー: {text}" + +#: ../src\sessions\twitter\wxUI.py:7 msgid "Authorising account..." msgstr "アカウントを連携中…" -#: ../src\sessions\twitter\wxUI.py:9 +#: ../src\sessions\twitter\wxUI.py:10 msgid "Enter your PIN code here" msgstr "PINコードを入力" -#: ../src\sound.py:159 +#: ../src\sound.py:160 msgid "Stopped." -msgstr "停止" +msgstr "停止。" -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "New version for %s" msgstr "「%s」の新しいバージョン" -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "" "There's a new %s version available, released on %s. Would you like to " "download it now?\n" @@ -1970,90 +2037,92 @@ msgstr "" "%sの新しいバージョンが%sにリリースされています。今すぐダウンロードします" "か?\n" "\n" -"%sバージョン:%s\n" +"%sバージョン: %s\n" "\n" -"更新履歴:\n" +"更新履歴: \n" "%s" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Download in Progress" msgstr "ダウンロード中" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Downloading the new version..." -msgstr "新しいバージョンをダウンロードしています" +msgstr "新しいバージョンをダウンロード中…" -#: ../src\update\wxUpdater.py:28 +#: ../src\update\wxUpdater.py:32 msgid "Updating... %s of %s" msgstr "アップデート中… %s/%s" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "Done!" -msgstr "完了" +msgstr "完了!" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "" "The update has been downloaded and installed successfully. Press OK to " "continue." msgstr "" -"アップデートは正常にインストールされました。続行する場合は、「OK」を押してく" -"ださい" +"アップデートは正常にダウンロードされ、インストールされました。続行する場合" +"は、「OK」を押してください。" -#: ../src\wxUI\buffers\base.py:11 +#: ../src\wxUI\buffers\base.py:12 msgid "Client" msgstr "クライアント" -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "内容" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "日時" -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\people.py:12 +#: ../src\wxUI\buffers\user_searches.py:11 +#: ../src\wxUI\dialogs\userAliasDialogs.py:14 +#: ../src\wxUI\dialogs\userSelection.py:11 ../src\wxUI\dialogs\utils.py:32 msgid "User" msgstr "ユーザー" -#: ../src\wxUI\buffers\base.py:27 +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "内容" + +#: ../src\wxUI\buffers\base.py:28 msgid "Direct message" msgstr "ダイレクトメッセージ" -#: ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\events.py:14 msgid "Event" msgstr "イベント" -#: ../src\wxUI\buffers\events.py:15 +#: ../src\wxUI\buffers\events.py:16 msgid "Remove event" msgstr "イベントを削除" -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 +#: ../src\wxUI\buffers\panels.py:12 ../src\wxUI\buffers\panels.py:20 msgid "Login" msgstr "ログイン" -#: ../src\wxUI\buffers\panels.py:13 +#: ../src\wxUI\buffers\panels.py:14 msgid "Log in automatically" msgstr "自動的にログインする" -#: ../src\wxUI\buffers\panels.py:21 +#: ../src\wxUI\buffers\panels.py:22 msgid "Logout" msgstr "ログアウト" -#: ../src\wxUI\buffers\trends.py:8 +#: ../src\wxUI\buffers\trends.py:9 msgid "Trending topic" -msgstr "トレンドの話題" +msgstr "トレンド" -#: ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\buffers\trends.py:19 msgid "Tweet about this trend" msgstr "このトレンドのツイート" -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 +#: ../src\wxUI\buffers\trends.py:20 ../src\wxUI\menus.py:97 msgid "Search topic" msgstr "トピックを検索" -#: ../src\wxUI\commonMessageDialogs.py:6 +#: ../src\wxUI\commonMessageDialogs.py:7 msgid "" "This retweet is over 140 characters. Would you like to post it as a mention " "to the poster with your comments and a link to the original tweet?" @@ -2061,39 +2130,38 @@ msgstr "" "このリツイートは、140文字を超えています。投稿者へのリプライとコメント、お" "よび元のツイートへのリンクで登校しますか?" -#: ../src\wxUI\commonMessageDialogs.py:9 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Would you like to add a comment to this tweet?" msgstr "このツイートにコメントをつけますか?" -#: ../src\wxUI\commonMessageDialogs.py:12 +#: ../src\wxUI\commonMessageDialogs.py:13 msgid "" "Do you really want to delete this tweet? It will be deleted from Twitter as " "well." msgstr "" -"本当にこのツイートを削除しますか?このツイートは、ツイッターから削除されま" -"す。" +"本当にこのツイートを削除しますか?このツイートは、Twitterから削除されます。" -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\commonMessageDialogs.py:13 ../src\wxUI\dialogs\lists.py:149 msgid "Delete" msgstr "削除" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Do you really want to close {0}?" msgstr "本当に「{0}」を終了しますか?" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Exit" msgstr "終了確認" -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid " {0} must be restarted for these changes to take effect." msgstr "これらの変更を有効にするには、「{0}」を再起動する必要があります。" -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid "Restart {0} " msgstr "「{0}」を再起動" -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "" "Are you sure you want to delete this user from the database? This user will " "not appear in autocomplete results anymore." @@ -2101,56 +2169,56 @@ msgstr "" "データベースからこのユーザーを削除してもよろしいですか?このユーザーは、自動" "補完結果には表示されません。" -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "Confirm" msgstr "確認" -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 msgid "Enter the name of the client : " -msgstr "クライアントの名前:" +msgstr "クライアントの名前: " -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 #: ../src\wxUI\dialogs\configuration.py:246 msgid "Add client" msgstr "クライアントを追加" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "" "Do you really want to empty this buffer? It's items will be removed from " "the list but not from Twitter" msgstr "" -"本当にこのバッファをクリアしますか?これは、ツイッターからは削除されません。" +"本当にこのバッファをクリアしますか?これは、Twitterからは削除されません。" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "Empty buffer" msgstr "バッファをクリア" -#: ../src\wxUI\commonMessageDialogs.py:35 +#: ../src\wxUI\commonMessageDialogs.py:36 msgid "Do you really want to destroy this buffer?" msgstr "本当にこのバッファを削除しますか?" -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 +#: ../src\wxUI\commonMessageDialogs.py:36 +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Attention" msgstr "確認" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "A timeline for this user already exists. You can't open another" msgstr "" "そのユーザーのタイムラインは、既に開かれています。他のユーザーを開いてくださ" "い。" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "Existing timeline" msgstr "既存のタイムライン" -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "This user has no tweets, so you can't open a timeline for them." msgstr "" "このユーザーは、何もツイートしていないため、タイムラインを開くことができませ" "ん。" -#: ../src\wxUI\commonMessageDialogs.py:47 +#: ../src\wxUI\commonMessageDialogs.py:48 msgid "" "This is a protected Twitter user, which means you can't open a timeline " "using the Streaming API. The user's tweets will not update due to a twitter " @@ -2160,12 +2228,12 @@ msgstr "" "ムラインを開くことができないことを意味します。ユーザーのツイートはTwitterのポ" "リシーにより更新されません。続行しますか?" -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:48 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "Warning" msgstr "警告" -#: ../src\wxUI\commonMessageDialogs.py:50 +#: ../src\wxUI\commonMessageDialogs.py:51 msgid "" "This is a protected user account, you need to follow this user to view their " "tweets or likes." @@ -2173,7 +2241,7 @@ msgstr "" "このユーザーは保護されています。このユーザーのツイートやお気に入り一覧を見る" "には、このユーザーをフォローする必要があります。" -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "" "If you like {0} we need your help to keep it going. Help us by donating to " "the project. This will help us pay for the server, the domain and some other " @@ -2187,47 +2255,47 @@ msgstr "" "ののために支払うのに役立ちます。あなたの寄付は私たちに「{0}」の開発を継続する" "ための手段を与え、自由な「{0}」を維持します。今すぐ寄付しますか?" -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "We need your help" msgstr "寄付のお願い" -#: ../src\wxUI\commonMessageDialogs.py:57 +#: ../src\wxUI\commonMessageDialogs.py:58 msgid "This user has no tweets. {0} can't create a timeline." msgstr "" "このユーザーにはツイートがないため、「{0}」のタイムラインを作成することはでき" "ません。" -#: ../src\wxUI\commonMessageDialogs.py:60 +#: ../src\wxUI\commonMessageDialogs.py:61 msgid "This user has no favorited tweets. {0} can't create a timeline." msgstr "" "このユーザーには、お気に入り登録されたツイートがないため、「{0}」のタイムライ" "ンを作成することはできません。" -#: ../src\wxUI\commonMessageDialogs.py:63 +#: ../src\wxUI\commonMessageDialogs.py:64 msgid "This user has no followers. {0} can't create a timeline." msgstr "" "このユーザーのフォロワーがいないため、「{0}」でタイムラインを作ることはできま" "せん。" -#: ../src\wxUI\commonMessageDialogs.py:66 +#: ../src\wxUI\commonMessageDialogs.py:67 msgid "This user has no friends. {0} can't create a timeline." msgstr "" "このユーザーは、誰もフォローしていないため、「{0}」でタイムラインを作ることは" "できません。" -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geo data for this tweet" msgstr "このツイートの位置情報" -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geolocation data: {0}" msgstr "位置情報: {0}" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "Information" msgstr "情報" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "" "TWBlue has detected that you're running windows 10 and has changed the " "default keymap to the Windows 10 keymap. It means that some keyboard " @@ -2239,11 +2307,11 @@ msgstr "" "違うことを意味します。このキーマップで使用できる全てのショートカットを見るに" "は、Alt+Win+Kで、キーストロークエディタを開いて確認してください。" -#: ../src\wxUI\commonMessageDialogs.py:76 +#: ../src\wxUI\commonMessageDialogs.py:77 msgid "You have been blocked from viewing this content" msgstr "このコンテンツの表示がブロックされています" -#: ../src\wxUI\commonMessageDialogs.py:79 +#: ../src\wxUI\commonMessageDialogs.py:80 msgid "" "You have been blocked from viewing someone's content. In order to avoid " "conflicts with the full session, TWBlue will remove the affected timeline." @@ -2251,170 +2319,121 @@ msgstr "" "他のユーザーのコンテンツを表示できないようになっています。フルセッションとの" "競合を避けるため、TWBlueは影響を受けるタイムラインを削除します。" -#: ../src\wxUI\commonMessageDialogs.py:82 +#: ../src\wxUI\commonMessageDialogs.py:83 msgid "" "TWBlue cannot load this timeline because the user has been suspended from " "Twitter." msgstr "" "ユーザーがTwitterから凍結されているため、このタイムラインをロードできません。" -#: ../src\wxUI\commonMessageDialogs.py:85 +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Do you really want to delete this filter?" msgstr "本当に、このフィルターを削除しますか?" -#: ../src\wxUI\commonMessageDialogs.py:88 +#: ../src\wxUI\commonMessageDialogs.py:89 msgid "This filter already exists. Please use a different title" msgstr "このフィルターはすでに利用されています。別の名前を利用してください" -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." msgstr "" -"前回、 {0} は正常に終了しませんでした. この問題が継続して発生する場合には、 " -"{0} の開発者までレポートを送ってください。" +"{0}は、前回の実行時に予期せず終了しました。問題が解決しない場合は、{0}開発者" +"に報告してください。" -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "添付ファイル" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "タイトル" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "形式" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "画像(&P)" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "添付ファイルを削除" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "アップロードする画像を選択" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "説明を入力" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "説明" - -#: ../src\wxUI\dialogs\configuration.py:16 +#: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "言語" -#: ../src\wxUI\dialogs\configuration.py:23 +#: ../src\wxUI\dialogs\configuration.py:22 msgid "Run {0} at Windows startup" msgstr "Windows起動時に{0}を実行" -#: ../src\wxUI\dialogs\configuration.py:24 +#: ../src\wxUI\dialogs\configuration.py:23 msgid "ask before exiting {0}" msgstr "{0}を終了する前に確認" -#: ../src\wxUI\dialogs\configuration.py:27 +#: ../src\wxUI\dialogs\configuration.py:26 msgid "Disable Streaming functions" msgstr "ストリーミング機能を無効化する" -#: ../src\wxUI\dialogs\configuration.py:30 +#: ../src\wxUI\dialogs\configuration.py:29 msgid "Buffer update interval, in minutes" msgstr "バッファの更新間隔(分)" -#: ../src\wxUI\dialogs\configuration.py:36 +#: ../src\wxUI\dialogs\configuration.py:35 msgid "Play a sound when {0} launches" msgstr "{0}が起動したときに、音声を再生" -#: ../src\wxUI\dialogs\configuration.py:38 +#: ../src\wxUI\dialogs\configuration.py:37 msgid "Speak a message when {0} launches" msgstr "{0}が起動した際に、メッセージを読み上げ" -#: ../src\wxUI\dialogs\configuration.py:40 +#: ../src\wxUI\dialogs\configuration.py:39 msgid "Use invisible interface's keyboard shortcuts while GUI is visible" msgstr "GUI表示中でもGUI非表示時に利用できるショートカットを利用する" -#: ../src\wxUI\dialogs\configuration.py:42 +#: ../src\wxUI\dialogs\configuration.py:41 msgid "Activate Sapi5 when any other screen reader is not being run" msgstr "他のスクリーンリーダーが起動していないときは、Sapi5を利用する" -#: ../src\wxUI\dialogs\configuration.py:44 +#: ../src\wxUI\dialogs\configuration.py:43 msgid "Hide GUI on launch" msgstr "起動時にGUIを隠す" -#: ../src\wxUI\dialogs\configuration.py:46 +#: ../src\wxUI\dialogs\configuration.py:45 msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" msgstr "" "Codeofduskを利用して長いツイートをできるようにする(パフォーマンスが低下する" "場合があります)" -#: ../src\wxUI\dialogs\configuration.py:48 +#: ../src\wxUI\dialogs\configuration.py:47 msgid "Remember state for mention all and long tweet" msgstr "" "「全員にリプライ」および「ツイートを短縮して投稿」のチェック状態を保持する" -#: ../src\wxUI\dialogs\configuration.py:51 +#: ../src\wxUI\dialogs\configuration.py:50 msgid "Keymap" msgstr "キーマップ" -#: ../src\wxUI\dialogs\configuration.py:56 +#: ../src\wxUI\dialogs\configuration.py:55 msgid "Check for updates when {0} launches" msgstr "{0}の起動時にアップデートを確認" -#: ../src\wxUI\dialogs\configuration.py:66 +#: ../src\wxUI\dialogs\configuration.py:65 msgid "Proxy type: " msgstr "プロキシタイプ: " -#: ../src\wxUI\dialogs\configuration.py:73 +#: ../src\wxUI\dialogs\configuration.py:72 msgid "Proxy server: " -msgstr "プロキシサーバー:" +msgstr "プロキシサーバー: " -#: ../src\wxUI\dialogs\configuration.py:79 +#: ../src\wxUI\dialogs\configuration.py:78 msgid "Port: " -msgstr "ポート:" +msgstr "ポート: " -#: ../src\wxUI\dialogs\configuration.py:85 +#: ../src\wxUI\dialogs\configuration.py:84 msgid "User: " -msgstr "ユーザー名:" +msgstr "ユーザー名: " -#: ../src\wxUI\dialogs\configuration.py:91 +#: ../src\wxUI\dialogs\configuration.py:90 msgid "Password: " -msgstr "パスワード:" +msgstr "パスワード: " -#: ../src\wxUI\dialogs\configuration.py:103 +#: ../src\wxUI\dialogs\configuration.py:102 msgid "Autocompletion settings..." -msgstr "自動保管の設定" +msgstr "自動保管の設定..." -#: ../src\wxUI\dialogs\configuration.py:105 +#: ../src\wxUI\dialogs\configuration.py:104 msgid "Relative timestamps" msgstr "相対的な時刻を利用する" -#: ../src\wxUI\dialogs\configuration.py:108 +#: ../src\wxUI\dialogs\configuration.py:107 msgid "Items on each API call" msgstr "各API呼び出しの回数" -#: ../src\wxUI\dialogs\configuration.py:114 +#: ../src\wxUI\dialogs\configuration.py:113 msgid "" "Inverted buffers: The newest tweets will be shown at the beginning while the " "oldest at the end" @@ -2422,15 +2441,15 @@ msgstr "" "バッファの並び順を入れ替える(新しいツイートを先頭に、古いツイートを最後に表" "示)" -#: ../src\wxUI\dialogs\configuration.py:116 +#: ../src\wxUI\dialogs\configuration.py:115 msgid "Retweet mode" msgstr "リツイートのモード" -#: ../src\wxUI\dialogs\configuration.py:122 +#: ../src\wxUI\dialogs\configuration.py:121 msgid "Show screen names instead of full names" msgstr "表示名の代わりに、ユーザー名を表示する" -#: ../src\wxUI\dialogs\configuration.py:124 +#: ../src\wxUI\dialogs\configuration.py:123 msgid "" "Number of items per buffer to cache in database (0 to disable caching, blank " "for unlimited)" @@ -2438,6 +2457,14 @@ msgstr "" "バッファごとにデータベースにキャッシュする項目数(0はキャッシュしない、空欄の" "場合は無制限)" +#: ../src\wxUI\dialogs\configuration.py:127 +msgid "" +"Load cache for tweets in memory (much faster in big datasets but requires " +"more RAM)" +msgstr "" +"ツイートのキャッシュをメモリにロードする(大きなデータセットでははるかに高速" +"ですが、より多くのRAMが必要です)" + #: ../src\wxUI\dialogs\configuration.py:134 msgid "Enable automatic speech feedback" msgstr "自動音声フィードバックを有効化" @@ -2451,7 +2478,7 @@ msgid "Status" msgstr "ステータス" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "バッファ" @@ -2484,20 +2511,20 @@ msgstr "非表示" #: ../src\wxUI\dialogs\configuration.py:169 #: ../src\wxUI\dialogs\configuration.py:193 msgid "Select a buffer first." -msgstr "最初にバッファを選んでください" +msgstr "最初にバッファを選んでください。" #: ../src\wxUI\dialogs\configuration.py:172 #: ../src\wxUI\dialogs\configuration.py:196 msgid "The buffer is hidden, show it first." -msgstr "そのバッファは非表示状態です。まず最初に、表示してください" +msgstr "そのバッファは非表示状態です。まず最初に、表示してください。" #: ../src\wxUI\dialogs\configuration.py:175 msgid "The buffer is already at the top of the list." -msgstr "既にそのバッファは、リストの先頭です" +msgstr "既にそのバッファは、リストの先頭です。" #: ../src\wxUI\dialogs\configuration.py:199 msgid "The buffer is already at the bottom of the list." -msgstr "既にそのバッファは、リストの最後です" +msgstr "既にそのバッファは、リストの最後です。" #: ../src\wxUI\dialogs\configuration.py:240 #: ../src\wxUI\dialogs\configuration.py:381 @@ -2576,277 +2603,199 @@ msgstr "その他" msgid "Save" msgstr "保存" -#: ../src\wxUI\dialogs\filterDialogs.py:15 +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "このバッファのフィルタを作成" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" msgstr "フィルター名" -#: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by word" msgstr "単語でフィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:26 +#: ../src\wxUI\dialogs\filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "次の単語が含まれるツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: ../src\wxUI\dialogs\filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "次の単語が含まれないツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:32 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" msgstr "単語" -#: ../src\wxUI\dialogs\filterDialogs.py:37 +#: ../src\wxUI\dialogs\filterDialogs.py:36 msgid "Allow retweets" msgstr "リツイートを許可する" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: ../src\wxUI\dialogs\filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "引用ツイートを許可する" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: ../src\wxUI\dialogs\filterDialogs.py:38 msgid "Allow replies" msgstr "リプライを許可するフォロワー一覧" -#: ../src\wxUI\dialogs\filterDialogs.py:47 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "正規表現を利用" -#: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by language" msgstr "言語でフィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:50 +#: ../src\wxUI\dialogs\filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "下記の言語のツイートを表示" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: ../src\wxUI\dialogs\filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "下記の言語のツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: ../src\wxUI\dialogs\filterDialogs.py:51 msgid "Don't filter by language" msgstr "言語でフィルタしない" -#: ../src\wxUI\dialogs\filterDialogs.py:63 +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" msgstr "サポートしている言語" -#: ../src\wxUI\dialogs\filterDialogs.py:68 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" msgstr "選択した言語をフィルターに追加" -#: ../src\wxUI\dialogs\filterDialogs.py:72 +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" msgstr "選択した言語" -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "削除" -#: ../src\wxUI\dialogs\filterDialogs.py:122 +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "フィルター名がありません" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "フィルターを作成する前に、フィルターの名前を定義する必要があります。" + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" msgstr "フィルターの管理" -#: ../src\wxUI\dialogs\filterDialogs.py:124 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" msgstr "フィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" msgstr "フィルター" -#: ../src\wxUI\dialogs\find.py:12 +#: ../src\wxUI\dialogs\find.py:13 msgid "Find in current buffer" msgstr "現在のバッファ内を検索" -#: ../src\wxUI\dialogs\find.py:13 +#: ../src\wxUI\dialogs\find.py:14 msgid "String" msgstr "検索文字" -#: ../src\wxUI\dialogs\lists.py:10 +#: ../src\wxUI\dialogs\lists.py:11 msgid "Lists manager" msgstr "リストの管理" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "List" msgstr "リスト" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Members" msgstr "メンバー" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Owner" msgstr "所有者" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "mode" msgstr "モード" -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "説明" + +#: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "新しいリストを作成" -#: ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:22 msgid "Open in buffer" msgstr "バッファで開く" -#: ../src\wxUI\dialogs\lists.py:51 +#: ../src\wxUI\dialogs\lists.py:52 msgid "Viewing lists for %s" msgstr "「%s」のリストを閲覧中" -#: ../src\wxUI\dialogs\lists.py:52 +#: ../src\wxUI\dialogs\lists.py:53 msgid "Subscribe" msgstr "登録" -#: ../src\wxUI\dialogs\lists.py:53 +#: ../src\wxUI\dialogs\lists.py:54 msgid "Unsubscribe" msgstr "登録解除" -#: ../src\wxUI\dialogs\lists.py:64 +#: ../src\wxUI\dialogs\lists.py:65 msgid "Name (20 characters maximun)" msgstr "名前(二〇文字以内)" -#: ../src\wxUI\dialogs\lists.py:74 +#: ../src\wxUI\dialogs\lists.py:75 msgid "Mode" msgstr "モード" -#: ../src\wxUI\dialogs\lists.py:75 +#: ../src\wxUI\dialogs\lists.py:76 msgid "Public" msgstr "公開" -#: ../src\wxUI\dialogs\lists.py:76 +#: ../src\wxUI\dialogs\lists.py:77 msgid "Private" msgstr "プライベート" -#: ../src\wxUI\dialogs\lists.py:96 +#: ../src\wxUI\dialogs\lists.py:97 msgid "Editing the list %s" msgstr "リスト「%s」を編集中" -#: ../src\wxUI\dialogs\lists.py:107 +#: ../src\wxUI\dialogs\lists.py:108 msgid "Select a list to add the user" msgstr "ユーザーを追加するリストを選択" -#: ../src\wxUI\dialogs\lists.py:108 +#: ../src\wxUI\dialogs\lists.py:109 msgid "Add" msgstr "追加" -#: ../src\wxUI\dialogs\lists.py:130 +#: ../src\wxUI\dialogs\lists.py:131 msgid "Select a list to remove the user" msgstr "ユーザーを削除するには、リストを選択" -#: ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\dialogs\lists.py:149 msgid "Do you really want to delete this list?" msgstr "本当に、このリストを削除しますか?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "ツイートを短縮して投稿(&L)" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "画像をアップロード(&U)" - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "スペルチェック(&S)" - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "音声を添付(&A)" - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "URLを短縮(&O)" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "URLを元に戻す(&E)" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "翻訳(&T)..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "ユーザーを自動保管(&C)" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "送信(&D)" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "閉じる(&C)" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "送信先(&R)" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "全員にリプライ(&M)" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "ツイート - %i文字" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "画像の説明" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "リツイート:" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "いいね" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "ソース:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "日時" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "ツイート" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "アイテム" - -#: ../src\wxUI\dialogs\search.py:13 +#: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "ツイッターを検索" -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 +#: ../src\wxUI\dialogs\search.py:13 ../src\wxUI\view.py:21 msgid "&Search" msgstr "検索(&S)" @@ -2854,13 +2803,13 @@ msgstr "検索(&S)" msgid "Tweets" msgstr "ツイート" -#: ../src\wxUI\dialogs\search.py:22 +#: ../src\wxUI\dialogs\search.py:22 ../src\wxUI\dialogs\userAliasDialogs.py:43 msgid "Users" msgstr "ユーザー" #: ../src\wxUI\dialogs\search.py:29 msgid "&Language for results: " -msgstr "結果の言語(&L):" +msgstr "結果の言語(&L): " #: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 msgid "any" @@ -2868,7 +2817,7 @@ msgstr "指定しない" #: ../src\wxUI\dialogs\search.py:37 msgid "Results &type: " -msgstr "結果のタイプ(&T):" +msgstr "結果のタイプ(&T): " #: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 msgid "Mixed" @@ -2882,562 +2831,678 @@ msgstr "最近" msgid "Popular" msgstr "人気" -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 +#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:25 +#: ../src\wxUI\dialogs\userActions.py:41 +#: ../src\wxUI\dialogs\userSelection.py:33 msgid "&OK" msgstr "OK(&O)" -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 +#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:19 +#: ../src\wxUI\dialogs\trends.py:27 ../src\wxUI\dialogs\update_profile.py:37 +#: ../src\wxUI\dialogs\userActions.py:43 +#: ../src\wxUI\dialogs\userSelection.py:35 msgid "&Close" msgstr "閉じる(&C)" -#: ../src\wxUI\dialogs\show_user.py:11 +#: ../src\wxUI\dialogs\show_user.py:12 msgid "Details" msgstr "詳細" -#: ../src\wxUI\dialogs\show_user.py:16 +#: ../src\wxUI\dialogs\show_user.py:17 msgid "&Go to URL" msgstr "URLへ移動(&G)" -#: ../src\wxUI\dialogs\trends.py:12 +#: ../src\wxUI\dialogs\trends.py:10 msgid "View trending topics" -msgstr "トレンドの話題を表示" +msgstr "トレンドを表示" -#: ../src\wxUI\dialogs\trends.py:13 +#: ../src\wxUI\dialogs\trends.py:11 msgid "Trending topics by" -msgstr "トレンドの話題" +msgstr "トレンド" -#: ../src\wxUI\dialogs\trends.py:15 +#: ../src\wxUI\dialogs\trends.py:12 msgid "Country" msgstr "国" -#: ../src\wxUI\dialogs\trends.py:16 +#: ../src\wxUI\dialogs\trends.py:13 msgid "City" msgstr "都市" -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 +#: ../src\wxUI\dialogs\trends.py:19 ../src\wxUI\dialogs\update_profile.py:18 msgid "&Location" msgstr "場所(&L)" -#: ../src\wxUI\dialogs\update_profile.py:9 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "添付ファイル" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "形式" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "添付ファイルを削除" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "ツイートを追加" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "ツイートを削除" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "追加(&D)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "ツイートを追加(&W)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "音声を添付(&A)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "ユーザーを自動保管(&C)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "スペルチェック(&S)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "翻訳(&T)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "送信(&D)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "画像" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "動画" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "投票" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "説明を入力" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "アップロードする画像を選択" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "アップロードする動画を選択" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "動画ファイル (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "添付ファイルの追加中にエラーが発生しました" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"これ以上添付ファイルを追加することはできません。ツイートがTwitterの添付ルール" +"に準拠していることを確認してください。すべてのツイートに追加できるビデオまた" +"はGIFは1つだけで、最大4枚の写真を追加できます。" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "全員にリプライ(&M)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "送信先(&R)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "ツイート - %i文字" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "画像の説明" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "リツイート: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "いいね: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "ソース: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "日付: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "リンクをクリップボードへコピー" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "翻訳(&T)..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "閉じる(&C)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "ツイート" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "アイテム" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "URLを元に戻す(&E)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "投票を追加" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "投票期間(日数)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "選択肢" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "オプション1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "オプション2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "オプション3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "オプション4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "十分な情報がありません" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "投票に少なくとも2つのオプションを提供していることを確認してください。" + +#: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "プロフィールを更新" -#: ../src\wxUI\dialogs\update_profile.py:11 +#: ../src\wxUI\dialogs\update_profile.py:12 msgid "&Name (50 characters maximum)" msgstr "名前(50文字以内)(&N)" -#: ../src\wxUI\dialogs\update_profile.py:22 +#: ../src\wxUI\dialogs\update_profile.py:23 msgid "&Website" msgstr "ウェブサイト(&W)" -#: ../src\wxUI\dialogs\update_profile.py:27 +#: ../src\wxUI\dialogs\update_profile.py:28 msgid "&Bio (160 characters maximum)" msgstr "自己紹介(160文字以内)(&B)" -#: ../src\wxUI\dialogs\update_profile.py:33 +#: ../src\wxUI\dialogs\update_profile.py:34 msgid "Upload a &picture" msgstr "画像をアップロード(&P)" -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 +#: ../src\wxUI\dialogs\update_profile.py:35 ../src\wxUI\view.py:19 msgid "&Update profile" msgstr "プロフィールを更新(&U)" -#: ../src\wxUI\dialogs\update_profile.py:76 +#: ../src\wxUI\dialogs\update_profile.py:77 msgid "Upload a picture" msgstr "画像をアップロード" -#: ../src\wxUI\dialogs\update_profile.py:78 +#: ../src\wxUI\dialogs\update_profile.py:79 msgid "Discard image" msgstr "画像をアップロードできません" -#: ../src\wxUI\dialogs\urlList.py:5 +#: ../src\wxUI\dialogs\urlList.py:6 msgid "Select URL" msgstr "URLを選択" -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 +#: ../src\wxUI\dialogs\userActions.py:11 ../src\wxUI\view.py:87 msgid "&User" msgstr "ユーザー(&U)" -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 +#: ../src\wxUI\dialogs\userActions.py:14 +#: ../src\wxUI\dialogs\userAliasDialogs.py:13 +#: ../src\wxUI\dialogs\userSelection.py:14 ../src\wxUI\dialogs\utils.py:31 msgid "&Autocomplete users" msgstr "自動保管されたユーザー" -#: ../src\wxUI\dialogs\userActions.py:19 +#: ../src\wxUI\dialogs\userActions.py:20 msgid "&Follow" msgstr "フォロー(&F)" -#: ../src\wxUI\dialogs\userActions.py:20 +#: ../src\wxUI\dialogs\userActions.py:21 msgid "U&nfollow" msgstr "フォロー解除(&N)" -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 +#: ../src\wxUI\dialogs\userActions.py:22 ../src\wxUI\view.py:63 msgid "&Mute" msgstr "ミュート(&M)" -#: ../src\wxUI\dialogs\userActions.py:22 +#: ../src\wxUI\dialogs\userActions.py:23 msgid "Unmu&te" msgstr "ミュート解除(&T)" -#: ../src\wxUI\dialogs\userActions.py:23 +#: ../src\wxUI\dialogs\userActions.py:24 msgid "&Block" msgstr "ブロック(&B)" -#: ../src\wxUI\dialogs\userActions.py:24 +#: ../src\wxUI\dialogs\userActions.py:25 msgid "Unbl&ock" msgstr "ブロック解除(&O)" -#: ../src\wxUI\dialogs\userActions.py:25 +#: ../src\wxUI\dialogs\userActions.py:26 msgid "&Report as spam" msgstr "スパムとして報告(&R)" -#: ../src\wxUI\dialogs\userActions.py:26 +#: ../src\wxUI\dialogs\userActions.py:27 msgid "&Ignore tweets from this client" msgstr "このクライアントからのツイートを無視(&I)" -#: ../src\wxUI\dialogs\userSelection.py:9 +#: ../src\wxUI\dialogs\userAliasDialogs.py:18 +msgid "Alias" +msgstr "エイリアス" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:41 +msgid "Edit user aliases" +msgstr "ユーザーエイリアスを編集" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:48 +msgid "Actions" +msgstr "操作" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:50 +msgid "Add alias" +msgstr "エイリアスを追加" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:51 +msgid "Adds a new user alias" +msgstr "新しいユーザーエイリアスを追加" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:54 +msgid "Edit the currently focused user Alias." +msgstr "現在フォーカスされているユーザーエイリアスを編集します。" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:58 +msgid "Remove the currently focused user alias." +msgstr "現在フォーカスされているユーザーエイリアスを削除します。" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Are you sure you want to delete this user alias?" +msgstr "このユーザーエイリアスを削除してもよろしいですか?" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Remove user alias" +msgstr "ユーザーエイリアスを削除" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:93 +msgid "User alias" +msgstr "ユーザーエイリアス" + +#: ../src\wxUI\dialogs\userSelection.py:10 msgid "Timeline for %s" msgstr "「%s」のタイムライン" -#: ../src\wxUI\dialogs\userSelection.py:18 +#: ../src\wxUI\dialogs\userSelection.py:19 msgid "Buffer type" msgstr "バッファのタイプ" -#: ../src\wxUI\dialogs\userSelection.py:19 +#: ../src\wxUI\dialogs\userSelection.py:20 msgid "&Tweets" msgstr "ツイート(&T)" -#: ../src\wxUI\dialogs\userSelection.py:20 +#: ../src\wxUI\dialogs\userSelection.py:21 msgid "&Likes" msgstr "いいね(&L)" -#: ../src\wxUI\dialogs\userSelection.py:21 +#: ../src\wxUI\dialogs\userSelection.py:22 msgid "&Followers" msgstr "フォロワー(&F)" -#: ../src\wxUI\dialogs\userSelection.py:22 +#: ../src\wxUI\dialogs\userSelection.py:23 msgid "F&riends" msgstr "フォロー(&R)" -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 +#: ../src\wxUI\menus.py:8 ../src\wxUI\view.py:33 msgid "&Retweet" msgstr "リツイート(&R)" -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 +#: ../src\wxUI\menus.py:10 ../src\wxUI\menus.py:34 ../src\wxUI\view.py:32 msgid "Re&ply" msgstr "リプライ(&P)" -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 +#: ../src\wxUI\menus.py:12 ../src\wxUI\view.py:34 msgid "&Like" msgstr "いいね(&L)" -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 +#: ../src\wxUI\menus.py:14 ../src\wxUI\view.py:35 msgid "&Unlike" msgstr "いいねを解除(&U)" -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 +#: ../src\wxUI\menus.py:16 ../src\wxUI\menus.py:36 ../src\wxUI\menus.py:52 msgid "&Open URL" msgstr "URLを開く(&O)" -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy +#: ../src\wxUI\menus.py:18 ../src\wxUI\menus.py:54 ../src\wxUI\menus.py:87 msgid "&Open in Twitter" msgstr "ツイッターを検索" -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 +#: ../src\wxUI\menus.py:20 ../src\wxUI\menus.py:38 ../src\wxUI\menus.py:56 msgid "&Play audio" msgstr "音声を再生(&P)" -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 +#: ../src\wxUI\menus.py:22 ../src\wxUI\menus.py:58 ../src\wxUI\view.py:36 msgid "&Show tweet" msgstr "ツイートを表示(&S)" -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 +#: ../src\wxUI\menus.py:24 ../src\wxUI\menus.py:42 ../src\wxUI\menus.py:60 +#: ../src\wxUI\menus.py:70 ../src\wxUI\menus.py:89 ../src\wxUI\menus.py:103 msgid "&Copy to clipboard" msgstr "クリップボードにコピー(&C)" -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 +#: ../src\wxUI\menus.py:26 ../src\wxUI\menus.py:44 ../src\wxUI\menus.py:62 +#: ../src\wxUI\menus.py:72 ../src\wxUI\view.py:40 msgid "&Delete" msgstr "削除(&D)" -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 +#: ../src\wxUI\menus.py:28 ../src\wxUI\menus.py:46 ../src\wxUI\menus.py:91 msgid "&User actions..." msgstr "ユーザーのアクション(&U)" -#: ../src\wxUI\menus.py:39 +#: ../src\wxUI\menus.py:40 msgid "&Show direct message" msgstr "ダイレクトメッセージを表示(&S)" -#: ../src\wxUI\menus.py:67 +#: ../src\wxUI\menus.py:68 msgid "&Show event" msgstr "イベントを表示(&S)" -#: ../src\wxUI\menus.py:77 +#: ../src\wxUI\menus.py:78 msgid "Direct &message" msgstr "ダイレクトメッセージ(&M)" -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 +#: ../src\wxUI\menus.py:80 ../src\wxUI\view.py:50 msgid "&View lists" msgstr "リストを見る(&V)" -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 +#: ../src\wxUI\menus.py:83 ../src\wxUI\view.py:51 msgid "Show user &profile" msgstr "ユーザーのプロフィールを表示(&P)" -#: ../src\wxUI\menus.py:84 +#: ../src\wxUI\menus.py:85 msgid "&Show user" msgstr "ユーザーを表示(&S)" -#: ../src\wxUI\menus.py:98 +#: ../src\wxUI\menus.py:99 msgid "&Tweet about this trend" msgstr "このトレンドのツイート(&T)" -#: ../src\wxUI\menus.py:100 +#: ../src\wxUI\menus.py:101 msgid "&Show item" msgstr "アイテムを表示(&S)" -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 +#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:26 msgid "&Global settings" msgstr "全般設定(&G)" -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 +#: ../src\wxUI\sysTrayIcon.py:37 ../src\wxUI\view.py:25 msgid "Account se&ttings" msgstr "アカウント設定(&T(" -#: ../src\wxUI\sysTrayIcon.py:37 +#: ../src\wxUI\sysTrayIcon.py:38 msgid "Update &profile" msgstr "プロフィールを更新(&P)" -#: ../src\wxUI\sysTrayIcon.py:38 +#: ../src\wxUI\sysTrayIcon.py:39 msgid "&Show / hide" msgstr "表示または非表示(&S)" -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 +#: ../src\wxUI\sysTrayIcon.py:40 ../src\wxUI\view.py:75 msgid "&Documentation" msgstr "取扱説明書(&D)" -#: ../src\wxUI\sysTrayIcon.py:40 +#: ../src\wxUI\sysTrayIcon.py:41 msgid "Check for &updates" msgstr "アップデートを確認(&U)" -#: ../src\wxUI\sysTrayIcon.py:41 +#: ../src\wxUI\sysTrayIcon.py:42 msgid "&Exit" msgstr "終了(&E)" -#: ../src\wxUI\view.py:16 +#: ../src\wxUI\view.py:18 msgid "&Manage accounts" msgstr "アカウントの管理(&M)" -#: ../src\wxUI\view.py:18 +#: ../src\wxUI\view.py:20 msgid "&Hide window" msgstr "ウィンドウを隠す(&H)" -#: ../src\wxUI\view.py:20 +#: ../src\wxUI\view.py:22 msgid "&Lists manager" msgstr "リストの管理(&L)" -#: ../src\wxUI\view.py:21 +#: ../src\wxUI\view.py:23 +msgid "Manage user aliases" +msgstr "ユーザーエイリアスの管理" + +#: ../src\wxUI\view.py:24 msgid "&Edit keystrokes" msgstr "キーストロークを編集(&E)" -#: ../src\wxUI\view.py:24 +#: ../src\wxUI\view.py:27 msgid "E&xit" msgstr "終了(&X)" -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 +#: ../src\wxUI\view.py:31 ../src\wxUI\view.py:86 msgid "&Tweet" msgstr "ツイート(&T)" -#: ../src\wxUI\view.py:34 +#: ../src\wxUI\view.py:37 msgid "View &address" msgstr "位置情報を表示(&A)" -#: ../src\wxUI\view.py:35 +#: ../src\wxUI\view.py:38 msgid "View conversa&tion" msgstr "会話を見る(&T)" -#: ../src\wxUI\view.py:36 +#: ../src\wxUI\view.py:39 msgid "Read text in picture" msgstr "画像からテキストを読み取り" -#: ../src\wxUI\view.py:41 +#: ../src\wxUI\view.py:44 msgid "&Actions..." msgstr "操作(&A)" -#: ../src\wxUI\view.py:42 +#: ../src\wxUI\view.py:45 msgid "&View timeline..." msgstr "タイムラインを表示(&V)" -#: ../src\wxUI\view.py:43 +#: ../src\wxUI\view.py:46 msgid "Direct me&ssage" msgstr "ダイレクトメッセージ(&S)" -#: ../src\wxUI\view.py:44 +#: ../src\wxUI\view.py:47 +msgid "Add a&lias" +msgstr "エイリアスを追加(&A)" + +#: ../src\wxUI\view.py:48 msgid "&Add to list" msgstr "リストに追加(&A)" -#: ../src\wxUI\view.py:45 +#: ../src\wxUI\view.py:49 msgid "R&emove from list" msgstr "リストから削除(&E)" -#: ../src\wxUI\view.py:48 +#: ../src\wxUI\view.py:52 msgid "V&iew likes" msgstr "いいね一覧を見る(&I)" -#: ../src\wxUI\view.py:52 +#: ../src\wxUI\view.py:56 msgid "&Update buffer" msgstr "バッファを更新(&U)" -#: ../src\wxUI\view.py:53 +#: ../src\wxUI\view.py:57 msgid "New &trending topics buffer..." -msgstr "新しいトレンドの話題のバッファ(&T)" +msgstr "新しいトレンドのバッファ(&T)" -#: ../src\wxUI\view.py:54 +#: ../src\wxUI\view.py:58 msgid "Create a &filter" msgstr "新しいフィルターを作成(&F)" -#: ../src\wxUI\view.py:55 +#: ../src\wxUI\view.py:59 msgid "&Manage filters" msgstr "フィルターの管理(&M)" -#: ../src\wxUI\view.py:56 +#: ../src\wxUI\view.py:60 msgid "Find a string in the currently focused buffer..." -msgstr "現在フォーカス中のバッファ内の文字列を検索" +msgstr "現在フォーカス中のバッファ内の文字列を検索..." -#: ../src\wxUI\view.py:57 +#: ../src\wxUI\view.py:61 msgid "&Load previous items" msgstr "以前のアイテムを取得(&L)" -#: ../src\wxUI\view.py:60 +#: ../src\wxUI\view.py:64 msgid "&Autoread" msgstr "自動読み上げ(&A)" -#: ../src\wxUI\view.py:61 +#: ../src\wxUI\view.py:65 msgid "&Clear buffer" msgstr "バッファをクリア(&C)" -#: ../src\wxUI\view.py:62 +#: ../src\wxUI\view.py:66 msgid "&Destroy" msgstr "バッファを削除(&D)" -#: ../src\wxUI\view.py:66 +#: ../src\wxUI\view.py:70 msgid "&Seek back 5 seconds" msgstr "5秒戻る(&S)" -#: ../src\wxUI\view.py:67 +#: ../src\wxUI\view.py:71 msgid "&Seek forward 5 seconds" msgstr "5秒進む(&S)" -#: ../src\wxUI\view.py:72 +#: ../src\wxUI\view.py:76 msgid "Sounds &tutorial" msgstr "サウンドの確認(&T)" -#: ../src\wxUI\view.py:73 +#: ../src\wxUI\view.py:77 msgid "&What's new in this version?" msgstr "更新履歴(&W)" -#: ../src\wxUI\view.py:74 +#: ../src\wxUI\view.py:78 msgid "&Check for updates" msgstr "アップデートを確認(&C)" -#: ../src\wxUI\view.py:75 +#: ../src\wxUI\view.py:79 msgid "&Report an error" msgstr "エラーを報告(&R)" -#: ../src\wxUI\view.py:76 +#: ../src\wxUI\view.py:80 msgid "{0}'s &website" msgstr "「{0}」のウェブサイト(&W)" -#: ../src\wxUI\view.py:77 +#: ../src\wxUI\view.py:81 msgid "Get soundpacks for TWBlue" -msgstr "TWBlue のサウンドパックを入手" +msgstr "TWBlueのサウンドパックを入手" -#: ../src\wxUI\view.py:78 +#: ../src\wxUI\view.py:82 msgid "About &{0}" msgstr "{0}について(&A)" -#: ../src\wxUI\view.py:81 +#: ../src\wxUI\view.py:85 msgid "&Application" msgstr "アプリケーション(&A)" -#: ../src\wxUI\view.py:84 +#: ../src\wxUI\view.py:88 msgid "&Buffer" msgstr "バッファ(&B)" -#: ../src\wxUI\view.py:85 +#: ../src\wxUI\view.py:89 msgid "&Audio" msgstr "音声(&A)" -#: ../src\wxUI\view.py:86 +#: ../src\wxUI\view.py:90 msgid "&Help" msgstr "ヘルプ(&H)" -#: ../src\wxUI\view.py:172 +#: ../src\wxUI\view.py:176 msgid "Address" msgstr "アドレス" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Update" msgstr "アップデート" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Your {0} version is up to date" msgstr "「{0}」のバージョンは最新です" - -#~ msgid "Empty" -#~ msgstr "何もありません" - -#~ msgid "One mention from %s " -#~ msgstr "%sからの返信" - -#~ msgid "One tweet from %s" -#~ msgstr "「%s」からのツイート" - -#~ msgid "You've blocked %s" -#~ msgstr "「%s」をブロックしました。" - -#~ msgid "You've unblocked %s" -#~ msgstr "「%s」のブロックを解除しました" - -#~ msgid "%s(@%s) has followed you" -#~ msgstr "「%s: @%s」がフォローしました" - -#~ msgid "You've followed %s(@%s)" -#~ msgstr "「%s: @%s」をフォローしました" - -#~ msgid "You've unfollowed %s (@%s)" -#~ msgstr "「%s: @%s」のフォローを解除しました" - -#~ msgid "You've liked: %s, %s" -#~ msgstr "%s %sをいいねしました" - -#~ msgid "%s(@%s) has liked: %s" -#~ msgstr "%s(@%s)が「%s」をいいねしました" - -#~ msgid "You've unliked: %s, %s" -#~ msgstr "%s %sのいいねを解除しました" - -#~ msgid "%s(@%s) has unliked: %s" -#~ msgstr "%s(@%s)が%sのいいねを解除しました" - -#~ msgid "You've created the list %s" -#~ msgstr "リスト「%s」を作成しました" - -#~ msgid "You've deleted the list %s" -#~ msgstr "リスト「%s」を削除しました" - -#~ msgid "You've updated the list %s" -#~ msgstr "リスト「%s」をアップデートしました" - -#~ msgid "You've added %s(@%s) to the list %s" -#~ msgstr "「%s: @%s」をリスト「%s」に追加しました" - -#~ msgid "%s(@%s) has added you to the list %s" -#~ msgstr "「%s: @%s」がリスト「%s」にあなたを追加しました" - -#~ msgid "You'be removed %s(@%s) from the list %s" -#~ msgstr "「%s: @%s」をリスト「%s」から削除しました" - -#~ msgid "%s(@%s) has removed you from the list %s" -#~ msgstr "「%s: @%s」がリスト「%s」からあなたを削除しました" - -#~ msgid "You've subscribed to the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」に加入しました" - -#~ msgid "%s(@%s) has subscribed you to the list %s" -#~ msgstr "「%s(@%s)」があなたのリスト「%s」を購読しました" - -#~ msgid "You've unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」から退会しました" - -#~ msgid "You've been unsubscribed from the list %s, which is owned by %s(@%s)" -#~ msgstr "「%s: @%s」によって所有されているリスト「%s」から退会してきました" - -#~ msgid "You have retweeted a retweet from %s(@%s): %s" -#~ msgstr "「%s: @%s」がリツイートした「%s」をリツイートしました" - -#~ msgid "%s(@%s) has retweeted your retweet: %s" -#~ msgstr "「%s: @%s」があなたのリツイート「%s」をリツイートしました" - -#~ msgid "" -#~ "API calls (One API call = 200 tweets, two API calls = 400 tweets, etc):" -#~ msgstr "" -#~ "APIの呼び出し数(1回のAPIの呼び出し=200、2回のAPIの呼び出し=400、など)" - -#~ msgid "Unable to upload the audio" -#~ msgstr "音声をアップロードできません" - -#~ msgid "Waiting for account authorisation..." -#~ msgstr "アカウント連携を待機しています…" - -#~ msgid "autodetect" -#~ msgstr "自動検出" - -#~ msgid "" -#~ "There's a new %s version available. Would you like to download it now?\n" -#~ "\n" -#~ " %s version: %s\n" -#~ "\n" -#~ "Changes:\n" -#~ "%s" -#~ msgstr "" -#~ "「%s」の新しいバージョンが利用可能です。今すぐダウンロードしますか?\n" -#~ "\n" -#~ "%sバージョン: %s\n" -#~ "\n" -#~ "更新履歴\n" -#~ "%s" - -#~ msgid "Start {0} after logging in windows" -#~ msgstr "Windowsログオン後に{0}を起動" - -#~ msgid "" -#~ "If you have a SndUp account, enter your API Key here. If your API Key is " -#~ "invalid, {0} will fail to upload. If there is no API Key here, {0} will " -#~ "upload annonymously." -#~ msgstr "" -#~ "SndUpアカウントをお持ちの場合は、ここにAPIキーを入力してください。APIキー" -#~ "が無効である場合、{0}のアップロードに失敗します。APIキーが存在しない場合" -#~ "は、{0}は、匿名でアップロードされます。" - -#~ msgid "Disconnect your Pocket account" -#~ msgstr "Poketとの連携を解除" - -#~ msgid "Connect your Pocket account" -#~ msgstr "Pocketアカウントと連携" - -#~ msgid "Pocket Authorization" -#~ msgstr "Pocketの認証" - -#~ msgid "" -#~ "The authorization request will be opened in your browser. You only need " -#~ "to do this once. Do you want to continue?" -#~ msgstr "" -#~ "認証要求をブラウザで開きます。一度だけこれを実行する必要があります。続行し" -#~ "ますか?" - -#~ msgid "Error during authorization. Try again later." -#~ msgstr "認証中にエラーが発生しました。後でやり直してください。" - -#~ msgid "Services" -#~ msgstr "サービス" - -#~ msgid "Contains" -#~ msgstr "含む" - -#~ msgid "Doesn't contain" -#~ msgstr "含まない" - -#~ msgid "" -#~ "You have successfully logged into Twitter with {0}. You can close this " -#~ "window now." -#~ msgstr "" -#~ "{0}でのTwitterのログインに成功しました。今すぐこのウィンドウを閉じることが" -#~ "できます。" diff --git a/src/locales/ru/LC_MESSAGES/twblue.mo b/src/locales/ru/LC_MESSAGES/twblue.mo index fea14909..ab4e6268 100644 Binary files a/src/locales/ru/LC_MESSAGES/twblue.mo and b/src/locales/ru/LC_MESSAGES/twblue.mo differ diff --git a/src/locales/ru/LC_MESSAGES/twblue.po b/src/locales/ru/LC_MESSAGES/twblue.po index ee83c122..4b041800 100644 --- a/src/locales/ru/LC_MESSAGES/twblue.po +++ b/src/locales/ru/LC_MESSAGES/twblue.po @@ -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 \n" "Language-Team: Alexander Jaszyn \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" diff --git a/src/locales/sr/LC_MESSAGES/twblue.mo b/src/locales/sr/LC_MESSAGES/twblue.mo index 5a32e58d..4406f6ca 100644 Binary files a/src/locales/sr/LC_MESSAGES/twblue.mo and b/src/locales/sr/LC_MESSAGES/twblue.mo differ diff --git a/src/locales/sr/LC_MESSAGES/twblue.po b/src/locales/sr/LC_MESSAGES/twblue.po index 91c2fe2a..79d3e91d 100644 --- a/src/locales/sr/LC_MESSAGES/twblue.po +++ b/src/locales/sr/LC_MESSAGES/twblue.po @@ -5,293 +5,289 @@ msgid "" msgstr "" "Project-Id-Version: TwBlue 0.80\n" -"POT-Creation-Date: 2019-03-17 13:34+Hora estndar romance\n" -"PO-Revision-Date: 2018-08-07 13:46-0500\n" -"Last-Translator: Manuel Cortez \n" +"POT-Creation-Date: 2021-11-11 01:16+0100\n" +"PO-Revision-Date: 2021-11-11 01:30+0100\n" +"Last-Translator: Nikola Jović \n" "Language-Team: Aleksandar Đurić \n" "Language: sr_RS@latin\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 2.0.1\n" +"X-Generator: Poedit 1.6.10\n" "X-Poedit-Bookmarks: -1,442,-1,-1,-1,-1,-1,-1,-1,-1\n" "X-Poedit-SourceCharset: UTF-8\n" -#: ../src\controller\attach.py:23 -msgid "Photo" -msgstr "Slika" - -#: ../src\controller\buffers\baseBuffers.py:95 +#: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "Ova radnja nije podržana na ovom kanalu" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:306 ../src\controller\settings.py:282 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 msgid "Home" msgstr "Početak" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:310 ../src\controller\settings.py:283 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 msgid "Mentions" msgstr "Spominjanja" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:314 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:341 msgid "Direct messages" msgstr "Direktne poruke" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:318 ../src\controller\settings.py:285 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 msgid "Sent direct messages" msgstr "Poslate direktne poruke" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:322 ../src\controller\settings.py:286 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 msgid "Sent tweets" msgstr "Poslati tvitovi" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:326 -#: ../src\controller\mainController.py:1363 ../src\controller\settings.py:287 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:347 +#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 msgid "Likes" msgstr "Sviđanja" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:330 -#: ../src\controller\mainController.py:1368 ../src\controller\settings.py:288 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:349 +#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 msgid "Followers" msgstr "Pratioci" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:334 -#: ../src\controller\mainController.py:1373 ../src\controller\settings.py:289 -msgid "Friends" -msgstr "Prijatelji" - -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:338 -#: ../src\controller\mainController.py:1378 ../src\controller\settings.py:290 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:353 +#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 msgid "Blocked users" msgstr "Blokirani korisnici" -#: ../src\controller\buffers\twitterBuffers.py:69 -#: ../src\controller\mainController.py:342 -#: ../src\controller\mainController.py:1383 ../src\controller\settings.py:291 +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:355 +#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 msgid "Muted users" msgstr "Utišani korisnici" -#: ../src\controller\buffers\twitterBuffers.py:75 -#, fuzzy +#: ../src\controller\buffers\twitter\base.py:70 +#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 +msgid "Friends" +msgstr "Prijatelji" + +#: ../src\controller\buffers\twitter\base.py:76 msgid "{username}'s timeline" -msgstr "Otvori korisničku vremensku crtu" +msgstr "Vremenska linija korisnika {username}" -#: ../src\controller\buffers\twitterBuffers.py:77 +#: ../src\controller\buffers\twitter\base.py:78 msgid "{username}'s likes" -msgstr "" +msgstr "Sviđanja korisnika {username}" -#: ../src\controller\buffers\twitterBuffers.py:79 +#: ../src\controller\buffers\twitter\base.py:80 msgid "{username}'s followers" -msgstr "" +msgstr "Pratioci korisnika {username}" -#: ../src\controller\buffers\twitterBuffers.py:81 +#: ../src\controller\buffers\twitter\base.py:82 msgid "{username}'s friends" -msgstr "" +msgstr "Prijatelji korisnika {username}" -#: ../src\controller\buffers\twitterBuffers.py:83 -#, fuzzy +#: ../src\controller\buffers\twitter\base.py:84 msgid "Unknown buffer" -msgstr "Nepoznato" +msgstr "Nepoznat kanal" -#: ../src\controller\buffers\twitterBuffers.py:86 -#: ../src\controller\buffers\twitterBuffers.py:1242 -#: ../src\controller\messages.py:205 ../src\wxUI\buffers\base.py:24 -#: ../src\wxUI\buffers\events.py:14 ../src\wxUI\buffers\trends.py:17 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:34 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 +#: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "Tvit" -#: ../src\controller\buffers\twitterBuffers.py:87 -#: ../src\controller\buffers\twitterBuffers.py:1243 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "Otkucajte tvit ovde:" -#: ../src\controller\buffers\twitterBuffers.py:194 -#, fuzzy +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" -msgstr "Novi tvit" +msgstr "Novi tvit u kanalu {0}" -#: ../src\controller\buffers\twitterBuffers.py:197 -#, fuzzy +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." -msgstr "@{0} citira vaš tvit: {1}" +msgstr "{0} novih tvitova u kanalu {1}." -#: ../src\controller\buffers\twitterBuffers.py:232 -#: ../src\controller\buffers\twitterBuffers.py:676 -#: ../src\controller\buffers\twitterBuffers.py:910 -#: ../src\controller\buffers\twitterBuffers.py:1061 -#: ../src\controller\buffers\twitterBuffers.py:1126 +#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\directMessages.py:88 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s primljenih stavki" -#: ../src\controller\buffers\twitterBuffers.py:264 -#: ../src\controller\buffers\twitterBuffers.py:840 +#: ../src\controller\buffers\twitter\base.py:266 +#: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ovaj kanal nije vremenska linija i ne može biti izbrisan." -#: ../src\controller\buffers\twitterBuffers.py:402 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "Odgovori {arg0}" -#: ../src\controller\buffers\twitterBuffers.py:404 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:26 +#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Odgovori" -#: ../src\controller\buffers\twitterBuffers.py:405 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "Odgovori %s" -#: ../src\controller\buffers\twitterBuffers.py:451 -msgid "Direct message to %s" -msgstr "Direktna poruka za %s" - -#: ../src\controller\buffers\twitterBuffers.py:451 -#: ../src\controller\buffers\twitterBuffers.py:725 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "Nova direktna poruka" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 +msgid "Direct message to %s" +msgstr "Direktna poruka za %s" + +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "Dodajte vaš komentar u tvit" -#: ../src\controller\buffers\twitterBuffers.py:500 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "Citiraj" -#: ../src\controller\buffers\twitterBuffers.py:572 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." msgstr "Otvaram vezu..." -#: ../src\controller\buffers\twitterBuffers.py:607 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "Podaci o korisniku" -#: ../src\controller\buffers\twitterBuffers.py:634 -#: ../src\controller\buffers\twitterBuffers.py:987 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." -msgstr "" +msgstr "Otvaram stavku u Web pretraživaču..." -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "Spomeni %s" -#: ../src\controller\buffers\twitterBuffers.py:688 -#: ../src\controller\buffers\twitterBuffers.py:855 -#: ../src\wxUI\buffers\people.py:16 +#: ../src\controller\buffers\twitter\directMessages.py:93 +#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "Spomeni" -#: ../src\controller\buffers\twitterBuffers.py:728 -#, fuzzy +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." -msgstr "Nova direktna poruka" +msgstr "{0} novih direktnih poruka." -#: ../src\controller\buffers\twitterBuffers.py:731 -#, fuzzy +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." -msgstr "Ova radnja nije podržana na ovom kanalu" +msgstr "Ova radnja još uvek nije podržana na ovom kanalu." -#: ../src\controller\buffers\twitterBuffers.py:741 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." msgstr "" +"Nemoguće preuzeti dodatne stavke za ovaj kanal. Umesto toga, koristite kanal " +"direktne poruke." -#: ../src\controller\buffers\twitterBuffers.py:983 -#, fuzzy +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." -msgstr "Novi pratilac." +msgstr "{0} novih pratilaca." -#: ../src\controller\buffers\twitterBuffers.py:1266 -#, fuzzy +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." -msgstr "Ova radnja nije podržana na ovom kanalu" +msgstr "Ova radnja još uvek nije podržana na ovom kanalu" -#: ../src\controller\mainController.py:273 +#: ../src\controller\mainController.py:277 msgid "Ready" msgstr "Spreman" -#: ../src\controller\mainController.py:345 +#: ../src\controller\mainController.py:351 +msgid "Following" +msgstr "Praćenja" + +#: ../src\controller\mainController.py:356 msgid "Timelines" msgstr "Vremenske linije" -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:860 -#: ../src\controller\mainController.py:1559 +#: ../src\controller\mainController.py:359 +#: ../src\controller\mainController.py:883 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "Vremenska linija od {}" -#: ../src\controller\mainController.py:352 +#: ../src\controller\mainController.py:360 msgid "Likes timelines" msgstr "Vremenska linija omiljenih tvitova" -#: ../src\controller\mainController.py:356 -#: ../src\controller\mainController.py:879 -#: ../src\controller\mainController.py:1561 +#: ../src\controller\mainController.py:363 +#: ../src\controller\mainController.py:902 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "Sviđanja od {}" -#: ../src\controller\mainController.py:359 -msgid "Followers' Timelines" -msgstr "Vremenska linija pratilaca" +#: ../src\controller\mainController.py:364 +msgid "Followers timelines" +msgstr "Vremenske linije pratilaca" -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:898 -#: ../src\controller\mainController.py:1563 +#: ../src\controller\mainController.py:367 +#: ../src\controller\mainController.py:921 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "Pratioci od {}" -#: ../src\controller\mainController.py:366 -msgid "Friends' Timelines" -msgstr "Vremenska linija prijatelja" +#: ../src\controller\mainController.py:368 +msgid "Following timelines" +msgstr "Vremenske linije praćenih korisnika" -#: ../src\controller\mainController.py:370 -#: ../src\controller\mainController.py:917 -#: ../src\controller\mainController.py:1565 +#: ../src\controller\mainController.py:371 +#: ../src\controller\mainController.py:940 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "Prijatelji od {}" -#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:12 +#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 msgid "Lists" msgstr "Liste" -#: ../src\controller\mainController.py:378 -#: ../src\controller\mainController.py:1399 +#: ../src\controller\mainController.py:375 +#: ../src\controller\mainController.py:1422 msgid "List for {}" msgstr "Liste od {}" -#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:376 msgid "Searches" msgstr "Pretrage" -#: ../src\controller\mainController.py:385 -#: ../src\controller\mainController.py:444 +#: ../src\controller\mainController.py:379 +#: ../src\controller\mainController.py:426 +#: ../src\controller\mainController.py:431 msgid "Search for {}" msgstr "Pretraga za {}" -#: ../src\controller\mainController.py:391 -#: ../src\controller\mainController.py:959 +#: ../src\controller\mainController.py:381 +#: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" msgstr "Teme u trendu za %s" -#: ../src\controller\mainController.py:461 -#: ../src\controller\mainController.py:477 -#: ../src\controller\mainController.py:1059 -#: ../src\controller\mainController.py:1078 -#: ../src\controller\mainController.py:1097 -#: ../src\controller\mainController.py:1116 +#: ../src\controller\mainController.py:448 +#: ../src\controller\mainController.py:464 +#: ../src\controller\mainController.py:1080 +#: ../src\controller\mainController.py:1099 +#: ../src\controller\mainController.py:1118 +#: ../src\controller\mainController.py:1137 msgid "" "No session is currently in focus. Focus a session with the next or previous " "session shortcut." @@ -299,241 +295,246 @@ msgstr "" "Trenutno nijedna sesija nije u fokusu. Fokusirajte neku pritiskom na prečicu " "za prethodnu ili sledeću." -#: ../src\controller\mainController.py:465 +#: ../src\controller\mainController.py:452 msgid "Empty buffer." msgstr "Prazan kanal." -#: ../src\controller\mainController.py:472 +#: ../src\controller\mainController.py:459 msgid "{0} not found." msgstr "{0} nije pronađen." -#: ../src\controller\mainController.py:482 -#, fuzzy +#: ../src\controller\mainController.py:469 msgid "Filters cannot be applied on this buffer" -msgstr "Ova radnja nije podržana na ovom kanalu" +msgstr "Filteri se ne mogu primeniti na ovaj kanal" -#: ../src\controller\mainController.py:535 -#: ../src\controller\mainController.py:552 -#: ../src\controller\mainController.py:580 +#: ../src\controller\mainController.py:522 +#: ../src\controller\mainController.py:539 +#: ../src\controller\mainController.py:568 msgid "Select the user" msgstr "Izaberite korisnika" -#: ../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" +#: ../src\controller\mainController.py:753 +msgid "Add an user alias" +msgstr "Dodaj nadimak za korisnika" -#: ../src\controller\mainController.py:934 +#: ../src\controller\mainController.py:761 +msgid "Alias has been set correctly for {}." +msgstr "Nadimak za {} je uspešno podešen." + +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 +msgid "MMM D, YYYY. H:m" +msgstr "MMM D, YYYY. H:m" + +#: ../src\controller\mainController.py:957 msgid "Conversation with {0}" msgstr "Razgovor sa {0}" -#: ../src\controller\mainController.py:975 -#: ../src\controller\mainController.py:994 +#: ../src\controller\mainController.py:998 +#: ../src\controller\mainController.py:1015 msgid "There are no coordinates in this tweet" msgstr "Nema koordinata u ovom tvitu." -#: ../src\controller\mainController.py:977 -#: ../src\controller\mainController.py:996 -msgid "There are no results for the coordinates in this tweet" -msgstr "Nema rezultata za te koordinate u ovom tvitu." - -#: ../src\controller\mainController.py:979 -#: ../src\controller\mainController.py:998 +#: ../src\controller\mainController.py:1000 +#: ../src\controller\mainController.py:1019 msgid "Error decoding coordinates. Try again later." msgstr "Greška prilikom čitanja koordinata. Molimo vas da pokušate kasnije." -#: ../src\controller\mainController.py:1107 -#: ../src\controller\mainController.py:1126 +#: ../src\controller\mainController.py:1004 +msgid "Unable to find address in OpenStreetMap." +msgstr "Nemoguće pronaći adresu u OpenStreet mapi." + +#: ../src\controller\mainController.py:1017 +msgid "There are no results for the coordinates in this tweet" +msgstr "Nema rezultata za te koordinate u ovom tvitu." + +#: ../src\controller\mainController.py:1128 +#: ../src\controller\mainController.py:1147 msgid "%s, %s of %s" msgstr "%s, %s od %s" -#: ../src\controller\mainController.py:1109 -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1153 -#: ../src\controller\mainController.py:1178 +#: ../src\controller\mainController.py:1130 +#: ../src\controller\mainController.py:1149 +#: ../src\controller\mainController.py:1174 +#: ../src\controller\mainController.py:1199 msgid "%s. Empty" msgstr "%s. Prazno." -#: ../src\controller\mainController.py:1141 -#: ../src\controller\mainController.py:1145 +#: ../src\controller\mainController.py:1162 #: ../src\controller\mainController.py:1166 +#: ../src\controller\mainController.py:1187 msgid "{0}: This account is not logged into Twitter." msgstr "{0}: Ovaj nalog nije prijavljen na twitter." -#: ../src\controller\mainController.py:1151 -#: ../src\controller\mainController.py:1176 +#: ../src\controller\mainController.py:1172 +#: ../src\controller\mainController.py:1197 msgid "%s. %s, %s of %s" msgstr "%s. %s, %s od %s" -#: ../src\controller\mainController.py:1170 +#: ../src\controller\mainController.py:1191 msgid "{0}: This account is not logged into twitter." msgstr "{0}: Ovaj nalog nije prijavljen na twitter." -#: ../src\controller\mainController.py:1388 -msgid "Events" -msgstr "Događaji" - -#: ../src\controller\mainController.py:1393 +#: ../src\controller\mainController.py:1416 msgid "This list is already opened" msgstr "Ova lista je već otvorena" -#: ../src\controller\mainController.py:1423 -#: ../src\controller\mainController.py:1439 -#, fuzzy +#: ../src\controller\mainController.py:1446 +#: ../src\controller\mainController.py:1462 msgid "" "An error happened while trying to connect to the server. Please try later." msgstr "" -"Dogodilo se nešto neočekivano prilikom prijavljivanja greške. Molimo vas da " -"pokušate kasnije." +"Došlo je do greške pri pokušaju povezivanja na server. Molimo pokušajte " +"kasnije." -#: ../src\controller\mainController.py:1475 +#: ../src\controller\mainController.py:1498 msgid "The auto-reading of new tweets is enabled for this buffer" msgstr "Automatsko čitanje novih tvitova je uključeno na ovom kanalu" -#: ../src\controller\mainController.py:1478 +#: ../src\controller\mainController.py:1501 msgid "The auto-reading of new tweets is disabled for this buffer" msgstr "Automatsko čitanje tvitova je isključeno za tvitove na ovom kanalu" -#: ../src\controller\mainController.py:1485 +#: ../src\controller\mainController.py:1508 msgid "Session mute on" msgstr "Utišavanje sesije uključeno" -#: ../src\controller\mainController.py:1488 +#: ../src\controller\mainController.py:1511 msgid "Session mute off" msgstr "Utišavanje sesije isključeno" -#: ../src\controller\mainController.py:1496 +#: ../src\controller\mainController.py:1519 msgid "Buffer mute on" msgstr "Utišavanje kanala uključeno" -#: ../src\controller\mainController.py:1499 +#: ../src\controller\mainController.py:1522 msgid "Buffer mute off" msgstr "Utišavanje kanala isključeno" -#: ../src\controller\mainController.py:1522 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "Kopirano" -#: ../src\controller\mainController.py:1549 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "Ne mogu da ažuriram ovaj kanal." -#: ../src\controller\mainController.py:1552 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "Ažuriram kanal..." -#: ../src\controller\mainController.py:1555 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0} primljenih stavki" -#: ../src\controller\mainController.py:1572 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" msgstr "Nevažeći kanal" -#: ../src\controller\mainController.py:1576 -msgid "This tweet doesn't contain images" -msgstr "Ovaj tvit ne sadrži slike." - -#: ../src\controller\mainController.py:1579 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "Slika {0}" -#: ../src\controller\mainController.py:1580 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "Izaberite sliku" -#: ../src\controller\mainController.py:1596 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "Ne mogu da izdvojim tekst." -#: ../src\controller\messages.py:54 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "Prevedeno" -#: ../src\controller\messages.py:61 -msgid "There's no URL to be shortened" -msgstr "Nema veze koja bi mogla biti skraćena" - -#: ../src\controller\messages.py:65 ../src\controller\messages.py:73 -msgid "URL shortened" -msgstr "Veza je skraćena" - -#: ../src\controller\messages.py:80 -msgid "There's no URL to be expanded" -msgstr "Nema veze koja bi mogla biti proširena" - -#: ../src\controller\messages.py:84 ../src\controller\messages.py:92 -msgid "URL expanded" -msgstr "Veza je proširena" - -#: ../src\controller\messages.py:104 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s od %d znakova" -#: ../src\controller\messages.py:108 -msgid "%s - %s characters" -msgstr "%s - %s znakova" - -#: ../src\controller\messages.py:262 -#, fuzzy +#: ../src\controller\messages.py:354 msgid "View item" -msgstr "Vidi liste" +msgstr "Prikaži stavku" -#: ../src\controller\settings.py:75 -msgid "Direct connection" -msgstr "Direktna veza" +#: ../src\controller\messages.py:379 +msgid "Link copied to clipboard." +msgstr "Link kopiran u privremenu memoriju." -#: ../src\controller\settings.py:145 ../src\controller\settings.py:207 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:74 +msgid "HTTP" +msgstr "HTTP" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4" +msgstr "SOCKS v4" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v4 with DNS support" +msgstr "SOCKS v4 sa DNS podrškom" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: ../src\controller\settings.py:74 +msgid "SOCKS v5 with DNS support" +msgstr "SOCKS v5 sa DNS podrškom" + +#: ../src\controller\settings.py:74 +msgid "System default" +msgstr "Sistemski podrazumevani" + +#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Ask" msgstr "Pitaj" -#: ../src\controller\settings.py:147 ../src\controller\settings.py:209 -#: ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 +#: ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet without comments" msgstr "Retvituj bez komentara" -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:117 +#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet with comments" msgstr "Retvituj sa komentarima" -#: ../src\controller\settings.py:184 +#: ../src\controller\settings.py:185 msgid "Account settings for %s" msgstr "Postavke naloga za %s" -#: ../src\controller\settings.py:284 +#: ../src\controller\settings.py:288 msgid "Direct Messages" msgstr "Direktne poruke " -#: ../src\controller\user.py:28 ../src\controller\user.py:30 -#: ../src\extra\SpellChecker\wx_ui.py:79 ../src\issueReporter\wx_ui.py:83 -#: ../src\issueReporter\wx_ui.py:86 ../src\wxUI\commonMessageDialogs.py:38 -#: ../src\wxUI\commonMessageDialogs.py:50 -#: ../src\wxUI\commonMessageDialogs.py:57 -#: ../src\wxUI\commonMessageDialogs.py:60 -#: ../src\wxUI\commonMessageDialogs.py:63 -#: ../src\wxUI\commonMessageDialogs.py:66 -#: ../src\wxUI\commonMessageDialogs.py:76 -#: ../src\wxUI\commonMessageDialogs.py:79 -#: ../src\wxUI\commonMessageDialogs.py:82 -#: ../src\wxUI\commonMessageDialogs.py:88 -#: ../src\wxUI\commonMessageDialogs.py:91 +#: ../src\controller\user.py:29 ../src\controller\user.py:31 +#: ../src\extra\SpellChecker\wx_ui.py:80 ../src\issueReporter\wx_ui.py:84 +#: ../src\issueReporter\wx_ui.py:87 ../src\wxUI\commonMessageDialogs.py:39 +#: ../src\wxUI\commonMessageDialogs.py:51 +#: ../src\wxUI\commonMessageDialogs.py:58 +#: ../src\wxUI\commonMessageDialogs.py:61 +#: ../src\wxUI\commonMessageDialogs.py:64 +#: ../src\wxUI\commonMessageDialogs.py:67 +#: ../src\wxUI\commonMessageDialogs.py:77 +#: ../src\wxUI\commonMessageDialogs.py:80 +#: ../src\wxUI\commonMessageDialogs.py:83 +#: ../src\wxUI\commonMessageDialogs.py:89 +#: ../src\wxUI\commonMessageDialogs.py:92 msgid "Error" msgstr "Greška" -#: ../src\controller\user.py:28 ../src\wxUI\commonMessageDialogs.py:38 +#: ../src\controller\user.py:29 ../src\wxUI\commonMessageDialogs.py:39 msgid "That user does not exist" msgstr "Taj korisnik ne postoji." -#: ../src\controller\user.py:30 +#: ../src\controller\user.py:31 msgid "User has been suspended" msgstr "Korisnik je suspendovan." -#: ../src\controller\user.py:36 +#: ../src\controller\user.py:37 msgid "Information for %s" msgstr "Informacija za %s" -#: ../src\controller\user.py:66 ../src\extra\AudioUploader\audioUploader.py:124 +#: ../src\controller\user.py:67 +#: ../src\extra\AudioUploader\audioUploader.py:127 msgid "Discarded" msgstr "Odbačeno" @@ -553,31 +554,31 @@ msgstr "Mesto: %s\n" msgid "URL: %s\n" msgstr "Veza: %s\n" -#: ../src\controller\user.py:102 +#: ../src\controller\user.py:104 msgid "Bio: %s\n" msgstr "Bio: %s\n" -#: ../src\controller\user.py:103 ../src\controller\user.py:118 +#: ../src\controller\user.py:105 ../src\controller\user.py:120 msgid "Yes" msgstr "Da" -#: ../src\controller\user.py:104 ../src\controller\user.py:119 +#: ../src\controller\user.py:106 ../src\controller\user.py:121 msgid "No" msgstr "Ne" -#: ../src\controller\user.py:105 +#: ../src\controller\user.py:107 msgid "Protected: %s\n" msgstr "Zaštićeno: %s\n" -#: ../src\controller\user.py:110 +#: ../src\controller\user.py:112 msgid "You follow {0}. " msgstr "Pratite {0}. " -#: ../src\controller\user.py:113 +#: ../src\controller\user.py:115 msgid "{0} is following you." msgstr "{0} vas prati." -#: ../src\controller\user.py:117 +#: ../src\controller\user.py:119 msgid "" "Followers: %s\n" " Friends: %s\n" @@ -585,340 +586,342 @@ msgstr "" "Pratioci: %s\n" " Prijatelji: %s\n" -#: ../src\controller\user.py:120 +#: ../src\controller\user.py:122 msgid "Verified: %s\n" msgstr "Potvrđen: %s\n" -#: ../src\controller\user.py:121 +#: ../src\controller\user.py:123 msgid "Tweets: %s\n" msgstr "Tvitovi: %s\n" -#: ../src\controller\user.py:122 +#: ../src\controller\user.py:124 msgid "Likes: %s" msgstr "Omiljeno: %s" -#: ../src\controller\userActionsController.py:75 +#: ../src\controller\userActionsController.py:74 msgid "You can't ignore direct messages" msgstr "Ne možete zanemariti direktne poruke." -#: ../src\extra\AudioUploader\audioUploader.py:54 +#: ../src\controller\userAliasController.py:32 +msgid "Edit alias for {}" +msgstr "Uredi nadimak za {}" + +#: ../src\extra\AudioUploader\audioUploader.py:57 msgid "Attaching..." msgstr "Prilažem..." -#: ../src\extra\AudioUploader\audioUploader.py:71 +#: ../src\extra\AudioUploader\audioUploader.py:74 msgid "Pause" msgstr "Zastani" -#: ../src\extra\AudioUploader\audioUploader.py:73 +#: ../src\extra\AudioUploader\audioUploader.py:76 msgid "&Resume" msgstr "&Nastavi" -#: ../src\extra\AudioUploader\audioUploader.py:74 +#: ../src\extra\AudioUploader\audioUploader.py:77 msgid "Resume" msgstr "Nastavi" -#: ../src\extra\AudioUploader\audioUploader.py:76 -#: ../src\extra\AudioUploader\audioUploader.py:103 -#: ../src\extra\AudioUploader\wx_ui.py:36 +#: ../src\extra\AudioUploader\audioUploader.py:79 +#: ../src\extra\AudioUploader\audioUploader.py:106 +#: ../src\extra\AudioUploader\wx_ui.py:37 msgid "&Pause" msgstr "&zastani" -#: ../src\extra\AudioUploader\audioUploader.py:91 -#: ../src\extra\AudioUploader\audioUploader.py:137 +#: ../src\extra\AudioUploader\audioUploader.py:94 +#: ../src\extra\AudioUploader\audioUploader.py:140 msgid "&Stop" msgstr "&Zaustavi" -#: ../src\extra\AudioUploader\audioUploader.py:92 +#: ../src\extra\AudioUploader\audioUploader.py:95 msgid "Recording" msgstr "Snimanje" -#: ../src\extra\AudioUploader\audioUploader.py:97 -#: ../src\extra\AudioUploader\audioUploader.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:100 +#: ../src\extra\AudioUploader\audioUploader.py:151 msgid "Stopped" msgstr "Zaustavljeno" -#: ../src\extra\AudioUploader\audioUploader.py:99 -#: ../src\extra\AudioUploader\wx_ui.py:38 +#: ../src\extra\AudioUploader\audioUploader.py:102 +#: ../src\extra\AudioUploader\wx_ui.py:39 msgid "&Record" msgstr "&Snimi" -#: ../src\extra\AudioUploader\audioUploader.py:133 ../src\sound.py:146 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." msgstr "Reprodukujem..." -#: ../src\extra\AudioUploader\audioUploader.py:141 -#: ../src\extra\AudioUploader\audioUploader.py:151 -#: ../src\extra\AudioUploader\wx_ui.py:34 +#: ../src\extra\AudioUploader\audioUploader.py:144 +#: ../src\extra\AudioUploader\audioUploader.py:154 +#: ../src\extra\AudioUploader\wx_ui.py:35 msgid "&Play" msgstr "&Pusti" -#: ../src\extra\AudioUploader\audioUploader.py:156 +#: ../src\extra\AudioUploader\audioUploader.py:159 msgid "Recoding audio..." msgstr "Snimam zvučni zapis..." -#: ../src\extra\AudioUploader\transfer.py:78 -#: ../src\extra\AudioUploader\transfer.py:84 -#, fuzzy +#: ../src\extra\AudioUploader\transfer.py:82 +#: ../src\extra\AudioUploader\transfer.py:88 msgid "Error in file upload: {0}" -msgstr "Kod greške {0}" +msgstr "Greška u otpremanju datoteke: {0}" -#: ../src\extra\AudioUploader\utils.py:27 ../src\update\utils.py:27 +#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 msgid "%d day, " msgstr "%d dan, " -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 +#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 msgid "%d days, " msgstr "%d dana, " -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 +#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 msgid "%d hour, " msgstr "%d čas, " -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 +#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 msgid "%d hours, " msgstr "%d časova, " -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 +#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 msgid "%d minute, " msgstr "%d minut, " -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 +#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 msgid "%d minutes, " msgstr "%d minuta, " -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 +#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 msgid "%s second" msgstr "%s sekund" -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 +#: ../src\extra\AudioUploader\utils.py:43 ../src\update\utils.py:43 msgid "%s seconds" msgstr "%s sekundi" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:14 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "Datoteka" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:20 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:21 msgid "Transferred" msgstr "Preuzeto" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:25 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:26 msgid "Total file size" msgstr "Ukupna veličina datoteke" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:30 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:31 msgid "Transfer rate" msgstr "Brzina prenosa" -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:35 +#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:36 msgid "Time left" msgstr "Preostalo vreme" -#: ../src\extra\AudioUploader\wx_ui.py:28 +#: ../src\extra\AudioUploader\wx_ui.py:29 msgid "Attach audio" msgstr "Priloži zvučni zapis" -#: ../src\extra\AudioUploader\wx_ui.py:40 +#: ../src\extra\AudioUploader\wx_ui.py:41 msgid "&Add an existing file" msgstr "&Dodaj postojeću datoteku" -#: ../src\extra\AudioUploader\wx_ui.py:41 +#: ../src\extra\AudioUploader\wx_ui.py:42 msgid "&Discard" msgstr "&Odbaci" -#: ../src\extra\AudioUploader\wx_ui.py:43 +#: ../src\extra\AudioUploader\wx_ui.py:44 msgid "Upload to" msgstr "Otpremi na" -#: ../src\extra\AudioUploader\wx_ui.py:48 +#: ../src\extra\AudioUploader\wx_ui.py:49 msgid "Attach" msgstr "Priloži" -#: ../src\extra\AudioUploader\wx_ui.py:50 +#: ../src\extra\AudioUploader\wx_ui.py:51 msgid "&Cancel" msgstr "&Otkaži" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" msgstr "Zvučni zapisi (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -#: ../src\extra\AudioUploader\wx_ui.py:75 +#: ../src\extra\AudioUploader\wx_ui.py:76 msgid "Select the audio file to be uploaded" msgstr "Izaberite zvučni zapis koji želite da otpremite" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:6 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 msgid "Audio tweet." msgstr "Tvit sa zvučnim zapisom" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 msgid "User timeline buffer created." msgstr "Kanal sa korisničkom vremenskom linijom je stvoren" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 msgid "Buffer destroied." msgstr "Kanal je izbrisan" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 msgid "Direct message received." msgstr "Primljena direktna poruka." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 msgid "Direct message sent." msgstr "Direktna poruka je poslata." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 msgid "Error." msgstr "Greška." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 msgid "Tweet liked." msgstr "Tvit je označen sa sviđa mi se." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 msgid "Likes buffer updated." msgstr "Kanal sviđanja je ažuriran." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 msgid "Geotweet." msgstr "Tvit sa lokacijom" -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 msgid "Tweet contains one or more images" msgstr "Tvit sadrži jednu ili više slika." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 msgid "Boundary reached." msgstr "Vrh ili dno." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 msgid "List updated." msgstr "Lista ažurirana." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 msgid "Too many characters." msgstr "Previše znakova." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 msgid "Mention received." msgstr "Neko vas je spomenuo." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 msgid "New event." msgstr "Novi događaj." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 msgid "{0} is ready." msgstr "{0} je spreman." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 msgid "Mention sent." msgstr "Spominjanje je poslato." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 msgid "Tweet retweeted." msgstr "Tvit je retvitovan." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 msgid "Search buffer updated." msgstr "Kanal pretrage je ažuriran." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 msgid "Tweet received." msgstr "Tvit je primljen." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 msgid "Tweet sent." msgstr "Tvit je poslat." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 msgid "Trending topics buffer updated." msgstr "Kanal sa temama u trendu je ažuriran." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 msgid "New tweet in user timeline buffer." msgstr "Novi tvit u kanalu korisničke vremenske linije." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 msgid "New follower." msgstr "Novi pratilac." -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 +#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:31 msgid "Volume changed." msgstr "Jačina je promenjena." -#: ../src\extra\SoundsTutorial\wx_ui.py:8 +#: ../src\extra\SoundsTutorial\wx_ui.py:9 msgid "Sounds tutorial" msgstr "Zvučna uputstva" -#: ../src\extra\SoundsTutorial\wx_ui.py:11 +#: ../src\extra\SoundsTutorial\wx_ui.py:12 msgid "Press enter to listen to the sound for the selected event" msgstr "Pritisnite enter kako bi ste čuli zvuk određenog događaja." -#: ../src\extra\SpellChecker\spellchecker.py:57 +#: ../src\extra\SpellChecker\spellchecker.py:60 msgid "Misspelled word: %s" msgstr "Pogrešno napisana reč: %s" -#: ../src\extra\SpellChecker\wx_ui.py:27 +#: ../src\extra\SpellChecker\wx_ui.py:28 msgid "Misspelled word" msgstr "Pogrešno napisana reč." -#: ../src\extra\SpellChecker\wx_ui.py:32 +#: ../src\extra\SpellChecker\wx_ui.py:33 msgid "Context" msgstr "Kontekst." -#: ../src\extra\SpellChecker\wx_ui.py:37 +#: ../src\extra\SpellChecker\wx_ui.py:38 msgid "Suggestions" msgstr "Predlozi" -#: ../src\extra\SpellChecker\wx_ui.py:42 -#, fuzzy -msgid "&Ignore" -msgstr "Zamenari." - #: ../src\extra\SpellChecker\wx_ui.py:43 -#, fuzzy -msgid "I&gnore all" -msgstr "Zanemari sve" +msgid "&Ignore" +msgstr "&Zanemari" #: ../src\extra\SpellChecker\wx_ui.py:44 -#, fuzzy -msgid "&Replace" -msgstr "Zameni" +msgid "I&gnore all" +msgstr "Z&anemai sve" #: ../src\extra\SpellChecker\wx_ui.py:45 -#, fuzzy -msgid "R&eplace all" -msgstr "Zameni sve" +msgid "&Replace" +msgstr "&Zameni" #: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "&Add to personal dictionary" -msgstr "" +msgid "R&eplace all" +msgstr "Zam&eni sve" -#: ../src\extra\SpellChecker\wx_ui.py:79 +#: ../src\extra\SpellChecker\wx_ui.py:47 +msgid "&Add to personal dictionary" +msgstr "&Dodaj u lični rečnik" + +#: ../src\extra\SpellChecker\wx_ui.py:80 msgid "" "An error has occurred. There are no dictionaries available for the selected " "language in {0}" msgstr "Došlo je do greške. Nema rečnika za odabrani jezik {0}" -#: ../src\extra\SpellChecker\wx_ui.py:82 +#: ../src\extra\SpellChecker\wx_ui.py:83 msgid "Spell check complete." msgstr "Provera pravopisa je završena." -#: ../src\extra\autocompletionUsers\completion.py:21 -#: ../src\extra\autocompletionUsers\completion.py:39 +#: ../src\extra\autocompletionUsers\completion.py:20 +#: ../src\extra\autocompletionUsers\completion.py:38 msgid "You have to start writing" msgstr "Morate da počnete da pišete." -#: ../src\extra\autocompletionUsers\completion.py:31 -#: ../src\extra\autocompletionUsers\completion.py:48 +#: ../src\extra\autocompletionUsers\completion.py:30 +#: ../src\extra\autocompletionUsers\completion.py:47 msgid "There are no results in your users database" msgstr "Nema rezultata u vašoj bazi korisnika-." -#: ../src\extra\autocompletionUsers\completion.py:33 +#: ../src\extra\autocompletionUsers\completion.py:32 msgid "Autocompletion only works for users." msgstr "Automatsko dovršavanje radi samo za korisnike." -#: ../src\extra\autocompletionUsers\settings.py:27 +#: ../src\extra\autocompletionUsers\settings.py:25 msgid "" "Updating database... You can close this window now. A message will tell you " "when the process finishes." @@ -926,45 +929,45 @@ msgstr "" "Ažuriram bazu podataka... Sada možete zatvoriti ovaj prozor. Dobićete " "obaveštenje kada se proces završi." -#: ../src\extra\autocompletionUsers\wx_manage.py:8 +#: ../src\extra\autocompletionUsers\wx_manage.py:9 msgid "Manage Autocompletion database" msgstr "Upravljaj bazom automatskog dovršavanja" -#: ../src\extra\autocompletionUsers\wx_manage.py:11 +#: ../src\extra\autocompletionUsers\wx_manage.py:12 msgid "Editing {0} users database" msgstr "Uređujem {0} bazu korisničkih podataka" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 msgid "Username" msgstr "Korisničko ime" -#: ../src\extra\autocompletionUsers\wx_manage.py:12 +#: ../src\extra\autocompletionUsers\wx_manage.py:13 #: ../src\wxUI\dialogs\configuration.py:144 msgid "Name" msgstr "Ime" -#: ../src\extra\autocompletionUsers\wx_manage.py:15 +#: ../src\extra\autocompletionUsers\wx_manage.py:16 msgid "Add user" msgstr "Dodaj korisnika" -#: ../src\extra\autocompletionUsers\wx_manage.py:16 +#: ../src\extra\autocompletionUsers\wx_manage.py:17 msgid "Remove user" msgstr "Ukloni korisnika" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Add user to database" msgstr "Dodaj korisnika u bazu podataka" -#: ../src\extra\autocompletionUsers\wx_manage.py:37 +#: ../src\extra\autocompletionUsers\wx_manage.py:38 msgid "Twitter username" msgstr "Twitter korisničko ime" -#: ../src\extra\autocompletionUsers\wx_manage.py:43 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 msgid "The user does not exist" msgstr "Korisnik ne postoji." -#: ../src\extra\autocompletionUsers\wx_manage.py:43 -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\extra\autocompletionUsers\wx_manage.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "Error!" msgstr "Greška" @@ -992,449 +995,449 @@ msgstr "Dovršeno" msgid "{0}'s database of users has been updated." msgstr "{0}'s korisničkih baza podataka je ažurirano." -#: ../src\extra\ocr\OCRSpace.py:5 +#: ../src\extra\ocr\OCRSpace.py:7 msgid "Detect automatically" msgstr "Otkrij automatski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:31 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:41 msgid "Danish" msgstr "danski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:33 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:43 msgid "Dutch" msgstr "Holandski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:34 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:44 msgid "English" msgstr "engleski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:38 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:48 msgid "Finnish" msgstr "finski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:39 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:49 msgid "French" msgstr "francuski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:42 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:52 msgid "German" msgstr "nemački" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:48 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:58 msgid "Hungarian" msgstr "mađarski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:53 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:63 msgid "Italian" msgstr "italijanski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:54 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:64 msgid "Japanese" msgstr "japanski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:58 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:68 msgid "Korean" msgstr "korejski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:75 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:85 msgid "Polish" msgstr "poljski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:76 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:86 msgid "Portuguese" msgstr "portugalski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:79 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:89 msgid "Russian" msgstr "ruski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:86 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:96 msgid "Spanish" msgstr "španski" -#: ../src\extra\ocr\OCRSpace.py:5 ../src\extra\translator\translator.py:95 +#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:105 msgid "Turkish" msgstr "turski" -#: ../src\extra\translator\translator.py:12 +#: ../src\extra\translator\translator.py:22 msgid "Afrikaans" msgstr "Afrički" -#: ../src\extra\translator\translator.py:13 +#: ../src\extra\translator\translator.py:23 msgid "Albanian" msgstr "Albanski" -#: ../src\extra\translator\translator.py:14 +#: ../src\extra\translator\translator.py:24 msgid "Amharic" msgstr "Amharic" -#: ../src\extra\translator\translator.py:15 +#: ../src\extra\translator\translator.py:25 msgid "Arabic" msgstr "arapski" -#: ../src\extra\translator\translator.py:16 +#: ../src\extra\translator\translator.py:26 msgid "Armenian" msgstr "jermenski" -#: ../src\extra\translator\translator.py:17 +#: ../src\extra\translator\translator.py:27 msgid "Azerbaijani" msgstr "azerbejdžanski" -#: ../src\extra\translator\translator.py:18 +#: ../src\extra\translator\translator.py:28 msgid "Basque" msgstr "Baskijski" -#: ../src\extra\translator\translator.py:19 +#: ../src\extra\translator\translator.py:29 msgid "Belarusian" msgstr "Beloruski" -#: ../src\extra\translator\translator.py:20 +#: ../src\extra\translator\translator.py:30 msgid "Bengali" msgstr "Bengalski" -#: ../src\extra\translator\translator.py:21 +#: ../src\extra\translator\translator.py:31 msgid "Bihari" msgstr "Bihari" -#: ../src\extra\translator\translator.py:22 +#: ../src\extra\translator\translator.py:32 msgid "Bulgarian" msgstr "Bugarski" -#: ../src\extra\translator\translator.py:23 +#: ../src\extra\translator\translator.py:33 msgid "Burmese" msgstr "Burmese" -#: ../src\extra\translator\translator.py:24 +#: ../src\extra\translator\translator.py:34 msgid "Catalan" msgstr "Katalonski" -#: ../src\extra\translator\translator.py:25 +#: ../src\extra\translator\translator.py:35 msgid "Cherokee" msgstr "Cherokee" -#: ../src\extra\translator\translator.py:26 +#: ../src\extra\translator\translator.py:36 msgid "Chinese" msgstr "Kineski" -#: ../src\extra\translator\translator.py:27 +#: ../src\extra\translator\translator.py:37 msgid "Chinese_simplified" msgstr "kineski pojednostavljeni" -#: ../src\extra\translator\translator.py:28 +#: ../src\extra\translator\translator.py:38 msgid "Chinese_traditional" msgstr "kineski tradicionalni" -#: ../src\extra\translator\translator.py:29 +#: ../src\extra\translator\translator.py:39 msgid "Croatian" msgstr "hrvatski" -#: ../src\extra\translator\translator.py:30 +#: ../src\extra\translator\translator.py:40 msgid "Czech" msgstr "češki" -#: ../src\extra\translator\translator.py:32 +#: ../src\extra\translator\translator.py:42 msgid "Dhivehi" msgstr "Dhivehi" -#: ../src\extra\translator\translator.py:35 +#: ../src\extra\translator\translator.py:45 msgid "Esperanto" msgstr "Esperanto" -#: ../src\extra\translator\translator.py:36 +#: ../src\extra\translator\translator.py:46 msgid "Estonian" msgstr "estonski" -#: ../src\extra\translator\translator.py:37 +#: ../src\extra\translator\translator.py:47 msgid "Filipino" msgstr "filipinski" -#: ../src\extra\translator\translator.py:40 +#: ../src\extra\translator\translator.py:50 msgid "Galician" msgstr "galicijski" -#: ../src\extra\translator\translator.py:41 +#: ../src\extra\translator\translator.py:51 msgid "Georgian" msgstr "gruzijski" -#: ../src\extra\translator\translator.py:43 +#: ../src\extra\translator\translator.py:53 msgid "Greek" msgstr "grčki" -#: ../src\extra\translator\translator.py:44 +#: ../src\extra\translator\translator.py:54 msgid "Guarani" msgstr "Guarani" -#: ../src\extra\translator\translator.py:45 +#: ../src\extra\translator\translator.py:55 msgid "Gujarati" msgstr "Gujarati" -#: ../src\extra\translator\translator.py:46 +#: ../src\extra\translator\translator.py:56 msgid "Hebrew" msgstr "jevrejski" -#: ../src\extra\translator\translator.py:47 +#: ../src\extra\translator\translator.py:57 msgid "Hindi" msgstr "indijski" -#: ../src\extra\translator\translator.py:49 +#: ../src\extra\translator\translator.py:59 msgid "Icelandic" msgstr "islandski" -#: ../src\extra\translator\translator.py:50 +#: ../src\extra\translator\translator.py:60 msgid "Indonesian" msgstr "indonežanski" -#: ../src\extra\translator\translator.py:51 +#: ../src\extra\translator\translator.py:61 msgid "Inuktitut" msgstr "Inuktitut" -#: ../src\extra\translator\translator.py:52 +#: ../src\extra\translator\translator.py:62 msgid "Irish" msgstr "irski" -#: ../src\extra\translator\translator.py:55 +#: ../src\extra\translator\translator.py:65 msgid "Kannada" msgstr "Kannada" -#: ../src\extra\translator\translator.py:56 +#: ../src\extra\translator\translator.py:66 msgid "Kazakh" msgstr "Kazakh" -#: ../src\extra\translator\translator.py:57 +#: ../src\extra\translator\translator.py:67 msgid "Khmer" msgstr "Khmer" -#: ../src\extra\translator\translator.py:59 +#: ../src\extra\translator\translator.py:69 msgid "Kurdish" msgstr "kurdski" -#: ../src\extra\translator\translator.py:60 +#: ../src\extra\translator\translator.py:70 msgid "Kyrgyz" msgstr "kirgistanski" -#: ../src\extra\translator\translator.py:61 +#: ../src\extra\translator\translator.py:71 msgid "Laothian" msgstr "Laothian" -#: ../src\extra\translator\translator.py:62 +#: ../src\extra\translator\translator.py:72 msgid "Latvian" msgstr "letonski" -#: ../src\extra\translator\translator.py:63 +#: ../src\extra\translator\translator.py:73 msgid "Lithuanian" msgstr "litvanski" -#: ../src\extra\translator\translator.py:64 +#: ../src\extra\translator\translator.py:74 msgid "Macedonian" msgstr "makedonski" -#: ../src\extra\translator\translator.py:65 +#: ../src\extra\translator\translator.py:75 msgid "Malay" msgstr "Malay" -#: ../src\extra\translator\translator.py:66 +#: ../src\extra\translator\translator.py:76 msgid "Malayalam" msgstr "Malayalam" -#: ../src\extra\translator\translator.py:67 +#: ../src\extra\translator\translator.py:77 msgid "Maltese" msgstr "malteški" -#: ../src\extra\translator\translator.py:68 +#: ../src\extra\translator\translator.py:78 msgid "Marathi" msgstr "Marathi" -#: ../src\extra\translator\translator.py:69 +#: ../src\extra\translator\translator.py:79 msgid "Mongolian" msgstr "mongolski" -#: ../src\extra\translator\translator.py:70 +#: ../src\extra\translator\translator.py:80 msgid "Nepali" msgstr "nepalski" -#: ../src\extra\translator\translator.py:71 +#: ../src\extra\translator\translator.py:81 msgid "Norwegian" msgstr "norveški" -#: ../src\extra\translator\translator.py:72 +#: ../src\extra\translator\translator.py:82 msgid "Oriya" msgstr "Oriya" -#: ../src\extra\translator\translator.py:73 +#: ../src\extra\translator\translator.py:83 msgid "Pashto" msgstr "Pashto" -#: ../src\extra\translator\translator.py:74 +#: ../src\extra\translator\translator.py:84 msgid "Persian" msgstr "persijski" -#: ../src\extra\translator\translator.py:77 +#: ../src\extra\translator\translator.py:87 msgid "Punjabi" msgstr "Punjabi" -#: ../src\extra\translator\translator.py:78 +#: ../src\extra\translator\translator.py:88 msgid "Romanian" msgstr "rumunski" -#: ../src\extra\translator\translator.py:80 +#: ../src\extra\translator\translator.py:90 msgid "Sanskrit" msgstr "Sanskrit" -#: ../src\extra\translator\translator.py:81 +#: ../src\extra\translator\translator.py:91 msgid "Serbian" msgstr "srpski" -#: ../src\extra\translator\translator.py:82 +#: ../src\extra\translator\translator.py:92 msgid "Sindhi" msgstr "Sindhi" -#: ../src\extra\translator\translator.py:83 +#: ../src\extra\translator\translator.py:93 msgid "Sinhalese" msgstr "Sinhalese" -#: ../src\extra\translator\translator.py:84 +#: ../src\extra\translator\translator.py:94 msgid "Slovak" msgstr "slovački" -#: ../src\extra\translator\translator.py:85 +#: ../src\extra\translator\translator.py:95 msgid "Slovenian" msgstr "slovenački" -#: ../src\extra\translator\translator.py:87 +#: ../src\extra\translator\translator.py:97 msgid "Swahili" msgstr "Swahili" -#: ../src\extra\translator\translator.py:88 +#: ../src\extra\translator\translator.py:98 msgid "Swedish" msgstr "švedski" -#: ../src\extra\translator\translator.py:89 +#: ../src\extra\translator\translator.py:99 msgid "Tajik" msgstr "Tajik" -#: ../src\extra\translator\translator.py:90 +#: ../src\extra\translator\translator.py:100 msgid "Tamil" msgstr "Tamil" -#: ../src\extra\translator\translator.py:91 +#: ../src\extra\translator\translator.py:101 msgid "Tagalog" msgstr "Tagalog" -#: ../src\extra\translator\translator.py:92 +#: ../src\extra\translator\translator.py:102 msgid "Telugu" msgstr "Telugu" -#: ../src\extra\translator\translator.py:93 +#: ../src\extra\translator\translator.py:103 msgid "Thai" msgstr "Thai" -#: ../src\extra\translator\translator.py:94 +#: ../src\extra\translator\translator.py:104 msgid "Tibetan" msgstr "tibetanski" -#: ../src\extra\translator\translator.py:96 +#: ../src\extra\translator\translator.py:106 msgid "Ukrainian" msgstr "ukrajinski" -#: ../src\extra\translator\translator.py:97 +#: ../src\extra\translator\translator.py:107 msgid "Urdu" msgstr "Urdu" -#: ../src\extra\translator\translator.py:98 +#: ../src\extra\translator\translator.py:108 msgid "Uzbek" msgstr "uzbekitanski" -#: ../src\extra\translator\translator.py:99 +#: ../src\extra\translator\translator.py:109 msgid "Uighur" msgstr "Uighur" -#: ../src\extra\translator\translator.py:100 +#: ../src\extra\translator\translator.py:110 msgid "Vietnamese" msgstr "vijetnamski" -#: ../src\extra\translator\translator.py:101 +#: ../src\extra\translator\translator.py:111 msgid "Welsh" msgstr "velški" -#: ../src\extra\translator\translator.py:102 +#: ../src\extra\translator\translator.py:112 msgid "Yiddish" msgstr "Yiddish" -#: ../src\extra\translator\wx_ui.py:44 +#: ../src\extra\translator\wx_ui.py:29 msgid "Translate message" msgstr "prevedi poruku" -#: ../src\extra\translator\wx_ui.py:47 +#: ../src\extra\translator\wx_ui.py:32 msgid "Target language" msgstr "Odredišni jezik" -#: ../src\issueReporter\issueReporter.py:30 +#: ../src\issueReporter\issueReporter.py:32 #: ../src\wxUI\dialogs\configuration.py:359 #: ../src\wxUI\dialogs\configuration.py:368 msgid "General" msgstr "opšte" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "always" msgstr "Uvek" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "have not tried" msgstr "Nismo pokušali" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "random" msgstr "slučajno" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "sometimes" msgstr "Ponekad" -#: ../src\issueReporter\issueReporter.py:31 +#: ../src\issueReporter\issueReporter.py:33 msgid "unable to duplicate" msgstr "Ne mogu da dupliram" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "block" msgstr "blokiraj" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "crash" msgstr "pad" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "feature" msgstr "Mogućnost" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "major" msgstr "glavno" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "minor" msgstr "sporedno" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "text" msgstr "tekst" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "trivial" msgstr "beznačajno" -#: ../src\issueReporter\issueReporter.py:32 +#: ../src\issueReporter\issueReporter.py:34 msgid "tweak" msgstr "podešavanje" -#: ../src\issueReporter\wx_ui.py:25 +#: ../src\issueReporter\wx_ui.py:26 msgid "Report an error" msgstr "Prijavi grešku" -#: ../src\issueReporter\wx_ui.py:28 +#: ../src\issueReporter\wx_ui.py:29 msgid "Select a category" msgstr "Izaberite vrstu" -#: ../src\issueReporter\wx_ui.py:36 +#: ../src\issueReporter\wx_ui.py:37 msgid "" "Briefly describe what happened. You will be able to thoroughly explain it " "later" @@ -1442,19 +1445,19 @@ msgstr "" "Ukratko objasnite šta se dogodilo. Bićete u mogućnosti da iznesete više " "pojedinosti kasnije." -#: ../src\issueReporter\wx_ui.py:45 +#: ../src\issueReporter\wx_ui.py:46 msgid "Here, you can describe the bug in detail" msgstr "Ovde, možete opisati sve pojedinosti greške." -#: ../src\issueReporter\wx_ui.py:55 +#: ../src\issueReporter\wx_ui.py:56 msgid "how often does this bug happen?" msgstr "Koliko se često ova greška dešava?" -#: ../src\issueReporter\wx_ui.py:62 +#: ../src\issueReporter\wx_ui.py:63 msgid "Select the importance that you think this bug has" msgstr "Izaberite važnost greške" -#: ../src\issueReporter\wx_ui.py:69 +#: ../src\issueReporter\wx_ui.py:70 msgid "" "I know that the {0} bug system will get my Twitter username to contact me " "and fix the bug quickly" @@ -1462,20 +1465,20 @@ msgstr "" "Znam da će {0} sistem za prijavljivanje grešaka imati moje Twitter " "korisničko ime za kontakt i popraviti grešku brzo" -#: ../src\issueReporter\wx_ui.py:72 +#: ../src\issueReporter\wx_ui.py:73 msgid "Send report" msgstr "Pošalji izveštaj" -#: ../src\issueReporter\wx_ui.py:74 ../src\wxUI\dialogs\filterDialogs.py:83 -#: ../src\wxUI\dialogs\find.py:22 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 +#: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "Otkaži" -#: ../src\issueReporter\wx_ui.py:83 +#: ../src\issueReporter\wx_ui.py:84 msgid "You must fill out both fields" msgstr "Morate ispuniti oba polja." -#: ../src\issueReporter\wx_ui.py:86 +#: ../src\issueReporter\wx_ui.py:87 msgid "" "You need to mark the checkbox to provide us your twitter username to contact " "you if it is necessary." @@ -1483,7 +1486,7 @@ msgstr "" "Morate označiti kvadratić u kome prihvatate da nam pošaljete vaše twitter " "korisničko ime, kako bi vas kontaktirali ako je to neophodno." -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "" "Thanks for reporting this bug! In future versions, you may be able to find " "it in the changes list. You've reported the bug number %i" @@ -1491,15 +1494,15 @@ msgstr "" "Hvala vam što ste prijavili ovu grešku! U narednim verzijama, videćete " "ispravku na spisku promena. Prijavili ste grešku pod brojem %i" -#: ../src\issueReporter\wx_ui.py:89 +#: ../src\issueReporter\wx_ui.py:90 msgid "reported" msgstr "Prijavljeno" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "Error while reporting" msgstr "Greška prilikom prijavljivanja" -#: ../src\issueReporter\wx_ui.py:93 +#: ../src\issueReporter\wx_ui.py:94 msgid "" "Something unexpected occurred while trying to report the bug. Please, try " "again later" @@ -1539,8 +1542,8 @@ msgstr "Prikaži ili sakrij okruženje" msgid "New tweet" msgstr "Novi tvit" -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\commonMessageDialogs.py:9 ../src\wxUI\dialogs\message.py:126 +#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "Retvituj" @@ -1553,9 +1556,8 @@ msgid "Like a tweet" msgstr "Označi tvit sa sviđa mi se" #: ../src\keystrokeEditor\constants.py:15 -#, fuzzy msgid "Like/unlike a tweet" -msgstr "Označi tvit sa ne sviđa mi se" +msgstr "Označi da ti se tvit sviđa / ne sviđa" #: ../src\keystrokeEditor\constants.py:16 msgid "Unlike a tweet" @@ -1594,9 +1596,8 @@ msgid "Open URL" msgstr "Otvori vezu" #: ../src\keystrokeEditor\constants.py:25 -#, fuzzy msgid "View in Twitter" -msgstr "Pretraži ttwitter" +msgstr "Prikaži na Twitteru" #: ../src\keystrokeEditor\constants.py:26 msgid "Increase volume by 5%" @@ -1715,9 +1716,8 @@ msgid "Opens the global settings dialogue" msgstr "Otvara dijalog globalnih podešavanja" #: ../src\keystrokeEditor\constants.py:54 -#, fuzzy msgid "Opens the list manager" -msgstr "Upravljanje listama" +msgstr "Otvara upravljanje listama" #: ../src\keystrokeEditor\constants.py:55 msgid "Opens the account settings dialogue" @@ -1735,6 +1735,10 @@ msgstr "Ažurira kanal i preuzima moguće izgubljene stavke." msgid "Extracts the text from a picture and displays the result in a dialog." msgstr "Izdvaja tekst iz slike i prikazuje rezultat u dijaloškom prozoru." +#: ../src\keystrokeEditor\constants.py:59 +msgid "Adds an alias to an user" +msgstr "Dodaje nadimak za korisnika" + #: ../src\keystrokeEditor\wx_ui.py:8 msgid "Keystroke editor" msgstr "Uređivač prečica" @@ -1747,63 +1751,76 @@ msgstr "Izaberite prečicu koju želite da izmenite" msgid "Keystroke" msgstr "Prečica" -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:9 -#: ../src\wxUI\dialogs\userActions.py:18 ../src\wxUI\dialogs\userActions.py:19 +#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:10 +#: ../src\wxUI\dialogs\userActions.py:19 ../src\wxUI\dialogs\userActions.py:20 msgid "Action" msgstr "Radnja" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:130 -#: ../src\wxUI\dialogs\lists.py:19 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 +#: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "Izmeni" -#: ../src\keystrokeEditor\wx_ui.py:20 +#: ../src\keystrokeEditor\wx_ui.py:20 ../src\keystrokeEditor\wx_ui.py:50 +msgid "Undefine keystroke" +msgstr "Izbriši prečicu" + +#: ../src\keystrokeEditor\wx_ui.py:21 msgid "Execute action" msgstr "Izvrši radnju" -#: ../src\keystrokeEditor\wx_ui.py:21 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\utils.py:38 +#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 +#: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 msgid "Close" msgstr "Zatvori" -#: ../src\keystrokeEditor\wx_ui.py:48 +#: ../src\keystrokeEditor\wx_ui.py:42 +msgid "Undefined" +msgstr "Izbrisana" + +#: ../src\keystrokeEditor\wx_ui.py:50 +msgid "Are you sure you want to undefine this keystroke?" +msgstr "Da li zaista želite da izbrišete ovu prečicu?" + +#: ../src\keystrokeEditor\wx_ui.py:54 msgid "Editing keystroke" msgstr "Uređujem prečicu" -#: ../src\keystrokeEditor\wx_ui.py:51 +#: ../src\keystrokeEditor\wx_ui.py:57 msgid "Control" msgstr "Control" -#: ../src\keystrokeEditor\wx_ui.py:52 +#: ../src\keystrokeEditor\wx_ui.py:58 msgid "Alt" msgstr "Alt" -#: ../src\keystrokeEditor\wx_ui.py:53 +#: ../src\keystrokeEditor\wx_ui.py:59 msgid "Shift" msgstr "Shift" -#: ../src\keystrokeEditor\wx_ui.py:54 +#: ../src\keystrokeEditor\wx_ui.py:60 msgid "Windows" msgstr "Windows" -#: ../src\keystrokeEditor\wx_ui.py:60 +#: ../src\keystrokeEditor\wx_ui.py:66 msgid "Key" msgstr "Taster" -#: ../src\keystrokeEditor\wx_ui.py:65 ../src\wxUI\dialogs\filterDialogs.py:81 -#: ../src\wxUI\dialogs\find.py:20 ../src\wxUI\dialogs\utils.py:35 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 +#: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 +#: ../src\wxUI\dialogs\utils.py:36 msgid "OK" msgstr "U redu" -#: ../src\keystrokeEditor\wx_ui.py:78 +#: ../src\keystrokeEditor\wx_ui.py:84 msgid "You need to use the Windows key" msgstr "Morate koristiti Windows taster" -#: ../src\keystrokeEditor\wx_ui.py:78 ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:84 ../src\keystrokeEditor\wx_ui.py:87 msgid "Invalid keystroke" msgstr "Pogrešna prečica" -#: ../src\keystrokeEditor\wx_ui.py:81 +#: ../src\keystrokeEditor\wx_ui.py:87 msgid "You must provide a character for the keystroke" msgstr "Morate omogućiti znak u prečici" @@ -1811,54 +1828,58 @@ msgstr "Morate omogućiti znak u prečici" msgid "User default" msgstr "Podrazumevano" -#: ../src\main.py:105 +#: ../src\main.py:120 msgid "https://twblue.es/donate" msgstr "https://twblue.es/donate" -#: ../src\main.py:122 +#: ../src\main.py:137 msgid "" "{0} is already running. Close the other instance before starting this one. " "If you're sure that {0} isn't running, try deleting the file at {1}. If " "you're unsure of how to do this, contact the {0} developers." msgstr "" +"{0} je već pokrenut. Zatvorite druge pokrenute prozore aplikacije pre " +"pokretanja ovog. Ako ste sigurni da {0} nije pokrenut, pokušajte da obrišete " +"datoteku koja se nalazi na {1}. Ako niste sigurni kako ovo da uradite, " +"kontaktirajte {0} programere." -#: ../src\sessionmanager\wxUI.py:8 +#: ../src\sessionmanager\wxUI.py:9 msgid "Session manager" msgstr "Upravljanje sesijama" -#: ../src\sessionmanager\wxUI.py:11 +#: ../src\sessionmanager\wxUI.py:12 msgid "Accounts list" msgstr "Lista naloga" -#: ../src\sessionmanager\wxUI.py:13 +#: ../src\sessionmanager\wxUI.py:14 msgid "Account" msgstr "Nalog" -#: ../src\sessionmanager\wxUI.py:17 +#: ../src\sessionmanager\wxUI.py:18 msgid "New account" msgstr "Novi nalog" -#: ../src\sessionmanager\wxUI.py:18 ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:19 ../src\sessionmanager\wxUI.py:65 msgid "Remove account" msgstr "Ukloni nalog" -#: ../src\sessionmanager\wxUI.py:19 +#: ../src\sessionmanager\wxUI.py:20 msgid "Global Settings" msgstr "Globalna podešavanja" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "Account Error" msgstr "Greška naloga" -#: ../src\sessionmanager\wxUI.py:42 +#: ../src\sessionmanager\wxUI.py:43 msgid "You need to configure an account." msgstr "Morate podesiti nalog." -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "Authorization" msgstr "Autorizacija" -#: ../src\sessionmanager\wxUI.py:48 +#: ../src\sessionmanager\wxUI.py:49 msgid "" "The request to authorize your Twitter account will be opened in your " "browser. You only need to do this once. Would you like to continue?" @@ -1866,15 +1887,15 @@ msgstr "" "Zahtev za autorizaciju vašeg Twitter naloga će biti otvoren u vašem " "pregledniku. Potrebno je da to uradite samo jednom. Želite li da nastavite?" -#: ../src\sessionmanager\wxUI.py:52 +#: ../src\sessionmanager\wxUI.py:53 msgid "Authorized account %d" msgstr "Autorizovan nalog %d" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "Invalid user token" msgstr "Pogrešan korisnički token" -#: ../src\sessionmanager\wxUI.py:58 +#: ../src\sessionmanager\wxUI.py:59 msgid "" "Your access token is invalid or the authorization has failed. Please try " "again." @@ -1882,30 +1903,66 @@ msgstr "" "Vaš pristupni token je pogrešan ili autorizacija nije uspela. Molimo vas, " "pokušajte ponovo." -#: ../src\sessionmanager\wxUI.py:64 +#: ../src\sessionmanager\wxUI.py:65 msgid "Do you really want to delete this account?" msgstr "Želite li zaista da izbrišete ovaj nalog?" -#: ../src\sessions\twitter\compose.py:39 ../src\sessions\twitter\compose.py:89 -#: ../src\sessions\twitter\compose.py:152 -#: ../src\sessions\twitter\compose.py:161 +#: ../src\sessionmanager\wxUI.py:81 +msgid "Authentication error for session {}" +msgstr "Greška u autentikaciji za sesiju {}" + +#: ../src\sessionmanager\wxUI.py:81 +msgid "" +"TWBlue is unable to authenticate the account for {} in Twitter. It might be " +"due to an invalid or expired token, revoqued access to the application, or " +"after an account reactivation. Please remove the account manually from your " +"Twitter sessions in order to stop seeing this message." +msgstr "" +"TWBlue ne može da izvrši autentikaciju naloga za {} na Twitteru. Ovo se može " +"desiti zbog neispravnog ili isteklog tokena, odbijanja pristupa aplikacije, " +"ili nakon ponovne aktivacije naloga. Molimo ručno uklonite nalog iz vaših " +"Twitter sesija kako biste prestali da dobijate ovu poruku." + +#: ../src\sessions\base.py:113 +msgid "" +"An exception occurred while saving the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Došlo je do greške pri čuvanju {app} baze podataka. Biće obrisana i " +"automatski ponovno napravljena. Ako se ova greška nastavi, pošaljite " +"dnevnike sa greškama {app} programerima." + +#: ../src\sessions\base.py:153 +msgid "" +"An exception occurred while loading the {app} database. It will be deleted " +"and rebuilt automatically. If this error persists, send the error log to the " +"{app} developers." +msgstr "" +"Došlo je do greške pri čuvanju {app} baze podataka. Biće obrisana i " +"automatski ponovno napravljena. Ako se ova greška nastavi, pošaljite " +"dnevnike sa greškama {app} programerima." + +#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 +#: ../src\sessions\twitter\compose.py:146 +#: ../src\sessions\twitter\compose.py:155 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd, MMMM D, YYYY H:m:s" -#: ../src\sessions\twitter\compose.py:97 ../src\sessions\twitter\compose.py:99 +#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 msgid "Dm to %s " msgstr "Direktna poruka za %s " -#: ../src\sessions\twitter\compose.py:141 +#: ../src\sessions\twitter\compose.py:130 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0}. citira tvit od @{1}: {2}" -#: ../src\sessions\twitter\compose.py:163 -#: ../src\sessions\twitter\compose.py:165 +#: ../src\sessions\twitter\compose.py:157 +#: ../src\sessions\twitter\compose.py:159 msgid "Unavailable" msgstr "Nedostupno" -#: ../src\sessions\twitter\compose.py:166 +#: ../src\sessions\twitter\compose.py:160 msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1913,61 +1970,66 @@ msgstr "" "%s (@%s). %s pratilaca, %s prijatelja, %s tvitova. Poslednji tvit %s. " "Pridružio se twitteru %s" -#: ../src\sessions\twitter\compose.py:170 +#: ../src\sessions\twitter\compose.py:164 msgid "No description available" msgstr "Opis nije dostupan" -#: ../src\sessions\twitter\compose.py:174 +#: ../src\sessions\twitter\compose.py:168 msgid "private" msgstr "Privatno" -#: ../src\sessions\twitter\compose.py:175 +#: ../src\sessions\twitter\compose.py:169 msgid "public" msgstr "Javno" -#: ../src\sessions\twitter\session.py:169 -#, fuzzy -msgid "There are no more items to retrieve in this buffer." -msgstr "Nema koordinata u ovom tvitu." - -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" msgstr "%s nije uspelo. Razlog: %s" -#: ../src\sessions\twitter\session.py:221 +#: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%s uspelo." -#: ../src\sessions\twitter\utils.py:225 +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 +msgid "Deleted account" +msgstr "Obrisan nalog" + +#: ../src\sessions\twitter\utils.py:231 msgid "Sorry, you are not authorised to see this status." msgstr "Izvinite, nije vam dozvoljeno da vidite ovaj status." -#: ../src\sessions\twitter\utils.py:227 +#: ../src\sessions\twitter\utils.py:233 msgid "No status found with that ID" msgstr "Status nije pronađen pod tim brojem." -#: ../src\sessions\twitter\utils.py:229 -msgid "Error code {0}" -msgstr "Kod greške {0}" +#: ../src\sessions\twitter\utils.py:235 +msgid "Error {0}" +msgstr "Greška {0}" -#: ../src\sessions\twitter\wxUI.py:6 -#, fuzzy +#: ../src\sessions\twitter\utils.py:262 +msgid "{user_1}, {user_2} and {all_users} more: {text}" +msgstr "{user_1}, {user_2} i još {all_users} korisnika: {text}" + +#: ../src\sessions\twitter\wxUI.py:7 msgid "Authorising account..." -msgstr "Autorizovan nalog %d" +msgstr "Autorizacija naloga..." -#: ../src\sessions\twitter\wxUI.py:9 +#: ../src\sessions\twitter\wxUI.py:10 msgid "Enter your PIN code here" -msgstr "" +msgstr "Ovde upišite vaš PIN kod" -#: ../src\sound.py:159 +#: ../src\sound.py:160 msgid "Stopped." msgstr "Zaustavljeno" -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "New version for %s" msgstr "Nova verzija za %s" -#: ../src\update\wxUpdater.py:10 +#: ../src\update\wxUpdater.py:14 msgid "" "There's a new %s version available, released on %s. Would you like to " "download it now?\n" @@ -1984,84 +2046,86 @@ msgstr "" "Promene:\n" "%s" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Download in Progress" msgstr "Preuzimanje u toku" -#: ../src\update\wxUpdater.py:18 +#: ../src\update\wxUpdater.py:22 msgid "Downloading the new version..." msgstr "Preuzimam novu verziju..." -#: ../src\update\wxUpdater.py:28 +#: ../src\update\wxUpdater.py:32 msgid "Updating... %s of %s" msgstr "Ažuriram... %s od %s" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "Done!" msgstr "Dovršeno" -#: ../src\update\wxUpdater.py:31 +#: ../src\update\wxUpdater.py:35 msgid "" "The update has been downloaded and installed successfully. Press OK to " "continue." msgstr "" "Ažuriranje je preuzeto i uspešno instalirano. Pritisnite u redu za nastavak." -#: ../src\wxUI\buffers\base.py:11 +#: ../src\wxUI\buffers\base.py:12 msgid "Client" msgstr "Klijent" -#: ../src\wxUI\buffers\base.py:11 -msgid "Text" -msgstr "Tekst" - -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "Datum" -#: ../src\wxUI\buffers\base.py:11 ../src\wxUI\buffers\people.py:11 -#: ../src\wxUI\buffers\user_searches.py:10 -#: ../src\wxUI\dialogs\userSelection.py:10 ../src\wxUI\dialogs\utils.py:31 +#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\people.py:12 +#: ../src\wxUI\buffers\user_searches.py:11 +#: ../src\wxUI\dialogs\userAliasDialogs.py:14 +#: ../src\wxUI\dialogs\userSelection.py:11 ../src\wxUI\dialogs\utils.py:32 msgid "User" msgstr "Korisnik" -#: ../src\wxUI\buffers\base.py:27 +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "Tekst" + +#: ../src\wxUI\buffers\base.py:28 msgid "Direct message" msgstr "Direktna poruka" -#: ../src\wxUI\buffers\events.py:13 +#: ../src\wxUI\buffers\events.py:14 msgid "Event" msgstr "Događaj" -#: ../src\wxUI\buffers\events.py:15 +#: ../src\wxUI\buffers\events.py:16 msgid "Remove event" msgstr "Ukloni događaj" -#: ../src\wxUI\buffers\panels.py:11 ../src\wxUI\buffers\panels.py:19 +#: ../src\wxUI\buffers\panels.py:12 ../src\wxUI\buffers\panels.py:20 msgid "Login" msgstr "Prijavi se" -#: ../src\wxUI\buffers\panels.py:13 +#: ../src\wxUI\buffers\panels.py:14 msgid "Log in automatically" msgstr "Prijavi se automatski" -#: ../src\wxUI\buffers\panels.py:21 +#: ../src\wxUI\buffers\panels.py:22 msgid "Logout" msgstr "Odjavi se" -#: ../src\wxUI\buffers\trends.py:8 +#: ../src\wxUI\buffers\trends.py:9 msgid "Trending topic" msgstr "Tema trenda" -#: ../src\wxUI\buffers\trends.py:18 +#: ../src\wxUI\buffers\trends.py:19 msgid "Tweet about this trend" msgstr "Tvituj o ovom trendu" -#: ../src\wxUI\buffers\trends.py:19 ../src\wxUI\menus.py:96 +#: ../src\wxUI\buffers\trends.py:20 ../src\wxUI\menus.py:97 msgid "Search topic" -msgstr "tema Pretrage" +msgstr "Pretraži temu" -#: ../src\wxUI\commonMessageDialogs.py:6 +#: ../src\wxUI\commonMessageDialogs.py:7 msgid "" "This retweet is over 140 characters. Would you like to post it as a mention " "to the poster with your comments and a link to the original tweet?" @@ -2069,11 +2133,11 @@ msgstr "" "Ovaj retvit ima preko 140 znakova. Želite li da pošaljete to kao spominjanje " "na pošiljaoca sa vašim komentarom i linkom do izvornog tvita?" -#: ../src\wxUI\commonMessageDialogs.py:9 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Would you like to add a comment to this tweet?" msgstr "Želite li da dodate komentar na ovaj tvit?" -#: ../src\wxUI\commonMessageDialogs.py:12 +#: ../src\wxUI\commonMessageDialogs.py:13 msgid "" "Do you really want to delete this tweet? It will be deleted from Twitter as " "well." @@ -2081,27 +2145,27 @@ msgstr "" "Želite li zaista da izbrišete ovaj tvit? On će biti izbrisan sa Twitera " "takođe." -#: ../src\wxUI\commonMessageDialogs.py:12 ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\commonMessageDialogs.py:13 ../src\wxUI\dialogs\lists.py:149 msgid "Delete" msgstr "Izbriši" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Do you really want to close {0}?" msgstr "Želite li stvarno da zatvorite {0}?" -#: ../src\wxUI\commonMessageDialogs.py:15 +#: ../src\wxUI\commonMessageDialogs.py:16 msgid "Exit" msgstr "Izlaz" -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid " {0} must be restarted for these changes to take effect." msgstr " {0} se mora ponovo pokrenuti kako bi ove promene stupile na snagu." -#: ../src\wxUI\commonMessageDialogs.py:19 +#: ../src\wxUI\commonMessageDialogs.py:20 msgid "Restart {0} " msgstr "Ponovo pokreni {0} " -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "" "Are you sure you want to delete this user from the database? This user will " "not appear in autocomplete results anymore." @@ -2110,20 +2174,20 @@ msgstr "" "Ovaj korisnik se više neće pojavljivati u rezultatima automatskog " "dovršavanja." -#: ../src\wxUI\commonMessageDialogs.py:22 +#: ../src\wxUI\commonMessageDialogs.py:23 msgid "Confirm" msgstr "Potvrdi" -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 msgid "Enter the name of the client : " msgstr "Unesite ime klijenta" -#: ../src\wxUI\commonMessageDialogs.py:25 +#: ../src\wxUI\commonMessageDialogs.py:26 #: ../src\wxUI\dialogs\configuration.py:246 msgid "Add client" msgstr "Dodaj program" -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "" "Do you really want to empty this buffer? It's items will be removed from " "the list but not from Twitter" @@ -2131,35 +2195,35 @@ msgstr "" "Želite li zaista da očistite ovaj kanal? Njegove stavke će biti uklonjene sa " "kanala, ali ne i sa twittera." -#: ../src\wxUI\commonMessageDialogs.py:31 +#: ../src\wxUI\commonMessageDialogs.py:32 msgid "Empty buffer" msgstr "Očisti kanal" -#: ../src\wxUI\commonMessageDialogs.py:35 +#: ../src\wxUI\commonMessageDialogs.py:36 msgid "Do you really want to destroy this buffer?" msgstr "Želite li zaista da izbrišete ovaj kanal?" -#: ../src\wxUI\commonMessageDialogs.py:35 -#: ../src\wxUI\commonMessageDialogs.py:85 +#: ../src\wxUI\commonMessageDialogs.py:36 +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Attention" msgstr "Pažnja" -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "A timeline for this user already exists. You can't open another" msgstr "" "Vremenska linija za tog korisnika već postoji. Ne možete otvoriti još jednu." -#: ../src\wxUI\commonMessageDialogs.py:41 +#: ../src\wxUI\commonMessageDialogs.py:42 msgid "Existing timeline" msgstr "Postojeća vremenska linija." -#: ../src\wxUI\commonMessageDialogs.py:44 +#: ../src\wxUI\commonMessageDialogs.py:45 msgid "This user has no tweets, so you can't open a timeline for them." msgstr "" "Ovaj korisnik nema nijedan tvit, te s toga ne možete otvoriti njegovu " "vremensku liniju." -#: ../src\wxUI\commonMessageDialogs.py:47 +#: ../src\wxUI\commonMessageDialogs.py:48 msgid "" "This is a protected Twitter user, which means you can't open a timeline " "using the Streaming API. The user's tweets will not update due to a twitter " @@ -2169,12 +2233,12 @@ msgstr "" "vremensku liniju koristeći Streaming API. Tvitovi korisnika neće biti " "ažurirani zbog politike tvitera. Želite li da nastavite??" -#: ../src\wxUI\commonMessageDialogs.py:47 -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:48 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "Warning" msgstr "Upozorenje" -#: ../src\wxUI\commonMessageDialogs.py:50 +#: ../src\wxUI\commonMessageDialogs.py:51 msgid "" "This is a protected user account, you need to follow this user to view their " "tweets or likes." @@ -2182,7 +2246,7 @@ msgstr "" "Ovaj korisnik je zaštitio svoj nalog. Morate ga zapratiti kako bi videli " "njegove tvitove ili omiljene stvari." -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "" "If you like {0} we need your help to keep it going. Help us by donating to " "the project. This will help us pay for the server, the domain and some other " @@ -2196,42 +2260,42 @@ msgstr "" "motivaciju da nastavimo sa razvojem {0}, i da sačuvamo {0} besplatnim. " "Želite li da donirate sada?" -#: ../src\wxUI\commonMessageDialogs.py:53 +#: ../src\wxUI\commonMessageDialogs.py:54 msgid "We need your help" msgstr "Potrebna nam je vaša pomoć" -#: ../src\wxUI\commonMessageDialogs.py:57 +#: ../src\wxUI\commonMessageDialogs.py:58 msgid "This user has no tweets. {0} can't create a timeline." msgstr "Ovaj korisnik nema tvitove. {0} ne može da napravi vremensku liniju." -#: ../src\wxUI\commonMessageDialogs.py:60 +#: ../src\wxUI\commonMessageDialogs.py:61 msgid "This user has no favorited tweets. {0} can't create a timeline." msgstr "" "Ovaj korisnik nema omiljenih tvitova. {0} ne može da napravi vremensku " "liniju." -#: ../src\wxUI\commonMessageDialogs.py:63 +#: ../src\wxUI\commonMessageDialogs.py:64 msgid "This user has no followers. {0} can't create a timeline." msgstr "Ovog korisnika niko ne prati. {0} ne može da kreira vremensku liniju." -#: ../src\wxUI\commonMessageDialogs.py:66 +#: ../src\wxUI\commonMessageDialogs.py:67 msgid "This user has no friends. {0} can't create a timeline." msgstr "" "Ovaj korisnik nema prijatelje. {0} ne može da napravi vremensku liniju." -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geo data for this tweet" msgstr "Geografski podaci o ovom tvitu" -#: ../src\wxUI\commonMessageDialogs.py:70 +#: ../src\wxUI\commonMessageDialogs.py:71 msgid "Geolocation data: {0}" msgstr "Podaci o geografskoj lokaciji: {0}" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "Information" msgstr "Informacija" -#: ../src\wxUI\commonMessageDialogs.py:73 +#: ../src\wxUI\commonMessageDialogs.py:74 msgid "" "TWBlue has detected that you're running windows 10 and has changed the " "default keymap to the Windows 10 keymap. It means that some keyboard " @@ -2241,14 +2305,14 @@ msgstr "" "TWBlue je otkrio da koristite windows 10 i promenio je podrazumevane " "tasterske prečice na Windows 10 način rada. To znači da neke tasterske " "prečice mogu biti drugačije. Molimo vas da proverite uređivač tasterskih " -"prečica pritiskanjem Alt+Win+K i pogledate sve dostupne prečice za ovja " +"prečica pritiskanjem Alt+Win+K i pogledate sve dostupne prečice za ovaj " "način rada." -#: ../src\wxUI\commonMessageDialogs.py:76 +#: ../src\wxUI\commonMessageDialogs.py:77 msgid "You have been blocked from viewing this content" msgstr "Blokirani ste i ne možete videti ovaj sadržaj." -#: ../src\wxUI\commonMessageDialogs.py:79 +#: ../src\wxUI\commonMessageDialogs.py:80 msgid "" "You have been blocked from viewing someone's content. In order to avoid " "conflicts with the full session, TWBlue will remove the affected timeline." @@ -2257,7 +2321,7 @@ msgstr "" "izbegli konflikte sa sesijom, TWBlue će ukloniti vremensku liniju na koju " "ovo utiče." -#: ../src\wxUI\commonMessageDialogs.py:82 +#: ../src\wxUI\commonMessageDialogs.py:83 msgid "" "TWBlue cannot load this timeline because the user has been suspended from " "Twitter." @@ -2265,162 +2329,114 @@ msgstr "" "TWBlue ne može da učita ovu vremensku liniju zbog toga što je korisnik " "suspendovan sa tvitera." -#: ../src\wxUI\commonMessageDialogs.py:85 -#, fuzzy +#: ../src\wxUI\commonMessageDialogs.py:86 msgid "Do you really want to delete this filter?" -msgstr "Želite li zaista da izbrišete ovu listu?" +msgstr "Da li zaista želite da izbrišete ovaj filter?" -#: ../src\wxUI\commonMessageDialogs.py:88 +#: ../src\wxUI\commonMessageDialogs.py:89 msgid "This filter already exists. Please use a different title" -msgstr "" +msgstr "Ovaj filter već postoji. Molimo koristite drugi naziv" -#: ../src\wxUI\commonMessageDialogs.py:94 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." msgstr "" +"{0} je neočekivano zatvoren pri poslednjem pokretanju. Ako se problem " +"nastavi, molimo prijavite ga{0} programerima." -#: ../src\wxUI\dialogs\attach.py:9 -msgid "Add an attachment" -msgstr "Dodaj prilog" - -#: ../src\wxUI\dialogs\attach.py:12 -msgid "Attachments" -msgstr "Prilozi" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Title" -msgstr "Naslov" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Type" -msgstr "Vrsta" - -#: ../src\wxUI\dialogs\attach.py:18 -msgid "Add attachments" -msgstr "Dodaj priloge" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "&Photo" -msgstr "Slika" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "Remove attachment" -msgstr "Ukloni prilog" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Datoteke sa slikama" - -#: ../src\wxUI\dialogs\attach.py:36 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:81 -msgid "Select the picture to be uploaded" -msgstr "Izaberite sliku koju želite da otpremite" - -#: ../src\wxUI\dialogs\attach.py:43 -msgid "please provide a description" -msgstr "Molimo vas navedite opis:" - -#: ../src\wxUI\dialogs\attach.py:43 ../src\wxUI\dialogs\lists.py:13 -#: ../src\wxUI\dialogs\lists.py:69 -msgid "Description" -msgstr "Opis" - -#: ../src\wxUI\dialogs\configuration.py:16 +#: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "Jezik" -#: ../src\wxUI\dialogs\configuration.py:23 +#: ../src\wxUI\dialogs\configuration.py:22 msgid "Run {0} at Windows startup" msgstr "Pokreni {0} prilikom pokretanja Windowsa" -#: ../src\wxUI\dialogs\configuration.py:24 +#: ../src\wxUI\dialogs\configuration.py:23 msgid "ask before exiting {0}" msgstr "Pitaj pre zatvaranja {0}" -#: ../src\wxUI\dialogs\configuration.py:27 +#: ../src\wxUI\dialogs\configuration.py:26 msgid "Disable Streaming functions" -msgstr "" +msgstr "Onemogući streaming funkcije" -#: ../src\wxUI\dialogs\configuration.py:30 +#: ../src\wxUI\dialogs\configuration.py:29 msgid "Buffer update interval, in minutes" -msgstr "" +msgstr "Interval ažuriranja kanala, u minutima" -#: ../src\wxUI\dialogs\configuration.py:36 +#: ../src\wxUI\dialogs\configuration.py:35 msgid "Play a sound when {0} launches" msgstr "Reprodukuj zvuk kada se {0} pokrene" -#: ../src\wxUI\dialogs\configuration.py:38 +#: ../src\wxUI\dialogs\configuration.py:37 msgid "Speak a message when {0} launches" msgstr "Izgovori poruku kada se {0} pokrene" -#: ../src\wxUI\dialogs\configuration.py:40 +#: ../src\wxUI\dialogs\configuration.py:39 msgid "Use invisible interface's keyboard shortcuts while GUI is visible" msgstr "" "Koristi prečice nevidljivog okruženja dok je grafičko okruženje prikazano" -#: ../src\wxUI\dialogs\configuration.py:42 +#: ../src\wxUI\dialogs\configuration.py:41 msgid "Activate Sapi5 when any other screen reader is not being run" msgstr "Aktiviraj SAPI 5 u slučaju da nijedan čitač ekrana nije pokrenut" -#: ../src\wxUI\dialogs\configuration.py:44 +#: ../src\wxUI\dialogs\configuration.py:43 msgid "Hide GUI on launch" msgstr "Sakrij grafičko okruženje prilikom pokretanja" -#: ../src\wxUI\dialogs\configuration.py:46 +#: ../src\wxUI\dialogs\configuration.py:45 msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" msgstr "" "Koristi Codeofdusk's upravljanje dugim tvitovima (može usporiti performanse " "programa)" -#: ../src\wxUI\dialogs\configuration.py:48 +#: ../src\wxUI\dialogs\configuration.py:47 msgid "Remember state for mention all and long tweet" -msgstr "" +msgstr "Pamti stanje opcija spomeni sve i dug tvit" -#: ../src\wxUI\dialogs\configuration.py:51 +#: ../src\wxUI\dialogs\configuration.py:50 msgid "Keymap" msgstr "Tasterske prečice" -#: ../src\wxUI\dialogs\configuration.py:56 +#: ../src\wxUI\dialogs\configuration.py:55 msgid "Check for updates when {0} launches" msgstr "Proveri postojanje nove verzije kada se {0} pokrene" -#: ../src\wxUI\dialogs\configuration.py:66 +#: ../src\wxUI\dialogs\configuration.py:65 msgid "Proxy type: " msgstr "Vrsta proksija:" -#: ../src\wxUI\dialogs\configuration.py:73 +#: ../src\wxUI\dialogs\configuration.py:72 msgid "Proxy server: " msgstr "Proksi server:" -#: ../src\wxUI\dialogs\configuration.py:79 +#: ../src\wxUI\dialogs\configuration.py:78 msgid "Port: " msgstr "Port:" -#: ../src\wxUI\dialogs\configuration.py:85 +#: ../src\wxUI\dialogs\configuration.py:84 msgid "User: " msgstr "Korisnik:" -#: ../src\wxUI\dialogs\configuration.py:91 +#: ../src\wxUI\dialogs\configuration.py:90 msgid "Password: " msgstr "Lozinka:" -#: ../src\wxUI\dialogs\configuration.py:103 +#: ../src\wxUI\dialogs\configuration.py:102 msgid "Autocompletion settings..." msgstr "Postavke automatskod dovršavanja..." -#: ../src\wxUI\dialogs\configuration.py:105 +#: ../src\wxUI\dialogs\configuration.py:104 msgid "Relative timestamps" msgstr "Relativne vremenske oznake" -#: ../src\wxUI\dialogs\configuration.py:108 +#: ../src\wxUI\dialogs\configuration.py:107 msgid "Items on each API call" msgstr "Stavke po svakom API pozivu" -#: ../src\wxUI\dialogs\configuration.py:114 +#: ../src\wxUI\dialogs\configuration.py:113 msgid "" "Inverted buffers: The newest tweets will be shown at the beginning while the " "oldest at the end" @@ -2428,15 +2444,15 @@ msgstr "" "Okreni kanal: Najnoviji tvitovi će biti prikazani na vrhu a najstariji na " "dnu." -#: ../src\wxUI\dialogs\configuration.py:116 +#: ../src\wxUI\dialogs\configuration.py:115 msgid "Retweet mode" msgstr "Način retvitovanja" -#: ../src\wxUI\dialogs\configuration.py:122 +#: ../src\wxUI\dialogs\configuration.py:121 msgid "Show screen names instead of full names" msgstr "Prikaži Twitter korisničko ime umesto punog imena" -#: ../src\wxUI\dialogs\configuration.py:124 +#: ../src\wxUI\dialogs\configuration.py:123 msgid "" "Number of items per buffer to cache in database (0 to disable caching, blank " "for unlimited)" @@ -2444,20 +2460,28 @@ msgstr "" "Broj stavki po kanalu u bazi podataka (0 za isključivanje memorije, prazno " "za neograničeno)" +#: ../src\wxUI\dialogs\configuration.py:127 +msgid "" +"Load cache for tweets in memory (much faster in big datasets but requires " +"more RAM)" +msgstr "" +"Učitavaj keš za Tvitove iz memorije (dosta brže sa većim količinama podataka " +"ali zahteva više RAM memorije)" + #: ../src\wxUI\dialogs\configuration.py:134 msgid "Enable automatic speech feedback" -msgstr "" +msgstr "Omogući automatske govorne povratne informacije" #: ../src\wxUI\dialogs\configuration.py:136 msgid "Enable automatic Braille feedback" -msgstr "" +msgstr "Omogući automatske povratne informacije na brajevom redu" #: ../src\wxUI\dialogs\configuration.py:144 msgid "Status" msgstr "Status" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "Kanal" @@ -2564,7 +2588,7 @@ msgstr "Proksi" #: ../src\wxUI\dialogs\configuration.py:373 msgid "Feedback" -msgstr "" +msgstr "Povratne informacije" #: ../src\wxUI\dialogs\configuration.py:377 msgid "Buffers" @@ -2582,285 +2606,199 @@ msgstr "Dodaci" msgid "Save" msgstr "Sačuvaj" -#: ../src\wxUI\dialogs\filterDialogs.py:15 -#, fuzzy +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" -msgstr "Stvori kanal trenutnih tema u trendu" +msgstr "Napravi filter za ovaj kanal" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" -msgstr "" +msgstr "Naziv filtera" + +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 +msgid "Filter by word" +msgstr "Filtriraj na osnovu reči" #: ../src\wxUI\dialogs\filterDialogs.py:25 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -msgid "Filter by word" -msgstr "" +msgid "Ignore tweets wich contain the following word" +msgstr "Zanemari tvitove koji sadrže sledeću reč" #: ../src\wxUI\dialogs\filterDialogs.py:26 -msgid "Ignore tweets wich contain the following word" -msgstr "" - -#: ../src\wxUI\dialogs\filterDialogs.py:27 -#, fuzzy msgid "Ignore tweets without the following word" -msgstr "Zanemari tvitove iz ovog klijenta" +msgstr "Zanemari tvitove bez sledeće reči" -#: ../src\wxUI\dialogs\filterDialogs.py:32 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" -msgstr "" +msgstr "Reč" + +#: ../src\wxUI\dialogs\filterDialogs.py:36 +msgid "Allow retweets" +msgstr "Dozvoli retvitove" #: ../src\wxUI\dialogs\filterDialogs.py:37 -#, fuzzy -msgid "Allow retweets" -msgstr "Prikaži tvit" +msgid "Allow quoted tweets" +msgstr "Dozvoli citirane tvitove" #: ../src\wxUI\dialogs\filterDialogs.py:38 -msgid "Allow quoted tweets" -msgstr "" - -#: ../src\wxUI\dialogs\filterDialogs.py:39 -#, fuzzy msgid "Allow replies" -msgstr "Vremenska linija pratilaca" +msgstr "Dozvoli odgovore" -#: ../src\wxUI\dialogs\filterDialogs.py:47 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" -msgstr "" +msgstr "Koristi ovaj termin kao regulara nizraz" + +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 +msgid "Filter by language" +msgstr "Filtriraj na osnovu jezika" #: ../src\wxUI\dialogs\filterDialogs.py:49 -#: ../src\wxUI\dialogs\filterDialogs.py:125 -#, fuzzy -msgid "Filter by language" -msgstr "Izvorni jezik" +msgid "Load tweets in the following languages" +msgstr "Učitaj tvitove na sledećim jezicima" #: ../src\wxUI\dialogs\filterDialogs.py:50 -msgid "Load tweets in the following languages" -msgstr "" +msgid "Ignore tweets in the following languages" +msgstr "Zanemari tvitove na sledećim jezicima" #: ../src\wxUI\dialogs\filterDialogs.py:51 -msgid "Ignore tweets in the following languages" -msgstr "" - -#: ../src\wxUI\dialogs\filterDialogs.py:52 msgid "Don't filter by language" -msgstr "" +msgstr "Ne filtriraj na osnovu jezika" -#: ../src\wxUI\dialogs\filterDialogs.py:63 -#, fuzzy +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" -msgstr "Izvorni jezik" +msgstr "Podržani jezici" -#: ../src\wxUI\dialogs\filterDialogs.py:68 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" -msgstr "" +msgstr "Dodaj izabrani jezik u filter" -#: ../src\wxUI\dialogs\filterDialogs.py:72 -#, fuzzy +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" -msgstr "Izvorni jezik" +msgstr "Izabrani jezici" -#: ../src\wxUI\dialogs\filterDialogs.py:74 -#: ../src\wxUI\dialogs\filterDialogs.py:132 ../src\wxUI\dialogs\lists.py:20 -#: ../src\wxUI\dialogs\lists.py:131 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "Ukloni" -#: ../src\wxUI\dialogs\filterDialogs.py:122 -#, fuzzy +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Ime filtera nedostaje" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Morate upisati ime za filter pre nego što ga napravite." + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" -msgstr "Upravljaj nalozima" +msgstr "Upravljanje filterima" -#: ../src\wxUI\dialogs\filterDialogs.py:124 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" -msgstr "" +msgstr "Filteri" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" -msgstr "" +msgstr "Filter" -#: ../src\wxUI\dialogs\find.py:12 +#: ../src\wxUI\dialogs\find.py:13 msgid "Find in current buffer" msgstr "Pronađi u trenutnom kanalu" -#: ../src\wxUI\dialogs\find.py:13 +#: ../src\wxUI\dialogs\find.py:14 msgid "String" msgstr "Pojam" -#: ../src\wxUI\dialogs\lists.py:10 +#: ../src\wxUI\dialogs\lists.py:11 msgid "Lists manager" msgstr "Upravljanje listama" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "List" msgstr "Lista" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Members" msgstr "Članovi" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "Owner" msgstr "Vlasnik" -#: ../src\wxUI\dialogs\lists.py:13 +#: ../src\wxUI\dialogs\lists.py:14 msgid "mode" msgstr "Način" -#: ../src\wxUI\dialogs\lists.py:18 ../src\wxUI\dialogs\lists.py:61 +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "Opis" + +#: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "Stvori novu listu" -#: ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\lists.py:22 msgid "Open in buffer" msgstr "Otvori u kanalu" -#: ../src\wxUI\dialogs\lists.py:51 +#: ../src\wxUI\dialogs\lists.py:52 msgid "Viewing lists for %s" msgstr "Prikazivanje lista za %s" -#: ../src\wxUI\dialogs\lists.py:52 +#: ../src\wxUI\dialogs\lists.py:53 msgid "Subscribe" msgstr "Prijavi se" -#: ../src\wxUI\dialogs\lists.py:53 +#: ../src\wxUI\dialogs\lists.py:54 msgid "Unsubscribe" msgstr "Odjavi se" -#: ../src\wxUI\dialogs\lists.py:64 +#: ../src\wxUI\dialogs\lists.py:65 msgid "Name (20 characters maximun)" msgstr "Ime, najviše 20 znakova" -#: ../src\wxUI\dialogs\lists.py:74 +#: ../src\wxUI\dialogs\lists.py:75 msgid "Mode" msgstr "Način" -#: ../src\wxUI\dialogs\lists.py:75 +#: ../src\wxUI\dialogs\lists.py:76 msgid "Public" msgstr "Javna" -#: ../src\wxUI\dialogs\lists.py:76 +#: ../src\wxUI\dialogs\lists.py:77 msgid "Private" msgstr "Privatna" -#: ../src\wxUI\dialogs\lists.py:96 +#: ../src\wxUI\dialogs\lists.py:97 msgid "Editing the list %s" msgstr "Uređivanje liste %s" -#: ../src\wxUI\dialogs\lists.py:107 +#: ../src\wxUI\dialogs\lists.py:108 msgid "Select a list to add the user" msgstr "Izaberite listu na koju želite da dodate korisnika" -#: ../src\wxUI\dialogs\lists.py:108 +#: ../src\wxUI\dialogs\lists.py:109 msgid "Add" msgstr "Dodaj" -#: ../src\wxUI\dialogs\lists.py:130 +#: ../src\wxUI\dialogs\lists.py:131 msgid "Select a list to remove the user" msgstr "Izaberite listu sa koje želite da uklonite korisnika" -#: ../src\wxUI\dialogs\lists.py:148 +#: ../src\wxUI\dialogs\lists.py:149 msgid "Do you really want to delete this list?" msgstr "Želite li zaista da izbrišete ovu listu?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "Dug tvit" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "Otpremi sliku..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:430 -msgid "Check &spelling..." -msgstr "Proveri pravopis..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "Priloži zvučni zapis..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Skrati vezu" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:358 ../src\wxUI\dialogs\message.py:431 -msgid "&Expand URL" -msgstr "Proširi vezu" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:433 -msgid "&Translate..." -msgstr "Prevedi..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "&Automatsko dovršavanje" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "Pošalji" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:361 ../src\wxUI\dialogs\message.py:434 -msgid "C&lose" -msgstr "Zatvori" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "Primalac" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "Spomeni sve" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tvit - %i znakova" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Opis slike" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retvitova" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Sviđanja:" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Izvor:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:420 -#, fuzzy -msgid "Date: " -msgstr "Datum" - -#: ../src\wxUI\dialogs\message.py:405 -msgid "View" -msgstr "Vidi" - -#: ../src\wxUI\dialogs\message.py:407 -msgid "Item" -msgstr "Stavka" - -#: ../src\wxUI\dialogs\search.py:13 +#: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "Pretraži ttwitter" -#: ../src\wxUI\dialogs\search.py:14 ../src\wxUI\view.py:19 +#: ../src\wxUI\dialogs\search.py:13 ../src\wxUI\view.py:21 msgid "&Search" msgstr "Pretraži" @@ -2868,7 +2806,7 @@ msgstr "Pretraži" msgid "Tweets" msgstr "Tvitovi" -#: ../src\wxUI\dialogs\search.py:22 +#: ../src\wxUI\dialogs\search.py:22 ../src\wxUI\dialogs\userAliasDialogs.py:43 msgid "Users" msgstr "Korisnici" @@ -2896,418 +2834,748 @@ msgstr "Nedavno" msgid "Popular" msgstr "Popularno" -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:28 -#: ../src\wxUI\dialogs\userActions.py:40 -#: ../src\wxUI\dialogs\userSelection.py:32 +#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:25 +#: ../src\wxUI\dialogs\userActions.py:41 +#: ../src\wxUI\dialogs\userSelection.py:33 msgid "&OK" msgstr "U redu" -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:18 -#: ../src\wxUI\dialogs\trends.py:30 ../src\wxUI\dialogs\update_profile.py:36 -#: ../src\wxUI\dialogs\userActions.py:42 -#: ../src\wxUI\dialogs\userSelection.py:34 +#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:19 +#: ../src\wxUI\dialogs\trends.py:27 ../src\wxUI\dialogs\update_profile.py:37 +#: ../src\wxUI\dialogs\userActions.py:43 +#: ../src\wxUI\dialogs\userSelection.py:35 msgid "&Close" msgstr "Zatvori" -#: ../src\wxUI\dialogs\show_user.py:11 +#: ../src\wxUI\dialogs\show_user.py:12 msgid "Details" msgstr "Pojedoinosti" -#: ../src\wxUI\dialogs\show_user.py:16 +#: ../src\wxUI\dialogs\show_user.py:17 msgid "&Go to URL" msgstr "Idi na vezu" -#: ../src\wxUI\dialogs\trends.py:12 +#: ../src\wxUI\dialogs\trends.py:10 msgid "View trending topics" msgstr "Pogledaj teme u trendu" -#: ../src\wxUI\dialogs\trends.py:13 +#: ../src\wxUI\dialogs\trends.py:11 msgid "Trending topics by" msgstr "Teme u trendu po" -#: ../src\wxUI\dialogs\trends.py:15 +#: ../src\wxUI\dialogs\trends.py:12 msgid "Country" msgstr "Zemlji" -#: ../src\wxUI\dialogs\trends.py:16 +#: ../src\wxUI\dialogs\trends.py:13 msgid "City" msgstr "Gradu" -#: ../src\wxUI\dialogs\trends.py:22 ../src\wxUI\dialogs\update_profile.py:17 +#: ../src\wxUI\dialogs\trends.py:19 ../src\wxUI\dialogs\update_profile.py:18 msgid "&Location" msgstr "Mesto" -#: ../src\wxUI\dialogs\update_profile.py:9 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "Prilozi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "Vrsta" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "Ukloni prilog" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "Dodati tvitovi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "Obriši tvit" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "&Dodaj..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "Dodaj t&vit" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "Priloži zvučni zapis..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "&Automatsko dovršavanje" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "Proveri pravopis..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "&Prevedi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "Pošalji" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "Slika" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "Video" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "Anketa" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "Molimo vas navedite opis:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Datoteke sa slikama" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Izaberite sliku koju želite da otpremite" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "Izaberite video zapis koji želite da otpremite" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Datoteke video zapisa (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "Greška pri dodavanju priloga" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"Nije moguće dodati više priloga. Molimo uverite se da vaš tvit poštuje " +"Twitter pravila o prilozima. Možete dodati samo jedan video ili GIF u svaki " +"tvit, i najviše 4 slike." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "Spomeni sve" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "Primalac" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "Tvit - %i znakova" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "Opis slike" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "Retvitova" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "Sviđanja:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "Izvor:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "Datum:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "Kopiraj link u privremenu memoriju" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "Prevedi..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "Zatvori" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "Vidi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "Stavka" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "Proširi vezu" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "Dodaj anketu" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "Vreme učešća (u danima)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "Opcije" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "Opcija 1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "Opcija 2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "Opcija 3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "Opcija 4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "Nema dovoljno informacija" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "Molimo uverite se da ste ponudili bar dve opcije u anketi." + +#: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "Ažurirajte vaš profil" -#: ../src\wxUI\dialogs\update_profile.py:11 -#, fuzzy +#: ../src\wxUI\dialogs\update_profile.py:12 msgid "&Name (50 characters maximum)" -msgstr "Ime, najviše 20 znakova" +msgstr "&Ime(najviše 50 znakova)" -#: ../src\wxUI\dialogs\update_profile.py:22 +#: ../src\wxUI\dialogs\update_profile.py:23 msgid "&Website" msgstr "Web:" -#: ../src\wxUI\dialogs\update_profile.py:27 +#: ../src\wxUI\dialogs\update_profile.py:28 msgid "&Bio (160 characters maximum)" msgstr "Biografija, najviše 160 znakova" -#: ../src\wxUI\dialogs\update_profile.py:33 +#: ../src\wxUI\dialogs\update_profile.py:34 msgid "Upload a &picture" msgstr "Otpremi sliku" -#: ../src\wxUI\dialogs\update_profile.py:34 ../src\wxUI\view.py:17 +#: ../src\wxUI\dialogs\update_profile.py:35 ../src\wxUI\view.py:19 msgid "&Update profile" msgstr "Ažuriraj profil" -#: ../src\wxUI\dialogs\update_profile.py:76 +#: ../src\wxUI\dialogs\update_profile.py:77 msgid "Upload a picture" msgstr "Otpremi sliku" -#: ../src\wxUI\dialogs\update_profile.py:78 +#: ../src\wxUI\dialogs\update_profile.py:79 msgid "Discard image" msgstr "Odbaci sliku" -#: ../src\wxUI\dialogs\urlList.py:5 +#: ../src\wxUI\dialogs\urlList.py:6 msgid "Select URL" msgstr "Izaberite vezu" -#: ../src\wxUI\dialogs\userActions.py:10 ../src\wxUI\view.py:83 +#: ../src\wxUI\dialogs\userActions.py:11 ../src\wxUI\view.py:87 msgid "&User" msgstr "Korisnik" -#: ../src\wxUI\dialogs\userActions.py:13 -#: ../src\wxUI\dialogs\userSelection.py:13 ../src\wxUI\dialogs\utils.py:30 +#: ../src\wxUI\dialogs\userActions.py:14 +#: ../src\wxUI\dialogs\userAliasDialogs.py:13 +#: ../src\wxUI\dialogs\userSelection.py:14 ../src\wxUI\dialogs\utils.py:31 msgid "&Autocomplete users" msgstr "&Automatsko dovršavanje" -#: ../src\wxUI\dialogs\userActions.py:19 +#: ../src\wxUI\dialogs\userActions.py:20 msgid "&Follow" msgstr "Prati" -#: ../src\wxUI\dialogs\userActions.py:20 +#: ../src\wxUI\dialogs\userActions.py:21 msgid "U&nfollow" msgstr "Otprati" -#: ../src\wxUI\dialogs\userActions.py:21 ../src\wxUI\view.py:59 +#: ../src\wxUI\dialogs\userActions.py:22 ../src\wxUI\view.py:63 msgid "&Mute" msgstr "Utišaj" -#: ../src\wxUI\dialogs\userActions.py:22 +#: ../src\wxUI\dialogs\userActions.py:23 msgid "Unmu&te" msgstr "Ukloni utišavanje" -#: ../src\wxUI\dialogs\userActions.py:23 +#: ../src\wxUI\dialogs\userActions.py:24 msgid "&Block" msgstr "Blokiraj" -#: ../src\wxUI\dialogs\userActions.py:24 +#: ../src\wxUI\dialogs\userActions.py:25 msgid "Unbl&ock" msgstr "Odblokiraj" -#: ../src\wxUI\dialogs\userActions.py:25 +#: ../src\wxUI\dialogs\userActions.py:26 msgid "&Report as spam" msgstr "Prijavi kao neželjeno" -#: ../src\wxUI\dialogs\userActions.py:26 +#: ../src\wxUI\dialogs\userActions.py:27 msgid "&Ignore tweets from this client" msgstr "Zanemari tvitove iz ovog klijenta" -#: ../src\wxUI\dialogs\userSelection.py:9 +#: ../src\wxUI\dialogs\userAliasDialogs.py:18 +msgid "Alias" +msgstr "Nadimak" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:41 +msgid "Edit user aliases" +msgstr "Uredi korisničke nadimke" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:48 +msgid "Actions" +msgstr "Radnje" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:50 +msgid "Add alias" +msgstr "Dodaj nadimak" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:51 +msgid "Adds a new user alias" +msgstr "Dodaje novi nadimak za korisnika" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:54 +msgid "Edit the currently focused user Alias." +msgstr "Uredi trenutno fokusirani korisnički nadimak." + +#: ../src\wxUI\dialogs\userAliasDialogs.py:58 +msgid "Remove the currently focused user alias." +msgstr "Ukloni trenutno fokusirani korisnički nadimak." + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Are you sure you want to delete this user alias?" +msgstr "Da li zaista želite da izbrišete ovaj korisnički nadimak?" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +msgid "Remove user alias" +msgstr "Ukloni korisnički nadimak" + +#: ../src\wxUI\dialogs\userAliasDialogs.py:93 +msgid "User alias" +msgstr "Korisnički nadimak" + +#: ../src\wxUI\dialogs\userSelection.py:10 msgid "Timeline for %s" msgstr "Vremenska crta od %s" -#: ../src\wxUI\dialogs\userSelection.py:18 +#: ../src\wxUI\dialogs\userSelection.py:19 msgid "Buffer type" msgstr "Vrsta kanala" -#: ../src\wxUI\dialogs\userSelection.py:19 +#: ../src\wxUI\dialogs\userSelection.py:20 msgid "&Tweets" msgstr "Tvitovi" -#: ../src\wxUI\dialogs\userSelection.py:20 +#: ../src\wxUI\dialogs\userSelection.py:21 msgid "&Likes" msgstr "Sviđanja" -#: ../src\wxUI\dialogs\userSelection.py:21 +#: ../src\wxUI\dialogs\userSelection.py:22 msgid "&Followers" msgstr "Pratioci" -#: ../src\wxUI\dialogs\userSelection.py:22 +#: ../src\wxUI\dialogs\userSelection.py:23 msgid "F&riends" msgstr "Prijatelji" -#: ../src\wxUI\menus.py:7 ../src\wxUI\view.py:30 +#: ../src\wxUI\menus.py:8 ../src\wxUI\view.py:33 msgid "&Retweet" msgstr "Retvituj" -#: ../src\wxUI\menus.py:9 ../src\wxUI\menus.py:33 ../src\wxUI\view.py:29 +#: ../src\wxUI\menus.py:10 ../src\wxUI\menus.py:34 ../src\wxUI\view.py:32 msgid "Re&ply" msgstr "Odgovori" -#: ../src\wxUI\menus.py:11 ../src\wxUI\view.py:31 +#: ../src\wxUI\menus.py:12 ../src\wxUI\view.py:34 msgid "&Like" msgstr "Sviđa mi se" -#: ../src\wxUI\menus.py:13 ../src\wxUI\view.py:32 +#: ../src\wxUI\menus.py:14 ../src\wxUI\view.py:35 msgid "&Unlike" msgstr "Ne sviđa mi se" -#: ../src\wxUI\menus.py:15 ../src\wxUI\menus.py:35 ../src\wxUI\menus.py:51 +#: ../src\wxUI\menus.py:16 ../src\wxUI\menus.py:36 ../src\wxUI\menus.py:52 msgid "&Open URL" msgstr "otvori vezu" -#: ../src\wxUI\menus.py:17 ../src\wxUI\menus.py:53 ../src\wxUI\menus.py:86 -#, fuzzy +#: ../src\wxUI\menus.py:18 ../src\wxUI\menus.py:54 ../src\wxUI\menus.py:87 msgid "&Open in Twitter" -msgstr "Pretraži ttwitter" +msgstr "&Otvori na Twitteru" -#: ../src\wxUI\menus.py:19 ../src\wxUI\menus.py:37 ../src\wxUI\menus.py:55 +#: ../src\wxUI\menus.py:20 ../src\wxUI\menus.py:38 ../src\wxUI\menus.py:56 msgid "&Play audio" msgstr "reprodukuj zvučni zapis" -#: ../src\wxUI\menus.py:21 ../src\wxUI\menus.py:57 ../src\wxUI\view.py:33 +#: ../src\wxUI\menus.py:22 ../src\wxUI\menus.py:58 ../src\wxUI\view.py:36 msgid "&Show tweet" msgstr "Prikaži tvit" -#: ../src\wxUI\menus.py:23 ../src\wxUI\menus.py:41 ../src\wxUI\menus.py:59 -#: ../src\wxUI\menus.py:69 ../src\wxUI\menus.py:88 ../src\wxUI\menus.py:102 +#: ../src\wxUI\menus.py:24 ../src\wxUI\menus.py:42 ../src\wxUI\menus.py:60 +#: ../src\wxUI\menus.py:70 ../src\wxUI\menus.py:89 ../src\wxUI\menus.py:103 msgid "&Copy to clipboard" msgstr "Kopiraj u ostavu" -#: ../src\wxUI\menus.py:25 ../src\wxUI\menus.py:43 ../src\wxUI\menus.py:61 -#: ../src\wxUI\menus.py:71 ../src\wxUI\view.py:37 +#: ../src\wxUI\menus.py:26 ../src\wxUI\menus.py:44 ../src\wxUI\menus.py:62 +#: ../src\wxUI\menus.py:72 ../src\wxUI\view.py:40 msgid "&Delete" msgstr "Izbriši" -#: ../src\wxUI\menus.py:27 ../src\wxUI\menus.py:45 ../src\wxUI\menus.py:90 +#: ../src\wxUI\menus.py:28 ../src\wxUI\menus.py:46 ../src\wxUI\menus.py:91 msgid "&User actions..." msgstr "Radnje korisnika..." -#: ../src\wxUI\menus.py:39 +#: ../src\wxUI\menus.py:40 msgid "&Show direct message" msgstr "Prikaži direktnu poruku" -#: ../src\wxUI\menus.py:67 +#: ../src\wxUI\menus.py:68 msgid "&Show event" msgstr "Prikaži događaj" -#: ../src\wxUI\menus.py:77 +#: ../src\wxUI\menus.py:78 msgid "Direct &message" msgstr "Direktna poruka" -#: ../src\wxUI\menus.py:79 ../src\wxUI\view.py:46 +#: ../src\wxUI\menus.py:80 ../src\wxUI\view.py:50 msgid "&View lists" msgstr "Vidi liste" -#: ../src\wxUI\menus.py:82 ../src\wxUI\view.py:47 +#: ../src\wxUI\menus.py:83 ../src\wxUI\view.py:51 msgid "Show user &profile" msgstr "Prikaži profil korisnika" -#: ../src\wxUI\menus.py:84 +#: ../src\wxUI\menus.py:85 msgid "&Show user" msgstr "Prikaži korisnika" -#: ../src\wxUI\menus.py:98 +#: ../src\wxUI\menus.py:99 msgid "&Tweet about this trend" msgstr "Tvituj o ovom trendu" -#: ../src\wxUI\menus.py:100 +#: ../src\wxUI\menus.py:101 msgid "&Show item" msgstr "Prikaži stavku" -#: ../src\wxUI\sysTrayIcon.py:35 ../src\wxUI\view.py:23 +#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:26 msgid "&Global settings" msgstr "Globalna podešavanja" -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:22 +#: ../src\wxUI\sysTrayIcon.py:37 ../src\wxUI\view.py:25 msgid "Account se&ttings" msgstr "Postavke naloga" -#: ../src\wxUI\sysTrayIcon.py:37 +#: ../src\wxUI\sysTrayIcon.py:38 msgid "Update &profile" msgstr "Ažuriraj profil" -#: ../src\wxUI\sysTrayIcon.py:38 +#: ../src\wxUI\sysTrayIcon.py:39 msgid "&Show / hide" msgstr "Prikaži ili sakrij" -#: ../src\wxUI\sysTrayIcon.py:39 ../src\wxUI\view.py:71 +#: ../src\wxUI\sysTrayIcon.py:40 ../src\wxUI\view.py:75 msgid "&Documentation" msgstr "Dokumentacija" -#: ../src\wxUI\sysTrayIcon.py:40 +#: ../src\wxUI\sysTrayIcon.py:41 msgid "Check for &updates" msgstr "Proveri da li postoje nadogradnje" -#: ../src\wxUI\sysTrayIcon.py:41 +#: ../src\wxUI\sysTrayIcon.py:42 msgid "&Exit" msgstr "Izlaz" -#: ../src\wxUI\view.py:16 +#: ../src\wxUI\view.py:18 msgid "&Manage accounts" msgstr "Upravljaj nalozima" -#: ../src\wxUI\view.py:18 +#: ../src\wxUI\view.py:20 msgid "&Hide window" msgstr "Sakrij prozor" -#: ../src\wxUI\view.py:20 +#: ../src\wxUI\view.py:22 msgid "&Lists manager" msgstr "Upravljanje listama" -#: ../src\wxUI\view.py:21 +#: ../src\wxUI\view.py:23 +msgid "Manage user aliases" +msgstr "Upravljanje korisničkim nadimcima" + +#: ../src\wxUI\view.py:24 msgid "&Edit keystrokes" msgstr "Izmeni tasterske prečice" -#: ../src\wxUI\view.py:24 +#: ../src\wxUI\view.py:27 msgid "E&xit" msgstr "Izlaz" -#: ../src\wxUI\view.py:28 ../src\wxUI\view.py:82 +#: ../src\wxUI\view.py:31 ../src\wxUI\view.py:86 msgid "&Tweet" msgstr "Tvit" -#: ../src\wxUI\view.py:34 +#: ../src\wxUI\view.py:37 msgid "View &address" msgstr "Vidi adresu" -#: ../src\wxUI\view.py:35 +#: ../src\wxUI\view.py:38 msgid "View conversa&tion" msgstr "Vidi razgovor" -#: ../src\wxUI\view.py:36 +#: ../src\wxUI\view.py:39 msgid "Read text in picture" msgstr "Čitaj tekst u slici" -#: ../src\wxUI\view.py:41 +#: ../src\wxUI\view.py:44 msgid "&Actions..." msgstr "Radnje..." -#: ../src\wxUI\view.py:42 +#: ../src\wxUI\view.py:45 msgid "&View timeline..." msgstr "Vidi vremensku liniju..." -#: ../src\wxUI\view.py:43 +#: ../src\wxUI\view.py:46 msgid "Direct me&ssage" msgstr "Direktna poruka" -#: ../src\wxUI\view.py:44 +#: ../src\wxUI\view.py:47 +msgid "Add a&lias" +msgstr "Dodaj &nadimak" + +#: ../src\wxUI\view.py:48 msgid "&Add to list" msgstr "Dodaj na listu" -#: ../src\wxUI\view.py:45 +#: ../src\wxUI\view.py:49 msgid "R&emove from list" msgstr "Ukloni sa liste" -#: ../src\wxUI\view.py:48 +#: ../src\wxUI\view.py:52 msgid "V&iew likes" msgstr "Vidi sviđanja" -#: ../src\wxUI\view.py:52 +#: ../src\wxUI\view.py:56 msgid "&Update buffer" msgstr "Ažuriraj kanal" -#: ../src\wxUI\view.py:53 +#: ../src\wxUI\view.py:57 msgid "New &trending topics buffer..." msgstr "Novi kanal sa temama u trendu" -#: ../src\wxUI\view.py:54 -#, fuzzy +#: ../src\wxUI\view.py:58 msgid "Create a &filter" -msgstr "Stvori novu listu" +msgstr "Napravi &filter" -#: ../src\wxUI\view.py:55 -#, fuzzy +#: ../src\wxUI\view.py:59 msgid "&Manage filters" -msgstr "Upravljaj nalozima" +msgstr "&Upravljanje filterima" -#: ../src\wxUI\view.py:56 +#: ../src\wxUI\view.py:60 msgid "Find a string in the currently focused buffer..." msgstr "Pronađi pojam u trenutno označenom kanalu..." -#: ../src\wxUI\view.py:57 +#: ../src\wxUI\view.py:61 msgid "&Load previous items" msgstr "Učitaj prethodne stavke" -#: ../src\wxUI\view.py:60 +#: ../src\wxUI\view.py:64 msgid "&Autoread" msgstr "Automatski čitaj" -#: ../src\wxUI\view.py:61 +#: ../src\wxUI\view.py:65 msgid "&Clear buffer" msgstr "Očisti kanal" -#: ../src\wxUI\view.py:62 +#: ../src\wxUI\view.py:66 msgid "&Destroy" msgstr "Izbriši" -#: ../src\wxUI\view.py:66 +#: ../src\wxUI\view.py:70 msgid "&Seek back 5 seconds" msgstr "Premotaj unazad za 5 sekundi" -#: ../src\wxUI\view.py:67 +#: ../src\wxUI\view.py:71 msgid "&Seek forward 5 seconds" msgstr "Premotaj unapred za 5 sekundi" -#: ../src\wxUI\view.py:72 +#: ../src\wxUI\view.py:76 msgid "Sounds &tutorial" msgstr "Zvučna uputstva" -#: ../src\wxUI\view.py:73 +#: ../src\wxUI\view.py:77 msgid "&What's new in this version?" msgstr "Šta je novo u ovoj verziji" -#: ../src\wxUI\view.py:74 +#: ../src\wxUI\view.py:78 msgid "&Check for updates" msgstr "Proveri da li postoje nadogradnje" -#: ../src\wxUI\view.py:75 +#: ../src\wxUI\view.py:79 msgid "&Report an error" msgstr "Prijavi grešku" -#: ../src\wxUI\view.py:76 +#: ../src\wxUI\view.py:80 msgid "{0}'s &website" msgstr "{0} &website" -#: ../src\wxUI\view.py:77 +#: ../src\wxUI\view.py:81 msgid "Get soundpacks for TWBlue" -msgstr "" +msgstr "Nabavi zvučne pakete za TW Blue" -#: ../src\wxUI\view.py:78 +#: ../src\wxUI\view.py:82 msgid "About &{0}" msgstr "O &{0}" -#: ../src\wxUI\view.py:81 +#: ../src\wxUI\view.py:85 msgid "&Application" msgstr "Aplikacija" -#: ../src\wxUI\view.py:84 +#: ../src\wxUI\view.py:88 msgid "&Buffer" msgstr "Kanal" -#: ../src\wxUI\view.py:85 +#: ../src\wxUI\view.py:89 msgid "&Audio" msgstr "Audio" -#: ../src\wxUI\view.py:86 +#: ../src\wxUI\view.py:90 msgid "&Help" msgstr "Pomoć" -#: ../src\wxUI\view.py:172 +#: ../src\wxUI\view.py:176 msgid "Address" msgstr "Adresa" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Update" msgstr "Ažuriraj" -#: ../src\wxUI\view.py:203 +#: ../src\wxUI\view.py:207 msgid "Your {0} version is up to date" msgstr "Imate najnoviju verziju {0}." +#~ msgid "Photo" +#~ msgstr "Slika" + +#~ msgid "There's no URL to be shortened" +#~ msgstr "Nema veze koja bi mogla biti skraćena" + +#~ msgid "URL shortened" +#~ msgstr "Veza je skraćena" + +#~ msgid "There's no URL to be expanded" +#~ msgstr "Nema veze koja bi mogla biti proširena" + +#~ msgid "URL expanded" +#~ msgstr "Veza je proširena" + +#~ msgid "%s - %s characters" +#~ msgstr "%s - %s znakova" + +#~ msgid "Title" +#~ msgstr "Naslov" + +#~ msgid "Add attachments" +#~ msgstr "Dodaj priloge" + +#~ msgid "&Photo" +#~ msgstr "Slika" + +#~ msgid "&Long tweet" +#~ msgstr "Dug tvit" + +#~ msgid "&Upload image..." +#~ msgstr "Otpremi sliku..." + +#~ msgid "Sh&orten URL" +#~ msgstr "Skrati vezu" + +#~ msgid "Friends' Timelines" +#~ msgstr "Vremenska linija prijatelja" + +#~ msgid "Waiting for account authorisation..." +#~ msgstr "En attente d'autorisation du compte..." + +#~ msgid "Contains" +#~ msgstr "Contient" + +#~ msgid "Doesn't contain" +#~ msgstr "Ne contient pas" + +#~ msgid "Create a filter" +#~ msgstr "Créer un filtre" + +#~ msgid "&Name (20 characters maximum)" +#~ msgstr "&Nom (maximum 20 caractères)" + +#~ msgid "Events" +#~ msgstr "Događaji" + +#~ msgid "This tweet doesn't contain images" +#~ msgstr "Ovaj tvit ne sadrži slike." + +#~ msgid "Direct connection" +#~ msgstr "Direktna veza" + +#~ msgid "There are no more items to retrieve in this buffer." +#~ msgstr "Nema više stavki koje se mogu preuzeti u ovom kanalu." + #~ msgid "Empty" #~ msgstr "Prazno" diff --git a/src/logger.py b/src/logger.py index 89895b34..0e8293aa 100644 --- a/src/logger.py +++ b/src/logger.py @@ -37,9 +37,9 @@ error_handler.setLevel(logging.ERROR) logger.addHandler(error_handler) def handle_exception(exc_type, exc_value, exc_traceback): - if issubclass(exc_type, KeyboardInterrupt): - sys.__excepthook__(exc_type, exc_value, exc_traceback) - return - logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) + if issubclass(exc_type, KeyboardInterrupt): + sys.__excepthook__(exc_type, exc_value, exc_traceback) + return + logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) sys.excepthook = handle_exception diff --git a/src/main.py b/src/main.py index 0bb3c802..147155c9 100644 --- a/src/main.py +++ b/src/main.py @@ -7,19 +7,19 @@ from win32com.client import GetObject system = platform.system() if system == "Windows": - import sys - import os - #redirect the original stdout and stderr - stdout=sys.stdout - stderr=sys.stderr - sys.stdout = open(os.path.join(os.getenv("temp"), "stdout.log"), "w") - sys.stderr = open(os.path.join(os.getenv("temp"), "stderr.log"), "w") + import sys + import os + #redirect the original stdout and stderr + stdout=sys.stdout + stderr=sys.stderr + sys.stdout = open(os.path.join(os.getenv("temp"), "stdout.log"), "w") + sys.stderr = open(os.path.join(os.getenv("temp"), "stderr.log"), "w") import languageHandler import paths #check if TWBlue is installed (Windows only) # ToDo: Remove this soon as this is done already when importing the paths module. if os.path.exists(os.path.join(paths.app_path(), "Uninstall.exe")): - paths.mode="installed" + paths.mode="installed" import commandline import config import output @@ -32,114 +32,114 @@ import widgetUtils import webbrowser from wxUI import commonMessageDialogs if system == "Windows": - from logger import logger - from update import updater - stdout_temp=sys.stdout - stderr_temp=sys.stderr + from logger import logger + from update import updater + stdout_temp=sys.stdout + stderr_temp=sys.stderr #if it's a binary version - if hasattr(sys, 'frozen'): - sys.stderr = open(os.path.join(paths.logs_path(), "stderr.log"), 'w') - sys.stdout = open(os.path.join(paths.logs_path(), "stdout.log"), 'w') - else: - sys.stdout=stdout - sys.stderr=stderr - # We are running from source, let's prepare vlc module for that situation - if system=="Windows": - arch="x86" - if platform.architecture()[0][:2] == "64": - arch="x64" - os.environ['PYTHON_VLC_MODULE_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", arch)) - os.environ['PYTHON_VLC_LIB_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", arch, "libvlc.dll")) - #the final log files have been opened succesfully, let's close the temporary files - stdout_temp.close() - stderr_temp.close() - #finally, remove the temporary files. TW Blue doesn't need them anymore, and we will get more free space on the harddrive - os.remove(stdout_temp.name) - os.remove(stderr_temp.name) + if hasattr(sys, 'frozen'): + sys.stderr = open(os.path.join(paths.logs_path(), "stderr.log"), 'w') + sys.stdout = open(os.path.join(paths.logs_path(), "stdout.log"), 'w') + else: + sys.stdout=stdout + sys.stderr=stderr + # We are running from source, let's prepare vlc module for that situation + if system=="Windows": + arch="x86" + if platform.architecture()[0][:2] == "64": + arch="x64" + os.environ['PYTHON_VLC_MODULE_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", arch)) + os.environ['PYTHON_VLC_LIB_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", arch, "libvlc.dll")) + #the final log files have been opened succesfully, let's close the temporary files + stdout_temp.close() + stderr_temp.close() + #finally, remove the temporary files. TW Blue doesn't need them anymore, and we will get more free space on the harddrive + os.remove(stdout_temp.name) + os.remove(stderr_temp.name) import sound if system == "Linux": - from gi.repository import Gdk, GObject, GLib + from gi.repository import Gdk, GObject, GLib log = logging.getLogger("main") def setup(): - log.debug("Starting " + application.name + " %s" % (application.version,)) - config.setup() - proxy_setup() - log.debug("Using %s %s" % (platform.system(), platform.architecture()[0])) - log.debug("Application path is %s" % (paths.app_path(),)) - log.debug("config path is %s" % (paths.config_path(),)) - sound.setup() - languageHandler.setLanguage(config.app["app-settings"]["language"]) - fixes.setup() - output.setup() - keys.setup() - from controller import settings - from controller import mainController - from sessionmanager import sessionManager - app = widgetUtils.mainLoopObject() - check_pid() - if system == "Windows": - if config.app["app-settings"]["donation_dialog_displayed"] == False: - donation() - if config.app['app-settings']['check_for_updates']: - updater.do_update() - sm = sessionManager.sessionManagerController() - sm.fill_list() - if len(sm.sessions) == 0: sm.show() - else: - sm.do_ok() - if hasattr(sm.view, "destroy"): - sm.view.destroy() - del sm - r = mainController.Controller() - r.view.show() - r.do_work() - r.check_invisible_at_startup() - if system == "Windows": - call_threaded(r.start) - elif system == "Linux": - GLib.idle_add(r.start) - app.run() + log.debug("Starting " + application.name + " %s" % (application.version,)) + config.setup() + proxy_setup() + log.debug("Using %s %s" % (platform.system(), platform.architecture()[0])) + log.debug("Application path is %s" % (paths.app_path(),)) + log.debug("config path is %s" % (paths.config_path(),)) + sound.setup() + languageHandler.setLanguage(config.app["app-settings"]["language"]) + fixes.setup() + output.setup() + keys.setup() + from controller import settings + from controller import mainController + from sessionmanager import sessionManager + app = widgetUtils.mainLoopObject() + check_pid() + if system == "Windows": + if config.app["app-settings"]["donation_dialog_displayed"] == False: + donation() + if config.app['app-settings']['check_for_updates']: + updater.do_update() + sm = sessionManager.sessionManagerController() + sm.fill_list() + if len(sm.sessions) == 0: sm.show() + else: + sm.do_ok() + if hasattr(sm.view, "destroy"): + sm.view.destroy() + del sm + r = mainController.Controller() + r.view.show() + r.do_work() + r.check_invisible_at_startup() + if system == "Windows": + call_threaded(r.start) + elif system == "Linux": + GLib.idle_add(r.start) + app.run() def proxy_setup(): - if config.app["proxy"]["server"] != "" and config.app["proxy"]["type"] > 0: - log.debug("Loading proxy settings") - proxy_url = config.app["proxy"]["server"] + ":" + str(config.app["proxy"]["port"]) - if config.app["proxy"]["user"] != "" and config.app["proxy"]["password"] != "": - proxy_url = config.app["proxy"]["user"] + ":" + config.app["proxy"]["password"] + "@" + proxy_url - elif config.app["proxy"]["user"] != "" and config.proxyTypes[config.app["proxy"]["type"]] in ["socks4", "socks4a"]: - proxy_url = config.app["proxy"]["user"] + "@" + proxy_url - proxy_url = config.proxyTypes[config.app["proxy"]["type"]] + "://" + proxy_url - os.environ["HTTP_PROXY"] = proxy_url - os.environ["HTTPS_PROXY"] = proxy_url + if config.app["proxy"]["server"] != "" and config.app["proxy"]["type"] > 0: + log.debug("Loading proxy settings") + proxy_url = config.app["proxy"]["server"] + ":" + str(config.app["proxy"]["port"]) + if config.app["proxy"]["user"] != "" and config.app["proxy"]["password"] != "": + proxy_url = config.app["proxy"]["user"] + ":" + config.app["proxy"]["password"] + "@" + proxy_url + elif config.app["proxy"]["user"] != "" and config.proxyTypes[config.app["proxy"]["type"]] in ["socks4", "socks4a"]: + proxy_url = config.app["proxy"]["user"] + "@" + proxy_url + proxy_url = config.proxyTypes[config.app["proxy"]["type"]] + "://" + proxy_url + os.environ["HTTP_PROXY"] = proxy_url + os.environ["HTTPS_PROXY"] = proxy_url def donation(): - dlg = commonMessageDialogs.donation() - if dlg == widgetUtils.YES: - webbrowser.open_new_tab(_("https://twblue.es/donate")) - config.app["app-settings"]["donation_dialog_displayed"] = True + dlg = commonMessageDialogs.donation() + if dlg == widgetUtils.YES: + webbrowser.open_new_tab(_("https://twblue.es/donate")) + config.app["app-settings"]["donation_dialog_displayed"] = True def is_running(pid): - "Check if the process with ID pid is running. Adapted from https://stackoverflow.com/a/568589" - WMI = GetObject('winmgmts:') - processes = WMI.InstancesOf('Win32_Process') - return [process.Properties_('ProcessID').Value for process in processes if process.Properties_('ProcessID').Value == pid] + "Check if the process with ID pid is running. Adapted from https://stackoverflow.com/a/568589" + WMI = GetObject('winmgmts:') + processes = WMI.InstancesOf('Win32_Process') + return [process.Properties_('ProcessID').Value for process in processes if process.Properties_('ProcessID').Value == pid] def check_pid(): - "Insures that only one copy of the application is running at a time." - pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) - if os.path.exists(pidpath): - with open(pidpath) as fin: - pid = int(fin.read()) - if is_running(pid): - # Display warning dialog - commonMessageDialogs.common_error(_(u"{0} is already running. Close the other instance before starting this one. If you're sure that {0} isn't running, try deleting the file at {1}. If you're unsure of how to do this, contact the {0} developers.").format(application.name, pidpath)) - sys.exit(1) - else: - commonMessageDialogs.dead_pid() - # Write the new PID - with open(pidpath,"w") as cam: - cam.write(str(os.getpid())) + "Insures that only one copy of the application is running at a time." + pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) + if os.path.exists(pidpath): + with open(pidpath) as fin: + pid = int(fin.read()) + if is_running(pid): + # Display warning dialog + commonMessageDialogs.common_error(_(u"{0} is already running. Close the other instance before starting this one. If you're sure that {0} isn't running, try deleting the file at {1}. If you're unsure of how to do this, contact the {0} developers.").format(application.name, pidpath)) + sys.exit(1) + else: + commonMessageDialogs.dead_pid() + # Write the new PID + with open(pidpath,"w") as cam: + cam.write(str(os.getpid())) setup() diff --git a/src/main.spec b/src/main.spec deleted file mode 100644 index 8c0f9cf7..00000000 --- a/src/main.spec +++ /dev/null @@ -1,84 +0,0 @@ -# -*- mode: python -*- -""" specification file for creating distributable versions using Pyinstaller. """ -import os -import glob -import wx -import platform -from requests import certs - -block_cipher = None - -def get_architecture_files(): - """ Returns architecture files for 32 or 64 bits. """ - if platform.architecture()[0][:2] == "32": - return [ - ("..\\windows-dependencies\\x86\\oggenc2.exe", "."), - ("..\\windows-dependencies\\x86\\bootstrap.exe", "."), - ("..\\windows-dependencies\\x86\\*.dll", "."), - ("..\\windows-dependencies\\x86\\plugins", "plugins"), - ] - elif platform.architecture()[0][:2] == "64": - return [ - ("..\\windows-dependencies\\x64\\oggenc2.exe", "."), - ("..\\windows-dependencies\\x64\\bootstrap.exe", "."), - ("..\\windows-dependencies\\x64\\*.dll", "."), - ("..\\windows-dependencies\\x64\\plugins", "plugins"), - ] - -def wx_files(): - wxDir=wx.__path__[0] - localeMoFiles=set() - for f in glob.glob("locales/*/LC_MESSAGES"): - g=f.replace("locales", "locale") - wxMoFile=os.path.join(wxDir,g,"wxstd.mo") - if os.path.isfile(wxMoFile): - localeMoFiles.add((wxMoFile, f)) - lang=os.path.split(os.path.split(f)[0])[1] - if '_' in lang: - lang=lang.split('_')[0] - f=os.path.join('locale',lang,'lc_messages') - g=f.replace("locale", "locales") - wxMoFile=os.path.join(wxDir,f,"wxstd.mo") - if os.path.isfile(wxMoFile): - localeMoFiles.add((wxMoFile, g)) - return list(localeMoFiles) - -a = Analysis(['main.py'], - pathex=['.'], - binaries=[("sounds", "sounds"), -("documentation", "documentation"), -("locales", "locales"), -("keymaps", "keymaps"), -("keys/lib", "keys/lib"), -("..\\windows-dependencies\\dictionaries", "enchant\\share\\enchant\\myspell"), -(certs.where(), "."), -("app-configuration.defaults", "."), -("conf.defaults", "."), -("icon.ico", "."), -]+get_architecture_files()+wx_files(), - - datas=[], - hiddenimports=[], - hookspath=[], - runtime_hooks=[], - excludes=[], - win_no_prefer_redirects=False, - win_private_assemblies=False, - cipher=block_cipher) -pyz = PYZ(a.pure, a.zipped_data, - cipher=block_cipher) -exe = EXE(pyz, - a.scripts, - exclude_binaries=True, - name='TWBlue', - debug=False, - strip=False, - upx=True, - console=False) -coll = COLLECT(exe, - a.binaries, - a.zipfiles, - a.datas, - strip=False, - upx=True, - name='TWBlue') diff --git a/src/multiplatform_widgets/__init__.py b/src/multiplatform_widgets/__init__.py index fe9bf3f2..f50f564e 100644 --- a/src/multiplatform_widgets/__init__.py +++ b/src/multiplatform_widgets/__init__.py @@ -1,3 +1,3 @@ from __future__ import absolute_import from __future__ import unicode_literals -from . import widgets \ No newline at end of file +from . import widgets diff --git a/src/multiplatform_widgets/widgets.py b/src/multiplatform_widgets/widgets.py index 5693c245..1a15e4ca 100644 --- a/src/multiplatform_widgets/widgets.py +++ b/src/multiplatform_widgets/widgets.py @@ -8,85 +8,85 @@ import logging log = logging.getLogger("multiplatform_widgets.widgets") class list(object): - def __init__(self, parent, *columns, **listArguments): - self.system = platform.system() - self.columns = columns - self.listArguments = listArguments - log.debug("Creating list: Columns: %s, arguments: %s" % (self.columns, self.listArguments)) - self.create_list(parent) + def __init__(self, parent, *columns, **listArguments): + self.system = platform.system() + self.columns = columns + self.listArguments = listArguments + log.debug("Creating list: Columns: %s, arguments: %s" % (self.columns, self.listArguments)) + self.create_list(parent) # self.set_size() - def set_windows_size(self, column, characters_max): -# it = wx.ListItem() -# dc = wx.WindowDC(self.list) -# dc.SetFont(it.GetFont()) -# (x, y) = dc.GetTextExtent("r"*characters_max) - self.list.SetColumnWidth(column, characters_max*2) + def set_windows_size(self, column, characters_max): + # it = wx.ListItem() + # dc = wx.WindowDC(self.list) + # dc.SetFont(it.GetFont()) + # (x, y) = dc.GetTextExtent("r"*characters_max) + self.list.SetColumnWidth(column, characters_max*2) - def set_size(self): - self.list.SetSize((self.list.GetBestSize()[0], 728)) + def set_size(self): + self.list.SetSize((self.list.GetBestSize()[0], 728)) # self.list.SetSize((1439, 1000)) - def create_list(self, parent): - if self.system == "Windows": - self.list = wx.ListCtrl(parent, -1, **self.listArguments) - for i in range(0, len(self.columns)): - self.list.InsertColumn(i, u"%s" % (self.columns[i])) - else: - self.list = wx.ListBox(parent, -1, choices=[]) + def create_list(self, parent): + if self.system == "Windows": + self.list = wx.ListCtrl(parent, -1, **self.listArguments) + for i in range(0, len(self.columns)): + self.list.InsertColumn(i, u"%s" % (self.columns[i])) + else: + self.list = wx.ListBox(parent, -1, choices=[]) - def insert_item(self, reversed, *item): - """ Inserts an item on the list, depending on the OS.""" - if self.system == "Windows": - if reversed == False: items = self.list.GetItemCount() - else: items = 0 - self.list.InsertItem(items, item[0]) - for i in range(1, len(self.columns)): - self.list.SetItem(items, i, item[i]) - else: - self.list.Append(" ".join(item)) + def insert_item(self, reversed, *item): + """ Inserts an item on the list, depending on the OS.""" + if self.system == "Windows": + if reversed == False: items = self.list.GetItemCount() + else: items = 0 + self.list.InsertItem(items, item[0]) + for i in range(1, len(self.columns)): + self.list.SetItem(items, i, item[i]) + else: + self.list.Append(" ".join(item)) - def remove_item(self, pos): - """ Deletes an item from the list.""" - if self.system == "Windows": - if pos > 0: self.list.Focus(pos-1) - self.list.DeleteItem(pos) - else: - if pos > 0: self.list.SetSelection(pos-1) - self.list.Delete(pos) + def remove_item(self, pos): + """ Deletes an item from the list.""" + if self.system == "Windows": + if pos > 0: self.list.Focus(pos-1) + self.list.DeleteItem(pos) + else: + if pos > 0: self.list.SetSelection(pos-1) + self.list.Delete(pos) - def clear(self): - if self.system == "Windows": - self.list.DeleteAllItems() - else: - self.list.Clear() + def clear(self): + if self.system == "Windows": + self.list.DeleteAllItems() + else: + self.list.Clear() - def get_selected(self): - if self.system == "Windows": - return self.list.GetFocusedItem() - else: - return self.list.GetSelection() + def get_selected(self): + if self.system == "Windows": + return self.list.GetFocusedItem() + else: + return self.list.GetSelection() - def select_item(self, pos): - if self.system == "Windows": - self.list.Focus(pos) - else: - self.list.SetSelection(pos) + def select_item(self, pos): + if self.system == "Windows": + self.list.Focus(pos) + else: + self.list.SetSelection(pos) - def get_count(self): - if self.system == "Windows": - selected = self.list.GetItemCount() - else: - selected = self.list.GetCount() - if selected == -1: - return 0 - else: - return selected + def get_count(self): + if self.system == "Windows": + selected = self.list.GetItemCount() + else: + selected = self.list.GetCount() + if selected == -1: + return 0 + else: + return selected - def get_text_column(self, indexId, column): - item = self.list.GetItem(indexId, column) - return item.GetText() + def get_text_column(self, indexId, column): + item = self.list.GetItem(indexId, column) + return item.GetText() - def set_text_column(self, indexId, column, text): - item = self.list.SetStringItem(indexId, column, text) - return item \ No newline at end of file + def set_text_column(self, indexId, column, text): + item = self.list.SetStringItem(indexId, column, text) + return item diff --git a/src/mysc/autostart.py b/src/mysc/autostart.py index 01a555f2..845bd0b8 100644 --- a/src/mysc/autostart.py +++ b/src/mysc/autostart.py @@ -10,35 +10,35 @@ from platform_utils import paths RUN_REGKEY = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run" def is_installed(app_subkey): - """Checks if the currently running copy is installed or portable variant. Requires the name of the application subkey found under the uninstall section in Windows registry.""" + """Checks if the currently running copy is installed or portable variant. Requires the name of the application subkey found under the uninstall section in Windows registry.""" - try: - key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey) - inst_dir = winreg.QueryValueEx(key,"InstallLocation")[0] - except WindowsError: - return False - winreg.CloseKey(key) - try: - return os.stat(inst_dir) == os.stat(paths.app_path()) - except WindowsError: - return False + try: + key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s" % app_subkey) + inst_dir = winreg.QueryValueEx(key,"InstallLocation")[0] + except WindowsError: + return False + winreg.CloseKey(key) + try: + return os.stat(inst_dir) == os.stat(paths.app_path()) + except WindowsError: + return False def getAutoStart(app_name): - """Queries if the automatic startup should be set for the application or not, depending on it's current state.""" + """Queries if the automatic startup should be set for the application or not, depending on it's current state.""" - try: - key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY) - val = winreg.QueryValueEx(key, str(app_name))[0] - return os.stat(val) == os.stat(sys.argv[0]) - except (WindowsError, OSError): - return False + try: + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY) + val = winreg.QueryValueEx(key, str(app_name))[0] + return os.stat(val) == os.stat(sys.argv[0]) + except (WindowsError, OSError): + return False def setAutoStart(app_name, enable=True): - """Configures automatic startup for the application, if the enable argument is set to True. If set to False, deletes the application AutoStart value.""" - if getAutoStart(app_name) == enable: - return - key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, winreg.KEY_WRITE) - if enable: - winreg.SetValueEx(key, str(app_name), None, winreg.REG_SZ, paths.get_executable()) - else: - winreg.DeleteValue(key, str(app_name)) + """Configures automatic startup for the application, if the enable argument is set to True. If set to False, deletes the application AutoStart value.""" + if getAutoStart(app_name) == enable: + return + key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, RUN_REGKEY, 0, winreg.KEY_WRITE) + if enable: + winreg.SetValueEx(key, str(app_name), None, winreg.REG_SZ, paths.get_executable()) + else: + winreg.DeleteValue(key, str(app_name)) diff --git a/src/mysc/localization.py b/src/mysc/localization.py index 01a7357d..b6e360cc 100644 --- a/src/mysc/localization.py +++ b/src/mysc/localization.py @@ -5,14 +5,14 @@ import logging log = logging.getLogger("mysc.localization") def get(rootFolder): - log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,)) - defaultLocale = languageHandler.curLang - if len(defaultLocale) > 2: - defaultLocale = defaultLocale[:2] - log.debug("Locale: %s" % (defaultLocale,)) - if os.path.exists(rootFolder+"/"+defaultLocale): - return defaultLocale - else: - log.debug("The folder does not exist, using the English folder...") - return "en" + log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,)) + defaultLocale = languageHandler.curLang + if len(defaultLocale) > 2: + defaultLocale = defaultLocale[:2] + log.debug("Locale: %s" % (defaultLocale,)) + if os.path.exists(rootFolder+"/"+defaultLocale): + return defaultLocale + else: + log.debug("The folder does not exist, using the English folder...") + return "en" diff --git a/src/mysc/repeating_timer.py b/src/mysc/repeating_timer.py index 41b4a5c5..fcc3c021 100644 --- a/src/mysc/repeating_timer.py +++ b/src/mysc/repeating_timer.py @@ -4,34 +4,34 @@ import logging log = logging.getLogger("mysc.repeating_timer") class RepeatingTimer(threading.Thread): - """Call a function after a specified number of seconds, it will then repeat again after the specified number of seconds - Note: If the function provided takes time to execute, this time is NOT taken from the next wait period + """Call a function after a specified number of seconds, it will then repeat again after the specified number of seconds + Note: If the function provided takes time to execute, this time is NOT taken from the next wait period - t = RepeatingTimer(30.0, f, args=[], kwargs={}) - t.start() - t.cancel() # stop the timer's actions - """ + t = RepeatingTimer(30.0, f, args=[], kwargs={}) + t.start() + t.cancel() # stop the timer's actions + """ - def __init__(self, interval, function, daemon=True, *args, **kwargs): - threading.Thread.__init__(self) - self.daemon = daemon - self.interval = float(interval) - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() + def __init__(self, interval, function, daemon=True, *args, **kwargs): + threading.Thread.__init__(self) + self.daemon = daemon + self.interval = float(interval) + self.function = function + self.args = args + self.kwargs = kwargs + self.finished = threading.Event() - def cancel(self): - """Stop the timer if it hasn't finished yet""" - log.debug("Stopping repeater for %s" % (self.function,)) - self.finished.set() - stop = cancel + def cancel(self): + """Stop the timer if it hasn't finished yet""" + log.debug("Stopping repeater for %s" % (self.function,)) + self.finished.set() + stop = cancel - def run(self): - while not self.finished.is_set(): - self.finished.wait(self.interval) - if not self.finished.is_set(): #In case someone has canceled while waiting - try: - self.function(*self.args, **self.kwargs) - except: - log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs)) + def run(self): + while not self.finished.is_set(): + self.finished.wait(self.interval) + if not self.finished.is_set(): #In case someone has canceled while waiting + try: + self.function(*self.args, **self.kwargs) + except: + log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs)) diff --git a/src/mysc/restart.py b/src/mysc/restart.py index cd1a0926..3ea9d14a 100644 --- a/src/mysc/restart.py +++ b/src/mysc/restart.py @@ -4,13 +4,13 @@ import sys, os import application def restart_program(): - """ Function that restarts the application if is executed.""" - args = sys.argv[:] - if not hasattr(sys, "frozen"): - args.insert(0, sys.executable) - if sys.platform == 'win32': - args = ['"%s"' % arg for arg in args] - pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) - if os.path.exists(pidpath): - os.remove(pidpath) - os.execv(sys.executable, args) \ No newline at end of file + """ Function that restarts the application if is executed.""" + args = sys.argv[:] + if not hasattr(sys, "frozen"): + args.insert(0, sys.executable) + if sys.platform == 'win32': + args = ['"%s"' % arg for arg in args] + pidpath = os.path.join(os.getenv("temp"), "{}.pid".format(application.name)) + if os.path.exists(pidpath): + os.remove(pidpath) + os.execv(sys.executable, args) diff --git a/src/mysc/thread_utils.py b/src/mysc/thread_utils.py index 3a112e33..39cdaa09 100644 --- a/src/mysc/thread_utils.py +++ b/src/mysc/thread_utils.py @@ -6,16 +6,14 @@ import wx from pubsub import pub def call_threaded(func, *args, **kwargs): - #Call the given function in a daemonized thread and return the thread. - def new_func(*a, **k): - try: - func(*a, **k) - except TwythonRateLimitError: - pass - except: - log.exception("Thread %d with function %r, args of %r, and kwargs of %r failed to run." % (threading.current_thread().ident, func, a, k)) + #Call the given function in a daemonized thread and return the thread. + def new_func(*a, **k): + try: + func(*a, **k) + except: + log.exception("Thread %d with function %r, args of %r, and kwargs of %r failed to run." % (threading.current_thread().ident, func, a, k)) # pass - thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) - thread.daemon = True - thread.start() - return thread \ No newline at end of file + thread = threading.Thread(target=new_func, args=args, kwargs=kwargs) + thread.daemon = True + thread.start() + return thread diff --git a/src/notifier/__init__.py b/src/notifier/__init__.py index 6283342c..381ca60a 100644 --- a/src/notifier/__init__.py +++ b/src/notifier/__init__.py @@ -8,16 +8,16 @@ import platform notify = None def setup(): - global notify - if platform.system() == "Windows": - from . import windows - notify = windows.notification() - elif platform.system() == "Linux": - from . import linux - notify = linux.notification() + global notify + if platform.system() == "Windows": + from . import windows + notify = windows.notification() + elif platform.system() == "Linux": + from . import linux + notify = linux.notification() def send(title, text): - global notify - if not notify or notify is None: - setup() - notify.notify(title, text) \ No newline at end of file + global notify + if not notify or notify is None: + setup() + notify.notify(title, text) diff --git a/src/notifier/linux.py b/src/notifier/linux.py index 18d78203..91b2e217 100644 --- a/src/notifier/linux.py +++ b/src/notifier/linux.py @@ -5,23 +5,23 @@ import dbus import application class notifications(object): - """Supports notifications on Linux. - """ + """Supports notifications on Linux. + """ - def __init__(self): - super(notifications, self).__init__() - self.item = "org.freedesktop.Notifications" - self.path = "/org/freedesktop/Notifications" - self.interface = "org.freedesktop.Notifications" - self.app_name = application.name - self.id_num_to_replace = 0 - self.icon = "/usr/share/icons/Tango/32x32/status/sunny.png" + def __init__(self): + super(notifications, self).__init__() + self.item = "org.freedesktop.Notifications" + self.path = "/org/freedesktop/Notifications" + self.interface = "org.freedesktop.Notifications" + self.app_name = application.name + self.id_num_to_replace = 0 + self.icon = "/usr/share/icons/Tango/32x32/status/sunny.png" - def notify(self, title="", text=""): - actions_list = '' - hint = '' - time = 5000 # Use seconds x 1000 - bus = dbus.SessionBus() - notif = bus.get_object(self.item, self.path) - notify = dbus.Interface(notif, self.interface) - notify.Notify(self.app_name, self.id_num_to_replace, self.icon, title, text, actions_list, hint, time) \ No newline at end of file + def notify(self, title="", text=""): + actions_list = '' + hint = '' + time = 5000 # Use seconds x 1000 + bus = dbus.SessionBus() + notif = bus.get_object(self.item, self.path) + notify = dbus.Interface(notif, self.interface) + notify.Notify(self.app_name, self.id_num_to_replace, self.icon, title, text, actions_list, hint, time) diff --git a/src/notifier/windows.py b/src/notifier/windows.py index af7b22cc..a521c4a5 100644 --- a/src/notifier/windows.py +++ b/src/notifier/windows.py @@ -5,5 +5,5 @@ import wx class notification(object): - def notify(self, title, text): - wx.NotificationMessage(title, text).Show() \ No newline at end of file + def notify(self, title, text): + wx.NotificationMessage(title, text).Show() diff --git a/src/output.py b/src/output.py index 1bb2975f..75ac2c6b 100644 --- a/src/output.py +++ b/src/output.py @@ -8,28 +8,28 @@ import sys speaker = None def speak(text, interrupt=0, speech=True, braille=True): - global speaker - if not speaker: - setup() - if speech: - speaker.speak(text, interrupt) - if braille: - speaker.braille(text) + global speaker + if not speaker: + setup() + if speech: + speaker.speak(text, interrupt) + if braille: + speaker.braille(text) def setup (): - global speaker - logging.debug("Initializing output subsystem.") - try: -# speaker = speech.Speaker(speech.outputs.Sapi5()) -# else: - speaker = outputs.auto.Auto() - except: - return logging.exception("Output: Error during initialization.") + global speaker + logging.debug("Initializing output subsystem.") + try: + # speaker = speech.Speaker(speech.outputs.Sapi5()) + # else: + speaker = outputs.auto.Auto() + except: + return logging.exception("Output: Error during initialization.") def copy(text): - import win32clipboard - #Copies text to the clipboard. - win32clipboard.OpenClipboard() - win32clipboard.EmptyClipboard() - win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT) - win32clipboard.CloseClipboard() + import win32clipboard + #Copies text to the clipboard. + win32clipboard.OpenClipboard() + win32clipboard.EmptyClipboard() + win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT) + win32clipboard.CloseClipboard() diff --git a/src/paths.py b/src/paths.py index 61f454b2..72435db0 100644 --- a/src/paths.py +++ b/src/paths.py @@ -10,58 +10,58 @@ directory = None fsencoding = sys.getfilesystemencoding() if len(glob.glob("Uninstall.exe")) > 0: # installed copy - mode= "installed" + mode= "installed" def app_path(): - return paths_.app_path() + return paths_.app_path() def config_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "config") - elif directory == None: path = os.path.join(app_path(), "config") - elif mode == "installed": - path = os.path.join(data_path(), "config") - if not os.path.exists(path): -# log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "config") + elif directory == None: path = os.path.join(app_path(), "config") + elif mode == "installed": + path = os.path.join(data_path(), "config") + if not os.path.exists(path): + # log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path def logs_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "logs") - elif directory == None: path = os.path.join(app_path(), "logs") - elif mode == "installed": - path = os.path.join(data_path(), "logs") - if not os.path.exists(path): -# log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "logs") + elif directory == None: path = os.path.join(app_path(), "logs") + elif mode == "installed": + path = os.path.join(data_path(), "logs") + if not os.path.exists(path): + # log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path -def data_path(app_name='socializer'): - if platform.system() == "Windows": - data_path = os.path.join(os.getenv("AppData"), app_name) - else: - data_path = os.path.join(os.environ['HOME'], ".%s" % app_name) - if not os.path.exists(data_path): - os.mkdir(data_path) - return data_path +def data_path(app_name='TW Blue'): + if platform.system() == "Windows": + data_path = os.path.join(os.getenv("AppData"), app_name) + else: + data_path = os.path.join(os.environ['HOME'], ".%s" % app_name) + if not os.path.exists(data_path): + os.mkdir(data_path) + return data_path def locale_path(): - return os.path.join(app_path(), "locales") + return os.path.join(app_path(), "locales") def sound_path(): - return os.path.join(app_path(), "sounds") + return os.path.join(app_path(), "sounds") def com_path(): - global mode, directory - if mode == "portable": - if directory != None: path = os.path.join(directory, "com_cache") - elif directory == None: path = os.path.join(app_path(), "com_cache") - elif mode == "installed": - path = os.path.join(data_path(), "com_cache") - if not os.path.exists(path): -# log.debug("%s path does not exist, creating..." % (path,)) - os.mkdir(path) - return path + global mode, directory + if mode == "portable": + if directory != None: path = os.path.join(directory, "com_cache") + elif directory == None: path = os.path.join(app_path(), "com_cache") + elif mode == "installed": + path = os.path.join(data_path(), "com_cache") + if not os.path.exists(path): + # log.debug("%s path does not exist, creating..." % (path,)) + os.mkdir(path) + return path diff --git a/src/run_tests.py b/src/run_tests.py new file mode 100644 index 00000000..41842347 --- /dev/null +++ b/src/run_tests.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +import unittest + +testmodules = ["test.test_cache"] + +suite = unittest.TestSuite() + +for t in testmodules: + try: + # If the module defines a suite() function, call it to get the suite. + mod = __import__(t, globals(), locals(), ['suite']) + suitefn = getattr(mod, 'suite') + suite.addTest(suitefn()) + except (ImportError, AttributeError): + # else, just load all the test cases from the module. + suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t)) + +unittest.TextTestRunner(verbosity=2).run(suite) \ No newline at end of file diff --git a/src/sessionmanager/__init__.py b/src/sessionmanager/__init__.py index 77b12468..000da2cf 100644 --- a/src/sessionmanager/__init__.py +++ b/src/sessionmanager/__init__.py @@ -7,4 +7,4 @@ Contents of this package: manager: Handles multiple sessions, setting the configuration files and check if the session is valid. Part of the model. session: Creates a twitter session for an user. The other part of the model. """ -from __future__ import unicode_literals \ No newline at end of file +from __future__ import unicode_literals diff --git a/src/sessionmanager/gtkUI.py b/src/sessionmanager/gtkUI.py index aa0b4a18..a6f8a4f0 100644 --- a/src/sessionmanager/gtkUI.py +++ b/src/sessionmanager/gtkUI.py @@ -3,55 +3,55 @@ from gi.repository import Gtk import widgetUtils class sessionManagerWindow(widgetUtils.baseDialog): - def __init__(self): - super(sessionManagerWindow, self).__init__("Session Manager", None, 0, (Gtk.STOCK_OK, widgetUtils.OK, Gtk.STOCK_CANCEL, widgetUtils.CANCEL)) - self.list = widgetUtils.list("Session") - self.box.add(self.list.list) - btnBox = Gtk.Box(spacing=6) - self.new = Gtk.Button("New account") - self.remove = Gtk.Button("Remove account") - self.configuration = Gtk.Button("Configuration") - btnBox.add(self.new) - btnBox.add(self.remove) - btnBox.add(self.configuration) - self.box.add(btnBox) - self.show_all() + def __init__(self): + super(sessionManagerWindow, self).__init__("Session Manager", None, 0, (Gtk.STOCK_OK, widgetUtils.OK, Gtk.STOCK_CANCEL, widgetUtils.CANCEL)) + self.list = widgetUtils.list("Session") + self.box.add(self.list.list) + btnBox = Gtk.Box(spacing=6) + self.new = Gtk.Button("New account") + self.remove = Gtk.Button("Remove account") + self.configuration = Gtk.Button("Configuration") + btnBox.add(self.new) + btnBox.add(self.remove) + btnBox.add(self.configuration) + self.box.add(btnBox) + self.show_all() - def fill_list(self, sessionsList): - for i in sessionsList: - self.list.insert_item(False, i) - if self.list.get_count() > 0: - self.list.select_item(0) + def fill_list(self, sessionsList): + for i in sessionsList: + self.list.insert_item(False, i) + if self.list.get_count() > 0: + self.list.select_item(0) - def new_account_dialog(self): - dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Authorization") - dialog.format_secondary_text("The request to authorize your Twitter account will be opened in your browser. You only need to do this once. Would you like to continue?") - answer = dialog.run() - dialog.destroy() - return answer + def new_account_dialog(self): + dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Authorization") + dialog.format_secondary_text("The request to authorize your Twitter account will be opened in your browser. You only need to do this once. Would you like to continue?") + answer = dialog.run() + dialog.destroy() + return answer - def add_new_session_to_list(self): - total = self.list.get_count() - name = "Authorized account %d" % (total+1) - self.list.insert_item(name) - if self.list.get_count() == 1: - self.list.select_item(0) + def add_new_session_to_list(self): + total = self.list.get_count() + name = "Authorized account %d" % (total+1) + self.list.insert_item(name) + if self.list.get_count() == 1: + self.list.select_item(0) - def show_unauthorised_error(self): - dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Invalid user token") - dialog.format_secondary_text("Your access token is invalid or the authorization has failed. Please try again.") - answer = dialog.run() - return answer + def show_unauthorised_error(self): + dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Invalid user token") + dialog.format_secondary_text("Your access token is invalid or the authorization has failed. Please try again.") + answer = dialog.run() + return answer - def remove_account_dialog(self): - dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Remove account") - dialog.format_secondary_text("Do you really want delete this account?") - answer = dialog.run() - return answer + def remove_account_dialog(self): + dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Remove account") + dialog.format_secondary_text("Do you really want delete this account?") + answer = dialog.run() + return answer - def get_selected(self): - return self.list.get_selected() + def get_selected(self): + return self.list.get_selected() - def remove_session(self, sessionID): - self.list.remove_item(sessionID) + def remove_session(self, sessionID): + self.list.remove_item(sessionID) diff --git a/src/sessionmanager/manager.py b/src/sessionmanager/manager.py index f0745cce..3ec251fe 100644 --- a/src/sessionmanager/manager.py +++ b/src/sessionmanager/manager.py @@ -11,41 +11,41 @@ from sessions import session_exceptions manager = None def setup(): - global manager - if not manager: - manager = sessionManager() + global manager + if not manager: + manager = sessionManager() class sessionManager(object): -# def __init__(self): -# FILE = "sessions.conf" -# SPEC = "app-configuration.defaults" -# try: -# self.main = Configuration(paths.config_path(FILE), paths.app_path(SPEC)) -# except ConfigurationResetException: -# pass + # def __init__(self): + # FILE = "sessions.conf" + # SPEC = "app-configuration.defaults" + # try: + # self.main = Configuration(paths.config_path(FILE), paths.app_path(SPEC)) + # except ConfigurationResetException: + # pass - def get_current_session(self): - if self.is_valid(config.app["sessions"]["current_session"]): - return config.app["sessions"]["current_session"] - else: - return False + def get_current_session(self): + if self.is_valid(config.app["sessions"]["current_session"]): + return config.app["sessions"]["current_session"] + else: + return False - def add_session(self, id): - log.debug("Adding a new session: %s" % (id,)) - path = os.path.join(paths.config_path(), id) - if not os.path.exists(path): - log.debug("Creating %s path" % (os.path.join(paths.config_path(), path),)) - os.mkdir(path) - config.app["sessions"]["sessions"].append(id) + def add_session(self, id): + log.debug("Adding a new session: %s" % (id,)) + path = os.path.join(paths.config_path(), id) + if not os.path.exists(path): + log.debug("Creating %s path" % (os.path.join(paths.config_path(), path),)) + os.mkdir(path) + config.app["sessions"]["sessions"].append(id) - def set_current_session(self, sessionID): - config.app["sessions"]["current_session"] = sessionID - config.app.write() + def set_current_session(self, sessionID): + config.app["sessions"]["current_session"] = sessionID + config.app.write() - def is_valid(self, id): - if not os.path.exists(os.path.join(paths.config_path(), id)): - raise session_exceptions.NonExistentSessionError("That session does not exist.") - config.app["sessions"]["current_session"] = "" - return False - else: - return True \ No newline at end of file + def is_valid(self, id): + if not os.path.exists(os.path.join(paths.config_path(), id)): + raise session_exceptions.NonExistentSessionError("That session does not exist.") + config.app["sessions"]["current_session"] = "" + return False + else: + return True diff --git a/src/sessionmanager/sessionManager.py b/src/sessionmanager/sessionManager.py index 73757e4f..d4255862 100644 --- a/src/sessionmanager/sessionManager.py +++ b/src/sessionmanager/sessionManager.py @@ -4,10 +4,10 @@ import widgetUtils import platform import output if platform.system() == "Windows": - from . import wxUI as view - from controller import settings + from . import wxUI as view + from controller import settings elif platform.system() == "Linux": - from . import gtkUI as view + from . import gtkUI as view import paths import time import os @@ -17,110 +17,110 @@ from sessions.twitter import session from . import manager import config_utils import config -from tweepy.error import TweepError +from tweepy.errors import TweepyException log = logging.getLogger("sessionmanager.sessionManager") class sessionManagerController(object): - def __init__(self, started=False): - super(sessionManagerController, self).__init__() - log.debug("Setting up the session manager.") - self.started = started - manager.setup() - self.view = view.sessionManagerWindow() - widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account) - widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove) - if self.started == False: - widgetUtils.connect_event(self.view.configuration, widgetUtils.BUTTON_PRESSED, self.configuration) - else: - self.view.hide_configuration() - self.new_sessions = {} - self.removed_sessions = [] + def __init__(self, started=False): + super(sessionManagerController, self).__init__() + log.debug("Setting up the session manager.") + self.started = started + manager.setup() + self.view = view.sessionManagerWindow() + widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account) + widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove) + if self.started == False: + widgetUtils.connect_event(self.view.configuration, widgetUtils.BUTTON_PRESSED, self.configuration) + else: + self.view.hide_configuration() + self.new_sessions = {} + self.removed_sessions = [] - def fill_list(self): - sessionsList = [] - reserved_dirs = ["dicts"] - log.debug("Filling the sessions list.") - self.sessions = [] - for i in os.listdir(paths.config_path()): - if os.path.isdir(os.path.join(paths.config_path(), i)) and i not in reserved_dirs: - log.debug("Adding session %s" % (i,)) - strconfig = "%s/session.conf" % (os.path.join(paths.config_path(), i)) - config_test = config_utils.load_config(strconfig) - if len(config_test) == 0: - try: - log.debug("Deleting session %s" % (i,)) - shutil.rmtree(os.path.join(paths.config_path(), i)) - continue - except: - output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) - os.exception("Exception thrown while removing malformed session") - continue - name = config_test["twitter"]["user_name"] - if config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != "": - sessionsList.append(name) - self.sessions.append(i) - else: - try: - log.debug("Deleting session %s" % (i,)) - shutil.rmtree(os.path.join(paths.config_path(), i)) - except: - output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) - os.exception("Exception thrown while removing malformed session") - self.view.fill_list(sessionsList) + def fill_list(self): + sessionsList = [] + reserved_dirs = ["dicts"] + log.debug("Filling the sessions list.") + self.sessions = [] + for i in os.listdir(paths.config_path()): + if os.path.isdir(os.path.join(paths.config_path(), i)) and i not in reserved_dirs: + log.debug("Adding session %s" % (i,)) + strconfig = "%s/session.conf" % (os.path.join(paths.config_path(), i)) + config_test = config_utils.load_config(strconfig) + if len(config_test) == 0: + try: + log.debug("Deleting session %s" % (i,)) + shutil.rmtree(os.path.join(paths.config_path(), i)) + continue + except: + output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) + os.exception("Exception thrown while removing malformed session") + continue + name = config_test["twitter"]["user_name"] + if config_test["twitter"]["user_key"] != "" and config_test["twitter"]["user_secret"] != "": + sessionsList.append(name) + self.sessions.append(i) + else: + try: + log.debug("Deleting session %s" % (i,)) + shutil.rmtree(os.path.join(paths.config_path(), i)) + except: + output.speak("An exception was raised while attempting to clean malformed session data. See the error log for details. If this message persists, contact the developers.",True) + os.exception("Exception thrown while removing malformed session") + self.view.fill_list(sessionsList) - def show(self): - if self.view.get_response() == widgetUtils.OK: - self.do_ok() + def show(self): + if self.view.get_response() == widgetUtils.OK: + self.do_ok() # else: - self.view.destroy() + self.view.destroy() - def do_ok(self): - log.debug("Starting sessions...") - for i in self.sessions: - if (i in sessions.sessions) == True: continue - s = session.Session(i) - s.get_configuration() - if i not in config.app["sessions"]["ignored_sessions"]: - try: - s.login() - except TweepError: - self.show_auth_error(s.settings["twitter"]["user_name"]) - continue - sessions.sessions[i] = s - self.new_sessions[i] = s + def do_ok(self): + log.debug("Starting sessions...") + for i in self.sessions: + if (i in sessions.sessions) == True: continue + s = session.Session(i) + s.get_configuration() + if i not in config.app["sessions"]["ignored_sessions"]: + try: + s.login() + except TweepyException: + self.show_auth_error(s.settings["twitter"]["user_name"]) + continue + sessions.sessions[i] = s + self.new_sessions[i] = s # self.view.destroy() - def show_auth_error(self, user_name): - error = view.auth_error(user_name) + def show_auth_error(self, user_name): + error = view.auth_error(user_name) - def manage_new_account(self, *args, **kwargs): - if self.view.new_account_dialog() == widgetUtils.YES: - location = (str(time.time())[-6:]) - log.debug("Creating session in the %s path" % (location,)) - s = session.Session(location) - manager.manager.add_session(location) - s.get_configuration() + def manage_new_account(self, *args, **kwargs): + if self.view.new_account_dialog() == widgetUtils.YES: + location = (str(time.time())[-6:]) + log.debug("Creating session in the %s path" % (location,)) + s = session.Session(location) + manager.manager.add_session(location) + s.get_configuration() # try: - s.authorise() - self.sessions.append(location) - self.view.add_new_session_to_list() - s.settings.write() + s.authorise() + self.sessions.append(location) + self.view.add_new_session_to_list() + s.settings.write() # except: # log.exception("Error authorising the session") # self.view.show_unauthorised_error() # return - def remove(self, *args, **kwargs): - if self.view.remove_account_dialog() == widgetUtils.YES: - selected_account = self.sessions[self.view.get_selected()] - self.view.remove_session(self.view.get_selected()) - self.removed_sessions.append(selected_account) - self.sessions.remove(selected_account) - shutil.rmtree(path=os.path.join(paths.config_path(), selected_account), ignore_errors=True) + def remove(self, *args, **kwargs): + if self.view.remove_account_dialog() == widgetUtils.YES: + selected_account = self.sessions[self.view.get_selected()] + self.view.remove_session(self.view.get_selected()) + self.removed_sessions.append(selected_account) + self.sessions.remove(selected_account) + shutil.rmtree(path=os.path.join(paths.config_path(), selected_account), ignore_errors=True) - def configuration(self, *args, **kwargs): - """ Opens the global settings dialogue.""" - d = settings.globalSettingsController() - if d.response == widgetUtils.OK: - d.save_configuration() + def configuration(self, *args, **kwargs): + """ Opens the global settings dialogue.""" + d = settings.globalSettingsController() + if d.response == widgetUtils.OK: + d.save_configuration() diff --git a/src/sessionmanager/wxUI.py b/src/sessionmanager/wxUI.py index fccfcdbf..6441f6e8 100644 --- a/src/sessionmanager/wxUI.py +++ b/src/sessionmanager/wxUI.py @@ -5,77 +5,77 @@ from multiplatform_widgets import widgets import application class sessionManagerWindow(wx.Dialog): - def __init__(self): - super(sessionManagerWindow, self).__init__(parent=None, title=_(u"Session manager"), size=wx.DefaultSize) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize) - listSizer = wx.BoxSizer(wx.HORIZONTAL) - self.list = widgets.list(panel, _(u"Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT) - listSizer.Add(label, 0, wx.ALL, 5) - listSizer.Add(self.list.list, 0, wx.ALL, 5) - sizer.Add(listSizer, 0, wx.ALL, 5) - self.new = wx.Button(panel, -1, _(u"New account"), size=wx.DefaultSize) - self.remove = wx.Button(panel, -1, _(u"Remove account")) - self.configuration = wx.Button(panel, -1, _(u"Global Settings")) - ok = wx.Button(panel, wx.ID_OK, size=wx.DefaultSize) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize) - buttons = wx.BoxSizer(wx.HORIZONTAL) - buttons.Add(self.new, 0, wx.ALL, 5) - buttons.Add(self.configuration, 0, wx.ALL, 5) - buttons.Add(ok, 0, wx.ALL, 5) - buttons.Add(cancel, 0, wx.ALL, 5) - sizer.Add(buttons, 0, wx.ALL, 5) - panel.SetSizer(sizer) - min = sizer.CalcMin() - self.SetClientSize(min) + def __init__(self): + super(sessionManagerWindow, self).__init__(parent=None, title=_(u"Session manager"), size=wx.DefaultSize) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize) + listSizer = wx.BoxSizer(wx.HORIZONTAL) + self.list = widgets.list(panel, _(u"Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT) + listSizer.Add(label, 0, wx.ALL, 5) + listSizer.Add(self.list.list, 0, wx.ALL, 5) + sizer.Add(listSizer, 0, wx.ALL, 5) + self.new = wx.Button(panel, -1, _(u"New account"), size=wx.DefaultSize) + self.remove = wx.Button(panel, -1, _(u"Remove account")) + self.configuration = wx.Button(panel, -1, _(u"Global Settings")) + ok = wx.Button(panel, wx.ID_OK, size=wx.DefaultSize) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize) + buttons = wx.BoxSizer(wx.HORIZONTAL) + buttons.Add(self.new, 0, wx.ALL, 5) + buttons.Add(self.configuration, 0, wx.ALL, 5) + buttons.Add(ok, 0, wx.ALL, 5) + buttons.Add(cancel, 0, wx.ALL, 5) + sizer.Add(buttons, 0, wx.ALL, 5) + panel.SetSizer(sizer) + min = sizer.CalcMin() + self.SetClientSize(min) - def fill_list(self, sessionsList): - for i in sessionsList: - self.list.insert_item(False, i) - if self.list.get_count() > 0: - self.list.select_item(0) - self.list.list.SetSize(self.list.list.GetBestSize()) + def fill_list(self, sessionsList): + for i in sessionsList: + self.list.insert_item(False, i) + if self.list.get_count() > 0: + self.list.select_item(0) + self.list.list.SetSize(self.list.list.GetBestSize()) - def ok(self, ev): - if self.list.get_count() == 0: - wx.MessageDialog(None, _(u"You need to configure an account."), _(u"Account Error"), wx.ICON_ERROR).ShowModal() - return - self.controller.do_ok() - self.EndModal(wx.ID_OK) + def ok(self, ev): + if self.list.get_count() == 0: + wx.MessageDialog(None, _(u"You need to configure an account."), _(u"Account Error"), wx.ICON_ERROR).ShowModal() + return + self.controller.do_ok() + self.EndModal(wx.ID_OK) - def new_account_dialog(self): - return wx.MessageDialog(self, _(u"The request to authorize your Twitter account will be opened in your browser. You only need to do this once. Would you like to continue?"), _(u"Authorization"), wx.YES_NO).ShowModal() + def new_account_dialog(self): + return wx.MessageDialog(self, _(u"The request to authorize your Twitter account will be opened in your browser. You only need to do this once. Would you like to continue?"), _(u"Authorization"), wx.YES_NO).ShowModal() - def add_new_session_to_list(self): - total = self.list.get_count() - name = _(u"Authorized account %d") % (total+1) - self.list.insert_item(False, name) - if self.list.get_count() == 1: - self.list.select_item(0) + def add_new_session_to_list(self): + total = self.list.get_count() + name = _(u"Authorized account %d") % (total+1) + self.list.insert_item(False, name) + if self.list.get_count() == 1: + self.list.select_item(0) - def show_unauthorised_error(self): - wx.MessageDialog(None, _(u"Your access token is invalid or the authorization has failed. Please try again."), _(u"Invalid user token"), wx.ICON_ERROR).ShowModal() + def show_unauthorised_error(self): + wx.MessageDialog(None, _(u"Your access token is invalid or the authorization has failed. Please try again."), _(u"Invalid user token"), wx.ICON_ERROR).ShowModal() - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def remove_account_dialog(self): - return wx.MessageDialog(self, _(u"Do you really want to delete this account?"), _(u"Remove account"), wx.YES_NO).ShowModal() + def remove_account_dialog(self): + return wx.MessageDialog(self, _(u"Do you really want to delete this account?"), _(u"Remove account"), wx.YES_NO).ShowModal() - def get_selected(self): - return self.list.get_selected() + def get_selected(self): + return self.list.get_selected() - def remove_session(self, sessionID): - self.list.remove_item(sessionID) + def remove_session(self, sessionID): + self.list.remove_item(sessionID) - def hide_configuration(self): - self.configuration.Hide() + def hide_configuration(self): + self.configuration.Hide() - def destroy(self): - self.Destroy() + def destroy(self): + self.Destroy() def auth_error(user_name): - return wx.MessageDialog(None, _("TWBlue is unable to authenticate the account for {} in Twitter. It might be due to an invalid or expired token, revoqued access to the application, or after an account reactivation. Please remove the account manually from your Twitter sessions in order to stop seeing this message.").format(user_name,), _("Authentication error for session {}").format(user_name,), wx.OK).ShowModal() + return wx.MessageDialog(None, _("TWBlue is unable to authenticate the account for {} in Twitter. It might be due to an invalid or expired token, revoqued access to the application, or after an account reactivation. Please remove the account manually from your Twitter sessions in order to stop seeing this message.").format(user_name,), _("Authentication error for session {}").format(user_name,), wx.OK).ShowModal() diff --git a/src/sessions/__init__.py b/src/sessions/__init__.py index 4ab464c0..a9341e79 100644 --- a/src/sessions/__init__.py +++ b/src/sessions/__init__.py @@ -3,4 +3,4 @@ In TWBlue, a session module defines everything a social network needs to be used in the program.""" from __future__ import unicode_literals # let's define a global object for storing sessions across the program. -sessions = {} \ No newline at end of file +sessions = {} diff --git a/src/sessions/base.py b/src/sessions/base.py index 8d58e5bf..84270257 100644 --- a/src/sessions/base.py +++ b/src/sessions/base.py @@ -1,9 +1,5 @@ # -*- coding: utf-8 -*- """ A base class to be derived in possible new sessions for TWBlue and services.""" -from __future__ import absolute_import -from __future__ import unicode_literals -from builtins import str -from builtins import object import os import paths import output @@ -11,110 +7,153 @@ import time import sound import logging import config_utils -import shelve +import sqlitedict import application -import os from . import session_exceptions as Exceptions log = logging.getLogger("sessionmanager.session") class baseSession(object): - """ toDo: Decorators does not seem to be working when using them in an inherited class.""" + """ toDo: Decorators does not seem to be working when using them in an inherited class.""" - # Decorators. + # Decorators. - def _require_login(fn): - """ Decorator for checking if the user is logged in. - Some functions may need this to avoid making unneeded calls.""" - def f(self, *args, **kwargs): - if self.logged == True: - fn(self, *args, **kwargs) - else: - raise Exceptions.NotLoggedSessionError("You are not logged in yet.") - return f + def _require_login(fn): + """ Decorator for checking if the user is logged in. + Some functions may need this to avoid making unneeded calls.""" + def f(self, *args, **kwargs): + if self.logged == True: + fn(self, *args, **kwargs) + else: + raise Exceptions.NotLoggedSessionError("You are not logged in yet.") + return f - def _require_configuration(fn): - """ Check if the user has a configured session.""" - def f(self, *args, **kwargs): - if self.settings != None: - fn(self, *args, **kwargs) - else: - raise Exceptions.NotConfiguredSessionError("Not configured.") - return f + def _require_configuration(fn): + """ Check if the user has a configured session.""" + def f(self, *args, **kwargs): + if self.settings != None: + fn(self, *args, **kwargs) + else: + raise Exceptions.NotConfiguredSessionError("Not configured.") + return f - def __init__(self, session_id): - """ session_id (str): The name of the folder inside the config directory where the session is located.""" - super(baseSession, self).__init__() - self.session_id = session_id - self.logged = False - self.settings = None - self.db={} - - @property - def is_logged(self): - return self.logged + def __init__(self, session_id): + """ session_id (str): The name of the folder inside the config directory where the session is located.""" + super(baseSession, self).__init__() + self.session_id = session_id + self.logged = False + self.settings = None + self.db={} + # Config specification file. + self.config_spec = "conf.defaults" + # Session type. + self.type = "base" - def get_configuration(self): - """ Get settings for a session.""" - file_ = "%s/session.conf" % (self.session_id,) - log.debug("Creating config file %s" % (file_,)) - self.settings = config_utils.load_config(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), "Conf.defaults")) - self.init_sound() - self.deshelve() + @property + def is_logged(self): + return self.logged - def init_sound(self): - try: self.sound = sound.soundSystem(self.settings["sound"]) - except: pass + def get_configuration(self): + """ Get settings for a session.""" + file_ = "%s/session.conf" % (self.session_id,) + log.debug("Creating config file %s" % (file_,)) + self.settings = config_utils.load_config(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), self.config_spec)) + self.init_sound() + self.load_persistent_data() - @_require_configuration - def login(self, verify_credentials=True): - pass + def init_sound(self): + try: self.sound = sound.soundSystem(self.settings["sound"]) + except: pass - @_require_configuration - def authorise(self): - pass + @_require_configuration + def login(self, verify_credentials=True): + pass - def shelve(self): - """Shelve the database to allow for persistance.""" - shelfname=os.path.join(paths.config_path(), str(self.session_id)+"/cache") - if self.settings["general"]["persist_size"] == 0: - if os.path.exists(shelfname+".dat"): - os.remove(shelfname+".dat") - return - try: - if not os.path.exists(shelfname+".dat"): - output.speak("Generating database, this might take a while.",True) - shelf=shelve.open(os.path.join(paths.config_path(), shelfname),'c') - for key,value in list(self.db.items()): - if type(key) != str and type(key) != str: - output.speak("Uh oh, while shelving the database, a key of type " + str(type(key)) + " has been found. It will be converted to type str, but this will cause all sorts of problems on deshelve. Please bring this to the attention of the " + application.name + " developers immediately. More information about the error will be written to the error log.",True) - log.error("Uh oh, " + str(key) + " is of type " + str(type(key)) + "!") - if type(value) == list and self.settings["general"]["persist_size"] != -1 and len(value) > self.settings["general"]["persist_size"]: - shelf[key]=value[self.settings["general"]["persist_size"]:] - else: - shelf[key]=value - shelf.close() - except: - output.speak("An exception occurred while shelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True) - log.exception("Exception while shelving" + shelfname) - os.remove(shelfname) + @_require_configuration + def authorise(self): + pass - def deshelve(self): - """Import a shelved database.""" - shelfname=os.path.join(paths.config_path(), str(self.session_id)+"/cache") - if self.settings["general"]["persist_size"] == 0: - if os.path.exists(shelfname+".dat"): - os.remove(shelfname+".dat") - return - try: - shelf=shelve.open(os.path.join(paths.config_path(), shelfname),'c') - for key,value in list(shelf.items()): - self.db[key]=value - shelf.close() - except: - output.speak("An exception occurred while deshelving the " + application.name + " database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the " + application.name + " developers.",True) - log.exception("Exception while deshelving" + shelfname) - try: - os.remove(shelfname) - except: - pass + def get_sized_buffer(self, buffer, size, reversed=False): + """ Returns a list with the amount of items specified by size.""" + if isinstance(buffer, list) and size != -1 and len(buffer) > size: + log.debug("Requesting {} items from a list of {} items. Reversed mode: {}".format(size, len(buffer), reversed)) + if reversed == True: + return buffer[:size] + else: + return buffer[len(buffer)-size:] + else: + return buffer + + def save_persistent_data(self): + """ Save the data to a persistent sqlite backed file. .""" + dbname=os.path.join(paths.config_path(), str(self.session_id), "cache.db") + log.debug("Saving storage information...") + # persist_size set to 0 means not saving data actually. + if self.settings["general"]["persist_size"] == 0: + if os.path.exists(dbname): + os.remove(dbname) + return + # Let's check if we need to create a new SqliteDict object (when loading db in memory) or we just need to call to commit in self (if reading from disk).db. + # If we read from disk, we cannot modify the buffer size here as we could damage the app's integrity. + # We will modify buffer's size (managed by persist_size) upon loading the db into memory in app startup. + if self.settings["general"]["load_cache_in_memory"] and isinstance(self.db, dict): + log.debug("Opening database to dump memory contents...") + db=sqlitedict.SqliteDict(dbname, 'c') + for k in self.db.keys(): + sized_buff = self.get_sized_buffer(self.db[k], self.settings["general"]["persist_size"], self.settings["general"]["reverse_timelines"]) + db[k] = sized_buff + db.commit(blocking=True) + db.close() + log.debug("Data has been saved in the database.") + else: + try: + log.debug("Syncing new data to disk...") + if hasattr(self.db, "commit"): + self.db.commit() + except: + output.speak(_("An exception occurred while saving the {app} database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the {app} developers.").format(app=application.name),True) + log.exception("Exception while saving {}".format(dbname)) + os.remove(dbname) + + def load_persistent_data(self): + """Import data from a database file from user config.""" + log.debug("Loading storage data...") + dbname=os.path.join(paths.config_path(), str(self.session_id), "cache.db") + # If persist_size is set to 0, we should remove the db file as we are no longer going to save anything. + if self.settings["general"]["persist_size"] == 0: + if os.path.exists(dbname): + os.remove(dbname) + # Let's return from here, as we are not loading anything. + return + # try to load the db file. + try: + log.debug("Opening database...") + db=sqlitedict.SqliteDict(os.path.join(paths.config_path(), dbname), 'c') + # If load_cache_in_memory is set to true, we will load the whole database into memory for faster access. + # This is going to be faster when retrieving specific objects, at the cost of more memory. + # Setting this to False will read the objects from database as they are needed, which might be slower for bigger datasets. + if self.settings["general"]["load_cache_in_memory"]: + log.debug("Loading database contents into memory...") + for k in db.keys(): + self.db[k] = db[k] + db.commit(blocking=True) + db.close() + log.debug("Contents were loaded successfully.") + else: + log.debug("Instantiating database from disk.") + self.db = db + # We must make sure we won't load more than the amount of buffer specified. + log.debug("Checking if we will load all content...") + for k in self.db.keys(): + sized_buffer = self.get_sized_buffer(self.db[k], self.settings["general"]["persist_size"], self.settings["general"]["reverse_timelines"]) + self.db[k] = sized_buffer + if self.db.get("cursors") == None: + cursors = dict(direct_messages=-1) + self.db["cursors"] = cursors + except: + output.speak(_("An exception occurred while loading the {app} database. It will be deleted and rebuilt automatically. If this error persists, send the error log to the {app} developers.").format(app=application.name), True) + log.exception("Exception while loading {}".format(dbname)) + try: + os.remove(dbname) + except: + pass diff --git a/src/sessions/session_exceptions.py b/src/sessions/session_exceptions.py index e45f843a..9b16e287 100644 --- a/src/sessions/session_exceptions.py +++ b/src/sessions/session_exceptions.py @@ -6,4 +6,4 @@ class NonExistentSessionError(Exception): pass class NotLoggedSessionError(BaseException): pass class NotConfiguredSessionError(BaseException): pass class RequireCredentialsSessionError(BaseException): pass -class AlreadyAuthorisedError(BaseException): pass \ No newline at end of file +class AlreadyAuthorisedError(BaseException): pass diff --git a/src/sessions/twitter/__init__.py b/src/sessions/twitter/__init__.py index 7c68785e..40a96afc 100644 --- a/src/sessions/twitter/__init__.py +++ b/src/sessions/twitter/__init__.py @@ -1 +1 @@ -# -*- coding: utf-8 -*- \ No newline at end of file +# -*- coding: utf-8 -*- diff --git a/src/sessions/twitter/compose.py b/src/sessions/twitter/compose.py index 98370391..1b761390 100644 --- a/src/sessions/twitter/compose.py +++ b/src/sessions/twitter/compose.py @@ -1,11 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -from builtins import str -from builtins import chr -from builtins import range import platform system = platform.system() from . import utils @@ -21,153 +14,157 @@ from .long_tweets import twishort, tweets log = logging.getLogger("compose") def StripChars(s): - """Converts any html entities in s to their unicode-decoded equivalents and returns a string.""" - entity_re = re.compile(r"&(#\d+|\w+);") - def matchFunc(match): - """Nested function to handle a match object. - If we match &blah; and it's not found, &blah; will be returned. - if we match #\d+, unichr(digits) will be returned. - Else, a unicode string will be returned.""" - if match.group(1).startswith('#'): return chr(int(match.group(1)[1:])) - replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1)) - return replacement - return str(entity_re.sub(matchFunc, s)) + """Converts any html entities in s to their unicode-decoded equivalents and returns a string.""" + entity_re = re.compile(r"&(#\d+|\w+);") + def matchFunc(match): + """Nested function to handle a match object. + If we match &blah; and it's not found, &blah; will be returned. + if we match #\d+, unichr(digits) will be returned. + Else, a unicode string will be returned.""" + if match.group(1).startswith('#'): return chr(int(match.group(1)[1:])) + replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1)) + return replacement + return str(entity_re.sub(matchFunc, s)) chars = "abcdefghijklmnopqrstuvwxyz" def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=None): - """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" - if system == "Windows": - original_date = arrow.get(tweet.created_at, locale="en") - if relative_times == True: - ts = original_date.humanize(locale=languageHandler.curLang[:2]) - else: - ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) - else: - ts = tweet.created_at - if hasattr(tweet, "message"): - value = "message" - elif hasattr(tweet, "full_text"): - value = "full_text" - else: - value = "text" - if hasattr(tweet, "retweeted_status") and value != "message": - text = StripChars(getattr(tweet.retweeted_status, value)) - else: - text = StripChars(getattr(tweet, value)) - if show_screen_names: - user = tweet.user.screen_name - else: - user = tweet.user.name - source = re.sub(r"(?s)<.*?>", "", tweet.source) - if hasattr(tweet, "retweeted_status"): - if (hasattr(tweet, "message")) == False and tweet.retweeted_status.is_quote_status == False: - text = "RT @%s: %s" % (tweet.retweeted_status.user.screen_name, text) - elif tweet.retweeted_status.is_quote_status: - text = "%s" % (text) - else: - text = "RT @%s: %s" % (tweet.retweeted_status.user.screen_name, text) - if not hasattr(tweet, "message"): - - if hasattr(tweet, "retweeted_status"): - text = utils.expand_urls(text, tweet.retweeted_status.entities) - else: - text = utils.expand_urls(text, tweet.entities) - if config.app['app-settings']['handle_longtweets']: pass - return [user+", ", text, ts+", ", source] + """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" + if system == "Windows": + original_date = arrow.get(tweet.created_at, locale="en") + if relative_times == True: + ts = original_date.humanize(locale=languageHandler.curLang[:2]) + else: + ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) + else: + ts = tweet.created_at + if hasattr(tweet, "message"): + value = "message" + elif hasattr(tweet, "full_text"): + value = "full_text" + else: + value = "text" + if hasattr(tweet, "retweeted_status") and value != "message": + text = utils.clean_mentions(StripChars(getattr(tweet.retweeted_status, value))) + else: + text = utils.clean_mentions(StripChars(getattr(tweet, value))) + if show_screen_names: + user = session.get_user(tweet.user).screen_name + else: + user = session.get_user(tweet.user).name + source = re.sub(r"(?s)<.*?>", "", tweet.source) + if hasattr(tweet, "retweeted_status"): + if hasattr(tweet, "message") == False and hasattr(tweet.retweeted_status, "is_quote_status") == False: + text = "RT @%s: %s" % (session.get_user(tweet.retweeted_status.user).screen_name, text) + elif hasattr(tweet.retweeted_status, "is_quote_status"): + text = "%s" % (text) + else: + text = "RT @%s: %s" % (session.get_user(tweet.retweeted_status.user).screen_name, text) + if not hasattr(tweet, "message"): + if hasattr(tweet, "retweeted_status"): + if hasattr(tweet.retweeted_status, "entities"): + text = utils.expand_urls(text, tweet.retweeted_status.entities) + else: + if hasattr(tweet, "entities"): + text = utils.expand_urls(text, tweet.entities) + if config.app['app-settings']['handle_longtweets']: pass + return [user+", ", text, ts+", ", source] def compose_direct_message(item, db, relative_times, show_screen_names=False, session=None): - # for a while this function will be together with compose_dm. - # this one composes direct messages based on events (new API Endpoints). - if system == "Windows": - # Let's remove the last 3 digits in the timestamp string. - # Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it. - original_date = arrow.get(int(item.created_timestamp)) - if relative_times == True: - ts = original_date.humanize(locale=languageHandler.curLang[:2]) - else: - ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) - else: - ts = item.created_timestamp - text = StripChars(item.message_create["message_data"]["text"]) - source = "DM" - sender = session.get_user(item.message_create["sender_id"]) - if db["user_name"] == sender.screen_name: - if show_screen_names: - user = _(u"Dm to %s ") % (session.get_user(item.message_create["target"]["recipient_id"]).screen_name) - else: - user = _(u"Dm to %s ") % (session.get_user(item.message_create["target"]["recipient_id"]).name) - else: - if show_screen_names: - user = sender.screen_name - else: - user = sender.name - if text[-1] in chars: text=text+"." - text = utils.expand_urls(text, item.message_create["message_data"]["entities"]) - return [user+", ", text, ts+", ", source] + if system == "Windows": + # Let's remove the last 3 digits in the timestamp string. + # Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it. + original_date = arrow.get(int(item.created_timestamp)) + if relative_times == True: + ts = original_date.humanize(locale=languageHandler.curLang[:2]) + else: + ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) + else: + ts = item.created_timestamp + text = StripChars(item.message_create["message_data"]["text"]) + source = "DM" + sender = session.get_user(item.message_create["sender_id"]) + if db["user_name"] == sender.screen_name: + if show_screen_names: + user = _(u"Dm to %s ") % (session.get_user(item.message_create["target"]["recipient_id"]).screen_name) + else: + user = _(u"Dm to %s ") % (session.get_user(item.message_create["target"]["recipient_id"]).name) + else: + if show_screen_names: + user = sender.screen_name + else: + user = sender.name + if text[-1] in chars: text=text+"." + text = utils.expand_urls(text, item.message_create["message_data"]["entities"]) + return [user+", ", text, ts+", ", source] def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False, session=None): - """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" - if hasattr(quoted_tweet, "retweeted_status"): - if hasattr(quoted_tweet.retweeted_status, "full_text"): - value = "full_text" - else: - value = "text" - text = StripChars(getattr(quoted_tweet.retweeted_status, value)) - else: - if hasattr(quoted_tweet, "full_text"): - value = "full_text" - else: - value = "text" - text = StripChars(getattr(quoted_tweet, value)) - if show_screen_names: - quoting_user = quoted_tweet.user.screen_name - else: - quoting_user = quoted_tweet.user.name - source = quoted_tweet.source - if hasattr(quoted_tweet, "retweeted_status"): - text = "rt @%s: %s" % (quoted_tweet.retweeted_status.user.screen_name, text) - if text[-1] in chars: text=text+"." - original_user = original_tweet.user.screen_name - if hasattr(original_tweet, "message"): - original_text = original_tweet.message - elif hasattr(original_tweet, "full_text"): - original_text = StripChars(original_tweet.full_text) - else: - original_text = 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) - quoted_tweet.entities["urls"].extend(original_tweet.entities["urls"]) - return quoted_tweet + """ It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is.""" + if hasattr(quoted_tweet, "retweeted_status"): + if hasattr(quoted_tweet.retweeted_status, "full_text"): + value = "full_text" + else: + value = "text" + text = StripChars(getattr(quoted_tweet.retweeted_status, value)) + else: + if hasattr(quoted_tweet, "full_text"): + value = "full_text" + else: + value = "text" + text = utils.clean_mentions(StripChars(getattr(quoted_tweet, value))) + if show_screen_names: + quoting_user = session.get_user(quoted_tweet.user).screen_name + else: + quoting_user = session.get_user(quoted_tweet.user).name + source = quoted_tweet.source + if hasattr(quoted_tweet, "retweeted_status"): + text = "rt @%s: %s" % (session.get_user(quoted_tweet.retweeted_status.user).screen_name, text) + if text[-1] in chars: text=text+"." + original_user = session.get_user(original_tweet.user).screen_name + if hasattr(original_tweet, "message"): + original_text = original_tweet.message + elif hasattr(original_tweet, "full_text"): + original_text = utils.clean_mentions(StripChars(original_tweet.full_text)) + else: + 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"): + if hasattr(quoted_tweet, "entities") == False: + quoted_tweet.entities = {} + if quoted_tweet.entities.get("urls") == None: + quoted_tweet.entities["urls"] = [] + quoted_tweet.entities["urls"].extend(original_tweet.entities["urls"]) + return quoted_tweet def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False, session=None): - if system == "Windows": - original_date = arrow.get(tweet.created_at, locale="en") - if relative_times == True: - ts = original_date.humanize(locale=languageHandler.curLang[:2]) - else: - ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) - else: - ts = tweet.created_at - if hasattr(tweet, "status"): - if system == "Windows": - original_date2 = arrow.get(tweet.status.created_at, locale="en") - if relative_times: - ts2 = original_date2.humanize(locale=languageHandler.curLang[:2]) - else: - ts2 = original_date2.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) - else: - ts2 = _("Unavailable") - else: - ts2 = _("Unavailable") - return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet.name, tweet.screen_name, tweet.followers_count, tweet.friends_count, tweet.statuses_count, ts2, ts)] + if system == "Windows": + original_date = arrow.get(tweet.created_at, locale="en") + if relative_times == True: + ts = original_date.humanize(locale=languageHandler.curLang[:2]) + else: + ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) + else: + ts = tweet.created_at + if hasattr(tweet, "status"): + if system == "Windows": + original_date2 = arrow.get(tweet.status.created_at, locale="en") + if relative_times: + ts2 = original_date2.humanize(locale=languageHandler.curLang[:2]) + else: + ts2 = original_date2.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) + else: + ts2 = _("Unavailable") + else: + ts2 = _("Unavailable") + return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet.name, tweet.screen_name, tweet.followers_count, tweet.friends_count, tweet.statuses_count, ts2, ts)] def compose_list(list): - name = list.name - if list.description == None: description = _(u"No description available") - else: description = list.description - user = list.user.name - members = str(list.member_count) - if list.mode == "private": status = _(u"private") - else: status = _(u"public") - return [name, description, user, members, status] + name = list.name + if list.description == None: description = _(u"No description available") + else: description = list.description + user = list.user.name + members = str(list.member_count) + if list.mode == "private": status = _(u"private") + else: status = _(u"public") + return [name, description, user, members, status] diff --git a/src/sessions/twitter/long_tweets/__init__.py b/src/sessions/twitter/long_tweets/__init__.py index 20e9c4c4..007ad61c 100644 --- a/src/sessions/twitter/long_tweets/__init__.py +++ b/src/sessions/twitter/long_tweets/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """ this package holds different modules to extract information regarding long tweets. A long tweet contains more than one tweet (such a quoted tweet), or is made via services like twishort.""" -from __future__ import unicode_literals \ No newline at end of file +from __future__ import unicode_literals diff --git a/src/sessions/twitter/long_tweets/tweets.py b/src/sessions/twitter/long_tweets/tweets.py index 2ba1b48f..54d8d86d 100644 --- a/src/sessions/twitter/long_tweets/tweets.py +++ b/src/sessions/twitter/long_tweets/tweets.py @@ -20,33 +20,33 @@ from __future__ import unicode_literals from sessions.twitter import utils def is_long(tweet): - """ Check if the passed tweet contains a quote in its metadata. - tweet dict: a tweet dictionary. - returns True if a quote is detected, False otherwise.""" - if hasattr(tweet, "quoted_status_id") and hasattr(tweet, "quoted_status"): - return tweet.quoted_status_id - elif hasattr(tweet, "retweeted_status") and hasattr(tweet, "quoted_status_id") and hasattr(tweet, "quoted_status"): - return tweet.retweeted_status.quoted_status_id - return False + """ Check if the passed tweet contains a quote in its metadata. + tweet dict: a tweet dictionary. + returns True if a quote is detected, False otherwise.""" + if hasattr(tweet, "quoted_status_id") and hasattr(tweet, "quoted_status"): + return tweet.quoted_status_id + elif hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "quoted_status_id") and hasattr(tweet.retweeted_status, "quoted_status"): + return tweet.retweeted_status.quoted_status_id + return False def clear_url(tweet): - """ Reads data from a quoted tweet and removes the link to the Status from the tweet's text. - tweet dict: a tweet dictionary. - returns a tweet dictionary without the URL to the status ID in its text to display.""" - if hasattr(tweet, "retweeted_status"): - if hasattr(tweet.retweeted_status, "full_text"): - value = "full_text" - else: - value = "text" - urls = utils.find_urls_in_text(getattr(tweet.retweeted_status, value)) - try: tweet.message = tweet.message.replace(urls[-1], "") - except IndexError: pass - else: - if hasattr(tweet, "full_text"): - value = "full_text" - else: - value = "text" - urls = utils.find_urls_in_text(getattr(tweet, value)) - try: tweet.message = tweet.message.replace(urls[-1], "") - except IndexError: pass - return tweet \ No newline at end of file + """ Reads data from a quoted tweet and removes the link to the Status from the tweet's text. + tweet dict: a tweet dictionary. + returns a tweet dictionary without the URL to the status ID in its text to display.""" + if hasattr(tweet, "retweeted_status"): + if hasattr(tweet.retweeted_status, "full_text"): + value = "full_text" + else: + value = "text" + urls = utils.find_urls_in_text(getattr(tweet.retweeted_status, value)) + try: tweet.message = tweet.message.replace(urls[-1], "") + except IndexError: pass + else: + if hasattr(tweet, "full_text"): + value = "full_text" + else: + value = "text" + urls = utils.find_urls_in_text(getattr(tweet, value)) + try: tweet.message = tweet.message.replace(urls[-1], "") + except IndexError: pass + return tweet diff --git a/src/sessions/twitter/long_tweets/twishort.py b/src/sessions/twitter/long_tweets/twishort.py index 25878cf0..4e42fbf8 100644 --- a/src/sessions/twitter/long_tweets/twishort.py +++ b/src/sessions/twitter/long_tweets/twishort.py @@ -28,77 +28,71 @@ from sessions.twitter import utils log = logging.getLogger("long_tweets.twishort") def get_twishort_uri(url): - """ Takes A twishort URl and returns the twishort ID. - url str: an url like http://twishort.com/id. - returns a twishort ID if the URL is valid, False otherwise.""" - try: - return url.split("twishort.com/")[1] - except ValueError: - return False + """ Takes A twishort URl and returns the twishort ID. + url str: an url like http://twishort.com/id. + returns a twishort ID if the URL is valid, False otherwise.""" + try: + return url.split("twishort.com/")[1] + except ValueError: + return False def is_long(tweet): - """ Check if the passed tweet is made with Twishort. - returns True if is a long tweet, False otherwise.""" - long = False - for url in range(0, len(tweet.entities["urls"])): - try: - if tweet.entities["urls"][url] != None and "twishort.com" in tweet.entities["urls"][url]["expanded_url"]: - long = get_twishort_uri(tweet.entities["urls"][url]["expanded_url"]) - except IndexError: - pass - # sometimes Twitter returns URL's with None objects, so let's take it. - # see https://github.com/manuelcortez/TWBlue/issues/103 - except TypeError: - pass - if long == False and hasattr(tweet, "retweeted_status"): - for url in range(0, len(tweet.retweeted_status.entities["urls"])): - try: - if tweet.retweeted_status.entities["urls"][url] != None and "twishort.com" in tweet.retweeted_status.entities["urls"][url]["expanded_url"]: - long = get_twishort_uri(tweet.retweeted_status.entities["urls"][url]["expanded_url"]) - except IndexError: - pass - except TypeError: - pass - return long + """ Check if the passed tweet is made with Twishort. + returns True if is a long tweet, False otherwise.""" + long = False + if hasattr(tweet, "entities") and tweet.entities.get("urls"): + for url in range(0, len(tweet.entities["urls"])): + try: + if tweet.entities["urls"][url] != None and "twishort.com" in tweet.entities["urls"][url]["expanded_url"]: + long = get_twishort_uri(tweet.entities["urls"][url]["expanded_url"]) + except IndexError: + pass + # sometimes Twitter returns URL's with None objects, so let's take it. + # see https://github.com/manuelcortez/TWBlue/issues/103 + except TypeError: + pass + if long == False and hasattr(tweet, "retweeted_status"): + return is_long(tweet.retweeted_status) + return long def get_full_text(uri): - """ Get Twishort's full text. - uri str: Twishort's identifier. - returns the contents of the tweet.""" - try: - r = requests.get("http://api.twishort.com/1.1/get.json", params={"uri": uri, "api_key": keys.keyring.get("twishort_api_key")}) - msg = r.json()["text"] - # Try to parse possible HTML entities. - from sessions.twitter.compose import StripChars - msg = StripChars(msg) - return msg - except: - return False + """ Get Twishort's full text. + uri str: Twishort's identifier. + returns the contents of the tweet.""" + try: + r = requests.get("http://api.twishort.com/1.1/get.json", params={"uri": uri, "api_key": keys.keyring.get("twishort_api_key")}) + msg = r.json()["text"] + # Try to parse possible HTML entities. + from sessions.twitter.compose import StripChars + msg = StripChars(msg) + return msg + except: + return False def create_tweet(user_token, user_secret, text, media=0): - """ Send a tweet to be extended by using Twishort. - user_token, user_secret str: Twitter user access key and secret, used by TWBlue to authorise against Twitter. - text str: Tweet text, max 10000 characters. - media int: Not used currently. - Returns text to be placed in the Tweet if the post has been succeeded, 0 otherwise.""" - twitter = OAuth1Session(keys.keyring.get("api_key"), client_secret=keys.keyring.get("api_secret"), resource_owner_key=user_token, resource_owner_secret=user_secret) - twishort_key=keys.keyring.get("twishort_api_key") - x_auth_service_provider = "https://api.twitter.com/1.1/account/verify_credentials.json" - twishort_post_url = "http://api.twishort.com/1.1/post.json" - twishort_update_ids_url = "http://api.twishort.com/1.1/update_ids.json" - r=requests.Request('GET', x_auth_service_provider) - prep=twitter.prepare_request(r) - resp=twitter.send(prep) - twitter.headers={ - 'X-Auth-Service-Provider':x_auth_service_provider, - 'X-Verify-Credentials-Authorization':prep.headers['Authorization'], - } - data = {'api_key':twishort_key, - "text": text.encode("utf-8"), - "media": media} - response = twitter.post(twishort_post_url, data=data) - try: - return response.json()["text_to_tweet"] - except: - print("There was a problem creating a long tweet") - return 0 \ No newline at end of file + """ Send a tweet to be extended by using Twishort. + user_token, user_secret str: Twitter user access key and secret, used by TWBlue to authorise against Twitter. + text str: Tweet text, max 10000 characters. + media int: Not used currently. + Returns text to be placed in the Tweet if the post has been succeeded, 0 otherwise.""" + twitter = OAuth1Session(keys.keyring.get("api_key"), client_secret=keys.keyring.get("api_secret"), resource_owner_key=user_token, resource_owner_secret=user_secret) + twishort_key=keys.keyring.get("twishort_api_key") + x_auth_service_provider = "https://api.twitter.com/1.1/account/verify_credentials.json" + twishort_post_url = "http://api.twishort.com/1.1/post.json" + twishort_update_ids_url = "http://api.twishort.com/1.1/update_ids.json" + r=requests.Request('GET', x_auth_service_provider) + prep=twitter.prepare_request(r) + resp=twitter.send(prep) + twitter.headers={ + 'X-Auth-Service-Provider':x_auth_service_provider, + 'X-Verify-Credentials-Authorization':prep.headers['Authorization'], + } + data = {'api_key':twishort_key, + "text": text.encode("utf-8"), + "media": media} + response = twitter.post(twishort_post_url, data=data) + try: + return response.json()["text_to_tweet"] + except: + print("There was a problem creating a long tweet") + return 0 diff --git a/src/sessions/twitter/reduce.py b/src/sessions/twitter/reduce.py new file mode 100644 index 00000000..73d8c45e --- /dev/null +++ b/src/sessions/twitter/reduce.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +""" Strips unneeded tweet information in order to store tweet objects by using less memory. This is especially useful when buffers start to contain more than a certain amount of items. """ +from tweepy.models import Status + +def reduce_tweet(tweet): + """ generates a new Tweet model with the fields we currently need, excluding everything else including null values and empty collections. """ + allowed_values = ["created_at", "id", "full_text", "text", "message", "in_reply_to_status_id", "in_reply_to_user_id", "is_quote_status", "lang", "source", "coordinates", "quoted_status_id", "extended_entities"] + allowed_entities = ["hashtags", "media", "urls", "user_mentions", "polls"] + status_dict = {} + for key in allowed_values: + if tweet._json.get(key): + status_dict[key] = tweet._json[key] + entities = dict() + for key in allowed_entities: + if tweet._json["entities"].get(key) and tweet._json["entities"].get(key) != None: + entities[key] = tweet._json["entities"][key] + status_dict["entities"] = entities + # If tweet comes from the cached database, it does not include an API, so we can pass None here as we do not use that reference to tweepy's API. + if hasattr(tweet, "_api"): + api = tweet._api + else: + api = None + status = Status().parse(api=api, json=status_dict) + # Quotes and retweets are different objects. So we parse a new tweet when we have a quoted or retweeted status here. + if tweet._json.get("quoted_status"): + quoted_tweet = reduce_tweet(tweet.quoted_status) + status.quoted_status = quoted_tweet + if tweet._json.get("retweeted_status"): + retweeted_tweet = reduce_tweet(tweet.retweeted_status) + status.retweeted_status = retweeted_tweet + # Adds user ID to here so we can reference it later. + # Sometimes, the conversations buffer would send an already reduced tweet here so we will need to return it as is. + if isinstance(tweet.user, str) == False: + status.user = tweet.user.id_str + else: + return tweet + return status \ No newline at end of file diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index fcdbea79..55373aa7 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -8,426 +8,661 @@ import wx import config import output import application +import appkeys from pubsub import pub import tweepy -from tweepy.error import TweepError +from tweepy.errors import TweepyException, Forbidden, NotFound +from tweepy.models import User as UserModel from mysc.thread_utils import call_threaded from keys import keyring from sessions import base from sessions.twitter import utils, compose from sessions.twitter.long_tweets import tweets, twishort +from . import reduce, streaming from .wxUI import authorisationDialog log = logging.getLogger("sessions.twitterSession") class Session(base.baseSession): - """ A session object where we will save configuration, the twitter object and a local storage for saving the items retrieved through the Twitter API methods""" + """ A session object where we will save configuration, the twitter object and a local storage for saving the items retrieved through the Twitter API methods""" - def order_buffer(self, name, data, ignore_older=True): - """ Put new items in the local database. - name str: The name for the buffer stored in the dictionary. - data list: A list with tweets. - ignore_older bool: if set to True, items older than the first element on the list will be ignored. - returns the number of items that have been added in this execution""" - if name == "direct_messages": - return self.order_direct_messages(data) - num = 0 - last_id = None - if (name in self.db) == False: - self.db[name] = [] - if ("users" in self.db) == False: - self.db["users"] = {} - if ignore_older and len(self.db[name]) > 0: - if self.settings["general"]["reverse_timelines"] == False: - last_id = self.db[name][0].id - else: - last_id = self.db[name][-1].id - for i in data: - if ignore_older and last_id != None: - 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: - i = self.check_quoted_status(i) - i = self.check_long_tweet(i) - if i == False: continue - if self.settings["general"]["reverse_timelines"] == False: self.db[name].append(i) - else: self.db[name].insert(0, i) - num = num+1 - if hasattr(i, "user"): - if (i.user.id in self.db["users"]) == False: - self.db["users"][i.user.id] = i.user - return num + def order_buffer(self, name, data, ignore_older=True): + """ Put new items in the local database. + name str: The name for the buffer stored in the dictionary. + data list: A list with tweets. + ignore_older bool: if set to True, items older than the first element on the list will be ignored. + returns the number of items that have been added in this execution""" + if name == "direct_messages": + return self.order_direct_messages(data) + num = 0 + last_id = None + if (name in self.db) == False: + self.db[name] = [] + if ("users" in self.db) == False: + self.db["users"] = {} + objects = self.db[name] + if ignore_older and len(self.db[name]) > 0: + if self.settings["general"]["reverse_timelines"] == False: + last_id = self.db[name][0].id + else: + last_id = self.db[name][-1].id + self.add_users_from_results(data) + for i in data: + if ignore_older and last_id != None: + 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, 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) + reduced_object = self.check_long_tweet(reduced_object) + if self.settings["general"]["reverse_timelines"] == False: objects.append(reduced_object) + else: objects.insert(0, reduced_object) + num = num+1 + self.db[name] = objects + return num - def order_people(self, name, data): - """ Put new items on the local database. Useful for cursored buffers (followers, friends, users of a list and searches) - name str: The name for the buffer stored in the dictionary. - data list: A list with items and some information about cursors. - returns the number of items that have been added in this execution""" - num = 0 - if (name in self.db) == False: - self.db[name] = [] - for i in data: - if utils.find_item(i.id, self.db[name]) == None: - if self.settings["general"]["reverse_timelines"] == False: self.db[name].append(i) - else: self.db[name].insert(0, i) - num = num+1 - return num + def order_people(self, name, data): + """ Put new items on the local database. Useful for cursored buffers (followers, friends, users of a list and searches) + name str: The name for the buffer stored in the dictionary. + data list: A list with items and some information about cursors. + returns the number of items that have been added in this execution""" + num = 0 + if (name in self.db) == False: + self.db[name] = [] + objects = self.db[name] + for i in data: + 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 + self.db[name] = objects + return num - def order_direct_messages(self, data): - """ Add incoming and sent direct messages to their corresponding database items. - data list: A list of direct messages to add. - returns the number of incoming messages processed in this execution, and sends an event with data regarding amount of sent direct messages added.""" - incoming = 0 - sent = 0 - if ("direct_messages" in self.db) == False: - self.db["direct_messages"] = [] - 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 self.settings["general"]["reverse_timelines"] == False: self.db["sent_direct_messages"].append(i) - else: self.db["sent_direct_messages"].insert(0, i) - sent = sent+1 - else: - if utils.find_item(i.id, self.db["direct_messages"]) == None: - if self.settings["general"]["reverse_timelines"] == False: self.db["direct_messages"].append(i) - else: self.db["direct_messages"].insert(0, i) - incoming = incoming+1 - pub.sendMessage("sent-dms-updated", total=sent, account=self.db["user_name"]) - return incoming + def order_direct_messages(self, data): + """ Add incoming and sent direct messages to their corresponding database items. + data list: A list of direct messages to add. + returns the number of incoming messages processed in this execution, and sends an event with data regarding amount of sent direct messages added.""" + incoming = 0 + sent = 0 + if ("direct_messages" in self.db) == False: + self.db["direct_messages"] = [] + if ("sent_direct_messages" in self.db) == False: + self.db["sent_direct_messages"] = [] + objects = self.db["direct_messages"] + sent_objects = self.db["sent_direct_messages"] + 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, 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, self.db["direct_messages"]) == None: + if self.settings["general"]["reverse_timelines"] == False: objects.append(i) + else: objects.insert(0, i) + incoming = incoming+1 + self.db["direct_messages"] = objects - def __init__(self, *args, **kwargs): - super(Session, self).__init__(*args, **kwargs) - # Adds here the optional cursors objects. - cursors = dict(direct_messages=-1) - self.db["cursors"] = cursors - self.reconnection_function_active = False - self.counter = 0 - self.lists = [] + self.db["sent_direct_messages"] = sent_objects + pub.sendMessage("sent-dms-updated", total=sent, account=self.db["user_name"]) + + return incoming + + def __init__(self, *args, **kwargs): + super(Session, self).__init__(*args, **kwargs) + # Adds here the optional cursors objects. + cursors = dict(direct_messages=-1) + self.db["cursors"] = cursors + self.reconnection_function_active = False + self.counter = 0 + self.lists = [] + # As users are cached for accessing them with not too many twitter calls, + # there could be a weird situation where a deleted user who sent direct messages to the current account will not be able to be retrieved at twitter. + # So we need to store an "user deleted" object in the cache, but have the ID of the deleted user in a local reference. + # This will be especially useful because if the user reactivates their account later, TWblue will try to retrieve such user again at startup. + # If we wouldn't implement this approach, TWBlue would save permanently the "deleted user" object. + self.deleted_users = {} + self.type = "twitter" + pub.subscribe(self.handle_new_status, "newStatus") + pub.subscribe(self.handle_connected, "streamConnected") # @_require_configuration - def login(self, verify_credentials=True): - """ Log into twitter using credentials from settings. - if the user account isn't authorised, it needs to call self.authorise() before login.""" - if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None: - try: - log.debug("Logging in to twitter...") - self.auth = tweepy.OAuthHandler(keyring.get("api_key"), keyring.get("api_secret")) - self.auth.set_access_token(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"]) - self.twitter = tweepy.API(self.auth) - if verify_credentials == True: - self.credentials = self.twitter.verify_credentials() - self.logged = True - log.debug("Logged.") - self.counter = 0 - except IOError: - log.error("The login attempt failed.") - self.logged = False - else: - self.logged = False - raise Exceptions.RequireCredentialsSessionError + def login(self, verify_credentials=True): + """ Log into twitter using credentials from settings. + if the user account isn't authorised, it needs to call self.authorise() before login.""" + if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None: + try: + log.debug("Logging in to twitter...") + self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) + self.auth.set_access_token(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"]) + self.twitter = tweepy.API(self.auth) + self.twitter_v2 = tweepy.Client(consumer_key=appkeys.twitter_api_key, consumer_secret=appkeys.twitter_api_secret, access_token=self.settings["twitter"]["user_key"], access_token_secret=self.settings["twitter"]["user_secret"]) + if verify_credentials == True: + self.credentials = self.twitter.verify_credentials() + self.logged = True + log.debug("Logged.") + self.counter = 0 + except IOError: + log.error("The login attempt failed.") + self.logged = False + else: + self.logged = False + raise Exceptions.RequireCredentialsSessionError # @_require_configuration - def authorise(self): - """ Authorises a Twitter account. This function needs to be called for each new session, after self.get_configuration() and before self.login()""" - if self.logged == True: - raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.") - else: - self.auth = tweepy.OAuthHandler(keyring.get("api_key"), keyring.get("api_secret")) - redirect_url = self.auth.get_authorization_url() - webbrowser.open_new_tab(redirect_url) - self.authorisation_dialog = authorisationDialog() - self.authorisation_dialog.cancel.Bind(wx.EVT_BUTTON, self.authorisation_cancelled) - self.authorisation_dialog.ok.Bind(wx.EVT_BUTTON, self.authorisation_accepted) - self.authorisation_dialog.ShowModal() + def authorise(self): + """ Authorises a Twitter account. This function needs to be called for each new session, after self.get_configuration() and before self.login()""" + if self.logged == True: + raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.") + else: + self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) + redirect_url = self.auth.get_authorization_url() + webbrowser.open_new_tab(redirect_url) + self.authorisation_dialog = authorisationDialog() + self.authorisation_dialog.cancel.Bind(wx.EVT_BUTTON, self.authorisation_cancelled) + self.authorisation_dialog.ok.Bind(wx.EVT_BUTTON, self.authorisation_accepted) + self.authorisation_dialog.ShowModal() - def verify_authorisation(self, pincode): - self.auth.get_access_token(pincode) - self.settings["twitter"]["user_key"] = self.auth.access_token - self.settings["twitter"]["user_secret"] = self.auth.access_token_secret - self.settings.write() - del self.auth + def verify_authorisation(self, pincode): + self.auth.get_access_token(pincode) + self.settings["twitter"]["user_key"] = self.auth.access_token + self.settings["twitter"]["user_secret"] = self.auth.access_token_secret + self.settings.write() + del self.auth - def authorisation_cancelled(self, *args, **kwargs): - """ Destroy the authorization dialog. """ - self.authorisation_dialog.Destroy() - del self.authorisation_dialog + def authorisation_cancelled(self, *args, **kwargs): + """ Destroy the authorization dialog. """ + self.authorisation_dialog.Destroy() + del self.authorisation_dialog - def authorisation_accepted(self, *args, **kwargs): - """ Gets the PIN code entered by user and validate it through Twitter.""" - pincode = self.authorisation_dialog.text.GetValue() - self.verify_authorisation(pincode) - self.authorisation_dialog.Destroy() + def authorisation_accepted(self, *args, **kwargs): + """ Gets the PIN code entered by user and validate it through Twitter.""" + pincode = self.authorisation_dialog.text.GetValue() + self.verify_authorisation(pincode) + self.authorisation_dialog.Destroy() - def get_more_items(self, update_function, users=False, dm=False, name=None, *args, **kwargs): - """ Get more items for twitter objects. - update_function str: function to call for getting more items. Must be member of self.twitter. - users, dm bool: If any of these is set to True, the function will treat items as users or dm (they need different handling). - name str: name of the database item to put new element in.""" - results = [] - if "cursor" in kwargs and kwargs["cursor"] == 0: - output.speak(_(u"There are no more items to retrieve in this buffer.")) - return - data = getattr(self.twitter, update_function)(*args, **kwargs) - if users == True: - if type(data) == dict and "next_cursor" in data: - if "next_cursor" in data: # There are more objects to retrieve. - self.db[name]["cursor"] = data["next_cursor"] - else: # Set cursor to 0, wich means no more items available. - self.db[name]["cursor"] = 0 - for i in data["users"]: results.append(i) - elif type(data) == list: - results.extend(data[1:]) - elif dm == True: - if "next_cursor" in data: # There are more objects to retrieve. - self.db[name]["cursor"] = data["next_cursor"] - else: # Set cursor to 0, wich means no more items available. - self.db[name]["cursor"] = 0 - for i in data["events"]: results.append(i) - else: - results.extend(data[1:]) - return results - - def api_call(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs): - """ Make a call to the Twitter API. If there is a connectionError or another exception not related to Twitter, It will call the method again at least 25 times, waiting a while between calls. Useful for post methods. - If twitter returns an error, it will not call the method anymore. - call_name str: The method to call - action str: What you are doing on twitter, it will be reported to the user if report_success is set to True. - for example "following @tw_blue2" will be reported as "following @tw_blue2 succeeded". - _sound str: a sound to play if the call is executed properly. - report_success and report_failure bool: These are self explanatory. True or False. - preexec_message str: A message to speak to the user while the method is running, example: "trying to follow x user".""" - finished = False - tries = 0 - if preexec_message: - output.speak(preexec_message, True) - while finished==False and tries < 25: - try: - val = getattr(self.twitter, call_name)(*args, **kwargs) - finished = True - except TweepError as e: - output.speak(e.reason) - val = None - if e.error_code != 403 and e.error_code != 404: - tries = tries+1 - time.sleep(5) - elif report_failure and hasattr(e, 'reason'): - output.speak(_("%s failed. Reason: %s") % (action, e.reason)) - finished = True + def api_call(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs): + """ Make a call to the Twitter API. If there is a connectionError or another exception not related to Twitter, It will call the method again at least 25 times, waiting a while between calls. Useful for post methods. + If twitter returns an error, it will not call the method anymore. + call_name str: The method to call + action str: What you are doing on twitter, it will be reported to the user if report_success is set to True. + for example "following @tw_blue2" will be reported as "following @tw_blue2 succeeded". + _sound str: a sound to play if the call is executed properly. + report_success and report_failure bool: These are self explanatory. True or False. + preexec_message str: A message to speak to the user while the method is running, example: "trying to follow x user".""" + finished = False + tries = 0 + if preexec_message: + output.speak(preexec_message, True) + while finished==False and tries < 25: + try: + val = getattr(self.twitter, call_name)(*args, **kwargs) + finished = True + except TweepyException as e: + output.speak(str(e)) + val = None + if type(e) != NotFound and type(e) != Forbidden: + tries = tries+1 + time.sleep(5) + elif report_failure: + output.speak(_("%s failed. Reason: %s") % (action, str(e))) + finished = True # except: # tries = tries + 1 # time.sleep(5) - if report_success: - output.speak(_("%s succeeded.") % action) - if _sound != None: self.sound.play(_sound) - return val + if report_success: + output.speak(_("%s succeeded.") % action) + if _sound != None: self.sound.play(_sound) + return val - def search(self, name, *args, **kwargs): - """ Search in twitter, passing args and kwargs as arguments to the Twython function.""" - tl = self.twitter.search(*args, **kwargs) - tl.reverse() - return tl + def api_call_v2(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs): + finished = False + tries = 0 + if preexec_message: + output.speak(preexec_message, True) + while finished==False and tries < 25: + try: + val = getattr(self.twitter_v2, call_name)(*args, **kwargs) + finished = True + except TweepyException as e: + log.exception("Error sending the tweet.") + output.speak(str(e)) + val = None + if type(e) != NotFound and type(e) != Forbidden: + tries = tries+1 + time.sleep(5) + elif report_failure: + output.speak(_("%s failed. Reason: %s") % (action, str(e))) + finished = True + if report_success: + output.speak(_("%s succeeded.") % action) + if _sound != None: self.sound.play(_sound) + return val + + def search(self, name, *args, **kwargs): + """ Search in twitter, passing args and kwargs as arguments to the Twython function.""" + tl = self.twitter.search_tweets(*args, **kwargs) + tl.reverse() + return tl # @_require_login - def get_favourites_timeline(self, name, *args, **kwargs): - """ Gets favourites for the authenticated user or a friend or follower. - name str: Name for storage in the database. - args and kwargs are passed directly to the Twython function.""" - tl = self.call_paged("favorites", *args, **kwargs) - return self.order_buffer(name, tl) + def get_favourites_timeline(self, name, *args, **kwargs): + """ Gets favourites for the authenticated user or a friend or follower. + name str: Name for storage in the database. + args and kwargs are passed directly to the Twython function.""" + tl = self.call_paged("favorites", *args, **kwargs) + return self.order_buffer(name, tl) - def call_paged(self, update_function, *args, **kwargs): - """ Makes a call to the Twitter API methods several times. Useful for get methods. - this function is needed for retrieving more than 200 items. - update_function str: The function to call. This function must be child of self.twitter - args and kwargs are passed to update_function. - returns a list with all items retrieved.""" - max = 0 - results = [] - data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) - results.extend(data) - for i in range(0, max): - if i == 0: max_id = results[-1].id - else: max_id = results[0].id - data = getattr(self.twitter, update_function)(max_id=max_id, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) - results.extend(data) - results.reverse() - return results + def call_paged(self, update_function, *args, **kwargs): + """ Makes a call to the Twitter API methods several times. Useful for get methods. + this function is needed for retrieving more than 200 items. + update_function str: The function to call. This function must be child of self.twitter + args and kwargs are passed to update_function. + returns a list with all items retrieved.""" + max = 0 + results = [] + data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) + results.extend(data) + for i in range(0, max): + if i == 0: max_id = results[-1].id + else: max_id = results[0].id + data = getattr(self.twitter, update_function)(max_id=max_id, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) + results.extend(data) + results.reverse() + return results # @_require_login - def get_user_info(self): - """ Retrieves some information required by TWBlue for setup.""" - f = self.twitter.get_settings() - sn = f["screen_name"] - self.settings["twitter"]["user_name"] = sn - self.db["user_name"] = sn - self.db["user_id"] = self.twitter.get_user(screen_name=sn).id - try: - self.db["utc_offset"] = f["time_zone"]["utc_offset"] - except KeyError: - self.db["utc_offset"] = -time.timezone - # Get twitter's supported languages and save them in a global variable - #so we won't call to this method once per session. - if len(application.supported_languages) == 0: - application.supported_languages = self.twitter.supported_languages() - self.get_lists() - self.get_muted_users() - self.settings.write() + def get_user_info(self): + """ Retrieves some information required by TWBlue for setup.""" + f = self.twitter.get_settings() + sn = f["screen_name"] + self.settings["twitter"]["user_name"] = sn + self.db["user_name"] = sn + self.db["user_id"] = self.twitter.get_user(screen_name=sn).id + try: + self.db["utc_offset"] = f["time_zone"]["utc_offset"] + except KeyError: + self.db["utc_offset"] = -time.timezone + # Get twitter's supported languages and save them in a global variable + #so we won't call to this method once per session. + if len(application.supported_languages) == 0: + application.supported_languages = self.twitter.supported_languages() + self.get_lists() + self.get_muted_users() + self.settings.write() # @_require_login - def get_lists(self): - """ Gets the lists that the user is subscribed to and stores them in the database. Returns None.""" - self.db["lists"] = self.twitter.lists_all(reverse=True) + def get_lists(self): + """ Gets the lists that the user is subscribed to and stores them in the database. Returns None.""" + self.db["lists"] = self.twitter.get_lists(reverse=True) # @_require_login - def get_muted_users(self): - """ Gets muted users (oh really?).""" - self.db["muted_users"] = self.twitter.mutes_ids + def get_muted_users(self): + """ Gets muted users (oh really?).""" + self.db["muted_users"] = self.twitter.get_muted_ids() # @_require_login - def get_stream(self, name, function, *args, **kwargs): - """ Retrieves the items for a regular stream. - name str: Name to save items to the database. - function str: A function to get the items.""" - last_id = -1 - if name in self.db: - try: - if self.db[name][0]["id"] > self.db[name][-1]["id"]: - last_id = self.db[name][0]["id"] - else: - last_id = self.db[name][-1]["id"] - except IndexError: - pass - tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs) - self.order_buffer(name, tl) + def get_stream(self, name, function, *args, **kwargs): + """ Retrieves the items for a regular stream. + name str: Name to save items to the database. + function str: A function to get the items.""" + last_id = -1 + if name in self.db: + try: + if self.db[name][0]["id"] > self.db[name][-1]["id"]: + last_id = self.db[name][0]["id"] + else: + last_id = self.db[name][-1]["id"] + except IndexError: + pass + tl = self.call_paged(function, sinze_id=last_id, *args, **kwargs) + self.order_buffer(name, tl) - def get_cursored_stream(self, name, function, items="users", get_previous=False, *args, **kwargs): - """ Gets items for API calls that require using cursors to paginate the results. - name str: Name to save it in the database. - function str: Function that provides the items. - items: When the function returns the list with results, items will tell how the order function should be look. for example get_followers_list returns a list and users are under list["users"], here the items should point to "users". - get_previous bool: wether this function will be used to get previous items in a buffer or load the buffer from scratch. - returns number of items retrieved.""" - items_ = [] - try: - if "cursor" in self.db[name] and get_previous: - cursor = self.db[name]["cursor"] - else: - cursor = -1 - except KeyError: - cursor = -1 - if cursor != -1: - tl = getattr(self.twitter, function)(cursor=cursor, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) - else: - tl = getattr(self.twitter, function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) - tl[items].reverse() - num = self.order_cursored_buffer(name, tl[items]) - # Recently, Twitter's new endpoints have cursor if there are more results. - if "next_cursor" in tl: - self.db[name]["cursor"] = tl["next_cursor"] - else: - self.db[name]["cursor"] = 0 - return num + def get_cursored_stream(self, name, function, items="users", get_previous=False, *args, **kwargs): + """ Gets items for API calls that require using cursors to paginate the results. + name str: Name to save it in the database. + function str: Function that provides the items. + items: When the function returns the list with results, items will tell how the order function should be look. for example get_followers_list returns a list and users are under list["users"], here the items should point to "users". + get_previous bool: wether this function will be used to get previous items in a buffer or load the buffer from scratch. + returns number of items retrieved.""" + items_ = [] + try: + if "cursor" in self.db[name] and get_previous: + cursor = self.db[name]["cursor"] + else: + cursor = -1 + except KeyError: + cursor = -1 + if cursor != -1: + tl = getattr(self.twitter, function)(cursor=cursor, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) + else: + tl = getattr(self.twitter, function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) + tl[items].reverse() + num = self.order_cursored_buffer(name, tl[items]) + # Recently, Twitter's new endpoints have cursor if there are more results. + if "next_cursor" in tl: + self.db[name]["cursor"] = tl["next_cursor"] + else: + self.db[name]["cursor"] = 0 + return num - def check_connection(self): - """ Restart the Twitter object every 5 executions. It is useful for dealing with requests timeout and other oddities.""" - log.debug("Executing check connection...") - self.counter += 1 - if self.counter >= 4: - log.debug("Restarting connection after 5 minutes.") - del self.twitter - self.logged = False - self.login(False) - self.counter = 0 + def check_connection(self): + """ Restart the Twitter object every 5 executions. It is useful for dealing with requests timeout and other oddities.""" + log.debug("Executing check connection...") + self.counter += 1 + if self.counter >= 4: + log.debug("Restarting connection after 5 minutes.") + del self.twitter + self.logged = False + self.login(False) + self.counter = 0 - def check_quoted_status(self, tweet): - """ Helper for get_quoted_tweet. Get a quoted status inside a tweet and create a special tweet with all info available. - tweet dict: A tweet dictionary. - Returns a quoted tweet or the original tweet if is not a quote""" - status = tweets.is_long(tweet) - if status != False and config.app["app-settings"]["handle_longtweets"]: - quoted_tweet = self.get_quoted_tweet(tweet) - return quoted_tweet - return tweet + def check_quoted_status(self, tweet): + """ Helper for get_quoted_tweet. Get a quoted status inside a tweet and create a special tweet with all info available. + tweet dict: A tweet dictionary. + Returns a quoted tweet or the original tweet if is not a quote""" + status = tweets.is_long(tweet) + if status != False and config.app["app-settings"]["handle_longtweets"]: + quoted_tweet = self.get_quoted_tweet(tweet) + return quoted_tweet + return tweet - def get_quoted_tweet(self, tweet): - """ Process a tweet and extract all information related to the quote.""" - quoted_tweet = tweet - if hasattr(tweet, "full_text"): - value = "full_text" - else: - value = "text" - setattr(quoted_tweet, value, utils.expand_urls(getattr(quoted_tweet, value), quoted_tweet.entities)) - if hasattr(quoted_tweet, "quoted_status"): - original_tweet = quoted_tweet.quoted_status - elif hasattr(quoted_tweet, "retweeted_status") and hasattr(quoted_tweet.retweeted_status, "quoted_status"): - original_tweet = quoted_tweet.retweeted_status.quoted_status - else: - return quoted_tweet - original_tweet = self.check_long_tweet(original_tweet) - if hasattr(original_tweet, "full_text"): - value = "full_text" - elif hasattr(original_tweet, "message"): - value = "message" - else: - value = "text" - setattr(original_tweet, value, utils.expand_urls(getattr(original_tweet, value), original_tweet.entities)) - return compose.compose_quoted_tweet(quoted_tweet, original_tweet) + def get_quoted_tweet(self, tweet): + """ Process a tweet and extract all information related to the quote. """ + quoted_tweet = tweet + if hasattr(tweet, "full_text"): + value = "full_text" + else: + value = "text" + if hasattr(quoted_tweet, "entities"): + setattr(quoted_tweet, value, utils.expand_urls(getattr(quoted_tweet, value), quoted_tweet.entities)) + if hasattr(quoted_tweet, "is_quote_status") == True and hasattr(quoted_tweet, "quoted_status"): + original_tweet = quoted_tweet.quoted_status + elif hasattr(quoted_tweet, "retweeted_status") and hasattr(quoted_tweet.retweeted_status, "is_quote_status") == True and hasattr(quoted_tweet.retweeted_status, "quoted_status"): + original_tweet = quoted_tweet.retweeted_status.quoted_status + else: + return quoted_tweet + original_tweet = self.check_long_tweet(original_tweet) + if hasattr(original_tweet, "full_text"): + value = "full_text" + elif hasattr(original_tweet, "message"): + value = "message" + else: + value = "text" + if hasattr(original_tweet, "entities"): + setattr(original_tweet, value, utils.expand_urls(getattr(original_tweet, value), original_tweet.entities)) + # ToDo: Shall we check whether we should add show_screen_names here? + return compose.compose_quoted_tweet(quoted_tweet, original_tweet, session=self) - def check_long_tweet(self, tweet): - """ Process a tweet and add extra info if it's a long tweet made with Twyshort. - tweet dict: a tweet object. - returns a tweet with a new argument message, or original tweet if it's not a long tweet.""" - long = twishort.is_long(tweet) - if long != False and config.app["app-settings"]["handle_longtweets"]: - message = twishort.get_full_text(long) - if hasattr(tweet, "quoted_status"): - tweet.quoted_status.message = message - if tweet.quoted_status.message == False: return False - tweet.quoted_status.twishort = True - for i in tweet.quoted_status.entities["user_mentions"]: - if "@%s" % (i["screen_name"]) not in tweet.quoted_status.message and i["screen_name"] != tweet.user.screen_name: - if hasattr(tweet["quoted_status"], "retweeted_status") and tweet.retweeted_status.user.screen_name == i["screen_name"]: - continue - tweet.quoted_status.message = u"@%s %s" % (i["screen_name"], tweet.message) - else: - tweet.message = message - if tweet.message == False: return False - tweet.twishort = True - for i in tweet.entities["user_mentions"]: - if "@%s" % (i["screen_name"]) not in tweet.message and i["screen_name"] != tweet.user.screen_name: - if hasattr(tweet, "retweeted_status") and tweet.retweeted_status.user.screen_name == i["screen_name"]: - continue - return tweet + def check_long_tweet(self, tweet): + """ Process a tweet and add extra info if it's a long tweet made with Twyshort. + tweet dict: a tweet object. + returns a tweet with a new argument message, or original tweet if it's not a long tweet.""" + long = False + if hasattr(tweet, "entities") and tweet.entities.get("urls"): + long = twishort.is_long(tweet) + if long != False and config.app["app-settings"]["handle_longtweets"]: + message = twishort.get_full_text(long) + if hasattr(tweet, "quoted_status"): + tweet.quoted_status.message = message + if tweet.quoted_status.message == False: return False + tweet.quoted_status.twishort = True + if hasattr(tweet.quoted_status, "entities") and tweet.quoted_status.entities.get("user_mentions"): + for i in tweet.quoted_status.entities["user_mentions"]: + if "@%s" % (i["screen_name"]) not in tweet.quoted_status.message and i["screen_name"] != self.get_user(tweet.user).screen_name: + if hasattr(tweet.quoted_status, "retweeted_status") and self.get_user(tweet.retweeted_status.user).screen_name == i["screen_name"]: + continue + tweet.quoted_status.message = u"@%s %s" % (i["screen_name"], tweet.message) + else: + tweet.message = message + if tweet.message == False: return False + tweet.twishort = True + if hasattr(tweet, "entities") and tweet.entities.get("user_mentions"): + for i in tweet.entities["user_mentions"]: + if "@%s" % (i["screen_name"]) not in tweet.message and i["screen_name"] != self.get_user(tweet.user).screen_name: + if hasattr(tweet, "retweeted_status") and self.get_user(tweet.retweeted_status.user).screen_name == i["screen_name"]: + continue + tweet.message = u"@%s %s" % (i["screen_name"], tweet.message) + return tweet - def get_user(self, id): - """ Returns an user object associated with an ID. - id str: User identifier, provided by Twitter. - returns an user dict.""" - if ("users" in self.db) == False or (id in self.db["users"]) == False: - try: - user = self.twitter.get_user(id=id) - except TweepError as err: - user = dict(screen_name="deleted_account", name="Deleted account") - return user - self.db["users"][user.id_str] = user - return user - else: - return self.db["users"][id] + def get_user(self, id): + """ Returns an user object associated with an ID. + id str: User identifier, provided by Twitter. + returns a tweepy user object.""" + if hasattr(id, "id_str"): + log.error("Called get_user function by passing a full user id as a parameter.") + id = id.id_str + # Check if the user has been added to the list of deleted users previously. + if id in self.deleted_users: + log.debug("Returning user {} from the list of deleted users.".format(id)) + return self.deleted_users[id] + if ("users" in self.db) == False or (str(id) in self.db["users"]) == False: + log.debug("Requesting user id {} as it is not present in the users database.".format(id)) + try: + user = self.twitter.get_user(id=id) + except TweepyException as err: + user = UserModel(None) + user.screen_name = "deleted_user" + user.id = id + user.name = _("Deleted account") + if type(err) == NotFound: + self.deleted_users[id] = user + return user + else: + log.exception("Error when attempting to retrieve an user from Twitter.") + return user + users = self.db["users"] + users[user.id_str] = user + self.db["users"] = users + user.name = self.get_user_alias(user) + return user + else: + user = self.db["users"][str(id)] + user.name = self.get_user_alias(user) + return user - def get_user_by_screen_name(self, screen_name): - """ Returns an user identifier associated with a screen_name. - screen_name str: User name, such as tw_blue2, provided by Twitter. - returns an user ID.""" - if ("users" in self.db) == False: - user = utils.if_user_exists(self.twitter, screen_name) - self.db["users"][user["id_str"]] = user - return user["id_str"] - else: - for i in list(self.db["users"].keys()): - if self.db["users"][i].screen_name == screen_name: - return self.db["users"][i].id_str - user = utils.if_user_exists(self.twitter, screen_name) - self.db["users"][user.id_str] = user - return user.id_str \ No newline at end of file + 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. + screen_name str: User name, such as tw_blue2, provided by Twitter. + returns an user ID.""" + if ("users" in self.db) == False: + user = utils.if_user_exists(self.twitter, screen_name) + users = self.db["users"] + users[user["id"]] = user + self.db["users"] = users + return user["id"] + else: + for i in list(self.db["users"].keys()): + if self.db["users"][i].screen_name == screen_name: + return self.db["users"][i].id + user = utils.if_user_exists(self.twitter, screen_name) + users = self.db["users"] + users[user.id] = user + self.db["users"] = users + return user.id + + def save_users(self, user_ids): + """ Adds all new users to the users database. """ + if len(user_ids) == 0: + return + log.debug("Received %d user IDS to be added in the database." % (len(user_ids))) + users_to_retrieve = [user_id for user_id in user_ids if (user_id not in self.db["users"] and user_id not in self.deleted_users)] + # Remove duplicates + users_to_retrieve = list(dict.fromkeys(users_to_retrieve)) + if len(users_to_retrieve) == 0: + return + log.debug("TWBlue will get %d new users from Twitter." % (len(users_to_retrieve))) + try: + users = self.twitter.lookup_users(user_id=users_to_retrieve, tweet_mode="extended") + users_db = self.db["users"] + for user in users: + users_db[user.id_str] = user + log.debug("Added %d new users" % (len(users))) + self.db["users"] = users_db + except TweepyException as err: + if type(err) == NotFound: # User not found. + log.error("The specified users {} were not found in twitter.".format(user_ids)) + # Creates a deleted user object for every user_id not found here. + # This will make TWBlue to not waste Twitter API calls when attempting to retrieve those users again. + # As deleted_users is not saved across restarts, when restarting TWBlue, it will retrieve the correct users if they enabled their accounts. + for id in users_to_retrieve: + user = UserModel(None) + user.screen_name = "deleted_user" + user.id = id + user.name = _("Deleted account") + self.deleted_users[id] = user + else: + log.exception("An exception happened while attempting to retrieve a list of users from direct messages in Twitter.") + + def add_users_from_results(self, data): + users = self.db["users"] + for i in data: + if hasattr(i, "user"): + if isinstance(i.user, str): + log.warning("A String was passed to be added as an user. This is normal only if TWBlue tried to load a conversation.") + continue + if (i.user.id_str in self.db["users"]) == False: + users[i.user.id_str] = i.user + if hasattr(i, "quoted_status") and (i.quoted_status.user.id_str in self.db["users"]) == False: + users[i.quoted_status.user.id_str] = i.quoted_status.user + + if hasattr(i, "retweeted_status") and (i.retweeted_status.user.id_str in self.db["users"]) == False: + users[i.retweeted_status.user.id_str] = i.retweeted_status.user + self.db["users"] = users + + def start_streaming(self): + if config.app["app-settings"]["no_streaming"]: + return + self.stream = streaming.Stream(twitter_api=self.twitter, user=self.db["user_name"], user_id=self.db["user_id"], muted_users=self.db["muted_users"], consumer_key=appkeys.twitter_api_key, consumer_secret=appkeys.twitter_api_secret, access_token=self.settings["twitter"]["user_key"], access_token_secret=self.settings["twitter"]["user_secret"], chunk_size=1025) + self.stream_thread = call_threaded(self.stream.filter, follow=self.stream.users, stall_warnings=True) + + def stop_streaming(self): + if config.app["app-settings"]["no_streaming"]: + return + if hasattr(self, "stream"): + self.stream.running = False + log.debug("Stream stopped for accounr {}".format(self.db["user_name"])) + + def handle_new_status(self, status, user): + """ Handles a new status present in the Streaming API. """ + if self.logged == False: + return + # Discard processing the status if the streaming sends a tweet for another account. + if self.db["user_name"] != user: + return + # the Streaming API sends non-extended tweets with an optional parameter "extended_tweets" which contains full_text and other data. + # so we have to make sure we check it before processing the normal status. + # As usual, we handle also quotes and retweets at first. + if hasattr(status, "retweeted_status") and hasattr(status.retweeted_status, "extended_tweet"): + status.retweeted_status._json = {**status.retweeted_status._json, **status.retweeted_status._json["extended_tweet"]} + # compose.compose_tweet requires the parent tweet to have a full_text field, so we have to add it to retweets here. + status._json["full_text"] = status._json["text"] + if hasattr(status, "quoted_status") and hasattr(status.quoted_status, "extended_tweet"): + status.quoted_status._json = {**status.quoted_status._json, **status.quoted_status._json["extended_tweet"]} + if status.truncated: + status._json = {**status._json, **status._json["extended_tweet"]} + # Sends status to database, where it will be reduced and changed according to our needs. + buffers_to_send = [] + if status.user.id_str in self.stream.users: + buffers_to_send.append("home_timeline") + if status.user.id == self.db["user_id"]: + buffers_to_send.append("sent_tweets") + for user in status.entities["user_mentions"]: + if user["id"] == self.db["user_id"]: + buffers_to_send.append("mentions") + users_with_timeline = [user.split("-")[0] for user in self.db.keys() if user.endswith("-timeline")] + for user in users_with_timeline: + if status.user.id_str == user: + buffers_to_send.append("{}-timeline".format(user)) + for buffer in buffers_to_send[::]: + num = self.order_buffer(buffer, [status]) + if num == 0: + buffers_to_send.remove(buffer) + # However, we have to do the "reduce and change" process here because the status we sent to the db is going to be a different object that the one sent to database. + status = reduce.reduce_tweet(status) + status = self.check_quoted_status(status) + status = self.check_long_tweet(status) + # Send it to the main controller object. + pub.sendMessage("newTweet", data=status, user=self.db["user_name"], _buffers=buffers_to_send) + + def check_streams(self): + if config.app["app-settings"]["no_streaming"]: + return + if not hasattr(self, "stream"): + return + log.debug("Status of running stream for user {}: {}".format(self.db["user_name"], self.stream.running)) + if self.stream.running == False: + self.start_streaming() + + def handle_connected(self, user): + if self.logged == False: + return + if user != self.db["user_name"]: + log.debug("Connected streaming endpoint on account {}".format(user)) + + def send_tweet(self, *tweets): + """ Convenience function to send a thread. """ + in_reply_to_status_id = None + for obj in tweets: + # When quoting a tweet, the tweet_data dict might contain a parameter called quote_tweet_id. Let's add it, or None, so quotes will be posted successfully. + if len(obj["attachments"]) == 0: + item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) + in_reply_to_status_id = item.data["id"] + else: + media_ids = [] + for i in obj["attachments"]: + img = self.api_call("media_upload", filename=i["file"]) + if i["type"] == "photo": + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + media_ids.append(img.media_id) + item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) + in_reply_to_status_id = item.data["id"] + + def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): + if len(attachments) == 0: + item = self.api_call_v2(call_name="create_tweet", text=text, _sound="reply_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, *args, **kwargs) + else: + media_ids = [] + for i in attachments: + img = self.api_call("media_upload", filename=i["file"]) + if i["type"] == "photo": + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + media_ids.append(img.media_id) + item = self.api_call_v2(call_name="create_tweet", text=text, _sound="reply_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) + + def direct_message(self, text, recipient, attachment=None, *args, **kwargs): + if attachment == None: + item = self.api_call(call_name="send_direct_message", recipient_id=recipient, text=text) + else: + if attachment["type"] == "photo": + media_category = "DmImage" + elif attachment["type"] == "gif": + media_category = "DmGif" + elif attachment["type"] == "video": + media_category = "DmVideo" + media = self.api_call("media_upload", filename=attachment["file"], media_category=media_category) + item = self.api_call(call_name="send_direct_message", recipient_id=recipient, text=text, attachment_type="media", attachment_media_id=media.media_id) + if item != None: + sent_dms = self.db["sent_direct_messages"] + if self.settings["general"]["reverse_timelines"] == False: + sent_dms.append(item) + else: + sent_dms.insert(0, item) + self.db["sent_direct_messages"] = sent_dms + pub.sendMessage("sent-dm", data=item, user=self.db["user_name"]) diff --git a/src/sessions/twitter/streaming.py b/src/sessions/twitter/streaming.py new file mode 100644 index 00000000..137147fc --- /dev/null +++ b/src/sessions/twitter/streaming.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +""" Streaming support for TWBlue. """ +import time +import sys +import six +import requests +import urllib3 +import ssl +import tweepy +import logging +from pubsub import pub + +log = logging.getLogger("sessions.twitter.streaming") + +class Stream(tweepy.Stream): + + def __init__(self, twitter_api, user, user_id, muted_users=[], *args, **kwargs): + super(Stream, self).__init__(*args, **kwargs) + log.debug("Starting streaming listener for account {}".format(user)) + self.started = False + self.users = [] + self.api = twitter_api + self.user = user + self.user_id = user_id + friends = self.api.get_friend_ids() + log.debug("Retrieved {} friends to add to the streaming listener.".format(len(friends))) + self.users.append(str(self.user_id)) + log.debug("Got {} muted users.".format(len(muted_users))) + for user in friends: + if user not in muted_users: + self.users.append(str(user)) + self.started = True + log.debug("Streaming listener started with {} users to follow.".format(len(self.users))) + + def on_connect(self): + pub.sendMessage("streamConnected", user=self.user) + + def on_exception(self, ex): + log.exception("Exception received on streaming endpoint for user {}".format(self.user)) + + def on_status(self, status): + """ Checks data arriving as a tweet. """ + # Hide replies to users not followed by current account. + if status.in_reply_to_user_id_str != None and status.in_reply_to_user_id_str not in self.users and status.user.screen_name != self.user: + return + if status.user.id_str in self.users: + pub.sendMessage("newStatus", status=status, user=self.user) diff --git a/src/sessions/twitter/utils.py b/src/sessions/twitter/utils.py index 57e02f3a..47cef7a7 100644 --- a/src/sessions/twitter/utils.py +++ b/src/sessions/twitter/utils.py @@ -1,12 +1,10 @@ # -*- coding: utf-8 -*- -import url_shortener, re +import re import output -import config import logging import requests import time -import sound -from tweepy.error import TweepError +from tweepy.errors import TweepyException, NotFound, Forbidden log = logging.getLogger("twitter.utils") """ Some utilities for the twitter interface.""" @@ -19,198 +17,245 @@ url_re2 = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ \\n\\t]*") bad_chars = '\'\\\n.,[](){}:;"' def find_urls_in_text(text): - return url_re2.findall(text) + return url_re2.findall(text) -def find_urls (tweet): - urls = [] - # Let's add URLS from tweet entities. - if hasattr(tweet, "message_create"): - entities = tweet.message_create["message_data"]["entities"] - else: - entities = tweet.entities - for i in entities["urls"]: - if i["expanded_url"] not in urls: - urls.append(i["expanded_url"]) - if hasattr(tweet, "quoted_status"): - for i in tweet.quoted_status.entities["urls"]: - if i["expanded_url"] not in urls: - urls.append(i["expanded_url"]) - if hasattr(tweet, "retweeted_status"): - for i in tweet.retweeted_status.entities["urls"]: - if i["expanded_url"] not in urls: - urls.append(i["expanded_url"]) - if hasattr(tweet["retweeted_status"], "quoted_status"): - for i in tweet.retweeted_status.quoted_status.entities["urls"]: - if i["expanded_url"] not in urls: - urls.append(i["expanded_url"]) - if hasattr(tweet, "message"): - i = "message" - elif hasattr(tweet, "full_text"): - i = "full_text" - else: - i = "text" - if hasattr(tweet, "message_create"): - extracted_urls = find_urls_in_text(tweet.message_create["message_data"]["text"]) - else: - extracted_urls = find_urls_in_text(getattr(tweet, i)) - # Don't include t.co links (mostly they are photos or shortened versions of already added URLS). - for i in extracted_urls: - if i not in urls and "https://t.co" not in i: - urls.append(i) - return urls +def find_urls (tweet, twitter_media=False): + urls = [] + if twitter_media and hasattr(tweet, "extended_entities"): + for mediaItem in tweet.extended_entities["media"]: + if mediaItem["type"] == "video": + for variant in mediaItem["video_info"]["variants"]: + if variant["content_type"] == "video/mp4": + urls.append(variant["url"]) + break + # Let's add URLS from tweet entities. + if hasattr(tweet, "message_create"): + entities = tweet.message_create["message_data"]["entities"] + else: + if hasattr(tweet, "entities") == True: + entities = tweet.entities + if entities.get("urls") != None: + for i in entities["urls"]: + if i["expanded_url"] not in urls: + urls.append(i["expanded_url"]) + if hasattr(tweet, "quoted_status"): + urls.extend(find_urls(tweet.quoted_status, twitter_media)) + if hasattr(tweet, "retweeted_status"): + urls.extend(find_urls(tweet.retweeted_status, twitter_media)) + if hasattr(tweet, "message"): + i = "message" + elif hasattr(tweet, "full_text"): + i = "full_text" + else: + i = "text" + if hasattr(tweet, "message_create"): + extracted_urls = find_urls_in_text(tweet.message_create["message_data"]["text"]) + else: + extracted_urls = find_urls_in_text(getattr(tweet, i)) + # Don't include t.co links (mostly they are photos or shortened versions of already added URLS). + for i in extracted_urls: + if i not in urls and "https://t.co" not in i: + urls.append(i) + return urls -def find_item(id, listItem): - for i in range(0, len(listItem)): - if listItem[i].id == id: return i - return None +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): - for i in range(0, len(lists)): - if lists[i].name == name: return lists[i].id + for i in range(0, len(lists)): + if lists[i].name == name: return lists[i].id def is_audio(tweet): - try: - if len(find_urls(tweet)) < 1: - return False - if hasattr(tweet, "message_create"): - entities = tweet.message_create["message_data"]["entities"] - else: - entities = tweet.entities - if len(entities["hashtags"]) > 0: - for i in entities["hashtags"]: - if i["text"] == "audio": - return True - except IndexError: - print(tweet.entities["hashtags"]) - log.exception("Exception while executing is_audio hashtag algorithm") + if hasattr(tweet, "quoted_status") and hasattr(tweet.quoted_status, "extended_entities"): + result = is_audio(tweet.quoted_status) + if result != None: + return result + if hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "extended_entities"): + result = is_audio(tweet.retweeted_status) + if result == True: + return result + # Checks firstly for Twitter videos and audios. + if hasattr(tweet, "extended_entities"): + for mediaItem in tweet.extended_entities["media"]: + if mediaItem["type"] == "video": + return True + try: + if len(find_urls(tweet)) < 1: + return False + if hasattr(tweet, "message_create"): + entities = tweet.message_create["message_data"]["entities"] + else: + if hasattr(tweet, "entities") == False or tweet.entities.get("hashtags") == None: + return False + entities = tweet.entities + if len(entities["hashtags"]) > 0: + for i in entities["hashtags"]: + if i["text"] == "audio": + return True + except IndexError: + log.exception("Exception while executing is_audio hashtag algorithm") def is_geocoded(tweet): - if hasattr(tweet, "coordinates") and tweet.coordinates != None: - return True + if hasattr(tweet, "coordinates") and tweet.coordinates != None: + return True def is_media(tweet): - if hasattr(tweet, "message_create"): - entities = tweet.message_create["message_data"]["entities"] - else: - entities = tweet.entities - if entities.get("media") == None: - return False - for i in entities["media"]: - if i.get("type") != None and i.get("type") == "photo": - return True - return False + if hasattr(tweet, "message_create"): + entities = tweet.message_create["message_data"]["entities"] + else: + if hasattr(tweet, "entities") == False or tweet.entities.get("hashtags") == None: + return False + entities = tweet.entities + if entities.get("media") == None: + return False + for i in entities["media"]: + if i.get("type") != None and i.get("type") == "photo": + return True + return False def get_all_mentioned(tweet, conf, field="screen_name"): - """ Gets all users that have been mentioned.""" - results = [] - for i in tweet.entities["user_mentions"]: - if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet.user.screen_name: - if i.get(field) not in results: - results.append(i.get(field)) - return results + """ Gets all users that have been mentioned.""" + results = [] + if hasattr(tweet, "retweeted_status"): + results.extend(get_all_mentioned(tweet.retweeted_status, conf, field)) + if hasattr(tweet, "quoted_status"): + 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: + if i.get(field) not in results: + results.append(i.get(field)) + return results -def get_all_users(tweet, conf): - string = [] - if hasattr(tweet, "retweeted_status"): - string.append(tweet.user.screen_name) - tweet = tweet.retweeted_status - if hasattr(tweet, "sender"): - string.append(tweet.sender.screen_name) - else: - if tweet.user.screen_name != conf["user_name"]: - string.append(tweet.user.screen_name) - for i in tweet.entities["user_mentions"]: - if i["screen_name"] != conf["user_name"] and i["screen_name"] != tweet.user.screen_name: - if i["screen_name"] not in string: - string.append(i["screen_name"]) - if len(string) == 0: - string.append(tweet.user.screen_name) - return string +def get_all_users(tweet, session): + string = [] + user = session.get_user(tweet.user) + if user.screen_name != session.db["user_name"]: + string.append(user.screen_name) + if hasattr(tweet, "retweeted_status"): + string.extend(get_all_users(tweet.retweeted_status, session)) + if hasattr(tweet, "quoted_status"): + string.extend(get_all_users(tweet.quoted_status, session)) + if hasattr(tweet, "entities") and tweet.entities.get("user_mentions"): + for i in tweet.entities["user_mentions"]: + if i["screen_name"] != session.db["user_name"] and i["screen_name"] != user.screen_name: + if i["screen_name"] not in string: + string.append(i["screen_name"]) + # Attempt to remove duplicates, tipically caused by nested tweets. + string = list(dict.fromkeys(string)) + if len(string) == 0: + string.append(user.screen_name) + return string def if_user_exists(twitter, user): - try: - data = twitter.get_user(screen_name=user) - return data - except TweepError as err: - if err.api_code == 50: - return None - else: - return user + try: + data = twitter.get_user(screen_name=user) + return data + except TweepyException as err: + if type(err) == NotFound: + return None + else: + return user def is_allowed(tweet, settings, buffer_name): - clients = settings["twitter"]["ignored_clients"] - if hasattr(tweet, "sender"): return True - allowed = True - tweet_data = {} - if hasattr(tweet, "retweeted_status"): - tweet_data["retweet"] = True - if tweet.in_reply_to_status_id_str != None: - tweet_data["reply"] = True - if hasattr(tweet, "quoted_status"): - tweet_data["quote"] = True - if hasattr(tweet, "retweeted_status"): - tweet = tweet.retweeted_status - source = tweet.source - for i in clients: - if i.lower() == source.lower(): - return False - return filter_tweet(tweet, tweet_data, settings, buffer_name) + clients = settings["twitter"]["ignored_clients"] + if hasattr(tweet, "sender"): return True + allowed = True + tweet_data = {} + if hasattr(tweet, "retweeted_status"): + tweet_data["retweet"] = True + if hasattr(tweet, "in_reply_to_status_id"): + tweet_data["reply"] = True + if hasattr(tweet, "quoted_status"): + tweet_data["quote"] = True + if hasattr(tweet, "retweeted_status"): + tweet = tweet.retweeted_status + source = tweet.source + for i in clients: + if i.lower() == source.lower(): + return False + return filter_tweet(tweet, tweet_data, settings, buffer_name) def filter_tweet(tweet, tweet_data, settings, buffer_name): - if hasattr(tweet, "full_text"): - value = "full_text" - else: - value = "text" - for i in settings["filters"]: - if settings["filters"][i]["in_buffer"] == buffer_name: - regexp = settings["filters"][i]["regexp"] - word = settings["filters"][i]["word"] - # Added if/else for compatibility reasons. - if "allow_rts" in settings["filters"][i]: - allow_rts = settings["filters"][i]["allow_rts"] - else: - allow_rts = "True" - if "allow_quotes" in settings["filters"][i]: - allow_quotes = settings["filters"][i]["allow_quotes"] - else: - allow_quotes = "True" - if "allow_replies" in settings["filters"][i]: - allow_replies = settings["filters"][i]["allow_replies"] - else: - allow_replies = "True" - if allow_rts == "False" and "retweet" in tweet_data: - return False - if allow_quotes == "False" and "quote" in tweet_data: - return False - if allow_replies == "False" and "reply" in tweet_data: - return False - if word != "" and settings["filters"][i]["if_word_exists"]: - if word in getattr(tweet, value): - return False - elif word != "" and settings["filters"][i]["if_word_exists"] == False: - if word not in getattr(tweet, value): - return False - if settings["filters"][i]["in_lang"] == "True": - if getattr(tweet, lang) not in settings["filters"][i]["languages"]: - return False - elif settings["filters"][i]["in_lang"] == "False": - if tweet.lang in settings["filters"][i]["languages"]: - return False - return True + if hasattr(tweet, "full_text"): + value = "full_text" + else: + value = "text" + for i in settings["filters"]: + if settings["filters"][i]["in_buffer"] == buffer_name: + regexp = settings["filters"][i]["regexp"] + word = settings["filters"][i]["word"] + # Added if/else for compatibility reasons. + if "allow_rts" in settings["filters"][i]: + allow_rts = settings["filters"][i]["allow_rts"] + else: + allow_rts = "True" + if "allow_quotes" in settings["filters"][i]: + allow_quotes = settings["filters"][i]["allow_quotes"] + else: + allow_quotes = "True" + if "allow_replies" in settings["filters"][i]: + allow_replies = settings["filters"][i]["allow_replies"] + else: + allow_replies = "True" + if allow_rts == "False" and "retweet" in tweet_data: + return False + if allow_quotes == "False" and "quote" in tweet_data: + return False + if allow_replies == "False" and "reply" in tweet_data: + return False + if word != "" and settings["filters"][i]["if_word_exists"]: + if word in getattr(tweet, value): + return False + elif word != "" and settings["filters"][i]["if_word_exists"] == False: + if word not in getattr(tweet, value): + return False + if settings["filters"][i]["in_lang"] == "True": + if getattr(tweet, lang) not in settings["filters"][i]["languages"]: + return False + elif settings["filters"][i]["in_lang"] == "False": + if tweet.lang in settings["filters"][i]["languages"]: + return False + return True def twitter_error(error): - if error.api_code == 179: - msg = _(u"Sorry, you are not authorised to see this status.") - elif error.api_code == 144: - msg = _(u"No status found with that ID") - else: - msg = _(u"Error code {0}").format(error.api_code,) - output.speak(msg) + if type(error) == Forbidden: + msg = _(u"Sorry, you are not authorised to see this status.") + elif type(error) == NotFound: + msg = _(u"No status found with that ID") + else: + msg = _(u"Error {0}").format(str(error),) + output.speak(msg) def expand_urls(text, entities): - """ Expand all URLS present in text with information found in entities""" - urls = find_urls_in_text(text) - for url in entities["urls"]: - if url["url"] in text: - text = text.replace(url["url"], url["expanded_url"]) - return text + """ Expand all URLS present in text with information found in entities""" + if entities.get("urls") == None: + return text + urls = find_urls_in_text(text) + for url in entities["urls"]: + 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), "", 1) + total_users = total_users+1 + end = user.end() + if total_users-2 < 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 \ No newline at end of file diff --git a/src/sessions/twitter/wxUI.py b/src/sessions/twitter/wxUI.py index 787e6581..a765e72c 100644 --- a/src/sessions/twitter/wxUI.py +++ b/src/sessions/twitter/wxUI.py @@ -1,18 +1,18 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals import wx - + class authorisationDialog(wx.Dialog): - def __init__(self): - super(authorisationDialog, self).__init__(parent=None, title=_(u"Authorising account...")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - static = wx.StaticText(panel, wx.NewId(), _(u"Enter your PIN code here")) - self.text = wx.TextCtrl(panel, -1) - self.ok = wx.Button(panel, wx.ID_OK) - self.cancel = wx.Button(panel, wx.ID_CANCEL) - sizer.Add(self.text, 0, wx.ALL, 5) - sizer.Add(self.cancel, 0, wx.ALL, 5) - panel.SetSizer(sizer) - min = sizer.CalcMin() - self.SetClientSize(min) \ No newline at end of file + def __init__(self): + super(authorisationDialog, self).__init__(parent=None, title=_(u"Authorising account...")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + static = wx.StaticText(panel, wx.NewId(), _(u"Enter your PIN code here")) + self.text = wx.TextCtrl(panel, -1) + self.ok = wx.Button(panel, wx.ID_OK) + self.cancel = wx.Button(panel, wx.ID_CANCEL) + sizer.Add(self.text, 0, wx.ALL, 5) + sizer.Add(self.cancel, 0, wx.ALL, 5) + panel.SetSizer(sizer) + min = sizer.CalcMin() + self.SetClientSize(min) diff --git a/src/setup.py b/src/setup.py index 1a5b013a..b0734eaa 100644 --- a/src/setup.py +++ b/src/setup.py @@ -3,53 +3,56 @@ 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(): - if platform.architecture()[0][:2] == "32": - return ["../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", "../windows-dependencies/x86/libvlc.dll", "../windows-dependencies/x86/libvlccore.dll", "../windows-dependencies/x86/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell"], ["../windows-dependencies/x86/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFC", "."]] - elif platform.architecture()[0][:2] == "64": - return ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x64/bootstrap.exe", "../windows-dependencies/x64/libvlc.dll", "../windows-dependencies/x64/libvlccore.dll", "../windows-dependencies/x64/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw64/share/enchant/hunspell"], ["../windows-dependencies/x64/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFC", "."]] + if platform.architecture()[0][:2] == "32": + return ["../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", "../windows-dependencies/x86/libvlc.dll", "../windows-dependencies/x86/libvlccore.dll", "../windows-dependencies/x86/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell"], ["../windows-dependencies/x86/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFC", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFCLOC", "."], ["../windows-dependencies/x86/ucrt", "."]] + elif platform.architecture()[0][:2] == "64": + return ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x64/bootstrap.exe", "../windows-dependencies/x64/libvlc.dll", "../windows-dependencies/x64/libvlccore.dll", "../windows-dependencies/x64/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw64/share/enchant/hunspell"], ["../windows-dependencies/x64/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFC", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFCLOC", "."], ["../windows-dependencies/x64/ucrt", "."]] def find_sound_lib_datafiles(): - import os - import platform - import sound_lib - path = os.path.join(sound_lib.__path__[0], 'lib') - if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin': - arch = 'x86' - else: - arch = 'x64' - dest_dir = os.path.join('sound_lib', 'lib', arch) - source = os.path.join(path, arch) - return (source, dest_dir) + import os + import platform + import sound_lib + path = os.path.join(sound_lib.__path__[0], 'lib') + if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin': + arch = 'x86' + else: + arch = 'x64' + dest_dir = os.path.join('sound_lib', 'lib', arch) + source = os.path.join(path, arch) + return (source, dest_dir) def find_accessible_output2_datafiles(): - import os - import accessible_output2 - path = os.path.join(accessible_output2.__path__[0], 'lib') - dest_dir = os.path.join('accessible_output2', 'lib') - return (path, dest_dir) + import os + import accessible_output2 + path = os.path.join(accessible_output2.__path__[0], 'lib') + dest_dir = os.path.join('accessible_output2', 'lib') + return (path, dest_dir) base = None if sys.platform == 'win32': base = 'Win32GUI' build_exe_options = dict( - build_exe="dist", - optimize=1, - includes=["enchant.tokenize.en"], # This is not handled automatically by cx_freeze. - include_msvcr=True, - 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"], - ) + build_exe="dist", + optimize=1, + includes=["enchant.tokenize.en"], # This is not handled automatically by cx_freeze. + 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"], + bin_path_excludes=["C:\\Program Files", "C:\Program Files (x86)"], +) executables = [ - Executable('main.py', base=base, targetName="twblue") + Executable('main.py', base=base, target_name="twblue") ] +winmsvcr.FILES = () +winmsvcr.FILES_TO_DUPLICATE = () setup(name=application.name, version=application.version, description=application.description, diff --git a/src/sound.py b/src/sound.py index 859001c7..cd0f5a93 100644 --- a/src/sound.py +++ b/src/sound.py @@ -6,7 +6,6 @@ import subprocess import platform import tempfile import glob -import url_shortener import audio_services import paths import sound_lib @@ -15,11 +14,11 @@ from audio_services import youtube_utils import application system = platform.system() if system=="Windows" and not hasattr(sys, 'frozen'): # We are running from source on Windows - current_dir=os.getcwd() - os.chdir(os.environ['PYTHON_VLC_MODULE_PATH']) + current_dir=os.getcwd() + os.chdir(os.environ['PYTHON_VLC_MODULE_PATH']) import vlc if system=="Windows" and not hasattr(sys, 'frozen'): # Restore the original folder - os.chdir(current_dir) + os.chdir(current_dir) import sound_lib.output, sound_lib.input, sound_lib.stream, sound_lib.recording from mysc.repeating_timer import RepeatingTimer from mysc.thread_utils import call_threaded @@ -29,132 +28,140 @@ URLPlayer = None log = original_logger.getLogger("sound") def setup(): - global URLPlayer - if not URLPlayer: - log.debug("creating stream URL player...") - URLPlayer = URLStream() + global URLPlayer + if not URLPlayer: + log.debug("creating stream URL player...") + URLPlayer = URLStream() def recode_audio(filename, quality=4.5): - global system - if system == "Windows": subprocess.call(r'"%s" -q %r "%s"' % (os.path.join(paths.app_path(), 'oggenc2.exe'), quality, filename)) + global system + if system == "Windows": subprocess.call(r'"%s" -q %r "%s"' % (os.path.join(paths.app_path(), 'oggenc2.exe'), quality, filename)) def recording(filename): -# try: - val = sound_lib.recording.WaveRecording(filename=filename) + # try: + val = sound_lib.recording.WaveRecording(filename=filename) # except sound_lib.main.BassError: # sound_lib.input.Input() # val = sound_lib.recording.WaveRecording(filename=filename) - return val + return val class soundSystem(object): - def check_soundpack(self): - """ Checks if the folder where live the current soundpack exists.""" - self.soundpack_OK = False - if os.path.exists(os.path.join(paths.sound_path(), self.config["current_soundpack"])): - self.path = os.path.join(paths.sound_path(), self.config["current_soundpack"]) - self.soundpack_OK = True - elif os.path.exists(os.path.join(paths.sound_path(), "default")): - log.error("The soundpack does not exist, using default...") - self.path = os.path.join(paths.sound_path(), "default") - self.soundpack_OK = True - else: - log.error("The current soundpack could not be found and the default soundpack has been deleted, " + application.name + " will not play sounds.") - self.soundpack_OK = False + def check_soundpack(self): + """ Checks if the folder where live the current soundpack exists.""" + self.soundpack_OK = False + if os.path.exists(os.path.join(paths.sound_path(), self.config["current_soundpack"])): + self.path = os.path.join(paths.sound_path(), self.config["current_soundpack"]) + self.soundpack_OK = True + elif os.path.exists(os.path.join(paths.sound_path(), "default")): + log.error("The soundpack does not exist, using default...") + self.path = os.path.join(paths.sound_path(), "default") + self.soundpack_OK = True + else: + log.error("The current soundpack could not be found and the default soundpack has been deleted, " + application.name + " will not play sounds.") + self.soundpack_OK = False - def __init__(self, soundConfig): - """ Sound Player.""" - self.config = soundConfig - # Set the output and input default devices. - try: - self.output = sound_lib.output.Output() - self.input = sound_lib.input.Input() - except: - pass - # Try to use the selected device from the configuration. It can fail if the machine does not has a mic. - try: - log.debug("Setting input and output devices...") - self.output.set_device(self.output.find_device_by_name(self.config["output_device"])) - self.input.set_device(self.input.find_device_by_name(self.config["input_device"])) - except: - log.error("Error in input or output devices, using defaults...") - self.config["output_device"] = "Default" - self.config["input_device"] = "Default" + def __init__(self, soundConfig): + """ Sound Player.""" + self.config = soundConfig + # Set the output and input default devices. + try: + self.output = sound_lib.output.Output() + self.input = sound_lib.input.Input() + except: + pass + # Try to use the selected device from the configuration. It can fail if the machine does not has a mic. + try: + log.debug("Setting input and output devices...") + self.output.set_device(self.output.find_device_by_name(self.config["output_device"])) + self.input.set_device(self.input.find_device_by_name(self.config["input_device"])) + except: + log.error("Error in input or output devices, using defaults...") + self.config["output_device"] = "Default" + self.config["input_device"] = "Default" - self.files = [] - self.cleaner = RepeatingTimer(60, self.clear_list) - self.cleaner.start() - self.check_soundpack() + self.files = [] + self.cleaner = RepeatingTimer(60, self.clear_list) + self.cleaner.start() + self.check_soundpack() - def clear_list(self): - if len(self.files) == 0: return - try: - for i in range(0, len(self.files)): - if self.files[i].is_playing == False: - self.files[i].free() - self.files.pop(i) - except IndexError: - pass + def clear_list(self): + if len(self.files) == 0: return + try: + for i in range(0, len(self.files)): + if self.files[i].is_playing == False: + self.files[i].free() + self.files.pop(i) + except IndexError: + pass - def play(self, sound, argument=False): - if self.soundpack_OK == False: return - if self.config["session_mute"] == True: return - sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound)) - sound_object.volume = float(self.config["volume"]) - self.files.append(sound_object) - sound_object.play() + def play(self, sound, argument=False): + if self.soundpack_OK == False: return + if self.config["session_mute"] == True: return + sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound)) + sound_object.volume = float(self.config["volume"]) + self.files.append(sound_object) + sound_object.play() class URLStream(object): - """ URL Stream Player implementation.""" + """ URL Stream Player implementation.""" - def __init__(self): - # URL status. Should be True after URL expansion and transformation. - self.prepared = False - log.debug("URL Player initialized") - # LibVLC controls. - self.instance = vlc.Instance() - self.player = self.instance.media_player_new() + def __init__(self): + # URL status. Should be True after URL expansion and transformation. + self.prepared = False + log.debug("URL Player initialized") + # LibVLC controls. + self.instance = vlc.Instance() + self.player = self.instance.media_player_new() + self.event_manager = self.player.event_manager() + self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.end_callback) - def prepare(self, url): - """ Takes an URL and prepares it to be streamed. This function will try to unshorten the passed URL and, if needed, to transform it into a valid URL.""" - log.debug("Preparing URL: %s" % (url,)) - self.prepared = False - self.url = url_shortener.unshorten(url) - if self.url == None: - self.url = url - log.debug("Expanded URL: %s" % (self.url,)) - if self.url != None: - transformer = audio_services.find_url_transformer(self.url) - transformed_url = transformer(self.url) - self.url = transformed_url - log.debug("Transformed URL: %s. Prepared" % (self.url,)) - self.prepared = True + def prepare(self, url): + """ Takes an URL and prepares it to be streamed. This function will try to unshorten the passed URL and, if needed, to transform it into a valid URL.""" + log.debug("Preparing URL: %s" % (url,)) + self.prepared = False + self.url = url + if self.url == None: + self.url = url + log.debug("Expanded URL: %s" % (self.url,)) + if self.url != None: + transformer = audio_services.find_url_transformer(self.url) + transformed_url = transformer(self.url) + self.url = transformed_url + log.debug("Transformed URL: %s. Prepared" % (self.url,)) + self.prepared = True - def seek(self, step): - pos=self.player.get_time() - pos+=step - pos=self.player.set_time(pos) + def seek(self, step): + pos=self.player.get_time() + pos+=step + pos=self.player.set_time(pos) - def playpause(self): - if self.player.is_playing() == True: - self.player.pause() - else: - self.player.play() + def playpause(self): + if self.player.is_playing() == True: + self.player.pause() + else: + self.player.play() - def play(self, url=None, volume=1.0, announce=True): - if announce: - output.speak(_(u"Playing...")) - log.debug("Attempting to play an URL...") - if url != None: - self.prepare(url) - if self.prepared == True: - media = self.instance.media_new(self.url) - self.player.set_media(media) - self.player.audio_set_volume(int(volume*100)) - self.player.play() - log.debug("played") - self.prepared=False + def play(self, url=None, volume=1.0, announce=True): + if announce: + output.speak(_(u"Playing...")) + log.debug("Attempting to play an URL...") + if url != None: + self.prepare(url) + if self.prepared == True: + media = self.instance.media_new(self.url) + self.player.set_media(media) + self.player.audio_set_volume(int(volume*100)) + self.player.play() + log.debug("played") + self.prepared=False - def stop_audio(self): - output.speak(_(u"Stopped."), True) - self.player.stop() + def stop_audio(self): + output.speak(_(u"Stopped."), True) + self.player.stop() + + def end_callback(self, event, *args, **kwargs): + call_threaded(self.player.stop) + + def __del__(self): + self.event_manager.event_detach(vlc.EventType.MediaPlayerEndReached) \ No newline at end of file diff --git a/src/test/__init__.py b/src/test/__init__.py new file mode 100644 index 00000000..40a96afc --- /dev/null +++ b/src/test/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/src/test/test_cache.py b/src/test/test_cache.py new file mode 100644 index 00000000..6337c3b2 --- /dev/null +++ b/src/test/test_cache.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +""" Test case to check some of the scenarios we might face when storing tweets in cache, both loading into memory or rreading from disk. """ +import unittest +import os +import paths +import sqlitedict +import shutil +# The base session module requires sound as a dependency, and this needs libVLC to be locatable. +os.environ['PYTHON_VLC_MODULE_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", "x86")) +os.environ['PYTHON_VLC_LIB_PATH']=os.path.abspath(os.path.join(paths.app_path(), "..", "windows-dependencies", "x86", "libvlc.dll")) +from sessions import base + +class cacheTestCase(unittest.TestCase): + + def setUp(self): + """ Configures a fake session to check caching objects here. """ + self.session = base.baseSession("testing") + if os.path.exists(os.path.join(paths.config_path(), "testing")) == False: + os.mkdir(os.path.join(paths.config_path(), "testing")) + self.session.get_configuration() + + def tearDown(self): + """ Removes the previously configured session. """ + session_folder = os.path.join(paths.config_path(), "testing") + if os.path.exists(session_folder): + shutil.rmtree(session_folder) + + def generate_dataset(self): + """ Generates a sample dataset""" + dataset = dict(home_timeline=["message" for i in range(10000)], mentions_timeline=["mention" for i in range(20000)]) + return dataset + + ### Testing database being read from disk. + + def test_cache_in_disk_unlimited_size(self): + """ Tests cache database being read from disk, storing the whole datasets. """ + dataset = self.generate_dataset() + self.session.settings["general"]["load_cache_in_memory"] = False + self.session.settings["general"]["persist_size"] = -1 + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + self.session.save_persistent_data() + self.assertIsInstance(self.session.db, sqlitedict.SqliteDict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(len(self.session.db.get("home_timeline")), 10000) + self.assertEquals(len(self.session.db.get("mentions_timeline")), 20000) + self.session.db.close() + + def test_cache_in_disk_limited_dataset(self): + """ Tests wether the cache stores only the amount of items we ask it to store. """ + dataset = self.generate_dataset() + self.session.settings["general"]["load_cache_in_memory"] = False + self.session.settings["general"]["persist_size"] = 100 + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + # We need to save and load the db again because we cannot modify buffers' size while the database is opened. + # As TWBlue reads directly from db when reading from disk, an attempt to modify buffers size while Blue is reading the db + # Might cause an out of sync error between the GUI lists and the database. + # So we perform the changes to buffer size when loading data during app startup if the DB is read from disk. + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, sqlitedict.SqliteDict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(len(self.session.db.get("home_timeline")), 100) + self.assertEquals(len(self.session.db.get("mentions_timeline")), 100) + self.session.db.close() + + def test_cache_in_disk_limited_dataset_unreversed(self): + """Test if the cache is saved properly in unreversed buffers, when newest items are at the end of the list. """ + dataset = dict(home_timeline=[i for i in range(20)], mentions_timeline=[i for i in range(20)]) + self.session.settings["general"]["load_cache_in_memory"] = False + self.session.settings["general"]["persist_size"] = 10 + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + # We need to save and load the db again because we cannot modify buffers' size while the database is opened. + # As TWBlue reads directly from db when reading from disk, an attempt to modify buffers size while Blue is reading the db + # Might cause an out of sync error between the GUI lists and the database. + # So we perform the changes to buffer size when loading data during app startup if the DB is read from disk. + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, sqlitedict.SqliteDict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(self.session.db.get("home_timeline")[0], 10) + self.assertEquals(self.session.db.get("mentions_timeline")[0], 10) + self.assertEquals(self.session.db.get("home_timeline")[-1], 19) + self.assertEquals(self.session.db.get("mentions_timeline")[-1], 19) + self.session.db.close() + + def test_cache_in_disk_limited_dataset_reversed(self): + """Test if the cache is saved properly in reversed buffers, when newest items are at the start of the list. """ + dataset = dict(home_timeline=[i for i in range(19, -1, -1)], mentions_timeline=[i for i in range(19, -1, -1)]) + self.session.settings["general"]["load_cache_in_memory"] = False + self.session.settings["general"]["persist_size"] = 10 + self.session.settings["general"]["reverse_timelines"] = True + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + # We need to save and load the db again because we cannot modify buffers' size while the database is opened. + # As TWBlue reads directly from db when reading from disk, an attempt to modify buffers size while Blue is reading the db + # Might cause an out of sync error between the GUI lists and the database. + # So we perform the changes to buffer size when loading data during app startup if the DB is read from disk. + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, sqlitedict.SqliteDict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(self.session.db.get("home_timeline")[0], 19) + self.assertEquals(self.session.db.get("mentions_timeline")[0], 19) + self.assertEquals(self.session.db.get("home_timeline")[-1], 10) + self.assertEquals(self.session.db.get("mentions_timeline")[-1], 10) + self.session.db.close() + + ### Testing database being loaded into memory. Those tests should give the same results than before + ### but as we have different code depending whether we load db into memory or read it from disk, + ### We need to test this anyways. + def test_cache_in_memory_unlimited_size(self): + """ Tests cache database being loaded in memory, storing the whole datasets. """ + dataset = self.generate_dataset() + self.session.settings["general"]["load_cache_in_memory"] = True + self.session.settings["general"]["persist_size"] = -1 + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, dict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(len(self.session.db.get("home_timeline")), 10000) + self.assertEquals(len(self.session.db.get("mentions_timeline")), 20000) + + def test_cache_in_memory_limited_dataset(self): + """ Tests wether the cache stores only the amount of items we ask it to store, when loaded in memory. """ + dataset = self.generate_dataset() + self.session.settings["general"]["load_cache_in_memory"] = True + self.session.settings["general"]["persist_size"] = 100 + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, dict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(len(self.session.db.get("home_timeline")), 100) + self.assertEquals(len(self.session.db.get("mentions_timeline")), 100) + + def test_cache_in_memory_limited_dataset_unreversed(self): + """Test if the cache is saved properly when loaded in memory in unreversed buffers, when newest items are at the end of the list. """ + dataset = dict(home_timeline=[i for i in range(20)], mentions_timeline=[i for i in range(20)]) + self.session.settings["general"]["load_cache_in_memory"] = True + self.session.settings["general"]["persist_size"] = 10 + self.session.load_persistent_data() + self.assertTrue(len(self.session.db)==1) + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, dict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(self.session.db.get("home_timeline")[0], 10) + self.assertEquals(self.session.db.get("mentions_timeline")[0], 10) + self.assertEquals(self.session.db.get("home_timeline")[-1], 19) + self.assertEquals(self.session.db.get("mentions_timeline")[-1], 19) + + def test_cache_in_memory_limited_dataset_reversed(self): + """Test if the cache is saved properly in reversed buffers, when newest items are at the start of the list. This test if for db read into memory. """ + dataset = dict(home_timeline=[i for i in range(19, -1, -1)], mentions_timeline=[i for i in range(19, -1, -1)]) + self.session.settings["general"]["load_cache_in_memory"] = True + self.session.settings["general"]["persist_size"] = 10 + self.session.settings["general"]["reverse_timelines"] = True + self.session.load_persistent_data() + self.session.db["home_timeline"] = dataset["home_timeline"] + self.session.db["mentions_timeline"] = dataset["mentions_timeline"] + self.session.save_persistent_data() + self.session.db = dict() + self.session.load_persistent_data() + self.assertIsInstance(self.session.db, dict) + self.assertTrue(self.session.db.get("home_timeline") != None) + self.assertTrue(self.session.db.get("mentions_timeline") != None) + self.assertEquals(self.session.db.get("home_timeline")[0], 19) + self.assertEquals(self.session.db.get("mentions_timeline")[0], 19) + self.assertEquals(self.session.db.get("home_timeline")[-1], 10) + self.assertEquals(self.session.db.get("mentions_timeline")[-1], 10) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/src/update/__init__.py b/src/update/__init__.py index 3c5275a4..443025e3 100644 --- a/src/update/__init__.py +++ b/src/update/__init__.py @@ -4,10 +4,10 @@ import os.path import platform def find_datafiles(): - system = platform.system() - if system == 'Windows': - file_ext = '*.exe' - else: - file_ext = '*.sh' - path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext)) - return [('', glob.glob(path))] + system = platform.system() + if system == 'Windows': + file_ext = '*.exe' + else: + file_ext = '*.sh' + path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext)) + return [('', glob.glob(path))] diff --git a/src/update/update.py b/src/update/update.py index ce5cfced..d6b47f5c 100644 --- a/src/update/update.py +++ b/src/update/update.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals from logging import getLogger logger = getLogger('update') @@ -12,116 +11,116 @@ from wxUI import commonMessageDialogs import widgetUtils import webbrowser try: - import czipfile as zipfile + import czipfile as zipfile except ImportError: - import zipfile + import zipfile from platform_utils import paths def perform_update(endpoint, current_version, app_name='', password=None, update_available_callback=None, progress_callback=None, update_complete_callback=None): - requests_session = create_requests_session(app_name=app_name, version=current_version) - available_update = find_update(endpoint, requests_session=requests_session) - if not available_update: - logger.debug("No update available") - return False - available_version = float(available_update['current_version']) - if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']: - logger.debug("No update for this architecture") - return False - available_description = available_update.get('description', None) - available_date = available_update.get('date', None) - update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]] - logger.info("A new update is available. Version %s" % available_version) - donation() - if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description, date=available_date): #update_available_callback should return a falsy value to stop the process - logger.info("User canceled update.") - return - base_path = tempfile.mkdtemp() - download_path = os.path.join(base_path, 'update.zip') - update_path = os.path.join(base_path, 'update') - downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback) - extracted = extract_update(downloaded, update_path, password=password) - bootstrap_path = move_bootstrap(extracted) - execute_bootstrap(bootstrap_path, extracted) - logger.info("Update prepared for installation.") - if callable(update_complete_callback): - update_complete_callback() + requests_session = create_requests_session(app_name=app_name, version=current_version) + available_update = find_update(endpoint, requests_session=requests_session) + if not available_update: + logger.debug("No update available") + return False + available_version = available_update['current_version'] + if available_version == current_version or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']: + logger.debug("No update for this architecture") + return False + available_description = available_update.get('description', None) + available_date = available_update.get('date', None) + update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]] + logger.info("A new update is available. Version %s" % available_version) + donation() + if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description, date=available_date): #update_available_callback should return a falsy value to stop the process + logger.info("User canceled update.") + return + base_path = tempfile.mkdtemp() + download_path = os.path.join(base_path, 'update.zip') + update_path = os.path.join(base_path, 'update') + downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback) + extracted = extract_update(downloaded, update_path, password=password) + bootstrap_path = move_bootstrap(extracted) + if callable(update_complete_callback): + update_complete_callback() + execute_bootstrap(bootstrap_path, extracted) + logger.info("Update prepared for installation.") def create_requests_session(app_name=None, version=None): - user_agent = '' - session = requests.session() - if app_name: - user_agent = ' %s/%r' % (app_name, version) - session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent - return session + user_agent = '' + session = requests.session() + if app_name: + user_agent = ' %s/%r' % (app_name, version) + session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent + return session def find_update(endpoint, requests_session): - response = requests_session.get(endpoint) - response.raise_for_status() - content = response.json() - return content + response = requests_session.get(endpoint) + response.raise_for_status() + content = response.json() + return content def download_update(update_url, update_destination, requests_session, progress_callback=None, chunk_size=io.DEFAULT_BUFFER_SIZE): - total_downloaded = total_size = 0 - with io.open(update_destination, 'w+b') as outfile: - download = requests_session.get(update_url, stream=True) - total_size = int(download.headers.get('content-length', 0)) - logger.debug("Total update size: %d" % total_size) - download.raise_for_status() - for chunk in download.iter_content(chunk_size): - outfile.write(chunk) - total_downloaded += len(chunk) - if callable(progress_callback): - call_callback(progress_callback, total_downloaded, total_size) - logger.debug("Update downloaded") - return update_destination + total_downloaded = total_size = 0 + with io.open(update_destination, 'w+b') as outfile: + download = requests_session.get(update_url, stream=True) + total_size = int(download.headers.get('content-length', 0)) + logger.debug("Total update size: %d" % total_size) + download.raise_for_status() + for chunk in download.iter_content(chunk_size): + outfile.write(chunk) + total_downloaded += len(chunk) + if callable(progress_callback): + call_callback(progress_callback, total_downloaded, total_size) + logger.debug("Update downloaded") + return update_destination def extract_update(update_archive, destination, password=None): - """Given an update archive, extracts it. Returns the directory to which it has been extracted""" - with contextlib.closing(zipfile.ZipFile(update_archive)) as archive: - if password: - archive.setpassword(password) - archive.extractall(path=destination) - logger.debug("Update extracted") - return destination + """Given an update archive, extracts it. Returns the directory to which it has been extracted""" + with contextlib.closing(zipfile.ZipFile(update_archive)) as archive: + if password: + archive.setpassword(password) + archive.extractall(path=destination) + logger.debug("Update extracted") + return destination def move_bootstrap(extracted_path): - working_path = os.path.abspath(os.path.join(extracted_path, '..')) - if platform.system() == 'Darwin': - extracted_path = os.path.join(extracted_path, 'Contents', 'Resources') - downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name()) - new_bootstrap_path = os.path.join(working_path, bootstrap_name()) - os.rename(downloaded_bootstrap, new_bootstrap_path) - return new_bootstrap_path + working_path = os.path.abspath(os.path.join(extracted_path, '..')) + if platform.system() == 'Darwin': + extracted_path = os.path.join(extracted_path, 'Contents', 'Resources') + downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name()) + new_bootstrap_path = os.path.join(working_path, bootstrap_name()) + os.rename(downloaded_bootstrap, new_bootstrap_path) + return new_bootstrap_path def execute_bootstrap(bootstrap_path, source_path): - arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable()) - if platform.system() == 'Windows': - import win32api - win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5) - else: - import subprocess - make_executable(bootstrap_path) - subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True) - logger.info("Bootstrap executed") + arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable()) + if platform.system() == 'Windows': + import win32api + win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5) + else: + import subprocess + make_executable(bootstrap_path) + subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True) + logger.info("Bootstrap executed") def bootstrap_name(): - if platform.system() == 'Windows': return 'bootstrap.exe' - if platform.system() == 'Darwin': return 'bootstrap-mac.sh' - return 'bootstrap-lin.sh' + if platform.system() == 'Windows': return 'bootstrap.exe' + if platform.system() == 'Darwin': return 'bootstrap-mac.sh' + return 'bootstrap-lin.sh' def make_executable(path): - import stat - st = os.stat(path) - os.chmod(path, st.st_mode | stat.S_IEXEC) + import stat + st = os.stat(path) + os.chmod(path, st.st_mode | stat.S_IEXEC) def call_callback(callback, *args, **kwargs): -# try: - callback(*args, **kwargs) + # try: + callback(*args, **kwargs) # except: # logger.exception("Failed calling callback %r with args %r and kwargs %r" % (callback, args, kwargs)) def donation(): - dlg = commonMessageDialogs.donation() - if dlg == widgetUtils.YES: - webbrowser.open_new_tab("http://twblue.es/?q=donate") \ No newline at end of file + dlg = commonMessageDialogs.donation() + if dlg == widgetUtils.YES: + webbrowser.open_new_tab("http://twblue.es/?q=donate") diff --git a/src/update/updater.py b/src/update/updater.py index 9cc20af2..5214c1de 100644 --- a/src/update/updater.py +++ b/src/update/updater.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals import application from . import update import platform @@ -11,13 +9,13 @@ from .wxUpdater import * logger = logging.getLogger("updater") def do_update(endpoint=application.update_url): - try: - result = update.perform_update(endpoint=endpoint, current_version=application.version, app_name=application.name, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished) - except: - if endpoint == application.update_url: - logger.error("Update failed! Using mirror URL...") - return do_update(endpoint=application.mirror_update_url) - else: - logger.exception("Update failed.") - output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True) - return result \ No newline at end of file + try: + result = update.perform_update(endpoint=endpoint, current_version=application.version, app_name=application.name, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished) + except: + if endpoint == application.update_url: + logger.error("Update failed! Using mirror URL...") + return do_update(endpoint=application.mirror_update_url) + else: + logger.exception("Update failed.") + output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True) + return result diff --git a/src/update/utils.py b/src/update/utils.py index 9ec89156..c9bbdc9a 100644 --- a/src/update/utils.py +++ b/src/update/utils.py @@ -3,42 +3,42 @@ from __future__ import unicode_literals from builtins import str def convert_bytes(n): - K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 - if n >= P: - return '%.2fPb' % (float(n) / T) - elif n >= T: - return '%.2fTb' % (float(n) / T) - elif n >= G: - return '%.2fGb' % (float(n) / G) - elif n >= M: - return '%.2fMb' % (float(n) / M) - elif n >= K: - return '%.2fKb' % (float(n) / K) - else: - return '%d' % n + K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 + if n >= P: + return '%.2fPb' % (float(n) / T) + elif n >= T: + return '%.2fTb' % (float(n) / T) + elif n >= G: + return '%.2fGb' % (float(n) / G) + elif n >= M: + return '%.2fMb' % (float(n) / M) + elif n >= K: + return '%.2fKb' % (float(n) / K) + else: + return '%d' % n def seconds_to_string(seconds, precision=0): - day = seconds // 86400 - hour = seconds // 3600 - min = (seconds // 60) % 60 - sec = seconds - (hour * 3600) - (min * 60) - sec_spec = "." + str(precision) + "f" - sec_string = sec.__format__(sec_spec) - string = "" - if day == 1: - string += _(u"%d day, ") % day - elif day >= 2: - string += _(u"%d days, ") % day - if (hour == 1): - string += _(u"%d hour, ") % hour - elif (hour >= 2): - string += _("%d hours, ") % hour - if (min == 1): - string += _(u"%d minute, ") % min - elif (min >= 2): - string += _(u"%d minutes, ") % min - if sec >= 0 and sec <= 2: - string += _(u"%s second") % sec_string - else: - string += _(u"%s seconds") % sec_string - return string \ No newline at end of file + day = seconds // 86400 + hour = seconds // 3600 + min = (seconds // 60) % 60 + sec = seconds - (hour * 3600) - (min * 60) + sec_spec = "." + str(precision) + "f" + sec_string = sec.__format__(sec_spec) + string = "" + if day == 1: + string += _(u"%d day, ") % day + elif day >= 2: + string += _(u"%d days, ") % day + if (hour == 1): + string += _(u"%d hour, ") % hour + elif (hour >= 2): + string += _("%d hours, ") % hour + if (min == 1): + string += _(u"%d minute, ") % min + elif (min >= 2): + string += _(u"%d minutes, ") % min + if sec >= 0 and sec <= 2: + string += _(u"%s second") % sec_string + else: + string += _(u"%s seconds") % sec_string + return string diff --git a/src/update/wxUpdater.py b/src/update/wxUpdater.py index 437e0a41..6ba6fd2a 100644 --- a/src/update/wxUpdater.py +++ b/src/update/wxUpdater.py @@ -11,25 +11,25 @@ from . import utils progress_dialog = None def available_update_dialog(version, description, date): - dialog = wx.MessageDialog(None, _(u"There's a new %s version available, released on %s. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, date, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING) - if dialog.ShowModal() == wx.ID_YES: - return True - else: - return False + dialog = wx.MessageDialog(None, _(u"There's a new %s version available, released on %s. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, date, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING) + if dialog.ShowModal() == wx.ID_YES: + return True + else: + return False def create_progress_dialog(): - return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100) + return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100) def progress_callback(total_downloaded, total_size): - global progress_dialog - if progress_dialog == None: - progress_dialog = create_progress_dialog() - progress_dialog.Show() - if total_downloaded == total_size: - progress_dialog.Destroy() - else: - progress_dialog.Update(old_div((total_downloaded*100),total_size), _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) + global progress_dialog + if progress_dialog == None: + progress_dialog = create_progress_dialog() + progress_dialog.Show() + if total_downloaded == total_size: + progress_dialog.Destroy() + else: + progress_dialog.Update(old_div((total_downloaded*100),total_size), _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) def update_finished(): - ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() \ No newline at end of file + ms = wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() diff --git a/src/url_shortener/__init__.py b/src/url_shortener/__init__.py deleted file mode 100644 index 419c8170..00000000 --- a/src/url_shortener/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from __future__ import unicode_literals -from . import shorteners -from . __main__ import * diff --git a/src/url_shortener/__main__.py b/src/url_shortener/__main__.py deleted file mode 100644 index 51ccf8d8..00000000 --- a/src/url_shortener/__main__.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import unicode_literals -from functools import wraps -from . import shorteners - - -def service_selecter (func): - @wraps(func) - def wrapper (*args, **kwargs): - tmp = dict(kwargs) - if 'service' in tmp: - del(tmp['service']) - kwargs['service'] = find_service(kwargs['service'], **tmp) or default_service() - else: - kwargs['service'] = default_service() - return func(*args, **kwargs) - return wrapper - -@service_selecter -def shorten (url, service=None, **kwargs): - return service(**kwargs).shorten(url) - - -@service_selecter -def unshorten (url, service=None, **kwargs): - return service(**kwargs).unshorten(url) - - -def default_service (): - return shorteners.AcortameShortener - -def find_service (service, **kwargs): - for i in shorteners.__all__: - obj = getattr(shorteners, i)(**kwargs) - if obj.name.lower() == service.lower(): - return getattr(shorteners, i) - -def list_services (): - return [getattr(shorteners, i)().name for i in shorteners.__all__] - -def unshorten_any (url): - """Unshortens an URL using any available unshortener. Check to see if unshortened URL was created by a shortener (nested) and unshorten if so.""" - unshortened_url = shorteners.URLShortener().unshorten(url) - # None is returned if URL not unshortened - if unshortened_url: - return unshorten_any(unshortened_url) - return url diff --git a/src/url_shortener/shorteners/__init__.py b/src/url_shortener/shorteners/__init__.py deleted file mode 100644 index aa0b763d..00000000 --- a/src/url_shortener/shorteners/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from __future__ import unicode_literals -from .url_shortener import URLShortener -from .hkcim import HKCShortener -from . isgd import IsgdShortener -from . onjme import OnjmeShortener -from . tinyarrows import TinyArrowsShortener -from . tinyurl import TinyurlShortener -from . xedcc import XedccShortener -from . clckru import ClckruShortener -from . acortame import AcortameShortener -__all__ = ["HKCShortener", "IsgdShortener", "OnjmeShortener", "TinyArrowsShortener", "TinyurlShortener", "XedccShortener", "ClckruShortener", "AcortameShortener"] diff --git a/src/url_shortener/shorteners/acortame.py b/src/url_shortener/shorteners/acortame.py deleted file mode 100644 index fda92ce5..00000000 --- a/src/url_shortener/shorteners/acortame.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -from . url_shortener import URLShortener -import requests -import urllib.request, urllib.parse, urllib.error -class AcortameShortener (URLShortener): - def __init__(self, *args, **kwargs): - self.name = "acorta.me" - super(AcortameShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("https://acorta.me/api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'acorta.me' in url - - def unshorten (self, url): - if not 'acorta.me' in url: - #use generic expand method - return super(AcortameShortener, self).unshorten(url) - answer = url - api = requests.get ("https://acorta.me/api.php?action=expand&format=simple&shorturl=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer diff --git a/src/url_shortener/shorteners/clckru.py b/src/url_shortener/shorteners/clckru.py deleted file mode 100644 index 9d6ce136..00000000 --- a/src/url_shortener/shorteners/clckru.py +++ /dev/null @@ -1,22 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - - -class ClckruShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "clck.ru" - super(ClckruShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://clck.ru/--?url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'clck.ru' in url diff --git a/src/url_shortener/shorteners/hkcim.py b/src/url_shortener/shorteners/hkcim.py deleted file mode 100644 index 43b4d608..00000000 --- a/src/url_shortener/shorteners/hkcim.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class HKCShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "HKC.im" - super(HKCShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'hkc.im' in url.lower() diff --git a/src/url_shortener/shorteners/isgd.py b/src/url_shortener/shorteners/isgd.py deleted file mode 100644 index 006089de..00000000 --- a/src/url_shortener/shorteners/isgd.py +++ /dev/null @@ -1,22 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - - -class IsgdShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Is.gd" - super(IsgdShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://is.gd/api.php?longurl=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'is.gd' in url diff --git a/src/url_shortener/shorteners/onjme.py b/src/url_shortener/shorteners/onjme.py deleted file mode 100644 index c2da3043..00000000 --- a/src/url_shortener/shorteners/onjme.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class OnjmeShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Onj.me" - super(OnjmeShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'onj.me' in url.lower() diff --git a/src/url_shortener/shorteners/tinyarrows.py b/src/url_shortener/shorteners/tinyarrows.py deleted file mode 100644 index a544d7be..00000000 --- a/src/url_shortener/shorteners/tinyarrows.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class TinyArrowsShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "TinyArro.ws" - super(TinyArrowsShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer.decode('UTF-8') - - def created_url(self, url): - return "tinyarro.ws" in url diff --git a/src/url_shortener/shorteners/tinyurl.py b/src/url_shortener/shorteners/tinyurl.py deleted file mode 100644 index a762ff4e..00000000 --- a/src/url_shortener/shorteners/tinyurl.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -from .url_shortener import URLShortener -import requests -import urllib.request, urllib.parse, urllib.error -class TinyurlShortener (URLShortener): - def __init__(self, *args, **kwargs): - self.name = "TinyURL.com" - super(TinyurlShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://tinyurl.com/api-create.php?url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'tinyurl.com' in url diff --git a/src/url_shortener/shorteners/url_shortener.py b/src/url_shortener/shorteners/url_shortener.py deleted file mode 100644 index dad0e355..00000000 --- a/src/url_shortener/shorteners/url_shortener.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import unicode_literals -from builtins import object -import requests - -class URLShortener (object): - - def __init__ (self, *args, **kwargs): - #Stub out arguments, silly object. :( - return super(URLShortener, self).__init__() - - def shorten (self, url): - if self.created_url(url): - return url - else: - return self._shorten(url) - - def _shorten (self, url): - raise NotImplementedError - - def created_url (self, url): - """Returns a boolean indicating whether or not this shortener created a provided url""" - raise NotImplementedError - - def unshorten(self, url): - try: - r=requests.head(url) - if 'location' in list(r.headers.keys()): - if 'dropbox.com' in r.headers['location']: - return handle_dropbox(r.headers['location']) - else: - return r.headers['location'] - else: # if the head method does not work, use get instead. Performance may decrease - r=requests.get(url, allow_redirects=False, stream=True) - # release the connection without downloading the content, we only need the response headers - r.close() - return r.headers['location'] - except: - return url #we cannot expand - -def handle_dropbox(url): - if url.endswith("dl=1"): - return url - else: - return url.replace("dl=0", "dl=1") diff --git a/src/url_shortener/shorteners/xedcc.py b/src/url_shortener/shorteners/xedcc.py deleted file mode 100644 index 8b2d2fb5..00000000 --- a/src/url_shortener/shorteners/xedcc.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class XedccShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Xed.cc" - super(XedccShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'xed.cc' in url.lower() diff --git a/src/widgetUtils/__init__.py b/src/widgetUtils/__init__.py index 86202b09..8c88f5ee 100644 --- a/src/widgetUtils/__init__.py +++ b/src/widgetUtils/__init__.py @@ -2,6 +2,6 @@ from __future__ import absolute_import from __future__ import unicode_literals import platform if platform.system() == "Windows": - from .wxUtils import * + from .wxUtils import * #elif platform.system() == "Linux": # from gtkUtils import * diff --git a/src/widgetUtils/gtkUtils.py b/src/widgetUtils/gtkUtils.py index bec88129..6902d324 100644 --- a/src/widgetUtils/gtkUtils.py +++ b/src/widgetUtils/gtkUtils.py @@ -31,116 +31,116 @@ MENU = "activate" CHECKBOX = "toggled" def exit_application(): - """ Closes the current window cleanly. """ - Gtk.main_quit() + """ Closes the current window cleanly. """ + Gtk.main_quit() def connect_event(parent, event, func, menuitem=None, *args, **kwargs): - """ Connects an event to a function. - parent Gtk.widget: The widget that will listen for the event. - event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. - function func: The function that will be connected to the event.""" - if menuitem == None: - return getattr(parent, "connect")(event, func, *args, **kwargs) - else: - return getattr(menuitem, "connect")(event, func, *args, **kwargs) + """ Connects an event to a function. + parent Gtk.widget: The widget that will listen for the event. + event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. + function func: The function that will be connected to the event.""" + if menuitem == None: + return getattr(parent, "connect")(event, func, *args, **kwargs) + else: + return getattr(menuitem, "connect")(event, func, *args, **kwargs) class list(object): - def __init__(self, *columns, **listArguments): - self.columns = columns - self.list_arguments = listArguments - self.create_list() + def __init__(self, *columns, **listArguments): + self.columns = columns + self.list_arguments = listArguments + self.create_list() - def create_list(self): - columns = [] - [columns.append(str) for i in self.columns] - self.store = Gtk.ListStore(*columns) - self.list = Gtk.TreeView(model=self.store) - renderer = Gtk.CellRendererText() - for i in range(0, len(self.columns)): - column = Gtk.TreeViewColumn(self.columns[i], renderer, text=i) + def create_list(self): + columns = [] + [columns.append(str) for i in self.columns] + self.store = Gtk.ListStore(*columns) + self.list = Gtk.TreeView(model=self.store) + renderer = Gtk.CellRendererText() + for i in range(0, len(self.columns)): + column = Gtk.TreeViewColumn(self.columns[i], renderer, text=i) # column.set_sort_column_id(i) - self.list.append_column(column) + self.list.append_column(column) - def insert_item(self, reversed=False, *item): - if reversed == False: - self.store.append(row=item) - else: - self.store.insert(position=0, row=item) + def insert_item(self, reversed=False, *item): + if reversed == False: + self.store.append(row=item) + else: + self.store.insert(position=0, row=item) - def get_selected(self): - tree_selection = self.list.get_selection() - (model, pathlist) = tree_selection.get_selected_rows() - return int(pathlist[0].to_string() ) + def get_selected(self): + tree_selection = self.list.get_selection() + (model, pathlist) = tree_selection.get_selected_rows() + return int(pathlist[0].to_string() ) - def select_item(self, item): - tree_selection = self.list.get_selection() - tree_selection.select_path(item) + def select_item(self, item): + tree_selection = self.list.get_selection() + tree_selection.select_path(item) - def remove_item(self, item): - self.store.remove(self.store.get_iter(item)) + def remove_item(self, item): + self.store.remove(self.store.get_iter(item)) - def get_count(self): - return len(self.store) + def get_count(self): + return len(self.store) class baseDialog(Gtk.Dialog): - def __init__(self, *args, **kwargs): - super(baseDialog, self).__init__(*args, **kwargs) - self.box = self.get_content_area() + def __init__(self, *args, **kwargs): + super(baseDialog, self).__init__(*args, **kwargs) + self.box = self.get_content_area() - def get_response(self): - answer = self.run() - return answer + def get_response(self): + answer = self.run() + return answer class buffer(GObject.GObject): - name = GObject.property(type=str) + name = GObject.property(type=str) - def __init__(self, obj): - super(buffer, self).__init__() - self.buffer = obj + def __init__(self, obj): + super(buffer, self).__init__() + self.buffer = obj class notebook(object): - def __init__(self): - self.store = Gtk.TreeStore(buffer.__gtype__) - self.view = Gtk.TreeView() - self.view.set_model(self.store) + def __init__(self): + self.store = Gtk.TreeStore(buffer.__gtype__) + self.view = Gtk.TreeView() + self.view.set_model(self.store) - column = Gtk.TreeViewColumn("Buffer") - cell = Gtk.CellRendererText() - column.pack_start(cell, True) - column.set_cell_data_func(cell, self.get_buffer) - self.view.append_column(column) + column = Gtk.TreeViewColumn("Buffer") + cell = Gtk.CellRendererText() + column.pack_start(cell, True) + column.set_cell_data_func(cell, self.get_buffer) + self.view.append_column(column) - def get_current_page(self): - tree_selection = self.view.get_selection() - (model, pathlist) = tree_selection.get_selected_rows() - iter = pathlist[0] - return self.store[iter][0].buffer + def get_current_page(self): + tree_selection = self.view.get_selection() + (model, pathlist) = tree_selection.get_selected_rows() + iter = pathlist[0] + return self.store[iter][0].buffer - def get_buffer(self, column, cell, model, iter, data): - cell.set_property('text', self.store.get_value(iter, 0).name) + def get_buffer(self, column, cell, model, iter, data): + cell.set_property('text', self.store.get_value(iter, 0).name) - def match_func(self, row, name_, account): - name = name_ - account = account - iter = self.store.get_iter(row.path) - if self.store[iter][0].buffer.name == name and self.store[iter][0].buffer.account == account: - return (row.path, iter) - else: - return (None, None) + def match_func(self, row, name_, account): + name = name_ + account = account + iter = self.store.get_iter(row.path) + if self.store[iter][0].buffer.name == name and self.store[iter][0].buffer.account == account: + return (row.path, iter) + else: + return (None, None) - def search(self, rows, name_, account): - if not rows: return None - for row in rows: - (path, iter) = self.match_func(row, name_, account) - if iter != None: - return (path, iter) - (result_path, result_iter) = self.search(row.iterchildren(), name_, account) - if result_path: return (result_path, result_iter) - return (None, None) + def search(self, rows, name_, account): + if not rows: return None + for row in rows: + (path, iter) = self.match_func(row, name_, account) + if iter != None: + return (path, iter) + (result_path, result_iter) = self.search(row.iterchildren(), name_, account) + if result_path: return (result_path, result_iter) + return (None, None) class mainLoopObject(object): - def run(self): - GObject.type_register(buffer) - Gtk.main() + def run(self): + GObject.type_register(buffer) + Gtk.main() diff --git a/src/widgetUtils/wxUtils.py b/src/widgetUtils/wxUtils.py index 10c43362..9eb453ec 100644 --- a/src/widgetUtils/wxUtils.py +++ b/src/widgetUtils/wxUtils.py @@ -59,71 +59,71 @@ TASKBAR_RIGHT_CLICK = wx.adv.EVT_TASKBAR_RIGHT_DOWN TASKBAR_LEFT_CLICK = wx.adv.EVT_TASKBAR_LEFT_DOWN def exit_application(): - """ Closes the current window cleanly. """ - wx.GetApp().ExitMainLoop() + """ Closes the current window cleanly. """ + wx.GetApp().ExitMainLoop() def connect_event(parent, event, func, menuitem=None, *args, **kwargs): - """ Connects an event to a function. - parent wx.window: The widget that will listen for the event. - event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. - function func: The function that will be connected to the event.""" - if menuitem == None: - return getattr(parent, "Bind")(event, func, *args, **kwargs) - else: - return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs) + """ Connects an event to a function. + parent wx.window: The widget that will listen for the event. + event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events. + function func: The function that will be connected to the event.""" + if menuitem == None: + return getattr(parent, "Bind")(event, func, *args, **kwargs) + else: + return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs) def connectExitFunction(exitFunction): - """ This connect the events in WX when an user is turning off the machine.""" - wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, exitFunction) - wx.GetApp().Bind(wx.EVT_END_SESSION, exitFunction) + """ This connect the events in WX when an user is turning off the machine.""" + wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, exitFunction) + wx.GetApp().Bind(wx.EVT_END_SESSION, exitFunction) class BaseDialog(wx.Dialog): - def __init__(self, *args, **kwargs): - super(BaseDialog, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + super(BaseDialog, self).__init__(*args, **kwargs) - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def get(self, control): - if hasattr(self, control): - control = getattr(self, control) - if hasattr(control, "GetValue"): return getattr(control, "GetValue")() - elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")() - else: return -1 - else: return 0 + def get(self, control): + if hasattr(self, control): + control = getattr(self, control) + if hasattr(control, "GetValue"): return getattr(control, "GetValue")() + elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")() + else: return -1 + else: return 0 - def set(self, control, text): - if hasattr(self, control): - control = getattr(self, control) - if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text) - elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text) - elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) - else: return -1 - else: return 0 + def set(self, control, text): + if hasattr(self, control): + control = getattr(self, control) + if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text) + elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text) + elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) + else: return -1 + else: return 0 - def destroy(self): - self.Destroy() + def destroy(self): + self.Destroy() - def set_title(self, title): - self.SetTitle(title) + def set_title(self, title): + self.SetTitle(title) - def get_title(self): - return self.GetTitle() + def get_title(self): + return self.GetTitle() class mainLoopObject(wx.App): - def __init__(self): - self.app = wx.App() - self.lc = wx.Locale() - lang=languageHandler.getLanguage() - wxLang=self.lc.FindLanguageInfo(lang) - if not wxLang and '_' in lang: - wxLang=self.lc.FindLanguageInfo(lang.split('_')[0]) - if hasattr(sys,'frozen'): - self.lc.AddCatalogLookupPathPrefix(os.path.join(paths.app_path(), "locales")) - if wxLang: - self.lc.Init(wxLang.Language) + def __init__(self): + self.app = wx.App() + self.lc = wx.Locale() + lang=languageHandler.getLanguage() + wxLang=self.lc.FindLanguageInfo(lang) + if not wxLang and '_' in lang: + wxLang=self.lc.FindLanguageInfo(lang.split('_')[0]) + if hasattr(sys,'frozen'): + self.lc.AddCatalogLookupPathPrefix(os.path.join(paths.app_path(), "locales")) + if wxLang: + self.lc.Init(wxLang.Language) - def run(self): - self.app.MainLoop() + def run(self): + self.app.MainLoop() diff --git a/src/write_version_data.py b/src/write_version_data.py new file mode 100644 index 00000000..2136c3a0 --- /dev/null +++ b/src/write_version_data.py @@ -0,0 +1,30 @@ +#! /usr/bin/env python# -*- coding: iso-8859-1 -*- +""" Write version info (taken from the last commit) to application.py. This method has been implemented this way for running updates. +This file is not intended to be called by the user. It will be used only by the Gitlab CI runner.""" +import os +import requests +from codecs import open + +print("Writing version data for update...") +commit_info = requests.get("https://gitlab.com/api/v4/projects/23482196/repository/commits/next-gen") +commit_info = commit_info.json() +commit = commit_info["short_id"] +print("Got new version info: {commit}".format(commit=commit,)) +file = open("application.py", "r", encoding="utf-8") +lines = file.readlines() +lines[-1] = 'version = "{}"'.format(commit_info["created_at"][:10].replace("-", ".")) +file.close() +file2 = open("application.py", "w", encoding="utf-8") +file2.writelines(lines) +file2.close() +print("Wrote application.py with the new version info.") + +print("Updating next version on installer setup...") +file = open("..\\scripts\\twblue.nsi", "r", encoding="utf-8") +contents = file.read() +contents = contents.replace("0.95", commit_info["created_at"][:10].replace("-", ".")) +file.close() +file2 = open("..\\scripts\\twblue.nsi", "w", encoding="utf-8") +file2.write(contents) +file2.close() +print("done") diff --git a/src/wxUI/buffers/__init__.py b/src/wxUI/buffers/__init__.py index cc9de3f1..2825b5fb 100644 --- a/src/wxUI/buffers/__init__.py +++ b/src/wxUI/buffers/__init__.py @@ -10,4 +10,4 @@ from .panels import accountPanel, emptyPanel from .people import peoplePanel from .trends import trendsPanel from .tweet_searches import searchPanel -from .user_searches import searchUsersPanel \ No newline at end of file +from .user_searches import searchUsersPanel diff --git a/src/wxUI/buffers/base.py b/src/wxUI/buffers/base.py index 32287f9d..657caee3 100644 --- a/src/wxUI/buffers/base.py +++ b/src/wxUI/buffers/base.py @@ -4,43 +4,43 @@ import wx from multiplatform_widgets import widgets class basePanel(wx.Panel): - - def set_focus_function(self, f): - self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, f) - def create_list(self): - self.list = widgets.list(self, _(u"User"), _(u"Text"), _(u"Date"), _(u"Client"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) - self.list.set_windows_size(0, 60) - self.list.set_windows_size(1, 320) - self.list.set_windows_size(2, 110) - self.list.set_windows_size(3, 84) - self.list.set_size() + def set_focus_function(self, f): + self.list.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, f) - def __init__(self, parent, name): - super(basePanel, self).__init__(parent) - self.name = name - self.type = "baseBuffer" - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.create_list() - self.tweet = wx.Button(self, -1, _(u"Tweet")) - self.retweet = wx.Button(self, -1, _(u"Retweet")) - self.reply = wx.Button(self, -1, _(u"Reply")) - self.dm = wx.Button(self, -1, _(u"Direct message")) - btnSizer = wx.BoxSizer(wx.HORIZONTAL) - btnSizer.Add(self.tweet, 0, wx.ALL, 5) - btnSizer.Add(self.retweet, 0, wx.ALL, 5) - btnSizer.Add(self.reply, 0, wx.ALL, 5) - btnSizer.Add(self.dm, 0, wx.ALL, 5) - self.sizer.Add(btnSizer, 0, wx.ALL, 5) - self.sizer.Add(self.list.list, 0, wx.ALL|wx.EXPAND, 5) - self.SetSizer(self.sizer) - self.SetClientSize(self.sizer.CalcMin()) + def create_list(self): + self.list = widgets.list(self, _(u"User"), _(u"Text"), _(u"Date"), _(u"Client"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) + self.list.set_windows_size(0, 60) + self.list.set_windows_size(1, 320) + self.list.set_windows_size(2, 110) + self.list.set_windows_size(3, 84) + self.list.set_size() - def set_position(self, reversed=False): - if reversed == False: - self.list.select_item(self.list.get_count()-1) - else: - self.list.select_item(0) + def __init__(self, parent, name): + super(basePanel, self).__init__(parent) + self.name = name + self.type = "baseBuffer" + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.create_list() + self.tweet = wx.Button(self, -1, _(u"Tweet")) + self.retweet = wx.Button(self, -1, _(u"Retweet")) + self.reply = wx.Button(self, -1, _(u"Reply")) + self.dm = wx.Button(self, -1, _(u"Direct message")) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(self.tweet, 0, wx.ALL, 5) + btnSizer.Add(self.retweet, 0, wx.ALL, 5) + btnSizer.Add(self.reply, 0, wx.ALL, 5) + btnSizer.Add(self.dm, 0, wx.ALL, 5) + self.sizer.Add(btnSizer, 0, wx.ALL, 5) + self.sizer.Add(self.list.list, 0, wx.ALL|wx.EXPAND, 5) + self.SetSizer(self.sizer) + self.SetClientSize(self.sizer.CalcMin()) - def set_focus_in_list(self): - self.list.list.SetFocus() \ No newline at end of file + def set_position(self, reversed=False): + if reversed == False: + self.list.select_item(self.list.get_count()-1) + else: + self.list.select_item(0) + + def set_focus_in_list(self): + self.list.list.SetFocus() diff --git a/src/wxUI/buffers/dm.py b/src/wxUI/buffers/dm.py index 13ea457f..85cf7d11 100644 --- a/src/wxUI/buffers/dm.py +++ b/src/wxUI/buffers/dm.py @@ -5,9 +5,9 @@ import wx from .base import basePanel class dmPanel(basePanel): - def __init__(self, parent, name): - """ Class to DM'S. Reply and retweet buttons are not showed and they have your delete method for dm's.""" - super(dmPanel, self).__init__(parent, name) - self.retweet.Disable() - self.reply.Disable() - self.type = "dm" \ No newline at end of file + def __init__(self, parent, name): + """ Class to DM'S. Reply and retweet buttons are not showed and they have your delete method for dm's.""" + super(dmPanel, self).__init__(parent, name) + self.retweet.Disable() + self.reply.Disable() + self.type = "dm" diff --git a/src/wxUI/buffers/events.py b/src/wxUI/buffers/events.py index aaa9411c..9df06178 100644 --- a/src/wxUI/buffers/events.py +++ b/src/wxUI/buffers/events.py @@ -4,22 +4,22 @@ import wx from multiplatform_widgets import widgets class eventsPanel(wx.Panel): - """ Buffer to show events. Different than tweets or people.""" + """ Buffer to show events. Different than tweets or people.""" - def __init__(self, parent, name): - self.type = "event" - super(eventsPanel, self).__init__(parent) - self.name = name - sizer = wx.BoxSizer() - self.list = widgets.list(self, _(u"Date"), _(u"Event"), size=(600,600), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) - self.tweet = wx.Button(self, -1, _(u"Tweet")) - self.delete_event = wx.Button(self, -1, _(u"Remove event")) + def __init__(self, parent, name): + self.type = "event" + super(eventsPanel, self).__init__(parent) + self.name = name + sizer = wx.BoxSizer() + self.list = widgets.list(self, _(u"Date"), _(u"Event"), size=(600,600), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) + self.tweet = wx.Button(self, -1, _(u"Tweet")) + self.delete_event = wx.Button(self, -1, _(u"Remove event")) - def set_position(self, reversed=False): - if reversed == False: - self.list.select_item(self.list.get_count()-1) - else: - self.list.select_item(0) + def set_position(self, reversed=False): + if reversed == False: + self.list.select_item(self.list.get_count()-1) + else: + self.list.select_item(0) - def set_focus_in_list(self): - self.list.list.SetFocus() \ No newline at end of file + def set_focus_in_list(self): + self.list.list.SetFocus() diff --git a/src/wxUI/buffers/favourites.py b/src/wxUI/buffers/favourites.py index cc61e303..41ba04ae 100644 --- a/src/wxUI/buffers/favourites.py +++ b/src/wxUI/buffers/favourites.py @@ -5,6 +5,6 @@ import wx from .base import basePanel class favsPanel(basePanel): - def __init__(self, parent, name): - super(favsPanel, self).__init__(parent, name) - self.type = "favourites_timeline" \ No newline at end of file + def __init__(self, parent, name): + super(favsPanel, self).__init__(parent, name) + self.type = "favourites_timeline" diff --git a/src/wxUI/buffers/lists.py b/src/wxUI/buffers/lists.py index 9c31e95c..55c25813 100644 --- a/src/wxUI/buffers/lists.py +++ b/src/wxUI/buffers/lists.py @@ -5,6 +5,6 @@ import wx from .base import basePanel class listPanel(basePanel): - def __init__(self, parent, name): - super(listPanel, self).__init__(parent, name) - self.type = "list" + def __init__(self, parent, name): + super(listPanel, self).__init__(parent, name) + self.type = "list" diff --git a/src/wxUI/buffers/panels.py b/src/wxUI/buffers/panels.py index 5bd02498..f0ccfd4f 100644 --- a/src/wxUI/buffers/panels.py +++ b/src/wxUI/buffers/panels.py @@ -4,33 +4,33 @@ import wx from multiplatform_widgets import widgets class accountPanel(wx.Panel): - def __init__(self, parent, name=None): - super(accountPanel, self).__init__(parent=parent) - self.name = name - self.type = "account" - sizer = wx.BoxSizer(wx.VERTICAL) - self.login = wx.Button(self, -1, _(u"Login")) - sizer.Add(self.login, 0, wx.ALL, 5) - self.autostart_account = wx.CheckBox(self, -1, _(u"Log in automatically")) - sizer.Add(self.autostart_account, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent, name=None): + super(accountPanel, self).__init__(parent=parent) + self.name = name + self.type = "account" + sizer = wx.BoxSizer(wx.VERTICAL) + self.login = wx.Button(self, -1, _(u"Login")) + sizer.Add(self.login, 0, wx.ALL, 5) + self.autostart_account = wx.CheckBox(self, -1, _(u"Log in automatically")) + sizer.Add(self.autostart_account, 0, wx.ALL, 5) + self.SetSizer(sizer) - def change_login(self, login=True): - if login == True: - self.login.SetLabel(_(u"Login")) - else: - self.login.SetLabel(_(u"Logout")) + def change_login(self, login=True): + if login == True: + self.login.SetLabel(_(u"Login")) + else: + self.login.SetLabel(_(u"Logout")) - def change_autostart(self, autostart=True): - self.autostart_account.SetValue(autostart) + def change_autostart(self, autostart=True): + self.autostart_account.SetValue(autostart) - def get_autostart(self): - return self.autostart_account.GetValue() + def get_autostart(self): + return self.autostart_account.GetValue() class emptyPanel(wx.Panel): - def __init__(self, parent, name): - super(emptyPanel, self).__init__(parent=parent, name=name) - self.name = name - self.type = "account" - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetSizer(sizer) + def __init__(self, parent, name): + super(emptyPanel, self).__init__(parent=parent, name=name) + self.name = name + self.type = "account" + sizer = wx.BoxSizer(wx.VERTICAL) + self.SetSizer(sizer) diff --git a/src/wxUI/buffers/people.py b/src/wxUI/buffers/people.py index 25490be4..b2248f84 100644 --- a/src/wxUI/buffers/people.py +++ b/src/wxUI/buffers/people.py @@ -6,13 +6,13 @@ from multiplatform_widgets import widgets from .base import basePanel class peoplePanel(basePanel): - """ Buffer used to show people.""" + """ Buffer used to show people.""" - def create_list(self): - self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) + def create_list(self): + self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) - def __init__(self, parent, name): - super(peoplePanel, self).__init__(parent, name) - self.type = "people" - self.reply.SetLabel(_(u"Mention")) - self.retweet.Disable() + def __init__(self, parent, name): + super(peoplePanel, self).__init__(parent, name) + self.type = "people" + self.reply.SetLabel(_(u"Mention")) + self.retweet.Disable() diff --git a/src/wxUI/buffers/trends.py b/src/wxUI/buffers/trends.py index 51058e78..b9e67101 100644 --- a/src/wxUI/buffers/trends.py +++ b/src/wxUI/buffers/trends.py @@ -4,31 +4,33 @@ import wx from multiplatform_widgets import widgets class trendsPanel(wx.Panel): - def create_list(self): - """ Returns the list for put the tweets here.""" - self.list = widgets.list(self, _(u"Trending topic"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) - self.list.set_windows_size(0, 30) - self.list.set_size() + def create_list(self): + """ Returns the list for put the tweets here.""" + self.list = widgets.list(self, _(u"Trending topic"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VRULES) + self.list.set_windows_size(0, 30) + self.list.set_size() - def __init__(self, parent, name): - super(trendsPanel, self).__init__(parent) - self.type = "trends" - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.create_list() - self.tweet = wx.Button(self, -1, _(u"Tweet")) - self.tweetTrendBtn = wx.Button(self, -1, _(u"Tweet about this trend")) - self.search_topic = wx.Button(self, -1, _(u"Search topic")) - btnSizer = wx.BoxSizer(wx.HORIZONTAL) - btnSizer.Add(self.tweet, 0, wx.ALL, 5) - btnSizer.Add(self.tweetTrendBtn, 0, wx.ALL, 5) - btnSizer.Add(self.search_topic, 0, wx.ALL, 5) - self.sizer.Add(btnSizer, 0, wx.ALL, 5) - self.sizer.Add(self.list.list, 0, wx.ALL, 5) - self.SetSizer(self.sizer) + def __init__(self, parent, name): + super(trendsPanel, self).__init__(parent) + self.type = "trends" + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.create_list() + self.tweet = wx.Button(self, -1, _(u"Tweet")) + self.tweetTrendBtn = wx.Button(self, -1, _(u"Tweet about this trend")) + self.search_topic = wx.Button(self, -1, _(u"Search topic")) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(self.tweet, 0, wx.ALL, 5) + btnSizer.Add(self.tweetTrendBtn, 0, wx.ALL, 5) + btnSizer.Add(self.search_topic, 0, wx.ALL, 5) + self.sizer.Add(btnSizer, 0, wx.ALL, 5) + self.sizer.Add(self.list.list, 0, wx.ALL, 5) + self.SetSizer(self.sizer) - def set_position(self, reversed=False): - if reversed == False: - self.list.select_item(self.list.get_count()-1) - else: - self.list.select_item(0) - \ No newline at end of file + def set_position(self, reversed=False): + if reversed == False: + self.list.select_item(self.list.get_count()-1) + else: + self.list.select_item(0) + + def set_focus_in_list(self): + self.list.list.SetFocus() diff --git a/src/wxUI/buffers/tweet_searches.py b/src/wxUI/buffers/tweet_searches.py index 6862e482..df6560f0 100644 --- a/src/wxUI/buffers/tweet_searches.py +++ b/src/wxUI/buffers/tweet_searches.py @@ -5,6 +5,6 @@ import wx from .base import basePanel class searchPanel(basePanel): - def __init__(self, parent, name): - super(searchPanel, self).__init__(parent, name) - self.type = "search" + def __init__(self, parent, name): + super(searchPanel, self).__init__(parent, name) + self.type = "search" diff --git a/src/wxUI/buffers/user_searches.py b/src/wxUI/buffers/user_searches.py index 651c2a55..26292fd1 100644 --- a/src/wxUI/buffers/user_searches.py +++ b/src/wxUI/buffers/user_searches.py @@ -6,11 +6,11 @@ from .tweet_searches import searchPanel from multiplatform_widgets import widgets class searchUsersPanel(searchPanel): - def create_list(self): - """ Returns the list for put the tweets here.""" - self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) + def create_list(self): + """ Returns the list for put the tweets here.""" + self.list = widgets.list(self, _(u"User"), style=wx.LC_REPORT|wx.LC_SINGLE_SEL, size=(800, 800)) - def __init__(self, parent, name): - super(searchUsersPanel, self).__init__(parent, name) - self.create_list() - self.type = "user_searches" \ No newline at end of file + def __init__(self, parent, name): + super(searchUsersPanel, self).__init__(parent, name) + self.create_list() + self.type = "user_searches" diff --git a/src/wxUI/commonMessageDialogs.py b/src/wxUI/commonMessageDialogs.py index 3e683a98..1f4a77e6 100644 --- a/src/wxUI/commonMessageDialogs.py +++ b/src/wxUI/commonMessageDialogs.py @@ -4,95 +4,96 @@ import wx import application def retweet_as_link(parent): - return wx.MessageDialog(parent, _(u"This retweet is over 140 characters. Would you like to post it as a mention to the poster with your comments and a link to the original tweet?"), application.name, wx.YES_NO|wx.ICON_QUESTION).ShowModal() + return wx.MessageDialog(parent, _(u"This retweet is over 140 characters. Would you like to post it as a mention to the poster with your comments and a link to the original tweet?"), application.name, wx.YES_NO|wx.ICON_QUESTION).ShowModal() def retweet_question(parent): - return wx.MessageDialog(parent, _(u"Would you like to add a comment to this tweet?"), _("Retweet"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION).ShowModal() + return wx.MessageDialog(parent, _(u"Would you like to add a comment to this tweet?"), _("Retweet"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION).ShowModal() def delete_tweet_dialog(parent): - return wx.MessageDialog(parent, _(u"Do you really want to delete this tweet? It will be deleted from Twitter as well."), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO).ShowModal() + return wx.MessageDialog(parent, _(u"Do you really want to delete this tweet? It will be deleted from Twitter as well."), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO).ShowModal() def exit_dialog(parent): - dlg = wx.MessageDialog(parent, _(u"Do you really want to close {0}?").format(application.name,), _(u"Exit"), wx.YES_NO|wx.ICON_QUESTION) - return dlg.ShowModal() + dlg = wx.MessageDialog(parent, _(u"Do you really want to close {0}?").format(application.name,), _(u"Exit"), wx.YES_NO|wx.ICON_QUESTION) + return dlg.ShowModal() def needs_restart(): - wx.MessageDialog(None, _(u" {0} must be restarted for these changes to take effect.").format(application.name,), _("Restart {0} ").format(application.name,), wx.OK).ShowModal() + wx.MessageDialog(None, _(u" {0} must be restarted for these changes to take effect.").format(application.name,), _("Restart {0} ").format(application.name,), wx.OK).ShowModal() def delete_user_from_db(): - return wx.MessageDialog(None, _(u"Are you sure you want to delete this user from the database? This user will not appear in autocomplete results anymore."), _(u"Confirm"), wx.YES_NO|wx.ICON_QUESTION).ShowModal() + return wx.MessageDialog(None, _(u"Are you sure you want to delete this user from the database? This user will not appear in autocomplete results anymore."), _(u"Confirm"), wx.YES_NO|wx.ICON_QUESTION).ShowModal() def get_ignored_client(): - entry = wx.TextEntryDialog(None, _(u"Enter the name of the client : "), _(u"Add client")) - if entry.ShowModal() == wx.ID_OK: - return entry.GetValue() - return None + entry = wx.TextEntryDialog(None, _(u"Enter the name of the client : "), _(u"Add client")) + if entry.ShowModal() == wx.ID_OK: + return entry.GetValue() + return None def clear_list(): - dlg = wx.MessageDialog(None, _(u"Do you really want to empty this buffer? It's items will be removed from the list but not from Twitter"), _(u"Empty buffer"), wx.ICON_QUESTION|wx.YES_NO) - return dlg.ShowModal() + dlg = wx.MessageDialog(None, _(u"Do you really want to empty this buffer? It's items will be removed from the list but not from Twitter"), _(u"Empty buffer"), wx.ICON_QUESTION|wx.YES_NO) + return dlg.ShowModal() def remove_buffer(): - return wx.MessageDialog(None, _(u"Do you really want to destroy this buffer?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() + return wx.MessageDialog(None, _(u"Do you really want to destroy this buffer?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() def user_not_exist(): - return wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"That user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() def timeline_exist(): - return wx.MessageDialog(None, _(u"A timeline for this user already exists. You can't open another"), _(u"Existing timeline"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"A timeline for this user already exists. You can't open another"), _(u"Existing timeline"), wx.ICON_ERROR).ShowModal() def no_tweets(): - return wx.MessageDialog(None, _(u"This user has no tweets, so you can't open a timeline for them."), _(u"Error!"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This user has no tweets, so you can't open a timeline for them."), _(u"Error!"), wx.ICON_ERROR).ShowModal() def protected_user(): - return wx.MessageDialog(None, _(u"This is a protected Twitter user, which means you can't open a timeline using the Streaming API. The user's tweets will not update due to a twitter policy. Do you want to continue?"), _(u"Warning"), wx.ICON_WARNING|wx.YES_NO).ShowModal() + return wx.MessageDialog(None, _(u"This is a protected Twitter user, which means you can't open a timeline using the Streaming API. The user's tweets will not update due to a twitter policy. Do you want to continue?"), _(u"Warning"), wx.ICON_WARNING|wx.YES_NO).ShowModal() def no_following(): - return wx.MessageDialog(None, _(u"This is a protected user account, you need to follow this user to view their tweets or likes."), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This is a protected user account, you need to follow this user to view their tweets or likes."), _(u"Error"), wx.ICON_ERROR).ShowModal() def donation(): - dlg = wx.MessageDialog(None, _(u"If you like {0} we need your help to keep it going. Help us by donating to the project. This will help us pay for the server, the domain and some other things to ensure that {0} will be actively maintained. Your donation will give us the means to continue the development of {0}, and to keep {0} free. Would you like to donate now?").format(application.name), _(u"We need your help"), wx.ICON_QUESTION|wx.YES_NO) - return dlg.ShowModal() + dlg = wx.MessageDialog(None, _(u"If you like {0} we need your help to keep it going. Help us by donating to the project. This will help us pay for the server, the domain and some other things to ensure that {0} will be actively maintained. Your donation will give us the means to continue the development of {0}, and to keep {0} free. Would you like to donate now?").format(application.name), _(u"We need your help"), wx.ICON_QUESTION|wx.YES_NO) + return dlg.ShowModal() def no_tweets(): - return wx.MessageDialog(None, _(u"This user has no tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This user has no tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() def no_favs(): - return wx.MessageDialog(None, _(u"This user has no favorited tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This user has no favorited tweets. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() def no_followers(): - return wx.MessageDialog(None, _(u"This user has no followers. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This user has no followers. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() def no_friends(): - return wx.MessageDialog(None, _(u"This user has no friends. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(None, _(u"This user has no friends. {0} can't create a timeline.").format(application.name), _(u"Error"), wx.ICON_ERROR).ShowModal() def view_geodata(geotext): - """Specific message dialog to display geolocation data""" - return wx.MessageDialog(None, _(u"Geolocation data: {0}").format(geotext), _(u"Geo data for this tweet")).ShowModal() + """Specific message dialog to display geolocation data""" + return wx.MessageDialog(None, _(u"Geolocation data: {0}").format(geotext), _(u"Geo data for this tweet")).ShowModal() def changed_keymap(): - return wx.MessageDialog(None, _(u"TWBlue has detected that you're running windows 10 and has changed the default keymap to the Windows 10 keymap. It means that some keyboard shorcuts could be different. Please check the keystroke editor by pressing Alt+Win+K to see all available keystrokes for this keymap."), _(u"Information"), wx.OK).ShowModal() + return wx.MessageDialog(None, _(u"TWBlue has detected that you're running windows 10 and has changed the default keymap to the Windows 10 keymap. It means that some keyboard shorcuts could be different. Please check the keystroke editor by pressing Alt+Win+K to see all available keystrokes for this keymap."), _(u"Information"), wx.OK).ShowModal() def unauthorized(): - return wx.MessageDialog(None, _(u"You have been blocked from viewing this content"), _(u"Error"), wx.OK).ShowModal() + return wx.MessageDialog(None, _(u"You have been blocked from viewing this content"), _(u"Error"), wx.OK).ShowModal() def blocked_timeline(): - return wx.MessageDialog(None, _(u"You have been blocked from viewing someone's content. In order to avoid conflicts with the full session, TWBlue will remove the affected timeline."), _(u"Error"), wx.OK).ShowModal() - + return wx.MessageDialog(None, _(u"You have been blocked from viewing someone's content. In order to avoid conflicts with the full session, TWBlue will remove the affected timeline."), _(u"Error"), wx.OK).ShowModal() + def suspended_user(): - return wx.MessageDialog(None, _(u"TWBlue cannot load this timeline because the user has been suspended from Twitter."), _(u"Error"), wx.OK).ShowModal() + return wx.MessageDialog(None, _(u"TWBlue cannot load this timeline because the user has been suspended from Twitter."), _(u"Error"), wx.OK).ShowModal() def delete_filter(): - return wx.MessageDialog(None, _(u"Do you really want to delete this filter?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() + return wx.MessageDialog(None, _(u"Do you really want to delete this filter?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() def existing_filter(): - return wx.MessageDialog(None, _(u"This filter already exists. Please use a different title"), _(u"Error"), wx.OK).ShowModal() + return wx.MessageDialog(None, _(u"This filter already exists. Please use a different title"), _(u"Error"), wx.OK).ShowModal() def common_error(reason): - return wx.MessageDialog(None, reason, _(u"Error"), wx.OK).ShowModal() + return wx.MessageDialog(None, reason, _(u"Error"), wx.OK).ShowModal() + + def invalid_configuration(): + return wx.MessageDialog(None, _("The configuration file is invalid."), _("Error"), wx.ICON_ERROR).ShowModal() def dead_pid(): - return wx.MessageDialog(None, _(u"{0} quit unexpectedly the last time it was run. If the problem persists, please report it to the {0} developers.").format(application.name), _(u"Warning"), wx.OK).ShowModal() + return wx.MessageDialog(None, _(u"{0} quit unexpectedly the last time it was run. If the problem persists, please report it to the {0} developers.").format(application.name), _(u"Warning"), wx.OK).ShowModal() -def invalid_configration(): - return wx.MessageDialog(None, _(u"The configuration file is invalid."), _(u"Error"), wx.OK).ShowModal() \ No newline at end of file diff --git a/src/wxUI/dialogs/__init__.py b/src/wxUI/dialogs/__init__.py index a34f1b2f..d00a14c0 100644 --- a/src/wxUI/dialogs/__init__.py +++ b/src/wxUI/dialogs/__init__.py @@ -1,3 +1 @@ -from __future__ import absolute_import -from __future__ import unicode_literals -from . import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs +from . import baseDialog, trends, configuration, lists, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs, userAliasDialogs diff --git a/src/wxUI/dialogs/attach.py b/src/wxUI/dialogs/attach.py deleted file mode 100644 index ea8d35c1..00000000 --- a/src/wxUI/dialogs/attach.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -""" Attach dialog. Taken from socializer: https://github.com/manuelcortez/socializer""" -from __future__ import unicode_literals -import wx -import widgetUtils -from multiplatform_widgets import widgets - -class attachDialog(widgetUtils.BaseDialog): - def __init__(self): - super(attachDialog, self).__init__(None, title=_(u"Add an attachment")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - lbl1 = wx.StaticText(panel, wx.ID_ANY, _(u"Attachments")) - self.attachments = widgets.list(panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT) - box = wx.BoxSizer(wx.HORIZONTAL) - box.Add(lbl1, 0, wx.ALL, 5) - box.Add(self.attachments.list, 0, wx.ALL, 5) - sizer.Add(box, 0, wx.ALL, 5) - static = wx.StaticBox(panel, label=_(u"Add attachments")) - self.photo = wx.Button(panel, wx.ID_ANY, _(u"&Photo")) - self.remove = wx.Button(panel, wx.ID_ANY, _(u"Remove attachment")) - self.remove.Enable(False) - btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL) - btnsizer.Add(self.photo, 0, wx.ALL, 5) - sizer.Add(btnsizer, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK) - ok.SetDefault() - cancelBtn = wx.Button(panel, wx.ID_CANCEL) - btnSizer = wx.BoxSizer() - btnSizer.Add(ok, 0, wx.ALL, 5) - btnSizer.Add(cancelBtn, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return (None, None) - dsc = self.ask_description() - return (openFileDialog.GetPath(), dsc) - - def ask_description(self): - dlg = wx.TextEntryDialog(self, _(u"please provide a description"), _(u"Description")) - dlg.ShowModal() - result = dlg.GetValue() - dlg.Destroy() - return result diff --git a/src/wxUI/dialogs/baseDialog.py b/src/wxUI/dialogs/baseDialog.py index 01fe8b49..20480d9e 100644 --- a/src/wxUI/dialogs/baseDialog.py +++ b/src/wxUI/dialogs/baseDialog.py @@ -2,28 +2,28 @@ from __future__ import unicode_literals import wx class BaseWXDialog(wx.Dialog): - def __init__(self, *args, **kwargs): - super(BaseWXDialog, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + super(BaseWXDialog, self).__init__(*args, **kwargs) - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def get(self, control): - if hasattr(self, control): - control = getattr(self, control) - if hasattr(control, "GetValue"): return getattr(control, "GetValue")() - elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")() - else: return -1 - else: return 0 + def get(self, control): + if hasattr(self, control): + control = getattr(self, control) + if hasattr(control, "GetValue"): return getattr(control, "GetValue")() + elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")() + else: return -1 + else: return 0 - def set(self, control, text): - if hasattr(self, control): - control = getattr(self, control) - if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text) - elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text) - elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) - else: return -1 - else: return 0 + def set(self, control, text): + if hasattr(self, control): + control = getattr(self, control) + if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text) + elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text) + elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) + else: return -1 + else: return 0 - def set_title(self, title): - self.SetTitle(title) + def set_title(self, title): + self.SetTitle(title) diff --git a/src/wxUI/dialogs/configuration.py b/src/wxUI/dialogs/configuration.py index def44926..1bc5de9c 100644 --- a/src/wxUI/dialogs/configuration.py +++ b/src/wxUI/dialogs/configuration.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -from builtins import range import logging as original_logger import wx import application @@ -12,403 +9,404 @@ from . import baseDialog from multiplatform_widgets import widgets class general(wx.Panel, baseDialog.BaseWXDialog): - def __init__(self, parent, languages,keymaps): - super(general, self).__init__(parent) - sizer = wx.BoxSizer(wx.VERTICAL) - language = wx.StaticText(self, -1, _(u"Language")) - self.language = wx.ListBox(self, -1, choices=languages) - self.language.SetSize(self.language.GetBestSize()) - langBox = wx.BoxSizer(wx.HORIZONTAL) - langBox.Add(language, 0, wx.ALL, 5) - langBox.Add(self.language, 0, wx.ALL, 5) - sizer.Add(langBox, 0, wx.ALL, 5) - self.autostart = wx.CheckBox(self, -1, _(u"Run {0} at Windows startup").format(application.name,)) - self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting {0}").format(application.name,)) - sizer.Add(self.autostart, 0, wx.ALL, 5) - sizer.Add(self.ask_at_exit, 0, wx.ALL, 5) - self.no_streaming = wx.CheckBox(self, -1, _(U"Disable Streaming functions")) - sizer.Add(self.no_streaming, 0, wx.ALL, 5) - updatePeriodBox = wx.BoxSizer(wx.HORIZONTAL) - updatePeriodBox.Add(wx.StaticText(self, -1, _(u"Buffer update interval, in minutes")), 0, wx.ALL, 5) - self.update_period = wx.SpinCtrl(self, wx.ID_ANY) - self.update_period.SetRange(1, 30) - self.update_period.SetSize(self.update_period.GetBestSize()) - updatePeriodBox.Add(self.update_period, 0, wx.ALL, 5) - sizer.Add(updatePeriodBox, 0, wx.ALL, 5) - self.play_ready_sound = wx.CheckBox(self, -1, _(U"Play a sound when {0} launches").format(application.name,)) - sizer.Add(self.play_ready_sound, 0, wx.ALL, 5) - self.speak_ready_msg = wx.CheckBox(self, -1, _(U"Speak a message when {0} launches").format(application.name,)) - sizer.Add(self.speak_ready_msg, 0, wx.ALL, 5) - self.use_invisible_shorcuts = wx.CheckBox(self, -1, _(u"Use invisible interface's keyboard shortcuts while GUI is visible")) - sizer.Add(self.use_invisible_shorcuts, 0, wx.ALL, 5) - self.disable_sapi5 = wx.CheckBox(self, -1, _(u"Activate Sapi5 when any other screen reader is not being run")) - sizer.Add(self.disable_sapi5, 0, wx.ALL, 5) - self.hide_gui = wx.CheckBox(self, -1, _(u"Hide GUI on launch")) - sizer.Add(self.hide_gui, 0, wx.ALL, 5) - self.handle_longtweets = wx.CheckBox(self, wx.ID_ANY, _(u"Use Codeofdusk's longtweet handlers (may decrease client performance)")) - sizer.Add(self.handle_longtweets, 0, wx.ALL, 5) - self.remember_mention_and_longtweet = wx.CheckBox(self, -1, _(u"Remember state for mention all and long tweet")) - sizer.Add(self.remember_mention_and_longtweet, 0, wx.ALL, 5) - kmbox = wx.BoxSizer(wx.VERTICAL) - km_label = wx.StaticText(self, -1, _(u"Keymap")) - self.km = wx.ComboBox(self, -1, choices=keymaps, style=wx.CB_READONLY) - self.km.SetSize(self.km.GetBestSize()) - kmbox.Add(km_label, 0, wx.ALL, 5) - kmbox.Add(self.km, 0, wx.ALL, 5) - self.check_for_updates = wx.CheckBox(self, -1, _(U"Check for updates when {0} launches").format(application.name,)) - sizer.Add(self.check_for_updates, 0, wx.ALL, 5) - sizer.Add(kmbox, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent, languages,keymaps): + super(general, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + language = wx.StaticText(self, -1, _(u"Language")) + self.language = wx.ListBox(self, -1, choices=languages) + self.language.SetSize(self.language.GetBestSize()) + langBox = wx.BoxSizer(wx.HORIZONTAL) + langBox.Add(language, 0, wx.ALL, 5) + langBox.Add(self.language, 0, wx.ALL, 5) + sizer.Add(langBox, 0, wx.ALL, 5) + self.autostart = wx.CheckBox(self, -1, _(u"Run {0} at Windows startup").format(application.name,)) + self.ask_at_exit = wx.CheckBox(self, -1, _(U"ask before exiting {0}").format(application.name,)) + sizer.Add(self.autostart, 0, wx.ALL, 5) + sizer.Add(self.ask_at_exit, 0, wx.ALL, 5) + self.no_streaming = wx.CheckBox(self, -1, _(U"Disable Streaming functions")) + sizer.Add(self.no_streaming, 0, wx.ALL, 5) + updatePeriodBox = wx.BoxSizer(wx.HORIZONTAL) + updatePeriodBox.Add(wx.StaticText(self, -1, _(u"Buffer update interval, in minutes")), 0, wx.ALL, 5) + self.update_period = wx.SpinCtrl(self, wx.ID_ANY) + self.update_period.SetRange(1, 30) + self.update_period.SetSize(self.update_period.GetBestSize()) + updatePeriodBox.Add(self.update_period, 0, wx.ALL, 5) + sizer.Add(updatePeriodBox, 0, wx.ALL, 5) + self.play_ready_sound = wx.CheckBox(self, -1, _(U"Play a sound when {0} launches").format(application.name,)) + sizer.Add(self.play_ready_sound, 0, wx.ALL, 5) + self.speak_ready_msg = wx.CheckBox(self, -1, _(U"Speak a message when {0} launches").format(application.name,)) + sizer.Add(self.speak_ready_msg, 0, wx.ALL, 5) + self.use_invisible_shorcuts = wx.CheckBox(self, -1, _(u"Use invisible interface's keyboard shortcuts while GUI is visible")) + sizer.Add(self.use_invisible_shorcuts, 0, wx.ALL, 5) + self.disable_sapi5 = wx.CheckBox(self, -1, _(u"Activate Sapi5 when any other screen reader is not being run")) + sizer.Add(self.disable_sapi5, 0, wx.ALL, 5) + self.hide_gui = wx.CheckBox(self, -1, _(u"Hide GUI on launch")) + sizer.Add(self.hide_gui, 0, wx.ALL, 5) + self.handle_longtweets = wx.CheckBox(self, wx.ID_ANY, _(u"Use Codeofdusk's longtweet handlers (may decrease client performance)")) + sizer.Add(self.handle_longtweets, 0, wx.ALL, 5) + self.remember_mention_and_longtweet = wx.CheckBox(self, -1, _(u"Remember state for mention all and long tweet")) + sizer.Add(self.remember_mention_and_longtweet, 0, wx.ALL, 5) + kmbox = wx.BoxSizer(wx.VERTICAL) + km_label = wx.StaticText(self, -1, _(u"Keymap")) + self.km = wx.ComboBox(self, -1, choices=keymaps, style=wx.CB_READONLY) + self.km.SetSize(self.km.GetBestSize()) + kmbox.Add(km_label, 0, wx.ALL, 5) + kmbox.Add(self.km, 0, wx.ALL, 5) + self.check_for_updates = wx.CheckBox(self, -1, _(U"Check for updates when {0} launches").format(application.name,)) + sizer.Add(self.check_for_updates, 0, wx.ALL, 5) + sizer.Add(kmbox, 0, wx.ALL, 5) + self.SetSizer(sizer) class proxy(wx.Panel, baseDialog.BaseWXDialog): - def __init__(self, parent, proxyTypes): - super(proxy, self).__init__(parent) - sizer = wx.BoxSizer(wx.VERTICAL) - type=wx.StaticText(self, wx.ID_ANY, _(u"Proxy type: ")) - self.type=wx.ComboBox(self, -1, choices=proxyTypes, style=wx.CB_READONLY) - self.type.SetSize(self.type.GetBestSize()) - typeBox = wx.BoxSizer(wx.HORIZONTAL) - typeBox.Add(type, 0, wx.ALL, 5) - typeBox.Add(self.type, 0, wx.ALL, 5) - sizer.Add(typeBox, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"Proxy server: ")) - self.server = wx.TextCtrl(self, -1) - serverBox = wx.BoxSizer(wx.HORIZONTAL) - serverBox.Add(lbl, 0, wx.ALL, 5) - serverBox.Add(self.server, 0, wx.ALL, 5) - sizer.Add(serverBox, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"Port: ")) - self.port = wx.SpinCtrl(self, wx.ID_ANY, min=1, max=65535) - portBox = wx.BoxSizer(wx.HORIZONTAL) - portBox.Add(lbl, 0, wx.ALL, 5) - portBox.Add(self.port, 0, wx.ALL, 5) - sizer.Add(portBox, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"User: ")) - self.user = wx.TextCtrl(self, wx.ID_ANY) - userBox = wx.BoxSizer(wx.HORIZONTAL) - userBox.Add(lbl, 0, wx.ALL, 5) - userBox.Add(self.user, 0, wx.ALL, 5) - sizer.Add(userBox, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"Password: ")) - self.password = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PASSWORD) - passwordBox = wx.BoxSizer(wx.HORIZONTAL) - passwordBox.Add(lbl, 0, wx.ALL, 5) - passwordBox.Add(self.password, 0, wx.ALL, 5) - sizer.Add(serverBox, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent, proxyTypes): + super(proxy, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + type=wx.StaticText(self, wx.ID_ANY, _(u"Proxy type: ")) + self.type=wx.ComboBox(self, -1, choices=proxyTypes, style=wx.CB_READONLY) + self.type.SetSize(self.type.GetBestSize()) + typeBox = wx.BoxSizer(wx.HORIZONTAL) + typeBox.Add(type, 0, wx.ALL, 5) + typeBox.Add(self.type, 0, wx.ALL, 5) + sizer.Add(typeBox, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"Proxy server: ")) + self.server = wx.TextCtrl(self, -1) + serverBox = wx.BoxSizer(wx.HORIZONTAL) + serverBox.Add(lbl, 0, wx.ALL, 5) + serverBox.Add(self.server, 0, wx.ALL, 5) + sizer.Add(serverBox, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"Port: ")) + self.port = wx.SpinCtrl(self, wx.ID_ANY, min=1, max=65535) + portBox = wx.BoxSizer(wx.HORIZONTAL) + portBox.Add(lbl, 0, wx.ALL, 5) + portBox.Add(self.port, 0, wx.ALL, 5) + sizer.Add(portBox, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"User: ")) + self.user = wx.TextCtrl(self, wx.ID_ANY) + userBox = wx.BoxSizer(wx.HORIZONTAL) + userBox.Add(lbl, 0, wx.ALL, 5) + userBox.Add(self.user, 0, wx.ALL, 5) + sizer.Add(userBox, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"Password: ")) + self.password = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PASSWORD) + passwordBox = wx.BoxSizer(wx.HORIZONTAL) + passwordBox.Add(lbl, 0, wx.ALL, 5) + passwordBox.Add(self.password, 0, wx.ALL, 5) + sizer.Add(serverBox, 0, wx.ALL, 5) + self.SetSizer(sizer) class generalAccount(wx.Panel, baseDialog.BaseWXDialog): - def __init__(self, parent): - super(generalAccount, self).__init__(parent) - sizer = wx.BoxSizer(wx.VERTICAL) - self.au = wx.Button(self, wx.ID_ANY, _(u"Autocompletion settings...")) - sizer.Add(self.au, 0, wx.ALL, 5) - self.relative_time = wx.CheckBox(self, wx.ID_ANY, _(U"Relative timestamps")) - sizer.Add(self.relative_time, 0, wx.ALL, 5) - tweetsPerCallBox = wx.BoxSizer(wx.HORIZONTAL) - tweetsPerCallBox.Add(wx.StaticText(self, -1, _(u"Items on each API call")), 0, wx.ALL, 5) - self.itemsPerApiCall = wx.SpinCtrl(self, wx.ID_ANY) - self.itemsPerApiCall.SetRange(0, 200) - self.itemsPerApiCall.SetSize(self.itemsPerApiCall.GetBestSize()) - tweetsPerCallBox.Add(self.itemsPerApiCall, 0, wx.ALL, 5) - sizer.Add(tweetsPerCallBox, 0, wx.ALL, 5) - self.reverse_timelines = wx.CheckBox(self, wx.ID_ANY, _(u"Inverted buffers: The newest tweets will be shown at the beginning while the oldest at the end")) - sizer.Add(self.reverse_timelines, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"Retweet mode")) - self.retweet_mode = wx.ComboBox(self, wx.ID_ANY, choices=[_(u"Ask"), _(u"Retweet without comments"), _(u"Retweet with comments")], style=wx.CB_READONLY) - rMode = wx.BoxSizer(wx.HORIZONTAL) - rMode.Add(lbl, 0, wx.ALL, 5) - rMode.Add(self.retweet_mode, 0, wx.ALL, 5) - sizer.Add(rMode, 0, wx.ALL, 5) - self.show_screen_names = wx.CheckBox(self, wx.ID_ANY, _(U"Show screen names instead of full names")) - sizer.Add(self.show_screen_names, 0, wx.ALL, 5) - PersistSizeLabel = wx.StaticText(self, -1, _(u"Number of items per buffer to cache in database (0 to disable caching, blank for unlimited)")) - self.persist_size = wx.TextCtrl(self, -1) - sizer.Add(PersistSizeLabel, 0, wx.ALL, 5) - sizer.Add(self.persist_size, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent): + super(generalAccount, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + self.au = wx.Button(self, wx.ID_ANY, _(u"Autocompletion settings...")) + sizer.Add(self.au, 0, wx.ALL, 5) + self.relative_time = wx.CheckBox(self, wx.ID_ANY, _(U"Relative timestamps")) + sizer.Add(self.relative_time, 0, wx.ALL, 5) + tweetsPerCallBox = wx.BoxSizer(wx.HORIZONTAL) + tweetsPerCallBox.Add(wx.StaticText(self, -1, _(u"Items on each API call")), 0, wx.ALL, 5) + self.itemsPerApiCall = wx.SpinCtrl(self, wx.ID_ANY) + self.itemsPerApiCall.SetRange(0, 200) + self.itemsPerApiCall.SetSize(self.itemsPerApiCall.GetBestSize()) + tweetsPerCallBox.Add(self.itemsPerApiCall, 0, wx.ALL, 5) + sizer.Add(tweetsPerCallBox, 0, wx.ALL, 5) + self.reverse_timelines = wx.CheckBox(self, wx.ID_ANY, _(u"Inverted buffers: The newest tweets will be shown at the beginning while the oldest at the end")) + sizer.Add(self.reverse_timelines, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"Retweet mode")) + self.retweet_mode = wx.ComboBox(self, wx.ID_ANY, choices=[_(u"Ask"), _(u"Retweet without comments"), _(u"Retweet with comments")], style=wx.CB_READONLY) + rMode = wx.BoxSizer(wx.HORIZONTAL) + rMode.Add(lbl, 0, wx.ALL, 5) + rMode.Add(self.retweet_mode, 0, wx.ALL, 5) + sizer.Add(rMode, 0, wx.ALL, 5) + self.show_screen_names = wx.CheckBox(self, wx.ID_ANY, _(U"Show screen names instead of full names")) + sizer.Add(self.show_screen_names, 0, wx.ALL, 5) + PersistSizeLabel = wx.StaticText(self, -1, _(u"Number of items per buffer to cache in database (0 to disable caching, blank for unlimited)")) + self.persist_size = wx.TextCtrl(self, -1) + sizer.Add(PersistSizeLabel, 0, wx.ALL, 5) + sizer.Add(self.persist_size, 0, wx.ALL, 5) + self.load_cache_in_memory = wx.CheckBox(self, wx.NewId(), _("Load cache for tweets in memory (much faster in big datasets but requires more RAM)")) + self.SetSizer(sizer) class reporting(wx.Panel, baseDialog.BaseWXDialog): - def __init__(self, parent): - super(reporting, self).__init__(parent) - sizer = wx.BoxSizer(wx.VERTICAL) - self.speech_reporting = wx.CheckBox(self, wx.ID_ANY, _(U"Enable automatic speech feedback")) - sizer.Add(self.speech_reporting, 0, wx.ALL, 5) - self.braille_reporting = wx.CheckBox(self, wx.ID_ANY, _(U"Enable automatic Braille feedback")) - sizer.Add(self.braille_reporting, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent): + super(reporting, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + self.speech_reporting = wx.CheckBox(self, wx.ID_ANY, _(U"Enable automatic speech feedback")) + sizer.Add(self.speech_reporting, 0, wx.ALL, 5) + self.braille_reporting = wx.CheckBox(self, wx.ID_ANY, _(U"Enable automatic Braille feedback")) + sizer.Add(self.braille_reporting, 0, wx.ALL, 5) + self.SetSizer(sizer) class other_buffers(wx.Panel): - def __init__(self, parent): - super(other_buffers, self).__init__(parent) - sizer = wx.BoxSizer(wx.VERTICAL) - self.buffers = widgets.list(self, _(u"Buffer"), _(u"Name"), _(u"Status"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT) - sizer.Add(self.buffers.list, 0, wx.ALL, 5) - btnSizer = wx.BoxSizer(wx.HORIZONTAL) - self.toggle_state = wx.Button(self, -1, _(u"Show/hide")) - self.up = wx.Button(self, -1, _(u"Move up")) - self.down = wx.Button(self, -1, _(u"Move down")) - btnSizer.Add(self.toggle_state, 0, wx.ALL, 5) - btnSizer.Add(self.up, 0, wx.ALL, 5) - btnSizer.Add(self.down, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent): + super(other_buffers, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + self.buffers = widgets.list(self, _(u"Buffer"), _(u"Name"), _(u"Status"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT) + sizer.Add(self.buffers.list, 0, wx.ALL, 5) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + self.toggle_state = wx.Button(self, -1, _(u"Show/hide")) + self.up = wx.Button(self, -1, _(u"Move up")) + self.down = wx.Button(self, -1, _(u"Move down")) + btnSizer.Add(self.toggle_state, 0, wx.ALL, 5) + btnSizer.Add(self.up, 0, wx.ALL, 5) + btnSizer.Add(self.down, 0, wx.ALL, 5) + sizer.Add(btnSizer, 0, wx.ALL, 5) + self.SetSizer(sizer) - def insert_buffers(self, buffers): - for i in buffers: - if i[2] == True: - self.buffers.insert_item(False, *[i[0], i[1], _(u"Show")]) - else: - self.buffers.insert_item(False, *[i[0], i[1], _(u"Hide")]) + def insert_buffers(self, buffers): + for i in buffers: + if i[2] == True: + self.buffers.insert_item(False, *[i[0], i[1], _(u"Show")]) + else: + self.buffers.insert_item(False, *[i[0], i[1], _(u"Hide")]) - def connect_hook_func(self, func): - self.buffers.list.Bind(wx.EVT_CHAR_HOOK, func) + def connect_hook_func(self, func): + self.buffers.list.Bind(wx.EVT_CHAR_HOOK, func) - def move_up(self, *args, **kwargs): - current = self.buffers.get_selected() - if current == -1: - output.speak(_(u"Select a buffer first."), True) - return False - if self.buffers.get_text_column(current, 2) == _(u"Hide"): - output.speak(_(u"The buffer is hidden, show it first."), True) - return False - if current <= 0: - output.speak(_(u"The buffer is already at the top of the list."), True) - return False - current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) - current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) - current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) - text_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 0) - name_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 1) - text_above_state = self.buffers.get_text_column(self.buffers.get_selected()-1, 2) - self.buffers.set_text_column(self.buffers.get_selected()-1, 0, current_text) - self.buffers.set_text_column(self.buffers.get_selected()-1, 1, current_name) - self.buffers.set_text_column(self.buffers.get_selected()-1, 2, current_text_state) - self.buffers.set_text_column(self.buffers.get_selected(), 0, text_above) - self.buffers.set_text_column(self.buffers.get_selected(), 1, name_above) - self.buffers.set_text_column(self.buffers.get_selected(), 2, text_above_state) + def move_up(self, *args, **kwargs): + current = self.buffers.get_selected() + if current == -1: + output.speak(_(u"Select a buffer first."), True) + return False + if self.buffers.get_text_column(current, 2) == _(u"Hide"): + output.speak(_(u"The buffer is hidden, show it first."), True) + return False + if current <= 0: + output.speak(_(u"The buffer is already at the top of the list."), True) + return False + current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) + current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) + current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) + text_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 0) + name_above = self.buffers.get_text_column(self.buffers.get_selected()-1, 1) + text_above_state = self.buffers.get_text_column(self.buffers.get_selected()-1, 2) + self.buffers.set_text_column(self.buffers.get_selected()-1, 0, current_text) + self.buffers.set_text_column(self.buffers.get_selected()-1, 1, current_name) + self.buffers.set_text_column(self.buffers.get_selected()-1, 2, current_text_state) + self.buffers.set_text_column(self.buffers.get_selected(), 0, text_above) + self.buffers.set_text_column(self.buffers.get_selected(), 1, name_above) + self.buffers.set_text_column(self.buffers.get_selected(), 2, text_above_state) - def move_down(self, *args, **kwargs): - current = self.buffers.get_selected() - if current == -1: - output.speak(_(u"Select a buffer first."), True) - return False - if self.buffers.get_text_column(current, 2) == _(u"Hide"): - output.speak(_(u"The buffer is hidden, show it first."), True) - return False - if current+1 >= self.buffers.get_count(): - output.speak(_(u"The buffer is already at the bottom of the list."), True) - return False - current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) - current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) - current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) - text_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 0) - name_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 1) - text_below_state = self.buffers.get_text_column(self.buffers.get_selected()+1, 2) - self.buffers.set_text_column(self.buffers.get_selected()+1, 0, current_text) - self.buffers.set_text_column(self.buffers.get_selected()+1, 1, current_name) - self.buffers.set_text_column(self.buffers.get_selected()+1, 2, current_text_state) - self.buffers.set_text_column(self.buffers.get_selected(), 0, text_below) - self.buffers.set_text_column(self.buffers.get_selected(), 1, name_below) - self.buffers.set_text_column(self.buffers.get_selected(), 2, text_below_state) + def move_down(self, *args, **kwargs): + current = self.buffers.get_selected() + if current == -1: + output.speak(_(u"Select a buffer first."), True) + return False + if self.buffers.get_text_column(current, 2) == _(u"Hide"): + output.speak(_(u"The buffer is hidden, show it first."), True) + return False + if current+1 >= self.buffers.get_count(): + output.speak(_(u"The buffer is already at the bottom of the list."), True) + return False + current_text = self.buffers.get_text_column(self.buffers.get_selected(), 0) + current_name = self.buffers.get_text_column(self.buffers.get_selected(), 1) + current_text_state = self.buffers.get_text_column(self.buffers.get_selected(), 2) + text_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 0) + name_below = self.buffers.get_text_column(self.buffers.get_selected()+1, 1) + text_below_state = self.buffers.get_text_column(self.buffers.get_selected()+1, 2) + self.buffers.set_text_column(self.buffers.get_selected()+1, 0, current_text) + self.buffers.set_text_column(self.buffers.get_selected()+1, 1, current_name) + self.buffers.set_text_column(self.buffers.get_selected()+1, 2, current_text_state) + self.buffers.set_text_column(self.buffers.get_selected(), 0, text_below) + self.buffers.set_text_column(self.buffers.get_selected(), 1, name_below) + self.buffers.set_text_column(self.buffers.get_selected(), 2, text_below_state) - def get_event(self, ev): - if ev.GetKeyCode() == wx.WXK_SPACE: - return True - else: - ev.Skip() - return False + def get_event(self, ev): + if ev.GetKeyCode() == wx.WXK_SPACE: + return True + else: + ev.Skip() + return False - def change_selected_item(self): - current = self.buffers.get_selected() - text = self.buffers.get_text_column(current, 2) - if text == _(u"Show"): - self.buffers.set_text_column(current, 2, _(u"Hide")) - else: - self.buffers.set_text_column(current, 2, _(u"Show")) - output.speak(self.buffers.get_text_column(current, 2),True) - def get_list(self): - buffers_list = [] - for i in range(0, self.buffers.get_count()): - if self.buffers.get_text_column(i, 2) == _(u"Show"): - buffers_list.append(self.buffers.get_text_column(i, 0)) - return buffers_list + def change_selected_item(self): + current = self.buffers.get_selected() + text = self.buffers.get_text_column(current, 2) + if text == _(u"Show"): + self.buffers.set_text_column(current, 2, _(u"Hide")) + else: + self.buffers.set_text_column(current, 2, _(u"Show")) + output.speak(self.buffers.get_text_column(current, 2),True) + def get_list(self): + buffers_list = [] + for i in range(0, self.buffers.get_count()): + if self.buffers.get_text_column(i, 2) == _(u"Show"): + buffers_list.append(self.buffers.get_text_column(i, 0)) + return buffers_list class ignoredClients(wx.Panel): - def __init__(self, parent, choices): - super(ignoredClients, self).__init__(parent=parent) - sizer = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(self, -1, _(u"Ignored clients")) - self.clients = wx.ListBox(self, -1, choices=choices) - self.clients.SetSize(self.clients.GetBestSize()) - clientsBox = wx.BoxSizer(wx.HORIZONTAL) - clientsBox.Add(label, 0, wx.ALL, 5) - clientsBox.Add(self.clients, 0, wx.ALL, 5) - self.add = wx.Button(self, -1, _(u"Add client")) - self.remove = wx.Button(self, -1, _(u"Remove client")) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(self.add, 0, wx.ALL, 5) - btnBox.Add(self.remove, 0, wx.ALL, 5) - sizer.Add(clientsBox, 0, wx.ALL, 5) - sizer.Add(btnBox, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent, choices): + super(ignoredClients, self).__init__(parent=parent) + sizer = wx.BoxSizer(wx.VERTICAL) + label = wx.StaticText(self, -1, _(u"Ignored clients")) + self.clients = wx.ListBox(self, -1, choices=choices) + self.clients.SetSize(self.clients.GetBestSize()) + clientsBox = wx.BoxSizer(wx.HORIZONTAL) + clientsBox.Add(label, 0, wx.ALL, 5) + clientsBox.Add(self.clients, 0, wx.ALL, 5) + self.add = wx.Button(self, -1, _(u"Add client")) + self.remove = wx.Button(self, -1, _(u"Remove client")) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.add, 0, wx.ALL, 5) + btnBox.Add(self.remove, 0, wx.ALL, 5) + sizer.Add(clientsBox, 0, wx.ALL, 5) + sizer.Add(btnBox, 0, wx.ALL, 5) + self.SetSizer(sizer) - def append(self, client): - self.clients.Append(client) + def append(self, client): + self.clients.Append(client) - def get_clients(self): - return self.clients.GetCount() + def get_clients(self): + return self.clients.GetCount() - def get_client_id(self): - return self.clients.GetSelection() + def get_client_id(self): + return self.clients.GetSelection() - def remove_(self, id): - self.clients.Delete(id) + def remove_(self, id): + self.clients.Delete(id) class sound(wx.Panel): - def __init__(self, parent, input_devices, output_devices, soundpacks): - wx.Panel.__init__(self, parent) - sizer = wx.BoxSizer(wx.VERTICAL) - volume = wx.StaticText(self, -1, _(u"Volume")) - self.volumeCtrl = wx.Slider(self) - # Connect a key handler here to handle volume slider being inverted when moving with up and down arrows. - # see https://github.com/manuelcortez/TWBlue/issues/261 - widgetUtils.connect_event(self.volumeCtrl, widgetUtils.KEYPRESS, self.on_keypress) - self.volumeCtrl.SetRange(0, 100) - self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize()) - volumeBox = wx.BoxSizer(wx.HORIZONTAL) - volumeBox.Add(volume, 0, wx.ALL, 5) - volumeBox.Add(self.volumeCtrl, 0, wx.ALL, 5) - sizer.Add(volumeBox, 0, wx.ALL, 5) - self.session_mute = wx.CheckBox(self, -1, _(u"Session mute")) - sizer.Add(self.session_mute, 0, wx.ALL, 5) - output_label = wx.StaticText(self, -1, _(u"Output device")) - self.output = wx.ComboBox(self, -1, choices=output_devices, style=wx.CB_READONLY) - self.output.SetSize(self.output.GetBestSize()) - outputBox = wx.BoxSizer(wx.HORIZONTAL) - outputBox.Add(output_label, 0, wx.ALL, 5) - outputBox.Add(self.output, 0, wx.ALL, 5) - sizer.Add(outputBox, 0, wx.ALL, 5) - input_label = wx.StaticText(self, -1, _(u"Input device")) - self.input = wx.ComboBox(self, -1, choices=input_devices, style=wx.CB_READONLY) - self.input.SetSize(self.input.GetBestSize()) - inputBox = wx.BoxSizer(wx.HORIZONTAL) - inputBox.Add(input_label, 0, wx.ALL, 5) - inputBox.Add(self.input, 0, wx.ALL, 5) - sizer.Add(inputBox, 0, wx.ALL, 5) - soundBox = wx.BoxSizer(wx.VERTICAL) - soundpack_label = wx.StaticText(self, -1, _(u"Sound pack")) - self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY) - self.soundpack.SetSize(self.soundpack.GetBestSize()) - soundBox.Add(soundpack_label, 0, wx.ALL, 5) - soundBox.Add(self.soundpack, 0, wx.ALL, 5) - sizer.Add(soundBox, 0, wx.ALL, 5) - self.indicate_audio = wx.CheckBox(self, -1, _(u"Indicate audio tweets with sound")) - sizer.Add(self.indicate_audio, 0, wx.ALL, 5) - self.indicate_geo = wx.CheckBox(self, -1, _(u"Indicate geotweets with sound")) - sizer.Add(self.indicate_geo, 0, wx.ALL, 5) - self.indicate_img = wx.CheckBox(self, -1, _(u"Indicate tweets containing images with sound")) - sizer.Add(self.indicate_img, 0, wx.ALL, 5) - self.SetSizer(sizer) + def __init__(self, parent, input_devices, output_devices, soundpacks): + wx.Panel.__init__(self, parent) + sizer = wx.BoxSizer(wx.VERTICAL) + volume = wx.StaticText(self, -1, _(u"Volume")) + self.volumeCtrl = wx.Slider(self) + # Connect a key handler here to handle volume slider being inverted when moving with up and down arrows. + # see https://github.com/manuelcortez/TWBlue/issues/261 + widgetUtils.connect_event(self.volumeCtrl, widgetUtils.KEYPRESS, self.on_keypress) + self.volumeCtrl.SetRange(0, 100) + self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize()) + volumeBox = wx.BoxSizer(wx.HORIZONTAL) + volumeBox.Add(volume, 0, wx.ALL, 5) + volumeBox.Add(self.volumeCtrl, 0, wx.ALL, 5) + sizer.Add(volumeBox, 0, wx.ALL, 5) + self.session_mute = wx.CheckBox(self, -1, _(u"Session mute")) + sizer.Add(self.session_mute, 0, wx.ALL, 5) + output_label = wx.StaticText(self, -1, _(u"Output device")) + self.output = wx.ComboBox(self, -1, choices=output_devices, style=wx.CB_READONLY) + self.output.SetSize(self.output.GetBestSize()) + outputBox = wx.BoxSizer(wx.HORIZONTAL) + outputBox.Add(output_label, 0, wx.ALL, 5) + outputBox.Add(self.output, 0, wx.ALL, 5) + sizer.Add(outputBox, 0, wx.ALL, 5) + input_label = wx.StaticText(self, -1, _(u"Input device")) + self.input = wx.ComboBox(self, -1, choices=input_devices, style=wx.CB_READONLY) + self.input.SetSize(self.input.GetBestSize()) + inputBox = wx.BoxSizer(wx.HORIZONTAL) + inputBox.Add(input_label, 0, wx.ALL, 5) + inputBox.Add(self.input, 0, wx.ALL, 5) + sizer.Add(inputBox, 0, wx.ALL, 5) + soundBox = wx.BoxSizer(wx.VERTICAL) + soundpack_label = wx.StaticText(self, -1, _(u"Sound pack")) + self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY) + self.soundpack.SetSize(self.soundpack.GetBestSize()) + soundBox.Add(soundpack_label, 0, wx.ALL, 5) + soundBox.Add(self.soundpack, 0, wx.ALL, 5) + sizer.Add(soundBox, 0, wx.ALL, 5) + self.indicate_audio = wx.CheckBox(self, -1, _(u"Indicate audio tweets with sound")) + sizer.Add(self.indicate_audio, 0, wx.ALL, 5) + self.indicate_geo = wx.CheckBox(self, -1, _(u"Indicate geotweets with sound")) + sizer.Add(self.indicate_geo, 0, wx.ALL, 5) + self.indicate_img = wx.CheckBox(self, -1, _(u"Indicate tweets containing images with sound")) + sizer.Add(self.indicate_img, 0, wx.ALL, 5) + self.SetSizer(sizer) - def on_keypress(self, event, *args, **kwargs): - """ Invert movement of up and down arrow keys when dealing with a wX Slider. - See https://github.com/manuelcortez/TWBlue/issues/261 - and http://trac.wxwidgets.org/ticket/2068 - """ - keycode = event.GetKeyCode() - if keycode == wx.WXK_UP: - return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1) - elif keycode == wx.WXK_DOWN: - return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1) - event.Skip() + def on_keypress(self, event, *args, **kwargs): + """ Invert movement of up and down arrow keys when dealing with a wX Slider. + See https://github.com/manuelcortez/TWBlue/issues/261 + and http://trac.wxwidgets.org/ticket/2068 + """ + keycode = event.GetKeyCode() + if keycode == wx.WXK_UP: + return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1) + elif keycode == wx.WXK_DOWN: + return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1) + event.Skip() - def get(self, control): - return getattr(self, control).GetStringSelection() + def get(self, control): + return getattr(self, control).GetStringSelection() class extrasPanel(wx.Panel): - def __init__(self, parent, ocr_languages=[], translation_languages=[]): - super(extrasPanel, self).__init__(parent) - mainSizer = wx.BoxSizer(wx.VERTICAL) - OCRBox = wx.StaticBox(self, label=_(u"Language for OCR")) - self.ocr_lang = wx.ListBox(self, -1, choices=ocr_languages) - self.ocr_lang.SetSize(self.ocr_lang.GetBestSize()) - ocrLanguageSizer = wx.StaticBoxSizer(OCRBox, wx.HORIZONTAL) - ocrLanguageSizer.Add(self.ocr_lang, 0, wx.ALL, 5) - mainSizer.Add(ocrLanguageSizer, 0, wx.ALL, 5) - lbl = wx.StaticText(self, wx.ID_ANY, _(u"API Key for SndUp")) - self.sndup_apiKey = wx.TextCtrl(self, -1) - sndupBox = wx.BoxSizer(wx.HORIZONTAL) - sndupBox.Add(lbl, 0, wx.ALL, 5) - sndupBox.Add(self.sndup_apiKey, 0, wx.ALL, 5) - mainSizer.Add(sndupBox, 0, wx.ALL, 5) - self.SetSizer(mainSizer) + def __init__(self, parent, ocr_languages=[], translation_languages=[]): + super(extrasPanel, self).__init__(parent) + mainSizer = wx.BoxSizer(wx.VERTICAL) + OCRBox = wx.StaticBox(self, label=_(u"Language for OCR")) + self.ocr_lang = wx.ListBox(self, -1, choices=ocr_languages) + self.ocr_lang.SetSize(self.ocr_lang.GetBestSize()) + ocrLanguageSizer = wx.StaticBoxSizer(OCRBox, wx.HORIZONTAL) + ocrLanguageSizer.Add(self.ocr_lang, 0, wx.ALL, 5) + mainSizer.Add(ocrLanguageSizer, 0, wx.ALL, 5) + lbl = wx.StaticText(self, wx.ID_ANY, _(u"API Key for SndUp")) + self.sndup_apiKey = wx.TextCtrl(self, -1) + sndupBox = wx.BoxSizer(wx.HORIZONTAL) + sndupBox.Add(lbl, 0, wx.ALL, 5) + sndupBox.Add(self.sndup_apiKey, 0, wx.ALL, 5) + mainSizer.Add(sndupBox, 0, wx.ALL, 5) + self.SetSizer(mainSizer) class configurationDialog(baseDialog.BaseWXDialog): - def set_title(self, title): - self.SetTitle(title) + def set_title(self, title): + self.SetTitle(title) - def __init__(self): - super(configurationDialog, self).__init__(None, -1) - self.panel = wx.Panel(self) - self.SetTitle(_(u"{0} preferences").format(application.name,)) - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.notebook = wx.Notebook(self.panel) + def __init__(self): + super(configurationDialog, self).__init__(None, -1) + self.panel = wx.Panel(self) + self.SetTitle(_(u"{0} preferences").format(application.name,)) + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.notebook = wx.Notebook(self.panel) - def create_general(self, languageList,keymaps): - self.general = general(self.notebook, languageList,keymaps) - self.notebook.AddPage(self.general, _(u"General")) - self.general.SetFocus() + def create_general(self, languageList,keymaps): + self.general = general(self.notebook, languageList,keymaps) + self.notebook.AddPage(self.general, _(u"General")) + self.general.SetFocus() - def create_proxy(self, proxyTypes): - self.proxy = proxy(self.notebook, proxyTypes) - self.notebook.AddPage(self.proxy, _(u"Proxy")) + def create_proxy(self, proxyTypes): + self.proxy = proxy(self.notebook, proxyTypes) + self.notebook.AddPage(self.proxy, _(u"Proxy")) - def create_general_account(self): - self.general = generalAccount(self.notebook) - self.notebook.AddPage(self.general, _(u"General")) - self.general.SetFocus() + def create_general_account(self): + self.general = generalAccount(self.notebook) + self.notebook.AddPage(self.general, _(u"General")) + self.general.SetFocus() - def create_reporting(self): - self.reporting = reporting(self.notebook) - self.notebook.AddPage(self.reporting, _(u"Feedback")) + def create_reporting(self): + self.reporting = reporting(self.notebook) + self.notebook.AddPage(self.reporting, _(u"Feedback")) - def create_other_buffers(self): - self.buffers = other_buffers(self.notebook) - self.notebook.AddPage(self.buffers, _(u"Buffers")) + def create_other_buffers(self): + self.buffers = other_buffers(self.notebook) + self.notebook.AddPage(self.buffers, _(u"Buffers")) - def create_ignored_clients(self, ignored_clients_list): - self.ignored_clients = ignoredClients(self.notebook, ignored_clients_list) - self.notebook.AddPage(self.ignored_clients, _(u"Ignored clients")) + def create_ignored_clients(self, ignored_clients_list): + self.ignored_clients = ignoredClients(self.notebook, ignored_clients_list) + self.notebook.AddPage(self.ignored_clients, _(u"Ignored clients")) - def create_sound(self, output_devices, input_devices, soundpacks): - self.sound = sound(self.notebook, output_devices, input_devices, soundpacks) - self.notebook.AddPage(self.sound, _(u"Sound")) + def create_sound(self, output_devices, input_devices, soundpacks): + self.sound = sound(self.notebook, output_devices, input_devices, soundpacks) + self.notebook.AddPage(self.sound, _(u"Sound")) - def create_extras(self, ocr_languages=[], translator_languages=[]): - self.extras = extrasPanel(self.notebook, ocr_languages, translator_languages) - self.notebook.AddPage(self.extras, _(u"Extras")) + def create_extras(self, ocr_languages=[], translator_languages=[]): + self.extras = extrasPanel(self.notebook, ocr_languages, translator_languages) + self.notebook.AddPage(self.extras, _(u"Extras")) - def realize(self): - self.sizer.Add(self.notebook, 0, wx.ALL, 5) - ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL) - ok = wx.Button(self.panel, wx.ID_OK, _(u"Save")) - ok.SetDefault() - cancel = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close")) - self.SetEscapeId(cancel.GetId()) - ok_cancel_box.Add(ok, 0, wx.ALL, 5) - ok_cancel_box.Add(cancel, 0, wx.ALL, 5) - self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5) - self.panel.SetSizer(self.sizer) - self.SetClientSize(self.sizer.CalcMin()) + def realize(self): + self.sizer.Add(self.notebook, 0, wx.ALL, 5) + ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL) + ok = wx.Button(self.panel, wx.ID_OK, _(u"Save")) + ok.SetDefault() + cancel = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close")) + self.SetEscapeId(cancel.GetId()) + ok_cancel_box.Add(ok, 0, wx.ALL, 5) + ok_cancel_box.Add(cancel, 0, wx.ALL, 5) + self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5) + self.panel.SetSizer(self.sizer) + self.SetClientSize(self.sizer.CalcMin()) - def get_value(self, panel, key): - p = getattr(self, panel) - return getattr(p, key).GetValue() + def get_value(self, panel, key): + p = getattr(self, panel) + return getattr(p, key).GetValue() - def set_value(self, panel, key, value): - p = getattr(self, panel) - control = getattr(p, key) - getattr(control, "SetValue")(value) + def set_value(self, panel, key, value): + p = getattr(self, panel) + control = getattr(p, key) + getattr(control, "SetValue")(value) diff --git a/src/wxUI/dialogs/filterDialogs.py b/src/wxUI/dialogs/filterDialogs.py index edff9d6a..53dc202a 100644 --- a/src/wxUI/dialogs/filterDialogs.py +++ b/src/wxUI/dialogs/filterDialogs.py @@ -1,146 +1,150 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals -# -*- coding: utf-8 -*- -from . import baseDialog import wx import widgetUtils +from . import baseDialog from multiplatform_widgets import widgets class filterDialog(baseDialog.BaseWXDialog): - def __init__(self, value="", languages=[]): - super(filterDialog, self).__init__(None, -1) - self.langs_list = languages - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(_(u"Create a filter for this buffer")) - label = wx.StaticText(panel, wx.ID_ANY, _(u"Filter title")) - self.title = wx.TextCtrl(panel, -1, value) - dc = wx.WindowDC(self.title) - dc.SetFont(self.title.GetFont()) - self.title.SetSize(dc.GetTextExtent("0"*40)) - tsizer = wx.BoxSizer(wx.HORIZONTAL) - tsizer.Add(label, 0, wx.ALL, 5) - tsizer.Add(self.title, 0, wx.ALL, 5) - sizer.Add(tsizer, 0, wx.ALL, 5) - staticbox = wx.StaticBox(panel, label=_(u"Filter by word")) - self.contains = wx.RadioButton(panel, -1, _(u"Ignore tweets wich contain the following word"), style=wx.RB_GROUP) - self.doesnt_contain = wx.RadioButton(panel, -1, _(u"Ignore tweets without the following word")) - radioSizer1 = wx.StaticBoxSizer(staticbox, wx.HORIZONTAL) - radioSizer1.Add(self.contains, 0, wx.ALL, 5) - radioSizer1.Add(self.doesnt_contain, 0, wx.ALL, 5) - sizer.Add(radioSizer1, 0, wx.ALL, 5) - label = wx.StaticText(panel, -1, _(u"word")) - self.term = wx.TextCtrl(panel, -1, value) - dc = wx.WindowDC(self.term) - dc.SetFont(self.term.GetFont()) - self.term.SetSize(dc.GetTextExtent("0"*40)) - self.allow_rts = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow retweets")) - self.allow_quotes = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow quoted tweets")) - self.allow_replies = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow replies")) - self.allow_rts.SetValue(True) - self.allow_quotes.SetValue(True) - self.allow_replies.SetValue(True) - bsizer = wx.BoxSizer(wx.HORIZONTAL) - bsizer.Add(label, 0, wx.ALL, 5) - bsizer.Add(self.term, 0, wx.ALL, 5) - sizer.Add(bsizer, 0, wx.ALL, 5) - self.regexp = wx.CheckBox(panel, wx.ID_ANY, _(u"Use this term as a regular expression")) - sizer.Add(self.regexp, 0, wx.ALL, 5) - staticbox = wx.StaticBox(panel, label=_(u"Filter by language")) - self.load_language = wx.RadioButton(panel, -1, _(u"Load tweets in the following languages"), style=wx.RB_GROUP) - self.ignore_language = wx.RadioButton(panel, -1, _(u"Ignore tweets in the following languages")) - self.skip_language_filtering = wx.RadioButton(panel, -1, _(u"Don't filter by language")) - self.skip_language_filtering.SetValue(True) - widgetUtils.connect_event(self.load_language, widgetUtils.RADIOBUTTON, self.show_language_options) - widgetUtils.connect_event(self.ignore_language, widgetUtils.RADIOBUTTON, self.show_language_options) - widgetUtils.connect_event(self.skip_language_filtering, widgetUtils.RADIOBUTTON, self.hide_language_options) - radioSizer2 = wx.StaticBoxSizer(staticbox, wx.HORIZONTAL) - radioSizer2.Add(self.load_language, 0, wx.ALL, 5) - radioSizer2.Add(self.ignore_language, 0, wx.ALL, 5) - radioSizer2.Add(self.skip_language_filtering, 0, wx.ALL, 5) - sizer.Add(radioSizer2, 0, wx.ALL, 5) - self.indexes = [] - langsLabel = wx.StaticText(panel, -1, _(u"Supported languages")) - self.cb = wx.ComboBox(panel, -1, choices=languages, value=languages[0]) - langsSizer = wx.BoxSizer() - langsSizer.Add(langsLabel, 0, wx.ALL, 5) - langsSizer.Add(self.cb, 0, wx.ALL, 5) - self.add = wx.Button(panel, wx.ID_ANY, _(u"Add selected language to filter")) - self.add.Bind(wx.EVT_BUTTON, self.add_lang) - langsSizer.Add(self.add, 0, wx.ALL, 5) - sizer.Add(langsSizer, 0, wx.ALL, 5) - lbl = wx.StaticText(panel, wx.ID_ANY, _(u"Selected languages")) - self.langs = wx.ListBox(panel, -1) - self.remove = wx.Button(panel, wx.ID_ANY, _(u"Remove")) - self.remove.Bind(wx.EVT_BUTTON, self.remove_lang) - selectionSizer = wx.BoxSizer(wx.HORIZONTAL) - selectionSizer.Add(lbl, 0, wx.ALL, 5) - selectionSizer.Add(self.langs, 0, wx.ALL, 5) - selectionSizer.Add(self.remove, 0, wx.ALL, 5) - sizer.Add(selectionSizer, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK, _(u"OK")) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) - btnsizer = wx.BoxSizer() - btnsizer.Add(ok, 0, wx.ALL, 5) - btnsizer.Add(cancel, 0, wx.ALL, 5) - sizer.Add(btnsizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.hide_language_options() - self.SetClientSize(sizer.CalcMin()) + def __init__(self, value="", languages=[]): + super(filterDialog, self).__init__(None, -1) + self.langs_list = languages + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(_(u"Create a filter for this buffer")) + label = wx.StaticText(panel, wx.ID_ANY, _(u"Filter title")) + self.title = wx.TextCtrl(panel, -1, value) + dc = wx.WindowDC(self.title) + dc.SetFont(self.title.GetFont()) + self.title.SetSize(dc.GetTextExtent("0"*40)) + self.title.SetFocus() + tsizer = wx.BoxSizer(wx.HORIZONTAL) + tsizer.Add(label, 0, wx.ALL, 5) + tsizer.Add(self.title, 0, wx.ALL, 5) + sizer.Add(tsizer, 0, wx.ALL, 5) + staticbox = wx.StaticBox(panel, label=_(u"Filter by word")) + self.contains = wx.RadioButton(panel, -1, _(u"Ignore tweets wich contain the following word"), style=wx.RB_GROUP) + self.doesnt_contain = wx.RadioButton(panel, -1, _(u"Ignore tweets without the following word")) + radioSizer1 = wx.StaticBoxSizer(staticbox, wx.HORIZONTAL) + radioSizer1.Add(self.contains, 0, wx.ALL, 5) + radioSizer1.Add(self.doesnt_contain, 0, wx.ALL, 5) + sizer.Add(radioSizer1, 0, wx.ALL, 5) + label = wx.StaticText(panel, -1, _(u"word")) + self.term = wx.TextCtrl(panel, -1, value) + dc = wx.WindowDC(self.term) + dc.SetFont(self.term.GetFont()) + self.term.SetSize(dc.GetTextExtent("0"*40)) + self.allow_rts = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow retweets")) + self.allow_quotes = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow quoted tweets")) + self.allow_replies = wx.CheckBox(panel, wx.ID_ANY, _(u"Allow replies")) + self.allow_rts.SetValue(True) + self.allow_quotes.SetValue(True) + self.allow_replies.SetValue(True) + bsizer = wx.BoxSizer(wx.HORIZONTAL) + bsizer.Add(label, 0, wx.ALL, 5) + bsizer.Add(self.term, 0, wx.ALL, 5) + sizer.Add(bsizer, 0, wx.ALL, 5) + self.regexp = wx.CheckBox(panel, wx.ID_ANY, _(u"Use this term as a regular expression")) + sizer.Add(self.regexp, 0, wx.ALL, 5) + staticbox = wx.StaticBox(panel, label=_(u"Filter by language")) + self.load_language = wx.RadioButton(panel, -1, _(u"Load tweets in the following languages"), style=wx.RB_GROUP) + self.ignore_language = wx.RadioButton(panel, -1, _(u"Ignore tweets in the following languages")) + self.skip_language_filtering = wx.RadioButton(panel, -1, _(u"Don't filter by language")) + self.skip_language_filtering.SetValue(True) + widgetUtils.connect_event(self.load_language, widgetUtils.RADIOBUTTON, self.show_language_options) + widgetUtils.connect_event(self.ignore_language, widgetUtils.RADIOBUTTON, self.show_language_options) + widgetUtils.connect_event(self.skip_language_filtering, widgetUtils.RADIOBUTTON, self.hide_language_options) + radioSizer2 = wx.StaticBoxSizer(staticbox, wx.HORIZONTAL) + radioSizer2.Add(self.load_language, 0, wx.ALL, 5) + radioSizer2.Add(self.ignore_language, 0, wx.ALL, 5) + radioSizer2.Add(self.skip_language_filtering, 0, wx.ALL, 5) + sizer.Add(radioSizer2, 0, wx.ALL, 5) + self.indexes = [] + langsLabel = wx.StaticText(panel, -1, _(u"Supported languages")) + self.cb = wx.ComboBox(panel, -1, choices=languages, value=languages[0]) + langsSizer = wx.BoxSizer() + langsSizer.Add(langsLabel, 0, wx.ALL, 5) + langsSizer.Add(self.cb, 0, wx.ALL, 5) + self.add = wx.Button(panel, wx.ID_ANY, _(u"Add selected language to filter")) + self.add.Bind(wx.EVT_BUTTON, self.add_lang) + langsSizer.Add(self.add, 0, wx.ALL, 5) + sizer.Add(langsSizer, 0, wx.ALL, 5) + lbl = wx.StaticText(panel, wx.ID_ANY, _(u"Selected languages")) + self.langs = wx.ListBox(panel, -1) + self.remove = wx.Button(panel, wx.ID_ANY, _(u"Remove")) + self.remove.Bind(wx.EVT_BUTTON, self.remove_lang) + selectionSizer = wx.BoxSizer(wx.HORIZONTAL) + selectionSizer.Add(lbl, 0, wx.ALL, 5) + selectionSizer.Add(self.langs, 0, wx.ALL, 5) + selectionSizer.Add(self.remove, 0, wx.ALL, 5) + sizer.Add(selectionSizer, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK, _(u"OK")) + ok.SetDefault() + ok.Bind(wx.EVT_BUTTON, self.validate_title) + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) + btnsizer = wx.BoxSizer() + btnsizer.Add(ok, 0, wx.ALL, 5) + btnsizer.Add(cancel, 0, wx.ALL, 5) + sizer.Add(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.hide_language_options() + self.SetClientSize(sizer.CalcMin()) - def get_lang(self): - return self.cb.GetValue() + def get_lang(self): + return self.cb.GetValue() - def add_lang(self, *args, **kwargs): - selection = self.get_lang() - if selection in self.langs_list: - self.langs.Append(selection) - self.indexes.append(selection) + def add_lang(self, *args, **kwargs): + selection = self.get_lang() + if selection in self.langs_list: + self.langs.Append(selection) + self.indexes.append(selection) - def remove_lang(self, *args, **kwargs): - n = self.langs.GetSelection() - v = self.langs.GetStringSelection() - self.langs.Delete(n) - self.indexes.remove(v) + def remove_lang(self, *args, **kwargs): + n = self.langs.GetSelection() + v = self.langs.GetStringSelection() + self.langs.Delete(n) + self.indexes.remove(v) - def get_selected_langs(self): - return self.indexes + def get_selected_langs(self): + return self.indexes - def hide_language_options(self, *args, **kwargs): - for i in [self.cb, self.add, self.langs, self.remove]: - i.Hide() + def hide_language_options(self, *args, **kwargs): + for i in [self.cb, self.add, self.langs, self.remove]: + i.Hide() - def show_language_options(self, *args, **kwargs): - for i in [self.cb, self.add, self.langs, self.remove]: - i.Show() + def show_language_options(self, *args, **kwargs): + for i in [self.cb, self.add, self.langs, self.remove]: + i.Show() + + def validate_title(self, *args, **kwargs): + if self.title.GetValue() == "" or self.title.GetValue() == None: + return wx.MessageDialog(self, _("You must define a name for the filter before creating it."), _("Missing filter name"), wx.ICON_ERROR).ShowModal() + self.EndModal(wx.ID_OK) class filterManagerDialog(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(filterManagerDialog, self).__init__(parent=None, *args, **kwargs) - self.SetTitle(_(u"Manage filters")) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Filters")) - self.filters = widgets.list(panel, _(u"Filter"), _(u"Buffer"), _(u"Filter by word"), _(u"Filter by language"), size=(800, 800), style=wx.LC_REPORT|wx.LC_SINGLE_SEL) - self.filters.list.SetFocus() - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(label) - sizer.Add(self.filters.list) - self.edit = wx.Button(panel, wx.ID_ANY, _(u"Edit")) - self.edit.Enable(False) - self.delete = wx.Button(panel, wx.ID_ANY, _(u"Remove")) - self.cancel = wx.Button(panel, wx.ID_CANCEL) - btnSizer = wx.BoxSizer() - btnSizer.Add(self.edit, 0, wx.ALL, 5) - btnSizer.Add(self.delete, 0, wx.ALL, 5) - btnSizer.Add(self.cancel, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) + def __init__(self, *args, **kwargs): + super(filterManagerDialog, self).__init__(parent=None, *args, **kwargs) + self.SetTitle(_(u"Manage filters")) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Filters")) + self.filters = widgets.list(panel, _(u"Filter"), _(u"Buffer"), _(u"Filter by word"), _(u"Filter by language"), size=(800, 800), style=wx.LC_REPORT|wx.LC_SINGLE_SEL) + self.filters.list.SetFocus() + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(label) + sizer.Add(self.filters.list) + self.edit = wx.Button(panel, wx.ID_ANY, _(u"Edit")) + self.edit.Enable(False) + self.delete = wx.Button(panel, wx.ID_ANY, _(u"Remove")) + self.cancel = wx.Button(panel, wx.ID_CANCEL) + btnSizer = wx.BoxSizer() + btnSizer.Add(self.edit, 0, wx.ALL, 5) + btnSizer.Add(self.delete, 0, wx.ALL, 5) + btnSizer.Add(self.cancel, 0, wx.ALL, 5) + sizer.Add(btnSizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) - def get_item(self): - return self.filters.get_selected() + def get_item(self): + return self.filters.get_selected() - def clear(self): - self.filters.clear() + def clear(self): + self.filters.clear() diff --git a/src/wxUI/dialogs/find.py b/src/wxUI/dialogs/find.py index 73a3dd6f..c6176fc4 100644 --- a/src/wxUI/dialogs/find.py +++ b/src/wxUI/dialogs/find.py @@ -6,24 +6,24 @@ from . import baseDialog import wx class findDialog(baseDialog.BaseWXDialog): - def __init__(self, value=""): - super(findDialog, self).__init__(None, -1) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(_(u"Find in current buffer")) - label = wx.StaticText(panel, -1, _(u"String")) - self.string = wx.TextCtrl(panel, -1, value) - dc = wx.WindowDC(self.string) - dc.SetFont(self.string.GetFont()) - self.string.SetSize(dc.GetTextExtent("0"*40)) - sizer.Add(label, 0, wx.ALL, 5) - sizer.Add(self.string, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK, _(u"OK")) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) - btnsizer = wx.BoxSizer() - btnsizer.Add(ok, 0, wx.ALL, 5) - btnsizer.Add(cancel, 0, wx.ALL, 5) - sizer.Add(btnsizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) \ No newline at end of file + def __init__(self, value=""): + super(findDialog, self).__init__(None, -1) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(_(u"Find in current buffer")) + label = wx.StaticText(panel, -1, _(u"String")) + self.string = wx.TextCtrl(panel, -1, value) + dc = wx.WindowDC(self.string) + dc.SetFont(self.string.GetFont()) + self.string.SetSize(dc.GetTextExtent("0"*40)) + sizer.Add(label, 0, wx.ALL, 5) + sizer.Add(self.string, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK, _(u"OK")) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) + btnsizer = wx.BoxSizer() + btnsizer.Add(ok, 0, wx.ALL, 5) + btnsizer.Add(cancel, 0, wx.ALL, 5) + sizer.Add(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) diff --git a/src/wxUI/dialogs/lists.py b/src/wxUI/dialogs/lists.py index 9a30a4a3..cc8c3485 100644 --- a/src/wxUI/dialogs/lists.py +++ b/src/wxUI/dialogs/lists.py @@ -6,145 +6,145 @@ from multiplatform_widgets import widgets class listViewer(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(listViewer, self).__init__(parent=None, *args, **kwargs) - self.SetTitle(_(u"Lists manager")) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Lists")) - self.lista = widgets.list(panel, _(u"List"), _(u"Description"), _(u"Owner"), _(u"Members"), _(u"mode"), size=(800, 800), style=wx.LC_REPORT|wx.LC_SINGLE_SEL) - self.lista.list.SetFocus() - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(label) - sizer.Add(self.lista.list) - self.createBtn = wx.Button(panel, wx.ID_ANY, _(u"Create a new list")) - self.editBtn = wx.Button(panel, -1, _(u"Edit")) - self.deleteBtn = wx.Button(panel, -1, _(u"Remove")) - self.view = wx.Button(panel, -1, _(u"Open in buffer")) + def __init__(self, *args, **kwargs): + super(listViewer, self).__init__(parent=None, *args, **kwargs) + self.SetTitle(_(u"Lists manager")) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Lists")) + self.lista = widgets.list(panel, _(u"List"), _(u"Description"), _(u"Owner"), _(u"Members"), _(u"mode"), size=(800, 800), style=wx.LC_REPORT|wx.LC_SINGLE_SEL) + self.lista.list.SetFocus() + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(label) + sizer.Add(self.lista.list) + self.createBtn = wx.Button(panel, wx.ID_ANY, _(u"Create a new list")) + self.editBtn = wx.Button(panel, -1, _(u"Edit")) + self.deleteBtn = wx.Button(panel, -1, _(u"Remove")) + self.view = wx.Button(panel, -1, _(u"Open in buffer")) # self.members = wx.Button(panel, -1, _(u"View members")) # self.members.Disable() # self.subscriptors = wx.Button(panel, -1, _(u"View subscribers")) # self.subscriptors.Disable() # self.get_linkBtn = wx.Button(panel, -1, _(u"Get link for the list")) # self.get_linkBtn.Bind(wx.EVT_BUTTON, self.onGetLink) - self.cancelBtn = wx.Button(panel, wx.ID_CANCEL) - btnSizer = wx.BoxSizer() - btnSizer.Add(self.createBtn) - btnSizer.Add(self.editBtn) - btnSizer.Add(self.cancelBtn) - panel.SetSizer(sizer) + self.cancelBtn = wx.Button(panel, wx.ID_CANCEL) + btnSizer = wx.BoxSizer() + btnSizer.Add(self.createBtn) + btnSizer.Add(self.editBtn) + btnSizer.Add(self.cancelBtn) + panel.SetSizer(sizer) - def populate_list(self, lists, clear=False): - if clear == True: - self.clear() - for item in lists: - self.lista.insert_item(False, *item) + def populate_list(self, lists, clear=False): + if clear == True: + self.clear() + for item in lists: + self.lista.insert_item(False, *item) - def get_item(self): - return self.lista.get_selected() + def get_item(self): + return self.lista.get_selected() - def clear(self): - self.lista.clear() + def clear(self): + self.lista.clear() class userListViewer(listViewer): - def __init__(self, username, *args, **kwargs): - self.username = username - super(userListViewer, self).__init__(*args, **kwargs) - self.SetTitle(_(u"Viewing lists for %s") % (self.username)) - self.createBtn.SetLabel(_(u"Subscribe")) - self.deleteBtn.SetLabel(_(u"Unsubscribe")) - self.editBtn.Disable() - self.view.Disable() + def __init__(self, username, *args, **kwargs): + self.username = username + super(userListViewer, self).__init__(*args, **kwargs) + self.SetTitle(_(u"Viewing lists for %s") % (self.username)) + self.createBtn.SetLabel(_(u"Subscribe")) + self.deleteBtn.SetLabel(_(u"Unsubscribe")) + self.editBtn.Disable() + self.view.Disable() class createListDialog(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(createListDialog, self).__init__(parent=None, *args, **kwargs) - self.SetTitle(_(u"Create a new list")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - name = wx.StaticText(panel, -1, _(u"Name (20 characters maximun)")) - self.name = wx.TextCtrl(panel, -1) - nameSizer = wx.BoxSizer(wx.HORIZONTAL) - nameSizer.Add(name) - nameSizer.Add(self.name) - description = wx.StaticText(panel, -1, _(u"Description")) - self.description = wx.TextCtrl(panel, -1) - descriptionSizer = wx.BoxSizer(wx.HORIZONTAL) - descriptionSizer.Add(description) - descriptionSizer.Add(self.description) - mode = wx.StaticText(panel, -1, _(u"Mode")) - self.public = wx.RadioButton(panel, -1, _(u"Public"), style=wx.RB_GROUP) - self.private = wx.RadioButton(panel, -1, _(u"Private")) - modeBox = wx.BoxSizer(wx.HORIZONTAL) - modeBox.Add(mode) - modeBox.Add(self.public) - modeBox.Add(self.private) - ok = wx.Button(panel, wx.ID_OK) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(ok) - btnBox.Add(cancel) - sizer.Add(nameSizer) - sizer.Add(descriptionSizer) - sizer.Add(modeBox) - sizer.Add(btnBox) + def __init__(self, *args, **kwargs): + super(createListDialog, self).__init__(parent=None, *args, **kwargs) + self.SetTitle(_(u"Create a new list")) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + name = wx.StaticText(panel, -1, _(u"Name (20 characters maximun)")) + self.name = wx.TextCtrl(panel, -1) + nameSizer = wx.BoxSizer(wx.HORIZONTAL) + nameSizer.Add(name) + nameSizer.Add(self.name) + description = wx.StaticText(panel, -1, _(u"Description")) + self.description = wx.TextCtrl(panel, -1) + descriptionSizer = wx.BoxSizer(wx.HORIZONTAL) + descriptionSizer.Add(description) + descriptionSizer.Add(self.description) + mode = wx.StaticText(panel, -1, _(u"Mode")) + self.public = wx.RadioButton(panel, -1, _(u"Public"), style=wx.RB_GROUP) + self.private = wx.RadioButton(panel, -1, _(u"Private")) + modeBox = wx.BoxSizer(wx.HORIZONTAL) + modeBox.Add(mode) + modeBox.Add(self.public) + modeBox.Add(self.private) + ok = wx.Button(panel, wx.ID_OK) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(ok) + btnBox.Add(cancel) + sizer.Add(nameSizer) + sizer.Add(descriptionSizer) + sizer.Add(modeBox) + sizer.Add(btnBox) class editListDialog(createListDialog): - def __init__(self, list, *args, **kwargs): - super(editListDialog, self).__init__(*args, **kwargs) - self.SetTitle(_(u"Editing the list %s") % (list.name)) - self.name.ChangeValue(list.name) - self.description.ChangeValue(list.description) - if list.mode == "public": - self.public.SetValue(True) - else: - self.private.SetValue(True) + def __init__(self, list, *args, **kwargs): + super(editListDialog, self).__init__(*args, **kwargs) + self.SetTitle(_(u"Editing the list %s") % (list.name)) + self.name.ChangeValue(list.name) + self.description.ChangeValue(list.description) + if list.mode == "public": + self.public.SetValue(True) + else: + self.private.SetValue(True) class addUserListDialog(listViewer): - def __init__(self, *args, **kwargs): - super(addUserListDialog, self).__init__(*args, **kwargs) - self.SetTitle(_(u"Select a list to add the user")) - self.createBtn.SetLabel(_(u"Add")) - self.createBtn.SetDefault() - self.createBtn.Bind(wx.EVT_BUTTON, self.ok) - self.editBtn.Disable() - self.view.Disable() + def __init__(self, *args, **kwargs): + super(addUserListDialog, self).__init__(*args, **kwargs) + self.SetTitle(_(u"Select a list to add the user")) + self.createBtn.SetLabel(_(u"Add")) + self.createBtn.SetDefault() + self.createBtn.Bind(wx.EVT_BUTTON, self.ok) + self.editBtn.Disable() + self.view.Disable() # self.subscriptors.Disable() # self.members.Disable() - self.deleteBtn.Disable() - widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress) + self.deleteBtn.Disable() + widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress) - def on_keypress(self, event): - """Catch return and execute ok()""" - if event.GetKeyCode() == wx.WXK_RETURN: - return self.ok() - event.Skip() + def on_keypress(self, event): + """Catch return and execute ok()""" + if event.GetKeyCode() == wx.WXK_RETURN: + return self.ok() + event.Skip() - def ok(self, *args, **kwargs): - self.EndModal(wx.ID_OK) + def ok(self, *args, **kwargs): + self.EndModal(wx.ID_OK) class removeUserListDialog(listViewer): - def __init__(self, *args, **kwargs): - super(removeUserListDialog, self).__init__(*args, **kwargs) - self.SetTitle(_(u"Select a list to remove the user")) - self.createBtn.SetLabel(_(u"Remove")) - self.createBtn.SetDefault() - self.createBtn.SetId(wx.ID_OK) - self.editBtn.Disable() - self.view.Disable() + def __init__(self, *args, **kwargs): + super(removeUserListDialog, self).__init__(*args, **kwargs) + self.SetTitle(_(u"Select a list to remove the user")) + self.createBtn.SetLabel(_(u"Remove")) + self.createBtn.SetDefault() + self.createBtn.SetId(wx.ID_OK) + self.editBtn.Disable() + self.view.Disable() # self.subscriptors.Disable() # self.members.Disable() - self.deleteBtn.Disable() - widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress) + self.deleteBtn.Disable() + widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress) - def on_keypress(self, event): - """Catch return and execute EndModal()""" - if event.GetKeyCode() == wx.WXK_RETURN: - return self.EndModal(wx.ID_OK) - event.Skip() + def on_keypress(self, event): + """Catch return and execute EndModal()""" + if event.GetKeyCode() == wx.WXK_RETURN: + return self.EndModal(wx.ID_OK) + event.Skip() def remove_list(): - return wx.MessageDialog(None, _("Do you really want to delete this list?"), _("Delete"), wx.YES_NO).ShowModal() + return wx.MessageDialog(None, _("Do you really want to delete this list?"), _("Delete"), wx.YES_NO).ShowModal() diff --git a/src/wxUI/dialogs/message.py b/src/wxUI/dialogs/message.py deleted file mode 100644 index 50e380d7..00000000 --- a/src/wxUI/dialogs/message.py +++ /dev/null @@ -1,467 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import str -import wx -import widgetUtils - -class textLimited(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(textLimited, self).__init__(parent=None, *args, **kwargs) - - def createTextArea(self, message="", text=""): - if not hasattr(self, "panel"): - self.panel = wx.Panel(self) - self.label = wx.StaticText(self.panel, -1, message) - self.SetTitle(str(len(text))) - self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1),style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) -# font = self.text.GetFont() -# dc = wx.WindowDC(self.text) -# dc.SetFont(font) -# x, y = dc.GetTextExtent("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") -# self.text.SetSize((x, y)) - self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetFocus() - self.textBox = wx.BoxSizer(wx.HORIZONTAL) - self.textBox.Add(self.label, 0, wx.ALL, 5) - self.textBox.Add(self.text, 0, wx.ALL, 5) - - def text_focus(self): - self.text.SetFocus() - - def get_text(self): - return self.text.GetValue() - - def set_text(self, text): - return self.text.ChangeValue(text) - - def set_title(self, new_title): - return self.SetTitle(new_title) - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - - def disable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Disable() - - def onSelect(self, ev): - self.text.SelectAll() - - def handle_keys(self, event): - shift=event.ShiftDown() - if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'okButton'): - wx.PostEvent(self.okButton.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId,wx.ID_OK)) - else: - event.Skip() - - def set_cursor_at_end(self): - self.text.SetInsertionPoint(len(self.text.GetValue())) - - def set_cursor_at_position(self, position): - self.text.SetInsertionPoint(position) - - def get_position(self): - return self.text.GetInsertionPoint() - - def popup_menu(self, menu): - self.PopupMenu(menu, self.text.GetPosition()) - -class tweet(textLimited): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - -class retweet(tweet): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, "") - label = wx.StaticText(self.panel, -1, _(u"Retweet")) - self.text2 = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE|wx.TE_READONLY) - self.retweetBox = wx.BoxSizer(wx.HORIZONTAL) - self.retweetBox.Add(label, 0, wx.ALL, 5) - self.retweetBox.Add(self.text2, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.mainBox.Add(self.retweetBox, 0, wx.ALL, 5) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.createControls(message, title, text) -# self.onTimer(wx.EVT_CHAR_HOOK) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - -class dm(textLimited): - def createControls(self, title, message, users): - self.panel = wx.Panel(self) - self.mainBox = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(self.panel, -1, _(u"&Recipient")) - self.cb = wx.ComboBox(self.panel, -1, choices=users, value=users[0], size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.createTextArea(message, text="") - userBox = wx.BoxSizer(wx.HORIZONTAL) - userBox.Add(label, 0, wx.ALL, 5) - userBox.Add(self.cb, 0, wx.ALL, 5) - userBox.Add(self.autocompletionButton, 0, wx.ALL, 5) - self.mainBox.Add(userBox, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - self.buttonsBox.Add(self.attach, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox, 0, wx.ALL, 5) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.shortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.unshortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5) - self.buttonsBox3 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox3.Add(self.okButton, 0, wx.ALL, 5) - self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5) - self.panel.SetSizer(self.mainBox) - self.SetClientSize(self.mainBox.CalcMin()) - - def __init__(self, title, message, users, *args, **kwargs): - super(dm, self).__init__() - self.createControls(message, title, users) -# self.onTimer(wx.EVT_CHAR_HOOK) -# self.SetClientSize(self.mainBox.CalcMin()) - - def get_user(self): - return self.cb.GetValue() - - def set_user(self, user): - return self.cb.SetValue(user) - -class reply(textLimited): - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.usersbox = wx.BoxSizer(wx.VERTICAL) - self.mentionAll = wx.CheckBox(self.panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) - self.mentionAll.Disable() - self.usersbox.Add(self.mentionAll, 0, wx.ALL, 5) - self.checkboxes = [] - for i in self.users: - user_checkbox = wx.CheckBox(self.panel, -1, "@"+i, size=wx.DefaultSize) - self.checkboxes.append(user_checkbox) - self.usersbox.Add(self.checkboxes[-1], 0, wx.ALL, 5) - self.mainBox.Add(self.usersbox, 0, wx.ALL, 10) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer, 0, wx.ALL, 10) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, users=[], *args, **kwargs): - self.users = users - super(reply, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - -class viewTweet(widgetUtils.BaseDialog): - def set_title(self, lenght): - self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) - - def __init__(self, text, rt_count, favs_count, source, date="", *args, **kwargs): - super(viewTweet, self).__init__(None, size=(850,850)) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Tweet")) - self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - mainBox.Add(textBox, 0, wx.ALL, 5) - label2 = wx.StaticText(panel, -1, _(u"Image description")) - self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.image_description) - dc.SetFont(self.image_description.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*450) - self.image_description.SetSize((x, y)) - self.image_description.Enable(False) - iBox = wx.BoxSizer(wx.HORIZONTAL) - iBox.Add(label2, 0, wx.ALL, 5) - iBox.Add(self.image_description, 1, wx.EXPAND, 5) - mainBox.Add(iBox, 0, wx.ALL, 5) - rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) - rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - rtBox = wx.BoxSizer(wx.HORIZONTAL) - rtBox.Add(rtCountLabel, 0, wx.ALL, 5) - rtBox.Add(rtCount, 0, wx.ALL, 5) - favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) - favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - favsBox = wx.BoxSizer(wx.HORIZONTAL) - favsBox.Add(favsCountLabel, 0, wx.ALL, 5) - favsBox.Add(favsCount, 0, wx.ALL, 5) - sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) - sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - sourceBox = wx.BoxSizer(wx.HORIZONTAL) - sourceBox.Add(sourceLabel, 0, wx.ALL, 5) - sourceBox.Add(sourceTweet, 0, wx.ALL, 5) - dateLabel = wx.StaticText(panel, -1, _(u"Date: ")) - dateTweet = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - dc = wx.WindowDC(dateTweet) - dc.SetFont(dateTweet.GetFont()) - (x, y) = dc.GetTextExtent("0"*100) - dateTweet.SetSize((x, y)) - dateBox = wx.BoxSizer(wx.HORIZONTAL) - dateBox.Add(dateLabel, 0, wx.ALL, 5) - dateBox.Add(dateTweet, 0, wx.ALL, 5) - infoBox = wx.BoxSizer(wx.HORIZONTAL) - infoBox.Add(rtBox, 0, wx.ALL, 5) - infoBox.Add(favsBox, 0, wx.ALL, 5) - infoBox.Add(sourceBox, 0, wx.ALL, 5) - mainBox.Add(infoBox, 0, wx.ALL, 5) - mainBox.Add(dateBox, 0, wx.ALL, 5) - 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() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def set_image_description(self, desc): - self.image_description.Enable(True) - if len(self.image_description.GetValue()) == 0: - self.image_description.SetValue(desc) - else: - self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) - - def text_focus(self): - self.text.SetFocus() - - def onSelect(self, ev): - self.text.SelectAll() - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - -class viewNonTweet(widgetUtils.BaseDialog): - - def __init__(self, text, date="", *args, **kwargs): - super(viewNonTweet, self).__init__(None, size=(850,850)) - self.SetTitle(_(u"View")) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Item")) - self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - mainBox.Add(textBox, 0, wx.ALL, 5) - if date != "": - dateLabel = wx.StaticText(panel, -1, _(u"Date: ")) - date = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - dc = wx.WindowDC(date) - dc.SetFont(date.GetFont()) - (x, y) = dc.GetTextExtent("0"*100) - date.SetSize((x, y)) - dateBox = wx.BoxSizer(wx.HORIZONTAL) - dateBox.Add(dateLabel, 0, wx.ALL, 5) - dateBox.Add(date, 0, wx.ALL, 5) - mainBox.Add(dateBox, 0, wx.ALL, 5) - 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() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('A'), selectId), -]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def onSelect(self, ev): - self.text.SelectAll() - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def text_focus(self): - self.text.SetFocus() - - def enable_button(self, buttonName): - if getattr(self, buttonName): - return getattr(self, buttonName).Enable() diff --git a/src/wxUI/dialogs/search.py b/src/wxUI/dialogs/search.py index 13cc45ce..504cab9a 100644 --- a/src/wxUI/dialogs/search.py +++ b/src/wxUI/dialogs/search.py @@ -1,74 +1,73 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import -from __future__ import unicode_literals import widgetUtils from . import baseDialog import wx from extra import translator class searchDialog(baseDialog.BaseWXDialog): - def __init__(self, value=""): - super(searchDialog, self).__init__(None, -1) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(_(u"Search on Twitter")) - label = wx.StaticText(panel, -1, _(u"&Search")) - self.term = wx.TextCtrl(panel, -1, value) - dc = wx.WindowDC(self.term) - dc.SetFont(self.term.GetFont()) - self.term.SetSize(dc.GetTextExtent("0"*40)) - sizer.Add(label, 0, wx.ALL, 5) - sizer.Add(self.term, 0, wx.ALL, 5) - self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP) - self.users = wx.RadioButton(panel, -1, _(u"Users")) - widgetUtils.connect_event(self.tweets, widgetUtils.RADIOBUTTON, self.show_advanced_search) - widgetUtils.connect_event(self.users, widgetUtils.RADIOBUTTON, self.hide_advanced_search) - radioSizer = wx.BoxSizer(wx.HORIZONTAL) - radioSizer.Add(self.tweets, 0, wx.ALL, 5) - radioSizer.Add(self.users, 0, wx.ALL, 5) - sizer.Add(radioSizer, 0, wx.ALL, 5) - lang = wx.StaticText(panel, -1, _(u"&Language for results: ")) - langs = [x for x in list(translator.translator.languages.values())] - langs.insert(0, _(u"any")) - self.lang = wx.ComboBox(panel, -1, choices=langs, value=langs[0], style = wx.CB_READONLY) - langBox = wx.BoxSizer(wx.HORIZONTAL) - langBox.Add(lang, 0, wx.ALL, 5) - langBox.Add(self.lang, 0, wx.ALL, 5) - sizer.Add(langBox, 0, wx.ALL, 5) - resulttype = wx.StaticText(panel, -1, _(U"Results &type: ")) - self.resultstype = wx.ComboBox(panel, -1, choices=[_(u"Mixed"), _(u"Recent"), _(u"Popular")], value=_(u"Mixed"), style=wx.CB_READONLY) - rBox = wx.BoxSizer(wx.HORIZONTAL) - rBox.Add(resulttype, 0, wx.ALL, 5) - rBox.Add(self.resultstype, 0, wx.ALL, 5) - sizer.Add(rBox, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) - ok.SetDefault() - 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(btnsizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self, value=""): + super(searchDialog, self).__init__(None, -1) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(_(u"Search on Twitter")) + label = wx.StaticText(panel, -1, _(u"&Search")) + self.term = wx.TextCtrl(panel, -1, value) + self.term.SetFocus() + dc = wx.WindowDC(self.term) + dc.SetFont(self.term.GetFont()) + self.term.SetSize(dc.GetTextExtent("0"*40)) + sizer.Add(label, 0, wx.ALL, 5) + sizer.Add(self.term, 0, wx.ALL, 5) + self.tweets = wx.RadioButton(panel, -1, _(u"Tweets"), style=wx.RB_GROUP) + self.users = wx.RadioButton(panel, -1, _(u"Users")) + widgetUtils.connect_event(self.tweets, widgetUtils.RADIOBUTTON, self.show_advanced_search) + widgetUtils.connect_event(self.users, widgetUtils.RADIOBUTTON, self.hide_advanced_search) + radioSizer = wx.BoxSizer(wx.HORIZONTAL) + radioSizer.Add(self.tweets, 0, wx.ALL, 5) + radioSizer.Add(self.users, 0, wx.ALL, 5) + sizer.Add(radioSizer, 0, wx.ALL, 5) + lang = wx.StaticText(panel, -1, _(u"&Language for results: ")) + langs = [x for x in list(translator.translator.languages.values())] + langs.insert(0, _(u"any")) + self.lang = wx.ComboBox(panel, -1, choices=langs, value=langs[0], style = wx.CB_READONLY) + langBox = wx.BoxSizer(wx.HORIZONTAL) + langBox.Add(lang, 0, wx.ALL, 5) + langBox.Add(self.lang, 0, wx.ALL, 5) + sizer.Add(langBox, 0, wx.ALL, 5) + resulttype = wx.StaticText(panel, -1, _(U"Results &type: ")) + self.resultstype = wx.ComboBox(panel, -1, choices=[_(u"Mixed"), _(u"Recent"), _(u"Popular")], value=_(u"Mixed"), style=wx.CB_READONLY) + rBox = wx.BoxSizer(wx.HORIZONTAL) + rBox.Add(resulttype, 0, wx.ALL, 5) + rBox.Add(self.resultstype, 0, wx.ALL, 5) + sizer.Add(rBox, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) + ok.SetDefault() + 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(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def get_language(self): - l = self.lang.GetStringSelection() - if l == _(u"any"): - return "" - for langcode, langname in translator.translator.languages.items(): - if langname == l: - return langcode + def get_language(self): + l = self.lang.GetStringSelection() + if l == _(u"any"): + return "" + for langcode, langname in translator.translator.languages.items(): + if langname == l: + return langcode - def get_result_type(self): - r = self.resultstype.GetValue() - if r == _(u"Mixed"): return "mixed" - elif r == _(u"Recent"): return "recent" - elif r == _(u"Popular"): return "popular" + def get_result_type(self): + r = self.resultstype.GetValue() + if r == _(u"Mixed"): return "mixed" + elif r == _(u"Recent"): return "recent" + elif r == _(u"Popular"): return "popular" - def hide_advanced_search(self, *args, **kwargs): - self.lang.Hide() - self.resultstype.Hide() + def hide_advanced_search(self, *args, **kwargs): + self.lang.Hide() + self.resultstype.Hide() - def show_advanced_search(self, *args, **kwargs): - self.lang.Show() - self.resultstype.Show() + def show_advanced_search(self, *args, **kwargs): + self.lang.Show() + self.resultstype.Show() diff --git a/src/wxUI/dialogs/show_user.py b/src/wxUI/dialogs/show_user.py index 1c7be5b4..fe6c8b11 100644 --- a/src/wxUI/dialogs/show_user.py +++ b/src/wxUI/dialogs/show_user.py @@ -5,24 +5,24 @@ import wx from . import baseDialog class showUserProfile(baseDialog.BaseWXDialog): - def __init__(self): - super(showUserProfile, self).__init__(parent=None, id=wx.ID_ANY) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - static = wx.StaticText(panel, -1, _(u"Details")) - sizer.Add(static, 0, wx.ALL, 5) - self.text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(350, 250)) - self.text.SetFocus() - sizer.Add(self.text, 0, wx.ALL|wx.EXPAND, 5) - self.url = wx.Button(panel, -1, _(u"&Go to URL"), size=wx.DefaultSize) - self.url.Disable() - close = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) - btnSizer = wx.BoxSizer(wx.HORIZONTAL) - btnSizer.Add(self.url, 0, wx.ALL, 5) - btnSizer.Add(close, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(showUserProfile, self).__init__(parent=None, id=wx.ID_ANY) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + static = wx.StaticText(panel, -1, _(u"Details")) + sizer.Add(static, 0, wx.ALL, 5) + self.text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(350, 250)) + self.text.SetFocus() + sizer.Add(self.text, 0, wx.ALL|wx.EXPAND, 5) + self.url = wx.Button(panel, -1, _(u"&Go to URL"), size=wx.DefaultSize) + self.url.Disable() + close = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(self.url, 0, wx.ALL, 5) + btnSizer.Add(close, 0, wx.ALL, 5) + sizer.Add(btnSizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def enable_url(self, enabled=True): - self.url.Enable(enabled) \ No newline at end of file + def enable_url(self, enabled=True): + self.url.Enable(enabled) diff --git a/src/wxUI/dialogs/trends.py b/src/wxUI/dialogs/trends.py index d2d6ae75..24613e53 100644 --- a/src/wxUI/dialogs/trends.py +++ b/src/wxUI/dialogs/trends.py @@ -3,43 +3,43 @@ from . import baseDialog import wx class trendingTopicsDialog(baseDialog.BaseWXDialog): - def __init__(self): - super(trendingTopicsDialog, self).__init__(None, -1) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(_(u"View trending topics")) - label = wx.StaticText(panel, wx.NewId(), _(u"Trending topics by")) - self.country = wx.RadioButton(panel, -1, _(u"Country"), style=wx.RB_GROUP) - self.city = wx.RadioButton(panel, -1, _(u"City")) - radioSizer = wx.BoxSizer(wx.HORIZONTAL) - radioSizer.Add(label, 0, wx.ALL, 5) - radioSizer.Add(self.country, 0, wx.ALL, 5) - radioSizer.Add(self.city, 0, wx.ALL, 5) - sizer.Add(radioSizer, 0, wx.ALL, 5) - label = wx.StaticText(panel, -1, _(u"&Location")) - self.location = wx.ListBox(panel, -1, choices=[], style=wx.CB_READONLY) - locationBox = wx.BoxSizer(wx.HORIZONTAL) - locationBox.Add(label, 0, wx.ALL, 5) - locationBox.Add(self.location, 0, wx.ALL, 5) - sizer.Add(locationBox, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) - ok.SetDefault() - 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(btnsizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(trendingTopicsDialog, self).__init__(None, -1) + panel = wx.Panel(self) + sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(_(u"View trending topics")) + label = wx.StaticText(panel, wx.NewId(), _(u"Trending topics by")) + self.country = wx.RadioButton(panel, -1, _(u"Country"), style=wx.RB_GROUP) + self.city = wx.RadioButton(panel, -1, _(u"City")) + radioSizer = wx.BoxSizer(wx.HORIZONTAL) + radioSizer.Add(label, 0, wx.ALL, 5) + radioSizer.Add(self.country, 0, wx.ALL, 5) + radioSizer.Add(self.city, 0, wx.ALL, 5) + sizer.Add(radioSizer, 0, wx.ALL, 5) + label = wx.StaticText(panel, -1, _(u"&Location")) + self.location = wx.ListBox(panel, -1, choices=[], style=wx.CB_READONLY) + locationBox = wx.BoxSizer(wx.HORIZONTAL) + locationBox.Add(label, 0, wx.ALL, 5) + locationBox.Add(self.location, 0, wx.ALL, 5) + sizer.Add(locationBox, 0, wx.ALL, 5) + ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) + ok.SetDefault() + 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(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def get_active(self): - if self.country.GetValue() == True: - return "country" - else: - return "city" + def get_active(self): + if self.country.GetValue() == True: + return "country" + else: + return "city" - def get_item(self): - return self.location.GetStringSelection() + def get_item(self): + return self.location.GetStringSelection() - def set(self, values): - self.location.Set(values) \ No newline at end of file + def set(self, values): + self.location.Set(values) diff --git a/src/wxUI/dialogs/twitterDialogs/__init__.py b/src/wxUI/dialogs/twitterDialogs/__init__.py new file mode 100644 index 00000000..6a829f06 --- /dev/null +++ b/src/wxUI/dialogs/twitterDialogs/__init__.py @@ -0,0 +1 @@ +from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet, poll \ No newline at end of file diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py new file mode 100644 index 00000000..b917a25b --- /dev/null +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -0,0 +1,542 @@ +""" GUI dialogs for tweet writing and displaying. """ +import wx +from typing import List + +class tweet(wx.Dialog): + def __init__(self, title: str, caption: str, message: str = "", max_length: int = 280, thread_mode: bool = True, *args, **kwds) -> None: + """ Creates the basic Tweet dialog. This might be considered the base class for other dialogs. + title str: title to be used in the dialog. + caption str: This is the text to be placed alongside the text field. + message str: Text to be inserted in the tweet. + max_length int: Maximum amount of characters the tweet will accept. By default is 280 chahracters. + thread_mode bool: If set to False, disables the button that allows to make threads by adding more tweets. + """ + super(tweet, self).__init__(parent=None, *args, **kwds) + self.SetTitle(title) + self.create_controls(max_length=max_length, caption=caption, message=message, thread_mode=thread_mode) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(444, -1), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + tweet_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(tweet_sizer, 1, wx.EXPAND, 0) + label_3 = wx.StaticText(panel, wx.ID_ANY, _("Added Tweets")) + tweet_sizer.Add(label_3, 0, 0, 0) + self.tweets = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.tweets.AppendColumn(_("Text")) + self.tweets.AppendColumn(_("Attachments")) + self.tweets.Enable(False) + tweet_sizer.Add(self.tweets, 1, wx.EXPAND, 0) + self.remove_tweet = wx.Button(panel, wx.ID_ANY, _("Delete tweet")) + self.remove_tweet.Enable(False) + tweet_sizer.Add(self.remove_tweet, 0, 0, 0) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_tweet = wx.Button(panel, wx.ID_ANY, _("Add t&weet")) + self.add_tweet.Enable(thread_mode) + btn_sizer_1.Add(self.add_tweet, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.autocomplete_users = wx.Button(panel, wx.ID_ANY, _("Auto&complete users")) + btn_sizer_2.Add(self.autocomplete_users, 0, 0, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + + def handle_keys(self, event: wx.Event, *args, **kwargs) -> None: + """ Allows to react to certain keyboard events from the text control. """ + shift=event.ShiftDown() + if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'send'): + self.EndModal(wx.ID_OK) + else: + event.Skip() + + def reset_controls(self) -> None: + """ Resetss text control and attachments to their default, empty values. This is used while adding more tweets in a thread. """ + self.text.ChangeValue("") + self.attachments.DeleteAllItems() + + def add_item(self, list_type: str = "attachment", item: List[str] = []) -> None: + """ Adds an item to a list control. Item should be a list with the same amount of items for each column present in the ListCtrl. """ + if list_type == "attachment": + self.attachments.Append(item) + else: + self.tweets.Append(item) + + def remove_item(self, list_type: str = "attachment") -> None: + if list_type == "attachment": + item = self.attachments.GetFocusedItem() + if item > -1: + self.attachments.DeleteItem(item) + else: + item = self.tweets.GetFocusedItem() + if item > -1: + self.tweets.DeleteItem(item) + + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + self.add_poll = menu.Append(wx.ID_ANY, _("Poll")) + self.add_poll.Enable(enabled) + return menu + + def ask_description(self): + dlg = wx.TextEntryDialog(self, _(u"please provide a description"), _(u"Description")) + dlg.ShowModal() + result = dlg.GetValue() + dlg.Destroy() + return result + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return (None, None) + dsc = self.ask_description() + return (openFileDialog.GetPath(), dsc) + + def get_video(self): + openFileDialog = wx.FileDialog(self, _("Select the video to be uploaded"), "", "", _("Video files (*.mp4)|*.mp4"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return openFileDialog.GetPath() + + def unable_to_attach_file(self, *args, **kwargs): + return wx.MessageDialog(self, _("It is not possible to add more attachments. Please make sure your tweet complies with Twitter'S attachment rules. You can add only one video or GIF in every tweet, and a maximum of 4 photos."), _("Error adding attachment"), wx.ICON_ERROR).ShowModal() + +class reply(tweet): + + def __init__(self, users: List[str] = [], *args, **kwargs) -> None: + self.users = users + super(reply, self).__init__(*args, **kwargs) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(500, 200), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + user_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(user_sizer, 0, 0, 0) + self.mention_all = wx.CheckBox(panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) + self.mention_all.Disable() + user_sizer.Add(self.mention_all, 0, wx.ALL, 5) + self.checkboxes = [] + for i in self.users: + user_checkbox = wx.CheckBox(panel, -1, "@"+i, size=wx.DefaultSize) + self.checkboxes.append(user_checkbox) + user_sizer.Add(self.checkboxes[-1], 0, wx.ALL, 5) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.autocomplete_users = wx.Button(panel, wx.ID_ANY, _("Auto&complete users")) + btn_sizer_2.Add(self.autocomplete_users, 0, 0, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + return menu + +class dm(tweet): + + def __init__(self, users: List[str] = [], *args, **kwargs) -> None: + self.users = users + super(dm, self).__init__(*args, **kwargs) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + label_recipient = wx.StaticText(panel, -1, _("&Recipient")) + self.cb = wx.ComboBox(panel, -1, choices=self.users, value=self.users[0], size=wx.DefaultSize) + self.autocomplete_users = wx.Button(panel, -1, _(u"Auto&complete users")) + recipient_sizer = wx.BoxSizer(wx.HORIZONTAL) + recipient_sizer.Add(label_recipient, 0, 0, 0) + recipient_sizer.Add(self.cb, 1, wx.EXPAND, 0) + mainBox.Add(recipient_sizer, 0, wx.EXPAND, 0) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(500, 200), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + self.text.SetFocus() + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return (None, None) + return (openFileDialog.GetPath(), "") + + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + return menu + +class viewTweet(wx.Dialog): + def set_title(self, lenght): + self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) + + def __init__(self, text, rt_count, favs_count, source, date="", *args, **kwargs): + super(viewTweet, self).__init__(None, size=(850,850)) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Tweet")) + self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("W"*280) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(textBox, 0, wx.ALL, 5) + label2 = wx.StaticText(panel, -1, _(u"Image description")) + self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.image_description) + dc.SetFont(self.image_description.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*450) + self.image_description.SetSize((x, y)) + self.image_description.Enable(False) + iBox = wx.BoxSizer(wx.HORIZONTAL) + iBox.Add(label2, 0, wx.ALL, 5) + iBox.Add(self.image_description, 1, wx.EXPAND, 5) + mainBox.Add(iBox, 0, wx.ALL, 5) + rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) + rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + rtBox = wx.BoxSizer(wx.HORIZONTAL) + rtBox.Add(rtCountLabel, 0, wx.ALL, 5) + rtBox.Add(rtCount, 0, wx.ALL, 5) + favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) + favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + favsBox = wx.BoxSizer(wx.HORIZONTAL) + favsBox.Add(favsCountLabel, 0, wx.ALL, 5) + favsBox.Add(favsCount, 0, wx.ALL, 5) + sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) + sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + sourceBox = wx.BoxSizer(wx.HORIZONTAL) + sourceBox.Add(sourceLabel, 0, wx.ALL, 5) + sourceBox.Add(sourceTweet, 0, wx.ALL, 5) + dateLabel = wx.StaticText(panel, -1, _(u"Date: ")) + dateTweet = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + dc = wx.WindowDC(dateTweet) + dc.SetFont(dateTweet.GetFont()) + (x, y) = dc.GetTextExtent("0"*100) + dateTweet.SetSize((x, y)) + dateBox = wx.BoxSizer(wx.HORIZONTAL) + dateBox.Add(dateLabel, 0, wx.ALL, 5) + dateBox.Add(dateTweet, 0, wx.ALL, 5) + infoBox = wx.BoxSizer(wx.HORIZONTAL) + infoBox.Add(rtBox, 0, wx.ALL, 5) + infoBox.Add(favsBox, 0, wx.ALL, 5) + 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.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + 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.translateButton, 0, wx.ALL, 5) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.ID_ANY + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('A'), selectId), + ]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def set_image_description(self, desc): + self.image_description.Enable(True) + if len(self.image_description.GetValue()) == 0: + self.image_description.SetValue(desc) + else: + self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) + + def text_focus(self): + self.text.SetFocus() + + def onSelect(self, ev): + self.text.SelectAll() + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() + +class viewNonTweet(wx.Dialog): + + def __init__(self, text, date="", *args, **kwargs): + super(viewNonTweet, self).__init__(None, size=(850,850)) + self.SetTitle(_(u"View")) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Item")) + self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*140) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(textBox, 0, wx.ALL, 5) + if date != "": + dateLabel = wx.StaticText(panel, -1, _(u"Date: ")) + date = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + dc = wx.WindowDC(date) + dc.SetFont(date.GetFont()) + (x, y) = dc.GetTextExtent("0"*100) + date.SetSize((x, y)) + dateBox = wx.BoxSizer(wx.HORIZONTAL) + 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() + self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + 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) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.ID_ANY + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('A'), selectId), + ]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def onSelect(self, ev): + self.text.SelectAll() + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def text_focus(self): + self.text.SetFocus() + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() + +class poll(wx.Dialog): + def __init__(self, *args, **kwds): + super(poll, self).__init__(parent=None, id=wx.NewId(), title=_("Add a poll")) + sizer_1 = wx.BoxSizer(wx.VERTICAL) + period_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_1.Add(period_sizer, 1, wx.EXPAND, 0) + label_period = wx.StaticText(self, wx.ID_ANY, _("Participation time (in days)")) + period_sizer.Add(label_period, 0, 0, 0) + self.period = wx.SpinCtrl(self, wx.ID_ANY) + self.period.SetFocus() + self.period.SetRange(1, 7) + self.period.SetValue(7) + period_sizer.Add(self.period, 0, 0, 0) + sizer_2 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Choices")), wx.VERTICAL) + sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) + option1_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option1_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(self, wx.ID_ANY, _("Option 1")) + option1_sizer.Add(label_2, 0, 0, 0) + self.option1 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option1.SetMaxLength(25) + option1_sizer.Add(self.option1, 0, 0, 0) + option2_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option2_sizer, 1, wx.EXPAND, 0) + label_3 = wx.StaticText(self, wx.ID_ANY, _("Option 2")) + option2_sizer.Add(label_3, 0, 0, 0) + self.option2 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option2.SetMaxLength(25) + option2_sizer.Add(self.option2, 0, 0, 0) + option3_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option3_sizer, 1, wx.EXPAND, 0) + label_4 = wx.StaticText(self, wx.ID_ANY, _("Option 3")) + option3_sizer.Add(label_4, 0, 0, 0) + self.option3 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option3.SetMaxLength(25) + option3_sizer.Add(self.option3, 0, 0, 0) + option4_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option4_sizer, 1, wx.EXPAND, 0) + label_5 = wx.StaticText(self, wx.ID_ANY, _("Option 4")) + option4_sizer.Add(label_5, 0, 0, 0) + self.option4 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option4.SetMaxLength(25) + option4_sizer.Add(self.option4, 0, 0, 0) + btn_sizer = wx.StdDialogButtonSizer() + sizer_1.Add(btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.button_OK = wx.Button(self, wx.ID_OK) + self.button_OK.SetDefault() + self.button_OK.Bind(wx.EVT_BUTTON, self.validate_data) + btn_sizer.AddButton(self.button_OK) + self.button_CANCEL = wx.Button(self, wx.ID_CANCEL, "") + btn_sizer.AddButton(self.button_CANCEL) + btn_sizer.Realize() + self.SetSizer(sizer_1) + sizer_1.Fit(self) + self.SetAffirmativeId(self.button_OK.GetId()) + self.SetEscapeId(self.button_CANCEL.GetId()) + self.Layout() + + def get_options(self): + controls = [self.option1, self.option2, self.option3, self.option4] + options = [option.GetValue() for option in controls if option.GetValue() != ""] + return options + + def validate_data(self, *args, **kwargs): + options = self.get_options() + if len(options) < 2: + return wx.MessageDialog(self, _("Please make sure you have provided at least two options for the poll."), _("Not enough information"), wx.ICON_ERROR).ShowModal() + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/src/wxUI/dialogs/update_profile.py b/src/wxUI/dialogs/update_profile.py index ba1cb541..034c2388 100644 --- a/src/wxUI/dialogs/update_profile.py +++ b/src/wxUI/dialogs/update_profile.py @@ -5,96 +5,96 @@ import wx from . import baseDialog class updateProfileDialog(baseDialog.BaseWXDialog): - def __init__(self): - super(updateProfileDialog, self).__init__(parent=None, id=-1) - self.SetTitle(_(u"Update your profile")) - panel = wx.Panel(self) - labelName = wx.StaticText(panel, -1, _(u"&Name (50 characters maximum)")) - self.name = wx.TextCtrl(panel, -1) - self.name.SetFocus() - dc = wx.WindowDC(self.name) - dc.SetFont(self.name.GetFont()) - self.name.SetSize(dc.GetTextExtent("0"*50)) - labelLocation = wx.StaticText(panel, -1, _(u"&Location")) - self.location = wx.TextCtrl(panel, -1) - dc = wx.WindowDC(self.location) - dc.SetFont(self.location.GetFont()) - self.location.SetSize(dc.GetTextExtent("0"*35)) - labelUrl = wx.StaticText(panel, -1, _(u"&Website")) - self.url = wx.TextCtrl(panel, -1) - dc = wx.WindowDC(self.url) - dc.SetFont(self.url.GetFont()) - self.url.SetSize(dc.GetTextExtent("0"*22)) - labelDescription = wx.StaticText(panel, -1, _(u"&Bio (160 characters maximum)")) - self.description = wx.TextCtrl(panel, -1, size=(400, 400)) - dc = wx.WindowDC(self.description) - dc.SetFont(self.description.GetFont()) - self.description.SetSize(dc.GetTextExtent("0"*160)) - self.image = None - self.upload_image = wx.Button(panel, -1, _(u"Upload a &picture")) - self.ok = wx.Button(panel, wx.ID_OK, _(u"&Update profile")) - self.ok.SetDefault() - close = wx.Button(panel, wx.ID_CANCEL, _("&Close")) - sizer = wx.BoxSizer(wx.VERTICAL) - nameBox = wx.BoxSizer(wx.HORIZONTAL) - nameBox.Add(labelName, 0, wx.ALL, 5) - nameBox.Add(self.name, 0, wx.ALL, 5) - sizer.Add(nameBox, 0, wx.ALL, 5) - locationBox = wx.BoxSizer(wx.HORIZONTAL) - locationBox.Add(labelLocation, 0, wx.ALL, 5) - locationBox.Add(self.location, 0, wx.ALL, 5) - sizer.Add(locationBox, 0, wx.ALL, 5) - urlBox = wx.BoxSizer(wx.HORIZONTAL) - urlBox.Add(labelUrl, 0, wx.ALL, 5) - urlBox.Add(self.url, 0, wx.ALL, 5) - sizer.Add(urlBox, 0, wx.ALL, 5) - descriptionBox = wx.BoxSizer(wx.HORIZONTAL) - descriptionBox.Add(labelDescription, 0, wx.ALL, 5) - descriptionBox.Add(self.description, 0, wx.ALL, 5) - sizer.Add(descriptionBox, 0, wx.ALL, 5) - sizer.Add(self.upload_image, 5, wx.CENTER, 5) - btnBox = wx.BoxSizer(wx.HORIZONTAL) - btnBox.Add(self.ok, 0, wx.ALL, 5) - btnBox.Add(close, 0, wx.ALL, 5) - sizer.Add(btnBox, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self): + super(updateProfileDialog, self).__init__(parent=None, id=-1) + self.SetTitle(_(u"Update your profile")) + panel = wx.Panel(self) + labelName = wx.StaticText(panel, -1, _(u"&Name (50 characters maximum)")) + self.name = wx.TextCtrl(panel, -1) + self.name.SetFocus() + dc = wx.WindowDC(self.name) + dc.SetFont(self.name.GetFont()) + self.name.SetSize(dc.GetTextExtent("0"*50)) + labelLocation = wx.StaticText(panel, -1, _(u"&Location")) + self.location = wx.TextCtrl(panel, -1) + dc = wx.WindowDC(self.location) + dc.SetFont(self.location.GetFont()) + self.location.SetSize(dc.GetTextExtent("0"*35)) + labelUrl = wx.StaticText(panel, -1, _(u"&Website")) + self.url = wx.TextCtrl(panel, -1) + dc = wx.WindowDC(self.url) + dc.SetFont(self.url.GetFont()) + self.url.SetSize(dc.GetTextExtent("0"*22)) + labelDescription = wx.StaticText(panel, -1, _(u"&Bio (160 characters maximum)")) + self.description = wx.TextCtrl(panel, -1, size=(400, 400)) + dc = wx.WindowDC(self.description) + dc.SetFont(self.description.GetFont()) + self.description.SetSize(dc.GetTextExtent("0"*160)) + self.image = None + self.upload_image = wx.Button(panel, -1, _(u"Upload a &picture")) + self.ok = wx.Button(panel, wx.ID_OK, _(u"&Update profile")) + self.ok.SetDefault() + close = wx.Button(panel, wx.ID_CANCEL, _("&Close")) + sizer = wx.BoxSizer(wx.VERTICAL) + nameBox = wx.BoxSizer(wx.HORIZONTAL) + nameBox.Add(labelName, 0, wx.ALL, 5) + nameBox.Add(self.name, 0, wx.ALL, 5) + sizer.Add(nameBox, 0, wx.ALL, 5) + locationBox = wx.BoxSizer(wx.HORIZONTAL) + locationBox.Add(labelLocation, 0, wx.ALL, 5) + locationBox.Add(self.location, 0, wx.ALL, 5) + sizer.Add(locationBox, 0, wx.ALL, 5) + urlBox = wx.BoxSizer(wx.HORIZONTAL) + urlBox.Add(labelUrl, 0, wx.ALL, 5) + urlBox.Add(self.url, 0, wx.ALL, 5) + sizer.Add(urlBox, 0, wx.ALL, 5) + descriptionBox = wx.BoxSizer(wx.HORIZONTAL) + descriptionBox.Add(labelDescription, 0, wx.ALL, 5) + descriptionBox.Add(self.description, 0, wx.ALL, 5) + sizer.Add(descriptionBox, 0, wx.ALL, 5) + sizer.Add(self.upload_image, 5, wx.CENTER, 5) + btnBox = wx.BoxSizer(wx.HORIZONTAL) + btnBox.Add(self.ok, 0, wx.ALL, 5) + btnBox.Add(close, 0, wx.ALL, 5) + sizer.Add(btnBox, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def set_name(self, name): - self.set("name", name) + def set_name(self, name): + self.set("name", name) - def set_description(self, description): - self.set("description", description) + def set_description(self, description): + self.set("description", description) - def set_location(self, location): - self.set("location", location) + def set_location(self, location): + self.set("location", location) - def set_url(self, url): - self.set("url", url) + def set_url(self, url): + self.set("url", url) - def change_upload_button(self, uploaded=False): - if uploaded == False: - self.upload_image.SetLabel(_(u"Upload a picture")) - else: - self.upload_image.SetLabel(_(u"Discard image")) + def change_upload_button(self, uploaded=False): + if uploaded == False: + self.upload_image.SetLabel(_(u"Upload a picture")) + else: + self.upload_image.SetLabel(_(u"Discard image")) - def upload_picture(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return openFileDialog.GetPath() + def upload_picture(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return openFileDialog.GetPath() - def hide_upload_button(self, hide): - self.upload_image.Enable(hide) + def hide_upload_button(self, hide): + self.upload_image.Enable(hide) - def set_readonly(self): - self.name.style = wx.TE_READONLY - self.name.Refresh() - self.description.style = wx.TE_READONLY - self.description.Refresh() - self.location.style = wx.TE_READONLY - self.location.Refresh() - self.url.style = wx.TE_READONLY - self.url.Refresh() - self.hide_upload_button(False) - self.ok.Enable(False) \ No newline at end of file + def set_readonly(self): + self.name.style = wx.TE_READONLY + self.name.Refresh() + self.description.style = wx.TE_READONLY + self.description.Refresh() + self.location.style = wx.TE_READONLY + self.location.Refresh() + self.url.style = wx.TE_READONLY + self.url.Refresh() + self.hide_upload_button(False) + self.ok.Enable(False) diff --git a/src/wxUI/dialogs/urlList.py b/src/wxUI/dialogs/urlList.py index 16012f57..f8bdd7da 100644 --- a/src/wxUI/dialogs/urlList.py +++ b/src/wxUI/dialogs/urlList.py @@ -3,34 +3,34 @@ from __future__ import unicode_literals import wx class urlList(wx.Dialog): - def __init__(self, title=_(u"Select URL")): - super(urlList, self).__init__(parent=None, title=title) - panel = wx.Panel(self) - self.lista = wx.ListBox(panel, -1) - self.lista.SetFocus() - self.lista.SetSize(self.lista.GetBestSize()) - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(self.lista, 0, wx.ALL, 5) - goBtn = wx.Button(panel, wx.ID_OK) - goBtn.SetDefault() - cancelBtn = wx.Button(panel, wx.ID_CANCEL) - btnSizer = wx.BoxSizer() - btnSizer.Add(goBtn, 0, wx.ALL, 5) - btnSizer.Add(cancelBtn, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) + def __init__(self, title=_(u"Select URL")): + super(urlList, self).__init__(parent=None, title=title) + panel = wx.Panel(self) + self.lista = wx.ListBox(panel, -1) + self.lista.SetFocus() + self.lista.SetSize(self.lista.GetBestSize()) + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(self.lista, 0, wx.ALL, 5) + goBtn = wx.Button(panel, wx.ID_OK) + goBtn.SetDefault() + cancelBtn = wx.Button(panel, wx.ID_CANCEL) + btnSizer = wx.BoxSizer() + btnSizer.Add(goBtn, 0, wx.ALL, 5) + btnSizer.Add(cancelBtn, 0, wx.ALL, 5) + sizer.Add(btnSizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) - def populate_list(self, urls): - for i in urls: - self.lista.Append(i) - self.lista.SetSelection(0) + def populate_list(self, urls): + for i in urls: + self.lista.Append(i) + self.lista.SetSelection(0) - def get_string(self): - return self.lista.GetStringSelection() + def get_string(self): + return self.lista.GetStringSelection() - def get_item(self): - return self.lista.GetSelection() + def get_item(self): + return self.lista.GetSelection() - def get_response(self): - return self.ShowModal() \ No newline at end of file + def get_response(self): + return self.ShowModal() diff --git a/src/wxUI/dialogs/userActions.py b/src/wxUI/dialogs/userActions.py index c60f24bf..629d02aa 100644 --- a/src/wxUI/dialogs/userActions.py +++ b/src/wxUI/dialogs/userActions.py @@ -3,88 +3,88 @@ from __future__ import unicode_literals import wx class UserActionsDialog(wx.Dialog): - def __init__(self, users=[], default="follow", *args, **kwargs): - super(UserActionsDialog, self).__init__(parent=None, *args, **kwargs) - panel = wx.Panel(self) - userSizer = wx.BoxSizer() - self.SetTitle(_(u"Action")) - userLabel = wx.StaticText(panel, -1, _(u"&User")) - self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) - self.cb.SetFocus() - self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users")) - userSizer.Add(userLabel, 0, wx.ALL, 5) - userSizer.Add(self.cb, 0, wx.ALL, 5) - userSizer.Add(self.autocompletion, 0, wx.ALL, 5) - actionSizer = wx.BoxSizer(wx.VERTICAL) - label2 = wx.StaticText(panel, -1, _(u"Action")) - self.follow = wx.RadioButton(panel, -1, _(u"&Follow"), name=_(u"Action"), style=wx.RB_GROUP) - self.unfollow = wx.RadioButton(panel, -1, _(u"U&nfollow")) - self.mute = wx.RadioButton(panel, -1, _(u"&Mute")) - self.unmute = wx.RadioButton(panel, -1, _(u"Unmu&te")) - self.block = wx.RadioButton(panel, -1, _(u"&Block")) - self.unblock = wx.RadioButton(panel, -1, _(u"Unbl&ock")) - self.reportSpam = wx.RadioButton(panel, -1, _(u"&Report as spam")) - self.ignore_client = wx.RadioButton(panel, -1, _(u"&Ignore tweets from this client")) - self.setup_default(default) - hSizer = wx.BoxSizer(wx.HORIZONTAL) - hSizer.Add(label2, 0, wx.ALL, 5) - actionSizer.Add(self.follow, 0, wx.ALL, 5) - actionSizer.Add(self.unfollow, 0, wx.ALL, 5) - actionSizer.Add(self.mute, 0, wx.ALL, 5) - actionSizer.Add(self.unmute, 0, wx.ALL, 5) - actionSizer.Add(self.block, 0, wx.ALL, 5) - actionSizer.Add(self.unblock, 0, wx.ALL, 5) - actionSizer.Add(self.reportSpam, 0, wx.ALL, 5) - actionSizer.Add(self.ignore_client, 0, wx.ALL, 5) - hSizer.Add(actionSizer, 0, wx.ALL, 5) - sizer = wx.BoxSizer(wx.VERTICAL) - ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) - btnsizer = wx.BoxSizer() - btnsizer.Add(ok) - btnsizer.Add(cancel) - sizer.Add(userSizer) - sizer.Add(hSizer, 0, wx.ALL, 5) - sizer.Add(btnsizer) - panel.SetSizer(sizer) + def __init__(self, users=[], default="follow", *args, **kwargs): + super(UserActionsDialog, self).__init__(parent=None, *args, **kwargs) + panel = wx.Panel(self) + userSizer = wx.BoxSizer() + self.SetTitle(_(u"Action")) + userLabel = wx.StaticText(panel, -1, _(u"&User")) + self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) + self.cb.SetFocus() + self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users")) + userSizer.Add(userLabel, 0, wx.ALL, 5) + userSizer.Add(self.cb, 0, wx.ALL, 5) + userSizer.Add(self.autocompletion, 0, wx.ALL, 5) + actionSizer = wx.BoxSizer(wx.VERTICAL) + label2 = wx.StaticText(panel, -1, _(u"Action")) + self.follow = wx.RadioButton(panel, -1, _(u"&Follow"), name=_(u"Action"), style=wx.RB_GROUP) + self.unfollow = wx.RadioButton(panel, -1, _(u"U&nfollow")) + self.mute = wx.RadioButton(panel, -1, _(u"&Mute")) + self.unmute = wx.RadioButton(panel, -1, _(u"Unmu&te")) + self.block = wx.RadioButton(panel, -1, _(u"&Block")) + self.unblock = wx.RadioButton(panel, -1, _(u"Unbl&ock")) + self.reportSpam = wx.RadioButton(panel, -1, _(u"&Report as spam")) + self.ignore_client = wx.RadioButton(panel, -1, _(u"&Ignore tweets from this client")) + self.setup_default(default) + hSizer = wx.BoxSizer(wx.HORIZONTAL) + hSizer.Add(label2, 0, wx.ALL, 5) + actionSizer.Add(self.follow, 0, wx.ALL, 5) + actionSizer.Add(self.unfollow, 0, wx.ALL, 5) + actionSizer.Add(self.mute, 0, wx.ALL, 5) + actionSizer.Add(self.unmute, 0, wx.ALL, 5) + actionSizer.Add(self.block, 0, wx.ALL, 5) + actionSizer.Add(self.unblock, 0, wx.ALL, 5) + actionSizer.Add(self.reportSpam, 0, wx.ALL, 5) + actionSizer.Add(self.ignore_client, 0, wx.ALL, 5) + hSizer.Add(actionSizer, 0, wx.ALL, 5) + sizer = wx.BoxSizer(wx.VERTICAL) + ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) + btnsizer = wx.BoxSizer() + btnsizer.Add(ok) + btnsizer.Add(cancel) + sizer.Add(userSizer) + sizer.Add(hSizer, 0, wx.ALL, 5) + sizer.Add(btnsizer) + panel.SetSizer(sizer) - def get_action(self): - if self.follow.GetValue() == True: return "follow" - elif self.unfollow.GetValue() == True: return "unfollow" - elif self.mute.GetValue() == True: return "mute" - elif self.unmute.GetValue() == True: return "unmute" - elif self.reportSpam.GetValue() == True: return "report" - elif self.block.GetValue() == True: return "block" - elif self.unblock.GetValue() == True: return "unblock" - elif self.ignore_client.GetValue() == True: return "ignore_client" + def get_action(self): + if self.follow.GetValue() == True: return "follow" + elif self.unfollow.GetValue() == True: return "unfollow" + elif self.mute.GetValue() == True: return "mute" + elif self.unmute.GetValue() == True: return "unmute" + elif self.reportSpam.GetValue() == True: return "report" + elif self.block.GetValue() == True: return "block" + elif self.unblock.GetValue() == True: return "unblock" + elif self.ignore_client.GetValue() == True: return "ignore_client" - def setup_default(self, default): - if default == "follow": - self.follow.SetValue(True) - elif default == "unfollow": - self.unfollow.SetValue(True) - elif default == "mute": - self.mute.SetValue(True) - elif default == "unmute": - self.unmute.SetValue(True) - elif default == "report": - self.reportSpam.SetValue(True) - elif default == "block": - self.block.SetValue(True) - elif default == "unblock": - self.unblock.SetValue(True) - elif default == "ignore_client": - self.ignore_client.SetValue(True) + def setup_default(self, default): + if default == "follow": + self.follow.SetValue(True) + elif default == "unfollow": + self.unfollow.SetValue(True) + elif default == "mute": + self.mute.SetValue(True) + elif default == "unmute": + self.unmute.SetValue(True) + elif default == "report": + self.reportSpam.SetValue(True) + elif default == "block": + self.block.SetValue(True) + elif default == "unblock": + self.unblock.SetValue(True) + elif default == "ignore_client": + self.ignore_client.SetValue(True) - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def get_user(self): - return self.cb.GetValue() + def get_user(self): + return self.cb.GetValue() - def get_position(self): - return self.cb.GetPosition() + def get_position(self): + return self.cb.GetPosition() - def popup_menu(self, menu): - self.PopupMenu(menu, self.cb.GetPosition()) + def popup_menu(self, menu): + self.PopupMenu(menu, self.cb.GetPosition()) diff --git a/src/wxUI/dialogs/userAliasDialogs.py b/src/wxUI/dialogs/userAliasDialogs.py new file mode 100644 index 00000000..9156c0b5 --- /dev/null +++ b/src/wxUI/dialogs/userAliasDialogs.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +import wx +import gettext +from . import baseDialog + +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() + 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()) + +class userAliasEditorDialog(wx.Dialog): + def __init__(self, *args, **kwds): + super(userAliasEditorDialog, self).__init__(parent=None) + self.SetTitle(_("Edit user aliases")) + main_sizer = wx.BoxSizer(wx.VERTICAL) + userListSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Users")), wx.VERTICAL) + main_sizer.Add(userListSizer, 1, wx.EXPAND, 0) + self.users = wx.ListBox(self, wx.ID_ANY, choices=[]) + self.users.Bind(wx.EVT_LISTBOX, self.on_selection_changes) + userListSizer.Add(self.users, 0, 0, 0) + actionsSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Actions")), wx.HORIZONTAL) + main_sizer.Add(actionsSizer, 1, wx.EXPAND, 0) + self.add = wx.Button(self, wx.ID_ANY, _("Add alias")) + self.add.SetToolTip(_("Adds a new user alias")) + actionsSizer.Add(self.add, 0, 0, 0) + self.edit = wx.Button(self, wx.ID_ANY, _("Edit")) + self.edit.SetToolTip(_("Edit the currently focused user Alias.")) + self.edit.Enable(False) + actionsSizer.Add(self.edit, 0, 0, 0) + self.remove = wx.Button(self, wx.ID_ANY, _("Remove")) + self.remove.SetToolTip(_("Remove the currently focused user alias.")) + self.remove.Enable(False) + actionsSizer.Add(self.remove, 0, 0, 0) + btnSizer = wx.StdDialogButtonSizer() + main_sizer.Add(btnSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.button_CLOSE = wx.Button(self, wx.ID_CLOSE, "") + btnSizer.AddButton(self.button_CLOSE) + btnSizer.Realize() + self.SetSizer(main_sizer) + main_sizer.Fit(self) + self.SetEscapeId(self.button_CLOSE.GetId()) + self.Layout() + + def on_selection_changes(self, *args, **kwargs): + selection = self.users.GetSelection() + if selection == -1: + self.enable_action_buttons(False) + else: + self.enable_action_buttons(True) + + def get_selected_user(self): + return self.users.GetStringSelection() + + def remove_alias_dialog(self, *args, **kwargs): + dlg = wx.MessageDialog(self, _("Are you sure you want to delete this user alias?"), _("Remove user alias"), wx.YES_NO) + if dlg.ShowModal() == wx.ID_YES: + return True + else: + return False + + def enable_action_buttons(self, enabled=True): + self.edit.Enable(enabled) + self.remove.Enable(enabled) + + def edit_alias_dialog(self, title): + dlg = wx.TextEntryDialog(self, title, _("User alias")) + if dlg.ShowModal() == wx.ID_OK: + return dlg.GetValue() \ No newline at end of file diff --git a/src/wxUI/dialogs/userSelection.py b/src/wxUI/dialogs/userSelection.py index 30dc67d3..bb110910 100644 --- a/src/wxUI/dialogs/userSelection.py +++ b/src/wxUI/dialogs/userSelection.py @@ -3,64 +3,64 @@ from __future__ import unicode_literals import wx class selectUserDialog(wx.Dialog): - def __init__(self, users=[], default="tweets", *args, **kwargs): - super(selectUserDialog, self).__init__(parent=None, *args, **kwargs) - panel = wx.Panel(self) - userSizer = wx.BoxSizer() - self.SetTitle(_(u"Timeline for %s") % (users[0])) - userLabel = wx.StaticText(panel, -1, _(u"User")) - self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) - self.cb.SetFocus() - self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users")) - userSizer.Add(userLabel, 0, wx.ALL, 5) - userSizer.Add(self.cb, 0, wx.ALL, 5) - userSizer.Add(self.autocompletion, 0, wx.ALL, 5) - actionSizer = wx.BoxSizer(wx.VERTICAL) - label2 = wx.StaticText(panel, -1, _(u"Buffer type")) - self.tweets = wx.RadioButton(panel, -1, _(u"&Tweets"), style=wx.RB_GROUP) - self.favourites = wx.RadioButton(panel, -1, _(u"&Likes")) - self.followers = wx.RadioButton(panel, -1, _(u"&Followers")) - self.friends = wx.RadioButton(panel, -1, _(u"F&riends")) - self.setup_default(default) - hSizer = wx.BoxSizer(wx.HORIZONTAL) - hSizer.Add(label2, 0, wx.ALL, 5) - actionSizer.Add(self.tweets, 0, wx.ALL, 5) - actionSizer.Add(self.favourites, 0, wx.ALL, 5) - actionSizer.Add(self.followers, 0, wx.ALL, 5) - actionSizer.Add(self.friends, 0, wx.ALL, 5) - hSizer.Add(actionSizer, 0, wx.ALL, 5) - sizer = wx.BoxSizer(wx.VERTICAL) - ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) - ok.SetDefault() - cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) - btnsizer = wx.BoxSizer() - btnsizer.Add(ok) - btnsizer.Add(cancel) - sizer.Add(userSizer) - sizer.Add(hSizer, 0, wx.ALL, 5) - sizer.Add(btnsizer) - panel.SetSizer(sizer) + def __init__(self, users=[], default="tweets", *args, **kwargs): + super(selectUserDialog, self).__init__(parent=None, *args, **kwargs) + panel = wx.Panel(self) + userSizer = wx.BoxSizer() + self.SetTitle(_(u"Timeline for %s") % (users[0])) + userLabel = wx.StaticText(panel, -1, _(u"User")) + self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) + self.cb.SetFocus() + self.autocompletion = wx.Button(panel, -1, _(u"&Autocomplete users")) + userSizer.Add(userLabel, 0, wx.ALL, 5) + userSizer.Add(self.cb, 0, wx.ALL, 5) + userSizer.Add(self.autocompletion, 0, wx.ALL, 5) + actionSizer = wx.BoxSizer(wx.VERTICAL) + label2 = wx.StaticText(panel, -1, _(u"Buffer type")) + self.tweets = wx.RadioButton(panel, -1, _(u"&Tweets"), style=wx.RB_GROUP) + self.favourites = wx.RadioButton(panel, -1, _(u"&Likes")) + self.followers = wx.RadioButton(panel, -1, _(u"&Followers")) + self.friends = wx.RadioButton(panel, -1, _(u"F&riends")) + self.setup_default(default) + hSizer = wx.BoxSizer(wx.HORIZONTAL) + hSizer.Add(label2, 0, wx.ALL, 5) + actionSizer.Add(self.tweets, 0, wx.ALL, 5) + actionSizer.Add(self.favourites, 0, wx.ALL, 5) + actionSizer.Add(self.followers, 0, wx.ALL, 5) + actionSizer.Add(self.friends, 0, wx.ALL, 5) + hSizer.Add(actionSizer, 0, wx.ALL, 5) + sizer = wx.BoxSizer(wx.VERTICAL) + ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) + ok.SetDefault() + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) + btnsizer = wx.BoxSizer() + btnsizer.Add(ok) + btnsizer.Add(cancel) + sizer.Add(userSizer) + sizer.Add(hSizer, 0, wx.ALL, 5) + sizer.Add(btnsizer) + panel.SetSizer(sizer) - def get_action(self): - if self.tweets.GetValue() == True: return "tweets" - elif self.favourites.GetValue() == True: return "favourites" - elif self.followers.GetValue() == True: return "followers" - elif self.friends.GetValue() == True: return "friends" + def get_action(self): + if self.tweets.GetValue() == True: return "tweets" + elif self.favourites.GetValue() == True: return "favourites" + elif self.followers.GetValue() == True: return "followers" + elif self.friends.GetValue() == True: return "friends" - def setup_default(self, default): - if default == "tweets": - self.tweets.SetValue(True) - elif default == "favourites": - self.favourites.SetValue(True) + def setup_default(self, default): + if default == "tweets": + self.tweets.SetValue(True) + elif default == "favourites": + self.favourites.SetValue(True) - def get_response(self): - return self.ShowModal() + def get_response(self): + return self.ShowModal() - def get_user(self): - return self.cb.GetValue() + def get_user(self): + return self.cb.GetValue() - def get_position(self): - return self.cb.GetPosition() + def get_position(self): + return self.cb.GetPosition() - def popup_menu(self, menu): - self.PopupMenu(menu, self.cb.GetPosition()) + def popup_menu(self, menu): + self.PopupMenu(menu, self.cb.GetPosition()) diff --git a/src/wxUI/dialogs/utils.py b/src/wxUI/dialogs/utils.py index 36bdc8a8..a595acc7 100644 --- a/src/wxUI/dialogs/utils.py +++ b/src/wxUI/dialogs/utils.py @@ -22,29 +22,28 @@ import wx from . import baseDialog class selectUserDialog(baseDialog.BaseWXDialog): - def __init__(self, title, users): - super(selectUserDialog, 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) - sizer = wx.BoxSizer(wx.VERTICAL) - ok = wx.Button(panel, wx.ID_OK, _(u"OK")) - ok.SetDefault() + def __init__(self, title, users): + super(selectUserDialog, 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) + 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(btnsizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) - - def get_user(self): - return self.cb.GetValue() + 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(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) + def get_user(self): + return self.cb.GetValue() \ No newline at end of file diff --git a/src/wxUI/menus.py b/src/wxUI/menus.py index 70fbd7fa..9f2defed 100644 --- a/src/wxUI/menus.py +++ b/src/wxUI/menus.py @@ -3,102 +3,102 @@ from __future__ import unicode_literals import wx class basePanelMenu(wx.Menu): - def __init__(self): - super(basePanelMenu, self).__init__() - self.retweet = wx.MenuItem(self, wx.ID_ANY, _(u"&Retweet")) - self.Append(self.retweet) - self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply")) - self.Append(self.reply) - self.fav = wx.MenuItem(self, wx.ID_ANY, _(u"&Like")) - self.Append(self.fav) - self.unfav = wx.MenuItem(self, wx.ID_ANY, _(u"&Unlike")) - self.Append(self.unfav) - self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) - self.Append(self.openUrl) - self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) - self.Append(self.openInBrowser) - self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) - self.Append(self.play) - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show tweet")) - self.Append(self.view) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) - self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) - self.Append(self.remove) - self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) - self.Append(self.userActions) + def __init__(self): + super(basePanelMenu, self).__init__() + self.retweet = wx.MenuItem(self, wx.ID_ANY, _(u"&Retweet")) + self.Append(self.retweet) + self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply")) + self.Append(self.reply) + self.fav = wx.MenuItem(self, wx.ID_ANY, _(u"&Like")) + self.Append(self.fav) + self.unfav = wx.MenuItem(self, wx.ID_ANY, _(u"&Unlike")) + self.Append(self.unfav) + self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) + self.Append(self.openUrl) + self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) + self.Append(self.openInBrowser) + self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) + self.Append(self.play) + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show tweet")) + self.Append(self.view) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) + self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) + self.Append(self.remove) + self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) + self.Append(self.userActions) class dmPanelMenu(wx.Menu): - def __init__(self): - super(dmPanelMenu, self).__init__() - self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply")) - self.Append(self.reply) - self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) - self.Append(self.openUrl) - self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) - self.Append(self.play) - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show direct message")) - self.Append(self.view) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) - self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) - self.Append(self.remove) - self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) - self.Append(self.userActions) + def __init__(self): + super(dmPanelMenu, self).__init__() + self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Re&ply")) + self.Append(self.reply) + self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) + self.Append(self.openUrl) + self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) + self.Append(self.play) + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show direct message")) + self.Append(self.view) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) + self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) + self.Append(self.remove) + self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) + self.Append(self.userActions) class sentPanelMenu(wx.Menu): - def __init__(self): - super(sentPanelMenu, self).__init__() - self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) - self.Append(self.openUrl) - self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) - self.Append(self.openInBrowser) - self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) - self.Append(self.play) - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show tweet")) - self.Append(self.view) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) - self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) - self.Append(self.remove) + def __init__(self): + super(sentPanelMenu, self).__init__() + self.openUrl = wx.MenuItem(self, wx.ID_ANY, _(u"&Open URL")) + self.Append(self.openUrl) + self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) + self.Append(self.openInBrowser) + self.play = wx.MenuItem(self, wx.ID_ANY, _(u"&Play audio")) + self.Append(self.play) + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show tweet")) + self.Append(self.view) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) + self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) + self.Append(self.remove) class eventsPanelMenu(wx.Menu): - def __init__(self): - super(eventsPanelMenu, self).__init__() - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show event")) - self.Append(self.view) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) - self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) - self.Append(self.remove) + def __init__(self): + super(eventsPanelMenu, self).__init__() + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show event")) + self.Append(self.view) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) + self.remove = wx.MenuItem(self, wx.ID_ANY, _(u"&Delete")) + self.Append(self.remove) class peoplePanelMenu(wx.Menu): - def __init__(self): - super(peoplePanelMenu, self).__init__() - self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Direct &message")) - self.Append(self.reply) - self.lists = wx.MenuItem(self, wx.ID_ANY, _(u"&View lists")) - self.Append(self.lists) - self.lists.Enable(False) - self.details = wx.MenuItem(self, wx.ID_ANY, _(u"Show user &profile")) - self.Append(self.details) - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show user")) - self.Append(self.view) - self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) - self.Append(self.openInBrowser) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) - self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) - self.Append(self.userActions) + def __init__(self): + super(peoplePanelMenu, self).__init__() + self.reply = wx.MenuItem(self, wx.ID_ANY, _(u"Direct &message")) + self.Append(self.reply) + self.lists = wx.MenuItem(self, wx.ID_ANY, _(u"&View lists")) + self.Append(self.lists) + self.lists.Enable(False) + self.details = wx.MenuItem(self, wx.ID_ANY, _(u"Show user &profile")) + self.Append(self.details) + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show user")) + self.Append(self.view) + self.openInBrowser = wx.MenuItem(self, wx.ID_ANY, _(u"&Open in Twitter")) + self.Append(self.openInBrowser) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) + self.userActions = wx.MenuItem(self, wx.ID_ANY, _(u"&User actions...")) + self.Append(self.userActions) class trendsPanelMenu(wx.Menu): - def __init__(self): - super(trendsPanelMenu, self).__init__() - self.search_topic = wx.MenuItem(self, wx.ID_ANY, _(u"Search topic")) - self.Append(self.search_topic) - self.tweetThisTrend = wx.MenuItem(self, wx.ID_ANY, _(u"&Tweet about this trend")) - self.Append(self.tweetThisTrend) - self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show item")) - self.Append(self.view) - self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) - self.Append(self.copy) + def __init__(self): + super(trendsPanelMenu, self).__init__() + self.search_topic = wx.MenuItem(self, wx.ID_ANY, _(u"Search topic")) + self.Append(self.search_topic) + self.tweetThisTrend = wx.MenuItem(self, wx.ID_ANY, _(u"&Tweet about this trend")) + self.Append(self.tweetThisTrend) + self.view = wx.MenuItem(self, wx.ID_ANY, _(u"&Show item")) + self.Append(self.view) + self.copy = wx.MenuItem(self, wx.ID_ANY, _(u"&Copy to clipboard")) + self.Append(self.copy) diff --git a/src/wxUI/sysTrayIcon.py b/src/wxUI/sysTrayIcon.py index 81efcd10..a408c35c 100644 --- a/src/wxUI/sysTrayIcon.py +++ b/src/wxUI/sysTrayIcon.py @@ -27,23 +27,23 @@ import os class SysTrayIcon(wx.adv.TaskBarIcon): - def __init__(self): - super(SysTrayIcon, self).__init__() - icon=wx.Icon(os.path.join(paths.app_path(), "icon.ico"), wx.BITMAP_TYPE_ICO) - self.SetIcon(icon, application.name) - self.menu=wx.Menu() - self.tweet = self.menu.Append(wx.ID_ANY, _(u"Tweet")) - self.global_settings = self.menu.Append(wx.ID_ANY, _(u"&Global settings")) - self.account_settings = self.menu.Append(wx.ID_ANY, _(u"Account se&ttings")) - self.update_profile = self.menu.Append(wx.ID_ANY, _(u"Update &profile")) - self.show_hide = self.menu.Append(wx.ID_ANY, _(u"&Show / hide")) - self.doc = self.menu.Append(wx.ID_ANY, _(u"&Documentation")) - self.check_for_updates = self.menu.Append(wx.ID_ANY, _(u"Check for &updates")) - self.exit = self.menu.Append(wx.ID_ANY, _(u"&Exit")) + def __init__(self): + super(SysTrayIcon, self).__init__() + icon=wx.Icon(os.path.join(paths.app_path(), "icon.ico"), wx.BITMAP_TYPE_ICO) + self.SetIcon(icon, application.name) + self.menu=wx.Menu() + self.tweet = self.menu.Append(wx.ID_ANY, _(u"Tweet")) + self.global_settings = self.menu.Append(wx.ID_ANY, _(u"&Global settings")) + self.account_settings = self.menu.Append(wx.ID_ANY, _(u"Account se&ttings")) + self.update_profile = self.menu.Append(wx.ID_ANY, _(u"Update &profile")) + self.show_hide = self.menu.Append(wx.ID_ANY, _(u"&Show / hide")) + self.doc = self.menu.Append(wx.ID_ANY, _(u"&Documentation")) + self.check_for_updates = self.menu.Append(wx.ID_ANY, _(u"Check for &updates")) + self.exit = self.menu.Append(wx.ID_ANY, _(u"&Exit")) - def show_menu(self): - self.PopupMenu(self.menu) + def show_menu(self): + self.PopupMenu(self.menu) - def Destroy(self): - self.menu.Destroy() - super(SysTrayIcon, self).Destroy() \ No newline at end of file + def Destroy(self): + self.menu.Destroy() + super(SysTrayIcon, self).Destroy() diff --git a/src/wxUI/view.py b/src/wxUI/view.py index 2729f6bf..2d260023 100644 --- a/src/wxUI/view.py +++ b/src/wxUI/view.py @@ -6,200 +6,202 @@ import wx.adv import application class mainFrame(wx.Frame): - """ Main class of the Frame. This is the Main Window.""" + """ Main class of the Frame. This is the Main Window.""" - ### MENU - def makeMenus(self): - """ Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created.""" - menuBar = wx.MenuBar() + ### MENU + def makeMenus(self): + """ Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created.""" + menuBar = wx.MenuBar() - # Application menu - app = wx.Menu() - self.manage_accounts = app.Append(wx.ID_ANY, _(u"&Manage accounts")) - self.updateProfile = app.Append(wx.ID_ANY, _(u"&Update profile")) - self.show_hide = app.Append(wx.ID_ANY, _(u"&Hide window")) - self.menuitem_search = app.Append(wx.ID_ANY, _(u"&Search")) - self.lists = app.Append(wx.ID_ANY, _(u"&Lists manager")) - self.keystroke_editor = app.Append(wx.ID_ANY, _(u"&Edit keystrokes")) - self.account_settings = app.Append(wx.ID_ANY, _(u"Account se&ttings")) - self.prefs = app.Append(wx.ID_PREFERENCES, _(u"&Global settings")) - self.close = app.Append(wx.ID_EXIT, _(u"E&xit")) + # Application menu + app = wx.Menu() + self.manage_accounts = app.Append(wx.ID_ANY, _(u"&Manage accounts")) + self.updateProfile = app.Append(wx.ID_ANY, _(u"&Update profile")) + self.show_hide = app.Append(wx.ID_ANY, _(u"&Hide window")) + self.menuitem_search = app.Append(wx.ID_ANY, _(u"&Search")) + self.lists = app.Append(wx.ID_ANY, _(u"&Lists manager")) + self.manageAliases = app.Append(wx.ID_ANY, _("Manage user aliases")) + self.keystroke_editor = app.Append(wx.ID_ANY, _(u"&Edit keystrokes")) + self.account_settings = app.Append(wx.ID_ANY, _(u"Account se&ttings")) + self.prefs = app.Append(wx.ID_PREFERENCES, _(u"&Global settings")) + self.close = app.Append(wx.ID_EXIT, _(u"E&xit")) - # Tweet menu - tweet = wx.Menu() - self.compose = tweet.Append(wx.ID_ANY, _(u"&Tweet")) - self.reply = tweet.Append(wx.ID_ANY, _(u"Re&ply")) - self.retweet = tweet.Append(wx.ID_ANY, _(u"&Retweet")) - self.fav = tweet.Append(wx.ID_ANY, _(u"&Like")) - self.unfav = tweet.Append(wx.ID_ANY, _(u"&Unlike")) - self.view = tweet.Append(wx.ID_ANY, _(u"&Show tweet")) - self.view_coordinates = tweet.Append(wx.ID_ANY, _(u"View &address")) - self.view_conversation = tweet.Append(wx.ID_ANY, _(u"View conversa&tion")) - self.ocr = tweet.Append(wx.ID_ANY, _(u"Read text in picture")) - self.delete = tweet.Append(wx.ID_ANY, _(u"&Delete")) + # Tweet menu + tweet = wx.Menu() + self.compose = tweet.Append(wx.ID_ANY, _(u"&Tweet")) + self.reply = tweet.Append(wx.ID_ANY, _(u"Re&ply")) + self.retweet = tweet.Append(wx.ID_ANY, _(u"&Retweet")) + self.fav = tweet.Append(wx.ID_ANY, _(u"&Like")) + self.unfav = tweet.Append(wx.ID_ANY, _(u"&Unlike")) + self.view = tweet.Append(wx.ID_ANY, _(u"&Show tweet")) + self.view_coordinates = tweet.Append(wx.ID_ANY, _(u"View &address")) + self.view_conversation = tweet.Append(wx.ID_ANY, _(u"View conversa&tion")) + self.ocr = tweet.Append(wx.ID_ANY, _(u"Read text in picture")) + self.delete = tweet.Append(wx.ID_ANY, _(u"&Delete")) - # User menu - user = wx.Menu() - 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.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")) - self.details = user.Append(wx.ID_ANY, _(u"Show user &profile")) - self.favs = user.Append(wx.ID_ANY, _(u"V&iew likes")) + # User menu + user = wx.Menu() + 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")) + self.details = user.Append(wx.ID_ANY, _(u"Show user &profile")) + self.favs = user.Append(wx.ID_ANY, _(u"V&iew likes")) - # buffer menu - buffer = wx.Menu() - self.update_buffer = buffer.Append(wx.ID_ANY, _(u"&Update buffer")) - self.trends = buffer.Append(wx.ID_ANY, _(u"New &trending topics buffer...")) - self.filter = buffer.Append(wx.ID_ANY, _(u"Create a &filter")) - self.manage_filters = buffer.Append(wx.ID_ANY, _(u"&Manage filters")) - self.find = buffer.Append(wx.ID_ANY, _(u"Find a string in the currently focused buffer...")) - self.load_previous_items = buffer.Append(wx.ID_ANY, _(u"&Load previous items")) - buffer.AppendSeparator() - self.mute_buffer = buffer.AppendCheckItem(wx.ID_ANY, _(u"&Mute")) - self.autoread = buffer.AppendCheckItem(wx.ID_ANY, _(u"&Autoread")) - self.clear = buffer.Append(wx.ID_ANY, _(u"&Clear buffer")) - self.deleteTl = buffer.Append(wx.ID_ANY, _(u"&Destroy")) + # buffer menu + buffer = wx.Menu() + self.update_buffer = buffer.Append(wx.ID_ANY, _(u"&Update buffer")) + self.trends = buffer.Append(wx.ID_ANY, _(u"New &trending topics buffer...")) + self.filter = buffer.Append(wx.ID_ANY, _(u"Create a &filter")) + self.manage_filters = buffer.Append(wx.ID_ANY, _(u"&Manage filters")) + self.find = buffer.Append(wx.ID_ANY, _(u"Find a string in the currently focused buffer...")) + self.load_previous_items = buffer.Append(wx.ID_ANY, _(u"&Load previous items")) + buffer.AppendSeparator() + self.mute_buffer = buffer.AppendCheckItem(wx.ID_ANY, _(u"&Mute")) + self.autoread = buffer.AppendCheckItem(wx.ID_ANY, _(u"&Autoread")) + self.clear = buffer.Append(wx.ID_ANY, _(u"&Clear buffer")) + self.deleteTl = buffer.Append(wx.ID_ANY, _(u"&Destroy")) - # audio menu - audio = wx.Menu() - self.seekLeft = audio.Append(wx.ID_ANY, _(u"&Seek back 5 seconds")) - self.seekRight = audio.Append(wx.ID_ANY, _(u"&Seek forward 5 seconds")) + # audio menu + audio = wx.Menu() + self.seekLeft = audio.Append(wx.ID_ANY, _(u"&Seek back 5 seconds")) + self.seekRight = audio.Append(wx.ID_ANY, _(u"&Seek forward 5 seconds")) - # Help Menu - help = wx.Menu() - self.doc = help.Append(-1, _(u"&Documentation")) - self.sounds_tutorial = help.Append(wx.ID_ANY, _(u"Sounds &tutorial")) - self.changelog = help.Append(wx.ID_ANY, _(u"&What's new in this version?")) - self.check_for_updates = help.Append(wx.ID_ANY, _(u"&Check for updates")) - self.reportError = help.Append(wx.ID_ANY, _(u"&Report an error")) - self.visit_website = help.Append(-1, _(u"{0}'s &website").format(application.name,)) - self.get_soundpacks = help.Append(-1, _(u"Get soundpacks for TWBlue")) - self.about = help.Append(-1, _(u"About &{0}").format(application.name,)) + # Help Menu + help = wx.Menu() + self.doc = help.Append(-1, _(u"&Documentation")) + self.sounds_tutorial = help.Append(wx.ID_ANY, _(u"Sounds &tutorial")) + self.changelog = help.Append(wx.ID_ANY, _(u"&What's new in this version?")) + self.check_for_updates = help.Append(wx.ID_ANY, _(u"&Check for updates")) + self.reportError = help.Append(wx.ID_ANY, _(u"&Report an error")) + self.visit_website = help.Append(-1, _(u"{0}'s &website").format(application.name,)) + self.get_soundpacks = help.Append(-1, _(u"Get soundpacks for TWBlue")) + self.about = help.Append(-1, _(u"About &{0}").format(application.name,)) - # Add all to the menu Bar - menuBar.Append(app, _(u"&Application")) - menuBar.Append(tweet, _(u"&Tweet")) - menuBar.Append(user, _(u"&User")) - menuBar.Append(buffer, _(u"&Buffer")) - menuBar.Append(audio, _(u"&Audio")) - menuBar.Append(help, _(u"&Help")) + # Add all to the menu Bar + menuBar.Append(app, _(u"&Application")) + menuBar.Append(tweet, _(u"&Tweet")) + menuBar.Append(user, _(u"&User")) + menuBar.Append(buffer, _(u"&Buffer")) + menuBar.Append(audio, _(u"&Audio")) + menuBar.Append(help, _(u"&Help")) - self.accel_tbl = wx.AcceleratorTable([ -(wx.ACCEL_CTRL, ord('N'), self.compose.GetId()), -(wx.ACCEL_CTRL, ord('R'), self.reply.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), self.retweet.GetId()), -(wx.ACCEL_CTRL, ord('F'), self.fav.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), self.unfav.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), self.view.GetId()), -(wx.ACCEL_CTRL, ord('D'), self.dm.GetId()), + self.accel_tbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('N'), self.compose.GetId()), + (wx.ACCEL_CTRL, ord('R'), self.reply.GetId()), + (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), self.retweet.GetId()), + (wx.ACCEL_CTRL, ord('F'), self.fav.GetId()), + (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), self.unfav.GetId()), + (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), self.view.GetId()), + (wx.ACCEL_CTRL, ord('D'), self.dm.GetId()), -(wx.ACCEL_CTRL, ord('Q'), self.close.GetId()), -(wx.ACCEL_CTRL, ord('S'), self.follow.GetId()), -(wx.ACCEL_CTRL, ord('I'), self.timeline.GetId()), -(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), self.deleteTl.GetId()), -(wx.ACCEL_CTRL, ord('M'), self.show_hide.GetId()), -(wx.ACCEL_CTRL, wx.WXK_LEFT, self.seekLeft.GetId()), -(wx.ACCEL_CTRL, ord('P'), self.updateProfile.GetId()), -(wx.ACCEL_CTRL, wx.WXK_RIGHT, self.seekRight.GetId()), -(wx.ACCEL_CTRL, ord(' '), self.seekLeft.GetId()), - ]) + (wx.ACCEL_CTRL, ord('Q'), self.close.GetId()), + (wx.ACCEL_CTRL, ord('S'), self.follow.GetId()), + (wx.ACCEL_CTRL, ord('I'), self.timeline.GetId()), + (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), self.deleteTl.GetId()), + (wx.ACCEL_CTRL, ord('M'), self.show_hide.GetId()), + (wx.ACCEL_CTRL, wx.WXK_LEFT, self.seekLeft.GetId()), + (wx.ACCEL_CTRL, ord('P'), self.updateProfile.GetId()), + (wx.ACCEL_CTRL, wx.WXK_RIGHT, self.seekRight.GetId()), + (wx.ACCEL_CTRL, ord(' '), self.seekLeft.GetId()), + ]) - self.SetAcceleratorTable(self.accel_tbl) - return menuBar + self.SetAcceleratorTable(self.accel_tbl) + return menuBar - ### MAIN - def __init__(self): - """ Main function of this class.""" - super(mainFrame, self).__init__(None, -1, application.name, size=(1600, 1600)) - self.panel = wx.Panel(self) - self.sizer = wx.BoxSizer(wx.VERTICAL) - self.SetTitle(application.name) - self.SetMenuBar(self.makeMenus()) - self.nb = wx.Treebook(self.panel, wx.ID_ANY) - self.buffers = {} + ### MAIN + def __init__(self): + """ Main function of this class.""" + super(mainFrame, self).__init__(None, -1, application.name, size=(1600, 1600)) + self.panel = wx.Panel(self) + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.SetTitle(application.name) + self.SetMenuBar(self.makeMenus()) + self.nb = wx.Treebook(self.panel, wx.ID_ANY) + self.buffers = {} - def get_buffer_count(self): - return self.nb.GetPageCount() + def get_buffer_count(self): + return self.nb.GetPageCount() - def add_buffer(self, buffer, name): - self.nb.AddPage(buffer, name) - self.buffers[name] = buffer.GetId() + def add_buffer(self, buffer, name): + self.nb.AddPage(buffer, name) + self.buffers[name] = buffer.GetId() - def insert_buffer(self, buffer, name, pos): - self.nb.InsertSubPage(pos, buffer, name) - self.buffers[name] = buffer.GetId() + def insert_buffer(self, buffer, name, pos): + self.nb.InsertSubPage(pos, buffer, name) + self.buffers[name] = buffer.GetId() - def prepare(self): - self.sizer.Add(self.nb, 0, wx.ALL, 5) - self.panel.SetSizer(self.sizer) + def prepare(self): + self.sizer.Add(self.nb, 0, wx.ALL, 5) + self.panel.SetSizer(self.sizer) # self.Maximize() - self.sizer.Layout() - self.SetClientSize(self.sizer.CalcMin()) + self.sizer.Layout() + self.SetClientSize(self.sizer.CalcMin()) # print self.GetSize() - def get_buffers(self): - return [self.nb.GetPage(i) for i in range(0, self.nb.GetPageCount())] + def get_buffers(self): + return [self.nb.GetPage(i) for i in range(0, self.nb.GetPageCount())] - def search(self, name_, account): - for i in range(0, self.nb.GetPageCount()): - if self.nb.GetPage(i).name == name_ and self.nb.GetPage(i).account == account: return i + def search(self, name_, account): + for i in range(0, self.nb.GetPageCount()): + if self.nb.GetPage(i).name == name_ and self.nb.GetPage(i).account == account: return i - def get_current_buffer(self): - return self.nb.GetCurrentPage() + def get_current_buffer(self): + return self.nb.GetCurrentPage() - def get_current_buffer_pos(self): - return self.nb.GetSelection() + def get_current_buffer_pos(self): + return self.nb.GetSelection() - def get_buffer(self, pos): - return self.GetPage(pos) + def get_buffer(self, pos): + return self.GetPage(pos) - def change_buffer(self, position): - self.nb.ChangeSelection(position) + def change_buffer(self, position): + self.nb.ChangeSelection(position) - def get_buffer_text(self): - return self.nb.GetPageText(self.nb.GetSelection()) + def get_buffer_text(self): + return self.nb.GetPageText(self.nb.GetSelection()) - def get_buffer_by_id(self, id): - return self.nb.FindWindowById(id) - def advance_selection(self, forward): - self.nb.AdvanceSelection(forward) + def get_buffer_by_id(self, id): + return self.nb.FindWindowById(id) + def advance_selection(self, forward): + self.nb.AdvanceSelection(forward) - def show(self): - self.Show() + def show(self): + self.Show() - def show_address(self, address): - wx.MessageDialog(self, address, _(u"Address"), wx.OK).ShowModal() + def show_address(self, address): + wx.MessageDialog(self, address, _(u"Address"), wx.OK).ShowModal() - def delete_buffer(self, pos): - self.nb.DeletePage(pos) + def delete_buffer(self, pos): + self.nb.DeletePage(pos) - def about_dialog(self): - info = wx.adv.AboutDialogInfo() - info.SetName(application.name) - info.SetVersion(application.version) - info.SetDescription(application.description) - info.SetCopyright(application.copyright) - info.SetTranslators(application.translators) + def about_dialog(self): + info = wx.adv.AboutDialogInfo() + info.SetName(application.name) + info.SetVersion(application.version) + info.SetDescription(application.description) + info.SetCopyright(application.copyright) + info.SetTranslators(application.translators) # info.SetLicence(application.licence) - for i in application.authors: - info.AddDeveloper(i) - wx.adv.AboutBox(info) + for i in application.authors: + info.AddDeveloper(i) + wx.adv.AboutBox(info) - def set_focus(self): - self.SetFocus() + def set_focus(self): + self.SetFocus() - def check_menuitem(self, menuitem, check=True): - if hasattr(self, menuitem): - getattr(self, menuitem).Check(check) + def check_menuitem(self, menuitem, check=True): + if hasattr(self, menuitem): + getattr(self, menuitem).Check(check) - def set_page_title(self, page, title): - return self.nb.SetPageText(page, title) + def set_page_title(self, page, title): + return self.nb.SetPageText(page, title) - def get_page_title(self, page): - return self.nb.GetPageText(page) + def get_page_title(self, page): + return self.nb.GetPageText(page) def no_update_available(): - wx.MessageDialog(None, _(u"Your {0} version is up to date").format(application.name,), _(u"Update"), style=wx.OK).ShowModal() + wx.MessageDialog(None, _(u"Your {0} version is up to date").format(application.name,), _(u"Update"), style=wx.OK).ShowModal() diff --git a/tools/pygettext.py b/tools/pygettext.py index bb0dd35d..b46dd339 100644 --- a/tools/pygettext.py +++ b/tools/pygettext.py @@ -1,6 +1,6 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 # -*- coding: iso-8859-1 -*- -# Originally written by Barry Warsaw +# Originally written by Barry Warsaw # # Minimally patched to make it even more xgettext compatible # by Peter Funk @@ -156,14 +156,14 @@ If `inputfile' is -, standard input is read. """) import os -import imp +import importlib.machinery +import importlib.util import sys import glob import time import getopt import token import tokenize -import operator __version__ = '1.5' @@ -189,50 +189,51 @@ msgstr "" "Last-Translator: FULL NAME \\n" "Language-Team: LANGUAGE \\n" "MIME-Version: 1.0\\n" -"Content-Type: text/plain; charset=CHARSET\\n" -"Content-Transfer-Encoding: ENCODING\\n" +"Content-Type: text/plain; charset=%(charset)s\\n" +"Content-Transfer-Encoding: %(encoding)s\\n" "Generated-By: pygettext.py %(version)s\\n" ''') def usage(code, msg=''): - print >> sys.stderr, __doc__ % globals() + print(__doc__ % globals(), file=sys.stderr) if msg: - print >> sys.stderr, msg + print(msg, file=sys.stderr) sys.exit(code) -escapes = [] - -def make_escapes(pass_iso8859): - global escapes - if pass_iso8859: - # Allow iso-8859 characters to pass through so that e.g. 'msgid +def make_escapes(pass_nonascii): + global escapes, escape + if pass_nonascii: + # Allow non-ascii characters to pass through so that e.g. 'msgid # "Hhe"' would result not result in 'msgid "H\366he"'. Otherwise we # escape any character outside the 32..126 range. mod = 128 + escape = escape_ascii else: mod = 256 - for i in range(256): - if 32 <= (i % mod) <= 126: - escapes.append(chr(i)) - else: - escapes.append("\\%03o" % i) - escapes[ord('\\')] = '\\\\' - escapes[ord('\t')] = '\\t' - escapes[ord('\r')] = '\\r' - escapes[ord('\n')] = '\\n' - escapes[ord('\"')] = '\\"' + escape = escape_nonascii + escapes = [r"\%03o" % i for i in range(mod)] + for i in range(32, 127): + escapes[i] = chr(i) + escapes[ord('\\')] = r'\\' + escapes[ord('\t')] = r'\t' + escapes[ord('\r')] = r'\r' + escapes[ord('\n')] = r'\n' + escapes[ord('\"')] = r'\"' -def escape(s): - global escapes - s = list(s) - for i in range(len(s)): - s[i] = escapes[ord(s[i])] - return EMPTYSTRING.join(s) +def escape_ascii(s, encoding): + return ''.join(escapes[ord(c)] if ord(c) < 128 else c for c in s) + +def escape_nonascii(s, encoding): + return ''.join(escapes[b] for b in s.encode(encoding)) + + +def is_literal_string(s): + return s[0] in '\'"' or (s[0] in 'rRuU' and s[1] in '\'"') def safe_eval(s): @@ -240,18 +241,18 @@ def safe_eval(s): return eval(s, {'__builtins__':{}}, {}) -def normalize(s): +def normalize(s, encoding): # This converts the various Python string types into a format that is # appropriate for .po files, namely much closer to C style. lines = s.split('\n') if len(lines) == 1: - s = '"' + escape(s) + '"' + s = '"' + escape(s, encoding) + '"' else: if not lines[-1]: del lines[-1] lines[-1] = lines[-1] + '\n' for i in range(len(lines)): - lines[i] = escape(lines[i]) + lines[i] = escape(lines[i], encoding) lineterm = '\\n"\n"' s = '""\n"' + lineterm.join(lines) + '"' return s @@ -262,64 +263,6 @@ def containsAny(str, set): return 1 in [c in str for c in set] -def _visit_pyfiles(list, dirname, names): - """Helper for getFilesForName().""" - # get extension for python source files - if not globals().has_key('_py_ext'): - global _py_ext - _py_ext = [triple[0] for triple in imp.get_suffixes() - if triple[2] == imp.PY_SOURCE][0] - - # don't recurse into CVS directories - if 'CVS' in names: - names.remove('CVS') - - # add all *.py files to list - list.extend( - [os.path.join(dirname, file) for file in names - if os.path.splitext(file)[1] == _py_ext] - ) - - -def _get_modpkg_path(dotted_name, pathlist=None): - """Get the filesystem path for a module or a package. - - Return the file system path to a file for a module, and to a directory for - a package. Return None if the name is not found, or is a builtin or - extension module. - """ - # split off top-most name - parts = dotted_name.split('.', 1) - - if len(parts) > 1: - # we have a dotted path, import top-level package - try: - file, pathname, description = imp.find_module(parts[0], pathlist) - if file: file.close() - except ImportError: - return None - - # check if it's indeed a package - if description[2] == imp.PKG_DIRECTORY: - # recursively handle the remaining name parts - pathname = _get_modpkg_path(parts[1], [pathname]) - else: - pathname = None - else: - # plain name - try: - file, pathname, description = imp.find_module( - dotted_name, pathlist) - if file: - file.close() - if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]: - pathname = None - except ImportError: - pathname = None - - return pathname - - def getFilesForName(name): """Get a list of module files for a filename, a module or package name, or a directory. @@ -334,14 +277,28 @@ def getFilesForName(name): return list # try to find module or package - name = _get_modpkg_path(name) + try: + spec = importlib.util.find_spec(name) + name = spec.origin + except ImportError: + name = None if not name: return [] if os.path.isdir(name): # find all python files in directory list = [] - os.path.walk(name, _visit_pyfiles, list) + # get extension for python source files + _py_ext = importlib.machinery.SOURCE_SUFFIXES[0] + for root, dirs, files in os.walk(name): + # don't recurse into CVS directories + if 'CVS' in dirs: + dirs.remove('CVS') + # add all *.py files to list + list.extend( + [os.path.join(root, file) for file in files + if os.path.splitext(file)[1] == _py_ext] + ) return list elif os.path.exists(name): # a single file @@ -359,12 +316,13 @@ class TokenEater: self.__lineno = -1 self.__freshmodule = 1 self.__curfile = None + self.__enclosurecount = 0 def __call__(self, ttype, tstring, stup, etup, line): # dispatch ## import token -## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \ -## 'tstring:', tstring +## print('ttype:', token.tok_name[ttype], 'tstring:', tstring, +## file=sys.stderr) self.__state(ttype, tstring, stup[0]) def __waiting(self, ttype, tstring, lineno): @@ -373,13 +331,13 @@ class TokenEater: if opts.docstrings and not opts.nodocstrings.get(self.__curfile): # module docstring? if self.__freshmodule: - if ttype == tokenize.STRING: + if ttype == tokenize.STRING and is_literal_string(tstring): self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__freshmodule = 0 elif ttype not in (tokenize.COMMENT, tokenize.NL): self.__freshmodule = 0 return - # class docstring? + # class or func/method docstring? if ttype == tokenize.NAME and tstring in ('class', 'def'): self.__state = self.__suiteseen return @@ -387,13 +345,19 @@ class TokenEater: self.__state = self.__keywordseen def __suiteseen(self, ttype, tstring, lineno): - # ignore anything until we see the colon - if ttype == tokenize.OP and tstring == ':': - self.__state = self.__suitedocstring + # skip over any enclosure pairs until we see the colon + if ttype == tokenize.OP: + if tstring == ':' and self.__enclosurecount == 0: + # we see a colon and we're not in an enclosure: end of def + self.__state = self.__suitedocstring + elif tstring in '([{': + self.__enclosurecount += 1 + elif tstring in ')]}': + self.__enclosurecount -= 1 def __suitedocstring(self, ttype, tstring, lineno): # ignore any intervening noise - if ttype == tokenize.STRING: + if ttype == tokenize.STRING and is_literal_string(tstring): self.__addentry(safe_eval(tstring), lineno, isdocstring=1) self.__state = self.__waiting elif ttype not in (tokenize.NEWLINE, tokenize.INDENT, @@ -418,18 +382,18 @@ class TokenEater: if self.__data: self.__addentry(EMPTYSTRING.join(self.__data)) self.__state = self.__waiting - elif ttype == tokenize.STRING: + elif ttype == tokenize.STRING and is_literal_string(tstring): self.__data.append(safe_eval(tstring)) elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT, token.NEWLINE, tokenize.NL]: # warn if we see anything else than STRING or whitespace - print >> sys.stderr, _( + print(_( '*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"' ) % { 'token': tstring, 'file': self.__curfile, 'lineno': self.__lineno - } + }, file=sys.stderr) self.__state = self.__waiting def __addentry(self, msg, lineno=None, isdocstring=0): @@ -445,45 +409,41 @@ class TokenEater: def write(self, fp): options = self.__options - timestamp = time.strftime('%Y-%m-%d %H:%M+%Z') - # The time stamp in the header doesn't have the same format as that - # generated by xgettext... - print >> fp, pot_header % {'time': timestamp, 'version': __version__} + timestamp = time.strftime('%Y-%m-%d %H:%M%z') + encoding = fp.encoding if fp.encoding else 'UTF-8' + print(pot_header % {'time': timestamp, 'version': __version__, + 'charset': encoding, + 'encoding': '8bit'}, file=fp) # Sort the entries. First sort each particular entry's keys, then # sort all the entries by their first item. reverse = {} for k, v in self.__messages.items(): - keys = v.keys() - keys.sort() + keys = sorted(v.keys()) reverse.setdefault(tuple(keys), []).append((k, v)) - rkeys = reverse.keys() - rkeys.sort() + rkeys = sorted(reverse.keys()) for rkey in rkeys: rentries = reverse[rkey] rentries.sort() for k, v in rentries: - isdocstring = 0 # If the entry was gleaned out of a docstring, then add a # comment stating so. This is to aid translators who may wish # to skip translating some unimportant docstrings. - if reduce(operator.__add__, v.values()): - isdocstring = 1 + isdocstring = any(v.values()) # k is the message string, v is a dictionary-set of (filename, # lineno) tuples. We want to sort the entries in v first by # file name and then by line number. - v = v.keys() - v.sort() + v = sorted(v.keys()) if not options.writelocations: pass # location comments are different b/w Solaris and GNU: elif options.locationstyle == options.SOLARIS: for filename, lineno in v: d = {'filename': filename, 'lineno': lineno} - print >>fp, _( - '# File: %(filename)s, line: %(lineno)d') % d + print(_( + '# File: %(filename)s, line: %(lineno)d') % d, file=fp) elif options.locationstyle == options.GNU: # fit as many locations on one line, as long as the - # resulting line length doesn't exceeds 'options.width' + # resulting line length doesn't exceed 'options.width' locline = '#:' for filename, lineno in v: d = {'filename': filename, 'lineno': lineno} @@ -491,14 +451,14 @@ class TokenEater: if len(locline) + len(s) <= options.width: locline = locline + s else: - print >> fp, locline + print(locline, file=fp) locline = "#:" + s if len(locline) > 2: - print >> fp, locline + print(locline, file=fp) if isdocstring: - print >> fp, '#, docstring' - print >> fp, 'msgid', normalize(k) - print >> fp, 'msgstr ""\n' + print('#, docstring', file=fp) + print('msgid', normalize(k, encoding), file=fp) + print('msgstr ""\n', file=fp) @@ -514,7 +474,7 @@ def main(): 'style=', 'verbose', 'version', 'width=', 'exclude-file=', 'docstrings', 'no-docstrings', ]) - except getopt.error, msg: + except getopt.error as msg: usage(1, msg) # for holding option values @@ -572,7 +532,7 @@ def main(): elif opt in ('-v', '--verbose'): options.verbose = 1 elif opt in ('-V', '--version'): - print _('pygettext.py (xgettext for Python) %s') % __version__ + print(_('pygettext.py (xgettext for Python) %s') % __version__) sys.exit(0) elif opt in ('-w', '--width'): try: @@ -593,7 +553,7 @@ def main(): fp.close() # calculate escapes - make_escapes(options.escape) + make_escapes(not options.escape) # calculate all keywords options.keywords.extend(default_keywords) @@ -605,8 +565,8 @@ def main(): options.toexclude = fp.readlines() fp.close() except IOError: - print >> sys.stderr, _( - "Can't read --exclude-file: %s") % options.excludefilename + print(_( + "Can't read --exclude-file: %s") % options.excludefilename, file=sys.stderr) sys.exit(1) else: options.toexclude = [] @@ -625,21 +585,24 @@ def main(): for filename in args: if filename == '-': if options.verbose: - print _('Reading standard input') - fp = sys.stdin + print(_('Reading standard input')) + fp = sys.stdin.buffer closep = 0 else: if options.verbose: - print _('Working on %s') % filename - fp = open(filename) + print(_('Working on %s') % filename) + fp = open(filename, 'rb') closep = 1 try: eater.set_filename(filename) try: - tokenize.tokenize(fp.readline, eater) - except tokenize.TokenError, e: - print >> sys.stderr, '%s: %s, line %d, column %d' % ( - e[0], filename, e[1][0], e[1][1]) + tokens = tokenize.tokenize(fp.readline) + for _token in tokens: + eater(*_token) + except tokenize.TokenError as e: + print('%s: %s, line %d, column %d' % ( + e.args[0], filename, e.args[1][0], e.args[1][1]), + file=sys.stderr) finally: if closep: fp.close() @@ -663,7 +626,6 @@ def main(): if __name__ == '__main__': main() # some more test strings - _(u'a unicode string') # this one creates a warning _('*** Seen unexpected token "%(token)s"') % {'token': 'test'} _('more' 'than' 'one' 'string') diff --git a/updates/snapshots.json b/updates/snapshots.json deleted file mode 100644 index 6fdd3182..00000000 --- a/updates/snapshots.json +++ /dev/null @@ -1,5 +0,0 @@ -{"current_version": "3", -"description": "Snapshot version.", -"date": "unknown", -"downloads": -{"Windows32": "https://twblue.es/pubs/snapshot.zip"}} \ No newline at end of file diff --git a/updates/stable.json b/updates/stable.json deleted file mode 100644 index ef63523b..00000000 --- a/updates/stable.json +++ /dev/null @@ -1,6 +0,0 @@ -{"current_version": "0.95", -"description": "The first version for the new generation of TWBlue.", -"date": "day_name_abr month day_numb, 2016", -"downloads": -{"Windows32": "http://twblue.es/pubs/twblue_ngen_0.80_x86.zip", -"Windows64": "http://twblue.es/pubs/twblue_ngen_0.80_x64.zip"}} \ No newline at end of file diff --git a/updates/updates.json b/updates/updates.json new file mode 100644 index 00000000..ad94bf92 --- /dev/null +++ b/updates/updates.json @@ -0,0 +1,7 @@ +{"current_version": "11", +"description": "Snapshot version.", +"date": "unknown", +"downloads": +{"Windows32": "https://twblue.es/pubs/twblue_snapshot_x86.zip", +{"Windows64": "https://twblue.es/pubs/twblue_snapshot_x64.zip" +} \ No newline at end of file diff --git a/windows-dependencies b/windows-dependencies index 27d86088..1ee41752 160000 --- a/windows-dependencies +++ b/windows-dependencies @@ -1 +1 @@ -Subproject commit 27d860885f8f3bf9246364f69fc66d79b7412680 +Subproject commit 1ee4175276e8dcb04c23cd0b76ff516d5986c698