This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/gcui/gwinpckf.cpp

232 lines
6.1 KiB
C++

// This may look like C code, but it is really -*- C++ -*-
// ------------------------------------------------------------------
// The Goldware Library
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307, USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// GCUI: Golded+ Character-oriented User Interface.
// wpickfile() - Allows user to select a file name.
// ------------------------------------------------------------------
#include <gctype.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <gmemdbg.h>
#include <gfilutil.h>
#include <gwildmat.h>
#include <gwinall.h>
#include <gfilutil.h>
#include <gdirposx.h>
#include <gstrall.h>
// ------------------------------------------------------------------
static bool path_in_title, case_sensitive;
static IfcpCP open_function = NULL;
static char* cwdp;
static char* tcwdp;
static char* namextp;
// ------------------------------------------------------------------
// this function is the compare function for std::sort()
static bool compare(const std::string str1, const std::string str2)
{
// Sort with directories first
bool dir1 = !!strchr(str1.c_str(), GOLD_SLASH_CHR);
bool dir2 = !!strchr(str2.c_str(), GOLD_SLASH_CHR);
if (dir1 && !dir2) return true;
if (!dir1 && dir2) return false;
std::string s1 = dir1 ? str1.substr(0, str1.length()-1) : str1;
std::string s2 = dir2 ? str2.substr(0, str2.length()-1) : str2;
int cmp;
if (case_sensitive)
cmp = strcmp(s1.c_str(), s2.c_str());
else
{
cmp = stricmp(s1.c_str(), s2.c_str());
if (cmp == 0)
cmp = strcmp(s1.c_str(), s2.c_str());
}
return (cmp < 0);
}
// ------------------------------------------------------------------
// this function displays the title on the pick window border
static void disp_title() {
char buf[sizeof(Path)+2];
if(path_in_title or open_function) {
strcpy(buf, " ");
PathCopy(buf+1, cwdp);
strcat(buf, namextp);
strcat(buf, " ");
}
if(path_in_title) {
wtitle(buf, TCENTER, gwin.active->battr);
}
if(open_function) {
(*open_function)(buf);
}
}
// ------------------------------------------------------------------
bool wpickfile(int srow, int scol, int erow, int ecol, int btype, vattr bordattr, vattr winattr, vattr barattr, bool title, std::string &filespec, IfcpCP open, bool casesens)
{
Path cwd, dir, namext, tcwd, path, spec;
cwdp = cwd;
tcwdp = tcwd;
namextp = namext;
// set static variables
open_function = open;
path_in_title = title;
case_sensitive = casesens;
// save current working directory
getcwd(tcwd, GMAXPATH);
// if drive was specified, change to it
char* q = strxcpy(spec, filespec.c_str(), sizeof(Path));
// split up input filespec into its current
// working directory and filename/extension
char* r = strrchr(q, GOLD_SLASH_CHR);
#if defined(__HAVE_DRIVES__)
if(r == NULL)
if(q[1] == ':')
r = q + 1;
#endif
if(r == NULL) {
*dir = NUL;
strcpy(namext, q);
}
else {
strins(" ", ++r, 0);
*r++ = NUL;
strcpy(dir, q);
strcpy(namext, r);
}
bool finished;
int picked;
do
{
// if directory was specified, change to it
if (*dir && gchdir(dir))
{
gchdir(tcwdp);
return false;
}
// get current working directory
getcwd(cwd, GMAXPATH);
strcpy(dir, cwd);
// find all directories plus all files matching input filespec in
// current directory, allocating an array element for each
picked = -1;
gposixdir d(dir);
gstrarray strarr;
const gdirentry *de;
if (d.ok)
{
while((de = d.nextentry()) != NULL)
{
const char* name = NULL;
if (de->is_directory())
{
if(de->name != ".") {
strxmerge(path, sizeof(Path), de->name.c_str(), GOLD_SLASH_STR, NULL);
name = path;
}
}
else if(de->is_file())
{
if(case_sensitive ? gwildmat(de->name.c_str(), namext) : gwildmati(de->name.c_str(), namext))
name = de->name.c_str();
}
if (name) strarr.push_back(name);
}
}
// sort files in array by swapping their pointers
std::sort(strarr.begin(), strarr.end(), compare);
// let user pick file
if (strarr.size())
{
picked = wpickstr(srow, scol, erow, ecol, btype, bordattr, winattr, barattr, strarr, 0, disp_title);
}
if (picked == -1 or !strarr.size())
{
gchdir(tcwdp);
return false;
}
// see if a directory was selected. if so save
// directory name, otherwise build whole path name
const char *slash = strchr(strarr[picked].c_str(), GOLD_SLASH_CHR);
if (slash)
{
finished = false;
strcpy(dir, strarr[picked].c_str());
r = strrchr(dir, GOLD_SLASH_CHR);
if (r) *r = NUL;
}
else {
finished = true;
PathCopy(filespec, cwd);
filespec += strarr[picked].c_str();
}
strarr.clear();
}
while(not finished); // if a directory was selected, go back and do again
gchdir(tcwd); // change back to current drive and directory
return true; // return normally
}
// ------------------------------------------------------------------