diff --git a/CMakeLists.txt b/CMakeLists.txt index 934dfae..8518091 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,15 @@ cmake_minimum_required(VERSION 3.0) project(squawk) -# Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Instruct CMake to run moc automatically when needed. -set(CMAKE_AUTOMOC ON) -# Instruct CMake to create code from Qt designer ui files -set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) find_package(Qt5Widgets CONFIG REQUIRED) +find_package(Qt5LinguistTools) + set(squawk_SRC main.cpp global.cpp @@ -18,7 +17,15 @@ set(squawk_SRC signalcatcher.cpp ) -add_executable(squawk ${squawk_SRC} resources/resources.qrc) +set(TS_FILES + translations/squawk.ru.ts +) +qt5_add_translation(QM_FILES ${TS_FILES}) +add_custom_target(translations ALL DEPENDS ${QM_FILES}) + +qt5_add_resources(RCC resources/resources.qrc) + +add_executable(squawk ${squawk_SRC} ${RCC}) target_link_libraries(squawk Qt5::Widgets) add_subdirectory(ui) @@ -29,5 +36,8 @@ target_link_libraries(squawk squawkUI) target_link_libraries(squawk squawkCORE) target_link_libraries(squawk uuid) +add_dependencies(${CMAKE_PROJECT_NAME} translations) + # Install the executable install(TARGETS squawk DESTINATION bin) +install(FILES ${QM_FILES} DESTINATION share/l10n) diff --git a/core/archive.cpp b/core/archive.cpp index 9615914..00139ac 100644 --- a/core/archive.cpp +++ b/core/archive.cpp @@ -57,7 +57,7 @@ void Core::Archive::open(const QString& account) } mdb_env_set_maxdbs(environment, 4); - mdb_env_set_mapsize(environment, 1UL * 1024UL * 1024UL * 1024UL); + mdb_env_set_mapsize(environment, 512UL * 1024UL * 1024UL); mdb_env_open(environment, path.toStdString().c_str(), 0, 0664); MDB_txn *txn; diff --git a/global.h b/global.h index 5a8c902..77f89bf 100644 --- a/global.h +++ b/global.h @@ -20,6 +20,7 @@ #define GLOBAL_H #include +#include #include #include #include @@ -99,7 +100,6 @@ static const std::deque subscriptionStateNames = {"None", "From", "To", static const std::deque affiliationNames = {"Unspecified", "Outcast", "Nobody", "Member", "Admin", "Owner"}; static const std::deque roleNames = {"Unspecified", "Nobody", "Visitor", "Participant", "Moderator"}; - QString generateUUID(); class Message { diff --git a/main.cpp b/main.cpp index cbe8067..2b1b53e 100644 --- a/main.cpp +++ b/main.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include int main(int argc, char *argv[]) { @@ -36,7 +38,15 @@ int main(int argc, char *argv[]) QCoreApplication::setOrganizationName("Macaw"); QCoreApplication::setOrganizationDomain("macaw.me"); QCoreApplication::setApplicationName("Squawk"); - QCoreApplication::setApplicationVersion("0.0.3"); + QCoreApplication::setApplicationVersion("0.0.4"); + + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + app.installTranslator(&qtTranslator); + + QTranslator myappTranslator; + myappTranslator.load(QLocale(), QLatin1String("squawk"), "."); + app.installTranslator(&myappTranslator); QIcon icon; icon.addFile(":images/logo.svg", QSize(16, 16)); diff --git a/translations/main.ts b/translations/main.ts new file mode 100644 index 0000000..e655a2b --- /dev/null +++ b/translations/main.ts @@ -0,0 +1,283 @@ + + + + + Account + + + + Account + + + + + + Your account login + + + + + + Server + + + + + + A server address of your account. Like 404.city or macaw.me + + + + + + Login + + + + + + Password + + + + + + Password of your account + + + + + + Name + + + + + + Just a name how would you call this account, doesn't affect anything + + + + + + Resource + + + + + + A resource name like "Home" or "Work" + + + + + + QXmpp + + + + + Accounts + + + + Accounts + + + + + + Delete + + + + + + Add + + + + + + Edit + + + + + + Change password + + + + + + Connect + + + + + JoinConference + + + + Join new conference + + + + + + JID + + + + + + Room JID + + + + + + identifier@conference.server.org + + + + + + Account + + + + + + Join on login + + + + + + If checked Squawk will try to join this conference on login + + + + + + Nick name + + + + + + Your nick name for that conference. If you leave this field empty your account name will be used as a nick name + + + + + + John + + + + + NewContact + + + + Add new contact + + + + + + Account + + + + + + An account that is going to have new contact + + + + + + JID + + + + + + Jabber id of your new contact + + + + + + name@server.dmn + + + + + + Name + + + + + + The way this new contact will be labeled in your roster (optional) + + + + + + John Smith + + + + + Squawk + + + + squawk + + + + + + Settings + + + + + + Squawk + + + + + + Accounts + + + + + + Quit + + + + + + Add contact + + + + + + Add conference + + + + diff --git a/translations/main_ru.qm b/translations/main_ru.qm new file mode 100644 index 0000000..a0d42b2 Binary files /dev/null and b/translations/main_ru.qm differ diff --git a/translations/main_ru.qph b/translations/main_ru.qph new file mode 100644 index 0000000..5ae047d --- /dev/null +++ b/translations/main_ru.qph @@ -0,0 +1,22 @@ + + + + Add contact + Добавить контакт + Opens add contact dialog + + + Add conference + Присоединиться к беседе + Opens a dialog to join conference + + + Quit + Выйти + Quits the application + + + Account + Учетная запись + + diff --git a/translations/main_ru.ts b/translations/main_ru.ts new file mode 100644 index 0000000..c1b218a --- /dev/null +++ b/translations/main_ru.ts @@ -0,0 +1,288 @@ + + + + + Account + + + + Account + Заголовок окна + Учетная запись + + + + + Your account login + Имя пользователя Вашей учетной записи + + + + + Server + Сервер + + + + + A server address of your account. Like 404.city or macaw.me + Адресс сервера вашей учетной записи (выглядит как 404.city или macaw.me) + + + + + Login + Имя учетной записи + + + + + Password + Пароль + + + + + Password of your account + Пароль вашей учетной записи + + + + + Name + Имя + + + + + Just a name how would you call this account, doesn't affect anything + Просто имя, то как Вы называете свою учетную запись, может быть любым + + + + + Resource + Ресурс + + + + + A resource name like "Home" or "Work" + Имя этой программы для ваших контактов, может быть "Home" или "Phone" + + + + + QXmpp + Ресурс по умолчанию + QXmpp + + + + Accounts + + + + Accounts + Учетные записи + + + + + Delete + Удалить + + + + + Add + Добавить + + + + + Edit + Редактировать + + + + + Change password + Изменить пароль + + + + + Connect + Подключить + + + + JoinConference + + + + Join new conference + Заголовок окна + Присоединиться к новой беседе + + + + + JID + JID + + + + + Room JID + Jabber-идентификатор беседы + + + + + identifier@conference.server.org + + + + + + Account + + + + + + Join on login + + + + + + If checked Squawk will try to join this conference on login + + + + + + Nick name + + + + + + Your nick name for that conference. If you leave this field empty your account name will be used as a nick name + + + + + + John + + + + + NewContact + + + + Add new contact + Заголовок окна + Добавление нового контакта + + + + + Account + Учетная запись + + + + + An account that is going to have new contact + Учетная запись для которой будет добавлен контакт + + + + + JID + JID + + + + + Jabber id of your new contact + Jabber-идентификатор нового контакта + + + + + name@server.dmn + Placeholder поля ввода JID + name@server.dmn + + + + + Name + Имя + + + + + The way this new contact will be labeled in your roster (optional) + То, как будет подписан контакт в вашем списке контактов (не обязательно) + + + + + John Smith + Иван Иванов + + + + Squawk + + + + squawk + Squawk + + + + + Settings + Настройки + + + + + Squawk + Squawk + + + + + Accounts + Учетные записи + + + + + Quit + Выйти + + + + + Add contact + Добавить контакт + + + + + Add conference + Присоединиться к беседе + + + diff --git a/translations/squawk.ru.ts b/translations/squawk.ru.ts new file mode 100644 index 0000000..bb1fdef --- /dev/null +++ b/translations/squawk.ru.ts @@ -0,0 +1,639 @@ + + + + + Account + + + + Account + Заголовок окна + Учетная запись + + + + + Your account login + Имя пользователя Вашей учетной записи + + + + + john_smith1987 + ivan_ivanov1987 + + + + + Server + Сервер + + + + + A server address of your account. Like 404.city or macaw.me + Адресс сервера вашей учетной записи (выглядит как 404.city или macaw.me) + + + + + macaw.me + macaw.me + + + + + Login + Имя учетной записи + + + + + Password + Пароль + + + + + Password of your account + Пароль вашей учетной записи + + + + + Name + Имя + + + + + Just a name how would you call this account, doesn't affect anything + Просто имя, то как Вы называете свою учетную запись, может быть любым + + + + + John + Иван + + + + + Resource + Ресурс + + + + + A resource name like "Home" or "Work" + Имя этой программы для ваших контактов, может быть "Home" или "Phone" + + + + + QXmpp + Ресурс по умолчанию + QXmpp + + + + Accounts + + + + Accounts + Учетные записи + + + + + Delete + Удалить + + + + + Add + Добавить + + + + + Edit + Редактировать + + + + + Change password + Изменить пароль + + + + + + + Connect + Подключить + + + + Disconnect + Отключить + + + + Conversation + + + + Type your message here... + Введите сообщение... + + + + Global + + Disconnected + Отключен + + + Connecting + Подключается + + + Connected + Подключен + + + Error + Ошибка + + + Online + В сети + + + Away + Отошел + + + Busy + Занят + + + Absent + Недоступен + + + Chatty + Готов поболтать + + + Invisible + Невидимый + + + Offline + Отключен + + + None + Нет + + + From + Входящая + + + To + Исходящая + + + Both + Взаимная + + + Unknown + Неизвестно + + + Unspecified + Не назначено + + + Outcast + Изгой + + + Nobody + Никто + + + Member + Участник + + + Admin + Администратор + + + Owner + Владелец + + + Visitor + Гость + + + Participant + Участник + + + Moderator + Модератор + + + + JoinConference + + + + Join new conference + Заголовок окна + Присоединиться к новой беседе + + + + + JID + JID + + + + + Room JID + Jabber-идентификатор беседы + + + + + identifier@conference.server.org + identifier@conference.server.org + + + + + Account + Учетная запись + + + + + Join on login + Автовход + + + + + If checked Squawk will try to join this conference on login + Если стоит галочка Squawk автоматически присоединится к этой беседе при подключении + + + + + Nick name + Псевдоним + + + + + Your nick name for that conference. If you leave this field empty your account name will be used as a nick name + Ваш псевдоним в этой беседе, если оставите это поле пустым - будет использовано имя Вашей учетной записи + + + + + John + Ivan + + + + Message + + + Download + Скачать + + + + Error downloading file: %1 +You can try again + Ошибка загрузки файла: %1 +Вы можете попробовать снова + + + + %1 is offering you to download a file + %1 предлагает Вам скачать файл + + + + Open + Открыть + + + + Models::Accounts + + Name + Имя + + + Server + Сервер + + + State + Состояние + + + Error + Ошибка + + + + Models::Room + + + Subscribed + Вы состоите в беседе + + + + Temporarily unsubscribed + Вы временно не состоите в беседе + + + + Temporarily subscribed + Вы временно состоите в беседе + + + + Unsubscribed + Вы не состоите в беседе + + + + Models::Roster + + + New messages + Есть непрочитанные сообщения + + + + + + + New messages: + Новых сообщений: + + + + Jabber ID: + Идентификатор: + + + + + + Availability: + Доступность: + + + + + + Status: + Статус: + + + + + + Subscription: + Подписка: + + + + Affiliation: + Я правда не знаю, как это объяснить, не то что перевести + Причастность: + + + + Role: + Роль: + + + + Online contacts: + Контакстов в сети: + + + + Total contacts: + Всего контактов: + + + + Members: + Участников: + + + + NewContact + + + + Add new contact + Заголовок окна + Добавление нового контакта + + + + + Account + Учетная запись + + + + + An account that is going to have new contact + Учетная запись для которой будет добавлен контакт + + + + + JID + JID + + + + + Jabber id of your new contact + Jabber-идентификатор нового контакта + + + + + name@server.dmn + Placeholder поля ввода JID + name@server.dmn + + + + + Name + Имя + + + + + The way this new contact will be labeled in your roster (optional) + То, как будет подписан контакт в вашем списке контактов (не обязательно) + + + + + John Smith + Иван Иванов + + + + Squawk + + + + squawk + Squawk + + + + + Settings + Настройки + + + + + Squawk + Squawk + + + + + Accounts + Учетные записи + + + + + Quit + Выйти + + + + + Add contact + Добавить контакт + + + + + Add conference + Присоединиться к беседе + + + + Disconnect + Отключить + + + + Connect + Подключить + + + + + + Remove + Удалить + + + + Open dialog + Открыть диалог + + + + + Unsubscribe + Отписаться + + + + + Subscribe + Подписаться + + + + Rename + Переименовать + + + + Input new name for %1 +or leave it empty for the contact +to be displayed as %1 + Введите имя для %1 +или оставьте пустым, +тогда контакт будет отображаться как +%1 + + + + Renaming %1 + Назначение имени контакту %1 + + + + Groups + Группы + + + + New group + Создать новую группу + + + + New group name + Имя группы + + + + Add %1 to a new group + Добавление %1 в новую группу + + + + Open conversation + Открыть окно беседы + + + diff --git a/ui/models/account.cpp b/ui/models/account.cpp index 56a7806..b8758c2 100644 --- a/ui/models/account.cpp +++ b/ui/models/account.cpp @@ -151,7 +151,7 @@ QVariant Models::Account::data(int column) const case 1: return server; case 2: - return Shared::connectionStateNames[state]; + return QCoreApplication::translate("Global", Shared::connectionStateNames[state].toLatin1()); case 3: return error; case 4: @@ -159,7 +159,7 @@ QVariant Models::Account::data(int column) const case 5: return password; case 6: - return Shared::availabilityNames[availability]; + return QCoreApplication::translate("Global", Shared::availabilityNames[availability].toLatin1()); case 7: return resource; default: diff --git a/ui/models/accounts.cpp b/ui/models/accounts.cpp index 6a62376..b7f16ef 100644 --- a/ui/models/accounts.cpp +++ b/ui/models/accounts.cpp @@ -20,13 +20,9 @@ #include "../../global.h" #include +#include -std::deque Models::Accounts::columns = { - "name", - "server", - "state", - "error" -}; +std::deque Models::Accounts::columns = {"Name", "Server", "State", "Error"}; Models::Accounts::Accounts(QObject* parent): QAbstractTableModel(parent), @@ -72,7 +68,7 @@ int Models::Accounts::rowCount ( const QModelIndex& parent ) const QVariant Models::Accounts::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { - return columns[section]; + return tr(columns[section].toLatin1()); } return QVariant(); } @@ -81,7 +77,18 @@ QVariant Models::Accounts::headerData(int section, Qt::Orientation orientation, void Models::Accounts::addAccount(Account* account) { beginInsertRows(QModelIndex(), accs.size(), accs.size()); - accs.push_back(account); + int index = 0; + std::deque::const_iterator before = accs.begin(); + while (before != accs.end()) { + Account* bfr = *before; + if (bfr->getDisplayedName() > account->getDisplayedName()) { + break; + } + index++; + before++; + } + + accs.insert(before, account); connect(account, SIGNAL(childChanged(Models::Item*, int, int)), this, SLOT(onAccountChanged(Models::Item*, int, int))); endInsertRows(); @@ -96,8 +103,32 @@ void Models::Accounts::onAccountChanged(Item* item, int row, int col) return; //it means the signal is emitted by one of accounts' children, not exactly him, this model has no interest in that } + if (col == 0) { + int newRow = 0; + std::deque::const_iterator before = accs.begin(); + while (before != accs.end()) { + Item* bfr = *before; + if (bfr->getDisplayedName() > item->getDisplayedName()) { + break; + } + newRow++; + before++; + } + + if (newRow != row || (before != accs.end() && *before != item)) { + emit beginMoveRows(createIndex(row, 0), row, row, createIndex(newRow, 0), newRow); + std::deque::const_iterator old = accs.begin(); + old += row; + accs.erase(old); + accs.insert(before, acc); + emit endMoveRows(); + + row = newRow; + } + } + if (col < columnCount(QModelIndex())) { - emit dataChanged(createIndex(row, col, this), createIndex(row, col, this)); + emit dataChanged(createIndex(row, col), createIndex(row, col)); } emit changed(); } diff --git a/ui/models/room.cpp b/ui/models/room.cpp index 1752696..6addead 100644 --- a/ui/models/room.cpp +++ b/ui/models/room.cpp @@ -193,15 +193,15 @@ QString Models::Room::getStatusText() const { if (autoJoin) { if (joined) { - return "Subscribed"; + return tr("Subscribed"); } else { - return "Temporarily unsubscribed"; + return tr("Temporarily unsubscribed"); } } else { if (joined) { - return "Temporarily subscribed"; + return tr("Temporarily subscribed"); } else { - return "Unsubscribed"; + return tr("Unsubscribed"); } } } diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 79b0d03..f252583 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -21,8 +21,6 @@ #include #include -using namespace Models; - Models::Roster::Roster(QObject* parent): QAbstractItemModel(parent), accountsModel(new Accounts()), @@ -78,7 +76,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const str += gr->getName(); unsigned int amount = gr->getUnreadMessages(); if (amount > 0) { - str += QString(" (") + "New messages" + ")"; + str += QString(" (") + tr("New messages") + ")"; } result = str; @@ -143,7 +141,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const switch (item->type) { case Item::account: { Account* acc = static_cast(item); - result = QString(Shared::availabilityNames[acc->getAvailability()]); + result = QCoreApplication::translate("Global", Shared::availabilityNames[acc->getAvailability()].toLatin1()); } break; case Item::contact: { @@ -151,22 +149,22 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const QString str(""); int mc = contact->getMessagesCount(); if (mc > 0) { - str += QString("New messages: ") + std::to_string(mc).c_str() + "\n"; + str += QString(tr("New messages: ")) + std::to_string(mc).c_str() + "\n"; } - str += "Jabber ID: " + contact->getJid() + "\n"; + str += tr("Jabber ID: ") + contact->getJid() + "\n"; Shared::SubscriptionState ss = contact->getState(); if (ss == Shared::both) { Shared::Availability av = contact->getAvailability(); - str += "Availability: " + Shared::availabilityNames[av]; + str += tr("Availability: ") + QCoreApplication::translate("Global", Shared::availabilityNames[av].toLatin1()); if (av != Shared::offline) { QString s = contact->getStatus(); if (s.size() > 0) { - str += "\nStatus: " + s; + str += "\n" + tr("Status: ") + s; } } - str += "\nSubscription: " + Shared::subscriptionStateNames[ss]; + str += "\n" + tr("Subscription: ") + QCoreApplication::translate("Global", Shared::subscriptionStateNames[ss].toLatin1()); } else { - str += "Subscription: " + Shared::subscriptionStateNames[ss]; + str += tr("Subscription: ") + QCoreApplication::translate("Global", Shared::subscriptionStateNames[ss].toLatin1()); } result = str; @@ -177,13 +175,13 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const QString str(""); int mc = contact->getMessagesCount(); if (mc > 0) { - str += QString("New messages: ") + std::to_string(mc).c_str() + "\n"; + str += tr("New messages: ") + std::to_string(mc).c_str() + "\n"; } Shared::Availability av = contact->getAvailability(); - str += "Availability: " + Shared::availabilityNames[av]; + str += tr("Availability: ") + QCoreApplication::translate("Global", Shared::availabilityNames[av].toLatin1()); QString s = contact->getStatus(); if (s.size() > 0) { - str += "\nStatus: " + s; + str += "\n" + tr("Status: ") + s; } result = str; @@ -193,14 +191,18 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const Participant* p = static_cast(item); QString str(""); Shared::Availability av = p->getAvailability(); - str += "Availability: " + Shared::availabilityNames[av] + "\n"; + str += tr("Availability: ") + QCoreApplication::translate("Global", Shared::availabilityNames[av].toLatin1()) + "\n"; QString s = p->getStatus(); if (s.size() > 0) { - str += "Status: " + s + "\n"; + str += tr("Status: ") + s + "\n"; } - str += "Affiliation: " + Shared::affiliationNames[static_cast(p->getAffiliation())] + "\n"; - str += "Role: " + Shared::roleNames[static_cast(p->getRole())]; + str += tr("Affiliation: ") + + QCoreApplication::translate("Global", + Shared::affiliationNames[static_cast(p->getAffiliation())].toLatin1()) + "\n"; + str += tr("Role: ") + + QCoreApplication::translate("Global", + Shared::roleNames[static_cast(p->getRole())].toLatin1()); result = str; } @@ -210,10 +212,10 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const unsigned int count = gr->getUnreadMessages(); QString str(""); if (count > 0) { - str += QString("New messages: ") + std::to_string(count).c_str() + "\n"; + str += tr("New messages: ") + std::to_string(count).c_str() + "\n"; } - str += QString("Online contacts: ") + std::to_string(gr->getOnlineContacts()).c_str() + "\n"; - str += QString("Total contacts: ") + std::to_string(gr->childCount()).c_str(); + str += tr("Online contacts: ") + std::to_string(gr->getOnlineContacts()).c_str() + "\n"; + str += tr("Total contacts: ") + std::to_string(gr->childCount()).c_str(); result = str; } break; @@ -222,11 +224,11 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const unsigned int count = rm->getUnreadMessagesCount(); QString str(""); if (count > 0) { - str += QString("New messages: ") + std::to_string(count).c_str() + "\n"; + str += tr("New messages: ") + std::to_string(count).c_str() + "\n"; } - str += QString("Subscription: ") + rm->getStatusText(); + str += tr("Subscription: ") + rm->getStatusText(); if (rm->getJoined()) { - str += QString("\nMembers: ") + std::to_string(rm->childCount()).c_str(); + str += QString("\n") + tr("Members: ") + std::to_string(rm->childCount()).c_str(); } result = str; } diff --git a/ui/squawk.cpp b/ui/squawk.cpp index 5c095e6..e382ebd 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -37,7 +37,7 @@ Squawk::Squawk(QWidget *parent) : for (unsigned int i = Shared::availabilityLowest; i < Shared::availabilityHighest + 1; ++i) { Shared::Availability av = static_cast(i); - m_ui->comboBox->addItem(Shared::availabilityIcon(av), Shared::availabilityNames[av]); + m_ui->comboBox->addItem(Shared::availabilityIcon(av), QCoreApplication::translate("Global", Shared::availabilityNames[av].toLatin1())); } m_ui->comboBox->setCurrentIndex(Shared::offline); @@ -526,20 +526,19 @@ void Squawk::onRosterContextMenu(const QPoint& point) QString name = acc->getName(); if (acc->getState() != Shared::disconnected) { - QAction* con = contextMenu->addAction(Shared::icon("network-disconnect"), "Disconnect"); + QAction* con = contextMenu->addAction(Shared::icon("network-disconnect"), tr("Disconnect")); con->setEnabled(active); connect(con, &QAction::triggered, [this, name]() { emit disconnectAccount(name); }); } else { - QAction* con = contextMenu->addAction(Shared::icon("network-connect"), "Connect"); - con->setEnabled(active); + QAction* con = contextMenu->addAction(Shared::icon("network-connect"), tr("Connect")); connect(con, &QAction::triggered, [this, name]() { emit connectAccount(name); }); } - QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); remove->setEnabled(active); connect(remove, &QAction::triggered, [this, name]() { emit removeAccount(name); @@ -551,7 +550,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) Models::Contact* cnt = static_cast(item); hasMenu = true; - QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), "Open dialog"); + QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), tr("Open dialog")); dialog->setEnabled(active); connect(dialog, &QAction::triggered, [this, index]() { onRosterItemDoubleClicked(index); @@ -561,7 +560,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) switch (state) { case Shared::both: case Shared::to: { - QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), "Unsubscribe"); + QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe")); unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, cnt]() { emit unsubscribeContact(cnt->getAccountName(), cnt->getJid(), ""); @@ -571,7 +570,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) case Shared::from: case Shared::unknown: case Shared::none: { - QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), "Subscribe"); + QAction* sub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe")); sub->setEnabled(active); connect(sub, &QAction::triggered, [this, cnt]() { emit subscribeContact(cnt->getAccountName(), cnt->getJid(), ""); @@ -582,7 +581,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) QString cntJID = cnt->getJid(); QString cntName = cnt->getName(); - QAction* rename = contextMenu->addAction(Shared::icon("edit-rename"), "Rename"); + QAction* rename = contextMenu->addAction(Shared::icon("edit-rename"), tr("Rename")); rename->setEnabled(active); connect(rename, &QAction::triggered, [this, cntName, accName, cntJID]() { QInputDialog* dialog = new QInputDialog(this); @@ -595,14 +594,14 @@ void Squawk::onRosterContextMenu(const QPoint& point) }); connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater); dialog->setInputMode(QInputDialog::TextInput); - dialog->setLabelText("Input new name for " + cntJID + " \nor leave it empty for the contact \nto be displayed as " + cntJID); - dialog->setWindowTitle("Renaming " + cntJID); + dialog->setLabelText(tr("Input new name for %1\nor leave it empty for the contact \nto be displayed as %1").arg(cntJID)); + dialog->setWindowTitle(tr("Renaming %1").arg(cntJID)); dialog->setTextValue(cntName); dialog->exec(); }); - QMenu* groupsMenu = contextMenu->addMenu(Shared::icon("group"), "Groups"); + QMenu* groupsMenu = contextMenu->addMenu(Shared::icon("group"), tr("Groups")); std::deque groupList = rosterModel.groupList(accName); for (QString groupName : groupList) { QAction* gr = groupsMenu->addAction(groupName); @@ -617,7 +616,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) } }); } - QAction* newGroup = groupsMenu->addAction(Shared::icon("resource-group-new"), "New group"); + QAction* newGroup = groupsMenu->addAction(Shared::icon("resource-group-new"), tr("New group")); newGroup->setEnabled(active); connect(newGroup, &QAction::triggered, [this, accName, cntJID]() { QInputDialog* dialog = new QInputDialog(this); @@ -627,13 +626,13 @@ void Squawk::onRosterContextMenu(const QPoint& point) }); connect(dialog, &QDialog::rejected, dialog, &QObject::deleteLater); dialog->setInputMode(QInputDialog::TextInput); - dialog->setLabelText("New group name"); - dialog->setWindowTitle("Add " + cntJID + " to a new group"); + dialog->setLabelText(tr("New group name")); + dialog->setWindowTitle(tr("Add %1 to a new group").arg(cntJID)); dialog->exec(); }); - QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); remove->setEnabled(active); connect(remove, &QAction::triggered, [this, cnt]() { emit removeContactRequest(cnt->getAccountName(), cnt->getJid()); @@ -645,7 +644,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) Models::Room* room = static_cast(item); hasMenu = true; - QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), "Open conversation"); + QAction* dialog = contextMenu->addAction(Shared::icon("mail-message"), tr("Open conversation")); dialog->setEnabled(active); connect(dialog, &QAction::triggered, [this, index]() { onRosterItemDoubleClicked(index); @@ -654,7 +653,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) Models::Roster::ElId id(room->getAccountName(), room->getJid()); if (room->getAutoJoin()) { - QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), "Unsubscribe"); + QAction* unsub = contextMenu->addAction(Shared::icon("news-unsubscribe"), tr("Unsubscribe")); unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, id]() { emit setRoomAutoJoin(id.account, id.name, false); @@ -663,7 +662,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) } }); } else { - QAction* unsub = contextMenu->addAction(Shared::icon("news-subscribe"), "Subscribe"); + QAction* unsub = contextMenu->addAction(Shared::icon("news-subscribe"), tr("Subscribe")); unsub->setEnabled(active); connect(unsub, &QAction::triggered, [this, id]() { emit setRoomAutoJoin(id.account, id.name, true); @@ -673,7 +672,7 @@ void Squawk::onRosterContextMenu(const QPoint& point) }); } - QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), "Remove"); + QAction* remove = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove")); remove->setEnabled(active); connect(remove, &QAction::triggered, [this, id]() { emit removeRoomRequest(id.account, id.name); diff --git a/ui/utils/message.cpp b/ui/utils/message.cpp index e5d4852..4c8debe 100644 --- a/ui/utils/message.cpp +++ b/ui/utils/message.cpp @@ -22,7 +22,7 @@ #include #include "message.h" -const QRegExp urlReg("^(?!setText(""); text->hide(); } - downloadButton = new QPushButton(QIcon::fromTheme("download"), "Download"); + downloadButton = new QPushButton(QIcon::fromTheme("download"), tr("Download")); downloadButton->setToolTip("" + msg.getOutOfBandUrl() + ""); if (errorDownloadingFile) { fileComment->setWordWrap(true); - fileComment->setText("Error downloading file: " + errorText + "\nYou can try again"); + fileComment->setText(tr("Error downloading file: %1\nYou can try again").arg(QCoreApplication::translate("NetworkErrors", errorText.toLatin1()))); } else { - fileComment->setText(sender->text() + " is offering you to download a file"); + fileComment->setText(tr("%1 is offering you to download a file").arg(sender->text())); } fileComment->show(); connect(downloadButton, SIGNAL(clicked()), this, SLOT(onDownload())); @@ -188,7 +188,7 @@ void Message::showFile(const QString& path) fileComment->show(); } file->setContextMenuPolicy(Qt::ActionsContextMenu); - QAction* openAction = new QAction(QIcon::fromTheme("document-new-from-template"), "Open", file); + QAction* openAction = new QAction(QIcon::fromTheme("document-new-from-template"), tr("Open"), file); connect(openAction, &QAction::triggered, [path]() { //TODO need to get rid of this shame QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }); diff --git a/ui/widgets/account.ui b/ui/widgets/account.ui index c9f9eb5..bfd0926 100644 --- a/ui/widgets/account.ui +++ b/ui/widgets/account.ui @@ -39,6 +39,9 @@ Your account login + + john_smith1987 + @@ -53,6 +56,9 @@ A server address of your account. Like 404.city or macaw.me + + macaw.me + @@ -83,6 +89,9 @@ QLineEdit::Password + + + false @@ -100,6 +109,9 @@ Just a name how would you call this account, doesn't affect anything + + John + diff --git a/ui/widgets/accounts.cpp b/ui/widgets/accounts.cpp index 367a0a5..cb526cf 100644 --- a/ui/widgets/accounts.cpp +++ b/ui/widgets/accounts.cpp @@ -120,13 +120,13 @@ void Accounts::updateConnectButton() } if (allConnected) { toDisconnect = true; - m_ui->connectButton->setText("Disconnect"); + m_ui->connectButton->setText(tr("Disconnect")); } else { toDisconnect = false; - m_ui->connectButton->setText("Connect"); + m_ui->connectButton->setText(tr("Connect")); } } else { - m_ui->connectButton->setText("Connect"); + m_ui->connectButton->setText(tr("Connect")); toDisconnect = false; m_ui->connectButton->setEnabled(false); } diff --git a/ui/widgets/chat.cpp b/ui/widgets/chat.cpp index aeaec65..5e0b390 100644 --- a/ui/widgets/chat.cpp +++ b/ui/widgets/chat.cpp @@ -56,7 +56,7 @@ void Chat::updateState() { Shared::Availability av = contact->getAvailability(); statusIcon->setPixmap(Shared::availabilityIcon(av, true).pixmap(40)); - statusIcon->setToolTip(Shared::availabilityNames[av]); + statusIcon->setToolTip(QCoreApplication::translate("Global", Shared::availabilityNames[av].toLatin1())); } void Chat::handleSendMessage(const QString& text) diff --git a/ui/widgets/conversation.ui b/ui/widgets/conversation.ui index 0298603..0eb7ae8 100644 --- a/ui/widgets/conversation.ui +++ b/ui/widgets/conversation.ui @@ -445,6 +445,9 @@ QFrame::NoFrame + + Type your message here... +