diff --git a/src/handler/eventHandler.cpp b/src/handler/eventHandler.cpp index 2a64ad7..fc97e34 100644 --- a/src/handler/eventHandler.cpp +++ b/src/handler/eventHandler.cpp @@ -142,22 +142,38 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2) int itemID = _listView->listClicked(par1, par2); if (itemID != -1) { - if (_nextcloud.getItems()->at(itemID).getType() == Itemtype::IFOLDER) + if (_nextcloud.getItems().at(itemID).getType() == Itemtype::IFOLDER) { - FillAreaRect(_menu.getContentRect(), WHITE); - _menu.drawLoadingScreen(); + //TODO temp solution --> remove solution + //TODO if is the first option, go back and dont ask for sync + int dialogResult = DialogSynchro(ICON_QUESTION, "Action", "What do you want to to do?", "Open folder", "Sync Folder", "Cancel"); + switch (dialogResult) + { + case 1: + FillAreaRect(_menu.getContentRect(), WHITE); + _menu.drawLoadingScreen(); - _tempPath = _nextcloud.getItems()->at(itemID).getPath(); - if (!_tempPath.empty()) - _nextcloud.getDataStructure(_tempPath); - _listView.reset(new ListView(_menu.getContentRect(), _nextcloud.getItems())); - _listView->drawHeader(_tempPath.substr(NEXTCLOUD_ROOT_PATH.length())); + _tempPath = _nextcloud.getItems().at(itemID).getPath(); + if (!_tempPath.empty()) + _nextcloud.setItems(_nextcloud.getDataStructure(_tempPath)); + _listView.reset(new ListView(_menu.getContentRect(), _nextcloud.getItems())); + _listView->drawHeader(_tempPath.substr(NEXTCLOUD_ROOT_PATH.length())); + + break; + case 2: + //Sync folder + _nextcloud.downloadFolder(_nextcloud.getItems(), itemID); + //update the entry and say --> folder is synced + //entries in visual and in nextlcoud are out of sync + default: + break; + } } else { int dialogResult = 0; - if (_nextcloud.getItems()->at(itemID).getState() != FileState::ICLOUD) + if (_nextcloud.getItems().at(itemID).getState() != FileState::ICLOUD) { dialogResult = DialogSynchro(ICON_QUESTION, "Action", "What do you want to do?", "Open", "Remove", "Cancel"); } @@ -165,10 +181,10 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2) switch (dialogResult) { case 1: - _nextcloud.getItems()->at(itemID).open(); + _nextcloud.getItems().at(itemID).open(); break; case 2: - if (!_nextcloud.getItems()->at(itemID).removeFile()) + if (!_nextcloud.getItems().at(itemID).removeFile()) Message(ICON_WARNING, "Warning", "Could not delete the file, please try again.", 1200); break; case 3: @@ -199,12 +215,18 @@ int EventHandler::pointerHandler(const int type, const int par1, const int par2) if (_loginView->logginClicked(par1, par2) == 2) { _menu.drawLoadingScreen(); + //TODO use progressbar and log (check what can go wrong?) catch? if (_nextcloud.login(_loginView->getURL(), _loginView->getUsername(), _loginView->getPassword())) { _listView = std::unique_ptr(new ListView(_menu.getContentRect(), _nextcloud.getItems())); _loginView.reset(); - FullUpdate(); } + else + { + //redraw login screen so that loading disappears + Message(ICON_WARNING, "Warning", "Something went wrong...", 1200); + } + FullUpdate(); return 1; } } diff --git a/src/ui/listView.cpp b/src/ui/listView.cpp index 89a6273..ef99817 100644 --- a/src/ui/listView.cpp +++ b/src/ui/listView.cpp @@ -19,7 +19,7 @@ using std::string; using std::vector; -ListView::ListView(const irect *contentRect, const std::shared_ptr> items) : _contentRect(contentRect), _items(items) +ListView::ListView(const irect *contentRect, const vector items) : _contentRect(contentRect), _items(items) { FillAreaRect(_contentRect, WHITE); @@ -42,7 +42,7 @@ ListView::ListView(const irect *contentRect, const std::shared_ptr> _page = 1; _shownPage = _page; - auto i = _items->size(); + auto i = _items.size(); auto z = 0; _entries.reserve(i); @@ -107,7 +107,7 @@ void ListView::drawFooter() void ListView::drawEntry(int itemID) { FillAreaRect(_entries[itemID].getPosition(), WHITE); - _entries[itemID].draw(_items->at(itemID), _entryFont, _entryFontBold, _entryFontHeight); + _entries[itemID].draw(_items.at(itemID), _entryFont, _entryFontBold, _entryFontHeight); } void ListView::drawEntries() @@ -115,7 +115,7 @@ void ListView::drawEntries() for (auto i = 0; i < _entries.size(); i++) { if (_entries[i].getPage() == _shownPage) - _entries[i].draw(_items->at(i), _entryFont, _entryFontBold, _entryFontHeight); + _entries[i].draw(_items.at(i), _entryFont, _entryFontBold, _entryFontHeight); } } diff --git a/src/ui/listView.h b/src/ui/listView.h index 84ccb7d..8681c79 100644 --- a/src/ui/listView.h +++ b/src/ui/listView.h @@ -29,7 +29,7 @@ public: * @param ContentRect area of the screen where the list view is placed * @param Items items that shall be shown in the listview */ - ListView(const irect *contentRect, const std::shared_ptr> items); + ListView(const irect *contentRect, const vector items); /** * Destructor @@ -75,7 +75,7 @@ private: int _footerFontHeight; int _entryFontHeight; const irect *_contentRect; - const std::shared_ptr> _items = nullptr; + vector _items; vector _entries; ifont *_headerFont; ifont *_footerFont; diff --git a/src/util/nextcloud.cpp b/src/util/nextcloud.cpp index 327eed9..f0923b0 100644 --- a/src/util/nextcloud.cpp +++ b/src/util/nextcloud.cpp @@ -22,11 +22,10 @@ using std::ofstream; using std::string; //neccesary to use Dialog method -Nextcloud *Nextcloud::nextcloudStatic; - +std::unique_ptr Nextcloud::_nextcloudStatic; Nextcloud::Nextcloud() { - nextcloudStatic = this; + _nextcloudStatic = std::unique_ptr(this); if (iv_access(NEXTCLOUD_PATH.c_str(), W_OK) != 0) iv_mkdir(NEXTCLOUD_PATH.c_str(), 0777); @@ -67,6 +66,31 @@ void Nextcloud::setStartFolder(const string &Path) CloseConfig(nextcloudConfig); } +bool Nextcloud::setItems(const vector &tempItems) +{ + + if (tempItems.empty()) + return false; + + if (!_items.empty()) + _items.clear(); + + _items = tempItems; + + //resize item 1 + string header = _items.at(0).getPath(); + header = header.substr(0, header.find_last_of("/")); + header = header.substr(0, header.find_last_of("/") + 1); + _items.at(0).setPath(header); + _items.at(0).setTitle("..."); + _items.at(0).setLastEditDate(""); + + if (_items.at(0).getPath().compare(NEXTCLOUD_ROOT_PATH) == 0) + _items.erase(_items.begin()); + + return true; +} + bool Nextcloud::login() { string tempPath = getStartFolder(); @@ -74,7 +98,7 @@ bool Nextcloud::login() if (tempPath.empty()) tempPath = NEXTCLOUD_ROOT_PATH + this->getUsername() + "/"; - if (getDataStructure(tempPath, this->getUsername(), this->getPassword())) + if (setItems(getDataStructure(tempPath))) { _loggedIn = true; return true; @@ -87,7 +111,7 @@ bool Nextcloud::login(const string &Url, const string &Username, const string &P { _url = Url; string tempPath = NEXTCLOUD_ROOT_PATH + Username + "/"; - if (getDataStructure(tempPath, Username, Pass)) + if (setItems(getDataStructure(tempPath, Username, Pass))) { if (iv_access(NEXTCLOUD_CONFIG_PATH.c_str(), W_OK) != 0) iv_buildpath(NEXTCLOUD_CONFIG_PATH.c_str()); @@ -112,14 +136,14 @@ void Nextcloud::logout(bool deleteFiles) remove((NEXTCLOUD_CONFIG_PATH + ".back.").c_str()); _url.clear(); - _items = nullptr; + _items.clear(); _workOffline = false; _loggedIn = false; } void Nextcloud::downloadItem(int itemID) { - Log::writeLog("started download of " + _items->at(itemID).getPath() + " to " + _items->at(itemID).getLocalPath()); + Log::writeLog("started download of " + _items.at(itemID).getPath() + " to " + _items.at(itemID).getLocalPath()); if (!Util::connectToNetwork()) { @@ -127,7 +151,7 @@ void Nextcloud::downloadItem(int itemID) _workOffline = true; } - if (_items->at(itemID).getPath().empty()) + if (_items.at(itemID).getPath().empty()) { Message(ICON_ERROR, "Error", "Download path is not set, therefore cannot download the file.", 1200); return; @@ -143,9 +167,9 @@ void Nextcloud::downloadItem(int itemID) string post = this->getUsername() + std::string(":") + this->getPassword(); FILE *fp; - fp = iv_fopen(_items->at(itemID).getLocalPath().c_str(), "wb"); + fp = iv_fopen(_items.at(itemID).getLocalPath().c_str(), "wb"); - curl_easy_setopt(curl, CURLOPT_URL, (_url + _items->at(itemID).getPath()).c_str()); + curl_easy_setopt(curl, CURLOPT_URL, (_url + _items.at(itemID).getPath()).c_str()); curl_easy_setopt(curl, CURLOPT_USERPWD, post.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Util::writeData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); @@ -165,8 +189,8 @@ void Nextcloud::downloadItem(int itemID) switch (response_code) { case 200: - Log::writeLog("finished download of " + _items->at(itemID).getPath() + " to " + _items->at(itemID).getLocalPath()); - _items->at(itemID).setState(FileState::ISYNCED); + Log::writeLog("finished download of " + _items.at(itemID).getPath() + " to " + _items.at(itemID).getLocalPath()); + _items.at(itemID).setState(FileState::ISYNCED); break; case 401: Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200); @@ -179,14 +203,47 @@ void Nextcloud::downloadItem(int itemID) } } -bool Nextcloud::getDataStructure(string &pathUrl) +bool Nextcloud::downloadFolder(const vector &tempItems, int itemId) +{ + + //also has to look at the previous items? + + //do not change items oxml or use temp here? + if (tempItems.at(itemId).getType() == Itemtype::IFOLDER) + { + + //get the data structure under the folder that is requested --> overrides items object and therefore will fail! + + //should return items vector? + string temp = tempItems.at(itemId).getPath(); + vector tempItemsNew = getDataStructure(temp); + + //this will be the new item list --> where to switch to when this process is over --> open the folder that has t be synced? + //get item id? + for (auto i = 0; i < tempItemsNew.size(); i++) + { + + downloadFolder(tempItemsNew,itemId); + //overrides current item list and therefore nos possible! + // has to be read in again? + // call method again? + } + } + else + { + downloadItem(itemId); + } + + return true; +} + +vector Nextcloud::getDataStructure(string &pathUrl) { return getDataStructure(pathUrl, this->getUsername(), this->getPassword()); } -bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, const string &Pass) +vector Nextcloud::getDataStructure(const string &pathUrl, const string &Username, const string &Pass) { - //could not connect to internet, therefore offline modus if (_workOffline) return getOfflineStructure(pathUrl); @@ -203,7 +260,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, if (Username.empty() || Pass.empty()) { Message(ICON_ERROR, "Error", "Username/password not set.", 1200); - return false; + return {}; } string readBuffer; @@ -238,15 +295,15 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, string localPath = this->getLocalPath(pathUrl); //create items_ - if (!readInXML(readBuffer)) - return false; + vector tempItems = readInXML(readBuffer); + if (tempItems.empty()) + return {}; if (iv_access(localPath.c_str(), W_OK) != 0) { //if the current folder does not exist locally, create it iv_buildpath(localPath.c_str()); } - else { //get items from local path @@ -274,7 +331,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, } outFile.close(); - return true; + return tempItems; } case 401: Message(ICON_ERROR, "Error", "Username/password incorrect.", 1200); @@ -286,7 +343,7 @@ bool Nextcloud::getDataStructure(const string &pathUrl, const string &Username, } } } - return false; + return {}; } string Nextcloud::getUrl() @@ -329,11 +386,11 @@ void Nextcloud::DialogHandlerStatic(int Button) { if (Button == 2) { - nextcloudStatic->_workOffline = true; + _nextcloudStatic->_workOffline = true; } } -bool Nextcloud::readInXML(string xml) +vector Nextcloud::readInXML(string xml) { size_t begin; size_t end; @@ -347,32 +404,15 @@ bool Nextcloud::readInXML(string xml) { end = xml.find(endItem); - tempItems.push_back(Item(xml.substr(begin, end))); + tempItems.push_back(xml.substr(begin,end)); xml = xml.substr(end + endItem.length()); begin = xml.find(beginItem); } - if (_items) - _items->clear(); - _items = std::make_shared>(std::move(tempItems)); + return tempItems; - if (_items->size() < 1) - return false; - - //resize item 1 - string header = _items->at(0).getPath(); - header = header.substr(0, header.find_last_of("/")); - header = header.substr(0, header.find_last_of("/") + 1); - _items->at(0).setPath(header); - _items->at(0).setTitle("..."); - _items->at(0).setLastEditDate(""); - - if (_items->at(0).getPath().compare(NEXTCLOUD_ROOT_PATH) == 0) - _items->erase(_items->begin()); - - return true; } string Nextcloud::getLocalPath(string path) @@ -384,7 +424,7 @@ string Nextcloud::getLocalPath(string path) return NEXTCLOUD_FILE_PATH + "/" + path; } -bool Nextcloud::getOfflineStructure(const string &pathUrl) +vector Nextcloud::getOfflineStructure(const string &pathUrl) { string localPath = this->getLocalPath(pathUrl) + NEXTCLOUD_STRUCTURE_EXTENSION; if (iv_access(localPath.c_str(), W_OK) == 0) @@ -393,10 +433,13 @@ bool Nextcloud::getOfflineStructure(const string &pathUrl) std::stringstream buffer; buffer << inFile.rdbuf(); - if (!readInXML(buffer.str())) - return false; + vector tempItems = readInXML(buffer.str()); + + if (tempItems.empty()) + return {}; getLocalFileStructure(this->getLocalPath(pathUrl)); + return tempItems; } else { @@ -411,8 +454,7 @@ bool Nextcloud::getOfflineStructure(const string &pathUrl) Message(ICON_ERROR, "Error", "The selected structure is not available offline.", 1200); } } - - return false; + return {}; } void Nextcloud::getLocalFileStructure(const string &localPath) @@ -441,10 +483,10 @@ void Nextcloud::getLocalFileStructure(const string &localPath) continue; bool found = false; - for (auto i = 0; i < _items->size(); i++) + for (auto i = 0; i < _items.size(); i++) { //TODO compare last edit local and in cloud and display to user - if (_items->at(i).getLocalPath().compare(full_file_name) == 0) + if (_items.at(i).getLocalPath().compare(full_file_name) == 0) { found = true; break; @@ -452,7 +494,7 @@ void Nextcloud::getLocalFileStructure(const string &localPath) } if (!found) { - _items->push_back(Item(full_file_name, FileState::ILOCAL)); + _items.push_back(Item(full_file_name, FileState::ILOCAL)); } } closedir(dir); diff --git a/src/util/nextcloud.h b/src/util/nextcloud.h index a5b7599..bbe6431 100644 --- a/src/util/nextcloud.h +++ b/src/util/nextcloud.h @@ -58,20 +58,27 @@ public: */ void downloadItem(int itemID); + + /** + * + * + */ + bool downloadFolder(const vector &tempItems, int itemId); + /** * gets the dataStructure of the given URL and writes its WEBDAV items to the items vector, reads Userdata from configfile * * @param pathUrl URL to get the dataStructure of - * @return true - sucessfull, false - error + * @return vector of items */ - bool getDataStructure(string &pathUrl); + vector getDataStructure(string &pathUrl); void setURL(const string &Url); void setUsername(const string &Username); void setPassword(const string &Pass); void setStartFolder(const string &Path); - std::shared_ptr> getItems() const { return _items; }; + vector getItems() const { return _items; }; bool isLoggedIn() const { return _loggedIn; }; bool isWorkOffline() const { return _workOffline; }; void switchWorkOffline() { _workOffline = !_workOffline; }; @@ -80,10 +87,14 @@ public: void getLocalFileStructure(const string &localPath); -private: - static Nextcloud *nextcloudStatic; - std::shared_ptr> _items = nullptr; + bool setItems(const vector &tempItems); + + +private: + static std::unique_ptr _nextcloudStatic; + + vector _items; bool _loggedIn{false}; string _url; bool _workOffline{false}; @@ -94,9 +105,9 @@ private: * @param pathUrl URL to get the dataStructure of * @param Username the username of the Nextcloud instance * @param Pass the pass of the Nextcloud instance - * @return true - sucessfull, false - error + * @return vector of Items */ - bool getDataStructure(const string &pathUrl, const string &Username, const string &Pass); + vector getDataStructure(const string &pathUrl, const string &Username, const string &Pass); string getUrl(); string getUsername(); @@ -112,9 +123,9 @@ private: */ static void DialogHandlerStatic(int Button); - bool readInXML(string xml); + vector readInXML(string xml); - bool getOfflineStructure(const string &pathUrl); + vector getOfflineStructure(const string &pathUrl); }; #endif \ No newline at end of file