├── About.cpp ├── About.h ├── AddressBar.cpp ├── AddressBar.h ├── CometFTP.pro ├── CometFTP.pro.user ├── CometFTP.pro.user.3.2-pre1 ├── CometFTP.pro.user.35f3e9a ├── CustomFileModel.cpp ├── CustomFileModel.h ├── DownloadManager.cpp ├── DownloadManager.h ├── LocalExplorer.cpp ├── LocalExplorer.h ├── Main.css ├── MainWindow.cpp ├── MainWindow.h ├── Makefile ├── Makefile.Debug ├── Makefile.Release ├── NcFramelessHelper.h ├── NcFramlessHelper.cpp ├── README.md ├── SFTPSite.cpp ├── SFTPSite.h ├── Screenshots ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png └── 8.jpg ├── ServerBrowser.cpp ├── ServerBrowser.h ├── ServerExplorer.cpp ├── ServerExplorer.h ├── ServerFileModel.cpp ├── ServerFileModel.h ├── SlidingStackedWidget.cpp ├── SlidingStackedWidget.h ├── StatusArea.cpp ├── StatusArea.h ├── TODO.md ├── images ├── CometButton.png ├── CometButton.psd ├── ExitButton.png ├── ExitButton2.png ├── MaximiseGrey.png ├── MaximiseWhite.png ├── Maxmise.psd ├── Menu.svg ├── MinimiseGrey.png ├── MinimiseGrey.psd ├── MinimiseWhite.png ├── Screen.svg ├── Thumbs.db ├── arrow.jpg ├── arrow.png ├── arrow.psd ├── left37.svg ├── libssh-logo.png ├── menu.png ├── openssl-logo.png ├── pause15.svg ├── pausesmall.png ├── play43.svg ├── power26.svg ├── qt-logo.png ├── right33.svg ├── square64.svg └── stopsmall.png ├── main.cpp ├── object_script.CometFTP.Debug ├── object_script.CometFTP.Release └── resources.qrc /About.cpp: -------------------------------------------------------------------------------- 1 | #include "About.h" 2 | #include 3 | About::About(QWidget *parent) : 4 | QWidget(parent) 5 | { 6 | this->setFixedHeight(300); 7 | this->setFixedWidth(500); 8 | 9 | QHBoxLayout* mainLayout = new QHBoxLayout(this); 10 | QVBoxLayout* leftLayout = new QVBoxLayout(this); 11 | QVBoxLayout* rightLayout = new QVBoxLayout(this); 12 | QLabel* title = new QLabel("CometFTP 0.0.1"); 13 | QLabel* build = new QLabel("Built on Windows using MinGW 4.8"); 14 | QLabel* license = new QLabel("Licensed under GPL v3.0"); 15 | QLabel* thanks = new QLabel("Powered by Qt 5.2.0, Libssh and OpenSSL"); 16 | QLabel* icons = new QLabel("Some Icons licensed under CC by flaticon.com. Author: Appzgear"); 17 | QLabel* warranty = new QLabel("The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE."); 18 | warranty->setWordWrap(true); 19 | icons->setWordWrap(true); 20 | 21 | QImage qt = QImage(":/images/qt-logo.png"); 22 | QImage libssh = QImage(":/images/libssh-logo.png"); 23 | QImage openssl = QImage(":/images/openssl-logo.png"); 24 | 25 | 26 | 27 | QPixmap qtMap = QPixmap::fromImage(qt); 28 | QPixmap libsshMap = QPixmap::fromImage(libssh); 29 | QPixmap opensslMap = QPixmap::fromImage(openssl); 30 | 31 | qtMap = qtMap.scaledToWidth(50); 32 | libsshMap = libsshMap.scaledToWidth(100); 33 | opensslMap = opensslMap.scaledToWidth(100); 34 | 35 | QLabel* qtLbl = new QLabel(); 36 | QLabel* libsshLbl = new QLabel(); 37 | QLabel* opensslLbl = new QLabel(); 38 | 39 | qtLbl->setPixmap(qtMap); 40 | libsshLbl->setPixmap(libsshMap); 41 | opensslLbl->setPixmap(opensslMap); 42 | qtLbl->setFixedWidth(50); 43 | libsshLbl->setFixedWidth(100); 44 | opensslLbl->setFixedWidth(100); 45 | 46 | leftLayout->addWidget(qtLbl); 47 | leftLayout->addWidget(libsshLbl); 48 | leftLayout->addWidget(opensslLbl); 49 | 50 | rightLayout->addWidget(title); 51 | rightLayout->addWidget(build); 52 | rightLayout->addWidget(license); 53 | rightLayout->addWidget(icons); 54 | rightLayout->addWidget(thanks); 55 | rightLayout->addWidget(warranty); 56 | 57 | mainLayout->addLayout(leftLayout); 58 | mainLayout->addLayout(rightLayout); 59 | 60 | this->setLayout(mainLayout); 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /About.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_ABOUT_H 2 | #define COMET_ABOUT_H 3 | 4 | #include 5 | 6 | class About : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit About(QWidget *parent = 0); 11 | 12 | signals: 13 | 14 | public slots: 15 | 16 | }; 17 | 18 | #endif // COMET_ABOUT_H 19 | -------------------------------------------------------------------------------- /AddressBar.cpp: -------------------------------------------------------------------------------- 1 | #include "AddressBar.h" 2 | 3 | AddressBar::AddressBar(QWidget *parent, bool _disconnectVisible, QString _defaultPath) : 4 | QWidget(parent) 5 | { 6 | // Initial Setup 7 | this->setFixedHeight(24); 8 | disconnectVisible = _disconnectVisible; 9 | defaultPath = _defaultPath; 10 | setupView(); 11 | 12 | 13 | QObject::connect(backBtn, SIGNAL(clicked()),this, SLOT(backButtonClick())); 14 | QObject::connect(forwardBtn, SIGNAL(clicked()),this,SLOT(forwardButtonClick())); 15 | QObject::connect(addressEdit, SIGNAL(returnPressed()), this, SLOT(addressEditClick())); 16 | QObject::connect(disconnectBtn, SIGNAL(clicked()), this, SLOT(disconnectClicked())); 17 | } 18 | 19 | void AddressBar::setupView() 20 | { 21 | // Setup Widget Views 22 | QIcon backIcon = QIcon(":/images/left37.svg"); 23 | backBtn = new QPushButton(""); 24 | backBtn->setIcon(backIcon); 25 | 26 | QIcon forwardIcon = QIcon(":/images/right33.svg"); 27 | forwardBtn = new QPushButton(""); 28 | forwardBtn->setIcon(forwardIcon); 29 | 30 | QIcon disconnectIcon = QIcon(":/images/power26.svg"); 31 | disconnectBtn = new QPushButton(""); 32 | disconnectBtn->setIcon(disconnectIcon); 33 | disconnectBtn->setToolTip("Disconnect From Site"); 34 | 35 | addressEdit = new QLineEdit(); 36 | addressEdit->setStyle(QStyleFactory::create("Fusion")); 37 | addressEdit->setText(defaultPath); 38 | 39 | // Layout 40 | QHBoxLayout* mainLayout = new QHBoxLayout; 41 | mainLayout->setContentsMargins(0,0,0,0); 42 | mainLayout->addWidget(backBtn); 43 | mainLayout->addWidget(forwardBtn); 44 | mainLayout->addWidget(addressEdit); 45 | if (disconnectVisible){ 46 | mainLayout->addWidget(disconnectBtn); 47 | } 48 | this->setLayout(mainLayout); 49 | 50 | } 51 | 52 | void AddressBar::disconnectClicked() 53 | { 54 | emit disconnect(); 55 | } 56 | 57 | void AddressBar::updatePath(QString path) 58 | { 59 | // Add old path to back list 60 | backList << defaultPath; 61 | // Set new default path 62 | defaultPath = path; 63 | // Set Line Edit 64 | addressEdit->setText(path); 65 | } 66 | 67 | void AddressBar::backButtonClick() 68 | { 69 | qDebug() << "Back Button Clicked"; 70 | 71 | if (backList.count() >= 1){ 72 | // Add to forward 73 | forwardList << defaultPath; 74 | // Set New Default 75 | defaultPath = backList.last(); 76 | // Remove path from back 77 | backList.removeLast(); 78 | //set Line edit 79 | addressEdit->setText(defaultPath); 80 | 81 | emit updatedPath(defaultPath); 82 | 83 | } 84 | } 85 | 86 | void AddressBar::forwardButtonClick() 87 | { 88 | if (forwardList.count() >= 1){ 89 | backList << defaultPath; 90 | defaultPath = forwardList.last(); 91 | forwardList.removeLast(); 92 | addressEdit->setText(defaultPath); 93 | emit updatedPath(defaultPath); 94 | } 95 | } 96 | 97 | void AddressBar::addressEditClick() 98 | { 99 | if (disconnectVisible) { 100 | // SSH, send path 101 | /********************************/ 102 | emit updatedPath(addressEdit->text()); 103 | 104 | } else { 105 | QDir dir(addressEdit->text()); 106 | if (!dir.exists()){ 107 | // Does Not Exist 108 | qDebug() << "does not exist"; 109 | addressEdit->setText(defaultPath); 110 | // Do nothing 111 | } else { 112 | qDebug() << "adding default path " << defaultPath << " to list"; 113 | backList << defaultPath; 114 | qDebug() << "setting new path " <text(); 115 | defaultPath = addressEdit->text(); 116 | // Local, Send path 117 | emit updatedPath(addressEdit->text()); 118 | 119 | qDebug() << "backlist last " << backList.last(); 120 | 121 | } 122 | } 123 | 124 | } 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /AddressBar.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_ADDRESSBAR_H 2 | #define COMET_ADDRESSBAR_H 3 | 4 | #include 5 | #include 6 | class AddressBar : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit AddressBar(QWidget *parent = 0, 11 | bool _disconnectVisible = true, 12 | QString _defaultPath = ""); 13 | void updatePath(QString path); 14 | 15 | private: 16 | QPushButton* backBtn; 17 | QPushButton* forwardBtn; 18 | QLineEdit* addressEdit; 19 | QPushButton* disconnectBtn; 20 | QString defaultPath; 21 | QStringList backList; 22 | QStringList forwardList; 23 | void setupView(); 24 | bool disconnectVisible; 25 | 26 | 27 | 28 | signals: 29 | void updatedPath(QString path); 30 | void disconnect(); 31 | 32 | public slots: 33 | 34 | private slots: 35 | void backButtonClick(); 36 | void forwardButtonClick(); 37 | void addressEditClick(); 38 | void disconnectClicked(); 39 | 40 | }; 41 | 42 | #endif // COMET_ADDRESSBAR_H 43 | -------------------------------------------------------------------------------- /CometFTP.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-04-15T20:51:23 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = CometFTP 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | MainWindow.cpp \ 17 | SlidingStackedWidget.cpp \ 18 | NcFramlessHelper.cpp \ 19 | LocalExplorer.cpp \ 20 | StatusArea.cpp \ 21 | ServerExplorer.cpp \ 22 | SFTPSite.cpp \ 23 | ServerFileModel.cpp \ 24 | AddressBar.cpp \ 25 | DownloadManager.cpp \ 26 | CustomFileModel.cpp \ 27 | About.cpp 28 | 29 | HEADERS += \ 30 | MainWindow.h \ 31 | SlidingStackedWidget.h \ 32 | NcFramelessHelper.h \ 33 | LocalExplorer.h \ 34 | StatusArea.h \ 35 | ServerExplorer.h \ 36 | SFTPSite.h \ 37 | ServerFileModel.h \ 38 | AddressBar.h \ 39 | DownloadManager.h \ 40 | CustomFileModel.h \ 41 | About.h 42 | 43 | RESOURCES += resources.qrc 44 | 45 | CONFIG += c++11 46 | 47 | 48 | #win32: LIBS += -lssh 49 | #win32: LIBS += -llibeay32 50 | #win32: LIBS += -lssleay32 51 | -------------------------------------------------------------------------------- /CometFTP.pro.user.3.2-pre1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ProjectExplorer.Project.ActiveTarget 7 | 0 8 | 9 | 10 | ProjectExplorer.Project.EditorSettings 11 | 12 | true 13 | false 14 | true 15 | 16 | Cpp 17 | 18 | CppGlobal 19 | 20 | 21 | 22 | QmlJS 23 | 24 | QmlJSGlobal 25 | 26 | 27 | 2 28 | UTF-8 29 | false 30 | 4 31 | false 32 | true 33 | 1 34 | true 35 | 0 36 | true 37 | 0 38 | 8 39 | true 40 | 1 41 | true 42 | true 43 | true 44 | false 45 | 46 | 47 | 48 | ProjectExplorer.Project.PluginSettings 49 | 50 | 51 | 52 | ProjectExplorer.Project.Target.0 53 | 54 | Desktop Qt 5.2.0 MinGW 32bit 55 | Desktop Qt 5.2.0 MinGW 32bit 56 | qt.520.win32_mingw48.essentials_kit 57 | 1 58 | 0 59 | 0 60 | 61 | C:/Users/Shazib/Desktop/CometFTP/build-CometFTP-Desktop_Qt_5_2_0_MinGW_32bit-Debug 62 | 63 | 64 | true 65 | qmake 66 | 67 | QtProjectManager.QMakeBuildStep 68 | false 69 | true 70 | 71 | false 72 | 73 | 74 | true 75 | Make 76 | 77 | Qt4ProjectManager.MakeStep 78 | 79 | false 80 | 81 | 82 | 83 | 2 84 | Build 85 | 86 | ProjectExplorer.BuildSteps.Build 87 | 88 | 89 | 90 | true 91 | Make 92 | 93 | Qt4ProjectManager.MakeStep 94 | 95 | true 96 | clean 97 | 98 | 99 | 1 100 | Clean 101 | 102 | ProjectExplorer.BuildSteps.Clean 103 | 104 | 2 105 | false 106 | 107 | Debug 108 | 109 | Qt4ProjectManager.Qt4BuildConfiguration 110 | 2 111 | true 112 | 113 | 114 | C:/Users/Shazib/Desktop/CometFTP/build-CometFTP-Desktop_Qt_5_2_0_MinGW_32bit-Release 115 | 116 | 117 | true 118 | qmake 119 | 120 | QtProjectManager.QMakeBuildStep 121 | false 122 | true 123 | 124 | false 125 | 126 | 127 | true 128 | Make 129 | 130 | Qt4ProjectManager.MakeStep 131 | 132 | false 133 | 134 | 135 | 136 | 2 137 | Build 138 | 139 | ProjectExplorer.BuildSteps.Build 140 | 141 | 142 | 143 | true 144 | Make 145 | 146 | Qt4ProjectManager.MakeStep 147 | 148 | true 149 | clean 150 | 151 | 152 | 1 153 | Clean 154 | 155 | ProjectExplorer.BuildSteps.Clean 156 | 157 | 2 158 | false 159 | 160 | Release 161 | 162 | Qt4ProjectManager.Qt4BuildConfiguration 163 | 0 164 | true 165 | 166 | 2 167 | 168 | 169 | 0 170 | Deploy 171 | 172 | ProjectExplorer.BuildSteps.Deploy 173 | 174 | 1 175 | Deploy locally 176 | 177 | ProjectExplorer.DefaultDeployConfiguration 178 | 179 | 1 180 | 181 | 182 | 183 | false 184 | false 185 | false 186 | false 187 | true 188 | 0.01 189 | 10 190 | true 191 | 1 192 | 25 193 | 194 | 1 195 | true 196 | false 197 | true 198 | valgrind 199 | 200 | 0 201 | 1 202 | 2 203 | 3 204 | 4 205 | 5 206 | 6 207 | 7 208 | 8 209 | 9 210 | 10 211 | 11 212 | 12 213 | 13 214 | 14 215 | 216 | 2 217 | 218 | CometFTP 219 | 220 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Shazib/Desktop/CometFTP/CometFTP/CometFTP.pro 221 | 222 | CometFTP.pro 223 | false 224 | false 225 | 226 | 3768 227 | true 228 | false 229 | false 230 | false 231 | true 232 | 233 | 1 234 | 235 | 236 | 237 | ProjectExplorer.Project.TargetCount 238 | 1 239 | 240 | 241 | ProjectExplorer.Project.Updater.EnvironmentId 242 | {35f3e9a5-5cf7-47ef-9a87-77c42bf746e5} 243 | 244 | 245 | ProjectExplorer.Project.Updater.FileVersion 246 | 15 247 | 248 | 249 | -------------------------------------------------------------------------------- /CometFTP.pro.user.35f3e9a: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ProjectExplorer.Project.ActiveTarget 7 | 0 8 | 9 | 10 | ProjectExplorer.Project.EditorSettings 11 | 12 | true 13 | false 14 | true 15 | 16 | Cpp 17 | 18 | CppGlobal 19 | 20 | 21 | 22 | QmlJS 23 | 24 | QmlJSGlobal 25 | 26 | 27 | 2 28 | UTF-8 29 | false 30 | 4 31 | false 32 | true 33 | 1 34 | true 35 | 0 36 | true 37 | 0 38 | 8 39 | true 40 | 1 41 | true 42 | true 43 | true 44 | false 45 | 46 | 47 | 48 | ProjectExplorer.Project.PluginSettings 49 | 50 | 51 | 52 | ProjectExplorer.Project.Target.0 53 | 54 | Desktop Qt 5.2.0 MinGW 32bit 55 | Desktop Qt 5.2.0 MinGW 32bit 56 | qt.520.win32_mingw48.essentials_kit 57 | 0 58 | 0 59 | 0 60 | 61 | C:/Users/Shazib/Desktop/CometFTP/build-CometFTP-Desktop_Qt_5_2_0_MinGW_32bit-Debug 62 | 63 | 64 | true 65 | qmake 66 | 67 | QtProjectManager.QMakeBuildStep 68 | false 69 | true 70 | 71 | false 72 | 73 | 74 | true 75 | Make 76 | 77 | Qt4ProjectManager.MakeStep 78 | 79 | false 80 | 81 | 82 | 83 | 2 84 | Build 85 | 86 | ProjectExplorer.BuildSteps.Build 87 | 88 | 89 | 90 | true 91 | Make 92 | 93 | Qt4ProjectManager.MakeStep 94 | 95 | true 96 | clean 97 | 98 | 99 | 1 100 | Clean 101 | 102 | ProjectExplorer.BuildSteps.Clean 103 | 104 | 2 105 | false 106 | 107 | Debug 108 | 109 | Qt4ProjectManager.Qt4BuildConfiguration 110 | 2 111 | true 112 | 113 | 114 | C:/Users/Shazib/Desktop/CometFTP/build-CometFTP-Desktop_Qt_5_2_0_MinGW_32bit-Release 115 | 116 | 117 | true 118 | qmake 119 | 120 | QtProjectManager.QMakeBuildStep 121 | false 122 | true 123 | 124 | false 125 | 126 | 127 | true 128 | Make 129 | 130 | Qt4ProjectManager.MakeStep 131 | 132 | false 133 | 134 | 135 | 136 | 2 137 | Build 138 | 139 | ProjectExplorer.BuildSteps.Build 140 | 141 | 142 | 143 | true 144 | Make 145 | 146 | Qt4ProjectManager.MakeStep 147 | 148 | true 149 | clean 150 | 151 | 152 | 1 153 | Clean 154 | 155 | ProjectExplorer.BuildSteps.Clean 156 | 157 | 2 158 | false 159 | 160 | Release 161 | 162 | Qt4ProjectManager.Qt4BuildConfiguration 163 | 0 164 | true 165 | 166 | 2 167 | 168 | 169 | 0 170 | Deploy 171 | 172 | ProjectExplorer.BuildSteps.Deploy 173 | 174 | 1 175 | Deploy locally 176 | 177 | ProjectExplorer.DefaultDeployConfiguration 178 | 179 | 1 180 | 181 | 182 | 183 | false 184 | false 185 | false 186 | false 187 | true 188 | 0.01 189 | 10 190 | true 191 | 1 192 | 25 193 | 194 | 1 195 | true 196 | false 197 | true 198 | valgrind 199 | 200 | 0 201 | 1 202 | 2 203 | 3 204 | 4 205 | 5 206 | 6 207 | 7 208 | 8 209 | 9 210 | 10 211 | 11 212 | 12 213 | 13 214 | 14 215 | 216 | 2 217 | 218 | CometFTP 219 | 220 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Shazib/Desktop/CometFTP/CometFTP/CometFTP.pro 221 | 222 | CometFTP.pro 223 | false 224 | false 225 | 226 | 3768 227 | true 228 | false 229 | false 230 | false 231 | true 232 | 233 | 1 234 | 235 | 236 | 237 | ProjectExplorer.Project.TargetCount 238 | 1 239 | 240 | 241 | ProjectExplorer.Project.Updater.EnvironmentId 242 | {35f3e9a5-5cf7-47ef-9a87-77c42bf746e5} 243 | 244 | 245 | ProjectExplorer.Project.Updater.FileVersion 246 | 15 247 | 248 | 249 | -------------------------------------------------------------------------------- /CustomFileModel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This Class is a reimplementation of QFileSystemModel. 3 | * The default class provides all required functionality by default, and as such, 4 | * handles drop events internally. 5 | * 6 | * Files draged from the server technically do not exist on the local system 7 | * The default model does not know how to handle the custom mime type 8 | * It does not need to try and move/copy the files 9 | * It just needs to send the data to the downloader class to add to the queue. 10 | */ 11 | #include "CustomFileModel.h" 12 | 13 | CustomFileModel::CustomFileModel(QObject *parent) : 14 | QFileSystemModel(parent) 15 | { 16 | 17 | 18 | } 19 | // Returns the mime types that this class supports for drops 20 | QStringList CustomFileModel::mimeTypes() const 21 | { 22 | QStringList Temp = QStringList(QLatin1String("text/uri-list")); 23 | Temp << "text/comet-upload-download"; 24 | 25 | return Temp; 26 | } 27 | 28 | // Called when data is dropped 29 | bool CustomFileModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 30 | { 31 | if(data->data("text/comet-upload-download").count() > 0) { 32 | qDebug() << "Comet file"; 33 | // Emit the signal 34 | emit sendDropData("Download",QString(data->data("text/comet-upload-download")),filePath(parent),data->text()); 35 | return true; 36 | } else { 37 | 38 | 39 | 40 | // The Default Implementation from QFileSystemModel.cpp for copying normal mime types. 41 | Q_UNUSED(row); 42 | Q_UNUSED(column); 43 | if (!parent.isValid() || isReadOnly()) 44 | return false; 45 | 46 | bool success = true; 47 | QString to = filePath(parent) + QDir::separator(); 48 | 49 | QList urls = data->urls(); 50 | QList::const_iterator it = urls.constBegin(); 51 | 52 | switch (action) { 53 | case Qt::CopyAction: 54 | for (; it != urls.constEnd(); ++it) { 55 | QString path = (*it).toLocalFile(); 56 | success = QFile::copy(path, to + QFileInfo(path).fileName()) && success; 57 | } 58 | break; 59 | case Qt::LinkAction: 60 | for (; it != urls.constEnd(); ++it) { 61 | QString path = (*it).toLocalFile(); 62 | success = QFile::link(path, to + QFileInfo(path).fileName()) && success; 63 | } 64 | break; 65 | case Qt::MoveAction: 66 | for (; it != urls.constEnd(); ++it) { 67 | QString path = (*it).toLocalFile(); 68 | success = QFile::copy(path, to + QFileInfo(path).fileName()) 69 | && QFile::remove(path) && success; 70 | } 71 | break; 72 | default: 73 | return false; 74 | } 75 | return success; 76 | } 77 | 78 | } 79 | 80 | Qt::DropActions CustomFileModel::supportedDropActions() const 81 | { 82 | return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /CustomFileModel.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_CUSTOMFILEMODEL_H 2 | #define COMET_CUSTOMFILEMODEL_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | class CustomFileModel : public QFileSystemModel 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit CustomFileModel(QObject *parent = 0); 13 | 14 | // The only methods that needs reimplementing 15 | bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); 16 | QStringList mimeTypes() const; 17 | 18 | Qt::DropActions supportedDropActions() const; 19 | signals: 20 | void sendDropData(QString type, QString source, QString destination,QString sftpType); 21 | 22 | public slots: 23 | 24 | protected: 25 | }; 26 | 27 | #endif // COMET_CUSTOMFILEMODEL_H 28 | -------------------------------------------------------------------------------- /DownloadManager.cpp: -------------------------------------------------------------------------------- 1 | #include "DownloadManager.h" 2 | 3 | DownloadManager::DownloadManager(QWidget *parent) : 4 | QWidget(parent) 5 | { 6 | // Setup View + initial states 7 | QHBoxLayout* mainLayout = new QHBoxLayout(this); 8 | 9 | // Setup table widget 10 | table = new QTableWidget(); 11 | table->horizontalHeader()->setVisible(true); 12 | table->horizontalHeader()->show(); 13 | table->setSelectionBehavior(QAbstractItemView::SelectRows); 14 | table->setSelectionMode(QAbstractItemView::SingleSelection); 15 | table->setShowGrid(false); 16 | table->setAlternatingRowColors(true); 17 | table->setStyle(QStyleFactory::create("Fusion")); 18 | table->setObjectName("ServerTableView"); 19 | table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); 20 | table->verticalHeader()->setDefaultSectionSize(18); 21 | 22 | mainLayout->addWidget(table); 23 | this->setLayout(mainLayout); 24 | numRows = 0; 25 | table->setColumnCount(4); 26 | table->setRowCount(numRows); 27 | 28 | // Thread + queue management 29 | percentage = 0; 30 | fileCounter = 0; 31 | downloading = false; 32 | isAlive = false; 33 | 34 | 35 | qRegisterMetaType("std::string"); 36 | } 37 | 38 | void DownloadManager::addData(QString _type, 39 | QString _source, 40 | QString _destination, 41 | QString sftpType){ 42 | 43 | 44 | // The manager must check if folders are added. 45 | // Add data to model 46 | 47 | destination = _destination ; 48 | 49 | // If Upload 50 | if (_type == "Upload") 51 | { 52 | // Lets check if its a folder 53 | QFileInfo info(_source); 54 | if (info.isDir()){ 55 | // Get every individual file 56 | addLocalFolder(info.absoluteFilePath()); 57 | 58 | } else { 59 | numRows++; 60 | table->setRowCount(numRows); 61 | QTableWidgetItem* typeItem = new QTableWidgetItem(_type,1); 62 | QTableWidgetItem* sourceItem = new QTableWidgetItem(_source,2); 63 | QTableWidgetItem* destinationItem = new QTableWidgetItem(_destination,3); 64 | QTableWidgetItem* statusItem = new QTableWidgetItem("Pending",3); 65 | table->setItem((numRows-1),0,typeItem); 66 | table->setItem((numRows-1),1,sourceItem); 67 | table->setItem((numRows-1),2,destinationItem); 68 | table->setItem((numRows-1),3,statusItem); 69 | } 70 | 71 | } 72 | 73 | // If Download 74 | if (_type == "Download"){ 75 | if (sftpType == "Folder"){ 76 | // Now get all values; 77 | addServerFolder(_source,(_destination+"/")); 78 | } 79 | else { 80 | numRows++; 81 | table->setRowCount(numRows); 82 | QTableWidgetItem* typeItem = new QTableWidgetItem(_type,1); 83 | QTableWidgetItem* sourceItem = new QTableWidgetItem(_source,2); 84 | QTableWidgetItem* destinationItem = new QTableWidgetItem(_destination,3); 85 | QTableWidgetItem* statusItem = new QTableWidgetItem("Pending",3); 86 | table->setItem((numRows-1),0,typeItem); 87 | table->setItem((numRows-1),1,sourceItem); 88 | table->setItem((numRows-1),2,destinationItem); 89 | table->setItem((numRows-1),3,statusItem); 90 | } 91 | } 92 | // When Data is added, the queue is automatically processed. 93 | // The site will respond with a success or failure case and the queue will continue to process. 94 | 95 | if (!isAlive) { 96 | // Create thread 97 | sftp = new SFTPSite(); 98 | thread = new QThread(); 99 | sftp->moveToThread(thread); 100 | QObject::connect(this,SIGNAL(initThread(std::string,std::string,std::string,std::string)),sftp,SLOT(threadInit(std::string,std::string,std::string,std::string))); 101 | thread->start(); 102 | emit initThread(host,user,password,port); 103 | QObject::connect(this,SIGNAL(startDownload(QString,QString)),sftp,SLOT(startDownload(QString,QString))); 104 | QObject::connect(this,SIGNAL(startUpload(QString,QString)),sftp,SLOT(startUpload(QString,QString))); 105 | QObject::connect(sftp,SIGNAL(updateProgress()),this,SLOT(receivePercentage())); 106 | QObject::connect(sftp,SIGNAL(downloadComplete(int)), this,SLOT(receiveDownloadComplete(int))); 107 | QObject::connect(this,SIGNAL(sendCancelClick()),sftp,SLOT(cancelDownload()),Qt::DirectConnection); 108 | QObject::connect(this,SIGNAL(sendPauseClick()),sftp,SLOT(pauseDownload()), Qt::DirectConnection); 109 | QObject::connect(sftp,SIGNAL(sendSpeed(int)),this,SLOT(receiveSpeed(int))); 110 | isAlive = true; 111 | } 112 | // Start Queue 113 | if (!downloading){ 114 | // Start queue 115 | // Get data 116 | QString _type = table->item(fileCounter,0)->text(); 117 | QString _source = table->item(fileCounter,1)->text(); 118 | QString _destination = table->item(fileCounter,2)->text(); 119 | // If download 120 | if (_type == "Download"){ 121 | table->item(fileCounter,3)->setText("Processing"); 122 | qDebug() << "Starting Download"; 123 | emit startDownload(_source, _destination); 124 | downloading = true; 125 | emit setFileName(_source); 126 | 127 | qDebug() << "num rows - filecounter" << (numRows - fileCounter); 128 | } 129 | if (_type == "Upload"){ 130 | table->item(fileCounter,3)->setText("Processing"); 131 | qDebug() << "Starting Upload"; 132 | emit startUpload(_source, _destination); 133 | downloading = true; 134 | emit setFileName(_source); 135 | 136 | qDebug() << "num rows - filecounter" << (numRows - fileCounter); 137 | } 138 | 139 | } 140 | emit setNumFiles(numRows - fileCounter); 141 | } 142 | 143 | void DownloadManager::addLocalFolder(QString path) 144 | { 145 | //qDebug() << "add folder"; 146 | // qDebug() << "root folder" << path; 147 | QDir dir(path); 148 | // Get everything in directory 149 | QFileInfoList list = dir.entryInfoList(); 150 | 151 | // For each file/folder 152 | for (int i = 2; i < list.size(); i++){ 153 | 154 | // If is file 155 | if (list.at(i).isFile()){ 156 | QFileInfo info = list.at(i); 157 | //qDebug() << list.at(i).absoluteFilePath(); 158 | //qDebug() << destination; 159 | numRows++; 160 | table->setRowCount(numRows); 161 | QTableWidgetItem* typeItem = new QTableWidgetItem("Upload",1); 162 | QTableWidgetItem* sourceItem = new QTableWidgetItem(list.at(i).absoluteFilePath(),2); 163 | QTableWidgetItem* destinationItem = new QTableWidgetItem(destination,3); 164 | QTableWidgetItem* statusItem = new QTableWidgetItem("Pending",3); 165 | table->setItem((numRows-1),0,typeItem); 166 | table->setItem((numRows-1),1,sourceItem); 167 | table->setItem((numRows-1),2,destinationItem); 168 | table->setItem((numRows-1),3,statusItem); 169 | // If is dir 170 | } else if (list.at(i).isDir()){ 171 | // Recursive call 172 | list.at(i).fileName(); 173 | destinationTemp = list.at(i).fileName() + "/"; 174 | destination = destination + destinationTemp;// + "/"; 175 | addLocalFolder(list.at(i).absoluteFilePath()); 176 | 177 | 178 | } 179 | 180 | } 181 | // Reset Destination folder for parent 182 | destination.remove((destination.count()-destinationTemp.count()-1),destinationTemp.count()); 183 | //destination.remove(destination.count()-1,1); 184 | destinationTemp = ""; 185 | 186 | } 187 | 188 | void DownloadManager::addServerFolder(QString path, QString destination) 189 | { 190 | site = new SFTPSite(this, host, user, password, port); 191 | 192 | if( !site->silent_init()) { 193 | // ERROR 194 | } else { 195 | // Get all files 196 | QString dest = path + "/"; 197 | QStringList values = site->getAllFiles(dest,destination); 198 | int a = values.count(); 199 | while (a != 0){ 200 | 201 | qDebug() << values.count(); 202 | numRows++; 203 | table->setRowCount(numRows); 204 | QTableWidgetItem* typeItem = new QTableWidgetItem("Download",1); 205 | QTableWidgetItem* sourceItem = new QTableWidgetItem(values.first(),2); 206 | values.removeFirst(); 207 | a--; 208 | QTableWidgetItem* destinationItem = new QTableWidgetItem(values.first(),3); 209 | values.removeFirst(); 210 | a--; 211 | QTableWidgetItem* statusItem = new QTableWidgetItem("Pending",4); 212 | table->setItem((numRows-1),0,typeItem); 213 | table->setItem((numRows-1),1,sourceItem); 214 | table->setItem((numRows-1),2,destinationItem); 215 | table->setItem((numRows-1),3,statusItem); 216 | 217 | } 218 | 219 | 220 | } 221 | } 222 | 223 | void DownloadManager::receiveCredentials(std::string _host, std::string _user, std::string _password, std::string _port){ 224 | 225 | host = _host; 226 | user = _user; 227 | password = _password; 228 | port = _port; 229 | } 230 | 231 | void DownloadManager::receiveDownloadComplete(int a){ 232 | 233 | if ( a == DLOAD_CANCEL) { 234 | table->item(fileCounter,3)->setText("Cancelled"); 235 | } 236 | 237 | percentage = 0; 238 | emit setProgress(0); 239 | 240 | // A Download just completed. 241 | table->item(fileCounter,3)->setText("Complete"); 242 | fileCounter++; 243 | if (fileCounter > numRows-1){ 244 | // Set Value in table 245 | 246 | downloading = false; 247 | emit setNumFiles(0); 248 | return; 249 | 250 | } 251 | // Otherwise 252 | QString _type = table->item(fileCounter,0)->text(); 253 | QString _source = table->item(fileCounter,1)->text(); 254 | QString _destination = table->item(fileCounter,2)->text(); 255 | table->item(fileCounter,3)->setText("Processing"); 256 | 257 | if (_type == "Download"){ 258 | emit startDownload(_source,_destination); 259 | } else if (_type == "Upload"){ 260 | emit startUpload(_source,_destination); 261 | } 262 | emit setNumFiles(numRows - fileCounter); 263 | emit setFileName(_source); 264 | 265 | 266 | 267 | } 268 | 269 | void DownloadManager::receivePercentage() 270 | { 271 | percentage++; 272 | emit setProgress(percentage); 273 | 274 | } 275 | 276 | void DownloadManager::receiveCancelClick() 277 | { 278 | emit setProgress(0); 279 | //usleep(10); 280 | emit setSpeed(" "); 281 | // usleep(10); 282 | emit sendCancelClick(); 283 | 284 | 285 | } 286 | 287 | void DownloadManager::receivePauseClick() 288 | { 289 | emit sendPauseClick(); 290 | } 291 | 292 | void DownloadManager::receiveSpeed(int bytes) 293 | { 294 | int bytesPerSecond = bytes / 5; 295 | int speedInKb = bytesPerSecond / 1024; 296 | emit setSpeed(QString::number(speedInKb)); 297 | } 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | -------------------------------------------------------------------------------- /DownloadManager.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_DOWNLOADMANAGER_H 2 | #define COMET_DOWNLOADMANAGER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "SFTPSite.h" 8 | class DownloadManager : public QWidget 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit DownloadManager(QWidget *parent = 0); 13 | void getDataFromParent(QStringList data); 14 | void setCredentials(QStringList credentials); 15 | 16 | signals: 17 | //void downloadFinished(int a); 18 | void initThread(std::string host, std::string user, std::string pass, std::string port); 19 | void startDownload(QString source, QString destination); 20 | void startUpload(QString source, QString destination); 21 | 22 | // Status Area Updating 23 | void setProgress(int progress); 24 | void setFileName(QString fileName); 25 | void setNumFiles(int numFiles); 26 | void sendPauseClick(); 27 | void sendCancelClick(); 28 | void setSpeed(QString speed); 29 | 30 | private: 31 | std::string host, user, password, port; 32 | QTableWidget* table; 33 | QStringList queue; 34 | SFTPSite* sftp; 35 | SFTPSite* site; 36 | QThread* thread; 37 | int numRows; 38 | QString destination; 39 | QString destinationTemp; 40 | bool downloading; 41 | bool isAlive; 42 | int percentage; 43 | int fileCounter; 44 | 45 | enum returnCodes { 46 | DLOAD_FILE_EXISTS, 47 | DLOAD_COMPLETE, 48 | DLOAD_FAILED, 49 | DLOAD_OVERWRITE, 50 | DLOAD_CANCEL, 51 | DLOAD_ERROR 52 | }; 53 | public slots: 54 | // Thread slots 55 | void receivePercentage(); 56 | void receiveDownloadComplete(int a); 57 | void receiveCancelClick(); 58 | void receivePauseClick(); 59 | void receiveSpeed(int bytes); 60 | 61 | void addData(QString _type, QString _source, QString _destination, QString sftpType); 62 | void addLocalFolder(QString path); 63 | void addServerFolder(QString path, QString destination); 64 | void receiveCredentials(std::string _host, std::string _user, std::string _password, std::string _port); 65 | 66 | }; 67 | 68 | #endif // COMET_DOWNLOADMANAGER_H 69 | -------------------------------------------------------------------------------- /LocalExplorer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This class represents a tree view of the local file system 3 | * It is a single widget which encompasses an address bar and the treeview 4 | * 5 | * A table is setup with a model of the local file system. Directory changes are handled by 6 | * implementing the doubleclick event on a row. There is also an addressBar object, 7 | * of the AddressBar class 8 | * This object communicates with the table+model to point out back/forward presses, and 9 | * address edit area updates. 10 | * 11 | * The class always stores a string of the current directory to be used when communicating 12 | * to the address bar 13 | */ 14 | 15 | #include "LocalExplorer.h" 16 | 17 | #include 18 | 19 | LocalExplorer::LocalExplorer(QWidget* parent) : 20 | QWidget(parent) 21 | { 22 | 23 | // Setup Directory 24 | // File System Model 25 | model = new CustomFileModel(); 26 | model->setReadOnly(false); 27 | model->setRootPath(QDir::rootPath()); 28 | QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString,QString))); 29 | 30 | // Setup The View 31 | table = new QTableView(); 32 | //table->setStyle(QStyleFactory::create("Fusion")); 33 | table->setModel(model); 34 | table->verticalHeader()->hide(); 35 | table->horizontalHeader()->setVisible(true); 36 | table->horizontalHeader()->show(); 37 | table->setSelectionBehavior(QAbstractItemView::SelectRows); 38 | table->setSelectionMode(QAbstractItemView::SingleSelection); 39 | table->setShowGrid(false); 40 | table->setAlternatingRowColors(true); 41 | table->setObjectName("ServerTableView"); 42 | table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); 43 | table->verticalHeader()->setDefaultSectionSize(18); 44 | table->resizeColumnsToContents(); 45 | QHeaderView* header = table->horizontalHeader(); 46 | header->setResizeContentsPrecision(99); 47 | table->setHorizontalHeader(header); 48 | 49 | // Enabling Drag Drop on Table 50 | table->setDragDropMode(QAbstractItemView::DragDrop); 51 | table->setSortingEnabled(true); 52 | 53 | // Setup Address Bar 54 | addressBar = new AddressBar(0,false,QString::fromStdString( QDir::rootPath().toStdString())); 55 | QObject::connect(addressBar, SIGNAL(updatedPath(QString)), SLOT(updatedPath(QString))); 56 | 57 | // Layout 58 | QVBoxLayout* layout = new QVBoxLayout(); 59 | layout->addWidget(addressBar); 60 | layout->addWidget(table); 61 | layout->setContentsMargins(0,0,0,0); 62 | layout->setSpacing(0); 63 | this->setLayout(layout); 64 | 65 | // Connect Table Click event 66 | QObject::connect(table,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(rowSelected(QModelIndex))); 67 | 68 | 69 | 70 | } 71 | 72 | // This method checks if what was entered into the addresbar is valid 73 | // If it is valid then this is submitted to the table 74 | // If it is not valid, the existing (valid) path is reset on the address bar text edit 75 | void LocalExplorer::updatedPath(QString path) 76 | { 77 | // QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString))); 78 | 79 | QDir* dir = new QDir(path); 80 | if (dir->exists()){ 81 | table->setRootIndex(model->setRootPath(path)); 82 | table->resizeColumnsToContents(); 83 | mainDir = path; 84 | qDebug() << path; 85 | } 86 | else{ 87 | addressBar->updatePath(mainDir); 88 | } 89 | 90 | } 91 | 92 | // Row Selected update Path 93 | // Handle Clicks on folders in table 94 | void LocalExplorer::rowSelected(const QModelIndex indx) { 95 | 96 | // QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString))); 97 | // Get File Info 98 | QFileInfo info = model->fileInfo(indx); 99 | // Check if folder 100 | if (info.isDir()){ 101 | // Reset Model 102 | table->setRootIndex(model->setRootPath(info.filePath())); 103 | table->resizeColumnsToContents(); 104 | // Update AddressBar 105 | addressBar->updatePath(info.filePath()); 106 | mainDir = info.filePath(); 107 | 108 | } 109 | 110 | } 111 | void LocalExplorer::receiveDropData(QString type, QString source, QString destination,QString sftpType) 112 | { 113 | // Send Data To Parent 114 | qDebug() << "Data recieved"; 115 | emit sendDropData(type,source,destination,sftpType); 116 | } 117 | 118 | -------------------------------------------------------------------------------- /LocalExplorer.h: -------------------------------------------------------------------------------- 1 | #ifndef COMER_LOCALEXPLORER_H 2 | #define COMET_LOCALEXPLORER_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | // Custom Classes 9 | #include "AddressBar.h" 10 | #include "CustomFileModel.h" 11 | 12 | class LocalExplorer : public QWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit LocalExplorer(QWidget* parent = 0); 17 | QTableView* table; 18 | 19 | private: 20 | CustomFileModel* model; // Custom Class 21 | AddressBar* addressBar; 22 | QString mainDir; 23 | 24 | signals: 25 | void sendDropData(QString type, QString source, QString desination, QString sftpType); 26 | 27 | public slots: 28 | 29 | protected: 30 | 31 | private slots: 32 | void updatedPath(QString Path); 33 | void rowSelected(const QModelIndex indx); 34 | void receiveDropData(QString type, QString source, QString destination,QString sftpType); 35 | 36 | 37 | 38 | }; 39 | 40 | #endif // COMET_LOCALEXPLORER_H 41 | -------------------------------------------------------------------------------- /Main.css: -------------------------------------------------------------------------------- 1 | MainWindow{ 2 | padding:0px; 3 | background-color: #fefefe; 4 | border-style:solid; 5 | border-color:#bbbbbb; 6 | border-width:1px; 7 | } 8 | 9 | #btnQuit{ 10 | background-image:url(:/images/ExitButton.png); 11 | border-style:none; 12 | width:30px; 13 | height:26px 14 | } 15 | 16 | #btnQuit:hover{ 17 | background-color:#e04343; 18 | background-image:url(:/images/ExitButton2.png); 19 | } 20 | 21 | #btnMin{ 22 | background-image:url(:/images/MinimiseGrey.png); 23 | border-style:none; 24 | width:30px; 25 | height:26px; 26 | } 27 | 28 | #btnMin:hover{ 29 | background-color:#cccccc; 30 | background-image:url(:/images/MinimiseWhite.png); 31 | } 32 | 33 | #btnMax{ 34 | background-image:url(:/images/MaximiseGrey.png); 35 | border-style:none; 36 | width:30px; 37 | height:26px; 38 | } 39 | 40 | #btnMax:hover{ 41 | background-color:#cccccc; 42 | background-image:url(:/images/MaximiseWhite.png); 43 | } 44 | 45 | #btnMenu{ 46 | background-image:url(:/images/CometButton.png); 47 | border-style:none; 48 | width:102px; 49 | height:27px; 50 | } 51 | 52 | StatusArea{ 53 | background-color:#ebebeb; 54 | border:1px solid #cdcdcd; 55 | border-radius:1px; 56 | } 57 | 58 | StatusArea QLabel, StatusArea QPushButton{ 59 | background-color: #ebebeb; 60 | } 61 | 62 | #Status_CancelButton{ 63 | border-style:none; 64 | background-color:#ebebeb; 65 | color:red; 66 | background-image:url(:/images/stopsmall.png); 67 | background-position: bottom left; 68 | background-repeat:no-repeat; 69 | padding:1px; 70 | } 71 | 72 | #Status_PauseButton{ 73 | background-color:#FFFFFF; 74 | background-image:url(:/images/pausesmall.png) 75 | } 76 | 77 | #Status_PauseButton{ 78 | border-style:none; 79 | background-color:#ebebeb; 80 | margin:0px 0px 0px 0px; 81 | color:red; 82 | background-image:url(:/images/pausesmall.png); 83 | background-position: bottom left; 84 | background-repeat:no-repeat; 85 | } 86 | 87 | #Status_Progress{ 88 | border: 1px solid #cdcdcd; 89 | border-radius: 6px; 90 | background: white; 91 | padding:1px; 92 | } 93 | 94 | #Status_Progress::chunk:horizontal{ 95 | margin-left:1px; 96 | border:1px solid #0E7DFD; 97 | border-radius:4px; 98 | background: #0E7DFD; 99 | } 100 | 101 | #Status_NumberFiles{ 102 | background:gray; 103 | border-radius:10px; 104 | padding: 4px 4px 4px; 105 | margin-left:15px; 106 | margin-top: 5px; 107 | font-weight:bold; 108 | color:white; 109 | } 110 | 111 | #Server_Widget{ 112 | background-color:#ebebeb; 113 | } 114 | 115 | ServerExplorer{ 116 | background-color:#ebebeb; 117 | } 118 | 119 | #ServerTableView{ 120 | gridline-color:none; 121 | alternate-background-color:#efefef; 122 | background-color:#ffffff; 123 | border:1px solid #efefef; 124 | } 125 | 126 | AddressBar QPushButton{ 127 | background-color:none; 128 | border:none; 129 | 130 | } 131 | -------------------------------------------------------------------------------- /MainWindow.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the main class for the application 3 | * It contains all other widgets and manages them 4 | */ 5 | 6 | #include "MainWindow.h" 7 | 8 | #include 9 | 10 | 11 | MainWindow::MainWindow(QFrame *parent) 12 | : QFrame(parent) 13 | { 14 | // Initial Setup 15 | max = false; 16 | switched = false; 17 | 18 | // this->setGeometry( 0, 0, 900,500); 19 | 20 | //QFrame::frameShape(); 21 | 22 | auto shape = QFrame::frameShape(); 23 | 24 | //QWidget::setGeometry( 1, 1, 1,1 ); 25 | 26 | move(QApplication::desktop()->availableGeometry(this).center() - rect().center()); 27 | int _min=500; 28 | int _max=1500; 29 | animTime=(_min+_max)>>1; 30 | 31 | // Load GUI 32 | createGuiComponents(); 33 | createMainLayout(); 34 | 35 | // Load Slots 36 | QObject::connect(btnQuit, SIGNAL(clicked()), this, SLOT(close())); 37 | QObject::connect(btnMax, SIGNAL(clicked()), this, SLOT(maxSize())); 38 | QObject::connect(btnMin, SIGNAL(clicked()), this, SLOT(showMinimized())); 39 | QObject::connect(btnMenu, SIGNAL(clicked()), this, SLOT(aboutClick())); 40 | 41 | 42 | 43 | 44 | } 45 | // Setup main GUI components 46 | void MainWindow::createGuiComponents() 47 | { 48 | 49 | // Taskbar Buttons 50 | btnQuit = new QPushButton( QString(""),(QWidget*)this); 51 | btnMin = new QPushButton("", this); 52 | btnMax = new QPushButton("",this); 53 | btnMenu = new QPushButton("", this); 54 | btnMenu->setContentsMargins(QMargins(10,0,0,0)); 55 | 56 | // Button Naming 57 | btnQuit->setObjectName("btnQuit"); 58 | btnMin->setObjectName("btnMin"); 59 | btnMax->setObjectName("btnMax"); 60 | btnMenu->setObjectName("btnMenu"); 61 | 62 | // Button Sizes 63 | btnQuit->setMaximumSize(30,26); 64 | btnMax->setMinimumSize(30,26); 65 | btnMin->setMaximumSize(30,26); 66 | btnMenu->setMaximumSize(103,27); 67 | 68 | } 69 | 70 | // Create the main layout 71 | void MainWindow::createMainLayout() 72 | { 73 | 74 | // Setup Layouts 75 | mainLayout = new QVBoxLayout(); 76 | topLayout = new QHBoxLayout(); 77 | topLeftLayout = new QHBoxLayout(); 78 | topMiddleLayout = new QHBoxLayout(); 79 | topRightLayout = new QHBoxLayout(); 80 | 81 | 82 | // Create Top Layout 83 | // Adding Buttons to Layout 84 | topRightLayout->addWidget(btnMin); 85 | topRightLayout->addWidget(btnMax); 86 | topRightLayout->addWidget(btnQuit); 87 | topLeftLayout->addWidget(btnMenu); 88 | 89 | // Layout spacing 90 | topRightLayout->setContentsMargins(QMargins(0,0,0,0)); 91 | topRightLayout->setSpacing(0); 92 | topRightLayout->setAlignment(Qt::AlignRight|Qt::AlignTop); 93 | topLeftLayout->setContentsMargins(QMargins(10,0,0,0)); 94 | topLeftLayout->setSpacing(0); 95 | topLeftLayout->setAlignment(Qt::AlignTop); 96 | topLayout->setSpacing(0); 97 | topLayout->setAlignment(Qt::AlignTop); 98 | topLayout->setContentsMargins(QMargins(-1,-1,-1,0)); 99 | 100 | // Setup Status Area 101 | statusArea = new StatusArea(this); 102 | topMiddleLayout->addWidget(statusArea); 103 | topMiddleLayout->setContentsMargins(4,4,4,0); 104 | 105 | topLayout->addLayout(topLeftLayout); 106 | topLayout->addLayout(topMiddleLayout); 107 | topLayout->addLayout(topRightLayout); 108 | topLayout->setMargin(0); 109 | 110 | 111 | // Create Bottom Layout 112 | // Layouts 113 | bottomLeftLayout = new QHBoxLayout(); 114 | bottomRightLayout = new QHBoxLayout(); 115 | bottomLayout = new QHBoxLayout(); 116 | 117 | // Setup Required Widgets 118 | localExplorer = new LocalExplorer(); 119 | serverExplorer = new ServerExplorer(); 120 | QObject::connect(serverExplorer,SIGNAL(sendCredentials(std::string,std::string,std::string,std::string)),this,SLOT(recieveCredentials(std::string,std::string,std::string,std::string))); 121 | QObject::connect(serverExplorer,SIGNAL(sendDropData(QString,QString,QString,QString)),SLOT(recieveDropData(QString,QString,QString,QString))); 122 | QObject::connect(localExplorer,SIGNAL(sendDropData(QString,QString,QString,QString)),SLOT(recieveDropData(QString,QString,QString,QString))); 123 | 124 | bottomLeftLayout->addWidget(localExplorer); 125 | bottomRightLayout->addWidget(serverExplorer); 126 | // Proxy Widgets for Slider 127 | QWidget* localExplorerWidget = new QWidget(); 128 | QWidget* serverExplorerWidget = new QWidget(); 129 | localExplorerWidget->setLayout(bottomLeftLayout); 130 | serverExplorerWidget->setLayout(bottomRightLayout); 131 | 132 | // Main Slider Widget 1 133 | bottomLayout->addWidget(localExplorerWidget); 134 | bottomLayout->addWidget(serverExplorerWidget); 135 | bottomLayout->setContentsMargins(4,0,4,4); 136 | QWidget* explorerSlider = new QWidget(); 137 | explorerSlider->setLayout(bottomLayout); 138 | 139 | // Empty Frame to Test 140 | //QWidget* temp = new QWidget(); 141 | downloadManager = new DownloadManager(this); 142 | QObject::connect(this,SIGNAL(sendCredentials(std::string,std::string,std::string,std::string)),downloadManager,SLOT(receiveCredentials(std::string,std::string,std::string,std::string))); 143 | // Create Bottom Stacked Slider Widget 144 | mainContent = new SlidingStackedWidget(this); 145 | mainContent->addWidget(explorerSlider); 146 | mainContent->addWidget(downloadManager); 147 | mainContent->setSpeed(animTime); 148 | mainContent->setVerticalMode(true); 149 | mainContent->setAnimation(QEasingCurve::OutQuart); 150 | mainLayout->setContentsMargins(0,0,0,0); 151 | mainLayout->addLayout(topLayout,0); 152 | mainLayout->addWidget(mainContent,0,0); 153 | this->setLayout(mainLayout); 154 | 155 | QObject::connect(downloadManager, SIGNAL(setProgress(int)), statusArea,SLOT(setProgress(int))); 156 | QObject::connect(downloadManager, SIGNAL(setFileName(QString)),statusArea,SLOT(setFileName(QString))); 157 | QObject::connect(downloadManager, SIGNAL(setNumFiles(int)),statusArea,SLOT(setNumFiles(int))); 158 | QObject::connect(statusArea->cancel,SIGNAL(clicked()),downloadManager,SLOT(receiveCancelClick())); 159 | QObject::connect(statusArea->pause, SIGNAL(clicked()),downloadManager,SLOT(receivePauseClick())); 160 | QObject::connect(downloadManager,SIGNAL(setSpeed(QString)),statusArea,SLOT(setSpeed(QString))); 161 | } 162 | 163 | void MainWindow::maxSize() 164 | { 165 | 166 | if(!max) { 167 | 168 | int a = QApplication::desktop()->screenNumber(this); 169 | resize(QApplication::desktop()->availableGeometry(a).size()); 170 | move(QApplication::desktop()->availableGeometry(a).topLeft()); 171 | max = true; 172 | 173 | } else if (max){ 174 | resize(900,500); 175 | move(QApplication::desktop()->availableGeometry(this).center() - rect().center()); 176 | max = false; 177 | } 178 | 179 | } 180 | 181 | // Slots for status area 182 | void MainWindow::switchSlides() 183 | { 184 | 185 | if( switched == false){ 186 | 187 | mainContent->slideInIdx(1,SlidingStackedWidget::BOTTOM2TOP); 188 | 189 | switched = true; 190 | } else if (switched == true) { 191 | 192 | mainContent->slideInIdx(0,SlidingStackedWidget::BOTTOM2TOP); 193 | 194 | switched = false; 195 | } 196 | 197 | 198 | } 199 | 200 | 201 | 202 | void MainWindow::recieveCredentials(std::string host, std::string user, std::string password, std::string port) 203 | { 204 | qDebug() << "Credentials Recieved"; 205 | emit sendCredentials(host,user, password,port); 206 | 207 | } 208 | void MainWindow::recieveDropData(QString type, QString source, QString destination, QString sftpType) 209 | { 210 | // Send to downloader 211 | downloadManager->addData(type,source,destination,sftpType); 212 | 213 | } 214 | 215 | 216 | void MainWindow::aboutClick() 217 | { 218 | About* about = new About(); 219 | about->show(); 220 | } 221 | 222 | MainWindow::~MainWindow() 223 | { 224 | 225 | } 226 | -------------------------------------------------------------------------------- /MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_MAINWINDOW_H 2 | #define COMET_MAINWINDOW_H 3 | 4 | // Qt 5 | #include 6 | #include 7 | 8 | // Libraries 9 | //#include 10 | //#include 11 | 12 | // Classes 13 | #include "ServerExplorer.h" 14 | #include "LocalExplorer.h" 15 | #include "StatusArea.h" 16 | #include "SlidingStackedWidget.h" 17 | #include "DownloadManager.h" 18 | #include "About.h"; 19 | 20 | class MainWindow : public QFrame 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit MainWindow(QFrame *parent = 0); 26 | ~MainWindow(); 27 | 28 | private: 29 | 30 | // Widgets 31 | QPushButton* btnQuit; 32 | QPushButton* btnMax; 33 | QPushButton* btnMin; 34 | QPushButton* btnMenu; 35 | StatusArea* statusArea; 36 | LocalExplorer* localExplorer; 37 | ServerExplorer* serverExplorer; 38 | SlidingStackedWidget* mainContent; 39 | DownloadManager* downloadManager; 40 | // Layouts 41 | QVBoxLayout* mainLayout; 42 | QHBoxLayout* topLayout; 43 | QHBoxLayout* topLeftLayout; 44 | QHBoxLayout* topMiddleLayout; 45 | QHBoxLayout* topRightLayout; 46 | QHBoxLayout* bottomLayout; 47 | QHBoxLayout* bottomLeftLayout; 48 | QHBoxLayout* bottomRightLayout; 49 | 50 | bool max; // For Window Maximising with frameless helper 51 | int animTime; // For setting animation times on slides 52 | bool switched; 53 | QString bookmarks; 54 | 55 | // SFTP Session 56 | std::string host; 57 | std::string password; 58 | std::string user; 59 | std::string port; 60 | //sftp_session sftp; 61 | void connectSftp(); 62 | 63 | protected: 64 | void createGuiComponents(); 65 | void createMainLayout(); 66 | 67 | private slots: 68 | void maxSize(); 69 | void aboutClick(); 70 | 71 | public slots: 72 | void switchSlides(); 73 | void recieveCredentials(std::string host, std::string user, std::string password, std::string port); 74 | void recieveDropData(QString type, QString source, QString destination, QString stfpType); 75 | 76 | signals: 77 | void sendCredentials(std::string host, std::string user, std::string password, std::string port); 78 | 79 | }; 80 | 81 | #endif // COMET_MAINWINDOW_H 82 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Makefile for building: CometFTP 3 | # Generated by qmake (3.0) (Qt 5.2.0) 4 | # Project: CometFTP.pro 5 | # Template: app 6 | # Command: C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\qmake.exe -o Makefile CometFTP.pro 7 | ############################################################################# 8 | 9 | MAKEFILE = Makefile 10 | 11 | first: release 12 | install: release-install 13 | uninstall: release-uninstall 14 | QMAKE = C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\qmake.exe 15 | DEL_FILE = del 16 | CHK_DIR_EXISTS= if not exist 17 | MKDIR = mkdir 18 | COPY = copy /y 19 | COPY_FILE = $(COPY) 20 | COPY_DIR = xcopy /s /q /y /i 21 | INSTALL_FILE = $(COPY_FILE) 22 | INSTALL_PROGRAM = $(COPY_FILE) 23 | INSTALL_DIR = $(COPY_DIR) 24 | DEL_FILE = del 25 | SYMLINK = copy /y 26 | DEL_DIR = rmdir 27 | MOVE = move 28 | SUBTARGETS = \ 29 | release \ 30 | debug 31 | 32 | 33 | release: FORCE 34 | $(MAKE) -f $(MAKEFILE).Release 35 | release-make_first: FORCE 36 | $(MAKE) -f $(MAKEFILE).Release 37 | release-all: FORCE 38 | $(MAKE) -f $(MAKEFILE).Release all 39 | release-clean: FORCE 40 | $(MAKE) -f $(MAKEFILE).Release clean 41 | release-distclean: FORCE 42 | $(MAKE) -f $(MAKEFILE).Release distclean 43 | release-install: FORCE 44 | $(MAKE) -f $(MAKEFILE).Release install 45 | release-uninstall: FORCE 46 | $(MAKE) -f $(MAKEFILE).Release uninstall 47 | debug: FORCE 48 | $(MAKE) -f $(MAKEFILE).Debug 49 | debug-make_first: FORCE 50 | $(MAKE) -f $(MAKEFILE).Debug 51 | debug-all: FORCE 52 | $(MAKE) -f $(MAKEFILE).Debug all 53 | debug-clean: FORCE 54 | $(MAKE) -f $(MAKEFILE).Debug clean 55 | debug-distclean: FORCE 56 | $(MAKE) -f $(MAKEFILE).Debug distclean 57 | debug-install: FORCE 58 | $(MAKE) -f $(MAKEFILE).Debug install 59 | debug-uninstall: FORCE 60 | $(MAKE) -f $(MAKEFILE).Debug uninstall 61 | 62 | Makefile: CometFTP.pro ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/win32-g++/qmake.conf ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/spec_pre.prf \ 63 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/qdevice.pri \ 64 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/device_config.prf \ 65 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/common/shell-win32.conf \ 66 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/qconfig.pri \ 67 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axbase.pri \ 68 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axbase_private.pri \ 69 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axcontainer.pri \ 70 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axcontainer_private.pri \ 71 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axserver.pri \ 72 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_axserver_private.pri \ 73 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_bluetooth.pri \ 74 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_bluetooth_private.pri \ 75 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_bootstrap_private.pri \ 76 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_clucene_private.pri \ 77 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_concurrent.pri \ 78 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_concurrent_private.pri \ 79 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_core.pri \ 80 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_core_private.pri \ 81 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_declarative.pri \ 82 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_declarative_private.pri \ 83 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_designer.pri \ 84 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_designer_private.pri \ 85 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_designercomponents_private.pri \ 86 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_gui.pri \ 87 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_gui_private.pri \ 88 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_help.pri \ 89 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_help_private.pri \ 90 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_multimedia.pri \ 91 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_multimedia_private.pri \ 92 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_multimediawidgets.pri \ 93 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ 94 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_network.pri \ 95 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_network_private.pri \ 96 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_nfc.pri \ 97 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_nfc_private.pri \ 98 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_opengl.pri \ 99 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_opengl_private.pri \ 100 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_openglextensions.pri \ 101 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_openglextensions_private.pri \ 102 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_platformsupport_private.pri \ 103 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_positioning.pri \ 104 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_positioning_private.pri \ 105 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_printsupport.pri \ 106 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_printsupport_private.pri \ 107 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qml.pri \ 108 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qml_private.pri \ 109 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qmldevtools_private.pri \ 110 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qmltest.pri \ 111 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qmltest_private.pri \ 112 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ 113 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_quick.pri \ 114 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_quick_private.pri \ 115 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_quickparticles_private.pri \ 116 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_script.pri \ 117 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_script_private.pri \ 118 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_scripttools.pri \ 119 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_scripttools_private.pri \ 120 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_sensors.pri \ 121 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_sensors_private.pri \ 122 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_serialport.pri \ 123 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_serialport_private.pri \ 124 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_sql.pri \ 125 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_sql_private.pri \ 126 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_svg.pri \ 127 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_svg_private.pri \ 128 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_testlib.pri \ 129 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_testlib_private.pri \ 130 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_uitools.pri \ 131 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_uitools_private.pri \ 132 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_webkit.pri \ 133 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_webkit_private.pri \ 134 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_webkitwidgets.pri \ 135 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_webkitwidgets_private.pri \ 136 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_widgets.pri \ 137 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_widgets_private.pri \ 138 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_winextras.pri \ 139 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_winextras_private.pri \ 140 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_xml.pri \ 141 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_xml_private.pri \ 142 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_xmlpatterns.pri \ 143 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ 144 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/qt_functions.prf \ 145 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/qt_config.prf \ 146 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/win32-g++/qmake.conf \ 147 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/spec_post.prf \ 148 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/exclusive_builds.prf \ 149 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/default_pre.prf \ 150 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/win32/default_pre.prf \ 151 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/resolve_config.prf \ 152 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/exclusive_builds_post.prf \ 153 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/default_post.prf \ 154 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/c++11.prf \ 155 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/win32/rtti.prf \ 156 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/warn_on.prf \ 157 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/qt.prf \ 158 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/resources.prf \ 159 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/moc.prf \ 160 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/win32/opengl.prf \ 161 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/uic.prf \ 162 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/win32/windows.prf \ 163 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/testcase_targets.prf \ 164 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/exceptions.prf \ 165 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/yacc.prf \ 166 | ../../../../../Qt/Qt5.2.0/5.2.0/mingw48_32/mkspecs/features/lex.prf \ 167 | CometFTP.pro \ 168 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Widgets.prl \ 169 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Gui.prl \ 170 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Core.prl 171 | $(QMAKE) -o Makefile CometFTP.pro 172 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\spec_pre.prf: 173 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\qdevice.pri: 174 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\device_config.prf: 175 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\common\shell-win32.conf: 176 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\qconfig.pri: 177 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axbase.pri: 178 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axbase_private.pri: 179 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axcontainer.pri: 180 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axcontainer_private.pri: 181 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axserver.pri: 182 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_axserver_private.pri: 183 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_bluetooth.pri: 184 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_bluetooth_private.pri: 185 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_bootstrap_private.pri: 186 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_clucene_private.pri: 187 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_concurrent.pri: 188 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_concurrent_private.pri: 189 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_core.pri: 190 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_core_private.pri: 191 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_declarative.pri: 192 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_declarative_private.pri: 193 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_designer.pri: 194 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_designer_private.pri: 195 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_designercomponents_private.pri: 196 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_gui.pri: 197 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_gui_private.pri: 198 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_help.pri: 199 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_help_private.pri: 200 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_multimedia.pri: 201 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_multimedia_private.pri: 202 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_multimediawidgets.pri: 203 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_multimediawidgets_private.pri: 204 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_network.pri: 205 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_network_private.pri: 206 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_nfc.pri: 207 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_nfc_private.pri: 208 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_opengl.pri: 209 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_opengl_private.pri: 210 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_openglextensions.pri: 211 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_openglextensions_private.pri: 212 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_platformsupport_private.pri: 213 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_positioning.pri: 214 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_positioning_private.pri: 215 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_printsupport.pri: 216 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_printsupport_private.pri: 217 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qml.pri: 218 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qml_private.pri: 219 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qmldevtools_private.pri: 220 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qmltest.pri: 221 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qmltest_private.pri: 222 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_qtmultimediaquicktools_private.pri: 223 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_quick.pri: 224 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_quick_private.pri: 225 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_quickparticles_private.pri: 226 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_script.pri: 227 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_script_private.pri: 228 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_scripttools.pri: 229 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_scripttools_private.pri: 230 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_sensors.pri: 231 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_sensors_private.pri: 232 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_serialport.pri: 233 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_serialport_private.pri: 234 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_sql.pri: 235 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_sql_private.pri: 236 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_svg.pri: 237 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_svg_private.pri: 238 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_testlib.pri: 239 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_testlib_private.pri: 240 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_uitools.pri: 241 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_uitools_private.pri: 242 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_webkit.pri: 243 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_webkit_private.pri: 244 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_webkitwidgets.pri: 245 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_webkitwidgets_private.pri: 246 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_widgets.pri: 247 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_widgets_private.pri: 248 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_winextras.pri: 249 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_winextras_private.pri: 250 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_xml.pri: 251 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_xml_private.pri: 252 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_xmlpatterns.pri: 253 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\modules\qt_lib_xmlpatterns_private.pri: 254 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\qt_functions.prf: 255 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\qt_config.prf: 256 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\win32-g++\qmake.conf: 257 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\spec_post.prf: 258 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\exclusive_builds.prf: 259 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\default_pre.prf: 260 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\win32\default_pre.prf: 261 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\resolve_config.prf: 262 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\exclusive_builds_post.prf: 263 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\default_post.prf: 264 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\c++11.prf: 265 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\win32\rtti.prf: 266 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\warn_on.prf: 267 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\qt.prf: 268 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\resources.prf: 269 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\moc.prf: 270 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\win32\opengl.prf: 271 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\uic.prf: 272 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\win32\windows.prf: 273 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\testcase_targets.prf: 274 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\exceptions.prf: 275 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\yacc.prf: 276 | ..\..\..\..\..\Qt\Qt5.2.0\5.2.0\mingw48_32\mkspecs\features\lex.prf: 277 | CometFTP.pro: 278 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Widgets.prl: 279 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Gui.prl: 280 | C:/Qt/Qt5.2.0/5.2.0/mingw48_32/lib/Qt5Core.prl: 281 | qmake: FORCE 282 | @$(QMAKE) -o Makefile CometFTP.pro 283 | 284 | qmake_all: FORCE 285 | 286 | make_first: release-make_first debug-make_first FORCE 287 | all: release-all debug-all FORCE 288 | clean: release-clean debug-clean FORCE 289 | distclean: release-distclean debug-distclean FORCE 290 | -$(DEL_FILE) Makefile 291 | 292 | release-mocclean: 293 | $(MAKE) -f $(MAKEFILE).Release mocclean 294 | debug-mocclean: 295 | $(MAKE) -f $(MAKEFILE).Debug mocclean 296 | mocclean: release-mocclean debug-mocclean 297 | 298 | release-mocables: 299 | $(MAKE) -f $(MAKEFILE).Release mocables 300 | debug-mocables: 301 | $(MAKE) -f $(MAKEFILE).Debug mocables 302 | mocables: release-mocables debug-mocables 303 | 304 | check: first 305 | FORCE: 306 | 307 | $(MAKEFILE).Release: Makefile 308 | $(MAKEFILE).Debug: Makefile 309 | -------------------------------------------------------------------------------- /NcFramelessHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | NcFramelessHelper, an easy way to support move/resize on 3 | frameless toplevel windows. 4 | Copyright (C) 2011 Nishant Parashar 5 | Email:- nishcode (at) gmail (dot) com 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | //Version 3.0.0 22 | 23 | #ifndef NC_FRAMELESS_HELPER_H 24 | #define NC_FRAMELESS_HELPER_H 25 | 26 | #include 27 | 28 | class NcFramelessHelperImpl; 29 | 30 | class NcFramelessHelper : public QObject 31 | { 32 | 33 | public: 34 | explicit NcFramelessHelper( QObject* parent = 0 ); 35 | ~NcFramelessHelper(); 36 | 37 | void activateOn( QWidget* topLevelWidget ); 38 | void removeFrom( QWidget* topLevelWidget ); 39 | 40 | void setWidgetMovable( bool movable ); 41 | bool isWidgetMovable(); 42 | 43 | void setWidgetResizable( bool resizable ); 44 | bool isWidgetResizable(); 45 | 46 | void useRubberBandOnMove( bool use ); 47 | bool isUsingRubberBandOnMove(); 48 | 49 | void useRubberBandOnResize( bool use ); 50 | bool isUsingRubberBandOnResisze(); 51 | 52 | //Make sure to leave the same content margins 53 | //around the widget as the newBorderWidth 54 | //this can be done by 55 | //yourWidget->layout()->setMargin( newBorderWidth ); 56 | //otherwise your widget will not expose the 57 | //area where this class works 58 | void setBorderWidth( int newBorderWidth ); 59 | int borderWidth(); 60 | 61 | protected: 62 | virtual bool eventFilter( QObject* obj, QEvent* event ); 63 | 64 | private: 65 | NcFramelessHelperImpl* d; 66 | }; 67 | 68 | #endif // NC_FRAMELESS_HELPER_H 69 | -------------------------------------------------------------------------------- /NcFramlessHelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | FramelessHelper, an easy way to support move/resize on 3 | frameless toplevel windows. 4 | Copyright (C) 2011 Nishant Parashar 5 | Email:- nishcode (at) gmail (dot) com 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "NcFramelessHelper.h" 26 | 27 | class NcCursorPosCalculator 28 | { 29 | 30 | public: 31 | NcCursorPosCalculator(); 32 | void reset(); 33 | void recalculate( const QPoint& globalMousePos, const QRect& frameRect ); 34 | 35 | public: 36 | bool onEdges; 37 | bool onLeftEdge; 38 | bool onRightEdge; 39 | bool onTopEdge; 40 | bool onBottomEdge; 41 | bool onTopLeftEdge; 42 | bool onBottomLeftEdge; 43 | bool onTopRightEdge; 44 | bool onBottomRightEdge; 45 | 46 | static int mBorderWidth; 47 | }; 48 | //TODO: Should not be static. 49 | int NcCursorPosCalculator::mBorderWidth = 5; 50 | 51 | class NcWidgetData 52 | { 53 | public: 54 | NcWidgetData( NcFramelessHelperImpl* _d, QWidget* topLevelWidget ); 55 | ~NcWidgetData(); 56 | 57 | //void setWidget( QWidget* topLevelWidget ); 58 | QWidget* widget(); 59 | void handleWidgetEvent( QEvent* event ); 60 | void updateRubberBandStatus(); 61 | 62 | private: 63 | void updateCursorShape( const QPoint& globalMousePos ); 64 | void resizeWidget( const QPoint& globalMousePos ); 65 | void moveWidget( const QPoint& globalMousePos ); 66 | 67 | void handleMousePressEvent( QMouseEvent* event ); 68 | void handleMouseReleaseEvent( QMouseEvent* event ); 69 | void handleMouseMoveEvent( QMouseEvent* event ); 70 | void handleLeaveEvent( QEvent* event ); 71 | void handleHoverMoveEvent( QHoverEvent* event ); 72 | 73 | private: 74 | NcFramelessHelperImpl* d; 75 | QRubberBand* mRubberBand; 76 | bool mLeftButtonPressed; 77 | QWidget* mWidget; 78 | QPoint mDragPos; 79 | NcCursorPosCalculator mPressedMousePos; 80 | NcCursorPosCalculator mMoveMousePos; 81 | bool mCursorShapeChanged; 82 | Qt::WindowFlags mWindowFlags; 83 | }; 84 | 85 | 86 | class NcFramelessHelperImpl 87 | { 88 | public: 89 | QHash< QWidget*, NcWidgetData* > mHashWidgetData; 90 | bool mWidgetMovable; 91 | bool mWidgetResizable; 92 | bool mUseRubberBandOnResize; 93 | bool mUseRubberBandOnMove; 94 | }; 95 | 96 | NcCursorPosCalculator::NcCursorPosCalculator() 97 | { 98 | reset(); 99 | } 100 | 101 | void NcCursorPosCalculator::reset() 102 | { 103 | onEdges = false; 104 | onLeftEdge = false; 105 | onRightEdge = false; 106 | onTopEdge = false; 107 | onBottomEdge = false; 108 | onTopLeftEdge = false; 109 | onBottomLeftEdge = false; 110 | onTopRightEdge = false; 111 | onBottomRightEdge = false; 112 | } 113 | 114 | void NcCursorPosCalculator::recalculate( const QPoint& globalMousePos, const QRect& frameRect ) 115 | { 116 | int globalMouseX = globalMousePos.x(); 117 | int globalMouseY = globalMousePos.y(); 118 | 119 | int frameX = frameRect.x(); 120 | int frameY = frameRect.y(); 121 | 122 | int frameWidth = frameRect.width(); 123 | int frameHeight = frameRect.height(); 124 | 125 | onLeftEdge = globalMouseX >= frameX && 126 | globalMouseX <= frameX + mBorderWidth; 127 | 128 | 129 | onRightEdge = globalMouseX >= frameX + frameWidth - mBorderWidth && 130 | globalMouseX <= frameX + frameWidth; 131 | 132 | onTopEdge = globalMouseY >= frameY && 133 | globalMouseY <= frameY + mBorderWidth; 134 | 135 | 136 | onBottomEdge = globalMouseY >= frameY + frameHeight - mBorderWidth && 137 | globalMouseY <= frameY + frameHeight; 138 | 139 | onTopLeftEdge = onTopEdge && onLeftEdge; 140 | onBottomLeftEdge = onBottomEdge && onLeftEdge; 141 | onTopRightEdge = onTopEdge && onRightEdge; 142 | onBottomRightEdge = onBottomEdge && onRightEdge; 143 | 144 | //only these checks would be enough 145 | onEdges = onLeftEdge || onRightEdge || 146 | onTopEdge || onBottomEdge; 147 | 148 | } 149 | 150 | 151 | NcWidgetData::NcWidgetData( NcFramelessHelperImpl* _d, QWidget* topLevelWidget ) 152 | { 153 | d = _d; 154 | mWidget = topLevelWidget; 155 | mLeftButtonPressed = false; 156 | mRubberBand = 0; 157 | mCursorShapeChanged = false; 158 | 159 | mWindowFlags = mWidget->windowFlags(); 160 | 161 | //---from Qt docs of setWindowFlags()---- 162 | //Note: This function calls setParent() when 163 | //changing the flags for a window, causing the 164 | //widget to be hidden. You must call show() 165 | //to make the widget visible again.. 166 | 167 | bool visible = mWidget->isVisible(); 168 | 169 | mWidget->setMouseTracking( true ); 170 | mWidget->setWindowFlags( Qt::CustomizeWindowHint|Qt::FramelessWindowHint ); 171 | //Bug fix, mouse move events does not propagate from child widgets. 172 | //so need the hover events. 173 | mWidget->setAttribute( Qt::WA_Hover ); 174 | 175 | updateRubberBandStatus(); 176 | 177 | mWidget->setVisible( visible ); 178 | } 179 | 180 | NcWidgetData::~NcWidgetData() 181 | { 182 | //---from Qt docs of setWindowFlags()---- 183 | //Note: This function calls setParent() when 184 | //changing the flags for a window, causing the 185 | //widget to be hidden. You must call show() 186 | //to make the widget visible again.. 187 | 188 | bool visible = mWidget->isVisible(); 189 | 190 | mWidget->setMouseTracking( false ); 191 | mWidget->setWindowFlags( mWindowFlags );//^ Qt::CustomizeWindowHint ^ Qt::FramelessWindowHint ); 192 | mWidget->setAttribute( Qt::WA_Hover, false ); 193 | 194 | mWidget->setVisible( visible ); 195 | 196 | delete mRubberBand; 197 | } 198 | 199 | void NcWidgetData::updateRubberBandStatus() 200 | { 201 | if ( d->mUseRubberBandOnMove || d->mUseRubberBandOnResize ) 202 | { 203 | if ( !mRubberBand ) 204 | mRubberBand = new QRubberBand( QRubberBand::Rectangle ); 205 | } 206 | else 207 | { 208 | delete mRubberBand; 209 | mRubberBand = 0; 210 | } 211 | } 212 | 213 | QWidget* NcWidgetData::widget() 214 | { 215 | return mWidget; 216 | } 217 | 218 | void NcWidgetData::handleWidgetEvent( QEvent* event ) 219 | { 220 | switch ( event->type() ) 221 | { 222 | default: //qDebug() << "Event = " << event; 223 | break; 224 | case QEvent::MouseButtonPress: 225 | handleMousePressEvent( static_cast( event ) ); 226 | break; 227 | 228 | case QEvent::MouseButtonRelease: 229 | handleMouseReleaseEvent( static_cast( event ) ); 230 | break; 231 | 232 | case QEvent::MouseMove: 233 | handleMouseMoveEvent( static_cast( event ) ); 234 | break; 235 | 236 | case QEvent::Leave: 237 | handleLeaveEvent( event ); 238 | break; 239 | 240 | //Bug fix, hover event is necessary coz child widget does not 241 | //propagate mousemove events. so the cursor remains in edge shape 242 | //even in middle of widget. 243 | case QEvent::HoverMove: 244 | handleHoverMoveEvent( static_cast( event ) ); 245 | break; 246 | //case QEvent::Enter: 247 | //qDebug() << "Enter event";//d->handleEnterEvent( event ); 248 | //break; 249 | } 250 | } 251 | 252 | void NcWidgetData::updateCursorShape( const QPoint& globalMousePos ) 253 | { 254 | if ( mWidget->isFullScreen() || mWidget->isMaximized() ) 255 | { 256 | if ( mCursorShapeChanged ) 257 | mWidget->unsetCursor(); 258 | 259 | return; 260 | } 261 | 262 | mMoveMousePos.recalculate( globalMousePos, mWidget->frameGeometry() ); 263 | 264 | if( mMoveMousePos.onTopLeftEdge || mMoveMousePos.onBottomRightEdge ) 265 | { 266 | mWidget->setCursor( Qt::SizeFDiagCursor ); 267 | mCursorShapeChanged = true; 268 | } 269 | else if( mMoveMousePos.onTopRightEdge || mMoveMousePos.onBottomLeftEdge ) 270 | { 271 | mWidget->setCursor( Qt::SizeBDiagCursor ); 272 | mCursorShapeChanged = true; 273 | } 274 | else if( mMoveMousePos.onLeftEdge || mMoveMousePos.onRightEdge ) 275 | { 276 | mWidget->setCursor( Qt::SizeHorCursor ); 277 | mCursorShapeChanged = true; 278 | } 279 | else if( mMoveMousePos.onTopEdge || mMoveMousePos.onBottomEdge ) 280 | { 281 | mWidget->setCursor( Qt::SizeVerCursor ); 282 | mCursorShapeChanged = true; 283 | } 284 | else 285 | { 286 | if ( mCursorShapeChanged ) 287 | { 288 | mWidget->unsetCursor(); 289 | mCursorShapeChanged = false; 290 | } 291 | } 292 | } 293 | 294 | void NcWidgetData::resizeWidget( const QPoint& globalMousePos ) 295 | { 296 | QRect origRect; 297 | 298 | if ( d->mUseRubberBandOnResize ) 299 | origRect = mRubberBand->frameGeometry(); 300 | else 301 | origRect = mWidget->frameGeometry(); 302 | 303 | 304 | int left = origRect.left(); 305 | int top = origRect.top(); 306 | int right = origRect.right(); 307 | int bottom = origRect.bottom(); 308 | origRect.getCoords( &left, &top, &right, &bottom ); 309 | 310 | int minWidth = mWidget->minimumWidth(); 311 | int minHeight = mWidget->minimumHeight(); 312 | 313 | if ( mPressedMousePos.onTopLeftEdge ) 314 | { 315 | left = globalMousePos.x(); 316 | top = globalMousePos.y(); 317 | } 318 | else if ( mPressedMousePos.onBottomLeftEdge ) 319 | { 320 | left = globalMousePos.x(); 321 | bottom = globalMousePos.y(); 322 | } 323 | else if ( mPressedMousePos.onTopRightEdge ) 324 | { 325 | right = globalMousePos.x(); 326 | top = globalMousePos.y(); 327 | } 328 | else if ( mPressedMousePos.onBottomRightEdge ) 329 | { 330 | right = globalMousePos.x(); 331 | bottom = globalMousePos.y(); 332 | } 333 | else if ( mPressedMousePos.onLeftEdge ) 334 | { 335 | left = globalMousePos.x(); 336 | } 337 | else if ( mPressedMousePos.onRightEdge ) 338 | { 339 | right = globalMousePos.x(); 340 | } 341 | else if ( mPressedMousePos.onTopEdge ) 342 | { 343 | top = globalMousePos.y(); 344 | } 345 | else if ( mPressedMousePos.onBottomEdge ) 346 | { 347 | bottom = globalMousePos.y(); 348 | } 349 | 350 | QRect newRect( QPoint(left, top), QPoint(right, bottom) ); 351 | 352 | if ( newRect.isValid() ) 353 | { 354 | if ( minWidth > newRect.width() ) 355 | { 356 | //determine what has caused the width change. 357 | if( left != origRect.left() ) 358 | newRect.setLeft( origRect.left() ); 359 | else 360 | newRect.setRight( origRect.right() ); 361 | } 362 | if ( minHeight > newRect.height() ) 363 | { 364 | //determine what has caused the height change. 365 | if ( top != origRect.top() ) 366 | newRect.setTop( origRect.top() ); 367 | else 368 | newRect.setBottom( origRect.bottom() ); 369 | } 370 | 371 | if ( d->mUseRubberBandOnResize ) 372 | { 373 | mRubberBand->setGeometry( newRect ); 374 | } 375 | else 376 | { 377 | mWidget->setGeometry( newRect ); 378 | } 379 | } 380 | else 381 | { 382 | //qDebug() << "Calculated Rect is not valid" << newRect; 383 | } 384 | 385 | } 386 | 387 | void NcWidgetData::moveWidget( const QPoint& globalMousePos ) 388 | { 389 | if ( d->mUseRubberBandOnMove ) 390 | { 391 | mRubberBand->move( globalMousePos - mDragPos ); 392 | } 393 | else 394 | { 395 | mWidget->move( globalMousePos - mDragPos ); 396 | } 397 | } 398 | 399 | void NcWidgetData::handleMousePressEvent( QMouseEvent* event ) 400 | { 401 | if ( event->button() == Qt::LeftButton ) 402 | { 403 | mLeftButtonPressed = true; 404 | 405 | QRect frameRect = mWidget->frameGeometry(); 406 | mPressedMousePos.recalculate( event->globalPos(), frameRect ); 407 | 408 | mDragPos = event->globalPos() - frameRect.topLeft(); 409 | 410 | if ( mPressedMousePos.onEdges ) 411 | { 412 | if ( d->mUseRubberBandOnResize ) 413 | { 414 | mRubberBand->setGeometry( frameRect ); 415 | mRubberBand->show(); 416 | } 417 | } 418 | else if ( d->mUseRubberBandOnMove ) 419 | { 420 | mRubberBand->setGeometry( frameRect ); 421 | mRubberBand->show(); 422 | } 423 | 424 | } 425 | } 426 | 427 | void NcWidgetData::handleMouseReleaseEvent( QMouseEvent* event ) 428 | { 429 | if ( event->button() == Qt::LeftButton ) 430 | { 431 | mLeftButtonPressed = false; 432 | mPressedMousePos.reset(); 433 | if ( mRubberBand && mRubberBand->isVisible() ) 434 | { 435 | mRubberBand->hide(); 436 | mWidget->setGeometry( mRubberBand->geometry() ); 437 | } 438 | } 439 | } 440 | 441 | void NcWidgetData::handleMouseMoveEvent( QMouseEvent* event ) 442 | { 443 | if ( mLeftButtonPressed ) 444 | { 445 | if ( d->mWidgetResizable && mPressedMousePos.onEdges ) 446 | { 447 | resizeWidget( event->globalPos() ); 448 | } 449 | else if ( d->mWidgetMovable ) 450 | { 451 | moveWidget( event->globalPos() ); 452 | } 453 | } 454 | else if ( d->mWidgetResizable ) 455 | { 456 | updateCursorShape( event->globalPos() ); 457 | } 458 | 459 | } 460 | 461 | void NcWidgetData::handleLeaveEvent( QEvent* /*event*/ ) 462 | { 463 | if ( !mLeftButtonPressed ) 464 | mWidget->unsetCursor(); 465 | } 466 | 467 | void NcWidgetData::handleHoverMoveEvent( QHoverEvent* event ) 468 | { 469 | if ( d->mWidgetResizable ) 470 | updateCursorShape( mWidget->mapToGlobal( event->pos() ) ); 471 | } 472 | 473 | NcFramelessHelper::NcFramelessHelper( QObject* parent ) 474 | : QObject( parent ), 475 | d( new NcFramelessHelperImpl ) 476 | { 477 | d->mWidgetMovable = true; 478 | d->mWidgetResizable = true; 479 | d->mUseRubberBandOnResize = false; 480 | d->mUseRubberBandOnMove = false; 481 | } 482 | 483 | NcFramelessHelper::~NcFramelessHelper() 484 | { 485 | QList keys = d->mHashWidgetData.keys(); 486 | int size = keys.size(); 487 | for ( int i = 0; i < size; ++i ) 488 | { 489 | delete d->mHashWidgetData.take( keys[i] ); 490 | } 491 | 492 | delete d; 493 | } 494 | 495 | bool NcFramelessHelper::eventFilter( QObject *obj, QEvent *event ) 496 | { 497 | QEvent::Type type = event->type(); 498 | 499 | if ( type == QEvent::MouseMove || 500 | type == QEvent::HoverMove || 501 | type == QEvent::MouseButtonPress || 502 | type == QEvent::MouseButtonRelease || 503 | type == QEvent::Leave 504 | ) 505 | { 506 | NcWidgetData* data = d->mHashWidgetData.value( static_cast(obj) ); 507 | if ( data ) 508 | { 509 | data->handleWidgetEvent( event ); 510 | } 511 | 512 | } 513 | 514 | return false; 515 | } 516 | 517 | void NcFramelessHelper::activateOn( QWidget* topLevelWidget ) 518 | { 519 | if ( d->mHashWidgetData.contains( topLevelWidget ) ) 520 | return; 521 | 522 | NcWidgetData* data = new NcWidgetData( d, topLevelWidget ); 523 | d->mHashWidgetData.insert( topLevelWidget, data ); 524 | 525 | topLevelWidget->installEventFilter( this ); 526 | 527 | } 528 | 529 | void NcFramelessHelper::removeFrom( QWidget* topLevelWidget ) 530 | { 531 | NcWidgetData* data = d->mHashWidgetData.take( topLevelWidget ); 532 | if ( data ) 533 | { 534 | topLevelWidget->removeEventFilter( this ); 535 | delete data; 536 | } 537 | } 538 | 539 | void NcFramelessHelper::setWidgetMovable( bool movable ) 540 | { 541 | d->mWidgetMovable = movable; 542 | } 543 | 544 | bool NcFramelessHelper::isWidgetMovable() 545 | { 546 | return d->mWidgetMovable; 547 | } 548 | 549 | void NcFramelessHelper::setWidgetResizable( bool resizable ) 550 | { 551 | d->mWidgetResizable = resizable; 552 | } 553 | 554 | bool NcFramelessHelper::isWidgetResizable() 555 | { 556 | return d->mWidgetResizable; 557 | } 558 | 559 | void NcFramelessHelper::useRubberBandOnMove( bool use ) 560 | { 561 | d->mUseRubberBandOnMove = use; 562 | QList list = d->mHashWidgetData.values(); 563 | int size = list.size(); 564 | for ( int i = 0; i < size; ++i ) 565 | list[i]->updateRubberBandStatus(); 566 | } 567 | 568 | bool NcFramelessHelper::isUsingRubberBandOnMove() 569 | { 570 | return d->mUseRubberBandOnMove; 571 | } 572 | 573 | void NcFramelessHelper::useRubberBandOnResize( bool use ) 574 | { 575 | d->mUseRubberBandOnResize = use; 576 | QList list = d->mHashWidgetData.values(); 577 | int size = list.size(); 578 | for ( int i = 0; i < size; ++i ) 579 | list[i]->updateRubberBandStatus(); 580 | } 581 | 582 | bool NcFramelessHelper::isUsingRubberBandOnResisze() 583 | { 584 | return d->mUseRubberBandOnResize; 585 | } 586 | 587 | void NcFramelessHelper::setBorderWidth( int newBorderWidth ) 588 | { 589 | //TODO: Make it non-static. 590 | if ( newBorderWidth >= 0 ) 591 | NcCursorPosCalculator::mBorderWidth = newBorderWidth; 592 | } 593 | 594 | int NcFramelessHelper::borderWidth() 595 | { 596 | return NcCursorPosCalculator::mBorderWidth; 597 | } 598 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WARNING Very Very Incomplete 2 | 3 | BSc final project. The aim of this project was to build an open-source, user-friendly SFTP application produced with simplicity and platform-independence to encourage more widespread use of the SFTP protocol. While the project focuses on Microsoft Windows, the code is written using frameworks and techniques so that it will work on OS X and Linux systems with little or no modification. There is a heavy focus on GUI design and an entirely custom GUI is created. Utilises C++ and QtCreator and well as libcurl, libssh and Qt libraries. 4 | 5 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/1.png) 6 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/2.png) 7 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/3.png) 8 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/4.png) 9 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/5.png) 10 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/6.png) 11 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/7.png) 12 | ![alt tag](https://github.com/Shazib/CometFTP/blob/master/Screenshots/8.jpg) 13 | -------------------------------------------------------------------------------- /SFTPSite.cpp: -------------------------------------------------------------------------------- 1 | // Chunk Size For Transfers 2 | #define MAX_XFER_BUF_SIZE 16384 3 | 4 | #include "SFTPSite.h" 5 | 6 | //#include 7 | #include 8 | #include 9 | 10 | SFTPSite::SFTPSite(QObject *parent, std::string _host, std::string _user, std::string _pass, std::string _port) : 11 | QObject(parent) 12 | { 13 | 14 | qDebug() << "Stfp created"; 15 | //ssh_threads_set_callbacks(ssh_threads_get_pthread()); 16 | //ssh_init(); 17 | 18 | // Required variables 19 | //int verbosity = SSH_LOG_NOLOG; 20 | int portNum = atoi(port.c_str()); 21 | host = _host; 22 | user = _user; 23 | port = _port; 24 | pass = _pass; 25 | 26 | // New SSH session 27 | //my_ssh_session = ssh_new(); 28 | //if (my_ssh_session == NULL){ 29 | 30 | QMessageBox msgBox; 31 | msgBox.setText("The session could not be created"); 32 | msgBox.setInformativeText("Please check the help documentation"); 33 | msgBox.setStandardButtons(QMessageBox::Ok); 34 | msgBox.setDefaultButton(QMessageBox::Ok); 35 | msgBox.exec(); 36 | 37 | // } 38 | //Setting up session 39 | //ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host.c_str()); 40 | //ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); 41 | //ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &portNum); 42 | //ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, user.c_str()); 43 | 44 | } 45 | 46 | // Init the connection 47 | bool SFTPSite::init() 48 | { 49 | // // Connect to Site 50 | // int rc; 51 | // rc = ssh_connect(my_ssh_session); 52 | // if (rc != SSH_OK){ 53 | // // Get Error 54 | // QString temp = QString::fromUtf8(ssh_get_error(my_ssh_session)); 55 | // // Show Alert 56 | // QMessageBox msgBox; 57 | // msgBox.setText("Error calling ssh_connect"); 58 | // msgBox.setInformativeText("Click for details on the error"); 59 | // msgBox.setStandardButtons(QMessageBox::Ok); 60 | // msgBox.setDefaultButton(QMessageBox::Ok); 61 | // msgBox.setDetailedText(temp); 62 | // msgBox.exec(); 63 | 64 | // ssh_disconnect(my_ssh_session); 65 | // ssh_free(my_ssh_session); 66 | // status = false; 67 | // return false; 68 | // } else {status = true;} 69 | 70 | // // Authenticating server identity 71 | // if (verify_knownhost() < 0){ 72 | // QMessageBox msgBox; 73 | // msgBox.setText("The server could not be authenticated"); 74 | // msgBox.setInformativeText("Please check the help documentation"); 75 | // msgBox.setStandardButtons(QMessageBox::Ok); 76 | // msgBox.setDefaultButton(QMessageBox::Ok); 77 | // msgBox.exec(); 78 | 79 | // ssh_disconnect(my_ssh_session); 80 | // ssh_free(my_ssh_session); 81 | // status = false; 82 | // return false; 83 | // } else {status = true;} 84 | 85 | // // Authenticating user 86 | // if (verify_user(user,pass) < 0){ 87 | // status = false; 88 | // ssh_disconnect(my_ssh_session); 89 | // ssh_free(my_ssh_session); 90 | // return false; 91 | // } else { status = true; } 92 | 93 | // // Setup SFTP connection over SSH session 94 | 95 | // if (sftp_connection() != SSH_OK){ 96 | // status = false; 97 | // return false; 98 | // } else { return true;} 99 | 100 | } 101 | 102 | // Verify Host using SSH Key 103 | int SFTPSite::verify_knownhost() 104 | { 105 | 106 | // int state, hlen, rc; 107 | // unsigned char *hash = NULL; 108 | // QMessageBox msgBox; 109 | // state = ssh_is_server_known(my_ssh_session); // Check if key known 110 | // hlen = ssh_get_pubkey_hash(my_ssh_session, &hash); //store binary of key 111 | // if (hlen < 0){return -1;} // Check key is a key 112 | // char *publickeyhash = ssh_get_hexa(hash,hlen); 113 | // QString pubkey(publickeyhash); 114 | 115 | // switch (state) 116 | // { 117 | // case SSH_SERVER_KNOWN_OK: // The server is in the known list 118 | // free(hash);return 0; 119 | 120 | // case SSH_SERVER_KNOWN_CHANGED: 121 | // // The key has changed, must ask for user input. 122 | // msgBox.setText("Server Host Key Changed"); 123 | // msgBox.setInformativeText("The host key for the server has changed. For security you must confirm you want to continue"); 124 | // msgBox.setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel); 125 | // msgBox.setDefaultButton(QMessageBox::Ok); 126 | // msgBox.setDetailedText("The key for the server: /n" + pubkey); 127 | // rc = msgBox.exec(); 128 | // switch (rc) { 129 | // case QMessageBox::Ok: free(hash);return 0; 130 | // case QMessageBox::Cancel: free(hash);return -1; 131 | // } 132 | // free(hash); 133 | 134 | // return -1; 135 | 136 | // case SSH_SERVER_FOUND_OTHER: 137 | // // A Different Key was found, very bad, ask for input 138 | // msgBox.setText("Different Server Host Key Found"); 139 | // msgBox.setInformativeText("A different host key was found. An atacker might change the default server key to confuse your client into thinking the key does not exist. Do you wish to continue?"); 140 | // msgBox.setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel); 141 | // msgBox.setDefaultButton(QMessageBox::Ok); 142 | // msgBox.setDetailedText("The key for the server: /n" + pubkey); 143 | // rc = msgBox.exec(); 144 | // switch (rc) { 145 | // case QMessageBox::Ok: free(hash);return 0; 146 | // case QMessageBox::Cancel: free(hash);return -1; 147 | // } 148 | // free(hash); 149 | 150 | // return -1; 151 | 152 | // case SSH_SERVER_FILE_NOT_FOUND: 153 | // // A Different Key was found, very bad, ask for input 154 | // msgBox.setText("Could not find a known host file"); 155 | // msgBox.setInformativeText("If you accept the host key now,the file will be automatically created. Do you wish to continue?"); 156 | // msgBox.setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel); 157 | // msgBox.setDefaultButton(QMessageBox::Ok); 158 | // msgBox.setDetailedText("The key for the server: /n" + pubkey); 159 | // rc = msgBox.exec(); 160 | // switch (rc) { 161 | // case QMessageBox::Ok: 162 | // if (ssh_write_knownhost(my_ssh_session) < 0){ 163 | // msgBox.setText("Sorry, there was a problem saving the key"); 164 | // msgBox.setInformativeText(""); 165 | // msgBox.setStandardButtons(QMessageBox::Ok); 166 | // msgBox.setDefaultButton(QMessageBox::Ok); 167 | // msgBox.setDetailedText(""); 168 | // int rc = msgBox.exec(); 169 | // free(hash); 170 | 171 | // return -1; 172 | // } 173 | // free(hash); 174 | 175 | // return 0; 176 | // case QMessageBox::Cancel: return -1; 177 | // } 178 | // return -1; 179 | // case SSH_SERVER_NOT_KNOWN: 180 | // // Unknown server 181 | // msgBox.setText("The server is unknown"); 182 | // msgBox.setInformativeText("If you accept the host key now,the file will be automatically created. Do you trust the key?"); 183 | // msgBox.setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel); 184 | // msgBox.setDefaultButton(QMessageBox::Ok); 185 | // msgBox.setDetailedText("The key for the server: /n" + pubkey); 186 | // rc = msgBox.exec(); 187 | // switch (rc) { 188 | // case QMessageBox::Ok: 189 | // if (ssh_write_knownhost(my_ssh_session) < 0){ 190 | // msgBox.setText("Sorry, there was a problem saving the key"); 191 | // msgBox.setInformativeText(""); 192 | // msgBox.setStandardButtons(QMessageBox::Ok); 193 | // msgBox.setDefaultButton(QMessageBox::Ok); 194 | // msgBox.setDetailedText(""); 195 | // int rc = msgBox.exec(); 196 | // free(hash); 197 | 198 | // return -1; 199 | // } 200 | // free(hash); 201 | 202 | // return 0; 203 | // case QMessageBox::Cancel: return -1; 204 | // } 205 | // return -1; 206 | // case SSH_SERVER_ERROR: 207 | // msgBox.setText("There was an error with the server"); 208 | // msgBox.setInformativeText(""); 209 | // msgBox.setStandardButtons(QMessageBox::Ok); 210 | // msgBox.setDefaultButton(QMessageBox::Ok); 211 | // msgBox.setDetailedText(""); 212 | // rc = msgBox.exec(); 213 | // free(hash); 214 | 215 | // return -1; 216 | 217 | // } 218 | 219 | // free(hash); 220 | 221 | // return -1; 222 | } 223 | 224 | // Silent verify for already verififed sites 225 | int SFTPSite::silent_verify_knownhost() 226 | { 227 | // int state, hlen, rc; 228 | // unsigned char *hash = NULL; 229 | // //QMessageBox msgBox; 230 | // state = ssh_is_server_known(my_ssh_session); // Check if key known 231 | // hlen = ssh_get_pubkey_hash(my_ssh_session, &hash); //store binary of key 232 | // if (hlen < 0){return -1;} // Check key is a key 233 | // char *publickeyhash = ssh_get_hexa(hash,hlen); 234 | // QString pubkey(publickeyhash); 235 | 236 | // free(hash); 237 | 238 | // return 0; 239 | } 240 | 241 | // Silent init for background 242 | bool SFTPSite::silent_init() 243 | { 244 | /* // Connect to Site 245 | int rc; 246 | rc = ssh_connect(my_ssh_session); 247 | if (rc != SSH_OK){ 248 | // Get Error 249 | QString temp = QString::fromUtf8(ssh_get_error(my_ssh_session)); 250 | // Show Alert 251 | QMessageBox msgBox; 252 | msgBox.setText("Error calling ssh_connect"); 253 | msgBox.setInformativeText("Click for details on the error"); 254 | msgBox.setStandardButtons(QMessageBox::Ok); 255 | msgBox.setDefaultButton(QMessageBox::Ok); 256 | msgBox.setDetailedText(temp); 257 | msgBox.exec(); 258 | 259 | ssh_disconnect(my_ssh_session); 260 | ssh_free(my_ssh_session); 261 | status = false; 262 | return false; 263 | } else {status = true;} 264 | 265 | // Authenticating server identity 266 | if (silent_verify_knownhost() < 0){ 267 | QMessageBox msgBox; 268 | msgBox.setText("The server could not be authenticated"); 269 | msgBox.setInformativeText("Please check the help documentation"); 270 | msgBox.setStandardButtons(QMessageBox::Ok); 271 | msgBox.setDefaultButton(QMessageBox::Ok); 272 | msgBox.exec(); 273 | 274 | ssh_disconnect(my_ssh_session); 275 | ssh_free(my_ssh_session); 276 | status = false; 277 | return false; 278 | } else {status = true;} 279 | 280 | // Authenticating user 281 | if (verify_user(user,pass) < 0){ 282 | status = false; 283 | ssh_disconnect(my_ssh_session); 284 | ssh_free(my_ssh_session); 285 | return false; 286 | } else { status = true; } 287 | 288 | // Setup SFTP connection over SSH session 289 | 290 | if (sftp_connection() != SSH_OK){ 291 | status = false; 292 | return false; 293 | } else {*/ //return true;} 294 | 295 | } 296 | 297 | // Verify User using Password 298 | int SFTPSite::verify_user(std::string user, std::string pass) 299 | { 300 | 301 | // int rc = ssh_userauth_password(my_ssh_session, user.c_str(),pass.c_str()); 302 | // if (rc != SSH_AUTH_SUCCESS){ 303 | // QMessageBox msgBox; 304 | // msgBox.setText("Error Authenticating user"); 305 | // msgBox.setInformativeText("Please check your username and password"); 306 | // msgBox.setStandardButtons(QMessageBox::Ok); 307 | // msgBox.setDefaultButton(QMessageBox::Ok); 308 | // msgBox.exec(); 309 | // return -1; 310 | // } 311 | // return 0; 312 | } 313 | 314 | // Open SFTP session using the SSH Session 315 | int SFTPSite::sftp_connection() 316 | { 317 | 318 | 319 | // int rc; 320 | // sftp = sftp_new(my_ssh_session); 321 | 322 | // if (sftp == NULL){ 323 | // // Error allocating SFTP Session 324 | // QString error(ssh_get_error(my_ssh_session)); 325 | // return SSH_ERROR; 326 | // QMessageBox msgBox; 327 | // msgBox.setText("Error Creating SFTP"); 328 | // msgBox.setInformativeText("Click for details on the error"); 329 | // msgBox.setStandardButtons(QMessageBox::Ok); 330 | // msgBox.setDefaultButton(QMessageBox::Ok); 331 | // msgBox.setDetailedText(error); 332 | // msgBox.exec(); 333 | // return rc; 334 | // } 335 | 336 | // rc = sftp_init(sftp); 337 | // if (rc != SSH_OK){ 338 | // // Error initialising SFTP session 339 | // QString error(sftp_get_error(sftp)); 340 | // sftp_free(sftp); 341 | // QMessageBox msgBox; 342 | // msgBox.setText("Error Initing STFP"); 343 | // msgBox.setInformativeText("Click for details on the error"); 344 | // msgBox.setStandardButtons(QMessageBox::Ok); 345 | // msgBox.setDefaultButton(QMessageBox::Ok); 346 | // msgBox.setDetailedText(error); 347 | // msgBox.exec(); 348 | // return rc; 349 | // } 350 | 351 | // return SSH_OK; 352 | 353 | } 354 | 355 | int SFTPSite::sftp_listdir(QString path) 356 | { 357 | // // Initial Setup 358 | // values.clear(); 359 | // sftp_dir dir; 360 | // sftp_attributes attributes; 361 | // int rc = 0; 362 | // QByteArray ba = path.toLocal8Bit(); 363 | // const char* directoryPath = ba.data(); 364 | 365 | // // Open the Directory 366 | // dir = sftp_opendir(sftp, directoryPath); 367 | 368 | // if (!dir){ 369 | // qDebug() << "error opening directory"; 370 | // // Directory Probably Doesn't Exist! 371 | // return -1; 372 | 373 | 374 | // } else { 375 | 376 | // // Create the StringList to store the data 377 | // while ((attributes = sftp_readdir(sftp, dir)) != NULL){ 378 | 379 | // // check its not hidden. 380 | // if (strncmp(attributes->name,".",1) != 0) { 381 | 382 | // values << QString::fromStdString(attributes->name) << 383 | // QString::number(attributes->size) << 384 | // //getPermissions(attributes->permissions) << 385 | // QString::number(attributes->permissions) << 386 | // QString::fromStdString(attributes->owner) << 387 | // getType(attributes->type); 388 | // rc++; 389 | // } 390 | // } 391 | 392 | // sftp_closedir(dir); 393 | // sftp_attributes_free(attributes); 394 | // qDebug() << "Number of Rows" << rc; 395 | 396 | // return rc; 397 | // } 398 | } 399 | 400 | // Get Permissions in Human Readable syntax 401 | QString SFTPSite::getPermissions(uint32_t permissions) 402 | { 403 | 404 | // // Converting the decimal returned by libssh into an octal. 405 | // int rem, i=1, octal= 0; 406 | 407 | // while (permissions != 0){ 408 | // rem = permissions%8; 409 | // permissions /= 8; 410 | // octal+= rem * i; 411 | // i *= 10; 412 | // } 413 | 414 | // // Reading the octal into a string 415 | 416 | // // last three digits for permissions. 417 | // QString temp = QString::number(octal); 418 | // QString final = ""; 419 | // i = temp.count(); 420 | 421 | // // Add each set of permissions to string 422 | // for (int a=3; a >= 1; a--){ 423 | 424 | // switch(temp[i-a].digitValue()) 425 | // { 426 | // case 0: 427 | // final.append(QString("---")); 428 | // break; 429 | // case 1: 430 | // final.append(QString("--x")); 431 | // break; 432 | // case 2: 433 | // final.append(QString("-w-")); 434 | // break; 435 | // case 3: 436 | // final.append(QString("-wx")); 437 | // break; 438 | // case 4: 439 | // final.append(QString("r--")); 440 | // break; 441 | // case 5: 442 | // final.append(QString("r-x")); 443 | // break; 444 | // case 6: 445 | // final.append(QString("rw-")); 446 | // break; 447 | // case 7: 448 | // final.append(QString("rwx")); 449 | // break; 450 | 451 | // } 452 | // } 453 | 454 | // // Return the correct string 455 | // return final; 456 | 457 | } 458 | 459 | // Get File Type 460 | QString SFTPSite::getType(uint8_t type) 461 | { 462 | // switch(type) 463 | // { 464 | // case SSH_FILEXFER_TYPE_DIRECTORY: 465 | // return QString("Folder"); 466 | // case SSH_FILEXFER_TYPE_REGULAR: 467 | // return QString("File"); 468 | // case SSH_FILEXFER_TYPE_SYMLINK: 469 | // return QString("Symlink"); 470 | // case SSH_FILEXFER_TYPE_SPECIAL: 471 | // return QString("Special"); 472 | // case SSH_FILEXFER_TYPE_UNKNOWN: 473 | // return QString("Unknown"); 474 | // } 475 | } 476 | 477 | // Cleanup before deletion 478 | void SFTPSite::cleanup() 479 | { 480 | // sftp_free(sftp); 481 | // ssh_disconnect(my_ssh_session); 482 | // ssh_free(my_ssh_session); 483 | } 484 | 485 | // Public Access Method 486 | QPair SFTPSite::listDir(QString path) 487 | { 488 | // int a = sftp_listdir(path); 489 | 490 | // return { a, values}; 491 | } 492 | 493 | // Download a file 494 | int SFTPSite::downloadfile(QString source, QString Destination) 495 | { 496 | // int res = DLOAD_OVERWRITE; 497 | // // Check if the file exists locally first 498 | 499 | // // Temp strings 500 | 501 | 502 | // // Get Filename. 503 | // QStringList split = source.split("/"); 504 | // //split.removeLast(); 505 | // QString fileName = split.last(); 506 | // qDebug() << "Source " << source; 507 | // qDebug() << "File name " << fileName; 508 | // // Check if file exists locally 509 | // QString localPath = Destination + "/" + fileName; 510 | // qDebug() << "Local Path " << localPath; 511 | // QFile file; 512 | // file.setFileName(localPath); 513 | 514 | // // Check if folder exists. 515 | // QDir dir(Destination); 516 | // if (!dir.exists()){ 517 | // dir.mkdir(Destination); 518 | // } 519 | 520 | // // Now we can continue to download the file 521 | // if (res == DLOAD_OVERWRITE){ 522 | 523 | // QThread* thread = new QThread(this); 524 | // QTimer* timer= new QTimer(0); 525 | // timer->setInterval(5000); 526 | // timer->moveToThread(thread); 527 | // QObject::connect(timer,SIGNAL(timeout()),this,SLOT(receiveTimer()),Qt::DirectConnection); 528 | // QObject::connect(thread,SIGNAL(started()),timer,SLOT(start())); 529 | // thread->start(); 530 | 531 | 532 | 533 | 534 | // int result; 535 | // int access_type; 536 | // sftp_file file; // file handle 537 | // char buffer[MAX_XFER_BUF_SIZE]; // Buffer where files are written 538 | // int nbytes; // num bytes transferred 539 | 540 | // // Counting bytes for progress bar 541 | // sftp_attributes attributes; 542 | // attributes = sftp_stat(sftp,source.toLocal8Bit().data()); 543 | // uint64_t fileSize = attributes->size; 544 | // int percent = fileSize / 100; 545 | // int percentCounter = 0; 546 | 547 | // // Open local file for writing 548 | // FILE* fp; 549 | // fp = fopen(localPath.toLocal8Bit().data(),"ab"); 550 | // // Error Checking 551 | // if (fp == NULL){ qDebug() << "File is null"; } 552 | 553 | // // Open SFTP file 554 | // access_type = O_RDONLY; // Read Only 555 | // file = sftp_open(sftp, source.toLocal8Bit().data(),access_type,0); 556 | // if (file == NULL) { 557 | // // Can't open file 558 | // ssh_get_error(my_ssh_session); 559 | // qDebug() << SSH_ERROR; 560 | // } 561 | 562 | 563 | // for(;;) { 564 | // if (pause){ 565 | // usleep(100000); 566 | // } else { 567 | 568 | // nbytes = sftp_read(file,buffer, sizeof(buffer)); 569 | // if (nbytes == 0){ 570 | // qDebug() << "EOF"; 571 | // break; // EOF 572 | // } else if (nbytes < 0){ 573 | // // Error 574 | // sftp_close(file); 575 | // qDebug() << "error closing file"; 576 | // } 577 | // result = fwrite(buffer,1,nbytes,fp); 578 | // totalBytes+=nbytes; 579 | // percentCounter = percentCounter + nbytes; 580 | // if (percentCounter >= percent){ 581 | // percentCounter = 0; 582 | // emit updateProgress(); 583 | // //qDebug() << this->thread(); 584 | // } 585 | 586 | // // Cancel 587 | 588 | // if (cancel) { 589 | // // Cancel Download 590 | // fclose(fp); 591 | // remove(localPath.toLocal8Bit().data()); 592 | // sftp_close(file); 593 | // // emit updateProgress(); 594 | // thread->terminate(); 595 | // return DLOAD_CANCEL; 596 | 597 | // } 598 | 599 | // } 600 | // } 601 | 602 | // // Close files 603 | // fclose(fp); 604 | // sftp_close(file); 605 | 606 | // thread->terminate(); 607 | // } 608 | 609 | // return DLOAD_COMPLETE; 610 | 611 | 612 | 613 | } 614 | 615 | // Upload a file 616 | int SFTPSite::uploadFile(QString source, QString destination) 617 | { 618 | // qDebug() << "Source: " << source; 619 | // qDebug() << "dest: " << destination; 620 | 621 | // qDebug() << "Starting Upload method"; 622 | // int res = DLOAD_OVERWRITE; 623 | 624 | // QThread* thread = new QThread(this); 625 | // QTimer* timer= new QTimer(0); 626 | // timer->setInterval(5000); 627 | // timer->moveToThread(thread); 628 | // QObject::connect(timer,SIGNAL(timeout()),this,SLOT(receiveTimer()),Qt::DirectConnection); 629 | // QObject::connect(thread,SIGNAL(started()),timer,SLOT(start())); 630 | // thread->start(); 631 | // qDebug() << "Timer started"; 632 | 633 | // // Check if file exists on server 634 | // int access_type = O_WRONLY | O_CREAT | O_TRUNC; 635 | // QStringList split = source.split("/"); 636 | // QString fileName = split.last(); 637 | // sftp_file file; 638 | // sftp_attributes attrib; 639 | // FILE* fp; 640 | // // Destination full path 641 | // QString serverPath = destination + fileName; 642 | 643 | // qDebug() << "got full path"; 644 | 645 | // // Check if folder exists on server 646 | // //file = sftp_open(sftp, serverPath.toLocal8Bit().data(),access_type,0); 647 | 648 | // sftp_dir dir; 649 | // dir = sftp_opendir(sftp, destination.toLocal8Bit().data()); 650 | 651 | // if (dir != NULL){ 652 | // // Is a directory 653 | // } else { 654 | // // MkDir 655 | // int a = makeDir(destination); 656 | // qDebug() << "Made folder"; 657 | // //if (a != 0) {return DLOAD_ERROR;} 658 | // } 659 | 660 | // qDebug() << "done with checking"; 661 | 662 | // // Carry on with Upload 663 | // //sftp_attributes_free(attrib); 664 | // // sftp_close(file); 665 | // qDebug() << "Serverpath " << serverPath; 666 | // file = sftp_open(sftp, serverPath.toLocal8Bit().data(),access_type, S_IWUSR); 667 | 668 | // if (file == NULL){ 669 | // qDebug() << "Can't open file for writing"; 670 | // qDebug() << ssh_get_error(my_ssh_session); 671 | // thread->terminate(); 672 | // return SSH_ERROR; 673 | // } 674 | // qDebug() << "SFTP File opened"; 675 | 676 | 677 | // fp = fopen(source.toLocal8Bit().data(),"rb"); 678 | // fseek (fp,0,SEEK_END); 679 | // long size = ftell(fp); 680 | // int fileSize = (int)size; 681 | // int percent = fileSize / 100; 682 | // int percentCounter = 0; 683 | // rewind(fp); 684 | // int nbytes; 685 | // char* buffer[MAX_XFER_BUF_SIZE]; 686 | 687 | // nbytes = fread(buffer,1,MAX_XFER_BUF_SIZE,fp); 688 | // for (;;){ 689 | 690 | // totalBytes+=nbytes; 691 | // percentCounter = percentCounter + nbytes; 692 | // if (percentCounter >= percent){ 693 | // percentCounter = 0; 694 | // emit updateProgress(); 695 | // //qDebug() << this->thread(); 696 | // } 697 | // if (pause){ 698 | // usleep(100000); 699 | // } else { 700 | 701 | 702 | // sftp_write(file,buffer,nbytes); 703 | // nbytes = fread(buffer,1,MAX_XFER_BUF_SIZE,fp); 704 | 705 | // if (cancel){ 706 | // sftp_unlink(sftp,serverPath.toLocal8Bit().data()); 707 | // sftp_close(file); 708 | // fclose(fp); 709 | // thread->terminate(); 710 | // return DLOAD_CANCEL; 711 | 712 | // } 713 | // if (feof(fp)){ 714 | // break; 715 | // } 716 | 717 | // } 718 | 719 | // } 720 | 721 | // fclose(fp); 722 | // sftp_close(file); 723 | // thread->terminate(); 724 | // return DLOAD_COMPLETE; 725 | 726 | } 727 | 728 | // Return list of files only 729 | int SFTPSite::sftp_getAllFiles(QString path, QString destination) 730 | { 731 | // // Initial Setup 732 | // globalServer = path; 733 | // globalLocal = destination; 734 | 735 | // sftp_dir dir; 736 | // sftp_attributes attributes; 737 | // int rc = 0; 738 | // QByteArray ba = path.toLocal8Bit(); 739 | // const char* directoryPath = ba.data(); 740 | 741 | // // Open the Directory 742 | // dir = sftp_opendir(sftp, directoryPath); 743 | 744 | // // Check successful opening 745 | // if (!dir){ 746 | // qDebug() << "error opening directory"; 747 | // // Directory Probably Doesn't Exist! 748 | // return -1; 749 | // } else { 750 | 751 | // // Read the directory, 1 file at a time 752 | // while ((attributes = sftp_readdir(sftp, dir)) != NULL){ 753 | 754 | // // Check its not hidden. 755 | // if (strncmp(attributes->name,".",1) != 0) { 756 | // // If is file 757 | // if (attributes->type == SSH_FILEXFER_TYPE_REGULAR){ 758 | // // Add Paths 759 | // qDebug() << globalLocal + QString::fromStdString(attributes->name); 760 | // qDebug() << globalServer + QString::fromStdString(attributes->name); 761 | 762 | // values << (globalServer + QString::fromStdString(attributes->name)) 763 | // << globalLocal; 764 | 765 | // } 766 | // // If is dir 767 | // if (attributes->type == SSH_FILEXFER_TYPE_DIRECTORY){ 768 | // newDir = QString::fromStdString(attributes->name) + "/"; 769 | // qDebug() << "newdir is" << newDir; 770 | // globalLocal = globalLocal + newDir; 771 | // globalServer = globalServer + newDir; 772 | // // Recursive function call 773 | // sftp_getAllFiles(globalServer,globalLocal); 774 | 775 | 776 | // } 777 | 778 | // rc++; 779 | // } 780 | // } 781 | // // Once loop completes, reset path; 782 | // globalLocal.remove((globalLocal.count()-newDir.count()),newDir.count()); 783 | // globalServer.remove((globalServer.count()-newDir.count()),newDir.count()); 784 | // newDir = ""; 785 | 786 | // // Cleanup 787 | // sftp_closedir(dir); 788 | // sftp_attributes_free(attributes); 789 | 790 | // } 791 | 792 | // return rc; 793 | } 794 | 795 | // Make a directory 796 | int SFTPSite::makeDir(QString path) 797 | { 798 | // sftp_mkdir(sftp,path.toLocal8Bit().data(),S_IRWXU); 799 | } 800 | 801 | // Public Accessors 802 | QStringList SFTPSite::getAllFiles(QString path, QString destination) 803 | { 804 | // values.clear(); 805 | // sftp_getAllFiles(path, destination); 806 | // return values; 807 | } 808 | /* 809 | int SFTPSite::dloadFile(QString source, QString dest) 810 | { 811 | int a = downloadfile(source,dest); 812 | if ( a == DLOAD_COMPLETE || a == DLOAD_CANCEL){ 813 | emit downloadComplete(a); 814 | } 815 | } 816 | 817 | int SFTPSite::uloadFile(QString source, QString dest) 818 | { 819 | int a = uploadFile(source,dest); 820 | if (a == DLOAD_COMPLETE || a == DLOAD_CANCEL){ 821 | emit downloadComplete(a); 822 | } 823 | 824 | } 825 | */ 826 | // Slots for threaded download/upload handling 827 | void SFTPSite::startDownload(QString source, QString destination) 828 | { 829 | // qDebug() << "Download in sftp started"; 830 | // int a = downloadfile(source, destination); 831 | // emit downloadComplete(a); 832 | // qDebug() << "signal emit"; 833 | } 834 | 835 | void SFTPSite::startUpload(QString source, QString destination) 836 | { 837 | // int a = uploadFile(source,destination); 838 | // if (a == DLOAD_COMPLETE || a == DLOAD_CANCEL){ 839 | // emit downloadComplete(a); 840 | // } 841 | 842 | } 843 | 844 | void SFTPSite::threadInit(std::string _host, std::string _user, std::string _pass, std::string _port) 845 | { 846 | // host = _host; 847 | // user = _user; 848 | // pass = _pass; 849 | // port= _port; 850 | // int portNum = atoi(port.c_str()); 851 | // ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host.c_str()); 852 | // //ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); 853 | // ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &portNum); 854 | // ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, user.c_str()); 855 | // this->silent_init(); 856 | // qDebug() << "Thread SFTP Init"; 857 | 858 | } 859 | 860 | void SFTPSite::cancelDownload() 861 | { 862 | // cancel = !cancel; 863 | } 864 | 865 | void SFTPSite::pauseDownload() 866 | { 867 | // pause = !pause; 868 | } 869 | 870 | void SFTPSite::receiveTimer() 871 | { 872 | // emit sendSpeed(totalBytes); 873 | // qDebug() << "sending Speed"; 874 | // mutex.lock(); 875 | // totalBytes = 0; 876 | // mutex.unlock(); 877 | } 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | -------------------------------------------------------------------------------- /SFTPSite.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_SFTPSITE_H 2 | #define COMET_SFTPSITE_H 3 | 4 | #include 5 | //#include 6 | //#include 7 | #include 8 | 9 | class SFTPSite : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit SFTPSite(QObject *parent = 0, std::string host = "", std::string user = "", std::string pass ="", std::string port = ""); 14 | 15 | public slots: 16 | void startDownload(QString source, QString destination); 17 | void startUpload(QString source, QString destination); 18 | void threadInit(std::string _host, std::string _user, std::string _pass, std::string _port); 19 | void cancelDownload(); 20 | void pauseDownload(); 21 | void receiveTimer(); 22 | 23 | 24 | signals: 25 | void downloadComplete(int status); 26 | void updateProgress(); 27 | void sendSpeed(int bytes); 28 | 29 | private: 30 | int sftp_getAllFiles(QString path, QString destination); 31 | // ssh_session my_ssh_session; 32 | // sftp_session sftp; 33 | int verify_knownhost(); 34 | int verify_user(std::string user, std::string pass); 35 | int silent_verify_knownhost(); 36 | int sftp_connection(); 37 | //int sftp_upload 38 | QString getPermissions(uint32_t permissions); 39 | QString getType(uint8_t type); 40 | QStringList values; 41 | int sftp_listdir(QString path); 42 | std::string host, user, pass, port; 43 | int downloadfile(QString source, QString Destination); 44 | enum returnCodes { 45 | DLOAD_FILE_EXISTS, 46 | DLOAD_COMPLETE, 47 | DLOAD_FAILED, 48 | DLOAD_OVERWRITE, 49 | DLOAD_CANCEL, 50 | DLOAD_ERROR 51 | }; 52 | bool cancel = false; 53 | bool pause = false; 54 | QMutex mutex; 55 | int totalBytes; 56 | int uploadFile(QString source, QString destination); 57 | 58 | 59 | public: 60 | QString globalServer; 61 | QString globalLocal; 62 | QString newDir; 63 | bool status; 64 | bool init(); 65 | bool silent_init(); 66 | void cleanup(); 67 | QPair listDir(QString path); 68 | int numRows; 69 | int isDir(QString fileName); 70 | QStringList getAllFiles(QString path, QString destination); 71 | // int dloadFile(QString source, QString dest); 72 | // int uloadFile(QString source, QString dest); 73 | int makeDir(QString path); 74 | }; 75 | 76 | #endif // COMET_SFTPSITE_H 77 | -------------------------------------------------------------------------------- /Screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/1.png -------------------------------------------------------------------------------- /Screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/2.png -------------------------------------------------------------------------------- /Screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/3.png -------------------------------------------------------------------------------- /Screenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/4.png -------------------------------------------------------------------------------- /Screenshots/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/5.png -------------------------------------------------------------------------------- /Screenshots/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/6.png -------------------------------------------------------------------------------- /Screenshots/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/7.png -------------------------------------------------------------------------------- /Screenshots/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/Screenshots/8.jpg -------------------------------------------------------------------------------- /ServerBrowser.cpp: -------------------------------------------------------------------------------- 1 | #include "ServerBrowser.h" 2 | 3 | 4 | ServerBrowser::ServerBrowser(QWidget *parent) : 5 | QWidget(parent) 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /ServerBrowser.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_SERVERBROWSER_H 2 | #define COMET_SERVERBROWSER_H 3 | 4 | #include 5 | #include 6 | 7 | class ServerBrowser : public QWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit ServerBrowser(QWidget *parent = 0); 12 | ~ServerBrowser(); 13 | 14 | 15 | signals: 16 | 17 | public slots: 18 | 19 | }; 20 | 21 | #endif // COMET_SERVERBROWSER_H 22 | -------------------------------------------------------------------------------- /ServerExplorer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This Class shows the server-side file browser 3 | * as well as the connect panel and bookmarks areas 4 | * a sliding widget is used to change between bookmarks and connect area 5 | * another sliding widget is used to change between site explorer and boomark/connect 6 | * 7 | * Some styles here are required to be inline as they change. 8 | */ 9 | #include "ServerExplorer.h" 10 | //#include 11 | 12 | 13 | ServerExplorer::ServerExplorer(QWidget *parent) : 14 | QWidget(parent) 15 | { 16 | // Initial Setup 17 | int _min=500; 18 | int _max=1500; 19 | animTime=(_min+_max)>>1; 20 | mainDir = "/"; 21 | 22 | QCoreApplication::setOrganizationName("BCU"); 23 | QCoreApplication::setApplicationName("CometFTP"); 24 | QCoreApplication::setApplicationVersion("0.0.1"); 25 | 26 | // Main Slider Setup 27 | mainSlider = new SlidingStackedWidget(this); 28 | QVBoxLayout* mainLayout = new QVBoxLayout(); 29 | 30 | // Setup Slides For Main Slider 31 | setupSiteManager(); 32 | explorerSlide = new QWidget(); 33 | 34 | // Add Slides to Main Slider 35 | mainSlider->addWidget(siteManager); 36 | mainSlider->addWidget(explorerSlide); 37 | 38 | // Setup this Widget with main slider 39 | mainLayout->addWidget(mainSlider); 40 | mainLayout->setContentsMargins(0,0,0,0); 41 | this->setLayout(mainLayout); 42 | 43 | 44 | // Load Bookmarks 45 | QSettings settings; 46 | QVariant a = settings.value("bookmarks"); 47 | bookmarks = settings.value("bookmark").toStringList(); 48 | 49 | 50 | } 51 | 52 | 53 | // Setup site manager widget (includes a slider) 54 | // Includes connect area and bookmarks area. 55 | void ServerExplorer::setupSiteManager() 56 | { 57 | // Setup Toolbar 58 | QHBoxLayout* toolbarLayout = new QHBoxLayout(); 59 | toolbar = new QFrame(); 60 | toolbar->setFixedHeight(22); 61 | toolbar->setObjectName("Explorer_Toolbar"); 62 | 63 | // Bookmark Button 64 | QIcon bookmarkIcon = QIcon(":/images/Menu.svg"); 65 | bookmarkBtn = new QPushButton(" Bookmarks ", this); 66 | bookmarkBtn->setStyle(QStyleFactory::create("Fusion")); 67 | bookmarkBtn->setIcon(bookmarkIcon); 68 | bookmarkBtn->setStyleSheet("QPushButton{border-style:none; text-align:center;padding-top:2px; padding-bottom:4px; background-color:#cdcdcd; } "); 69 | 70 | // SFTP Button 71 | QIcon sftpIcon = QIcon(":/images/Screen.svg"); 72 | sftpBtn = new QPushButton(" SFTP ", this); 73 | sftpBtn->setStyle(QStyleFactory::create("Fusion")); 74 | sftpBtn->setIcon(sftpIcon); 75 | sftpBtn->setStyleSheet("QPushButton{border-style:none; text-align:center; padding-top:2px; padding-bottom:4px; }" ); 76 | 77 | toolbarLayout->addWidget(bookmarkBtn); 78 | toolbarLayout->addWidget(sftpBtn); 79 | toolbarLayout->setAlignment(Qt::AlignTop); 80 | toolbarLayout->setContentsMargins(0,0,0,0); 81 | toolbar->setLayout(toolbarLayout); 82 | 83 | 84 | 85 | // Setup Slider with bookmarks and connect 86 | 87 | // Init Slider 88 | SlidingStackedWidget* managerSlider = new SlidingStackedWidget(this); 89 | managerSlider->setObjectName("Server_Slider"); 90 | QWidget* bookmarkSlide = new QWidget(); 91 | QWidget* connectSlide = new QWidget(); 92 | 93 | // Setup Connect Area 94 | host = new QLineEdit(); 95 | host->setPlaceholderText("Host"); 96 | host->setFixedWidth(200); 97 | host->setStyle(QStyleFactory::create("Fusion")); 98 | user = new QLineEdit(); 99 | user->setPlaceholderText("User"); 100 | user->setFixedWidth(200); 101 | user->setStyle(QStyleFactory::create("Fusion")); 102 | password = new QLineEdit(); 103 | password->setPlaceholderText("Password"); 104 | password->setFixedWidth(200); 105 | password->setStyle(QStyleFactory::create("Fusion")); 106 | password->setEchoMode(QLineEdit::Password); 107 | password->setInputMethodHints(Qt::ImhHiddenText|Qt::ImhNoPredictiveText|Qt::ImhNoAutoUppercase); 108 | port = new QLineEdit(); 109 | port->setPlaceholderText("Port"); 110 | port->setFixedWidth(200); 111 | port->setStyle(QStyleFactory::create("Fusion")); 112 | QIntValidator *val = new QIntValidator(0,99999,this); 113 | port->setValidator(val); 114 | // Setup Connect Buttons 115 | connectBtn = new QPushButton("Connect"); 116 | connectBtn->setStyle(QStyleFactory::create("Fusion")); 117 | connectBookmarkBtn = new QPushButton("Bookmark"); 118 | connectBookmarkBtn->setStyle(QStyleFactory::create("Fusion")); 119 | 120 | // Setup connect layout 121 | QVBoxLayout* connectLayout = new QVBoxLayout(); 122 | QHBoxLayout* connectBtnsLayout = new QHBoxLayout(); 123 | connectBtnsLayout->addWidget(connectBtn); 124 | connectBtnsLayout->addWidget(connectBookmarkBtn); 125 | connectLayout->addWidget(host); 126 | connectLayout->addWidget(user); 127 | connectLayout->addWidget(password); 128 | connectLayout->addWidget(port); 129 | connectLayout->addLayout(connectBtnsLayout); 130 | connectLayout->setAlignment(Qt::AlignCenter); 131 | connectLayout->setContentsMargins(0,0,0,0); 132 | 133 | // Setup bookmark area 134 | // Get bookmarks 135 | 136 | QHBoxLayout* mainBookmarkLayout = new QHBoxLayout(); 137 | QHBoxLayout* leftBookmarkLayout = new QHBoxLayout(); 138 | QVBoxLayout* rightBookmarkLayout = new QVBoxLayout(); 139 | 140 | serverLbl = new QLabel(); 141 | userLbl = new QLabel(); 142 | bookmarkConnect = new QPushButton(); 143 | bookmarkConnect->setText("Connect"); 144 | bookmarkTable = new QListWidget(); 145 | bookmarkTable->setFixedWidth(100); 146 | rightBookmarkLayout->addWidget(serverLbl); 147 | rightBookmarkLayout->addWidget(userLbl); 148 | rightBookmarkLayout->addWidget(bookmarkConnect); 149 | leftBookmarkLayout->addWidget(bookmarkTable); 150 | rightBookmarkLayout->setAlignment(Qt::AlignCenter); 151 | 152 | setBookmarks(); 153 | setTableData(); 154 | 155 | mainBookmarkLayout->addLayout(leftBookmarkLayout); 156 | mainBookmarkLayout->addLayout(rightBookmarkLayout); 157 | bookmarkSlide->setLayout(mainBookmarkLayout); 158 | QObject::connect(bookmarkTable,SIGNAL(currentRowChanged(int)),this,SLOT(updateBookmarkView(int))); 159 | 160 | // Setup slides 161 | connectSlide->setLayout(connectLayout); 162 | 163 | // Add widgets to managerSlider 164 | managerSlider->addWidget(connectSlide); 165 | managerSlider->addWidget(bookmarkSlide); 166 | 167 | // Add slider to siteManager widget 168 | siteManager = new QWidget(); 169 | siteManager->setObjectName("Server_Widget"); 170 | QVBoxLayout* mainLayout = new QVBoxLayout(); 171 | 172 | siteManager->setLayout(mainLayout); 173 | mainLayout->addWidget(toolbar); 174 | mainLayout->addWidget(managerSlider); 175 | mainLayout->setContentsMargins(0,0,0,0); 176 | 177 | 178 | // Create Connections 179 | QObject::connect(bookmarkBtn,SIGNAL(clicked()),this,SLOT(bookmarkBtnPressed())); 180 | QObject::connect(sftpBtn,SIGNAL(clicked()),this,SLOT(sftpBtnPressed())); 181 | QObject::connect(bookmarkBtn, SIGNAL(clicked()),managerSlider,SLOT(slideInNext())); 182 | QObject::connect(sftpBtn, SIGNAL(clicked()),managerSlider, SLOT(slideInPrev())); 183 | QObject::connect(connectBtn, SIGNAL(clicked()),this,SLOT(connectBtnPressed())); 184 | QObject::connect(connectBookmarkBtn, SIGNAL(clicked()),this,SLOT(addBookmark())); 185 | 186 | 187 | managerSlider->setSpeed(animTime); 188 | managerSlider->setWrap(false); 189 | } 190 | 191 | // Handling Button Presses 192 | void ServerExplorer::bookmarkBtnPressed() 193 | { 194 | // Set Styling 195 | bookmarkBtn->setStyleSheet("QPushButton{border-style:none; text-align:center;padding-top:2px; padding-bottom:4px; background-color:#ebebeb;}"); 196 | sftpBtn->setStyleSheet("QPushButton{border-style:none; text-align:center; padding-top:2px;padding-bottom:4px; background-color:#cdcdcd;}"); 197 | 198 | 199 | 200 | } 201 | 202 | void ServerExplorer::sftpBtnPressed() 203 | { 204 | // Setup Style 205 | bookmarkBtn->setStyleSheet("QPushButton{border-style:none; text-align:center;padding-top:2px;padding-bottom:4px; background-color:#cdcdcd;}"); 206 | sftpBtn->setStyleSheet("QPushButton{border-style:none; text-align:center; padding-top:2px;padding-bottom:4px; background-color:#ebebeb;}"); 207 | 208 | // Switch to sftp slide 209 | 210 | } 211 | 212 | void ServerExplorer::connectBtnPressed() 213 | { 214 | // When connect is pressed, the login details are passed 215 | 216 | _host = host->text().toLocal8Bit().constData(); 217 | _user = user->text().toLocal8Bit().constData(); 218 | _password = password->text().toLocal8Bit().constData(); 219 | _port = port->text().toLocal8Bit().constData(); 220 | 221 | emit sendCredentials(_host, _user, _password, _port); 222 | 223 | // Setup SFTPSite class connection 224 | site = new SFTPSite(this,_host, _user, _password, _port); 225 | if( !site->init()) { 226 | // ERROR 227 | } else { 228 | // SUCCESS 229 | 230 | 231 | // Setup Explorer slide 232 | table = new QTableView(this); 233 | table->verticalHeader()->hide(); 234 | table->horizontalHeader()->setVisible(true); 235 | table->horizontalHeader()->show(); 236 | table->setSelectionBehavior(QAbstractItemView::SelectRows); 237 | table->setSelectionMode(QAbstractItemView::SingleSelection); 238 | table->setShowGrid(false); 239 | table->setAlternatingRowColors(true); 240 | //table->setStyle(QStyleFactory::create("Fusion")); 241 | table->setObjectName("ServerTableView"); 242 | table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); 243 | table->verticalHeader()->setDefaultSectionSize(18); 244 | 245 | 246 | // Testing Drag Drop 247 | 248 | //table->setDragDropMode(QAbstractItemView::DragDrop); 249 | table->setDragEnabled(true); 250 | table->viewport()->setAcceptDrops(true); 251 | table->setDropIndicatorShown(true); 252 | 253 | 254 | // table->setSortingEnabled(true); 255 | 256 | // Setup initial root directory view 257 | QPair pair = site->listDir("/"); 258 | model = new ServerFileModel(this, pair.first, pair.second, "/"); 259 | 260 | table->setModel(model); 261 | 262 | // Switch Main Slider; 263 | QVBoxLayout* mainExplorerLayout = new QVBoxLayout(); 264 | mainExplorerLayout->setContentsMargins(0,0,0,0); 265 | mainExplorerLayout->setSpacing(0); 266 | 267 | // Address Bar 268 | addressBar = new AddressBar(0,true,"/"); 269 | QObject::connect(addressBar,SIGNAL(updatedPath(QString)),this,SLOT(updatedPath(QString))); 270 | 271 | mainExplorerLayout->addWidget(addressBar); 272 | mainExplorerLayout->addWidget(table); 273 | explorerSlide->setLayout(mainExplorerLayout); 274 | mainSlider->slideInNext(); 275 | 276 | // Connect Table Click event 277 | QObject::connect(table,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(rowSelected(QModelIndex))); 278 | QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString,QString))); 279 | } 280 | 281 | } 282 | 283 | void ServerExplorer::updatedPath(QString path) 284 | { 285 | QPair pair = site->listDir(path); 286 | if (pair.first == -1){ // Dir doesn't exist 287 | // Reset Address Bar 288 | addressBar->updatePath(mainDir); 289 | } else { 290 | delete model; 291 | model = new ServerFileModel(this,pair.first, pair.second, path); 292 | QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString,QString))); 293 | mainDir = path; 294 | table->setModel(model); 295 | } 296 | 297 | } 298 | 299 | // Handle Clicks on folders in table 300 | void ServerExplorer::rowSelected(const QModelIndex indx) { 301 | 302 | if (indx.model()->data(indx.model()->index(indx.row(),4,indx),Qt::DisplayRole).toString() == QString("Folder")){ 303 | 304 | // Set Main Dir String 305 | 306 | mainDir +=indx.model()->data(indx.model()->index(indx.row(),0,indx),Qt::DisplayRole).toString(); 307 | mainDir += "/"; 308 | // Cleanup old model, set with new data. 309 | delete model; 310 | QPair pair = site->listDir(mainDir); 311 | model = new ServerFileModel(this,pair.first, pair.second, mainDir); 312 | QObject::connect(model,SIGNAL(sendDropData(QString,QString,QString,QString)),this,SLOT(receiveDropData(QString,QString,QString,QString))); 313 | table->setModel(model); 314 | 315 | // Update AddressBar 316 | addressBar->updatePath(mainDir); 317 | 318 | 319 | } 320 | 321 | } 322 | 323 | //Slot to recieve drop data from model 324 | void ServerExplorer::receiveDropData(QString type, QString source, QString destination, QString sftpType) 325 | { 326 | // Send Data To Parent 327 | qDebug() << "Data recieved"; 328 | emit sendDropData(type,source,destination,sftpType); 329 | } 330 | 331 | 332 | // Bookmark data 333 | void ServerExplorer::addBookmark() 334 | { 335 | QString temp = host->text(); 336 | if (!temp.isEmpty()) { 337 | qDebug() << "add bookmark"; 338 | // Save bookmark 339 | QSettings settings; 340 | QStringList values = settings.value("bookmark").toStringList(); 341 | values << host->text() << user->text() << encrypt(password->text()) << port->text(); 342 | settings.setValue("bookmark",values); 343 | 344 | qDebug() << "bookmark Added to settings: " << host->text() << " " << user->text() << " " << encrypt(password->text()) << " " << port->text(); 345 | 346 | setBookmarks(); 347 | } 348 | 349 | } 350 | 351 | QString ServerExplorer::encrypt(QString pass) 352 | { 353 | unsigned char ckey[] = "\x09\x8F\x6B\xCD\x46\x21\xD3\x73\xCA\xDE\x4E\x83\x26\x27\xB4\xF6"; 354 | const char* password = pass.toLocal8Bit().constData(); 355 | unsigned char encrypted[strlen(password)]; 356 | unsigned char out[strlen(password)]; 357 | //AES_KEY enc_key; 358 | //AES_set_encrypt_key(ckey,128,&enc_key); 359 | //AES_set_decrypt_key(ckey,128,&dec_key); 360 | // AES_encrypt((unsigned char*) password ,encrypted, &enc_key); 361 | //AES_decrypt(encrypted, out, &dec_key); 362 | return QString::fromLocal8Bit((char*)encrypted); 363 | } 364 | 365 | QString ServerExplorer::decrypt(QString encryptedPassword) 366 | { 367 | unsigned char ckey[] = "\x09\x8F\x6B\xCD\x46\x21\xD3\x73\xCA\xDE\x4E\x83\x26\x27\xB4\xF6"; 368 | // qDebug() << "Got Key"; 369 | unsigned char* encryptedPass = (unsigned char*)encryptedPassword.toLocal8Bit().data(); 370 | // qDebug() << "Got pass"; 371 | unsigned char out[strlen(encryptedPassword.toLocal8Bit().data())]; 372 | // qDebug() << "got output variable"; 373 | //AES_KEY dec_key; 374 | // qDebug() << "got decrypt key"; 375 | //AES_set_encrypt_key(ckey,128,&enc_key); 376 | // AES_set_decrypt_key(ckey,128,&dec_key); 377 | // qDebug() << "set key"; 378 | //AES_encrypt((unsigned char*) password ,encrypted, &enc_key); 379 | 380 | // AES_decrypt(encryptedPass, out, &dec_key); 381 | 382 | // qDebug() << "Decrypted"; 383 | 384 | return "hello";//QString::fromLocal8Bit((char*)out); 385 | 386 | } 387 | 388 | void ServerExplorer::setBookmarks() 389 | { 390 | bookmarks.clear(); 391 | int counter = 0; 392 | QSettings settings; 393 | 394 | foreach(QString a,settings.value("bookmark").toStringList() ){ 395 | counter++; 396 | if (counter == 3){ 397 | counter = 0; 398 | bookmarks << decrypt(a); 399 | } 400 | else { 401 | bookmarks << a; 402 | } 403 | } 404 | qDebug() << "bookmarks loaded from settings"; 405 | qDebug() << "count of bookmark list " << bookmarks.count(); 406 | setTableData(); 407 | } 408 | 409 | void ServerExplorer::updateBookmarkView(int row) 410 | { 411 | int a = row; 412 | //Start value = a * 4; 413 | 414 | serverLbl->setText(bookmarks.at(a*4)); 415 | userLbl->setText(bookmarks.at(a*4+1)); 416 | 417 | } 418 | 419 | void ServerExplorer::setTableData() 420 | { 421 | qDebug() << "Settings data in table"; 422 | 423 | int counter = 0; 424 | bookmarkTable->clear(); 425 | foreach(QString a, bookmarks){ 426 | // Add to table 427 | if (counter == 0){ 428 | bookmarkTable->addItem(a); 429 | } 430 | counter++; 431 | if (counter == 4){ 432 | counter = 0; 433 | } 434 | 435 | } 436 | 437 | } 438 | -------------------------------------------------------------------------------- /ServerExplorer.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_SERVEREXPLORER_H 2 | #define COMET_SERVEREXPLORER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "SFTPSite.h" 8 | #include "SlidingStackedWidget.h" 9 | #include "ServerFileModel.h" 10 | #include "AddressBar.h" 11 | 12 | class ServerExplorer : public QWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit ServerExplorer(QWidget *parent = 0); 17 | 18 | std::string _host; 19 | std::string _user; 20 | std::string _port; 21 | std::string _password; 22 | 23 | signals: 24 | void sendCredentials(std::string host, std::string user, std::string password, std::string port); 25 | void sendDropData(QString type, QString source, QString desination, QString stfpType); 26 | 27 | public slots: 28 | 29 | private slots: 30 | void bookmarkBtnPressed(); 31 | void sftpBtnPressed(); 32 | void connectBtnPressed(); 33 | void rowSelected(const QModelIndex indx); 34 | void updatedPath(QString path); 35 | void receiveDropData(QString type, QString source, QString destination, QString sftpType); 36 | void addBookmark(); 37 | void setBookmarks(); 38 | void updateBookmarkView(int row); 39 | void setTableData(); 40 | 41 | private: 42 | QFrame* toolbar; 43 | QWidget* explorerSlide; 44 | QWidget* siteManager; 45 | QWidget* bookmarkSlide; 46 | QWidget* connectSlide; 47 | void setupSiteManager(); 48 | QPushButton* bookmarkBtn; 49 | QPushButton* sftpBtn; 50 | QPushButton* connectBtn; 51 | QPushButton* connectBookmarkBtn; 52 | SFTPSite* site; 53 | SlidingStackedWidget* mainSlider; 54 | ServerFileModel* model; 55 | //Connect Area 56 | QLineEdit* host; 57 | QLineEdit* user; 58 | QLineEdit* password; 59 | QLineEdit* port; 60 | QString mainDir; 61 | int animTime; 62 | QTableView* table; 63 | AddressBar* addressBar; 64 | // Bookmarks 65 | QStringList bookmarks; 66 | QString encrypt(QString pass); 67 | QString decrypt(QString encryptedPassword); 68 | QListWidget* bookmarkTable; 69 | QLabel* serverLbl; 70 | QLabel* userLbl; 71 | QPushButton* bookmarkConnect; 72 | 73 | }; 74 | 75 | #endif // COMET_SERVEREXPLORER_H 76 | -------------------------------------------------------------------------------- /ServerFileModel.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "ServerFileModel.h" 4 | #include 5 | 6 | ServerFileModel::ServerFileModel(QObject* parent, int numRows, QStringList dataList, QString _path) : 7 | QAbstractTableModel(parent) 8 | { 9 | dataList_ = dataList; 10 | row = numRows; 11 | path = _path; 12 | } 13 | 14 | int ServerFileModel::columnCount(const QModelIndex &parent) const{ 15 | return 5; 16 | } 17 | 18 | int ServerFileModel::rowCount(const QModelIndex &parent) const{ 19 | return row; 20 | } 21 | 22 | QVariant ServerFileModel::data(const QModelIndex &index, int role) const{ 23 | 24 | if (!index.isValid()) 25 | return QVariant(); 26 | 27 | if (role == Qt::DisplayRole){ 28 | int i =(index.row()*5)+(index.column()); 29 | return dataList_.at(i); 30 | } 31 | else 32 | return QVariant(); 33 | } 34 | 35 | QVariant ServerFileModel::headerData(int section, Qt::Orientation orientation, int role) const{ 36 | 37 | if (role == Qt::DisplayRole){ 38 | if (orientation == Qt::Horizontal){ 39 | switch (section) 40 | { 41 | case 0: 42 | return QString("Name"); 43 | case 1: 44 | return QString("Size"); 45 | case 2: 46 | return QString("Permissions"); 47 | case 3: 48 | return QString("Owner"); 49 | case 4: 50 | return QString("Type"); 51 | } 52 | } 53 | } 54 | return QVariant(); 55 | } 56 | 57 | Qt::DropActions ServerFileModel::supportedDropActions() const 58 | { 59 | return Qt::CopyAction | Qt::MoveAction; 60 | } 61 | 62 | Qt::DropActions ServerFileModel::supportedDragActions() const 63 | { 64 | return Qt::CopyAction | Qt::MoveAction | Qt::IgnoreAction | Qt::TargetMoveAction | Qt::LinkAction; 65 | } 66 | 67 | Qt::ItemFlags ServerFileModel::flags(const QModelIndex &index) const 68 | { 69 | Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index); 70 | 71 | if (index.isValid()) 72 | return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; 73 | else 74 | return Qt::ItemIsDropEnabled | defaultFlags; 75 | } 76 | 77 | QStringList ServerFileModel::mimeTypes() const 78 | { 79 | QStringList types; 80 | types << "application/vnd.text.list"; 81 | //return types; 82 | return QStringList(QLatin1String("text/uri-list")); 83 | } 84 | 85 | // The Data for our mime type is set. 86 | // This passes just the url 87 | // The local file widget needs to handle this specific mime type 88 | QMimeData* ServerFileModel::mimeData(const QModelIndexList &indexes) const 89 | { 90 | 91 | QMimeData* mimeData = new QMimeData; 92 | 93 | foreach (const QModelIndex &index, indexes) { 94 | if (index.isValid()) { 95 | 96 | QString filename = index.model()->data(index.model()->index(index.row(),0,index),Qt::DisplayRole).toString(); 97 | 98 | QString filePath = path + filename; 99 | 100 | QByteArray ba = filePath.toLocal8Bit().data(); 101 | 102 | mimeData->setData("text/comet-upload-download", ba); 103 | mimeData->setText(index.model()->data(index.model()->index(index.row(),4,index),Qt::DisplayRole).toString()); 104 | return mimeData; 105 | } 106 | else{ 107 | return mimeData; 108 | } 109 | } 110 | 111 | } 112 | 113 | bool ServerFileModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 114 | { 115 | QString recipientPath; 116 | // Get The Path of the destination 117 | // Setup the recipients path 118 | if (parent.isValid()){ 119 | // Check if item was dropped onto a folder or a file 120 | if (parent.model()->data(parent.model()->index(parent.row(),4,parent),Qt::DisplayRole).toString() == QString("Folder")){ 121 | qDebug() << "Dropped onto Folder"; 122 | 123 | // Get path of folder 124 | recipientPath = path + parent.model()->data(parent.model()->index(parent.row(),0,parent),Qt::DisplayRole).toString() + "/"; 125 | qDebug() << "PATH " << recipientPath; 126 | 127 | } 128 | // Dropped onto file 129 | else { 130 | recipientPath = path; 131 | qDebug() << "PATH " << recipientPath; 132 | } 133 | }else { 134 | // Dropped on blank space 135 | recipientPath = path; 136 | qDebug() << "PATH " << recipientPath; 137 | } 138 | 139 | // Get the path of the source file/folder 140 | 141 | QList urls = data->urls(); 142 | QList::const_iterator it = urls.constBegin(); 143 | 144 | for (; it != urls.constEnd(); ++it) { 145 | QString _path = (*it).toLocalFile(); 146 | //success = QFile::copy(path, to + QFileInfo(path).fileName()) && success; 147 | qDebug() << "PATH OF SOURCE" << _path; 148 | source = _path; 149 | } 150 | 151 | // Now The source + destination path's must be sent to the download manager, along with a flag that this is a upload action. 152 | emit sendDropData("Upload",source,recipientPath,""); 153 | 154 | 155 | 156 | /* 157 | QByteArray encodedData = data->data("text/plain"); 158 | QDataStream stream(&encodedData, QIODevice::ReadOnly); 159 | QString temp; 160 | data->urls(); 161 | stream >> temp; 162 | //QFile file(data->urls().b); 163 | if (file.exists()){ 164 | qDebug() << "file exist"; 165 | } 166 | QFileInfo info(file); 167 | if (info.isDir()){ 168 | qDebug() << "Is a dir"; 169 | } 170 | qDebug() << "TEMP" << data->urls() << " " << data->text(); 171 | */ 172 | return true; 173 | } 174 | 175 | bool ServerFileModel::removeRows(int row, int count, const QModelIndex &parent) 176 | { 177 | qDebug() << "TESTING"; 178 | return true; 179 | } 180 | bool ServerFileModel::insertRows(int row, int count, const QModelIndex &parent) 181 | { 182 | qDebug() << "INSERTED"; 183 | return true; 184 | } 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /ServerFileModel.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_SERVERFILEMODEL_H 2 | #define COMET_SERVERFILEMODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | class ServerFileModel : public QAbstractTableModel 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit ServerFileModel(QObject* parent = 0, int numRows = 0, QStringList dataList = QStringList(), QString _path = ""); 12 | 13 | // Drag And Drop 14 | Qt::DropActions supportedDropActions() const; 15 | Qt::ItemFlags flags(const QModelIndex &index) const; 16 | Qt::DropActions supportedDragActions() const; 17 | QStringList mimeTypes() const; 18 | QMimeData* mimeData(const QModelIndexList &indexes) const; 19 | bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); 20 | bool removeRows(int row, int count, const QModelIndex &parent); 21 | bool insertRows(int row, int count, const QModelIndex &parent); 22 | 23 | 24 | 25 | 26 | // Default Model Actions 27 | 28 | int rowCount(const QModelIndex &parent = QModelIndex()) const ; 29 | int columnCount(const QModelIndex &parent = QModelIndex()) const; 30 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 31 | QStringList dataList_; 32 | int row; 33 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 34 | QString path; 35 | QString source; 36 | 37 | 38 | 39 | 40 | signals: 41 | void sendDropData(QString type, QString source, QString destination, QString sftpType); 42 | 43 | public slots: 44 | 45 | }; 46 | 47 | #endif // COMET_SERVERFILEMODEL_H 48 | 49 | -------------------------------------------------------------------------------- /SlidingStackedWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "SlidingStackedWidget.h" 2 | 3 | 4 | SlidingStackedWidget::SlidingStackedWidget(QWidget *parent) 5 | : QStackedWidget(parent) 6 | { 7 | if (parent!=0) { 8 | m_mainwindow=parent; 9 | } 10 | else { 11 | m_mainwindow=this; 12 | qDebug()<<"ATTENTION: untested mainwindow case !"; 13 | } 14 | //parent should not be 0; not tested for any other case yet !! 15 | #ifdef Q_OS_SYMBIAN 16 | #ifndef __S60_50__ 17 | qDebug()<< "WARNING: ONLY TESTED AND 5TH EDITION"; 18 | #endif //__S60_50__ 19 | #endif //Q_OS_SYMBIAN 20 | //Now, initialize some private variables with default values 21 | m_vertical=false; 22 | //setVerticalMode(true); 23 | m_speed=500; 24 | m_animationtype = QEasingCurve::OutBack; //check out the QEasingCurve documentation for different styles 25 | m_now=0; 26 | m_next=0; 27 | m_wrap=false; 28 | m_pnow=QPoint(0,0); 29 | m_active=false; 30 | } 31 | 32 | 33 | SlidingStackedWidget::~SlidingStackedWidget(){ 34 | } 35 | 36 | void SlidingStackedWidget::setVerticalMode(bool vertical) { 37 | m_vertical=vertical; 38 | } 39 | 40 | void SlidingStackedWidget::setSpeed(int speed) { 41 | m_speed = speed; 42 | } 43 | 44 | void SlidingStackedWidget::setAnimation(enum QEasingCurve::Type animationtype) { 45 | m_animationtype = animationtype; 46 | } 47 | 48 | void SlidingStackedWidget::setWrap(bool wrap) { 49 | m_wrap=wrap; 50 | } 51 | 52 | void SlidingStackedWidget::slideInNext() { 53 | int now=currentIndex(); 54 | if (m_wrap||(now0)) 63 | slideInIdx(now-1); 64 | } 65 | 66 | void SlidingStackedWidget::slideInIdx(int idx, enum t_direction direction) { 67 | //int idx, t_direction direction=AUTOMATIC 68 | if (idx>count()-1) { 69 | direction=m_vertical ? TOP2BOTTOM : RIGHT2LEFT; 70 | idx=(idx)%count(); 71 | } 72 | else if (idx<0) { 73 | direction= m_vertical ? BOTTOM2TOP: LEFT2RIGHT; 74 | idx=(idx+count())%count(); 75 | } 76 | slideInWgt(widget ( idx ),direction); 77 | //widget() is a function inherited from QStackedWidget 78 | } 79 | 80 | 81 | void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) { 82 | 83 | if (m_active) { 84 | return; // at the moment, do not allow re-entrance before an animation is completed. 85 | //other possibility may be to finish the previous animation abrupt, or 86 | //to revert the previous animation with a counter animation, before going ahead 87 | //or to revert the previous animation abrupt 88 | //and all those only, if the newwidget is not the same as that of the previous running animation. 89 | } 90 | else m_active=true; 91 | 92 | enum t_direction directionhint; 93 | int now=currentIndex(); //currentIndex() is a function inherited from QStackedWidget 94 | int next=indexOf(newwidget); 95 | if (now==next) { 96 | m_active=false; 97 | return; 98 | } 99 | else if (nowsetGeometry ( 0, 0, offsetx, offsety ); 117 | 118 | if (direction==BOTTOM2TOP) { 119 | offsetx=0; 120 | offsety=-offsety; 121 | } 122 | else if (direction==TOP2BOTTOM) { 123 | offsetx=0; 124 | //offsety=offsety; 125 | } 126 | else if (direction==RIGHT2LEFT) { 127 | offsetx=-offsetx; 128 | offsety=0; 129 | } 130 | else if (direction==LEFT2RIGHT) { 131 | //offsetx=offsetx; 132 | offsety=0; 133 | } 134 | //re-position the next widget outside/aside of the display area 135 | QPoint pnext=widget(next)->pos(); 136 | QPoint pnow=widget(now)->pos(); 137 | m_pnow=pnow; 138 | 139 | widget(next)->move(pnext.x()-offsetx,pnext.y()-offsety); 140 | //make it visible/show 141 | widget(next)->show(); 142 | widget(next)->raise(); 143 | 144 | //animate both, the now and next widget to the side, using animation framework 145 | QPropertyAnimation *animnow = new QPropertyAnimation(widget(now), "pos"); 146 | 147 | animnow->setDuration(m_speed); 148 | animnow->setEasingCurve(m_animationtype); 149 | animnow->setStartValue(QPoint(pnow.x(), pnow.y())); 150 | animnow->setEndValue(QPoint(offsetx+pnow.x(), offsety+pnow.y())); 151 | QPropertyAnimation *animnext = new QPropertyAnimation(widget(next), "pos"); 152 | animnext->setDuration(m_speed); 153 | animnext->setEasingCurve(m_animationtype); 154 | animnext->setStartValue(QPoint(-offsetx+pnext.x(), offsety+pnext.y())); 155 | animnext->setEndValue(QPoint(pnext.x(), pnext.y())); 156 | 157 | QParallelAnimationGroup *animgroup = new QParallelAnimationGroup; 158 | 159 | animgroup->addAnimation(animnow); 160 | animgroup->addAnimation(animnext); 161 | 162 | QObject::connect(animgroup, SIGNAL(finished()),this,SLOT(animationDoneSlot())); 163 | m_next=next; 164 | m_now=now; 165 | m_active=true; 166 | animgroup->start(); 167 | 168 | //note; the rest is done via a connect from the animation ready; 169 | //animation->finished() provides a signal when animation is done; 170 | //so we connect this to some post processing slot, 171 | //that we implement here below in animationDoneSlot. 172 | } 173 | 174 | 175 | void SlidingStackedWidget::animationDoneSlot(void) { 176 | //when ready, call the QStackedWidget slot setCurrentIndex(int) 177 | setCurrentIndex(m_next); //this function is inherit from QStackedWidget 178 | //then hide the outshifted widget now, and (may be done already implicitely by QStackedWidget) 179 | widget(m_now)->hide(); 180 | //then set the position of the outshifted widget now back to its original 181 | widget(m_now)->move(m_pnow); 182 | //so that the application could also still call the QStackedWidget original functions/slots for changings 183 | //widget(m_now)->update(); 184 | //setCurrentIndex(m_next); //this function is inherit from QStackedWidget 185 | m_active=false; 186 | emit animationFinished(); 187 | } 188 | 189 | 190 | 191 | /* REFERENCES 192 | 193 | http://doc.trolltech.com/4.6/animation-overview.html#easing-curves 194 | http://doc.trolltech.com/4.6/qpropertyanimation.html 195 | http://doc.trolltech.com/4.6/qanimationgroup.html 196 | 197 | */ 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /SlidingStackedWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_SLIDINGSTACKEDWIDGET_H 2 | #define COMET_SLIDINGSTACKEDWIDGET_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /*! 12 | Description 13 | SlidingStackedWidget is a class that is derived from QtStackedWidget 14 | and allows smooth side shifting of widgets, in addition 15 | to the original hard switching from one to another as offered by 16 | QStackedWidget itself. 17 | */ 18 | 19 | class SlidingStackedWidget : public QStackedWidget 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | //! This enumeration is used to define the animation direction 25 | enum t_direction { 26 | LEFT2RIGHT, 27 | RIGHT2LEFT, 28 | TOP2BOTTOM, 29 | BOTTOM2TOP, 30 | AUTOMATIC 31 | }; 32 | 33 | //! The Constructor and Destructor 34 | SlidingStackedWidget(QWidget *parent); 35 | ~SlidingStackedWidget(void); 36 | 37 | 38 | public slots: 39 | //! Some basic settings API 40 | void setSpeed(int speed); //animation duration in milliseconds 41 | void setAnimation(enum QEasingCurve::Type animationtype); //check out the QEasingCurve documentation for different styles 42 | void setVerticalMode(bool vertical=true); 43 | void setWrap(bool wrap); //wrapping is related to slideInNext/Prev;it defines the behaviour when reaching last/first page 44 | 45 | //! The Animation / Page Change API 46 | void slideInNext(); 47 | void slideInPrev(); 48 | void slideInIdx(int idx, enum t_direction direction=AUTOMATIC); 49 | 50 | 51 | signals: 52 | //! this is used for internal purposes in the class engine 53 | void animationFinished(void); 54 | 55 | protected slots: 56 | //! this is used for internal purposes in the class engine 57 | void animationDoneSlot(void); 58 | 59 | protected: 60 | //! this is used for internal purposes in the class engine 61 | void slideInWgt(QWidget * widget, enum t_direction direction=AUTOMATIC); 62 | 63 | QWidget *m_mainwindow; 64 | 65 | int m_speed; 66 | enum QEasingCurve::Type m_animationtype; 67 | bool m_vertical; 68 | int m_now; 69 | int m_next; 70 | bool m_wrap; 71 | QPoint m_pnow; 72 | bool m_active; 73 | 74 | QList blockedPageList; 75 | 76 | 77 | 78 | }; 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | #endif // COMET_SLIDINGSTACKEDWIDGET_H 94 | -------------------------------------------------------------------------------- /StatusArea.cpp: -------------------------------------------------------------------------------- 1 | #include "StatusArea.h" 2 | 3 | #include 4 | 5 | StatusArea::StatusArea(QWidget *parent) : 6 | QWidget(parent) 7 | { 8 | // Init 9 | this->setObjectName("StatusArea"); 10 | this->setFixedHeight(70); 11 | 12 | // Required Widgets 13 | file = new QLabel("Filename"); 14 | numFiles = new QPushButton("00"); 15 | cancel = new QPushButton(" "); 16 | pause = new QPushButton(" "); 17 | speed = new QLabel("KBs" ); 18 | cancel->setFixedSize(23, 23); 19 | pause->setFixedSize(23, 23); 20 | cancel->setObjectName("Status_CancelButton"); 21 | pause->setObjectName("Status_PauseButton"); 22 | numFiles->setObjectName("Status_NumberFiles"); 23 | 24 | // Layouts 25 | QVBoxLayout* main = new QVBoxLayout(); 26 | QHBoxLayout* top = new QHBoxLayout(); 27 | QHBoxLayout* topLeft = new QHBoxLayout(); 28 | QHBoxLayout* topRight = new QHBoxLayout(); 29 | QHBoxLayout* mid = new QHBoxLayout(); 30 | QHBoxLayout* bottom = new QHBoxLayout(); 31 | QHBoxLayout* bottomLeft = new QHBoxLayout(); 32 | QHBoxLayout* bottomRight = new QHBoxLayout(); 33 | 34 | // Top Half 35 | topLeft->addWidget(file); 36 | topLeft->setAlignment(Qt::AlignLeft); 37 | topRight->addWidget(speed); 38 | topRight->setAlignment(Qt::AlignRight); 39 | top->addLayout(topLeft); 40 | top->addLayout(topRight); 41 | 42 | // Setup progressbar 43 | progress = new QProgressBar(); 44 | progress->setObjectName("Status_Progress"); 45 | progress->setMaximum(100); 46 | progress->setMinimum(0); 47 | progress->setRange(0,100); 48 | progress->setValue(0); 49 | progress->setTextVisible(false); 50 | progress->setFixedHeight(12); 51 | mid->addWidget(progress); 52 | progress->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); 53 | 54 | // Bottom Half 55 | bottomRight->addWidget(numFiles); 56 | bottomRight->setAlignment(Qt::AlignRight); 57 | bottomLeft->addWidget(cancel); 58 | bottomLeft->addWidget(pause); 59 | bottomLeft->setAlignment(Qt::AlignLeft); 60 | bottomLeft->setSpacing(0); 61 | bottom->addLayout(bottomLeft); 62 | bottom->addLayout(mid); 63 | bottom->addLayout(bottomRight); 64 | 65 | 66 | main->addLayout(top); 67 | main->addLayout(bottom); 68 | 69 | this->setLayout(main); 70 | 71 | // Slots 72 | QObject::connect(numFiles, SIGNAL(clicked()),this->parent(), SLOT(switchSlides())); 73 | } 74 | 75 | // Enable StyleSheets 76 | void StatusArea::paintEvent(QPaintEvent* event) 77 | { 78 | QStyleOption o; 79 | o.initFrom(this); 80 | QPainter p(this); 81 | style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); 82 | 83 | } 84 | 85 | void StatusArea::setFileName(QString fileName) 86 | { 87 | file->setText("File: " +fileName); 88 | } 89 | 90 | void StatusArea::setNumFiles(int _numFiles) 91 | { 92 | QString s = QString::number(_numFiles); 93 | if (s.count() == 1){ 94 | s = " " + s + " "; 95 | } 96 | numFiles->setText(s); 97 | } 98 | 99 | void StatusArea::setSpeed(QString _speed) 100 | { 101 | speed->setText(_speed + " KB/s"); 102 | } 103 | 104 | void StatusArea::setProgress(int progressValue) 105 | { 106 | progress->setValue(progressValue); 107 | } 108 | -------------------------------------------------------------------------------- /StatusArea.h: -------------------------------------------------------------------------------- 1 | #ifndef COMET_STATUSAREA_H 2 | #define COMET_STATUSAREA_H 3 | 4 | #include 5 | #include 6 | 7 | class StatusArea : public QWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit StatusArea(QWidget *parent = 0); 12 | QPushButton* cancel; 13 | QPushButton* pause; 14 | private: 15 | QLabel* file; 16 | QPushButton* numFiles; 17 | 18 | QLabel *speed; 19 | QProgressBar* progress; 20 | 21 | signals: 22 | 23 | 24 | public slots: 25 | void paintEvent(QPaintEvent* event); 26 | void setFileName(QString fileName); 27 | void setNumFiles(int _numFiles); 28 | void setSpeed(QString _speed); 29 | void setProgress(int progressValue); 30 | 31 | 32 | }; 33 | 34 | #endif // COMET_STATUSAREA_H 35 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | * ~~Move getPermissions and getType from sftpdir into SFTPSite, as private methods.~~ 2 | * ~~All sftp controls internal in SFTPSite 3 | * ~~One internal sesion that never leaves the class 4 | * ~~only outputs the listings. 5 | * ~~for listings, recreate the model each time, delete/set to null and reinstantiate. 6 | * ~~Download display qabstracttableview 7 | * ~~add private free method to SFTPSite 8 | * ~~SFTPSite::sftp_connection, add error messagebox. 9 | * ~~listdir creates QstringList, serverFileBrowser passes to model. 10 | * Address Edit send path to local explorer 11 | * Address Edit send path to server explorer 12 | * qdrag selects file full path 13 | * downloads 14 | 15 | 16 | * interface the remote server access so we can support different services 17 | * use windows to store the saved PWs so we can remove openssl 18 | * tidy up mem management 19 | * file explorer column sizing 20 | * remove libssh and use QSSh or something else 21 | * fix naming conventions 22 | * add support for B3, S3, Dropbox(?) 23 | * review architecture .... Just rewrite the whole thing?? 24 | * cancel button sizing is wrong 25 | * resizing doesn't remember last window position, needs to follow default windows behaviour 26 | -------------------------------------------------------------------------------- /images/CometButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/CometButton.png -------------------------------------------------------------------------------- /images/CometButton.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/CometButton.psd -------------------------------------------------------------------------------- /images/ExitButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/ExitButton.png -------------------------------------------------------------------------------- /images/ExitButton2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/ExitButton2.png -------------------------------------------------------------------------------- /images/MaximiseGrey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/MaximiseGrey.png -------------------------------------------------------------------------------- /images/MaximiseWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/MaximiseWhite.png -------------------------------------------------------------------------------- /images/Maxmise.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/Maxmise.psd -------------------------------------------------------------------------------- /images/Menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /images/MinimiseGrey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/MinimiseGrey.png -------------------------------------------------------------------------------- /images/MinimiseGrey.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/MinimiseGrey.psd -------------------------------------------------------------------------------- /images/MinimiseWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/MinimiseWhite.png -------------------------------------------------------------------------------- /images/Screen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 76 | 77 | -------------------------------------------------------------------------------- /images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/Thumbs.db -------------------------------------------------------------------------------- /images/arrow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/arrow.jpg -------------------------------------------------------------------------------- /images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/arrow.png -------------------------------------------------------------------------------- /images/arrow.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/arrow.psd -------------------------------------------------------------------------------- /images/left37.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /images/libssh-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/libssh-logo.png -------------------------------------------------------------------------------- /images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/menu.png -------------------------------------------------------------------------------- /images/openssl-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/openssl-logo.png -------------------------------------------------------------------------------- /images/pause15.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /images/pausesmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/pausesmall.png -------------------------------------------------------------------------------- /images/play43.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /images/power26.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /images/qt-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/qt-logo.png -------------------------------------------------------------------------------- /images/right33.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /images/square64.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /images/stopsmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shazib/CometFTP/8423a6c1e8cea679107ffe80e62e7e37a0a6c76e/images/stopsmall.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindow.h" 2 | #include 3 | #include "NcFramelessHelper.h" 4 | #include 5 | int main(int argc, char *argv[]) 6 | { 7 | qDebug() << "Started"; 8 | QApplication a(argc, argv); 9 | MainWindow w; 10 | NcFramelessHelper fh; 11 | fh.activateOn(&w); 12 | 13 | QCoreApplication::setOrganizationName("BCU"); 14 | QCoreApplication::setApplicationName("CometFTP"); 15 | QCoreApplication::setApplicationVersion("0.0.1"); 16 | 17 | QFile cssFile(":/Main.css"); 18 | cssFile.open(QFile::ReadOnly); 19 | QString cssString = QLatin1String(cssFile.readAll()); 20 | 21 | a.setStyleSheet(cssString); 22 | 23 | qDebug() << "Activated Helper"; 24 | w.show(); 25 | 26 | return a.exec(); 27 | } 28 | -------------------------------------------------------------------------------- /object_script.CometFTP.Debug: -------------------------------------------------------------------------------- 1 | INPUT( 2 | ./debug\main.o 3 | ./debug\MainWindow.o 4 | ./debug\SlidingStackedWidget.o 5 | ./debug\NcFramlessHelper.o 6 | ./debug\LocalExplorer.o 7 | ./debug\StatusArea.o 8 | ./debug\ServerExplorer.o 9 | ./debug\SFTPSite.o 10 | ./debug\ServerFileModel.o 11 | ./debug\AddressBar.o 12 | ./debug\DownloadManager.o 13 | ./debug\CustomFileModel.o 14 | ./debug\qrc_resources.o 15 | ./debug\moc_MainWindow.o 16 | ./debug\moc_SlidingStackedWidget.o 17 | ./debug\moc_LocalExplorer.o 18 | ./debug\moc_StatusArea.o 19 | ./debug\moc_ServerExplorer.o 20 | ./debug\moc_SFTPSite.o 21 | ./debug\moc_ServerFileModel.o 22 | ./debug\moc_AddressBar.o 23 | ./debug\moc_DownloadManager.o 24 | ./debug\moc_CustomFileModel.o 25 | ); 26 | -------------------------------------------------------------------------------- /object_script.CometFTP.Release: -------------------------------------------------------------------------------- 1 | INPUT( 2 | ./release\main.o 3 | ./release\MainWindow.o 4 | ./release\SlidingStackedWidget.o 5 | ./release\NcFramlessHelper.o 6 | ./release\LocalExplorer.o 7 | ./release\StatusArea.o 8 | ./release\ServerExplorer.o 9 | ./release\SFTPSite.o 10 | ./release\ServerFileModel.o 11 | ./release\AddressBar.o 12 | ./release\DownloadManager.o 13 | ./release\CustomFileModel.o 14 | ./release\qrc_resources.o 15 | ./release\moc_MainWindow.o 16 | ./release\moc_SlidingStackedWidget.o 17 | ./release\moc_LocalExplorer.o 18 | ./release\moc_StatusArea.o 19 | ./release\moc_ServerExplorer.o 20 | ./release\moc_SFTPSite.o 21 | ./release\moc_ServerFileModel.o 22 | ./release\moc_AddressBar.o 23 | ./release\moc_DownloadManager.o 24 | ./release\moc_CustomFileModel.o 25 | ); 26 | -------------------------------------------------------------------------------- /resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/CometButton.png 4 | images/ExitButton.png 5 | images/ExitButton2.png 6 | images/MaximiseGrey.png 7 | images/MaximiseWhite.png 8 | images/MinimiseGrey.png 9 | images/MinimiseWhite.png 10 | images/pausesmall.png 11 | images/stopsmall.png 12 | images/Menu.svg 13 | images/Screen.svg 14 | Main.css 15 | images/left37.svg 16 | images/pause15.svg 17 | images/play43.svg 18 | images/right33.svg 19 | images/square64.svg 20 | images/power26.svg 21 | images/openssl-logo.png 22 | images/libssh-logo.png 23 | images/qt-logo.png 24 | 25 | 26 | --------------------------------------------------------------------------------