pax_global_header00006660000000000000000000000064135204723640014520gustar00rootroot0000000000000052 comment=259b8661bdbcca2b73a5d99137a570e0e1ece6d5 nm-tray-0.4.3/000077500000000000000000000000001352047236400131135ustar00rootroot00000000000000nm-tray-0.4.3/CMakeLists.txt000066400000000000000000000054451352047236400156630ustar00rootroot00000000000000project(nm-tray) cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) cmake_policy(SET CMP0071 NEW) set(NM_TRAY_VERSION "0.4.2") set(QT_MIN_VERSION "5.4.0") set(KF5_MIN_VERSION "5.36.0") set(CMAKE_AUTOMOC on) set(CMAKE_AUTOUIC on) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Widgets Gui Network DBus LinguistTools ) find_package(KF5NetworkManagerQt ${KF5_MIN_VERSION} REQUIRED) include(GNUInstallDirs) set(TRANSLATION_DIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}") add_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS "-DTRANSLATION_DIR=\"${TRANSLATION_DIR}\"" "-DNM_TRAY_VERSION=\"${NM_TRAY_VERSION}\"") if (NOT NM_TRAY_XDG_AUTOSTART_DIR) #Note: we need the default to be /etc... (not the ${CMAKE_INSTALL_PREFIX}/etc) set(NM_TRAY_XDG_AUTOSTART_DIR "${CMAKE_INSTALL_SYSCONFDIR}/xdg/autostart") endif () message(STATUS "Translations destination dir: ${TRANSLATION_DIR}") message(STATUS "Autostart .desktop entry destination dir: ${NM_TRAY_XDG_AUTOSTART_DIR}\n (can be overriden by setting the NM_TRAY_XDG_AUTOSTART_DIR cmake variable)") set(SRCS src/log.cpp src/icons.cpp src/nmmodel.cpp src/nmproxy.cpp src/connectioninfo.cpp src/nmlist.cpp src/menuview.cpp src/windowmenu.cpp src/tray.cpp src/translate.cpp src/main.cpp ) file(GLOB TSS "translations/${PROJECT_NAME}_*.ts") if (UPDATE_TRANSLATIONS) message(WARNING "!! Disable updating translation after make (-DUPDATE_TRANSLATIONS=no) to avoid 'make clean' delete them !!") qt5_create_translation(QMS "translations/${PROJECT_NAME}.ts" ${TSS} "src") else () qt5_add_translation(QMS ${TSS}) endif() qt5_add_dbus_interface(SRCS dbus/org.freedesktop.Notifications.xml dbus/org.freedesktop.Notifications ) add_executable(nm-tray ${SRCS} ${QMS} ) set_property(TARGET nm-tray PROPERTY CXX_STANDARD 11) set_property(TARGET nm-tray PROPERTY CXX_STANDARD_REQUIRED on) target_link_libraries(nm-tray Qt5::Widgets Qt5::Gui KF5::NetworkManagerQt ) if (WITH_MODEMMANAGER_SUPPORT) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Xml) find_package(KF5ModemManagerQt ${KF5_MIN_VERSION} REQUIRED) target_link_libraries(nm-tray KF5::ModemManagerQt) endif() install(TARGETS nm-tray RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" COMPONENT runtime) install(FILES ${QMS} DESTINATION "${TRANSLATION_DIR}" COMPONENT translations) install(FILES "resources/nm-tray.desktop" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications" COMPONENT data) install(FILES "resources/nm-tray-autostart.desktop" DESTINATION "${NM_TRAY_XDG_AUTOSTART_DIR}" COMPONENT data) install(FILES "resources/nm-tray.conf" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}" COMPONENT data) nm-tray-0.4.3/COPYING000066400000000000000000000432541352047236400141560ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. nm-tray-0.4.3/README.md000066400000000000000000000027721352047236400144020ustar00rootroot00000000000000# nm-tray **nm-tray** is a simple [NetworkManager](https://wiki.gnome.org/Projects/NetworkManager) front end with information icon residing in system tray (like e.g. nm-applet). It's a pure Qt application. For interaction with *NetworkManager* it uses API provided by [**KF5::NetworkManagerQt**](https://projects.kde.org/projects/frameworks/networkmanager-qt) -> plain DBus communication. ## License This software is licensed under [GNU GPLv2 or later](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) ## Build example git clone https://github.com/palinek/nm-tray.git cd nm-tray mkdir build cd build cmake .. make ./nm-tray ## Packages ### arch For [arch users](https://www.archlinux.org/) there is an AUR package [nm-tray-git](https://aur.archlinux.org/packages/nm-tray-git/) (thanks to [pmattern](https://github.com/pmattern)). ### openSUSE nm-tray is in the official repository of [openSUSE](https://www.opensuse.org/) since Leap 15.0. There is a also a [git package](https://build.opensuse.org/package/show/X11:LXQt:git/nm-tray) in the [X11:LXQt:git](https://build.opensuse.org/project/show/X11:LXQt:git) devel project of OBS. ### debian Thanks to [agaida](https://github.com/agaida) nm-tray is now in official debian repositories ([nm-tray](https://packages.debian.org/sid/nm-tray)). ## Translations Thanks to [Weblate](https://weblate.org/) anyone can help us to localize nm-tray by using the [hosted weblate service](https://hosted.weblate.org/projects/nm-tray/translations/). nm-tray-0.4.3/dbus/000077500000000000000000000000001352047236400140505ustar00rootroot00000000000000nm-tray-0.4.3/dbus/org.freedesktop.Notifications.xml000066400000000000000000000027501352047236400225070ustar00rootroot00000000000000 nm-tray-0.4.3/resources/000077500000000000000000000000001352047236400151255ustar00rootroot00000000000000nm-tray-0.4.3/resources/nm-tray-autostart.desktop000066400000000000000000000001661352047236400221360ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=nm-tray TryExec=nm-tray Exec=nm-tray NotShowIn=KDE;GNOME; X-LXQt-Need-Tray=true nm-tray-0.4.3/resources/nm-tray.conf000066400000000000000000000001131352047236400173560ustar00rootroot00000000000000[General] connectionsEditor=xterm, -e, nmtui-edit enableNotifications=true nm-tray-0.4.3/resources/nm-tray.desktop000066400000000000000000000002531352047236400201070ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=nm-tray Comment=NetworkManager frontend (tray icon) Icon=network-transmit TryExec=nm-tray Exec=nm-tray Categories=System;Monitor;Qt; nm-tray-0.4.3/src/000077500000000000000000000000001352047236400137025ustar00rootroot00000000000000nm-tray-0.4.3/src/connectioninfo.cpp000066400000000000000000000077071352047236400174340ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "connectioninfo.h" #include "ui_connectioninfo.h" #include "nmproxy.h" #include #include #include #include #include ConnectionInfo::ConnectionInfo(NmModel * model, QWidget *parent) : QDialog{parent} , ui{new Ui::ConnectionInfo} , mModel{model} , mActive{new NmProxy} , mSorted{new QSortFilterProxyModel} { setAttribute(Qt::WA_DeleteOnClose); ui->setupUi(this); mActive->setNmModel(mModel, NmModel::ActiveConnectionType); mSorted->setSortCaseSensitivity(Qt::CaseInsensitive); mSorted->sort(0); mSorted->setSourceModel(mActive.data()); for (int i = 0, row_cnt = mSorted->rowCount(); i < row_cnt; ++i) { addTab(mSorted->index(i, 0)); } connect(mSorted.data(), &QAbstractItemModel::rowsInserted, [this] (QModelIndex const & parent, int first, int last) { ui->tabWidget->setUpdatesEnabled(false); for (int i = first; i <= last; ++i) addTab(mSorted->index(i, 0, parent)); ui->tabWidget->setUpdatesEnabled(true); }); connect(mSorted.data(), &QAbstractItemModel::rowsAboutToBeRemoved, [this] (QModelIndex const & parent, int first, int last) { ui->tabWidget->setUpdatesEnabled(false); for (int i = first; i <= last; ++i) removeTab(mSorted->index(i, 0, parent)); ui->tabWidget->setUpdatesEnabled(true); }); connect(mSorted.data(), &QAbstractItemModel::dataChanged, [this] (const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector & /*roles*/) { ui->tabWidget->setUpdatesEnabled(false); for (auto const & i : QItemSelection{topLeft, bottomRight}.indexes()) changeTab(i); ui->tabWidget->setUpdatesEnabled(true); }); } ConnectionInfo::~ConnectionInfo() { } void ConnectionInfo::addTab(QModelIndex const & index) { QScrollArea * content = new QScrollArea; QLabel * l = new QLabel{mSorted->data(index, NmModel::ActiveConnectionInfoRole).toString()}; content->setWidget(l); //QTabWidget takes ownership of the page (if we will not take it back) ui->tabWidget->insertTab(index.row(), content, mSorted->data(index, NmModel::IconRole).value(), mSorted->data(index, NmModel::NameRole).toString()); } void ConnectionInfo::removeTab(QModelIndex const & index) { const int i = index.row(); QWidget * w = ui->tabWidget->widget(i); ui->tabWidget->removeTab(i); w->deleteLater(); } void ConnectionInfo::changeTab(QModelIndex const & index) { const int i = index.row(); QScrollArea * content = qobject_cast(ui->tabWidget->widget(i)); Q_ASSERT(nullptr != content); // Note: the text is HTML formatted and the QLabel probably creates some DOM internal represntation. // Should the DOM structure change, the QLabel will not update correctly upon the plain setText() content->setWidget(new QLabel{mSorted->data(index, NmModel::ActiveConnectionInfoRole).toString()}); ui->tabWidget->tabBar()->setTabText(i, mSorted->data(index, NmModel::NameRole).toString()); ui->tabWidget->tabBar()->setTabIcon(i, mSorted->data(index, NmModel::IconRole).value()); } nm-tray-0.4.3/src/connectioninfo.h000066400000000000000000000027111352047236400170670ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #ifndef CONNECTIONINFO_H #define CONNECTIONINFO_H #include namespace Ui { class ConnectionInfo; } class NmModel; class NmProxy; class QSortFilterProxyModel; class ConnectionInfo : public QDialog { Q_OBJECT public: explicit ConnectionInfo(NmModel * model, QWidget *parent = nullptr); ~ConnectionInfo(); private: void addTab(QModelIndex const & index); void removeTab(QModelIndex const & index); void changeTab(QModelIndex const & index); private: QScopedPointer ui; NmModel * mModel; QScopedPointer mActive; QScopedPointer mSorted; }; #endif // CONNECTIONINFO_H nm-tray-0.4.3/src/connectioninfo.ui000066400000000000000000000014161352047236400172560ustar00rootroot00000000000000 ConnectionInfo 0 0 570 614 Connection information -1 32 32 nm-tray-0.4.3/src/icons.cpp000066400000000000000000000116741352047236400155320ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "icons.h" #include #include namespace icons { QIcon getIcon(Icon ico, bool useSymbolic) { static const QStringList i_empty; QStringList const * icon_names = &i_empty; switch (ico) { case NETWORK_OFFLINE: static const QStringList i_network_offline = { QStringLiteral("network-offline") }; icon_names = &i_network_offline; break; case NETWORK_WIRED: static const QStringList i_network_wired = { QStringLiteral("network-wired") }; icon_names = &i_network_wired; break; case NETWORK_WIRED_DISCONNECTED: static const QStringList i_network_wired_disconnected = { QStringLiteral("network-wired-disconnected") }; icon_names = &i_network_wired_disconnected; break; case NETWORK_WIFI_DISCONNECTED: static const QStringList i_wifi_disconnected = { QStringLiteral("network-wireless-disconnected") }; icon_names = &i_wifi_disconnected; break; case NETWORK_WIFI_ACQUIRING: static const QStringList i_wifi_acquiring = { QStringLiteral("network-wireless-acquiring") }; icon_names = &i_wifi_acquiring; break; case NETWORK_WIFI_NONE: static const QStringList i_wifi_none = { QStringLiteral("network-wireless-signal-none"), QStringLiteral("network-wireless-connected-00") }; icon_names = &i_wifi_none; break; case NETWORK_WIFI_WEAK: static const QStringList i_wifi_weak = { QStringLiteral("network-wireless-signal-weak"), QStringLiteral("network-wireless-connected-25") }; icon_names = &i_wifi_weak; break; case NETWORK_WIFI_OK: static const QStringList i_wifi_ok = { QStringLiteral("network-wireless-signal-ok"), QStringLiteral("network-wireless-connected-50") }; icon_names = &i_wifi_ok; break; case NETWORK_WIFI_GOOD: static const QStringList i_wifi_good = { QStringLiteral("network-wireless-signal-good"), QStringLiteral("network-wireless-connected-75") }; icon_names = &i_wifi_good; break; case NETWORK_WIFI_EXCELENT: static const QStringList i_wifi_excelent = { QStringLiteral("network-wireless-signal-excellent"), QStringLiteral("network-wireless-connected-100") }; icon_names = &i_wifi_excelent; break; case NETWORK_VPN: static const QStringList i_network_vpn = { QStringLiteral("network-vpn") }; icon_names = &i_network_vpn; break; case SECURITY_LOW: static const QStringList i_security_low = { QStringLiteral("security-low") }; icon_names = &i_security_low; break; case SECURITY_HIGH: static const QStringList i_security_high = { QStringLiteral("security-high") }; icon_names = &i_security_high; break; case PREFERENCES_NETWORK: static const QStringList i_preferences_network = { QStringLiteral("preferences-system-network") }; icon_names = &i_preferences_network; break; }; for (auto const & name : *icon_names) { QIcon icon{QIcon::fromTheme(useSymbolic ? name % QStringLiteral("-symbolic") : name)}; if (!icon.isNull()) return icon; } //TODO: fallback!?! return QIcon::fromTheme(QStringLiteral("network-transmit")); } Icon wifiSignalIcon(const int signal) { if (0 >= signal) return icons::NETWORK_WIFI_NONE; else if (25 >= signal) return icons::NETWORK_WIFI_WEAK; else if (50 >= signal) return icons::NETWORK_WIFI_OK; else if (75 >= signal) return icons::NETWORK_WIFI_GOOD; else return icons::NETWORK_WIFI_EXCELENT; } } nm-tray-0.4.3/src/icons.h000066400000000000000000000026621352047236400151740ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(ICONS_H) #define ICONS_H #include namespace icons { enum Icon { NETWORK_OFFLINE , NETWORK_WIRED , NETWORK_WIRED_DISCONNECTED , NETWORK_WIFI_ACQUIRING , NETWORK_WIFI_NONE , NETWORK_WIFI_WEAK , NETWORK_WIFI_OK , NETWORK_WIFI_GOOD , NETWORK_WIFI_EXCELENT , NETWORK_WIFI_DISCONNECTED , NETWORK_VPN , SECURITY_LOW , SECURITY_HIGH , PREFERENCES_NETWORK }; QIcon getIcon(Icon ico, bool useSymbolic); Icon wifiSignalIcon(const int signal); } #endif nm-tray-0.4.3/src/log.cpp000066400000000000000000000017131352047236400151710ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "log.h" #include #if defined(NDEBUG) Q_LOGGING_CATEGORY(NM_TRAY, "nm-tray", QtInfoMsg) #else Q_LOGGING_CATEGORY(NM_TRAY, "nm-tray") #endif nm-tray-0.4.3/src/log.h000066400000000000000000000016371352047236400146430ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(LOG_H) #define LOG_H #include Q_DECLARE_LOGGING_CATEGORY(NM_TRAY) #endif //LOG_H nm-tray-0.4.3/src/main.cpp000066400000000000000000000023001352047236400153250ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include #include "tray.h" #include "icons.h" int main(int argc, char * argv[]) { QApplication app{argc, argv}; app.setOrganizationName(QStringLiteral("nm-tray")); app.setApplicationName(QStringLiteral("nm-tray")); app.setWindowIcon(icons::getIcon(icons::PREFERENCES_NETWORK, true)); app.setQuitOnLastWindowClosed(false); Tray tray; return app.exec(); } nm-tray-0.4.3/src/menuview.cpp000066400000000000000000000114571352047236400162550ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2016~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "menuview.h" #include "nmmodel.h" #include #include #include #include #include #include #include namespace { class SingleActivateStyle : public QProxyStyle { public: using QProxyStyle::QProxyStyle; virtual int styleHint(StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0) const override { if(hint == QStyle::SH_ItemView_ActivateItemOnSingleClick) return 1; return QProxyStyle::styleHint(hint, option, widget, returnData); } }; class MultiIconDelegate : public QStyledItemDelegate { public: using QStyledItemDelegate::QStyledItemDelegate; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { Q_ASSERT(index.isValid()); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); //add the security overlay icon QIcon sec_icon = qvariant_cast(index.data(NmModel::IconSecurityRole)); if (!sec_icon.isNull()) { QPixmap res_pixmap = opt.icon.pixmap(opt.decorationSize); QPainter p{&res_pixmap}; QSize sec_size = res_pixmap.size(); sec_size /= 2; QPoint sec_pos = res_pixmap.rect().bottomRight(); sec_pos -= QPoint{sec_size.width(), sec_size.height()}; p.drawPixmap(sec_pos, sec_icon.pixmap(sec_size)); opt.icon = QIcon{res_pixmap}; } QStyle *style = option.widget ? option.widget->style() : QApplication::style(); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, option.widget); } }; } MenuView::MenuView(QAbstractItemModel * model, QWidget * parent /*= nullptr*/) : QListView(parent) , mProxy{new QSortFilterProxyModel{this}} , mMaxItemsToShow(10) { setEditTriggers(NoEditTriggers); setSizeAdjustPolicy(AdjustToContents); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setSelectionBehavior(SelectRows); setSelectionMode(NoSelection); setFrameShape(QFrame::HLine); setFrameShadow(QFrame::Plain); setStyle(new SingleActivateStyle); mProxy->setSourceModel(model); mProxy->setDynamicSortFilter(true); mProxy->setFilterRole(Qt::DisplayRole); mProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); mProxy->setSortRole(Qt::DisplayRole); mProxy->setSortCaseSensitivity(Qt::CaseInsensitive); mProxy->sort(0); { QScopedPointer guard{selectionModel()}; setModel(mProxy); } { QScopedPointer guard{itemDelegate()}; setItemDelegate(new MultiIconDelegate{this}); } } void MenuView::setFilter(QString const & filter) { mProxy->setFilterFixedString(filter); const int count = mProxy->rowCount(); if (0 < count) { if (count > mMaxItemsToShow) { setCurrentIndex(mProxy->index(mMaxItemsToShow - 1, 0)); verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum); } else { setCurrentIndex(mProxy->index(count - 1, 0)); } } } void MenuView::setMaxItemsToShow(int max) { mMaxItemsToShow = max; } void MenuView::activateCurrent() { QModelIndex const index = currentIndex(); if (index.isValid()) emit activated(index); } QSize MenuView::viewportSizeHint() const { const int count = mProxy->rowCount(); QSize s{0, 0}; if (0 < count) { const bool scrollable = mMaxItemsToShow < count; s.setWidth(sizeHintForColumn(0) + (scrollable ? verticalScrollBar()->sizeHint().width() : 0)); s.setHeight(sizeHintForRow(0) * (scrollable ? mMaxItemsToShow : count)); } return s; } QSize MenuView::minimumSizeHint() const { return QSize{0, 0}; } nm-tray-0.4.3/src/menuview.h000066400000000000000000000032441352047236400157150ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2016~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(MENU_VIEW_H) #define MENU_VIEW_H #include class QAbstractItemModel; class QSortFilterProxyModel; class MenuView : public QListView { Q_OBJECT public: MenuView(QAbstractItemModel * model, QWidget * parent = nullptr); /*! \brief Sets the filter for entries to be presented */ void setFilter(QString const & filter); /*! \brief Set the maximum number of items/results to show */ void setMaxItemsToShow(int max); /*! \brief Set the maximum width of item to show */ void setMaxItemWidth(int max); public Q_SLOTS: /*! \brief Trigger action on currently active item */ void activateCurrent(); protected: virtual QSize viewportSizeHint() const override; virtual QSize minimumSizeHint() const override; private: QSortFilterProxyModel * mProxy; int mMaxItemsToShow; }; #endif //MENU_VIEW_H nm-tray-0.4.3/src/nmlist.cpp000066400000000000000000000063431352047236400157220ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "nmlist.h" #include "ui_nmlist.h" #include "nmmodel.h" #include "nmproxy.h" #include template void installDblClick(QAbstractItemView * view, QAbstractItemModel * m) { T * net_model = qobject_cast(m); if (net_model) { QAbstractProxyModel * proxy = qobject_cast(view->model()); Q_ASSERT(nullptr != proxy && proxy->sourceModel() == net_model); QObject::connect(view, &QAbstractItemView::doubleClicked, [net_model, proxy] (QModelIndex const & i) { QModelIndex source_i = proxy->mapToSource(i); switch (static_cast(net_model->data(source_i, NmModel::ItemTypeRole).toInt())) { case NmModel::ActiveConnectionType: net_model->deactivateConnection(source_i); break; case NmModel::WifiNetworkType: case NmModel::ConnectionType: net_model->activateConnection(source_i); break; default: //do nothing break; } }); } } NmList::NmList(QString const & title, QAbstractItemModel * m, QWidget *parent) : QDialog(parent) , ui(new Ui::NmList) { ui->setupUi(this); setWindowTitle(title); Q_ASSERT(qobject_cast(m)); QSortFilterProxyModel * proxy_sort = new QSortFilterProxyModel{this}; proxy_sort->setSortCaseSensitivity(Qt::CaseInsensitive); proxy_sort->sort(0); proxy_sort->setSourceModel(m); ui->treeView->setModel(proxy_sort); installDblClick(ui->treeView, m); NmProxy * proxy = new NmProxy(this); proxy->setNmModel(qobject_cast(m), NmModel::ActiveConnectionType); proxy_sort = new QSortFilterProxyModel{this}; proxy_sort->setSortCaseSensitivity(Qt::CaseInsensitive); proxy_sort->sort(0); proxy_sort->setSourceModel(proxy); ui->listActive->setModel(proxy_sort); installDblClick(ui->listActive, proxy); proxy = new NmProxy(this); proxy->setNmModel(qobject_cast(m), NmModel::WifiNetworkType); proxy_sort = new QSortFilterProxyModel{this}; proxy_sort->setSortCaseSensitivity(Qt::CaseInsensitive); proxy_sort->sort(0); proxy_sort->setSourceModel(proxy); ui->listWifi->setModel(proxy_sort); installDblClick(ui->listWifi, proxy); } NmList::~NmList() { delete ui; } nm-tray-0.4.3/src/nmlist.h000066400000000000000000000021651352047236400153650ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #ifndef NMLIST_H #define NMLIST_H #include namespace Ui { class NmList; } class QAbstractItemModel; class NmList : public QDialog { Q_OBJECT public: explicit NmList(QString const & title, QAbstractItemModel * m, QWidget *parent = nullptr); ~NmList(); private: Ui::NmList *ui; }; #endif // NMLIST_H nm-tray-0.4.3/src/nmlist.ui000066400000000000000000000024211352047236400155460ustar00rootroot00000000000000 NmList 0 0 565 507 All information Active connections Available wireless false nm-tray-0.4.3/src/nmmodel.cpp000066400000000000000000002047601352047236400160520ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "nmmodel.h" #include "nmmodel_p.h" #include "icons.h" #include "log.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { NetworkManager::ConnectionSettings::Ptr assembleWpaXPskSettings(const NetworkManager::AccessPoint::Ptr accessPoint) { //TODO: enhance getting the password from user bool ok; QString password = QInputDialog::getText(nullptr, NmModel::tr("nm-tray - wireless password") , NmModel::tr("Password is needed for connection to '%1':").arg(accessPoint->ssid()) , QLineEdit::Password, QString(), &ok); if (!ok) return NetworkManager::ConnectionSettings::Ptr{nullptr}; NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings{NetworkManager::ConnectionSettings::Wireless}}; settings->setId(accessPoint->ssid()); settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); settings->setAutoconnect(true); //Note: workaround for wrongly (randomly) initialized gateway-ping-timeout settings->setGatewayPingTimeout(0); NetworkManager::WirelessSetting::Ptr wifi_sett = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); wifi_sett->setInitialized(true); wifi_sett->setSsid(accessPoint->ssid().toUtf8()); wifi_sett->setSecurity("802-11-wireless-security"); NetworkManager::WirelessSecuritySetting::Ptr security_sett = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); security_sett->setInitialized(true); if (NetworkManager::AccessPoint::Adhoc == accessPoint->mode()) { wifi_sett->setMode(NetworkManager::WirelessSetting::Adhoc); security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone); } else { security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); } security_sett->setPsk(password); return settings; } } NmModelPrivate::NmModelPrivate() { insertActiveConnections(); insertConnections(); insertDevices(); insertWifiNetworks(); //initialize NetworkManager signals connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &NmModelPrivate::onDeviceAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &NmModelPrivate::onDeviceRemoved); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &NmModelPrivate::onActiveConnectionAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionRemoved, this, &NmModelPrivate::onActiveConnectionRemoved); connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionAdded, this, &NmModelPrivate::onConnectionAdded); connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionRemoved, this, static_cast(&NmModelPrivate::onConnectionRemoved)); // Note: the connectionRemoved is never emitted in case network-manager service stop, // we need remove the connections manually. connect(NetworkManager::notifier(), &NetworkManager::Notifier::serviceDisappeared, this, &NmModelPrivate::clearConnections); //qCDebug(NM_TRAY) << mActiveConns.size() << mConnections.size() << mDevices.size(); } NmModelPrivate::~NmModelPrivate() { } void NmModelPrivate::removeActiveConnection(int pos) { //active connections signals NetworkManager::ActiveConnection::Ptr conn = mActiveConns.takeAt(pos); conn->disconnect(this); } void NmModelPrivate::clearActiveConnections() { while (0 < mActiveConns.size()) removeActiveConnection(0); } void NmModelPrivate::addActiveConnection(NetworkManager::ActiveConnection::Ptr conn) { mActiveConns.push_back(conn); connect(conn.data(), &NetworkManager::ActiveConnection::connectionChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::default4Changed, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::default6Changed, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::dhcp4ConfigChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::dhcp6ConfigChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::ipV4ConfigChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::ipV6ConfigChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::idChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::typeChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::masterChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::specificObjectChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::stateChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::vpnChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::uuidChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(conn.data(), &NetworkManager::ActiveConnection::devicesChanged, this, &NmModelPrivate::onActiveConnectionUpdated); if (conn->vpn()) { connect(qobject_cast(conn.data()), &NetworkManager::VpnConnection::bannerChanged, this, &NmModelPrivate::onActiveConnectionUpdated); connect(qobject_cast(conn.data()), &NetworkManager::VpnConnection::stateChanged, this, &NmModelPrivate::onActiveConnectionUpdated); } } void NmModelPrivate::insertActiveConnections() { for (auto const & conn : NetworkManager::activeConnections()) addActiveConnection(conn); } void NmModelPrivate::removeConnection(int pos) { //connections signals NetworkManager::Connection::Ptr conn = mConnections.takeAt(pos); conn->disconnect(this); } void NmModelPrivate::clearConnections() { while (0 < mConnections.size()) removeConnection(0); } void NmModelPrivate::addConnection(NetworkManager::Connection::Ptr conn) { mConnections.push_back(conn); //connections signals connect(conn.data(), &NetworkManager::Connection::updated, this, &NmModelPrivate::onConnectionUpdated); connect(conn.data(), &NetworkManager::Connection::removed, this, static_cast(&NmModelPrivate::onConnectionRemoved)); } void NmModelPrivate::insertConnections() { for (auto const & conn : NetworkManager::listConnections()) addConnection(conn); } void NmModelPrivate::removeDevice(int pos) { //connections signals NetworkManager::Device::Ptr device = mDevices.takeAt(pos); device->disconnect(this); } void NmModelPrivate::clearDevices() { while (0 < mDevices.size()) removeDevice(0); } void NmModelPrivate::addDevice(NetworkManager::Device::Ptr device) { mDevices.push_back(device); //device signals connect(device.data(), &NetworkManager::Device::stateChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::activeConnectionChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::autoconnectChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::availableConnectionChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::availableConnectionAppeared, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::availableConnectionDisappeared, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::capabilitiesChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::dhcp4ConfigChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::dhcp6ConfigChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::driverChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::driverVersionChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::firmwareMissingChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::firmwareVersionChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::interfaceNameChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::ipV4AddressChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::ipV4ConfigChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::ipV6ConfigChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::ipInterfaceChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::managedChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::physicalPortIdChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::mtuChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::nmPluginMissingChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::meteredChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::connectionStateChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::stateReasonChanged, this, &NmModelPrivate::onDeviceUpdated); connect(device.data(), &NetworkManager::Device::udiChanged, this, &NmModelPrivate::onDeviceUpdated); switch (device->type()) { case NetworkManager::Ethernet: connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::bitRateChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::carrierChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::hardwareAddressChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::permanentHardwareAddressChanged, this, &NmModelPrivate::onDeviceUpdated); break; case NetworkManager::Device::Wifi: connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::bitRateChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::activeAccessPointChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::modeChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::wirelessCapabilitiesChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::hardwareAddressChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::permanentHardwareAddressChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::wirelessPropertiesChanged, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::accessPointAppeared, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::accessPointDisappeared, this, &NmModelPrivate::onDeviceUpdated); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::networkAppeared, this, &NmModelPrivate::onWifiNetworkAppeared); connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::networkDisappeared, this, &NmModelPrivate::onWifiNetworkDisappeared); break; default: //TODO: other device types! break; } } void NmModelPrivate::insertDevices() { for (auto const & device : NetworkManager::networkInterfaces()) addDevice(device); } void NmModelPrivate::removeWifiNetwork(int pos) { //network signals NetworkManager::WirelessNetwork::Ptr net = mWifiNets.takeAt(pos); net->disconnect(this); } void NmModelPrivate::clearWifiNetworks() { while (0 < mWifiNets.size()) removeWifiNetwork(0); } void NmModelPrivate::addWifiNetwork(NetworkManager::WirelessNetwork::Ptr net) { mWifiNets.push_back(net); //device signals connect(net.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &NmModelPrivate::onWifiNetworkUpdated); connect(net.data(), &NetworkManager::WirelessNetwork::referenceAccessPointChanged, this, &NmModelPrivate::onWifiNetworkUpdated); connect(net.data(), &NetworkManager::WirelessNetwork::disappeared, this, &NmModelPrivate::onWifiNetworkUpdated); } void NmModelPrivate::insertWifiNetworks() { for (auto const & device : mDevices) { if (NetworkManager::Device::Wifi == device->type()) { NetworkManager::WirelessDevice::Ptr w_dev = device.objectCast(); for (auto const & net : w_dev->networks()) { if (!net.isNull()) { addWifiNetwork(net); } } } } } NetworkManager::ActiveConnection::Ptr NmModelPrivate::findActiveConnection(QString const & path) { auto i = std::find_if(mActiveConns.cbegin(), mActiveConns.cend(), [&path] (NetworkManager::ActiveConnection::Ptr const & conn) -> bool { return conn->path() == path; }); return mActiveConns.cend() == i ? NetworkManager::ActiveConnection::Ptr{} : *i; } template NetworkManager::Device::Ptr NmModelPrivate::findDevice(Predicate const & pred) { auto i = std::find_if(mDevices.cbegin(), mDevices.cend(), pred); return mDevices.cend() == i ? NetworkManager::Device::Ptr{} : *i; } NetworkManager::Device::Ptr NmModelPrivate::findDeviceUni(QString const & uni) { return findDevice([&uni] (NetworkManager::Device::Ptr const & dev) { return dev->uni() == uni; }); } NetworkManager::Device::Ptr NmModelPrivate::findDeviceInterface(QString const & interfaceName) { return findDevice([&interfaceName] (NetworkManager::Device::Ptr const & dev) { return dev->interfaceName() == interfaceName; }); } NetworkManager::WirelessNetwork::Ptr NmModelPrivate::findWifiNetwork(QString const & ssid, QString const & devUni) { auto i = std::find_if(mWifiNets.cbegin(), mWifiNets.cend(), [&ssid, &devUni] (NetworkManager::WirelessNetwork::Ptr const & net) -> bool { return net->ssid() == ssid && net->device() == devUni; }); return mWifiNets.cend() == i ? NetworkManager::WirelessNetwork::Ptr{} : *i; } void NmModelPrivate::requestScan(NetworkManager::WirelessDevice * dev) { qCDebug(NM_TRAY) << __FUNCTION__ << dev->interfaceName(); QDBusPendingReply<> reply = dev->requestScan(); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, dev); connect(watcher, &QDBusPendingCallWatcher::finished, [dev] (QDBusPendingCallWatcher * watcher) { if (watcher->isError() || !watcher->isValid()) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << QStringLiteral("requestScan on device '%1' failed: %3").arg(dev->interfaceName()) .arg(watcher->error().message()); } watcher->deleteLater(); }); } void NmModelPrivate::onConnectionUpdated() { emit connectionUpdate(qobject_cast(sender())); } void NmModelPrivate::onConnectionRemoved() { emit connectionRemove(qobject_cast(sender())); } void NmModelPrivate::onActiveConnectionUpdated() { emit activeConnectionUpdate(qobject_cast(sender())); } void NmModelPrivate::onDeviceUpdated() { emit deviceUpdate(qobject_cast(sender())); } void NmModelPrivate::onWifiNetworkAppeared(QString const & ssid) { NetworkManager::Device * dev = qobject_cast(sender()); emit wifiNetworkAdd(dev, ssid); emit deviceUpdate(dev); } void NmModelPrivate::onWifiNetworkDisappeared(QString const & ssid) { NetworkManager::Device * dev = qobject_cast(sender()); emit wifiNetworkRemove(dev, ssid); emit deviceUpdate(dev); } void NmModelPrivate::onWifiNetworkUpdated() { emit wifiNetworkUpdate(qobject_cast(sender())); } void NmModelPrivate::onDeviceAdded(QString const & uni) { NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(uni); if (!dev.isNull()) { if (dev->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << uni << " is currently invalid..."; emit deviceAdd(dev); } } void NmModelPrivate::onDeviceRemoved(QString const & uni) { NetworkManager::Device::Ptr dev = findDeviceUni(uni); if (!dev.isNull()) { if (dev->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << uni << " is currently invalid..."; emit deviceRemove(dev.data()); } } void NmModelPrivate::onActiveConnectionAdded(QString const & path) { NetworkManager::ActiveConnection::Ptr conn = NetworkManager::findActiveConnection(path);//XXX: const QString &uni if (!conn.isNull()) { if (conn->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << path << " is currently invalid..."; emit activeConnectionAdd(conn); } } void NmModelPrivate::onActiveConnectionRemoved(QString const & path) { NetworkManager::ActiveConnection::Ptr conn = findActiveConnection(path);//XXX: const QString &uni if (!conn.isNull()) { if (conn->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << path << " is currently invalid..."; emit activeConnectionRemove(conn.data()); } } void NmModelPrivate::onActiveConnectionsChanged() { emit activeConnectionsReset(); } void NmModelPrivate::onConnectionAdded(QString const & path) { NetworkManager::Connection::Ptr conn = NetworkManager::findConnection(path); if (!conn.isNull()) { if (conn->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << path << " is currently invalid..."; emit connectionAdd(conn); } } void NmModelPrivate::onConnectionRemoved(QString const & path) { NetworkManager::Connection::Ptr conn = NetworkManager::findConnection(path); if (!conn.isNull()) { if (conn->isValid()) qCWarning(NM_TRAY).noquote() << Q_FUNC_INFO << path << " is currently invalid..."; emit connectionRemove(conn.data()); } } NmModel::NmModel(QObject * parent) : QAbstractItemModel(parent) , d{new NmModelPrivate} { connect(d.data(), &NmModelPrivate::connectionAdd, [this] (NetworkManager::Connection::Ptr conn) { //qCDebug(NM_TRAY) << "connectionAdd" << conn->name(); if (0 > d->mConnections.indexOf(conn)) { const int cnt = d->mConnections.size(); beginInsertRows(createIndex(1, 0, ITEM_CONNECTION), cnt, cnt); d->addConnection(conn); endInsertRows(); } else { //TODO: onConnectionUpdate } }); connect(d.data(), &NmModelPrivate::connectionUpdate, [this] (NetworkManager::Connection * conn) { //qCDebug(NM_TRAY) << "connectionUpdate" << conn->name(); auto i = std::find(d->mConnections.cbegin(), d->mConnections.cend(), conn); if (d->mConnections.cend() != i) { QModelIndex index = createIndex(i - d->mConnections.cbegin(), 0, ITEM_CONNECTION_LEAF); emit dataChanged(index, index); } }); connect(d.data(), &NmModelPrivate::connectionRemove, [this] (NetworkManager::Connection * conn) { //qCDebug(NM_TRAY) << "connectionRemove" << conn->name(); auto i = std::find(d->mConnections.cbegin(), d->mConnections.cend(), conn); if (d->mConnections.cend() != i) { const int pos = i - d->mConnections.cbegin(); beginRemoveRows(createIndex(1, 0, ITEM_CONNECTION), pos, pos); d->removeConnection(pos); endRemoveRows(); } }); connect(d.data(), &NmModelPrivate::activeConnectionAdd, [this] (NetworkManager::ActiveConnection::Ptr conn) { //qCDebug(NM_TRAY) << "activecCnnectionAdd" << conn->connection()->name(); if (0 > d->mActiveConns.indexOf(conn)) { const int cnt = d->mActiveConns.size(); beginInsertRows(createIndex(0, 0, ITEM_ACTIVE), cnt, cnt); d->addActiveConnection(conn); endInsertRows(); } else { //TODO: onActiveConnectionUpdate } }); connect(d.data(), &NmModelPrivate::activeConnectionUpdate, [this] (NetworkManager::ActiveConnection * conn) { //qCDebug(NM_TRAY) << "activecCnnectionUpdate" << conn->connection()->name(); auto i = std::find(d->mActiveConns.cbegin(), d->mActiveConns.cend(), conn); if (d->mActiveConns.cend() != i) { QModelIndex index = createIndex(i - d->mActiveConns.cbegin(), 0, ITEM_ACTIVE_LEAF); emit dataChanged(index, index); } }); connect(d.data(), &NmModelPrivate::activeConnectionRemove, [this] (NetworkManager::ActiveConnection * conn) { //qCDebug(NM_TRAY) << "activecCnnectionRemove" << conn->connection()->name(); auto i = std::find(d->mActiveConns.cbegin(), d->mActiveConns.cend(), conn); if (d->mActiveConns.cend() != i) { const int pos = i - d->mActiveConns.cbegin(); beginRemoveRows(createIndex(0, 0, ITEM_ACTIVE), pos, pos); d->removeActiveConnection(pos); endRemoveRows(); } }); connect(d.data(), &NmModelPrivate::activeConnectionsReset, [this] () { //qCDebug(NM_TRAY) << "activecCnnectionReset"; const int cnt = d->mActiveConns.size(); if (0 < cnt) { beginRemoveRows(createIndex(0, 0, ITEM_ACTIVE), 0, d->mActiveConns.size() - 1); d->clearActiveConnections(); endRemoveRows(); } const int new_cnt = NetworkManager::activeConnections().size(); if (0 < new_cnt) { beginInsertRows(createIndex(0, 0, ITEM_ACTIVE), 0, new_cnt - 1); d->insertActiveConnections(); endInsertRows(); } }); connect(d.data(), &NmModelPrivate::deviceAdd, [this] (NetworkManager::Device::Ptr dev) { //qCDebug(NM_TRAY) << "deviceAdd" << dev->interfaceName(); if (0 > d->mDevices.indexOf(dev)) { const int cnt = d->mDevices.size(); beginInsertRows(createIndex(2, 0, ITEM_DEVICE), cnt, cnt); d->addDevice(dev); endInsertRows(); } else { //TODO: onDeviceUpdate } }); connect(d.data(), &NmModelPrivate::deviceUpdate, [this] (NetworkManager::Device * dev) { //qCDebug(NM_TRAY) << "deviceUpdate" << dev << dev->interfaceName(); auto i = std::find(d->mDevices.cbegin(), d->mDevices.cend(), dev); if (d->mDevices.cend() != i) { QModelIndex index = createIndex(i - d->mDevices.cbegin(), 0, ITEM_DEVICE_LEAF); emit dataChanged(index, index); } }); connect(d.data(), &NmModelPrivate::deviceRemove, [this] (NetworkManager::Device * dev) { //qCDebug(NM_TRAY) << "deviceRemove" << dev->interfaceName(); auto i = std::find(d->mDevices.cbegin(), d->mDevices.cend(), dev); if (d->mDevices.cend() != i) { const int pos = i - d->mDevices.cbegin(); beginRemoveRows(createIndex(2, 0, ITEM_DEVICE), pos, pos); d->removeDevice(pos); endRemoveRows(); } }); connect(d.data(), &NmModelPrivate::wifiNetworkAdd, [this] (NetworkManager::Device * dev, QString const & ssid) { //qCDebug(NM_TRAY) << "wifiNetworkAdd" << dev << dev->interfaceName() << ssid; NetworkManager::WirelessDevice * w_dev = qobject_cast(dev); NetworkManager::WirelessNetwork::Ptr net = w_dev->findNetwork(ssid); if (!net.isNull()) { if (0 > d->mWifiNets.indexOf(net)) { const int cnt = d->mWifiNets.size(); beginInsertRows(createIndex(3, 0, ITEM_WIFINET), cnt, cnt); d->addWifiNetwork(net); endInsertRows(); } else { //TODO: onWifiNetworkUpdate } } }); connect(d.data(), &NmModelPrivate::wifiNetworkUpdate, [this] (NetworkManager::WirelessNetwork * net) { //qCDebug(NM_TRAY) << "wifiNetworkUpdate" << net << net->ssid(); auto i = std::find(d->mWifiNets.cbegin(), d->mWifiNets.cend(), net); if (d->mWifiNets.cend() != i) { if (net->accessPoints().isEmpty()) { //remove auto pos = i - d->mWifiNets.cbegin(); beginRemoveRows(createIndex(3, 0, ITEM_WIFINET), pos, pos); d->removeWifiNetwork(pos); endRemoveRows(); } else { //update QModelIndex index = createIndex(i - d->mWifiNets.cbegin(), 0, ITEM_WIFINET_LEAF); emit dataChanged(index, index); //XXX: active connection auto dev = d->findDeviceUni((*i)->device()); if (!dev.isNull()) { auto active = dev->activeConnection(); if (!active.isNull()) { QModelIndex index = createIndex(d->mActiveConns.indexOf(active), 0, ITEM_ACTIVE_LEAF); emit dataChanged(index, index); } } } } }); connect(d.data(), &NmModelPrivate::wifiNetworkRemove, [this] (NetworkManager::Device * dev, QString const & ssid) { //qCDebug(NM_TRAY) << "wifiNetworkRemove" << dev << dev->interfaceName() << ssid; NetworkManager::WirelessNetwork::Ptr net = d->findWifiNetwork(ssid, dev->uni()); if (!net.isNull()) { auto pos = d->mWifiNets.indexOf(net); if (0 <= pos) { beginRemoveRows(createIndex(3, 0, ITEM_WIFINET), pos, pos); d->removeWifiNetwork(pos); endRemoveRows(); } } }); //qCDebug(NM_TRAY) << __FUNCTION__ << "finished"; } NmModel::~NmModel() { } /* Model hierarchy * root * - mActiveConns * - mConnections * - mDevices */ int NmModel::rowCount(const QModelIndex &parent/* = QModelIndex()*/) const { int cnt = 0; if (!parent.isValid()) cnt = 1; else { const int id = parent.internalId(); if (ITEM_ROOT == id) cnt = 4; else if (ITEM_ACTIVE == id) cnt = d->mActiveConns.size(); else if (ITEM_CONNECTION == id) cnt = d->mConnections.size(); else if (ITEM_DEVICE == id) cnt = d->mDevices.size(); else if (ITEM_WIFINET == id) cnt = d->mWifiNets.size(); } //qCDebug(NM_TRAY) << __FUNCTION__ << parent << cnt; return cnt; } int NmModel::columnCount(const QModelIndex & /*parent = QModelIndex()*/) const { //qCDebug(NM_TRAY) << __FUNCTION__ << parent << 1; //XXX: more columns for wifi connections (for name && icons...)?? return 1; } bool NmModel::isValidDataIndex(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_WIFINET: return true; case ITEM_ACTIVE_LEAF: return d->mActiveConns.size() > index.row() && 0 == index.column(); case ITEM_CONNECTION_LEAF: return d->mConnections.size() > index.row() && 0 == index.column(); case ITEM_DEVICE_LEAF: return d->mDevices.size() > index.row() && 0 == index.column(); case ITEM_WIFINET_LEAF: return d->mWifiNets.size() > index.row() && 0 == index.column(); } return false; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_WIFINET: case ITEM_DEVICE: return HelperType; case ITEM_ACTIVE_LEAF: return ActiveConnectionType; case ITEM_CONNECTION_LEAF: return ConnectionType; case ITEM_DEVICE_LEAF: return DeviceType; case ITEM_WIFINET_LEAF: return WifiNetworkType; } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: return NmModel::tr("root"); case ITEM_ACTIVE: return NmModel::tr("active connection(s)"); case ITEM_CONNECTION: return NmModel::tr("connection(s)"); case ITEM_DEVICE: return NmModel::tr("device(s)"); case ITEM_WIFINET: return NmModel::tr("wifi network(s)"); case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->connection()->name(); case ITEM_CONNECTION_LEAF: return d->mConnections[index.row()]->name(); case ITEM_DEVICE_LEAF: return d->mDevices[index.row()]->interfaceName(); case ITEM_WIFINET_LEAF: return d->mWifiNets[index.row()]->referenceAccessPoint()->ssid(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_WIFINET: return QVariant{}; case ITEM_DEVICE_LEAF: //TODO: other types switch (d->mDevices[index.row()]->type()) { case NetworkManager::Device::Wifi: return NetworkManager::ConnectionSettings::Wireless; case NetworkManager::Device::Wimax: return NetworkManager::ConnectionSettings::Wimax; default: return NetworkManager::ConnectionSettings::Wired; } case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->connection()->settings()->connectionType(); case ITEM_CONNECTION_LEAF: return d->mConnections[index.row()]->settings()->connectionType(); case ITEM_WIFINET_LEAF: return NetworkManager::ConnectionSettings::Wireless; } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { const QVariant conn_type = dataRole(index); if (!conn_type.isValid()) { return QVariant{}; } return NetworkManager::ConnectionSettings::typeAsString(static_cast(conn_type.toInt())); } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_CONNECTION_LEAF: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: return QVariant{}; case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->state(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_CONNECTION_LEAF: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: return QVariant{}; case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->master(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_CONNECTION_LEAF: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: return QVariant{}; case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->devices(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { auto const internal_id = static_cast(index.internalId()); switch (internal_id) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_WIFINET: case ITEM_DEVICE_LEAF: return -1; case ITEM_CONNECTION_LEAF: case ITEM_ACTIVE_LEAF: { NetworkManager::ConnectionSettings::Ptr settings = ITEM_CONNECTION_LEAF == internal_id ? d->mConnections[index.row()]->settings() : d->mActiveConns[index.row()]->connection()->settings(); if (NetworkManager::ConnectionSettings::Wireless == settings->connectionType()) { NetworkManager::WirelessSecuritySetting::Ptr w_sett = settings->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); if (w_sett.isNull()) return icons::SECURITY_LOW; else if (NetworkManager::WirelessSecuritySetting::WpaNone != w_sett->keyMgmt()) return icons::SECURITY_HIGH; else return icons::SECURITY_LOW; } return -1; } case ITEM_WIFINET_LEAF: return d->mWifiNets[index.row()]->referenceAccessPoint()->capabilities().testFlag(NetworkManager::AccessPoint::Privacy) ? icons::SECURITY_HIGH : icons::SECURITY_LOW; } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { const auto type = dataRole(index).toInt(); if (0 <= type) return icons::getIcon(static_cast(type), true); else return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: return -1; case ITEM_ACTIVE_LEAF: { NetworkManager::ConnectionSettings::Ptr sett = d->mActiveConns[index.row()]->connection()->settings(); //TODO: other type with signals!?! if (NetworkManager::ConnectionSettings::Wireless == sett->connectionType()) { NetworkManager::WirelessSetting::Ptr w_sett = sett->setting(NetworkManager::Setting::Wireless).staticCast(); Q_ASSERT(!w_sett.isNull()); for (auto const & dev_uni : d->mActiveConns[index.row()]->devices()) { auto dev = NetworkManager::findNetworkInterface(dev_uni); if (!dev.isNull() && dev->isValid()) { auto w_dev = dev.objectCast(); if (!w_dev.isNull()) { auto wifi_net = w_dev->findNetwork(w_sett->ssid()); if (!wifi_net.isNull()) return wifi_net->signalStrength(); } } } } return -1; } case ITEM_CONNECTION_LEAF: //TODO: implement return -1; case ITEM_WIFINET_LEAF: return d->mWifiNets[index.row()]->signalStrength(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: return QVariant{}; case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->uuid(); case ITEM_CONNECTION_LEAF: return d->mConnections[index.row()]->uuid(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: return QVariant{}; case ITEM_ACTIVE_LEAF: return d->mActiveConns[index.row()]->path(); case ITEM_CONNECTION_LEAF: return d->mConnections[index.row()]->path(); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { NetworkManager::Device::Ptr dev; NetworkManager::ConnectionSettings::Ptr settings; switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_DEVICE_LEAF: case ITEM_WIFINET: case ITEM_WIFINET_LEAF: case ITEM_CONNECTION_LEAF: return QVariant{}; break; case ITEM_ACTIVE_LEAF: { auto const a_conn = d->mActiveConns[index.row()]; auto const dev_list = a_conn->devices(); //TODO: work with all devices?!? if (!dev_list.isEmpty()) dev = d->findDeviceUni(dev_list.first()); Q_ASSERT(!a_conn->connection().isNull()); settings = a_conn->connection()->settings(); } break; } //TODO: we probably shouldn't assemble a string information (with styling) here and leave it to the consumer QString info; QDebug str{&info}; str.noquote(); str.nospace(); if (!dev.isNull()) { auto m_enum = NetworkManager::Device::staticMetaObject.enumerator(NetworkManager::Device::staticMetaObject.indexOfEnumerator("Type")); QString hw_address = NmModel::tr("unknown", "hardware address"); QString security; int bit_rate = -1; switch (dev->type()) { case NetworkManager::Device::Adsl: break; case NetworkManager::Device::Bond: { auto spec_dev = dev->as(); hw_address = spec_dev->hwAddress(); } break; case NetworkManager::Device::Bridge: { auto spec_dev = dev->as(); hw_address = spec_dev->hwAddress(); } break; case NetworkManager::Device::Generic: { auto spec_dev = dev->as(); hw_address = spec_dev->hardwareAddress(); } break; case NetworkManager::Device::Gre: break; case NetworkManager::Device::InfiniBand: { auto spec_dev = dev->as(); hw_address = spec_dev->hwAddress(); } break; case NetworkManager::Device::IpTunnel: case NetworkManager::Device::MacVlan: case NetworkManager::Device::Modem: break; case NetworkManager::Device::Bluetooth: { auto spec_dev = dev->as(); hw_address = spec_dev->hardwareAddress(); } break; case NetworkManager::Device::OlpcMesh: { auto spec_dev = dev->as(); hw_address = spec_dev->hardwareAddress(); } break; case NetworkManager::Device::Team: { auto spec_dev = dev->as(); hw_address = spec_dev->hwAddress(); } break; case NetworkManager::Device::Tun: case NetworkManager::Device::Veth: break; case NetworkManager::Device::Vlan: { auto spec_dev = dev->as(); hw_address = spec_dev->hwAddress(); } break; case NetworkManager::Device::Wimax: //Wimax support was dropped in network manager 1.2.0 //we should never get here in runtime with nm >= 1.2.0 { auto spec_dev = dev->as(); Q_ASSERT(nullptr != spec_dev); hw_address = spec_dev->hardwareAddress(); //bit_rate = spec_dev->bitRate(); } break; case NetworkManager::Device::Ethernet: { auto spec_dev = dev->as(); Q_ASSERT(nullptr != spec_dev); hw_address = spec_dev->hardwareAddress(); bit_rate = spec_dev->bitRate(); } break; case NetworkManager::Device::Wifi: { auto spec_dev = dev->as(); Q_ASSERT(nullptr != spec_dev); hw_address = spec_dev->hardwareAddress(); bit_rate = spec_dev->bitRate(); NetworkManager::Setting::Ptr setting = settings->setting(NetworkManager::Setting::WirelessSecurity); if (!setting.isNull()) { QVariantMap const map = setting->toMap(); if (map.contains(QLatin1String(NM_SETTING_WIRELESS_SECURITY_KEY_MGMT))) security = map.value(QLatin1String(NM_SETTING_WIRELESS_SECURITY_KEY_MGMT)).toString(); } } break; case NetworkManager::Device::UnknownType: case NetworkManager::Device::Unused1: case NetworkManager::Device::Unused2: break; case NetworkManager::Device::VxLan: case NetworkManager::Device::MacSec: case NetworkManager::Device::Dummy: // Note: these devices are still not implemented in networkmanager-qt (as of v5.44.0) break; } str << QStringLiteral("") << QStringLiteral("") << QStringLiteral("") << QStringLiteral("") << QStringLiteral("") << QStringLiteral(""); if (!security.isEmpty()) { str << QStringLiteral(""); } //IP4/6 QString const ip4 = NmModel::tr("IPv4", "Active connection information"); QString const ip6 = NmModel::tr("IPv6", "Active connection information"); for (auto const & ip : { std::make_tuple(ip4, dev->ipV4Config()) , std::make_tuple(ip6, dev->ipV6Config()) }) { NetworkManager::IpConfig ip_config = std::get<1>(ip); if (ip_config.isValid()) { str << QStringLiteral(""); int i = 1; for (QNetworkAddressEntry const & address : ip_config.addresses()) { QString suffix = (i > 1 ? QString{"(%1)"}.arg(i) : QString{}); str << QStringLiteral("") << QStringLiteral("") ; ++i; } QString const gtw = ip_config.gateway(); if (!gtw.isEmpty()) { str << QStringLiteral(""); } i = 0; for (auto const & nameserver : ip_config.nameservers()) { str << QStringLiteral(""); } } } str << QStringLiteral("
") << NmModel::tr("General", "Active connection information") << QStringLiteral("
") << NmModel::tr("Interface", "Active connection information") << QStringLiteral(": ") << m_enum.valueToKey(dev->type()) << QStringLiteral(" (") << dev->interfaceName() << QStringLiteral(")
") << NmModel::tr("Hardware Address", "Active connection information") << QStringLiteral(": ") << hw_address << QStringLiteral("
") << NmModel::tr("Driver", "Active connection information") << QStringLiteral(": ") << dev->driver() << QStringLiteral("
") << NmModel::tr("Speed", "Active connection information") << QStringLiteral(": "); if (0 <= bit_rate) str << bit_rate << NmModel::tr(" Kb/s"); else str << NmModel::tr("unknown", "Speed"); str << QStringLiteral("
") << NmModel::tr("Security", "Active connection information") << QStringLiteral(": ") << security << QStringLiteral("
") << std::get<0>(ip) << QStringLiteral("
") << NmModel::tr("IP Address", "Active connection information") << suffix << QStringLiteral(": ") << address.ip().toString() << QStringLiteral("
") << NmModel::tr("Subnet Mask", "Active connection information") << suffix << QStringLiteral(": ") << address.netmask().toString() << QStringLiteral("
") << NmModel::tr("Default route", "Active connection information") << QStringLiteral(": ") << ip_config.gateway() << QStringLiteral("
") << NmModel::tr("DNS(%1)", "Active connection information").arg(++i) << QStringLiteral(": ") << nameserver.toString() << QStringLiteral("
"); } return info; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { switch (static_cast(index.internalId())) { case ITEM_ROOT: case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_WIFINET: return -1; case ITEM_ACTIVE_LEAF: case ITEM_CONNECTION_LEAF: case ITEM_DEVICE_LEAF: { const int type = static_cast(dataRole(index).toInt()); const QVariant state = dataRole(index); //TODO other types? switch (type) { case NetworkManager::ConnectionSettings::Wireless: case NetworkManager::ConnectionSettings::Wimax: if (!state.isValid()) return icons::NETWORK_WIFI_DISCONNECTED; switch (static_cast(state.toInt())) { case NetworkManager::ActiveConnection::Activating: return icons::NETWORK_WIFI_ACQUIRING; case NetworkManager::ActiveConnection::Activated: return icons::wifiSignalIcon(dataRole(index).toInt()); case NetworkManager::ActiveConnection::Unknown: case NetworkManager::ActiveConnection::Deactivating: case NetworkManager::ActiveConnection::Deactivated: return icons::NETWORK_WIFI_DISCONNECTED; } break; case NetworkManager::ConnectionSettings::Vpn: return icons::NETWORK_VPN; default: return NetworkManager::ActiveConnection::Activated == state ? icons::NETWORK_WIRED : icons::NETWORK_WIRED_DISCONNECTED; } } break; case ITEM_WIFINET_LEAF: return icons::wifiSignalIcon(d->mWifiNets[index.row()]->signalStrength()); } return QVariant{}; } template <> QVariant NmModel::dataRole(const QModelIndex & index) const { return icons::getIcon(static_cast(dataRole(index).toInt()), true); } QVariant NmModel::data(const QModelIndex &index, int role) const { //qCDebug(NM_TRAY) << __FUNCTION__ << index << role; Q_ASSERT(isValidDataIndex(index)); QVariant ret; if (index.isValid()) switch (role) { case ItemTypeRole: ret = dataRole(index); break; case Qt::DisplayRole: case NameRole: ret = dataRole(index); break; case ConnectionTypeRole: ret = dataRole(index); break; case ConnectionTypeStringRole: ret = dataRole(index); break; case ActiveConnectionStateRole: ret = dataRole(index); break; case ActiveConnectionMasterRole: ret = dataRole(index); break; case ActiveConnectionDevicesRole: ret = dataRole(index); break; case SignalRole: ret = dataRole(index); break; case ConnectionUuidRole: ret = dataRole(index); break; case ConnectionPathRole: ret = dataRole(index); break; case ActiveConnectionInfoRole: ret = dataRole(index); break; case IconTypeRole: ret = dataRole(index); break; case Qt::DecorationRole: case IconRole: ret = dataRole(index); break; case IconSecurityTypeRole: ret = dataRole(index); break; case IconSecurityRole: ret = dataRole(index); break; default: ret = QVariant{}; break; } //qCDebug(NM_TRAY) << __FUNCTION__ << "ret" << index << role << ret; return ret; } QModelIndex NmModel::index(int row, int column, const QModelIndex &parent/* = QModelIndex()*/) const { //qCDebug(NM_TRAY) << __FUNCTION__ << row << column << parent; if (!hasIndex(row, column, parent)) return QModelIndex{}; const int id = parent.internalId(); ItemId int_id; if (!parent.isValid()) { Q_ASSERT(0 == row && 0 == column); int_id = ITEM_ROOT; } else if (ITEM_ROOT == id) { Q_ASSERT(4 > row && 0 == column); switch (row) { case 0: int_id = ITEM_ACTIVE; break; case 1: int_id = ITEM_CONNECTION; break; case 2: int_id = ITEM_DEVICE; break; case 3: int_id = ITEM_WIFINET; break; } } else if (ITEM_ACTIVE == id) { Q_ASSERT(d->mActiveConns.size() > row); int_id = ITEM_ACTIVE_LEAF; } else if (ITEM_CONNECTION == id) { Q_ASSERT(d->mConnections.size() > row); int_id = ITEM_CONNECTION_LEAF; } else if (ITEM_DEVICE == id) { Q_ASSERT(d->mDevices.size() > row); int_id = ITEM_DEVICE_LEAF; } else if (ITEM_WIFINET == id) { Q_ASSERT(d->mWifiNets.size() > row); int_id = ITEM_WIFINET_LEAF; } else { Q_ASSERT(false); //should never get here return QModelIndex{}; } //qCDebug(NM_TRAY) << __FUNCTION__ << "ret: " << row << column << int_id; return createIndex(row, column, int_id); } QModelIndex NmModel::parent(const QModelIndex &index) const { QModelIndex parent_i; if (index.isValid()) { switch (static_cast(index.internalId())) { case ITEM_ROOT: break; case ITEM_ACTIVE: case ITEM_CONNECTION: case ITEM_DEVICE: case ITEM_WIFINET: parent_i = createIndex(0, 0, ITEM_ROOT); break; case ITEM_ACTIVE_LEAF: parent_i = createIndex(0, 0, ITEM_ACTIVE); break; case ITEM_CONNECTION_LEAF: parent_i = createIndex(1, 0, ITEM_CONNECTION); break; case ITEM_DEVICE_LEAF: parent_i = createIndex(2, 0, ITEM_DEVICE); break; case ITEM_WIFINET_LEAF: parent_i = createIndex(3, 0, ITEM_WIFINET); break; } } //qCDebug(NM_TRAY) << __FUNCTION__ << index << parent_i; return parent_i; } QModelIndex NmModel::indexTypeRoot(ItemType type) const { QModelIndex i; switch (type) { case HelperType: i = createIndex(0, 0, ITEM_ROOT); break; case ActiveConnectionType: i = createIndex(0, 0, ITEM_ACTIVE); break; case ConnectionType: i = createIndex(1, 0, ITEM_CONNECTION); break; case DeviceType: i = createIndex(2, 0, ITEM_DEVICE); break; case WifiNetworkType: i = createIndex(3, 0, ITEM_WIFINET); break; } return i; } void NmModel::activateConnection(QModelIndex const & index) { ItemId id = static_cast(index.internalId()); if (!isValidDataIndex(index) || (ITEM_CONNECTION_LEAF != id && ITEM_WIFINET_LEAF != id)) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << "got invalid index for connection activation" << index; return; } QString conn_uni, dev_uni; QString conn_name, dev_name; QString spec_object; NMVariantMapMap map_settings; bool add_connection = false; switch (id) { case ITEM_CONNECTION_LEAF: { auto const & conn = d->mConnections[index.row()]; conn_uni = conn->path(); conn_name = conn->name(); if (NetworkManager::ConnectionSettings::Vpn == conn->settings()->connectionType()) { spec_object = dev_uni = QStringLiteral("/"); /* // find first non-vpn active connection const auto act_i = std::find_if(d->mActiveConns.cbegin(), d->mActiveConns.cend(), [] (NetworkManager::ActiveConnection::Ptr const & conn) -> bool { return nullptr != dynamic_cast(conn.data()); }); if (act_i != d->mActiveConns.cend() && !(*act_i)->devices().empty()) { dev_uni = (*act_i)->devices().front(); spec_object = (*act_i)->path(); } */ } else { dev_name = conn->settings()->interfaceName(); for (auto const & dev : d->mDevices) for (auto const & dev_conn : dev->availableConnections()) if (dev_conn == conn) { dev_uni = dev->uni(); dev_name = dev->interfaceName(); } if (dev_uni.isEmpty() && !dev_name.isEmpty()) { auto dev = d->findDeviceInterface(dev_name); if (!dev.isNull()) dev_uni = dev->uni(); } } if (dev_uni.isEmpty()) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << QStringLiteral("can't find device '%1' to activate connection '%2' on").arg(dev_name).arg(conn->name()); return; } } break; case ITEM_WIFINET_LEAF: { auto const & net = d->mWifiNets[index.row()]; auto access_point = net->referenceAccessPoint(); Q_ASSERT(!access_point.isNull()); dev_uni = net->device(); auto dev = d->findDeviceUni(dev_uni); Q_ASSERT(!dev.isNull()); auto spec_dev = dev->as(); Q_ASSERT(nullptr != spec_dev); conn_uni = access_point->uni(); conn_name = access_point->ssid(); //find the device name NetworkManager::Connection::Ptr conn; dev_name = dev->interfaceName(); for (auto const & dev_conn : dev->availableConnections()) if (dev_conn->settings()->id() == conn_name) { conn = dev_conn; } if (conn.isNull()) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << QStringLiteral("can't find connection for '%1' on device '%2', will create new...").arg(conn_name).arg(dev_name); add_connection = true; spec_object = conn_uni; NetworkManager::WirelessSecurityType sec_type = NetworkManager::findBestWirelessSecurity(spec_dev->wirelessCapabilities() , true, (spec_dev->mode() == NetworkManager::WirelessDevice::Adhoc) , access_point->capabilities(), access_point->wpaFlags(), access_point->rsnFlags()); switch (sec_type) { case NetworkManager::UnknownSecurity: qCWarning(NM_TRAY).noquote() << QStringLiteral("unknown security to use for '%1'").arg(conn_name); case NetworkManager::NoneSecurity: //nothing to do break; case NetworkManager::WpaPsk: case NetworkManager::Wpa2Psk: if (NetworkManager::ConnectionSettings::Ptr settings = assembleWpaXPskSettings(access_point)) { map_settings = settings->toMap(); } else { qCWarning(NM_TRAY).noquote() << QStringLiteral("connection settings assembly for '%1' failed, abandoning activation...") .arg(conn_name); return; } break; //TODO: other types... } } else { conn_uni = conn->path(); } } break; default: Q_ASSERT(false); } qCDebug(NM_TRAY) << __FUNCTION__ << conn_uni << dev_uni << conn_name << dev_name << spec_object; //TODO: check vpn type etc.. QDBusPendingCallWatcher * watcher; if (add_connection) watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(map_settings, dev_uni, spec_object), this}; else watcher = new QDBusPendingCallWatcher{NetworkManager::activateConnection(conn_uni, dev_uni, spec_object), this}; connect(watcher, &QDBusPendingCallWatcher::finished, [conn_name, dev_name] (QDBusPendingCallWatcher * watcher) { if (watcher->isError() || !watcher->isValid()) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << QStringLiteral("activation of connection '%1' on interface '%2' failed: %3").arg(conn_name) .arg(dev_name).arg(watcher->error().message()); } watcher->deleteLater(); }); } void NmModel::deactivateConnection(QModelIndex const & index) { ItemId id = static_cast(index.internalId()); if (!isValidDataIndex(index) || ITEM_ACTIVE_LEAF != id) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << "got invalid index for connection deactivation" << index; return; } auto const & active = d->mActiveConns[index.row()]; qCDebug(NM_TRAY) << __FUNCTION__ << active->path(); QDBusPendingReply<> reply = NetworkManager::deactivateConnection(active->path()); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, &QDBusPendingCallWatcher::finished, [active] (QDBusPendingCallWatcher * watcher) { if (watcher->isError() || !watcher->isValid()) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << QStringLiteral("deactivation of connection '%1' failed: %3").arg(active->connection()->name()) .arg(watcher->error().message()); } watcher->deleteLater(); }); } void NmModel::requestScan(QModelIndex const & index) const { if (!isValidDataIndex(index) || ITEM_DEVICE != static_cast(index.internalId())) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << "got invalid index for scanning request" << index; return; } auto const & dev = d->mDevices[index.row()]; auto spec_dev = dev->as(); if (nullptr == spec_dev) { //TODO: in what form should we output the warning messages qCWarning(NM_TRAY).noquote() << "dropping request for scan on non wireles device " << dev->interfaceName(); return; } d->requestScan(spec_dev); } void NmModel::requestAllWifiScan() const { for (auto const & dev : d->mDevices) { auto spec_dev = dev->as(); if (nullptr != spec_dev) d->requestScan(spec_dev); } } nm-tray-0.4.3/src/nmmodel.h000066400000000000000000000057041352047236400155140ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(NMMODEL_H) #define NMMODEL_H #include class NmModelPrivate; class NmModel : public QAbstractItemModel { Q_OBJECT public: enum ItemType { HelperType , ActiveConnectionType , ConnectionType , DeviceType , WifiNetworkType }; enum ItemRole { ItemTypeRole = Qt::UserRole + 1 , NameRole , IconTypeRole , IconRole , ConnectionTypeRole , ActiveConnectionTypeRole = ConnectionTypeRole , ConnectionTypeStringRole , ActiveConnectionTypeStringRole = ConnectionTypeStringRole , ConnectionUuidRole , ActiveConnectionUuidRole = ConnectionUuidRole , ConnectionPathRole , ActiveConnectionPathRole = ConnectionPathRole , ActiveConnectionInfoRole , ActiveConnectionStateRole , ActiveConnectionMasterRole , ActiveConnectionDevicesRole , IconSecurityTypeRole , IconSecurityRole , SignalRole }; public: explicit NmModel(QObject * parent = nullptr); ~NmModel(); //QAbstractItemModel methods virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; virtual QModelIndex parent(const QModelIndex &index) const override; virtual QVariant data(const QModelIndex &index, int role) const override; QModelIndex indexTypeRoot(ItemType type) const; public Q_SLOTS: //NetworkManager management methods void activateConnection(QModelIndex const & index); void deactivateConnection(QModelIndex const & index); void requestScan(QModelIndex const & index) const; void requestAllWifiScan() const; private: bool isValidDataIndex(const QModelIndex & index) const; template QVariant dataRole(const QModelIndex & index) const; private: QScopedPointer d; }; #endif //NMMODEL_H nm-tray-0.4.3/src/nmmodel_p.h000066400000000000000000000104171352047236400160300ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(NMMODEL_P_H) #define NMMODEL_P_H #include #include #include class NmModelPrivate : public QObject { Q_OBJECT public: NmModelPrivate(); ~NmModelPrivate(); void removeActiveConnection(int pos); void clearActiveConnections(); void insertActiveConnections(); void addActiveConnection(NetworkManager::ActiveConnection::Ptr conn); void removeConnection(int pos); void clearConnections(); void insertConnections(); void addConnection(NetworkManager::Connection::Ptr conn); void removeDevice(int pos); void clearDevices(); void insertDevices(); void addDevice(NetworkManager::Device::Ptr conn); void removeWifiNetwork(int pos); void clearWifiNetworks(); void insertWifiNetworks(); void addWifiNetwork(NetworkManager::WirelessNetwork::Ptr net); NetworkManager::ActiveConnection::Ptr findActiveConnection(QString const & path); template NetworkManager::Device::Ptr findDevice(Predicate const & pred); NetworkManager::Device::Ptr findDeviceUni(QString const & uni); NetworkManager::Device::Ptr findDeviceInterface(QString const & interfaceName); NetworkManager::WirelessNetwork::Ptr findWifiNetwork(QString const & ssid, QString const & devUni); void requestScan(NetworkManager::WirelessDevice * dev); Q_SIGNALS: void connectionAdd(NetworkManager::Connection::Ptr conn); void connectionUpdate(NetworkManager::Connection * conn); void connectionRemove(NetworkManager::Connection * conn); void activeConnectionAdd(NetworkManager::ActiveConnection::Ptr conn); void activeConnectionUpdate(NetworkManager::ActiveConnection * conn); void activeConnectionRemove(NetworkManager::ActiveConnection * conn); void activeConnectionsReset(); void deviceAdd(NetworkManager::Device::Ptr dev); void deviceUpdate(NetworkManager::Device * dev); void deviceRemove(NetworkManager::Device * dev); void wifiNetworkAdd(NetworkManager::Device * dev, QString const & ssid); void wifiNetworkUpdate(NetworkManager::WirelessNetwork * net); void wifiNetworkRemove(NetworkManager::Device * dev, QString const & ssid); private Q_SLOT: //connection void onConnectionUpdated(); void onConnectionRemoved(); //active connection void onActiveConnectionUpdated(); //device void onDeviceUpdated(); void onWifiNetworkAppeared(QString const & ssid); void onWifiNetworkDisappeared(QString const & ssid); //wifi network void onWifiNetworkUpdated(); //notifier void onDeviceAdded(QString const & uni); void onDeviceRemoved(QString const & uni); void onActiveConnectionAdded(QString const & path); void onActiveConnectionRemoved(QString const & path); void onActiveConnectionsChanged(); //settings notifier void onConnectionAdded(QString const & path); void onConnectionRemoved(QString const & path); public: NetworkManager::ActiveConnection::List mActiveConns; NetworkManager::Connection::List mConnections; NetworkManager::Device::List mDevices; NetworkManager::WirelessNetwork::List mWifiNets; }; enum ItemId { ITEM_ROOT = 0x0 , ITEM_ACTIVE = 0x01 , ITEM_ACTIVE_LEAF = 0x11 , ITEM_CONNECTION = 0x2 , ITEM_CONNECTION_LEAF = 0x21 , ITEM_DEVICE = 0x3 , ITEM_DEVICE_LEAF = 0x31 , ITEM_WIFINET = 0x4 , ITEM_WIFINET_LEAF = 0x41 }; #endif //NMMODEL_P_H nm-tray-0.4.3/src/nmproxy.cpp000066400000000000000000000246041352047236400161300ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "nmproxy.h" #include "log.h" void NmProxy::setSourceModel(QAbstractItemModel * sourceModel) { //we operate only on our known model Q_ASSERT(sourceModel->metaObject() == &NmModel::staticMetaObject); Q_ASSERT(root.isValid()); beginResetModel(); if (nullptr != this->sourceModel()) { disconnect(this->sourceModel(), &QAbstractItemModel::dataChanged, this, &NmProxy::onSourceDataChanged); disconnect(this->sourceModel(), &QAbstractItemModel::headerDataChanged, this, &NmProxy::onSourceHeaderDataChanged); disconnect(this->sourceModel(), &QAbstractItemModel::rowsAboutToBeInserted, this, &NmProxy::onSourceRowsAboutToBeInserted); disconnect(this->sourceModel(), &QAbstractItemModel::rowsInserted, this, &NmProxy::onSourceRowsInserted); disconnect(this->sourceModel(), &QAbstractItemModel::rowsAboutToBeRemoved, this, &NmProxy::onSourceRowsAboutToBeRemoved); disconnect(this->sourceModel(), &QAbstractItemModel::rowsRemoved, this, &NmProxy::onSourceRowsRemoved); disconnect(this->sourceModel(), &QAbstractItemModel::columnsAboutToBeInserted, this, &NmProxy::onSourceColumnsAboutToBeInserted); disconnect(this->sourceModel(), &QAbstractItemModel::columnsInserted, this, &NmProxy::onSourceColumnsInserted); disconnect(this->sourceModel(), &QAbstractItemModel::columnsAboutToBeRemoved, this, &NmProxy::onSourceColumnsAboutToBeRemoved); disconnect(this->sourceModel(), &QAbstractItemModel::columnsRemoved, this, &NmProxy::onSourceColumnsRemoved); disconnect(this->sourceModel(), &QAbstractItemModel::modelAboutToBeReset, this, &NmProxy::onSourceModelAboutToBeReset); disconnect(this->sourceModel(), &QAbstractItemModel::modelReset, this, &NmProxy::onSourceModelReset); disconnect(this->sourceModel(), &QAbstractItemModel::rowsAboutToBeMoved, this, &NmProxy::onSourceRowsAboutToBeMoved); disconnect(this->sourceModel(), &QAbstractItemModel::rowsMoved, this, &NmProxy::onSourceRowsMoved); disconnect(this->sourceModel(), &QAbstractItemModel::columnsAboutToBeMoved, this, &NmProxy::onSourceColumnsAboutToBeMoved); disconnect(this->sourceModel(), &QAbstractItemModel::columnsMoved, this, &NmProxy::onSourceColumnsMoved); } QAbstractProxyModel::setSourceModel(sourceModel); connect(sourceModel, &QAbstractItemModel::dataChanged, this, &NmProxy::onSourceDataChanged); connect(sourceModel, &QAbstractItemModel::headerDataChanged, this, &NmProxy::onSourceHeaderDataChanged); connect(sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &NmProxy::onSourceRowsAboutToBeInserted); connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &NmProxy::onSourceRowsInserted); connect(sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &NmProxy::onSourceRowsAboutToBeRemoved); connect(sourceModel, &QAbstractItemModel::rowsRemoved, this, &NmProxy::onSourceRowsRemoved); connect(sourceModel, &QAbstractItemModel::columnsAboutToBeInserted, this, &NmProxy::onSourceColumnsAboutToBeInserted); connect(sourceModel, &QAbstractItemModel::columnsInserted, this, &NmProxy::onSourceColumnsInserted); connect(sourceModel, &QAbstractItemModel::columnsAboutToBeRemoved, this, &NmProxy::onSourceColumnsAboutToBeRemoved); connect(sourceModel, &QAbstractItemModel::columnsRemoved, this, &NmProxy::onSourceColumnsRemoved); connect(sourceModel, &QAbstractItemModel::modelAboutToBeReset, this, &NmProxy::onSourceModelAboutToBeReset); connect(sourceModel, &QAbstractItemModel::modelReset, this, &NmProxy::onSourceModelReset); connect(sourceModel, &QAbstractItemModel::rowsAboutToBeMoved, this, &NmProxy::onSourceRowsAboutToBeMoved); connect(sourceModel, &QAbstractItemModel::rowsMoved, this, &NmProxy::onSourceRowsMoved); connect(sourceModel, &QAbstractItemModel::columnsAboutToBeMoved, this, &NmProxy::onSourceColumnsAboutToBeMoved); connect(sourceModel, &QAbstractItemModel::columnsMoved, this, &NmProxy::onSourceColumnsMoved); endResetModel(); } void NmProxy::setNmModel(NmModel * model, NmModel::ItemType shownType) { root = model->indexTypeRoot(shownType); setSourceModel(model); //qCDebug(NM_TRAY) << __FUNCTION__ << model->indexTypeRoot(shownType) << "->" << root; } QModelIndex NmProxy::index(int row, int column, const QModelIndex & proxyParent) const { QModelIndex i; if (hasIndex(row, column, proxyParent)) i = createIndex(row, column); //qCDebug(NM_TRAY) << __FUNCTION__ << row << column << proxyParent << "->" << i; return i; } QModelIndex NmProxy::parent(const QModelIndex &/*proxyIndex*/) const { //showing only one level/list: leaf -> invalid, root -> invalid QModelIndex i; //qCDebug(NM_TRAY) << __FUNCTION__ << proxyIndex << "->" << i; return i; } int NmProxy::rowCount(const QModelIndex &proxyParent) const { //showing only one level/list: leaf -> source root rowcount, root -> 0 if (proxyParent.isValid()) return 0; else return sourceModel()->rowCount(root); } int NmProxy::columnCount(const QModelIndex &proxyParent) const { return sourceModel()->columnCount(mapToSource(proxyParent)); } void NmProxy::activateConnection(QModelIndex const & index) const { qobject_cast(sourceModel())->activateConnection(mapToSource(index)); } void NmProxy::deactivateConnection(QModelIndex const & index) const { qobject_cast(sourceModel())->deactivateConnection(mapToSource(index)); } QModelIndex NmProxy::mapToSource(const QModelIndex & proxyIndex) const { QModelIndex i; if (proxyIndex.isValid()) i = sourceModel()->index(proxyIndex.row(), proxyIndex.column(), root); //qCDebug(NM_TRAY) << __FUNCTION__ << proxyIndex << "->" << i; return i; } QModelIndex NmProxy::mapFromSource(const QModelIndex & sourceIndex) const { QModelIndex i; if (sourceIndex.isValid() && root != sourceIndex) i = createIndex(sourceIndex.row(), sourceIndex.column()); //qCDebug(NM_TRAY) << __FUNCTION__ << sourceIndex << "->" << i; return i; } void NmProxy::onSourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { if (root == topLeft.parent()) emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles); } void NmProxy::onSourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) { emit headerDataChanged(orientation, first, last); } void NmProxy::onSourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last) { if (root == parent) beginInsertRows(mapFromSource(parent), first, last); } void NmProxy::onSourceRowsInserted(const QModelIndex &parent, int, int) { if (root == parent) endInsertRows(); } void NmProxy::onSourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last) { if (root == parent) beginRemoveRows(mapFromSource(parent), first, last); } void NmProxy::onSourceRowsRemoved(const QModelIndex &parent, int, int) { if (root == parent) endRemoveRows(); } void NmProxy::onSourceColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last) { if (root == parent) beginInsertColumns(mapFromSource(parent), first, last); } void NmProxy::onSourceColumnsInserted(const QModelIndex &parent, int, int) { if (root == parent) endInsertColumns(); } void NmProxy::onSourceColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last) { if (root == parent) beginRemoveColumns(mapFromSource(parent), first, last); } void NmProxy::onSourceColumnsRemoved(const QModelIndex &parent, int, int) { if (root == parent) endRemoveColumns(); } void NmProxy::onSourceModelAboutToBeReset() { beginResetModel(); } void NmProxy::onSourceModelReset() { endResetModel(); } void NmProxy::onSourceRowsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) { if (root == sourceParent) { if (root == destinationParent) beginMoveRows(mapFromSource(sourceParent), sourceStart, sourceEnd, destinationParent, destinationRow); else beginRemoveRows(mapFromSource(sourceParent), sourceStart, sourceEnd); } else if (root == destinationParent) beginInsertRows(mapFromSource(destinationParent), destinationRow, destinationRow + (sourceEnd - sourceStart)); } void NmProxy::onSourceRowsMoved( const QModelIndex &sourceParent, int, int, const QModelIndex &destinationParent, int) { if (root == sourceParent) { if (root == destinationParent) endMoveRows(); else endRemoveRows(); } else if (root == destinationParent) endInsertRows(); } void NmProxy::onSourceColumnsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) { if (root == sourceParent) { if (root == destinationParent) beginMoveColumns(mapFromSource(sourceParent), sourceStart, sourceEnd, destinationParent, destinationColumn); else beginRemoveColumns(mapFromSource(sourceParent), sourceStart, sourceEnd); } else if (root == destinationParent) beginInsertColumns(mapFromSource(destinationParent), destinationColumn, destinationColumn + (sourceEnd - sourceStart)); } void NmProxy::onSourceColumnsMoved( const QModelIndex &sourceParent, int, int, const QModelIndex &destinationParent, int) { if (root == sourceParent) { if (root == destinationParent) endMoveColumns(); else endRemoveColumns(); } else if (root == destinationParent) endInsertColumns(); } nm-tray-0.4.3/src/nmproxy.h000066400000000000000000000065711352047236400156000ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(NMPROXY_H) #define NMPROXY_H #include #include "nmmodel.h" class NmProxy : public QAbstractProxyModel { Q_OBJECT public: using QAbstractProxyModel::QAbstractProxyModel; virtual void setSourceModel(QAbstractItemModel * sourceModel) override; void setNmModel(NmModel * model, NmModel::ItemType shownType); virtual QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override; virtual QModelIndex parent(const QModelIndex &index) const override; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; void activateConnection(QModelIndex const & index) const; void deactivateConnection(QModelIndex const & index) const; protected: virtual QModelIndex mapToSource(const QModelIndex & proxyIndex) const override; virtual QModelIndex mapFromSource(const QModelIndex & sourceIndex) const override; private Q_SLOTS: void onSourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); void onSourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); void onSourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last); void onSourceRowsInserted(const QModelIndex &parent, int first, int last); void onSourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last); void onSourceRowsRemoved(const QModelIndex &parent, int first, int last); void onSourceColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last); void onSourceColumnsInserted(const QModelIndex &parent, int first, int last); void onSourceColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last); void onSourceColumnsRemoved(const QModelIndex &parent, int first, int last); void onSourceModelAboutToBeReset(); void onSourceModelReset(); void onSourceRowsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow); void onSourceRowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); void onSourceColumnsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn); void onSourceColumnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column); private: QModelIndex root; }; #endif //NMPROXY_H nm-tray-0.4.3/src/translate.cpp000066400000000000000000000031661352047236400164110ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include #include #include #include #if !defined(TRANSLATION_DIR) #define TRANSLATION_DIR "/usr/share/nm-tray" #endif void translate() { const QString locale = QLocale::system().name(); QTranslator * qt_trans = new QTranslator{qApp}; if (qt_trans->load(QLatin1String("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) qApp->installTranslator(qt_trans); else delete qt_trans; QString trans_dir = qgetenv("NM_TRAY_TRANSLATION_DIR").constData(); QTranslator * my_trans = new QTranslator{qApp}; if (my_trans->load(QLatin1String("nm-tray_") + locale, trans_dir.isEmpty() ? TRANSLATION_DIR : trans_dir)) qApp->installTranslator(my_trans); else delete my_trans; } Q_COREAPP_STARTUP_FUNCTION(translate) nm-tray-0.4.3/src/tray.cpp000066400000000000000000000412621352047236400153720ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "tray.h" #include #include #include #include #include #include #include "icons.h" #include "nmmodel.h" #include "nmproxy.h" #include "log.h" #include "dbus/org.freedesktop.Notifications.h" #include "nmlist.h" #include "connectioninfo.h" #include "windowmenu.h" // config keys static const QString ENABLE_NOTIFICATIONS = QStringLiteral("enableNotifications"); static const QString CONNECTIONS_EDITOR = QStringLiteral("connectionsEditor"); class TrayPrivate { public: TrayPrivate(); void updateState(QModelIndex const & index, bool removing); void primaryConnectionUpdate(); void setShown(QPersistentModelIndex const & index); void updateIcon(); void refreshIcon(); void openCloseDialog(QDialog * dialog); void notify(QModelIndex const & index, bool removing); public: QSystemTrayIcon mTrayIcon; QMenu mContextMenu; QTimer mStateTimer; QAction * mActEnableNetwork; QAction * mActEnableWifi; QAction * mActConnInfo; QAction * mActDebugInfo; QAction * mRequestScan; NmModel mNmModel; NmProxy mActiveConnections; QPersistentModelIndex mPrimaryConnection; QPersistentModelIndex mShownConnection; QList mConnectionsToNotify; //!< just "created" connections to which notification wasn't sent yet icons::Icon mIconCurrent; icons::Icon mIcon2Show; QTimer mIconTimer; QScopedPointer mConnDialog; QScopedPointer mInfoDialog; org::freedesktop::Notifications mNotification; // configuration bool mEnableNotifications; //!< should info about connection establishment etc. be sent by org.freedesktop.Notifications }; TrayPrivate::TrayPrivate() : mNotification{QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QDBusConnection::sessionBus()} { mActiveConnections.setNmModel(&mNmModel, NmModel::ActiveConnectionType); } void TrayPrivate::updateState(QModelIndex const & index, bool removing) { notify(index, removing); const auto state = static_cast(mActiveConnections.data(index, NmModel::ActiveConnectionStateRole).toInt()); const bool is_primary = mPrimaryConnection == index; //qCDebug(NM_TRAY) << __FUNCTION__ << index << removing << mActiveConnections.data(index, NmModel::NameRole) << mActiveConnections.data(index, NmModel::ConnectionUuidRole).toString() << is_primary << mActiveConnections.data(index, NmModel::ConnectionTypeRole).toInt() << state; if (removing || NetworkManager::ActiveConnection::Deactivated == state || NetworkManager::ActiveConnection::Deactivating == state) { if (is_primary) { mPrimaryConnection = QModelIndex{}; setShown(mPrimaryConnection); } else if (mShownConnection == index) { setShown(mPrimaryConnection); } } else { if (is_primary || NetworkManager::ActiveConnection::Activating == state) { setShown(index); } else if (mShownConnection == index) { setShown(mPrimaryConnection); } } //TODO: optimize this text assembly (to not do it every time)? if (mPrimaryConnection.isValid()) { mTrayIcon.setToolTip(Tray::tr("
Connection %1(%2) active
") .arg(mPrimaryConnection.data(NmModel::NameRole).toString()) .arg(mPrimaryConnection.data(NmModel::ActiveConnectionTypeStringRole).toString()) ); } else { mTrayIcon.setToolTip(Tray::tr("
No active connection
")); } } void TrayPrivate::primaryConnectionUpdate() { NetworkManager::ActiveConnection::Ptr prim_conn = NetworkManager::primaryConnection(); if (!prim_conn || !prim_conn->isValid()) { mPrimaryConnection = QModelIndex{}; setShown(mPrimaryConnection); return; } //qCDebug(NM_TRAY) << __FUNCTION__ << prim_conn->uuid(); QModelIndexList l = mActiveConnections.match(mActiveConnections.index(0, 0, QModelIndex{}), NmModel::ActiveConnectionUuidRole, prim_conn->uuid(), -1, Qt::MatchExactly); //qCDebug(NM_TRAY) << __FUNCTION__ << l.size(); //nothing to do if the connection not populated in model yet if (0 >= l.size()) return; Q_ASSERT(1 == l.size()); mPrimaryConnection = l.first(); updateState(mPrimaryConnection, false); } void TrayPrivate::setShown(QPersistentModelIndex const & index) { mShownConnection = index; mIcon2Show = mShownConnection.isValid() ? static_cast(mActiveConnections.data(mShownConnection, NmModel::IconTypeRole).toInt()) : icons::NETWORK_OFFLINE; //postpone setting the icon (for case we change the icon in till our event is finished) mIconTimer.start(); } void TrayPrivate::updateIcon() { if (mIconCurrent == mIcon2Show) return; mIconCurrent = mIcon2Show; refreshIcon(); } void TrayPrivate::refreshIcon() { //Note: the icons::getIcon chooses the right icon from list of possible candidates // -> we need to refresh the icon in case of icon theme change mTrayIcon.setIcon(icons::getIcon(mIconCurrent, false)); } void TrayPrivate::openCloseDialog(QDialog * dialog) { if (dialog->isHidden() || dialog->isMinimized()) { dialog->showNormal(); dialog->activateWindow(); dialog->raise(); } else dialog->close(); } void TrayPrivate::notify(QModelIndex const & index, bool removing) { if (!mEnableNotifications) { return; } QString summary, body; if (removing) { mConnectionsToNotify.removeOne(index); summary = Tray::tr("Connection lost"); body = Tray::tr("No longer connected to %1 '%2'."); } else { const int notif_i = mConnectionsToNotify.indexOf(index); // do nothing if not just added or the connection is not activated yet if (-1 == notif_i || NetworkManager::ActiveConnection::Activated != static_cast(mActiveConnections.data(index, NmModel::ActiveConnectionStateRole).toInt()) ) { return; } mConnectionsToNotify.removeAt(notif_i); // fire the notification only once summary = Tray::tr("Connection established"); body = Tray::tr("Now connected to %1 '%2'."); } // TODO: do somehow check the result? mNotification.Notify(Tray::tr("NetworkManager(nm-tray)") , 0 , icons::getIcon(static_cast(mActiveConnections.data(index, NmModel::IconTypeRole).toInt()), false).name() , summary , body.arg(mActiveConnections.data(index, NmModel::ConnectionTypeStringRole).toString()).arg(mActiveConnections.data(index, NmModel::NameRole).toString()) , {} , {} , -1); } Tray::Tray(QObject *parent/* = nullptr*/) : QObject{parent} , d{new TrayPrivate} { d->mEnableNotifications = QSettings{}.value(ENABLE_NOTIFICATIONS, true).toBool(); connect(&d->mTrayIcon, &QSystemTrayIcon::activated, this, &Tray::onActivated); //postpone the update in case of signals flood connect(&d->mStateTimer, &QTimer::timeout, this, &Tray::setActionsStates); d->mStateTimer.setSingleShot(true); d->mStateTimer.setInterval(200); d->mIconCurrent = static_cast(-1); d->setShown(QModelIndex{}); d->refreshIcon(); //force setting the icon instantly //postpone updating of the icon connect(&d->mIconTimer, &QTimer::timeout, [this] { d->updateIcon(); }); d->mIconTimer.setSingleShot(true); d->mIconTimer.setInterval(0); d->mActEnableNetwork = d->mContextMenu.addAction(Tray::tr("Enable Networking")); d->mActEnableWifi = d->mContextMenu.addAction(Tray::tr("Enable Wi-Fi")); d->mContextMenu.addSeparator(); QAction * enable_notifications = d->mContextMenu.addAction(Tray::tr("Enable notifications")); d->mContextMenu.addSeparator(); d->mActConnInfo = d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("dialog-information")), Tray::tr("Connection information")); d->mActDebugInfo = d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("dialog-information")), Tray::tr("Debug information")); d->mRequestScan = d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("view-refresh")), Tray::tr("Wifi - request scan")); connect(d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), Tray::tr("Edit connections...")), &QAction::triggered , this, &Tray::onEditConnectionsTriggered); d->mContextMenu.addSeparator(); connect(d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("help-about")), Tray::tr("About")), &QAction::triggered , this, &Tray::onAboutTriggered); connect(d->mContextMenu.addAction(QIcon::fromTheme(QStringLiteral("application-exit")), Tray::tr("Quit")), &QAction::triggered , this, &Tray::onQuitTriggered); //for listening on the QEvent::ThemeChange (is delivered only to QWidget objects) d->mContextMenu.installEventFilter(this); d->mActEnableNetwork->setCheckable(true); d->mActEnableWifi->setCheckable(true); enable_notifications->setCheckable(true); enable_notifications->setChecked(d->mEnableNotifications); connect(d->mActEnableNetwork, &QAction::triggered, [] (bool checked) { NetworkManager::setNetworkingEnabled(checked); }); connect(d->mActEnableWifi, &QAction::triggered, [] (bool checked) { NetworkManager::setWirelessEnabled(checked); }); connect(enable_notifications, &QAction::triggered, this, [this] (bool checked) { d->mEnableNotifications = checked; QSettings{}.setValue(ENABLE_NOTIFICATIONS, checked); }); connect(d->mActConnInfo, &QAction::triggered, this, [this] (bool ) { if (d->mInfoDialog.isNull()) { d->mInfoDialog.reset(new ConnectionInfo{&d->mNmModel}); connect(d->mInfoDialog.data(), &QDialog::finished, [this] { d->mInfoDialog.reset(nullptr); }); } d->openCloseDialog(d->mInfoDialog.data()); }); connect(d->mActDebugInfo, &QAction::triggered, this, [this] (bool ) { if (d->mConnDialog.isNull()) { d->mConnDialog.reset(new NmList{Tray::tr("nm-tray info"), &d->mNmModel}); connect(d->mConnDialog.data(), &QDialog::finished, [this] { d->mConnDialog.reset(nullptr); }); } d->openCloseDialog(d->mConnDialog.data()); }); connect(d->mRequestScan, &QAction::triggered, &d->mNmModel, &NmModel::requestAllWifiScan); // Note: Force all the updates as the NetworkManager::Notifier signals aren't // emitted at application startup. d->primaryConnectionUpdate(); setActionsStates(); connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, &d->mStateTimer, static_cast(&QTimer::start)); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, &d->mStateTimer, static_cast(&QTimer::start)); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, &d->mStateTimer, static_cast(&QTimer::start)); connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionChanged, this, &Tray::onPrimaryConnectionChanged); connect(&d->mActiveConnections, &QAbstractItemModel::rowsInserted, [this] (QModelIndex const & parent, int first, int last) { for (int i = first; i <= last; ++i) { const QModelIndex index = d->mActiveConnections.index(i, 0, parent); //qCDebug(NM_TRAY) << "rowsInserted" << index; if (d->mEnableNotifications) { d->mConnectionsToNotify.append(index); } d->updateState(index, false); } }); connect(&d->mActiveConnections, &QAbstractItemModel::rowsAboutToBeRemoved, [this] (QModelIndex const & parent, int first, int last) { //qCDebug(NM_TRAY) << "rowsAboutToBeRemoved"; for (int i = first; i <= last; ++i) d->updateState(d->mActiveConnections.index(i, 0, parent), true); }); connect(&d->mActiveConnections, &QAbstractItemModel::dataChanged, [this] (const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector & /*roles*/) { //qCDebug(NM_TRAY) << "dataChanged"; for (auto const & i : QItemSelection{topLeft, bottomRight}.indexes()) d->updateState(i, false); }); d->mTrayIcon.setContextMenu(&d->mContextMenu); QTimer::singleShot(0, [this] { d->mTrayIcon.show(); }); } Tray::~Tray() { } bool Tray::eventFilter(QObject * object, QEvent * event) { Q_ASSERT(&d->mContextMenu == object); if (QEvent::ThemeChange == event->type()) d->refreshIcon(); return false; } void Tray::onEditConnectionsTriggered() { const QStringList connections_editor = QSettings{}.value(CONNECTIONS_EDITOR, QStringList{{"xterm", "-e", "nmtui-edit"}}).toStringList(); if (connections_editor.empty() || connections_editor.front().isEmpty()) { qCCritical(NM_TRAY) << "Can't start connection editor, because of misconfiguration. Value of" << CONNECTIONS_EDITOR << "invalid key," << connections_editor; return; } // Note: let this object dangle, if the process isn't finished until our application is closed QProcess * editor = new QProcess; editor->setProcessChannelMode(QProcess::ForwardedChannels); connect(editor, static_cast(&QProcess::finished) , [connections_editor, editor] (int exitCode, QProcess::ExitStatus exitStatus) { qCInfo(NM_TRAY) << "connection editor " << connections_editor << " finished, exitCode=" << exitCode << ", exitStatus=" << exitStatus; editor->deleteLater(); }); connect(editor, &QProcess::errorOccurred , [connections_editor, editor] (QProcess::ProcessError error) { qCInfo(NM_TRAY) << "connection editor " << connections_editor << " failed, error=" << error; editor->deleteLater(); }); qCInfo(NM_TRAY) << "starting connection editor " << connections_editor; QString program = connections_editor.front(); QStringList args; std::copy(connections_editor.cbegin() + 1, connections_editor.cend(), std::back_inserter(args)); editor->start(program, args); editor->closeWriteChannel(); } void Tray::onAboutTriggered() { QMessageBox::about(nullptr, Tray::tr("%1 about").arg(QStringLiteral("nm-tray")) , Tray::tr("nm-tray is a simple Qt based" " frontend for NetworkManager.

" "Version: %1").arg(NM_TRAY_VERSION)); } void Tray::onQuitTriggered() { QApplication::instance()->quit(); } void Tray::onActivated(const QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::Trigger: case QSystemTrayIcon::DoubleClick: { QMenu * menu = new WindowMenu(&d->mNmModel); menu->setAttribute(Qt::WA_DeleteOnClose); menu->popup(QCursor::pos()); } break; default: break; } } void Tray::setActionsStates() { const bool net_enabled = NetworkManager::isNetworkingEnabled(); d->mActEnableNetwork->setChecked(net_enabled); d->mActEnableWifi->setChecked(NetworkManager::isWirelessEnabled()); const bool wifi_enabled = NetworkManager::isNetworkingEnabled() && NetworkManager::isWirelessHardwareEnabled(); d->mActEnableWifi->setEnabled(wifi_enabled); d->mRequestScan->setEnabled(wifi_enabled); d->mActConnInfo->setEnabled(net_enabled); } void Tray::onPrimaryConnectionChanged(QString const & /*uni*/) { d->primaryConnectionUpdate(); } nm-tray-0.4.3/src/tray.h000066400000000000000000000027301352047236400150340ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2015~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(TRAY_H) #define TRAY_H #include #include #include class TrayPrivate; class Tray : public QObject { Q_OBJECT public: Tray(QObject *parent = nullptr); ~Tray(); protected: virtual bool eventFilter(QObject * object, QEvent * event) override; private Q_SLOTS: //menu void onEditConnectionsTriggered(); void onAboutTriggered(); void onQuitTriggered(); void onActivated(const QSystemTrayIcon::ActivationReason reason); //NetworkManager void setActionsStates(); void onPrimaryConnectionChanged(QString const & uni); private: QScopedPointer d; }; #endif //TRAY_H nm-tray-0.4.3/src/windowmenu.cpp000066400000000000000000000156101352047236400166050ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2016~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #include "windowmenu.h" #include "nmmodel.h" #include "nmproxy.h" #include "menuview.h" #include #include #include class WindowMenuPrivate { public: NmModel * mNmModel; QScopedPointer mWirelessModel; QWidgetAction * mWirelessAction; QScopedPointer mActiveModel; QWidgetAction * mActiveAction; QScopedPointer mConnectionModel; QWidgetAction * mConnectionAction; QAction * mMakeDirtyAction; QTimer mDelaySizeRefreshTimer; WindowMenuPrivate(WindowMenu * q); template void onActivated(QModelIndex const & index , QAbstractItemModel const * topParent , F const & functor); void forceSizeRefresh(); void onViewRowChange(QAction * viewAction, QAbstractItemModel const * model); private: WindowMenu * q_ptr; Q_DECLARE_PUBLIC(WindowMenu); }; WindowMenuPrivate::WindowMenuPrivate(WindowMenu * q) : q_ptr{q} { } template void WindowMenuPrivate::onActivated(QModelIndex const & index , QAbstractItemModel const * topParent , F const & functor) { QModelIndex i = index; for (QAbstractProxyModel const * proxy = qobject_cast(index.model()) ; nullptr != proxy && topParent != proxy ; proxy = qobject_cast(proxy->sourceModel()) ) { i = proxy->mapToSource(i); } functor(i); } void WindowMenuPrivate::forceSizeRefresh() { Q_Q(WindowMenu); if (!q->isVisible()) { return; } const QSize old_size = q->size(); //TODO: how to force the menu to recalculate it's size in a more elegant way? q->addAction(mMakeDirtyAction); q->removeAction(mMakeDirtyAction); // ensure to be visible (should the resize make it out of screen) if (old_size != q->size()) { q->popup(q->geometry().topLeft()); } } void WindowMenuPrivate::onViewRowChange(QAction * viewAction, QAbstractItemModel const * model) { viewAction->setVisible(model->rowCount(QModelIndex{}) > 0); mDelaySizeRefreshTimer.start(); } WindowMenu::WindowMenu(NmModel * nmModel, QWidget * parent /*= nullptr*/) : QMenu{parent} , d_ptr{new WindowMenuPrivate{this}} { Q_D(WindowMenu); d->mNmModel = nmModel; //active proxy & widgets d->mActiveModel.reset(new NmProxy); d->mActiveModel->setNmModel(d->mNmModel, NmModel::ActiveConnectionType); MenuView * active_view = new MenuView{d->mActiveModel.data()}; connect(active_view, &QAbstractItemView::activated, [this, d] (const QModelIndex & index) { d->onActivated(index, d->mActiveModel.data(), std::bind(&NmProxy::deactivateConnection, d->mActiveModel.data(), std::placeholders::_1)); close(); }); d->mActiveAction = new QWidgetAction{this}; d->mActiveAction->setDefaultWidget(active_view); connect(d->mActiveModel.data(), &QAbstractItemModel::modelReset, [d] { d->onViewRowChange(d->mActiveAction, d->mActiveModel.data()); }); connect(d->mActiveModel.data(), &QAbstractItemModel::rowsInserted, [d] { d->onViewRowChange(d->mActiveAction, d->mActiveModel.data()); }); connect(d->mActiveModel.data(), &QAbstractItemModel::rowsRemoved, [d] { d->onViewRowChange(d->mActiveAction, d->mActiveModel.data()); }); //wireless proxy & widgets d->mWirelessModel.reset(new NmProxy); d->mWirelessModel->setNmModel(d->mNmModel, NmModel::WifiNetworkType); MenuView * wifi_view = new MenuView{d->mWirelessModel.data()}; connect(wifi_view, &QAbstractItemView::activated, [this, d] (const QModelIndex & index) { d->onActivated(index, d->mWirelessModel.data(), std::bind(&NmProxy::activateConnection, d->mWirelessModel.data(), std::placeholders::_1)); close(); }); d->mWirelessAction = new QWidgetAction{this}; d->mWirelessAction->setDefaultWidget(wifi_view); connect(d->mWirelessModel.data(), &QAbstractItemModel::modelReset, [d] { d->onViewRowChange(d->mWirelessAction, d->mWirelessModel.data()); }); connect(d->mWirelessModel.data(), &QAbstractItemModel::rowsInserted, [d] { d->onViewRowChange(d->mWirelessAction, d->mWirelessModel.data()); }); connect(d->mWirelessModel.data(), &QAbstractItemModel::rowsRemoved, [d] { d->onViewRowChange(d->mWirelessAction, d->mWirelessModel.data()); }); //connection proxy & widgets d->mConnectionModel.reset(new NmProxy); d->mConnectionModel->setNmModel(d->mNmModel, NmModel::ConnectionType); MenuView * connection_view = new MenuView{d->mConnectionModel.data()}; connect(connection_view, &QAbstractItemView::activated, [this, d] (const QModelIndex & index) { d->onActivated(index, d->mConnectionModel.data(), std::bind(&NmProxy::activateConnection, d->mConnectionModel.data(), std::placeholders::_1)); close(); }); d->mConnectionAction = new QWidgetAction{this}; d->mConnectionAction->setDefaultWidget(connection_view); connect(d->mConnectionModel.data(), &QAbstractItemModel::modelReset, [d] { d->onViewRowChange(d->mConnectionAction, d->mConnectionModel.data()); }); connect(d->mConnectionModel.data(), &QAbstractItemModel::rowsInserted, [d] { d->onViewRowChange(d->mConnectionAction, d->mConnectionModel.data()); }); connect(d->mConnectionModel.data(), &QAbstractItemModel::rowsRemoved, [d] { d->onViewRowChange(d->mConnectionAction, d->mConnectionModel.data()); }); addAction(tr("Active connection(s)"))->setEnabled(false); addAction(d->mActiveAction); addAction(tr("Wi-Fi network(s)"))->setEnabled(false); addAction(d->mWirelessAction); addAction(tr("Known connection(s)"))->setEnabled(false); addAction(d->mConnectionAction); d->mMakeDirtyAction = new QAction{this}; d->mDelaySizeRefreshTimer.setInterval(200); d->mDelaySizeRefreshTimer.setSingleShot(true); connect(&d->mDelaySizeRefreshTimer, &QTimer::timeout, [d] { d->forceSizeRefresh(); }); d->onViewRowChange(d->mActiveAction, d->mActiveModel.data()); d->onViewRowChange(d->mWirelessAction, d->mWirelessModel.data()); d->onViewRowChange(d->mConnectionAction, d->mConnectionModel.data()); } WindowMenu::~WindowMenu() { } nm-tray-0.4.3/src/windowmenu.h000066400000000000000000000022311352047236400162450ustar00rootroot00000000000000/*COPYRIGHT_HEADER This file is a part of nm-tray. Copyright (c) 2016~now Palo Kisa nm-tray 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. COPYRIGHT_HEADER*/ #if !defined(WINDOW_MENU_H) #define WINDOW_MENU_H #include class WindowMenuPrivate; class NmModel; class WindowMenu : public QMenu { Q_OBJECT public: WindowMenu(NmModel * nmModel, QWidget * parent = nullptr); ~WindowMenu(); private: QScopedPointer d_ptr; Q_DECLARE_PRIVATE(WindowMenu); }; #endif //WINDOW_MENU_H nm-tray-0.4.3/translations/000077500000000000000000000000001352047236400156345ustar00rootroot00000000000000nm-tray-0.4.3/translations/nm-tray.ts000066400000000000000000000240321352047236400175740ustar00rootroot00000000000000 ConnectionInfo Connection information NmList All information Active connections Available wireless NmModel nm-tray - wireless password Password is needed for connection to '%1': root active connection(s) connection(s) device(s) wifi network(s) unknown hardware address General Active connection information Interface Active connection information Hardware Address Active connection information Driver Active connection information Speed Active connection information Kb/s unknown Speed Security Active connection information IPv4 Active connection information IPv6 Active connection information IP Address Active connection information Subnet Mask Active connection information Default route Active connection information DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>No active connection</pre> Connection lost No longer connected to %1 '%2'. Connection established Now connected to %1 '%2'. NetworkManager(nm-tray) Enable Networking Enable Wi-Fi Enable notifications Connection information Debug information Wifi - request scan Edit connections... About Quit nm-tray info %1 about <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 WindowMenu Active connection(s) Wi-Fi network(s) Known connection(s) nm-tray-0.4.3/translations/nm-tray_ca.ts000066400000000000000000000246601352047236400202460ustar00rootroot00000000000000 ConnectionInfo Connection information Informació de la connexió NmList Dialog Diàleg All information Tota la informació Active connections Connexions actives Available wireless Xarxes disponibles sense fil NmModel nm-tray - wireless password nm-tray - contrasenya de la xarxa sense fil Password is needed for connection to '%1': Cal una contrasenya per a la connexió a «%1»: root arrel active connection(s) connexions actives connection(s) connexions device(s) dispositius wifi network(s) xarxes wifi unknown hardware address desconeguda General Active connection information Interface Active connection information Interfície Hardware Address Active connection information Adreça de maquinari Driver Active connection information Controlador Speed Active connection information Velocitat Kb/s unknown Speed desconeguda Security Active connection information Seguretat IPv4 Active connection information IPv6 Active connection information IP Address Active connection information Adreça IP Subnet Mask Active connection information Màscara de subxarxa Default route Active connection information Encaminament predeterminat DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Connexió <strong>%1</strong>(%2) activa</pre> <pre>No active connection</pre> <pre>No hi ha cap connexió activa</pre> Connection lost Connexió perduda No longer connected to %1 '%2'. Ja no està connectat a %1 '%2'. Connection established Connexió establerta Now connected to %1 '%2'. Està connectat a %1 '%2'. NetworkManager(nm-tray) Enable Networking Habilita la xarxa Enable Wi-Fi Habilita el Wi-Fi Enable notifications Habilita les notificacions Connection information Informació de la connexió Debug information Informació de depuració Wifi - request scan Edit connections... Edita les connexions... About Quant a Quit Surt nm-tray info Informació de nm-tray %1 about Quant a %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> és un frontal en Qt senzill per <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Versió: %1 WindowMenu Active connection(s) Connexions actives Wi-Fi network(s) Xarxes Wi-Fi Known connection(s) Connexions conegudes nm-tray-0.4.3/translations/nm-tray_cs.ts000066400000000000000000000243731352047236400202710ustar00rootroot00000000000000 ConnectionInfo Connection information Informace o spojení NmList All information Všechny informace Active connections Aktivní připojení Available wireless Bezdrátové sítě k dispozici NmModel nm-tray - wireless password nm-tray – heslo k bezdrátové síti Password is needed for connection to '%1': Pro připojení k „%1“ je třeba heslo: root active connection(s) aktivní spojení connection(s) spojení device(s) zařízení wifi network(s) WiFi sítě unknown hardware address neznámé General Active connection information Obecné Interface Active connection information Rozhraní Hardware Address Active connection information Hardwarová (MAC) adresa Driver Active connection information Ovladač Speed Active connection information Rychlost Kb/s unknown Speed neznámá Security Active connection information Zabezpečení IPv4 Active connection information IPv6 Active connection information IP Address Active connection information IP Adresa Subnet Mask Active connection information Maska sítě Default route Active connection information Výchozí trasa DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Spojení <strong>%1</strong>(%2) aktivní</pre> <pre>No active connection</pre> <pre>Žádné aktivní spojení</pre> Connection lost Spojení ztraceno No longer connected to %1 '%2'. Nadále už nepřipojeno k %1 „%2“. Connection established Spojení navázáno Now connected to %1 '%2'. Nyní připojeno k %1 „%2“. NetworkManager(nm-tray) Enable Networking Zapnout síť Enable Wi-Fi Zapnout WiFi Enable notifications Zapnout oznamování Connection information Informace o připojení Debug information Ladící informace Wifi - request scan Wifi – vyžádat sken Edit connections... Upravit připojení… About O aplikaci Quit Ukončit nm-tray info nm-tray informace %1 about o %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> je jednoduchá nadstavba pro <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>, založená na Qt.<br/><br/>Verze: %1 WindowMenu Active connection(s) Aktivní připojení Wi-Fi network(s) WiFi sítě Known connection(s) Známá připojení nm-tray-0.4.3/translations/nm-tray_da.ts000066400000000000000000000243741352047236400202510ustar00rootroot00000000000000 ConnectionInfo Connection information Forbindelsesinformation NmList All information Al information Active connections Aktive forbindelser Available wireless Tilgængelige trådløse NmModel nm-tray - wireless password nm-tray - adgangskode til trådløs Password is needed for connection to '%1': Der kræves adgangskode for at oprette forbindelse til '%1': root active connection(s) aktive forbindelser connection(s) forbindelse(r) device(s) enhed(er) wifi network(s) wifi-netværk unknown hardware address ukendt General Active connection information Generelt Interface Active connection information Grænseflade Hardware Address Active connection information Hardwareadresse Driver Active connection information Speed Active connection information Hastighed Kb/s unknown Speed ukendt Security Active connection information Sikkerhed IPv4 Active connection information IPv6 Active connection information IP Address Active connection information IP-adresse Subnet Mask Active connection information Subnet-maske Default route Active connection information Standardrute DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Forbindelse <strong>%1</strong>(%2) aktiv</pre> <pre>No active connection</pre> <pre>Ingen aktiv forbindelse</pre> Connection lost Forbindelse mistet No longer connected to %1 '%2'. Ikke længere forbundet til %1 '%2'. Connection established Forbindelse etableret Now connected to %1 '%2'. Nu forbundet til %1 '%2'. NetworkManager(nm-tray) Enable Networking Aktivér netværk Enable Wi-Fi Aktivér Wi-Fi Enable notifications Aktivér underretninger Connection information Forbindelsesinformation Debug information Fejlretinformation Wifi - request scan Wifi - anmod om skanning Edit connections... Rediger forbindelser... About Om Quit Afslut nm-tray info nm-tray-info %1 about %1 om <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> er en simpel Qt-baseret frontend til <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 WindowMenu Active connection(s) Aktive forbindelser Wi-Fi network(s) Wi-Fi-netværk Known connection(s) Kendte forbindelser nm-tray-0.4.3/translations/nm-tray_de.ts000066400000000000000000000265431352047236400202550ustar00rootroot00000000000000 ConnectionInfo Connection information Verbindungsinformationen NmList Dialog Did not translate as "Dialog" seems to get replaced with string "nm-tray info" from context "Tray". Dialog All information Verfügbare Informationen Active connections Aktive Verbindungen Available wireless Verfügbare drahtlose Verbindungen NmModel root Translated as "network" hence not literally at all. Not sure what's best here but this seems a bit more reasonable to me. Netzwerk active connection(s) Aktive Verbindungen connection(s) Verbindung(en) device(s) Gerät(e) wifi network(s) WLAN-Netzwerk(e) unknown hardware address unbekannt nm-tray - wireless password nm-Tray - WLAN-Passwort Password is needed for connection to '%1': Passwort wird für die Verbindung zu „%1“ benötigt: General Active connection information Allgemeines Interface Active connection information Schnittstelle Hardware Address Active connection information Hardware-Adresse Driver Active connection information Treiber Speed Active connection information Übertragungsrate Kb/s Kb/s unknown Speed unbekannt Security Active connection information Sicherheit IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information IP-Adresse Subnet Mask Active connection information Subnetzmaske Default route Active connection information Standardroute DNS(%1) Active connection information DNS(%1) Tray Connection lost Die Verbindung wurde unterbrochen Connection established Verbindung hergestellt NetworkManager(nm-tray) NetworkManager (nm-Tray) Enable Networking Netzwerk aktivieren Enable Wi-fi Drahtlose Verbindungen aktivieren <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Verbindung <strong>%1</strong>(%2) aktiv</pre> <pre>No active connection</pre> <pre>Keine aktive Verbindung </pre> No longer connected to %1 '%2'. Nicht mehr verbunden mit %1 „%2“. Now connected to %1 '%2'. Jetzt verbunden mit %1 „%2“. Enable Wi-Fi WLAN aktivieren Enable notifications Benachrichtigungen aktivieren Connection information Verbindungsinformationen Debug information Debuginformationen Wifi - request scan WLAN - Scan anfordern Edit connections... Verbindungen bearbeiten … About Über Quit Beenden %1 about %1 über <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a><></strong> ist ein einfaches Qt-basiertes Frontend für den <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 This is the about nm-tray! Pimped this a little bit. Hope that's okay. nm-tray ist eine auf Qt basierende Nutzeroberfläche für den NetworkManager zur Ausführung in der Leiste von Desktop-Umgebungen. nm-tray info nm-tray Informationen WindowMenu Active connection(s) Aktive Verbindungen Wi-Fi network(s) WLAN-Netzwerk(e) Known connection(s) Bekannte Verbindung(en) nm-tray-0.4.3/translations/nm-tray_es.ts000066400000000000000000000244761352047236400202770ustar00rootroot00000000000000 ConnectionInfo Connection information Información de la conexión NmList All information Toda la información Active connections Conexiones activas Available wireless Redes inalámbricas disponibles NmModel nm-tray - wireless password nm-tray - contraseña del wireless Password is needed for connection to '%1': Se necesita una contraseña para conectarse a «%1»: root active connection(s) conexiones activas connection(s) conexiones device(s) dispositivos wifi network(s) redes wifi unknown hardware address desconocida General Active connection information General Interface Active connection information Interfaz Hardware Address Active connection information Dirección hardware Driver Active connection information Controlador Speed Active connection information Velocidad Kb/s Kb/s unknown Speed Desconocida Security Active connection information Seguridad IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information Dirección IP Subnet Mask Active connection information Mácara de subred Default route Active connection information Ruta por defecto DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Conexión <strong>%1</strong>(%2) activa</pre> <pre>No active connection</pre> <pre>Conexión no activa</pre> Connection lost Conexión perdida No longer connected to %1 '%2'. Sin conexión con %1 «%2». Connection established Conexión establecida Now connected to %1 '%2'. Conectado a %1 «%2». NetworkManager(nm-tray) NetworkManager(nm-tray) Enable Networking Habilitar la red Enable Wi-Fi Habilitar Wi-Fi Enable notifications Habilitar las notificaciones Connection information Información de la conexión Debug information Información de depuración Wifi - request scan Wifi - requiere escaneo Edit connections... Editar las conexiones... About Acerca de Quit Salir nm-tray info nm-tray info %1 about Acerca de %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> es una interfaz simple basada en Qt para <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Versión: %1 WindowMenu Active connection(s) Conexiones activas Wi-Fi network(s) Redes Wi-Fi Known connection(s) Conexiones conocidas nm-tray-0.4.3/translations/nm-tray_fr.ts000066400000000000000000000247021352047236400202670ustar00rootroot00000000000000 ConnectionInfo Connection information Informations de connexion NmList Dialog Dialogue All information Toutes les informations Active connections Connexions actives Available wireless Sans-fil disponible NmModel nm-tray - wireless password nm-tray - mot de passe sans-fil Password is needed for connection to '%1': Mot de passe nécessaire pour la connexion à '%1' : root active connection(s) connexion(s) active(s) connection(s) connexion(s) device(s) périphérique(s) wifi network(s) réseau(x) wifi unknown hardware address inconnu General Active connection information Général Interface Active connection information Hardware Address Active connection information Adresse matérielle Driver Active connection information Pilote Speed Active connection information Vitesse Kb/s unknown Speed inconnu Security Active connection information Sécurité IPv4 Active connection information IPv6 Active connection information IP Address Active connection information Adresse IP Subnet Mask Active connection information Masque de sous-réseau Default route Active connection information Route par défaut DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Connexion <strong>%1</strong>(%2) active</pre> <pre>No active connection</pre> <pre>Pas de connexion active</pre> Connection lost Connexion perdue No longer connected to %1 '%2'. Plus connecté à %1 '%2'. Connection established Connexion établie Now connected to %1 '%2'. Connecté à présent à %1 '%2'. NetworkManager(nm-tray) Enable Networking Activer le réseau Enable Wi-Fi Activer le Wi-Fi Enable notifications Activer les notifications Connection information Informations de connexion Debug information Informations de débogage Wifi - request scan Wifi - demande d'analyse Edit connections... Éditer les connexions... About À propos Quit Quitter nm-tray info Infos nm-tray %1 about à propos de %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> est une interface graphique simple basée sur Qt pour <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version : %1 WindowMenu Active connection(s) Connexion(s) active(s) Wi-Fi network(s) Réseau(x) Wi-Fi Known connection(s) Connexion(s) connue(s) nm-tray-0.4.3/translations/nm-tray_he.ts000066400000000000000000000252121352047236400202510ustar00rootroot00000000000000 ConnectionInfo Connection information פרטי החיבור NmList Dialog תיבת דו־שיח All information כל הפרטים Active connections חיבורים פעילים Available wireless אלחוטיות זמינות NmModel root active connection(s) חיבורים פעילים connection(s) חיבורים device(s) התקנים wifi network(s) רשתות אלחוטיות unknown hardware address לא ידוע nm-tray - wireless password nm-tray - ססמה לרשת אלחוטית Password is needed for connection to '%1': נדרשת ססמה כדי להתחבר אל ‚%1’: General Active connection information כללי Interface Active connection information מנשק Hardware Address Active connection information כתובת חומרה Driver Active connection information מנהל התקן Speed Active connection information מהירות Kb/s קסל״ש unknown Speed לא ידועה Security Active connection information אבטחה IPv4 Active connection information IPv6 Active connection information IP Address Active connection information כתובת IP Subnet Mask Active connection information מסכת רשת Default route Active connection information נתיב בררת מחדל DNS(%1) Active connection information Tray Connection lost החיבור נותק Connection established החיבור הצליח NetworkManager(nm-tray) Enable Networking הפעלת קישוריות רשת <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>החיבור <strong>%1</strong>(%2) פעיל</pre> <pre>No active connection</pre> <pre>אין חיבורים פעילים</pre> No longer connected to %1 '%2'. החיבור אל %1 נותק ‚%2’. Now connected to %1 '%2'. הצלחנו להתחבר אל %1 ‚%2’. Enable Wi-Fi הפעלת חיבור אלחוטי Enable notifications הפעלת התרעות Connection information פרטי החיבור Debug information פרטים לניפוי שגיאות Wifi - request scan רשת אלחוטית - בקשת סריקה Edit connections... עריכת חיבורים… About על אודות Quit יציאה %1 about על אודות %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> הוא מנשק מבוסס Qt עבור <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>גרסה: %1 nm-tray info פרטי nm-tray WindowMenu Active connection(s) חיבורים פעילים Wi-Fi network(s) רשתות אלחוטיות Known connection(s) חיבורים מוכרים nm-tray-0.4.3/translations/nm-tray_lt.ts000066400000000000000000000247011352047236400202760ustar00rootroot00000000000000 ConnectionInfo Connection information Ryšio informacija NmList Dialog Dialogas All information Visa informacija Active connections Aktyvūs ryšiai Available wireless Prieinami belaidžiai NmModel nm-tray - wireless password nm-tray - belaidžio slaptažodis Password is needed for connection to '%1': Norint prisijungti prie "%1", reikalingas slaptažodis: root šaknis active connection(s) aktyvus ryšys(-iai) connection(s) ryšys(-iai) device(s) įrenginys(-iai) wifi network(s) belaidis tinklas(-ai) unknown hardware address nežinoma General Active connection information Bendra Interface Active connection information Sąsaja Hardware Address Active connection information Aparatinės įrangos adresas Driver Active connection information Tvarkyklė Speed Active connection information Greitis Kb/s unknown Speed nežinoma Security Active connection information Saugumas IPv4 Active connection information IPv6 Active connection information IP Address Active connection information IP adresas Subnet Mask Active connection information Potinklio kaukė Default route Active connection information Numatytasis maršrutas DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Ryšys <strong>%1</strong>(%2) aktyvus</pre> <pre>No active connection</pre> <pre>Nėra aktyvių ryšių</pre> Connection lost Ryšys nutrūko No longer connected to %1 '%2'. Daugiau nebeprisijungta prie %1 "%2". Connection established Ryšys užmegztas Now connected to %1 '%2'. Dabar prisijungta prie %1 "%2". NetworkManager(nm-tray) Enable Networking Įjungti darbą tinkle Enable Wi-Fi Įjungti belaidį Enable notifications Įjungti pranešimus Connection information Ryšio informacija Debug information Derinimo informacija Wifi - request scan Belaidis - skenuoti tinklus Edit connections... Taisyti ryšius... About Apie Quit Išeiti nm-tray info nm-tray informacija %1 about Apie %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> yra paprasta Qt pagrįsta naudotojo sąsaja, kuri skirta <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Versija: %1 WindowMenu Active connection(s) Aktyvus ryšys(-iai) Wi-Fi network(s) Belaidis tinklas(-ai) Known connection(s) Žinomas ryšys(-iai) nm-tray-0.4.3/translations/nm-tray_nb_NO.ts000066400000000000000000000252531352047236400206550ustar00rootroot00000000000000 ConnectionInfo Connection information Tilkoblingsinformasjon NmList All information All informasjon Active connections Aktive tilkoblinger Available wireless Tilgjengelige trådløsnettverk NmModel root active connection(s) aktiv(e) tilkobling(er) connection(s) tilkobling(er) device(s) enhet(er) wifi network(s) unknown hardware address ukjent nm-tray - wireless password nm-tray - trådløspassord Password is needed for connection to '%1': Passord kreves for tilkobling til '%1': General Active connection information Interface Active connection information Grensesnitt Hardware Address Active connection information Driver Active connection information Speed Active connection information Hastighet Kb/s unknown Speed ukjent Security Active connection information Sikkerhet IPv4 Active connection information IPv6 Active connection information IP Address Active connection information Subnet Mask Active connection information Nettmaske Default route Active connection information DNS(%1) Active connection information Tray Connection lost Tilknytningen gitt tapt We have just lost the connection to %1 '%2'. Mistet tilknytningen til %1 '%2'. Connection established Tilkobling opprettet We have just established the connection to %1 '%2'. Tilkobling etablert til %1 '%2'. NetworkManager(nm-tray) Enable Networking Skru på nettverk Enable Wi-fi Skru på Wi-Fi <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Tilkobling <strong>%1</strong>(%2) aktiv</pre> <pre>No active connection</pre> <pre>Ingen aktive tilkoblinger</pre> No longer connected to %1 '%2'. Ikke lenger tilkoblet til %1 '%2'. Now connected to %1 '%2'. Nå tilkoblet til %1 '%2'. Enable Wi-Fi Skru på Wi-Fi Enable notifications Skru på merknader Connection information Tilkoblingsinformasjon Debug information Wifi - request scan Wi-Fi - forespør skanning Edit connections... Rediger tilkoblinger… About Om Quit Avslutt %1 about %1 om <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> er en enkel Qt-basert grenseflate for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 nm-tray info WindowMenu Active connection(s) Aktiv(e) tilkobling(er) Wi-Fi network(s) Known connection(s) Kjente tilkoblinger nm-tray-0.4.3/translations/nm-tray_nl.ts000066400000000000000000000246601352047236400202740ustar00rootroot00000000000000 ConnectionInfo Connection information Verbindingsinformatie NmList Dialog Dialoogvenster All information Alle informatie Active connections Actieve verbindingen Available wireless Beschikbare draadloze verbindingen NmModel nm-tray - wireless password nm-tray - draadloos wachtwoord Password is needed for connection to '%1': Het wachtwoord is benodigd om te verbinden met '%1': root active connection(s) actieve verbinding(en) connection(s) verbinding(en) device(s) appara(a)t(en) wifi network(s) wi-fi-netwerk(en) unknown hardware address onbekend General Active connection information Algemeen Interface Active connection information Uiterlijk Hardware Address Active connection information Hardware-adres Driver Active connection information Stuurprogramma Speed Active connection information Snelheid Kb/s unknown Speed onbekend Security Active connection information Beveiliging IPv4 Active connection information IPv6 Active connection information IP Address Active connection information IP-adres Subnet Mask Active connection information Subnet-mask Default route Active connection information Standaard route DNS(%1) Active connection information Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Verbinding <strong>%1</strong>(%2) actief</pre> <pre>No active connection</pre> <pre>Geen actieve verbinding</pre> Connection lost Verbinding verbroken No longer connected to %1 '%2'. Niet meer verbonden met %1 '%2'. Connection established Verbinding gemaakt Now connected to %1 '%2'. Nu verbonden met %1 '%2'. NetworkManager(nm-tray) Enable Networking Netwerk inschakelen Enable Wi-Fi Wi-Fi inschakelen Enable notifications Meldingen inschakelen Connection information Verbindingsinformatie Debug information Foutopsporingsinformatie Wifi - request scan Wi-Fi - verzoekscan Edit connections... Verbindingen bewerken... About Over Quit Afsluiten nm-tray info nm-tray informatie %1 about %1 over <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is eenvoudig, op Qt-gebaseerd frontend voor <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Versie: %1 WindowMenu Active connection(s) Actieve verbinding(en) Wi-Fi network(s) Wi-Fi-netwerk(en) Known connection(s) Opgeslagen verbinding(en) nm-tray-0.4.3/translations/nm-tray_pl.ts000066400000000000000000000260631352047236400202750ustar00rootroot00000000000000 ConnectionInfo Connection information Informacje o połączeniu NmList Dialog Okno dialogowe All information Wszystkie informacje Active connections Aktywne połączenia Available wireless Dostępne połączenia bezprzewodowe NmModel root root active connection(s) aktywne połączenia connection(s) połączenia device(s) urządzenia wifi network(s) sieci bezprzewodowe unknown hardware address nieznany nm-tray - wireless password nm-tray - hasło połączenia bezprzewodowego Password is needed for connection to '%1': Potrzebne jest hasło, aby połączyć się z '%1': General Active connection information Ogólne Interface Active connection information Interfejs Hardware Address Active connection information Adres urządzenia Driver Active connection information Informacje o aktywnym połączeniu Speed Active connection information Prędkość Kb/s Kb/s unknown Speed nieznana Security Active connection information Bezpieczeństwo IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information Adres IP Subnet Mask Active connection information Maska podsieci Default route Active connection information Brama domyślna DNS(%1) Active connection information DNS(%1) Tray Connection lost Utracono połączenie We have just lost the connection to %1 '%2'. Utracono połączenie z %1 '%2'. Connection established Ustanowiono połączenie We have just established the connection to %1 '%2'. Ustanowiono połączenie z %1 '%2'. NetworkManager(nm-tray) NetworkManager(nm-tray) Enable Networking Włącz sieci Enable Wi-fi Włącz Wi-Fi <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Połączenie <strong>%1</strong>(%2) aktywne</pre> <pre>No active connection</pre> <pre>Brak aktywnego połączenia</pre> No longer connected to %1 '%2'. Rozłączono z %1 '%2'. Now connected to %1 '%2'. Jesteś teraz połączony z %1 '%2'. Enable Wi-Fi Włącz Wi-Fi Enable notifications Włącz powiadomienia Connection information Informacje o połączeniu Debug information Informacje debugowania Wifi - request scan Edit connections... Edytuj połączenia… About O programie Quit Zakończ %1 about o %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> jest prostą, napisaną w Qt nakładką dla <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManagera</a>.<br/><br/>Wersja: %1 nm-tray info Informacje o nm-tray WindowMenu Active connection(s) Aktywne połączenia Wi-Fi network(s) Sieci Wi-Fi Known connection(s) Znane połączenia nm-tray-0.4.3/translations/nm-tray_pt_BR.ts000066400000000000000000000245051352047236400206670ustar00rootroot00000000000000 ConnectionInfo Connection information Informações da conexão NmList All information Todas as informações Active connections Conexões ativas Available wireless Redes wifi NmModel nm-tray - wireless password nm-tray - senha do wifi Password is needed for connection to '%1': A senha é necessária para conexão com '%1': root root active connection(s) conexão(ões) ativa connection(s) conexão(ões) device(s) dispositivo(s) wifi network(s) rede(s) wifi unknown hardware address desconhecido General Active connection information Geral Interface Active connection information Interface Hardware Address Active connection information Endereço de hardware Driver Active connection information Driver Speed Active connection information Velocidade Kb/s Kb/s unknown Speed desconhecido Security Active connection information Segurança IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information Endereço IP Subnet Mask Active connection information Máscara de sub-rede Default route Active connection information Rota padrão DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Conexão <strong>%1</strong>(%2) ativa</pre> <pre>No active connection</pre> <pre>Nenhuma conexão ativa</pre> Connection lost Conexão perdida No longer connected to %1 '%2'. Não está mais conectado a %1 '%2'. Connection established Conexão estabelecida Now connected to %1 '%2'. Conectado a %1 '%2'. NetworkManager(nm-tray) NetworkManager(nm-tray) Enable Networking Habilitar Rede Enable Wi-Fi Habilitar Wi-Fi Enable notifications Habilitar notificações Connection information Informações da conexão Debug information Informações de depuração Wifi - request scan Wifi - solicitar busca Edit connections... Editar conexões... About Sobre Quit Sair nm-tray info Informações sobre o nm-tray %1 about %1 sobre <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> é um frontend simples baseado em Qt para <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Versão: %1 WindowMenu Active connection(s) Conexão(ões) ativa Wi-Fi network(s) Rede(s) Wi-Fi Known connection(s) Conexões conhecidas nm-tray-0.4.3/translations/nm-tray_ru.ts000066400000000000000000000256261352047236400203140ustar00rootroot00000000000000 ConnectionInfo Connection information Информация о соединении NmList All information Вся информация Active connections Активные соединения Available wireless Доступные беспроводные сети NmModel nm-tray - wireless password nm-tray - пароль беспроводного соединения Password is needed for connection to '%1': Для соединения с '%1' требуется пароль: root root active connection(s) активные соединения connection(s) соединения device(s) устройства wifi network(s) сети wifi unknown hardware address неизвестно General Active connection information Общие Interface Active connection information Интерфейс Hardware Address Active connection information MAC-адрес Driver Active connection information Драйвер Speed Active connection information Скорость Kb/s Кб/с unknown Speed неизвестна Security Active connection information Защита IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information IP адрес Subnet Mask Active connection information Маска подсети Default route Active connection information Путь по умолчанию DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Соединение <strong>%1</strong>(%2) активно</pre> <pre>No active connection</pre> <pre>Нет активных соединений</pre> Connection lost Соединение потеряно No longer connected to %1 '%2'. Больше не присоединено к %1 '%2'. Connection established Соединение установлено Now connected to %1 '%2'. Соединён с %1 '%2'. NetworkManager(nm-tray) NetworkManager (nm-tray) Enable Networking Включить сеть Enable Wi-Fi Включить Wi-Fi Enable notifications Включить уведомления Connection information Информация о соединении Debug information Отладочная информация Wifi - request scan Wi-Fi - запрос сканирования Edit connections... Редактировать соединения... About О программе Quit Выход nm-tray info Информация о nm-tray %1 about О %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> простой Qt клиент <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Версия: %1 WindowMenu Active connection(s) Активные соединения Wi-Fi network(s) Сети Wi-Fi Known connection(s) Сохраненные соединения nm-tray-0.4.3/translations/nm-tray_sk.ts000066400000000000000000000246341352047236400203010ustar00rootroot00000000000000 ConnectionInfo Connection information Informácie o spojení NmList Dialog Dialóg All information Všetky informácie Active connections Aktívne spojenia Available wireless Dostupné bezdrôtové NmModel nm-tray - wireless password nm-tray - Wi-Fi heslo Password is needed for connection to '%1': Pre pripojenie k '%1' je potrebné heslo: root koreň active connection(s) aktívne spojenie/a connection(s) spojenie/a device(s) zariadenie/a wifi network(s) wifi sieť/te unknown hardware address neznáma General Active connection information Všeobecné Interface Active connection information Rozhranie Hardware Address Active connection information Hardvérová adresa Driver Active connection information Ovládač Speed Active connection information Rýchlosť Kb/s Kb/s unknown Speed neznáma Security Active connection information Bezpečnosť IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information IP adresa Subnet Mask Active connection information Maska podsiete Default route Active connection information Predvolená cesta DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Spojenie <strong>%1</strong>(%2) aktívne</pre> <pre>No active connection</pre> <pre>Žiadne aktívne spojenie</pre> Connection lost Spojenie stratené No longer connected to %1 '%2'. Už nie je spojenie k %1 '%2'. Connection established Spojenie naviazané Now connected to %1 '%2'. Aktuálne pripojený k %1 '%2'. NetworkManager(nm-tray) NetworkManager(nm-tray) Enable Networking Zapnúť sieť Enable Wi-Fi Zapnúť Wi-Fi Enable notifications Zapnúť notifikácie Connection information Informácie o spojení Debug information Debug informácie Wifi - request scan Edit connections... Editovať spojenia... About O aplikácii Quit Vypnúť nm-tray info nm-tray info %1 about %1 o aplikácii <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> je jednoduchý Qt frontend pre <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Verzia: %1 WindowMenu Active connection(s) Aktívne spojenie/a Wi-Fi network(s) Wi-Fi sieť/te Known connection(s) Známe spojenie/a nm-tray-0.4.3/translations/nm-tray_sv.ts000066400000000000000000000244351352047236400203130ustar00rootroot00000000000000 ConnectionInfo Connection information Anslutningsinformation NmList All information Fullständig information Active connections Aktiva anslutningar Available wireless Tillgängliga Wifi NmModel nm-tray - wireless password nm-tray - trådlöst lösenord Password is needed for connection to '%1': Lösenord krävs för anslutning till '%1': root root active connection(s) aktiv(a) anslutning(ar) connection(s) anslutning(ar) device(s) enhet(er) wifi network(s) Wifi-nätverk unknown hardware address okänd General Active connection information Allmänt Interface Active connection information Enhet Hardware Address Active connection information Hårdvaru-adress (MAC) Driver Active connection information Drivrutin Speed Active connection information Hastighet Kb/s Kb/s unknown Speed okänt Security Active connection information Säkerhet IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information IP-adress Subnet Mask Active connection information Nätmask Default route Active connection information Standard route DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Anslutning <strong>%1</strong>(%2) aktiv</pre> <pre>No active connection</pre> <pre>Ingen anslutning aktiv</pre> Connection lost Anslutningen försvann No longer connected to %1 '%2'. Ej längre ansluten till %1 '%2'. Connection established Anslutning etablerad Now connected to %1 '%2'. Ansluten till %1 '%2'. NetworkManager(nm-tray) NetworkManager (nm-tray) Enable Networking Aktivera nätverk Enable Wi-Fi Aktivera Wi-Fi Enable notifications Aktivera aviseringar Connection information Information om anslutningen Debug information Information för Debug Wifi - request scan Wifi - scan Edit connections... Ändra anslutningar... About Om Quit Avsluta nm-tray info nm-tray information %1 about %1 om <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> är en enkel Qt-baserad app för <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 WindowMenu Active connection(s) Aktiv(a) anslutning(ar) Wi-Fi network(s) Wi-Fi nätverk Known connection(s) Kända anslutningar nm-tray-0.4.3/translations/nm-tray_tr.ts000066400000000000000000000244561352047236400203130ustar00rootroot00000000000000 ConnectionInfo Connection information Bağlantı bilgileri NmList All information Tüm bilgiler Active connections Etkin bağlantılar Available wireless Mevcut kablosuz ağlar NmModel nm-tray - wireless password Password is needed for connection to '%1': '%1' bağlantısı için parola gerekiyor: root yönetici active connection(s) etkin bağlantı(lar) connection(s) bağlantı(lar) device(s) aygıt(lar) wifi network(s) kablosuz ağ(lar) unknown hardware address bilinmeyen General Active connection information Genel Interface Active connection information Arayüz Hardware Address Active connection information Donanım Adresi Driver Active connection information Sürücü Speed Active connection information Hız Kb/s Kb/sn unknown Speed bilinmeyen Security Active connection information Güvenlik IPv4 Active connection information IPv4 IPv6 Active connection information IPv6 IP Address Active connection information IP Adresi Subnet Mask Active connection information Alt Ağ Maskesi Default route Active connection information Öntanımlı rota DNS(%1) Active connection information DNS(%1) Tray <pre>Connection <strong>%1</strong>(%2) active</pre> <pre>Bağlantı <strong>%1</strong>(%2) etkin</pre> <pre>No active connection</pre> <pre>Etkin bağlantı yok</pre> Connection lost Bağlantı kaybedildi No longer connected to %1 '%2'. %1 bağlantısına artık bağlı değil '%2'. Connection established Bağlantı kuruldu Now connected to %1 '%2'. %1 bağlantısına yeni bağlantı '%2'. NetworkManager(nm-tray) NetworkManager(nm-tray) Enable Networking Eğ Etkin Enable Wi-Fi Kablosuz Ağ Etkin Enable notifications Bildirimler etkin Connection information Bağlantı bilgileri Debug information Hata ayıklama bilgileri Wifi - request scan Edit connections... Bağlantıları düzenle... About Hakkında Quit Kapat nm-tray info nm-tray bilgi %1 about %1 hakkında <strong><a href="https://github.com/palinek/nm-tray">nm-tray</a></strong> is a simple Qt based frontend for <a href="https://wiki.gnome.org/Projects/NetworkManager">NetworkManager</a>.<br/><br/>Version: %1 <strong><a href="https://github.com/palinek/nm-tray"></a></strong> <a href="https://wiki.gnome.org/Projects/NetworkManager"></a> için QT tabanlı basit bir arayüzdür. <br/><br/>Sürüm: %1 WindowMenu Active connection(s) Etkin bağlantı(lar) Wi-Fi network(s) Kablosuz ağ(lar) Known connection(s) Bilinen bağlantı(lar)