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/gall/gwinpckf.cpp
Alexander S. Aganichev 428385bc1e Random fixes
2002-11-09 21:08:34 +00:00

262 lines
6.7 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$
// ------------------------------------------------------------------
// Allows user to select a file name.
// ------------------------------------------------------------------
#include <gctype.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#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 qsort()
static int compare(const char** str1, const char** str2) {
// Sort with directories first
bool dir1 = !!strchr(*str1, GOLD_SLASH_CHR);
bool dir2 = !!strchr(*str2, GOLD_SLASH_CHR);
int cmp = compare_two(dir2, dir1);
if(cmp != 0)
return cmp;
Path p1, p2;
strcpy(p1, *str1); if(dir1) { p1[strlen(p1)-1] = NUL; }
strcpy(p2, *str2); if(dir2) { p2[strlen(p2)-1] = NUL; }
if(case_sensitive)
return strcmp(p1, p2);
else {
cmp = stricmp(p1, p2);
if(cmp == 0)
cmp = strcmp(p1, p2);
}
return cmp;
}
// ------------------------------------------------------------------
// 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);
}
}
// ------------------------------------------------------------------
// this function frees all allocated strings in the array of pointers
static void free_strings(char** p, int numelems) {
for(int i=0;i<numelems;i++)
throw_xfree(p[i]);
}
// ------------------------------------------------------------------
static void pre_exit(char** p, int numelems) {
free_strings(p,numelems);
throw_xfree(p);
gchdir(tcwdp);
}
// ------------------------------------------------------------------
bool wpickfile(int srow, int scol, int erow, int ecol, int btype, int bordattr, int winattr, int barattr, bool title, std::string &filespec, IfcpCP open, bool casesens) {
Path cwd, dir, namext, tcwd, path, spec;
cwdp = cwd;
tcwdp = tcwd;
namextp = namext;
// allocate space to hold array of char pointers
int allocated = 100;
char** p = (char**)throw_xmalloc(allocated*sizeof(char*));
// 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, files;
do {
// if directory was specified, change to it
if(*dir) {
if(gchdir(dir)) {
pre_exit(p, 0);
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
files = 0;
picked = -1;
gposixdir d(dir);
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) {
p[files] = throw_xstrdup(name);
files++;
if(files == allocated-1) {
allocated *= 2;
p = (char**)throw_xrealloc(p, allocated*sizeof(char*));
}
}
}
}
p[files] = NULL;
// sort files in array by swapping their pointers
qsort(p, files, sizeof(char*), (StdCmpCP)compare);
// let user pick file
if(files)
picked = wpickstr(srow, scol, erow, ecol, btype, bordattr, winattr, barattr, p, 0, disp_title);
if(picked == -1 or files == 0) {
pre_exit(p, files);
return false;
}
// see if a directory was selected. if so save
// directory name, otherwise build whole path name
q = strchr(p[picked], GOLD_SLASH_CHR);
if(q) {
finished = false;
strcpy(dir, p[picked]);
r = strrchr(dir, GOLD_SLASH_CHR);
if(r)
*r = NUL;
*q = NUL;
}
else {
finished = true;
PathCopy(filespec, cwd);
filespec += p[picked];
}
// free allocated strings
free_strings(p, files);
// if a directory was selected, go back and do again
} while(not finished);
// change back to current drive and directory
gchdir(tcwd);
// free allocated char pointers
throw_xfree(p);
// return normally
return true;
}
// ------------------------------------------------------------------