#include "dirBrowser.h"
#include "defines.h"
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "folder.xpm"
char currPath[PATH_MAX];
char pathName[NAME_MAX];
GtkWidget *browserDialog;
GtkWidget *directoryList;
/* This function will strip the last directory entry off of a path */
void stripDirectory(char *pathStr)
{
int length;
int pos;
/* Get the length of our string */
length=strlen(pathStr);
/* If the length of our string is 1 then we must already be at the root */
if (length==1) return;
/* Set the position to point to the last character in the
pathStr array */
pos=length-1;
/* If the last character is a slash then backup 1 */
if (pathStr[pos]=='/') pos--;
/* Backup until we hit a slash */
while (pathStr[pos]!='/') pos--;
/* Put a null character into our position to terminate the string there */
pathStr[pos]='\0';
/* Make sure we add a trailing slash */
checkSlash(pathStr);
}
void getLastName(char *pathStr,char *name)
{
int length;
int pos;
int nameLength;
length=strlen(pathStr);
if (length==1) return;
pos=length-1;
if (pathStr[pos]=='/') pos--;
while (pathStr[pos]!='/') pos--;
nameLength=length-pos-1;
pos++;
strcpy(name,&pathStr[pos]);
if (name[strlen(name)-1]=='/') name[strlen(name)-1]='\0';
}
void selectText(GtkCList *listWidget,char *selectedText)
{
int numRows;
int i;
gchar *listText;
numRows=listWidget->rows;
for (i=0;i<numRows;i++) {
gtk_clist_get_text(listWidget,i,0,&listText);
if (strcmp(selectedText,listText)==0) {
gtk_clist_select_row(listWidget,i,0);
}
}
}
void sortInsert(GtkCList *pList,char *entry)
{
gchar *firstText[1];
int position;
int num;
gchar *text;
position=0;
num=pList->rows;
firstText[0]=(gchar *)malloc(strlen(entry)+1);
strcpy(firstText[0],entry);
if (num==0) {
gtk_clist_append(pList,firstText);
} else {
gtk_clist_get_text(pList,position,0,&text);
while ((position<num) && strncasecmp(text,entry,strlen(entry)) < 0) {
position++;
gtk_clist_get_text(pList,position,0,&text);
}
gtk_clist_insert(pList,position,firstText);
}
}
void fillBrowserList(GtkWidget *directoryList)
{
DIR *directory;
struct dirent *directoryEntry;
struct stat statBuf;
char fullDirName[PATH_MAX];
/* Freeze the list */
gtk_clist_freeze(GTK_CLIST(directoryList));
/* Open the directory */
directory=opendir(currPath);
/* Search through the directory list */
while ((directoryEntry=readdir(directory))!=NULL) {
/* Make sure it's not the entry for the current directory */
if (strcmp(directoryEntry->d_name,".")) {
sprintf(fullDirName,"%s%s",currPath,directoryEntry->d_name);
stat(fullDirName,&statBuf);
/* Is it a directory? */
if (S_ISDIR(statBuf.st_mode)) {
sortInsert(GTK_CLIST(directoryList),directoryEntry->d_name);
}
}
}
/* Thaw the directory list */
gtk_clist_thaw(GTK_CLIST(directoryList));
/* Close the directory */
closedir(directory);
}
void listDoubleClick(GtkWidget *widget,gint row,gint col,GdkEventButton *event,
gpointer data)
{
GList *selection;
gchar *text;
if (event==NULL) return;
/* Check to see if we have a double click */
if (event->state==0) {
/* Get our selection */
selection=((GtkCList*)widget)->selection;
/* If no selection is made then return */
if (selection==NULL) return;
/* Get the name of our selection */
gtk_clist_get_text(GTK_CLIST(widget),row,0,&text);
/* Check to see if they are moving up a directory */
if (strcmp(text,"..")==0) stripDirectory(currPath);
else {
/* Append the new string to our current path */
strcat(currPath,text);
/* Make sure to add a trailing slash if there isn't one */
checkSlash(currPath);
}
/* Clear the list */
gtk_clist_clear(GTK_CLIST(widget));
/* Fill the list */
fillBrowserList(widget);
}
}
void browserOkPressed(GtkWidget *widget,gpointer okFunction)
{
void (*okFunc)();
GList *selection;
gchar *text;
int row;
okFunc=okFunction;
selection=((GtkCList*)directoryList)->selection;
if (selection==NULL) return;
row=(int)selection->data;
gtk_clist_get_text(GTK_CLIST(directoryList),row,0,&text);
strcat(currPath,text);
checkSlash(currPath);
okFunc(currPath);
gtk_widget_destroy(browserDialog);
}
void showDirBrowser(GtkSignalFunc okFunction,char *pathStart)
{
GtkWidget *okButton;
GtkWidget *cancelButton;
GtkWidget *scrolledWidget;
strcpy(pathName,"");
/* Create the dialog box */
browserDialog=gtk_dialog_new();
/* Set the title */
gtk_window_set_title(GTK_WINDOW(browserDialog),"Locate Directory");
/* Set the size of the dialog box */
gtk_widget_set_usize(browserDialog,230,350);
/* Create the ok button */
okButton=gtk_button_new_with_label("Okay");
/* Place the ok button in the dialog's action area */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(browserDialog)->action_area),
okButton,TRUE,TRUE,0);
/* If the ok button is clicked then call the funtion we were passed */
gtk_signal_connect(GTK_OBJECT(okButton),"clicked",
GTK_SIGNAL_FUNC(browserOkPressed),(gpointer)okFunction);
/* Show the ok button */
gtk_widget_show(okButton);
/* Create the cancel button */
cancelButton=gtk_button_new_with_label("Cancel");
/* Place the cancel button in the dialog's action area */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(browserDialog)->action_area),
cancelButton,TRUE,TRUE,0);
/* Close the dialog if the cancel button is pressed */
gtk_signal_connect_object(GTK_OBJECT(cancelButton),"clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),GTK_OBJECT(browserDialog));
/* Show the cancel button */
gtk_widget_show(cancelButton);
/* Set the current path */
getLastName(pathStart,pathName);
strcpy(currPath,pathStart);
stripDirectory(currPath);
/* Create the scrollable widget to place the directory list into */
scrolledWidget=gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWidget),
GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(browserDialog)->vbox),
scrolledWidget,TRUE,TRUE,0);
gtk_widget_show(scrolledWidget);
/* Create the directory list widget */
directoryList=gtk_clist_new(1);
gtk_clist_set_shadow_type(GTK_CLIST(directoryList),GTK_SHADOW_OUT);
gtk_clist_set_column_width(GTK_CLIST(directoryList),0,200);
gtk_container_add(GTK_CONTAINER(scrolledWidget),directoryList);
gtk_signal_connect(GTK_OBJECT(directoryList),"select_row",
GTK_SIGNAL_FUNC(listDoubleClick),NULL);
gtk_widget_show(directoryList);
/* Need to set the path name to the name of the current directory */
/* Fill the directory list */
fillBrowserList(directoryList);
selectText(GTK_CLIST(directoryList),pathName);
/* Set the dialog to modal mode */
gtk_window_set_modal(GTK_WINDOW(browserDialog),TRUE);
/* Show the browser dialog */
gtk_widget_show(browserDialog);
}
syntax highlighted by Code2HTML, v. 0.9.1