From 510d7da958153afd3749906e2dd816bc9c41efc6 Mon Sep 17 00:00:00 2001 From: "jsc@umbraculum.org" Date: Fri, 26 Apr 2013 09:30:45 +0200 Subject: Re-factored and -written. Does not change working directory. Showing drives on windows when in root is a missing feature (will be fixed later). --- plugingui/Makefile.am | 4 +- plugingui/directory.cc | 167 +++++++++++++++++++++++++++++++++++++++++++++++ plugingui/directory.h | 80 +++++++++++++++++++++++ plugingui/filebrowser.cc | 76 +++++++++++++++++---- plugingui/filebrowser.h | 1 + 5 files changed, 316 insertions(+), 12 deletions(-) create mode 100644 plugingui/directory.cc create mode 100644 plugingui/directory.h (limited to 'plugingui') diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am index 53c44e6..3219987 100644 --- a/plugingui/Makefile.am +++ b/plugingui/Makefile.am @@ -14,6 +14,7 @@ plugingui_CFLAGS = $(plugingui_CXXFLAGS) plugingui_SOURCES = \ $(PLUGIN_GUI_SOURCES) \ + directory.cc \ $(top_srcdir)/src/thread.cc \ $(top_srcdir)/src/semaphore.cc @@ -23,7 +24,8 @@ EXTRA_DIST = \ button.h \ checkbox.h \ colour.h \ - eventhandler.h \ + directory.h \ + eventhandler.h \ font.h \ globalcontext.h \ guievent.h \ diff --git a/plugingui/directory.cc b/plugingui/directory.cc new file mode 100644 index 0000000..f38d444 --- /dev/null +++ b/plugingui/directory.cc @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * directory.cc + * + * Tue Apr 23 22:01:07 CEST 2013 + * Copyright 2013 Jonas Suhr Christensen + * jsc@umbraculum.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "directory.h" + +#include + +#include + +Directory::Directory(std::string path) { + setPath(path); +} + +Directory::~Directory() { +} + +void Directory::setPath(std::string path) { + DEBUG(directory, "Setting path to '%s'\n", path.c_str()); + this->_path = path; + refresh(); +} + +size_t Directory::count() { + return _files.size(); +} + +void Directory::refresh() { + _files = listFiles(this->_path); +} + +bool Directory::cd(std::string dir) { + DEBUG(directory, "Changing to '%s'\n", dir.c_str()); + int r = chdir(dir.c_str()); + refresh(); + if(!r) return true; + else return false; +} + +bool Directory::cdUp() { + this->cd(".."); +} + +std::string Directory::path() { + return _path; +} + +Directory::EntryList Directory::entryList() { + return _files; +} + +#define MAX_FILE_LENGTH 1024 +std::string Directory::cwd() { + char path[MAX_FILE_LENGTH]; + char* c = getcwd(path, MAX_FILE_LENGTH); + + if(c) return c; + else return ""; +} + +std::string Directory::cleanPath(std::string path) { + // TODO! + return path; +} + +Directory::EntryList Directory::listFiles(std::string path) { + Directory::EntryList entries; + DIR *dir = opendir("."); + if(!dir) { + return entries; + } + + struct dirent *entry; + while((entry = readdir(dir)) != NULL) { + entries.push_back(entry->d_name); + } + + return entries; +} + +bool Directory::isRoot(std::string path) { + if(path == "/") return true; + else return false; +} + +Directory::DriveList Directory::drives() { + Directory::DriveList drives; +#ifdef WIN32 + unsigned int d = GetLogicalDrives(); + for(int i = 0; i < 32; i++) { + if(d & (1 << i)) { + drive_t drive; + char name[] = "X:"; + name[0] = i + 'A'; + + char num[32]; + sprintf(num, "%d", i); + + drive.name = name; + drive.number = num; + drives.push_back(drive); + } + } +#endif + return drives; +} + +bool Directory::isDir() +{ + return isDir(path()); +} + +bool Directory::exists(std::string filename) { + return !isDir(path() + "/" + filename); +} + +bool Directory::isDir(std::string path) { + DEBUG(directory, "Is '%s' dir?\n", path.c_str()); + struct stat st; + if(stat(path.c_str(), &st) == 0) { + if((st.st_mode & S_IFDIR) != 0) { + DEBUG(directory, "Yes\n"); + return true; + } + } + DEBUG(directory, "No\n"); + return false; +} + +#ifdef TEST_DIRECTORY +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" + +TEST_BEGIN; + +// TODO: Put some testcode here (see test.h for usable macros). + +TEST_END; + +#endif/*TEST_DIRECTORY*/ diff --git a/plugingui/directory.h b/plugingui/directory.h new file mode 100644 index 0000000..53213ee --- /dev/null +++ b/plugingui/directory.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * directory.h + * + * Tue Apr 23 22:01:07 CEST 2013 + * Copyright 2013 Jonas Suhr Christensen + * jsc@umbraculum.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __DRUMGIZMO_DIRECTORY_H__ +#define __DRUMGIZMO_DIRECTORY_H__ + +#include +#include + +#include + +#include +#include +#include + +class Directory { + + public: + typedef struct drive { + int number; + std::string name; + } drive_t; + + typedef std::list EntryList; + typedef std::list DriveList; + + Directory(std::string path); + ~Directory(); + + size_t count(); + void refresh(); + std::string path(); + bool cdUp(); + bool cd(std::string dir); + bool isDir(); + void setPath(std::string path); + bool exists(std::string file); + + // Add filter, ie. directories or files only + EntryList entryList(); + + //void setSorting(); + + static std::string cwd(); + static std::string cleanPath(std::string path); + static Directory::EntryList listFiles(std::string path); + static bool isRoot(std::string path); + static Directory::DriveList drives(); + static bool isDir(std::string path); + + private: + std::string _path; + EntryList _files; + DriveList _drives; +}; + +#endif/*__DRUMGIZMO_DIRECTORY_H__*/ diff --git a/plugingui/filebrowser.cc b/plugingui/filebrowser.cc index 2bd1a10..be909dd 100644 --- a/plugingui/filebrowser.cc +++ b/plugingui/filebrowser.cc @@ -27,9 +27,10 @@ #include "filebrowser.h" #include "painter.h" - #include "button.h" +#include "directory.h" + #include #include #include @@ -50,9 +51,10 @@ struct GUI::FileBrowser::private_data { GUI::ComboBox *drives; void (*filesel_handler)(void *, std::string); void *ptr; -#ifdef WIN32 - int drvidx; -#endif + Directory *dir; +//#ifdef WIN32 +// int drvidx; +//#endif }; static void cancel(void *ptr) @@ -61,6 +63,48 @@ static void cancel(void *ptr) fp->hide(); } +static void changeDir(void *ptr) { + struct GUI::FileBrowser::private_data *prv = + (struct GUI::FileBrowser::private_data *) ptr; + + + GUI::ListBox *lb = prv->listbox; + GUI::LineEdit *le = prv->lineedit; + std::string value = lb->selectedValue(); + Directory* dir = prv->dir; + + INFO(filebrowser, "Changing dir to '%s'\n", (dir->path() + "/" + value).c_str()); + + if(!value.empty() && dir->exists(value)) { + std::string file = dir->path() + "/" + value; + DEBUG(filebrowser, "Selecting file '%s'\n", file.c_str()); + if(prv->filesel_handler) prv->filesel_handler(prv->ptr, file); + return; + } + + if(!value.empty() && !dir->cd(value)) { + DEBUG(filebrowser, "Error changing to '%s'\n", + (dir->path() + "/" + value).c_str()); + return; + } + + //TODO: If root and windows show drives instead of files + + lb->clear(); + std::vector items; + Directory::EntryList entries = dir->entryList(); + for(Directory::EntryList::iterator it = entries.begin(); + it != entries.end(); it++) { + GUI::ListBoxBasic::Item item; + std::string name = *it; + item.name = name; + item.value = name; + items.push_back(item); + } + lb->addItems(items); +} + +#if 0 static void changeDir(void *ptr) { struct GUI::FileBrowser::private_data *prv = @@ -139,6 +183,7 @@ static void changeDir(void *ptr) closedir(dir); } +#endif/*0*/ GUI::FileBrowser::FileBrowser(GUI::Widget *parent) : GUI::Widget(parent), @@ -151,6 +196,8 @@ GUI::FileBrowser::FileBrowser(GUI::Widget *parent) prv = new struct GUI::FileBrowser::private_data(); prv->filesel_handler = NULL; + prv->dir = new Directory(Directory::cwd()); + lbl_path.setText("Path:"); lineedit.setReadOnly(true); @@ -165,6 +212,8 @@ GUI::FileBrowser::FileBrowser(GUI::Widget *parent) btn_esc.setText("Cancel"); btn_esc.registerClickHandler(cancel, this); + changeDir(prv); +/* #ifdef WIN32 lbl_drive.setText("Drive:"); @@ -185,8 +234,9 @@ GUI::FileBrowser::FileBrowser(GUI::Widget *parent) } prv->drives = &drv; #endif +*/ - changeDir(prv); +// changeDir(prv); resize(200, 190); } @@ -197,6 +247,7 @@ GUI::FileBrowser::~FileBrowser() delete prv; } +#if 0 #include static bool isDir(std::string d) @@ -213,23 +264,26 @@ static bool isDir(std::string d) DEBUG(dir, "No\n"); return false; } +#endif void GUI::FileBrowser::setPath(std::string path) { +// prv->dir->setPath(path); +/* std::string dir; - if(isDir(path)) { + if(prv->dir->isDir()) { dir = path; } else { char *d = strdup(path.c_str()); std::string _dirname = dirname(d); free(d); - if(isDir(_dirname)) dir = _dirname; + if(prv->dir->isDir(_dirname)) dir = _dirname; else return; } - - if(chdir(dir.c_str()) == -1) return; - prv->listbox->clear(); - changeDir(prv); +*/ +// if(chdir(dir.c_str()) == -1) return; +// prv->listbox->clear(); +// changeDir(prv); /* std::string dirname = path; diff --git a/plugingui/filebrowser.h b/plugingui/filebrowser.h index 6953dad..cd389be 100644 --- a/plugingui/filebrowser.h +++ b/plugingui/filebrowser.h @@ -35,6 +35,7 @@ #include "lineedit.h" #include "label.h" #include "image.h" +#include "directory.h" namespace GUI { -- cgit v1.2.3