diff --git a/core/smb4kauthinfo.cpp b/core/smb4kauthinfo.cpp index da93ab7..ce2439d 100644 --- a/core/smb4kauthinfo.cpp +++ b/core/smb4kauthinfo.cpp @@ -1,243 +1,239 @@ /*************************************************************************** This class provides a container for the authentication data. ------------------- begin : Sa Feb 28 2004 copyright : (C) 2004-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kauthinfo.h" #include "smb4khost.h" #include "smb4kshare.h" // Qt includes #include #include // KDE includes #include class Smb4KAuthInfoPrivate { public: QUrl url; QString workgroup; NetworkItem type; bool homesShare; QHostAddress ip; }; Smb4KAuthInfo::Smb4KAuthInfo(Smb4KBasicNetworkItem* item) : d(new Smb4KAuthInfoPrivate) { d->type = item->type(); switch (d->type) { case Host: { Smb4KHost *host = static_cast(item); if (host) { d->url = host->url(); d->workgroup = host->workgroupName(); d->homesShare = false; d->ip.setAddress(host->ipAddress()); } break; } case Share: { Smb4KShare *share = static_cast(item); if (share) { d->url = !share->isHomesShare() ? share->homeUrl() : share->url(); d->workgroup = share->workgroupName(); d->homesShare = share->isHomesShare(); d->ip.setAddress(share->hostIpAddress()); } break; } default: { break; } } } Smb4KAuthInfo::Smb4KAuthInfo() : d(new Smb4KAuthInfoPrivate) { d->type = UnknownNetworkItem; d->homesShare = false; d->url.clear(); d->workgroup.clear(); d->ip.clear(); } Smb4KAuthInfo::Smb4KAuthInfo(const Smb4KAuthInfo &i) : d(new Smb4KAuthInfoPrivate) { *d = *i.d; } Smb4KAuthInfo::~Smb4KAuthInfo() { } void Smb4KAuthInfo::setWorkgroupName(const QString &workgroup) { d->workgroup = workgroup; } QString Smb4KAuthInfo::workgroupName() const { return d->workgroup; } void Smb4KAuthInfo::setUrl(const QUrl &url) { d->url = url; d->url.setScheme("smb"); // Set the type. if (!d->url.path().isEmpty() && d->url.path().length() > 1 && !d->url.path().endsWith('/')) { d->type = Share; } else { d->type = Host; } // Determine whether this is a homes share. d->homesShare = (QString::compare(d->url.path().remove('/'), "homes", Qt::CaseSensitive) == 0); } void Smb4KAuthInfo::setUrl(const QString &url) { QUrl tempUrl(url, QUrl::TolerantMode); tempUrl.setScheme("smb"); setUrl(tempUrl); } QUrl Smb4KAuthInfo::url() const { return d->url; } QString Smb4KAuthInfo::hostName() const { return d->url.host().toUpper(); } QString Smb4KAuthInfo::shareName() const { if (d->url.path().startsWith('/')) { return d->url.path().remove(0, 1); } return d->url.path(); } void Smb4KAuthInfo::setUserName(const QString &username) { d->url.setUserName(username); if (d->homesShare) { d->url.setPath(username); } } QString Smb4KAuthInfo::userName() const { return d->url.userName(); } void Smb4KAuthInfo::setPassword(const QString &passwd) { d->url.setPassword(passwd); } QString Smb4KAuthInfo::password() const { return d->url.password(); } Smb4KGlobal::NetworkItem Smb4KAuthInfo::type() const { return d->type; } bool Smb4KAuthInfo::isHomesShare() const { return d->homesShare; } void Smb4KAuthInfo::setIpAddress(const QString &ip) { d->ip.setAddress(ip); } QString Smb4KAuthInfo::ipAddress() const { return d->ip.toString(); } QString Smb4KAuthInfo::displayString() const { return i18n("%1 on %2", shareName(), hostName()); } diff --git a/core/smb4kbasicnetworkitem.cpp b/core/smb4kbasicnetworkitem.cpp index af55d25..7589bc6 100644 --- a/core/smb4kbasicnetworkitem.cpp +++ b/core/smb4kbasicnetworkitem.cpp @@ -1,173 +1,169 @@ /*************************************************************************** This class provides the basic network item for the core library of Smb4K. ------------------- begin : Do Apr 2 2009 copyright : (C) 2009-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbasicnetworkitem.h" // Qt includes #include #include using namespace Smb4KGlobal; class Smb4KBasicNetworkItemPrivate { public: NetworkItem type; QIcon icon; QUrl url; }; Smb4KBasicNetworkItem::Smb4KBasicNetworkItem(NetworkItem type) : d(new Smb4KBasicNetworkItemPrivate) { // // Set the type // d->type = type; // // Initialize the protected variables // pUrl = &d->url; pIcon = &d->icon; } Smb4KBasicNetworkItem::Smb4KBasicNetworkItem(const Smb4KBasicNetworkItem &item) : d(new Smb4KBasicNetworkItemPrivate) { // // Copy the private variables // *d = *item.d; // // Initialize the protected variables // pUrl = &d->url; pIcon = &d->icon; } Smb4KBasicNetworkItem::~Smb4KBasicNetworkItem() { } Smb4KGlobal::NetworkItem Smb4KBasicNetworkItem::type() const { return d->type; } void Smb4KBasicNetworkItem::setIcon(const QIcon &icon) { d->icon = icon; } QIcon Smb4KBasicNetworkItem::icon() const { return d->icon; } void Smb4KBasicNetworkItem::setUrl(const QUrl& url) { // // Check that the URL is valid // if (!url.isValid()) { return; } // // Do some checks depending on the type of the network item // switch (d->type) { case Network: { break; } case Workgroup: case Host: { // // Check that the host name is present and there is no path // if (url.host().isEmpty() || !url.path().isEmpty()) { return; } break; } case Share: { // // Check that the share name is present // if (url.path().isEmpty() || (url.path().size() == 1 && url.path().endsWith('/'))) { return; } break; } default: { break; } } // // Set the URL // d->url = url; // // Force the scheme // if (d->url.scheme() != "smb") { d->url.setScheme("smb"); } } QUrl Smb4KBasicNetworkItem::url() const { return d->url; } diff --git a/core/smb4kbookmark.cpp b/core/smb4kbookmark.cpp index eddcb63..efafd3a 100644 --- a/core/smb4kbookmark.cpp +++ b/core/smb4kbookmark.cpp @@ -1,249 +1,245 @@ /*************************************************************************** This is the bookmark container for Smb4K (next generation). ------------------- begin : So Jun 8 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbookmark.h" #include "smb4kshare.h" // Qt includes #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include using namespace Smb4KGlobal; class Smb4KBookmarkPrivate { public: QUrl url; QString workgroup; QHostAddress ip; QString label; QString group; QString profile; QIcon icon; Smb4KGlobal::ShareType type; }; Smb4KBookmark::Smb4KBookmark(Smb4KShare *share, const QString &label) : d(new Smb4KBookmarkPrivate) { if (!share->isHomesShare()) { d->url = share->url(); } else { d->url = share->homeUrl(); } d->workgroup = share->workgroupName(); d->type = share->shareType(); d->label = label; d->icon = KDE::icon("folder-network"); d->ip.setAddress(share->hostIpAddress()); } Smb4KBookmark::Smb4KBookmark(const Smb4KBookmark &b) : d(new Smb4KBookmarkPrivate) { *d = *b.d; } Smb4KBookmark::Smb4KBookmark() : d(new Smb4KBookmarkPrivate) { d->type = FileShare; d->icon = KDE::icon("folder-network"); } Smb4KBookmark::~Smb4KBookmark() { } void Smb4KBookmark::setWorkgroupName( const QString &workgroup ) { d->workgroup = workgroup; } QString Smb4KBookmark::workgroupName() const { return d->workgroup; } void Smb4KBookmark::setHostName(const QString &host) { d->url.setHost(host); d->url.setScheme("smb"); } QString Smb4KBookmark::hostName() const { return d->url.host().toUpper(); } void Smb4KBookmark::setShareName(const QString &share) { d->url.setPath(share); } QString Smb4KBookmark::shareName() const { if (d->url.path().startsWith('/')) { return d->url.path().remove(0, 1); } return d->url.path(); } void Smb4KBookmark::setHostIpAddress(const QString &ip) { d->ip.setAddress(ip); } QString Smb4KBookmark::hostIpAddress() const { return d->ip.toString(); } void Smb4KBookmark::setShareType(Smb4KGlobal::ShareType type) { d->type = type; } Smb4KGlobal::ShareType Smb4KBookmark::shareType() const { return d->type; } void Smb4KBookmark::setLabel(const QString &label) { d->label = label; } QString Smb4KBookmark::label() const { return d->label; } void Smb4KBookmark::setLogin(const QString &login) { d->url.setUserName(login); } QString Smb4KBookmark::login() const { return d->url.userName(); } void Smb4KBookmark::setUrl(const QUrl &url) { d->url = url; d->url.setScheme("smb"); } void Smb4KBookmark::setUrl(const QString &url) { d->url.setUrl(url, QUrl::TolerantMode); d->url.setScheme("smb"); } QUrl Smb4KBookmark::url() const { return d->url; } void Smb4KBookmark::setGroupName(const QString &name) { d->group = name; } QString Smb4KBookmark::groupName() const { return d->group; } void Smb4KBookmark::setProfile(const QString &profile) { d->profile = profile; } QString Smb4KBookmark::profile() const { return d->profile; } void Smb4KBookmark::setIcon(const QIcon &icon) { d->icon = icon; } QIcon Smb4KBookmark::icon() const { return d->icon; } QString Smb4KBookmark::displayString() const { return i18n("%1 on %2", shareName(), hostName()); } diff --git a/core/smb4kbookmarkhandler.cpp b/core/smb4kbookmarkhandler.cpp index 9aec094..322a8b6 100644 --- a/core/smb4kbookmarkhandler.cpp +++ b/core/smb4kbookmarkhandler.cpp @@ -1,672 +1,668 @@ /*************************************************************************** This class handles the bookmarks. ------------------- begin : Fr Jan 9 2004 copyright : (C) 2004-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbookmarkhandler.h" #include "smb4kbookmarkhandler_p.h" #include "smb4khomesshareshandler.h" #include "smb4kglobal.h" #include "smb4kbookmark.h" #include "smb4khost.h" #include "smb4kshare.h" #include "smb4ksettings.h" #include "smb4knotification.h" #include "smb4kprofilemanager.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include using namespace Smb4KGlobal; Q_GLOBAL_STATIC(Smb4KBookmarkHandlerStatic, p); Smb4KBookmarkHandler::Smb4KBookmarkHandler(QObject *parent) : QObject(parent), d(new Smb4KBookmarkHandlerPrivate) { // // First we need the directory. // QString path = dataLocation(); QDir dir; if (!dir.exists(path)) { dir.mkpath(path); } // // Read the list of bookmarks // readBookmarkList(); // // Init the bookmark editor // d->editor = 0; } Smb4KBookmarkHandler::~Smb4KBookmarkHandler() { while (!d->bookmarks.isEmpty()) { d->bookmarks.takeFirst().clear(); } } Smb4KBookmarkHandler *Smb4KBookmarkHandler::self() { return &p->instance; } void Smb4KBookmarkHandler::addBookmark(const SharePtr &share) { if (share) { QList shares; shares << share; addBookmarks(shares); } } void Smb4KBookmarkHandler::addBookmarks(const QList &list) { // // Prepare the list of bookmarks that should be added // QList newBookmarks; for (const SharePtr &share : list) { // // Printer shares cannot be bookmarked // if (share->isPrinter()) { Smb4KNotification::cannotBookmarkPrinter(share); continue; } // // Process homes shares // if (share->isHomesShare() && !Smb4KHomesSharesHandler::self()->specifyUser(share, true)) { continue; } // // Check if the share has already been bookmarked and skip it if it // already exists // BookmarkPtr knownBookmark = findBookmarkByUrl(share->isHomesShare() ? share->homeUrl() : share->url()); if (knownBookmark) { Smb4KNotification::bookmarkExists(knownBookmark.data()); continue; } BookmarkPtr bookmark = BookmarkPtr(new Smb4KBookmark(share.data())); bookmark->setProfile(Smb4KProfileManager::self()->activeProfile()); newBookmarks << bookmark; } // // Show the bookmark dialog, if necessary // if (!newBookmarks.isEmpty()) { QPointer dlg = new Smb4KBookmarkDialog(newBookmarks, groupsList(), QApplication::activeWindow()); if (dlg->exec() == QDialog::Accepted) { // The bookmark dialog uses an internal list of bookmarks, // so use that one instead of the temporary list created // above. addBookmarks(dlg->bookmarks(), false); } delete dlg; } // // Clear the temporary list of bookmarks // while (!newBookmarks.isEmpty()) { newBookmarks.takeFirst().clear(); } } void Smb4KBookmarkHandler::addBookmarks(const QList &list, bool replace) { // // Process the incoming list. // In case the internal list should be replaced, clear the internal // list first. // if (replace) { QMutableListIterator it(d->bookmarks); while (it.hasNext()) { BookmarkPtr bookmark = it.next(); if (Smb4KSettings::useProfiles() && bookmark->profile() != Smb4KProfileManager::self()->activeProfile()) { continue; } it.remove(); } } // // Copy all bookmarks that are not in the list // for (const BookmarkPtr &bookmark : list) { // // Check if the bookmark label is already in use // if (!bookmark->label().isEmpty() && findBookmarkByLabel(bookmark->label())) { Smb4KNotification::bookmarkLabelInUse(bookmark.data()); bookmark->setLabel(QString("%1 (1)").arg(bookmark->label())); } // // Check if we have to add the bookmark // BookmarkPtr existingBookmark = findBookmarkByUrl(bookmark->url()); if (!existingBookmark) { d->bookmarks << bookmark; } else { // We do not need to update the bookmark, because we are // operating on a shared pointer. } } // // Save the bookmark list and emit the updated() signal // writeBookmarkList(); emit updated(); } void Smb4KBookmarkHandler::removeBookmark(const BookmarkPtr &bookmark) { if (bookmark) { for (int i = 0; i < d->bookmarks.size(); ++i) { if ((!Smb4KSettings::useProfiles() || Smb4KSettings::activeProfile() == d->bookmarks.at(i)->profile()) && QString::compare(d->bookmarks.at(i)->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), bookmark->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 && QString::compare(bookmark->groupName(), d->bookmarks.at(i)->groupName(), Qt::CaseInsensitive) == 0) { d->bookmarks.takeAt(i).clear(); break; } } // Write the list to the bookmarks file. writeBookmarkList(); emit updated(); } } void Smb4KBookmarkHandler::removeGroup(const QString& name) { QMutableListIterator it(d->bookmarks); while (it.hasNext()) { const BookmarkPtr &b = it.next(); if ((!Smb4KSettings::useProfiles() || Smb4KSettings::activeProfile() == b->profile()) || QString::compare(b->groupName(), name, Qt::CaseInsensitive) == 0) { it.remove(); } } // Write the list to the bookmarks file. writeBookmarkList(); emit updated(); } void Smb4KBookmarkHandler::writeBookmarkList() { QFile xmlFile(dataLocation()+QDir::separator()+"bookmarks.xml"); if (!d->bookmarks.isEmpty()) { if (xmlFile.open(QIODevice::WriteOnly|QIODevice::Text)) { QXmlStreamWriter xmlWriter(&xmlFile); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("bookmarks"); xmlWriter.writeAttribute("version", "2.0"); for (const BookmarkPtr &bookmark : d->bookmarks) { if (!bookmark->url().isValid()) { Smb4KNotification::invalidURLPassed(); continue; } xmlWriter.writeStartElement("bookmark"); xmlWriter.writeAttribute("profile", bookmark->profile()); xmlWriter.writeAttribute("group", bookmark->groupName()); xmlWriter.writeTextElement("workgroup", bookmark->workgroupName()); xmlWriter.writeTextElement("url", bookmark->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort)); xmlWriter.writeTextElement("login", bookmark->login()); xmlWriter.writeTextElement("ip", bookmark->hostIpAddress()); xmlWriter.writeTextElement("label", bookmark->label()); xmlWriter.writeEndElement(); } xmlWriter.writeEndDocument(); xmlFile.close(); } else { Smb4KNotification::openingFileFailed(xmlFile); } } else { xmlFile.remove(); } } void Smb4KBookmarkHandler::readBookmarkList() { // // Clear the list of bookmarks // while (!d->bookmarks.isEmpty()) { d->bookmarks.takeFirst().clear(); } // // Locate the XML file and read the bookmarks // QFile xmlFile(dataLocation()+QDir::separator()+"bookmarks.xml"); if (xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QXmlStreamReader xmlReader(&xmlFile); while (!xmlReader.atEnd()) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "bookmarks" && (xmlReader.attributes().value("version") != "1.1" && xmlReader.attributes().value("version") != "2.0")) { xmlReader.raiseError(i18n("The format of %1 is not supported.", xmlFile.fileName())); break; } else { if (xmlReader.name() == "bookmark") { QString profile = xmlReader.attributes().value("profile").toString(); BookmarkPtr bookmark = BookmarkPtr(new Smb4KBookmark()); bookmark->setProfile(profile); bookmark->setGroupName(xmlReader.attributes().value("group").toString()); while (!(xmlReader.isEndElement() && xmlReader.name() == "bookmark")) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "workgroup") { bookmark->setWorkgroupName(xmlReader.readElementText()); } else if (xmlReader.name() == "unc") { bookmark->setUrl(xmlReader.readElementText()); } else if (xmlReader.name() == "url") { bookmark->setUrl(QUrl(xmlReader.readElementText())); } else if (xmlReader.name() == "login") { bookmark->setLogin(xmlReader.readElementText()); } else if (xmlReader.name() == "ip") { bookmark->setHostIpAddress(xmlReader.readElementText()); } else if (xmlReader.name() == "label") { bookmark->setLabel(xmlReader.readElementText()); } continue; } else { continue; } } d->bookmarks << bookmark; } else { continue; } } } else { continue; } } xmlFile.close(); if (xmlReader.hasError()) { Smb4KNotification::readingFileFailed(xmlFile, xmlReader.errorString()); } } else { if (xmlFile.exists()) { Smb4KNotification::openingFileFailed(xmlFile); } } emit updated(); } BookmarkPtr Smb4KBookmarkHandler::findBookmarkByUrl(const QUrl &url) { // Update the bookmarks: update(); // Find the bookmark: BookmarkPtr bookmark; if (!url.isEmpty() && url.isValid() && !bookmarksList().isEmpty()) { for (const BookmarkPtr &b : bookmarksList()) { if (QString::compare(b->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { bookmark = b; break; } } } return bookmark; } BookmarkPtr Smb4KBookmarkHandler::findBookmarkByLabel(const QString &label) { // Update the bookmarks: update(); // Find the bookmark: BookmarkPtr bookmark; for (const BookmarkPtr &b : bookmarksList()) { if (QString::compare(b->label().toUpper(), label.toUpper()) == 0) { bookmark = b; break; } else { continue; } } return bookmark; } QList Smb4KBookmarkHandler::bookmarksList() const { // Update the bookmarks: update(); // Get this list of the bookmarks if (Smb4KSettings::useProfiles()) { QList bookmarks; for (const BookmarkPtr &b : d->bookmarks) { if (b->profile() == Smb4KSettings::activeProfile()) { bookmarks << b; } } return bookmarks; } // Return the list of bookmarks: return d->bookmarks; } QList Smb4KBookmarkHandler::bookmarksList(const QString &group) const { // Update bookmarks update(); // Get the list of bookmarks organized in the given group QList bookmarks; for (const BookmarkPtr &bookmark : bookmarksList()) { if (QString::compare(group, bookmark->groupName(), Qt::CaseInsensitive) == 0) { bookmarks << bookmark; } } return bookmarks; } QStringList Smb4KBookmarkHandler::groupsList() const { QStringList groups; for (const BookmarkPtr &b : bookmarksList()) { if (!groups.contains(b->groupName())) { groups << b->groupName(); } } return groups; } void Smb4KBookmarkHandler::resetBookmarks() { readBookmarkList(); } bool Smb4KBookmarkHandler::isBookmarked(const SharePtr& share) { if (findBookmarkByUrl(share->url())) { return true; } return false; } void Smb4KBookmarkHandler::editBookmarks() { // // Only allow one instance of the bookmark editor // if (!d->editor) { d->editor = new Smb4KBookmarkEditor(bookmarksList(), QApplication::activeWindow()); } else { d->editor->raise(); } if (d->editor->exec() == QDialog::Accepted) { addBookmarks(d->editor->editedBookmarks(), true); } else { resetBookmarks(); } // // Delete the editor after use // delete d->editor; d->editor = 0; } void Smb4KBookmarkHandler::update() const { // Get new IP addresses. for (const BookmarkPtr &bookmark : d->bookmarks) { HostPtr host = findHost(bookmark->hostName(), bookmark->workgroupName()); if (host) { if (host->hasIpAddress() && bookmark->hostIpAddress() != host->ipAddress()) { bookmark->setHostIpAddress(host->ipAddress()); } } } } void Smb4KBookmarkHandler::migrateProfile(const QString& from, const QString& to) { // Replace the old profile name with the new one. for (const BookmarkPtr &bookmark : d->bookmarks) { if (QString::compare(bookmark->profile(), from, Qt::CaseSensitive) == 0) { bookmark->setProfile(to); } } // Write the new list to the file. writeBookmarkList(); } void Smb4KBookmarkHandler::removeProfile(const QString& name) { QMutableListIterator it(d->bookmarks); while (it.hasNext()) { const BookmarkPtr &bookmark = it.next(); if (QString::compare(bookmark->profile(), name, Qt::CaseSensitive) == 0) { it.remove(); } } // Write the new list to the file. writeBookmarkList(); } diff --git a/core/smb4kbookmarkhandler_p.cpp b/core/smb4kbookmarkhandler_p.cpp index 30b7c4d..8ff1936 100644 --- a/core/smb4kbookmarkhandler_p.cpp +++ b/core/smb4kbookmarkhandler_p.cpp @@ -1,1015 +1,1011 @@ /*************************************************************************** Private classes for the bookmark handler ------------------- begin : Sun Mar 20 2011 copyright : (C) 2011-2018 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, 51 Franklin Street, Suite 500, Boston, * * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbookmarkhandler_p.h" #include "smb4ksettings.h" #include "smb4kbookmark.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include Smb4KBookmarkDialog::Smb4KBookmarkDialog(const QList &bookmarks, const QStringList &groups, QWidget *parent) : QDialog(parent) { // // Set the window title // setWindowTitle(i18n("Add Bookmarks")); // // Setup the view // setupView(); // // Load the list of bookmarks and groups // loadLists(bookmarks, groups); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "BookmarkDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Fill the completion objects // m_label_edit->completionObject()->setItems(group.readEntry("LabelCompletion", QStringList())); m_group_combo->completionObject()->setItems(group.readEntry("GroupCompletion", m_groups)); // // Connections // connect(KIconLoader::global(), SIGNAL(iconChanged(int)), SLOT(slotIconSizeChanged(int))); } Smb4KBookmarkDialog::~Smb4KBookmarkDialog() { while (!m_bookmarks.isEmpty()) { m_bookmarks.takeFirst().clear(); } } const QList &Smb4KBookmarkDialog::bookmarks() { return m_bookmarks; } void Smb4KBookmarkDialog::setupView() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); QWidget *description = new QWidget(this); QHBoxLayout *desc_layout = new QHBoxLayout(description); desc_layout->setSpacing(5); desc_layout->setMargin(0); QLabel *pixmap = new QLabel(description); QPixmap sync_pix = KDE::icon("bookmark-new").pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(sync_pix); pixmap->setAlignment(Qt::AlignBottom); QLabel *label = new QLabel(i18n("All listed shares will be bookmarked. To edit the label " "or group, click the respective bookmark entry."), description); label->setWordWrap(true); label->setAlignment(Qt::AlignBottom); desc_layout->addWidget(pixmap, 0); desc_layout->addWidget(label, Qt::AlignBottom); m_widget = new QListWidget(this); m_widget->setSortingEnabled(true); m_widget->setSelectionMode(QAbstractItemView::SingleSelection); int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_widget->setIconSize(QSize(icon_size, icon_size)); m_editors = new QWidget(this); m_editors->setEnabled(false); QGridLayout *editors_layout = new QGridLayout(m_editors); editors_layout->setSpacing(5); editors_layout->setMargin(0); QLabel *l_label = new QLabel(i18n("Label:"), m_editors); m_label_edit = new KLineEdit(m_editors); m_label_edit->setClearButtonEnabled(true); QLabel *g_label = new QLabel(i18n("Group:"), m_editors); m_group_combo = new KComboBox(true, m_editors); editors_layout->addWidget(l_label, 0, 0, 0); editors_layout->addWidget(m_label_edit, 0, 1, 0); editors_layout->addWidget(g_label, 1, 0, 0); editors_layout->addWidget(m_group_combo, 1, 1, 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_ok_button = buttonBox->addButton(QDialogButtonBox::Ok); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_ok_button->setShortcut(Qt::CTRL|Qt::Key_Return); m_cancel_button->setShortcut(Qt::Key_Escape); m_ok_button->setDefault(true); layout->addWidget(description, 0); layout->addWidget(m_widget, 0); layout->addWidget(m_editors, 0); layout->addWidget(buttonBox, 0); // // Connections // connect(m_widget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotBookmarkClicked(QListWidgetItem*))); connect(m_label_edit, SIGNAL(editingFinished()), this, SLOT(slotLabelEdited())); connect(m_group_combo->lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotGroupEdited())); connect(m_ok_button, SIGNAL(clicked()), this, SLOT(slotDialogAccepted())); connect(m_cancel_button, SIGNAL(clicked()), this, SLOT(reject())); } void Smb4KBookmarkDialog::loadLists(const QList &bookmarks, const QStringList &groups) { // Copy the bookmarks to the internal list and add them to // the list widget afterwards. for (const BookmarkPtr &b : bookmarks) { QListWidgetItem *item = new QListWidgetItem(b->icon(), b->displayString(), m_widget); item->setData(Qt::UserRole, static_cast(b->url())); m_bookmarks << b; } m_groups = groups; m_group_combo->addItems(m_groups); } BookmarkPtr Smb4KBookmarkDialog::findBookmark(const QUrl &url) { BookmarkPtr bookmark; for (const BookmarkPtr &b : m_bookmarks) { if (b->url() == url) { bookmark = b; break; } else { continue; } } return bookmark; } void Smb4KBookmarkDialog::slotBookmarkClicked(QListWidgetItem *bookmark_item) { if (bookmark_item) { // Enable the editor widgets if necessary if (!m_editors->isEnabled()) { m_editors->setEnabled(true); } QUrl url = bookmark_item->data(Qt::UserRole).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { m_label_edit->setText(bookmark->label()); m_group_combo->setCurrentItem(bookmark->groupName()); } else { m_label_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } else { m_label_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } void Smb4KBookmarkDialog::slotLabelEdited() { // Set the label QUrl url = m_widget->currentItem()->data(Qt::UserRole).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setLabel(m_label_edit->userText()); } // Add label to completion object KCompletion *completion = m_label_edit->completionObject(); if (!m_label_edit->userText().isEmpty()) { completion->addItem(m_label_edit->userText()); } } void Smb4KBookmarkDialog::slotGroupEdited() { // Set the group QUrl url = m_widget->currentItem()->data(Qt::UserRole).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setGroupName(m_group_combo->currentText()); } // Add the group name to the combo box if (m_group_combo->findText(m_group_combo->currentText()) == -1) { m_group_combo->addItem(m_group_combo->currentText()); } // Add group to completion object KCompletion *completion = m_group_combo->completionObject(); if (!m_group_combo->currentText().isEmpty()) { completion->addItem(m_group_combo->currentText()); } } void Smb4KBookmarkDialog::slotDialogAccepted() { KConfigGroup group(Smb4KSettings::self()->config(), "BookmarkDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); group.writeEntry("LabelCompletion", m_label_edit->completionObject()->items()); group.writeEntry("GroupCompletion", m_group_combo->completionObject()->items()); accept(); } void Smb4KBookmarkDialog::slotIconSizeChanged(int group) { switch (group) { case KIconLoader::Small: { int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_widget->setIconSize(QSize(icon_size, icon_size)); break; } default: { break; } } } Smb4KBookmarkEditor::Smb4KBookmarkEditor(const QList &bookmarks, QWidget *parent) : QDialog(parent), m_bookmarks(bookmarks) { // // Set the window title // setWindowTitle(i18n("Edit Bookmarks")); // // Setup the view // setupView(); // // Load the bookmarks into the editor // loadBookmarks(); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "BookmarkEditor"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Fill the completion objects // m_label_edit->completionObject()->setItems(group.readEntry("LabelCompletion", QStringList())); m_login_edit->completionObject()->setItems(group.readEntry("LoginCompletion", QStringList())); m_ip_edit->completionObject()->setItems(group.readEntry("IPCompletion", QStringList())); m_group_combo->completionObject()->setItems(group.readEntry("GroupCompletion", m_groups)); // // Connections // connect(KIconLoader::global(), SIGNAL(iconChanged(int)), SLOT(slotIconSizeChanged(int))); } Smb4KBookmarkEditor::~Smb4KBookmarkEditor() { while (!m_bookmarks.isEmpty()) { m_bookmarks.takeFirst().clear(); } } bool Smb4KBookmarkEditor::eventFilter(QObject *obj, QEvent *e) { if (obj == m_tree_widget->viewport()) { switch (e->type()) { case QEvent::DragEnter: { QDragEnterEvent *ev = static_cast(e); if (ev->source() == m_tree_widget->viewport()) { e->accept(); } else { e->ignore(); } break; } case QEvent::DragLeave: { e->ignore(); break; } case QEvent::Drop: { QTimer::singleShot(50, this, SLOT(slotAdjust())); break; } default: { break; } } } return QDialog::eventFilter(obj, e); } void Smb4KBookmarkEditor::setupView() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); m_tree_widget = new QTreeWidget(this); m_tree_widget->setColumnCount(2); m_tree_widget->hideColumn((m_tree_widget->columnCount() - 1)); // for sorting purposes m_tree_widget->headerItem()->setHidden(true); m_tree_widget->setRootIsDecorated(true); m_tree_widget->setSelectionMode(QAbstractItemView::SingleSelection); m_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu); m_tree_widget->header()->setSectionResizeMode(QHeaderView::ResizeToContents); m_tree_widget->setDragDropMode(QTreeWidget::InternalMove); int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_tree_widget->setIconSize(QSize(icon_size, icon_size)); m_tree_widget->viewport()->installEventFilter(this); m_add_group = new QAction(KDE::icon("bookmark-add-folder"), i18n("Add Group"), m_tree_widget); m_delete = new QAction(KDE::icon("edit-delete"), i18n("Remove"), m_tree_widget); m_clear = new QAction(KDE::icon("edit-clear"), i18n("Clear"), m_tree_widget); m_menu = new KActionMenu(m_tree_widget); m_menu->addAction(m_add_group); m_menu->addAction(m_delete); m_menu->addAction(m_clear); m_editors = new QWidget(this); m_editors->setEnabled(false); QGridLayout *editors_layout = new QGridLayout(m_editors); editors_layout->setSpacing(5); editors_layout->setMargin(0); QLabel *l_label = new QLabel(i18n("Label:"), m_editors); m_label_edit = new KLineEdit(m_editors); m_label_edit->setClearButtonEnabled(true); QLabel *lg_label = new QLabel(i18n("Login:"), m_editors); m_login_edit = new KLineEdit(m_editors); m_login_edit->setClearButtonEnabled(true); QLabel *i_label = new QLabel(i18n("IP Address:"), m_editors); m_ip_edit = new KLineEdit(m_editors); m_ip_edit->setClearButtonEnabled(true); QLabel *g_label = new QLabel(i18n("Group:"), m_editors); m_group_combo = new KComboBox(true, m_editors); m_group_combo->setDuplicatesEnabled(false); editors_layout->addWidget(l_label, 0, 0, 0); editors_layout->addWidget(m_label_edit, 0, 1, 0); editors_layout->addWidget(lg_label, 1, 0, 0); editors_layout->addWidget(m_login_edit, 1, 1, 0); editors_layout->addWidget(i_label, 2, 0, 0); editors_layout->addWidget(m_ip_edit, 2, 1, 0); editors_layout->addWidget(g_label, 3, 0, 0); editors_layout->addWidget(m_group_combo, 3, 1, 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_ok_button = buttonBox->addButton(QDialogButtonBox::Ok); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_ok_button->setShortcut(Qt::CTRL|Qt::Key_Return); m_cancel_button->setShortcut(Qt::Key_Escape); m_ok_button->setDefault(true); layout->addWidget(m_tree_widget); layout->addWidget(m_editors); layout->addWidget(buttonBox); // // Connections // connect(m_tree_widget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemClicked(QTreeWidgetItem*,int))); connect(m_tree_widget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); connect(m_label_edit, SIGNAL(editingFinished()), this, SLOT(slotLabelEdited())); connect(m_ip_edit, SIGNAL(editingFinished()), this, SLOT(slotIPEdited())); connect(m_login_edit, SIGNAL(editingFinished()), this, SLOT(slotLoginEdited())); connect(m_group_combo->lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotGroupEdited())); connect(m_add_group, SIGNAL(triggered(bool)), this, SLOT(slotAddGroupTriggered(bool))); connect(m_delete, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTriggered(bool))); connect(m_clear, SIGNAL(triggered(bool)), this, SLOT(slotClearTriggered(bool))); connect(m_ok_button, SIGNAL(clicked()), this, SLOT(slotDialogAccepted())); connect(m_cancel_button, SIGNAL(clicked()), this, SLOT(slotDialogRejected())); } void Smb4KBookmarkEditor::loadBookmarks() { // // Clear the tree widget and the group combo box // m_tree_widget->clear(); m_group_combo->clear(); // // Copy the groups into the internal list // m_groups.clear(); for (const BookmarkPtr &bookmark : m_bookmarks) { if (!m_groups.contains(bookmark->groupName())) { m_groups << bookmark->groupName(); } } // // Insert the groups into the tree widget // for (const QString &group : m_groups) { if (!group.isEmpty()) { QTreeWidgetItem *groupItem = new QTreeWidgetItem(QTreeWidgetItem::UserType); groupItem->setIcon(0, KDE::icon("folder-bookmark")); groupItem->setText(0, group); groupItem->setText((m_tree_widget->columnCount() - 1), QString("00_%1").arg(group)); groupItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsDropEnabled); m_tree_widget->addTopLevelItem(groupItem); } } // // Insert the bookmarks info the tree widget // for (const BookmarkPtr &bookmark : m_bookmarks) { QTreeWidgetItem *bookmarkItem = new QTreeWidgetItem(QTreeWidgetItem::UserType); bookmarkItem->setData(0, QTreeWidgetItem::UserType, static_cast(bookmark->url())); bookmarkItem->setIcon(0, bookmark->icon()); bookmarkItem->setText(0, bookmark->displayString()); bookmarkItem->setText((m_tree_widget->columnCount() - 1), QString("01_%1").arg(bookmark->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort))); bookmarkItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsDragEnabled); if (!bookmark->groupName().isEmpty()) { QList items = m_tree_widget->findItems(bookmark->groupName(), Qt::MatchFixedString|Qt::MatchCaseSensitive, 0); if (!items.isEmpty()) { items.first()->addChild(bookmarkItem); items.first()->setExpanded(true); } } else { m_tree_widget->addTopLevelItem(bookmarkItem); } } // // Sort // for (int i = 0; i < m_tree_widget->topLevelItemCount(); ++i) { m_tree_widget->topLevelItem(i)->sortChildren((m_tree_widget->columnCount() - 1), Qt::AscendingOrder); } m_tree_widget->sortItems((m_tree_widget->columnCount() - 1), Qt::AscendingOrder); // // Check that an empty group entry is also present. If it is not there, // add it now and insert the groups to the group combo box afterwards. // if (!m_groups.contains("") && !m_groups.contains(QString())) { m_groups << ""; } m_group_combo->addItems(m_groups); m_group_combo->setCurrentItem(""); } QList Smb4KBookmarkEditor::editedBookmarks() { return m_bookmarks; } BookmarkPtr Smb4KBookmarkEditor::findBookmark(const QUrl &url) { BookmarkPtr bookmark; for (const BookmarkPtr &b : m_bookmarks) { if (b->url() == url) { bookmark = b; break; } else { continue; } } return bookmark; } void Smb4KBookmarkEditor::slotItemClicked(QTreeWidgetItem *item, int /*col*/) { if (item) { if (m_tree_widget->indexOfTopLevelItem(item) != -1) { // This is a top-level item, i.e. it is either a bookmark without // group or a group entry. // Bookmarks have an URL stored, group folders not. if (!item->data(0, QTreeWidgetItem::UserType).toUrl().isEmpty()) { BookmarkPtr bookmark = findBookmark(item->data(0, QTreeWidgetItem::UserType).toUrl()); if (bookmark) { m_label_edit->setText(bookmark->label()); m_login_edit->setText(bookmark->login()); m_ip_edit->setText(bookmark->hostIpAddress()); m_group_combo->setCurrentItem(bookmark->groupName()); m_editors->setEnabled(true); } else { m_label_edit->clear(); m_login_edit->clear(); m_ip_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } else { m_label_edit->clear(); m_login_edit->clear(); m_ip_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } else { // This can only be a bookmark. BookmarkPtr bookmark = findBookmark(item->data(0, QTreeWidgetItem::UserType).toUrl()); if (bookmark) { m_label_edit->setText(bookmark->label()); m_login_edit->setText(bookmark->login()); m_ip_edit->setText(bookmark->hostIpAddress()); m_group_combo->setCurrentItem(bookmark->groupName()); m_editors->setEnabled(true); } else { m_label_edit->clear(); m_login_edit->clear(); m_ip_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } } else { m_label_edit->clear(); m_login_edit->clear(); m_ip_edit->clear(); m_group_combo->clearEditText(); m_editors->setEnabled(false); } } void Smb4KBookmarkEditor::slotContextMenuRequested(const QPoint &pos) { QTreeWidgetItem *item = m_tree_widget->itemAt(pos); m_delete->setEnabled((item)); m_menu->menu()->popup(m_tree_widget->viewport()->mapToGlobal(pos)); } void Smb4KBookmarkEditor::slotLabelEdited() { // Set the label QUrl url = m_tree_widget->currentItem()->data(0, QTreeWidgetItem::UserType).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setLabel(m_label_edit->userText()); } // Add label to completion object KCompletion *completion = m_label_edit->completionObject(); if (!m_label_edit->userText().isEmpty()) { completion->addItem(m_label_edit->userText()); } } void Smb4KBookmarkEditor::slotLoginEdited() { // Set the login QUrl url = m_tree_widget->currentItem()->data(0, QTreeWidgetItem::UserType).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setLogin(m_login_edit->userText()); } // Add login to completion object KCompletion *completion = m_login_edit->completionObject(); if (!m_login_edit->userText().isEmpty()) { completion->addItem(m_login_edit->userText()); } } void Smb4KBookmarkEditor::slotIPEdited() { // Set the ip address QUrl url = m_tree_widget->currentItem()->data(0, QTreeWidgetItem::UserType).toUrl(); BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setHostIpAddress(m_ip_edit->userText()); } // Add login to completion object KCompletion *completion = m_ip_edit->completionObject(); if (!m_ip_edit->userText().isEmpty()) { completion->addItem(m_ip_edit->userText()); } } void Smb4KBookmarkEditor::slotGroupEdited() { // // Get the URL of the current item. // QUrl url = m_tree_widget->currentItem()->data(0, QTreeWidgetItem::UserType).toUrl(); // // Return here, if the current item is a group // if (url.isEmpty()) { return; } // // Set the group name to the bookmark // BookmarkPtr bookmark = findBookmark(url); if (bookmark) { bookmark->setGroupName(m_group_combo->currentText()); } // // Reload the bookmarks (The current item is cleared by this!) // loadBookmarks(); // // Reset the current item // QTreeWidgetItemIterator it(m_tree_widget); while (*it) { if ((*it)->data(0, QTreeWidgetItem::UserType).toUrl() == url) { m_tree_widget->setCurrentItem(*it); slotItemClicked(*it, 0); break; } ++it; } // // Add the group to the completion object // KCompletion *completion = m_group_combo->completionObject(); if (!m_group_combo->currentText().isEmpty()) { completion->addItem(m_group_combo->currentText()); } } void Smb4KBookmarkEditor::slotAddGroupTriggered(bool /*checked*/) { bool ok = false; QString group_name = QInputDialog::getText(this, i18n("Add Group"), i18n("Group name:"), QLineEdit::Normal, QString(), &ok); if (ok && !group_name.isEmpty() && m_tree_widget->findItems(group_name, Qt::MatchFixedString|Qt::MatchCaseSensitive, 0).isEmpty()) { // Create a new group item and add it to the widget QTreeWidgetItem *group = new QTreeWidgetItem(QTreeWidgetItem::UserType); group->setIcon(0, KDE::icon("folder-bookmark")); group->setText(0, group_name); group->setText((m_tree_widget->columnCount() - 1), QString("00_%1").arg(group_name)); group->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsDropEnabled) ; m_tree_widget->addTopLevelItem(group); m_tree_widget->sortItems((m_tree_widget->columnCount() - 1), Qt::AscendingOrder); // Add the group to the combo box m_group_combo->addItem(group_name); m_group_combo->completionObject()->addItem(group_name); } } void Smb4KBookmarkEditor::slotDeleteTriggered(bool /*checked*/) { // // Remove the bookmarks from the view and the internal list // QList selected = m_tree_widget->selectedItems(); while (!selected.isEmpty()) { QTreeWidgetItem *item = selected.takeFirst(); QUrl url = item->data(0, QTreeWidgetItem::UserType).toUrl(); QMutableListIterator it(m_bookmarks); while (it.hasNext()) { BookmarkPtr bookmark = it.next(); if (bookmark->url() == url) { it.remove(); break; } } delete item; } } void Smb4KBookmarkEditor::slotClearTriggered(bool /*checked*/) { m_tree_widget->clear(); m_bookmarks.clear(); m_groups.clear(); } void Smb4KBookmarkEditor::slotDialogAccepted() { // // Write the dialog properties to the config file // KConfigGroup group(Smb4KSettings::self()->config(), "BookmarkEditor"); KWindowConfig::saveWindowSize(windowHandle(), group); group.writeEntry("LabelCompletion", m_label_edit->completionObject()->items()); group.writeEntry("LoginCompletion", m_login_edit->completionObject()->items()); group.writeEntry("IPCompletion", m_ip_edit->completionObject()->items()); group.writeEntry("GroupCompletion", m_group_combo->completionObject()->items()); // // Accept the dialog // accept(); } void Smb4KBookmarkEditor::slotDialogRejected() { // // Reject the dialog // reject(); } void Smb4KBookmarkEditor::slotIconSizeChanged(int group) { switch (group) { case KIconLoader::Small: { int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_tree_widget->setIconSize(QSize(icon_size, icon_size)); break; } default: { break; } } } void Smb4KBookmarkEditor::slotAdjust() { // Do the necessary adjustments: QTreeWidgetItemIterator it(m_tree_widget); while (*it) { if (!(*it)->parent()) { if ((*it)->data(0, QTreeWidgetItem::UserType).toUrl().isEmpty()) { if ((*it)->childCount() == 0) { delete *it; } } else { BookmarkPtr bookmark = findBookmark((*it)->data(0, QTreeWidgetItem::UserType).toUrl()); if (bookmark) { bookmark->setGroupName(""); } } } else { BookmarkPtr bookmark = findBookmark((*it)->data(0, QTreeWidgetItem::UserType).toUrl()); if (bookmark) { bookmark->setGroupName((*it)->parent()->text(0)); } } ++it; } } diff --git a/core/smb4kclient.cpp b/core/smb4kclient.cpp index fd5db43..f7ae376 100644 --- a/core/smb4kclient.cpp +++ b/core/smb4kclient.cpp @@ -1,1035 +1,1031 @@ /*************************************************************************** This class provides the interface to the libsmbclient library. ------------------- begin : Sa Oct 20 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kclient.h" #include "smb4kclient_p.h" #include "smb4khardwareinterface.h" #include "smb4ksettings.h" #include "smb4kcustomoptionsmanager.h" #include "smb4kcustomoptions.h" #include "smb4kbasicnetworkitem.h" #include "smb4kglobal.h" #include "smb4khomesshareshandler.h" #include "smb4kwalletmanager.h" #include "smb4knotification.h" // Qt includes #include #include #include #include using namespace Smb4KGlobal; Q_GLOBAL_STATIC(Smb4KClientStatic, p); Smb4KClient::Smb4KClient(QObject* parent) : KCompositeJob(parent), d(new Smb4KClientPrivate) { // // Connections // connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit())); } Smb4KClient::~Smb4KClient() { } Smb4KClient *Smb4KClient::self() { return &p->instance; } void Smb4KClient::start() { // // Check the network configurations // Smb4KHardwareInterface::self()->updateNetworkConfig(); // // Connect to Smb4KHardwareInterface to be able to get the response // connect(Smb4KHardwareInterface::self(), SIGNAL(networkConfigUpdated()), this, SLOT(slotStartJobs())); } bool Smb4KClient::isRunning() { return hasSubjobs(); } void Smb4KClient::abort() { QListIterator it(subjobs()); while (it.hasNext()) { it.next()->kill(KJob::EmitResult); } } void Smb4KClient::lookupDomains() { // // Send Wakeup-On-LAN packages // if (Smb4KSettings::enableWakeOnLAN()) { QList wakeOnLanEntries = Smb4KCustomOptionsManager::self()->wakeOnLanEntries(); if (!wakeOnLanEntries.isEmpty()) { NetworkItemPtr item = NetworkItemPtr(new Smb4KBasicNetworkItem()); emit aboutToStart(item, WakeUp); QUdpSocket *socket = new QUdpSocket(this); for (int i = 0; i < wakeOnLanEntries.size(); ++i) { if (wakeOnLanEntries.at(i)->wolSendBeforeNetworkScan()) { QHostAddress addr; if (wakeOnLanEntries.at(i)->hasIpAddress()) { addr.setAddress(wakeOnLanEntries.at(i)->ipAddress()); } else { addr.setAddress("255.255.255.255"); } // Construct magic sequence QByteArray sequence; // 6 times 0xFF for (int j = 0; j < 6; ++j) { sequence.append(QChar(0xFF).toLatin1()); } // 16 times the MAC address QStringList parts = wakeOnLanEntries.at(i)->macAddress().split(':', QString::SkipEmptyParts); for (int j = 0; j < 16; ++j) { for (int k = 0; k < parts.size(); ++k) { sequence.append(QChar(QString("0x%1").arg(parts.at(k)).toInt(0, 16)).toLatin1()); } } socket->writeDatagram(sequence, addr, 9); } } delete socket; // Wait the defined time int stop = 1000 * Smb4KSettings::wakeOnLANWaitingTime() / 250; int i = 0; while (i++ < stop) { QTest::qWait(250); } emit finished(item, WakeUp); item.clear(); } } // // Emit the aboutToStart() signal // NetworkItemPtr item = NetworkItemPtr(new Smb4KBasicNetworkItem(Network)); item->setUrl(QUrl("smb://")); emit aboutToStart(item, LookupDomains); // // Create the job // Smb4KClientJob *job = new Smb4KClientJob(this); job->setNetworkItem(item); job->setProcess(LookupDomains); // // Clear the pointer // item.clear(); // // Set the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job to the subjobs // addSubjob(job); // // Start the job // job->start(); } void Smb4KClient::lookupDomainMembers(const WorkgroupPtr &workgroup) { // // Emit the aboutToStart() signal // emit aboutToStart(workgroup, LookupDomainMembers); // // Create the job // Smb4KClientJob *job = new Smb4KClientJob(this); job->setNetworkItem(workgroup); job->setProcess(LookupDomainMembers); // // Set the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job to the subjobs // addSubjob(job); // // Start the job // job->start(); } void Smb4KClient::lookupShares(const HostPtr &host) { // // Emit the aboutToStart() signal // emit aboutToStart(host, LookupShares); // // Create the job // Smb4KClientJob *job = new Smb4KClientJob(this); job->setNetworkItem(host); job->setProcess(LookupShares); // // Set the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job to the subjobs // addSubjob(job); // // Start the job // job->start(); } void Smb4KClient::lookupFiles(const NetworkItemPtr &item) { // // Check that the network item has the correct type and process it. // if (item->type() == Share || item->type() == Directory) { // // Emit the aboutToStart() signal // emit aboutToStart(item, LookupFiles); // // Create the job // Smb4KClientJob *job = new Smb4KClientJob(this); job->setNetworkItem(item); job->setProcess(LookupFiles); // // Set the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job to the subjobs // addSubjob(job); // // Start the job // job->start(); } } void Smb4KClient::printFile(const SharePtr& share, const KFileItem& fileItem, int copies) { // // Emit the aboutToStart() signal // emit aboutToStart(share, PrintFile); // // Create the job // Smb4KClientJob *job = new Smb4KClientJob(this); job->setNetworkItem(share); job->setPrintFileItem(fileItem); job->setPrintCopies(copies); job->setProcess(PrintFile); // // Set the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job to the subjobs // addSubjob(job); // // Start the job // job->start(); } void Smb4KClient::search(const QString& item) { // // Create empty basic network item // NetworkItemPtr networkItem = NetworkItemPtr(new Smb4KBasicNetworkItem()); // // Emit the aboutToStart() signal // emit aboutToStart(networkItem, NetworkSearch); // // Before doing the search, lookup all domains, servers and shares in the // network neighborhood. // lookupDomains(); while(isRunning()) { QTest::qWait(50); } for (const WorkgroupPtr &workgroup : workgroupsList()) { lookupDomainMembers(workgroup); while(isRunning()) { QTest::qWait(50); } } for (const HostPtr &host : hostsList()) { lookupShares(host); while(isRunning()) { QTest::qWait(50); } } // // Do the actual search // QList results; for (const SharePtr &share : sharesList()) { if (share->shareName().contains(item, Qt::CaseInsensitive)) { results << share; } } // // Emit the search results // emit searchResults(results); // // Emit the finished() signal // emit finished(networkItem, NetworkSearch); } void Smb4KClient::openPreviewDialog(const SharePtr &share) { // // Printer share check // if (share->isPrinter()) { return; } // // 'homes' share check // if (share->isHomesShare()) { Smb4KHomesSharesHandler::self()->specifyUser(share, true); } // // Start the preview dialog // // First, check if a preview dialog has already been set up for this share // and reuse it, if possible. // QPointer dlg = 0; for (Smb4KPreviewDialog *p : d->previewDialogs) { if (share == p->share()) { dlg = p; } } // // If there was no preview dialog present, create a new one // if (!dlg) { dlg = new Smb4KPreviewDialog(share, QApplication::activeWindow()); d->previewDialogs << dlg; // // Connections // connect(dlg, SIGNAL(requestPreview(NetworkItemPtr)), this, SLOT(slotStartNetworkQuery(NetworkItemPtr))); connect(dlg, SIGNAL(aboutToClose(Smb4KPreviewDialog*)), this, SLOT(slotPreviewDialogClosed(Smb4KPreviewDialog*))); connect(dlg, SIGNAL(requestAbort()), this, SLOT(slotAbort())); connect(this, SIGNAL(files(QList)), dlg, SLOT(slotPreviewResults(QList))); connect(this, SIGNAL(aboutToStart(NetworkItemPtr,int)), dlg, SLOT(slotAboutToStart(NetworkItemPtr,int))); connect(this, SIGNAL(finished(NetworkItemPtr,int)), dlg, SLOT(slotFinished(NetworkItemPtr,int))); } // // Show the preview dialog // if (!dlg->isVisible()) { dlg->setVisible(true); } } void Smb4KClient::openPrintDialog(const SharePtr& share) { // // Printer share check // if (!share->isPrinter()) { return; } // // Start the print dialog // // First, check if a print dialog has already been set up for this share // and reuse it, if possible. // QPointer dlg = 0; for (Smb4KPrintDialog *p : d->printDialogs) { if (share == p->share()) { dlg = p; } } // // If there was no print dialog present, create a new one // if (!dlg) { Smb4KWalletManager::self()->readAuthInfo(share); dlg = new Smb4KPrintDialog(share, QApplication::activeWindow()); d->printDialogs << dlg; connect(dlg, SIGNAL(printFile(SharePtr,KFileItem,int)), this, SLOT(slotStartPrinting(SharePtr,KFileItem,int))); connect(dlg, SIGNAL(aboutToClose(Smb4KPrintDialog*)), this, SLOT(slotPrintDialogClosed(Smb4KPrintDialog*))); } // // Show the preview dialog // if (!dlg->isVisible()) { dlg->setVisible(true); } } void Smb4KClient::processErrors(Smb4KClientJob *job) { switch (job->error()) { case Smb4KClientJob::AccessDeniedError: { switch (job->networkItem()->type()) { case Host: { if (Smb4KWalletManager::self()->showPasswordDialog(job->networkItem())) { lookupShares(job->networkItem().staticCast()); } break; } case Share: { if (Smb4KWalletManager::self()->showPasswordDialog(job->networkItem())) { if (job->process() == Smb4KGlobal::PrintFile) { printFile(job->networkItem().staticCast(), job->printFileItem(), job->printCopies()); } else { lookupFiles(job->networkItem().staticCast()); } } break; } case Directory: case File: { FilePtr file = job->networkItem().staticCast(); SharePtr share = SharePtr(new Smb4KShare()); share->setWorkgroupName(file->workgroupName()); share->setHostName(file->hostName()); share->setShareName(file->shareName()); share->setLogin(file->login()); share->setPassword(file->password()); if (Smb4KWalletManager::self()->showPasswordDialog(share)) { file->setLogin(share->login()); file->setPassword(share->password()); lookupFiles(file); } break; } default: { qDebug() << "Authentication error. URL:" << job->networkItem()->url(); break; } } break; } default: { Smb4KNotification::networkCommunicationFailed(job->errorText()); break; } } } void Smb4KClient::processWorkgroups(Smb4KClientJob *job) { // // Remove obsolete workgroups and their members // QListIterator wIt(workgroupsList()); while (wIt.hasNext()) { WorkgroupPtr workgroup = wIt.next(); bool found = false; for (const WorkgroupPtr &w : job->workgroups()) { if (w->workgroupName() == workgroup->workgroupName()) { found = true; break; } else { continue; } } if (!found) { QList obsoleteHosts = workgroupMembers(workgroup); QListIterator hIt(obsoleteHosts); while (hIt.hasNext()) { removeHost(hIt.next()); } removeWorkgroup(workgroup); } } // // Add new workgroups and update existing ones. // for (const WorkgroupPtr &workgroup : job->workgroups()) { if (!findWorkgroup(workgroup->workgroupName())) { addWorkgroup(workgroup); // Since this is a new workgroup, no master browser is present. HostPtr masterBrowser = HostPtr(new Smb4KHost()); masterBrowser->setWorkgroupName(workgroup->workgroupName()); masterBrowser->setHostName(workgroup->masterBrowserName()); masterBrowser->setIpAddress(workgroup->masterBrowserIpAddress()); masterBrowser->setIsMasterBrowser(true); addHost(masterBrowser); } else { updateWorkgroup(workgroup); // Check if the master browser changed QList members = workgroupMembers(workgroup); for (const HostPtr &host : members) { if (workgroup->masterBrowserName() == host->hostName()) { host->setIsMasterBrowser(true); if (!host->hasIpAddress() && workgroup->hasMasterBrowserIpAddress()) { host->setIpAddress(workgroup->masterBrowserIpAddress()); } } else { host->setIsMasterBrowser(false); } } } } emit workgroups(); } void Smb4KClient::processHosts(Smb4KClientJob *job) { // // Get the workgroup pointer // WorkgroupPtr workgroup = job->networkItem().staticCast(); // // Remove obsolete workgroup members // QList members = workgroupMembers(workgroup); QListIterator hIt(members); while (hIt.hasNext()) { HostPtr host = hIt.next(); bool found = false; for (const HostPtr &h : job->hosts()) { if (h->workgroupName() == host->workgroupName() && h->hostName() == host->hostName()) { found = true; break; } else { continue; } } if (!found) { QList obsoleteShares = sharedResources(host); QListIterator sIt(obsoleteShares); while (sIt.hasNext()) { removeShare(sIt.next()); } removeHost(host); } } // // Add new hosts and update existing ones // for (const HostPtr &host : job->hosts()) { if (host->hostName() == workgroup->masterBrowserName()) { host->setIsMasterBrowser(true); } else { host->setIsMasterBrowser(false); } if (!findHost(host->hostName(), host->workgroupName())) { addHost(host); } else { updateHost(host); } } emit hosts(workgroup); } void Smb4KClient::processShares(Smb4KClientJob *job) { // // Get the host pointer // HostPtr host = job->networkItem().staticCast(); // // Remove obsolete shares // QList sharedRes = sharedResources(host); QListIterator sIt(sharedRes); while (sIt.hasNext()) { SharePtr share = sIt.next(); bool found = false; for (const SharePtr &s : job->shares()) { if (s->workgroupName() == share->workgroupName() && s->url().matches(share->url(), QUrl::RemoveUserInfo|QUrl::RemovePort)) { found = true; break; } else { continue; } } if (!found || (share->isHidden() && !Smb4KSettings::detectHiddenShares()) || (share->isPrinter() && !Smb4KSettings::detectPrinterShares())) { removeShare(share); } } // // Add new shares and update existing ones // for (const SharePtr &share : job->shares()) { // // Process only those shares that the user wants to see // if (share->isHidden() && !Smb4KSettings::detectHiddenShares()) { continue; } if (share->isPrinter() && !Smb4KSettings::detectPrinterShares()) { continue; } // // Add or update the shares // if (!findShare(share->url(), share->workgroupName())) { addShare(share); } else { updateShare(share); } } emit shares(host); } void Smb4KClient::processFiles(Smb4KClientJob *job) { QList list; for (const FilePtr &f : job->files()) { if (f->isHidden() && !Smb4KSettings::previewHiddenItems()) { continue; } list << f; } emit files(list); } void Smb4KClient::slotStartJobs() { if (Smb4KHardwareInterface::self()->isOnline()) { // // Disconnect from Smb4KHardwareInterface::networkConfigUpdated() signal, // otherwise we get unwanted periodic scanning. // disconnect(Smb4KHardwareInterface::self(), SIGNAL(networkConfigUpdated()), this, SLOT(slotStartJobs())); // // Lookup domains as the first step // lookupDomains(); } } void Smb4KClient::slotResult(KJob *job) { // // Get the client job // Smb4KClientJob *clientJob = qobject_cast(job); // // Define a network item pointer and the process value for the // finished() signal. // NetworkItemPtr item = clientJob->networkItem(); Smb4KGlobal::Process process = clientJob->process(); // // Get the result from the query and process it // if (clientJob) { if (clientJob->error() == 0) { switch (clientJob->networkItem()->type()) { case Network: { // Process the discovered workgroups processWorkgroups(clientJob); break; } case Workgroup: { // Process the discovered workgroup members processHosts(clientJob); break; } case Host: { // Process the discovered shares processShares(clientJob); break; } case Share: case Directory: { // Process the discoveres files and directories processFiles(clientJob); break; } default: { break; } } } else { processErrors(clientJob); } } // // Remove the job // removeSubjob(job); // // Emit the finished signal // finished(item, process); // // Clear the network item pointer // item.clear(); // // Restore the cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::restoreOverrideCursor(); } } void Smb4KClient::slotAboutToQuit() { abort(); } void Smb4KClient::slotStartNetworkQuery(NetworkItemPtr item) { // // Look up files // lookupFiles(item); } void Smb4KClient::slotPreviewDialogClosed(Smb4KPreviewDialog *dialog) { // // Remove the preview dialog from the list // if (dialog) { // Find the dialog in the list and take it from the list. // It will automatically be deleted on close, so there is // no need to delete the dialog here. int i = d->previewDialogs.indexOf(dialog); d->previewDialogs.takeAt(i); } } void Smb4KClient::slotAbort() { abort(); } void Smb4KClient::slotStartPrinting(const SharePtr& printer, const KFileItem& fileItem, int copies) { // // Start printing // printFile(printer, fileItem, copies); } void Smb4KClient::slotPrintDialogClosed(Smb4KPrintDialog* dialog) { // // Remove the print dialog from the list // if (dialog) { // Find the dialog in the list and take it from the list. // It will automatically be deleted on close, so there is // no need to delete the dialog here. int i = d->printDialogs.indexOf(dialog); d->printDialogs.takeAt(i); } } diff --git a/core/smb4kclient_p.cpp b/core/smb4kclient_p.cpp index ecbde74..0b5f6a8 100644 --- a/core/smb4kclient_p.cpp +++ b/core/smb4kclient_p.cpp @@ -1,2041 +1,2037 @@ /*************************************************************************** Private classes for the SMB client ------------------- begin : So Oct 21 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kclient_p.h" #include "smb4ksettings.h" #include "smb4kwalletmanager.h" #include "smb4kcustomoptions.h" #include "smb4kcustomoptionsmanager.h" #include "smb4knotification.h" // System includes #include // #include #include // #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include #define SMBC_DEBUG 0 using namespace Smb4KGlobal; // // Authentication function for libsmbclient // static void get_auth_data_with_context_fn(SMBCCTX *context, const char *server, const char *share, char *workgroup, int maxLenWorkgroup, char *username, int maxLenUsername, char *password, int maxLenPassword) { if (context != nullptr) { Smb4KClientJob *job = static_cast(smbc_getOptionUserData(context)); if (job) { job->get_auth_data_fn(server, share, workgroup, maxLenWorkgroup, username, maxLenUsername, password, maxLenPassword); } } } // // Client job // Smb4KClientJob::Smb4KClientJob(QObject* parent) : KJob(parent), m_process(Smb4KGlobal::NoProcess) { } Smb4KClientJob::~Smb4KClientJob() { // // Clear the list of workgroups // while (!m_workgroups.isEmpty()) { m_workgroups.takeFirst().clear(); } // // Clear the list of hosts // while (!m_hosts.isEmpty()) { m_hosts.takeFirst().clear(); } // // Clear the list of shares // while (!m_shares.isEmpty()) { m_shares.takeFirst().clear(); } // // Clear the list of files and directories // while (!m_files.isEmpty()) { m_files.takeFirst().clear(); } } void Smb4KClientJob::start() { QTimer::singleShot(50, this, SLOT(slotStartJob())); } void Smb4KClientJob::setNetworkItem(NetworkItemPtr item) { m_item = item; } NetworkItemPtr Smb4KClientJob::networkItem() const { return m_item; } void Smb4KClientJob::setProcess(Smb4KGlobal::Process process) { m_process = process; } Smb4KGlobal::Process Smb4KClientJob::process() const { return m_process; } void Smb4KClientJob::setPrintFileItem(const KFileItem& item) { m_fileItem = item; } KFileItem Smb4KClientJob::printFileItem() const { return m_fileItem; } void Smb4KClientJob::setPrintCopies(int copies) { m_copies = copies; } int Smb4KClientJob::printCopies() const { return m_copies; } void Smb4KClientJob::get_auth_data_fn(const char* server, const char* /*share*/, char* workgroup, int /*maxLenWorkgroup*/, char* username, int maxLenUsername, char* password, int maxLenPassword) { // // Authentication // switch (m_item->type()) { case Network: { // // No authentication needed // break; } case Workgroup: { // // Only request authentication data, if the master browsers require // authentication data. // if (Smb4KSettings::masterBrowsersRequireAuth()) { if (QString::fromUtf8(server).toUpper() != QString::fromUtf8(workgroup).toUpper()) { // // This is the master browser. Create a host object for it. // HostPtr h = HostPtr(new Smb4KHost()); h->setWorkgroupName(QString::fromUtf8(workgroup)); h->setHostName(QString::fromUtf8(server)); // // Get the authentication data // Smb4KWalletManager::self()->readAuthInfo(h); // // Copy the authentication data // qstrncpy(username, h->login().toUtf8().data(), maxLenUsername); qstrncpy(password, h->password().toUtf8().data(), maxLenPassword); } } break; } case Host: { // // The host object // HostPtr h = m_item.staticCast(); // // Get the authentication data // Smb4KWalletManager::self()->readAuthInfo(h); // // Copy the authentication data // qstrncpy(username, h->login().toUtf8().data(), maxLenUsername); qstrncpy(password, h->password().toUtf8().data(), maxLenPassword); break; } case Share: { // // The share object // SharePtr s = m_item.staticCast(); // // Get the authentication data // Smb4KWalletManager::self()->readAuthInfo(s); // // Copy the authentication data // qstrncpy(username, s->login().toUtf8().data(), maxLenUsername); qstrncpy(password, s->password().toUtf8().data(), maxLenPassword); break; } case Directory: { // // The file object // FilePtr f = m_item.staticCast(); // // Create a share object // SharePtr s = SharePtr(new Smb4KShare()); s->setWorkgroupName(f->workgroupName()); s->setHostName(f->hostName()); s->setShareName(f->shareName()); s->setLogin(f->login()); s->setPassword(f->password()); // // Get the authentication data // Smb4KWalletManager::self()->readAuthInfo(s); // // Copy the authentication data // qstrncpy(username, s->login().toUtf8().data(), maxLenUsername); qstrncpy(password, s->password().toUtf8().data(), maxLenPassword); break; } default: { break; } } } QList Smb4KClientJob::workgroups() { return m_workgroups; } QList Smb4KClientJob::hosts() { return m_hosts; } QList Smb4KClientJob::shares() { return m_shares; } QList Smb4KClientJob::files() { return m_files; } QString Smb4KClientJob::workgroup() { QString workgroup; switch (m_item->type()) { case Network: { break; } case Workgroup: { workgroup = m_item->url().host().toUpper(); break; } case Host: { workgroup = m_item.staticCast()->workgroupName(); break; } case Share: { workgroup = m_item.staticCast()->workgroupName(); break; } case Directory: case File: { workgroup = m_item.staticCast()->workgroupName(); break; } default: { break; } } return workgroup; } void Smb4KClientJob::doLookups() { // // Get the function to open the directory // smbc_opendir_fn openDirectory = smbc_getFunctionOpendir(m_context); if (!openDirectory) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); emitResult(); return; emitResult(); return; } // // Open the directory // SMBCFILE *directory = openDirectory(m_context, m_item->url().toString().toUtf8().data()); if (!directory) { int errorCode = errno; switch (errorCode) { case EACCES: { setError(AccessDeniedError); setErrorText(strerror(errorCode)); break; } default: { setError(ClientError); setErrorText(strerror(errorCode)); } } emitResult(); return; } // // Read the directory // struct smbc_dirent *directoryEntry = nullptr; smbc_readdir_fn readDirectory = smbc_getFunctionReaddir(m_context); if (!readDirectory) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); emitResult(); return; } while ((directoryEntry = readDirectory(m_context, directory)) != nullptr) { switch (directoryEntry->smbc_type) { case SMBC_WORKGROUP: { // // Create a workgroup pointer // WorkgroupPtr workgroup = WorkgroupPtr(new Smb4KWorkgroup()); // // Set the workgroup name // QString workgroupName = QString::fromUtf8(directoryEntry->name); workgroup->setWorkgroupName(workgroupName); // // Set the master browser // QString masterBrowserName = QString::fromUtf8(directoryEntry->comment); workgroup->setMasterBrowserName(masterBrowserName); // // Lookup IP address // QHostAddress address = lookupIpAddress(masterBrowserName); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip the // workgroup and delete the pointer. // if (!address.isNull()) { workgroup->setMasterBrowserIpAddress(address); m_workgroups << workgroup; } else { workgroup.clear(); } break; } case SMBC_SERVER: { // // Create a host pointer // HostPtr host = HostPtr(new Smb4KHost()); // // Set the workgroup name // host->setWorkgroupName(m_item->url().host()); // // Set the host name // QString hostName = QString::fromUtf8(directoryEntry->name); host->setHostName(hostName); // // Set the comment // QString comment = QString::fromUtf8(directoryEntry->comment); host->setComment(comment); // // Lookup IP address // QHostAddress address = lookupIpAddress(hostName); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { host->setIpAddress(address); m_hosts << host; } else { host.clear(); } break; } case SMBC_FILE_SHARE: { // // Create a share pointer // SharePtr share = SharePtr(new Smb4KShare()); // // Set the workgroup name // share->setWorkgroupName(m_item.staticCast()->workgroupName()); // // Set the host name // share->setHostName(m_item->url().host()); // // Set the share name // share->setShareName(QString::fromUtf8(directoryEntry->name)); // // Set the comment // share->setComment(QString::fromUtf8(directoryEntry->comment)); // // Set share type // share->setShareType(FileShare); // // Set the authentication data // share->setLogin(m_item->url().userName()); share->setPassword(m_item->url().password()); // // Lookup IP address // QHostAddress address = lookupIpAddress(m_item->url().host()); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { share->setHostIpAddress(address); m_shares << share; } else { share.clear(); } break; } case SMBC_PRINTER_SHARE: { // // Create a share pointer // SharePtr share = SharePtr(new Smb4KShare()); // // Set the workgroup name // share->setWorkgroupName(m_item.staticCast()->workgroupName()); // // Set the host name // share->setHostName(m_item->url().host()); // // Set the share name // share->setShareName(QString::fromUtf8(directoryEntry->name)); // // Set the comment // share->setComment(QString::fromUtf8(directoryEntry->comment)); // // Set share type // share->setShareType(PrinterShare); // // Set the authentication data // share->setLogin(m_item->url().userName()); share->setPassword(m_item->url().password()); // // Lookup IP address // QHostAddress address = lookupIpAddress(m_item->url().host()); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { share->setHostIpAddress(address); m_shares << share; } else { share.clear(); } break; } case SMBC_IPC_SHARE: { // // Create a share pointer // SharePtr share = SharePtr(new Smb4KShare()); // // Set the workgroup name // share->setWorkgroupName(m_item.staticCast()->workgroupName()); // // Set the host name // share->setHostName(m_item->url().host()); // // Set the share name // share->setShareName(QString::fromUtf8(directoryEntry->name)); // // Set the comment // share->setComment(QString::fromUtf8(directoryEntry->comment)); // // Set share type // share->setShareType(IpcShare); // // Set the authentication data // share->setLogin(m_item->url().userName()); share->setPassword(m_item->url().password()); // // Lookup IP address // QHostAddress address = lookupIpAddress(m_item->url().host()); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { share->setHostIpAddress(address); m_shares << share; } else { share.clear(); } break; } case SMBC_DIR: { // // Do not process '.' and '..' directories // QString name = QString::fromUtf8(directoryEntry->name); if (name != "." && name != "..") { // // Create the URL for the discovered item // QUrl u = m_item->url(); u.setPath(m_item->url().path()+QDir::separator()+QString::fromUtf8(directoryEntry->name)); // // We do not stat directories. Directly create the directory object // FilePtr dir = FilePtr(new Smb4KFile(u, Directory)); // // Set the workgroup name // dir->setWorkgroupName(m_item.staticCast()->workgroupName()); // // Set the authentication data // dir->setLogin(m_item->url().userName()); dir->setPassword(m_item->url().password()); // // Lookup IP address // QHostAddress address = lookupIpAddress(m_item->url().host()); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { dir->setHostIpAddress(address); m_files << dir; } else { dir.clear(); } } break; } case SMBC_FILE: { // // Create the URL for the discovered item // QUrl u = m_item->url(); u.setPath(m_item->url().path()+QDir::separator()+QString::fromUtf8(directoryEntry->name)); // // Create the directory object // FilePtr dir = FilePtr(new Smb4KFile(u, File)); // // Set the workgroup name // dir->setWorkgroupName(m_item.staticCast()->workgroupName()); // // Stat the file // // FIXME // // Set the authentication data // dir->setLogin(m_item->url().userName()); dir->setPassword(m_item->url().password()); // // Lookup IP address // QHostAddress address = lookupIpAddress(m_item->url().host()); // // Process the IP address. // If the address is null, the server most likely went offline. So, skip it // and delete the pointer. // if (!address.isNull()) { dir->setHostIpAddress(address); m_files << dir; } else { dir.clear(); } break; } case SMBC_LINK: { qDebug() << "Processing links is not implemented."; qDebug() << directoryEntry->name; qDebug() << directoryEntry->comment; break; } default: { qDebug() << "Need to process network item " << directoryEntry->name; break; } } } // // Close the directory // smbc_closedir_fn closeDirectory = smbc_getFunctionClosedir(m_context); if (!closeDirectory) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); emitResult(); return; } (void)closeDirectory(m_context, directory); } void Smb4KClientJob::doPrinting() { // // The URL that is to be printed // QUrl fileUrl; // // Set the temporary directory // QTemporaryDir tempDir; // // Check if we can directly print the file // if (m_fileItem.mimetype() == "application/postscript" || m_fileItem.mimetype() == "application/pdf" || m_fileItem.mimetype().startsWith(QLatin1String("image"))) { // // Set the URL to the incoming file // fileUrl = m_fileItem.url(); } else if (m_fileItem.mimetype() == "application/x-shellscript" || m_fileItem.mimetype().startsWith(QLatin1String("text")) || m_fileItem.mimetype().startsWith(QLatin1String("message"))) { // // Set a printer object // QPrinter printer(QPrinter::HighResolution); printer.setCreator("Smb4K"); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(QString("%1/smb4k_print.pdf").arg(tempDir.path())); // // Open the file that is to be printed and read it // QStringList contents; QFile file(m_fileItem.url().path()); if (file.open(QFile::ReadOnly|QFile::Text)) { QTextStream ts(&file); while (!ts.atEnd()) { contents << ts.readLine(); } } else { return; } // // Convert the file to PDF // QTextDocument doc; if (m_fileItem.mimetype().endsWith(QLatin1String("html"))) { doc.setHtml(contents.join(" ")); } else { doc.setPlainText(contents.join("\n")); } doc.print(&printer); // // Set the URL to the converted file // fileUrl.setUrl(printer.outputFileName()); fileUrl.setScheme("file"); } else { Smb4KNotification::mimetypeNotSupported(m_fileItem.mimetype()); return; } // // Get the open function for the printer // smbc_open_print_job_fn openPrinter = smbc_getFunctionOpenPrintJob(m_context); if (!openPrinter) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); emitResult(); return; } // // Open the printer for printing // SMBCFILE *printer = openPrinter(m_context, m_item->url().toString().toUtf8().data()); if (!printer) { int errorCode = errno; switch (errorCode) { case EACCES: { setError(AccessDeniedError); setErrorText(strerror(errorCode)); break; } default: { setError(ClientError); setErrorText(strerror(errorCode)); break; } } emitResult(); return; } // // Open the file // QFile file(fileUrl.path()); if (!file.open(QFile::ReadOnly)) { setError(FileAccessError); setErrorText(i18n("The file %1 could not be read", fileUrl.path())); emitResult(); return; } // // Write X copies of the file to the printer // char buffer[4096]; qint64 bytes = 0; int copy = 0; while (copy < m_copies) { while ((bytes = file.read(buffer, sizeof(buffer))) > 0) { smbc_write_fn writeFile = smbc_getFunctionWrite(m_context); if (writeFile(m_context, printer, buffer, bytes) < 0) { setError(PrintFileError); setErrorText(i18n("The file %1 could not be printed to %2", fileUrl.path(), m_item.staticCast()->displayString())); smbc_close_fn closePrinter = smbc_getFunctionClose(m_context); closePrinter(m_context, printer); } } copy++; } // // Close the printer // smbc_close_fn closePrinter = smbc_getFunctionClose(m_context); closePrinter(m_context, printer); } QHostAddress Smb4KClientJob::lookupIpAddress(const QString& name) { // // The IP address object // QHostAddress ipAddress; // If the IP address is not to be determined for the local machine, we can use QHostInfo to // determine it. Otherwise we need to use QNetworkInterface for it. if (name.toUpper() == QHostInfo::localHostName().toUpper() || name.toUpper() == globalSambaOptions()["netbios name"].toUpper() || name.toUpper() == Smb4KSettings::netBIOSName().toUpper()) { // FIXME: Do we need to honor 'interfaces' here? QList addresses = QNetworkInterface::allAddresses(); // Get the IP address for the host. For the time being, prefer the // IPv4 address over the IPv6 address. for (const QHostAddress &addr : addresses) { // We only use global addresses. #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) if (addr.isGlobal()) #else if (!addr.isLoopback() && !addr.isMulticast()) #endif { if (addr.protocol() == QAbstractSocket::IPv4Protocol) { ipAddress = addr; break; } else if (addr.protocol() == QAbstractSocket::IPv6Protocol) { // FIXME: Use the right address here. ipAddress = addr; } } } } else { // Get the IP address QHostInfo hostInfo = QHostInfo::fromName(name); if (hostInfo.error() == QHostInfo::NoError) { // Get the IP address for the host. For the time being, prefer the // IPv4 address over the IPv6 address. for (const QHostAddress &addr : hostInfo.addresses()) { // We only use global addresses. #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) if (addr.isGlobal()) #else if (!addr.isLoopback() && !addr.isMulticast()) #endif { if (addr.protocol() == QAbstractSocket::IPv4Protocol) { ipAddress = addr; break; } else if (addr.protocol() == QAbstractSocket::IPv6Protocol) { // FIXME: Use the right address here. ipAddress = addr; } } } } } return ipAddress; } void Smb4KClientJob::slotStartJob() { // // Allocate new context // m_context = smbc_new_context(); if (!m_context) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); emitResult(); return; } // // Get the custom options // OptionsPtr options = Smb4KCustomOptionsManager::self()->findOptions(m_item); // // Set debug level // smbc_setDebug(m_context, SMBC_DEBUG); // // Set the NetBIOS name and the workgroup to make connections // switch (m_item->type()) { case Network: { // // We do not know about the servers and the domains/workgroups // present. So, do not set anything and use the default. // break; } case Workgroup: { // // Set the NetBIOS name of the master browser and the workgroup to be queried // WorkgroupPtr workgroup = m_item.staticCast(); smbc_setNetbiosName(m_context, workgroup->masterBrowserName().toUtf8().data()); smbc_setWorkgroup(m_context, workgroup->workgroupName().toUtf8().data()); break; } case Host: { // // Set both the NetBIOS name of the server and the workgroup to be queried // HostPtr host = m_item.staticCast(); smbc_setNetbiosName(m_context, host->hostName().toUtf8().data()); smbc_setWorkgroup(m_context, host->workgroupName().toUtf8().data()); break; } case Share: { // // Set both the NetBIOS name of the server and the workgroup to be queried // SharePtr share = m_item.staticCast(); smbc_setNetbiosName(m_context, share->hostName().toUtf8().data()); smbc_setWorkgroup(m_context, share->workgroupName().toUtf8().data()); break; } case Directory: { // // Set both the NetBIOS name of the server and the workgroup to be queried // FilePtr file = m_item.staticCast(); smbc_setNetbiosName(m_context, file->hostName().toUtf8().data()); smbc_setWorkgroup(m_context, file->workgroupName().toUtf8().data()); break; } default: { break; } } // // Set the user for making the connection // if (!m_item->url().userName().isEmpty()) { smbc_setUser(m_context, m_item->url().userName().toUtf8().data()); } // // Set the port // if (options) { if (options->useSmbPort()) { smbc_setPort(m_context, options->smbPort()); } else { smbc_setPort(m_context, 0 /* use the default */); } } else { if (Smb4KSettings::useRemoteSmbPort()) { smbc_setPort(m_context, Smb4KSettings::remoteSmbPort()); } else { smbc_setPort(m_context, 0 /* use the default */); } } // // Set the user data (this class) // smbc_setOptionUserData(m_context, this); // // Set number of master browsers to be used // if (Smb4KSettings::largeNetworkNeighborhood()) { smbc_setOptionBrowseMaxLmbCount(m_context, 3); } else { smbc_setOptionBrowseMaxLmbCount(m_context, 0 /* all master browsers */); } // // Set the encryption level // if (Smb4KSettings::useEncryptionLevel()) { switch (Smb4KSettings::encryptionLevel()) { case Smb4KSettings::EnumEncryptionLevel::None: { smbc_setOptionSmbEncryptionLevel(m_context, SMBC_ENCRYPTLEVEL_NONE); break; } case Smb4KSettings::EnumEncryptionLevel::Request: { smbc_setOptionSmbEncryptionLevel(m_context, SMBC_ENCRYPTLEVEL_REQUEST); break; } case Smb4KSettings::EnumEncryptionLevel::Require: { smbc_setOptionSmbEncryptionLevel(m_context, SMBC_ENCRYPTLEVEL_REQUIRE); break; } default: { break; } } } // // Set the usage of anonymous login // smbc_setOptionNoAutoAnonymousLogin(m_context, false); // // Set the usage of the winbind ccache // smbc_setOptionUseCCache(m_context, Smb4KSettings::useWinbindCCache()); // // Set usage of Kerberos // if (options) { smbc_setOptionUseKerberos(m_context, options->useKerberos()); } else { smbc_setOptionUseKerberos(m_context, Smb4KSettings::useKerberos()); } smbc_setOptionFallbackAfterKerberos(m_context, 1); // // Set the channel for debug output // smbc_setOptionDebugToStderr(m_context, 1); // // Set auth callback function // smbc_setFunctionAuthDataWithContext(m_context, get_auth_data_with_context_fn); // // Initialize context with the previously defined options // if (!smbc_init_context(m_context)) { int errorCode = errno; setError(ClientError); setErrorText(strerror(errorCode)); smbc_free_context(m_context, 0); emitResult(); return; } // // Set the new context // (void)smbc_set_context(m_context); // // Process the given URL according to the passed process // switch (m_process) { case LookupDomains: case LookupDomainMembers: case LookupShares: case LookupFiles: { doLookups(); break; } case PrintFile: { doPrinting(); break; } default: { break; } } // // Free the context // smbc_free_context(m_context, 0); // // Emit the result // emitResult(); } Smb4KPreviewDialog::Smb4KPreviewDialog(const SharePtr& share, QWidget* parent) : QDialog(parent), m_share(share) { // // Dialog title // setWindowTitle(i18n("Preview of %1", share->displayString())); // // Attributes // setAttribute(Qt::WA_DeleteOnClose, true); // // Layout // QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); // // The list widget // QListWidget *listWidget = new QListWidget(this); listWidget->setSelectionMode(QAbstractItemView::SingleSelection); connect(listWidget, SIGNAL(itemActivated(QListWidgetItem*)), SLOT(slotItemActivated(QListWidgetItem*))); layout->addWidget(listWidget, 0); // // Toolbar // Use QToolBar here with the settings suggested by the note provided in the 'Detailed Description' // section of KToolBar (https://api.kde.org/frameworks/kxmlgui/html/classKToolBar.html) // QToolBar *toolBar = new QToolBar(this); toolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle); toolBar->setProperty("otherToolbar", true); // // Reload / cancel action // KDualAction *reloadAction = new KDualAction(toolBar); reloadAction->setObjectName("reload_action"); reloadAction->setInactiveText(i18n("Reload")); reloadAction->setInactiveIcon(KDE::icon("view-refresh")); reloadAction->setActiveText(i18n("Abort")); reloadAction->setActiveIcon(KDE::icon("process-stop")); reloadAction->setActive(false); reloadAction->setAutoToggle(false); connect(reloadAction, SIGNAL(toggled(bool)), this, SLOT(slotReloadActionTriggered())); toolBar->addAction(reloadAction); // // Up action // QAction *upAction =toolBar->addAction(KDE::icon("go-up"), i18n("Up"), this, SLOT(slotUpActionTriggered())); upAction->setObjectName("up_action"); upAction->setEnabled(false); toolBar->addSeparator(); // // URL combo box // KUrlComboBox *urlCombo = new KUrlComboBox(KUrlComboBox::Directories, toolBar); urlCombo->setEditable(false); toolBar->addWidget(urlCombo); connect(urlCombo, SIGNAL(urlActivated(QUrl)), this, SLOT(slotUrlActivated(QUrl))); layout->addWidget(toolBar, 0); // // Dialog button box // QDialogButtonBox *buttonBox = new QDialogButtonBox(this); buttonBox->setOrientation(Qt::Horizontal); QPushButton *closeButton = buttonBox->addButton(QDialogButtonBox::Close); connect(closeButton, SIGNAL(clicked()), this, SLOT(slotClosingDialog())); layout->addWidget(buttonBox, 0); // // Set the minimum width // setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "PreviewDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Start the preview // m_currentItem = m_share; QTimer::singleShot(0, this, SLOT(slotInitializePreview())); } Smb4KPreviewDialog::~Smb4KPreviewDialog() { // // Clear the share // m_share.clear(); // // Clear the current item // m_currentItem.clear(); // // Clear the listing // while (!m_listing.isEmpty()) { m_listing.takeFirst().clear(); } } SharePtr Smb4KPreviewDialog::share() const { return m_share; } void Smb4KPreviewDialog::slotClosingDialog() { // // Save the dialog size // KConfigGroup group(Smb4KSettings::self()->config(), "PreviewDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); // // Emit the aboutToClose() signal // emit aboutToClose(this); // // Close the dialog // accept(); } void Smb4KPreviewDialog::slotReloadActionTriggered() { KDualAction *reloadAction = findChild(); if (reloadAction->isActive()) { emit requestAbort(); } else { emit requestPreview(m_currentItem); } } void Smb4KPreviewDialog::slotUpActionTriggered() { // // Get the new URL // QUrl u = KIO::upUrl(m_currentItem->url()); // // Create a new network item object, if necessary and set the new current // item. Also, disable the "Up" action, if necessary. // if (m_share->url().matches(u, QUrl::StripTrailingSlash)) { findChild("up_action")->setEnabled(false); m_currentItem = m_share; } else if (m_share->url().path().length() < u.path().length()) { FilePtr file = FilePtr(new Smb4KFile(u, Directory)); file->setWorkgroupName(m_share->workgroupName()); m_currentItem = file; } else { return; } // // Emit the requestPreview() signal // emit requestPreview(m_currentItem); } void Smb4KPreviewDialog::slotUrlActivated(const QUrl &url) { // // Get the full authentication information. This is needed, since the combo // box only returns sanitized URLs, i.e. without password, etc. // QUrl u = url; u.setUserName(m_share->login()); u.setPassword(m_share->password()); // // Create a new network item object, if necessary and set the new current // item. // if (m_share->url().matches(u, QUrl::StripTrailingSlash)) { m_currentItem = m_share; } else { FilePtr file = FilePtr(new Smb4KFile(u, Directory)); file->setWorkgroupName(m_share->workgroupName()); m_currentItem = file; } // // Emit the requestPreview() signal // emit requestPreview(m_currentItem); } void Smb4KPreviewDialog::slotItemActivated(QListWidgetItem *item) { // // Only process the item if it represents a directory // if (item && item->type() == Directory) { // // Find the file item, make it the current one and emit the requestPreview() // signal. // for (const FilePtr &f : m_listing) { if (item->data(Qt::UserRole).toUrl().matches(f->url(), QUrl::None)) { m_currentItem = f; emit requestPreview(m_currentItem); break; } } } } void Smb4KPreviewDialog::slotInitializePreview() { emit requestPreview(m_currentItem); } void Smb4KPreviewDialog::slotPreviewResults(const QList &list) { // // Only process data the belongs to this dialog // if (m_share->workgroupName() == list.first()->workgroupName() && m_share->hostName() == list.first()->hostName() && list.first()->url().path().startsWith(m_share->url().path())) { // // Clear the internal listing // while (!m_listing.isEmpty()) { m_listing.takeFirst().clear(); } // // Copy the list into the private variable // m_listing = list; // // Get the list widget // QListWidget *listWidget = findChild(); // // Clear the list widget // listWidget->clear(); // // Insert the new listing // if (listWidget) { for (const FilePtr &f : list) { QListWidgetItem *item = new QListWidgetItem(f->icon(), f->name(), listWidget, f->isDirectory() ? Directory : File); item->setData(Qt::UserRole, f->url()); } } // // Sort the list widget // listWidget->sortItems(); // // Add the URL to the combo box and show it. Omit duplicates. // KUrlComboBox *urlCombo = findChild(); QStringList urls = urlCombo->urls(); urls << m_currentItem->url().toString(); urlCombo->setUrls(urls); urlCombo->setUrl(m_currentItem->url()); // // Enable / disable the "Up" action // findChild("up_action")->setEnabled(!m_share->url().matches(m_currentItem->url(), QUrl::StripTrailingSlash)); } } void Smb4KPreviewDialog::slotAboutToStart(const NetworkItemPtr &item, int type) { if (type == LookupFiles) { switch (item->type()) { case Share: { SharePtr s = item.staticCast(); if (m_share->workgroupName() == s->workgroupName() && m_share->hostName() == s->hostName() && s->url().path().startsWith(m_share->url().path())) { KDualAction *reloadAction = findChild(); reloadAction->setActive(true); } break; } case Directory: { FilePtr f = item.staticCast(); if (m_share->workgroupName() == f->workgroupName() && m_share->hostName() == f->hostName() && f->url().path().startsWith(m_share->url().path())) { KDualAction *reloadAction = findChild(); reloadAction->setActive(true); } break; } default: { break; } } } } void Smb4KPreviewDialog::slotFinished(const NetworkItemPtr &item, int type) { if (type == LookupFiles) { switch (item->type()) { case Share: { SharePtr s = item.staticCast(); if (m_share->workgroupName() == s->workgroupName() && m_share->hostName() == s->hostName() && s->url().path().startsWith(m_share->url().path())) { KDualAction *reloadAction = findChild(); reloadAction->setActive(false); } break; } case Directory: { FilePtr f = item.staticCast(); if (m_share->workgroupName() == f->workgroupName() && m_share->hostName() == f->hostName() && f->url().path().startsWith(m_share->url().path())) { KDualAction *reloadAction = findChild(); reloadAction->setActive(false); } break; } default: { break; } } } } Smb4KPrintDialog::Smb4KPrintDialog(const SharePtr& share, QWidget* parent) : QDialog(parent), m_share(share) { // // Dialog title // setWindowTitle(i18n("Print File")); // // Attributes // setAttribute(Qt::WA_DeleteOnClose, true); // // Layout // QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); // // Information group box // QGroupBox *informationBox = new QGroupBox(i18n("Information"), this); QGridLayout *informationBoxLayout = new QGridLayout(informationBox); // Printer name QLabel *printerNameLabel = new QLabel(i18n("Printer:"), informationBox); QLabel *printerName = new QLabel(share->displayString(), informationBox); informationBoxLayout->addWidget(printerNameLabel, 0, 0, 0); informationBoxLayout->addWidget(printerName, 0, 1, 0); // IP address QLabel *ipAddressLabel = new QLabel(i18n("IP Address:"), informationBox); QLabel *ipAddress = new QLabel(share->hostIpAddress(), informationBox); informationBoxLayout->addWidget(ipAddressLabel, 1, 0, 0); informationBoxLayout->addWidget(ipAddress, 1, 1, 0); // Workgroup QLabel *workgroupNameLabel = new QLabel(i18n("Domain:"), informationBox); QLabel *workgroupName = new QLabel(share->workgroupName(), informationBox); informationBoxLayout->addWidget(workgroupNameLabel, 2, 0, 0); informationBoxLayout->addWidget(workgroupName, 2, 1, 0); layout->addWidget(informationBox); // // File and settings group box // QGroupBox *fileBox = new QGroupBox(i18n("File and Settings"), this); QGridLayout *fileBoxLayout = new QGridLayout(fileBox); // File QLabel *fileLabel = new QLabel(i18n("File:"), fileBox); KUrlRequester *file = new KUrlRequester(fileBox); file->setMode(KFile::File|KFile::LocalOnly|KFile::ExistingOnly); file->setUrl(QUrl::fromLocalFile(QDir::homePath())); file->setWhatsThis(i18n("This is the file you want to print on the remote printer. " "Currently only a few mimetypes are supported such as PDF, Postscript, plain text, and " "images. If the file's mimetype is not supported, you need to convert it.")); connect(file, SIGNAL(textChanged(QString)), this, SLOT(slotUrlChanged())); fileBoxLayout->addWidget(fileLabel, 0, 0, 0); fileBoxLayout->addWidget(file, 0, 1, 0); // Copies QLabel *copiesLabel = new QLabel(i18n("Copies:"), fileBox); QSpinBox *copies = new QSpinBox(fileBox); copies->setValue(1); copies->setMinimum(1); copies->setWhatsThis(i18n("This is the number of copies you want to print.")); fileBoxLayout->addWidget(copiesLabel, 1, 0, 0); fileBoxLayout->addWidget(copies, 1, 1, 0); layout->addWidget(fileBox); // // Buttons // QDialogButtonBox *buttonBox = new QDialogButtonBox(this); QPushButton *printButton = buttonBox->addButton(i18n("Print"), QDialogButtonBox::ActionRole); printButton->setObjectName("print_button"); printButton->setShortcut(Qt::CTRL|Qt::Key_P); connect(printButton, SIGNAL(clicked(bool)), this, SLOT(slotPrintButtonClicked())); QPushButton *cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel); cancelButton->setObjectName("cancel_button"); cancelButton->setShortcut(Qt::Key_Escape); cancelButton->setDefault(true); connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(slotCancelButtonClicked())); layout->addWidget(buttonBox); // // Set the minimum width // setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "PrintDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Set the buttons // slotUrlChanged(); } Smb4KPrintDialog::~Smb4KPrintDialog() { } SharePtr Smb4KPrintDialog::share() const { return m_share; } KFileItem Smb4KPrintDialog::fileItem() const { return m_fileItem; } void Smb4KPrintDialog::slotUrlChanged() { // // Take the focus from the URL requester and give it to the dialog's // button box // QDialogButtonBox *buttonBox = findChild(); buttonBox->setFocus(); // // Get the URL from the URL requester // KUrlRequester *file = findChild(); KFileItem fileItem = KFileItem(file->url()); // // Apply the settings to the buttons of the dialog's button box // QPushButton *printButton = findChild("print_button"); printButton->setEnabled(fileItem.url().isValid() && fileItem.isFile()); printButton->setDefault(fileItem.url().isValid() && fileItem.isFile()); QPushButton *cancelButton = findChild("cancel_button"); cancelButton->setDefault(!fileItem.url().isValid() || !fileItem.isFile()); } void Smb4KPrintDialog::slotPrintButtonClicked() { // // Get the file item that is to be printed // KUrlRequester *file = findChild(); m_fileItem = KFileItem(file->url()); if (m_fileItem.url().isValid()) { // // Check if the mime type is supported or if the file can be // converted into a supported mimetype // if (m_fileItem.mimetype() != "application/postscript" && m_fileItem.mimetype() != "application/pdf" && m_fileItem.mimetype() != "application/x-shellscript" && !m_fileItem.mimetype().startsWith(QLatin1String("text")) && !m_fileItem.mimetype().startsWith(QLatin1String("message")) && !m_fileItem.mimetype().startsWith(QLatin1String("image"))) { Smb4KNotification::mimetypeNotSupported(m_fileItem.mimetype()); return; } // // Save the window size // KConfigGroup group(Smb4KSettings::self()->config(), "PrintDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); // // Emit the printFile() signal // QSpinBox *copies = findChild(); emit printFile(m_share, m_fileItem, copies->value()); // // Emit the aboutToClose() signal // emit aboutToClose(this); // // Close the print dialog // accept(); } } void Smb4KPrintDialog::slotCancelButtonClicked() { // // Abort the printing // Smb4KClient::self()->abort(); // // Emit the aboutToClose() signal // emit aboutToClose(this); // // Reject the dialog // reject(); } diff --git a/core/smb4kcustomoptions.cpp b/core/smb4kcustomoptions.cpp index e89130c..38b67db 100644 --- a/core/smb4kcustomoptions.cpp +++ b/core/smb4kcustomoptions.cpp @@ -1,977 +1,973 @@ /*************************************************************************** This class carries custom options ------------------- begin : Fr 29 Apr 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kcustomoptions.h" #include "smb4ksettings.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include // KDE includes #include #include class Smb4KCustomOptionsPrivate { public: QString workgroup; QUrl url; QHostAddress ip; NetworkItem type; Smb4KCustomOptions::Remount remount; bool useUser; KUser user; bool useGroup; KUserGroup group; bool useFileMode; QString fileMode; bool useDirectoryMode; QString directoryMode; #if defined(Q_OS_LINUX) bool cifsUnixExtensionsSupport; bool useFileSystemPort; int fileSystemPort; bool useSecurityMode; int securityMode; bool useWriteAccess; int writeAccess; #endif QString profile; bool useSmbPort; int smbPort; bool useKerberos; QString mac; bool wakeOnLanBeforeFirstScan; bool wakeOnLanBeforeMount; }; Smb4KCustomOptions::Smb4KCustomOptions(Smb4KHost *host) : d(new Smb4KCustomOptionsPrivate) { d->workgroup = host->workgroupName(); d->url = host->url(); d->type = Host; d->remount = UndefinedRemount; d->useUser = Smb4KMountSettings::useUserId(); d->user = KUser(Smb4KMountSettings::userId()); d->useGroup = Smb4KMountSettings::useGroupId(); d->group = KUserGroup(Smb4KMountSettings::groupId()); d->useFileMode = Smb4KMountSettings::useFileMode(); d->fileMode = Smb4KMountSettings::fileMode(); d->useDirectoryMode = Smb4KMountSettings::useDirectoryMode(); d->directoryMode = Smb4KMountSettings::directoryMode(); #if defined(Q_OS_LINUX) d->cifsUnixExtensionsSupport = Smb4KMountSettings::cifsUnixExtensionsSupport(); d->useFileSystemPort = Smb4KMountSettings::useRemoteFileSystemPort(); d->fileSystemPort = Smb4KMountSettings::remoteFileSystemPort(); d->useSecurityMode = Smb4KMountSettings::useSecurityMode(); d->securityMode = Smb4KMountSettings::securityMode(); d->useWriteAccess = Smb4KMountSettings::useWriteAccess(); d->writeAccess = Smb4KMountSettings::writeAccess(); #endif d->useSmbPort = Smb4KSettings::useRemoteSmbPort(); d->smbPort = host->port() != -1 ? host->port() : Smb4KSettings::remoteSmbPort(); d->useKerberos = Smb4KSettings::useKerberos(); d->ip.setAddress(host->ipAddress()); d->wakeOnLanBeforeFirstScan = false; d->wakeOnLanBeforeMount = false; } Smb4KCustomOptions::Smb4KCustomOptions(Smb4KShare *share) : d(new Smb4KCustomOptionsPrivate) { d->url = share->url(); d->workgroup = share->workgroupName(); d->type = Share; d->remount = UndefinedRemount; d->useUser = Smb4KMountSettings::useUserId(); d->user = share->user(); d->useGroup = Smb4KMountSettings::useGroupId(); d->group = share->group(); d->useFileMode = Smb4KMountSettings::useFileMode(); d->fileMode = Smb4KMountSettings::fileMode(); d->useDirectoryMode = Smb4KMountSettings::useDirectoryMode(); d->directoryMode = Smb4KMountSettings::directoryMode(); #if defined(Q_OS_LINUX) d->cifsUnixExtensionsSupport = Smb4KMountSettings::cifsUnixExtensionsSupport(); d->useFileSystemPort = Smb4KMountSettings::useRemoteFileSystemPort(); d->fileSystemPort = share->port() != -1 ? share->port() : Smb4KMountSettings::remoteFileSystemPort(); d->useSecurityMode = Smb4KMountSettings::useSecurityMode(); d->securityMode = Smb4KMountSettings::securityMode(); d->useWriteAccess = Smb4KMountSettings::useWriteAccess(); d->writeAccess = Smb4KMountSettings::writeAccess(); #endif d->useSmbPort = Smb4KSettings::useRemoteSmbPort(); d->smbPort = Smb4KSettings::remoteSmbPort(); d->useKerberos = Smb4KSettings::useKerberos(); d->ip.setAddress(share->hostIpAddress()); d->wakeOnLanBeforeFirstScan = false; d->wakeOnLanBeforeMount = false; } Smb4KCustomOptions::Smb4KCustomOptions(const Smb4KCustomOptions &o) : d(new Smb4KCustomOptionsPrivate) { *d = *o.d; } Smb4KCustomOptions::Smb4KCustomOptions() : d(new Smb4KCustomOptionsPrivate) { d->type = UnknownNetworkItem; d->remount = UndefinedRemount; d->useUser = Smb4KMountSettings::useUserId(); d->user = KUser(Smb4KMountSettings::userId()); d->useGroup = Smb4KMountSettings::useGroupId(); d->group = KUserGroup(Smb4KMountSettings::groupId()); d->useFileMode = Smb4KMountSettings::useFileMode(); d->fileMode = Smb4KMountSettings::fileMode(); d->useDirectoryMode = Smb4KMountSettings::useDirectoryMode(); d->directoryMode = Smb4KMountSettings::directoryMode(); #if defined(Q_OS_LINUX) d->cifsUnixExtensionsSupport = Smb4KMountSettings::cifsUnixExtensionsSupport(); d->useFileSystemPort = Smb4KMountSettings::useRemoteFileSystemPort(); d->fileSystemPort = Smb4KMountSettings::remoteFileSystemPort(); d->useSecurityMode = Smb4KMountSettings::useSecurityMode(); d->securityMode = Smb4KMountSettings::securityMode(); d->useWriteAccess = Smb4KMountSettings::useWriteAccess(); d->writeAccess = Smb4KMountSettings::writeAccess(); #endif d->useSmbPort = Smb4KSettings::useRemoteSmbPort(); d->smbPort = Smb4KSettings::remoteSmbPort(); d->useKerberos = Smb4KSettings::useKerberos(); d->wakeOnLanBeforeFirstScan = false; d->wakeOnLanBeforeMount = false; } Smb4KCustomOptions::~Smb4KCustomOptions() { } void Smb4KCustomOptions::setHost(Smb4KHost *host) { // // Set all variables that can be extracted from the host item // if (host) { switch (d->type) { case UnknownNetworkItem: { d->workgroup = host->workgroupName(); d->url = host->url(); d->type = Host; d->smbPort = host->port() != -1 ? host->port() : d->smbPort; d->ip.setAddress(host->ipAddress()); break; } default: { break; } } } } void Smb4KCustomOptions::setShare(Smb4KShare *share) { // // Set all variables that can be extracted from the share item // if (share) { switch (d->type) { case UnknownNetworkItem: { d->url = share->url(); d->workgroup = share->workgroupName(); d->type = Share; #if defined(Q_OS_LINUX) d->fileSystemPort = share->port() != -1 ? share->port() : d->fileSystemPort; #endif d->user = share->user(); d->group = share->group(); d->ip.setAddress(share->hostIpAddress()); break; } case Host: { if (QString::compare(d->url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), Qt::CaseInsensitive) == 0) { d->url = share->url(); d->type = Share; #if defined(Q_OS_LINUX) d->fileSystemPort = share->port() != -1 ? share->port() : d->fileSystemPort; #endif d->user = share->user(); d->group = share->group(); d->ip.setAddress(share->hostIpAddress()); } break; } default: { break; } } } } Smb4KGlobal::NetworkItem Smb4KCustomOptions::type() const { return d->type; } void Smb4KCustomOptions::setWorkgroupName(const QString &workgroup) { d->workgroup = workgroup; } QString Smb4KCustomOptions::workgroupName() const { return d->workgroup; } void Smb4KCustomOptions::setUrl(const QUrl &url) { d->url = url; } QUrl Smb4KCustomOptions::url() const { return d->url; } QString Smb4KCustomOptions::hostName() const { return d->url.host().toUpper(); } QString Smb4KCustomOptions::shareName() const { if (d->url.path().startsWith('/')) { return d->url.path().remove(0, 1); } return d->url.path(); } void Smb4KCustomOptions::setIpAddress(const QString &ip) { d->ip.setAddress(ip); } QString Smb4KCustomOptions::ipAddress() const { return d->ip.toString(); } bool Smb4KCustomOptions::hasIpAddress() const { return !d->ip.isNull(); } QString Smb4KCustomOptions::displayString() const { QString string; switch (d->type) { case Host: { string = hostName(); break; } case Share: { string = i18n("%1 on %2", shareName(), hostName()); break; } default: { break; } } return string; } void Smb4KCustomOptions::setRemount(Smb4KCustomOptions::Remount remount) { switch (d->type) { case Share: { d->remount = remount; break; } default: { d->remount = UndefinedRemount; break; } } } Smb4KCustomOptions::Remount Smb4KCustomOptions::remount() const { return d->remount; } void Smb4KCustomOptions::setUseUser(bool use) { d->useUser = use; } bool Smb4KCustomOptions::useUser() const { return d->useUser; } void Smb4KCustomOptions::setUser(const KUser &user) { d->user = user; } KUser Smb4KCustomOptions::user() const { return d->user; } void Smb4KCustomOptions::setUseGroup(bool use) { d->useGroup = use; } bool Smb4KCustomOptions::useGroup() const { return d->useGroup; } void Smb4KCustomOptions::setGroup(const KUserGroup& group) { d->group = group; } KUserGroup Smb4KCustomOptions::group() const { return d->group; } void Smb4KCustomOptions::setUseFileMode(bool use) { d->useFileMode = use; } bool Smb4KCustomOptions::useFileMode() const { return d->useFileMode; } void Smb4KCustomOptions::setFileMode(const QString& mode) { d->fileMode = mode; } QString Smb4KCustomOptions::fileMode() const { return d->fileMode; } void Smb4KCustomOptions::setUseDirectoryMode(bool use) { d->useDirectoryMode = use; } bool Smb4KCustomOptions::useDirectoryMode() const { return d->useDirectoryMode; } void Smb4KCustomOptions::setDirectoryMode(const QString& mode) { d->directoryMode = mode; } QString Smb4KCustomOptions::directoryMode() const { return d->directoryMode; } #if defined(Q_OS_LINUX) void Smb4KCustomOptions::setCifsUnixExtensionsSupport(bool support) { d->cifsUnixExtensionsSupport = support; } bool Smb4KCustomOptions::cifsUnixExtensionsSupport() const { return d->cifsUnixExtensionsSupport; } void Smb4KCustomOptions::setUseFileSystemPort(bool use) { d->useFileSystemPort = use; } bool Smb4KCustomOptions::useFileSystemPort() const { return d->useFileSystemPort; } void Smb4KCustomOptions::setFileSystemPort(int port) { d->fileSystemPort = port; switch (d->type) { case Share: { d->url.setPort(port); break; } default: { break; } } } int Smb4KCustomOptions::fileSystemPort() const { return d->fileSystemPort; } void Smb4KCustomOptions::setUseSecurityMode(bool use) { d->useSecurityMode = use; } bool Smb4KCustomOptions::useSecurityMode() const { return d->useSecurityMode; } void Smb4KCustomOptions::setSecurityMode(int mode) { d->securityMode = mode; } int Smb4KCustomOptions::securityMode() const { return d->securityMode; } void Smb4KCustomOptions::setUseWriteAccess(bool use) { d->useWriteAccess = use; } bool Smb4KCustomOptions::useWriteAccess() const { return d->useWriteAccess; } void Smb4KCustomOptions::setWriteAccess(int access) { d->writeAccess = access; } int Smb4KCustomOptions::writeAccess() const { return d->writeAccess; } #endif void Smb4KCustomOptions::setProfile(const QString &profile) { d->profile = profile; } QString Smb4KCustomOptions::profile() const { return d->profile; } void Smb4KCustomOptions::setUseSmbPort(bool use) { d->useSmbPort = use; } bool Smb4KCustomOptions::useSmbPort() const { return d->useSmbPort; } void Smb4KCustomOptions::setSmbPort(int port) { d->smbPort = port; switch (d->type) { case Host: { d->url.setPort(port); break; } default: { break; } } } int Smb4KCustomOptions::smbPort() const { return d->smbPort; } void Smb4KCustomOptions::setUseKerberos(bool use) { d->useKerberos = use; } bool Smb4KCustomOptions::useKerberos() const { return d->useKerberos; } void Smb4KCustomOptions::setMACAddress(const QString &macAddress) { QRegExp exp("..\\:..\\:..\\:..\\:..\\:.."); if (exp.exactMatch(macAddress)) { d->mac = macAddress; } } QString Smb4KCustomOptions::macAddress() const { return d->mac; } void Smb4KCustomOptions::setWOLSendBeforeNetworkScan(bool send) { d->wakeOnLanBeforeFirstScan = send; } bool Smb4KCustomOptions::wolSendBeforeNetworkScan() const { return d->wakeOnLanBeforeFirstScan; } void Smb4KCustomOptions::setWOLSendBeforeMount(bool send) { d->wakeOnLanBeforeMount = send; } bool Smb4KCustomOptions::wolSendBeforeMount() const { return d->wakeOnLanBeforeMount; } QMap Smb4KCustomOptions::customOptions() const { QMap entries; switch (d->remount) { case RemountOnce: { entries.insert("remount", "once"); break; } case RemountAlways: { entries.insert("remount", "always"); break; } case UndefinedRemount: { entries.insert("remount", QString()); break; } default: { break; } } entries.insert("use_user", d->useUser ? "true" : "false"); entries.insert("uid", QString("%1").arg(d->user.userId().toString())); entries.insert("owner", d->user.loginName()); entries.insert("use_group", d->useGroup ? "true" : "false"); entries.insert("gid", QString("%1").arg(d->group.groupId().toString())); entries.insert("group", d->group.name()); entries.insert("use_file_mode", d->useFileMode ? "true" : "false"); entries.insert("file_mode", d->fileMode); entries.insert("use_directory_mode", d->useDirectoryMode ? "true" : "false"); entries.insert("directory_mode", d->directoryMode); #if defined(Q_OS_LINUX) entries.insert("cifs_unix_extensions_support", d->cifsUnixExtensionsSupport ? "true" : "false"); entries.insert("use_filesystem_port", d->useFileSystemPort ? "true" : "false"); entries.insert("filesystem_port", QString("%1").arg(fileSystemPort())); entries.insert("use_security_mode", d->useSecurityMode ? "true" : "false"); switch (d->securityMode) { case Smb4KMountSettings::EnumSecurityMode::None: { entries.insert("security_mode", "none"); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5: { entries.insert("security_mode", "krb5"); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5i: { entries.insert("security_mode", "krb5i"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlm: { entries.insert("security_mode", "ntlm"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmi: { entries.insert("security_mode", "ntlmi"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2: { entries.insert("security_mode", "ntlmv2"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2i: { entries.insert("security_mode", "ntlmv2i"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmssp: { entries.insert("security_mode", "ntlmssp"); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmsspi: { entries.insert("security_mode", "ntlmsspi"); break; } default: { break; } } entries.insert("use_write_access", d->useWriteAccess ? "true" : "false"); switch (d->writeAccess) { case Smb4KMountSettings::EnumWriteAccess::ReadWrite: { entries.insert("write_access", "true"); break; } case Smb4KMountSettings::EnumWriteAccess::ReadOnly: { entries.insert("write_access", "false"); break; } default: { break; } } #endif entries.insert("use_smb_port", d->useSmbPort ? "true" : "false"); entries.insert("smb_port", QString("%1").arg(smbPort())); entries.insert("kerberos", d->useKerberos ? "true" : "false"); entries.insert("mac_address", d->mac); entries.insert("wol_send_before_first_scan", d->wakeOnLanBeforeFirstScan ? "true" : "false"); entries.insert("wol_send_before_mount", d->wakeOnLanBeforeMount ? "true" : "false"); return entries; } bool Smb4KCustomOptions::hasOptions() const { // // NOTE: This function does not honor the workgroup, the url, // the ip address, the type and the profile, because these things // are not custom options. // // Perform remount if (d->remount != Smb4KCustomOptions::UndefinedRemount) { return true; } // Use user information if (d->useUser != Smb4KMountSettings::useUserId()) { return true; } // User information if (d->user.userId() != KUser(Smb4KMountSettings::userId()).userId()) { return true; } // Use group information if (d->useGroup != Smb4KMountSettings::useGroupId()) { return true; } // Group information if (d->group.groupId() != KUserGroup(Smb4KMountSettings::groupId()).groupId()) { return true; } // Use file mask if (d->useFileMode != Smb4KMountSettings::useFileMode()) { return true; } if (d->fileMode != Smb4KMountSettings::fileMode()) { return true; } if (d->useDirectoryMode != Smb4KMountSettings::useDirectoryMode()) { return true; } if (d->directoryMode != Smb4KMountSettings::directoryMode()) { return true; } #if defined(Q_OS_LINUX) // CIFS Unix extension support if (d->cifsUnixExtensionsSupport != Smb4KMountSettings::cifsUnixExtensionsSupport()) { return true; } // Use filesystem port if (d->useFileSystemPort != Smb4KMountSettings::useRemoteFileSystemPort()) { return true; } // File system port (used for mounting) if (d->fileSystemPort != Smb4KMountSettings::remoteFileSystemPort()) { return true; } // Use security mode if (d->useSecurityMode != Smb4KMountSettings::useSecurityMode()) { return true; } // Security mode if (d->securityMode != Smb4KMountSettings::securityMode()) { return true; } // Use write access if (d->useWriteAccess != Smb4KMountSettings::useWriteAccess()) { return true; } // Write access if (d->writeAccess != Smb4KMountSettings::writeAccess()) { return true; } #endif // Use SMB port if (d->useSmbPort != Smb4KSettings::useRemoteSmbPort()) { return true; } // SMB port if (d->smbPort != Smb4KSettings::remoteSmbPort()) { return true; } // Kerberos if (d->useKerberos != Smb4KSettings::useKerberos()) { return true; } // MAC address if (!d->mac.isEmpty()) { return true; } // Send WOL packages before first scan if (d->wakeOnLanBeforeFirstScan) { return true; } // Send WOL packages before mount if (d->wakeOnLanBeforeMount) { return true; } return false; } void Smb4KCustomOptions::update(Smb4KCustomOptions *options) { d->ip.setAddress(options->ipAddress()); d->remount = options->remount(); d->useUser = options->useUser(); d->user = options->user(); d->useGroup = options->useGroup(); d->group = options->group(); d->useFileMode = options->useFileMode(); d->fileMode = options->fileMode(); d->useDirectoryMode = options->useDirectoryMode(); d->directoryMode = options->directoryMode(); #if defined(Q_OS_LINUX) d->cifsUnixExtensionsSupport = options->cifsUnixExtensionsSupport(); d->useFileSystemPort = options->useFileSystemPort(); d->fileSystemPort = options->fileSystemPort(); d->useSecurityMode = options->useSecurityMode(); d->securityMode = options->securityMode(); d->useWriteAccess = options->useWriteAccess(); d->writeAccess = options->writeAccess(); #endif d->profile = options->profile(); d->useSmbPort = options->useSmbPort(); d->smbPort = options->smbPort(); d->useKerberos = options->useKerberos(); d->mac = options->macAddress(); d->wakeOnLanBeforeFirstScan = options->wolSendBeforeNetworkScan(); d->wakeOnLanBeforeMount = options->wolSendBeforeMount(); } diff --git a/core/smb4kcustomoptionsmanager.cpp b/core/smb4kcustomoptionsmanager.cpp index 715f37e..f3d9bc0 100644 --- a/core/smb4kcustomoptionsmanager.cpp +++ b/core/smb4kcustomoptionsmanager.cpp @@ -1,1186 +1,1182 @@ /*************************************************************************** Manage custom options ------------------- begin : Fr 29 Apr 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kcustomoptionsmanager.h" #include "smb4kcustomoptionsmanager_p.h" #include "smb4kcustomoptions.h" #include "smb4khomesshareshandler.h" #include "smb4knotification.h" #include "smb4khost.h" #include "smb4kshare.h" #include "smb4ksettings.h" #include "smb4kglobal.h" #include "smb4kprofilemanager.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include using namespace Smb4KGlobal; Q_GLOBAL_STATIC(Smb4KCustomOptionsManagerStatic, p); Smb4KCustomOptionsManager::Smb4KCustomOptionsManager(QObject *parent) : QObject(parent), d(new Smb4KCustomOptionsManagerPrivate) { // First we need the directory. QString path = dataLocation(); QDir dir; if (!dir.exists(path)) { dir.mkpath(path); } readCustomOptions(); // Connections connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit())); } Smb4KCustomOptionsManager::~Smb4KCustomOptionsManager() { } Smb4KCustomOptionsManager *Smb4KCustomOptionsManager::self() { return &p->instance; } void Smb4KCustomOptionsManager::addRemount(const SharePtr &share, bool always) { if (share) { // // Find the right custom options, if they exist // OptionsPtr options = findOptions(share, true); if (options) { // If the options are already in the list, check if the share is // always to be remounted. If so, ignore the 'always' argument // and leave that option untouched. if (options->remount() != Smb4KCustomOptions::RemountAlways) { options->setRemount(always ? Smb4KCustomOptions::RemountAlways : Smb4KCustomOptions::RemountOnce); } } else { options = OptionsPtr(new Smb4KCustomOptions(share.data())); options->setProfile(Smb4KProfileManager::self()->activeProfile()); options->setRemount(always ? Smb4KCustomOptions::RemountAlways : Smb4KCustomOptions::RemountOnce); d->options << options; } // // Write the custom options // writeCustomOptions(); } } void Smb4KCustomOptionsManager::removeRemount(const SharePtr &share, bool force) { if (share) { // // Get the remount // OptionsPtr options = findOptions(share, true); // // Remove the remount flag and, if there are no more options defined, // the options object itself. Save the modified list to the file afterwards. // if (options) { if (options->remount() == Smb4KCustomOptions::RemountOnce) { options->setRemount(Smb4KCustomOptions::UndefinedRemount); } else if (options->remount() == Smb4KCustomOptions::RemountAlways && force) { options->setRemount(Smb4KCustomOptions::UndefinedRemount); } if (!options->hasOptions()) { removeCustomOptions(options, false); } } // // Write the options // writeCustomOptions(); } } void Smb4KCustomOptionsManager::clearRemounts(bool force) { // // Remove the remount flag and, if there are nomore options defined, // also the options object. Write everything to the file afterwards. // for (const OptionsPtr &o : d->options) { if (o->type() == Share) { if (o->remount() == Smb4KCustomOptions::RemountOnce) { o->setRemount(Smb4KCustomOptions::UndefinedRemount); } else if (o->remount() == Smb4KCustomOptions::RemountAlways && force) { o->setRemount(Smb4KCustomOptions::UndefinedRemount); } } if (!o->hasOptions()) { removeCustomOptions(o, false); } } // // Write the options // writeCustomOptions(); } QList Smb4KCustomOptionsManager::sharesToRemount() { // // List of relevant custom options // QList options = customOptions(false); // // List of remounts // QList remounts; // // Get the list of remounts // for (const OptionsPtr &o : options) { if (o->remount() == Smb4KCustomOptions::RemountOnce) { remounts << o; } else if (o->remount() == Smb4KCustomOptions::RemountAlways) { remounts << o; } } // // Return relevant options // return remounts; } OptionsPtr Smb4KCustomOptionsManager::findOptions(const NetworkItemPtr &networkItem, bool exactMatch) { // // The options that are to be returned // OptionsPtr options; // // Get the list of options // QList optionsList = customOptions(false); // // Only do something if the list of options is not empty. // if (!optionsList.isEmpty()) { for (const OptionsPtr &opt : optionsList) { // // If we want to have an exact match, skip all options that do not match // if (exactMatch) { if (networkItem->type() != opt->type() || QString::compare(networkItem->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) != 0) { continue; } } // // Now assign the options // if (networkItem->type() == Host && opt->type() == Host) { HostPtr host = networkItem.staticCast(); if (host) { if (QString::compare(host->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0 || (host->url().isEmpty() && host->ipAddress() == opt->ipAddress())) { options = opt; break; } } } else if (networkItem->type() == Share) { SharePtr share = networkItem.staticCast(); if (share) { if (opt->type() == Share && QString::compare(share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0) { // Since this is the exact match, break here options = opt; break; } else if (opt->type() == Host && QString::compare(share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath|QUrl::StripTrailingSlash), opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0) { // These options belong to the host. Do not break here, // because there might still be an exact match options = opt; } } } } } // // Return the options // return options; } OptionsPtr Smb4KCustomOptionsManager::findOptions(const QUrl &url) { // // The options that are to be returned // OptionsPtr options; // // Search the options for the given URL // if (url.isValid() && url.scheme() == "smb") { // // Get the relevant options // QList optionsList = customOptions(false); // // Get the options // for (const OptionsPtr &o : optionsList) { if (o->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash) == url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash)) { options = o; break; } } } // // Return the options // return options; } void Smb4KCustomOptionsManager::readCustomOptions() { // // Clear the list of options // while (!d->options.isEmpty()) { d->options.takeFirst().clear(); } // // Set the XML file // QFile xmlFile(dataLocation()+QDir::separator()+"custom_options.xml"); if (xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QXmlStreamReader xmlReader(&xmlFile); while (!xmlReader.atEnd()) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "custom_options" && (xmlReader.attributes().value("version") != "1.2" && xmlReader.attributes().value("version") != "2.0")) { xmlReader.raiseError(i18n("The format of %1 is not supported.", xmlFile.fileName())); break; } else { if (xmlReader.name() == "options") { OptionsPtr options = OptionsPtr(new Smb4KCustomOptions()); options->setProfile(xmlReader.attributes().value("profile").toString()); // // Initialize the options // if (QString::compare(xmlReader.attributes().value("type").toString(), "host", Qt::CaseInsensitive) == 0) { options->setHost(new Smb4KHost()); } else { options->setShare(new Smb4KShare()); } while (!(xmlReader.isEndElement() && xmlReader.name() == "options")) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "workgroup") { options->setWorkgroupName(xmlReader.readElementText()); } else if (xmlReader.name() == "url") { QUrl url(xmlReader.readElementText()); options->setUrl(url); } else if (xmlReader.name() == "unc") { QUrl url = QUrl::fromUserInput(xmlReader.readElementText()); url.setScheme("smb"); options->setUrl(url); } else if (xmlReader.name() == "ip") { options->setIpAddress(xmlReader.readElementText()); } else if (xmlReader.name() == "custom") { while (!(xmlReader.isEndElement() && xmlReader.name() == "custom")) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "smb_port") { bool ok = false; int portNumber = xmlReader.readElementText().toInt(&ok); if (ok) { options->setSmbPort(portNumber); } } else if (xmlReader.name() == "use_smb_port") { QString useSmbPort = xmlReader.readElementText(); if (useSmbPort == "true") { options->setUseSmbPort(true); } else { options->setUseSmbPort(false); } } else if (xmlReader.name() == "kerberos") { QString useKerberos = xmlReader.readElementText(); if (useKerberos == "true") { options->setUseKerberos(true); } else { options->setUseKerberos(false); } } else if (xmlReader.name() == "mac_address") { QString macAddress = xmlReader.readElementText(); QRegExp exp("..\\:..\\:..\\:..\\:..\\:.."); if (exp.exactMatch(macAddress)) { options->setMACAddress(macAddress); } } else if (xmlReader.name() == "wol_send_before_first_scan") { QString send = xmlReader.readElementText(); if (send == "true") { options->setWOLSendBeforeNetworkScan(true); } else { options->setWOLSendBeforeNetworkScan(false); } } else if (xmlReader.name() == "wol_send_before_mount") { QString send = xmlReader.readElementText(); if (send == "true") { options->setWOLSendBeforeMount(true); } else { options->setWOLSendBeforeMount(false); } } else if (xmlReader.name() == "remount") { QString remount = xmlReader.readElementText(); if (remount == "once") { options->setRemount(Smb4KCustomOptions::RemountOnce); } else if (remount == "always") { options->setRemount(Smb4KCustomOptions::RemountAlways); } else { options->setRemount(Smb4KCustomOptions::UndefinedRemount); } } else if (xmlReader.name() == "use_user") { QString useUser = xmlReader.readElementText(); if (useUser == "true") { options->setUseUser(true); } else { options->setUseUser(false); } } else if (xmlReader.name() == "uid") { KUser user((K_UID)xmlReader.readElementText().toInt()); if (user.isValid()) { options->setUser(user); } } else if (xmlReader.name() == "use_group") { QString useGroup = xmlReader.readElementText(); if (useGroup == "true") { options->setUseGroup(true); } else { options->setUseGroup(false); } } else if (xmlReader.name() == "gid") { KUserGroup group((K_GID)xmlReader.readElementText().toInt()); if (group.isValid()) { options->setGroup(group); } } else if (xmlReader.name() == "use_file_mode") { QString useFileMode = xmlReader.readElementText(); if (useFileMode == "true") { options->setUseFileMode(true); } else { options->setUseFileMode(false); } } else if (xmlReader.name() == "file_mode") { options->setFileMode(xmlReader.readElementText()); } else if (xmlReader.name() == "use_directory_mode") { QString useDirectoryMode = xmlReader.readElementText(); if (useDirectoryMode == "true") { options->setUseDirectoryMode(true); } else { options->setUseDirectoryMode(false); } } else if (xmlReader.name() == "directory_mode") { options->setDirectoryMode(xmlReader.readElementText()); } #if defined(Q_OS_LINUX) else if (xmlReader.name() == "cifs_unix_extensions_support") { QString support = xmlReader.readElementText(); if (support == "true") { options->setCifsUnixExtensionsSupport(true); } else { options->setCifsUnixExtensionsSupport(false); } } else if (xmlReader.name() == "use_filesystem_port") { QString useFilesystemPort = xmlReader.readElementText(); if (useFilesystemPort == "true") { options->setUseFileSystemPort(true); } else { options->setUseFileSystemPort(false); } } else if (xmlReader.name() == "filesystem_port") { bool ok = false; int portNumber = xmlReader.readElementText().toInt(&ok); if (ok) { options->setFileSystemPort(portNumber); } } else if (xmlReader.name() == "use_security_mode") { QString useSecurityMode = xmlReader.readElementText(); if (useSecurityMode == "true") { options->setUseSecurityMode(true); } else { options->setUseSecurityMode(false); } } else if (xmlReader.name() == "security_mode") { QString securityMode = xmlReader.readElementText(); if (securityMode == "none") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::None); } else if (securityMode == "krb5") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5); } else if (securityMode == "krb5i") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5i); } else if (securityMode == "ntlm") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlm); } else if (securityMode == "ntlmi") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmi); } else if (securityMode == "ntlmv2") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2); } else if (securityMode == "ntlmv2i") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i); } else if (securityMode == "ntlmssp") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmssp); } else if (securityMode == "ntlmsspi") { options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi); } } else if (xmlReader.name() == "use_write_access") { QString useWriteAccess = xmlReader.readElementText(); if (useWriteAccess == "true") { options->setUseWriteAccess(true); } else { options->setUseWriteAccess(false); } } else if (xmlReader.name() == "write_access") { QString writeAccess = xmlReader.readElementText(); if (writeAccess == "true") { options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadWrite); } else if (writeAccess == "false") { options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadWrite); } } #endif } } } continue; } else { continue; } } d->options << options; } } } } xmlFile.close(); if (xmlReader.hasError()) { Smb4KNotification::readingFileFailed(xmlFile, xmlReader.errorString()); } } else { if (xmlFile.exists()) { Smb4KNotification::openingFileFailed(xmlFile); } } } void Smb4KCustomOptionsManager::writeCustomOptions() { // // Set the XML file // QFile xmlFile(dataLocation()+QDir::separator()+"custom_options.xml"); // // Write the options to the file // if (!d->options.isEmpty()) { if (xmlFile.open(QIODevice::WriteOnly|QIODevice::Text)) { QXmlStreamWriter xmlWriter(&xmlFile); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("custom_options"); xmlWriter.writeAttribute("version", "2.0"); for (const OptionsPtr &options : d->options) { if (options->hasOptions() || options->remount() == Smb4KCustomOptions::RemountOnce) { xmlWriter.writeStartElement("options"); xmlWriter.writeAttribute("type", options->type() == Host ? "host" : "share"); xmlWriter.writeAttribute("profile", options->profile()); xmlWriter.writeTextElement("workgroup", options->workgroupName()); xmlWriter.writeTextElement("url", options->url().toDisplayString()); xmlWriter.writeTextElement("ip", options->ipAddress()); xmlWriter.writeStartElement("custom"); QMap map = options->customOptions(); QMapIterator it(map); while (it.hasNext()) { it.next(); if (!it.value().isEmpty()) { xmlWriter.writeTextElement(it.key(), it.value()); } } xmlWriter.writeEndElement(); xmlWriter.writeEndElement(); } } xmlWriter.writeEndDocument(); xmlFile.close(); } else { Smb4KNotification::openingFileFailed(xmlFile); } } else { xmlFile.remove(); } } QList Smb4KCustomOptionsManager::customOptions(bool optionsOnly) { // // Options list // QList options; // // Get this list of options // for (const OptionsPtr &o : d->options) { if (Smb4KSettings::useProfiles() && o->profile() != Smb4KProfileManager::self()->activeProfile()) { continue; } if (o->hasOptions() || (!optionsOnly && o->remount() == Smb4KCustomOptions::RemountOnce)) { options << o; } } // // Return the list of relevant options // return options; } void Smb4KCustomOptionsManager::replaceCustomOptions(const QList &optionsList) { // // Clear the list of options. Honor profiles. // QMutableListIterator it(d->options); while (it.hasNext()) { OptionsPtr options = it.next(); if (Smb4KSettings::useProfiles() && options->profile() != Smb4KProfileManager::self()->activeProfile()) { continue; } it.remove(); } // // Append the new list // if (!optionsList.isEmpty()) { for (const OptionsPtr &options : optionsList) { if (Smb4KSettings::useProfiles()) { options->setProfile(Smb4KProfileManager::self()->activeProfile()); } if (options->hasOptions() || options->remount() == Smb4KCustomOptions::RemountOnce) { d->options << options; } } } writeCustomOptions(); } void Smb4KCustomOptionsManager::openCustomOptionsDialog(const NetworkItemPtr &item) { if (item) { OptionsPtr options; switch (item->type()) { case Host: { HostPtr host = item.staticCast(); if (host) { options = findOptions(host); if (!options) { options = OptionsPtr(new Smb4KCustomOptions(host.data())); options->setProfile(Smb4KProfileManager::self()->activeProfile()); } } break; } case Share: { SharePtr share = item.staticCast(); if (share && !share->isPrinter()) { if (share->isHomesShare()) { if (!Smb4KHomesSharesHandler::self()->specifyUser(share, true)) { return; } } options = findOptions(share); if (!options) { options = OptionsPtr(new Smb4KCustomOptions(share.data())); options->setProfile(Smb4KProfileManager::self()->activeProfile()); // Get rid of the 'homes' share if (share->isHomesShare()) { options->setUrl(share->homeUrl()); } } else { // In case the custom options object for the host has been // returned, change its internal network item, otherwise we // will change the host's custom options... options->setShare(share.data()); } } break; } default: { break; } } if (options) { QPointer dlg = new Smb4KCustomOptionsDialog(options, QApplication::activeWindow()); if (dlg->exec() == QDialog::Accepted) { if (options->hasOptions()) { addCustomOptions(options, true); } else { removeCustomOptions(options, true); } } else { resetCustomOptions(); } delete dlg; } } } void Smb4KCustomOptionsManager::addCustomOptions(const OptionsPtr &options, bool write) { if (options) { // // Check if options for the URL already exist // OptionsPtr knownOptions = findOptions(options->url()); if (knownOptions) { // // Update the options // knownOptions->update(options.data()); } else { // // Add the options // if (options->profile().isEmpty()) { options->setProfile(Smb4KProfileManager::self()->activeProfile()); } d->options << options; } // // In case the options are defined for a host, propagate them // to the options of shares belonging to that host. Overwrite // the settings // if (options->type() == Host) { for (const OptionsPtr &o : d->options) { if (o->type() == Share && o->hostName() == options->hostName() && o->workgroupName() == options->workgroupName()) { o->setIpAddress(options->ipAddress()); o->setUseUser(options->useUser()); o->setUser(options->user()); o->setUseGroup(options->useGroup()); o->setGroup(options->group()); o->setUseFileMode(options->useFileMode()); o->setFileMode(options->fileMode()); o->setUseDirectoryMode(options->useDirectoryMode()); o->setDirectoryMode(options->directoryMode()); #if defined(Q_OS_LINUX) o->setCifsUnixExtensionsSupport(options->cifsUnixExtensionsSupport()); o->setUseFileSystemPort(options->useFileSystemPort()); o->setFileSystemPort(options->fileSystemPort()); o->setUseSecurityMode(options->useSecurityMode()); o->setSecurityMode(options->securityMode()); o->setUseWriteAccess(options->useWriteAccess()); o->setWriteAccess(options->writeAccess()); #endif o->setUseSmbPort(options->useSmbPort()); o->setSmbPort(options->smbPort()); o->setUseKerberos(options->useKerberos()); o->setMACAddress(options->macAddress()); o->setWOLSendBeforeNetworkScan(options->wolSendBeforeNetworkScan()); o->setWOLSendBeforeMount(options->wolSendBeforeMount()); } } } // // Write the custom options to the file, if desired // if (write) { writeCustomOptions(); } } } void Smb4KCustomOptionsManager::removeCustomOptions(const OptionsPtr &options, bool write) { if (options) { // // Find the custom options and remove them // for (int i = 0; i < d->options.size(); ++i) { if ((!Smb4KSettings::useProfiles() || Smb4KProfileManager::self()->activeProfile() == d->options.at(i)->profile()) && d->options.at(i)->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash) == options->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash)) { d->options.takeAt(i).clear(); break; } } // // Write the custom options to the file, if desired // if (write) { writeCustomOptions(); } } } QList Smb4KCustomOptionsManager::wakeOnLanEntries() const { QList list; // // Get the Wake-On-LAN entries // for (const OptionsPtr &options : d->options) { if (!options->macAddress().isEmpty() && (options->wolSendBeforeNetworkScan() || options->wolSendBeforeMount())) { list << options; } } // // Return them // return list; } void Smb4KCustomOptionsManager::resetCustomOptions() { readCustomOptions(); } void Smb4KCustomOptionsManager::migrateProfile(const QString& from, const QString& to) { // // Replace the old with the new profile // for (const OptionsPtr &options : d->options) { if (options->profile() == from) { options->setProfile(to); } } // // Write all custom options to the file. // writeCustomOptions(); } void Smb4KCustomOptionsManager::removeProfile(const QString& name) { // // Remove all entries belonging to the profile // QMutableListIterator it(d->options); while (it.hasNext()) { OptionsPtr options = it.next(); if (QString::compare(options->profile(), name, Qt::CaseSensitive) == 0) { it.remove(); } } // // Write all custom options to the file. // writeCustomOptions(); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KCustomOptionsManager::slotAboutToQuit() { writeCustomOptions(); } diff --git a/core/smb4kcustomoptionsmanager_p.cpp b/core/smb4kcustomoptionsmanager_p.cpp index 1f93ec6..fae2bf3 100644 --- a/core/smb4kcustomoptionsmanager_p.cpp +++ b/core/smb4kcustomoptionsmanager_p.cpp @@ -1,2024 +1,2020 @@ /*************************************************************************** Private helper classes for Smb4KCustomOptionsManagerPrivate class ------------------- begin : Fr 29 Apr 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kcustomoptionsmanager_p.h" #include "smb4ksettings.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include #include #include #include Smb4KCustomOptionsDialog::Smb4KCustomOptionsDialog(const OptionsPtr &options, QWidget *parent) : QDialog(parent), m_options(options) { // // Set the title // setWindowTitle(i18n("Custom Options")); // // Set up the layout // QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); setLayout(layout); // Header QWidget *header = new QWidget(this); QHBoxLayout *headerLayout = new QHBoxLayout(header); headerLayout->setSpacing(5); headerLayout->setMargin(0); QLabel *pixmap = new QLabel(header); QPixmap preferencesPixmap = KDE::icon("preferences-system-network").pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(preferencesPixmap); pixmap->setAlignment(Qt::AlignCenter); QLabel *description = 0; switch (m_options->type()) { case Host: { description = new QLabel(i18n("

Define custom options for host %1 and all the shares it provides.

", m_options->displayString()), header); break; } case Share: { description = new QLabel(i18n("

Define custom options for share %1.

", m_options->displayString()), header); break; } default: { description = new QLabel(); break; } } description->setWordWrap(true); description->setAlignment(Qt::AlignVCenter); headerLayout->addWidget(pixmap, 0); headerLayout->addWidget(description, Qt::AlignVCenter); layout->addWidget(header, 0); // // Set up the operating system dependent stuff // setupView(); // // Finish the layout // QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); QPushButton *restoreButton = buttonBox->addButton(QDialogButtonBox::RestoreDefaults); QPushButton *okButton = buttonBox->addButton(QDialogButtonBox::Ok); okButton->setShortcut(Qt::CTRL|Qt::Key_Return); okButton->setDefault(true); QPushButton *cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel); cancelButton->setShortcut(Qt::Key_Escape); layout->addWidget(buttonBox, 0); // // Connections // connect(restoreButton, SIGNAL(clicked()), SLOT(slotSetDefaultValues())); connect(okButton, SIGNAL(clicked()), SLOT(slotOKClicked())); connect(cancelButton, SIGNAL(clicked()), SLOT(reject())); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "CustomOptionsDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Enable/disable buttons // restoreButton->setEnabled(!checkDefaultValues()); } Smb4KCustomOptionsDialog::~Smb4KCustomOptionsDialog() { } #if defined(Q_OS_LINUX) // // Linux // void Smb4KCustomOptionsDialog::setupView() { // // Tab widget with settings // QTabWidget *tabWidget = new QTabWidget(this); QVBoxLayout *dialogLayout = qobject_cast(layout()); dialogLayout->addWidget(tabWidget, 0); // // Custom options for mounting // QWidget *mountingTab = new QWidget(tabWidget); QVBoxLayout *mountingTabLayout = new QVBoxLayout(mountingTab); mountingTabLayout->setSpacing(5); // // Common options // QGroupBox *commonBox = new QGroupBox(i18n("Common Options"), mountingTab); QGridLayout *commonBoxLayout = new QGridLayout(commonBox); commonBoxLayout->setSpacing(5); QCheckBox *remountAlways = new QCheckBox(i18n("Always remount this share"), commonBox); remountAlways->setObjectName("RemountAlways"); remountAlways->setEnabled(m_options->type() == Share); connect(remountAlways, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(remountAlways, 0, 0, 1, 2, 0); // Write access QCheckBox *useWriteAccess = new QCheckBox(Smb4KMountSettings::self()->useWriteAccessItem()->label(), commonBox); useWriteAccess->setObjectName("UseWriteAccess"); KComboBox *writeAccess = new KComboBox(commonBox); writeAccess->setObjectName("WriteAccess"); QString readWriteText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadWrite).label; QString readOnlyText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadOnly).label; writeAccess->addItem(readWriteText); writeAccess->addItem(readOnlyText); connect(useWriteAccess, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(writeAccess, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(useWriteAccess, 1, 0, 0); commonBoxLayout->addWidget(writeAccess, 1, 1, 0); // Remote file system port QCheckBox *useFilesystemPort = new QCheckBox(Smb4KMountSettings::self()->useRemoteFileSystemPortItem()->label(), commonBox); useFilesystemPort->setObjectName("UseFilesystemPort"); QSpinBox *filesystemPort = new QSpinBox(commonBox); filesystemPort->setObjectName("FileSystemPort"); filesystemPort->setMinimum(Smb4KMountSettings::self()->remoteFileSystemPortItem()->minValue().toInt()); filesystemPort->setMaximum(Smb4KMountSettings::self()->remoteFileSystemPortItem()->maxValue().toInt()); // filesystemPort->setSliderEnabled(true); connect(useFilesystemPort, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(filesystemPort, SIGNAL(valueChanged(int)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(useFilesystemPort, 2, 0, 0); commonBoxLayout->addWidget(filesystemPort, 2, 1, 0); mountingTabLayout->addWidget(commonBox, 0); // // CIFS Unix Extensions Support // QGroupBox *extensionsSupportBox = new QGroupBox(i18n("CIFS Unix Extensions Support"), mountingTab); QGridLayout *extensionsSupportBoxLayout = new QGridLayout(extensionsSupportBox); extensionsSupportBoxLayout->setSpacing(5); QCheckBox *cifsExtensionsSupport = new QCheckBox(i18n("This server supports the CIFS Unix extensions"), extensionsSupportBox); cifsExtensionsSupport->setObjectName("CifsExtensionsSupport"); connect(cifsExtensionsSupport, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(cifsExtensionsSupport, SIGNAL(toggled(bool)), SLOT(slotCifsExtensionsSupport(bool))); extensionsSupportBoxLayout->addWidget(cifsExtensionsSupport, 0, 0, 1, 4, 0); // User Id QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), extensionsSupportBox); useUserId->setObjectName("UseUserId"); KComboBox *userId = new KComboBox(extensionsSupportBox); userId->setObjectName("UserId"); QList allUsers = KUser::allUsers(); for (const KUser &u : allUsers) { userId->addItem(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId()), QVariant::fromValue(u.groupId().nativeId())); } connect(useUserId, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(userId, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); extensionsSupportBoxLayout->addWidget(useUserId, 1, 0, 0); extensionsSupportBoxLayout->addWidget(userId, 1, 1, 0); // Group Id QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), extensionsSupportBox); useGroupId->setObjectName("UseGroupId"); KComboBox *groupId = new KComboBox(extensionsSupportBox); groupId->setObjectName("GroupId"); QList allGroups = KUserGroup::allGroups(); for (const KUserGroup &g : allGroups) { groupId->addItem(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId()), QVariant::fromValue(g.groupId().nativeId())); } connect(useGroupId, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(groupId, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); extensionsSupportBoxLayout->addWidget(useGroupId, 2, 0, 0); extensionsSupportBoxLayout->addWidget(groupId, 2, 1, 0); // File mode QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), extensionsSupportBox); useFileMode->setObjectName("UseFileMode"); KLineEdit *fileMode = new KLineEdit(extensionsSupportBox); fileMode->setObjectName("FileMode"); fileMode->setClearButtonEnabled(true); fileMode->setAlignment(Qt::AlignRight); connect(useFileMode, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(fileMode, SIGNAL(textEdited(QString)), this, SLOT(slotCheckValues())); extensionsSupportBoxLayout->addWidget(useFileMode, 3, 0, 0); extensionsSupportBoxLayout->addWidget(fileMode, 3, 1, 0); // Directory mode QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), extensionsSupportBox); useDirectoryMode->setObjectName("UseDirectoryMode"); KLineEdit *directoryMode = new KLineEdit(extensionsSupportBox); directoryMode->setObjectName("DirectoryMode"); directoryMode->setClearButtonEnabled(true); directoryMode->setAlignment(Qt::AlignRight); connect(useDirectoryMode, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(directoryMode, SIGNAL(textEdited(QString)), this, SLOT(slotCheckValues())); extensionsSupportBoxLayout->addWidget(useDirectoryMode, 4, 0, 0); extensionsSupportBoxLayout->addWidget(directoryMode, 4, 1, 0); mountingTabLayout->addWidget(extensionsSupportBox, 0); // // Advanced options // QGroupBox *advancedOptionsBox = new QGroupBox(i18n("Advanced Options"), mountingTab); QGridLayout *advancedOptionsBoxLayout = new QGridLayout(advancedOptionsBox); advancedOptionsBoxLayout->setSpacing(5); // Security mode QCheckBox *useSecurityMode = new QCheckBox(Smb4KMountSettings::self()->useSecurityModeItem()->label(), advancedOptionsBox); useSecurityMode->setObjectName("UseSecurityMode"); KComboBox *securityMode = new KComboBox(advancedOptionsBox); securityMode->setObjectName("SecurityMode"); QString noneText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::None).label; QString krb5Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5).label; QString krb5iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5i).label; QString ntlmText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlm).label; QString ntlmiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmi).label; QString ntlmv2Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2).label; QString ntlmv2iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i).label; QString ntlmsspText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmssp).label; QString ntlmsspiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi).label; securityMode->addItem(noneText); securityMode->addItem(krb5Text); securityMode->addItem(krb5iText); securityMode->addItem(ntlmText); securityMode->addItem(ntlmiText); securityMode->addItem(ntlmv2Text); securityMode->addItem(ntlmv2iText); securityMode->addItem(ntlmsspText); connect(useSecurityMode, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(securityMode, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); advancedOptionsBoxLayout->addWidget(useSecurityMode, 0, 0, 0); advancedOptionsBoxLayout->addWidget(securityMode, 0, 1, 0); mountingTabLayout->addWidget(advancedOptionsBox, 0); mountingTabLayout->addStretch(100); tabWidget->addTab(mountingTab, i18n("Mounting")); // // Custom options for Samba // QWidget *sambaTab = new QWidget(tabWidget); QVBoxLayout *sambaTabLayout = new QVBoxLayout(sambaTab); sambaTabLayout->setSpacing(5); // // Common Options // QGroupBox *commonSambaOptionsBox = new QGroupBox(i18n("Common Options"), sambaTab); QGridLayout *commonSambaOptionsBoxLayout = new QGridLayout(commonSambaOptionsBox); commonSambaOptionsBoxLayout->setSpacing(5); // SMB port QCheckBox *useSmbPort = new QCheckBox(Smb4KSettings::self()->useRemoteSmbPortItem()->label(), commonSambaOptionsBox); useSmbPort->setObjectName("UseSmbPort"); QSpinBox *smbPort = new QSpinBox(commonSambaOptionsBox); smbPort->setObjectName("SmbPort"); smbPort->setMinimum(Smb4KSettings::self()->remoteSmbPortItem()->minValue().toInt()); smbPort->setMaximum(Smb4KSettings::self()->remoteSmbPortItem()->maxValue().toInt()); // smbPort->setSliderEnabled(true); connect(useSmbPort, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(smbPort, SIGNAL(valueChanged(int)), this, SLOT(slotCheckValues())); commonSambaOptionsBoxLayout->addWidget(useSmbPort, 0, 0, 0); commonSambaOptionsBoxLayout->addWidget(smbPort, 0, 1, 0); sambaTabLayout->addWidget(commonSambaOptionsBox, 0); // // Authentication // QGroupBox *authenticationBox = new QGroupBox(i18n("Authentication"), sambaTab); QVBoxLayout *authenticationBoxLayout = new QVBoxLayout(authenticationBox); authenticationBoxLayout->setSpacing(5); // Kerberos QCheckBox *useKerberos = new QCheckBox(Smb4KSettings::self()->useKerberosItem()->label(), authenticationBox); useKerberos->setObjectName("UseKerberos"); connect(useKerberos, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); authenticationBoxLayout->addWidget(useKerberos, 0); sambaTabLayout->addWidget(authenticationBox, 0); sambaTabLayout->addStretch(100); tabWidget->addTab(sambaTab, i18n("Samba")); // // Custom options for Wake-On-LAN // // NOTE: If you change the texts here, also alter them in the respective // config page. // QWidget *wakeOnLanTab = new QWidget(tabWidget); QVBoxLayout *wakeOnLanTabLayout = new QVBoxLayout(wakeOnLanTab); wakeOnLanTabLayout->setSpacing(5); // // MAC address // QGroupBox *macAddressBox = new QGroupBox(i18n("MAC Address"), wakeOnLanTab); QGridLayout *macAddressBoxLayout = new QGridLayout(macAddressBox); macAddressBoxLayout->setSpacing(5); // MAC address QLabel *macAddressLabel = new QLabel(i18n("MAC Address:"), macAddressBox); KLineEdit *macAddress = new KLineEdit(macAddressBox); macAddress->setObjectName("MACAddress"); macAddress->setClearButtonEnabled(true); macAddress->setInputMask("HH:HH:HH:HH:HH:HH;_"); // MAC address, see QLineEdit doc macAddressLabel->setBuddy(macAddress); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotCheckValues())); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotEnableWOLFeatures(QString))); macAddressBoxLayout->addWidget(macAddressLabel, 0, 0, 0); macAddressBoxLayout->addWidget(macAddress, 0, 1, 0); wakeOnLanTabLayout->addWidget(macAddressBox, 0); // // Wake-On-LAN Actions // QGroupBox *wakeOnLANActionsBox = new QGroupBox(i18n("Actions"), wakeOnLanTab); QVBoxLayout *wakeOnLANActionsBoxLayout = new QVBoxLayout(wakeOnLANActionsBox); wakeOnLANActionsBoxLayout->setSpacing(5); // Send magic package before network scan QCheckBox *sendPackageBeforeScan = new QCheckBox(i18n("Send magic package before scanning the network neighborhood"), wakeOnLANActionsBox); sendPackageBeforeScan->setObjectName("SendPackageBeforeScan"); connect(sendPackageBeforeScan, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeScan, 0); // Send magic package before mount QCheckBox *sendPackageBeforeMount = new QCheckBox(i18n("Send magic package before mounting a share"), wakeOnLanTab); sendPackageBeforeMount->setObjectName("SendPackageBeforeMount"); connect(sendPackageBeforeMount, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeMount, 0); wakeOnLanTabLayout->addWidget(wakeOnLANActionsBox, 0); wakeOnLanTabLayout->addStretch(100); tabWidget->addTab(wakeOnLanTab, i18n("Wake-On-LAN")); // // Load settings // if (m_options->hasOptions()) { if (m_options->type() == Share) { remountAlways->setChecked((m_options->remount() == Smb4KCustomOptions::RemountAlways)); } // CIFS Unix extensions support cifsExtensionsSupport->setChecked(m_options->cifsUnixExtensionsSupport()); // User information useUserId->setChecked(m_options->useUser()); userId->setCurrentText(QString("%1 (%2)").arg(m_options->user().loginName()).arg(m_options->user().userId().nativeId())); // Group information useGroupId->setChecked(m_options->useGroup()); groupId->setCurrentText(QString("%1 (%2)").arg(m_options->group().name()).arg(m_options->group().groupId().nativeId())); // File mode useFileMode->setChecked(m_options->useFileMode()); fileMode->setText(m_options->fileMode()); // Directory mode useDirectoryMode->setChecked(m_options->useDirectoryMode()); directoryMode->setText(m_options->directoryMode()); // Remote file system port useFilesystemPort->setChecked(m_options->useFileSystemPort()); filesystemPort->setValue(m_options->fileSystemPort()); // Write access useWriteAccess->setChecked(m_options->useWriteAccess()); switch (m_options->writeAccess()) { case Smb4KMountSettings::EnumWriteAccess::ReadWrite: { writeAccess->setCurrentText(readWriteText); break; } case Smb4KMountSettings::EnumWriteAccess::ReadOnly: { writeAccess->setCurrentText(readOnlyText); break; } default: { break; } } // Security mode useSecurityMode->setChecked(m_options->useSecurityMode()); switch (m_options->securityMode()) { case Smb4KMountSettings::EnumSecurityMode::None: { securityMode->setCurrentText(noneText); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5: { securityMode->setCurrentText(krb5Text); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5i: { securityMode->setCurrentText(krb5iText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlm: { securityMode->setCurrentText(ntlmText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmi: { securityMode->setCurrentText(ntlmiText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2: { securityMode->setCurrentText(ntlmv2Text); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2i: { securityMode->setCurrentText(ntlmv2iText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmssp: { securityMode->setCurrentText(ntlmsspText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmsspi: { securityMode->setCurrentText(ntlmsspiText); break; } default: { break; } } // Remote SMB port useSmbPort->setChecked(m_options->useSmbPort()); smbPort->setValue(m_options->smbPort()); // Kerberos useKerberos->setChecked(m_options->useKerberos()); // MAC address macAddress->setText(m_options->macAddress()); // Send magic package before scan sendPackageBeforeScan->setChecked(m_options->wolSendBeforeNetworkScan()); // Send magic package before mount sendPackageBeforeMount->setChecked(m_options->wolSendBeforeMount()); } else { setDefaultValues(); } // // Enable/disable features // wakeOnLanTab->setEnabled((m_options->type() == Host && Smb4KSettings::enableWakeOnLAN())); slotEnableWOLFeatures(macAddress->text()); slotCifsExtensionsSupport(cifsExtensionsSupport->isChecked()); } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // // FreeBSD and NetBSD // void Smb4KCustomOptionsDialog::setupView() { // // Tab widget with settings // QTabWidget *tabWidget = new QTabWidget(this); QVBoxLayout *dialogLayout = qobject_cast(layout()); dialogLayout->addWidget(tabWidget, 0); // // Custom options for mounting // QWidget *mountingTab = new QWidget(tabWidget); QVBoxLayout *mountingTabLayout = new QVBoxLayout(mountingTab); mountingTabLayout->setSpacing(5); // // Common options // QGroupBox *commonBox = new QGroupBox(i18n("Common Options"), mountingTab); QGridLayout *commonBoxLayout = new QGridLayout(commonBox); commonBoxLayout->setSpacing(5); QCheckBox *remountAlways = new QCheckBox(i18n("Always remount this share"), commonBox); remountAlways->setObjectName("RemountAlways"); remountAlways->setEnabled(m_options->type() == Share); connect(remountAlways, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(remountAlways, 0, 0, 1, 2, 0); // User Id QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), commonBox); useUserId->setObjectName("UseUserId"); KComboBox *userId = new KComboBox(commonBox); userId->setObjectName("UserId"); QList allUsers = KUser::allUsers(); for (const KUser &u : allUsers) { userId->addItem(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId()), QVariant::fromValue(u.groupId().nativeId())); } connect(useUserId, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(userId, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(useUserId, 1, 0, 0); commonBoxLayout->addWidget(userId, 1, 1, 0); // Group Id QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), commonBox); useGroupId->setObjectName("UseGroupId"); KComboBox *groupId = new KComboBox(commonBox); groupId->setObjectName("GroupId"); QList allGroups = KUserGroup::allGroups(); for (const KUserGroup &g : allGroups) { groupId->addItem(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId()), QVariant::fromValue(g.groupId().nativeId())); } connect(useGroupId, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); connect(groupId, SIGNAL(currentIndexChanged(int)), SLOT(slotCheckValues())); commonBoxLayout->addWidget(useGroupId, 2, 0, 0); commonBoxLayout->addWidget(groupId, 2, 1, 0); // File mode QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), commonBox); useFileMode->setObjectName("UseFileMode"); KLineEdit *fileMode = new KLineEdit(commonBox); fileMode->setObjectName("FileMode"); fileMode->setClearButtonEnabled(true); fileMode->setAlignment(Qt::AlignRight); connect(useFileMode, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(fileMode, SIGNAL(textEdited(QString)), this, SLOT(slotCheckValues())); commonBoxLayout->addWidget(useFileMode, 3, 0, 0); commonBoxLayout->addWidget(fileMode, 3, 1, 0); // Directory mode QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), commonBox); useDirectoryMode->setObjectName("UseDirectoryMode"); KLineEdit *directoryMode = new KLineEdit(commonBox); directoryMode->setObjectName("DirectoryMode"); directoryMode->setClearButtonEnabled(true); directoryMode->setAlignment(Qt::AlignRight); connect(useDirectoryMode, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(directoryMode, SIGNAL(textEdited(QString)), this, SLOT(slotCheckValues())); commonBoxLayout->addWidget(useDirectoryMode, 4, 0, 0); commonBoxLayout->addWidget(directoryMode, 4, 1, 0); mountingTabLayout->addWidget(commonBox, 0); mountingTabLayout->addStretch(100); tabWidget->addTab(mountingTab, i18n("Mounting")); // // Custom options for Samba // QWidget *sambaTab = new QWidget(tabWidget); QVBoxLayout *sambaTabLayout = new QVBoxLayout(sambaTab); sambaTabLayout->setSpacing(5); // // Common Options // QGroupBox *commonSambaOptionsBox = new QGroupBox(i18n("Common Options"), sambaTab); QGridLayout *commonSambaOptionsBoxLayout = new QGridLayout(commonSambaOptionsBox); commonSambaOptionsBoxLayout->setSpacing(5); // SMB port QCheckBox *useSmbPort = new QCheckBox(Smb4KSettings::self()->useRemoteSmbPortItem()->label(), commonSambaOptionsBox); useSmbPort->setObjectName("UseSmbPort"); QSpinBox *smbPort = new QSpinBox(commonSambaOptionsBox); smbPort->setObjectName("SmbPort"); smbPort->setMinimum(Smb4KSettings::self()->remoteSmbPortItem()->minValue().toInt()); smbPort->setMaximum(Smb4KSettings::self()->remoteSmbPortItem()->maxValue().toInt()); // smbPort->setSliderEnabled(true); connect(useSmbPort, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(smbPort, SIGNAL(valueChanged(int)), this, SLOT(slotCheckValues())); commonSambaOptionsBoxLayout->addWidget(useSmbPort, 0, 0, 0); commonSambaOptionsBoxLayout->addWidget(smbPort, 0, 1, 0); sambaTabLayout->addWidget(commonSambaOptionsBox, 0); // // Authentication // QGroupBox *authenticationBox = new QGroupBox(i18n("Authentication"), sambaTab); QVBoxLayout *authenticationBoxLayout = new QVBoxLayout(authenticationBox); authenticationBoxLayout->setSpacing(5); // Kerberos QCheckBox *useKerberos = new QCheckBox(Smb4KSettings::self()->useKerberosItem()->label(), authenticationBox); useKerberos->setObjectName("UseKerberos"); connect(useKerberos, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); authenticationBoxLayout->addWidget(useKerberos, 0); sambaTabLayout->addWidget(authenticationBox, 0); sambaTabLayout->addStretch(100); tabWidget->addTab(sambaTab, i18n("Samba")); // // Custom options for Wake-On-LAN // // NOTE: If you change the texts here, also alter them in the respective // config page. // QWidget *wakeOnLanTab = new QWidget(tabWidget); QVBoxLayout *wakeOnLanTabLayout = new QVBoxLayout(wakeOnLanTab); wakeOnLanTabLayout->setSpacing(5); // // MAC address // QGroupBox *macAddressBox = new QGroupBox(i18n("MAC Address"), wakeOnLanTab); QGridLayout *macAddressBoxLayout = new QGridLayout(macAddressBox); macAddressBoxLayout->setSpacing(5); // MAC address QLabel *macAddressLabel = new QLabel(i18n("MAC Address:"), macAddressBox); KLineEdit *macAddress = new KLineEdit(macAddressBox); macAddress->setObjectName("MACAddress"); macAddress->setClearButtonEnabled(true); macAddress->setInputMask("HH:HH:HH:HH:HH:HH;_"); // MAC address, see QLineEdit doc macAddressLabel->setBuddy(macAddress); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotCheckValues())); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotEnableWOLFeatures(QString))); macAddressBoxLayout->addWidget(macAddressLabel, 0, 0, 0); macAddressBoxLayout->addWidget(macAddress, 0, 1, 0); wakeOnLanTabLayout->addWidget(macAddressBox, 0); // // Wake-On-LAN Actions // QGroupBox *wakeOnLANActionsBox = new QGroupBox(i18n("Actions"), wakeOnLanTab); QVBoxLayout *wakeOnLANActionsBoxLayout = new QVBoxLayout(wakeOnLANActionsBox); wakeOnLANActionsBoxLayout->setSpacing(5); // Send magic package before network scan QCheckBox *sendPackageBeforeScan = new QCheckBox(i18n("Send magic package before scanning the network neighborhood"), wakeOnLANActionsBox); sendPackageBeforeScan->setObjectName("SendPackageBeforeScan"); connect(sendPackageBeforeScan, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeScan, 0); // Send magic package before mount QCheckBox *sendPackageBeforeMount = new QCheckBox(i18n("Send magic package before mounting a share"), wakeOnLanTab); sendPackageBeforeMount->setObjectName("SendPackageBeforeMount"); connect(sendPackageBeforeMount, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeMount, 0); wakeOnLanTabLayout->addWidget(wakeOnLANActionsBox, 0); wakeOnLanTabLayout->addStretch(100); tabWidget->addTab(wakeOnLanTab, i18n("Wake-On-LAN")); // // Load settings // if (m_options->hasOptions()) { if (m_options->type() == Share) { remountAlways->setChecked((m_options->remount() == Smb4KCustomOptions::RemountAlways)); } // User information useUserId->setChecked(m_options->useUser()); userId->setCurrentText(QString("%1 (%2)").arg(m_options->user().loginName()).arg(m_options->user().userId().nativeId())); // Group information useGroupId->setChecked(m_options->useGroup()); groupId->setCurrentText(QString("%1 (%2)").arg(m_options->group().name()).arg(m_options->group().groupId().nativeId())); // File mode useFileMode->setChecked(m_options->useFileMode()); fileMode->setText(m_options->fileMode()); // Directory mode useDirectoryMode->setChecked(m_options->useDirectoryMode()); directoryMode->setText(m_options->directoryMode()); // Remote SMB port useSmbPort->setChecked(m_options->useSmbPort()); smbPort->setValue(m_options->smbPort()); // Kerberos useKerberos->setChecked(m_options->useKerberos()); // MAC address macAddress->setText(m_options->macAddress()); // Send magic package before scan sendPackageBeforeScan->setChecked(m_options->wolSendBeforeNetworkScan()); // Send magic package before mount sendPackageBeforeMount->setChecked(m_options->wolSendBeforeMount()); } else { setDefaultValues(); } // // Enable/disable features // wakeOnLanTab->setEnabled((m_options->type() == Host && Smb4KSettings::enableWakeOnLAN())); slotEnableWOLFeatures(macAddress->text()); } #else // // Generic (without mount options) // void Smb4KCustomOptionsDialog::setupView() { // // Tab widget with settings // QTabWidget *tabWidget = new QTabWidget(this); QVBoxLayout *dialogLayout = qobject_cast(layout()); dialogLayout->addWidget(tabWidget, 0); // // Custom options for Samba // QWidget *sambaTab = new QWidget(tabWidget); QVBoxLayout *sambaTabLayout = new QVBoxLayout(sambaTab); sambaTabLayout->setSpacing(5); // // Common Options // QGroupBox *commonSambaOptionsBox = new QGroupBox(i18n("Common Options"), sambaTab); QGridLayout *commonSambaOptionsBoxLayout = new QGridLayout(commonSambaOptionsBox); commonSambaOptionsBoxLayout->setSpacing(5); // SMB port QCheckBox *useSmbPort = new QCheckBox(Smb4KSettings::self()->useRemoteSmbPortItem()->label(), commonSambaOptionsBox); useSmbPort->setObjectName("UseSmbPort"); QSpinBox *smbPort = new QSpinBox(commonSambaOptionsBox); smbPort->setObjectName("SmbPort"); smbPort->setMinimum(Smb4KSettings::self()->remoteSmbPortItem()->minValue().toInt()); smbPort->setMaximum(Smb4KSettings::self()->remoteSmbPortItem()->maxValue().toInt()); // smbPort->setSliderEnabled(true); connect(useSmbPort, SIGNAL(toggled(bool)), this, SLOT(slotCheckValues())); connect(smbPort, SIGNAL(valueChanged(int)), this, SLOT(slotCheckValues())); commonSambaOptionsBoxLayout->addWidget(useSmbPort, 0, 0, 0); commonSambaOptionsBoxLayout->addWidget(smbPort, 0, 1, 0); sambaTabLayout->addWidget(commonSambaOptionsBox, 0); // // Authentication // QGroupBox *authenticationBox = new QGroupBox(i18n("Authentication"), sambaTab); QVBoxLayout *authenticationBoxLayout = new QVBoxLayout(authenticationBox); authenticationBoxLayout->setSpacing(5); // Kerberos QCheckBox *useKerberos = new QCheckBox(Smb4KSettings::self()->useKerberosItem()->label(), authenticationBox); useKerberos->setObjectName("UseKerberos"); connect(useKerberos, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); authenticationBoxLayout->addWidget(useKerberos, 0); sambaTabLayout->addWidget(authenticationBox, 0); sambaTabLayout->addStretch(100); tabWidget->addTab(sambaTab, i18n("Samba")); // // Custom options for Wake-On-LAN // // NOTE: If you change the texts here, also alter them in the respective // config page. // QWidget *wakeOnLanTab = new QWidget(tabWidget); QVBoxLayout *wakeOnLanTabLayout = new QVBoxLayout(wakeOnLanTab); wakeOnLanTabLayout->setSpacing(5); // // MAC address // QGroupBox *macAddressBox = new QGroupBox(i18n("MAC Address"), wakeOnLanTab); QGridLayout *macAddressBoxLayout = new QGridLayout(macAddressBox); macAddressBoxLayout->setSpacing(5); // MAC address QLabel *macAddressLabel = new QLabel(i18n("MAC Address:"), macAddressBox); KLineEdit *macAddress = new KLineEdit(macAddressBox); macAddress->setObjectName("MACAddress"); macAddress->setClearButtonEnabled(true); macAddress->setInputMask("HH:HH:HH:HH:HH:HH;_"); // MAC address, see QLineEdit doc macAddressLabel->setBuddy(macAddress); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotCheckValues())); connect(macAddress, SIGNAL(textEdited(QString)), SLOT(slotEnableWOLFeatures(QString))); macAddressBoxLayout->addWidget(macAddressLabel, 0, 0, 0); macAddressBoxLayout->addWidget(macAddress, 0, 1, 0); wakeOnLanTabLayout->addWidget(macAddressBox, 0); // // Wake-On-LAN Actions // QGroupBox *wakeOnLANActionsBox = new QGroupBox(i18n("Actions"), wakeOnLanTab); QVBoxLayout *wakeOnLANActionsBoxLayout = new QVBoxLayout(wakeOnLANActionsBox); wakeOnLANActionsBoxLayout->setSpacing(5); // Send magic package before network scan QCheckBox *sendPackageBeforeScan = new QCheckBox(i18n("Send magic package before scanning the network neighborhood"), wakeOnLANActionsBox); sendPackageBeforeScan->setObjectName("SendPackageBeforeScan"); connect(sendPackageBeforeScan, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeScan, 0); // Send magic package before mount QCheckBox *sendPackageBeforeMount = new QCheckBox(i18n("Send magic package before mounting a share"), wakeOnLanTab); sendPackageBeforeMount->setObjectName("SendPackageBeforeMount"); connect(sendPackageBeforeMount, SIGNAL(toggled(bool)), SLOT(slotCheckValues())); wakeOnLANActionsBoxLayout->addWidget(sendPackageBeforeMount, 0); wakeOnLanTabLayout->addWidget(wakeOnLANActionsBox, 0); wakeOnLanTabLayout->addStretch(100); tabWidget->addTab(wakeOnLanTab, i18n("Wake-On-LAN")); // // Load settings // if (m_options->hasOptions()) { // Remote SMB port useSmbPort->setChecked(m_options->useSmbPort()); smbPort->setValue(m_options->smbPort()); // Kerberos useKerberos->setChecked(m_options->useKerberos()); // MAC address macAddress->setText(m_options->macAddress()); // Send magic package before scan sendPackageBeforeScan->setChecked(m_options->wolSendBeforeNetworkScan()); // Send magic package before mount sendPackageBeforeMount->setChecked(m_options->wolSendBeforeMount()); } else { setDefaultValues(); } // // Enable/disable features // wakeOnLanTab->setEnabled((m_options->type() == Host && Smb4KSettings::enableWakeOnLAN())); slotEnableWOLFeatures(macAddress->text()); } #endif bool Smb4KCustomOptionsDialog::checkDefaultValues() { // // Always remount the share // if (m_options->type() == Share) { QCheckBox *remountAlways = findChild("RemountAlways"); if (remountAlways) { if (remountAlways->isChecked()) { return false; } } } // // User Id // QCheckBox *useUserId = findChild("UseUserId"); if (useUserId) { if (useUserId->isChecked() != Smb4KMountSettings::useUserId()) { return false; } } KComboBox *userId = findChild("UserId"); if (userId) { K_UID uid = (K_UID)userId->itemData(userId->currentIndex()).toInt(); if (uid != (K_UID)Smb4KMountSettings::userId().toInt()) { return false; } } // // Group Id // QCheckBox *useGroupId = findChild("UseGroupId"); if (useGroupId) { if (useGroupId->isChecked() != Smb4KMountSettings::useGroupId()) { return false; } } KComboBox *groupId = findChild("GroupId"); if (groupId) { K_GID gid = (K_GID)groupId->itemData(groupId->currentIndex()).toInt(); if (gid != (K_GID)Smb4KMountSettings::groupId().toInt()) { return false; } } // // File mode // QCheckBox *useFileMode = findChild("UseFileMode"); if (useFileMode) { if (useFileMode->isChecked() != Smb4KMountSettings::useFileMode()) { return false; } } KLineEdit *fileMode = findChild("FileMode"); if (fileMode) { if (fileMode->text() != Smb4KMountSettings::fileMode()) { return false; } } // // Directory mode // QCheckBox *useDirectoryMode = findChild("UseDirectoryMode"); if (useDirectoryMode) { if (useDirectoryMode->isChecked() != Smb4KMountSettings::useDirectoryMode()) { return false; } } KLineEdit *directoryMode = findChild("DirectoryMode"); if (directoryMode) { if (directoryMode->text() != Smb4KMountSettings::directoryMode()) { return false; } } #if defined(Q_OS_LINUX) // // CIFS Unix extensions support // QCheckBox *cifsExtensionsSupport = findChild("CifsExtensionsSupport"); if (cifsExtensionsSupport) { if (cifsExtensionsSupport->isChecked() != Smb4KMountSettings::cifsUnixExtensionsSupport()) { return false; } } // // Filesystem port // QCheckBox *useFilesystemPort = findChild("UseFilesystemPort"); if (useFilesystemPort) { if (useFilesystemPort->isChecked() != Smb4KMountSettings::useRemoteFileSystemPort()) { return false; } } QSpinBox *filesystemPort = findChild("FileSystemPort"); if (filesystemPort) { if (filesystemPort->value() != Smb4KMountSettings::remoteFileSystemPort()) { return false; } } // // Write access // QCheckBox *useWriteAccess = findChild("UseWriteAccess"); if (useWriteAccess) { if (useWriteAccess->isChecked() != Smb4KMountSettings::useWriteAccess()) { return false; } } KComboBox *writeAccess = findChild("WriteAccess"); if (writeAccess) { if (writeAccess->currentText() != Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::self()->writeAccess()).label) { return false; } } // // Security mode // QCheckBox *useSecurityMode = findChild("UseSecurityMode"); if (useSecurityMode) { if (useSecurityMode->isChecked() != Smb4KMountSettings::useSecurityMode()) { return false; } } KComboBox *securityMode = findChild("SecurityMode"); if (securityMode) { if (securityMode->currentText() != Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::self()->securityMode()).label) { return false; } } #endif // // SMB port // QCheckBox *useSmbPort = findChild("UseSmbPort"); if (useSmbPort) { if (useSmbPort->isChecked() != Smb4KSettings::useRemoteSmbPort()) { return false; } } QSpinBox *smbPort = findChild("SmbPort"); if (smbPort) { if (smbPort->value() != Smb4KSettings::remoteSmbPort()) { return false; } } // // Kerberos // QCheckBox *useKerberos = findChild("UseKerberos"); if (useKerberos) { if (useKerberos->isChecked() != Smb4KSettings::useKerberos()) { return false; } } // // MAC address & Wake-On-LAN features // if (m_options->type() == Host && Smb4KSettings::enableWakeOnLAN()) { KLineEdit *macAddress = findChild("MACAddress"); if (macAddress) { QRegExp exp("..\\:..\\:..\\:..\\:..\\:.."); if (exp.exactMatch(macAddress->text())) { return false; } } QCheckBox *sendPackageBeforeScan = findChild("SendPackageBeforeScan"); if (sendPackageBeforeScan) { if (sendPackageBeforeScan->isChecked()) { return false; } } QCheckBox *sendPackageBeforeMount = findChild("SendPackageBeforeMount"); if (sendPackageBeforeMount) { if (sendPackageBeforeMount->isChecked()) { return false; } } } return true; } void Smb4KCustomOptionsDialog::setDefaultValues() { // // Always remount the share // if (m_options->type() == Share) { QCheckBox *remountAlways = findChild("RemountAlways"); if (remountAlways) { remountAlways->setChecked(false); } } // // User Id // QCheckBox *useUserId = findChild("UseUserId"); if (useUserId) { useUserId->setChecked(Smb4KMountSettings::useUserId()); } KComboBox *userId = findChild("UserId"); if (userId) { KUser user((K_UID)Smb4KMountSettings::userId().toInt()); userId->setCurrentText(QString("%1 (%2)").arg(user.loginName()).arg(user.userId().nativeId())); } // // Group Id // QCheckBox *useGroupId = findChild("UseGroupId"); if (useGroupId) { useGroupId->setChecked(Smb4KMountSettings::useGroupId()); } KComboBox *groupId = findChild("GroupId"); if (groupId) { KUserGroup group((K_GID)Smb4KMountSettings::groupId().toInt()); groupId->setCurrentText(QString("%1 (%2)").arg(group.name()).arg(group.groupId().nativeId()));; } // // File mask // QCheckBox *useFileMode = findChild("UseFileMode"); if (useFileMode) { useFileMode->setChecked(Smb4KMountSettings::useFileMode()); } KLineEdit *fileMode = findChild("FileMode"); if (fileMode) { fileMode->setText(Smb4KMountSettings::fileMode()); } // // Directory mode // QCheckBox *useDirectoryMode = findChild("UseDirectoryMode"); if (useDirectoryMode) { useDirectoryMode->setChecked(Smb4KMountSettings::useDirectoryMode()); } KLineEdit *directoryMode = findChild("DirectoryMode"); if (directoryMode) { directoryMode->setText(Smb4KMountSettings::directoryMode()); } #if defined(Q_OS_LINUX) // // CIFS Unix extensions support // QCheckBox *cifsExtensionsSupport = findChild("CifsExtensionsSupport"); if (cifsExtensionsSupport) { cifsExtensionsSupport->setChecked(Smb4KMountSettings::cifsUnixExtensionsSupport()); } // // Filesystem port // QCheckBox *useFilesystemPort = findChild("UseFilesystemPort"); if (useFilesystemPort) { useFilesystemPort->setChecked(Smb4KMountSettings::useRemoteFileSystemPort()); } QSpinBox *filesystemPort = findChild("FileSystemPort"); if (filesystemPort) { filesystemPort->setValue(Smb4KMountSettings::remoteFileSystemPort()); } // // Write access // QCheckBox *useWriteAccess = findChild("UseWriteAccess"); if (useWriteAccess) { useWriteAccess->setChecked(Smb4KMountSettings::useWriteAccess()); } KComboBox *writeAccess = findChild("WriteAccess"); if (writeAccess) { QString readWriteText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadWrite).label; QString readOnlyText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadOnly).label; switch (Smb4KMountSettings::writeAccess()) { case Smb4KMountSettings::EnumWriteAccess::ReadWrite: { writeAccess->setCurrentText(readWriteText); break; } case Smb4KMountSettings::EnumWriteAccess::ReadOnly: { writeAccess->setCurrentText(readOnlyText); break; } default: { break; } } } // // Security mode // QCheckBox *useSecurityMode = findChild("UseSecurityMode"); if (useSecurityMode) { useSecurityMode->setChecked(Smb4KMountSettings::useSecurityMode()); } KComboBox *securityMode = findChild("SecurityMode"); if (securityMode) { QString noneText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::None).label; QString krb5Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5).label; QString krb5iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5i).label; QString ntlmText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlm).label; QString ntlmiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmi).label; QString ntlmv2Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2).label; QString ntlmv2iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i).label; QString ntlmsspText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmssp).label; QString ntlmsspiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi).label; switch (Smb4KMountSettings::securityMode()) { case Smb4KMountSettings::EnumSecurityMode::None: { securityMode->setCurrentText(noneText); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5: { securityMode->setCurrentText(krb5Text); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5i: { securityMode->setCurrentText(krb5iText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlm: { securityMode->setCurrentText(ntlmText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmi: { securityMode->setCurrentText(ntlmiText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2: { securityMode->setCurrentText(ntlmv2Text); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2i: { securityMode->setCurrentText(ntlmv2iText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmssp: { securityMode->setCurrentText(ntlmsspText); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmsspi: { securityMode->setCurrentText(ntlmsspiText); break; } default: { break; } } } #endif // // SMB port // QCheckBox *useSmbPort = findChild("UseSmbPort"); if (useSmbPort) { useSmbPort->setChecked(Smb4KSettings::useRemoteSmbPort()); } QSpinBox *smbPort = findChild("SmbPort"); if (smbPort) { smbPort->setValue(Smb4KSettings::remoteSmbPort()); } // // Kerberos // QCheckBox *useKerberos = findChild("UseKerberos"); if (useKerberos) { useKerberos->setChecked(Smb4KSettings::useKerberos()); } // // MAC address & Wake-On-LAN features // if (m_options->type() == Host) { KLineEdit *macAddress = findChild("MACAddress"); if (macAddress) { macAddress->clear(); macAddress->setInputMask("HH:HH:HH:HH:HH:HH;_"); } QCheckBox *sendPackageBeforeScan = findChild("SendPackageBeforeScan"); if (sendPackageBeforeScan) { sendPackageBeforeScan->setChecked(false); } QCheckBox *sendPackageBeforeMount = findChild("SendPackageBeforeMount"); if (sendPackageBeforeMount) { sendPackageBeforeMount->setChecked(false); } } } void Smb4KCustomOptionsDialog::saveValues() { // // Always remount the share // if (m_options->type() == Share) { QCheckBox *remountAlways = findChild("RemountAlways"); if (remountAlways) { if (remountAlways->isChecked()) { m_options->setRemount(Smb4KCustomOptions::RemountAlways); } else { m_options->setRemount(Smb4KCustomOptions::UndefinedRemount); } } } // // User Id // QCheckBox *useUserId = findChild("UseUserId"); if (useUserId) { m_options->setUseUser(useUserId->isChecked()); } KComboBox *userId = findChild("UserId"); if (userId) { m_options->setUser(KUser(userId->itemData(userId->currentIndex()).toInt())); } // // Group Id // QCheckBox *useGroupId = findChild("UseGroupId"); if (useGroupId) { m_options->setUseGroup(useGroupId->isChecked()); } KComboBox *groupId = findChild("GroupId"); if (groupId) { m_options->setGroup(KUserGroup(groupId->itemData(groupId->currentIndex()).toInt())); } // // File mode // QCheckBox *useFileMode = findChild("UseFileMode"); if (useFileMode) { m_options->setUseFileMode(useFileMode->isChecked()); } KLineEdit *fileMode = findChild("FileMode"); if (fileMode) { m_options->setFileMode(fileMode->text()); } // // Directory mode // QCheckBox *useDirectoryMode = findChild("UseDirectoryMode"); if (useDirectoryMode) { m_options->setUseDirectoryMode(useDirectoryMode->isChecked()); } KLineEdit *directoryMode = findChild("DirectoryMode"); if (directoryMode) { m_options->setDirectoryMode(directoryMode->text()); } #if defined(Q_OS_LINUX) // // CIFS Unix extensions support // QCheckBox *cifsExtensionsSupport = findChild("CifsExtensionsSupport"); if (cifsExtensionsSupport) { m_options->setCifsUnixExtensionsSupport(cifsExtensionsSupport->isChecked()); } // // Filesystem port // QCheckBox *useFilesystemPort = findChild("UseFilesystemPort"); if (useFilesystemPort) { m_options->setUseFileSystemPort(useFilesystemPort->isChecked()); } QSpinBox *filesystemPort = findChild("FileSystemPort"); if (filesystemPort) { m_options->setFileSystemPort(filesystemPort->value()); } // // Write access // QCheckBox *useWriteAccess = findChild("UseWriteAccess"); if (useWriteAccess) { m_options->setUseWriteAccess(useWriteAccess->isChecked()); } KComboBox *writeAccess = findChild("WriteAccess"); if (writeAccess) { QString readWriteText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadWrite).label; QString readOnlyText = Smb4KMountSettings::self()->writeAccessItem()->choices().value(Smb4KMountSettings::EnumWriteAccess::ReadOnly).label; if (writeAccess->currentText() == readWriteText) { m_options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadWrite); } else if (writeAccess->currentText() == readOnlyText) { m_options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadOnly); } } // // Security mode // QCheckBox *useSecurityMode = findChild("UseSecurityMode"); if (useSecurityMode) { m_options->setUseSecurityMode(useSecurityMode->isChecked()); } KComboBox *securityMode = findChild("SecurityMode"); if (securityMode) { QString noneText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::None).label; QString krb5Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5).label; QString krb5iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Krb5i).label; QString ntlmText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlm).label; QString ntlmiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmi).label; QString ntlmv2Text = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2).label; QString ntlmv2iText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i).label; QString ntlmsspText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmssp).label; QString ntlmsspiText = Smb4KMountSettings::self()->securityModeItem()->choices().value(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi).label; if (securityMode->currentText() == noneText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::None); } else if (securityMode->currentText() == krb5Text) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5); } else if (securityMode->currentText() == krb5iText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5i); } else if (securityMode->currentText() == ntlmText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlm); } else if (securityMode->currentText() == ntlmiText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmi); } else if (securityMode->currentText() == ntlmv2Text) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2); } else if (securityMode->currentText() == ntlmv2iText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i); } else if (securityMode->currentText() == ntlmsspText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmssp); } else if (securityMode->currentText() == ntlmsspiText) { m_options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi); } } #endif // // SMB port // QCheckBox *useSmbPort = findChild("UseSmbPort"); if (useSmbPort) { m_options->setUseSmbPort(useSmbPort->isChecked()); } QSpinBox *smbPort = findChild("SmbPort"); if (smbPort) { m_options->setSmbPort(smbPort->value()); } // Kerberos QCheckBox *useKerberos = findChild("UseKerberos"); if (useKerberos) { m_options->setUseKerberos(useKerberos->isChecked()); } // MAC address & Wake-On-LAN features if (m_options->type() == Host) { KLineEdit *macAddress = findChild("MACAddress"); if (macAddress) { m_options->setMACAddress(macAddress->text()); } QCheckBox *sendPackageBeforeScan = findChild("SendPackageBeforeScan"); if (sendPackageBeforeScan) { m_options->setWOLSendBeforeNetworkScan(sendPackageBeforeScan->isChecked()); } QCheckBox *sendPackageBeforeMount = findChild("SendPackageBeforeMount"); if (sendPackageBeforeMount) { m_options->setWOLSendBeforeMount(sendPackageBeforeMount->isChecked()); } } KConfigGroup group(Smb4KSettings::self()->config(), "CustomOptionsDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); } void Smb4KCustomOptionsDialog::slotSetDefaultValues() { setDefaultValues(); } void Smb4KCustomOptionsDialog::slotCheckValues() { QDialogButtonBox *buttonBox = findChild(); if (buttonBox) { for (QAbstractButton *b : buttonBox->buttons()) { if (buttonBox->buttonRole(b) == QDialogButtonBox::ResetRole) { b->setEnabled(!checkDefaultValues()); break; } } } } void Smb4KCustomOptionsDialog::slotOKClicked() { saveValues(); accept(); } void Smb4KCustomOptionsDialog::slotEnableWOLFeatures(const QString &mac) { QRegExp exp("..\\:..\\:..\\:..\\:..\\:.."); QCheckBox *sendPackageBeforeScan = findChild("SendPackageBeforeScan"); if (sendPackageBeforeScan) { sendPackageBeforeScan->setEnabled(m_options->type() == Host && exp.exactMatch(mac)); } QCheckBox *sendPackageBeforeMount = findChild("SendPackageBeforeMount"); if (sendPackageBeforeMount) { sendPackageBeforeMount->setEnabled(m_options->type() == Host && exp.exactMatch(mac)); } } void Smb4KCustomOptionsDialog::slotCifsExtensionsSupport(bool support) { #if defined(Q_OS_LINUX) // // User id // QCheckBox *useUserId = findChild("UseUserId"); if (useUserId) { useUserId->setEnabled(!support); } KComboBox *userId = findChild("UserId"); if (userId) { userId->setEnabled(!support); } // // Group id // QCheckBox *useGroupId = findChild("UseGroupId"); if (useGroupId) { useGroupId->setEnabled(!support); } KComboBox *groupId = findChild("GroupId"); if (groupId) { groupId->setEnabled(!support); } // // File mode // QCheckBox *useFileMode = findChild("UseFileMode"); if (useFileMode) { useFileMode->setEnabled(!support); } KLineEdit *fileMode = findChild("FileMode"); if (fileMode) { fileMode->setEnabled(!support); } // // Directory mode // QCheckBox *useDirectoryMode = findChild("UseDirectoryMode"); if (useDirectoryMode) { useDirectoryMode->setEnabled(!support); } KLineEdit *directoryMode = findChild("DirectoryMode"); if (directoryMode) { directoryMode->setEnabled(!support); } #endif } diff --git a/core/smb4kfile.cpp b/core/smb4kfile.cpp index f4a5093..0725133 100644 --- a/core/smb4kfile.cpp +++ b/core/smb4kfile.cpp @@ -1,186 +1,182 @@ /*************************************************************************** Smb4K's container class for information about a directory or file. ------------------- begin : Sa Nov 10 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kfile.h" #include "smb4kglobal.h" // Qt includes #include #include // KDE includes #include #include using namespace Smb4KGlobal; class Smb4KFilePrivate { public: QString workgroupName; QHostAddress ip; }; Smb4KFile::Smb4KFile(const QUrl& url, Smb4KGlobal::NetworkItem type) : Smb4KBasicNetworkItem(type), d(new Smb4KFilePrivate) { *pUrl = url; if (type == Directory) { *pIcon = KDE::icon("folder"); } else { *pIcon = KDE::icon(KIO::iconNameForUrl(url)); } } Smb4KFile::Smb4KFile(const Smb4KFile &file) : Smb4KBasicNetworkItem(file.type()), d(new Smb4KFilePrivate) { *d = *file.d; } Smb4KFile::~Smb4KFile() { } void Smb4KFile::setWorkgroupName(const QString &name) { d->workgroupName = name; } QString Smb4KFile::workgroupName() const { return d->workgroupName; } QString Smb4KFile::hostName() const { return pUrl->host().toUpper(); } void Smb4KFile::setHostIpAddress(const QHostAddress &address) { if (!address.isNull() && address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { d->ip = address; } } QString Smb4KFile::hostIpAddress() const { return d->ip.toString(); } bool Smb4KFile::hasHostIpAddress() const { return !d->ip.isNull(); } QString Smb4KFile::shareName() const { return pUrl->path().section('/', 1, 1); } void Smb4KFile::setLogin(const QString &name) { pUrl->setUserName(name); } QString Smb4KFile::login() const { return pUrl->userName(); } void Smb4KFile::setPassword(const QString &pass) { pUrl->setPassword(pass); } QString Smb4KFile::password() const { return pUrl->password(); } bool Smb4KFile::isDirectory() const { return (type() == Directory); } QString Smb4KFile::name() const { QString name; switch (type()) { case Directory: { name = pUrl->path().section(QDir::separator(), -1, -1); break; } case File: { name = pUrl->fileName(); break; } default: { break; } } return name; } bool Smb4KFile::isHidden() const { return name().startsWith('.'); } diff --git a/core/smb4kglobal.cpp b/core/smb4kglobal.cpp index b583249..be744b3 100644 --- a/core/smb4kglobal.cpp +++ b/core/smb4kglobal.cpp @@ -1,990 +1,986 @@ /*************************************************************************** This is the global namespace for Smb4K. ------------------- begin : Sa Apr 2 2005 copyright : (C) 2005-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kglobal.h" #include "smb4kglobal_p.h" #include "smb4knotification.h" #include "smb4ksynchronizer.h" #include "smb4kclient.h" #include "smb4kmounter.h" // Qt includes #include #include #include #include #include // KDE includes #include #include Q_GLOBAL_STATIC(Smb4KGlobalPrivate, p); QMutex mutex(QMutex::Recursive /* needed to avoid dead-locks */); void Smb4KGlobal::initCore(bool modifyCursor, bool initClasses) { if (!p->coreInitialized) { // // Busy cursor // p->modifyCursor = modifyCursor; // // Initialize the necessary core classes // if (initClasses) { Smb4KClient::self()->start(); Smb4KMounter::self()->start(); } p->coreInitialized = true; } } void Smb4KGlobal::abortCore() { Smb4KClient::self()->abort(); Smb4KMounter::self()->abort(); Smb4KSynchronizer::self()->abort(); } bool Smb4KGlobal::coreIsRunning() { return (Smb4KClient::self()->isRunning() || Smb4KMounter::self()->isRunning() || Smb4KSynchronizer::self()->isRunning()); } bool Smb4KGlobal::coreIsInitialized() { return p->coreInitialized; } const QList &Smb4KGlobal::workgroupsList() { return p->workgroupsList; } WorkgroupPtr Smb4KGlobal::findWorkgroup(const QString &name) { WorkgroupPtr workgroup; mutex.lock(); for (const WorkgroupPtr &w : p->workgroupsList) { if (QString::compare(w->workgroupName(), name, Qt::CaseInsensitive) == 0) { workgroup = w; break; } } mutex.unlock(); return workgroup; } bool Smb4KGlobal::addWorkgroup(WorkgroupPtr workgroup) { Q_ASSERT(workgroup); bool added = false; if (workgroup) { mutex.lock(); if (!findWorkgroup(workgroup->workgroupName())) { p->workgroupsList.append(workgroup); added = true; } mutex.unlock(); } return added; } bool Smb4KGlobal::updateWorkgroup(WorkgroupPtr workgroup) { Q_ASSERT(workgroup); bool updated = false; if (workgroup) { mutex.lock(); WorkgroupPtr existingWorkgroup = findWorkgroup(workgroup->workgroupName()); if (existingWorkgroup) { existingWorkgroup->update(workgroup.data()); updated = true; } mutex.unlock(); } return updated; } bool Smb4KGlobal::removeWorkgroup(WorkgroupPtr workgroup) { Q_ASSERT(workgroup); bool removed = false; if (workgroup) { mutex.lock(); int index = p->workgroupsList.indexOf(workgroup); if (index != -1) { // The workgroup was found. Remove it. p->workgroupsList.takeAt(index).clear(); removed = true; } else { // Try harder to find the workgroup. WorkgroupPtr wg = findWorkgroup(workgroup->workgroupName()); if (wg) { index = p->workgroupsList.indexOf(wg); if (index != -1) { p->workgroupsList.takeAt(index).clear(); removed = true; } } workgroup.clear(); } mutex.unlock(); } return removed; } void Smb4KGlobal::clearWorkgroupsList() { mutex.lock(); while (!p->workgroupsList.isEmpty()) { p->workgroupsList.takeFirst().clear(); } mutex.unlock(); } const QList &Smb4KGlobal::hostsList() { return p->hostsList; } HostPtr Smb4KGlobal::findHost(const QString &name, const QString &workgroup) { HostPtr host; mutex.lock(); for (const HostPtr &h : p->hostsList) { if ((workgroup.isEmpty() || QString::compare(h->workgroupName(), workgroup, Qt::CaseInsensitive) == 0) && QString::compare(h->hostName(), name, Qt::CaseInsensitive) == 0) { host = h; break; } } mutex.unlock(); return host; } bool Smb4KGlobal::addHost(HostPtr host) { Q_ASSERT(host); bool added = false; if (host) { mutex.lock(); if (!findHost(host->hostName(), host->workgroupName())) { p->hostsList.append(host); added = true; } mutex.unlock(); } return added; } bool Smb4KGlobal::updateHost(HostPtr host) { Q_ASSERT(host); bool updated = false; if (host) { mutex.lock(); HostPtr existingHost = findHost(host->hostName(), host->workgroupName()); if (existingHost) { existingHost->update(host.data()); updated = true; } mutex.unlock(); } return updated; } bool Smb4KGlobal::removeHost(HostPtr host) { Q_ASSERT(host); bool removed = false; if (host) { mutex.lock(); int index = p->hostsList.indexOf(host); if (index != -1) { // The host was found. Remove it. p->hostsList.takeAt(index).clear(); removed = true; } else { // Try harder to find the host. HostPtr h = findHost(host->hostName(), host->workgroupName()); if (h) { index = p->hostsList.indexOf(h); if (index != -1) { p->hostsList.takeAt(index).clear(); removed = true; } } host.clear(); } mutex.unlock(); } return removed; } void Smb4KGlobal::clearHostsList() { mutex.lock(); while (!p->hostsList.isEmpty()) { p->hostsList.takeFirst().clear(); } mutex.unlock(); } QList Smb4KGlobal::workgroupMembers(WorkgroupPtr workgroup) { QList hosts; mutex.lock(); for (const HostPtr &h : p->hostsList) { if (QString::compare(h->workgroupName(), workgroup->workgroupName(), Qt::CaseInsensitive) == 0) { hosts << h; } } mutex.unlock(); return hosts; } const QList &Smb4KGlobal::sharesList() { return p->sharesList; } SharePtr Smb4KGlobal::findShare(const QUrl& url, const QString& workgroup) { SharePtr share; mutex.lock(); for (const SharePtr &s : p->sharesList) { if (QString::compare(s->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 && (workgroup.isEmpty() || QString::compare(s->workgroupName(), workgroup, Qt::CaseInsensitive) == 0)) { share = s; break; } } mutex.unlock(); return share; } bool Smb4KGlobal::addShare(SharePtr share) { Q_ASSERT(share); bool added = false; if (share) { mutex.lock(); // // Add the share // if (!findShare(share->url(), share->workgroupName())) { // // Set the share mounted // Only honor shares that are owned by the user // QList mountedShares = findShareByUrl(share->url()); if (!mountedShares.isEmpty()) { for (const SharePtr &s : mountedShares) { if (!s->isForeign()) { share->setMountData(s.data()); break; } else { continue; } } } // // Add it // p->sharesList.append(share); added = true; } } mutex.unlock(); return added; } bool Smb4KGlobal::updateShare(SharePtr share) { Q_ASSERT(share); bool updated = false; if (share) { mutex.lock(); // // Updated the share // SharePtr existingShare = findShare(share->url(), share->workgroupName()); if (existingShare) { // // Set the share mounted // Only honor shares that are owned by the user // QList mountedShares = findShareByUrl(share->url()); if (!mountedShares.isEmpty()) { for (const SharePtr &s : mountedShares) { if (!s->isForeign()) { share->setMountData(s.data()); break; } else { continue; } } } // // Update it // existingShare->update(share.data()); updated = true; } mutex.unlock(); } return updated; } bool Smb4KGlobal::removeShare(SharePtr share) { Q_ASSERT(share); bool removed = false; if (share) { mutex.lock(); int index = p->sharesList.indexOf(share); if (index != -1) { // The share was found. Remove it. p->sharesList.takeAt(index).clear(); removed = true; } else { // Try harder to find the share. SharePtr s = findShare(share->url(), share->workgroupName()); if (s) { index = p->sharesList.indexOf(s); if (index != -1) { p->sharesList.takeAt(index).clear(); removed = true; } } share.clear(); } mutex.unlock(); } return removed; } void Smb4KGlobal::clearSharesList() { mutex.lock(); while (!p->sharesList.isEmpty()) { p->sharesList.takeFirst().clear(); } mutex.unlock(); } QList Smb4KGlobal::sharedResources(HostPtr host) { QList shares; mutex.lock(); for (const SharePtr &s : p->sharesList) { if (QString::compare(s->hostName(), host->hostName(), Qt::CaseInsensitive) == 0 && QString::compare(s->workgroupName(), host->workgroupName(), Qt::CaseInsensitive) == 0) { shares += s; } } mutex.unlock(); return shares; } const QList &Smb4KGlobal::mountedSharesList() { return p->mountedSharesList; } SharePtr Smb4KGlobal::findShareByPath(const QString &path) { SharePtr share; mutex.lock(); if (!path.isEmpty() && !p->mountedSharesList.isEmpty()) { for (const SharePtr &s : p->mountedSharesList) { if (QString::compare(s->path(), path, Qt::CaseInsensitive) == 0 || QString::compare(s->canonicalPath(), path, Qt::CaseInsensitive) == 0) { share = s; break; } } } mutex.unlock(); return share; } QList Smb4KGlobal::findShareByUrl(const QUrl &url) { QList shares; mutex.lock(); if (!url.isEmpty() && url.isValid() && !p->mountedSharesList.isEmpty()) { for (const SharePtr &s : p->mountedSharesList) { if (QString::compare(s->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { shares << s; } } } mutex.unlock(); return shares; } QList Smb4KGlobal::findInaccessibleShares() { QList inaccessibleShares; mutex.lock(); for (const SharePtr &s : p->mountedSharesList) { if (s->isInaccessible()) { inaccessibleShares += s; } } mutex.unlock(); return inaccessibleShares; } bool Smb4KGlobal::addMountedShare(SharePtr share) { Q_ASSERT(share); bool added = false; if (share) { mutex.lock(); // // Copy the mount data to the network share if available. // Only honor shares that were mounted by the user. // if (!share->isForeign()) { // Network share SharePtr networkShare = findShare(share->url(), share->workgroupName()); if (networkShare) { networkShare->setMountData(share.data()); } } if (!findShareByPath(share->path())) { // // Check if we have to add a workgroup name and/or IP address // HostPtr networkHost = findHost(share->hostName(), share->workgroupName()); if (networkHost) { // Set the IP address if (!share->hasHostIpAddress() || networkHost->ipAddress() != share->hostIpAddress()) { share->setHostIpAddress(networkHost->ipAddress()); } // Set the workgroup name if (share->workgroupName().isEmpty()) { share->setWorkgroupName(networkHost->workgroupName()); } } p->mountedSharesList.append(share); added = true; p->onlyForeignShares = true; for (const SharePtr &s : p->mountedSharesList) { if (!s->isForeign()) { p->onlyForeignShares = false; break; } } } mutex.unlock(); } return added; } bool Smb4KGlobal::updateMountedShare(SharePtr share) { Q_ASSERT(share); bool updated = false; if (share) { mutex.lock(); // // Copy the mount data to the network share (needed for unmounting from the network browser) // Only honor shares that were mounted by the user. // if (!share->isForeign()) { SharePtr networkShare = findShare(share->url(), share->workgroupName()); if (networkShare) { networkShare->setMountData(share.data()); } } SharePtr mountedShare = findShareByPath(share->path()); if (mountedShare) { // // Check if we have to add a workgroup name and/or IP address // HostPtr networkHost = findHost(share->hostName(), share->workgroupName()); if (networkHost) { // Set the IP address if (!share->hasHostIpAddress() || networkHost->ipAddress() != share->hostIpAddress()) { share->setHostIpAddress(networkHost->ipAddress()); } // Set the workgroup name if (share->workgroupName().isEmpty()) { share->setWorkgroupName(networkHost->workgroupName()); } } // // Update share // mountedShare->setMountData(share.data()); updated = true; } mutex.unlock(); } return updated; } bool Smb4KGlobal::removeMountedShare(SharePtr share) { Q_ASSERT(share); bool removed = false; if (share) { mutex.lock(); // // Reset the mount data for the network share and the // search result // if (!share->isForeign()) { // Network share SharePtr networkShare = findShare(share->url(), share->workgroupName()); if (networkShare) { networkShare->resetMountData(); } } // // Remove the mounted share // int index = p->mountedSharesList.indexOf(share); if (index != -1) { // The share was found. Remove it. p->mountedSharesList.takeAt(index).clear(); removed = true; } else { // Try harder to find the share. SharePtr s = findShareByPath(share->isInaccessible() ? share->path() : share->canonicalPath()); if (s) { index = p->mountedSharesList.indexOf(s); if (index != -1) { p->mountedSharesList.takeAt(index).clear(); removed = true; } } share.clear(); } for (const SharePtr &s : p->mountedSharesList) { if (!s->isForeign()) { p->onlyForeignShares = false; break; } } mutex.unlock(); } return removed; } bool Smb4KGlobal::onlyForeignMountedShares() { return p->onlyForeignShares; } void Smb4KGlobal::openShare(SharePtr share, OpenWith openWith) { if (!share || share->isInaccessible()) { return; } switch (openWith) { case FileManager: { QUrl url = QUrl::fromLocalFile(share->canonicalPath()); (void) new KRun(url, 0); break; } case Konsole: { QString konsole = QStandardPaths::findExecutable("konsole"); if (konsole.isEmpty()) { Smb4KNotification::commandNotFound("konsole"); } else { KRun::runCommand(konsole+" --workdir "+KShell::quoteArg(share->canonicalPath()), 0); } break; } default: { break; } } } const QMap &Smb4KGlobal::globalSambaOptions() { return p->globalSambaOptions(); } bool Smb4KGlobal::modifyCursor() { return p->modifyCursor; } #if defined(Q_OS_LINUX) QStringList Smb4KGlobal::whitelistedMountArguments() { return p->whitelistedMountArguments; } #endif const QString Smb4KGlobal::findMountExecutable() { QDirIterator it("/", QStringList("mount.cifs"), QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { QString result = it.next(); if (result.endsWith("mount.cifs")) qDebug() << result; } QStringList paths; paths << "/bin"; paths << "/sbin"; paths << "/usr/bin"; paths << "/usr/sbin"; paths << "/usr/local/bin"; paths << "/usr/local/sbin"; #if defined(Q_OS_LINUX) return QStandardPaths::findExecutable("mount.cifs", paths); #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) return QStandardPaths::findExecutable("mount_smbfs", paths); #else return QString(); #endif } const QString Smb4KGlobal::findUmountExecutable() { QStringList paths; paths << "/bin"; paths << "/sbin"; paths << "/usr/bin"; paths << "/usr/sbin"; paths << "/usr/local/bin"; paths << "/usr/local/sbin"; return QStandardPaths::findExecutable("umount", paths); } const QString Smb4KGlobal::dataLocation() { return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QDir::separator()+"smb4k"; } diff --git a/core/smb4kglobal_p.cpp b/core/smb4kglobal_p.cpp index 039d5ac..2deb2c1 100644 --- a/core/smb4kglobal_p.cpp +++ b/core/smb4kglobal_p.cpp @@ -1,310 +1,306 @@ /*************************************************************************** These are the private helper classes of the Smb4KGlobal namespace. ------------------- begin : Di Jul 24 2007 copyright : (C) 2007-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kglobal_p.h" #include "smb4knotification.h" #include "smb4ksettings.h" // Qt includes #include #include #include #include #include #include #include #include #include Smb4KGlobalPrivate::Smb4KGlobalPrivate() { onlyForeignShares = false; coreInitialized = false; m_sambaConfigMissing = false; #ifdef Q_OS_LINUX whitelistedMountArguments << "dynperm"; whitelistedMountArguments << "rwpidforward"; whitelistedMountArguments << "hard"; whitelistedMountArguments << "soft"; whitelistedMountArguments << "noacl"; whitelistedMountArguments << "cifsacl"; whitelistedMountArguments << "backupuid"; whitelistedMountArguments << "backupgid"; whitelistedMountArguments << "ignorecase"; whitelistedMountArguments << "nocase"; whitelistedMountArguments << "nobrl"; whitelistedMountArguments << "sfu"; whitelistedMountArguments << "nounix"; whitelistedMountArguments << "nouser_xattr"; whitelistedMountArguments << "fsc"; whitelistedMountArguments << "multiuser"; whitelistedMountArguments << "actimeo"; whitelistedMountArguments << "noposixpaths"; whitelistedMountArguments << "posixpaths"; #endif // // File system watcher for smb.conf file // m_watcher = new QFileSystemWatcher(this); // // Connections // connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit())); connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotSmbConfModified(QString))); } Smb4KGlobalPrivate::~Smb4KGlobalPrivate() { // Clear the workgroup list. while (!workgroupsList.isEmpty()) { workgroupsList.takeFirst().clear(); } // Clear the host list. while (!hostsList.isEmpty()) { hostsList.takeFirst().clear(); } // Clear the list of mounted shares. while (!mountedSharesList.isEmpty()) { mountedSharesList.takeFirst().clear(); } // Clear the list of shares. while (!sharesList.isEmpty()) { sharesList.takeFirst().clear(); } } const QMap &Smb4KGlobalPrivate::globalSambaOptions(bool read) { if ((!m_sambaConfigMissing && m_sambaOptions.isEmpty()) || read) { // // Clear the options. // m_sambaOptions.clear(); // // Now search the smb.conf file. // // With the introduction of Samba 4, the smb.conf file might also // be named smb4.conf. Thus we need to search for two filenames. // QStringList paths; paths << "/etc"; paths << "/usr/local/etc"; paths << "/usr/pkg/etc"; paths << "/app/etc"; QStringList files; files << "smb.conf"; files << "smb4.conf"; QString result; for (const QString &path : paths) { QDirIterator it(path, files, QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { result = it.next(); } if (!result.isEmpty()) { break; } } // // Check if we found the file and read it. Otherwise show an error // message to the user. // QStringList contents; if (!result.isEmpty()) { QFile smbConf(result); if (smbConf.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream ts(&smbConf); while (!ts.atEnd()) { contents << ts.readLine(0); } smbConf.close(); } else { Smb4KNotification::openingFileFailed(smbConf); return m_sambaOptions; } // // Add the file to the file system watcher // m_watcher->addPath(result); // // Tell the program that the config file was found // m_sambaConfigMissing = false; } else { if (!m_sambaConfigMissing) { Smb4KNotification::sambaConfigFileMissing(); m_sambaConfigMissing = true; return m_sambaOptions; } } // // Process the contents of the smb.conf file // if (!contents.isEmpty()) { // // Jump to the [global] section and get the listed parameters // for (int i = contents.indexOf("[global]", 0); i < contents.size(); ++i) { if (i == -1) { // // No [global] section found. Stop. // break; } else if (contents.at(i).trimmed().startsWith('#') || contents.at(i).trimmed().startsWith(';') || contents.at(i).trimmed().isEmpty()) { // // This is either a comment or an empty line. We do not want it. // continue; } else if (contents.at(i).trimmed().startsWith(QLatin1String("include"))) { // // This is an include file. Get its contents and insert it into the // global Samba options map // QFile includeFile(contents.at(i).section('=', 1, 1).trimmed()); if (includeFile.exists()) { if (includeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream ts(&includeFile); QString buffer; while(!ts.atEnd()) { buffer = ts.readLine(0).trimmed(); if (buffer.startsWith('#') || buffer.startsWith(';')) { // // This is either a comment or an empty line. We do not want it. // continue; } else { // // This is an option. Put it into the global Samba options map // QString key = contents.at(i).section('=', 0, 0).trimmed().toLower(); QString value = contents.at(i).section('=', 1, 1).trimmed().toUpper(); m_sambaOptions.insert(key, value); } } } else { Smb4KNotification::openingFileFailed(includeFile); continue; } } } else if (contents.at(i).trimmed().startsWith('[') && !contents.at(i).contains("[global]", Qt::CaseSensitive)) { // // A new section begins. Stop. // break; } else { // // This is an option. Put it into the global Samba options map // QString key = contents.at(i).section('=', 0, 0).trimmed().toLower(); QString value = contents.at(i).section('=', 1, 1).trimmed().toUpper(); m_sambaOptions.insert(key, value); } } } } return m_sambaOptions; } void Smb4KGlobalPrivate::slotAboutToQuit() { Smb4KSettings::self()->save(); } void Smb4KGlobalPrivate::slotSmbConfModified(const QString &/*file*/) { globalSambaOptions(true); } diff --git a/core/smb4khardwareinterface.cpp b/core/smb4khardwareinterface.cpp index 036219c..49e00f3 100644 --- a/core/smb4khardwareinterface.cpp +++ b/core/smb4khardwareinterface.cpp @@ -1,182 +1,178 @@ /*************************************************************************** Provides an interface to the computer's hardware ------------------- begin : Die Jul 14 2015 copyright : (C) 2015-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4khardwareinterface.h" #include "smb4khardwareinterface_p.h" // Qt includes #include #include // KDE includes #include #include #include #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include #endif Q_GLOBAL_STATIC(Smb4KHardwareInterfaceStatic, p); Smb4KHardwareInterface::Smb4KHardwareInterface(QObject *parent) : QObject(parent), d(new Smb4KHardwareInterfacePrivate) { d->networkConfigUpdated = false; connect(&d->networkConfigManager, SIGNAL(updateCompleted()), this, SLOT(slotNetworkConfigUpdated())); connect(&d->networkConfigManager, SIGNAL(onlineStateChanged(bool)), this, SIGNAL(onlineStateChanged(bool))); connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), this, SLOT(slotDeviceAdded(QString))); connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString))); #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) startTimer(2000); #endif } Smb4KHardwareInterface::~Smb4KHardwareInterface() { } Smb4KHardwareInterface* Smb4KHardwareInterface::self() { return &p->instance; } void Smb4KHardwareInterface::updateNetworkConfig() { d->networkConfigManager.updateConfigurations(); } bool Smb4KHardwareInterface::networkConfigIsUpdated() const { return d->networkConfigUpdated; } bool Smb4KHardwareInterface::isOnline() const { return d->networkConfigManager.isOnline(); } #if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // Using FreeBSD 11 with KF 5.27, Solid is not able to detect mounted shares. // Thus, we check here whether shares have been mounted or unmounted. // This is a hack and should be removed as soon as possible. void Smb4KHardwareInterface::timerEvent(QTimerEvent */*e*/) { KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::BasicInfoNeeded|KMountPoint::NeedMountOptions); QStringList mountPointList, alreadyMounted; for (const QExplicitlySharedDataPointer &mountPoint : mountPoints) { if (QString::compare(mountPoint->mountType(), "smbfs") == 0 || QString::compare(mountPoint->mountType(), "cifs") == 0) { mountPointList.append(mountPoint->mountPoint()); } } QMutableStringListIterator it(mountPointList); while (it.hasNext()) { QString mp = it.next(); int index = -1; if ((index = d->mountPoints.indexOf(mp)) != -1) { d->mountPoints.removeAt(index); alreadyMounted.append(mp); it.remove(); } } if (!d->mountPoints.isEmpty()) { emit networkShareRemoved(); } if (!mountPointList.isEmpty()) { emit networkShareAdded(); } d->mountPoints.clear(); d->mountPoints.append(alreadyMounted); d->mountPoints.append(mountPointList); } #endif void Smb4KHardwareInterface::slotNetworkConfigUpdated() { d->networkConfigUpdated = true; emit networkConfigUpdated(); } void Smb4KHardwareInterface::slotDeviceAdded(const QString& udi) { Solid::Device device(udi); if (device.isDeviceInterface(Solid::DeviceInterface::NetworkShare)) { d->udis.append(udi); emit networkShareAdded(); } } void Smb4KHardwareInterface::slotDeviceRemoved(const QString& udi) { Solid::Device device(udi); // For some reason, the device has no valid type at the moment (Frameworks 5.9, // July 2015). Thus, we need the code in the else block for now. if (device.isDeviceInterface(Solid::DeviceInterface::NetworkShare)) { emit networkShareRemoved(); } else { if (d->udis.contains(udi)) { emit networkShareRemoved(); d->udis.removeOne(udi); } } } diff --git a/core/smb4khomesshareshandler.cpp b/core/smb4khomesshareshandler.cpp index a27e0cb..c7a0662 100644 --- a/core/smb4khomesshareshandler.cpp +++ b/core/smb4khomesshareshandler.cpp @@ -1,500 +1,496 @@ /*************************************************************************** This class handles the homes shares ------------------- begin : Do Aug 10 2006 copyright : (C) 2006-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335 USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4khomesshareshandler.h" #include "smb4khomesshareshandler_p.h" #include "smb4kshare.h" #include "smb4ksettings.h" #include "smb4kauthinfo.h" #include "smb4knotification.h" #include "smb4kprofilemanager.h" // Qt includes #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include Q_GLOBAL_STATIC(Smb4KHomesSharesHandlerStatic, p); Smb4KHomesSharesHandler::Smb4KHomesSharesHandler(QObject *parent) : QObject(parent), d(new Smb4KHomesSharesHandlerPrivate) { // First we need the directory. QString path = dataLocation(); QDir dir; if (!dir.exists(path)) { dir.mkpath(path); } d->homesUsers = readUserNames(false); // // Connections // connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit())); connect(Smb4KProfileManager::self(), SIGNAL(activeProfileChanged(QString)), this, SLOT(slotActiveProfileChanged(QString))); } Smb4KHomesSharesHandler::~Smb4KHomesSharesHandler() { while (!d->homesUsers.isEmpty()) { delete d->homesUsers.takeFirst(); } } Smb4KHomesSharesHandler *Smb4KHomesSharesHandler::self() { return &p->instance; } bool Smb4KHomesSharesHandler::specifyUser(const SharePtr &share, bool overwrite) { Q_ASSERT(share); bool success = false; // Avoid that the dialog is opened although the homes // user name has already been defined. if (share->isHomesShare() && (share->homeUrl().isEmpty() || overwrite)) { QStringList users = findHomesUsers(share); QPointer dlg = new Smb4KHomesUserDialog(share, QApplication::activeWindow()); dlg->setUserNames(users); if (dlg->exec() == QDialog::Accepted) { QString login = dlg->login(); users = dlg->userNames(); addHomesUsers(share, users); if (!login.isEmpty()) { // If the login names do not match, clear the password. if (!share->login().isEmpty() && QString::compare(share->login(), login) != 0) { share->setPassword(QString()); } // Set the login name. share->setLogin(login); success = true; } writeUserNames(d->homesUsers); } delete dlg; } else { // The user name has already been set. success = true; } return success; } QStringList Smb4KHomesSharesHandler::homesUsers(const SharePtr &share) { Q_ASSERT(share); QStringList users = findHomesUsers(share); return users; } const QList Smb4KHomesSharesHandler::readUserNames(bool allUsers) { QList list; // Locate the XML file. QFile xmlFile(dataLocation()+QDir::separator()+"homes_shares.xml"); if (xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QXmlStreamReader xmlReader(&xmlFile); while (!xmlReader.atEnd()) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "homes_shares" && xmlReader.attributes().value("version") != "1.0") { xmlReader.raiseError(i18n("%1 is not a version 1.0 file.", xmlFile.fileName())); break; } else { if (xmlReader.name() == "homes") { QString profile = xmlReader.attributes().value("profile").toString(); // FIXME: Remove the last check in the if statement with Smb4K > 2.0. // It was introduced for migration, because the default profile // (e.g. use of no profiles) was not empty but named "Default"... if (allUsers || QString::compare(profile, Smb4KProfileManager::self()->activeProfile(), Qt::CaseSensitive) == 0 || (!Smb4KProfileManager::self()->useProfiles() && QString::compare(profile, "Default", Qt::CaseSensitive) == 0)) { Smb4KHomesUsers *users = new Smb4KHomesUsers(); users->setProfile(profile); users->setShareName(xmlReader.name().toString()); while (!(xmlReader.isEndElement() && xmlReader.name() == "homes")) { xmlReader.readNext(); if (xmlReader.isStartElement()) { if (xmlReader.name() == "host") { users->setHostName(xmlReader.readElementText()); } else if (xmlReader.name() == "workgroup") { users->setWorkgroupName(xmlReader.readElementText()); } else if (xmlReader.name() == "ip") { users->setHostIP(xmlReader.readElementText()); } else if (xmlReader.name() == "users") { QStringList u; while (!(xmlReader.isEndElement() && xmlReader.name() == "users")) { xmlReader.readNext(); if (xmlReader.isStartElement() && xmlReader.name() == "user") { u << xmlReader.readElementText(); } } users->setUsers(u); } continue; } else { continue; } } list << users; } else { continue; } } else { continue; } } } else { continue; } } xmlFile.close(); if (xmlReader.hasError()) { Smb4KNotification::readingFileFailed(xmlFile, xmlReader.errorString()); } } else { if (xmlFile.exists()) { Smb4KNotification::openingFileFailed(xmlFile); } } return list; } void Smb4KHomesSharesHandler::writeUserNames(const QList &list, bool listOnly) { QList allUsers; if (!listOnly) { // First read all entries. Then remove all, that belong to // the currently active profile. allUsers = readUserNames(true); QMutableListIterator it(allUsers); while (it.hasNext()) { Smb4KHomesUsers *users = it.next(); if (QString::compare(users->profile(), Smb4KProfileManager::self()->activeProfile()) == 0) { it.remove(); } } } for (Smb4KHomesUsers *users : list) { allUsers << new Smb4KHomesUsers(*users); } QFile xmlFile(dataLocation()+QDir::separator()+"homes_shares.xml"); if (!allUsers.isEmpty()) { if (xmlFile.open(QIODevice::WriteOnly|QIODevice::Text)) { QXmlStreamWriter xmlWriter(&xmlFile); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("homes_shares"); xmlWriter.writeAttribute("version", "1.0"); for (Smb4KHomesUsers *users : allUsers) { xmlWriter.writeStartElement("homes"); // FIXME: Remove this block with Smb4K > 2.0 and use the commented line below. // This block was introduced for migration, because the default profile // (i.e. use of no profiles) was not empty but named "Default"... if (!Smb4KProfileManager::self()->useProfiles()) { xmlWriter.writeAttribute("profile", Smb4KSettings::self()->activeProfile()); } else { xmlWriter.writeAttribute("profile", users->profile()); } // xmlWriter.writeAttribute("profile", users->profile()); xmlWriter.writeTextElement("host", users->hostName()); xmlWriter.writeTextElement("workgroup", users->workgroupName()); xmlWriter.writeTextElement("ip", users->hostIP()); xmlWriter.writeStartElement("users"); for (const QString &user : users->users()) { xmlWriter.writeTextElement("user", user); } xmlWriter.writeEndElement(); xmlWriter.writeEndElement(); } xmlWriter.writeEndDocument(); xmlFile.close(); } else { Smb4KNotification::openingFileFailed(xmlFile); } } else { xmlFile.remove(); } while (!allUsers.isEmpty()) { delete allUsers.takeFirst(); } } const QStringList Smb4KHomesSharesHandler::findHomesUsers(const SharePtr &share) { Q_ASSERT(share); QStringList users; if (!d->homesUsers.isEmpty()) { for (int i = 0; i < d->homesUsers.size(); ++i) { if (QString::compare(share->hostName(), d->homesUsers.at(i)->hostName(), Qt::CaseInsensitive) == 0 && QString::compare(share->shareName(), d->homesUsers.at(i)->shareName(), Qt::CaseInsensitive) == 0 && ((d->homesUsers.at(i)->workgroupName().isEmpty() || share->workgroupName().isEmpty()) || QString::compare(share->workgroupName(), d->homesUsers.at(i)->workgroupName(), Qt::CaseInsensitive) == 0)) { users = d->homesUsers.at(i)->users(); break; } else { continue; } } } return users; } void Smb4KHomesSharesHandler::addHomesUsers(const SharePtr &share, const QStringList &users) { Q_ASSERT(share); bool found = false; if (!d->homesUsers.isEmpty()) { for (int i = 0; i < d->homesUsers.size(); ++i) { if (QString::compare(share->hostName(), d->homesUsers.at(i)->hostName(), Qt::CaseInsensitive) == 0 && QString::compare(share->shareName(), d->homesUsers.at(i)->shareName(), Qt::CaseInsensitive) == 0 && ((d->homesUsers.at(i)->workgroupName().isEmpty() || share->workgroupName().isEmpty()) || QString::compare(share->workgroupName(), d->homesUsers.at(i)->workgroupName(), Qt::CaseInsensitive) == 0)) { d->homesUsers[i]->setUsers(users); found = true; break; } else { continue; } } } if (!found) { Smb4KHomesUsers *u = new Smb4KHomesUsers(share, users); u->setProfile(Smb4KProfileManager::self()->activeProfile()); d->homesUsers << u; } } void Smb4KHomesSharesHandler::migrateProfile(const QString& from, const QString& to) { // Read all entries for later conversion. QList allUsers = readUserNames(true); // Replace the old profile name with the new one. for (int i = 0; i < allUsers.size(); ++i) { if (QString::compare(allUsers.at(i)->profile(), from, Qt::CaseSensitive) == 0) { allUsers[i]->setProfile(to); } } // Write the new list to the file. writeUserNames(allUsers, true); // Profile settings changed, so invoke the slot. slotActiveProfileChanged(Smb4KProfileManager::self()->activeProfile()); // Clear the temporary lists of bookmarks and groups. while (!allUsers.isEmpty()) { delete allUsers.takeFirst(); } } void Smb4KHomesSharesHandler::removeProfile(const QString& name) { // Read all entries for later removal. QList allUsers = readUserNames(true); QMutableListIterator it(allUsers); while (it.hasNext()) { Smb4KHomesUsers *user = it.next(); if (QString::compare(user->profile(), name, Qt::CaseSensitive) == 0) { it.remove(); } } // Write the new list to the file. writeUserNames(allUsers, true); // Profile settings changed, so invoke the slot. slotActiveProfileChanged(Smb4KProfileManager::self()->activeProfile()); // Clear the temporary list of homes users. while (!allUsers.isEmpty()) { delete allUsers.takeFirst(); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KHomesSharesHandler::slotAboutToQuit() { writeUserNames(d->homesUsers); } void Smb4KHomesSharesHandler::slotActiveProfileChanged(const QString& /*activeProfile*/) { // Clear the list of homes users. while (!d->homesUsers.isEmpty()) { delete d->homesUsers.takeFirst(); } // Reload the list of homes users. d->homesUsers = readUserNames(false); } diff --git a/core/smb4khomesshareshandler_p.cpp b/core/smb4khomesshareshandler_p.cpp index 89ac83d..5c551fd 100644 --- a/core/smb4khomesshareshandler_p.cpp +++ b/core/smb4khomesshareshandler_p.cpp @@ -1,330 +1,326 @@ /*************************************************************************** Private helpers for the homes shares handler ------------------- begin : Mo Apr 11 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, 51 Franklin Street, Suite 500, Boston, * * MA 02110-1335 USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4khomesshareshandler_p.h" #include "smb4ksettings.h" #include "smb4kshare.h" // Qt includes #include #include #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include Smb4KHomesUsers::Smb4KHomesUsers(const SharePtr &s, const QStringList &u) { m_workgroup_name = s->workgroupName(); m_host_name = s->hostName(); m_share_name = s->shareName(); m_host_ip.setAddress(s->hostIpAddress()); m_users = u; } Smb4KHomesUsers::Smb4KHomesUsers(const Smb4KHomesUsers &u) { m_workgroup_name = u.workgroupName(); m_host_name = u.hostName(); m_share_name = u.shareName(); m_host_ip.setAddress(u.hostIP()); m_users = u.users(); m_profile = u.profile(); } Smb4KHomesUsers::Smb4KHomesUsers() { } Smb4KHomesUsers::~Smb4KHomesUsers() { } QString Smb4KHomesUsers::workgroupName() const { return m_workgroup_name; } void Smb4KHomesUsers::setWorkgroupName(const QString& name) { m_workgroup_name = name; } QString Smb4KHomesUsers::hostName() const { return m_host_name; } void Smb4KHomesUsers::setHostName(const QString& name) { m_host_name = name; } QString Smb4KHomesUsers::shareName() const { return m_share_name; } void Smb4KHomesUsers::setShareName(const QString& name) { m_share_name = name; } QString Smb4KHomesUsers::hostIP() const { return m_host_ip.toString(); } void Smb4KHomesUsers::setHostIP(const QString& ip) { m_host_ip.setAddress(ip); } QStringList Smb4KHomesUsers::users() const { return m_users; } void Smb4KHomesUsers::setUsers(const QStringList& users) { m_users = users; } QString Smb4KHomesUsers::profile() const { return m_profile; } void Smb4KHomesUsers::setProfile(const QString& profile) { m_profile = profile; } Smb4KHomesUserDialog::Smb4KHomesUserDialog(const SharePtr &share, QWidget *parent) : QDialog(parent), m_share(share) { // // Set the window title // setWindowTitle(i18n("Specify User")); // // Setup the view // setupView(); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "HomesUserDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Fill the completion object // m_user_combo->completionObject()->setItems(group.readEntry("HomesUsersCompletion", QStringList())); } Smb4KHomesUserDialog::~Smb4KHomesUserDialog() { } void Smb4KHomesUserDialog::setupView() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); QWidget *description = new QWidget(this); QHBoxLayout *desc_layout = new QHBoxLayout(description); desc_layout->setSpacing(5); desc_layout->setMargin(0); QLabel *pixmap = new QLabel(description); QPixmap user_pix = KDE::icon("user-identity").pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(user_pix); pixmap->setAlignment(Qt::AlignBottom); QLabel *label = new QLabel(i18n("Please specify a username for share
%1.", m_share->displayString()), description); label->setWordWrap(true); label->setAlignment(Qt::AlignBottom); desc_layout->addWidget(pixmap, 0); desc_layout->addWidget(label, Qt::AlignBottom); QWidget *input = new QWidget(this); QGridLayout *input_layout = new QGridLayout(input); input_layout->setSpacing(5); input_layout->setMargin(0); input_layout->setColumnStretch(0, 0); input_layout->setColumnStretch(1, 1); QLabel *input_label = new QLabel(i18n("User:"), input); m_user_combo = new KComboBox(true, input); m_user_combo->setDuplicatesEnabled(false); m_user_combo->setEditable(true); input_layout->addWidget(input_label, 0, 0, 0); input_layout->addWidget(m_user_combo, 0, 1, 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_clear_button = buttonBox->addButton(i18n("Clear List"), QDialogButtonBox::ActionRole); m_clear_button->setIcon(KDE::icon("edit-clear")); m_clear_button->setEnabled(false); m_ok_button = buttonBox->addButton(QDialogButtonBox::Ok); m_ok_button->setEnabled(false); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_ok_button->setShortcut(Qt::CTRL|Qt::Key_Return); m_cancel_button->setShortcut(Qt::Key_Escape); m_ok_button->setDefault(true); layout->addWidget(description, 0); layout->addWidget(input, 0); layout->addWidget(buttonBox, 0); m_user_combo->setFocus(); connect(m_user_combo, SIGNAL(currentTextChanged(QString)), SLOT(slotTextChanged(QString))); connect(m_user_combo->lineEdit(), SIGNAL(editingFinished()), SLOT(slotHomesUserEntered())); connect(m_clear_button, SIGNAL(clicked()), SLOT(slotClearClicked())); connect(m_ok_button, SIGNAL(clicked()), SLOT(slotOkClicked())); connect(m_cancel_button, SIGNAL(clicked()), SLOT(reject())); } void Smb4KHomesUserDialog::setUserNames(const QStringList &users) { if (!users.isEmpty()) { m_user_combo->addItems(users); m_user_combo->setCurrentItem(""); m_clear_button->setEnabled(true); } } QStringList Smb4KHomesUserDialog::userNames() { QStringList users; for (int i = 0; i < m_user_combo->count(); ++i) { users << m_user_combo->itemText(i); } if (!users.contains(m_user_combo->currentText())) { users << m_user_combo->currentText(); } return users; } void Smb4KHomesUserDialog::slotTextChanged(const QString &text) { m_ok_button->setEnabled(!text.isEmpty()); } void Smb4KHomesUserDialog::slotClearClicked() { m_user_combo->clearEditText(); m_user_combo->clear(); m_clear_button->setEnabled(false); } void Smb4KHomesUserDialog::slotOkClicked() { KConfigGroup group(Smb4KSettings::self()->config(), "HomesUserDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); group.writeEntry("HomesUsersCompletion", m_user_combo->completionObject()->items()); accept(); } void Smb4KHomesUserDialog::slotHomesUserEntered() { KCompletion *completion = m_user_combo->completionObject(); if (!m_user_combo->currentText().isEmpty()) { completion->addItem(m_user_combo->currentText()); } } diff --git a/core/smb4khost.cpp b/core/smb4khost.cpp index 9e5a9ac..6ed8f46 100644 --- a/core/smb4khost.cpp +++ b/core/smb4khost.cpp @@ -1,222 +1,218 @@ /*************************************************************************** Smb4K's container class for information about a host. ------------------- begin : Sa Jan 26 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4khost.h" #include "smb4kauthinfo.h" // Qt includes #include #include #include // KDE includes #include class Smb4KHostPrivate { public: QString workgroup; QHostAddress ip; QString comment; bool isMaster; }; Smb4KHost::Smb4KHost(const QString &name) : Smb4KBasicNetworkItem(Host), d(new Smb4KHostPrivate) { d->isMaster = false; *pIcon = KDE::icon("network-server"); setHostName(name); } Smb4KHost::Smb4KHost(const Smb4KHost &h) : Smb4KBasicNetworkItem(Host), d(new Smb4KHostPrivate) { *d = *h.d; if (pIcon->isNull()) { *pIcon = KDE::icon("network-server"); } } Smb4KHost::Smb4KHost() : Smb4KBasicNetworkItem(Host), d(new Smb4KHostPrivate) { d->isMaster = false; *pIcon = KDE::icon("network-server"); } Smb4KHost::~Smb4KHost() { } void Smb4KHost::setHostName(const QString &name) { pUrl->setHost(name); pUrl->setScheme("smb"); } QString Smb4KHost::hostName() const { return pUrl->host().toUpper(); } void Smb4KHost::setWorkgroupName(const QString &workgroup) { d->workgroup = workgroup.toUpper(); } QString Smb4KHost::workgroupName() const { return d->workgroup; } void Smb4KHost::setIpAddress(const QString &ip) { d->ip.setAddress(ip); } void Smb4KHost::setIpAddress(const QHostAddress& address) { if (!address.isNull() && address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { d->ip = address; } } QString Smb4KHost::ipAddress() const { return d->ip.toString(); } bool Smb4KHost::hasIpAddress() const { return !d->ip.isNull(); } void Smb4KHost::setComment(const QString &comment) { d->comment = comment; } QString Smb4KHost::comment() const { return d->comment; } void Smb4KHost::setIsMasterBrowser(bool master) { d->isMaster = master; } bool Smb4KHost::isMasterBrowser() const { return d->isMaster; } void Smb4KHost::setLogin(const QString &login) { pUrl->setUserName(login); } QString Smb4KHost::login() const { return pUrl->userName(); } void Smb4KHost::setPassword(const QString &passwd) { pUrl->setPassword(passwd); } QString Smb4KHost::password() const { return pUrl->password(); } void Smb4KHost::setPort(int port) { pUrl->setPort(port); } int Smb4KHost::port() const { return pUrl->port(); } void Smb4KHost::setAuthInfo(Smb4KAuthInfo *authInfo) { pUrl->setUserName(authInfo->userName()); pUrl->setPassword(authInfo->password()); } void Smb4KHost::update(Smb4KHost* host) { if (QString::compare(workgroupName(), host->workgroupName()) == 0 && QString::compare(hostName(), host->hostName()) == 0) { *pUrl = host->url(); setComment(host->comment()); setIsMasterBrowser(host->isMasterBrowser()); // Do not kill the already discovered IP address if (!hasIpAddress() && host->hasIpAddress()) { setIpAddress(host->ipAddress()); } } } diff --git a/core/smb4kmounter.cpp b/core/smb4kmounter.cpp index b523e8e..264626b 100644 --- a/core/smb4kmounter.cpp +++ b/core/smb4kmounter.cpp @@ -1,2487 +1,2483 @@ /*************************************************************************** The core class that mounts the shares. ------------------- begin : Die Jun 10 2003 copyright : (C) 2003-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // Application specific includes #include "smb4kmounter.h" #include "smb4kmounter_p.h" #include "smb4kauthinfo.h" #include "smb4kshare.h" #include "smb4ksettings.h" #include "smb4khomesshareshandler.h" #include "smb4kwalletmanager.h" #include "smb4knotification.h" #include "smb4kbookmarkhandler.h" #include "smb4kcustomoptionsmanager.h" #include "smb4kcustomoptions.h" #include "smb4kbookmark.h" #include "smb4kprofilemanager.h" #include "smb4khardwareinterface.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include #include #include #include #include #include #include using namespace Smb4KGlobal; #define TIMEOUT 50 Q_GLOBAL_STATIC(Smb4KMounterStatic, p); Smb4KMounter::Smb4KMounter(QObject *parent) : KCompositeJob(parent), d(new Smb4KMounterPrivate) { setAutoDelete(false); d->timerId = -1; d->remountTimeout = 0; d->remountAttempts = 0; d->checkTimeout = 0; d->newlyMounted = 0; d->newlyUnmounted = 0; d->dialog = 0; d->firstImportDone = false; d->mountShares = false; d->unmountShares = false; d->activeProfile = Smb4KProfileManager::self()->activeProfile(); d->detectAllShares = Smb4KMountSettings::detectAllShares(); // // Connections // connect(Smb4KHardwareInterface::self(), SIGNAL(onlineStateChanged(bool)), this, SLOT(slotOnlineStateChanged(bool))); connect(Smb4KHardwareInterface::self(), SIGNAL(networkShareAdded()), this, SLOT(slotTriggerImport())); connect(Smb4KHardwareInterface::self(), SIGNAL(networkShareRemoved()), this, SLOT(slotTriggerImport())); connect(Smb4KProfileManager::self(), SIGNAL(migratedProfile(QString,QString)), this, SLOT(slotProfileMigrated(QString,QString))); connect(Smb4KProfileManager::self(), SIGNAL(aboutToChangeProfile()), this, SLOT(slotAboutToChangeProfile())); connect(Smb4KProfileManager::self(), SIGNAL(activeProfileChanged(QString)), this, SLOT(slotActiveProfileChanged(QString))); connect(Smb4KMountSettings::self(), SIGNAL(configChanged()), this, SLOT(slotConfigChanged())); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),this, SLOT(slotAboutToQuit())); } Smb4KMounter::~Smb4KMounter() { while (!d->importedShares.isEmpty()) { d->importedShares.takeFirst().clear(); } while (!d->retries.isEmpty()) { d->retries.takeFirst().clear(); } } Smb4KMounter *Smb4KMounter::self() { return &p->instance; } void Smb4KMounter::abort() { if (!QCoreApplication::closingDown()) { QListIterator it(subjobs()); while (it.hasNext()) { it.next()->kill(KJob::EmitResult); } } } bool Smb4KMounter::isRunning() { return hasSubjobs(); } void Smb4KMounter::triggerRemounts(bool fill_list) { if (Smb4KMountSettings::remountShares() /* one-time remounts */ || !Smb4KCustomOptionsManager::self()->sharesToRemount().isEmpty() /* permanent remounts */) { if (fill_list) { // // Get the shares that are to be remounted // QList list = Smb4KCustomOptionsManager::self()->sharesToRemount(); if (!list.isEmpty()) { // // Check which shares actually need to be remounted // for (const OptionsPtr &opt : list) { QList mountedShares = findShareByUrl(opt->url()); if (!mountedShares.isEmpty()) { bool mount = true; for (const SharePtr &s : mountedShares) { if (!s->isForeign()) { mount = false; break; } else { continue; } } if (mount) { SharePtr share = SharePtr(new Smb4KShare()); share->setUrl(opt->url()); share->setWorkgroupName(opt->workgroupName()); share->setHostIpAddress(opt->ipAddress()); if (share->url().isValid() && !share->url().isEmpty()) { d->remounts << share; } } } else { SharePtr share = SharePtr(new Smb4KShare()); share->setUrl(opt->url()); share->setWorkgroupName(opt->workgroupName()); share->setHostIpAddress(opt->ipAddress()); if (share->url().isValid() && !share->url().isEmpty()) { d->remounts << share; } } } } } if (!d->remounts.isEmpty()) { mountShares(d->remounts); } d->remountAttempts++; } } void Smb4KMounter::import(bool checkInaccessible) { // // Immediately return here if we are still processing imported shares // if (!d->importedShares.isEmpty()) { return; } // // Get the mountpoints that are present on the system // KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::BasicInfoNeeded|KMountPoint::NeedMountOptions); // Now determine all mountpoints that have the SMBFS or the CIFS // filesystem. for (const QExplicitlySharedDataPointer &mountPoint : mountPoints) { if (QString::compare(mountPoint->mountType(), "cifs") == 0 || QString::compare(mountPoint->mountType(), "smbfs") == 0) { // Create new share and set the mountpoint and the filesystem SharePtr share = SharePtr(new Smb4KShare()); share->setUrl(mountPoint->mountedFrom()); share->setPath(mountPoint->mountPoint()); share->setMounted(true); // Get all mount options for (const QString &option : mountPoint->mountOptions()) { if (option.startsWith(QLatin1String("domain=")) || option.startsWith(QLatin1String("workgroup="))) { share->setWorkgroupName(option.section('=', 1, 1).trimmed()); } else if (option.startsWith(QLatin1String("addr="))) { share->setHostIpAddress(option.section('=', 1, 1).trimmed()); } else if (option.startsWith(QLatin1String("username=")) || option.startsWith(QLatin1String("user="))) { share->setLogin(option.section('=', 1, 1).trimmed()); } } // Work around empty usernames if (share->login().isEmpty()) { share->setLogin("guest"); } d->importedShares << share; } } // // Check which shares were unmounted. Remove all obsolete mountpoints, emit // the unmounted() signal on each of the unmounted shares and remove them // from the global list. // NOTE: The unmount() signal is emitted *BEFORE* the share is removed // from the global list! You need to account for that in your application. // QList unmountedShares; bool found = false; for (const SharePtr &mountedShare : mountedSharesList()) { for (const SharePtr &importedShare : d->importedShares) { // Check the mountpoint, since that one is unique. We will only use // Smb4KShare::path(), so that we do not run into trouble if a share // is inaccessible. if (QString::compare(mountedShare->path(), importedShare->path()) == 0) { found = true; break; } } if (!found) { // Remove the mountpoint if the share is not a foreign one if (!mountedShare->isForeign()) { QDir dir; dir.cd(mountedShare->canonicalPath()); dir.rmdir(dir.canonicalPath()); if (dir.cdUp()) { dir.rmdir(dir.canonicalPath()); } } mountedShare->setMounted(false); unmountedShares << mountedShare; } found = false; } if (!unmountedShares.isEmpty()) { d->newlyUnmounted += unmountedShares.size(); if (!d->mountShares && !d->unmountShares) { if (d->newlyUnmounted == 1) { // Copy the share SharePtr unmountedShare = unmountedShares.first(); // Remove the share from the global list and notify the program and user removeMountedShare(unmountedShares.first()); emit unmounted(unmountedShare); Smb4KNotification::shareUnmounted(unmountedShare); unmountedShare.clear(); } else { for (const SharePtr &share : unmountedShares) { // Copy the share SharePtr unmountedShare = share; // Remove the share from the global list and notify the program removeMountedShare(share); emit unmounted(unmountedShare); unmountedShare.clear(); } // Notify the user Smb4KNotification::sharesUnmounted(d->newlyUnmounted); } d->newlyUnmounted = 0; } else { for (const SharePtr &share : unmountedShares) { // Copy the share SharePtr unmountedShare = share; // Remove the share from the global list and notify the program removeMountedShare(share); emit unmounted(unmountedShare); unmountedShare.clear(); } } emit mountedSharesListChanged(); } else { d->newlyUnmounted = 0; } // // Now stat the imported shares to get information about them. // Do not use Smb4KShare::canonicalPath() here, otherwise we might // get lock-ups with inaccessible shares. // if (Smb4KHardwareInterface::self()->isOnline()) { QMutableListIterator it(d->importedShares); while (it.hasNext()) { SharePtr share = it.next(); SharePtr mountedShare = findShareByPath(share->path()); if (mountedShare) { if (mountedShare->isInaccessible() && !checkInaccessible) { it.remove(); continue; } } QUrl url = QUrl::fromLocalFile(share->path()); KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo); job->setDetails(0); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotStatResult(KJob*))); // Do not use addSubJob(), because that would confuse isRunning(), etc. job->start(); } // // Set d->firstImportDone here only for the case that no mounted shares // could be found. In all other cases d->firstImportDone will be set in // slotStatResult(). // if (!d->firstImportDone && d->importedShares.isEmpty()) { d->firstImportDone = true; } } } void Smb4KMounter::mountShare(const SharePtr &share) { Q_ASSERT(share); if (share) { // // Check that the URL is valid // if (!share->url().isValid()) { Smb4KNotification::invalidURLPassed(); return; } // // Check if the share has already been mounted. If it is already present, // do not process it and return. // QUrl url; if (share->isHomesShare()) { if (!Smb4KHomesSharesHandler::self()->specifyUser(share, true)) { return; } url = share->homeUrl(); } else { url = share->url(); } QList mountedShares = findShareByUrl(url); bool isMounted = false; for (const SharePtr &s : mountedShares) { if (!s->isForeign()) { isMounted = true; break; } } if (isMounted) { return; } // // Wake-On-LAN: Wake up the host before mounting // if (Smb4KSettings::enableWakeOnLAN()) { OptionsPtr options = Smb4KCustomOptionsManager::self()->findOptions(KIO::upUrl(share->url())); if (options && options->wolSendBeforeMount()) { emit aboutToStart(WakeUp); QUdpSocket *socket = new QUdpSocket(this); QHostAddress addr; // Use the host's IP address directly from the share object. if (share->hasHostIpAddress()) { addr.setAddress(share->hostIpAddress()); } else { addr.setAddress("255.255.255.255"); } // Construct magic sequence QByteArray sequence; // 6 times 0xFF for (int j = 0; j < 6; ++j) { sequence.append(QChar(0xFF).toLatin1()); } // 16 times the MAC address QStringList parts = options->macAddress().split(':', QString::SkipEmptyParts); for (int j = 0; j < 16; ++j) { for (int k = 0; k < parts.size(); ++k) { sequence.append(QChar(QString("0x%1").arg(parts.at(k)).toInt(0, 16)).toLatin1()); } } socket->writeDatagram(sequence, addr, 9); delete socket; // Wait the defined time int stop = 1000 * Smb4KSettings::wakeOnLANWaitingTime() / 250; int i = 0; while (i++ < stop) { QTest::qWait(250); } emit finished(WakeUp); } } // // Create the mountpoint // QString mountpoint; mountpoint += Smb4KMountSettings::mountPrefix().path(); mountpoint += QDir::separator(); mountpoint += (Smb4KMountSettings::forceLowerCaseSubdirs() ? share->hostName().toLower() : share->hostName()); mountpoint += QDir::separator(); if (!share->isHomesShare()) { mountpoint += (Smb4KMountSettings::forceLowerCaseSubdirs() ? share->shareName().toLower() : share->shareName()); } else { mountpoint += (Smb4KMountSettings::forceLowerCaseSubdirs() ? share->login().toLower() : share->login()); } // Get the permissions that should be used for creating the // mount prefix and all its subdirectories. // Please note that the actual permissions of the mount points // are determined by the mount utility. QFile::Permissions permissions; QUrl parentDirectory; if (QFile::exists(Smb4KMountSettings::mountPrefix().path())) { parentDirectory = Smb4KMountSettings::mountPrefix(); } else { QUrl u = Smb4KMountSettings::mountPrefix(); parentDirectory = KIO::upUrl(u); } QFile f(parentDirectory.path()); permissions = f.permissions(); QDir dir(mountpoint); if (!dir.mkpath(dir.path())) { share->setPath(""); Smb4KNotification::mkdirFailed(dir); return; } else { QUrl u = QUrl::fromLocalFile(dir.path()); while (!parentDirectory.matches(u, QUrl::StripTrailingSlash)) { QFile(u.path()).setPermissions(permissions); u = KIO::upUrl(u); } } share->setPath(QDir::cleanPath(mountpoint)); // // Get the authentication information // Smb4KWalletManager::self()->readAuthInfo(share); // // Mount arguments // QVariantMap args; if (!fillMountActionArgs(share, args)) { return; } // // Emit the aboutToStart() signal // emit aboutToStart(MountShare); // // Create the mount action // KAuth::Action mountAction("org.kde.smb4k.mounthelper.mount"); mountAction.setHelperId("org.kde.smb4k.mounthelper"); mountAction.setArguments(args); KAuth::ExecuteJob *job = mountAction.execute(); // // Modify the cursor, if necessary. // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job // addSubjob(job); // // Start the job and process the returned result. // bool success = job->exec(); if (success) { int errorCode = job->error(); if (errorCode == 0) { // Get the error message QString errorMsg = job->data()["mh_error_message"].toString(); if (!errorMsg.isEmpty()) { #if defined(Q_OS_LINUX) if (errorMsg.contains("mount error 13") || errorMsg.contains("mount error(13)") /* authentication error */) { if (Smb4KWalletManager::self()->showPasswordDialog(share)) { d->retries << share; } } else if (errorMsg.contains("Unable to find suitable address.")) { // Swallow this } else { Smb4KNotification::mountingFailed(share, errorMsg); } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) if (errorMsg.contains("Authentication error") || errorMsg.contains("Permission denied")) { if (Smb4KWalletManager::self()->showPasswordDialog(share)) { d->retries << share; } } else { Smb4KNotification::mountingFailed(share, errorMsg); } #else qWarning() << "Smb4KMounter::slotMountJobFinished(): Error handling not implemented!"; Smb4KNotification::mountingFailed(share.data(), errorMsg); #endif } } else { Smb4KNotification::actionFailed(errorCode); } } else { // FIXME: Report that the action could not be started } // // Remove the job from the job list // removeSubjob(job); // // Reset the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::restoreOverrideCursor(); } // // Emit the finished() signal // emit finished(MountShare); } } void Smb4KMounter::mountShares(const QList &shares) { d->mountShares = true; for (const SharePtr &share : shares) { mountShare(share); } d->mountShares = false; } void Smb4KMounter::unmountShare(const SharePtr &share, bool silent) { Q_ASSERT(share); if (share) { // // Check that the URL is valid. // if (!share->url().isValid()) { Smb4KNotification::invalidURLPassed(); return; } // // Handle foreign shares according to the settings // if (share->isForeign()) { if (!Smb4KMountSettings::unmountForeignShares()) { if (!silent) { Smb4KNotification::unmountingNotAllowed(share); } return; } else { if (!silent) { if (KMessageBox::warningYesNo(QApplication::activeWindow(), i18n("

The share %1 is mounted to
%2 and owned by user %3.

" "

Do you really want to unmount it?

", share->displayString(), share->path(), share->user().loginName()), i18n("Foreign Share")) == KMessageBox::No) { return; } } else { // Without the confirmation of the user, we are not // unmounting a foreign share! return; } } } // // Force the unmounting of the share either if the system went offline // or if the user chose to forcibly unmount inaccessible shares (Linux only). // bool force = false; if (Smb4KHardwareInterface::self()->isOnline()) { #if defined(Q_OS_LINUX) if (share->isInaccessible()) { force = Smb4KMountSettings::forceUnmountInaccessible(); } #endif } else { force = true; } // // Unmount arguments // QVariantMap args; if (!fillUnmountActionArgs(share, force, silent, args)) { return; } // // Emit the aboutToStart() signal // emit aboutToStart(UnmountShare); // // Create the unmount action // KAuth::Action unmountAction("org.kde.smb4k.mounthelper.unmount"); unmountAction.setHelperId("org.kde.smb4k.mounthelper"); unmountAction.setArguments(args); KAuth::ExecuteJob *job = unmountAction.execute(); // // Modify the cursor, if necessary. // if (!hasSubjobs() && modifyCursor()) { QApplication::setOverrideCursor(Qt::BusyCursor); } // // Add the job // addSubjob(job); // // Start the job and process the returned result. // bool success = job->exec(); if (success) { int errorCode = job->error(); if (errorCode == 0) { // Get the error message QString errorMsg = job->data()["mh_error_message"].toString(); if (!errorMsg.isEmpty()) { // No error handling needed, just report the error message. Smb4KNotification::unmountingFailed(share, errorMsg); } } else { Smb4KNotification::actionFailed(errorCode); } } else { // FIXME: Report that the action could not be started } // // Remove the job from the job list // removeSubjob(job); // // Reset the busy cursor // if (!hasSubjobs() && modifyCursor()) { QApplication::restoreOverrideCursor(); } // // Emit the finished() signal // emit finished(UnmountShare); } } void Smb4KMounter::unmountShares(const QList &shares, bool silent) { #if defined(Q_OS_LINUX) // // Under Linux, we have to take an approach that is a bit awkward in this function. // Since the import function is invoked via Smb4KHardwareInterface::networkShareRemoved() // before mountShare() returns, no unmount of multiple shares will ever be reported // when d->unmountShares is set to FALSE *after* the loop ended. To make the reporting // work correctly, we need to set d->unmountShares to FALSE before the last unmount // is started. // d->unmountShares = true; int number = shares.size(); for (const SharePtr &share : shares) { number--; d->unmountShares = (number != 0); unmountShare(share, silent); } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // // Since under FreeBSD the emission of Smb4KHardwareInterface::networkShareRemoved() is // triggered by a timer, we can use a nice approach here. // d->unmountShares = true; for (const SharePtr &share : shares) { unmountShare(share, silent); } d->unmountShares = false; #endif } void Smb4KMounter::unmountAllShares(bool silent) { unmountShares(mountedSharesList(), silent); } void Smb4KMounter::openMountDialog() { if (!d->dialog) { SharePtr share = SharePtr(new Smb4KShare()); d->dialog = new Smb4KMountDialog(share, QApplication::activeWindow()); if (d->dialog->exec() == QDialog::Accepted && d->dialog->validUserInput()) { // Pass the share to mountShare(). mountShare(share); // Bookmark the share if the user wants this. if (d->dialog->bookmarkShare()) { Smb4KBookmarkHandler::self()->addBookmark(share); } } delete d->dialog; d->dialog = 0; share.clear(); } } void Smb4KMounter::start() { // // Check the network configurations // Smb4KHardwareInterface::self()->updateNetworkConfig(); // // Connect to Smb4KHardwareInterface to be able to get the response // connect(Smb4KHardwareInterface::self(), SIGNAL(networkConfigUpdated()), this, SLOT(slotStartJobs())); } void Smb4KMounter::saveSharesForRemount() { // // Save the shares for remount // for (const SharePtr &share : mountedSharesList()) { if (!share->isForeign()) { Smb4KCustomOptionsManager::self()->addRemount(share, false); } else { Smb4KCustomOptionsManager::self()->removeRemount(share, false); } } // // Also save each failed remount and remove it from the list // while (!d->remounts.isEmpty()) { SharePtr share = d->remounts.takeFirst(); Smb4KCustomOptionsManager::self()->addRemount(share, false); share.clear(); } } void Smb4KMounter::timerEvent(QTimerEvent *) { // Try to remount those shares that could not be mounted // before. Do this only if there are no subjobs, because we // do not want to get crashes because a share was invalidated // during processing the shares. if ((Smb4KMountSettings::remountShares() || !Smb4KCustomOptionsManager::self()->sharesToRemount().isEmpty()) && Smb4KMountSettings::remountAttempts() > d->remountAttempts) { if (d->firstImportDone && !isRunning()) { if (d->remountAttempts == 0) { triggerRemounts(true); } else if (!d->remounts.isEmpty() && d->remountTimeout >= (60000 * Smb4KMountSettings::remountInterval())) { triggerRemounts(false); d->remountTimeout = -TIMEOUT; } } d->remountTimeout += TIMEOUT; } // Retry mounting those shares that failed. This is also only // done when there are no subjobs. if (!d->retries.isEmpty() && !hasSubjobs()) { mountShares(d->retries); while (!d->retries.isEmpty()) { d->retries.takeFirst().clear(); } } // // Check the size, accessibility, etc. of the shares // // FIXME: Hopefully we can replace this with a recursive QFileSystemWatcher // approach in the future. However, using the existing QFileSystemWatcher // and a QDirIterator to add all the subdirectories of a share to the watcher // seems to be too resource consuming... // if (d->checkTimeout >= 2500 && !isRunning() && d->importedShares.isEmpty()) { for (const SharePtr &share : mountedSharesList()) { check(share); emit updated(share); } d->checkTimeout = 0; } else { d->checkTimeout += TIMEOUT; } } #if defined(Q_OS_LINUX) // // Linux arguments // bool Smb4KMounter::fillMountActionArgs(const SharePtr &share, QVariantMap& map) { // // Find the mount executable // const QString mount = findMountExecutable(); if (!mount.isEmpty()) { map.insert("mh_command", mount); } else { Smb4KNotification::commandNotFound("mount.cifs"); return false; } // // Global and custom options // QMap globalOptions = globalSambaOptions(); OptionsPtr options = Smb4KCustomOptionsManager::self()->findOptions(share); // // Pass the remote file system port to the URL // if (options) { if (options->useFileSystemPort()) { share->setPort(options->fileSystemPort()); } } else { if (Smb4KMountSettings::useRemoteFileSystemPort()) { share->setPort(Smb4KMountSettings::remoteFileSystemPort()); } } // // List of arguments passed via "-o ..." to the mount command // QStringList argumentsList; // // Workgroup or domain // if (!share->workgroupName().trimmed().isEmpty()) { argumentsList << QString("domain=%1").arg(KShell::quoteArg(share->workgroupName())); } // // Host IP address // if (share->hasHostIpAddress()) { argumentsList << QString("ip=%1").arg(share->hostIpAddress()); } // // User name (login) // if (!share->login().isEmpty()) { argumentsList << QString("username=%1").arg(share->login()); } else { argumentsList << "guest"; } // // Client's and server's NetBIOS name // // According to the manual page, this is only needed when port 139 // is used. So, we only pass the NetBIOS name in that case. // if (options) { if (options->useFileSystemPort() && options->fileSystemPort() == 139) { // The client's NetBIOS name if (!Smb4KSettings::netBIOSName().isEmpty()) { argumentsList << QString("netbiosname=%1").arg(KShell::quoteArg(Smb4KSettings::netBIOSName())); } else if (!globalOptions["netbios name"].isEmpty()) { argumentsList << QString("netbiosname=%1").arg(KShell::quoteArg(globalOptions["netbios name"])); } // The server's NetBIOS name argumentsList << QString("servernetbiosname=%1").arg(KShell::quoteArg(share->hostName())); } } else { if (Smb4KMountSettings::useRemoteFileSystemPort() && Smb4KMountSettings::remoteFileSystemPort() == 139) { // The client's NetBIOS name if (!Smb4KSettings::netBIOSName().isEmpty()) { argumentsList << QString("netbiosname=%1").arg(KShell::quoteArg(Smb4KSettings::netBIOSName())); } else if (!globalOptions["netbios name"].isEmpty()) { argumentsList << QString("netbiosname=%1").arg(KShell::quoteArg(globalOptions["netbios name"])); } // The server's NetBIOS name argumentsList << QString("servernetbiosname=%1").arg(KShell::quoteArg(share->hostName())); } } // // CIFS Unix extensions support // // This sets the uid, gid, file_mode and dir_mode arguments, if necessary. // if (options) { if (!options->cifsUnixExtensionsSupport()) { // User id if (options->useUser()) { argumentsList << QString("uid=%1").arg(options->user().userId().nativeId()); } // Group id if (options->useGroup()) { argumentsList << QString("gid=%1").arg(options->group().groupId().nativeId()); } // File mode if (options->useFileMode()) { argumentsList << QString("file_mode=%1").arg(options->fileMode()); } // Directory mode if (options->useDirectoryMode()) { argumentsList << QString("dir_mode=%1").arg(options->directoryMode()); } } } else { if (!Smb4KMountSettings::cifsUnixExtensionsSupport()) { // User id if (Smb4KMountSettings::useUserId()) { argumentsList << QString("uid=%1").arg((K_UID)Smb4KMountSettings::userId().toInt()); } // Group id if (Smb4KMountSettings::useGroupId()) { argumentsList << QString("gid=%1").arg((K_GID)Smb4KMountSettings::groupId().toInt()); } // File mode if (Smb4KMountSettings::useFileMode()) { argumentsList << QString("file_mode=%1").arg(Smb4KMountSettings::fileMode()); } // Directory mode if (Smb4KMountSettings::useDirectoryMode()) { argumentsList << QString("dir_mode=%1").arg(Smb4KMountSettings::directoryMode()); } } } // // Force user id // // FIXME: The manual page is not clear about this: Is this option only useful when the uid=... // argument is given? If so, this should be moved into the 'User id' code block above. // if (Smb4KMountSettings::forceUID()) { argumentsList << "forceuid"; } // // Force group id // // FIXME: The manual page is not clear about this: Is this option only useful when the gid=... // argument is given? If so, this should be moved into the 'Group id' code block above. // if (Smb4KMountSettings::forceGID()) { argumentsList << "forcegid"; } // // Client character set // if (Smb4KMountSettings::useClientCharset()) { switch (Smb4KMountSettings::clientCharset()) { case Smb4KMountSettings::EnumClientCharset::default_charset: { if (!globalOptions["unix charset"].isEmpty()) { argumentsList << QString("iocharset=%1").arg(globalOptions["unix charset"].toLower()); } break; } default: { argumentsList << QString("iocharset=%1").arg(Smb4KMountSettings::self()->clientCharsetItem()->choices().value(Smb4KMountSettings::clientCharset()).label); break; } } } // // File system port // if (options) { if (options->useFileSystemPort()) { argumentsList << QString("port=%1").arg(options->fileSystemPort()); } } else { if (Smb4KMountSettings::useRemoteFileSystemPort()) { argumentsList << QString("port=%1").arg(Smb4KMountSettings::remoteFileSystemPort()); } } // // Write access // if (options) { if (options->useWriteAccess()) { switch (options->writeAccess()) { case Smb4KMountSettings::EnumWriteAccess::ReadWrite: { argumentsList << "rw"; break; } case Smb4KMountSettings::EnumWriteAccess::ReadOnly: { argumentsList << "ro"; break; } default: { break; } } } } else { if (Smb4KMountSettings::useWriteAccess()) { switch (Smb4KMountSettings::writeAccess()) { case Smb4KMountSettings::EnumWriteAccess::ReadWrite: { argumentsList << "rw"; break; } case Smb4KMountSettings::EnumWriteAccess::ReadOnly: { argumentsList << "ro"; break; } default: { break; } } } } // // Permission checks // if (Smb4KMountSettings::permissionChecks()) { argumentsList << "perm"; } else { argumentsList << "noperm"; } // // Client controls ids // if (Smb4KMountSettings::clientControlsIDs()) { argumentsList << "setuids"; } else { argumentsList << "nosetuids"; } // // Server inode numbers // if (Smb4KMountSettings::serverInodeNumbers()) { argumentsList << "serverino"; } else { argumentsList << "noserverino"; } // // Cache mode // if (Smb4KMountSettings::useCacheMode()) { switch (Smb4KMountSettings::cacheMode()) { case Smb4KMountSettings::EnumCacheMode::None: { argumentsList << "cache=none"; break; } case Smb4KMountSettings::EnumCacheMode::Strict: { argumentsList << "cache=strict"; break; } case Smb4KMountSettings::EnumCacheMode::Loose: { argumentsList << "cache=loose"; break; } default: { break; } } } // // Translate reserved characters // if (Smb4KMountSettings::translateReservedChars()) { argumentsList << "mapchars"; } else { argumentsList << "nomapchars"; } // // Locking // if (Smb4KMountSettings::noLocking()) { argumentsList << "nolock"; } // // Security mode // if (options) { if (options->useSecurityMode()) { switch (options->securityMode()) { case Smb4KMountSettings::EnumSecurityMode::None: { argumentsList << "sec=none"; break; } case Smb4KMountSettings::EnumSecurityMode::Krb5: { argumentsList << "sec=krb5"; argumentsList << QString("cruid=%1").arg(KUser(KUser::UseRealUserID).userId().nativeId()); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5i: { argumentsList << "sec=krb5i"; argumentsList << QString("cruid=%1").arg(KUser(KUser::UseRealUserID).userId().nativeId()); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlm: { argumentsList << "sec=ntlm"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmi: { argumentsList << "sec=ntlmi"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2: { argumentsList << "sec=ntlmv2"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2i: { argumentsList << "sec=ntlmv2i"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmssp: { argumentsList << "sec=ntlmssp"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmsspi: { argumentsList << "sec=ntlmsspi"; break; } default: { // Smb4KSettings::EnumSecurityMode::Default, break; } } } } else { if (Smb4KMountSettings::useSecurityMode()) { switch (Smb4KMountSettings::securityMode()) { case Smb4KMountSettings::EnumSecurityMode::None: { argumentsList << "sec=none"; break; } case Smb4KMountSettings::EnumSecurityMode::Krb5: { argumentsList << "sec=krb5"; argumentsList << QString("cruid=%1").arg(KUser(KUser::UseRealUserID).userId().nativeId()); break; } case Smb4KMountSettings::EnumSecurityMode::Krb5i: { argumentsList << "sec=krb5i"; argumentsList << QString("cruid=%1").arg(KUser(KUser::UseRealUserID).userId().nativeId()); break; } case Smb4KMountSettings::EnumSecurityMode::Ntlm: { argumentsList << "sec=ntlm"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmi: { argumentsList << "sec=ntlmi"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2: { argumentsList << "sec=ntlmv2"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmv2i: { argumentsList << "sec=ntlmv2i"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmssp: { argumentsList << "sec=ntlmssp"; break; } case Smb4KMountSettings::EnumSecurityMode::Ntlmsspi: { argumentsList << "sec=ntlmsspi"; break; } default: { // Smb4KSettings::EnumSecurityMode::Default, break; } } } } // // SMB protocol version // if (Smb4KMountSettings::useSmbProtocolVersion()) { switch (Smb4KMountSettings::smbProtocolVersion()) { case Smb4KMountSettings::EnumSmbProtocolVersion::OnePointZero: { argumentsList << "vers=1.0"; break; } case Smb4KMountSettings::EnumSmbProtocolVersion::TwoPointZero: { argumentsList << "vers=2.0"; break; } case Smb4KMountSettings::EnumSmbProtocolVersion::TwoPointOne: { argumentsList << "vers=2.1"; break; } case Smb4KMountSettings::EnumSmbProtocolVersion::ThreePointZero: { argumentsList << "vers=3.0"; break; } case Smb4KMountSettings::EnumSmbProtocolVersion::ThreePointOnePointOne: { argumentsList << "vers=3.1.1"; break; } default: { break; } } } // // Mount options provided by the user // if (!Smb4KMountSettings::customCIFSOptions().isEmpty()) { // SECURITY: Only pass those arguments to mount.cifs that do not pose // a potential security risk and that have not already been defined. // // This is, among others, the proper fix to the security issue reported // by Heiner Markert (aka CVE-2014-2581). QStringList whitelist = whitelistedMountArguments(); QStringList list = Smb4KMountSettings::customCIFSOptions().split(',', QString::SkipEmptyParts); QMutableStringListIterator it(list); while (it.hasNext()) { QString arg = it.next().section("=", 0, 0); if (!whitelist.contains(arg)) { it.remove(); } argumentsList += list; } } // // Insert the mount options into the map // QStringList mh_options; mh_options << "-o"; mh_options << argumentsList.join(","); map.insert("mh_options", mh_options); // // Insert the mountpoint into the map // map.insert("mh_mountpoint", share->canonicalPath()); // // Insert information about the share and its URL into the map // if (!share->isHomesShare()) { map.insert("mh_url", share->url()); } else { map.insert("mh_url", share->homeUrl()); map.insert("mh_homes_url", share->url()); } map.insert("mh_workgroup", share->workgroupName()); map.insert("mh_ip", share->hostIpAddress()); // // Location of the Kerberos ticket // // The path to the Kerberos ticket is stored - if it exists - in the // KRB5CCNAME environment variable. By default, the ticket is located // at /tmp/krb5cc_[uid]. So, if the environment variable does not exist, // but the cache file is there, try to use it. // if (QProcessEnvironment::systemEnvironment().contains("KRB5CCNAME")) { map.insert("mh_krb5ticket", QProcessEnvironment::systemEnvironment().value("KRB5CCNAME", "")); } else { QString ticket = QString("/tmp/krb5cc_%1").arg(KUser(KUser::UseRealUserID).userId().nativeId()); if (QFile::exists(ticket)) { map.insert("mh_krb5ticket", "FILE:"+ticket); } } return true; } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // // FreeBSD and NetBSD arguments // bool Smb4KMounter::fillMountActionArgs(const SharePtr &share, QVariantMap& map) { // // Find the mount executable // const QString mount = findMountExecutable(); if (!mount.isEmpty()) { map.insert("mh_command", mount); } else { Smb4KNotification::commandNotFound("mount_smbfs"); return false; } // // Global and custom options // QMap globalOptions = globalSambaOptions(); OptionsPtr options = Smb4KCustomOptionsManager::self()->findOptions(share); // // List of arguments // QStringList argumentsList; // // Workgroup // if (!share->workgroupName().isEmpty()) { argumentsList << "-W"; argumentsList << KShell::quoteArg(share->workgroupName()); } // // IP address // if (!share->hostIpAddress().isEmpty()) { argumentsList << "-I"; argumentsList << share->hostIpAddress(); } // // User Id // if (options) { if (options->useUser()) { argumentsList << "-u"; argumentsList << QString("%1").arg(options->user().userId().nativeId()); } } else { if (Smb4KMountSettings::useUserId()) { argumentsList << "-u"; argumentsList << QString("%1").arg((K_UID)Smb4KMountSettings::userId().toInt()); } } // // Group Id // if (options) { if (options->useGroup()) { argumentsList << "-g"; argumentsList << QString("%1").arg(options->group().groupId().nativeId()); } } else { if (Smb4KMountSettings::useGroupId()) { argumentsList << "-g"; argumentsList << QString("%1").arg((K_GID)Smb4KMountSettings::groupId().toInt()); } } if (Smb4KMountSettings::useCharacterSets()) { // Client character set QString clientCharset, serverCharset; switch (Smb4KMountSettings::clientCharset()) { case Smb4KMountSettings::EnumClientCharset::default_charset: { clientCharset = globalOptions["unix charset"].toLower(); // maybe empty break; } default: { clientCharset = Smb4KMountSettings::self()->clientCharsetItem()->choices().value(Smb4KMountSettings::clientCharset()).label; break; } } // Server character set switch (Smb4KMountSettings::serverCodepage()) { case Smb4KMountSettings::EnumServerCodepage::default_codepage: { serverCharset = globalOptions["dos charset"].toLower(); // maybe empty break; } default: { serverCharset = Smb4KMountSettings::self()->serverCodepageItem()->choices().value(Smb4KMountSettings::serverCodepage()).label; break; } } if (!clientCharset.isEmpty() && !serverCharset.isEmpty()) { argumentsList << "-E"; argumentsList << QString("%1:%2").arg(clientCharset, serverCharset); } } // // File mode // if (options) { if (options->useFileMode()) { argumentsList << "-f"; argumentsList << options->fileMode(); } } else { if (Smb4KMountSettings::useFileMode()) { argumentsList << "-f"; argumentsList << Smb4KMountSettings::fileMode(); } } // // Directory mode // if (options) { if (options->useDirectoryMode()) { argumentsList << "-d"; argumentsList << options->directoryMode(); } } else { if (Smb4KMountSettings::useDirectoryMode()) { argumentsList << "-d"; argumentsList << Smb4KMountSettings::directoryMode(); } } // // User name (login) // if (!share->login().isEmpty()) { argumentsList << "-U"; argumentsList << share->login(); } else { argumentsList << "-N"; } // // Insert the mount options into the map // map.insert("mh_options", argumentsList); // // Insert the mountpoint into the map // map.insert("mh_mountpoint", share->canonicalPath()); // // Insert information about the share and its URL into the map // if (!share->isHomesShare()) { map.insert("mh_url", share->url()); } else { map.insert("mh_url", share->homeUrl()); map.insert("mh_homes_url", share->url()); } map.insert("mh_workgroup", share->workgroupName()); map.insert("mh_ip", share->hostIpAddress()); return true; } #else // // Dummy // bool Smb4KMounter::fillMountActionArgs(const SharePtr &, QVariantMap&) { qWarning() << "Smb4KMounter::fillMountActionArgs() is not implemented!"; qWarning() << "Mounting under this operating system is not supported..."; return false; } #endif #if defined(Q_OS_LINUX) // // Linux arguments // bool Smb4KMounter::fillUnmountActionArgs(const SharePtr &share, bool force, bool silent, QVariantMap &map) { // // The umount program // const QString umount = findUmountExecutable(); if (umount.isEmpty() && !silent) { Smb4KNotification::commandNotFound("umount"); return false; } // // The options // QStringList options; if (force) { options << "-l"; // lazy unmount } // // Insert data into the map // map.insert("mh_command", umount); map.insert("mh_url", share->url()); if (Smb4KHardwareInterface::self()->isOnline()) { map.insert("mh_mountpoint", share->canonicalPath()); } else { map.insert("mh_mountpoint", share->path()); } map.insert("mh_options", options); return true; } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // // FreeBSD and NetBSD arguments // bool Smb4KMounter::fillUnmountActionArgs(const SharePtr &share, bool force, bool silent, QVariantMap &map) { // // The umount program // const QString umount = findUmountExecutable(); if (umount.isEmpty() && !silent) { Smb4KNotification::commandNotFound("umount"); return false; } // // The options // QStringList options; if (force) { options << "-f"; } // // Insert data into the map // map.insert("mh_command", umount); map.insert("mh_url", share->url()); if (Smb4KHardwareInterface::self()->isOnline()) { map.insert("mh_mountpoint", share->canonicalPath()); } else { map.insert("mh_mountpoint", share->path()); } map.insert("mh_options", options); return true; } #else // // Dummy // bool Smb4KMounter::fillUnmountActionArgs(const SharePtr &, bool, bool, QVariantMap &) { qWarning() << "Smb4KMounter::fillUnmountActionArgs() is not implemented!"; qWarning() << "Unmounting under this operating system is not supported..."; return false; } #endif void Smb4KMounter::check(const SharePtr &share) { // Get the info about the usage, etc. KDiskFreeSpaceInfo spaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(share->path()); if (spaceInfo.isValid()) { // Accessibility share->setInaccessible(false); // Size information share->setFreeDiskSpace(spaceInfo.available()); share->setTotalDiskSpace(spaceInfo.size()); share->setUsedDiskSpace(spaceInfo.used()); // Get the owner an group, if possible. QFileInfo fileInfo(share->path()); fileInfo.setCaching(false); if (fileInfo.exists()) { share->setUser(KUser(static_cast(fileInfo.ownerId()))); share->setGroup(KUserGroup(static_cast(fileInfo.groupId()))); share->setInaccessible(!(fileInfo.isDir() && fileInfo.isExecutable())); } else { share->setInaccessible(true); share->setFreeDiskSpace(0); share->setTotalDiskSpace(0); share->setUsedDiskSpace(0); share->setUser(KUser(KUser::UseRealUserID)); share->setGroup(KUserGroup(KUser::UseRealUserID)); } } else { share->setInaccessible(true); share->setFreeDiskSpace(0); share->setTotalDiskSpace(0); share->setUsedDiskSpace(0); share->setUser(KUser(KUser::UseRealUserID)); share->setGroup(KUserGroup(KUser::UseRealUserID)); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KMounter::slotStartJobs() { // // Disconnect from Smb4KHardwareInterface. // disconnect(Smb4KHardwareInterface::self(), SIGNAL(networkConfigUpdated()), this, SLOT(slotStartJobs())); // // Start the import of shares // if (Smb4KHardwareInterface::self()->isOnline()) { // // Import the mounted shares // if (!d->firstImportDone) { import(true); } // // Start the timer // if (d->timerId == -1) { d->timerId = startTimer(TIMEOUT); } } } void Smb4KMounter::slotAboutToQuit() { // // Abort any actions // abort(); // // Check if the user wants to remount shares and save the // shares for remount if so. // if (Smb4KMountSettings::remountShares()) { saveSharesForRemount(); } // // Unmount the shares if the user chose to do so. // if (Smb4KMountSettings::unmountSharesOnExit()) { unmountAllShares(true); } // // Clean up the mount prefix. // KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::BasicInfoNeeded|KMountPoint::NeedMountOptions); QDir dir; dir.cd(Smb4KMountSettings::mountPrefix().path()); QStringList hostDirs = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::NoSort); QStringList mountpoints; for (const QString &hostDir : hostDirs) { dir.cd(hostDir); QStringList shareDirs = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::NoSort); for (const QString &shareDir : shareDirs) { dir.cd(shareDir); mountpoints << dir.absolutePath(); dir.cdUp(); } dir.cdUp(); } // Remove those mountpoints where a share is actually mounted. for (const QExplicitlySharedDataPointer &mountPoint : mountPoints) { mountpoints.removeOne(mountPoint->mountPoint()); } // Remove the empty mountpoints. for (const QString &mp : mountpoints) { dir.cd(mp); dir.rmdir(dir.canonicalPath()); if (dir.cdUp()) { dir.rmdir(dir.canonicalPath()); } } } void Smb4KMounter::slotOnlineStateChanged(bool online) { if (online) { // Remount shares after the network became available (again) // If the computer awakes from a sleep state, there might still be // an unmount job in the queue. So, wait until all jobs have been // performed before starting to remount the shares. while (isRunning()) { QTest::qWait(TIMEOUT); } triggerRemounts(true); } else { // Abort all running mount jobs abort(); // Mark all mounted shares as inaccessible for (const SharePtr &share : mountedSharesList()) { share->setInaccessible(true); } // Save the shares for automatic remounting saveSharesForRemount(); // Unmount all shares unmountAllShares(true); } } void Smb4KMounter::slotStatResult(KJob *job) { Q_ASSERT(job); // // Stat job // KIO::StatJob *statJob = static_cast(job); // // Get the mountpoint // QString mountpoint = statJob->url().toDisplayString(QUrl::PreferLocalFile); // // Find the imported share // SharePtr importedShare; for (int i = 0; i < d->importedShares.size(); ++i) { if (QString::compare(d->importedShares.at(i)->path(), mountpoint) == 0) { importedShare = d->importedShares.takeAt(i); break; } else { continue; } } // // If the share should have vanished in the meantime, return here. // if (!importedShare) { return; } // // Add the size, user and group information // if (statJob->error() == 0 /* no error */) { check(importedShare); } else { importedShare->setInaccessible(true); importedShare->setFreeDiskSpace(0); importedShare->setTotalDiskSpace(0); importedShare->setUsedDiskSpace(0); importedShare->setUser(KUser(KUser::UseRealUserID)); importedShare->setGroup(KUserGroup(KUser::UseRealUserID)); } // // Decide whether this is a share mounted by the user or by someone else. // QString canonicalMountPrefix = QDir(Smb4KMountSettings::mountPrefix().path()).canonicalPath(); QString canonicalHomePath = QDir::home().canonicalPath(); if (importedShare->path().startsWith(Smb4KMountSettings::mountPrefix().path()) || importedShare->canonicalPath().startsWith(canonicalMountPrefix)) { // // The path is below the mount prefix // importedShare->setForeign(false); } else if (importedShare->path().startsWith(QDir::homePath()) || importedShare->canonicalPath().startsWith(canonicalHomePath)) { // // The path is below the home directory // importedShare->setForeign(false); } else if (importedShare->user().userId() == KUser(KUser::UseRealUserID).userId() && importedShare->group().groupId() == KUserGroup(KUser::UseRealUserID).groupId()) { // // The IDs are the same // importedShare->setForeign(false); } else { // // The path is elsewhere. This is most certainly a foreign share. // importedShare->setForeign(true); } // // Search for a previously added mounted share and try to update it. If this fails, // add the share to the global list. // if (!importedShare->isForeign() || Smb4KMountSettings::detectAllShares()) { if (updateMountedShare(importedShare)) { SharePtr updatedShare = findShareByPath(importedShare->path()); if (updatedShare) { emit updated(updatedShare); } importedShare.clear(); } else { if (addMountedShare(importedShare)) { // Remove the share from the list of shares that are to be remounted QMutableListIterator s(d->remounts); while (s.hasNext()) { SharePtr remount = s.next(); if (!importedShare->isForeign() && QString::compare(remount->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), importedShare->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { Smb4KCustomOptionsManager::self()->removeRemount(remount); s.remove(); break; } else { continue; } } // Tell the program and the user that the share was mounted. Also, reset the // counter of newly mounted shares, if necessary. d->newlyMounted += 1; emit mounted(importedShare); if (d->importedShares.isEmpty() && !d->mountShares && !d->unmountShares) { if (d->firstImportDone) { if (d->newlyMounted == 1) { Smb4KNotification::shareMounted(importedShare); } else { Smb4KNotification::sharesMounted(d->newlyMounted); } } d->newlyMounted = 0; } emit mountedSharesListChanged(); } else { importedShare.clear(); } } } else { importedShare.clear(); } if (!d->firstImportDone && d->importedShares.isEmpty()) { d->firstImportDone = true; } } void Smb4KMounter::slotAboutToChangeProfile() { // // Save those shares that are to be remounted // if (Smb4KMountSettings::remountShares()) { saveSharesForRemount(); } } void Smb4KMounter::slotActiveProfileChanged(const QString &newProfile) { if (d->activeProfile != newProfile) { // Stop the timer. killTimer(d->timerId); abort(); // Clear all remounts. while (!d->remounts.isEmpty()) { d->remounts.takeFirst().clear(); } // Clear all retries. while (!d->retries.isEmpty()) { d->retries.takeFirst().clear(); } // Unmount all shares unmountAllShares(true); // Reset some variables. d->remountTimeout = 0; d->remountAttempts = 0; d->firstImportDone = false; d->activeProfile = newProfile; // Restart the timer d->timerId = startTimer(TIMEOUT); } } void Smb4KMounter::slotProfileMigrated(const QString& from, const QString& to) { if (QString::compare(from, d->activeProfile, Qt::CaseSensitive) == 0) { d->activeProfile = to; } } void Smb4KMounter::slotTriggerImport() { // Wait until there are no jobs anymore while(isRunning()) { QTest::qWait(TIMEOUT); } // Initialize an import import(true); } void Smb4KMounter::slotConfigChanged() { if (d->detectAllShares != Smb4KMountSettings::detectAllShares()) { slotTriggerImport(); d->detectAllShares = Smb4KMountSettings::detectAllShares(); } } diff --git a/core/smb4kmounter_p.cpp b/core/smb4kmounter_p.cpp index e384c53..429a304 100644 --- a/core/smb4kmounter_p.cpp +++ b/core/smb4kmounter_p.cpp @@ -1,298 +1,294 @@ /*************************************************************************** This file contains private helper classes for the Smb4KMounter class. ------------------- begin : Do Jul 19 2007 copyright : (C) 2007-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kmounter_p.h" #include "smb4ksettings.h" #include "smb4knotification.h" #include "smb4khomesshareshandler.h" #include "smb4kglobal.h" #include "smb4kcustomoptions.h" #include "smb4kcustomoptionsmanager.h" // Qt includes #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include using namespace Smb4KGlobal; Smb4KMountDialog::Smb4KMountDialog(const SharePtr &share, QWidget *parent) : QDialog(parent), m_share(share), m_valid(true) { // // Set the title // setWindowTitle(i18n("Mount Share")); // // Set up the view // setupView(); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "MountDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 // // Fill the completion objects // m_share_input->completionObject()->setItems(group.readEntry("ShareNameCompletion", QStringList())); m_ip_input->completionObject()->setItems(group.readEntry("IPAddressCompletion", QStringList())); m_workgroup_input->completionObject()->setItems(group.readEntry("WorkgroupCompletion", QStringList())); } Smb4KMountDialog::~Smb4KMountDialog() { } void Smb4KMountDialog::setupView() { QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); QWidget *description = new QWidget(this); QHBoxLayout *desc_layout = new QHBoxLayout(description); desc_layout->setSpacing(5); QLabel *pixmap = new QLabel(description); QPixmap mount_pix = KDE::icon("view-form", QStringList("emblem-mounted")).pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(mount_pix); pixmap->setAlignment(Qt::AlignBottom); QLabel *label = new QLabel(i18n("Enter the location and optionally the IP address and workgroup to mount a share."), description); label->setWordWrap(true); label->setAlignment(Qt::AlignBottom); desc_layout->addWidget(pixmap, 0); desc_layout->addWidget(label, Qt::AlignBottom); QWidget *edit_widget = new QWidget(this); QGridLayout *edit_layout = new QGridLayout(edit_widget); layout->setSpacing(5); QLabel *shareLabel = new QLabel(i18n("Location:"), edit_widget); m_share_input = new KLineEdit(edit_widget); m_share_input->setWhatsThis(i18n("The location of the share is provided by the Uniform Resource Locator (URL). It generally has the following syntax: " "[smb:]//[USER:PASSWORD@]HOST:PORT/SHARE. The username, password and port are optional. You should omit to enter the password here, because it is shown in cleartext.")); // m_share_input->setToolTip(i18n("The URL of the share")); m_share_input->setCompletionMode(KCompletion::CompletionPopupAuto); m_share_input->setClearButtonEnabled(true); m_share_input->setMinimumWidth(200); m_share_input->setFocus(); QLabel *addressLabel = new QLabel(i18n("IP Address:"), edit_widget); m_ip_input = new KLineEdit(edit_widget); m_ip_input->setWhatsThis(i18n("The Internet Protocol (IP) address identifies the " "host in the network and indicates where it is. It has two valid formats, the one " "known as IP version 4 (e.g. 192.168.2.11) and the version 6 format " "(e.g. 2001:0db8:85a3:08d3:1319:8a2e:0370:7334).")); // m_ip_input->setToolTip(i18n("The IP address of the host where the share is located")); m_ip_input->setCompletionMode(KCompletion::CompletionPopupAuto); m_ip_input->setClearButtonEnabled(true); m_ip_input->setMinimumWidth(200); QLabel *workgroupLabel = new QLabel(i18n("Workgroup:"), edit_widget); m_workgroup_input = new KLineEdit(edit_widget); m_workgroup_input->setWhatsThis(i18n("The workgroup or domain identifies the " "peer-to-peer computer network the host is located in.")); // m_workgroup_input->setToolTip(i18n("The workgroup where the host is located")); m_workgroup_input->setCompletionMode(KCompletion::CompletionPopupAuto); m_workgroup_input->setClearButtonEnabled(true); m_workgroup_input->setMinimumWidth(200); edit_layout->addWidget(shareLabel, 0, 0, 0); edit_layout->addWidget(m_share_input, 0, 1, 0); edit_layout->addWidget(addressLabel, 1, 0, 0); edit_layout->addWidget(m_ip_input, 1, 1, 0); edit_layout->addWidget(workgroupLabel, 2, 0, 0); edit_layout->addWidget(m_workgroup_input, 2, 1, 0); m_bookmark = new QCheckBox(i18n("Add this share to the bookmarks"), this); m_bookmark->setWhatsThis(i18n("If you tick this checkbox, the share will be bookmarked " "and you can access it e.g. through the \"Bookmarks\" menu entry in the main window.")); // m_bookmark->setToolTip(i18n("Add this share to the bookmarks")); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_ok_button = buttonBox->addButton(QDialogButtonBox::Ok); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_ok_button->setShortcut(Qt::CTRL|Qt::Key_Return); m_cancel_button->setShortcut(Qt::Key_Escape); layout->addWidget(description, Qt::AlignBottom); layout->addWidget(edit_widget, 0); layout->addWidget(m_bookmark, 0); layout->addWidget(buttonBox, 0); slotChangeInputValue(m_share_input->text()); // // Connections // connect(m_share_input, SIGNAL(textChanged(QString)), this, SLOT(slotChangeInputValue(QString))); connect(m_share_input, SIGNAL(editingFinished()), this, SLOT(slotShareNameEntered())); connect(m_ip_input, SIGNAL(editingFinished()), this, SLOT(slotIPEntered())); connect(m_workgroup_input, SIGNAL(editingFinished()), this, SLOT(slotWorkgroupEntered())); connect(m_ok_button, SIGNAL(clicked()), this, SLOT(slotOkClicked())); connect(m_cancel_button, SIGNAL(clicked()), this, SLOT(slotCancelClicked())); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KMountDialog::slotChangeInputValue(const QString& _test) { m_ok_button->setEnabled(!_test.isEmpty()); } void Smb4KMountDialog::slotOkClicked() { if (!m_share_input->text().trimmed().isEmpty()) { // // Get the URL // QString userInput = m_share_input->text().trimmed(); // // Take care of a Windows-like UNC addresses // if (userInput.startsWith(QLatin1String("\\"))) { userInput.replace("\\", "/"); } // // Set the URL and adjust the scheme // QUrl smbUrl = QUrl::fromUserInput(userInput); smbUrl.setScheme("smb"); // // Set the URL of the share // if (smbUrl.isValid() && !smbUrl.host().isEmpty() && !smbUrl.path().isEmpty() && !smbUrl.path().endsWith(QLatin1String("/"))) { m_share->setUrl(smbUrl); m_share->setWorkgroupName(m_workgroup_input->text().trimmed()); m_share->setHostIpAddress(m_ip_input->text().trimmed()); } else { Smb4KNotification::invalidURLPassed(); m_valid = false; } } KConfigGroup group(Smb4KSettings::self()->config(), "MountDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); group.writeEntry("ShareNameCompletion", m_share_input->completionObject()->items()); group.writeEntry("IPAddressCompletion", m_ip_input->completionObject()->items()); group.writeEntry("WorkgroupCompletion", m_workgroup_input->completionObject()->items()); accept(); } void Smb4KMountDialog::slotCancelClicked() { Smb4KMounter::self()->abort(); reject(); } void Smb4KMountDialog::slotShareNameEntered() { KCompletion *completion = m_share_input->completionObject(); QUrl url(m_share_input->userText()); url.setScheme("smb"); if (url.isValid() && !url.isEmpty()) { completion->addItem(m_share_input->userText()); } } void Smb4KMountDialog::slotIPEntered() { KCompletion *completion = m_ip_input->completionObject(); if (!m_ip_input->userText().isEmpty()) { completion->addItem(m_ip_input->userText()); } } void Smb4KMountDialog::slotWorkgroupEntered() { KCompletion *completion = m_workgroup_input->completionObject(); if (!m_workgroup_input->userText().isEmpty()) { completion->addItem(m_workgroup_input->userText()); } } diff --git a/core/smb4knotification.cpp b/core/smb4knotification.cpp index 27975e9..e233598 100644 --- a/core/smb4knotification.cpp +++ b/core/smb4knotification.cpp @@ -1,489 +1,485 @@ /*************************************************************************** This class provides notifications for Smb4K. ------------------- begin : Son Jun 27 2010 copyright : (C) 2010-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knotification.h" #include "smb4knotification_p.h" #include "smb4ksettings.h" #include "smb4kbookmark.h" #include "smb4kworkgroup.h" #include "smb4khost.h" #include "smb4kshare.h" // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include #include #include "kiconthemes_version.h" using namespace KAuth; // // Notifications // void Smb4KNotification::shareMounted(const SharePtr &share) { Q_ASSERT(share); if (share) { QUrl mountpoint = QUrl::fromLocalFile(share->path()); Smb4KNotifier *notification = new Smb4KNotifier("shareMounted"); notification->setText(i18n("

The share %1 has been mounted to %2.

", share->displayString(), share->path())); #if KICONTHEMES_VERSION < QT_VERSION_CHECK(5,52,0) notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList("emblem-mounted"))); #else notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList({"","emblem-mounted"}))); #endif notification->setActions(QStringList(i18n("Open"))); notification->setMountpoint(mountpoint); notification->sendEvent(); } } void Smb4KNotification::shareUnmounted(const SharePtr &share) { Q_ASSERT(share); if (share) { Smb4KNotifier *notification = new Smb4KNotifier("shareUnmounted"); notification->setText(i18n("

The share %1 has been unmounted from %2.

", share->displayString(), share->path())); #if KICONTHEMES_VERSION < QT_VERSION_CHECK(5,52,0) notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList("emblem-unmounted"))); #else notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList({"","emblem-unmounted"}))); #endif notification->sendEvent(); } } void Smb4KNotification::sharesMounted(int number) { Smb4KNotifier *notification = new Smb4KNotifier("sharesMounted"); notification->setText(i18np("

%1 share has been mounted.

", "

%1 shares have been mounted.

", number)); notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList("emblem-mounted"))); notification->sendEvent(); } void Smb4KNotification::sharesUnmounted(int number) { Smb4KNotifier *notification = new Smb4KNotifier("sharesUnmounted"); notification->setText(i18np("

%1 share has been unmounted.

", "

%1 shares have been unmounted.

", number)); notification->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::NoGroup, 0, KIconLoader::DefaultState, QStringList("emblem-unmounted"))); notification->sendEvent(); } // // Warnings // void Smb4KNotification::openingWalletFailed(const QString& name) { Smb4KNotifier *notification = new Smb4KNotifier("openingWalletFailed"); notification->setText(i18n("

Opening the wallet %1 failed.

", name)); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::credentialsNotAccessible() { Smb4KNotifier *notification = new Smb4KNotifier("credentialsNotAccessible"); notification->setText(i18n("

The credentials stored in the wallet could not be accessed. " "There is either no wallet available or it could not be opened.

")); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::mimetypeNotSupported(const QString& mimetype) { Smb4KNotifier *notification = new Smb4KNotifier("mimetypeNotSupported"); notification->setText(i18n("

The mimetype %1 is not supported for printing. " "Please convert the file to PDF or Postscript and try again.

", mimetype)); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::bookmarkExists(Smb4KBookmark* bookmark) { if (bookmark) { Smb4KNotifier *notification = new Smb4KNotifier("bookmarkExists"); notification->setText(i18n("

The bookmark for share %1 already exists and will be skipped.

", bookmark->displayString())); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::bookmarkLabelInUse(Smb4KBookmark* bookmark) { if (bookmark) { Smb4KNotifier *notification = new Smb4KNotifier("bookmarkLabelInUse"); notification->setText(i18n("

The label %1 of the bookmark for the share %2 " "is already being used and will automatically be renamed.

", bookmark->label(), bookmark->displayString())); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::sambaConfigFileMissing() { Smb4KNotifier *notification = new Smb4KNotifier("sambaConfigFileMissing"); notification->setText(i18n("The configuration file for the Samba suite smb.conf is missing. This is not " "a fatal error, but you should consider creating one.")); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-warning", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } // // Errors // void Smb4KNotification::mountingFailed(const SharePtr &share, const QString& err_msg) { if (share) { QString text; if (!err_msg.isEmpty()) { text = i18n("

Mounting the share %1 failed:

%2

", share->displayString(), err_msg); } else { text = i18n("

Mounting the share %1 failed.

", share->displayString()); } Smb4KNotifier *notification = new Smb4KNotifier("mountingFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::unmountingFailed(const SharePtr &share, const QString& err_msg) { if (share) { QString text; if (!err_msg.isEmpty()) { text = i18n("

Unmounting the share %1 from %2 failed:

%3

", share->displayString(), share->path(), err_msg); } else { text = i18n("

Unmounting the share %1 from %2 failed.

", share->displayString(), share->path()); } Smb4KNotifier *notification = new Smb4KNotifier("unmountingFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::unmountingNotAllowed(const SharePtr &share) { Q_ASSERT(share); if (share) { Smb4KNotifier *notification = new Smb4KNotifier("unmountingNotAllowed"); notification->setText(i18n("

You are not allowed to unmount the share %1 from %2. " "It is owned by the user %3.

", share->displayString(), share->path(), share->user().loginName())); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::synchronizationFailed(const QUrl& src, const QUrl& dest, const QString& err_msg) { QString text; if (!err_msg.isEmpty()) { text = i18n("

Synchronizing %1 with %2 failed:

%3

", dest.path(), src.path(), err_msg); } else { text = i18n("

Synchronizing %1 with %2 failed.

", dest.path(), src.path()); } Smb4KNotifier *notification = new Smb4KNotifier("synchronizationFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::commandNotFound(const QString& command) { Smb4KNotifier *notification = new Smb4KNotifier("commandNotFound"); notification->setText(i18n("

The command %1 could not be found. Please check your installation.

", command)); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::cannotBookmarkPrinter(const SharePtr &share) { if (share && share->isPrinter()) { Smb4KNotifier *notification = new Smb4KNotifier("cannotBookmarkPrinter"); notification->setText(i18n("

The share %1 is a printer and cannot be bookmarked.

", share->displayString())); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } } void Smb4KNotification::fileNotFound(const QString& fileName) { Smb4KNotifier *notification = new Smb4KNotifier("fileNotFound"); notification->setText(i18n("

The file %1 could not be found.

", fileName)); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::openingFileFailed(const QFile& file) { QString text; if (!file.errorString().isEmpty()) { text = i18n("

Opening the file %1 failed:

%2

", file.fileName(), file.errorString()); } else { text = i18n("

Opening the file %1 failed.

", file.fileName()); } Smb4KNotifier *notification = new Smb4KNotifier("openingFileFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::readingFileFailed(const QFile& file, const QString& err_msg) { QString text; if (!err_msg.isEmpty()) { text = i18n("

Reading from file %1 failed:

%2

", file.fileName(), err_msg); } else { if (!file.errorString().isEmpty()) { text = i18n("

Reading from file %1 failed:

%2

", file.fileName(), file.errorString()); } else { text = i18n("

Reading from file %1 failed.

", file.fileName()); } } Smb4KNotifier *notification = new Smb4KNotifier("readingFileFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::mkdirFailed(const QDir& dir) { Smb4KNotifier *notification = new Smb4KNotifier("mkdirFailed"); notification->setText(i18n("

The following directory could not be created:

%1

", dir.absolutePath())); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::processError(QProcess::ProcessError error) { QString text; switch (error) { case QProcess::FailedToStart: { text = i18n("

The process failed to start (error code: %1).

", error); break; } case QProcess::Crashed: { text = i18n("

The process crashed (error code: %1).

", error); break; } case QProcess::Timedout: { text = i18n("

The process timed out (error code: %1).

", error); break; } case QProcess::WriteError: { text = i18n("

Could not write to the process (error code: %1).

", error); break; } case QProcess::ReadError: { text = i18n("

Could not read from the process (error code: %1).

", error); break; } case QProcess::UnknownError: default: { text = i18n("

The process reported an unknown error.

"); break; } } Smb4KNotifier *notification = new Smb4KNotifier("processError"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::actionFailed(int err_code) { QString text, err_msg; switch (err_code) { case ActionReply::NoResponderError: { err_msg = "NoResponderError"; break; } case ActionReply::NoSuchActionError: { err_msg = "NoSuchActionError"; break; } case ActionReply::InvalidActionError: { err_msg = "InvalidActionError"; break; } case ActionReply::AuthorizationDeniedError: { err_msg = "AuthorizationDeniedError"; break; } case ActionReply::UserCancelledError: { err_msg = "UserCancelledError"; break; } case ActionReply::HelperBusyError: { err_msg = "HelperBusyError"; break; } case ActionReply::AlreadyStartedError: { err_msg = "AlreadyStartedError"; break; } case ActionReply::DBusError: { err_msg = "DBusError"; break; } case ActionReply::BackendError: { err_msg = "BackendError"; break; } default: { break; } } if (!err_msg.isEmpty()) { text = i18n("

Executing an action with root privileges failed (error code: %1).

", err_msg); } else { text = i18n("

Executing an action with root privileges failed.

"); } Smb4KNotifier *notification = new Smb4KNotifier("actionFailed"); notification->setText(text); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::invalidURLPassed() { Smb4KNotifier *notification = new Smb4KNotifier("invalidURL"); notification->setText(i18n("

The URL that was passed is invalid.

")); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } void Smb4KNotification::networkCommunicationFailed(const QString& errorMessage) { Smb4KNotifier *notification = new Smb4KNotifier("networkCommunicationFailed"); notification->setText(i18n("The network communication failed with the following error message: %1", errorMessage)); notification->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::NoGroup, 0, KIconLoader::DefaultState)); notification->sendEvent(); } diff --git a/core/smb4kprofilemanager.cpp b/core/smb4kprofilemanager.cpp index f11d49c..8f5bd62 100644 --- a/core/smb4kprofilemanager.cpp +++ b/core/smb4kprofilemanager.cpp @@ -1,345 +1,341 @@ /*************************************************************************** This class manages the profiles that were defined by the user. ------------------- begin : Mi Aug 06 2014 copyright : (C) 2014-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kprofilemanager.h" #include "smb4kprofilemanager_p.h" #include "smb4ksettings.h" #include "smb4khomesshareshandler.h" #include "smb4kcustomoptionsmanager.h" #include "smb4kbookmarkhandler.h" // Qt includes #include #include #include Q_GLOBAL_STATIC(Smb4KProfileManagerStatic, p); // // NOTE: Do not invoke writeConfig() here, because this will/might // trigger the configChanged() signal which can lead to unwanted // effects. // Smb4KProfileManager::Smb4KProfileManager(QObject* parent) : QObject(parent), d(new Smb4KProfileManagerPrivate) { d->useProfiles = Smb4KSettings::useProfiles(); if (d->useProfiles) { d->profiles = Smb4KSettings::profilesList(); d->activeProfile = !Smb4KSettings::activeProfile().isEmpty() ? Smb4KSettings::activeProfile() : d->profiles.first(); } else { d->profiles.clear(); d->activeProfile.clear(); } connect(Smb4KSettings::self(), SIGNAL(configChanged()), this, SLOT(slotConfigChanged())); } Smb4KProfileManager::~Smb4KProfileManager() { } Smb4KProfileManager* Smb4KProfileManager::self() { return &p->instance; } void Smb4KProfileManager::setActiveProfile(const QString& name) { // // Check if the active profile is going to be changed. If so, // notify the program so that things can be done before the // profile is actually changed. // bool change = false; if (d->useProfiles) { if (name != d->activeProfile) { emit aboutToChangeProfile(); change = true; } } else { if (!d->activeProfile.isEmpty()) { emit aboutToChangeProfile(); change = true; } } // // Now change the profile // if (change) { d->activeProfile = d->useProfiles ? name : QString(); Smb4KSettings::setActiveProfile(d->activeProfile); emit activeProfileChanged(d->activeProfile); } } QString Smb4KProfileManager::activeProfile() const { return d->activeProfile; } QStringList Smb4KProfileManager::profilesList() const { return d->useProfiles ? d->profiles : QStringList(); } bool Smb4KProfileManager::useProfiles() const { return d->useProfiles; } void Smb4KProfileManager::migrateProfile(const QString& from, const QString& to) { QList> list; list << QPair(from, to); migrateProfiles(list); } void Smb4KProfileManager::migrateProfiles(const QList>& list) { if (d->useProfiles || (list.size() == 1 && list.first().second.isEmpty())) { for (int i = 0; i < list.size(); ++i) { QString from = list.at(i).first; QString to = list.at(i).second; if (!to.isEmpty()) { // Migrate one/the default profile to another one. // First exchange the old profile. for (int j = 0; j < d->profiles.size(); ++j) { if (QString::compare(from, d->profiles.at(j), Qt::CaseSensitive) == 0) { d->profiles.replace(j, to); break; } } // Migrate profiles. Smb4KBookmarkHandler::self()->migrateProfile(from, to); Smb4KCustomOptionsManager::self()->migrateProfile(from, to); Smb4KHomesSharesHandler::self()->migrateProfile(from, to); emit migratedProfile(from, to); // In case the active profile was modified, rename it according // the value passed. if (QString::compare(from, d->activeProfile, Qt::CaseSensitive) == 0) { setActiveProfile(to); } } else { // Migrate all profiles to the default one. for (int j = 0; j < d->profiles.size(); ++j) { Smb4KBookmarkHandler::self()->migrateProfile(d->profiles.at(j), to); Smb4KCustomOptionsManager::self()->migrateProfile(d->profiles.at(j), to); Smb4KHomesSharesHandler::self()->migrateProfile(d->profiles.at(j), to); emit migratedProfile(d->profiles.at(i), to); } } } Smb4KSettings::setProfilesList(d->profiles); emit profilesListChanged(d->profiles); } } void Smb4KProfileManager::removeProfile(const QString& name) { QStringList list; list << name; removeProfiles(list); } void Smb4KProfileManager::removeProfiles(const QStringList& list) { if (d->useProfiles) { for (int i = 0; i < list.size(); ++i) { QString name = list.at(i); // First remove the profile from the list. QMutableStringListIterator it(d->profiles); while (it.hasNext()) { QString entry = it.next(); if (QString::compare(name, entry, Qt::CaseSensitive) == 0) { it.remove(); break; } } if (!d->profiles.isEmpty()) { // Ask the user if he/she wants to migrate the entries // of the removed profile to another one. if (Smb4KSettings::useMigrationAssistant()) { QPointer dlg = new Smb4KProfileMigrationDialog(QStringList(name), d->profiles, QApplication::activeWindow()); if (dlg->exec() == QDialog::Accepted) { migrateProfile(dlg->from(), dlg->to()); } delete dlg; } } // Remove the profile. Smb4KBookmarkHandler::self()->removeProfile(name); Smb4KCustomOptionsManager::self()->removeProfile(name); Smb4KHomesSharesHandler::self()->removeProfile(name); emit removedProfile(name); // Set a new active profile if the user removed the current one. if (QString::compare(name, d->activeProfile, Qt::CaseSensitive) == 0) { setActiveProfile(!d->profiles.isEmpty() ? d->profiles.first() : QString()); } } Smb4KSettings::setProfilesList(d->profiles); emit profilesListChanged(d->profiles); } } void Smb4KProfileManager::slotConfigChanged() { bool usageChanged = false; // // Check if the usage of profiles changed // if (d->useProfiles != Smb4KSettings::useProfiles()) { d->useProfiles = Smb4KSettings::useProfiles(); emit profileUsageChanged(d->useProfiles); usageChanged = true; } // // Updated the list of profiles // if (d->profiles != Smb4KSettings::profilesList()) { d->profiles = Smb4KSettings::profilesList(); emit profilesListChanged(d->profiles); } // // Migrate profiles. // Profiles are only migrated, if the usage changed and the // user chose to use the migration assistant. // if (usageChanged && Smb4KSettings::useMigrationAssistant()) { QStringList from, to; if (d->useProfiles) { // Since the setting changed, the use of profiles was // switched off before. So, ask the user if he/she wants // to migrate the default profile to any other one. // Therefore, from needs to get one empty entry (default // profile) and to has to be d->profiles. from << QString(); to << d->profiles; } else { // Here it is vice versa: Ask the user if he/she wants to // migrate all profiles to the default profile. Therefore, // set from to d->profiles and to to empty. from << d->profiles; to << QString(); } // Now, launch the migration dialog. QPointer dlg = new Smb4KProfileMigrationDialog(from, to, QApplication::activeWindow()); if (dlg->exec() == QDialog::Accepted) { migrateProfile(dlg->from(), dlg->to()); } delete dlg; } // // Set the active profile // if (!Smb4KSettings::activeProfile().isEmpty() && d->profiles.contains(Smb4KSettings::activeProfile())) { setActiveProfile(Smb4KSettings::activeProfile()); } else { setActiveProfile(d->profiles.first()); } } diff --git a/core/smb4kprofilemanager_p.cpp b/core/smb4kprofilemanager_p.cpp index 372cd25..effbd7c 100644 --- a/core/smb4kprofilemanager_p.cpp +++ b/core/smb4kprofilemanager_p.cpp @@ -1,217 +1,213 @@ /*************************************************************************** Private helper class(es) for the profile manager. ------------------- begin : Mi Aug 12 2014 copyright : (C) 2014-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kprofilemanager_p.h" #include "smb4ksettings.h" // Qt includes #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include Smb4KProfileMigrationDialog::Smb4KProfileMigrationDialog(const QStringList& from, const QStringList& to, QWidget* parent) : QDialog(parent), m_from_list(from), m_to_list(to) { // // Set the window title // setWindowTitle(i18n("Profile Migration Assistant")); // // Setup the view // setupView(); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "ProfileMigrationDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 } Smb4KProfileMigrationDialog::~Smb4KProfileMigrationDialog() { } void Smb4KProfileMigrationDialog::setupView() { // // The layout // QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); // // The description // QWidget *description = new QWidget(this); QHBoxLayout *desc_layout = new QHBoxLayout(description); desc_layout->setSpacing(5); desc_layout->setMargin(0); QLabel *pixmap = new QLabel(description); QPixmap pix = KDE::icon("format-list-unordered").pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(pix); pixmap->setAlignment(Qt::AlignBottom); QLabel *label = new QLabel(i18n("Migrate all relevant settings of one profile to another.")); label->setWordWrap(true); label->setAlignment(Qt::AlignBottom); desc_layout->addWidget(pixmap, 0); desc_layout->addWidget(label, Qt::AlignBottom); // // The input widgets // QWidget *editors = new QWidget(this); QGridLayout *editors_layout = new QGridLayout(editors); editors_layout->setSpacing(5); editors_layout->setMargin(0); editors_layout->setColumnStretch(0, 0); editors_layout->setColumnStretch(1, 1); QLabel *from = new QLabel(i18n("Old Profile:"), editors); editors_layout->addWidget(from, 0, 0, 0); m_from_box = new KComboBox(editors); if (m_from_list.size() == 1 && m_from_list.first().isEmpty()) { m_from_box->addItem(i18n("")); } else { if (m_to_list.size() == 1 && m_to_list.first().isEmpty()) { m_from_box->addItem(i18n("")); } else { m_from_box->addItems(m_from_list); } } editors_layout->addWidget(m_from_box, 0, 1, 0); QLabel *to = new QLabel(i18n("New Profile:"), editors); editors_layout->addWidget(to, 1, 0, 0); m_to_box = new KComboBox(editors); if (m_to_list.size() == 1 && m_to_list.first().isEmpty()) { m_to_box->addItem(i18n("")); } else { m_to_box->addItems(m_to_list); m_to_box->setCurrentText(Smb4KProfileManager::self()->activeProfile()); } editors_layout->addWidget(m_to_box, 1, 1, 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_ok_button = buttonBox->addButton(QDialogButtonBox::Ok); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_ok_button->setShortcut(Qt::CTRL|Qt::Key_Return); m_cancel_button->setShortcut(Qt::Key_Escape); m_ok_button->setDefault(true); m_ok_button->setEnabled(!m_to_box->currentText().isEmpty()); layout->addWidget(description, 0); layout->addWidget(editors, 0); layout->addWidget(buttonBox, 0); connect(m_ok_button, SIGNAL(clicked()), this, SLOT(slotOkClicked())); connect(m_cancel_button, SIGNAL(clicked()), this, SLOT(reject())); } QString Smb4KProfileMigrationDialog::from() const { if (m_from_box->currentText() == i18n("")) { return QString(); } return m_from_box->currentText(); } QString Smb4KProfileMigrationDialog::to() const { if (m_to_box->currentText() == i18n("")) { return QString(); } return m_to_box->currentText(); } void Smb4KProfileMigrationDialog::slotOkClicked() { KConfigGroup group(Smb4KSettings::self()->config(), "ProfileMigrationDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); accept(); } diff --git a/core/smb4kshare.cpp b/core/smb4kshare.cpp index 40164a1..e17dafb 100644 --- a/core/smb4kshare.cpp +++ b/core/smb4kshare.cpp @@ -1,699 +1,695 @@ /*************************************************************************** Smb4K's container class for information about a share. ------------------- begin : Mo Jan 28 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kshare.h" #include "smb4kauthinfo.h" // Qt include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include #include #include "kiconthemes_version.h" class Smb4KSharePrivate { public: QString workgroup; QString comment; QHostAddress ip; QString path; bool inaccessible; bool foreign; KUser user; KUserGroup group; qulonglong totalSpace; qulonglong freeSpace; qulonglong usedSpace; bool mounted; QString filesystem; Smb4KGlobal::ShareType shareType; }; Smb4KShare::Smb4KShare(const QString &host, const QString &name) : Smb4KBasicNetworkItem(Share), d(new Smb4KSharePrivate) { d->inaccessible = false; d->foreign = false; d->filesystem = QString(); d->user = KUser(KUser::UseRealUserID); d->group = KUserGroup(KUser::UseRealUserID); d->totalSpace = -1; d->freeSpace = -1; d->usedSpace = -1; d->mounted = false; d->shareType = FileShare; setHostName(host); setShareName(name); setShareIcon(); } Smb4KShare::Smb4KShare(const QUrl &url) : Smb4KBasicNetworkItem(Share), d(new Smb4KSharePrivate) { // // Set the private variables // d->inaccessible = false; d->foreign = false; d->filesystem = QString(); d->user = KUser(KUser::UseRealUserID); d->group = KUserGroup(KUser::UseRealUserID); d->totalSpace = -1; d->freeSpace = -1; d->usedSpace = -1; d->mounted = false; d->shareType = FileShare; // // Set the URL // *pUrl = url; // // Set the icon // setShareIcon(); } Smb4KShare::Smb4KShare(const Smb4KShare &s) : Smb4KBasicNetworkItem(Share), d(new Smb4KSharePrivate) { // // Copy the private variables // *d = *s.d; // // Set the icon if necessary // if (pIcon->isNull()) { setShareIcon(); } } Smb4KShare::Smb4KShare() : Smb4KBasicNetworkItem(Share), d(new Smb4KSharePrivate) { // // Set the private variables // d->inaccessible = false; d->foreign = false; d->filesystem = QString(); d->user = KUser(KUser::UseRealUserID); d->group = KUserGroup(KUser::UseRealUserID); d->totalSpace = -1; d->freeSpace = -1; d->usedSpace = -1; d->mounted = false; d->shareType = FileShare; // // Set the URL // pUrl->setScheme("smb"); // // Set the icon // setShareIcon(); } Smb4KShare::~Smb4KShare() { } void Smb4KShare::setShareName(const QString &name) { if (name.startsWith('/')) { pUrl->setPath(name.trimmed()); } else { pUrl->setPath('/'+name.trimmed()); } pUrl->setScheme("smb"); } QString Smb4KShare::shareName() const { return pUrl->path().remove('/'); } void Smb4KShare::setHostName(const QString &hostName) { pUrl->setHost(hostName.trimmed()); pUrl->setScheme("smb"); } QString Smb4KShare::hostName() const { return pUrl->host().toUpper(); } QUrl Smb4KShare::homeUrl() const { QUrl u; if (isHomesShare() && !pUrl->userName().isEmpty()) { u = *pUrl; u.setPath('/'+pUrl->userName(), QUrl::TolerantMode); } return u; } QString Smb4KShare::displayString(bool showHomesShare) const { if (showHomesShare && isHomesShare()) { return i18n("%1 on %2", homeUrl().path().remove('/'), hostName()); } return i18n("%1 on %2", shareName(), hostName()); } void Smb4KShare::setWorkgroupName(const QString &workgroup) { d->workgroup = workgroup; } QString Smb4KShare::workgroupName() const { return d->workgroup; } void Smb4KShare::setShareType(Smb4KGlobal::ShareType type) { d->shareType = type; setShareIcon(); } Smb4KGlobal::ShareType Smb4KShare::shareType() const { return d->shareType; } QString Smb4KShare::shareTypeString() const { QString typeString; switch (d->shareType) { case FileShare: { typeString = i18n("Disk"); break; } case PrinterShare: { typeString = i18n("Printer"); break; } case IpcShare: { typeString = i18n("IPC"); break; } default: { break; } } return typeString; } void Smb4KShare::setComment(const QString &comment) { d->comment = comment; } QString Smb4KShare::comment() const { return d->comment; } void Smb4KShare::setHostIpAddress(const QString &ip) { d->ip.setAddress(ip); } void Smb4KShare::setHostIpAddress(const QHostAddress& address) { if (!address.isNull() && address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { d->ip = address; } } QString Smb4KShare::hostIpAddress() const { return d->ip.toString(); } bool Smb4KShare::hasHostIpAddress() const { return !d->ip.isNull(); } bool Smb4KShare::isHidden() const { return pUrl->path().endsWith('$'); } bool Smb4KShare::isPrinter() const { return (d->shareType == PrinterShare); } void Smb4KShare::setPath(const QString &mountpoint) { d->path = mountpoint; } QString Smb4KShare::path() const { return d->path; } QString Smb4KShare::canonicalPath() const { return (d->inaccessible ? d->path : QDir(d->path).canonicalPath()); } void Smb4KShare::setInaccessible(bool in) { d->inaccessible = in; setShareIcon(); } bool Smb4KShare::isInaccessible() const { return (d->mounted && d->inaccessible); } void Smb4KShare::setForeign(bool foreign) { d->foreign = foreign; setShareIcon(); } bool Smb4KShare::isForeign() const { return (d->mounted && d->foreign); } QString Smb4KShare::fileSystemString() const { if (!path().isEmpty() && d->filesystem.isEmpty()) { KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(path()); d->filesystem = mp->mountType().toUpper(); } return d->filesystem; } void Smb4KShare::setUser(const KUser &user) { d->user = user; } KUser Smb4KShare::user() const { return d->user; } void Smb4KShare::setGroup(const KUserGroup &group) { d->group = group; } KUserGroup Smb4KShare::group() const { return d->group; } void Smb4KShare::setMounted(bool mounted) { if (!isPrinter()) { d->mounted = mounted; setShareIcon(); } } bool Smb4KShare::isMounted() const { return d->mounted; } void Smb4KShare::setTotalDiskSpace(qulonglong size) { d->totalSpace = size; } qulonglong Smb4KShare::totalDiskSpace() const { return d->totalSpace; } QString Smb4KShare::totalDiskSpaceString() const { return KIO::convertSize(d->totalSpace); } void Smb4KShare::setFreeDiskSpace(qulonglong size) { d->freeSpace = size; } qulonglong Smb4KShare::freeDiskSpace() const { return d->freeSpace; } QString Smb4KShare::freeDiskSpaceString() const { return KIO::convertSize(d->freeSpace); } void Smb4KShare::setUsedDiskSpace(qulonglong size) { d->usedSpace = size; } qulonglong Smb4KShare::usedDiskSpace() const { return d->usedSpace; } QString Smb4KShare::usedDiskSpaceString() const { return KIO::convertSize(d->usedSpace); } qreal Smb4KShare::diskUsage() const { qreal used(usedDiskSpace()); qreal total(totalDiskSpace()); if (total > 0) { return used * 100 / total; } return 0; } QString Smb4KShare::diskUsageString() const { return QString("%1 %").arg(diskUsage(), 0, 'f', 1); } void Smb4KShare::setMountData(Smb4KShare *share) { Q_ASSERT(share); if (QString::compare(url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 && (share->workgroupName().isEmpty() || QString::compare(workgroupName(), share->workgroupName(), Qt::CaseInsensitive) == 0)) { d->path = share->path(); d->inaccessible = share->isInaccessible(); d->foreign = share->isForeign(); d->user = share->user(); d->group = share->group(); d->totalSpace = share->totalDiskSpace(); d->freeSpace = share->freeDiskSpace(); d->usedSpace = share->usedDiskSpace(); d->mounted = share->isMounted(); d->shareType = share->shareType(); setShareIcon(); } } void Smb4KShare::resetMountData() { d->path.clear(); d->inaccessible = false; d->foreign = false; d->user = KUser(KUser::UseRealUserID); d->group = KUserGroup(KUser::UseRealUserID); d->totalSpace = -1; d->freeSpace = -1; d->usedSpace = -1; d->mounted = false; d->shareType = FileShare; setShareIcon(); } bool Smb4KShare::isHomesShare() const { return pUrl->path().endsWith(QLatin1String("homes")); } void Smb4KShare::setPort(int port) { pUrl->setPort(port); } int Smb4KShare::port() const { return pUrl->port(); } void Smb4KShare::setAuthInfo(Smb4KAuthInfo *authInfo) { // Avoid that the login is overwritten with an empty // string if we have a homes share. if (!isHomesShare() || !authInfo->userName().isEmpty()) { pUrl->setUserName(authInfo->userName()); pUrl->setPassword(authInfo->password()); } } void Smb4KShare::setLogin(const QString &login) { // Avoid that the login is overwritten with an empty // string if we have a homes share. if (!isHomesShare() || !login.isEmpty()) { pUrl->setUserName(login); } } QString Smb4KShare::login() const { return pUrl->userName(); } void Smb4KShare::setPassword(const QString &passwd) { // Avoid that the password is overwritten with an empty // string if we have a homes share. if (!isHomesShare() || !passwd.isEmpty()) { pUrl->setPassword(passwd); } } QString Smb4KShare::password() const { return pUrl->password(); } #if KICONTHEMES_VERSION < QT_VERSION_CHECK(5,52,0) void Smb4KShare::setShareIcon() { if (!isPrinter()) { // Overlays QStringList overlays; if (isMounted()) { overlays << "emblem-mounted"; } else { overlays << ""; } if (isForeign()) { overlays << "emblem-warning"; } if (!isInaccessible()) { *pIcon = KDE::icon("folder-network", overlays); } else { *pIcon = KDE::icon("folder-locked", overlays); } } else { *pIcon = KDE::icon("printer"); } } #else void Smb4KShare::setShareIcon() { if (!isPrinter()) { // Overlays QStringList overlays; if (isMounted()) { if (isForeign()) { overlays << "emblem-warning"; } else { overlays << ""; } overlays << "emblem-mounted"; } if (!isInaccessible()) { *pIcon = KDE::icon("folder-network", overlays); } else { *pIcon = KDE::icon("folder-locked", overlays); } } else { *pIcon = KDE::icon("printer"); } } #endif void Smb4KShare::update(Smb4KShare* share) { if (QString::compare(workgroupName(), share->workgroupName(), Qt::CaseInsensitive) == 0 && (QString::compare(url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 || QString::compare(homeUrl().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->homeUrl().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0)) { *pUrl = share->url(); setMountData(share); setShareType(share->shareType()); setComment(share->comment()); setHostIpAddress(share->hostIpAddress()); } } diff --git a/core/smb4ksynchronizer.cpp b/core/smb4ksynchronizer.cpp index 5ab3533..760c6cd 100644 --- a/core/smb4ksynchronizer.cpp +++ b/core/smb4ksynchronizer.cpp @@ -1,170 +1,166 @@ /*************************************************************************** This is the new synchronizer of Smb4K. ------------------- begin : Fr Feb 04 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksynchronizer.h" #include "smb4ksynchronizer_p.h" #include "smb4knotification.h" #include "smb4kglobal.h" #include "smb4kshare.h" // Qt includes #include #include #include #include #include // KDE includes #include using namespace Smb4KGlobal; Q_GLOBAL_STATIC(Smb4KSynchronizerStatic, p); Smb4KSynchronizer::Smb4KSynchronizer(QObject *parent) : KCompositeJob(parent), d(new Smb4KSynchronizerPrivate) { setAutoDelete(false); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit())); } Smb4KSynchronizer::~Smb4KSynchronizer() { } Smb4KSynchronizer *Smb4KSynchronizer::self() { return &p->instance; } void Smb4KSynchronizer::synchronize(const SharePtr &share) { if (!isRunning(share)) { // Create a new job, add it to the subjobs and register it // with the job tracker. Smb4KSyncJob *job = new Smb4KSyncJob(this); job->setObjectName(QString("SyncJob_%1").arg(share->canonicalPath())); job->setupSynchronization(share); connect(job, SIGNAL(result(KJob*)), SLOT(slotJobFinished(KJob*))); connect(job, SIGNAL(aboutToStart(QString)), SIGNAL(aboutToStart(QString))); connect(job, SIGNAL(finished(QString)), SIGNAL(finished(QString))); addSubjob(job); job->start(); } } bool Smb4KSynchronizer::isRunning() { return hasSubjobs(); } bool Smb4KSynchronizer::isRunning(const SharePtr &share) { bool running = false; for (int i = 0; i < subjobs().size(); ++i) { if (QString::compare(QString("SyncJob_%1").arg(share->canonicalPath()), subjobs().at(i)->objectName()) == 0) { running = true; break; } else { continue; } } return running; } void Smb4KSynchronizer::abort(const SharePtr &share) { if (share && !share.isNull()) { for (KJob *job : subjobs()) { if (QString("SyncJob_%1").arg(share->canonicalPath()) == job->objectName()) { job->kill(KJob::EmitResult); break; } } } else { QListIterator it(subjobs()); while (it.hasNext()) { it.next()->kill(KJob::EmitResult); } } } void Smb4KSynchronizer::start() { QTimer::singleShot(0, this, SLOT(slotStartJobs())); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KSynchronizer::slotStartJobs() { // FIXME: Not implemented yet. I do not see a use case at the moment. } void Smb4KSynchronizer::slotJobFinished(KJob *job) { // Remove the job. removeSubjob(job); } void Smb4KSynchronizer::slotAboutToQuit() { abort(); } diff --git a/core/smb4ksynchronizer_p.cpp b/core/smb4ksynchronizer_p.cpp index 6d7a2fd..60f334f 100644 --- a/core/smb4ksynchronizer_p.cpp +++ b/core/smb4ksynchronizer_p.cpp @@ -1,813 +1,809 @@ /*************************************************************************** This file contains private helper classes for the Smb4KSynchronizer class. ------------------- begin : Fr Okt 24 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksynchronizer_p.h" #include "smb4knotification.h" #include "smb4ksettings.h" #include "smb4kglobal.h" #include "smb4kshare.h" // Qt includes #include #include #include #include #include #include #include #include // KDE includes #define TRANSLATION_DOMAIN "smb4k-core" #include #include #include #include #include using namespace Smb4KGlobal; Smb4KSyncJob::Smb4KSyncJob(QObject *parent) : KJob(parent), m_share(0), m_process(0) { setCapabilities(KJob::Killable); m_job_tracker = new KUiServerJobTracker(this); } Smb4KSyncJob::~Smb4KSyncJob() { } void Smb4KSyncJob::start() { QTimer::singleShot(0, this, SLOT(slotStartSynchronization())); } void Smb4KSyncJob::setupSynchronization(const SharePtr &share) { if (share) { m_share = share; } } bool Smb4KSyncJob::doKill() { if (m_process && m_process->state() != KProcess::NotRunning) { m_process->terminate(); } return KJob::doKill(); } void Smb4KSyncJob::slotStartSynchronization() { // // Find the shell command // QString rsync = QStandardPaths::findExecutable("rsync"); if (rsync.isEmpty()) { Smb4KNotification::commandNotFound("rsync"); emitResult(); return; } else { // Go ahead } // // The synchronization dialog // if (m_share) { // Show the user an URL input dialog. QPointer dlg = new Smb4KSynchronizationDialog(m_share, QApplication::activeWindow()); if (dlg->exec() == QDialog::Accepted) { // Create the destination directory if it does not already exits. QDir syncDir(dlg->destination().path()); if (!syncDir.exists()) { if (!QDir().mkpath(syncDir.path())) { Smb4KNotification::mkdirFailed(syncDir); emitResult(); return; } } // Make sure that we have got the trailing slash present. // rsync is very picky regarding it. m_src = dlg->source(); m_dest = dlg->destination(); delete dlg; } else { delete dlg; emitResult(); return; } } else { emitResult(); return; } // // The command // QStringList command; command << rsync; command << "--progress"; // // Basic settings // if (Smb4KSettings::archiveMode()) { command << "--archive"; } else { if (Smb4KSettings::recurseIntoDirectories()) { command << "--recursive"; } if (Smb4KSettings::preserveSymlinks()) { command << "--links"; } if (Smb4KSettings::preservePermissions()) { command << "--perms"; } if (Smb4KSettings::preserveTimes()) { command << "--times"; } if (Smb4KSettings::preserveGroup()) { command << "--group"; } if (Smb4KSettings::preserveOwner()) { command << "--owner"; } if (Smb4KSettings::preserveDevicesAndSpecials()) { // Alias -D command << "--devices"; command << "--specials"; } } if (Smb4KSettings::relativePathNames()) { command << "--relative"; } if (Smb4KSettings::noImpliedDirectories()) { command << "--no-implied-dirs"; } if (Smb4KSettings::transferDirectories()) { command << "--dirs"; } if (Smb4KSettings::makeBackups()) { command << "--backup"; if (Smb4KSettings::useBackupDirectory()) { command << QString("--backup-dir=%1").arg(Smb4KSettings::backupDirectory().path()); } if (Smb4KSettings::useBackupSuffix()) { command << QString("--suffix=%1").arg(Smb4KSettings::backupSuffix()); } } // // File handling // if (Smb4KSettings::updateTarget()) { command << "--update"; } if (Smb4KSettings::updateInPlace()) { command << "--inplace"; } if (Smb4KSettings::efficientSparseFileHandling()) { command << "--sparse"; } if (Smb4KSettings::copyFilesWhole()) { command << "--whole-file"; } if (Smb4KSettings::updateExisting()) { command << "--existing"; } if (Smb4KSettings::ignoreExisting()) { command << "--ignore-existing"; } if (Smb4KSettings::transformSymlinks()) { command << "--copy-links"; } if (Smb4KSettings::transformUnsafeSymlinks()) { command << "--copy-unsafe-links"; } if (Smb4KSettings::ignoreUnsafeSymlinks()) { command << "--safe-links"; } if (Smb4KSettings::mungeSymlinks()) { command << "--munge-links"; } if (Smb4KSettings::preserveHardLinks()) { command << "--hard-links"; } if (Smb4KSettings::copyDirectorySymlinks()) { command << "--copy-dirlinks"; } if (Smb4KSettings::keepDirectorySymlinks()) { command << "--keep-dirlinks"; } if (Smb4KSettings::omitDirectoryTimes()) { command << "--omit-dir-times"; } // // File transfer // if (Smb4KSettings::compressData()) { command << "--compress"; if (Smb4KSettings::useCompressionLevel()) { command << QString("--compress-level=%1").arg(Smb4KSettings::compressionLevel()); } if (Smb4KSettings::useSkipCompression()) { command << QString("--skip-compress=%1").arg(Smb4KSettings::skipCompression()); } } if (Smb4KSettings::self()->useMaximalTransferSize()) { command << QString("--max-size=%1K").arg(Smb4KSettings::self()->maximalTransferSize()); } if (Smb4KSettings::self()->useMinimalTransferSize()) { command << QString("--min-size=%1K").arg(Smb4KSettings::self()->minimalTransferSize()); } if (Smb4KSettings::keepPartial()) { command << " --partial"; if (Smb4KSettings::usePartialDirectory()) { command << QString("--partial-dir=%1").arg(Smb4KSettings::partialDirectory().path()); } } if (Smb4KSettings::useBandwidthLimit()) { command << QString("--bwlimit=%1K").arg(Smb4KSettings::bandwidthLimit()); } // // File deletion // if (Smb4KSettings::removeSourceFiles()) { command << "--remove-source-files"; } if (Smb4KSettings::deleteExtraneous()) { command << "--delete"; } if (Smb4KSettings::deleteBefore()) { command << "--delete-before"; } if (Smb4KSettings::deleteDuring()) { command << "--delete-during"; } if (Smb4KSettings::deleteAfter()) { command << "--delete-after"; } if (Smb4KSettings::deleteExcluded()) { command << "--delete-excluded"; } if (Smb4KSettings::ignoreErrors()) { command << "--ignore-errors"; } if (Smb4KSettings::forceDirectoryDeletion()) { command << "--force"; } if (Smb4KSettings::useMaximumDelete()) { command << QString("--max-delete=%1").arg(Smb4KSettings::maximumDeleteValue()); } // // Filtering // if (Smb4KSettings::useCVSExclude()) { command << "--cvs-exclude"; } if (Smb4KSettings::useExcludePattern()) { command << QString("--exclude=%1").arg(Smb4KSettings::excludePattern()); } if (Smb4KSettings::useExcludeFrom()) { command << QString("--exclude-from=%1").arg(Smb4KSettings::excludeFrom().path()); } if (Smb4KSettings::useIncludePattern()) { command << QString("--include=%1").arg(Smb4KSettings::includePattern()); } if (Smb4KSettings::useIncludeFrom()) { command << QString("--include-from=%1").arg(Smb4KSettings::includeFrom().path()); } if (!Smb4KSettings::customFilteringRules().isEmpty()) { qDebug() << "Do we need to spilt the filtering rules into a list?"; command << Smb4KSettings::customFilteringRules(); } if (Smb4KSettings::useFFilterRule()) { command << "-F"; } if (Smb4KSettings::useFFFilterRule()) { command << "-F"; command << "-F"; } // // Miscellaneous // if (Smb4KSettings::useBlockSize()) { command << QString("--block-size=%1").arg(Smb4KSettings::blockSize()); } if (Smb4KSettings::useChecksumSeed()) { command << QString("--checksum-seed=%1").arg(Smb4KSettings::checksumSeed()); } if (Smb4KSettings::useChecksum()) { command << "--checksum"; } if (Smb4KSettings::oneFileSystem()) { command << "--one-file-system"; } if (Smb4KSettings::delayUpdates()) { command << "--delay-updates"; } // Make sure that the trailing slash is present. rsync is very // picky regarding it. QString source = m_src.path() + (!m_src.path().endsWith('/') ? "/" : ""); QString destination = m_dest.path() + (!m_dest.path().endsWith('/') ? "/" : ""); command << source; command << destination; // // The job tracker // m_job_tracker->registerJob(this); connect(this, SIGNAL(result(KJob*)), m_job_tracker, SLOT(unregisterJob(KJob*))); // // The process // m_process = new KProcess(this); m_process->setEnv("LANG", "en_US.UTF-8"); m_process->setOutputChannelMode(KProcess::SeparateChannels); m_process->setProgram(command); connect(m_process, SIGNAL(readyReadStandardOutput()), SLOT(slotReadStandardOutput())); connect(m_process, SIGNAL(readyReadStandardError()), SLOT(slotReadStandardError())); connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotProcessFinished(int,QProcess::ExitStatus))); // Start the synchronization process emit aboutToStart(m_dest.path()); // Send description to the GUI emit description(this, i18n("Synchronizing"), qMakePair(i18n("Source"), source), qMakePair(i18n("Destination"), destination)); // Dummy to show 0 % emitPercent(0, 100); m_process->start(); } void Smb4KSyncJob::slotReadStandardOutput() { QStringList stdOut = QString::fromUtf8(m_process->readAllStandardOutput(), -1).split('\n', QString::SkipEmptyParts); for (int i = 0; i < stdOut.size(); ++i) { if (stdOut.at(i)[0].isSpace()) { // Get the overall transfer progress if (stdOut.at(i).contains(" to-check=")) { QString tmp = stdOut.at(i).section(" to-check=", 1, 1).section(')', 0, 0).trimmed(); bool success1 = true; bool success2 = true; qulonglong files = tmp.section('/', 0, 0).trimmed().toLongLong(&success1); qulonglong total = tmp.section('/', 1, 1).trimmed().toLongLong(&success2); if (success1 && success2) { setProcessedAmount(KJob::Files, total - files); setTotalAmount(KJob::Files, total); emitPercent(total - files, total); } } else if (stdOut.at(i).contains(" to-chk=")) { // Make Smb4K work with rsync >= 3.1. QString tmp = stdOut.at(i).section(" to-chk=", 1, 1).section(')', 0, 0).trimmed(); bool success1 = true; bool success2 = true; qulonglong files = tmp.section('/', 0, 0).trimmed().toLongLong(&success1); qulonglong total = tmp.section('/', 1, 1).trimmed().toLongLong(&success2); if (success1 && success2) { setProcessedAmount(KJob::Files, total - files); setTotalAmount(KJob::Files, total); emitPercent(total - files, total); } } else if (stdOut.at(i).contains(" ir-chk=")) { // Make Smb4K work with rsync >= 3.1. QString tmp = stdOut.at(i).section(" ir-chk=", 1, 1).section(')', 0, 0).trimmed(); bool success1 = true; bool success2 = true; qulonglong files = tmp.section('/', 0, 0).trimmed().toLongLong(&success1); qulonglong total = tmp.section('/', 1, 1).trimmed().toLongLong(&success2); if (success1 && success2) { setProcessedAmount(KJob::Files, total - files); setTotalAmount(KJob::Files, total); emitPercent(total - files, total); } } // Get transfer rate if (stdOut.at(i).contains("/s ", Qt::CaseSensitive)) { bool success = true; double tmp_speed = stdOut.at(i).section(QRegExp("../s"), 0, 0).section(' ', -1 -1).trimmed().toDouble(&success); if (success) { // MB == 1000000 B and kB == 1000 B per definition! if (stdOut.at(i).contains("MB/s")) { tmp_speed *= 1e6; } else if (stdOut.at(i).contains("kB/s")) { tmp_speed *= 1e3; } ulong speed = (ulong)tmp_speed; emitSpeed(speed /* B/s */); } } } else if (!stdOut.at(i).contains("sending incremental file list")) { QString file = stdOut.at(i).trimmed(); QUrl src_url = m_src; src_url.setPath(QDir::cleanPath(src_url.path() + '/' + file)); QUrl dest_url = m_dest; dest_url.setPath(QDir::cleanPath(dest_url.path() + '/' + file)); // Send description to the GUI emit description(this, i18n("Synchronizing"), qMakePair(i18n("Source"), src_url.path()), qMakePair(i18n("Destination"), dest_url.path())); } } } void Smb4KSyncJob::slotReadStandardError() { // // Get the error message // QString stdErr = QString::fromUtf8(m_process->readAllStandardError(), -1).trimmed(); // // Make sure the process is terminated // if (m_process->state() != KProcess::NotRunning) { m_process->terminate(); } // // Report an error if the process was not terminated // if (!(stdErr.contains("rsync error") && stdErr.contains("(code 20)"))) { Smb4KNotification::synchronizationFailed(m_src, m_dest, stdErr); } } void Smb4KSyncJob::slotProcessFinished(int, QProcess::ExitStatus status) { // Dummy to show 100 % emitPercent(100, 100); // Handle error. switch (status) { case QProcess::CrashExit: { Smb4KNotification::processError(m_process->error()); break; } default: { break; } } // Finish job emitResult(); emit finished(m_dest.path()); } Smb4KSynchronizationDialog::Smb4KSynchronizationDialog(const SharePtr &share, QWidget *parent) : QDialog(parent), m_share(share) { setWindowTitle(i18n("Synchronization")); QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); m_swap_button = buttonBox->addButton(i18n("Swap Paths"), QDialogButtonBox::ActionRole); m_swap_button->setToolTip(i18n("Swap source and destination")); m_synchronize_button = buttonBox->addButton(i18n("Synchronize"), QDialogButtonBox::ActionRole); m_synchronize_button->setToolTip(i18n("Synchronize the destination with the source")); m_cancel_button = buttonBox->addButton(QDialogButtonBox::Cancel); m_cancel_button->setShortcut(Qt::Key_Escape); m_synchronize_button->setDefault(true); QGridLayout *layout = new QGridLayout(this); layout->setSpacing(5); QLabel *pixmap = new QLabel(this); QPixmap sync_pix = KDE::icon("folder-sync").pixmap(KIconLoader::SizeHuge); pixmap->setPixmap(sync_pix); pixmap->setAlignment(Qt::AlignBottom); QLabel *description = new QLabel(i18n("Please provide the source and destination " "directory for the synchronization."), this); description->setWordWrap(true); description->setAlignment(Qt::AlignBottom); QUrl src_url = QUrl(QDir::cleanPath(m_share->path())); QUrl dest_url = QUrl(QDir::cleanPath(QString("%1/%2/%3").arg(Smb4KSettings::rsyncPrefix().path()) .arg(m_share->hostName()).arg(m_share->shareName()))); QLabel *source_label = new QLabel(i18n("Source:"), this); m_source = new KUrlRequester(this); m_source->setUrl(src_url); m_source->setMode(KFile::Directory | KFile::LocalOnly); m_source->lineEdit()->setSqueezedTextEnabled(true); m_source->completionObject()->setCompletionMode(KCompletion::CompletionPopupAuto); m_source->completionObject()->setMode(KUrlCompletion::FileCompletion); m_source->setWhatsThis(i18n("This is the source directory. The data that it contains is to be written " "to the destination directory.")); QLabel *destination_label = new QLabel(i18n("Destination:"), this); m_destination = new KUrlRequester(this); m_destination->setUrl(dest_url); m_destination->setMode(KFile::Directory | KFile::LocalOnly); m_destination->lineEdit()->setSqueezedTextEnabled(true); m_destination->completionObject()->setCompletionMode(KCompletion::CompletionPopupAuto); m_destination->completionObject()->setMode(KUrlCompletion::FileCompletion); m_destination->setWhatsThis(i18n("This is the destination directory. It will be updated with the data " "from the source directory.")); layout->addWidget(pixmap, 0, 0, 0); layout->addWidget(description, 0, 1, Qt::AlignBottom); layout->addWidget(source_label, 1, 0, 0); layout->addWidget(m_source, 1, 1, 0); layout->addWidget(destination_label, 2, 0, 0); layout->addWidget(m_destination, 2, 1, 0); layout->addWidget(buttonBox, 3, 0, 1, 2, 0); // // Connections // connect(m_cancel_button, SIGNAL(clicked()), SLOT(slotCancelClicked())); connect(m_synchronize_button, SIGNAL(clicked()), SLOT(slotSynchronizeClicked())); connect(m_swap_button, SIGNAL(clicked()), SLOT(slotSwapPathsClicked())); // // Set the dialog size // create(); KConfigGroup group(Smb4KSettings::self()->config(), "SynchronizationDialog"); QSize dialogSize; if (group.exists()) { KWindowConfig::restoreWindowSize(windowHandle(), group); dialogSize = windowHandle()->size(); } else { dialogSize = sizeHint(); } resize(dialogSize); // workaround for QTBUG-40584 } Smb4KSynchronizationDialog::~Smb4KSynchronizationDialog() { } const QUrl Smb4KSynchronizationDialog::source() { return m_source->url(); } const QUrl Smb4KSynchronizationDialog::destination() { return m_destination->url(); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KSynchronizationDialog::slotCancelClicked() { reject(); } void Smb4KSynchronizationDialog::slotSynchronizeClicked() { KConfigGroup group(Smb4KSettings::self()->config(), "SynchronizationDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); accept(); } void Smb4KSynchronizationDialog::slotSwapPathsClicked() { // Swap URLs. QString sourceURL = m_source->url().path(); QString destinationURL = m_destination->url().path(); m_source->setUrl(QUrl(destinationURL)); m_destination->setUrl(QUrl(sourceURL)); } diff --git a/core/smb4kwalletmanager.cpp b/core/smb4kwalletmanager.cpp index 237e6de..f5c3377 100644 --- a/core/smb4kwalletmanager.cpp +++ b/core/smb4kwalletmanager.cpp @@ -1,757 +1,753 @@ /*************************************************************************** This is the wallet manager of Smb4K. ------------------- begin : Sa Dez 27 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kwalletmanager.h" #include "smb4kwalletmanager_p.h" #include "smb4ksettings.h" #include "smb4kauthinfo.h" #include "smb4khomesshareshandler.h" #include "smb4kglobal.h" #include "smb4knotification.h" #include "smb4khost.h" #include "smb4kshare.h" // Qt includes #include #include #include // KDE includes using namespace Smb4KGlobal; Q_GLOBAL_STATIC(Smb4KWalletManagerStatic, p); Smb4KWalletManager::Smb4KWalletManager(QObject *parent) : QObject(parent), d(new Smb4KWalletManagerPrivate) { d->wallet = 0; } Smb4KWalletManager::~Smb4KWalletManager() { } Smb4KWalletManager *Smb4KWalletManager::self() { return &p->instance; } void Smb4KWalletManager::init() { if (useWalletSystem()) { // // Get a pointer to the wallet, if we do not have one yet // if (!d->wallet) { // // Open the wallet synchronously. // d->wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), QApplication::activeWindow() ? QApplication::activeWindow()->winId() : 0); // // Check if the walled was opened successfully and set the // right folder, if it was // if (d->wallet) { if (d->wallet->isOpen()) { if (!d->wallet->hasFolder("Smb4K")) { d->wallet->createFolder("Smb4K"); d->wallet->setFolder("Smb4K"); } else { d->wallet->setFolder("Smb4K"); } } else { Smb4KNotification::credentialsNotAccessible(); } } else { delete d->wallet; d->wallet = 0; Smb4KNotification::openingWalletFailed(KWallet::Wallet::NetworkWallet()); } } } else { if (d->wallet) { // // Close the wallet, if Smb4K is the only application that // is using it. Thus, use force=false, otherwise it will definitely // be closed. // d->wallet->closeWallet(KWallet::Wallet::NetworkWallet(), false); // // Delete the wallet and set it to 0. // delete d->wallet; d->wallet = 0; } } emit initialized(); } void Smb4KWalletManager::readAuthInfo(const NetworkItemPtr &networkItem) { // // Only do something, if the networkItem is not null // if (networkItem) { // // Initialize the wallet manager. // init(); // // Proceed if the wallet is open // if (walletIsOpen()) { // // Get the list of entries // QStringList entryList = d->wallet->entryList(); // // Create the map to store the authentication information // QMap authInfoMap; // // Now loop through the stored credentials and make a case insensitive comparison // with the URL of the network item. // for (const QString &entry : entryList) { if (networkItem->type() == Host) { if (QString::compare(entry, networkItem->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 || QString::compare(entry, networkItem->url().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { d->wallet->readMap(entry, authInfoMap); break; } } else if (networkItem->type() == Share) { // // Cast the network item. We need some share specific info // SharePtr share = networkItem.staticCast(); if (share) { // // Process normal and 'homes' shares differently // if (!share->isHomesShare()) { // // Prefer the credentials for the share. Use the ones for the // host as fallback. // if (QString::compare(entry, share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 || QString::compare(entry, share->url().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { d->wallet->readMap(entry, authInfoMap); break; } else if (QString::compare(entry, share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), Qt::CaseInsensitive) == 0 || QString::compare(entry, share->url().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), Qt::CaseInsensitive) == 0) { d->wallet->readMap(entry, authInfoMap); } } else { // // Prefer the credentials for the share. Use the ones for the // host as fallback. // if (QString::compare(entry, share->homeUrl().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0 || QString::compare(entry, share->homeUrl().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { d->wallet->readMap(entry, authInfoMap); break; } else if (QString::compare(entry, share->homeUrl().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), Qt::CaseInsensitive) == 0 || QString::compare(entry, share->homeUrl().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath), Qt::CaseInsensitive) == 0) { d->wallet->readMap(entry, authInfoMap); } } } } } // // Set the authentication information // if (!authInfoMap.isEmpty()) { switch (networkItem->type()) { case Host: { HostPtr host = networkItem.staticCast(); if (QString::compare(host->workgroupName(), authInfoMap.value("Workgroup"), Qt::CaseInsensitive) == 0) { host->setLogin(authInfoMap.value("Login")); host->setPassword(authInfoMap.value("Password")); } break; } case Share: { SharePtr share = networkItem.staticCast(); if (QString::compare(share->workgroupName(), authInfoMap.value("Workgroup"), Qt::CaseInsensitive) == 0) { share->setLogin(authInfoMap.value("Login")); share->setPassword(authInfoMap.value("Password")); } break; } default: { break; } } } else { // // In case the map is empty, set the default login, if it is to be used // if (Smb4KSettings::useDefaultLogin()) { d->wallet->readMap("DEFAULT_LOGIN", authInfoMap); switch (networkItem->type()) { case Host: { HostPtr host = networkItem.staticCast(); host->setLogin(authInfoMap.value("Login")); host->setPassword(authInfoMap.value("Password")); break; } case Share: { SharePtr share = networkItem.staticCast(); share->setLogin(authInfoMap.value("Login")); share->setPassword(authInfoMap.value("Password")); break; } default: { break; } } } } } } } void Smb4KWalletManager::readDefaultAuthInfo(Smb4KAuthInfo *authInfo) { if (authInfo) { // // Initialize the wallet manager. // init(); if (walletIsOpen()) { // // Read the default authentication information from the // wallet. // QMap authInfoMap; d->wallet->readMap("DEFAULT_LOGIN", authInfoMap); if (!authInfoMap.isEmpty()) { authInfo->setUserName(authInfoMap.value("Login")); authInfo->setPassword(authInfoMap.value("Password")); } } } } void Smb4KWalletManager::writeAuthInfo(const NetworkItemPtr &networkItem) { if (networkItem) { // // Initialize the wallet manager. // init(); if (walletIsOpen()) { // // Handle the network item according to its type // switch (networkItem->type()) { case Host: { // // Cast the network item // HostPtr host = networkItem.staticCast(); if (host) { // // Write the authentication information to the wallet, if it // is not empty. // if (!host->login().isEmpty() /* allow empty passwords */ && !host->hostName().isEmpty()) { // // Create the map that carries the authentication information // QMap authInfoMap; // // Insert login and password // authInfoMap.insert("Login", host->login()); authInfoMap.insert("Password", host->password()); // // Enter the workgroup, if it exists // if (!host->workgroupName().isEmpty()) { authInfoMap.insert("Workgroup", host->workgroupName()); } // // Enter the IP address, if is exists // if (host->hasIpAddress()) { authInfoMap.insert("IP Address", host->ipAddress()); } // // Write the entry to the wallet // d->wallet->writeMap(host->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), authInfoMap); d->wallet->sync(); } } break; } case Share: { // // Cast the network item // SharePtr share = networkItem.staticCast(); if (share) { // // Write the authentication information to the wallet, if it // is not empty. // if (!share->login().isEmpty() /* allow empty passwords */ && !share->hostName().isEmpty()) { // // Create the map that carries the authentication information // QMap authInfoMap; // // Insert login and password // authInfoMap.insert("Login", share->login()); authInfoMap.insert("Password", share->password()); // // Enter the workgroup, if it exists // if (!share->workgroupName().isEmpty()) { authInfoMap.insert("Workgroup", share->workgroupName()); } // // Enter the IP address, if is exists // if (share->hasHostIpAddress()) { authInfoMap.insert("IP Address", share->hostIpAddress()); } // // Write the entry to the wallet // if (!share->isHomesShare()) { d->wallet->writeMap(share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), authInfoMap); } else { d->wallet->writeMap(share->homeUrl().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), authInfoMap); } } } break; } default: { break; } } } } } void Smb4KWalletManager::writeDefaultAuthInfo(Smb4KAuthInfo *authInfo) { if (authInfo) { // // Initialize the wallet manager. // init(); if (walletIsOpen()) { // // Write the default authentication information to the // wallet. // if (!authInfo->userName().isEmpty() /* allow empty passwords */) { QMap authInfoMap; authInfoMap.insert("Login", authInfo->userName()); authInfoMap.insert("Password", authInfo->password()); d->wallet->writeMap("DEFAULT_LOGIN", authInfoMap); d->wallet->sync(); } } } } bool Smb4KWalletManager::showPasswordDialog(const NetworkItemPtr &networkItem) { // // Define the return value here // bool success = false; // // Check that the network item is not null // if (networkItem) { // // Initialize the wallet manager. // init(); // // Get the known logins (for homes shares) and read the authentication // information. // QMap knownLogins; switch(networkItem->type()) { case Share: { // // Cast the network item // SharePtr share = networkItem.staticCast(); // // If the share is a 'homes' share, read the known logins // for that share. // if (share->isHomesShare()) { // // Get the known logins // QStringList users = Smb4KHomesSharesHandler::self()->homesUsers(share); // // Read the authentication information for all known logins // for (const QString &user : users) { // // Create a temp share // SharePtr tempShare = share; // // Set the login // tempShare->setLogin(user); // // Read the authentication information // readAuthInfo(tempShare); // // Save the authentication data in the map // knownLogins.insert(tempShare->login(), tempShare->password()); // // Clear the temp share // tempShare.clear(); } } else { readAuthInfo(networkItem); } break; } default: { readAuthInfo(networkItem); break; } } // // Set up the password dialog and show it // QPointer dlg = new Smb4KPasswordDialog(networkItem, knownLogins, QApplication::activeWindow()); if (dlg->exec() == Smb4KPasswordDialog::Accepted) { // Write the authentication information. writeAuthInfo(networkItem); success = true; } delete dlg; } return success; } bool Smb4KWalletManager::useWalletSystem() const { return (KWallet::Wallet::isEnabled() && Smb4KSettings::useWallet()); } QList Smb4KWalletManager::walletEntries() { // // Initialize the wallet manager. // init(); // // Define the return value // QList entries; // // Only read from the wallet if it is open // if (walletIsOpen()) { // // Get all entries from the wallet // QStringList entryList = d->wallet->entryList(); // // Process the entries // for (const QString &entry : entryList) { // // Create a auth info object // Smb4KAuthInfo *authInfo = new Smb4KAuthInfo(); // // Read the authentication information from the wallet // QMap authInfoMap; d->wallet->readMap(entry, authInfoMap); // // Process the entry // if (entry == "DEFAULT_LOGIN") { // // Default login // authInfo->setUserName(authInfoMap.value("Login")); authInfo->setPassword(authInfoMap.value("Password")); } else { // // Entry for a specific URL // authInfo->setUrl(entry); authInfo->setIpAddress(authInfoMap.value("IP Address")); authInfo->setWorkgroupName(authInfoMap.value("Workgroup")); authInfo->setUserName(authInfoMap.value("Login")); authInfo->setPassword(authInfoMap.value("Password")); } entries << authInfo; } } return entries; } void Smb4KWalletManager::writeWalletEntries(const QList &entries) { // // Initialize the wallet manager. // init(); // // Write the list if the wallet is open // if (walletIsOpen()) { // // First clear the wallet // QStringList entryList = d->wallet->entryList(); for (const QString &entry : entryList) { d->wallet->removeEntry(entry); } // // Now write the new entries to the wallet // for (Smb4KAuthInfo *authInfo : entries) { QMap authInfoMap; if (authInfo->type() == UnknownNetworkItem) { // // Default login // authInfoMap.insert("Login", authInfo->userName()); authInfoMap.insert("Password", authInfo->password()); // // Write the default authentication information to the wallet // d->wallet->writeMap("DEFAULT_LOGIN", authInfoMap); } else { // // Authentication information for a specific URL // authInfoMap.insert("IP Address", authInfo->ipAddress()); authInfoMap.insert("Workgroup", authInfo->workgroupName()); authInfoMap.insert("Login", authInfo->userName()); authInfoMap.insert("Password", authInfo->password()); // // Write the authentication information to the wallet // d->wallet->writeMap(authInfo->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), authInfoMap); } // // Sync the entries to disk // d->wallet->sync(); } } } bool Smb4KWalletManager::walletIsOpen() const { return (d->wallet ? (useWalletSystem() && d->wallet->isOpen()) : false); } diff --git a/core/smb4kworkgroup.cpp b/core/smb4kworkgroup.cpp index 1e9faea..0824f0c 100644 --- a/core/smb4kworkgroup.cpp +++ b/core/smb4kworkgroup.cpp @@ -1,170 +1,166 @@ /*************************************************************************** Smb4K's container class for information about a workgroup. ------------------- begin : Sa Jan 26 2008 copyright : (C) 2008-2017 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kworkgroup.h" #include "smb4kglobal.h" // Qt includes #include #include // KDE includes #include using namespace Smb4KGlobal; class Smb4KWorkgroupPrivate { public: QUrl masterURL; QHostAddress masterIP; }; Smb4KWorkgroup::Smb4KWorkgroup(const QString &name) : Smb4KBasicNetworkItem(Workgroup), d(new Smb4KWorkgroupPrivate) { // // Set the URL of the workgroup // pUrl->setScheme("smb"); pUrl->setHost(name); // // Set the icon // *pIcon = KDE::icon("network-workgroup"); } Smb4KWorkgroup::Smb4KWorkgroup(const Smb4KWorkgroup &w) : Smb4KBasicNetworkItem(Workgroup), d(new Smb4KWorkgroupPrivate) { // Copy the private variables // *d = *w.d; // // Set the icon if necessary // if (pIcon->isNull()) { *pIcon = KDE::icon("network-workgroup"); } } Smb4KWorkgroup::Smb4KWorkgroup() : Smb4KBasicNetworkItem(Workgroup), d(new Smb4KWorkgroupPrivate) { // // Set the URL // pUrl->setScheme("smb"); // // Set the icon // *pIcon = KDE::icon("network-workgroup"); } Smb4KWorkgroup::~Smb4KWorkgroup() { } void Smb4KWorkgroup::setWorkgroupName(const QString &name) { pUrl->setHost(name); pUrl->setScheme("smb"); } QString Smb4KWorkgroup::workgroupName() const { return pUrl->host().toUpper(); } void Smb4KWorkgroup::setMasterBrowserName(const QString &name) { d->masterURL.setHost(name); d->masterURL.setScheme("smb"); } QString Smb4KWorkgroup::masterBrowserName() const { return d->masterURL.host().toUpper(); } void Smb4KWorkgroup::setMasterBrowserIpAddress(const QString &ip) { d->masterIP.setAddress(ip); } void Smb4KWorkgroup::setMasterBrowserIpAddress(const QHostAddress& address) { if (!address.isNull() && address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) { d->masterIP = address; } } QString Smb4KWorkgroup::masterBrowserIpAddress() const { return d->masterIP.toString(); } bool Smb4KWorkgroup::hasMasterBrowserIpAddress() const { return !d->masterIP.isNull(); } void Smb4KWorkgroup::update(Smb4KWorkgroup* workgroup) { if (QString::compare(workgroupName(), workgroup->workgroupName()) == 0) { setMasterBrowserName(workgroup->masterBrowserName()); setMasterBrowserIpAddress(workgroup->masterBrowserIpAddress()); } } diff --git a/helpers/smb4kmounthelper.cpp b/helpers/smb4kmounthelper.cpp index 2438a3f..83c5ae9 100644 --- a/helpers/smb4kmounthelper.cpp +++ b/helpers/smb4kmounthelper.cpp @@ -1,267 +1,263 @@ /*************************************************************************** The helper that mounts and unmounts shares. ------------------- begin : Sa Okt 16 2010 copyright : (C) 2010-2017 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kmounthelper.h" #include "../core/smb4kglobal.h" // Qt includes #include #include #include #include // KDE includes #include #include #include #include using namespace Smb4KGlobal; KAUTH_HELPER_MAIN("org.kde.smb4k.mounthelper", Smb4KMountHelper); KAuth::ActionReply Smb4KMountHelper::mount(const QVariantMap& args) { // // The action reply // ActionReply reply; // // Get the mount executable // const QString mount = findMountExecutable(); // // Check the mount executable // if (mount != args["mh_command"].toString()) { // Something weird is going on, bail out. reply.setType(ActionReply::HelperErrorType); return reply; } // // Mount command // QStringList command; #if defined(Q_OS_LINUX) command << mount; command << args["mh_url"].toUrl().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort); command << args["mh_mountpoint"].toString(); command << args["mh_options"].toStringList(); #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) command << mount; command << args["mh_options"].toStringList(); command << args["mh_url"].toUrl().toString(QUrl::RemoveScheme|QUrl::RemoveUserInfo|QUrl::RemovePort); command << args["mh_mountpoint"].toString(); #endif // // The process // KProcess proc(this); proc.setOutputChannelMode(KProcess::SeparateChannels); proc.setProcessEnvironment(QProcessEnvironment::systemEnvironment()); #if defined(Q_OS_LINUX) proc.setEnv("PASSWD", args["mh_url"].toUrl().password(), true); #endif // We need this to avoid a translated password prompt. proc.setEnv("LANG", "C"); // If the location of a Kerberos ticket is passed, it needs to // be passed to the process environment here. if (args.contains("mh_krb5ticket")) { proc.setEnv("KRB5CCNAME", args["mh_krb5ticket"].toString()); } proc.setProgram(command); proc.start(); if (proc.waitForStarted(-1)) { bool userKill = false; while (!proc.waitForFinished(10)) { // Check if there is a password prompt. If there is one, pass // the password to it. QByteArray out = proc.readAllStandardError(); if (out.startsWith("Password")) { proc.write(args["mh_url"].toUrl().password().toUtf8()); proc.write("\r"); } // We want to be able to terminate the process from outside. // Thus, we implement a loop that checks periodically, if we // need to kill the process. if (HelperSupport::isStopped()) { proc.kill(); userKill = true; } } if (proc.exitStatus() == KProcess::CrashExit) { if (!userKill) { reply.setType(ActionReply::HelperErrorType); reply.setErrorDescription(i18n("The mount process crashed.")); } } else { // Check if there is output on stderr. QString stdErr = QString::fromUtf8(proc.readAllStandardError()); reply.addData("mh_error_message", stdErr.trimmed()); } } else { reply.setType(ActionReply::HelperErrorType); reply.setErrorDescription(i18n("The mount process could not be started.")); } return reply; } KAuth::ActionReply Smb4KMountHelper::unmount(const QVariantMap& args) { ActionReply reply; // // Get the umount executable // const QString umount = findUmountExecutable(); // // Check the mount executable // if (umount != args["mh_command"].toString()) { // Something weird is going on, bail out. reply.setType(ActionReply::HelperErrorType); return reply; } // // Check if the mountpoint is valid and the filesystem is correct. // bool mountPointOk = false; KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::BasicInfoNeeded|KMountPoint::NeedMountOptions); for (const QExplicitlySharedDataPointer &mountPoint : mountPoints) { #if defined(Q_OS_LINUX) if (QString::compare(args["mh_mountpoint"].toString(), mountPoint->mountPoint()) == 0 && QString::compare(mountPoint->mountType(), "cifs", Qt::CaseInsensitive) == 0) #else if (QString::compare(args["mh_mountpoint"].toString(), mountPoint->mountPoint()) == 0 && QString::compare(mountPoint->mountType(), "smbfs", Qt::CaseInsensitive) == 0) #endif { mountPointOk = true; break; } } // // Stop here if the mountpoint is not valid // if (!mountPointOk) { reply.setType(ActionReply::HelperErrorType); reply.setErrorDescription(i18n("The mountpoint %1 is invalid.", args["mh_mountpoint"].toString())); } // // The command // QStringList command; command << umount; command << args["mh_options"].toStringList(); command << args["mh_mountpoint"].toString(); // // The process // KProcess proc(this); proc.setOutputChannelMode(KProcess::SeparateChannels); proc.setProcessEnvironment(QProcessEnvironment::systemEnvironment()); proc.setProgram(command); proc.start(); if (proc.waitForStarted(-1)) { // We want to be able to terminate the process from outside. // Thus, we implement a loop that checks periodically, if we // need to kill the process. bool userKill = false; while (!proc.waitForFinished(10)) { if (HelperSupport::isStopped()) { proc.kill(); userKill = true; break; } } if (proc.exitStatus() == KProcess::CrashExit) { if (!userKill) { reply.setType(ActionReply::HelperErrorType); reply.setErrorDescription(i18n("The unmount process crashed.")); } } else { // Check if there is output on stderr. QString stdErr = QString::fromUtf8(proc.readAllStandardError()); reply.addData("mh_error_message", stdErr.trimmed()); } } else { reply.setType(ActionReply::HelperErrorType); reply.setErrorDescription(i18n("The unmount process could not be started.")); } return reply; } diff --git a/plasmoid/plugin/smb4kbookmarkobject.cpp b/plasmoid/plugin/smb4kbookmarkobject.cpp index 0d9c030..6e54c1a 100644 --- a/plasmoid/plugin/smb4kbookmarkobject.cpp +++ b/plasmoid/plugin/smb4kbookmarkobject.cpp @@ -1,210 +1,206 @@ /*************************************************************************** This class derives from QObject and encapsulates a bookmark item. It is for use with QtQuick. ------------------- begin : Fr Mai 11 2013 copyright : (C) 2013-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbookmarkobject.h" // Qt includes #include // KDE includes #include class Smb4KBookmarkObjectPrivate { public: QString workgroup; QUrl url; QString label; QString group; QString login; bool isGroup; bool isMounted; QHostAddress hostIP; }; Smb4KBookmarkObject::Smb4KBookmarkObject(Smb4KBookmark* bookmark, QObject* parent) : QObject(parent), d(new Smb4KBookmarkObjectPrivate) { d->workgroup = bookmark->workgroupName(); d->url = bookmark->url(); d->label = bookmark->label(); d->group = bookmark->groupName(); d->login = bookmark->login(); d->isGroup = false; d->isMounted = false; d->hostIP.setAddress(bookmark->hostIpAddress()); } Smb4KBookmarkObject::Smb4KBookmarkObject(const QString& groupName, QObject* parent) : QObject(parent), d(new Smb4KBookmarkObjectPrivate) { d->group = groupName; d->isGroup = true; d->isMounted = false; } Smb4KBookmarkObject::Smb4KBookmarkObject(QObject* parent) : QObject(parent), d(new Smb4KBookmarkObjectPrivate) { d->isGroup = false; d->isMounted = false; } Smb4KBookmarkObject::~Smb4KBookmarkObject() { } QString Smb4KBookmarkObject::workgroupName() const { return d->workgroup; } void Smb4KBookmarkObject::setWorkgroupName(const QString& name) { d->workgroup = name; emit changed(); } QString Smb4KBookmarkObject::hostName() const { return d->url.host().toUpper(); } QString Smb4KBookmarkObject::shareName() const { return d->url.path().remove('/'); } QString Smb4KBookmarkObject::label() const { return d->label; } void Smb4KBookmarkObject::setLabel(const QString& label) { d->label = label; emit changed(); } QUrl Smb4KBookmarkObject::url() const { return d->url; } void Smb4KBookmarkObject::setURL(const QUrl& url) { d->url = url; emit changed(); } QString Smb4KBookmarkObject::groupName() const { return d->group; } void Smb4KBookmarkObject::setGroupName(const QString& name) { d->group = name; emit changed(); } bool Smb4KBookmarkObject::isGroup() const { return d->isGroup; } void Smb4KBookmarkObject::setGroup(bool group) { d->isGroup = group; emit changed(); } bool Smb4KBookmarkObject::isMounted() const { return d->isMounted; } void Smb4KBookmarkObject::setMounted(bool mounted) { d->isMounted = mounted; emit changed(); } QString Smb4KBookmarkObject::login() const { return d->login; } void Smb4KBookmarkObject::setLogin(const QString& name) { d->login = name; emit changed(); } QString Smb4KBookmarkObject::hostIP() const { return d->hostIP.toString(); } void Smb4KBookmarkObject::setHostIP(const QString& ip) { if (d->hostIP.setAddress(ip)) { emit changed(); } } diff --git a/plasmoid/plugin/smb4kdeclarative.cpp b/plasmoid/plugin/smb4kdeclarative.cpp index a5936fc..d7d30e7 100644 --- a/plasmoid/plugin/smb4kdeclarative.cpp +++ b/plasmoid/plugin/smb4kdeclarative.cpp @@ -1,792 +1,788 @@ /*************************************************************************** This class provides the interface for Plasma and QtQuick ------------------- begin : Mo 02 Sep 2013 copyright : (C) 2013-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kdeclarative.h" #include "smb4kdeclarative_p.h" #include "smb4kbookmarkobject.h" #include "smb4knetworkobject.h" #include "smb4kprofileobject.h" #include "core/smb4kmounter.h" #include "core/smb4kglobal.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" #include "core/smb4kbasicnetworkitem.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kbookmark.h" #include "core/smb4kcustomoptionsmanager.h" #include "core/smb4kprofilemanager.h" #include "core/smb4ksynchronizer.h" #include "core/smb4kclient.h" // Qt includes #include #include // KDE includes #include #include #include Smb4KDeclarative::Smb4KDeclarative(QObject* parent) : QObject(parent), d(new Smb4KDeclarativePrivate) { // // Initialize the core // Smb4KGlobal::initCore(true, false); // // Connections // connect(Smb4KClient::self(), SIGNAL(workgroups()), this, SLOT(slotWorkgroupsListChanged())); connect(Smb4KClient::self(), SIGNAL(hosts(WorkgroupPtr)), this, SLOT(slotHostsListChanged())); connect(Smb4KClient::self(), SIGNAL(shares(HostPtr)), this, SLOT(slotSharesListChanged())); connect(Smb4KClient::self(), SIGNAL(aboutToStart(NetworkItemPtr,int)), this, SIGNAL(busy())); connect(Smb4KClient::self(), SIGNAL(finished(NetworkItemPtr,int)), this, SIGNAL(idle())); connect(Smb4KMounter::self(), SIGNAL(mountedSharesListChanged()), this, SLOT(slotMountedSharesListChanged())); connect(Smb4KMounter::self(), SIGNAL(aboutToStart(int)), this, SIGNAL(busy())); connect(Smb4KMounter::self(), SIGNAL(finished(int)), this, SIGNAL(idle())); connect(Smb4KBookmarkHandler::self(), SIGNAL(updated()), this, SLOT(slotBookmarksListChanged())); connect(Smb4KProfileManager::self(), SIGNAL(profilesListChanged(QStringList)), this, SLOT(slotProfilesListChanged(QStringList))); connect(Smb4KProfileManager::self(), SIGNAL(activeProfileChanged(QString)), this, SLOT(slotActiveProfileChanged(QString))); connect(Smb4KProfileManager::self(), SIGNAL(profileUsageChanged(bool)), this, SLOT(slotProfileUsageChanged(bool))); // // Do the initial loading of items // slotBookmarksListChanged(); slotProfilesListChanged(Smb4KProfileManager::self()->profilesList()); slotActiveProfileChanged(Smb4KProfileManager::self()->activeProfile()); slotProfileUsageChanged(Smb4KProfileManager::self()->useProfiles()); } Smb4KDeclarative::~Smb4KDeclarative() { while (!d->workgroupObjects.isEmpty()) { delete d->workgroupObjects.takeFirst(); } while (!d->hostObjects.isEmpty()) { delete d->hostObjects.takeFirst(); } while (!d->shareObjects.isEmpty()) { delete d->shareObjects.takeFirst(); } while (!d->mountedObjects.isEmpty()) { delete d->mountedObjects.takeFirst(); } while (!d->bookmarkObjects.isEmpty()) { delete d->bookmarkObjects.takeFirst(); } while (!d->bookmarkGroupObjects.isEmpty()) { delete d->bookmarkGroupObjects.takeFirst(); } while (!d->profileObjects.isEmpty()) { delete d->profileObjects.takeFirst(); } } QQmlListProperty Smb4KDeclarative::workgroups() { return QQmlListProperty(this, d->workgroupObjects); } QQmlListProperty Smb4KDeclarative::hosts() { return QQmlListProperty(this, d->hostObjects); } QQmlListProperty Smb4KDeclarative::shares() { return QQmlListProperty(this, d->shareObjects); } QQmlListProperty Smb4KDeclarative::mountedShares() { return QQmlListProperty(this, d->mountedObjects); } QQmlListProperty Smb4KDeclarative::bookmarks() { return QQmlListProperty(this, d->bookmarkObjects); } QQmlListProperty Smb4KDeclarative::bookmarkGroups() { return QQmlListProperty(this, d->bookmarkGroupObjects); } QQmlListProperty Smb4KDeclarative::profiles() { return QQmlListProperty(this, d->profileObjects); } void Smb4KDeclarative::lookup(Smb4KNetworkObject *object) { if (object) { switch (object->type()) { case Smb4KNetworkObject::Network: { Smb4KClient::self()->lookupDomains(); break; } case Smb4KNetworkObject::Workgroup: { // Check if the workgroup is known. WorkgroupPtr workgroup = Smb4KGlobal::findWorkgroup(object->url().host().toUpper()); if (workgroup) { Smb4KClient::self()->lookupDomainMembers(workgroup); } break; } case Smb4KNetworkObject::Host: { // Check if the host is known. HostPtr host = Smb4KGlobal::findHost(object->url().host().toUpper()); if (host) { Smb4KClient::self()->lookupShares(host); } break; } case Smb4KNetworkObject::Share: { break; } default: { // Shares are ignored break; } } } else { // If the object is 0, scan the whole network. Smb4KClient::self()->lookupDomains(); } } Smb4KNetworkObject *Smb4KDeclarative::findNetworkItem(const QUrl &url, int type) { Smb4KNetworkObject *object = 0; if (url.isValid()) { switch (type) { case Smb4KNetworkObject::Workgroup: { for (Smb4KNetworkObject *obj : d->workgroupObjects) { if (url == obj->url()) { object = obj; break; } else { continue; } } break; } case Smb4KNetworkObject::Host: { for (Smb4KNetworkObject *obj : d->hostObjects) { if (url == obj->url()) { object = obj; break; } else { continue; } } break; } case Smb4KNetworkObject::Share: { for (Smb4KNetworkObject *obj : d->shareObjects) { if (url == obj->url()) { object = obj; break; } else { continue; } } break; } default: { break; } } } return object; } void Smb4KDeclarative::openMountDialog() { Smb4KMounter::self()->openMountDialog(); } void Smb4KDeclarative::mount(Smb4KNetworkObject *object) { if (object && object->type() == Smb4KNetworkObject::Share) { QString shareName = object->url().path(); if (shareName.startsWith('/')) { shareName = shareName.mid(1, -1); } SharePtr share = Smb4KGlobal::findShare(object->url(), object->workgroupName()); if (share) { Smb4KMounter::self()->mountShare(share); } else { // If the share is not in the global list of shares, // try the list of bookmarks. BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(object->url()); share = SharePtr(new Smb4KShare()); share->setUrl(object->url()); share->setWorkgroupName(bookmark->workgroupName()); share->setHostIpAddress(bookmark->hostIpAddress()); Smb4KMounter::self()->mountShare(share); while (Smb4KMounter::self()->isRunning()) { QTest::qWait(50); } share.clear(); } } } void Smb4KDeclarative::unmount(Smb4KNetworkObject *object) { if (object && object->type()) { if (object->mountpoint().isValid()) { SharePtr share = Smb4KGlobal::findShareByPath(object->mountpoint().path()); if (share) { Smb4KMounter::self()->unmountShare(share); } } } } void Smb4KDeclarative::unmountAll() { Smb4KMounter::self()->unmountAllShares(false); } Smb4KNetworkObject* Smb4KDeclarative::findMountedShare(const QUrl& url, bool exactMatch) { Smb4KNetworkObject *object = 0; if (url.isValid()) { for (Smb4KNetworkObject *obj : d->mountedObjects) { if (url.matches(obj->url(), QUrl::None)) { object = obj; break; } else if (!exactMatch && url.matches(obj->url(), QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash)) { object = obj; continue; } else { continue; } } } return object; } void Smb4KDeclarative::print(Smb4KNetworkObject* object) { if (object && object->type() == Smb4KNetworkObject::Share) { SharePtr printer = Smb4KGlobal::findShare(object->url(), object->workgroupName()); if (printer) { Smb4KClient::self()->openPrintDialog(printer); } } } void Smb4KDeclarative::addBookmark(Smb4KNetworkObject* object) { if (object) { QList shares; // First, search the list of shares gathered by the scanner. for (const SharePtr &share : Smb4KGlobal::sharesList()) { if (share->url() == object->url()) { shares << share; break; } else { continue; } } // Second, if the list is still empty, try the list of mounted shares. if (shares.isEmpty()) { for (const SharePtr &mountedShare : Smb4KGlobal::mountedSharesList()) { if (mountedShare->url() == object->url()) { shares << mountedShare; break; } else { continue; } } } // Now add the share. if (!shares.isEmpty()) { for (const SharePtr &p : shares) { qDebug() << p->url(); } Smb4KBookmarkHandler::self()->addBookmarks(shares); } } } void Smb4KDeclarative::removeBookmark(Smb4KBookmarkObject* object) { if (object) { // // Find the bookmark in the list and remove it. // BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(object->url()); if (bookmark) { Smb4KBookmarkHandler::self()->removeBookmark(bookmark); } } } void Smb4KDeclarative::editBookmarks() { Smb4KBookmarkHandler::self()->editBookmarks(); } void Smb4KDeclarative::synchronize(Smb4KNetworkObject* object) { if (object && object->type() == Smb4KNetworkObject::Share) { for (const SharePtr &share : Smb4KGlobal::mountedSharesList()) { if (share->url() == object->url()) { Smb4KSynchronizer::self()->synchronize(share); } } } } void Smb4KDeclarative::openCustomOptionsDialog(Smb4KNetworkObject *object) { if (object) { switch (object->type()) { case Smb4KNetworkObject::Host: { for (const HostPtr &host : Smb4KGlobal::hostsList()) { if (host->url() == object->url()) { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(host); break; } else { continue; } } break; } case Smb4KNetworkObject::Share: { for (const SharePtr &share : Smb4KGlobal::sharesList()) { if (share->url() == object->url()) { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(share); break; } else { continue; } } break; } default: { break; } } } } void Smb4KDeclarative::startClient() { Smb4KClient::self()->start(); } void Smb4KDeclarative::abortClient() { Smb4KClient::self()->abort(); } void Smb4KDeclarative::startMounter() { Smb4KMounter::self()->start(); } void Smb4KDeclarative::abortMounter() { Smb4KMounter::self()->abort(); } QString Smb4KDeclarative::activeProfile() const { QString activeProfile; for (Smb4KProfileObject *profile : d->profileObjects) { if (profile->isActiveProfile()) { activeProfile = profile->profileName(); break; } else { continue; } } return activeProfile; } void Smb4KDeclarative::setActiveProfile(const QString& profile) { Smb4KProfileManager::self()->setActiveProfile(profile); } bool Smb4KDeclarative::profileUsage() const { return Smb4KProfileManager::self()->useProfiles(); } void Smb4KDeclarative::preview(Smb4KNetworkObject* object) { if (object->type() == Smb4KNetworkObject::Share) { SharePtr share = Smb4KGlobal::findShare(object->url(), object->workgroupName()); if (share) { Smb4KClient::self()->openPreviewDialog(share); } } } void Smb4KDeclarative::openConfigurationDialog() { // // Check if the configuration dialog exists and try to show it. // if (KConfigDialog::exists("Smb4KConfigDialog")) { KConfigDialog::showDialog("Smb4KConfigDialog"); return; } // // If the dialog does not exist, load and show it: // KPluginLoader loader("smb4kconfigdialog", this); KPluginFactory *configFactory = loader.factory(); if (configFactory) { KConfigDialog *dlg = configFactory->create(); if (dlg) { dlg->setObjectName("Smb4KConfigDialog"); dlg->show(); } } } void Smb4KDeclarative::slotWorkgroupsListChanged() { // (Re)fill the list of workgroup objects. while (!d->workgroupObjects.isEmpty()) { delete d->workgroupObjects.takeFirst(); } for (const WorkgroupPtr &workgroup : Smb4KGlobal::workgroupsList()) { d->workgroupObjects << new Smb4KNetworkObject(workgroup.data()); } emit workgroupsListChanged(); } void Smb4KDeclarative::slotHostsListChanged() { // (Re)fill the list of host object. while (!d->hostObjects.isEmpty()) { delete d->hostObjects.takeFirst(); } for (const HostPtr &host : Smb4KGlobal::hostsList()) { d->hostObjects << new Smb4KNetworkObject(host.data()); } emit hostsListChanged(); } void Smb4KDeclarative::slotSharesListChanged() { // (Re)fill the list of share objects. while (!d->shareObjects.isEmpty()) { delete d->shareObjects.takeFirst(); } for (const SharePtr &share : Smb4KGlobal::sharesList()) { d->shareObjects << new Smb4KNetworkObject(share.data()); } emit sharesListChanged(); } void Smb4KDeclarative::slotMountedSharesListChanged() { // (Re)fill the list of share objects. while (!d->mountedObjects.isEmpty()) { delete d->mountedObjects.takeFirst(); } for (const SharePtr &mountedShare : Smb4KGlobal::mountedSharesList()) { d->mountedObjects << new Smb4KNetworkObject(mountedShare.data()); } emit mountedSharesListChanged(); } void Smb4KDeclarative::slotBookmarksListChanged() { // (Re)fill the list of bookmark and group objects. while (!d->bookmarkObjects.isEmpty()) { delete d->bookmarkObjects.takeFirst(); } while (!d->bookmarkGroupObjects.isEmpty()) { delete d->bookmarkGroupObjects.takeFirst(); } for (const BookmarkPtr &bookmark : Smb4KBookmarkHandler::self()->bookmarksList()) { d->bookmarkObjects << new Smb4KBookmarkObject(bookmark.data()); } for (const QString &group : Smb4KBookmarkHandler::self()->groupsList()) { d->bookmarkGroupObjects << new Smb4KBookmarkObject(group); } emit bookmarksListChanged(); } void Smb4KDeclarative::slotProfilesListChanged(const QStringList& profiles) { while (!d->profileObjects.isEmpty()) { delete d->profileObjects.takeFirst(); } for (const QString &p : profiles) { Smb4KProfileObject *profile = new Smb4KProfileObject(); profile->setProfileName(p); if (QString::compare(p, Smb4KProfileManager::self()->activeProfile()) == 0) { profile->setActiveProfile(true); } else { profile->setActiveProfile(false); } d->profileObjects << profile; } emit profilesListChanged(); } void Smb4KDeclarative::slotActiveProfileChanged(const QString& activeProfile) { for (Smb4KProfileObject *profile : d->profileObjects) { if (QString::compare(profile->profileName(), activeProfile) == 0) { profile->setActiveProfile(true); } else { profile->setActiveProfile(false); } } emit activeProfileChanged(); } void Smb4KDeclarative::slotProfileUsageChanged(bool /*use*/) { emit profileUsageChanged(); } diff --git a/plasmoid/plugin/smb4kdeclarative_p.cpp b/plasmoid/plugin/smb4kdeclarative_p.cpp index 34c8aeb..ee21582 100644 --- a/plasmoid/plugin/smb4kdeclarative_p.cpp +++ b/plasmoid/plugin/smb4kdeclarative_p.cpp @@ -1,32 +1,28 @@ /*************************************************************************** This class provides helper classes for Smb4KDeclarative ------------------- begin : Mo 02 Sep 2013 copyright : (C) 2013-2017 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kdeclarative_p.h" diff --git a/plasmoid/plugin/smb4knetworkobject.cpp b/plasmoid/plugin/smb4knetworkobject.cpp index ccba476..86e2403 100644 --- a/plasmoid/plugin/smb4knetworkobject.cpp +++ b/plasmoid/plugin/smb4knetworkobject.cpp @@ -1,434 +1,430 @@ /*************************************************************************** This class derives from QObject and encapsulates the network items. It is for use with QtQuick. ------------------- begin : Fr Mär 02 2012 copyright : (C) 2012-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knetworkobject.h" #include "core/smb4kglobal.h" // Qt includes #include using namespace Smb4KGlobal; class Smb4KNetworkObjectPrivate { public: QString workgroup; QUrl url; int type; int parentType; QString comment; bool mounted; QUrl mountpoint; bool printer; bool isMaster; bool inaccessible; }; Smb4KNetworkObject::Smb4KNetworkObject(Smb4KWorkgroup *workgroup, QObject *parent) : QObject(parent), d(new Smb4KNetworkObjectPrivate) { d->workgroup = workgroup->workgroupName(); d->url = workgroup->url(); d->mounted = false; d->inaccessible = false; d->printer = false; d->isMaster = false; setType(Workgroup); } Smb4KNetworkObject::Smb4KNetworkObject(Smb4KHost *host, QObject *parent) : QObject(parent), d(new Smb4KNetworkObjectPrivate) { d->workgroup = host->workgroupName(); d->url = host->url(); d->comment = host->comment(); d->mounted = false; d->inaccessible = false; d->printer = false; d->isMaster = host->isMasterBrowser(); setType(Host); } Smb4KNetworkObject::Smb4KNetworkObject(Smb4KShare *share, QObject *parent) : QObject(parent), d(new Smb4KNetworkObjectPrivate) { d->workgroup = share->workgroupName(); d->url = share->url(); d->comment = share->comment(); d->mounted = share->isMounted(); d->inaccessible = share->isInaccessible(); d->printer = share->isPrinter(); d->isMaster = false; d->mountpoint = QUrl::fromLocalFile(share->path()); setType(Share); } Smb4KNetworkObject::Smb4KNetworkObject(QObject *parent) : QObject(parent), d(new Smb4KNetworkObjectPrivate) { d->url.setUrl("smb://", QUrl::TolerantMode); d->mounted = false; d->inaccessible = false; d->printer = false; d->isMaster = false; setType(Network); } Smb4KNetworkObject::~Smb4KNetworkObject() { } Smb4KNetworkObject::NetworkItem Smb4KNetworkObject::type() const { return static_cast(d->type); } Smb4KNetworkObject::NetworkItem Smb4KNetworkObject::parentType() const { return static_cast(d->parentType); } void Smb4KNetworkObject::setType(NetworkItem type) { d->type = type; switch (type) { case Host: { d->parentType = Workgroup; break; } case Share: { d->parentType = Host; break; } default: { d->parentType = Network; break; } } emit changed(); } QString Smb4KNetworkObject::workgroupName() const { return d->workgroup; } void Smb4KNetworkObject::setWorkgroupName(const QString& name) { d->workgroup = name; emit changed(); } QString Smb4KNetworkObject::hostName() const { return d->url.host().toUpper(); } void Smb4KNetworkObject::setHostName(const QString& name) { d->url.setHost(name); emit changed(); } bool Smb4KNetworkObject::isMasterBrowser() const { return d->isMaster; } void Smb4KNetworkObject::setMasterBrowser(bool master) { if (type() == Host) { d->isMaster = master; emit changed(); } } QString Smb4KNetworkObject::shareName() const { // Since users might come up with very weird share names, // we are careful and do not use QString::remove("/"), but // only remove preceding and trailing slashes. QString share_name = d->url.path(); if (share_name.startsWith('/')) { share_name = share_name.remove(0, 1); } if (share_name.endsWith('/')) { share_name = share_name.remove(share_name.size() - 1, 1); } return share_name; } void Smb4KNetworkObject::setShareName(const QString& name) { d->url.setPath(name); emit changed(); } QString Smb4KNetworkObject::name() const { QString name; switch (d->type) { case Workgroup: { name = workgroupName(); break; } case Host: { name = hostName(); break; } case Share: { name = shareName(); break; } default: { break; } } return name; } QString Smb4KNetworkObject::comment() const { return d->comment; } void Smb4KNetworkObject::setComment(const QString& comment) { d->comment = comment; emit changed(); } QUrl Smb4KNetworkObject::url() const { return d->url; } QUrl Smb4KNetworkObject::parentUrl() const { // Do not use QUrl::upUrl() here, because it produces // an URL like this: smb://HOST/Share/../ and we do not // want that. QUrl parent_url; parent_url.setUrl("smb://"); switch (d->type) { case Host: { parent_url.setHost(d->workgroup); break; } case Share: { parent_url.setHost(d->url.host()); break; } default: { break; } } return parent_url; } void Smb4KNetworkObject::setUrl(const QUrl& url) { d->url = url; emit changed(); } bool Smb4KNetworkObject::isMounted() const { return d->mounted; } void Smb4KNetworkObject::setMounted(bool mounted) { d->mounted = mounted; emit changed(); } void Smb4KNetworkObject::update(Smb4KBasicNetworkItem *networkItem) { if (d->type == Workgroup && networkItem->type() == Smb4KGlobal::Workgroup) { Smb4KWorkgroup *workgroup = static_cast(networkItem); if (workgroup) { // Check that we update with the correct item. if (QString::compare(workgroupName(), workgroup->workgroupName(), Qt::CaseInsensitive) == 0) { d->workgroup = workgroup->workgroupName(); d->url = workgroup->url(); d->type = Workgroup; d->mounted = false; d->inaccessible = false; d->printer = false; } } } else if (d->type == Host && networkItem->type() == Smb4KGlobal::Host) { Smb4KHost *host = static_cast(networkItem); if (host) { // Check that we update with the correct item. if (QString::compare(workgroupName(), host->workgroupName(), Qt::CaseInsensitive) == 0 && QString::compare(hostName(), host->hostName(), Qt::CaseInsensitive) == 0) { d->workgroup = host->workgroupName(); d->url = host->url(); d->comment = host->comment(); d->type = Host; d->mounted = false; d->inaccessible = false; d->printer = false; } } } else if (d->type == Share && networkItem->type() == Smb4KGlobal::Share) { Smb4KShare *share = static_cast(networkItem); if (share) { // Check that we update with the correct item. if (QString::compare(workgroupName(), share->workgroupName(), Qt::CaseInsensitive) == 0 && QString::compare(hostName(), share->hostName(), Qt::CaseInsensitive) == 0 && QString::compare(shareName(), share->shareName(), Qt::CaseInsensitive) == 0) { d->workgroup = share->workgroupName(); d->url = share->url(); d->comment = share->comment(); d->type = Share; d->mounted = share->isMounted(); d->inaccessible = share->isInaccessible(); d->printer = share->isPrinter(); d->mountpoint.setUrl(share->path(), QUrl::TolerantMode); d->mountpoint.setScheme("file"); } } } else { d->type = Network; } emit changed(); } bool Smb4KNetworkObject::isPrinter() const { return d->printer; } void Smb4KNetworkObject::setPrinter(bool printer) { d->printer = printer; emit changed(); } QUrl Smb4KNetworkObject::mountpoint() const { return d->mountpoint; } void Smb4KNetworkObject::setMountpoint(const QUrl &mountpoint) { d->mountpoint = mountpoint; emit changed(); } bool Smb4KNetworkObject::isInaccessible() const { return (d->mounted && d->inaccessible); } void Smb4KNetworkObject::setInaccessible(bool inaccessible) { d->inaccessible = inaccessible; } diff --git a/plasmoid/plugin/smb4kprofileobject.cpp b/plasmoid/plugin/smb4kprofileobject.cpp index b5eb3a5..e5c8844 100644 --- a/plasmoid/plugin/smb4kprofileobject.cpp +++ b/plasmoid/plugin/smb4kprofileobject.cpp @@ -1,80 +1,76 @@ /*************************************************************************** This class derives from QObject and encapsulates a profile item/name. It is for use with QtQuick. ------------------- begin : So 23 Nov 2014 copyright : (C) 2014-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kprofileobject.h" class Smb4KProfileObjectPrivate { public: QString profileName; bool activeProfile; }; Smb4KProfileObject::Smb4KProfileObject(QObject* parent) : QObject(parent), d(new Smb4KProfileObjectPrivate) { d->profileName = QString(); d->activeProfile = false; } Smb4KProfileObject::~Smb4KProfileObject() { } QString Smb4KProfileObject::profileName() const { return d->profileName; } void Smb4KProfileObject::setProfileName(const QString& profileName) { d->profileName = profileName; emit changed(); } bool Smb4KProfileObject::isActiveProfile() const { return d->activeProfile; } void Smb4KProfileObject::setActiveProfile(bool active) { d->activeProfile = active; emit changed(); } diff --git a/plasmoid/plugin/smb4kqmlplugin.cpp b/plasmoid/plugin/smb4kqmlplugin.cpp index ef66d87..9c6ad77 100644 --- a/plasmoid/plugin/smb4kqmlplugin.cpp +++ b/plasmoid/plugin/smb4kqmlplugin.cpp @@ -1,50 +1,46 @@ /*************************************************************************** smb4kqmlplugin - The QML plugin for use with Plasma/QtQuick ------------------- begin : Di Feb 21 2012 copyright : (C) 2012-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kqmlplugin.h" #include "smb4kbookmarkobject.h" #include "smb4kdeclarative.h" #include "smb4knetworkobject.h" #include "smb4kprofileobject.h" #include "core/smb4kglobal.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kcustomoptionsmanager.h" // Qt includes #include void Smb4KQMLPlugin::registerTypes(const char *uri) { qmlRegisterType(uri, 2, 0, "NetworkObject"); qmlRegisterType(uri, 2, 0, "BookmarkObject"); qmlRegisterType(uri, 2, 0, "ProfileObject"); qmlRegisterType(uri, 2, 0, "Interface"); } diff --git a/smb4k/smb4kbookmarkmenu.cpp b/smb4k/smb4kbookmarkmenu.cpp index 4b78a6d..350e12e 100644 --- a/smb4k/smb4kbookmarkmenu.cpp +++ b/smb4k/smb4kbookmarkmenu.cpp @@ -1,585 +1,581 @@ /*************************************************************************** smb4kbookmarkmenu - Bookmark menu ------------------- begin : Sat Apr 02 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kbookmarkmenu.h" #include "core/smb4kbookmark.h" #include "core/smb4kshare.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kmounter.h" #include "core/smb4ksettings.h" #include "core/smb4kglobal.h" // Qt includes #include #include #include // KDE includes #include #include using namespace Smb4KGlobal; Smb4KBookmarkMenu::Smb4KBookmarkMenu(int type, QWidget *parentWidget, QObject *parent) : KActionMenu(KDE::icon("folder-favorites"), i18n("Bookmarks"), parent), m_type(type), m_parent_widget(parentWidget) { // // Set up the action group for the actions // m_actions = new QActionGroup(menu()); // // Set up the action group for the bookmarks // m_bookmarks = new QActionGroup(menu()); // Set up the menu setupMenu(); // Connections connect(Smb4KBookmarkHandler::self(), SIGNAL(updated()), SLOT(slotBookmarksUpdated())); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), SLOT(slotEnableBookmark(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), SLOT(slotEnableBookmark(SharePtr))); connect(m_actions, SIGNAL(triggered(QAction*)), SLOT(slotGroupActionTriggered(QAction*))); connect(m_bookmarks, SIGNAL(triggered(QAction*)), SLOT(slotBookmarkActionTriggered(QAction*))); } Smb4KBookmarkMenu::~Smb4KBookmarkMenu() { } void Smb4KBookmarkMenu::refreshMenu() { // // Delete all entries from the menu // while (!menu()->actions().isEmpty()) { QAction *action = menu()->actions().takeFirst(); removeAction(action); delete action; } // // Clear the rest of the menu // if (!menu()->isEmpty()) { menu()->clear(); } // // Set up the menu // setupMenu(); // // Make sure the correct menu entries are shown // menu()->update(); } void Smb4KBookmarkMenu::setBookmarkActionEnabled(bool enable) { QAction *action = menu()->findChild("add_action"); if (action) { action->setEnabled(enable); } } void Smb4KBookmarkMenu::setupMenu() { // // Depending on the type chosen, some global actions need to be inserted // into the menu. These actions are always enabled. // switch (m_type) { case MainWindow: { QAction *editBookmarksAction = new QAction(KDE::icon("bookmarks-organize"), i18n("&Edit Bookmarks"), menu()); editBookmarksAction->setObjectName("edit_action"); QMap editInfo; editInfo["type"] = "edit"; editBookmarksAction->setData(editInfo); connect(editBookmarksAction, SIGNAL(triggered(bool)), SLOT(slotEditActionTriggered(bool))); addAction(editBookmarksAction); m_actions->addAction(editBookmarksAction); QAction *addBookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), menu()); addBookmarkAction->setObjectName("add_action"); QMap addInfo; addInfo["type"] = "add"; addBookmarkAction->setData(addInfo); addBookmarkAction->setEnabled(false); connect(addBookmarkAction, SIGNAL(triggered(bool)), SLOT(slotAddActionTriggered(bool))); addAction(addBookmarkAction); m_actions->addAction(addBookmarkAction); break; } case SystemTray: { QAction *editBookmarksAction = new QAction(KDE::icon("bookmarks-organize"), i18n("&Edit Bookmarks"), menu()); editBookmarksAction->setObjectName("edit_action"); QMap editInfo; editInfo["type"] = "edit"; editBookmarksAction->setData(editInfo); connect(editBookmarksAction, SIGNAL(triggered(bool)), SLOT(slotEditActionTriggered(bool))); addAction(editBookmarksAction); m_actions->addAction(editBookmarksAction); break; } default: { break; } } // // Get the list of groups // QStringList allGroups = Smb4KBookmarkHandler::self()->groupsList(); allGroups.sort(); // // Insert a toplevel mount action, if necessary. Crucial for this is that there are // no (non-empty) groups defined. Enable it if not all toplevel bookmarks are mounted. // if (allGroups.isEmpty() || (allGroups.size() == 1 && allGroups.first().isEmpty())) { QAction *toplevelMount = new QAction(KDE::icon("media-mount"), i18n("Mount All Bookmarks"), menu()); toplevelMount->setObjectName("toplevel_mount"); QMap mountInfo; mountInfo["type"] = "toplevel_mount"; toplevelMount->setData(mountInfo); connect(toplevelMount, SIGNAL(triggered(bool)), SLOT(slotToplevelMountActionTriggered(bool))); addAction(toplevelMount); m_actions->addAction(toplevelMount); QList bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(); int mountedBookmarks = 0; for (const BookmarkPtr &bookmark : bookmarks) { QList mountedShares = findShareByUrl(bookmark->url()); if (!mountedShares.isEmpty()) { for (const SharePtr &share : mountedShares) { if (!share->isForeign()) { mountedBookmarks++; break; } else { continue; } } } } toplevelMount->setEnabled(mountedBookmarks != bookmarks.size()); } // // Add a separator // addSeparator(); // // Now add the groups and their bookmarks // for (const QString &group : allGroups) { if (!group.isEmpty()) { // Group menu entry KActionMenu *bookmarkGroupMenu = new KActionMenu(group, menu()); bookmarkGroupMenu->setIcon(KDE::icon("folder-favorites")); QMap menuInfo; menuInfo["type"] = "group_menu"; menuInfo["group"] = group; bookmarkGroupMenu->setData(menuInfo); addAction(bookmarkGroupMenu); // Mount action for the group QAction *bookmarkGroupMount = new QAction(KDE::icon("media-mount"), i18n("Mount All Bookmarks"), bookmarkGroupMenu->menu()); QMap groupMountInfo; groupMountInfo["type"] = "group_mount"; groupMountInfo["group"] = group; bookmarkGroupMount->setData(groupMountInfo); bookmarkGroupMenu->addAction(bookmarkGroupMount); m_actions->addAction(bookmarkGroupMount); // Get the list of bookmarks belonging to this group. // Use it to decide whether the group mount action should be enabled // (only if not all bookmarks belonging to this group are mounted) and // to sort the bookmarks. QList bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(group); QStringList sortedBookmarks; int mountedBookmarks = 0; for (const BookmarkPtr &bookmark : bookmarks) { QAction *bookmarkAction = 0; if (Smb4KSettings::showCustomBookmarkLabel() && !bookmark->label().isEmpty()) { bookmarkAction = new QAction(bookmark->icon(), bookmark->label(), bookmarkGroupMenu->menu()); bookmarkAction->setObjectName(bookmark->url().toDisplayString()); QMap bookmarkInfo; bookmarkInfo["type"] = "bookmark"; bookmarkInfo["group"] = group; bookmarkInfo["url"] = bookmark->url(); bookmarkInfo["text"] = bookmark->label(); bookmarkAction->setData(bookmarkInfo); m_bookmarks->addAction(bookmarkAction); sortedBookmarks << bookmark->label(); } else { bookmarkAction = new QAction(bookmark->icon(), bookmark->displayString(), bookmarkGroupMenu->menu()); bookmarkAction->setObjectName(bookmark->url().toDisplayString()); QMap bookmarkInfo; bookmarkInfo["type"] = "bookmark"; bookmarkInfo["group"] = group; bookmarkInfo["url"] = bookmark->url(); bookmarkInfo["text"] = bookmark->displayString(); bookmarkAction->setData(bookmarkInfo); m_bookmarks->addAction(bookmarkAction); sortedBookmarks << bookmark->displayString(); } QList mountedShares = findShareByUrl(bookmark->url()); if (!mountedShares.isEmpty()) { for (const SharePtr &share : mountedShares) { if (!share->isForeign()) { bookmarkAction->setEnabled(false); mountedBookmarks++; break; } else { continue; } } } } bookmarkGroupMount->setEnabled(mountedBookmarks != bookmarks.size()); sortedBookmarks.sort(); // Add a separator bookmarkGroupMenu->addSeparator(); // Insert the sorted bookmarks into the group menu QList actions = m_bookmarks->actions(); for (const QString &b : sortedBookmarks) { for (QAction *a : actions) { if (a->text() == b) { bookmarkGroupMenu->addAction(a); break; } else { continue; } } } } } // // Add all bookmarks that have no group // Sort the bookmarks before. // QList bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(""); QStringList sortedBookmarks; for (const BookmarkPtr &bookmark : bookmarks) { QAction *bookmarkAction = 0; if (Smb4KSettings::showCustomBookmarkLabel() && !bookmark->label().isEmpty()) { bookmarkAction = new QAction(bookmark->icon(), bookmark->label(), menu()); bookmarkAction->setObjectName(bookmark->url().toDisplayString()); QMap bookmarkInfo; bookmarkInfo["type"] = "bookmark"; bookmarkInfo["group"] = ""; bookmarkInfo["url"] = bookmark->url(); bookmarkInfo["text"] = bookmark->label(); bookmarkAction->setData(bookmarkInfo); m_bookmarks->addAction(bookmarkAction); sortedBookmarks << bookmark->label(); } else { bookmarkAction = new QAction(bookmark->icon(), bookmark->displayString(), menu()); bookmarkAction->setObjectName(bookmark->url().toDisplayString()); QMap bookmarkInfo; bookmarkInfo["type"] = "bookmark"; bookmarkInfo["group"] = ""; bookmarkInfo["url"] = bookmark->url(); bookmarkInfo["text"] = bookmark->displayString(); bookmarkAction->setData(bookmarkInfo); m_bookmarks->addAction(bookmarkAction); sortedBookmarks << bookmark->displayString(); } QList mountedShares = findShareByUrl(bookmark->url()); if (!mountedShares.isEmpty()) { for (const SharePtr &share : mountedShares) { if (!share->isForeign()) { bookmarkAction->setEnabled(false); break; } else { continue; } } } } sortedBookmarks.sort(); QList actions = m_bookmarks->actions(); for (const QString &b : sortedBookmarks) { for (QAction *a : actions) { if (a->data().toMap().value("text").toString() == b) { addAction(a); break; } else { continue; } } } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KBookmarkMenu::slotEditActionTriggered(bool /*checked*/) { Smb4KBookmarkHandler::self()->editBookmarks(); } void Smb4KBookmarkMenu::slotAddActionTriggered(bool /*checked*/) { emit addBookmark(); } void Smb4KBookmarkMenu::slotToplevelMountActionTriggered(bool /*checked*/) { // // Mount all top level bookmarks. // This slot will only be called if there are no groups defined. // QList bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(); QList mounts; for (const BookmarkPtr &bookmark : bookmarks) { // FIXME: Check if the bookmarked share has already been mounted. SharePtr share = SharePtr(new Smb4KShare()); share->setHostName(bookmark->hostName()); share->setShareName(bookmark->shareName()); share->setWorkgroupName(bookmark->workgroupName()); share->setHostIpAddress(bookmark->hostIpAddress()); share->setLogin(bookmark->login()); mounts << share; } Smb4KMounter::self()->mountShares(mounts); while (!mounts.isEmpty()) { mounts.takeFirst().clear(); } } void Smb4KBookmarkMenu::slotGroupActionTriggered(QAction *action) { if (action->data().toMap().value("type").toString() == "group_mount") { // // Mount all bookmarks of one group // QList bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(action->data().toMap().value("group").toString()); QList mounts; for (const BookmarkPtr &bookmark : bookmarks) { // FIXME: Check if the bookmarked share has already been mounted. SharePtr share = SharePtr(new Smb4KShare()); share->setHostName(bookmark->hostName()); share->setShareName(bookmark->shareName()); share->setWorkgroupName(bookmark->workgroupName()); share->setHostIpAddress(bookmark->hostIpAddress()); share->setLogin(bookmark->login()); mounts << share; } Smb4KMounter::self()->mountShares(mounts); while (!mounts.isEmpty()) { mounts.takeFirst().clear(); } } } void Smb4KBookmarkMenu::slotBookmarkActionTriggered(QAction *action) { QMap info = action->data().toMap(); QString bookmarkGroup = info.value("group").toString(); QUrl url = info.value("url").toUrl(); BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(url); if (bookmark && bookmarkGroup == bookmark->groupName()) { SharePtr share = SharePtr(new Smb4KShare()); share->setHostName(bookmark->hostName()); share->setShareName(bookmark->shareName()); share->setWorkgroupName(bookmark->workgroupName()); share->setHostIpAddress(bookmark->hostIpAddress()); share->setLogin(bookmark->login()); Smb4KMounter::self()->mountShare(share); share.clear(); } } void Smb4KBookmarkMenu::slotBookmarksUpdated() { refreshMenu(); } void Smb4KBookmarkMenu::slotEnableBookmark(const SharePtr &share) { if (!share->isForeign() && !m_bookmarks->actions().isEmpty()) { // // Enable or disable the bookmark // QList actions = m_bookmarks->actions(); QString bookmarkGroup; for (QAction *a : actions) { if (share->url() == a->data().toMap().value("url").toUrl()) { a->setEnabled(!share->isMounted()); bookmarkGroup = a->data().toMap().value("group").toString(); break; } } // // Check if all bookmarks belonging to this group are // mounted. Enable the respective mount action if necessary. // bool allMounted = true; for (QAction *a : actions) { if (a->data().toMap().value("group").toString() == bookmarkGroup && a->isEnabled()) { allMounted = false; break; } else { continue; } } QList allActions = m_actions->actions(); for (QAction *a : allActions) { if (a->data().toMap().value("type").toString() == "toplevel_mount" && bookmarkGroup.isEmpty()) { a->setEnabled(!allMounted); break; } else if (a->data().toMap().value("type").toString() == "group_mount" && a->data().toMap().value("group").toString() == bookmarkGroup) { a->setEnabled(!allMounted); break; } else { continue; } } } } diff --git a/smb4k/smb4kconfigdialog.cpp b/smb4k/smb4kconfigdialog.cpp index 62e6993..2b0259e 100644 --- a/smb4k/smb4kconfigdialog.cpp +++ b/smb4k/smb4kconfigdialog.cpp @@ -1,727 +1,723 @@ /*************************************************************************** The configuration dialog of Smb4K ------------------- begin : Sa Apr 14 2007 copyright : (C) 2004-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigdialog.h" #include "smb4kconfigpageauthentication.h" #include "smb4kconfigpagecustomoptions.h" #include "smb4kconfigpagemounting.h" #include "smb4kconfigpagenetwork.h" #include "smb4kconfigpageprofiles.h" #include "smb4kconfigpagesynchronization.h" #include "smb4kconfigpageuserinterface.h" #include "core/smb4ksettings.h" #include "core/smb4kglobal.h" #include "core/smb4kauthinfo.h" #include "core/smb4kwalletmanager.h" #include "core/smb4kcustomoptions.h" #include "core/smb4kcustomoptionsmanager.h" #include "core/smb4kprofilemanager.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include using namespace Smb4KGlobal; K_PLUGIN_FACTORY(Smb4KConfigDialogFactory, registerPlugin();) Smb4KConfigDialog::Smb4KConfigDialog(QWidget *parent, const QList &/*args*/) : KConfigDialog(parent, "ConfigDialog", Smb4KSettings::self()) { setupDialog(); } Smb4KConfigDialog::~Smb4KConfigDialog() { } void Smb4KConfigDialog::setupDialog() { // FIXME: I guess, normally we would not need to close destructively, // but at the moment there are issues with the KURLRequester in file // mode. To work around those, we are closing the dialog destructively. // Maybe we can remove this if we moved to KDE4. setAttribute(Qt::WA_DeleteOnClose, true); // Add the pages: Smb4KConfigPageUserInterface *interface_options = new Smb4KConfigPageUserInterface(this); QScrollArea *interface_area = new QScrollArea(this); interface_area->setWidget(interface_options); interface_area->setWidgetResizable(true); interface_area->setFrameStyle(QFrame::NoFrame); Smb4KConfigPageNetwork *network_options = new Smb4KConfigPageNetwork(this); QScrollArea *network_area = new QScrollArea(this); network_area->setWidget(network_options); network_area->setWidgetResizable(true); network_area->setFrameStyle(QFrame::NoFrame); Smb4KConfigPageMounting *mount_options = new Smb4KConfigPageMounting(this); QScrollArea *mount_area = new QScrollArea(this); mount_area->setWidget(mount_options); mount_area->setWidgetResizable(true); mount_area->setFrameStyle(QFrame::NoFrame); Smb4KConfigPageAuthentication *auth_options = new Smb4KConfigPageAuthentication(this); QScrollArea *auth_area = new QScrollArea(this); auth_area->setWidget(auth_options); auth_area->setWidgetResizable(true); auth_area->setFrameStyle(QFrame::NoFrame); Smb4KConfigPageSynchronization *rsync_options = new Smb4KConfigPageSynchronization(this); QScrollArea *rsync_area = new QScrollArea(this); rsync_area->setWidget(rsync_options); rsync_area->setWidgetResizable(true); rsync_area->setFrameStyle(QFrame::NoFrame); rsync_options->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty()); Smb4KConfigPageCustomOptions *custom_options = new Smb4KConfigPageCustomOptions(this); QScrollArea *custom_area = new QScrollArea(this); custom_area->setWidget(custom_options); custom_area->setWidgetResizable(true); custom_area->setFrameStyle(QFrame::NoFrame); Smb4KConfigPageProfiles *profiles_page = new Smb4KConfigPageProfiles(this); QScrollArea *profiles_area = new QScrollArea(this); profiles_area->setWidget(profiles_page); profiles_area->setWidgetResizable(true); profiles_area->setFrameStyle(QFrame::NoFrame); // // Pages to the configuration dialog // m_user_interface = addPage(interface_area, Smb4KSettings::self(), i18n("User Interface"), "preferences-desktop"); m_network = addPage(network_area, Smb4KSettings::self(), i18n("Network"), "network-workgroup"); m_mounting = addPage(mount_area, Smb4KMountSettings::self(), i18n("Mounting"), "system-run"); m_authentication = addPage(auth_area, Smb4KSettings::self(), i18n("Authentication"), "dialog-password"); m_synchronization = addPage(rsync_area, Smb4KSettings::self(),i18n("Synchronization"), "folder-sync"); m_custom_options = addPage(custom_area, Smb4KSettings::self(), i18n("Custom Options"), "preferences-system-network"); m_profiles = addPage(profiles_area, Smb4KSettings::self(), i18n("Profiles"), "format-list-unordered"); // // Connections // connect(custom_options, SIGNAL(customSettingsModified()), this, SLOT(slotEnableApplyButton())); connect(auth_options, SIGNAL(loadWalletEntries()), this, SLOT(slotLoadAuthenticationInformation())); connect(auth_options, SIGNAL(saveWalletEntries()), this, SLOT(slotSaveAuthenticationInformation())); connect(auth_options, SIGNAL(setDefaultLogin()), this, SLOT(slotSetDefaultLogin())); connect(auth_options, SIGNAL(walletEntriesModified()), this, SLOT(slotEnableApplyButton())); connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slotCheckPage(KPageWidgetItem*,KPageWidgetItem*))); // // Dialog size // create(); windowHandle()->resize(QSize(800, 600)); KConfigGroup group(Smb4KSettings::self()->config(), "ConfigDialog"); KWindowConfig::restoreWindowSize(windowHandle(), group); resize(windowHandle()->size()); // workaround for QTBUG-40584 } void Smb4KConfigDialog::loadCustomOptions() { if (m_custom_options) { QList options = Smb4KCustomOptionsManager::self()->customOptions(); m_custom_options->widget()->findChild()->insertCustomOptions(options); } } void Smb4KConfigDialog::saveCustomOptions() { if (m_custom_options) { QList options = m_custom_options->widget()->findChild()->getCustomOptions(); Smb4KCustomOptionsManager::self()->replaceCustomOptions(options); } } void Smb4KConfigDialog::propagateProfilesChanges() { Smb4KConfigPageProfiles *profiles_page = m_profiles->widget()->findChild(); if (profiles_page) { // Remove the profiles. QStringList removed_profiles = profiles_page->removedProfiles(); if (!removed_profiles.isEmpty()) { Smb4KProfileManager::self()->removeProfiles(removed_profiles); profiles_page->clearRemovedProfiles(); } // Rename the profiles. QList< QPair > renamed_profiles = profiles_page->renamedProfiles(); if (!renamed_profiles.isEmpty()) { Smb4KProfileManager::self()->migrateProfiles(renamed_profiles); profiles_page->clearRenamedProfiles(); } // Finally reload the custom options. if (!removed_profiles.isEmpty() || !renamed_profiles.isEmpty()) { loadCustomOptions(); } } } bool Smb4KConfigDialog::checkNetworkPage() { QRadioButton *query_custom_master = m_network->widget()->findChild("kcfg_QueryCustomMaster"); KLineEdit *custom_master_input = m_network->widget()->findChild("kcfg_CustomMasterBrowser"); QString msg = i18n("An incorrect setting has been found. You are now taken to the corresponding configuration page to fix it."); if ((query_custom_master && query_custom_master->isChecked()) && (custom_master_input && custom_master_input->text().trimmed().isEmpty())) { KMessageBox::sorry(this, msg); setCurrentPage(m_network); custom_master_input->setFocus(); return false; } QRadioButton *scan_bcast_areas = m_network->widget()->findChild("kcfg_ScanBroadcastAreas"); KLineEdit *bcast_areas_input = m_network->widget()->findChild("kcfg_BroadcastAreas"); if ((scan_bcast_areas && scan_bcast_areas->isChecked()) && (bcast_areas_input && bcast_areas_input->text().trimmed().isEmpty())) { KMessageBox::sorry(this, msg); setCurrentPage(m_network); bcast_areas_input->setFocus(); return false; } return true; } bool Smb4KConfigDialog::checkMountingPage() { KUrlRequester *mount_prefix = m_mounting->widget()->findChild("kcfg_MountPrefix"); QString msg = i18n("An incorrect setting has been found. You are now taken to the corresponding configuration page to fix it."); if (mount_prefix && mount_prefix->url().path().trimmed().isEmpty()) { KMessageBox::sorry(this, msg); setCurrentPage(m_mounting); mount_prefix->setFocus(); return false; } KLineEdit *file_mask = m_mounting->widget()->findChild("kcfg_FileMask"); msg = i18n("An incorrect setting has been found. You are now taken to the corresponding configuration page to fix it."); if (file_mask && file_mask->text().trimmed().isEmpty()) { KMessageBox::sorry(this, msg); setCurrentPage(m_mounting); file_mask->setFocus(); return false; } KLineEdit *directory_mask = m_mounting->widget()->findChild("kcfg_DirectoryMask"); if (directory_mask && directory_mask->text().trimmed().isEmpty()) { KMessageBox::sorry(this, msg); setCurrentPage(m_mounting); directory_mask->setFocus(); return false; } return true; } bool Smb4KConfigDialog::checkSynchronizationPage() { // // Get the config page // Since the config page is embedded into a scroll area, use findChild() here. // Smb4KConfigPageSynchronization *configPage = m_synchronization->widget()->findChild(); if (configPage) { // // The error message // QString errorMessage = i18n("An incorrect setting has been found. You are now taken to the corresponding configuration page to fix it."); // Find the tab number and the url requester for (int i = 0; i < configPage->count(); i++) { // Synchronization prefix KUrlRequester *syncPrefix = configPage->widget(i)->findChild("kcfg_RsyncPrefix"); if (syncPrefix && (!syncPrefix->url().isValid() || syncPrefix->url().path().trimmed().isEmpty())) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); syncPrefix->setFocus(); return false; } // Backups QCheckBox *makeBackups = configPage->widget(i)->findChild("kcfg_MakeBackups"); QCheckBox *useBackupSuffix = configPage->widget(i)->findChild("kcfg_UseBackupSuffix"); KLineEdit *backupSuffix = configPage->widget(i)->findChild("kcfg_BackupSuffix"); QCheckBox *useBackupDir = configPage->widget(i)->findChild("kcfg_UseBackupDirectory"); KUrlRequester *backupDir = configPage->widget(i)->findChild("kcfg_BackupDirectory"); if (makeBackups && makeBackups->isChecked()) { if (useBackupSuffix && useBackupSuffix->isChecked()) { if (backupSuffix && backupSuffix->text().trimmed().isEmpty()) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); backupSuffix->setFocus(); return false; } } if (useBackupDir && useBackupDir->isChecked()) { if (backupDir && (!backupDir->url().isValid() || backupDir->url().path().trimmed().isEmpty())) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); backupDir->setFocus(); return false; } } } // Minimal transfer size QCheckBox *useMinTransferSize = configPage->widget(i)->findChild("kcfg_UseMinimalTransferSize"); QSpinBox *minTransferSize = configPage->widget(i)->findChild("kcfg_MinimalTransferSize"); if (useMinTransferSize && useMinTransferSize->isChecked()) { if (minTransferSize && minTransferSize->value() == 0) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); minTransferSize->setFocus(); return false; } } // Maximal transfer size QCheckBox *useMaxTransferSize = configPage->widget(i)->findChild("kcfg_UseMaximalTransferSize"); QSpinBox *maxTransferSize = configPage->widget(i)->findChild("kcfg_MaximalTransferSize"); if (useMaxTransferSize && useMaxTransferSize->isChecked()) { if (maxTransferSize && maxTransferSize->value() == 0) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); maxTransferSize->setFocus(); return false; } } // Partial directory QCheckBox *usePartialDirectory = configPage->widget(i)->findChild("kcfg_UsePartialDirectory"); KUrlRequester *partialDirectory = configPage->widget(i)->findChild("kcfg_PartialDirectory"); if (usePartialDirectory && usePartialDirectory->isChecked()) { if (partialDirectory && (!partialDirectory->url().isValid() || partialDirectory->url().path().trimmed().isEmpty())) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); partialDirectory->setFocus(); return false; } } // Exclude exclude QCheckBox *useExcludePattern = configPage->widget(i)->findChild("kcfg_UseExcludePattern"); KLineEdit *excludePattern = configPage->widget(i)->findChild("kcfg_ExcludePattern"); if (useExcludePattern && useExcludePattern->isChecked()) { if (excludePattern && excludePattern->text().trimmed().isEmpty()) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); excludePattern->setFocus(); return false; } } // Read exclude pattern from file QCheckBox *useExcludeFrom = configPage->widget(i)->findChild("kcfg_UseExcludeFrom"); KUrlRequester *excludeFrom = configPage->widget(i)->findChild("kcfg_ExcludeFrom"); if (useExcludeFrom && useExcludeFrom->isChecked()) { if (excludeFrom && (!excludeFrom->url().isValid() || excludeFrom->url().path().trimmed().isEmpty())) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); excludeFrom->setFocus(); return false; } } // Exclude exclude QCheckBox *useIncludePattern = configPage->widget(i)->findChild("kcfg_UseIncludePattern"); KLineEdit *includePattern = configPage->widget(i)->findChild("kcfg_IncludePattern"); if (useIncludePattern && useIncludePattern->isChecked()) { if (includePattern && includePattern->text().trimmed().isEmpty()) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); includePattern->setFocus(); return false; } } // Read exclude pattern from file QCheckBox *useIncludeFrom = configPage->widget(i)->findChild("kcfg_UseIncludeFrom"); KUrlRequester *includeFrom = configPage->widget(i)->findChild("kcfg_IncludeFrom"); if (useIncludeFrom && useIncludeFrom->isChecked()) { if (includeFrom && (!includeFrom->url().isValid() || includeFrom->url().path().trimmed().isEmpty())) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); includeFrom->setFocus(); return false; } } // Block size QCheckBox *useFixedBlocksize = configPage->widget(i)->findChild("kcfg_UseBlockSize"); QSpinBox *fixedBlocksize = configPage->widget(i)->findChild("kcfg_BlockSize"); if (useFixedBlocksize && useFixedBlocksize->isChecked()) { if (fixedBlocksize && fixedBlocksize->value() == 0) { KMessageBox::sorry(this, errorMessage); setCurrentPage(m_synchronization); configPage->setCurrentIndex(i); fixedBlocksize->setFocus(); return false; } } // NOTE: The is no need to check the following settings, because they may be empty or 0: // - kcfg_UseCompressionLevel & kcfg_CompressionLevel // - kcfg_UseSkipCompression & kcfg_SkipCompression // - kcfg_UseBandwidthLimit & kcfg_BandwidthLimit // - kcfg_UseMaximumDelete & kcfg_MaximumDeleteValue // - kcfg_CustomFilteringRules // - kcfg_UseChecksumSeed & kcfg_ChecksumSeed } } return true; } bool Smb4KConfigDialog::checkSettings() { // Check Network page if (!checkNetworkPage()) { return false; } // Check Mounting page if (!checkMountingPage()) { return false; } // Check Synchronization page if (!checkSynchronizationPage()) { return false; } return true; } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KConfigDialog::updateSettings() { saveCustomOptions(); slotSaveAuthenticationInformation(); propagateProfilesChanges(); (void)checkSettings(); KConfigGroup group(Smb4KSettings::self()->config(), "ConfigDialog"); KWindowConfig::saveWindowSize(windowHandle(), group); KConfigDialog::updateSettings(); } void Smb4KConfigDialog::updateWidgets() { loadCustomOptions(); KConfigDialog::updateWidgets(); } void Smb4KConfigDialog::reject() { Smb4KCustomOptionsManager::self()->resetCustomOptions(); QDialog::reject(); } void Smb4KConfigDialog::slotLoadAuthenticationInformation() { // // Get the Authentication config page // Smb4KConfigPageAuthentication *authenticationPage = m_authentication->widget()->findChild(); // // Insert and display the wallet entries // authenticationPage->insertWalletEntries(Smb4KWalletManager::self()->walletEntries()); } void Smb4KConfigDialog::slotSaveAuthenticationInformation() { // // Get the Authentication config page // Smb4KConfigPageAuthentication *authenticationPage = m_authentication->widget()->findChild(); // // Save the authentication information to the wallet // if (authenticationPage->walletEntriesDisplayed()) { Smb4KWalletManager::self()->writeWalletEntries(authenticationPage->getWalletEntries()); } } void Smb4KConfigDialog::slotSetDefaultLogin() { // // Get the Authentication config page // Smb4KConfigPageAuthentication *authenticationPage = m_authentication->widget()->findChild(); // // Create an authentication object for the default authentication information // Smb4KAuthInfo authInfo; // // Read the default authentication information // Smb4KWalletManager::self()->readDefaultAuthInfo(&authInfo); // // Show the password dialog to enter or modify the default authentication // information. // QPointer dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine); dlg->setPrompt(i18n("Enter the default login information.")); dlg->setUsername(authInfo.userName()); dlg->setPassword(authInfo.password()); if (dlg->exec() == KPasswordDialog::Accepted) { // // Save the authentication information to the wallet // authInfo.setUserName(dlg->username()); authInfo.setPassword(dlg->password()); Smb4KWalletManager::self()->writeDefaultAuthInfo(&authInfo); // // Reload the list of authentication information // if (authenticationPage->walletEntriesDisplayed()) { slotLoadAuthenticationInformation(); } } else { // // Discard the password dialog and reset the checkbox // authenticationPage->findChild("kcfg_UseDefaultLogin")->setChecked(false); } delete dlg; } void Smb4KConfigDialog::slotEnableApplyButton() { // // Check if we need to enable the Apply button // bool enable = false; // // Check the wallet entries // Smb4KConfigPageAuthentication *authenticationPage = m_authentication->widget()->findChild(); if (authenticationPage->walletEntriesMaybeChanged()) { QList oldWalletEntries = Smb4KWalletManager::self()->walletEntries(); QList newWalletEntries = authenticationPage->getWalletEntries(); for (Smb4KAuthInfo *oldEntry : oldWalletEntries) { for (Smb4KAuthInfo *newEntry : newWalletEntries) { if (QString::compare(oldEntry->url().toString(QUrl::RemovePort), newEntry->url().toString(QUrl::RemovePort), Qt::CaseInsensitive) == 0 /* leave the user info here */ && QString::compare(oldEntry->workgroupName(), newEntry->workgroupName(), Qt::CaseInsensitive) == 0) { enable = true; break; } } if (enable) { break; } } } // // Check the custom options // Smb4KConfigPageCustomOptions *customOptionsPage = m_custom_options->widget()->findChild(); if (!enable && customOptionsPage && customOptionsPage->customSettingsMaybeChanged()) { enable = true; } QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply); if (applyButton) { applyButton->setEnabled(enable); } } void Smb4KConfigDialog::slotCheckPage(KPageWidgetItem* /*current*/, KPageWidgetItem* before) { if (before == m_network) { (void)checkNetworkPage(); } else if (before == m_mounting) { (void)checkMountingPage(); } else if (before == m_synchronization) { (void)checkSynchronizationPage(); } } #include "smb4kconfigdialog.moc" diff --git a/smb4k/smb4kconfigpageauthentication.cpp b/smb4k/smb4kconfigpageauthentication.cpp index 1fbfd37..f42fadd 100644 --- a/smb4k/smb4kconfigpageauthentication.cpp +++ b/smb4k/smb4kconfigpageauthentication.cpp @@ -1,739 +1,735 @@ /*************************************************************************** The configuration page for the authentication settings of Smb4K ------------------- begin : Sa Nov 15 2003 copyright : (C) 2003-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpageauthentication.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include Smb4KConfigPageAuthentication::Smb4KConfigPageAuthentication(QWidget *parent) : QWidget(parent) { m_entries_displayed = false; m_maybe_changed = false; // // Layout // QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); layout->setMargin(0); // // Settings group box // QGroupBox *settingsBox = new QGroupBox(i18n("Settings"), this); QVBoxLayout *settingsBoxLayout = new QVBoxLayout(settingsBox); settingsBoxLayout->setSpacing(5); // Wallet usage QCheckBox *useWallet = new QCheckBox(Smb4KSettings::self()->useWalletItem()->label(), settingsBox); useWallet->setObjectName("kcfg_UseWallet"); connect(useWallet, SIGNAL(toggled(bool)), this, SLOT(slotKWalletButtonToggled(bool))); settingsBoxLayout->addWidget(useWallet, 0); // Default login QCheckBox *defaultAuth = new QCheckBox(Smb4KSettings::self()->useDefaultLoginItem()->label(), settingsBox); defaultAuth->setObjectName("kcfg_UseDefaultLogin"); connect(defaultAuth, SIGNAL(toggled(bool)), this, SLOT(slotDefaultLoginToggled(bool))); settingsBoxLayout->addWidget(defaultAuth, 0); layout->addWidget(settingsBox, 0); // // Wallet Entries group box // QGroupBox *walletEntriesBox = new QGroupBox(i18n("Wallet Entries"), this); QVBoxLayout *walletEntriesBoxLayout = new QVBoxLayout(walletEntriesBox); walletEntriesBoxLayout->setSpacing(5); // // Wallet Entries editor // QWidget *walletEntriesEditor = new QWidget(walletEntriesBox); walletEntriesEditor->setObjectName("WalletEntriesEditor"); QGridLayout *walletEntriesEditorLayout= new QGridLayout(walletEntriesEditor); walletEntriesEditorLayout->setSpacing(5); // // The list view // QListWidget *walletEntriesWidget = new QListWidget(walletEntriesEditor); walletEntriesWidget->setObjectName("WalletEntriesWidget"); walletEntriesWidget->setDragDropMode(QListWidget::NoDragDrop); walletEntriesWidget->setSelectionMode(QListWidget::SingleSelection); walletEntriesWidget->setContextMenuPolicy(Qt::ActionsContextMenu); walletEntriesWidget->viewport()->installEventFilter(this); // Edit action QAction *editAction = new QAction(KDE::icon("edit-rename"), i18n("Edit"), walletEntriesWidget); editAction->setObjectName("EditAction"); editAction->setEnabled(false); connect(editAction, SIGNAL(triggered(bool)), this, SLOT(slotEditClicked())); walletEntriesWidget->addAction(editAction); // Remove action QAction *removeAction = new QAction(KDE::icon("edit-delete"), i18n("Remove"), walletEntriesWidget); removeAction->setObjectName("RemoveAction"); removeAction->setEnabled(false); connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(slotRemoveClicked())); walletEntriesWidget->addAction(removeAction); // Clear action QAction *clearAction = new QAction(KDE::icon("edit-clear-list"), i18n("Clear"), walletEntriesWidget); clearAction->setObjectName("ClearAction"); clearAction->setEnabled(false); connect(clearAction, SIGNAL(triggered(bool)), this, SLOT(slotClearClicked())); walletEntriesWidget->addAction(clearAction); connect(walletEntriesWidget, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); walletEntriesEditorLayout->addWidget(walletEntriesWidget, 0, 0, 7, 1, 0); // // Load button // QPushButton *loadButton = new QPushButton(walletEntriesEditor); loadButton->setObjectName("LoadButton"); loadButton->setText(i18n("Load")); loadButton->setIcon(KDE::icon("document-open")); loadButton->setWhatsThis(i18n("The login information that was stored by Smb4K will be loaded from the wallet.")); connect(loadButton, SIGNAL(clicked(bool)), this, SIGNAL(loadWalletEntries())); walletEntriesEditorLayout->addWidget(loadButton, 0, 1, 0); // // Save button // QPushButton *saveButton = new QPushButton(walletEntriesEditor); saveButton->setObjectName("SaveButton"); saveButton->setText(i18n("Save")); saveButton->setIcon(KDE::icon("document-save-all")); saveButton->setWhatsThis(i18n("All modifications you applied are saved to the wallet.")); saveButton->setEnabled(false); connect(saveButton, SIGNAL(clicked(bool)), this, SIGNAL(saveWalletEntries())); connect(saveButton, SIGNAL(clicked(bool)), this, SLOT(slotSaveClicked(bool))); walletEntriesEditorLayout->addWidget(saveButton, 1, 1, 0); walletEntriesEditorLayout->addItem(new QSpacerItem(0, 10, QSizePolicy::Fixed, QSizePolicy::Fixed), 2, 1); // // The details widget // KCollapsibleGroupBox *detailsBox = new KCollapsibleGroupBox(walletEntriesEditor); detailsBox->setObjectName("DetailsBox"); detailsBox->setTitle(i18n("Details")); detailsBox->setEnabled(false); QVBoxLayout *detailsBoxLayout = new QVBoxLayout(detailsBox); detailsBoxLayout->setSpacing(5); QTableWidget *detailsWidget = new QTableWidget(detailsBox); detailsWidget->setObjectName("DetailsWidget"); detailsWidget->horizontalHeader()->setVisible(false); detailsWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); detailsWidget->verticalHeader()->setVisible(false); detailsWidget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); detailsWidget->viewport()->installEventFilter(this); detailsBoxLayout->addWidget(detailsWidget, 0); walletEntriesEditorLayout->addWidget(detailsBox, 5, 1, 0); walletEntriesEditorLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding), 6, 1); walletEntriesBoxLayout->addWidget(walletEntriesEditor, 0); layout->addWidget(walletEntriesBox, 0); // // Adjustments // slotKWalletButtonToggled(useWallet->isChecked()); slotDefaultLoginToggled(defaultAuth->isChecked()); // // Set focus // loadButton->setFocus(); } Smb4KConfigPageAuthentication::~Smb4KConfigPageAuthentication() { } void Smb4KConfigPageAuthentication::insertWalletEntries(const QList &list) { // // Insert the list of authentication information // m_entriesList = list; // // Reset the changed flag, since we are (re)loading the information // m_maybe_changed = false; emit walletEntriesModified(); // // Get the list wirdget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Clear the list widget // walletEntriesWidget->clear(); // // Insert the authentication information entries into the // list widget // for (Smb4KAuthInfo *authInfo : m_entriesList) { switch (authInfo->type()) { case UnknownNetworkItem: { (void) new QListWidgetItem(KDE::icon("dialog-password"), i18n("Default Login"), walletEntriesWidget); break; } default: { (void) new QListWidgetItem(KDE::icon("dialog-password"), authInfo->displayString(), walletEntriesWidget); break; } } } // // Sort the entries // walletEntriesWidget->sortItems(); // // Set the display flag to true // m_entries_displayed = true; // // Enable buttons and actions // findChild("SaveButton")->setEnabled(walletEntriesWidget->count() != 0); findChild("ClearAction")->setEnabled(walletEntriesWidget->count() != 0); } bool Smb4KConfigPageAuthentication::eventFilter(QObject *object, QEvent *e) { // // Get the list widget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Process the events in the list widget // if (object == walletEntriesWidget->viewport()) { // If the user clicked on the viewport of the entries view, clear // the details widget and the "Details" button, if no item // is under the mouse. if (e->type() == QEvent::MouseButtonPress) { QMouseEvent *event = static_cast(e); QPoint pos = walletEntriesWidget->mapFromGlobal(event->globalPos()); if (!walletEntriesWidget->itemAt(pos)) { clearDetails(); walletEntriesWidget->clearSelection(); findChild("EditAction")->setEnabled(false); findChild("RemoveAction")->setEnabled(false); } } return walletEntriesWidget->viewport()->eventFilter(object, e); } return QWidget::eventFilter(object, e); } void Smb4KConfigPageAuthentication::loadDetails(Smb4KAuthInfo *authInfo) { // // Get the widgets // QTableWidget *detailsWidget = findChild("DetailsWidget"); KCollapsibleGroupBox *detailsGroupBox = findChild("DetailsBox"); QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Fill the details table widget with the information // switch (authInfo->type()) { case Host: case Share: { detailsWidget->setColumnCount(2); detailsWidget->setRowCount(4); QTableWidgetItem *entry_label = new QTableWidgetItem(i18n("Entry")); entry_label->setFlags(entry_label->flags() & Qt::ItemIsEditable); entry_label->setForeground(palette().text()); QTableWidgetItem *entry = new QTableWidgetItem(authInfo->displayString()); entry->setFlags(entry->flags() & Qt::ItemIsEditable); entry->setForeground(palette().text()); QTableWidgetItem *workgroup_label = new QTableWidgetItem(i18n("Workgroup")); workgroup_label->setFlags(workgroup_label->flags() & Qt::ItemIsEditable); workgroup_label->setForeground(palette().text()); QTableWidgetItem *login_label = new QTableWidgetItem(i18n("Login")); login_label->setFlags(login_label->flags() & Qt::ItemIsEditable); login_label->setForeground(palette().text()); QTableWidgetItem *password_label = new QTableWidgetItem(i18n("Password")); password_label->setFlags(password_label->flags() & Qt::ItemIsEditable); password_label->setForeground(palette().text()); detailsWidget->setItem(0, 0, entry_label); detailsWidget->setItem(0, 1, entry); detailsWidget->setItem(1, 0, workgroup_label); detailsWidget->setItem(1, 1, new QTableWidgetItem(authInfo->workgroupName())); detailsWidget->setItem(2, 0, login_label); detailsWidget->setItem(2, 1, new QTableWidgetItem(authInfo->userName())); detailsWidget->setItem(3, 0, password_label); detailsWidget->setItem(3, 1, new QTableWidgetItem(authInfo->password())); break; } default: { detailsWidget->setColumnCount(2); detailsWidget->setRowCount(3); QTableWidgetItem *entry_label = new QTableWidgetItem(i18n("Entry")); entry_label->setFlags(entry_label->flags() & Qt::ItemIsEditable); entry_label->setForeground(palette().text()); QTableWidgetItem *entry = new QTableWidgetItem(i18n("Default Login")); entry->setFlags(entry->flags() & Qt::ItemIsEditable); entry->setForeground(palette().text()); QTableWidgetItem *login_label = new QTableWidgetItem(i18n("Login")); login_label->setFlags(login_label->flags() & Qt::ItemIsEditable); login_label->setForeground(palette().text()); QTableWidgetItem *password_label = new QTableWidgetItem(i18n("Password")); password_label->setFlags(password_label->flags() & Qt::ItemIsEditable); password_label->setForeground(palette().text()); detailsWidget->setItem(0, 0, entry_label); detailsWidget->setItem(0, 1, entry); detailsWidget->setItem(1, 0, login_label); detailsWidget->setItem(1, 1, new QTableWidgetItem(authInfo->userName())); detailsWidget->setItem(2, 0, password_label); detailsWidget->setItem(2, 1, new QTableWidgetItem(authInfo->password())); break; } } // // Connect signals // connect(detailsWidget, SIGNAL(cellChanged(int,int)), this, SLOT(slotDetailsChanged(int,int))); // // Enable the details box // detailsGroupBox->setEnabled(!walletEntriesWidget->selectedItems().isEmpty()); } void Smb4KConfigPageAuthentication::clearDetails() { // // Get the widgets // QTableWidget *detailsWidget = findChild("DetailsWidget"); KCollapsibleGroupBox *detailsGroupBox = findChild("DetailsBox"); QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Disconnect signals // disconnect(detailsWidget, SIGNAL(cellChanged(int,int)), this, SLOT(slotDetailsChanged(int,int))); // // Collapse the details box and disable it. // detailsGroupBox->setExpanded(false); detailsGroupBox->setEnabled(!walletEntriesWidget->selectedItems().isEmpty()); // // Clear the table widget // if (detailsWidget->rowCount() != 0 && detailsWidget->columnCount() != 0) { detailsWidget->clear(); detailsWidget->setRowCount(0); detailsWidget->setColumnCount(0); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KConfigPageAuthentication::slotKWalletButtonToggled(bool checked) { findChild("kcfg_UseDefaultLogin")->setEnabled(checked); findChild("WalletEntriesEditor")->setEnabled(checked); } void Smb4KConfigPageAuthentication::slotDefaultLoginToggled(bool checked) { if (checked && !Smb4KSettings::useDefaultLogin()) { emit setDefaultLogin(); } } void Smb4KConfigPageAuthentication::slotItemSelectionChanged() { // // Get the list widget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Clear details widget // clearDetails(); // // Get the authentication information and load its // details into the details widget // if (walletEntriesWidget->currentItem()) { for (Smb4KAuthInfo *authInfo : m_entriesList) { if (walletEntriesWidget->currentItem()->text() == authInfo->displayString() || (walletEntriesWidget->currentItem()->text() == i18n("Default Login") && authInfo->type() == UnknownNetworkItem)) { loadDetails(authInfo); break; } } // Enable actions findChild("EditAction")->setEnabled(true); findChild("RemoveAction")->setEnabled(true); } } void Smb4KConfigPageAuthentication::slotDetailsChanged(int row, int column) { // // Get the widget // QTableWidget *detailsWidget = findChild("DetailsWidget"); // // Find the right authentication information and pass the modifications // for (Smb4KAuthInfo *authInfo : m_entriesList) { if (QString::compare(detailsWidget->item(0, 1)->text(), authInfo->displayString()) == 0 || (QString::compare(detailsWidget->item(0, 1)->text(), i18n("Default Login")) == 0 && authInfo->type() == UnknownNetworkItem)) { switch (authInfo->type()) { case Host: case Share: { if (column == 1) { switch (row) { case 1: // Workgroup { authInfo->setWorkgroupName(detailsWidget->item(row, column)->text()); break; } case 2: // Login { authInfo->setUserName(detailsWidget->item(row, column)->text()); break; } case 3: // Password { authInfo->setPassword(detailsWidget->item(row, column)->text()); break; } default: { break; } } } break; } default: { if (column == 1) { switch (row) { case 1: // Login { authInfo->setUserName(detailsWidget->item(row, column)->text()); break; } case 2: // Password { authInfo->setPassword(detailsWidget->item(row, column)->text()); break; } default: { break; } } } break; } } break; } } // // Tell the program that the authentication information may be changed // and emit the appropriate signal // m_maybe_changed = true; emit walletEntriesModified(); } void Smb4KConfigPageAuthentication::slotEditClicked() { // // Get the widgets // KCollapsibleGroupBox *detailsGroupBox = findChild("DetailsBox"); QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); if (walletEntriesWidget->currentItem()) { // // Since the details have been loaded to the details widget already // by slotItemSelectionChanged(), only open the details widget here. // if (!detailsGroupBox->isExpanded()) { detailsGroupBox->setExpanded(true); } } } void Smb4KConfigPageAuthentication::slotRemoveClicked() { // // Get the list widget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Clear the details widget // clearDetails(); // // Remove the appropriate entry from the list of authentication information // for (int i = 0; i < m_entriesList.size(); ++i) { if (QString::compare(walletEntriesWidget->currentItem()->text(), m_entriesList.at(i)->displayString()) == 0 || (QString::compare(walletEntriesWidget->currentItem()->text(), i18n("Default Login")) == 0 && m_entriesList.at(i)->type() == UnknownNetworkItem)) { switch (m_entriesList.at(i)->type()) { case UnknownNetworkItem: { QCheckBox *default_login = findChild("kcfg_UseDefaultLogin"); default_login->setChecked(false); break; } default: { break; } } delete m_entriesList.takeAt(i); break; } else { continue; } } // // Remove the current item // delete walletEntriesWidget->currentItem(); // // Enable actions // findChild("ClearAction")->setEnabled((walletEntriesWidget->count() != 0)); // // Tell the program that the authentication information may be changed // and emit the appropriate signal // m_maybe_changed = true; emit walletEntriesModified(); } void Smb4KConfigPageAuthentication::slotClearClicked() { // // Get the list widget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Clear the details widget // clearDetails(); // // Remove all entries from the view // while (walletEntriesWidget->count() != 0) { delete walletEntriesWidget->item(0); } // // Remove all entries from the list off authentication information // while(!m_entriesList.isEmpty()) { delete m_entriesList.takeFirst(); } // // Enabled widgets // findChild("ClearAction")->setEnabled(false); // // Uncheck the Default Login checkbox // findChild("kcfg_UseDefaultLogin")->setChecked(false); // // Tell the program that the authentication information may be changed // and emit the appropriate signal // m_maybe_changed = true; emit walletEntriesModified(); } void Smb4KConfigPageAuthentication::slotSaveClicked(bool /*checked*/) { // // Get the list widget // QListWidget *walletEntriesWidget = findChild("WalletEntriesWidget"); // // Disable buttons // findChild("EditAction")->setEnabled(false); findChild("RemoveAction")->setEnabled(false); findChild("ClearAction")->setEnabled((walletEntriesWidget->count() != 0)); // // Clear the selection in the list view // walletEntriesWidget->clearSelection(); // // Tell the program that the authentication information may be changed // and emit the appropriate signal // m_maybe_changed = false; emit walletEntriesModified(); } diff --git a/smb4k/smb4kconfigpagemounting.cpp b/smb4k/smb4kconfigpagemounting.cpp index eca1d70..c406c2f 100644 --- a/smb4k/smb4kconfigpagemounting.cpp +++ b/smb4k/smb4kconfigpagemounting.cpp @@ -1,954 +1,950 @@ /*************************************************************************** The configuration page for the mount options ------------------- begin : So Mär 22 2015 copyright : (C) 2015-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpagemounting.h" #include "core/smb4kglobal.h" #if defined(Q_OS_LINUX) #include "core/smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "core/smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include using namespace Smb4KGlobal; Smb4KConfigPageMounting::Smb4KConfigPageMounting(QWidget* parent): QTabWidget(parent) { setupWidget(); } Smb4KConfigPageMounting::~Smb4KConfigPageMounting() { } #if defined(Q_OS_LINUX) // // Linux // void Smb4KConfigPageMounting::setupWidget() { // // Basic Settings tab // QWidget *basicTab = new QWidget(this); QVBoxLayout *basicTabLayout = new QVBoxLayout(basicTab); basicTabLayout->setSpacing(5); basicTabLayout->setMargin(0); // // Directories // QGroupBox *directoryBox = new QGroupBox(i18n("Directories"), basicTab); QGridLayout *directoryBoxLayout = new QGridLayout(directoryBox); directoryBoxLayout->setSpacing(5); QLabel *prefixLabel = new QLabel(Smb4KMountSettings::self()->mountPrefixItem()->label(), directoryBox); KUrlRequester *prefix = new KUrlRequester(directoryBox); prefix->setMode(KFile::Directory | KFile::LocalOnly); prefix->setObjectName("kcfg_MountPrefix"); prefixLabel->setBuddy(prefix); QCheckBox *lowercaseSubdirs = new QCheckBox(Smb4KMountSettings::self()->forceLowerCaseSubdirsItem()->label(), directoryBox); lowercaseSubdirs->setObjectName("kcfg_ForceLowerCaseSubdirs"); directoryBoxLayout->addWidget(prefixLabel, 0, 0, 0); directoryBoxLayout->addWidget(prefix, 0, 1, 0); directoryBoxLayout->addWidget(lowercaseSubdirs, 1, 0, 1, 2, 0); basicTabLayout->addWidget(directoryBox, 0); // // Behavior // QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), this); QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox); behaviorBoxLayout->setSpacing(5); QCheckBox *remountShares = new QCheckBox(Smb4KMountSettings::self()->remountSharesItem()->label(), behaviorBox); remountShares->setObjectName("kcfg_RemountShares"); QLabel *remountAttemptsLabel = new QLabel(Smb4KMountSettings::self()->remountAttemptsItem()->label(), behaviorBox); remountAttemptsLabel->setIndent(25); QSpinBox *remountAttempts = new QSpinBox(behaviorBox); remountAttempts->setObjectName("kcfg_RemountAttempts"); remountAttemptsLabel->setBuddy(remountAttempts); QLabel *remountIntervalLabel = new QLabel(Smb4KMountSettings::self()->remountIntervalItem()->label(), behaviorBox); remountIntervalLabel->setIndent(25); QSpinBox *remountInterval = new QSpinBox(behaviorBox); remountInterval->setObjectName("kcfg_RemountInterval"); remountInterval->setSuffix(i18n(" min")); remountIntervalLabel->setBuddy(remountInterval); QCheckBox *unmountAllShares = new QCheckBox(Smb4KMountSettings::self()->unmountSharesOnExitItem()->label(), behaviorBox); unmountAllShares->setObjectName("kcfg_UnmountSharesOnExit"); QCheckBox *unmountForeignShares = new QCheckBox(Smb4KMountSettings::self()->unmountForeignSharesItem()->label(), behaviorBox); unmountForeignShares->setObjectName("kcfg_UnmountForeignShares"); QCheckBox *unmountInaccessibleShares = new QCheckBox(Smb4KMountSettings::self()->forceUnmountInaccessibleItem()->label(), behaviorBox); unmountInaccessibleShares->setObjectName("kcfg_ForceUnmountInaccessible"); QCheckBox *detectAllShares = new QCheckBox(Smb4KMountSettings::self()->detectAllSharesItem()->label(), behaviorBox); detectAllShares->setObjectName("kcfg_DetectAllShares"); behaviorBoxLayout->addWidget(remountShares, 0, 0, 1, 2, 0); behaviorBoxLayout->addWidget(remountAttemptsLabel, 1, 0, 0); behaviorBoxLayout->addWidget(remountAttempts, 1, 1, 0); behaviorBoxLayout->addWidget(remountIntervalLabel, 2, 0, 0); behaviorBoxLayout->addWidget(remountInterval, 2, 1, 0); behaviorBoxLayout->addWidget(unmountAllShares, 3, 0, 1, 2, 0); behaviorBoxLayout->addWidget(unmountInaccessibleShares, 4, 0, 1, 2, 0); behaviorBoxLayout->addWidget(unmountForeignShares, 5, 0, 1, 2, 0); behaviorBoxLayout->addWidget(detectAllShares, 6, 0, 1, 2, 0); basicTabLayout->addWidget(behaviorBox, 0); basicTabLayout->addStretch(100); addTab(basicTab, i18n("Basic Settings")); // // Common Mount Settings tab // QWidget *commonTab = new QWidget(this); QVBoxLayout *commonTabLayout = new QVBoxLayout(commonTab); commonTabLayout->setSpacing(5); commonTabLayout->setMargin(0); // // Common options group box // QGroupBox *commonOptions = new QGroupBox(i18n("Common Options"), commonTab); QGridLayout *commonOptionsLayout = new QGridLayout(commonOptions); commonOptionsLayout->setSpacing(5); // Write access QCheckBox *useWriteAccess = new QCheckBox(Smb4KMountSettings::self()->useWriteAccessItem()->label(), commonOptions); useWriteAccess->setObjectName("kcfg_UseWriteAccess"); KComboBox *writeAccess = new KComboBox(commonOptions); writeAccess->setObjectName("kcfg_WriteAccess"); QList writeAccessChoices = Smb4KMountSettings::self()->writeAccessItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &wa : writeAccessChoices) { writeAccess->addItem(wa.label); } commonOptionsLayout->addWidget(useWriteAccess, 0, 0, 0); commonOptionsLayout->addWidget(writeAccess, 0, 1, 0); // Character set QCheckBox *useCharacterSet = new QCheckBox(Smb4KMountSettings::self()->useClientCharsetItem()->label(), commonOptions); useCharacterSet->setObjectName("kcfg_UseClientCharset"); KComboBox *characterSet = new KComboBox(commonOptions); characterSet->setObjectName("kcfg_ClientCharset"); QList charsetChoices = Smb4KMountSettings::self()->clientCharsetItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : charsetChoices) { characterSet->addItem(c.label); } commonOptionsLayout->addWidget(useCharacterSet, 1, 0, 0); commonOptionsLayout->addWidget(characterSet, 1, 1, 0); // Remote filesystem port QCheckBox *useFilesystemPort = new QCheckBox(Smb4KMountSettings::self()->useRemoteFileSystemPortItem()->label(), commonOptions); useFilesystemPort->setObjectName("kcfg_UseRemoteFileSystemPort"); QSpinBox *filesystemPort = new QSpinBox(commonOptions); filesystemPort->setObjectName("kcfg_RemoteFileSystemPort"); commonOptionsLayout->addWidget(useFilesystemPort, 2, 0, 0); commonOptionsLayout->addWidget(filesystemPort, 2, 1, 0); commonTabLayout->addWidget(commonOptions, 0); // // CIFS Unix Extensions Support group box // QGroupBox *cifsExtensionSupportBox= new QGroupBox(i18n("CIFS Unix Extensions Support"), commonTab); QGridLayout *cifsExtensionSupportLayout = new QGridLayout(cifsExtensionSupportBox); cifsExtensionSupportLayout->setSpacing(5); // CIFS Unix extensions support QCheckBox *cifsExtensionsSupport = new QCheckBox(Smb4KMountSettings::self()->cifsUnixExtensionsSupportItem()->label(), cifsExtensionSupportBox); cifsExtensionsSupport->setObjectName("kcfg_CifsUnixExtensionsSupport"); cifsExtensionSupportLayout->addWidget(cifsExtensionsSupport, 0, 0, 1, 2, 0); // User information QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), cifsExtensionSupportBox); useUserId->setObjectName("kcfg_UseUserId"); QWidget *userIdInputWidget = new QWidget(cifsExtensionSupportBox); userIdInputWidget->setObjectName("UserIdInputWidget"); QGridLayout *userLayout = new QGridLayout(userIdInputWidget); userLayout->setSpacing(5); userLayout->setMargin(0); KLineEdit *userId = new KLineEdit(userIdInputWidget); userId->setObjectName("kcfg_UserId"); userId->setAlignment(Qt::AlignRight); userId->setReadOnly(true); QToolButton *userChooser = new QToolButton(userIdInputWidget); userChooser->setIcon(KDE::icon("edit-find-user")); userChooser->setToolTip(i18n("Choose a different user")); userChooser->setPopupMode(QToolButton::InstantPopup); QMenu *userMenu = new QMenu(userChooser); userChooser->setMenu(userMenu); QList allUsers = KUser::allUsers(); for (const KUser &u : allUsers) { QAction *userAction = userMenu->addAction(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId())); userAction->setData(u.userId().nativeId()); } userLayout->addWidget(userId, 0, 0, 0); userLayout->addWidget(userChooser, 0, 1, Qt::AlignCenter); cifsExtensionSupportLayout->addWidget(useUserId, 1, 0, 0); cifsExtensionSupportLayout->addWidget(userIdInputWidget, 1, 1, 0); // Group information QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), cifsExtensionSupportBox); useGroupId->setObjectName("kcfg_UseGroupId"); QWidget *groupIdInputWidget = new QWidget(cifsExtensionSupportBox); groupIdInputWidget->setObjectName("GroupIdInputWidget"); QGridLayout *groupLayout = new QGridLayout(groupIdInputWidget); groupLayout->setSpacing(5); groupLayout->setMargin(0); KLineEdit *groupId = new KLineEdit(groupIdInputWidget); groupId->setObjectName("kcfg_GroupId"); groupId->setAlignment(Qt::AlignRight); groupId->setReadOnly(true); QToolButton *groupChooser = new QToolButton(groupIdInputWidget); groupChooser->setIcon(KDE::icon("edit-find-user")); groupChooser->setToolTip(i18n("Choose a different group")); groupChooser->setPopupMode(QToolButton::InstantPopup); QMenu *groupMenu = new QMenu(groupChooser); groupChooser->setMenu(groupMenu); QList groupList = KUserGroup::allGroups(); for (const KUserGroup &g : groupList) { QAction *groupAction = groupMenu->addAction(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId())); groupAction->setData(g.groupId().nativeId()); } groupLayout->addWidget(groupId, 0, 0, 0); groupLayout->addWidget(groupChooser, 0, 1, Qt::AlignCenter); cifsExtensionSupportLayout->addWidget(useGroupId, 2, 0, 0); cifsExtensionSupportLayout->addWidget(groupIdInputWidget, 2, 1, 0); // File mask QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), cifsExtensionSupportBox); useFileMode->setObjectName("kcfg_UseFileMode"); KLineEdit *fileMode = new KLineEdit(cifsExtensionSupportBox); fileMode->setObjectName("kcfg_FileMode"); fileMode->setClearButtonEnabled(true); fileMode->setAlignment(Qt::AlignRight); cifsExtensionSupportLayout->addWidget(useFileMode, 3, 0, 0); cifsExtensionSupportLayout->addWidget(fileMode, 3, 1, 0); // Directory mask QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), cifsExtensionSupportBox); useDirectoryMode->setObjectName("kcfg_UseDirectoryMode"); KLineEdit *directoryMode = new KLineEdit(cifsExtensionSupportBox); directoryMode->setObjectName("kcfg_DirectoryMode"); directoryMode->setClearButtonEnabled(true); directoryMode->setAlignment(Qt::AlignRight); cifsExtensionSupportLayout->addWidget(useDirectoryMode, 4, 0, 0); cifsExtensionSupportLayout->addWidget(directoryMode, 4, 1, 0); commonTabLayout->addWidget(cifsExtensionSupportBox, 1, 0); commonTabLayout->addStretch(100); addTab(commonTab, i18n("Common Mount Settings")); // // Advanced Mount Settings tab // QWidget *advancedTab = new QWidget(this); QVBoxLayout *advancedTabLayout = new QVBoxLayout(advancedTab); advancedTabLayout->setSpacing(5); advancedTabLayout->setMargin(0); QGroupBox *advancedOptions = new QGroupBox(i18n("Advanced Options"), advancedTab); QGridLayout *advancedOptionsLayout = new QGridLayout(advancedOptions); advancedOptionsLayout->setSpacing(5); // Force Uid QCheckBox *forceUid = new QCheckBox(Smb4KMountSettings::self()->forceUIDItem()->label(), advancedOptions); forceUid->setObjectName("kcfg_ForceUID"); advancedOptionsLayout->addWidget(forceUid, 0, 0, 0); // Force Gid QCheckBox *forceGid = new QCheckBox(Smb4KMountSettings::self()->forceGIDItem()->label(), advancedOptions); forceGid->setObjectName("kcfg_ForceGID"); advancedOptionsLayout->addWidget(forceGid, 0, 1, 0); // Permission checks QCheckBox *permissionChecks = new QCheckBox(Smb4KMountSettings::self()->permissionChecksItem()->label(), advancedOptions); permissionChecks->setObjectName("kcfg_PermissionChecks"); advancedOptionsLayout->addWidget(permissionChecks, 1, 0, 0); // Client controls Ids QCheckBox *clientControlsIds = new QCheckBox(Smb4KMountSettings::self()->clientControlsIDsItem()->label(), advancedOptions); clientControlsIds->setObjectName("kcfg_ClientControlsIDs"); advancedOptionsLayout->addWidget(clientControlsIds, 1, 1, 0); // Use server inode numbers QCheckBox *useServerInodes = new QCheckBox(Smb4KMountSettings::self()->serverInodeNumbersItem()->label(), advancedOptions); useServerInodes->setObjectName("kcfg_ServerInodeNumbers"); advancedOptionsLayout->addWidget(useServerInodes, 2, 0, 0); // Translate reserved characters QCheckBox *translateReservedCharacters = new QCheckBox(Smb4KMountSettings::self()->translateReservedCharsItem()->label(), advancedOptions); translateReservedCharacters->setObjectName("kcfg_TranslateReservedChars"); advancedOptionsLayout->addWidget(translateReservedCharacters, 2, 1, 0); // No locking QCheckBox *no_locking = new QCheckBox(Smb4KMountSettings::self()->noLockingItem()->label(), advancedOptions); no_locking->setObjectName("kcfg_NoLocking"); advancedOptionsLayout->addWidget(no_locking, 3, 0, 0); // Extra widget for the rest of the options QWidget *advancedOptionsExtraWidget = new QWidget(advancedOptions); QGridLayout *advancedOptionsExtraWidgetLayout = new QGridLayout(advancedOptionsExtraWidget); advancedOptionsExtraWidgetLayout->setSpacing(5); advancedOptionsExtraWidgetLayout->setMargin(0); // SMB protocol version QCheckBox *useSmbProtocol = new QCheckBox(Smb4KMountSettings::self()->useSmbProtocolVersionItem()->label(), advancedOptionsExtraWidget); useSmbProtocol->setObjectName("kcfg_UseSmbProtocolVersion"); KComboBox *smbProtocol = new KComboBox(advancedOptionsExtraWidget); smbProtocol->setObjectName("kcfg_SmbProtocolVersion"); QList smbProtocolChoices = Smb4KMountSettings::self()->smbProtocolVersionItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : smbProtocolChoices) { smbProtocol->addItem(c.label); } advancedOptionsExtraWidgetLayout->addWidget(useSmbProtocol, 0, 0, 0); advancedOptionsExtraWidgetLayout->addWidget(smbProtocol, 0, 1, 0); // Cache mode QCheckBox *useCacheMode = new QCheckBox(Smb4KMountSettings::self()->useCacheModeItem()->label(), advancedOptionsExtraWidget); useCacheMode->setObjectName("kcfg_UseCacheMode"); KComboBox *cacheMode = new KComboBox(advancedOptionsExtraWidget); cacheMode->setObjectName("kcfg_CacheMode"); QList cacheModeChoices = Smb4KMountSettings::self()->cacheModeItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : cacheModeChoices) { cacheMode->addItem(c.label); } advancedOptionsExtraWidgetLayout->addWidget(useCacheMode, 1, 0, 0); advancedOptionsExtraWidgetLayout->addWidget(cacheMode, 1, 1, 0); // Security mode QCheckBox *useSecurityMode = new QCheckBox(Smb4KMountSettings::self()->useSecurityModeItem()->label(), advancedOptionsExtraWidget); useSecurityMode->setObjectName("kcfg_UseSecurityMode"); KComboBox *securityMode = new KComboBox(advancedOptionsExtraWidget); securityMode->setObjectName("kcfg_SecurityMode"); QList securityModeChoices = Smb4KMountSettings::self()->securityModeItem()->choices(); for (const KConfigSkeleton::ItemEnum::Choice &c : securityModeChoices) { securityMode->addItem(c.label); } advancedOptionsExtraWidgetLayout->addWidget(useSecurityMode, 2, 0, 0); advancedOptionsExtraWidgetLayout->addWidget(securityMode, 2, 1, 0); // Additional options QLabel *additionalOptionsLabel = new QLabel(Smb4KMountSettings::self()->customCIFSOptionsItem()->label(), advancedOptionsExtraWidget); QWidget *additionalOptionsWidget = new QWidget(advancedOptionsExtraWidget); QHBoxLayout *additionalOptionsWidgetLayout = new QHBoxLayout(additionalOptionsWidget); additionalOptionsWidgetLayout->setSpacing(5); additionalOptionsWidgetLayout->setMargin(0); KLineEdit *additionalOptions = new KLineEdit(additionalOptionsWidget); additionalOptions->setObjectName("kcfg_CustomCIFSOptions"); additionalOptions->setReadOnly(true); additionalOptions->setClearButtonEnabled(true); additionalOptionsLabel->setBuddy(additionalOptions); QToolButton *additionalOptionsEdit = new QToolButton(advancedOptionsExtraWidget); additionalOptionsEdit->setIcon(KDE::icon("document-edit")); additionalOptionsEdit->setToolTip(i18n("Edit the additional CIFS options.")); additionalOptionsWidgetLayout->addWidget(additionalOptions, 0); additionalOptionsWidgetLayout->addWidget(additionalOptionsEdit, 0); advancedOptionsExtraWidgetLayout->addWidget(additionalOptionsLabel, 3, 0, 0); advancedOptionsExtraWidgetLayout->addWidget(additionalOptionsWidget, 3, 1, 0); advancedOptionsLayout->addWidget(advancedOptionsExtraWidget, 4, 0, 1, 2, 0); advancedTabLayout->addWidget(advancedOptions, 0); advancedTabLayout->addStretch(100); addTab(advancedTab, i18n("Advanced Mount Settings")); // // Adjust widgets // slotCIFSUnixExtensionsSupport(Smb4KMountSettings::cifsUnixExtensionsSupport()); // // Connections // connect(userMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewUserTriggered(QAction*))); connect(groupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewGroupTriggered(QAction*))); connect(cifsExtensionsSupport, SIGNAL(clicked(bool)), this, SLOT(slotCIFSUnixExtensionsSupport(bool))); connect(additionalOptionsEdit, SIGNAL(clicked(bool)), this, SLOT(slotAdditionalCIFSOptions())); } #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) // // FreeBSD and NetBSD // void Smb4KConfigPageMounting::setupWidget() { // // Basic Settings tab // QWidget *basicTab = new QWidget(this); QVBoxLayout *basicTabLayout = new QVBoxLayout(basicTab); basicTabLayout->setSpacing(5); basicTabLayout->setMargin(0); // // Directories // QGroupBox *directoryBox = new QGroupBox(i18n("Directories"), basicTab); QGridLayout *directoryBoxLayout = new QGridLayout(directoryBox); directoryBoxLayout->setSpacing(5); QLabel *prefixLabel = new QLabel(Smb4KMountSettings::self()->mountPrefixItem()->label(), directoryBox); KUrlRequester *prefix = new KUrlRequester(directoryBox); prefix->setMode(KFile::Directory | KFile::LocalOnly); prefix->setObjectName("kcfg_MountPrefix"); prefixLabel->setBuddy(prefix); QCheckBox *lowercaseSubdirs = new QCheckBox(Smb4KMountSettings::self()->forceLowerCaseSubdirsItem()->label(), directoryBox); lowercaseSubdirs->setObjectName("kcfg_ForceLowerCaseSubdirs"); directoryBoxLayout->addWidget(prefixLabel, 0, 0, 0); directoryBoxLayout->addWidget(prefix, 0, 1, 0); directoryBoxLayout->addWidget(lowercaseSubdirs, 1, 0, 1, 2, 0); basicTabLayout->addWidget(directoryBox, 0); // // Behavior // QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), basicTab); QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox); behaviorBoxLayout->setSpacing(5); QCheckBox *remountShares = new QCheckBox(Smb4KMountSettings::self()->remountSharesItem()->label(), behaviorBox); remountShares->setObjectName("kcfg_RemountShares"); QLabel *remountAttemptsLabel = new QLabel(Smb4KMountSettings::self()->remountAttemptsItem()->label(), behaviorBox); remountAttemptsLabel->setIndent(25); QSpinBox *remountAttempts = new QSpinBox(behaviorBox); remountAttempts->setObjectName("kcfg_RemountAttempts"); remountAttemptsLabel->setBuddy(remountAttempts); QLabel *remountIntervalLabel = new QLabel(Smb4KMountSettings::self()->remountIntervalItem()->label(), behaviorBox); remountIntervalLabel->setIndent(25); QSpinBox *remountInterval = new QSpinBox(behaviorBox); remountInterval->setObjectName("kcfg_RemountInterval"); remountInterval->setSuffix(i18n(" min")); remountIntervalLabel->setBuddy(remountInterval); QCheckBox *unmountAllShares = new QCheckBox(Smb4KMountSettings::self()->unmountSharesOnExitItem()->label(), behaviorBox); unmountAllShares->setObjectName("kcfg_UnmountSharesOnExit"); QCheckBox *unmountForeignShares = new QCheckBox(Smb4KMountSettings::self()->unmountForeignSharesItem()->label(), behaviorBox); unmountForeignShares->setObjectName("kcfg_UnmountForeignShares"); QCheckBox *detectAllShares = new QCheckBox(Smb4KMountSettings::self()->detectAllSharesItem()->label(), behaviorBox); detectAllShares->setObjectName("kcfg_DetectAllShares"); behaviorBoxLayout->addWidget(remountShares, 0, 0, 1, 2, 0); behaviorBoxLayout->addWidget(remountAttemptsLabel, 1, 0, 0); behaviorBoxLayout->addWidget(remountAttempts, 1, 1, 0); behaviorBoxLayout->addWidget(remountIntervalLabel, 2, 0, 0); behaviorBoxLayout->addWidget(remountInterval, 2, 1, 0); behaviorBoxLayout->addWidget(unmountAllShares, 3, 0, 1, 2, 0); behaviorBoxLayout->addWidget(unmountForeignShares, 4, 0, 1, 2, 0); behaviorBoxLayout->addWidget(detectAllShares, 5, 0, 1, 2, 0); basicTabLayout->addWidget(behaviorBox, 0); basicTabLayout->addStretch(100); addTab(basicTab, i18n("Basic Settings")); // // Mount Settings tab // QWidget *mountTab = new QWidget(this); QVBoxLayout *mountTabLayout = new QVBoxLayout(mountTab); mountTabLayout->setSpacing(5); mountTabLayout->setMargin(0); // // Common Options // QGroupBox *commonOptionsBox = new QGroupBox(i18n("Common Options"), mountTab); QGridLayout *commonOptionsBoxLayout = new QGridLayout(commonOptionsBox); commonOptionsBoxLayout->setSpacing(5); // User information QCheckBox *useUserId = new QCheckBox(Smb4KMountSettings::self()->useUserIdItem()->label(), commonOptionsBox); useUserId->setObjectName("kcfg_UseUserId"); QWidget *userIdInputWidget = new QWidget(commonOptionsBox); userIdInputWidget->setObjectName("UserIdInputWidget"); QGridLayout *userLayout = new QGridLayout(userIdInputWidget); userLayout->setSpacing(5); userLayout->setMargin(0); KLineEdit *userId = new KLineEdit(userIdInputWidget); userId->setObjectName("kcfg_UserId"); userId->setAlignment(Qt::AlignRight); userId->setReadOnly(true); QToolButton *userChooser = new QToolButton(userIdInputWidget); userChooser->setIcon(KDE::icon("edit-find-user")); userChooser->setToolTip(i18n("Choose a different user")); userChooser->setPopupMode(QToolButton::InstantPopup); QMenu *userMenu = new QMenu(userChooser); userChooser->setMenu(userMenu); QList allUsers = KUser::allUsers(); for (const KUser &u : allUsers) { QAction *userAction = userMenu->addAction(QString("%1 (%2)").arg(u.loginName()).arg(u.userId().nativeId())); userAction->setData(u.userId().nativeId()); } userLayout->addWidget(userId, 0, 0, 0); userLayout->addWidget(userChooser, 0, 1, Qt::AlignCenter); commonOptionsBoxLayout->addWidget(useUserId, 0, 0, 0); commonOptionsBoxLayout->addWidget(userIdInputWidget, 0, 1, 0); // Group information QCheckBox *useGroupId = new QCheckBox(Smb4KMountSettings::self()->useGroupIdItem()->label(), commonOptionsBox); useGroupId->setObjectName("kcfg_UseGroupId"); QWidget *groupIdInputWidget = new QWidget(commonOptionsBox); groupIdInputWidget->setObjectName("GroupIdInputWidget"); QGridLayout *groupLayout = new QGridLayout(groupIdInputWidget); groupLayout->setSpacing(5); groupLayout->setMargin(0); KLineEdit *groupId = new KLineEdit(groupIdInputWidget); groupId->setObjectName("kcfg_GroupId"); groupId->setAlignment(Qt::AlignRight); groupId->setReadOnly(true); QToolButton *groupChooser = new QToolButton(groupIdInputWidget); groupChooser->setIcon(KDE::icon("edit-find-user")); groupChooser->setToolTip(i18n("Choose a different group")); groupChooser->setPopupMode(QToolButton::InstantPopup); QMenu *groupMenu = new QMenu(groupChooser); groupChooser->setMenu(groupMenu); QList groupList = KUserGroup::allGroups(); for (const KUserGroup &g : groupList) { QAction *groupAction = groupMenu->addAction(QString("%1 (%2)").arg(g.name()).arg(g.groupId().nativeId())); groupAction->setData(g.groupId().nativeId()); } groupLayout->addWidget(groupId, 0, 0, 0); groupLayout->addWidget(groupChooser, 0, 1, Qt::AlignCenter); commonOptionsBoxLayout->addWidget(useGroupId, 1, 0, 0); commonOptionsBoxLayout->addWidget(groupIdInputWidget, 1, 1, 0); // File mask QCheckBox *useFileMode = new QCheckBox(Smb4KMountSettings::self()->useFileModeItem()->label(), commonOptionsBox); useFileMode->setObjectName("kcfg_UseFileMode"); KLineEdit *fileMode = new KLineEdit(commonOptionsBox); fileMode->setObjectName("kcfg_FileMode"); fileMode->setClearButtonEnabled(true); fileMode->setAlignment(Qt::AlignRight); commonOptionsBoxLayout->addWidget(useFileMode, 2, 0, 0); commonOptionsBoxLayout->addWidget(fileMode, 2, 1, 0); // Directory mask QCheckBox *useDirectoryMode = new QCheckBox(Smb4KMountSettings::self()->useDirectoryModeItem()->label(), commonOptionsBox); useDirectoryMode->setObjectName("kcfg_UseDirectoryMode"); KLineEdit *directoryMode = new KLineEdit(commonOptionsBox); directoryMode->setObjectName("kcfg_DirectoryMode"); directoryMode->setClearButtonEnabled(true); directoryMode->setAlignment(Qt::AlignRight); commonOptionsBoxLayout->addWidget(useDirectoryMode, 3, 0, 0); commonOptionsBoxLayout->addWidget(directoryMode, 3, 1, 0); // // Character sets // QGroupBox *characterSetsBox = new QGroupBox(i18n("Character Sets"), mountTab); QGridLayout *characterSetsBoxLayout = new QGridLayout(characterSetsBox); characterSetsBoxLayout->setSpacing(5); // Client character set QCheckBox *useCharacterSets = new QCheckBox(Smb4KMountSettings::self()->useCharacterSetsItem()->label(), characterSetsBox); useCharacterSets->setObjectName("kcfg_UseCharacterSets"); QLabel *clientCharacterSetLabel = new QLabel(Smb4KMountSettings::self()->clientCharsetItem()->label(), characterSetsBox); clientCharacterSetLabel->setIndent(25); clientCharacterSetLabel->setObjectName("ClientCharacterSetLabel"); KComboBox *clientCharacterSet = new KComboBox(characterSetsBox); clientCharacterSet->setObjectName("kcfg_ClientCharset"); QList charsetChoices = Smb4KMountSettings::self()->clientCharsetItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : charsetChoices) { clientCharacterSet->addItem(c.label); } clientCharacterSetLabel->setBuddy(clientCharacterSet); // Server character set QLabel *serverCharacterSetLabel = new QLabel(Smb4KMountSettings::self()->serverCodepageItem()->label(), characterSetsBox); serverCharacterSetLabel->setIndent(25); serverCharacterSetLabel->setObjectName("ServerCodepageLabel"); KComboBox *serverCharacterSet = new KComboBox(characterSetsBox); serverCharacterSet->setObjectName("kcfg_ServerCodepage"); QList codepageChoices = Smb4KMountSettings::self()->serverCodepageItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : codepageChoices) { serverCharacterSet->addItem(c.label); } serverCharacterSetLabel->setBuddy(serverCharacterSet); characterSetsBoxLayout->addWidget(useCharacterSets, 0, 0, 1, 2, 0); characterSetsBoxLayout->addWidget(clientCharacterSetLabel, 1, 0, 0); characterSetsBoxLayout->addWidget(clientCharacterSet, 1, 1, 0); characterSetsBoxLayout->addWidget(serverCharacterSetLabel, 2, 0, 0); characterSetsBoxLayout->addWidget(serverCharacterSet, 2, 1, 0); mountTabLayout->addWidget(commonOptionsBox, 0); mountTabLayout->addWidget(characterSetsBox, 0); mountTabLayout->addStretch(100); addTab(mountTab, i18n("Mount Settings")); // // Connections // connect(userMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewUserTriggered(QAction*))); connect(groupMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotNewGroupTriggered(QAction*))); connect(useCharacterSets, SIGNAL(toggled(bool)), this, SLOT(slotCharacterSets(bool))); // // Enable / disable widgets // slotCharacterSets(Smb4KMountSettings::useCharacterSets()); } #else // // Dummy // void Smb4KConfigPageMounting::setupWidget() { } #endif void Smb4KConfigPageMounting::slotNewUserTriggered(QAction *action) { KLineEdit *userId = findChild("kcfg_UserId"); if (userId) { userId->setText(action->data().toString()); } } void Smb4KConfigPageMounting::slotNewGroupTriggered(QAction *action) { KLineEdit *groupId = findChild("kcfg_GroupId"); if (groupId) { groupId->setText(action->data().toString()); } } void Smb4KConfigPageMounting::slotCIFSUnixExtensionsSupport(bool checked) { QCheckBox *useUserId = findChild("kcfg_UseUserId"); if (useUserId) { useUserId->setEnabled(!checked); } QWidget *userIdInputWidget = findChild("UserIdInputWidget"); if (userIdInputWidget) { userIdInputWidget->setEnabled(!checked); } QCheckBox *useGroupId = findChild("kcfg_UseGroupId"); if (useGroupId) { useGroupId->setEnabled(!checked); } QWidget *groupIdInputWidget = findChild("GroupIdInputWidget"); if (groupIdInputWidget) { groupIdInputWidget->setEnabled(!checked); } QCheckBox *useFileMode = findChild("kcfg_UseFileMode"); if (useFileMode) { useFileMode->setEnabled(!checked); } KLineEdit *fileMode = findChild("kcfg_FileMode"); if (fileMode) { fileMode->setEnabled(!checked); } QCheckBox *useDirectoryMode = findChild("kcfg_UseDirectoryMode"); if (useDirectoryMode) { useDirectoryMode->setEnabled(!checked); } KLineEdit *directoryMode = findChild("kcfg_DirectoryMode"); if (directoryMode) { directoryMode->setEnabled(!checked); } } void Smb4KConfigPageMounting::slotAdditionalCIFSOptions() { #if defined(Q_OS_LINUX) KLineEdit *cifsOptions = findChild("kcfg_CustomCIFSOptions"); if (cifsOptions) { QString options = cifsOptions->originalText(); bool ok = false; options = QInputDialog::getText(this, i18n("Additional CIFS Options"), i18n("Enter the desired options as a comma separated list:"), QLineEdit::Normal, options, &ok); if (ok) { if(!options.trimmed().isEmpty()) { // SECURITY: Only pass those arguments to mount.cifs that do not pose // a potential security risk and that have not already been defined. // // This is, among others, the proper fix to the security issue reported // by Heiner Markert (aka CVE-2014-2581). QStringList whitelist = whitelistedMountArguments(); QStringList deniedArgs; QStringList list = options.split(',', QString::SkipEmptyParts); QMutableStringListIterator it(list); while (it.hasNext()) { QString arg = it.next().section("=", 0, 0); if (!whitelist.contains(arg)) { deniedArgs << arg; it.remove(); } } if (!deniedArgs.isEmpty()) { QString msg = i18np("The following entry is going to be removed from the additional options: %2. Please read the handbook for details.", "The following %1 entries are going to be removed from the additional options: %2. Please read the handbook for details.", deniedArgs.size(), deniedArgs.join(", ")); KMessageBox::sorry(this, msg); } cifsOptions->setText(list.join(",").trimmed()); } else { cifsOptions->clear(); } } } #endif } void Smb4KConfigPageMounting::slotCharacterSets(bool on) { // // Client character set // QLabel *clientCharacterSetLabel = findChild("ClientCharacterSetLabel"); if (clientCharacterSetLabel) { clientCharacterSetLabel->setEnabled(on); } KComboBox *clientCharacterSet = findChild("kcfg_ClientCharset"); if (clientCharacterSet) { clientCharacterSet->setEnabled(on); } // // Server character set // QLabel *serverCharacterSetLabel = findChild("ServerCodepageLabel"); if (serverCharacterSetLabel) { serverCharacterSetLabel->setEnabled(on); } KComboBox *serverCharacterSet = findChild("kcfg_ServerCodepage"); if (serverCharacterSet) { serverCharacterSet->setEnabled(on); } } diff --git a/smb4k/smb4kconfigpagenetwork.cpp b/smb4k/smb4kconfigpagenetwork.cpp index 9c92684..d67e782 100644 --- a/smb4k/smb4kconfigpagenetwork.cpp +++ b/smb4k/smb4kconfigpagenetwork.cpp @@ -1,241 +1,237 @@ /*************************************************************************** smb4knetworkoptions - The configuration page for the network settings of Smb4K ------------------- begin : Sa Nov 15 2003 copyright : (C) 2003-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpagenetwork.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include #include #include #include // KDE includes #include #include #include #include Smb4KConfigPageNetwork::Smb4KConfigPageNetwork(QWidget *parent) : QTabWidget(parent) { // // Network Neighborhood tab // QWidget *sambaTab = new QWidget(this); QVBoxLayout *sambaTabLayout = new QVBoxLayout(sambaTab); sambaTabLayout->setSpacing(5); sambaTabLayout->setMargin(0); // // Basic Settings group box // QGroupBox *basicSettingsBox = new QGroupBox(i18n("Basic Settings"), sambaTab); QGridLayout *basicSettingsBoxLayout = new QGridLayout(basicSettingsBox); basicSettingsBoxLayout->setSpacing(5); QLabel *nebiosNameLabel = new QLabel(Smb4KSettings::self()->netBIOSNameItem()->label(), basicSettingsBox); KLineEdit *netbiosName = new KLineEdit(basicSettingsBox); netbiosName->setObjectName("kcfg_NetBIOSName"); netbiosName->setClearButtonEnabled(true); nebiosNameLabel->setBuddy(netbiosName); QLabel *domainLabel = new QLabel(Smb4KSettings::self()->domainNameItem()->label(), basicSettingsBox); KLineEdit *domain = new KLineEdit(basicSettingsBox); domain->setObjectName("kcfg_DomainName"); domain->setClearButtonEnabled(true); domainLabel->setBuddy(domain); QCheckBox *useRemoteSmbPort = new QCheckBox(Smb4KSettings::self()->useRemoteSmbPortItem()->label(), basicSettingsBox); useRemoteSmbPort->setObjectName("kcfg_UseRemoteSmbPort"); QSpinBox *remoteSmbPort = new QSpinBox(basicSettingsBox); remoteSmbPort->setObjectName("kcfg_RemoteSmbPort"); // remoteSmbPort->setSliderEnabled(true); QCheckBox *largeNetworkNeighborhood = new QCheckBox(Smb4KSettings::self()->largeNetworkNeighborhoodItem()->label(), basicSettingsBox); largeNetworkNeighborhood->setObjectName("kcfg_LargeNetworkNeighborhood"); basicSettingsBoxLayout->addWidget(nebiosNameLabel, 0, 0, 0); basicSettingsBoxLayout->addWidget(netbiosName, 0, 1, 0); basicSettingsBoxLayout->addWidget(domainLabel, 1, 0, 0); basicSettingsBoxLayout->addWidget(domain, 1, 1, 0); basicSettingsBoxLayout->addWidget(useRemoteSmbPort, 2, 0, 0); basicSettingsBoxLayout->addWidget(remoteSmbPort, 2, 1, 0); basicSettingsBoxLayout->addWidget(largeNetworkNeighborhood, 3, 0, 1, 2, 0); sambaTabLayout->addWidget(basicSettingsBox, 0); // // Authentication group box // QGroupBox *authenticationBox = new QGroupBox(i18n("Authentication"), sambaTab); QGridLayout *authenticationBoxLayout = new QGridLayout(authenticationBox); authenticationBoxLayout->setSpacing(5); QCheckBox *masterBrowsersRequireAuth = new QCheckBox(Smb4KSettings::self()->masterBrowsersRequireAuthItem()->label(), authenticationBox); masterBrowsersRequireAuth->setObjectName("kcfg_MasterBrowsersRequireAuth"); QCheckBox *useKerberos = new QCheckBox(Smb4KSettings::self()->useKerberosItem()->label(), authenticationBox); useKerberos->setObjectName("kcfg_UseKerberos"); QCheckBox *useCCache = new QCheckBox(Smb4KSettings::self()->useWinbindCCacheItem()->label(), authenticationBox); useCCache->setObjectName("kcfg_UseWinbindCCache"); authenticationBoxLayout->addWidget(masterBrowsersRequireAuth, 0, 0, 0); authenticationBoxLayout->addWidget(useKerberos, 0, 1, 0); authenticationBoxLayout->addWidget(useCCache, 1, 0, 0); sambaTabLayout->addWidget(authenticationBox, 0); // // Security group box // QGroupBox *securityBox = new QGroupBox(i18n("Security"), sambaTab); QGridLayout *securityBoxLayout = new QGridLayout(securityBox); securityBoxLayout->setSpacing(5); // Encryption level QCheckBox *useEncryptionLevel = new QCheckBox(Smb4KSettings::self()->useEncryptionLevelItem()->label(), securityBox); useEncryptionLevel->setObjectName("kcfg_UseEncryptionLevel"); KComboBox *encryptionLevel = new KComboBox(securityBox); encryptionLevel->setObjectName("kcfg_EncryptionLevel"); QList encryptionLevelChoices = Smb4KSettings::self()->encryptionLevelItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &c : encryptionLevelChoices) { encryptionLevel->addItem(c.label); } securityBoxLayout->addWidget(useEncryptionLevel, 0, 0, 0); securityBoxLayout->addWidget(encryptionLevel, 0, 1, 0); sambaTabLayout->addWidget(securityBox, 0); // // Behavior group box // QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), sambaTab); QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox); behaviorBoxLayout->setSpacing(5); QCheckBox *detectPrinters = new QCheckBox(Smb4KSettings::self()->detectPrinterSharesItem()->label(), behaviorBox); detectPrinters->setObjectName("kcfg_DetectPrinterShares"); QCheckBox *detectHiddenShares = new QCheckBox(Smb4KSettings::self()->detectHiddenSharesItem()->label(), behaviorBox); detectHiddenShares->setObjectName("kcfg_DetectHiddenShares"); QCheckBox *previewHiddenItems = new QCheckBox(Smb4KSettings::self()->previewHiddenItemsItem()->label(), behaviorBox); previewHiddenItems->setObjectName("kcfg_PreviewHiddenItems"); behaviorBoxLayout->addWidget(detectPrinters, 0, 0, 0); behaviorBoxLayout->addWidget(detectHiddenShares, 0, 1, 0); behaviorBoxLayout->addWidget(previewHiddenItems, 1, 0, 0); sambaTabLayout->addWidget(behaviorBox, 0); sambaTabLayout->addStretch(100); addTab(sambaTab, i18n("Samba")); // // Wake-On-LAN tab // QWidget *wakeOnLanTab = new QWidget(this); // // Wake-On-LAN tab layout // QVBoxLayout *wakeOnLanTabLayout = new QVBoxLayout(wakeOnLanTab); wakeOnLanTabLayout->setSpacing(5); wakeOnLanTabLayout->setMargin(0); // // Wake-On-LAN group box // QGroupBox *wakeOnLanBox = new QGroupBox(i18n("Wake-On-LAN"), wakeOnLanTab); QGridLayout *wakeOnLanBoxLayout = new QGridLayout(wakeOnLanBox); wakeOnLanBoxLayout->setSpacing(5); QCheckBox *enableWakeOnLan = new QCheckBox(Smb4KSettings::self()->enableWakeOnLANItem()->label(), wakeOnLanBox); enableWakeOnLan->setObjectName("kcfg_EnableWakeOnLAN"); QLabel *wakeOnLanWaitingTimeLabel = new QLabel(Smb4KSettings::self()->wakeOnLANWaitingTimeItem()->label(), wakeOnLanBox); wakeOnLanWaitingTimeLabel->setIndent(25); QSpinBox *wakeOnLanWaitingTime = new QSpinBox(wakeOnLanBox); wakeOnLanWaitingTime->setObjectName("kcfg_WakeOnLANWaitingTime"); wakeOnLanWaitingTime->setSuffix(i18n(" s")); wakeOnLanWaitingTime->setSingleStep(1); // wakeOnLanWaitingTime->setSliderEnabled(true); wakeOnLanWaitingTimeLabel->setBuddy(wakeOnLanWaitingTime); QFrame *wakeOnLanNote = new QFrame(wakeOnLanBox); QGridLayout *wakeOnLanNoteLayout = new QGridLayout(wakeOnLanNote); wakeOnLanNoteLayout->setSpacing(10); wakeOnLanNoteLayout->setMargin(5); QLabel *importantPixmap = new QLabel(wakeOnLanNote); importantPixmap->setPixmap(KIconLoader::global()->loadIcon("emblem-important", KIconLoader::Desktop, KIconLoader::SizeMedium)); importantPixmap->adjustSize(); QLabel *message = new QLabel(wakeOnLanNote); message->setText(i18n("Define the hosts that should be woken up via the custom options dialog.")); message->setTextFormat(Qt::AutoText); message->setWordWrap(true); message->setAlignment(Qt::AlignJustify); wakeOnLanNoteLayout->addWidget(importantPixmap, 0, 0, Qt::AlignVCenter); wakeOnLanNoteLayout->addWidget(message, 0, 1, Qt::AlignVCenter); wakeOnLanNoteLayout->setColumnStretch(1, 1); wakeOnLanBoxLayout->addWidget(enableWakeOnLan, 0, 0, 1, 2, 0); wakeOnLanBoxLayout->addWidget(wakeOnLanWaitingTimeLabel, 1, 0, 0); wakeOnLanBoxLayout->addWidget(wakeOnLanWaitingTime, 1, 1, 0); wakeOnLanBoxLayout->addWidget(wakeOnLanNote, 2, 0, 1, 2, 0); wakeOnLanTabLayout->addWidget(wakeOnLanBox, 0); wakeOnLanTabLayout->addStretch(100); addTab(wakeOnLanTab, i18n("Wake-On-LAN")); } Smb4KConfigPageNetwork::~Smb4KConfigPageNetwork() { } diff --git a/smb4k/smb4kconfigpageprofiles.cpp b/smb4k/smb4kconfigpageprofiles.cpp index 9224001..d4c3c63 100644 --- a/smb4k/smb4kconfigpageprofiles.cpp +++ b/smb4k/smb4kconfigpageprofiles.cpp @@ -1,209 +1,205 @@ /*************************************************************************** The configuration page for the profiles ------------------- begin : Do Aug 07 2014 copyright : (C) 2014-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpageprofiles.h" #include "core/smb4ksettings.h" #include "core/smb4kprofilemanager.h" // Qt includes #include #include #include // KDE includes #include #include Smb4KConfigPageProfiles::Smb4KConfigPageProfiles(QWidget* parent) : QWidget(parent) { // Layout QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); layout->setMargin(0); QGroupBox *settings = new QGroupBox(i18n("Settings"), this); QVBoxLayout *settings_layout = new QVBoxLayout(settings); settings_layout->setSpacing(5); // settings_layout->setMargin(0); // Use profiles QCheckBox *use_profiles = new QCheckBox(Smb4KSettings::self()->useProfilesItem()->label(), settings); use_profiles->setObjectName("kcfg_UseProfiles"); // Use profile migration assistant QCheckBox *use_assistant = new QCheckBox(Smb4KSettings::self()->useMigrationAssistantItem()->label(), settings); use_assistant->setObjectName("kcfg_UseMigrationAssistant"); settings_layout->addWidget(use_profiles, 0, 0); settings_layout->addWidget(use_assistant, 1, 0); QGroupBox *profiles = new QGroupBox(i18n("Profiles"), this); QVBoxLayout *profiles_layout = new QVBoxLayout(profiles); profiles_layout->setSpacing(5); // List of profiles m_profiles = new KEditListWidget(profiles); m_profiles->setObjectName("kcfg_ProfilesList"); m_profiles->setEnabled(Smb4KSettings::self()->useProfiles()); profiles_layout->addWidget(m_profiles, 0, 0); layout->addWidget(settings, 0, 0); layout->addWidget(profiles, 1, 0); connect(use_profiles, SIGNAL(stateChanged(int)), this, SLOT(slotEnableWidget(int))); connect(m_profiles, SIGNAL(removed(QString)), this, SLOT(slotProfileRemoved(QString))); connect(m_profiles->lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotProfileChanged())); } Smb4KConfigPageProfiles::~Smb4KConfigPageProfiles() { } QList< QPair > Smb4KConfigPageProfiles::renamedProfiles() const { return m_renamed; } void Smb4KConfigPageProfiles::clearRenamedProfiles() { m_renamed.clear(); } QStringList Smb4KConfigPageProfiles::removedProfiles() const { return m_removed; } void Smb4KConfigPageProfiles::clearRemovedProfiles() { m_removed.clear(); } void Smb4KConfigPageProfiles::slotEnableWidget(int state) { switch (state) { case Qt::Unchecked: { m_profiles->setEnabled(false); break; } case Qt::Checked: { m_profiles->setEnabled(true); break; } default: { break; } } } void Smb4KConfigPageProfiles::slotProfileRemoved(const QString& name) { // If the removed profile was renamed before, remove it from // the list. QMutableListIterator< QPair > it(m_renamed); while (it.hasNext()) { QPair entry = it.next(); if (QString::compare(entry.first, name) == 0 || QString::compare(entry.second, name) == 0) { it.remove(); } } m_removed << name; } void Smb4KConfigPageProfiles::slotProfileChanged() { QStringList savedProfiles = Smb4KProfileManager::self()->profilesList(); QStringList currentProfiles = m_profiles->items(); if (savedProfiles.size() == currentProfiles.size()) { QMutableStringListIterator it(savedProfiles); while (it.hasNext()) { QString entry = it.next(); int index = currentProfiles.indexOf(entry); if (index != -1) { currentProfiles.removeAt(index); it.remove(); } } if (!savedProfiles.isEmpty() && !currentProfiles.isEmpty()) { // Take care that multiple renamings will have the correct // result. bool write = true; for (int i = 0; i < m_renamed.size(); ++i) { if (QString::compare(savedProfiles.first(), m_renamed.at(i).first, Qt::CaseSensitive) == 0) { QPair pair = static_cast< QPair >(m_renamed.at(i)); pair.second = currentProfiles.first(); write = false; break; } } // Write the renamed profile to the list, if necessary. if (write) { QPair renamed(savedProfiles.first(), currentProfiles.first()); m_renamed << renamed; } } } } diff --git a/smb4k/smb4kconfigpagesynchronization.cpp b/smb4k/smb4kconfigpagesynchronization.cpp index a50e57e..3d430a7 100644 --- a/smb4k/smb4kconfigpagesynchronization.cpp +++ b/smb4k/smb4kconfigpagesynchronization.cpp @@ -1,590 +1,586 @@ /*************************************************************************** The configuration page for the synchronization options ------------------- begin : So Nov 20 2005 copyright : (C) 2005-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpagesynchronization.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include #include #include #include #include // KDE includes #include #include #include Smb4KConfigPageSynchronization::Smb4KConfigPageSynchronization(QWidget *parent) : QTabWidget(parent) { // // 'Basic Settings' tab // QWidget *basicTab = new QWidget(this); QVBoxLayout *basicTabLayout = new QVBoxLayout(basicTab); basicTabLayout->setSpacing(5); basicTabLayout->setMargin(0); // Default destination (rsync) QGroupBox *pathsBox = new QGroupBox(i18n("Default Destination"), basicTab); QGridLayout *pathsBoxLayout = new QGridLayout(pathsBox); pathsBoxLayout->setSpacing(5); QLabel *rsyncPrefixLabel = new QLabel(Smb4KSettings::self()->rsyncPrefixItem()->label(), pathsBox); KUrlRequester *rsyncPrefix = new KUrlRequester(pathsBox); rsyncPrefix->setMode(KFile::Directory|KFile::LocalOnly); rsyncPrefix->setObjectName("kcfg_RsyncPrefix"); rsyncPrefixLabel->setBuddy(rsyncPrefix); pathsBoxLayout->addWidget(rsyncPrefixLabel, 0, 0, 0); pathsBoxLayout->addWidget(rsyncPrefix, 0, 1, 0); // Behavior QGroupBox *behaviorBox = new QGroupBox(i18n("Behavior"), basicTab); QGridLayout *behaviorBoxLayout = new QGridLayout(behaviorBox); behaviorBoxLayout->setSpacing(5); QCheckBox *archiveMode = new QCheckBox(Smb4KSettings::self()->archiveModeItem()->label(), behaviorBox); archiveMode->setObjectName("kcfg_ArchiveMode"); QCheckBox *recurseDirs = new QCheckBox(Smb4KSettings::self()->recurseIntoDirectoriesItem()->label(), behaviorBox); recurseDirs->setObjectName("kcfg_RecurseIntoDirectories"); QCheckBox *relativePaths = new QCheckBox(Smb4KSettings::self()->relativePathNamesItem()->label(), behaviorBox); relativePaths->setObjectName("kcfg_RelativePathNames"); QCheckBox *noImpliedDirs = new QCheckBox(Smb4KSettings::self()->noImpliedDirectoriesItem()->label(), behaviorBox); noImpliedDirs->setObjectName("kcfg_NoImpliedDirectories"); QCheckBox *transferDirs = new QCheckBox(Smb4KSettings::self()->transferDirectoriesItem()->label(), behaviorBox); transferDirs->setObjectName("kcfg_TransferDirectories"); behaviorBoxLayout->addWidget(archiveMode, 0, 0, 0); behaviorBoxLayout->addWidget(recurseDirs, 0, 1, 0); behaviorBoxLayout->addWidget(relativePaths, 1, 0, 0); behaviorBoxLayout->addWidget(noImpliedDirs, 1, 1, 0); behaviorBoxLayout->addWidget(transferDirs, 2, 0, 0); // Backup QGroupBox *backupBox = new QGroupBox(i18n("Backup"), basicTab); QGridLayout *backupBoxLayout = new QGridLayout(backupBox); backupBoxLayout->setSpacing(5); QCheckBox *makeBackups = new QCheckBox(Smb4KSettings::self()->makeBackupsItem()->label(), backupBox); makeBackups->setObjectName("kcfg_MakeBackups"); QCheckBox *backupSuffixButton = new QCheckBox(Smb4KSettings::self()->useBackupSuffixItem()->label(), backupBox); backupSuffixButton->setObjectName("kcfg_UseBackupSuffix"); KLineEdit *backupSuffix = new KLineEdit(backupBox); backupSuffix->setObjectName("kcfg_BackupSuffix"); backupSuffix->setClearButtonEnabled(true); QCheckBox *backupDirButton = new QCheckBox(Smb4KSettings::self()->useBackupDirectoryItem()->label(), backupBox); backupDirButton->setObjectName("kcfg_UseBackupDirectory"); KUrlRequester *backupDir= new KUrlRequester(backupBox); backupDir->setObjectName("kcfg_BackupDirectory"); backupDir->setMode(KFile::Directory | KFile::LocalOnly); backupBoxLayout->addWidget(makeBackups, 0, 0, 0); backupBoxLayout->addWidget(backupSuffixButton, 1, 0, 0); backupBoxLayout->addWidget(backupSuffix, 1, 1, 0); backupBoxLayout->addWidget(backupDirButton, 2, 0, 0); backupBoxLayout->addWidget(backupDir, 2, 1, 0); basicTabLayout->addWidget(pathsBox, 0); basicTabLayout->addWidget(behaviorBox, 0); basicTabLayout->addWidget(backupBox, 0); basicTabLayout->addStretch(100); addTab(basicTab, i18n("Basic Settings")); // // 'File Handling' tab // QWidget *fileHandlingTab = new QWidget(this); QVBoxLayout *fileHandlingTabLayout = new QVBoxLayout(fileHandlingTab); fileHandlingTabLayout->setSpacing(5); fileHandlingTabLayout->setMargin(0); // General QGroupBox *generalHandlingBox = new QGroupBox(i18n("General"), fileHandlingTab); QGridLayout *generalHandlingBoxLayout = new QGridLayout(generalHandlingBox); generalHandlingBoxLayout->setSpacing(5); QCheckBox *updateTarget = new QCheckBox(Smb4KSettings::self()->updateTargetItem()->label(), generalHandlingBox); updateTarget->setObjectName("kcfg_UpdateTarget"); QCheckBox *updateInPlace = new QCheckBox(Smb4KSettings::self()->updateInPlaceItem()->label(), generalHandlingBox); updateInPlace->setObjectName("kcfg_UpdateInPlace"); QCheckBox *sparseFiles = new QCheckBox(Smb4KSettings::self()->efficientSparseFileHandlingItem()->label(), generalHandlingBox); sparseFiles->setObjectName("kcfg_EfficientSparseFileHandling"); QCheckBox *copyFilesWhole = new QCheckBox(Smb4KSettings::self()->copyFilesWholeItem()->label(), generalHandlingBox); copyFilesWhole->setObjectName("kcfg_CopyFilesWhole"); QCheckBox *updateExisting = new QCheckBox(Smb4KSettings::self()->updateExistingItem()->label(), generalHandlingBox); updateExisting->setObjectName("kcfg_UpdateExisting"); QCheckBox *ignoreExisting = new QCheckBox(Smb4KSettings::self()->ignoreExistingItem()->label(), generalHandlingBox); ignoreExisting->setObjectName("kcfg_IgnoreExisting"); generalHandlingBoxLayout->addWidget(updateTarget, 0, 0, 0); generalHandlingBoxLayout->addWidget(updateInPlace, 0, 1, 0); generalHandlingBoxLayout->addWidget(sparseFiles, 1, 0, 0); generalHandlingBoxLayout->addWidget(copyFilesWhole, 1, 1, 0); generalHandlingBoxLayout->addWidget(updateExisting, 2, 0, 0); generalHandlingBoxLayout->addWidget(ignoreExisting, 2, 1, 0); // Links QGroupBox *linksBox = new QGroupBox(i18n("Links"), fileHandlingTab); QGridLayout *linksBoxLayout = new QGridLayout(linksBox); linksBoxLayout->setSpacing(5); QCheckBox *preserveLinks = new QCheckBox(Smb4KSettings::self()->preserveSymlinksItem()->label(), linksBox); preserveLinks->setObjectName("kcfg_PreserveSymlinks"); QCheckBox *transformLinks = new QCheckBox(Smb4KSettings::self()->transformSymlinksItem()->label(), linksBox); transformLinks->setObjectName("kcfg_TransformSymlinks"); QCheckBox *transformUnsafe = new QCheckBox(Smb4KSettings::self()->transformUnsafeSymlinksItem()->label(), linksBox); transformUnsafe->setObjectName("kcfg_TransformUnsafeSymlinks"); QCheckBox *ignoreUnsafe = new QCheckBox(Smb4KSettings::self()->ignoreUnsafeSymlinksItem()->label(), linksBox); ignoreUnsafe->setObjectName("kcfg_IgnoreUnsafeSymlinks"); QCheckBox *mungeLinks = new QCheckBox(Smb4KSettings::self()->mungeSymlinksItem()->label(), linksBox); mungeLinks->setObjectName("kcfg_MungeSymlinks"); QCheckBox *preserveHlinks = new QCheckBox(Smb4KSettings::self()->preserveHardLinksItem()->label(), linksBox); preserveHlinks->setObjectName("kcfg_PreserveHardLinks"); QCheckBox *copyDirLinks = new QCheckBox(Smb4KSettings::self()->copyDirectorySymlinksItem()->label(), linksBox); copyDirLinks->setObjectName("kcfg_CopyDirectorySymlinks"); QCheckBox *keepDirLinks = new QCheckBox(Smb4KSettings::self()->keepDirectorySymlinksItem()->label(), linksBox); keepDirLinks->setObjectName("kcfg_KeepDirectorySymlinks"); linksBoxLayout->addWidget(preserveLinks, 0, 0, 0); linksBoxLayout->addWidget(transformLinks, 0, 1, 0); linksBoxLayout->addWidget(transformUnsafe, 1, 0, 0); linksBoxLayout->addWidget(ignoreUnsafe, 1, 1, 0); linksBoxLayout->addWidget(mungeLinks, 2, 0, 0); linksBoxLayout->addWidget(preserveHlinks, 2, 1, 0); linksBoxLayout->addWidget(copyDirLinks, 3, 0, 0); linksBoxLayout->addWidget(keepDirLinks, 3, 1, 0); // Permissions & Attributes QGroupBox *permissionsBox = new QGroupBox(i18n("Permissions, etc."), fileHandlingTab); QGridLayout *permissionsBoxLayout = new QGridLayout(permissionsBox); permissionsBoxLayout->setSpacing(5); QCheckBox *preservePerms = new QCheckBox(Smb4KSettings::self()->preservePermissionsItem()->label(), permissionsBox); preservePerms->setObjectName("kcfg_PreservePermissions"); QCheckBox *preserveOwner = new QCheckBox(Smb4KSettings::self()->preserveOwnerItem()->label(), permissionsBox); preserveOwner->setObjectName("kcfg_PreserveOwner"); QCheckBox *preserveGroup = new QCheckBox(Smb4KSettings::self()->preserveGroupItem()->label(), permissionsBox); preserveGroup->setObjectName("kcfg_PreserveGroup"); QCheckBox *preserveDevices = new QCheckBox(Smb4KSettings::self()->preserveDevicesAndSpecialsItem()->label(), permissionsBox); preserveDevices->setObjectName("kcfg_PreserveDevicesAndSpecials"); QCheckBox *preserveTimes = new QCheckBox(Smb4KSettings::self()->preserveTimesItem()->label(), permissionsBox); preserveTimes->setObjectName("kcfg_PreserveTimes"); QCheckBox *omitDirTimes = new QCheckBox(Smb4KSettings::self()->omitDirectoryTimesItem()->label(), permissionsBox); omitDirTimes->setObjectName("kcfg_OmitDirectoryTimes"); permissionsBoxLayout->addWidget(preservePerms, 0, 0, 0); permissionsBoxLayout->addWidget(preserveOwner, 0, 1, 0); permissionsBoxLayout->addWidget(preserveGroup, 1, 0, 0); permissionsBoxLayout->addWidget(preserveDevices, 1, 1, 0); permissionsBoxLayout->addWidget(preserveTimes, 2, 0, 0); permissionsBoxLayout->addWidget(omitDirTimes, 2, 1, 0); fileHandlingTabLayout->addWidget(generalHandlingBox, 0); fileHandlingTabLayout->addWidget(linksBox, 0); fileHandlingTabLayout->addWidget(permissionsBox, 0); fileHandlingTabLayout->addStretch(100); addTab(fileHandlingTab, i18n("File Handling")); // // 'File Transfer' tab // QWidget *transferTab = new QWidget(this); QVBoxLayout *transferTabLayout = new QVBoxLayout(transferTab); transferTabLayout->setSpacing(5); transferTabLayout->setMargin(0); // Compression QGroupBox *compressionBox = new QGroupBox(i18n("Compression"), transferTab); QGridLayout *compressionBoxLayout = new QGridLayout(compressionBox); compressionBoxLayout->setSpacing(5); QCheckBox *compressData = new QCheckBox(Smb4KSettings::self()->compressDataItem()->label(), compressionBox); compressData->setObjectName("kcfg_CompressData"); QCheckBox *compressionLevelButton = new QCheckBox(Smb4KSettings::self()->useCompressionLevelItem()->label(), compressionBox); compressionLevelButton->setObjectName("kcfg_UseCompressionLevel"); QSpinBox *compressionLevel = new QSpinBox(compressionBox); compressionLevel->setObjectName("kcfg_CompressionLevel"); QCheckBox *skipCompressionButton = new QCheckBox(Smb4KSettings::self()->useSkipCompressionItem()->label(), compressionBox); skipCompressionButton->setObjectName("kcfg_UseSkipCompression"); KLineEdit *skipCompression = new KLineEdit(compressionBox); skipCompression->setObjectName("kcfg_SkipCompression"); skipCompression->setClearButtonEnabled(true); compressionBoxLayout->addWidget(compressData, 0, 0, 1, -1, 0); compressionBoxLayout->addWidget(compressionLevelButton, 1, 0, 1, 1, 0); compressionBoxLayout->addWidget(compressionLevel, 1, 1, 1, 1, 0); compressionBoxLayout->addWidget(skipCompressionButton, 2, 0, 1, 1, 0); compressionBoxLayout->addWidget(skipCompression, 2, 1, 1, 1, 0); // Files QGroupBox *filesBox = new QGroupBox(i18n("Files"), transferTab); QGridLayout *filesBoxLayout = new QGridLayout(filesBox); filesBoxLayout->setSpacing(5); QCheckBox *minTransferSizeButton = new QCheckBox(Smb4KSettings::self()->useMinimalTransferSizeItem()->label(), filesBox); minTransferSizeButton->setObjectName("kcfg_UseMinimalTransferSize"); QSpinBox *minTransferSize = new QSpinBox(filesBox); minTransferSize->setObjectName("kcfg_MinimalTransferSize"); minTransferSize->setSuffix(i18n(" KiB")); QCheckBox *maxTransferSizeButton = new QCheckBox(Smb4KSettings::self()->useMaximalTransferSizeItem()->label(), filesBox); maxTransferSizeButton->setObjectName("kcfg_UseMaximalTransferSize"); QSpinBox *maxTransferSize = new QSpinBox(filesBox); maxTransferSize->setObjectName("kcfg_MaximalTransferSize"); maxTransferSize->setSuffix(i18n(" KiB")); QCheckBox *keepPartial = new QCheckBox(Smb4KSettings::self()->keepPartialItem()->label(), filesBox); keepPartial->setObjectName("kcfg_KeepPartial"); QCheckBox *partialDirButton = new QCheckBox(Smb4KSettings::self()->usePartialDirectoryItem()->label(), filesBox); partialDirButton->setObjectName("kcfg_UsePartialDirectory"); KUrlRequester *partialDir = new KUrlRequester(filesBox); partialDir->setObjectName("kcfg_PartialDirectory"); partialDir->setMode(KFile::Directory | KFile::LocalOnly); filesBoxLayout->addWidget(minTransferSizeButton, 0, 0, 0); filesBoxLayout->addWidget(minTransferSize, 0, 1, 0); filesBoxLayout->addWidget(maxTransferSizeButton, 1, 0, 0); filesBoxLayout->addWidget(maxTransferSize, 1, 1, 0); filesBoxLayout->addWidget(keepPartial, 2, 0, 1, -1, 0); filesBoxLayout->addWidget(partialDirButton, 3, 0, 0); filesBoxLayout->addWidget(partialDir, 3, 1, 0); // Miscellaneous QGroupBox *miscTransferBox = new QGroupBox(i18n("Miscellaneous"), transferTab); QGridLayout *miscTransferBoxLayout = new QGridLayout(miscTransferBox); miscTransferBoxLayout->setSpacing(5); QCheckBox *bwLimitButton = new QCheckBox(Smb4KSettings::self()->useBandwidthLimitItem()->label(), miscTransferBox); bwLimitButton->setObjectName("kcfg_UseBandwidthLimit"); QSpinBox *bwLimit = new QSpinBox(miscTransferBox); bwLimit->setObjectName("kcfg_BandwidthLimit"); bwLimit->setSuffix(i18n(" KiB/s")); miscTransferBoxLayout->addWidget(bwLimitButton, 0, 0, 0); miscTransferBoxLayout->addWidget(bwLimit, 0, 1, 0); transferTabLayout->addWidget(compressionBox, 0); transferTabLayout->addWidget(filesBox, 0); transferTabLayout->addWidget(miscTransferBox, 0); transferTabLayout->addStretch(100); addTab(transferTab, i18n("File Transfer")); // // 'File Deletion' tab // QWidget *deleteTab = new QWidget(this); QVBoxLayout *deleteTabLayout = new QVBoxLayout(deleteTab); deleteTabLayout->setSpacing(5); deleteTabLayout->setMargin(0); // Files and Directories QGroupBox *filesAndDirsBox = new QGroupBox(i18n("Files && Directories"), deleteTab); QGridLayout *filesAndDirsBoxLayout = new QGridLayout(filesAndDirsBox); filesAndDirsBoxLayout->setSpacing(5); QCheckBox *removeSource = new QCheckBox(Smb4KSettings::self()->removeSourceFilesItem()->label(), filesAndDirsBox); removeSource->setObjectName("kcfg_RemoveSourceFiles"); QCheckBox *deleteExtraneous = new QCheckBox(Smb4KSettings::self()->deleteExtraneousItem()->label(), filesAndDirsBox); deleteExtraneous->setObjectName("kcfg_DeleteExtraneous"); QCheckBox *deleteBefore = new QCheckBox(Smb4KSettings::self()->deleteBeforeItem()->label(), filesAndDirsBox); deleteBefore->setObjectName("kcfg_DeleteBefore"); QCheckBox *deleteAfter = new QCheckBox(Smb4KSettings::self()->deleteAfterItem()->label(), filesAndDirsBox); deleteAfter->setObjectName("kcfg_DeleteAfter"); QCheckBox *deleteDuring = new QCheckBox(Smb4KSettings::self()->deleteDuringItem()->label(), filesAndDirsBox); deleteDuring->setObjectName("kcfg_DeleteDuring"); QCheckBox *deleteExcluded = new QCheckBox(Smb4KSettings::self()->deleteExcludedItem()->label(), filesAndDirsBox); deleteExcluded->setObjectName("kcfg_DeleteExcluded"); QCheckBox *ignoreIOErrors = new QCheckBox(Smb4KSettings::self()->ignoreErrorsItem()->label(), filesAndDirsBox); ignoreIOErrors->setObjectName("kcfg_IgnoreErrors"); QCheckBox *forceDirDeletion = new QCheckBox(Smb4KSettings::self()->forceDirectoryDeletionItem()->label(), filesAndDirsBox); forceDirDeletion->setObjectName("kcfg_ForceDirectoryDeletion"); filesAndDirsBoxLayout->addWidget(removeSource, 0, 0, 0); filesAndDirsBoxLayout->addWidget(deleteExtraneous, 0, 1, 0); filesAndDirsBoxLayout->addWidget(deleteBefore, 1, 0, 0); filesAndDirsBoxLayout->addWidget(deleteAfter, 1, 1, 0); filesAndDirsBoxLayout->addWidget(deleteDuring, 2, 0, 0); filesAndDirsBoxLayout->addWidget(deleteExcluded, 2, 1, 0); filesAndDirsBoxLayout->addWidget(ignoreIOErrors, 3, 0, 0); filesAndDirsBoxLayout->addWidget(forceDirDeletion, 3, 1, 0); // Restrictions QGroupBox *restrictionsBox = new QGroupBox(i18n("Restrictions"), deleteTab); QGridLayout *restrictionsBoxLayout = new QGridLayout(restrictionsBox); restrictionsBoxLayout->setSpacing(5); QCheckBox *maxDeleteButton = new QCheckBox(Smb4KSettings::self()->useMaximumDeleteItem()->label(), restrictionsBox); maxDeleteButton->setObjectName("kcfg_UseMaximumDelete"); QSpinBox *maxDelete = new QSpinBox(restrictionsBox); maxDelete->setObjectName("kcfg_MaximumDeleteValue"); restrictionsBoxLayout->addWidget(maxDeleteButton, 0, 0, 0); restrictionsBoxLayout->addWidget(maxDelete, 0, 1, 0); deleteTabLayout->addWidget(filesAndDirsBox, 0); deleteTabLayout->addWidget(restrictionsBox, 0); deleteTabLayout->addStretch(100); addTab(deleteTab, i18n("File Deletion")); // // 'Filter' tab // QWidget *filterTab = new QWidget(this); QVBoxLayout *filterTabLayout = new QVBoxLayout(filterTab); filterTabLayout->setSpacing(5); filterTabLayout->setMargin(0); // General QGroupBox *generalFilterBox = new QGroupBox(i18n("General"), filterTab); QGridLayout *generalFilterBoxLayout = new QGridLayout(generalFilterBox); generalFilterBoxLayout->setSpacing(5); QCheckBox *cvsExclude = new QCheckBox(Smb4KSettings::self()->useCVSExcludeItem()->label(), generalFilterBox); cvsExclude->setObjectName("kcfg_UseCVSExclude"); QCheckBox *excludePatternButton = new QCheckBox(Smb4KSettings::self()->useExcludePatternItem()->label(), generalFilterBox); excludePatternButton->setObjectName("kcfg_UseExcludePattern"); KLineEdit *excludePattern = new KLineEdit(generalFilterBox); excludePattern->setObjectName("kcfg_ExcludePattern"); excludePattern->setClearButtonEnabled(true); QCheckBox *excludeFromButton = new QCheckBox(Smb4KSettings::self()->useExcludeFromItem()->label(), generalFilterBox); excludeFromButton->setObjectName("kcfg_UseExcludeFrom"); KUrlRequester *excludeFrom = new KUrlRequester(generalFilterBox); excludeFrom->setObjectName("kcfg_ExcludeFrom"); excludeFrom->setMode(KFile::File | KFile::LocalOnly); QCheckBox *includePatternButton = new QCheckBox(Smb4KSettings::self()->useIncludePatternItem()->label(), generalFilterBox); includePatternButton->setObjectName("kcfg_UseIncludePattern"); KLineEdit *includePattern = new KLineEdit(generalFilterBox); includePattern->setObjectName("kcfg_IncludePattern"); includePattern->setClearButtonEnabled(true); QCheckBox *includeFromButton = new QCheckBox(Smb4KSettings::self()->useIncludeFromItem()->label(), generalFilterBox); includeFromButton->setObjectName("kcfg_UseIncludeFrom"); KUrlRequester *includeFrom = new KUrlRequester(generalFilterBox); includeFrom->setObjectName("kcfg_IncludeFrom"); includeFrom->setMode(KFile::File | KFile::LocalOnly); generalFilterBoxLayout->addWidget(cvsExclude, 0, 0, 1, -1, 0); generalFilterBoxLayout->addWidget(excludePatternButton, 1, 0, 0); generalFilterBoxLayout->addWidget(excludePattern, 1, 1, 0); generalFilterBoxLayout->addWidget(excludeFromButton, 2, 0, 0); generalFilterBoxLayout->addWidget(excludeFrom, 2, 1, 0); generalFilterBoxLayout->addWidget(includePatternButton, 3, 0, 0); generalFilterBoxLayout->addWidget(includePattern, 3, 1, 0); generalFilterBoxLayout->addWidget(includeFromButton, 4, 0, 0); generalFilterBoxLayout->addWidget(includeFrom, 4, 1, 0); // Filter rules QGroupBox *filterRulesBox = new QGroupBox(i18n("Filter Rules"), filterTab); QGridLayout *filterRulesBoxLayout = new QGridLayout(filterRulesBox); filterRulesBoxLayout->setSpacing(5); QLabel *customRulesLabel = new QLabel(Smb4KSettings::self()->customFilteringRulesItem()->label(), filterRulesBox); KLineEdit *customRules = new KLineEdit(filterRulesBox); customRules->setObjectName("kcfg_CustomFilteringRules"); customRules->setClearButtonEnabled(true); customRulesLabel->setBuddy(customRules); QLabel *specialRulesLabel = new QLabel(i18n("Special filter rules:"), filterRulesBox); QCheckBox *useFFilterRule = new QCheckBox(Smb4KSettings::self()->useFFilterRuleItem()->label(), filterRulesBox); useFFilterRule->setObjectName("kcfg_UseFFilterRule"); QCheckBox *useFFFilterRule = new QCheckBox(Smb4KSettings::self()->useFFFilterRuleItem()->label(), filterRulesBox); useFFFilterRule->setObjectName("kcfg_UseFFFilterRule"); filterRulesBoxLayout->addWidget(customRulesLabel, 0, 0, 0); filterRulesBoxLayout->addWidget(customRules, 0, 1, 0); filterRulesBoxLayout->addWidget(specialRulesLabel, 1, 0, 1, -1, 0); filterRulesBoxLayout->addWidget(useFFilterRule, 2, 0, 1, -1, 0); filterRulesBoxLayout->addWidget(useFFFilterRule, 3, 0, 1, -1, 0); filterTabLayout->addWidget(generalFilterBox, 0); filterTabLayout->addWidget(filterRulesBox, 0); filterTabLayout->addStretch(100); addTab(filterTab, i18n("Filtering")); // // 'Miscellaneous' tab // QWidget *miscTab = new QWidget(this); QVBoxLayout *miscTabLayout = new QVBoxLayout(miscTab); miscTabLayout->setSpacing(5); miscTabLayout->setMargin(0); // Checksums QGroupBox *checksumsBox= new QGroupBox(i18n("Checksums"), miscTab); QGridLayout *checksumsBoxLayout = new QGridLayout(checksumsBox); checksumsBoxLayout->setSpacing(5); QCheckBox *blockSizeButton = new QCheckBox(Smb4KSettings::self()->useBlockSizeItem()->label(), checksumsBox); blockSizeButton->setObjectName("kcfg_UseBlockSize"); QSpinBox *blockSize = new QSpinBox(checksumsBox); blockSize->setObjectName("kcfg_BlockSize"); QCheckBox *checksumSeedButton = new QCheckBox(Smb4KSettings::self()->useChecksumSeedItem()->label(), checksumsBox); checksumSeedButton->setObjectName("kcfg_UseChecksumSeed"); QSpinBox *checksumSeed = new QSpinBox(checksumsBox); checksumSeed->setObjectName("kcfg_ChecksumSeed"); QCheckBox *useChecksum = new QCheckBox(Smb4KSettings::self()->useChecksumItem()->label(), checksumsBox); useChecksum->setObjectName("kcfg_UseChecksum"); checksumsBoxLayout->addWidget(blockSizeButton, 0, 0, 0); checksumsBoxLayout->addWidget(blockSize, 0, 1, 0); checksumsBoxLayout->addWidget(checksumSeedButton, 1, 0, 0); checksumsBoxLayout->addWidget(checksumSeed, 1, 1, 0); checksumsBoxLayout->addWidget(useChecksum, 2, 0, 0); // Miscellaneous QGroupBox *miscBox = new QGroupBox(i18n("Miscellaneous"), miscTab); QGridLayout *miscBoxLayout = new QGridLayout(miscBox); miscBoxLayout->setSpacing(5); QCheckBox *oneFilesystem = new QCheckBox(Smb4KSettings::self()->oneFileSystemItem()->label(), miscBox); oneFilesystem->setObjectName("kcfg_OneFileSystem"); QCheckBox *delayUpdates = new QCheckBox(Smb4KSettings::self()->delayUpdatesItem()->label(), miscBox); delayUpdates->setObjectName("kcfg_DelayUpdates"); miscBoxLayout->addWidget(oneFilesystem, 0, 0, 0); miscBoxLayout->addWidget(delayUpdates, 0, 1, 0); miscTabLayout->addWidget(checksumsBox, 0); miscTabLayout->addWidget(miscBox, 0); miscTabLayout->addStretch(100); addTab(miscTab, i18n("Miscellaneous")); // // Connections // connect(archiveMode, SIGNAL(toggled(bool)), this, SLOT(slotArchiveToggled(bool))); connect(recurseDirs, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preserveLinks, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preservePerms, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preserveTimes, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preserveGroup, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preserveOwner, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(preserveDevices, SIGNAL(toggled(bool)), this, SLOT(slotUncheckArchive(bool))); connect(useFFilterRule, SIGNAL(toggled(bool)), this, SLOT(slotFFilterRuleToggled(bool))); connect(useFFFilterRule, SIGNAL(toggled(bool)), this, SLOT(slotFFFilterRuleToggled(bool))); connect(makeBackups, SIGNAL(toggled(bool)), this, SLOT(slotBackupToggled(bool))); connect(compressData, SIGNAL(toggled(bool)), this, SLOT(slotCompressToggled(bool))); connect(keepPartial, SIGNAL(toggled(bool)), this, SLOT(slotKeepPartialToggled(bool))); slotArchiveToggled(Smb4KSettings::archiveMode()); slotBackupToggled(Smb4KSettings::makeBackups()); slotCompressToggled(Smb4KSettings::compressData()); slotKeepPartialToggled(Smb4KSettings::keepPartial()); } Smb4KConfigPageSynchronization::~Smb4KConfigPageSynchronization() { } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KConfigPageSynchronization::slotArchiveToggled(bool checked) { if (checked) { findChild("kcfg_RecurseIntoDirectories")->setChecked(checked); findChild("kcfg_PreserveSymlinks")->setChecked(checked); findChild("kcfg_PreservePermissions")->setChecked(checked); findChild("kcfg_PreserveTimes")->setChecked(checked); findChild("kcfg_PreserveGroup")->setChecked(checked); findChild("kcfg_PreserveOwner")->setChecked(checked); findChild("kcfg_PreserveDevicesAndSpecials")->setChecked(checked); } } void Smb4KConfigPageSynchronization::slotUncheckArchive(bool checked) { if (!checked) { findChild("kcfg_ArchiveMode")->setChecked(checked); } } void Smb4KConfigPageSynchronization::slotBackupToggled(bool checked) { findChild("kcfg_UseBackupDirectory")->setEnabled(checked); findChild("kcfg_BackupDirectory")->setEnabled(checked); findChild("kcfg_UseBackupSuffix")->setEnabled(checked); findChild("kcfg_BackupSuffix")->setEnabled(checked); } void Smb4KConfigPageSynchronization::slotCompressToggled(bool checked) { findChild("kcfg_UseCompressionLevel")->setEnabled(checked); findChild("kcfg_CompressionLevel")->setEnabled(checked); findChild("kcfg_UseSkipCompression")->setEnabled(checked); findChild("kcfg_SkipCompression")->setEnabled(checked); } void Smb4KConfigPageSynchronization::slotKeepPartialToggled(bool checked) { findChild("kcfg_UsePartialDirectory")->setEnabled(checked); findChild("kcfg_PartialDirectory")->setEnabled(checked); } void Smb4KConfigPageSynchronization::slotFFilterRuleToggled(bool on) { QCheckBox *ff_filter = findChild("kcfg_UseFFFilterRule"); if (on && ff_filter->isChecked()) { ff_filter->setChecked(false); } } void Smb4KConfigPageSynchronization::slotFFFilterRuleToggled(bool on) { QCheckBox *f_filter = findChild("kcfg_UseFFilterRule"); if (on && f_filter->isChecked()) { f_filter->setChecked(false); } } diff --git a/smb4k/smb4kconfigpageuserinterface.cpp b/smb4k/smb4kconfigpageuserinterface.cpp index b59c423..406af67 100644 --- a/smb4k/smb4kconfigpageuserinterface.cpp +++ b/smb4k/smb4kconfigpageuserinterface.cpp @@ -1,231 +1,227 @@ /*************************************************************************** This configuration page takes care of all settings concerning the user interface ------------------- begin : Mi Aug 30 2006 copyright : (C) 2006-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kconfigpageuserinterface.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include #include #include #include #include // KDE includes #include #include Smb4KConfigPageUserInterface::Smb4KConfigPageUserInterface(QWidget *parent) : QWidget(parent) { // // Layout // QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(5); layout->setMargin(0); // // Main Window settings // QGroupBox *mainWindowBox = new QGroupBox(i18n("Main Window"), this); QGridLayout *mainWindowBoxLayout = new QGridLayout(mainWindowBox); mainWindowBoxLayout->setSpacing(5); QLabel *tabOrientationLabel = new QLabel(Smb4KSettings::self()->mainWindowTabOrientationItem()->label(), mainWindowBox); KComboBox *tabOrientation = new KComboBox(mainWindowBox); tabOrientation->setObjectName("kcfg_MainWindowTabOrientation"); QList tabOrientationChoices = Smb4KSettings::self()->mainWindowTabOrientationItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &to : tabOrientationChoices) { tabOrientation->addItem(to.label); } tabOrientationLabel->setBuddy(tabOrientation); mainWindowBoxLayout->addWidget(tabOrientationLabel, 0, 0, 0); mainWindowBoxLayout->addWidget(tabOrientation, 0, 1, 0); QCheckBox *showBookmarkLabel = new QCheckBox(Smb4KSettings::self()->showCustomBookmarkLabelItem()->label(), mainWindowBox); showBookmarkLabel->setObjectName("kcfg_ShowCustomBookmarkLabel"); mainWindowBoxLayout->addWidget(showBookmarkLabel, 1, 0, 1, 2, 0); layout->addWidget(mainWindowBox, 0); // // Network Neighborhood settings // QGroupBox *networkNeighhoodBox = new QGroupBox(i18n("Network Neighborhood"), this); QGridLayout *networkNeighhoodBoxLayout = new QGridLayout(networkNeighhoodBox); networkNeighhoodBoxLayout->setSpacing(5); QCheckBox *autoExpand = new QCheckBox(Smb4KSettings::self()->autoExpandNetworkItemsItem()->label(), networkNeighhoodBox); autoExpand->setObjectName("kcfg_AutoExpandNetworkItems"); networkNeighhoodBoxLayout->addWidget(autoExpand, 0, 0, 0); QCheckBox *showType = new QCheckBox(Smb4KSettings::self()->showTypeItem()->label(), networkNeighhoodBox); showType->setObjectName("kcfg_ShowType"); networkNeighhoodBoxLayout->addWidget(showType, 0, 1, 0); QCheckBox *showIpAddress = new QCheckBox(Smb4KSettings::self()->showIPAddressItem()->label(), networkNeighhoodBox); showIpAddress->setObjectName("kcfg_ShowIPAddress"); networkNeighhoodBoxLayout->addWidget(showIpAddress, 1, 0, 0); QCheckBox *showComment = new QCheckBox(Smb4KSettings::self()->showCommentItem()->label(), networkNeighhoodBox); showComment->setObjectName("kcfg_ShowComment"); networkNeighhoodBoxLayout->addWidget(showComment, 1, 1, 0); QCheckBox *showNetworkTooltip = new QCheckBox(Smb4KSettings::self()->showNetworkItemToolTipItem()->label(), networkNeighhoodBox); showNetworkTooltip->setObjectName("kcfg_ShowNetworkItemToolTip"); networkNeighhoodBoxLayout->addWidget(showNetworkTooltip, 2, 0, 1, 2, 0); layout->addWidget(networkNeighhoodBox, 0); // // Shares View settings // QGroupBox *sharesViewBox = new QGroupBox(i18n("Shares View"), this); QGridLayout *sharesViewBoxLayout = new QGridLayout(sharesViewBox); sharesViewBoxLayout->setSpacing(5); QLabel *viewModeLabel = new QLabel(Smb4KSettings::self()->sharesViewModeItem()->label(), sharesViewBox); KComboBox *viewMode = new KComboBox(sharesViewBox); viewMode->setObjectName("kcfg_SharesViewMode"); QList sharesViewModeChoices = Smb4KSettings::self()->sharesViewModeItem()->choices(); for (const KCoreConfigSkeleton::ItemEnum::Choice &vm : sharesViewModeChoices) { viewMode->addItem(vm.label); } viewModeLabel->setBuddy(viewMode); sharesViewBoxLayout->addWidget(viewModeLabel, 0, 0, 0); sharesViewBoxLayout->addWidget(viewMode, 0, 1, 0); QCheckBox *showShareTooltip = new QCheckBox(Smb4KSettings::self()->showShareToolTipItem()->label(), sharesViewBox); showShareTooltip->setObjectName("kcfg_ShowShareToolTip"); sharesViewBoxLayout->addWidget(showShareTooltip, 1, 0, 1, 2, 0); layout->addWidget(sharesViewBox, 0); layout->addStretch(100); // // Network item tooltips // QGroupBox *network_tooltips_box = new QGroupBox(i18n("Tooltips"), networkNeighborhoodTab); // // QGridLayout *n_tooltips_layout = new QGridLayout(network_tooltips_box); // n_tooltips_layout->setSpacing(5); // // // n_tooltips_layout->addWidget(network_tooltip, 0, 0, 0); // // networkNeighborhoodTabLayout->addWidget(behavior_box); // networkNeighborhoodTabLayout->addWidget(columns_box); // networkNeighborhoodTabLayout->addWidget(network_tooltips_box); // networkNeighborhoodTabLayout->addStretch(100); // // addTab(networkNeighborhoodTab, i18n("Network Neighborhood")); // // // // // Shares view // // // QWidget *shares_view_tab = new QWidget(this); // // QVBoxLayout *shares_view_layout = new QVBoxLayout(shares_view_tab); // shares_view_layout->setSpacing(5); // shares_view_layout->setMargin(0); // // // View // QGroupBox *viewBox = new QGroupBox(i18n("View Mode"), shares_view_tab); // QHBoxLayout *viewBoxLayout = new QHBoxLayout(viewBox); // viewBoxLayout->setSpacing(5); // // QLabel *viewModeLabel = new QLabel(Smb4KSettings::self()->sharesViewModeItem()->label(), viewBox); // KComboBox *viewMode = new KComboBox(viewBox); // viewMode->setObjectName("kcfg_SharesViewMode"); // viewMode->insertItem(Smb4KSettings::EnumSharesViewMode::IconView, // Smb4KSettings::self()->sharesViewModeItem()->choices().value(Smb4KSettings::EnumSharesViewMode::IconView).label); // viewMode->insertItem(Smb4KSettings::EnumSharesViewMode::ListView, // Smb4KSettings::self()->sharesViewModeItem()->choices().value(Smb4KSettings::EnumSharesViewMode::ListView).label); // viewModeLabel->setBuddy(viewMode); // // viewBoxLayout->addWidget(viewModeLabel); // viewBoxLayout->addWidget(viewMode); // // // Share tooltips // QGroupBox *share_tooltips_box = new QGroupBox(i18n("Tooltips"), shares_view_tab); // // QGridLayout *s_tooltips_layout = new QGridLayout(share_tooltips_box); // s_tooltips_layout->setSpacing(5); // // QCheckBox *show_share_tooltip = new QCheckBox(Smb4KSettings::self()->showShareToolTipItem()->label(), share_tooltips_box); // show_share_tooltip->setObjectName("kcfg_ShowShareToolTip"); // // s_tooltips_layout->addWidget(show_share_tooltip, 0, 0, 0); // // QSpacerItem *spacer4 = new QSpacerItem(10, 10, QSizePolicy::Preferred, QSizePolicy::Expanding); // // shares_view_layout->addWidget(viewBox); // shares_view_layout->addWidget(share_tooltips_box); // shares_view_layout->addItem(spacer4); // // addTab(shares_view_tab, i18n("Mounted Shares")); } Smb4KConfigPageUserInterface::~Smb4KConfigPageUserInterface() { } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// diff --git a/smb4k/smb4kmainwindow.cpp b/smb4k/smb4kmainwindow.cpp index 22ab2fc..5d471ea 100644 --- a/smb4k/smb4kmainwindow.cpp +++ b/smb4k/smb4kmainwindow.cpp @@ -1,1128 +1,1124 @@ /*************************************************************************** The main window of Smb4K ------------------- begin : Di Jan 1 2008 copyright : (C) 2008-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kmainwindow.h" #include "smb4ksystemtray.h" #include "smb4kbookmarkmenu.h" #include "smb4kprofilesmenu.h" #include "smb4knetworkbrowserdockwidget.h" #include "smb4ksharesviewdockwidget.h" #include "core/smb4ksettings.h" #include "core/smb4kglobal.h" #include "core/smb4kwalletmanager.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" #include "core/smb4kfile.h" #include "core/smb4kmounter.h" #include "core/smb4ksynchronizer.h" #include "core/smb4kclient.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include using namespace Smb4KGlobal; using namespace KParts; Smb4KMainWindow::Smb4KMainWindow() : KXmlGuiWindow(), m_system_tray_widget(0) { // // The widget (embedded into the dock widgets) that has the focus // m_focusWidget = 0; // // Set up main window // setStandardToolBarMenuEnabled(true); createStandardStatusBarAction(); setDockNestingEnabled(true); setupActions(); setupGUI(QSize(800, 600), Default, "smb4k_shell.rc"); setupView(); setupMenuBar(); setupStatusBar(); setupSystemTrayWidget(); // // Set the tab orientation // switch (Smb4KSettings::mainWindowTabOrientation()) { case Smb4KSettings::EnumMainWindowTabOrientation::Top: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Bottom: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Left: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::West); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Right: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::East); break; } default: { break; } } // // Apply the main window settings // setAutoSaveSettings(KConfigGroup(Smb4KSettings::self()->config(), "MainWindow"), true); } Smb4KMainWindow::~Smb4KMainWindow() { } void Smb4KMainWindow::setupActions() { // // Quit action // QAction *quit_action = KStandardAction::quit(this, SLOT(slotQuit()), actionCollection()); actionCollection()->addAction("quit_action", quit_action); // // Configure action // QAction *configure_action = KStandardAction::preferences(this, SLOT(slotConfigDialog()), actionCollection()); actionCollection()->addAction("configure_action", configure_action); // // Dock widgets action menu // KActionMenu *dock_widgets_menu = new KActionMenu(KDE::icon("tab-duplicate"), i18n("Dock Widgets"), actionCollection()); actionCollection()->addAction("dock_widgets_menu", dock_widgets_menu); m_dockWidgets = new QActionGroup(actionCollection()); m_dockWidgets->setExclusive(false); // // Bookmarks menu and action // Smb4KBookmarkMenu *bookmarksMenu = new Smb4KBookmarkMenu(Smb4KBookmarkMenu::MainWindow, this, this); QAction *addBookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), actionCollection()); addBookmarkAction->setEnabled(false); actionCollection()->addAction("bookmarks_menu", bookmarksMenu); actionCollection()->addAction("bookmark_action", addBookmarkAction); connect(addBookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotAddBookmarks())); connect(bookmarksMenu, SIGNAL(addBookmark()), this, SLOT(slotAddBookmarks())); // // Profiles menu // Smb4KProfilesMenu *profiles = new Smb4KProfilesMenu(this); actionCollection()->addAction("profiles_menu", profiles); } void Smb4KMainWindow::setupStatusBar() { // Set up the progress bar. m_progress_bar = new QProgressBar(statusBar()); m_progress_bar->setFixedWidth(100); m_progress_bar->setMaximum(0); m_progress_bar->setMinimum(0); m_progress_bar->setFixedHeight(statusBar()->fontMetrics().height()); m_progress_bar->setAlignment(Qt::AlignCenter); m_progress_bar->setVisible(false); // Set the icon on the right side that represents the initial // state of the wallet manager. m_pass_icon = new QLabel(statusBar()); m_pass_icon->setContentsMargins(0, 0, 0, 0); m_pass_icon->setAlignment(Qt::AlignCenter); // The feedback icon. m_feedback_icon = new QLabel(statusBar()); m_feedback_icon->setContentsMargins(0, 0, 0, 0); m_feedback_icon->setAlignment(Qt::AlignCenter); statusBar()->addPermanentWidget(m_progress_bar); statusBar()->addPermanentWidget(m_feedback_icon); statusBar()->addPermanentWidget(m_pass_icon); slotWalletManagerInitialized(); setupMountIndicator(); // // Connections // connect(Smb4KClient::self(), SIGNAL(aboutToStart(NetworkItemPtr,int)), this, SLOT(slotClientAboutToStart(NetworkItemPtr,int))); connect(Smb4KClient::self(), SIGNAL(finished(NetworkItemPtr,int)), this, SLOT(slotClientFinished(NetworkItemPtr,int))); connect(Smb4KWalletManager::self(), SIGNAL(initialized()), this, SLOT(slotWalletManagerInitialized())); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotVisualMountFeedback(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotVisualUnmountFeedback(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(aboutToStart(int)), this, SLOT(slotMounterAboutToStart(int))); connect(Smb4KMounter::self(), SIGNAL(finished(int)), this, SLOT(slotMounterFinished(int))); connect(Smb4KSynchronizer::self(), SIGNAL(aboutToStart(QString)), this, SLOT(slotSynchronizerAboutToStart(QString))); connect(Smb4KSynchronizer::self(), SIGNAL(finished(QString)), this, SLOT(slotSynchronizerFinished(QString))); } void Smb4KMainWindow::setupView() { // // We do not set a central widget, because it causes "problems" // with the dock widgets. We have the nested dock widget property // set to true, so we can arrange the dock widgets as we like, // nonetheless. // // // Network browser dock widget // Smb4KNetworkBrowserDockWidget *networkBrowserDock = new Smb4KNetworkBrowserDockWidget(i18n("Network Neighborhood"), this); networkBrowserDock->setObjectName("NetworkBrowserDockWidget"); networkBrowserDock->setAllowedAreas(Qt::LeftDockWidgetArea); // Install event filter networkBrowserDock->widget()->installEventFilter(this); // Connections connect(networkBrowserDock, SIGNAL(visibilityChanged(bool)), SLOT(slotNetworkBrowserVisibilityChanged(bool))); // Add dock widget addDockWidget(Qt::LeftDockWidgetArea, networkBrowserDock); // Insert the toggle view mode action to the action group. m_dockWidgets->addAction(networkBrowserDock->toggleViewAction()); static_cast(actionCollection()->action("dock_widgets_menu"))->addAction(networkBrowserDock->toggleViewAction()); // Insert the Network menu plugActionList("network_menu", networkBrowserDock->actionCollection()->actions()); // // Shares view dock widget // Smb4KSharesViewDockWidget *sharesViewDock = new Smb4KSharesViewDockWidget(i18n("Mounted Shares"), this); sharesViewDock->setObjectName("SharesViewDockWidget"); sharesViewDock->setAllowedAreas(Qt::LeftDockWidgetArea); // Install event filter sharesViewDock->widget()->installEventFilter(this); // Connections connect(sharesViewDock, SIGNAL(visibilityChanged(bool)), this, SLOT(slotSharesViewVisibilityChanged(bool))); // Add dock widget addDockWidget(Qt::LeftDockWidgetArea, sharesViewDock); // Insert the toggle view mode action to the action group. m_dockWidgets->addAction(sharesViewDock->toggleViewAction()); static_cast(actionCollection()->action("dock_widgets_menu"))->addAction(sharesViewDock->toggleViewAction()); // Insert the Shares menu plugActionList("shares_menu", sharesViewDock->actionCollection()->actions()); // // Initial main window look // KConfigGroup configGroup(Smb4KSettings::self()->config(), "MainWindow"); if (!configGroup.exists()) { QList docks = findChildren(); for (int i = 1; i < docks.size(); ++i) { tabifyDockWidget(docks.at(i-1), docks.at(i)); } } } void Smb4KMainWindow::setupMenuBar() { // Get the "Bookmarks" menu QList actions = menuBar()->actions(); QListIterator it(actions); while (it.hasNext()) { QAction *action = it.next(); if (QString::compare("bookmarks", action->objectName()) == 0) { Smb4KBookmarkMenu *menu = static_cast(actionCollection()->action("bookmarks_menu")); action->setMenu(menu->menu()); break; } else { continue; } } } void Smb4KMainWindow::setupSystemTrayWidget() { if (!m_system_tray_widget) { m_system_tray_widget = new Smb4KSystemTray(this); } connect(m_system_tray_widget, SIGNAL(settingsChanged(QString)), this, SLOT(slotSettingsChanged(QString))); } void Smb4KMainWindow::loadSettings() { // // Main window // switch (Smb4KSettings::mainWindowTabOrientation()) { case Smb4KSettings::EnumMainWindowTabOrientation::Top: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Bottom: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Left: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::West); break; } case Smb4KSettings::EnumMainWindowTabOrientation::Right: { setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::East); break; } default: { break; } } // // Let the network browser load its settings // Smb4KNetworkBrowserDockWidget *networkBrowserDock = findChild(); if (networkBrowserDock) { networkBrowserDock->loadSettings(); } // // Let the shares view load its settings // Smb4KSharesViewDockWidget *sharesViewDock = findChild(); if (sharesViewDock) { sharesViewDock->loadSettings(); } // // Reload the list of bookmarks // Smb4KBookmarkMenu *bookmarkMenu = findChild(); if (bookmarkMenu) { bookmarkMenu->refreshMenu(); } // Check the state of the password handler and the wallet settings and // set the pixmap in the status bar accordingly. slotWalletManagerInitialized(); // Set up the mount indicator icon. setupMountIndicator(); } void Smb4KMainWindow::saveSettings() { // // Save the settings of the network browser // Smb4KNetworkBrowserDockWidget *networkBrowserDock = findChild(); if (networkBrowserDock) { networkBrowserDock->saveSettings(); } // // Let the shares view load its settings // Smb4KSharesViewDockWidget *sharesViewDock = findChild(); if (sharesViewDock) { sharesViewDock->saveSettings(); } // // Save if the main window should be started docked. // Smb4KSettings::setStartMainWindowDocked(!isVisible()); } bool Smb4KMainWindow::queryClose() { if (!qApp->isSavingSession() && isVisible()) { // This part has been 'stolen' from JuK application. KMessageBox::information(this, i18n("Closing the main window will keep Smb4K running in the system tray. " "Use Quit from the File menu to quit the application."), i18n("Docking"), "DockToSystemTrayInfo"); setVisible(false); return false; } else { saveSettings(); return true; } } bool Smb4KMainWindow::eventFilter(QObject *obj, QEvent* e) { switch (e->type()) { case QEvent::FocusIn: { // // Check if the widget that has the focus belongs to the network // browser widget // Smb4KNetworkBrowserDockWidget *networkBrowserDock = findChild(); if (networkBrowserDock) { QObjectList children = networkBrowserDock->children(); for (QObject *object : children) { if (object == obj) { m_focusWidget = networkBrowserDock; setupDynamicActionList(networkBrowserDock); break; } } } // // Check if the widget that has the focus belongs to the shares // view // Smb4KSharesViewDockWidget *sharesViewDock = findChild(); if (sharesViewDock) { QObjectList children = sharesViewDock->children(); for (QObject *object : children) { if (object == obj) { m_focusWidget = sharesViewDock; setupDynamicActionList(sharesViewDock); break; } } } break; } default: { break; } } return KXmlGuiWindow::eventFilter(obj, e); } void Smb4KMainWindow::setupMountIndicator() { QStringList overlays; if (mountedSharesList().size() == 0) { m_feedback_icon->setToolTip(i18n("There are currently no shares mounted.")); } else { overlays.append("emblem-mounted"); m_feedback_icon->setToolTip(i18np("There is currently %1 share mounted.", "There are currently %1 shares mounted.", mountedSharesList().size())); } m_feedback_icon->setPixmap(KIconLoader::global()->loadIcon("folder-network", KIconLoader::Small, 0, KIconLoader::DefaultState, overlays)); } void Smb4KMainWindow::setupDynamicActionList(QDockWidget* dock) { if (dock) { // // Remove all connections to Smb4KMainWindow::slotEnableBookmarkAction() and // disable the bookmark action. // disconnect(this, SLOT(slotEnableBookmarkAction())); actionCollection()->action("bookmark_action")->setEnabled(false); // // Get also the bookmark menu and disable the bookmark action // there, too. // Smb4KBookmarkMenu *bookmarkMenu = findChild(); if (bookmarkMenu) { bookmarkMenu->setBookmarkActionEnabled(false); } // // Prepare the dynamic action list for the main window // QList dynamicList; KActionCollection *dockActionCollection = 0; if (dock->objectName() == "NetworkBrowserDockWidget") { dockActionCollection = static_cast(dock)->actionCollection(); } else if (dock->objectName() == "SharesViewDockWidget") { dockActionCollection = static_cast(dock)->actionCollection(); } for (QAction *action : dockActionCollection->actions()) { if (action->objectName() == "bookmark_action") { if (bookmarkMenu) { bookmarkMenu->setBookmarkActionEnabled(action->isEnabled()); connect(action, SIGNAL(changed()), this, SLOT(slotEnableBookmarkAction())); continue; } } else if (QString::compare(action->objectName(), "filemanager_action") == 0) { continue; } else if (QString::compare(action->objectName(), "konsole_action") == 0) { continue; } else if (QString::compare(action->objectName(), "icon_view_action") == 0) { continue; } else if (QString::compare(action->objectName(), "list_view_action") == 0) { continue; } dynamicList << action; } // // Remove old and insert new dynamic action list // unplugActionList("dynamic_list"); plugActionList("dynamic_list", dynamicList); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KMainWindow::slotQuit() { // // Save the settings. Work around queryClose() not being called. :( // saveSettings(); // // Quit the application // qApp->quit(); } void Smb4KMainWindow::slotConfigDialog() { // // Check if the configuration dialog exists and try to show it. // if (KConfigDialog::exists("Smb4KConfigDialog")) { KConfigDialog::showDialog("Smb4KConfigDialog"); return; } // // If the dialog does not exist, load and show it: // KPluginLoader loader("smb4kconfigdialog"); KPluginFactory *configFactory = loader.factory(); if (configFactory) { KConfigDialog *dlg = configFactory->create(this); if (dlg) { dlg->setObjectName("Smb4KConfigDialog"); connect(dlg, SIGNAL(settingsChanged(QString)), this, SLOT(slotSettingsChanged(QString)), Qt::UniqueConnection); connect(dlg, SIGNAL(settingsChanged(QString)), m_system_tray_widget, SLOT(slotSettingsChanged(QString)), Qt::UniqueConnection); dlg->show(); } } else { KMessageBox::error(0, ""+loader.errorString()+""); return; } } void Smb4KMainWindow::slotSettingsChanged(const QString &) { loadSettings(); } void Smb4KMainWindow::slotAddBookmarks() { // // If we have a widget that has the focus, trigger its 'Add Bookmark' // action to add bookmarks. // if (m_focusWidget) { if (QString::compare(m_focusWidget->metaObject()->className(), "Smb4KNetworkBrowserDockWidget") == 0) { Smb4KNetworkBrowserDockWidget *dockWidget = qobject_cast(m_focusWidget); if (dockWidget) { QAction *action = dockWidget->actionCollection()->action("bookmark_action"); // Only trigger the action if it is enabled if (action && action->isEnabled()) { action->trigger(); } } } else if (QString::compare(m_focusWidget->metaObject()->className(), "Smb4KSharesViewDockWidget") == 0) { Smb4KSharesViewDockWidget *dockWidget = qobject_cast(m_focusWidget); if (dockWidget) { QAction *action = dockWidget->actionCollection()->action("bookmark_action"); // Only trigger the action if it is enabled if (action && action->isEnabled()) { action->trigger(); } } } } } void Smb4KMainWindow::slotWalletManagerInitialized() { if (Smb4KWalletManager::self()->useWalletSystem()) { if (KIconLoader::global()->hasIcon("kwalletmanager")) { m_pass_icon->setPixmap(KIconLoader::global()->loadIcon("kwalletmanager", KIconLoader::Small, 0, KIconLoader::DefaultState)); } else { m_pass_icon->setPixmap(KIconLoader::global()->loadIcon("security-high", KIconLoader::Small, 0, KIconLoader::DefaultState)); } m_pass_icon->setToolTip(i18n("The wallet is used.")); } else { m_pass_icon->setPixmap(KIconLoader::global()->loadIcon("dialog-password", KIconLoader::Small, 0, KIconLoader::DefaultState)); m_pass_icon->setToolTip(i18n("The password dialog is used.")); } } void Smb4KMainWindow::slotClientAboutToStart(const NetworkItemPtr &item, int process) { Q_ASSERT(item); switch (process) { case LookupDomains: { statusBar()->showMessage(i18n("Looking for workgroups and domains..."), 0); break; } case LookupDomainMembers: { WorkgroupPtr workgroup = item.staticCast(); statusBar()->showMessage(i18n("Looking for hosts in domain %1...", workgroup->workgroupName()), 0); break; } case LookupShares: { HostPtr host = item.staticCast(); statusBar()->showMessage(i18n("Looking for shares provided by host %1...", host->hostName()), 0); break; } case LookupFiles: { QString message; switch (item->type()) { case Share: { message = i18n("Looking for files and directories in %1...", item.staticCast()->displayString()); break; } case Directory: { FilePtr file = item.staticCast(); for (const SharePtr &s : sharesList()) { if (s->workgroupName() == file->workgroupName() && s->hostName() == file->hostName() && s->shareName() == file->shareName()) { message = i18n("Looking for files and directories in %1...", s->displayString()); break; } } break; } default: { break; } } statusBar()->showMessage(message, 0); break; } case WakeUp: { statusBar()->showMessage(i18n("Waking up remote hosts..."), 0); break; } case PrintFile: { SharePtr share = item.staticCast(); statusBar()->showMessage(i18n("Sending file to printer %1...", share->displayString()), 0); break; } case NetworkSearch: { statusBar()->showMessage(i18n("Searching..."), 0); break; } default: { break; } } if (!m_progress_bar->isVisible()) { m_progress_bar->setVisible(true); } } void Smb4KMainWindow::slotClientFinished(const NetworkItemPtr &/*item*/, int /*process*/) { if (!coreIsRunning()) { m_progress_bar->setVisible(false); m_progress_bar->reset(); statusBar()->showMessage(i18n("Done."), 2000); } } void Smb4KMainWindow::slotMounterAboutToStart(int process) { // Tell the user which action is performed by the mounter: // mounting, unmounting or waking up. switch (process) { case MountShare: { statusBar()->showMessage(i18n("Mounting..."), 0); break; } case UnmountShare: { statusBar()->showMessage(i18n("Unmounting..."), 0); break; } case WakeUp: { statusBar()->showMessage(i18n("Waking up host..."), 0); break; } default: { break; } } if (!m_progress_bar->isVisible()) { m_progress_bar->setVisible(true); } } void Smb4KMainWindow::slotMounterFinished(int /*process*/) { if (!coreIsRunning()) { m_progress_bar->setVisible(false); m_progress_bar->reset(); statusBar()->showMessage(i18n("Done."), 2000); } } void Smb4KMainWindow::slotVisualMountFeedback(const SharePtr &share) { Q_ASSERT(share); if (share) { m_feedback_icon->setPixmap(KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Small, 0, KIconLoader::DefaultState)); m_feedback_icon->setToolTip(i18n("%1 has been mounted successfully.", share->displayString())); QList list = findChildren(); QDockWidget *shares_dock = findChild("SharesViewDockWidget"); if (shares_dock) { for (int i = 0; i < list.size(); ++i) { if (list.at(i)->count() != 0) { for (int j = 0; j < list.at(i)->count(); ++j) { if (QString::compare(shares_dock->windowTitle(), list.at(i)->tabText(j)) == 0 && list.at(i)->currentIndex() != j) { list.at(i)->setTabTextColor(j, palette().highlightedText().color()) ; break; } else { continue; } } continue; } else { continue; } } } QTimer::singleShot(2000, this, SLOT(slotEndVisualFeedback())); } } void Smb4KMainWindow::slotVisualUnmountFeedback(const SharePtr &share) { Q_ASSERT(share); if (share) { m_feedback_icon->setPixmap(KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Small, 0, KIconLoader::DefaultState)); m_feedback_icon->setToolTip(i18n("%1 has been unmounted successfully.", share->displayString())); QList list = findChildren(); QDockWidget *shares_dock = findChild("SharesViewDockWidget"); if (shares_dock) { for (int i = 0; i < list.size(); ++i) { if (list.at(i)->count() != 0) { for (int j = 0; j < list.at(i)->count(); ++j) { if (QString::compare(shares_dock->windowTitle(), list.at(i)->tabText(j)) == 0 && list.at(i)->currentIndex() != j) { list.at(i)->setTabTextColor(j, palette().highlightedText().color()) ; break; } else { continue; } } continue; } else { continue; } } } QTimer::singleShot(2000, this, SLOT(slotEndVisualFeedback())); } } void Smb4KMainWindow::slotEndVisualFeedback() { QList list = findChildren(); QDockWidget *shares_dock = findChild("SharesViewDockWidget"); if (shares_dock) { for (int i = 0; i < list.size(); ++i) { if (list.at(i)->count() != 0) { for (int j = 0; j < list.at(i)->count(); ++j) { if (QString::compare(shares_dock->windowTitle(), list.at(i)->tabText(j)) == 0) { list.at(i)->setTabTextColor(j, palette().text().color()) ; break; } else { continue; } } continue; } else { continue; } } } setupMountIndicator(); } void Smb4KMainWindow::slotSynchronizerAboutToStart(const QString &dest) { statusBar()->showMessage(i18n("Synchronizing %1", dest), 0); if (!m_progress_bar->isVisible()) { m_progress_bar->setVisible(true); } } void Smb4KMainWindow::slotSynchronizerFinished(const QString &/*dest*/) { if (!coreIsRunning()) { m_progress_bar->setVisible(false); m_progress_bar->reset(); statusBar()->showMessage(i18n("Done."), 2000); } } void Smb4KMainWindow::slotEnableBookmarkAction() { // // Get the focused widget's 'Add Bookmark' action and read its // isEnabled() property. Set the action of the main window and the // bookmark menu respectively. // if (m_focusWidget) { if (QString::compare(m_focusWidget->metaObject()->className(), "Smb4KNetworkBrowserDockWidget") == 0) { Smb4KNetworkBrowserDockWidget *dockWidget = qobject_cast(m_focusWidget); if (dockWidget) { QAction *action = dockWidget->actionCollection()->action("bookmark_action"); if (action) { // Bookmark action of the main window actionCollection()->action("bookmark_action")->setEnabled(action->isEnabled()); // Bookmark action of the bookmark menu Smb4KBookmarkMenu *bookmarkMenu = findChild(); if (bookmarkMenu) { bookmarkMenu->setBookmarkActionEnabled(action->isEnabled()); } } } } else if (QString::compare(m_focusWidget->metaObject()->className(), "Smb4KSharesViewDockWidget") == 0) { Smb4KSharesViewDockWidget *dockWidget = static_cast(m_focusWidget); if (dockWidget) { QAction *action = dockWidget->actionCollection()->action("bookmark_action"); if (action) { // Bookmark action of the main window actionCollection()->action("bookmark_action")->setEnabled(action->isEnabled()); // Bookmark action of the bookmark menu Smb4KBookmarkMenu *bookmarkMenu = findChild(); if (bookmarkMenu) { bookmarkMenu->setBookmarkActionEnabled(action->isEnabled()); } } } } } } void Smb4KMainWindow::slotNetworkBrowserVisibilityChanged(bool visible) { QDockWidget *dock = findChild(); if (dock) { if (visible) { dock->widget()->setFocus(); } else { dock->widget()->clearFocus(); } } } void Smb4KMainWindow::slotSharesViewVisibilityChanged(bool visible) { QDockWidget *dock = findChild(); if (dock) { if (visible) { dock->widget()->setFocus(); } else { dock->widget()->clearFocus(); } } } diff --git a/smb4k/smb4knetworkbrowser.cpp b/smb4k/smb4knetworkbrowser.cpp index 2f49600..1ed5a17 100644 --- a/smb4k/smb4knetworkbrowser.cpp +++ b/smb4k/smb4knetworkbrowser.cpp @@ -1,381 +1,377 @@ /*************************************************************************** smb4knetworkbrowser - The network browser widget of Smb4K. ------------------- begin : Mo Jan 8 2007 copyright : (C) 2007-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knetworkbrowser.h" #include "smb4knetworkbrowseritem.h" #include "smb4ktooltip.h" #include "core/smb4ksettings.h" #include "core/smb4kglobal.h" #include "core/smb4kshare.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include using namespace Smb4KGlobal; Smb4KNetworkBrowser::Smb4KNetworkBrowser(QWidget *parent) : QTreeWidget(parent) { setRootIsDecorated(true); setAllColumnsShowFocus(false); setMouseTracking(true); setSelectionMode(ExtendedSelection); setContextMenuPolicy(Qt::CustomContextMenu); m_tooltip_item = 0; m_mouse_inside = false; QStringList header_labels; header_labels.append(i18n("Network")); header_labels.append(i18n("Type")); header_labels.append(i18n("IP Address")); header_labels.append(i18n("Comment")); setHeaderLabels(header_labels); header()->setSectionResizeMode(QHeaderView::ResizeToContents); // // Connections // connect(this, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemActivated(QTreeWidgetItem*,int))); connect(this, SIGNAL(itemEntered(QTreeWidgetItem*,int)), this, SLOT(slotItemEntered(QTreeWidgetItem*,int))); connect(this, SIGNAL(viewportEntered()), this, SLOT(slotViewportEntered())); connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); } Smb4KNetworkBrowser::~Smb4KNetworkBrowser() { } bool Smb4KNetworkBrowser::event(QEvent *e) { switch (e->type()) { case QEvent::ToolTip: { // Intercept the tool tip event and show our own tool tip. QPoint pos = viewport()->mapFromGlobal(cursor().pos()); Smb4KNetworkBrowserItem *item = static_cast(itemAt(pos)); if (item) { if (Smb4KSettings::showNetworkItemToolTip()) { int ind = 0; switch (item->type()) { case Host: { ind = 2; break; } case Share: { ind = 3; break; } default: { ind = 1; break; } } // Check that the tooltip is not over the root decoration. // If it is, hide it. if (pos.x() <= ind * indentation()) { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } else { m_tooltip_item = item; emit aboutToShowToolTip(m_tooltip_item); m_tooltip_item->tooltip()->show(cursor().pos()); } } else { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } } else { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } break; } default: { break; } } return QTreeWidget::event(e); } void Smb4KNetworkBrowser::mouseMoveEvent(QMouseEvent *e) { // Find the item over which the user moved the mouse: Smb4KNetworkBrowserItem *item = static_cast(itemAt(e->pos())); if (item) { emit itemEntered(item, columnAt(e->pos().x())); // Hide tool tip if the items diverge. if (m_tooltip_item && m_tooltip_item->tooltip()->networkItem() != item->networkItem()) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } else { // Hide the tool tip if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } QTreeWidget::mouseMoveEvent(e); } void Smb4KNetworkBrowser::leaveEvent(QEvent *e) { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } m_mouse_inside = false; QTreeWidget::leaveEvent(e); } void Smb4KNetworkBrowser::enterEvent(QEvent *e) { m_mouse_inside = true; QTreeWidget::enterEvent(e); } void Smb4KNetworkBrowser::mousePressEvent(QMouseEvent *e) { // Hide the current tool tip so that it is not in the way. if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } // Get the item that is under the mouse. If there is no // item, unselect the current item. QTreeWidgetItem *item = itemAt(e->pos()); if (!item && currentItem()) { currentItem()->setSelected(false); setCurrentItem(0); emit itemPressed(currentItem(), -1); } QTreeWidget::mousePressEvent(e); } void Smb4KNetworkBrowser::focusOutEvent(QFocusEvent *e) { QTreeWidget::focusOutEvent(e); } void Smb4KNetworkBrowser::wheelEvent(QWheelEvent *e) { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } QTreeWidget::wheelEvent(e); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KNetworkBrowser::slotItemEntered(QTreeWidgetItem *item, int /*column*/) { Smb4KNetworkBrowserItem *browser_item = static_cast(item); if (m_tooltip_item && m_tooltip_item != browser_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } void Smb4KNetworkBrowser::slotViewportEntered() { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } } void Smb4KNetworkBrowser::slotItemActivated(QTreeWidgetItem *item, int /*column*/) { if (m_tooltip_item) { emit aboutToHideToolTip(m_tooltip_item); m_tooltip_item->tooltip()->hide(); m_tooltip_item = 0; } // Only do something if there are no keyboard modifiers pressed // and there is only one item selected. if (QApplication::keyboardModifiers() == Qt::NoModifier && selectedItems().size() == 1) { if (item) { switch (item->type()) { case Workgroup: case Host: { if (!item->isExpanded()) { expandItem(item); } else { collapseItem(item); } break; } default: { break; } } } } } void Smb4KNetworkBrowser::slotItemSelectionChanged() { if (selectedItems().size() > 1) { // If multiple items are selected, only allow shares // to stay selected. for (int i = 0; i < selectedItems().size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(selectedItems()[i]); if (item) { switch (item->networkItem()->type()) { case Workgroup: case Host: { item->setSelected(false); break; } case Share: { if (item->shareItem()->isPrinter()) { item->setSelected(false); } break; } default: { break; } } } } } } diff --git a/smb4k/smb4knetworkbrowserdockwidget.cpp b/smb4k/smb4knetworkbrowserdockwidget.cpp index c7a824d..794e6cd 100644 --- a/smb4k/smb4knetworkbrowserdockwidget.cpp +++ b/smb4k/smb4knetworkbrowserdockwidget.cpp @@ -1,1454 +1,1450 @@ /*************************************************************************** The network neighborhood browser dock widget ------------------- begin : Sat Apr 28 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knetworkbrowserdockwidget.h" #include "smb4knetworkbrowseritem.h" #include "core/smb4kmounter.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" #include "core/smb4ksettings.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kwalletmanager.h" #include "core/smb4kcustomoptionsmanager.h" #include "core/smb4kclient.h" // Qt includes #include #include #include #include #include // KDE includes #include #include #include #include using namespace Smb4KGlobal; Smb4KNetworkBrowserDockWidget::Smb4KNetworkBrowserDockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) { // // The network browser widget // QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainWidgetLayout = new QVBoxLayout(mainWidget); mainWidgetLayout->setMargin(0); mainWidgetLayout->setSpacing(5); m_networkBrowser = new Smb4KNetworkBrowser(mainWidget); m_searchToolBar = new Smb4KNetworkSearchToolBar(mainWidget); m_searchToolBar->setVisible(false); mainWidgetLayout->addWidget(m_networkBrowser); mainWidgetLayout->addWidget(m_searchToolBar); setWidget(mainWidget); // // The action collection // m_actionCollection = new KActionCollection(this); // // The context menu // m_contextMenu = new KActionMenu(this); // // Search underway? // m_searchRunning = false; // // Set up the actions // setupActions(); // // Load the settings // loadSettings(); // // Connections // connect(m_networkBrowser, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); connect(m_networkBrowser, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemActivated(QTreeWidgetItem*,int))); connect(m_networkBrowser, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); connect(m_searchToolBar, SIGNAL(close()), this, SLOT(slotHideSearchToolBar())); connect(m_searchToolBar, SIGNAL(search(QString)), this, SLOT(slotPerformSearch(QString))); connect(m_searchToolBar, SIGNAL(abort()), this, SLOT(slotStopSearch())); connect(m_searchToolBar, SIGNAL(jumpToResult(QString)), this, SLOT(slotJumpToResult(QString))); connect(m_searchToolBar, SIGNAL(clearSearchResults()), this, SLOT(slotClearSearchResults())); connect(Smb4KClient::self(), SIGNAL(aboutToStart(NetworkItemPtr,int)), this, SLOT(slotClientAboutToStart(NetworkItemPtr,int))); connect(Smb4KClient::self(), SIGNAL(finished(NetworkItemPtr,int)), this, SLOT(slotClientFinished(NetworkItemPtr,int))); connect(Smb4KClient::self(), SIGNAL(workgroups()), this, SLOT(slotWorkgroups())); connect(Smb4KClient::self(), SIGNAL(hosts(WorkgroupPtr)), this, SLOT(slotWorkgroupMembers(WorkgroupPtr))); connect(Smb4KClient::self(), SIGNAL(shares(HostPtr)), this, SLOT(slotShares(HostPtr))); connect(Smb4KClient::self(), SIGNAL(searchResults(QList)), this, SLOT(slotSearchResults(QList))); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotShareMounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotShareUnmounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(aboutToStart(int)), this, SLOT(slotMounterAboutToStart(int))); connect(Smb4KMounter::self(), SIGNAL(finished(int)), this, SLOT(slotMounterFinished(int))); connect(KIconLoader::global(), SIGNAL(iconChanged(int)), this, SLOT(slotIconSizeChanged(int))); } Smb4KNetworkBrowserDockWidget::~Smb4KNetworkBrowserDockWidget() { } void Smb4KNetworkBrowserDockWidget::setupActions() { // // Rescan and abort dual action // KDualAction *rescanAbortAction = new KDualAction(this); rescanAbortAction->setInactiveIcon(KDE::icon("view-refresh")); rescanAbortAction->setInactiveText(i18n("Scan Netwo&rk")); rescanAbortAction->setActiveIcon(KDE::icon("process-stop")); rescanAbortAction->setActiveText(i18n("&Abort")); rescanAbortAction->setAutoToggle(false); rescanAbortAction->setEnabled(true); connect(rescanAbortAction, SIGNAL(triggered(bool)), this, SLOT(slotRescanAbortActionTriggered(bool))); m_actionCollection->addAction("rescan_abort_action", rescanAbortAction); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); // // Search action // QAction *searchAction = new QAction(KDE::icon("search"), i18n("&Search"), this); connect(searchAction, SIGNAL(triggered(bool)), this, SLOT(slotShowSearchToolBar())); m_actionCollection->addAction("search_action", searchAction); m_actionCollection->setDefaultShortcut(searchAction, QKeySequence::Find); // // Separator // QAction *separator1 = new QAction(this); separator1->setSeparator(true); m_actionCollection->addAction("network_separator1", separator1); // // Bookmark action // QAction *bookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), this); bookmarkAction->setEnabled(false); connect(bookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotAddBookmark(bool))); m_actionCollection->addAction("bookmark_action", bookmarkAction); m_actionCollection->setDefaultShortcut(bookmarkAction, QKeySequence(Qt::CTRL+Qt::Key_B)); // // Mount dialog action // QAction *manualAction = new QAction(KDE::icon("view-form", QStringList("emblem-mounted")), i18n("&Open Mount Dialog"), this); manualAction->setEnabled(true); connect(manualAction, SIGNAL(triggered(bool)), this, SLOT(slotMountManually(bool))); m_actionCollection->addAction("mount_manually_action", manualAction); m_actionCollection->setDefaultShortcut(manualAction, QKeySequence(Qt::CTRL+Qt::Key_O)); // // Separator // QAction *separator2 = new QAction(this); separator2->setSeparator(true); m_actionCollection->addAction("network_separator2", separator2); // // Authentication action // QAction *authAction = new QAction(KDE::icon("dialog-password"), i18n("Au&thentication"), this); authAction->setEnabled(false); connect(authAction, SIGNAL(triggered(bool)), this, SLOT(slotAuthentication(bool))); m_actionCollection->addAction("authentication_action", authAction); m_actionCollection->setDefaultShortcut(authAction, QKeySequence(Qt::CTRL+Qt::Key_T)); // // Custom options action // QAction *customAction = new QAction(KDE::icon("preferences-system-network"), i18n("&Custom Options"), this); customAction->setEnabled(false); connect(customAction, SIGNAL(triggered(bool)), this, SLOT(slotCustomOptions(bool))); m_actionCollection->addAction("custom_action", customAction); m_actionCollection->setDefaultShortcut(customAction, QKeySequence(Qt::CTRL+Qt::Key_C)); // // Preview action // QAction *previewAction = new QAction(KDE::icon("view-list-icons"), i18n("Pre&view"), this); previewAction->setEnabled(false); connect(previewAction, SIGNAL(triggered(bool)), this, SLOT(slotPreview(bool))); m_actionCollection->addAction("preview_action", previewAction); m_actionCollection->setDefaultShortcut(previewAction, QKeySequence(Qt::CTRL+Qt::Key_V)); // // Print action // QAction *printAction = new QAction(KDE::icon("printer"), i18n("&Print File"), this); printAction->setEnabled(false); connect(printAction, SIGNAL(triggered(bool)), this, SLOT(slotPrint(bool))); m_actionCollection->addAction("print_action", printAction); m_actionCollection->setDefaultShortcut(printAction, QKeySequence(Qt::CTRL+Qt::Key_P)); // // Mount/unmount action // KDualAction *mountAction = new KDualAction(this); KGuiItem mountItem(i18n("&Mount"), KDE::icon("media-mount")); KGuiItem unmountItem(i18n("&Unmount"), KDE::icon("media-eject")); mountAction->setActiveGuiItem(mountItem); mountAction->setInactiveGuiItem(unmountItem); mountAction->setActive(true); mountAction->setAutoToggle(false); mountAction->setEnabled(false); connect(mountAction, SIGNAL(triggered(bool)), this, SLOT(slotMountActionTriggered(bool))); connect(mountAction, SIGNAL(activeChanged(bool)), this, SLOT(slotMountActionChanged(bool))); m_actionCollection->addAction("mount_action", mountAction); m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_M)); // // Plug the actions into the context menu // for (QAction *a : m_actionCollection->actions()) { m_contextMenu->addAction(a); } } void Smb4KNetworkBrowserDockWidget::loadSettings() { // // Load icon size // int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_networkBrowser->setIconSize(QSize(iconSize, iconSize)); // // Show/hide columns // m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::IP, !Smb4KSettings::showIPAddress()); m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Type, !Smb4KSettings::showType()); m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Comment, !Smb4KSettings::showComment()); // // Load and apply the positions of the columns // KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); QMap map; map.insert(configGroup.readEntry("ColumnPositionNetwork", (int)Smb4KNetworkBrowser::Network), Smb4KNetworkBrowser::Network); map.insert(configGroup.readEntry("ColumnPositionType", (int)Smb4KNetworkBrowser::Type), Smb4KNetworkBrowser::Type); map.insert(configGroup.readEntry("ColumnPositionIP", (int)Smb4KNetworkBrowser::IP), Smb4KNetworkBrowser::IP); map.insert(configGroup.readEntry("ColumnPositionComment", (int)Smb4KNetworkBrowser::Comment), Smb4KNetworkBrowser::Comment); QMap::const_iterator it = map.constBegin(); while (it != map.constEnd()) { if (it.key() != m_networkBrowser->header()->visualIndex(it.value())) { m_networkBrowser->header()->moveSection(m_networkBrowser->header()->visualIndex(it.value()), it.key()); } ++it; } // // Apply the completion strings to the search toolbar // m_searchToolBar->setCompletionStrings(configGroup.readEntry("SearchItemCompletion", QStringList())); // // Does anything has to be changed with the marked shares? // for (const SharePtr &share : mountedSharesList()) { // We do not need to use slotShareUnmounted() here, too, // because slotShareMounted() will take care of everything // we need here. slotShareMounted(share); } // // Adjust the actions, if needed // slotItemSelectionChanged(); } void Smb4KNetworkBrowserDockWidget::saveSettings() { // // Save the position of the columns // KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); configGroup.writeEntry("ColumnPositionNetwork", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Network)); configGroup.writeEntry("ColumnPositionType", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Type)); configGroup.writeEntry("ColumnPositionIP", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::IP)); configGroup.writeEntry("ColumnPositionComment", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Comment)); // // Save the completion strings // configGroup.writeEntry("SearchItemCompletion", m_searchToolBar->completionStrings()); configGroup.sync(); } KActionCollection *Smb4KNetworkBrowserDockWidget::actionCollection() { return m_actionCollection; } void Smb4KNetworkBrowserDockWidget::slotContextMenuRequested(const QPoint& pos) { m_contextMenu->menu()->popup(m_networkBrowser->viewport()->mapToGlobal(pos)); } void Smb4KNetworkBrowserDockWidget::slotItemActivated(QTreeWidgetItem* item, int /*column*/) { // // Process the activated item // if (QApplication::keyboardModifiers() == Qt::NoModifier && m_networkBrowser->selectedItems().size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem) { switch (browserItem->type()) { case Workgroup: { if (browserItem->isExpanded()) { Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); } break; } case Host: { if (browserItem->isExpanded()) { Smb4KClient::self()->lookupShares(browserItem->hostItem()); } break; } case Share: { if (!browserItem->shareItem()->isPrinter()) { slotMountActionTriggered(false); // boolean is ignored } else { slotPrint(false); // boolean is ignored } break; } default: { break; } } } } } void Smb4KNetworkBrowserDockWidget::slotItemSelectionChanged() { // // Get the selected item // QList items = m_networkBrowser->selectedItems(); // // Enable/disable and/or adjust the actions depending of the number // of selected items and their type // if (items.size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(items.first()); if (browserItem) { switch (browserItem->type()) { case Host: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Compute&r")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(true); m_actionCollection->action("custom_action")->setEnabled(true); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); break; } case Share: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Compute&r")); m_actionCollection->action("bookmark_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("authentication_action")->setEnabled(true); m_actionCollection->action("custom_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("preview_action")->setEnabled(!browserItem->shareItem()->isPrinter()); m_actionCollection->action("print_action")->setEnabled(browserItem->shareItem()->isPrinter()); if (!browserItem->shareItem()->isPrinter()) { if (!browserItem->shareItem()->isMounted() || (browserItem->shareItem()->isMounted() && browserItem->shareItem()->isForeign())) { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(true); } else if (browserItem->shareItem()->isMounted() && !browserItem->shareItem()->isForeign()) { static_cast(m_actionCollection->action("mount_action"))->setActive(false); m_actionCollection->action("mount_action")->setEnabled(true); } else { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); } } else { static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(true); } break; } default: { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Wo&rkgroup")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); break; } } } } else if (items.size() > 1) { // // In this case there are only shares selected, because all other items // are automatically deselected in extended selection mode. // // For deciding which function the mount action should have, we use // the number of unmounted shares. If that is identical with the items.size(), // it will mount the items, otherwise it will unmount them. // int unmountedShares = items.size(); for (QTreeWidgetItem *item : items) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem && browserItem->shareItem()->isMounted() && !browserItem->shareItem()->isForeign()) { // // Subtract shares mounted by the user // unmountedShares--; } } // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Netwo&rk")); m_actionCollection->action("bookmark_action")->setEnabled(true); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(true); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(unmountedShares == items.size()); m_actionCollection->action("mount_action")->setEnabled(true); } else { // // Adjust the actions // qobject_cast(m_actionCollection->action("rescan_abort_action"))->setInactiveText(i18n("Scan Netwo&rk")); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("authentication_action")->setEnabled(false); m_actionCollection->action("custom_action")->setEnabled(false); m_actionCollection->action("preview_action")->setEnabled(false); m_actionCollection->action("print_action")->setEnabled(false); static_cast(m_actionCollection->action("mount_action"))->setActive(true); m_actionCollection->action("mount_action")->setEnabled(false); } } void Smb4KNetworkBrowserDockWidget::slotClientAboutToStart(const NetworkItemPtr& /*item*/, int process) { // // Get the rescan/abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Make adjustments // if (rescanAbortAction) { rescanAbortAction->setActive(true); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Cancel); } // // Set the active status of the search tool bar // if (process == NetworkSearch) { m_searchToolBar->setActiveState(true); } } void Smb4KNetworkBrowserDockWidget::slotClientFinished(const NetworkItemPtr& /*item*/, int process) { // // Get the rescan/abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Make adjustments // if (rescanAbortAction) { rescanAbortAction->setActive(false); m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); } // // Set the active status of the search tool bar // if (process == NetworkSearch) { m_searchToolBar->setActiveState(false); } } void Smb4KNetworkBrowserDockWidget::slotWorkgroups() { // // Process the global workgroup list // if (!workgroupsList().isEmpty()) { // // Remove obsolete workgroups and update existing ones // QTreeWidgetItemIterator itemIt(m_networkBrowser, QTreeWidgetItemIterator::All); while (*itemIt) { Smb4KNetworkBrowserItem *networkItem = static_cast(*itemIt); if (networkItem->type() == Workgroup) { WorkgroupPtr workgroup = findWorkgroup(networkItem->workgroupItem()->workgroupName()); if (workgroup) { networkItem->update(); // Update the master browser for (int i = 0; i < networkItem->childCount(); ++i) { Smb4KNetworkBrowserItem *host = static_cast(networkItem->child(i)); host->update(); } } else { delete networkItem; } } ++itemIt; } // // Add new workgroups to the tree widget // for (const WorkgroupPtr &workgroup : workgroupsList()) { QList items = m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString, Smb4KNetworkBrowser::Network); if (items.isEmpty()) { (void) new Smb4KNetworkBrowserItem(m_networkBrowser, workgroup); } } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); } else { // // Clear the tree widget // m_networkBrowser->clear(); } } void Smb4KNetworkBrowserDockWidget::slotWorkgroupMembers(const WorkgroupPtr& workgroup) { // // Process the list of domain members // if (workgroup) { // // Find the workgroup(s) // QList workgroups = m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString, Smb4KNetworkBrowser::Network); QMutableListIterator it(workgroups); while (it.hasNext()) { QTreeWidgetItem *item = it.next(); if (item->type() == Workgroup) { Smb4KNetworkBrowserItem *workgroupItem = static_cast(item); QTreeWidgetItemIterator itemIt(workgroupItem); // // Remove obsolete hosts and update existing ones // while (*itemIt) { Smb4KNetworkBrowserItem *networkItem = static_cast(*itemIt); if (networkItem->type() == Host) { HostPtr host = findHost(networkItem->hostItem()->hostName(), networkItem->hostItem()->workgroupName()); if (host) { networkItem->update(); } else { delete networkItem; } } else { break; } ++itemIt; } // // Add new hosts to the workgroup item and remove obsolete workgroups if // necessary. Honor the auto-expand feature. // QList members = workgroupMembers(workgroupItem->workgroupItem()); if (!members.isEmpty()) { for (const HostPtr &host : members) { bool foundHost = false; for (int i = 0; i < workgroupItem->childCount(); ++i) { Smb4KNetworkBrowserItem *hostItem = static_cast(workgroupItem->child(i)); if (hostItem->hostItem()->hostName() == host->hostName()) { foundHost = true; break; } else { continue; } } if (!foundHost) { (void) new Smb4KNetworkBrowserItem(workgroupItem, host); } } // Auto-expand the workgroup item, if applicable if (Smb4KSettings::autoExpandNetworkItems() && !workgroupItem->isExpanded() && !m_searchRunning) { m_networkBrowser->expandItem(workgroupItem); } } else { // Delete all hosts of the workgroup (if there should still be some) and // remove the workgroup item from the view (no hosts => no workgroup) while (workgroupItem->childCount() != 0) { delete workgroupItem->takeChild(0); } delete workgroupItem; } } } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); } } void Smb4KNetworkBrowserDockWidget::slotShares(const HostPtr& host) { // // Process the list of shares // if (host) { // // Find the host(s) // QList hosts = m_networkBrowser->findItems(host->hostName(), Qt::MatchFixedString|Qt::MatchRecursive, Smb4KNetworkBrowser::Network); QMutableListIterator it(hosts); while (it.hasNext()) { Smb4KNetworkBrowserItem *hostItem = static_cast(it.next()); if (hostItem->type() == Host && hostItem->hostItem()->workgroupName() == host->workgroupName()) { QTreeWidgetItemIterator itemIt(hostItem); // // Remove obsolete shares and update existing ones // while (*itemIt) { Smb4KNetworkBrowserItem *shareItem = static_cast(*itemIt); if (shareItem->type() == Share) { SharePtr share = findShare(shareItem->shareItem()->url(), shareItem->shareItem()->workgroupName()); if (share) { shareItem->update(); } else { delete shareItem; } } else { break; } ++itemIt; } // // Add new shares to the host item. The host will not be removed from the // view when it has no shares. Honor the auto-expand feature. // QList shares = sharedResources(host); if (!shares.isEmpty()) { for (const SharePtr &share : shares) { bool foundShare = false; for (int i = 0; i < hostItem->childCount(); ++i) { Smb4KNetworkBrowserItem *shareItem = static_cast(hostItem->child(i)); if (QString::compare(shareItem->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { foundShare = true; break; } else { continue; } } if (!foundShare) { (void) new Smb4KNetworkBrowserItem(hostItem, share); } } // Auto-expand the host item, if applicable if (Smb4KSettings::autoExpandNetworkItems() && !hostItem->isExpanded() && !m_searchRunning) { m_networkBrowser->expandItem(hostItem); } } else { // Delete all shares (if there should still be some), but leave the // host in the view. while (hostItem->childCount() != 0) { delete hostItem->takeChild(0); } } } else { continue; } } // // Sort the items // m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); } } void Smb4KNetworkBrowserDockWidget::slotRescanAbortActionTriggered(bool /*checked*/) { // // Get the Rescan/Abort action // KDualAction *rescanAbortAction = static_cast(m_actionCollection->action("rescan_abort_action")); // // Get the selected items // QList selectedItems = m_networkBrowser->selectedItems(); // // Perform actions according to the state of the action and the number of // selected items. // if (!rescanAbortAction->isActive()) { if (selectedItems.size() == 1) { Smb4KNetworkBrowserItem *browserItem = static_cast(selectedItems.first()); if (browserItem) { switch (browserItem->type()) { case Workgroup: { Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); break; } case Host: { Smb4KClient::self()->lookupShares(browserItem->hostItem()); break; } case Share: { Smb4KNetworkBrowserItem *parentItem = static_cast(browserItem->parent()); Smb4KClient::self()->lookupShares(parentItem->hostItem()); break; } default: { break; } } } } else { // If several items are selected or no selected items, // only the network can be scanned. Smb4KClient::self()->lookupDomains(); } } else { // Stop all actions performed by the client if (Smb4KClient::self()->isRunning()) { Smb4KClient::self()->abort(); } } } void Smb4KNetworkBrowserDockWidget::slotAddBookmark(bool /*checked*/) { QList items = m_networkBrowser->selectedItems(); QList shares; if (!items.isEmpty()) { for (int i = 0; i < items.size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(items.at(i)); if (item && item->type() == Share && !item->shareItem()->isPrinter()) { shares << item->shareItem(); } } } else { // No selected items. Just return. return; } if (!shares.isEmpty()) { Smb4KBookmarkHandler::self()->addBookmarks(shares); } } void Smb4KNetworkBrowserDockWidget::slotMountManually(bool /*checked*/) { Smb4KMounter::self()->openMountDialog(); } void Smb4KNetworkBrowserDockWidget::slotAuthentication(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item) { switch (item->type()) { case Host: { Smb4KWalletManager::self()->showPasswordDialog(item->hostItem()); break; } case Share: { Smb4KWalletManager::self()->showPasswordDialog(item->shareItem()); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotCustomOptions(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item) { switch (item->type()) { case Host: { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(item->hostItem()); break; } case Share: { Smb4KCustomOptionsManager::self()->openCustomOptionsDialog(item->shareItem()); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotPreview(bool /*checked*/) { QList items = m_networkBrowser->selectedItems(); if (!items.isEmpty()) { for (int i = 0; i < items.size(); ++i) { Smb4KNetworkBrowserItem *item = static_cast(items.at(i)); if (item && item->type() == Share && !item->shareItem()->isPrinter()) { Smb4KClient::self()->openPreviewDialog(item->shareItem()); } } } } void Smb4KNetworkBrowserDockWidget::slotPrint(bool /*checked*/) { Smb4KNetworkBrowserItem *item = static_cast(m_networkBrowser->currentItem()); if (item && item->shareItem()->isPrinter()) { Smb4KClient::self()->openPrintDialog(item->shareItem()); } } void Smb4KNetworkBrowserDockWidget::slotMountActionTriggered(bool /*checked*/) { // // Get the selected items // QList selectedItems = m_networkBrowser->selectedItems(); if (selectedItems.size() > 1) { // // In the case of multiple selected network items, selectedItems() // only contains shares. Thus, we do not need to test for the type. // For deciding what the mount action is supposed to do, i.e. mount // the (remaining) selected unmounted shares or unmounting all selected // mounted shares, we use the number of unmounted shares. If that is // greater than 0, we mount all shares that need to be mounted, otherwise // we unmount all selected shares. // QList unmounted, mounted; for (QTreeWidgetItem *item : selectedItems) { Smb4KNetworkBrowserItem *browserItem = static_cast(item); if (browserItem && browserItem->shareItem()->isMounted()) { mounted << browserItem->shareItem(); } else if (browserItem && !browserItem->shareItem()->isMounted()) { unmounted << browserItem->shareItem(); } } if (!unmounted.empty()) { // Mount the (remaining) unmounted shares. Smb4KMounter::self()->mountShares(unmounted); } else { // Unmount all shares. Smb4KMounter::self()->unmountShares(mounted, m_networkBrowser); } } else { // // If only one network item is selected, we need to test for the type // of the item. Only in case of a share we need to do something. // Smb4KNetworkBrowserItem *browserItem = static_cast(selectedItems.first()); if (browserItem) { switch (browserItem->type()) { case Share: { if (!browserItem->shareItem()->isMounted()) { Smb4KMounter::self()->mountShare(browserItem->shareItem()); } else { Smb4KMounter::self()->unmountShare(browserItem->shareItem(), false); } break; } default: { break; } } } } } void Smb4KNetworkBrowserDockWidget::slotMountActionChanged(bool active) { // // Get the mount action // KDualAction *mountAction = static_cast(m_actionCollection->action("mount_action")); // // Change the shortcuts depending on the value of the 'active' argument // if (mountAction) { if (active) { m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_M)); } else { m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(Qt::CTRL+Qt::Key_U)); } } } void Smb4KNetworkBrowserDockWidget::slotShareMounted(const SharePtr& share) { QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *item = static_cast(*it); if (item->type() == Share) { if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { item->update(); break; } } ++it; } } void Smb4KNetworkBrowserDockWidget::slotShareUnmounted(const SharePtr& share) { QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *item = static_cast(*it); if (item->type() == Share) { if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort), Qt::CaseInsensitive) == 0) { item->update(); break; } } ++it; } } void Smb4KNetworkBrowserDockWidget::slotMounterAboutToStart(int /*process*/) { // // Unused at the moment // } void Smb4KNetworkBrowserDockWidget::slotMounterFinished(int process) { // // Get the mount/unmount action // KDualAction *mountAction = static_cast(m_actionCollection->action("mount_action")); // // Make adjustments // if (mountAction) { switch (process) { case MountShare: { mountAction->setActive(false); break; } case UnmountShare: { mountAction->setActive(true); break; } default: { break; } } } } void Smb4KNetworkBrowserDockWidget::slotIconSizeChanged(int group) { switch (group) { case KIconLoader::Small: { int icon_size = KIconLoader::global()->currentSize(KIconLoader::Small); m_networkBrowser->setIconSize(QSize(icon_size, icon_size)); break; } default: { break; } } } void Smb4KNetworkBrowserDockWidget::slotShowSearchToolBar() { // // Show the search toolbar // m_searchToolBar->setVisible(true); // // Set the focus to the search item input // m_searchToolBar->prepareInput(); } void Smb4KNetworkBrowserDockWidget::slotHideSearchToolBar() { // // Prevent another dock widget from stealing the focus when // the search tool bar is hidden // m_networkBrowser->setFocus(); // // Hide the search toolbar // m_searchToolBar->setVisible(false); } void Smb4KNetworkBrowserDockWidget::slotPerformSearch(const QString& item) { // // Prevent another dock widget from stealing the focus when // the search item input is disabled // m_networkBrowser->setFocus(); // // A global search is underway // m_searchRunning = true; // // Start the search // Smb4KClient::self()->search(item); } void Smb4KNetworkBrowserDockWidget::slotStopSearch() { // // Stop the network search // Smb4KClient::self()->abort(); // // A global search finished // m_searchRunning = false; } void Smb4KNetworkBrowserDockWidget::slotSearchResults(const QList& shares) { // // A global search finished // m_searchRunning = false; // // Process the search results // QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *networkItem = static_cast(*it); if (networkItem->type() == Share) { for (const SharePtr &share : shares) { if (networkItem->shareItem() == share) { // // Select the search result // networkItem->setSelected(true); // // Expand the branch of the network tree where a search result // was retrieved // if (!networkItem->parent()->isExpanded()) { m_networkBrowser->expandItem(networkItem->parent()); } if (!networkItem->parent()->parent()->isExpanded()) { m_networkBrowser->expandItem(networkItem->parent()->parent()); } } } } it++; } // // Pass the search results to the search toolbar // m_searchToolBar->setSearchResults(shares); } void Smb4KNetworkBrowserDockWidget::slotJumpToResult(const QString& url) { // // Find the share item with URL url // QTreeWidgetItemIterator it(m_networkBrowser); while (*it) { Smb4KNetworkBrowserItem *networkItem = static_cast(*it); if (networkItem->type() == Share && networkItem->shareItem()->url().toString() == url) { m_networkBrowser->setCurrentItem(networkItem); break; } it++; } } void Smb4KNetworkBrowserDockWidget::slotClearSearchResults() { m_networkBrowser->clearSelection(); } diff --git a/smb4k/smb4knetworkbrowseritem.cpp b/smb4k/smb4knetworkbrowseritem.cpp index 5f82e1c..fa6ebee 100644 --- a/smb4k/smb4knetworkbrowseritem.cpp +++ b/smb4k/smb4knetworkbrowseritem.cpp @@ -1,282 +1,278 @@ /*************************************************************************** smb4knetworkbrowseritem - Smb4K's network browser list item. ------------------- begin : Mo Jan 8 2007 copyright : (C) 2007-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knetworkbrowseritem.h" #include "core/smb4kglobal.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" // Qt includes #include #include #include using namespace Smb4KGlobal; Smb4KNetworkBrowserItem::Smb4KNetworkBrowserItem(QTreeWidget *parent, const NetworkItemPtr &item) : QTreeWidgetItem(parent, item->type()), m_item(item) { m_tooltip = new Smb4KToolTip(); m_tooltip->setup(Smb4KToolTip::NetworkBrowser, m_item); switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); setText(Network, workgroup->workgroupName()); setIcon(Network, workgroup->icon()); break; } case Host: { HostPtr host = m_item.staticCast(); setText(Network, host->hostName()); setText(IP, host->ipAddress()); setText(Comment, host->comment()); if (host->isMasterBrowser()) { for (int i = 0; i < columnCount(); ++i) { QBrush brush(Qt::darkBlue); setForeground(i, brush); } } setIcon(Network, host->icon()); break; } case Share: { SharePtr share = m_item.staticCast(); setText(Network, share->shareName()); setText(Type, share->shareTypeString()); setText(Comment, share->comment()); if (!share->isPrinter() && share->isMounted()) { for (int i = 0; i < columnCount(); ++i) { QFont f = font(i); f.setItalic(true); setFont(i, f); } } setIcon(Network, share->icon()); break; } default: { break; } } } Smb4KNetworkBrowserItem::Smb4KNetworkBrowserItem(QTreeWidgetItem *parent, const NetworkItemPtr &item) : QTreeWidgetItem(parent, item->type()), m_item(item) { m_tooltip = new Smb4KToolTip(); m_tooltip->setup(Smb4KToolTip::NetworkBrowser, m_item); switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); setText(Network, workgroup->workgroupName()); setIcon(Network, workgroup->icon()); break; } case Host: { HostPtr host = m_item.staticCast(); setText(Network, host->hostName()); setText(IP, host->ipAddress()); setText(Comment, host->comment()); if (host->isMasterBrowser()) { for (int i = 0; i < columnCount(); ++i) { QBrush brush(Qt::darkBlue); setForeground(i, brush); } } setIcon(Network, host->icon()); break; } case Share: { SharePtr share = m_item.staticCast(); setText(Network, share->shareName()); setText(Type, share->shareTypeString()); setText(Comment, share->comment()); if (!share->isPrinter() && share->isMounted()) { for (int i = 0; i < columnCount(); ++i) { QFont f = font(i); f.setItalic(true); setFont(i, f); } } setIcon(Network, share->icon()); break; } default: { break; } } } Smb4KNetworkBrowserItem::~Smb4KNetworkBrowserItem() { delete m_tooltip; } WorkgroupPtr Smb4KNetworkBrowserItem::workgroupItem() { if (!m_item || (m_item && m_item->type() != Workgroup)) { return WorkgroupPtr(); } return m_item.staticCast(); } HostPtr Smb4KNetworkBrowserItem::hostItem() { if (!m_item || (m_item && m_item->type() != Host)) { return HostPtr(); } return m_item.staticCast(); } SharePtr Smb4KNetworkBrowserItem::shareItem() { if (!m_item || (m_item && m_item->type() != Share)) { return SharePtr(); } return m_item.staticCast(); } const NetworkItemPtr &Smb4KNetworkBrowserItem::networkItem() { return m_item; } void Smb4KNetworkBrowserItem::update() { switch (m_item->type()) { case Host: { HostPtr host = m_item.staticCast(); // Adjust the item's color. if (host->isMasterBrowser()) { for (int i = 0; i < columnCount(); ++i) { QBrush brush(Qt::darkBlue); setForeground(i, brush); } } else { for (int i = 0; i < columnCount(); ++i) { QBrush brush = QApplication::palette().text(); setForeground(i, brush); } } // Set the IP address setText(IP, host->ipAddress()); // Set the comment setText(Comment, host->comment()); break; } case Share: { SharePtr share = m_item.staticCast(); // Set the comment setText(Comment, share->comment()); // Set the icon setIcon(Network, share->icon()); // Set the font for (int i = 0; i < columnCount(); ++i) { QFont f = font(i); f.setItalic(share->isMounted()); setFont(i, f); } break; } default: { break; } } m_tooltip->update(Smb4KToolTip::NetworkBrowser, m_item); } Smb4KToolTip* Smb4KNetworkBrowserItem::tooltip() { return m_tooltip; } diff --git a/smb4k/smb4knetworksearchtoolbar.cpp b/smb4k/smb4knetworksearchtoolbar.cpp index 5b5ab8d..98147a0 100644 --- a/smb4k/smb4knetworksearchtoolbar.cpp +++ b/smb4k/smb4knetworksearchtoolbar.cpp @@ -1,405 +1,401 @@ /*************************************************************************** This class provides the network search toolbar. ------------------- begin : Su Dec 23 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4knetworksearchtoolbar.h" #include "core/smb4kshare.h" // Qt includes #include // KDE includes #include #include #include #include #include Smb4KNetworkSearchToolBar::Smb4KNetworkSearchToolBar(QWidget* parent) : QToolBar(parent), m_iterator(QStringList()) { // // Set up tool bar // // Use the settings suggested by the note provided in the 'Detailed Description' // section of KToolBar (https://api.kde.org/frameworks/kxmlgui/html/classKToolBar.html) // setToolButtonStyle(Qt::ToolButtonFollowStyle); setProperty("otherToolbar", true); // // The Close action // QAction *closeAction = new QAction(this); closeAction->setObjectName("CloseAction"); closeAction->setIcon(KDE::icon("window-close")); closeAction->setText(i18n("Close")); connect(closeAction, SIGNAL(triggered(bool)), this, SLOT(slotCloseButtonPressed())); addAction(closeAction); // // The search combo box // KComboBox *comboBox = new KComboBox(true, this); comboBox->setObjectName("SearchCombo"); comboBox->lineEdit()->setPlaceholderText(i18n("Search string")); comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); comboBox->setCompletionMode(KCompletion::CompletionPopupAuto); connect(comboBox, SIGNAL(returnPressed()), this, SLOT(slotReturnKeyPressed())); // FIXME: Add a connection to the clearSearch() slot addWidget(comboBox); // // The search dual action // KDualAction *searchAction = new KDualAction(this); searchAction->setObjectName("SearchAction"); searchAction->setInactiveIcon(KDE::icon("search")); searchAction->setInactiveText(i18n("Search")); searchAction->setActiveIcon(KDE::icon("process-stop")); searchAction->setActiveText(i18n("Stop")); searchAction->setAutoToggle(false); connect(searchAction, SIGNAL(triggered(bool)), this, SLOT(slotSearchActionTriggered())); addAction(searchAction); // // Go one item down action // QAction *downAction = new QAction(this); downAction->setObjectName("DownAction"); downAction->setIcon(KDE::icon("go-down-search")); downAction->setText(i18n("Item Down")); downAction->setEnabled(false); connect(downAction, SIGNAL(triggered(bool)), this, SLOT(slotDownActionTriggered())); addAction(downAction); // // Go one item up action // QAction *upAction = new QAction(this); upAction->setObjectName("UpAction"); upAction->setIcon(KDE::icon("go-up-search")); upAction->setText(i18n("Item Up")); upAction->setEnabled(false); connect(upAction, SIGNAL(triggered(bool)), this, SLOT(slotUpActionTriggered())); addAction(upAction); /** * Clear the search */ QAction *clearAction = new QAction(this); clearAction->setObjectName("ClearAction"); clearAction->setIcon(KDE::icon("edit-clear-all")); clearAction->setText(i18n("Clear")); clearAction->setEnabled(false); connect(clearAction, SIGNAL(triggered(bool)), this, SLOT(slotClearSearch())); addAction(clearAction); } Smb4KNetworkSearchToolBar::~Smb4KNetworkSearchToolBar() { } void Smb4KNetworkSearchToolBar::prepareInput() { // // Get the search combo box // KComboBox *comboBox = findChild("SearchCombo"); // // Set the keyboard focus to the lineedit // comboBox->lineEdit()->setFocus(); } void Smb4KNetworkSearchToolBar::setActiveState(bool active) { // // Get the search dual action and set the active state // KDualAction *searchAction = findChild("SearchAction"); searchAction->setActive(active); // // Get the search combo box and disable/enable it // KComboBox *comboBox = findChild("SearchCombo"); comboBox->setEnabled(!active); } void Smb4KNetworkSearchToolBar::clearSearch() { // // Clear the list of search results // m_searchResults.clear(); // // Clear the combo box // KComboBox *comboBox = findChild("SearchCombo"); comboBox->clear(); comboBox->clearEditText(); // // Get the down action and disable it // QAction *downAction = findChild("DownAction"); downAction->setEnabled(!m_searchResults.isEmpty()); // // Get the up action and disable it // QAction *upAction = findChild("UpAction"); upAction->setEnabled(!m_searchResults.isEmpty()); // // Get the clear action and disable it // QAction *clearAction = findChild("ClearAction"); clearAction->setEnabled(!m_searchResults.isEmpty()); // // Emit the clearSearchResults() signal // emit clearSearchResults(); } void Smb4KNetworkSearchToolBar::setSearchResults(const QList& list) { // // Set the new list // for (const SharePtr &share : list) { m_searchResults << share->url().toString(); } // // Sort the search results // m_searchResults.sort(); // // Set the iterator // m_iterator = m_searchResults; // // Get the down action and enable it // QAction *downAction = findChild("DownAction"); downAction->setEnabled(!m_searchResults.isEmpty()); // // Get the up action and enable it // QAction *upAction = findChild("UpAction"); upAction->setEnabled(!m_searchResults.isEmpty()); // // Get the clear action and enable it // QAction *clearAction = findChild("ClearAction"); clearAction->setEnabled(!m_searchResults.isEmpty()); } void Smb4KNetworkSearchToolBar::setCompletionStrings(const QStringList& strings) { // // Get the input combo box // KComboBox *comboBox = findChild("SearchCombo"); // // Set the completion strings // comboBox->completionObject()->setItems(strings); } QStringList Smb4KNetworkSearchToolBar::completionStrings() const { // // Get the input combo box // KComboBox *comboBox = findChild("SearchCombo"); // // Return the completion strings // return comboBox->completionObject()->items(); } void Smb4KNetworkSearchToolBar::slotReturnKeyPressed() { // // Get the input combo box // KComboBox *comboBox = findChild("SearchCombo"); // // Initialize a search if the line edit is not empty // if (!comboBox->currentText().isEmpty()) { // // Add the search item to the completion object // comboBox->completionObject()->addItem(comboBox->currentText()); // // Emit the search signal // emit search(comboBox->currentText()); } } void Smb4KNetworkSearchToolBar::slotSearchActionTriggered() { // // Get the search dual action // KDualAction *searchAction = findChild("SearchAction"); // // Initialize a search if the action is in active state and abort // the search if it is in inactive state // if (!searchAction->isActive()) { KComboBox *comboBox = findChild("SearchCombo"); if (!comboBox->currentText().isEmpty()) { // // Add the search item to the completion object // comboBox->completionObject()->addItem(comboBox->currentText()); // // Emit the search signal // emit search(comboBox->currentText()); } } else { // // Emit the abort signal // emit abort(); } } void Smb4KNetworkSearchToolBar::slotCloseButtonPressed() { // // Clear the search toolbar // clearSearch(); // // Emit the abort signal // emit abort(); // // Emit the close signal // emit close(); } void Smb4KNetworkSearchToolBar::slotDownActionTriggered() { if (m_iterator.hasNext()) { // // Get the URL of the item // QString url = m_iterator.next(); // // Emit the jumpToResult() signal // emit jumpToResult(url); } } void Smb4KNetworkSearchToolBar::slotUpActionTriggered() { if (m_iterator.hasPrevious()) { // // Get the URL of the item // QString url = m_iterator.previous(); // // Emit the jumpToResult() signal // emit jumpToResult(url); } } void Smb4KNetworkSearchToolBar::slotClearSearch() { clearSearch(); } diff --git a/smb4k/smb4kprofilesmenu.cpp b/smb4k/smb4kprofilesmenu.cpp index d93fe5c..3928264 100644 --- a/smb4k/smb4kprofilesmenu.cpp +++ b/smb4k/smb4kprofilesmenu.cpp @@ -1,131 +1,127 @@ /*************************************************************************** smb4kprofilesmenu - The menu for the profiles ------------------- begin : Do Aug 10 2014 copyright : (C) 2014-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4kprofilesmenu.h" #include "core/smb4ksettings.h" #include "core/smb4kprofilemanager.h" // Qt includes #include #include // KDE includes #include #include Smb4KProfilesMenu::Smb4KProfilesMenu(QObject* parent) : KSelectAction(KDE::icon("format-list-unordered"), i18n("Profiles"), parent) { QStringList profiles = Smb4KProfileManager::self()->profilesList(); slotProfilesListChanged(profiles); setToolBarMode(KSelectAction::MenuMode); // // Connections // connect(Smb4KProfileManager::self(), SIGNAL(activeProfileChanged(QString)), this, SLOT(slotActiveProfileChanged(QString))); connect(Smb4KProfileManager::self(), SIGNAL(profilesListChanged(QStringList)), this, SLOT(slotProfilesListChanged(QStringList))); connect(Smb4KProfileManager::self(), SIGNAL(profileUsageChanged(bool)), this, SLOT(slotProfileUsageChanged(bool))); connect(this, SIGNAL(triggered(QString)), this, SLOT(slotActionTriggered(QString))); } Smb4KProfilesMenu::~Smb4KProfilesMenu() { } void Smb4KProfilesMenu::refreshMenu() { // // Clear the select action // clear(); // // Get the list of profiles and add all profiles to the select action // QStringList profiles = Smb4KProfileManager::self()->profilesList(); for (const QString &profile : profiles) { QAction *action = addAction(profile); if (action) { action->setEnabled(Smb4KProfileManager::self()->useProfiles()); } } // // Enable the action if the user chose to use profiles // setEnabled(Smb4KProfileManager::self()->useProfiles()); // // Set the current action // setCurrentAction(Smb4KProfileManager::self()->activeProfile()); } void Smb4KProfilesMenu::slotActiveProfileChanged(const QString& newProfile) { setCurrentAction(newProfile); } void Smb4KProfilesMenu::slotProfilesListChanged(const QStringList& /*profiles*/) { refreshMenu(); } void Smb4KProfilesMenu::slotProfileUsageChanged(bool use) { for (QAction *action : actions()) { if (action) { action->setEnabled(use); } } setEnabled(use); } void Smb4KProfilesMenu::slotActionTriggered(const QString& name) { Smb4KProfileManager::self()->setActiveProfile(name); } diff --git a/smb4k/smb4ksharesmenu.cpp b/smb4k/smb4ksharesmenu.cpp index 3a61f3c..8a364f8 100644 --- a/smb4k/smb4ksharesmenu.cpp +++ b/smb4k/smb4ksharesmenu.cpp @@ -1,320 +1,316 @@ /*************************************************************************** smb4ksharesmenu - Shares menu ------------------- begin : Mon Sep 05 2011 copyright : (C) 2011-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksharesmenu.h" #include "core/smb4kshare.h" #include "core/smb4kmounter.h" #include "core/smb4kglobal.h" #include "core/smb4ksynchronizer.h" #include "core/smb4kbookmarkhandler.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include #include #include // KDE includes #include #include using namespace Smb4KGlobal; Smb4KSharesMenu::Smb4KSharesMenu(QWidget *parentWidget, QObject *parent) : KActionMenu(KDE::icon("folder-network", QStringList("emblem-mounted")), i18n("Mounted Shares"), parent), m_parent_widget(parentWidget) { // // Set up action group for the shares menus // m_menus = new QActionGroup(menu()); // // Set up action group for the shares actions // m_actions = new QActionGroup(menu()); // // Setup the menu // setupMenu(); // // Connections // connect(m_actions, SIGNAL(triggered(QAction*)), SLOT(slotShareAction(QAction*))); connect(Smb4KMounter::self(), SIGNAL(mountedSharesListChanged()), SLOT(slotMountedSharesListChanged())); } Smb4KSharesMenu::~Smb4KSharesMenu() { } void Smb4KSharesMenu::refreshMenu() { // // Delete all entries from the menu // while (!menu()->actions().isEmpty()) { QAction *action = menu()->actions().takeFirst(); removeAction(action); delete action; } // // Clear the rest of the menu // if (!menu()->isEmpty()) { menu()->clear(); } // // Set up the menu // setupMenu(); // // Make sure the correct menu entries are shown // menu()->update(); } void Smb4KSharesMenu::setupMenu() { // // Add the Unmount All action // QAction *unmount_all = new QAction(KDE::icon("system-run"), i18n("U&nmount All"), menu()); unmount_all->setEnabled(false); connect(unmount_all, SIGNAL(triggered(bool)), SLOT(slotUnmountAllShares())); addAction(unmount_all); // // Add a separator // addSeparator(); // // Add the share entries // QStringList displayNames; for (const SharePtr &share : mountedSharesList()) { // Do not process null pointers if (!share) { continue; } // Add the display name to the list displayNames << share->displayString(); // Create the share menu KActionMenu *shareMenu = new KActionMenu(share->displayString(), menu()); shareMenu->setIcon(share->icon()); QMap data; data["text"] = share->displayString(); shareMenu->setData(data); m_menus->addAction(shareMenu); // Add the unmount action to the menu QAction *unmount = new QAction(KDE::icon("media-eject"), i18n("Unmount"), shareMenu->menu()); QMap unmountData; unmountData["type"] = "unmount"; unmountData["mountpoint"] = share->path(); unmount->setData(unmountData); unmount->setEnabled(!share->isForeign() || Smb4KMountSettings::unmountForeignShares()); shareMenu->addAction(unmount); m_actions->addAction(unmount); // Add a separator shareMenu->addSeparator(); // Add the bookmark action to the menu QAction *addBookmark = new QAction(KDE::icon("bookmark-new"), i18n("Add Bookmark"), shareMenu->menu()); QMap bookmarkData; bookmarkData["type"] = "bookmark"; bookmarkData["mountpoint"] = share->path(); addBookmark->setData(bookmarkData); shareMenu->addAction(addBookmark); m_actions->addAction(addBookmark); // Add the synchronization action to the menu QAction *synchronize = new QAction(KDE::icon("folder-sync"), i18n("Synchronize"), shareMenu->menu()); QMap syncData; syncData["type"] = "sync"; syncData["mountpoint"] = share->path(); synchronize->setData(syncData); synchronize->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && !share->isInaccessible()); shareMenu->addAction(synchronize); m_actions->addAction(synchronize); // Add a separator shareMenu->addSeparator(); // Add the Open with Konsole action to the menu QAction *konsole = new QAction(KDE::icon("utilities-terminal"), i18n("Open with Konsole"), shareMenu->menu()); QMap konsoleData; konsoleData["type"] = "konsole"; konsoleData["mountpoint"] = share->path(); konsole->setData(konsoleData); konsole->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty() && !share->isInaccessible()); shareMenu->addAction(konsole); m_actions->addAction(konsole); // Add the Open with Filemanager action to the menu QAction *filemanager = new QAction(KDE::icon("system-file-manager"), i18n("Open with File Manager"), shareMenu->menu()); QMap fmData; fmData["type"] = "filemanager"; fmData["mountpoint"] = share->path(); filemanager->setData(fmData); filemanager->setEnabled(!share->isInaccessible()); shareMenu->addAction(filemanager); m_actions->addAction(filemanager); } // // Sort the display names and add the share menus to the menu // in the sorted order. // displayNames.sort(); for (const QString &name : displayNames) { for (QAction *action : m_menus->actions()) { if (action->data().toMap().value("text").toString() == name) { addAction(action); break; } } } // // Enable or disable the Unmount All action, depending on the number of // mounted shares present. // unmount_all->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && !m_menus->actions().isEmpty())); } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KSharesMenu::slotMountedSharesListChanged() { // // Refresh the menu // refreshMenu(); } void Smb4KSharesMenu::slotUnmountAllShares() { Smb4KMounter::self()->unmountAllShares(false); } void Smb4KSharesMenu::slotShareAction(QAction *action) { // // Create a share // SharePtr share; // // Check that we have a share related action // if (action->data().toMap().contains("type")) { share = findShareByPath(action->data().toMap().value("mountpoint").toString()); } // // Now process the action // if (share) { QString type = action->data().toMap().value("type").toString(); QString mountpoint = action->data().toMap().value("mountpoint").toString(); if (type == "unmount") { Smb4KMounter::self()->unmountShare(share, false); } else if (type == "bookmark") { Smb4KBookmarkHandler::self()->addBookmark(share); } else if (type == "sync") { Smb4KSynchronizer::self()->synchronize(share); } else if (type == "konsole") { openShare(share, Smb4KGlobal::Konsole); } else if (type == "filemanager") { openShare(share, Smb4KGlobal::FileManager); } } } diff --git a/smb4k/smb4ksharesview.cpp b/smb4k/smb4ksharesview.cpp index ef14f61..0c93c15 100644 --- a/smb4k/smb4ksharesview.cpp +++ b/smb4k/smb4ksharesview.cpp @@ -1,399 +1,395 @@ /*************************************************************************** This is the shares view of Smb4K. ------------------- begin : Mo Dez 4 2006 copyright : (C) 2006-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksharesview.h" #include "smb4ksharesviewitem.h" #include "smb4ktooltip.h" #include "core/smb4kshare.h" #include "core/smb4ksettings.h" // Qt includes #include #include #include #include #include // KDE includes #include Smb4KSharesView::Smb4KSharesView(QWidget *parent) : QListWidget(parent) { setMouseTracking(true); setSelectionMode(ExtendedSelection); setResizeMode(Adjust); setSortingEnabled(true); setWordWrap(true); setAcceptDrops(true); setDragEnabled(true); setDropIndicatorShown(true); setUniformItemSizes(true); setWrapping(true); setContextMenuPolicy(Qt::CustomContextMenu); m_tooltipItem = 0; m_mouseInside = false; // // Connections // connect(this, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(slotItemEntered(QListWidgetItem*))); connect(this, SIGNAL(viewportEntered()), this, SLOT(slotViewportEntered())); } Smb4KSharesView::~Smb4KSharesView() { } void Smb4KSharesView::setViewMode(QListView::ViewMode mode, int iconSize) { // // Set the view mode // QListWidget::setViewMode(mode); // // Make adjustments // switch(mode) { case IconMode: { setUniformItemSizes(true); setIconSize(QSize(iconSize, iconSize)); setSpacing(5); break; } case ListMode: { setUniformItemSizes(false); setIconSize(QSize(iconSize, iconSize)); setSpacing(0); break; } default: { break; } } // // Align the items // for (int i = 0; i < count(); ++i) { Smb4KSharesViewItem *viewItem = static_cast(item(i)); viewItem->setItemAlignment(mode); } } bool Smb4KSharesView::event(QEvent *e) { switch (e->type()) { case QEvent::ToolTip: { // Intercept the tool tip event and show our own tool tip. QPoint pos = viewport()->mapFromGlobal(cursor().pos()); Smb4KSharesViewItem *item = static_cast(itemAt(pos)); if (item) { if (Smb4KSettings::showShareToolTip()) { m_tooltipItem = item; emit aboutToShowToolTip(m_tooltipItem); m_tooltipItem->tooltip()->show(cursor().pos()); } else { if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } } } else { if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } } break; } default: { break; } } return QListWidget::event(e); } void Smb4KSharesView::leaveEvent(QEvent *e) { if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } m_mouseInside = false; QListWidget::leaveEvent(e); } void Smb4KSharesView::enterEvent(QEvent *e) { m_mouseInside = true; QListWidget::enterEvent(e); } void Smb4KSharesView::mousePressEvent(QMouseEvent *e) { // Hide the current tool tip so that it is not in the way. if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } // Get the item that is under the mouse. If there is no // item, unselect the current item. QListWidgetItem *item = itemAt(e->pos()); if (!item && !selectedItems().isEmpty()) { clearSelection(); setCurrentItem(0); emit itemPressed(currentItem()); } QListWidget::mousePressEvent(e); } void Smb4KSharesView::focusOutEvent(QFocusEvent *e) { QListWidget::focusOutEvent(e); } void Smb4KSharesView::wheelEvent(QWheelEvent *e) { if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } QListWidget::wheelEvent(e); } void Smb4KSharesView::dragEnterEvent(QDragEnterEvent *e) { if (e->mimeData()->hasUrls()) { e->accept(); } else { e->ignore(); } } void Smb4KSharesView::dragMoveEvent(QDragMoveEvent *e) { // Let the QAbstractItemView do the highlighting of the item, etc. QAbstractItemView::dragMoveEvent(e); // Now we do our thing. Smb4KSharesViewItem *item = static_cast(itemAt(e->pos())); if (item && !item->shareItem()->isInaccessible() && (item->flags() & Qt::ItemIsDropEnabled) && (e->proposedAction() & (Qt::CopyAction | Qt::MoveAction))) { QUrl url = QUrl::fromLocalFile(item->shareItem()->path()); if (e->source() == this && e->mimeData()->urls().first() == url) { e->ignore(); } else { e->accept(); } } else { e->ignore(); } } void Smb4KSharesView::dropEvent(QDropEvent *e) { // Get the item and process the drop event Smb4KSharesViewItem *item = static_cast(itemAt(e->pos())); if (item && !item->shareItem()->isInaccessible() && (e->proposedAction() & (Qt::CopyAction|Qt::MoveAction))) { QUrl url = QUrl::fromLocalFile(item->shareItem()->path()); if (e->source() == this && e->mimeData()->urls().first() == url) { e->ignore(); } else { e->acceptProposedAction(); emit acceptedDropEvent(item, e); e->accept(); } } else { e->ignore(); } } Qt::DropActions Smb4KSharesView::supportedDropActions() const { // Only allow copying and linking. return (Qt::CopyAction|Qt::LinkAction); } QMimeData *Smb4KSharesView::mimeData(const QList list) const { QMimeData *mimeData = new QMimeData(); QList urls; for (int i = 0; i < list.count(); ++i) { Smb4KSharesViewItem *item = static_cast(list.at(i)); urls << QUrl::fromLocalFile(item->shareItem()->path()); } mimeData->setUrls(urls); return mimeData; } void Smb4KSharesView::startDrag(Qt::DropActions supported) { if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } QList list = selectedItems(); if (!list.isEmpty()) { QMimeData *data = mimeData(list); if (!data) { return; } QDrag *drag = new QDrag(this); QPixmap pixmap; if (list.count() == 1) { Smb4KSharesViewItem *item = static_cast(list.first()); pixmap = item->icon().pixmap(KIconLoader::SizeMedium); } else { pixmap = KDE::icon("document-multiple").pixmap(KIconLoader::SizeMedium); } drag->setPixmap(pixmap); drag->setMimeData(data); drag->exec(supported, Qt::IgnoreAction); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KSharesView::slotItemEntered(QListWidgetItem *item) { Smb4KSharesViewItem *share_item = static_cast(item); if (m_tooltipItem && m_tooltipItem != share_item) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } } void Smb4KSharesView::slotViewportEntered() { // Hide the tool tip. if (m_tooltipItem) { emit aboutToHideToolTip(m_tooltipItem); m_tooltipItem->tooltip()->hide(); m_tooltipItem = 0; } } diff --git a/smb4k/smb4ksharesviewdockwidget.cpp b/smb4k/smb4ksharesviewdockwidget.cpp index 64bb982..1167f5d 100644 --- a/smb4k/smb4ksharesviewdockwidget.cpp +++ b/smb4k/smb4ksharesviewdockwidget.cpp @@ -1,652 +1,648 @@ /*************************************************************************** The network search widget dock widget ------------------- begin : Fri Mai 04 2018 copyright : (C) 2018-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksharesviewdockwidget.h" #include "smb4ksharesviewitem.h" #include "core/smb4ksettings.h" #include "core/smb4kmounter.h" #include "core/smb4ksynchronizer.h" #include "core/smb4kbookmarkhandler.h" #include "core/smb4kshare.h" #include "core/smb4khardwareinterface.h" #if defined(Q_OS_LINUX) #include "smb4kmountsettings_linux.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) #include "smb4kmountsettings_bsd.h" #endif // Qt includes #include #include #include #include // KDE includes #include #include #include #include #include Smb4KSharesViewDockWidget::Smb4KSharesViewDockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) { // // Set the shares view // m_sharesView = new Smb4KSharesView(this); setWidget(m_sharesView); // // The action collection // m_actionCollection = new KActionCollection(this); // // The context menu // m_contextMenu = new KActionMenu(this); // // Set up the actions // setupActions(); // // Load the settings // loadSettings(); // // Connections // connect(m_sharesView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); connect(m_sharesView, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(slotItemActivated(QListWidgetItem*))); connect(m_sharesView, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); connect(m_sharesView, SIGNAL(acceptedDropEvent(Smb4KSharesViewItem*,QDropEvent*)), this, SLOT(slotDropEvent(Smb4KSharesViewItem*,QDropEvent*))); connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotShareMounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotShareUnmounted(SharePtr))); connect(Smb4KMounter::self(), SIGNAL(updated(SharePtr)), this, SLOT(slotShareUpdated(SharePtr))); connect(KIconLoader::global(), SIGNAL(iconChanged(int)), this, SLOT(slotIconSizeChanged(int))); } Smb4KSharesViewDockWidget::~Smb4KSharesViewDockWidget() { } void Smb4KSharesViewDockWidget::loadSettings() { // // Adjust the view according to the setting chosen // switch (Smb4KSettings::sharesViewMode()) { case Smb4KSettings::EnumSharesViewMode::IconView: { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Desktop); m_sharesView->setViewMode(Smb4KSharesView::IconMode, iconSize); break; } case Smb4KSettings::EnumSharesViewMode::ListView: { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_sharesView->setViewMode(Smb4KSharesView::ListMode, iconSize); break; } default: { break; } } // // Adjust the unmount actions if needed // if (!m_sharesView->selectedItems().isEmpty()) { QList selectedItems = m_sharesView->selectedItems(); if (selectedItems.size() == 1) { Smb4KSharesViewItem *item = static_cast(selectedItems.first()); m_actionCollection->action("unmount_action")->setEnabled((!item->shareItem()->isForeign() || Smb4KMountSettings::unmountForeignShares())); } else if (selectedItems.size() > 1) { int foreign = 0; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && item->shareItem()->isForeign()) { foreign++; } } m_actionCollection->action("unmount_action")->setEnabled(((selectedItems.size() > foreign) || Smb4KMountSettings::unmountForeignShares())); } } actionCollection()->action("unmount_all_action")->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } void Smb4KSharesViewDockWidget::saveSettings() { // // Not used at the moment // } KActionCollection *Smb4KSharesViewDockWidget::actionCollection() { return m_actionCollection; } void Smb4KSharesViewDockWidget::setupActions() { // // The 'View Modes' submenu and the respective actions // KActionMenu *viewModesMenu = new KActionMenu(KDE::icon("view-choose"), i18n("View Modes"), this); QActionGroup *viewModesGroup = new QActionGroup(this); viewModesGroup->setExclusive(true); connect(viewModesGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewModeChanged(QAction*))); QAction *iconViewAction = new QAction(KDE::icon("view-list-icons"), i18n("Icon View"), this); iconViewAction->setObjectName("icon_view_action"); iconViewAction->setCheckable(true); viewModesGroup->addAction(iconViewAction); viewModesMenu->addAction(iconViewAction); QAction *listViewAction = new QAction(KDE::icon("view-list-details"), i18n("List View"), this); listViewAction->setObjectName("list_view_action"); listViewAction->setCheckable(true); viewModesGroup->addAction(listViewAction); viewModesMenu->addAction(listViewAction); switch (Smb4KSettings::sharesViewMode()) { case Smb4KSettings::EnumSharesViewMode::IconView: { iconViewAction->setChecked(true); break; } case Smb4KSettings::EnumSharesViewMode::ListView: { listViewAction->setChecked(true); break; } default: { break; } } // // The Unmount action // QAction *unmountAction = new QAction(KDE::icon("media-eject"), i18n("&Unmount"), this); connect(unmountAction, SIGNAL(triggered(bool)), this, SLOT(slotUnmountActionTriggered(bool))); // // The Unmount All action // QAction *unmountAllAction = new QAction(KDE::icon("system-run"), i18n("U&nmount All"), this); connect(unmountAllAction, SIGNAL(triggered(bool)), this, SLOT(slotUnmountAllActionTriggered(bool))); // // The Add Bookmark action // QAction *bookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), this); connect(bookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotBookmarkActionTriggered(bool))); // // The Synchronize action // QAction *synchronizeAction = new QAction(KDE::icon("folder-sync"), i18n("S&ynchronize"), this); connect(synchronizeAction, SIGNAL(triggered(bool)), this, SLOT(slotSynchronizeActionTriggered(bool))); // // The Open with Konsole action // QAction *konsoleAction = new QAction(KDE::icon("utilities-terminal"), i18n("Open with Konso&le"), this); connect(konsoleAction, SIGNAL(triggered(bool)), this, SLOT(slotKonsoleActionTriggered(bool))); QAction *filemanagerAction = new QAction(KDE::icon("system-file-manager"), i18n("Open with F&ile Manager"), this); connect(filemanagerAction, SIGNAL(triggered(bool)), this, SLOT(slotFileManagerActionTriggered(bool))); // // Three separators // QAction *separator1 = new QAction(this); separator1->setSeparator(true); QAction *separator2 = new QAction(this); separator2->setSeparator(true); QAction *separator3 = new QAction(this); separator3->setSeparator(true); // // Add the actions // m_actionCollection->addAction("shares_view_modes", viewModesMenu); m_actionCollection->addAction("shares_separator1", separator1); m_actionCollection->addAction("unmount_action", unmountAction); m_actionCollection->addAction("unmount_all_action", unmountAllAction); m_actionCollection->addAction("shares_separator2", separator2); m_actionCollection->addAction("bookmark_action", bookmarkAction); m_actionCollection->addAction("synchronize_action", synchronizeAction); m_actionCollection->addAction("shares_separator3", separator3); m_actionCollection->addAction("konsole_action", konsoleAction); m_actionCollection->addAction("filemanager_action", filemanagerAction); // // Set the shortcuts // m_actionCollection->setDefaultShortcut(unmountAction, QKeySequence(Qt::CTRL+Qt::Key_U)); m_actionCollection->setDefaultShortcut(unmountAllAction, QKeySequence(Qt::CTRL+Qt::Key_N)); m_actionCollection->setDefaultShortcut(bookmarkAction, QKeySequence(Qt::CTRL+Qt::Key_B)); m_actionCollection->setDefaultShortcut(synchronizeAction, QKeySequence(Qt::CTRL+Qt::Key_Y)); m_actionCollection->setDefaultShortcut(konsoleAction, QKeySequence(Qt::CTRL+Qt::Key_L)); m_actionCollection->setDefaultShortcut(filemanagerAction, QKeySequence(Qt::CTRL+Qt::Key_I)); // // Disable all actions // unmountAction->setEnabled(false); unmountAllAction->setEnabled(false); bookmarkAction->setEnabled(false); synchronizeAction->setEnabled(false); konsoleAction->setEnabled(false); filemanagerAction->setEnabled(false); // // Plug the actions into the context menu // for (QAction *a : m_actionCollection->actions()) { m_contextMenu->addAction(a); } } void Smb4KSharesViewDockWidget::slotContextMenuRequested(const QPoint& pos) { m_contextMenu->menu()->popup(m_sharesView->viewport()->mapToGlobal(pos)); } void Smb4KSharesViewDockWidget::slotItemActivated(QListWidgetItem* /*item*/) { // // Do not execute the item when keyboard modifiers were pressed // or the mouse button is not the left one. // if (QApplication::keyboardModifiers() == Qt::NoModifier) { slotFileManagerActionTriggered(false); } } void Smb4KSharesViewDockWidget::slotItemSelectionChanged() { QList selectedItems = m_sharesView->selectedItems(); if (selectedItems.size() == 1) { Smb4KSharesViewItem *item = static_cast(selectedItems.first()); bool syncRunning = Smb4KSynchronizer::self()->isRunning(item->shareItem()); m_actionCollection->action("unmount_action")->setEnabled((!item->shareItem()->isForeign() || Smb4KMountSettings::unmountForeignShares())); m_actionCollection->action("bookmark_action")->setEnabled(true); if (!item->shareItem()->isInaccessible()) { m_actionCollection->action("synchronize_action")->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && !syncRunning); m_actionCollection->action("konsole_action")->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty()); m_actionCollection->action("filemanager_action")->setEnabled(true); } else { m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } else if (selectedItems.size() > 1) { int syncsRunning = 0; int inaccessible = 0; int foreign = 0; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item) { // Is the share synchronized at the moment? if (Smb4KSynchronizer::self()->isRunning(item->shareItem())) { syncsRunning += 1; } // Is the share inaccessible at the moment? if (item->shareItem()->isInaccessible()) { inaccessible += 1; } // Was the share being mounted by another user? if (item->shareItem()->isForeign()) { foreign += 1; } } } m_actionCollection->action("unmount_action")->setEnabled(((selectedItems.size() > foreign) || Smb4KMountSettings::unmountForeignShares())); m_actionCollection->action("bookmark_action")->setEnabled(true); if (selectedItems.size() > inaccessible) { m_actionCollection->action("synchronize_action")->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && (selectedItems.size() > syncsRunning)); m_actionCollection->action("konsole_action")->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty()); m_actionCollection->action("filemanager_action")->setEnabled(true); } else { m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } else { m_actionCollection->action("unmount_action")->setEnabled(false); m_actionCollection->action("bookmark_action")->setEnabled(false); m_actionCollection->action("synchronize_action")->setEnabled(false); m_actionCollection->action("konsole_action")->setEnabled(false); m_actionCollection->action("filemanager_action")->setEnabled(false); } } void Smb4KSharesViewDockWidget::slotDropEvent(Smb4KSharesViewItem* item, QDropEvent* e) { if (item && e) { if (e->mimeData()->hasUrls()) { if (Smb4KHardwareInterface::self()->isOnline()) { QUrl dest = QUrl::fromLocalFile(item->shareItem()->path()); KIO::DropJob *job = drop(e, dest, KIO::DefaultFlags); job->uiDelegate()->setAutoErrorHandlingEnabled(true); job->uiDelegate()->setAutoWarningHandlingEnabled(true); } else { KMessageBox::sorry(m_sharesView, i18n("There is no active connection to the share %1! You cannot drop any files here.", item->shareItem()->displayString())); } } } } void Smb4KSharesViewDockWidget::slotViewModeChanged(QAction* action) { // // Set the new view mode // if (action->objectName() == "icon_view_action") { Smb4KSettings::setSharesViewMode(Smb4KSettings::EnumSharesViewMode::IconView); } else if (action->objectName() == "list_view_action") { Smb4KSettings::setSharesViewMode(Smb4KSettings::EnumSharesViewMode::ListView); } // // Save settings // Smb4KSettings::self()->save(); // // Load the settings // loadSettings(); } void Smb4KSharesViewDockWidget::slotShareMounted(const SharePtr& share) { // // Add the share to the shares view // if (share) { // Add the item (void) new Smb4KSharesViewItem(m_sharesView, share); // Sort the view m_sharesView->sortItems(Qt::AscendingOrder); // Enable/disable the 'Unmount All' action actionCollection()->action("unmount_all_action")->setEnabled( ((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } } void Smb4KSharesViewDockWidget::slotShareUnmounted(const SharePtr& share) { // // Remove the share from the shares view // if (share) { // Get the item and delete it. Take care of the current item, if necessary. for (int i = 0; i < m_sharesView->count(); ++i) { Smb4KSharesViewItem *item = static_cast(m_sharesView->item(i)); if (item && (item->shareItem()->path() == share->path() || item->shareItem()->canonicalPath() == share->canonicalPath())) { if (item == m_sharesView->currentItem()) { m_sharesView->setCurrentItem(0); } delete m_sharesView->takeItem(i); break; } else { continue; } } // Enable/disable the 'Unmount All' action actionCollection()->action("unmount_all_action")->setEnabled( ((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && m_sharesView->count() != 0)); } } void Smb4KSharesViewDockWidget::slotShareUpdated(const SharePtr& share) { // // Get the share item and updated it // if (share) { for (int i = 0; i < m_sharesView->count(); ++i) { Smb4KSharesViewItem *item = static_cast(m_sharesView->item(i)); if (item && (item->shareItem()->path() == share->path() || item->shareItem()->canonicalPath() == share->canonicalPath())) { item->update(); break; } else { continue; } } } } void Smb4KSharesViewDockWidget::slotUnmountActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); QList shares; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item) { shares << item->shareItem(); } } Smb4KMounter::self()->unmountShares(shares, false); } void Smb4KSharesViewDockWidget::slotUnmountAllActionTriggered(bool /*checked*/) { Smb4KMounter::self()->unmountAllShares(false); } void Smb4KSharesViewDockWidget::slotBookmarkActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); QList shares; for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); shares << item->shareItem(); } Smb4KBookmarkHandler::self()->addBookmarks(shares); } void Smb4KSharesViewDockWidget::slotSynchronizeActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible() && !Smb4KSynchronizer::self()->isRunning(item->shareItem())) { Smb4KSynchronizer::self()->synchronize(item->shareItem()); } } } void Smb4KSharesViewDockWidget::slotKonsoleActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible()) { openShare(item->shareItem(), Konsole); } } } void Smb4KSharesViewDockWidget::slotFileManagerActionTriggered(bool /*checked*/) { QList selectedItems = m_sharesView->selectedItems(); for (QListWidgetItem *selectedItem : selectedItems) { Smb4KSharesViewItem *item = static_cast(selectedItem); if (item && !item->shareItem()->isInaccessible()) { openShare(item->shareItem(), FileManager); } } } void Smb4KSharesViewDockWidget::slotIconSizeChanged(int group) { // // Change the icon size depending of the view mode // if (group == KIconLoader::Desktop && Smb4KSettings::sharesViewMode() == Smb4KSettings::EnumSharesViewMode::IconView) { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Desktop); m_sharesView->setIconSize(QSize(iconSize, iconSize)); } else if (group == KIconLoader::Small && Smb4KSettings::sharesViewMode() == Smb4KSettings::EnumSharesViewMode::ListView) { int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small); m_sharesView->setIconSize(QSize(iconSize, iconSize)); } } diff --git a/smb4k/smb4ksharesviewitem.cpp b/smb4k/smb4ksharesviewitem.cpp index c02176c..7e52006 100644 --- a/smb4k/smb4ksharesviewitem.cpp +++ b/smb4k/smb4ksharesviewitem.cpp @@ -1,92 +1,88 @@ /*************************************************************************** The item for Smb4K's shares view. ------------------- begin : Di Dez 5 2006 copyright : (C) 2006-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksharesviewitem.h" #include "smb4ksharesview.h" #include "core/smb4kshare.h" Smb4KSharesViewItem::Smb4KSharesViewItem(Smb4KSharesView *parent, const SharePtr &share) : QListWidgetItem(parent), m_share(share) { setFlags(flags() | Qt::ItemIsDropEnabled); setItemAlignment(parent->viewMode()); m_tooltip = new Smb4KToolTip(); m_tooltip->setup(Smb4KToolTip::SharesView, m_share); setText(m_share->displayString()); setIcon(m_share->icon()); } Smb4KSharesViewItem::~Smb4KSharesViewItem() { delete m_tooltip; } void Smb4KSharesViewItem::update() { m_tooltip->update(Smb4KToolTip::SharesView, m_share); setText(m_share->displayString()); setIcon(m_share->icon()); } Smb4KToolTip* Smb4KSharesViewItem::tooltip() { return m_tooltip; } void Smb4KSharesViewItem::setItemAlignment(QListView::ViewMode mode) { switch (mode) { case QListView::IconMode: { setTextAlignment(Qt::AlignHCenter|Qt::AlignTop); break; } case QListView::ListMode: { setTextAlignment(Qt::AlignAbsolute|Qt::AlignVCenter); break; } default: { break; } } } diff --git a/smb4k/smb4ksystemtray.cpp b/smb4k/smb4ksystemtray.cpp index f96fe16..3c92885 100644 --- a/smb4k/smb4ksystemtray.cpp +++ b/smb4k/smb4ksystemtray.cpp @@ -1,234 +1,230 @@ /*************************************************************************** smb4ksystemtray - This is the system tray window class of Smb4K. ------------------- begin : Mi Jun 13 2007 copyright : (C) 2007-2019 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ksystemtray.h" #include "smb4kbookmarkmenu.h" #include "smb4ksharesmenu.h" #include "smb4kprofilesmenu.h" #include "core/smb4kworkgroup.h" #include "core/smb4kshare.h" #include "core/smb4kglobal.h" #include "core/smb4kmounter.h" #include "core/smb4kclient.h" // Qt includes #include #include // KDE specific includes #include #include #include #include #include #include #include #include #include using namespace Smb4KGlobal; Smb4KSystemTray::Smb4KSystemTray(QWidget *parent) : KStatusNotifierItem("smb4k_systemtray", parent) { // // Set the icon for the system tray // QString iconName = QStringLiteral("network-workgroup"); setIconByName(iconName); // // Set the tooltip text // setToolTip(iconName, i18n("Smb4K"), KAboutData::applicationData().shortDescription()); // // Set the status of the icon. By default, it is active. It will become passive, // if the scanner could not find something and no shares were mounted. // setStatus(Active); // // Set the category // setCategory(ApplicationStatus); // // Add the actions to the action collection // QAction *mountAction = new QAction(KDE::icon("view-form", QStringList("emblem-mounted")), i18n("&Open Mount Dialog"), this); connect(mountAction, SIGNAL(triggered(bool)), SLOT(slotMountDialog())); addAction("shares_menu", new Smb4KSharesMenu(associatedWidget())); addAction("bookmarks_menu", new Smb4KBookmarkMenu(Smb4KBookmarkMenu::SystemTray, associatedWidget())); addAction("profiles_menu", new Smb4KProfilesMenu()); addAction("mount_action", mountAction); addAction("config_action", KStandardAction::preferences(this, SLOT(slotConfigDialog()), this)); // // Set up the menu // contextMenu()->addAction(action("shares_menu")); contextMenu()->addAction(action("bookmarks_menu")); contextMenu()->addAction(action("profiles_menu")); contextMenu()->addSeparator(); contextMenu()->addAction(action("mount_action")); contextMenu()->addAction(action("config_action")); // // Connections // connect(Smb4KMounter::self(), SIGNAL(mountedSharesListChanged()), SLOT(slotSetStatus())); connect(Smb4KClient::self(), SIGNAL(workgroups()), SLOT(slotSetStatus())); } Smb4KSystemTray::~Smb4KSystemTray() { } void Smb4KSystemTray::loadSettings() { // // Adjust the bookmarks menu // Smb4KBookmarkMenu *bookmarkMenu = static_cast(action("bookmarks_menu")); if (bookmarkMenu) { bookmarkMenu->refreshMenu(); } // // Adjust the shares menu // Smb4KSharesMenu *sharesMenu = static_cast(action("shares_menu")); if (sharesMenu) { sharesMenu->refreshMenu(); } // // Adjust the profiles menu // Smb4KProfilesMenu *profilesMenu = static_cast(action("profiles_menu")); if (profilesMenu) { profilesMenu->refreshMenu(); } } ///////////////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KSystemTray::slotMountDialog() { Smb4KMounter::self()->openMountDialog(); } void Smb4KSystemTray::slotConfigDialog() { // // Check if the configuration dialog exists and try to show it. // if (KConfigDialog::exists("ConfigDialog")) { KConfigDialog::showDialog("ConfigDialog"); return; } // // If the dialog does not exist, load and show it: // KPluginLoader loader("smb4kconfigdialog"); KPluginFactory *configFactory = loader.factory(); if (configFactory) { KConfigDialog *dlg = 0; if (associatedWidget()) { dlg = configFactory->create(associatedWidget()); dlg->setObjectName("ConfigDialog"); } else { dlg = configFactory->create(contextMenu()); dlg->setObjectName("ConfigDialog"); } if (dlg) { dlg->setObjectName("ConfigDialog"); connect(dlg, SIGNAL(settingsChanged(QString)), this, SLOT(slotSettingsChanged(QString)), Qt::UniqueConnection); connect(dlg, SIGNAL(settingsChanged(QString)), this, SIGNAL(settingsChanged(QString)), Qt::UniqueConnection); dlg->show(); } } else { KMessageBox::error(0, ""+loader.errorString()+""); return; } } void Smb4KSystemTray::slotSettingsChanged(const QString &) { // // Execute loadSettings() // loadSettings(); } void Smb4KSystemTray::slotSetStatus() { // // Set the status of the system tray icon // if (!mountedSharesList().isEmpty() || !workgroupsList().isEmpty()) { setStatus(KStatusNotifierItem::Active); } else { setStatus(KStatusNotifierItem::Passive); } } diff --git a/smb4k/smb4ktooltip.cpp b/smb4k/smb4ktooltip.cpp index 7cd38ae..6a1edb2 100644 --- a/smb4k/smb4ktooltip.cpp +++ b/smb4k/smb4ktooltip.cpp @@ -1,861 +1,857 @@ /*************************************************************************** smb4ktooltip - Provides tooltips for Smb4K ------------------- begin : Sa Dez 23 2010 copyright : (C) 2010-2017 by Alexander Reinholdt email : alexander.reinholdt@kdemail.net ***************************************************************************/ /*************************************************************************** * 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, Suite 500, Boston,* * MA 02110-1335, USA * ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - // application specific includes #include "smb4ktooltip.h" #include "core/smb4kbasicnetworkitem.h" #include "core/smb4kworkgroup.h" #include "core/smb4khost.h" #include "core/smb4kshare.h" #include "core/smb4kglobal.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include using namespace Smb4KGlobal; Smb4KToolTip::Smb4KToolTip(QWidget* parent) : QWidget(parent, Qt::ToolTip|Qt::BypassGraphicsProxyWidget|Qt::FramelessWindowHint), m_item(NetworkItemPtr()), m_tip_layout(0), m_info_layout(0), m_text_layout(0) { qDebug() << "Use KToolTipWidget for the tooltips"; m_master_browser_label = 0; m_comment_label = 0; m_ip_label = 0; m_mounted_label = 0; m_size_label = 0; setAttribute(Qt::WA_TranslucentBackground); // Copied from QToolTip setForegroundRole(QPalette::ToolTipText); setBackgroundRole(QPalette::ToolTipBase); setPalette(QToolTip::palette()); ensurePolished(); setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0); } Smb4KToolTip::~Smb4KToolTip() { // Never delete m_item here. We only have a pointer to // somewhere outside of this class. } void Smb4KToolTip::setup(Smb4KToolTip::Parent parent, const NetworkItemPtr &item) { if (item) { m_item = item; // Set up tool tip. switch (parent) { case NetworkBrowser: { setupNetworkBrowserToolTip(); break; } case SharesView: { setupSharesViewToolTip(); break; } default: { return; } } } } void Smb4KToolTip::update(Smb4KToolTip::Parent parent, const NetworkItemPtr &item) { if (item) { m_item = item; switch (parent) { case NetworkBrowser: { switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = item.staticCast(); if (workgroup->hasMasterBrowserIpAddress()) { m_master_browser_label->setText(workgroup->masterBrowserName()+" ("+workgroup->masterBrowserIpAddress()+')'); } else { m_master_browser_label->setText(workgroup->masterBrowserName()); } break; } case Host: { HostPtr host = item.staticCast(); if (!host->comment().isEmpty()) { m_comment_label->setText(host->comment()); } else { m_comment_label->setText("-"); } if (host->hasIpAddress()) { m_ip_label->setText(host->ipAddress()); } else { m_ip_label->setText("-"); } break; } case Share: { SharePtr share = item.staticCast(); if (!share->comment().isEmpty()) { m_comment_label->setText(share->comment()); } else { m_comment_label->setText("-"); } if (!share->isPrinter()) { if (share->isMounted()) { m_mounted_label->setText(i18n("yes")); } else { m_mounted_label->setText(i18n("no")); } } else { m_mounted_label->setText("-"); } if (share->hasHostIpAddress()) { m_ip_label->setText(share->hostIpAddress()); } else { m_ip_label->setText("-"); } break; } default: { break; } } break; } case SharesView: { SharePtr share = item.staticCast(); if (share->totalDiskSpace() != 0 && share->freeDiskSpace() != 0) { m_size_label->setText(i18n("%1 of %2 free (%3 used)", share->freeDiskSpaceString(), share->totalDiskSpaceString(), share->diskUsageString())); } else { m_size_label->setText(i18n("unknown")); } break; } default: { break; } } } } void Smb4KToolTip::show(const QPoint &pos) { // Get the geometry of the screen where the cursor is const QRect screenRect = QApplication::desktop()->screenGeometry(pos); // Adjust the size adjustSize(); // The position where the tooltip is to be shown QPoint tooltipPos; // Correct the position of the tooltip, so that it is completely // shown. if (pos.x() + width() + 5 >= screenRect.x() + screenRect.width()) { tooltipPos.setX(pos.x() - width() - 5); } else { tooltipPos.setX(pos.x() + 5); } if (pos.y() + height() + 5 >= screenRect.y() + screenRect.height()) { tooltipPos.setY(pos.y() - height() - 5); } else { tooltipPos.setY(pos.y() + 5); } move(tooltipPos); setVisible(true); QTimer::singleShot(10000, this, SLOT(slotHideToolTip())); } void Smb4KToolTip::hide() { setVisible(false); } void Smb4KToolTip::setupNetworkBrowserToolTip() { // NOTE: If you change the layout here, adjust also the update function! m_tip_layout = new QHBoxLayout(this); m_tip_layout->setAlignment(Qt::AlignTop); m_info_layout = new QVBoxLayout(); m_info_layout->setAlignment(Qt::AlignTop); // Set the icon QLabel *icon_label = new QLabel(this); icon_label->setPixmap(m_item->icon().pixmap(KIconLoader::SizeEnormous)); m_tip_layout->addWidget(icon_label, Qt::AlignHCenter); m_tip_layout->addLayout(m_info_layout); // Use a brighter color for the left label. This was copied from // KFileMetaDataWidget class. QPalette p = palette(); const QPalette::ColorRole role = foregroundRole(); QColor textColor = p.color(role); textColor.setAlpha(128); p.setColor(role, textColor); // FIXME: Use smaller font for the information. Get the current // point size of the window system with QFontInfo::pointSize(). switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); QLabel *caption = new QLabel(workgroup->workgroupName(), this); caption->setAlignment(Qt::AlignHCenter); QFont caption_font = caption->font(); caption_font.setBold(true); caption->setFont(caption_font); m_info_layout->addWidget(caption); m_info_layout->addWidget(new KSeparator(this), Qt::AlignHCenter); m_text_layout = new QGridLayout(); QLabel *type_label = new QLabel(i18n("Type"), this); type_label->setPalette(p); m_text_layout->addWidget(type_label, 0, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(i18n("Workgroup"), this), 0, 1, 0); QLabel *mb_label = new QLabel(i18n("Master browser"), this); mb_label->setPalette(p); m_text_layout->addWidget(mb_label, 1, 0, Qt::AlignRight); if (workgroup->hasMasterBrowserIpAddress()) { m_master_browser_label = new QLabel(workgroup->masterBrowserName()+" ("+workgroup->masterBrowserIpAddress()+')', this); m_text_layout->addWidget(m_master_browser_label, 1, 1, 0); } else { m_master_browser_label = new QLabel(workgroup->masterBrowserName(), this); m_text_layout->addWidget(m_master_browser_label, 1, 1, 0); } m_info_layout->addLayout(m_text_layout); m_info_layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); break; } case Host: { HostPtr host = m_item.staticCast(); QLabel *caption = new QLabel(host->hostName(), this); caption->setAlignment(Qt::AlignHCenter); QFont caption_font = caption->font(); caption_font.setBold(true); caption->setFont(caption_font); m_info_layout->addWidget(caption, Qt::AlignHCenter); m_info_layout->addWidget(new KSeparator(this), Qt::AlignHCenter); m_text_layout = new QGridLayout(); QLabel *type_label = new QLabel(i18n("Type"), this); type_label->setPalette(p); m_text_layout->addWidget(type_label, 0, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(i18n("Host"), this), 0, 1, 0); QLabel *co_label = new QLabel(i18n("Comment"), this); co_label->setPalette(p); m_text_layout->addWidget(co_label, 1, 0, Qt::AlignRight); if (!host->comment().isEmpty()) { m_comment_label = new QLabel(host->comment(), this); m_text_layout->addWidget(m_comment_label, 1, 1, 0); } else { m_comment_label = new QLabel("-", this); m_text_layout->addWidget(m_comment_label, 1, 1, 0); } QLabel *ip_label = new QLabel(i18n("IP Address"), this); ip_label->setPalette(p); m_text_layout->addWidget(ip_label, 2, 0, Qt::AlignRight); if (host->hasIpAddress()) { m_ip_label = new QLabel(host->ipAddress(), this); m_text_layout->addWidget(m_ip_label, 2, 1, 0); } else { m_ip_label = new QLabel("-", this); m_text_layout->addWidget(m_ip_label, 2, 1, 0); } QLabel *wg_label = new QLabel(i18n("Workgroup"), this); wg_label->setPalette(p); m_text_layout->addWidget(wg_label, 3, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(host->workgroupName(), this), 3, 1, 0); m_info_layout->addLayout(m_text_layout); m_info_layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); break; } case Share: { SharePtr share = m_item.staticCast(); QLabel *caption = new QLabel(share->shareName(), this); caption->setAlignment(Qt::AlignHCenter); QFont caption_font = caption->font(); caption_font.setBold(true); caption->setFont(caption_font); m_info_layout->addWidget(caption); m_info_layout->addWidget(new KSeparator(this), Qt::AlignHCenter); m_text_layout = new QGridLayout(); QLabel *type_label = new QLabel(i18n("Type"), this); type_label->setPalette(p); m_text_layout->addWidget(type_label, 0, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(i18n("Share (%1)", share->shareTypeString()), this), 0, 1, 0); QLabel *co_label = new QLabel(i18n("Comment"), this); co_label->setPalette(p); m_text_layout->addWidget(co_label, 1, 0, Qt::AlignRight); if (!share->comment().isEmpty()) { m_comment_label = new QLabel(share->comment(), this); m_text_layout->addWidget(m_comment_label, 1, 1, 0); } else { m_comment_label = new QLabel("-", this); m_text_layout->addWidget(m_comment_label, 1, 1, 0); } QLabel *mnt_label = new QLabel(i18n("Mounted"), this); mnt_label->setPalette(p); m_text_layout->addWidget(mnt_label, 2, 0, Qt::AlignRight); if (!share->isPrinter()) { if (share->isMounted()) { m_mounted_label = new QLabel(i18n("yes"), this); m_text_layout->addWidget(m_mounted_label, 2, 1, 0); } else { m_mounted_label = new QLabel(i18n("no"), this); m_text_layout->addWidget(m_mounted_label, 2, 1, 0); } } else { m_mounted_label = new QLabel("-", this); m_text_layout->addWidget(m_mounted_label, 2, 1, 0); } QLabel *h_label = new QLabel(i18n("Host"), this); h_label->setPalette(p); m_text_layout->addWidget(h_label, 3, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(share->hostName()), 3, 1, 0); QLabel *ip_label = new QLabel(i18n("IP Address"), this); ip_label->setPalette(p); m_text_layout->addWidget(ip_label, 4, 0, Qt::AlignRight); if (share->hasHostIpAddress()) { m_ip_label = new QLabel(share->hostIpAddress(), this); m_text_layout->addWidget(m_ip_label, 4, 1, 0); } else { m_ip_label = new QLabel("-", this); m_text_layout->addWidget(m_ip_label, 4, 1, 0); } QLabel *unc_label = new QLabel(i18n("Location"), this); unc_label->setPalette(p); m_text_layout->addWidget(unc_label, 5, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(share->displayString(), this), 5, 1, 0); m_info_layout->addLayout(m_text_layout); m_info_layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); break; } default: { return; } } adjustSize(); } void Smb4KToolTip::setupSharesViewToolTip() { // NOTE: If you change the layout here, adjust also the update function! SharePtr share = m_item.staticCast(); m_tip_layout = new QHBoxLayout(this); m_tip_layout->setAlignment(Qt::AlignTop); m_info_layout = new QVBoxLayout(); m_info_layout->setAlignment(Qt::AlignTop); // Set the icon QLabel *icon_label = new QLabel(this); icon_label->setPixmap(share->icon().pixmap(KIconLoader::SizeEnormous)); m_tip_layout->addWidget(icon_label, Qt::AlignHCenter); m_tip_layout->addLayout(m_info_layout); // Use a brighter color for the left label. This was copied from // KFileMetaDataWidget class. QPalette p = palette(); const QPalette::ColorRole role = foregroundRole(); QColor textColor = p.color(role); textColor.setAlpha(128); p.setColor(role, textColor); // FIXME: Use smaller font for the information. Get the current // point size of the window system with QFontInfo::pointSize(). QLabel *caption = new QLabel(share->shareName(), this); caption->setAlignment(Qt::AlignHCenter); QFont caption_font = caption->font(); caption_font.setBold(true); caption->setFont(caption_font); m_info_layout->addWidget(caption); m_info_layout->addWidget(new KSeparator(this), Qt::AlignHCenter); m_text_layout = new QGridLayout(); QLabel *unc_label = new QLabel(i18n("Location"), this); unc_label->setPalette(p); m_text_layout->addWidget(unc_label, 0, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(share->displayString(), this), 0, 1, 0); QLabel *mp_label = new QLabel(i18n("Mountpoint"), this); mp_label->setPalette(p); m_text_layout->addWidget(mp_label, 1, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(share->path(), this), 1, 1, 0); QLabel *log_label = new QLabel(i18n("Login"), this); log_label->setPalette(p); m_text_layout->addWidget(log_label, 2, 0, Qt::AlignRight); if (!share->login().isEmpty()) { m_text_layout->addWidget(new QLabel(share->login(), this), 2, 1, 0); } else { m_text_layout->addWidget(new QLabel(i18n("unknown"), this), 2, 1, 0); } QLabel *own_label = new QLabel(i18n("Owner"), this); own_label->setPalette(p); m_text_layout->addWidget(own_label, 3, 0, Qt::AlignRight); QString owner = (!share->user().loginName().isEmpty() ? share->user().loginName() : i18n("unknown")); QString group = (!share->group().name().isEmpty() ? share->group().name() : i18n("unknown")); m_text_layout->addWidget(new QLabel(QString("%1 - %2") .arg(owner).arg(group), this), 3, 1, 0); QLabel *fs_label = new QLabel(i18n("File system"), this); fs_label->setPalette(p); m_text_layout->addWidget(fs_label, 4, 0, Qt::AlignRight); m_text_layout->addWidget(new QLabel(share->fileSystemString()), 4, 1, 0); QLabel *s_label = new QLabel(i18n("Size"), this); s_label->setPalette(p); m_text_layout->addWidget(s_label, 5, 0, Qt::AlignRight); if (share->totalDiskSpace() != 0 && share->freeDiskSpace() != 0) { m_size_label = new QLabel(i18n("%1 free of %2 (%3 used)", share->freeDiskSpaceString(), share->totalDiskSpaceString(), share->diskUsageString())); m_text_layout->addWidget(m_size_label, 5, 1, 0); } else { m_size_label = new QLabel(i18n("unknown")); m_text_layout->addWidget(m_size_label, 5, 1, 0); } m_info_layout->addLayout(m_text_layout); m_info_layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); } void Smb4KToolTip::updateNetworkBrowserToolTip() { if (m_item && m_text_layout && m_tip_layout) { switch (m_item->type()) { case Workgroup: { WorkgroupPtr workgroup = m_item.staticCast(); // Master browser name and IP address QLayoutItem *mb_item = m_text_layout->itemAtPosition(1, 1); QLabel *mb_label = static_cast(mb_item->widget()); if (mb_label) { if (!workgroup->hasMasterBrowserIpAddress()) { mb_label->setText(workgroup->masterBrowserName()+" ("+workgroup->masterBrowserIpAddress()+')'); } else { mb_label->setText(workgroup->masterBrowserName()); } } break; } case Host: { HostPtr host = m_item.staticCast(); // Comment QLayoutItem *co_item = m_text_layout->itemAtPosition(1, 1); QLabel *co_label = static_cast(co_item->widget()); if (co_label) { if (!host->comment().isEmpty()) { co_label->setText(host->comment()); } else { co_label->setText("-"); } } // IP address QLayoutItem *ip_item = m_text_layout->itemAtPosition(2, 1); QLabel *ip_label = static_cast(ip_item->widget()); if (ip_label) { if (host->hasIpAddress()) { ip_label->setText(host->ipAddress()); } else { ip_label->setText("-"); } } break; } case Share: { SharePtr share = m_item.staticCast(); // Icon QLayoutItem *icon_item = m_tip_layout->itemAt(0); QLabel *icon_label = static_cast(icon_item->widget()); icon_label->setPixmap(m_item->icon().pixmap(KIconLoader::SizeEnormous)); // Comment QLayoutItem *co_item = m_text_layout->itemAtPosition(1, 1); QLabel *co_label = static_cast(co_item->widget()); if (co_label) { if (!share->comment().isEmpty()) { co_label->setText(share->comment()); } else { co_label->setText("-"); } } // Mounted indicator QLayoutItem *mnt_item = m_text_layout->itemAtPosition(2, 1); QLabel *mnt_label = static_cast(mnt_item->widget()); if (mnt_label) { if (!share->isPrinter()) { if (share->isMounted()) { mnt_label->setText(i18n("yes")); } else { mnt_label->setText(i18n("no")); } } else { mnt_label->setText("-"); } } // The rest won't change while the tool tip is shown. break; } default: { break; } } } } void Smb4KToolTip::updateSharesViewToolTip() { if (m_item && m_text_layout && m_tip_layout) { SharePtr share = m_item.staticCast(); // Set the icon QLayoutItem *icon_item = m_tip_layout->itemAt(0); QLabel *icon_label = static_cast(icon_item->widget()); icon_label->setPixmap(m_item->icon().pixmap(KIconLoader::SizeEnormous)); QLayoutItem *log_item = m_text_layout->itemAtPosition(2, 1); QLabel *log_label = static_cast(log_item->widget()); if (!share->login().isEmpty()) { log_label->setText(share->login()); } else { log_label->setText(i18n("unknown")); } QLayoutItem *s_item = m_text_layout->itemAtPosition(5, 1); QLabel *s_label = static_cast(s_item->widget()); if (share->totalDiskSpace() != 0 && share->freeDiskSpace() != 0) { s_label->setText(i18n("%1 free of %2 (%3 used)", share->freeDiskSpaceString(), share->totalDiskSpaceString(), share->diskUsageString())); } else { s_label->setText(i18n("unknown")); } } // The rest won't change while the tool tip is shown. } void Smb4KToolTip::paintEvent(QPaintEvent *e) { // Copied from Dolphin's meta data tool tips. Q_UNUSED(e); QPainter painter(this); QColor toColor = palette().brush(QPalette::ToolTipBase).color(); QColor fromColor = KColorScheme::shade(toColor, KColorScheme::LightShade, 0.2); const bool haveAlphaChannel = KWindowSystem::compositingActive(); if (haveAlphaChannel) { painter.setRenderHint(QPainter::Antialiasing); painter.translate(0.5, 0.5); toColor.setAlpha(220); fromColor.setAlpha(220); } QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(0.0, height())); gradient.setColorAt(0.0, fromColor); gradient.setColorAt(1.0, toColor); painter.setPen(Qt::NoPen); painter.setBrush(gradient); const QRect rect(0, 0, width(), height()); if (haveAlphaChannel) { const qreal radius = 5.0; QPainterPath path; path.moveTo(rect.left(), rect.top() + radius); arc(path, rect.left() + radius, rect.top() + radius, radius, 180, -90); arc(path, rect.right() - radius, rect.top() + radius, radius, 90, -90); arc(path, rect.right() - radius, rect.bottom() - radius, radius, 0, -90); arc(path, rect.left() + radius, rect.bottom() - radius, radius, 270, -90); path.closeSubpath(); painter.drawPath(path); } else { painter.drawRect(rect); } } void Smb4KToolTip::arc(QPainterPath& path, qreal cx, qreal cy, qreal radius, qreal angle, qreal sweepLength) { // Copied from Dolphin's meta data tool tips. path.arcTo(cx-radius, cy-radius, radius * 2, radius * 2, angle, sweepLength); } void Smb4KToolTip::slotHideToolTip() { hide(); }