ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

remotebrowser.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "gui/remotebrowser.h"
00024 #include "gui/gui-manager.h"
00025 #include "gui/widgets/list.h"
00026 
00027 #include "common/config-manager.h"
00028 #include "common/system.h"
00029 #include "common/algorithm.h"
00030 
00031 #include "common/translation.h"
00032 #include "backends/networking/curl/request.h"
00033 #include "backends/cloud/storage.h"
00034 #include "backends/cloud/cloudmanager.h"
00035 #include "message.h"
00036 
00037 namespace GUI {
00038 
00039 enum {
00040     kChooseCmd = 'Chos',
00041     kGoUpCmd = 'GoUp'
00042 };
00043 
00044 RemoteBrowserDialog::RemoteBrowserDialog(const char *title):
00045     Dialog("Browser"), _navigationLocked(false), _updateList(false), _showError(false),
00046     _workingRequest(nullptr), _ignoreCallback(false) {
00047     _backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
00048 
00049     new StaticTextWidget(this, "Browser.Headline", title);
00050     _currentPath = new StaticTextWidget(this, "Browser.Path", "DUMMY");
00051 
00052     _fileList = new ListWidget(this, "Browser.List");
00053     _fileList->setNumberingMode(kListNumberingOff);
00054     _fileList->setEditable(false);
00055 
00056     if (g_system->getOverlayWidth() > 320)
00057         new ButtonWidget(this, "Browser.Up", _("Go up"), _("Go to previous directory level"), kGoUpCmd);
00058     else
00059         new ButtonWidget(this, "Browser.Up", _c("Go up", "lowres"), _("Go to previous directory level"), kGoUpCmd);
00060     new ButtonWidget(this, "Browser.Cancel", _("Cancel"), 0, kCloseCmd);
00061     new ButtonWidget(this, "Browser.Choose", _("Choose"), 0, kChooseCmd);
00062 }
00063 
00064 RemoteBrowserDialog::~RemoteBrowserDialog() {
00065     if (_workingRequest) {
00066         _ignoreCallback = true;
00067         _workingRequest->finish();
00068     }
00069 }
00070 
00071 void RemoteBrowserDialog::open() {
00072     Dialog::open();
00073     listDirectory(Cloud::StorageFile());
00074 }
00075 
00076 void RemoteBrowserDialog::close() {
00077     Dialog::close();
00078     if (_workingRequest) {
00079         _ignoreCallback = true;
00080         _workingRequest->finish();
00081         _ignoreCallback = false;
00082     }
00083 }
00084 
00085 void RemoteBrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
00086     switch (cmd) {
00087     case kChooseCmd: {
00088         // If nothing is selected in the list widget, choose the current dir.
00089         // Else, choose the dir that is selected.
00090         int selection = _fileList->getSelected();
00091         if (selection >= 0)
00092             _choice = _nodeContent[selection];
00093         else
00094             _choice = _node;
00095         setResult(1);
00096         close();
00097         break;
00098     }
00099     case kGoUpCmd:
00100         goUp();
00101         break;
00102     case kListItemActivatedCmd:
00103     case kListItemDoubleClickedCmd:
00104         if (_nodeContent[data].isDirectory()) {
00105             _rememberedNodeContents[_node.path()] = _nodeContent;
00106             listDirectory(_nodeContent[data]);
00107         }
00108         break;
00109     case kListSelectionChangedCmd:
00110         // We do not allow selecting directories,
00111         // thus we will invalidate the selection
00112         // when the user selects a directory over here.
00113         if (data != (uint32)-1 && !_nodeContent[data].isDirectory())
00114             _fileList->setSelected(-1);
00115         break;
00116     default:
00117         Dialog::handleCommand(sender, cmd, data);
00118     }
00119 }
00120 
00121 void RemoteBrowserDialog::handleTickle() {
00122     if (_updateList) {
00123         updateListing();
00124         _updateList = false;
00125     }
00126 
00127     if (_showError) {
00128         _showError = false;
00129         MessageDialog alert(_("ScummVM could not access the directory!"));
00130         alert.runModal();
00131     }
00132 
00133     Dialog::handleTickle();
00134 }
00135 
00136 void RemoteBrowserDialog::updateListing() {
00137     // Update the path display
00138     Common::String path = _node.path();
00139     if (path.empty())
00140         path = "/"; //root
00141     if (_navigationLocked)
00142         path = "Loading... " + path;
00143     _currentPath->setLabel(path);
00144 
00145     if (!_navigationLocked) {
00146         // Populate the ListWidget
00147         ListWidget::StringArray list;
00148         ListWidget::ColorList colors;
00149         for (Common::Array<Cloud::StorageFile>::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
00150             if (i->isDirectory()) {
00151                 list.push_back(i->name() + "/");
00152                 colors.push_back(ThemeEngine::kFontColorNormal);
00153             } else {
00154                 list.push_back(i->name());
00155                 colors.push_back(ThemeEngine::kFontColorAlternate);
00156             }
00157         }
00158 
00159         _fileList->setList(list, &colors);
00160         _fileList->scrollTo(0);
00161     }
00162 
00163     _fileList->setEnabled(!_navigationLocked);
00164 
00165     // Finally, redraw
00166     g_gui.scheduleTopDialogRedraw();
00167 }
00168 
00169 void RemoteBrowserDialog::goUp() {
00170     if (_rememberedNodeContents.contains(_node.path()))
00171         _rememberedNodeContents.erase(_node.path());
00172 
00173     Common::String path = _node.path();
00174     if (path.size() && (path.lastChar() == '/' || path.lastChar() == '\\'))
00175         path.deleteLastChar();
00176     if (path.empty()) {
00177         _rememberedNodeContents.erase("");
00178     } else {
00179         for (int i = path.size() - 1; i >= 0; --i)
00180             if (i == 0 || path[i] == '/' || path[i] == '\\') {
00181                 path.erase(i);
00182                 break;
00183             }
00184     }
00185 
00186     listDirectory(Cloud::StorageFile(path, 0, 0, true));
00187 }
00188 
00189 void RemoteBrowserDialog::listDirectory(Cloud::StorageFile node) {
00190     if (_navigationLocked || _workingRequest)
00191         return;
00192 
00193     if (_rememberedNodeContents.contains(node.path())) {
00194         _nodeContent = _rememberedNodeContents[node.path()];
00195     } else {
00196         _navigationLocked = true;
00197 
00198         _workingRequest = CloudMan.listDirectory(
00199             node.path(),
00200             new Common::Callback<RemoteBrowserDialog, Cloud::Storage::ListDirectoryResponse>(this, &RemoteBrowserDialog::directoryListedCallback),
00201             new Common::Callback<RemoteBrowserDialog, Networking::ErrorResponse>(this, &RemoteBrowserDialog::directoryListedErrorCallback),
00202             false
00203         );
00204     }
00205 
00206     _backupNode = _node;
00207     _node = node;
00208     updateListing();
00209 }
00210 
00211 void RemoteBrowserDialog::directoryListedCallback(Cloud::Storage::ListDirectoryResponse response) {
00212     _workingRequest = nullptr;
00213     if (_ignoreCallback)
00214         return;
00215 
00216     _navigationLocked = false;
00217     _nodeContent = response.value;
00218     Common::sort(_nodeContent.begin(), _nodeContent.end(), FileListOrder());
00219     _updateList = true;
00220 }
00221 
00222 void RemoteBrowserDialog::directoryListedErrorCallback(Networking::ErrorResponse error) {
00223     _workingRequest = nullptr;
00224     if (_ignoreCallback)
00225         return;
00226 
00227     _navigationLocked = false;
00228     _node = _backupNode;
00229     _updateList = true;
00230     _showError = true;
00231 }
00232 
00233 } // End of namespace GUI


Generated on Sat May 18 2019 05:01:18 for ResidualVM by doxygen 1.7.1
curved edge   curved edge