config/cf/{DragonFly,OpenBSD,darwin}.cf: Remove Freetype imake settings
config/cf/darwinLib.tmpl: Do not link against Freetype
debian/control: Remove Freetype and Xft dependencies
*/Imakefile: Purge Freetype includes
lib/DtWidget/ComboBoxP.h
lib/DtWidget/SpinBoxP.h
programs/dtfile/ChangeDirP.c
programs/dtlogin/vgcallback.c
Undefine USE_XFT so Motif 2.3 doesn't pull in Freetype
CDE included Freetype and Xft solely to satisfy builds of Motif with
Xft support enabled. However, as CDE only supports bitmap fonts, this
dependency was entirely superfluous and unnecessarily broke backwards
compatibility with older systems.
1393 lines
42 KiB
C
1393 lines
42 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $TOG: ChangeDirP.c /main/8 1998/04/01 15:05:07 rafi $ */
|
|
/************************************<+>*************************************
|
|
****************************************************************************
|
|
*
|
|
* FILE: ChangeDirP.c
|
|
*
|
|
* COMPONENT_NAME: Desktop File Manager (dtfile)
|
|
*
|
|
* Description: Processing functions for the change directory display
|
|
* line and the current directory dialog.
|
|
*
|
|
* FUNCTIONS: ABS
|
|
* CheckCurrentDirectorySelect
|
|
* CurrentDirChange
|
|
* CurrentDirClose
|
|
* CurrentDirDropCallback
|
|
* CurrentDirExposed
|
|
* CurrentDirIconCallback
|
|
* CurrentDirSelected
|
|
* CurrentDirectoryIconMotion
|
|
* DrawCurrentDirectory
|
|
* GetStatusMsg
|
|
* ResizeFastText
|
|
* ShowChangeDirDialog
|
|
* ShowFastChangeDir
|
|
* TimerEvent
|
|
* draw_imagestring
|
|
* get_text_pieces
|
|
* get_textwidth
|
|
*
|
|
* (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
|
|
* (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
|
|
* (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
|
|
* (c) Copyright 1993, 1994, 1995 Novell, Inc.
|
|
*
|
|
****************************************************************************
|
|
************************************<+>*************************************/
|
|
|
|
#include <limits.h>
|
|
#include <Xm/Xm.h>
|
|
#include <Xm/XmP.h>
|
|
#include <Xm/DrawP.h>
|
|
#undef USE_XFT
|
|
#include <Xm/TextFP.h>
|
|
#include <Xm/PushBG.h>
|
|
#include <Xm/DragDrop.h>
|
|
#include <Xm/RowColumn.h>
|
|
#include <Dt/Icon.h>
|
|
#include <Dt/IconP.h>
|
|
#include <Dt/DtNlUtils.h>
|
|
#include <Dt/Connect.h>
|
|
#include <Dt/FileM.h>
|
|
#include "Encaps.h"
|
|
#include "SharedProcs.h"
|
|
|
|
#include "Desktop.h"
|
|
#include "FileMgr.h"
|
|
#include "Main.h"
|
|
#include "ChangeDir.h"
|
|
#include "Prefs.h"
|
|
|
|
|
|
/******** Static Function Declarations ********/
|
|
|
|
static void CurrentDirChange(
|
|
XtPointer client_data,
|
|
DialogData *old_dialog_data,
|
|
DialogData *new_dialog_data,
|
|
XtPointer call_data) ;
|
|
static void CurrentDirClose(
|
|
XtPointer client_data,
|
|
DialogData *old_dialog_data,
|
|
DialogData *new_dialog_data) ;
|
|
static void CheckCurrentDirectorySelect(
|
|
FileMgrData *file_mgr_data ) ;
|
|
static void TimerEvent(
|
|
XtPointer client_data,
|
|
XtIntervalId *id );
|
|
static void ResizeFastText(
|
|
FileMgrRec *file_mgr_rec,
|
|
FileMgrData *file_mgr_data,
|
|
short columns) ;
|
|
static int get_textwidth(
|
|
FileMgrData *fmd,
|
|
char *str,
|
|
int len);
|
|
static void draw_imagestring(
|
|
Display *display,
|
|
Drawable d,
|
|
FileMgrData *fmd,
|
|
GC gc,
|
|
int x, int y,
|
|
char *text,
|
|
int bytes);
|
|
|
|
/******** End Static Function Declarations ********/
|
|
|
|
/* absolute value macro */
|
|
#ifndef ABS
|
|
#define ABS(x) (((x) > 0) ? (x) : (-(x)))
|
|
#endif
|
|
|
|
/* layout constants */
|
|
#define CUR_DIR_SPACING 5
|
|
|
|
|
|
/* local global varible to determine whether the user has double clicked
|
|
or not */
|
|
static Boolean doubleClick = False;
|
|
|
|
/*--------------------------------------------------------------------
|
|
* get_text_pieces:
|
|
*
|
|
* Given a width available for the current directory text,
|
|
* determines the text to be drawn in one of three formats:
|
|
*
|
|
* /path (non-restricted directory)
|
|
* /.../path (restricted directory)
|
|
* .../subpath (if the full path wouldn't fit)
|
|
*
|
|
* Returns the length (in chars) and width (in pixels) of each of
|
|
* the two components of the text:
|
|
* (1) prefix "/..." or "...", and (2) path or subpath.
|
|
* Returns True if the path was chopped because it wouldn't fit.
|
|
*
|
|
*------------------------------------------------------------------*/
|
|
|
|
static Boolean
|
|
get_text_pieces(
|
|
FileMgrData *file_mgr_data,
|
|
int width,
|
|
char buf[],
|
|
int *host_len_p,
|
|
int *host_pixels_p,
|
|
int *prefix_len_p,
|
|
int *prefix_pixels_p,
|
|
int *path_len_p,
|
|
int *path_pixels_p)
|
|
{
|
|
Boolean chopped = False;
|
|
int prefix_len;
|
|
int prefix_pixels;
|
|
int path_len;
|
|
int path_pixels;
|
|
char *path_begin;
|
|
char *next_part = NULL;
|
|
|
|
*host_len_p = *host_pixels_p = 0;
|
|
|
|
/* if restricted directory, path prefix is "/..." */
|
|
if (file_mgr_data->restricted_directory)
|
|
{
|
|
strcpy(buf, "/...");
|
|
prefix_len = strlen("/...");
|
|
prefix_pixels = get_textwidth (file_mgr_data, "/...", prefix_len);
|
|
path_begin = file_mgr_data->current_directory +
|
|
strlen(file_mgr_data->restricted_directory);
|
|
if (*path_begin == '\0')
|
|
path_begin = "/";
|
|
else if (*path_begin != '/')
|
|
-- path_begin;
|
|
|
|
}
|
|
else
|
|
{
|
|
prefix_len = 0;
|
|
prefix_pixels = 0;
|
|
path_begin = file_mgr_data->current_directory;
|
|
}
|
|
|
|
/* calculate path length & width */
|
|
path_len = strlen(path_begin);
|
|
path_pixels = get_textwidth (file_mgr_data, path_begin, path_len);
|
|
|
|
/* if whole path doesn't fit, we need to chop off pieces until it does */
|
|
if (prefix_pixels + path_pixels > width)
|
|
{
|
|
chopped = True;
|
|
|
|
/* change the path prefix */
|
|
strcpy(buf, "...");
|
|
prefix_len = strlen("...");
|
|
prefix_pixels = get_textwidth (file_mgr_data, "...", prefix_len);
|
|
|
|
do
|
|
{
|
|
/* chop off the next piece (everything up to the next '/') */
|
|
next_part = NULL;
|
|
next_part = DtStrchr(path_begin + 1, '/');
|
|
if (next_part == NULL)
|
|
{
|
|
/* Got here only when the last directory is still too
|
|
long to display
|
|
*/
|
|
break;
|
|
}
|
|
|
|
/* calculate new path length */
|
|
path_begin = next_part;
|
|
path_len = strlen(path_begin);
|
|
path_pixels = get_textwidth (file_mgr_data, path_begin, path_len);
|
|
|
|
/* keep going until it fits */
|
|
} while (prefix_pixels + path_pixels > width);
|
|
}
|
|
|
|
/* add the path to the buffer */
|
|
if( NULL == next_part )
|
|
{
|
|
/* Got here only when the last directory is still too
|
|
long to display
|
|
*/
|
|
int len = path_len;
|
|
char saved_char;
|
|
|
|
while( 0 != len )
|
|
{
|
|
/* Going back one character at a time to see if it fit
|
|
*/
|
|
path_pixels = get_textwidth( file_mgr_data, path_begin, len );
|
|
if( prefix_pixels + path_pixels < width )
|
|
{
|
|
break;
|
|
}
|
|
--len;
|
|
}
|
|
|
|
if( 0 == len )
|
|
{
|
|
buf[prefix_len] = 0x0;
|
|
*path_len_p = 0;
|
|
*path_pixels_p = 0;
|
|
}
|
|
else
|
|
{
|
|
strncpy (buf + prefix_len, path_begin, len);
|
|
*path_len_p = len;
|
|
*path_pixels_p = path_pixels;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strcpy (buf + prefix_len, path_begin);
|
|
*path_len_p = path_len;
|
|
*path_pixels_p = path_pixels;
|
|
}
|
|
|
|
/* return values */
|
|
*prefix_len_p = prefix_len;
|
|
*prefix_pixels_p = prefix_pixels;
|
|
return chopped;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* ShowChangeDirDialog
|
|
* Callback functions invoked from the Change Directory... menu
|
|
* item. This function displays the change directory dialog.
|
|
*
|
|
************************************************************************/
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
ShowChangeDirDialog(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer callback )
|
|
{
|
|
FileMgrRec * file_mgr_rec;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
ChangeDirData * change_dir_data;
|
|
ChangeDirRec * change_dir_rec;
|
|
Arg args[1];
|
|
Widget mbar;
|
|
char *tempStr, *tmpStr;
|
|
|
|
|
|
/* Set the menu item to insensitive to prevent multiple */
|
|
/* dialogs from being posted and get the area under the */
|
|
/* menu pane redrawn. */
|
|
|
|
if (w)
|
|
{
|
|
if((XtArgVal)client_data == FM_POPUP)
|
|
mbar = XtParent(w);
|
|
else
|
|
mbar = (Widget) XmGetPostedFromWidget(XtParent(w));
|
|
|
|
XmUpdateDisplay (w);
|
|
XtSetArg(args[0], XmNuserData, &file_mgr_rec);
|
|
XtGetValues(mbar, args, 1);
|
|
|
|
/* Ignore accelerators when we're insensitive */
|
|
if ((file_mgr_rec->menuStates & CHANGEDIR) == 0)
|
|
{
|
|
XSetInputFocus(XtDisplay(w),
|
|
XtWindow(file_mgr_rec->change_directoryBtn_child),
|
|
RevertToParent, CurrentTime);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Done only during a restore session */
|
|
file_mgr_rec = (FileMgrRec *)client_data;
|
|
}
|
|
|
|
/* Got an accelerator after we were unposted */
|
|
if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
|
|
return;
|
|
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
|
|
change_dir_data->file_mgr_rec = (XtPointer) file_mgr_rec;
|
|
|
|
file_mgr_rec->menuStates &= ~CHANGEDIR;
|
|
|
|
_DtShowDialog (file_mgr_rec->shell, (Widget)NULL, (XtPointer)file_mgr_rec,
|
|
file_mgr_data->change_dir,
|
|
CurrentDirChange, (XtPointer)file_mgr_rec,
|
|
CurrentDirClose, (XtPointer)file_mgr_rec, (char *)NULL,
|
|
False, False, (char *)NULL, (XClassHint *)NULL);
|
|
|
|
/* Save a ptr to file_mgr_rec in the find dialogs structure */
|
|
change_dir_rec = (ChangeDirRec *)_DtGetDialogInstance(
|
|
file_mgr_data->change_dir);
|
|
|
|
if(file_mgr_data->title != NULL &&
|
|
strcmp(file_mgr_data->helpVol, DTFILE_HELP_NAME) != 0)
|
|
{
|
|
tmpStr = GETMESSAGE(2,15, "Go To");
|
|
tempStr = (char *)XtMalloc(strlen(tmpStr) +
|
|
strlen(file_mgr_data->title) + 5);
|
|
sprintf(tempStr, "%s - %s", file_mgr_data->title, tmpStr);
|
|
}
|
|
else
|
|
{
|
|
tmpStr = (GETMESSAGE(2,17, "File Manager - Go To"));
|
|
tempStr = XtNewString(tmpStr);
|
|
}
|
|
XtSetArg (args[0], XmNtitle, tempStr);
|
|
XtSetValues (XtParent (change_dir_rec->change_dir), args, 1);
|
|
XtFree(tempStr);
|
|
|
|
file_mgr_rec->change_directoryBtn_child=XtParent (change_dir_rec->change_dir);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirSelected
|
|
* When a Button1 selection occurs on the current directory line,
|
|
* see if it occurred within the directory path, highlight the
|
|
* selected sub-path, or if the sub-path was already highlighted,
|
|
* set the current directory to the path and dehighlight.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
CurrentDirSelected(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
{
|
|
FileMgrRec *file_mgr_rec = (FileMgrRec *) client_data;
|
|
DialogData *dialog_data;
|
|
FileMgrData *file_mgr_data;
|
|
char buf[2*MAX_PATH];
|
|
char host_name[MAX_PATH];
|
|
Boolean chopped;
|
|
int host_len;
|
|
int host_pixels;
|
|
int prefix_len;
|
|
int prefix_pixels;
|
|
int path_len;
|
|
int path_pixels;
|
|
|
|
XmDrawnButtonCallbackStruct *button_data;
|
|
XButtonEvent *event;
|
|
Dimension width, highlight, shadow, margin;
|
|
Arg args[4];
|
|
|
|
int left_margin;
|
|
int begin_x;
|
|
int end_x;
|
|
int len;
|
|
int i;
|
|
char *ptr;
|
|
char *new_select;
|
|
int swidth;
|
|
static XtIntervalId TimerId;
|
|
|
|
/* if doubleClick is true than we have a double click so we want
|
|
* to change to the new directory that the user double clicked on
|
|
*/
|
|
if (doubleClick)
|
|
XtRemoveTimeOut(TimerId);
|
|
|
|
button_data = (XmDrawnButtonCallbackStruct *) call_data;
|
|
event = (XButtonEvent *) button_data->event;
|
|
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
/* Get layout values */
|
|
XtSetArg (args[0], XmNwidth, &width);
|
|
XtSetArg (args[1], XmNhighlightThickness, &highlight);
|
|
XtGetValues (w, args, 2);
|
|
XtSetArg (args[0], XmNshadowThickness, &shadow);
|
|
XtSetArg (args[1], XmNmarginWidth, &margin);
|
|
XtGetValues (file_mgr_rec->current_directory_text, args, 2);
|
|
left_margin = highlight + shadow + margin;
|
|
|
|
/* Get the starting and ending locations of the current */
|
|
/* directory text. */
|
|
chopped = get_text_pieces(file_mgr_data, width - 2*left_margin,
|
|
buf, &host_len, &host_pixels, &prefix_len, &prefix_pixels,
|
|
&path_len, &path_pixels);
|
|
|
|
begin_x = left_margin;
|
|
end_x = begin_x + host_pixels + prefix_pixels + path_pixels;
|
|
|
|
/* Get the selected path */
|
|
if (event->x < begin_x || event->x >= end_x)
|
|
{
|
|
/* click outside the directory text: nothing selected */
|
|
new_select = NULL;
|
|
}
|
|
else if (event->x < begin_x + host_pixels ||
|
|
event->x < begin_x + host_pixels + prefix_pixels && !chopped)
|
|
{
|
|
/* click on host name or "/..." prefix: root selected */
|
|
if (file_mgr_data->restricted_directory)
|
|
new_select = XtNewString(file_mgr_data->restricted_directory);
|
|
else
|
|
new_select = XtNewString("/");
|
|
}
|
|
else if (event->x < begin_x + host_pixels + prefix_pixels && chopped)
|
|
{
|
|
/* click on "..." prefix: directory above the visible piece selected */
|
|
len = strlen(file_mgr_data->current_directory) - path_len;
|
|
new_select = (char *) XtMalloc(len + 1);
|
|
memcpy(new_select, file_mgr_data->current_directory, len);
|
|
new_select[len] = 0;
|
|
}
|
|
else /* event->x >= begin_x + host_pixels + prefix_pixels */
|
|
{
|
|
/* click on the path: determine which subdirectory selected */
|
|
begin_x += host_pixels + prefix_pixels;
|
|
i = host_len + prefix_len;
|
|
swidth = get_textwidth(file_mgr_data, "/", strlen("/")) / 2;
|
|
|
|
while (begin_x - swidth < event->x)
|
|
{
|
|
/* find next '/' in path */
|
|
ptr = DtStrchr(buf + i, '/');
|
|
if (ptr == NULL)
|
|
{
|
|
i = host_len + prefix_len + path_len + 1;
|
|
break;
|
|
}
|
|
|
|
/* get x-position of next path component */
|
|
len = ((ptr + 1) - buf) - i;
|
|
begin_x += get_textwidth(file_mgr_data, buf + i, len);
|
|
i += len;
|
|
}
|
|
|
|
/* if we have a restricted diretory and i == 5 ("/.../") then we want
|
|
the len to be the restricted directory */
|
|
if (file_mgr_data->restricted_directory && i == 5)
|
|
len = strlen(file_mgr_data->restricted_directory);
|
|
else
|
|
len = strlen(file_mgr_data->current_directory)
|
|
- (host_len + prefix_len + path_len - i) - 1;
|
|
new_select = (char *) XtMalloc(len + 1);
|
|
if (len == 0)
|
|
strcpy(new_select, "/");
|
|
else
|
|
{
|
|
memcpy(new_select, file_mgr_data->current_directory, len);
|
|
new_select[len] = 0;
|
|
}
|
|
}
|
|
|
|
/* in restricted mode, don't allow going above the user's home dir */
|
|
if (new_select != NULL && restrictMode)
|
|
{
|
|
/* check if new_select is the same as or a subdirectory of $HOME */
|
|
len = strlen(users_home_dir);
|
|
if (strncmp(new_select, users_home_dir, len) != 0
|
|
|| new_select[len] != '\0' && new_select[len] != '/')
|
|
{
|
|
/* change new_select to $HOME */
|
|
XtFree(new_select);
|
|
new_select = XtNewString(users_home_dir);
|
|
}
|
|
}
|
|
|
|
|
|
/* If the path is the same as what is already selected, */
|
|
/* free cd_select, set the directory to the selected */
|
|
/* directory, redraw the directory display. */
|
|
|
|
/* If the path was different, set cd_select to the */
|
|
/* selected directory and redraw the directory. */
|
|
|
|
if (new_select != NULL && file_mgr_data->cd_select != NULL &&
|
|
strcmp(new_select, file_mgr_data->cd_select) == 0)
|
|
{
|
|
XtFree (file_mgr_data->cd_select);
|
|
file_mgr_data->cd_select = NULL;
|
|
|
|
strcpy(buf, new_select);
|
|
strcpy(host_name, file_mgr_data->host);
|
|
|
|
if (strcmp (buf, file_mgr_data->current_directory) == 0)
|
|
FileMgrReread (file_mgr_rec);
|
|
else
|
|
ShowNewDirectory (file_mgr_data, host_name, buf);
|
|
|
|
XtFree (new_select);
|
|
}
|
|
else
|
|
{
|
|
XtFree (file_mgr_data->cd_select);
|
|
file_mgr_data->cd_select = new_select;
|
|
}
|
|
|
|
if (doubleClick)
|
|
{
|
|
doubleClick = False;
|
|
DrawCurrentDirectory (w, file_mgr_rec, file_mgr_data);
|
|
}
|
|
else
|
|
{
|
|
doubleClick = True;
|
|
TimerId = XtAppAddTimeOut (XtWidgetToApplicationContext (w),
|
|
XtGetMultiClickTime(XtDisplay(w)),
|
|
(XtTimerCallbackProc) TimerEvent,
|
|
(XtPointer) file_mgr_rec);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirDropCallback
|
|
* Callback function invoked upon an action on the change view drop.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
CurrentDirDropCallback(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
{
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
XmAnyCallbackStruct * callback;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
char host_name[MAX_PATH];
|
|
|
|
callback = (XmAnyCallbackStruct *) call_data;
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
if (callback->reason == XmCR_DEFAULT_ACTION)
|
|
{
|
|
strcpy(host_name, file_mgr_data->host);
|
|
ShowNewDirectory (file_mgr_data, host_name,
|
|
_DtPName (file_mgr_data->current_directory));
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirIconCallback
|
|
* Callback function invoked upon an action occurring on an icon.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
CurrentDirIconCallback(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
{
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
XmAnyCallbackStruct * callback;
|
|
XButtonEvent * event;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
|
|
callback = (XmAnyCallbackStruct *) call_data;
|
|
event = (XButtonEvent *) callback->event;
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
if (callback->reason == XmCR_DRAG)
|
|
{
|
|
/* Do nothing if a Button 1 drag is already ramping up */
|
|
if (B1DragPossible)
|
|
return;
|
|
|
|
/* Save starting X and Y, for threshold detection */
|
|
initialDragX = event->x;
|
|
initialDragY = event->y;
|
|
|
|
/* Flag that a Button 2 drag is ramping up */
|
|
B2DragPossible = True;
|
|
|
|
UnpostTextField(file_mgr_data);
|
|
}
|
|
else if (callback->reason == XmCR_ARM)
|
|
{
|
|
/* Do nothing if a Button 2 drag is already ramping up */
|
|
if (B2DragPossible)
|
|
return;
|
|
|
|
/* Save starting X and Y, for threshold detection */
|
|
initialDragX = event->x;
|
|
initialDragY = event->y;
|
|
|
|
/* Flag that a Button 1 drag is ramping up */
|
|
B1DragPossible = True;
|
|
|
|
/* but since we're in the current directory icon we don't want to
|
|
process on the button up */
|
|
ProcessBtnUpCD = False;
|
|
|
|
UnpostTextField(file_mgr_data);
|
|
}
|
|
else if (callback->reason == XmCR_DEFAULT_ACTION)
|
|
{
|
|
/* We now know that a drag operation won't be starting up */
|
|
B1DragPossible = False;
|
|
B2DragPossible = False;
|
|
|
|
UnpostTextField(file_mgr_data);
|
|
|
|
/* Default action is to reread the directory */
|
|
FileMgrReread (file_mgr_rec);
|
|
}
|
|
else if ((callback->reason == XmCR_SELECT) ||
|
|
(callback->reason == XmCR_DISARM) ||
|
|
(callback->reason == XmCR_DROP))
|
|
{
|
|
/* We now know that a drag operation won't be starting up */
|
|
B1DragPossible = False;
|
|
B2DragPossible = False;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* This function processes motion events anytime a B1 or B2 drag operation
|
|
* has the potential of starting. When the drag threshold is surpassed,
|
|
* a drag operation will be started.
|
|
*/
|
|
|
|
void
|
|
CurrentDirectoryIconMotion(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XEvent *event)
|
|
{
|
|
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
Pixmap drag_pixmap;
|
|
char * type_set;
|
|
char * file_set;
|
|
int diffX, diffY;
|
|
Widget dirIcon;
|
|
DtIconGadget iconG;
|
|
|
|
|
|
if ((B1DragPossible && (event->xmotion.state & Button1Mask)) ||
|
|
(B2DragPossible && (event->xmotion.state & Button2Mask)))
|
|
{
|
|
/* Have we passed the drag threshold? */
|
|
diffX = initialDragX - event->xmotion.x;
|
|
diffY = initialDragY - event->xmotion.y;
|
|
|
|
if ((ABS(diffX) >= dragThreshold) || (ABS(diffY) >= dragThreshold))
|
|
{
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
initiating_view = (XtPointer) file_mgr_data;
|
|
dirIcon = file_mgr_rec->current_directory_icon;
|
|
StartDrag(dirIcon, NULL, event);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirExposed
|
|
* Callback functions invoked from the current directory display
|
|
* drawn button. This function extracts some structures and calls
|
|
* the directory display function.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
CurrentDirExposed(
|
|
Widget w,
|
|
XtPointer client_data,
|
|
XtPointer call_data )
|
|
{
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
|
|
/* Check to see if the view has been closed */
|
|
|
|
if (dialog_data == NULL) return;
|
|
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
if (file_mgr_data->cd_normal_gc != 0)
|
|
DrawCurrentDirectory (w, file_mgr_rec, file_mgr_data);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* GetStatusMsg
|
|
* Construct the status message (normally "x Items, y Hidden").
|
|
* Returns True if the message is deemed "important".
|
|
*
|
|
* @@@ Note 2/17/95: messages below containing "Item(s)" should really
|
|
* be just "Item", but the message catalog is frozen at this time, so
|
|
* we can't fix this now. (In practice, it doesn't matter, because
|
|
* the item count should always be > 1, since every directory shoule
|
|
* contain at least two files "." and "..")
|
|
*
|
|
************************************************************************/
|
|
|
|
Boolean
|
|
GetStatusMsg(
|
|
FileMgrData *file_mgr_data,
|
|
char *buf )
|
|
{
|
|
int n_files;
|
|
int n_hidden;
|
|
int i, j;
|
|
TreeShow ts;
|
|
FileViewData **file_view_data;
|
|
|
|
/*
|
|
* If we are currently busy reading a directory, display a progress
|
|
* message instead of the normal "x Items, y Hidden" message.
|
|
*/
|
|
if (file_mgr_data->busy_status == initiating_readdir ||
|
|
file_mgr_data->busy_status == busy_readdir)
|
|
{
|
|
if (file_mgr_data->busy_detail == 0)
|
|
sprintf (buf, "%s", (GETMESSAGE(3,5, "Reading ...")));
|
|
else if (file_mgr_data->busy_detail == 1)
|
|
sprintf (buf, (GETMESSAGE(3,11, "%d Item(s)...")),
|
|
file_mgr_data->busy_detail);
|
|
else
|
|
sprintf (buf, (GETMESSAGE(3,9, "%3d Items ...")),
|
|
file_mgr_data->busy_detail);
|
|
|
|
return True; /* this message deemed important! */
|
|
}
|
|
|
|
else if (file_mgr_data->show_type == MULTIPLE_DIRECTORY)
|
|
{
|
|
/*
|
|
* In tree mode, we only show a count of the hidden files
|
|
* in branches that are currently expanded.
|
|
* The idea is we want to show how many additional files would
|
|
* show up if the user turned on the "Show Hidden" option.
|
|
*/
|
|
n_hidden = 0;
|
|
for (i = 0; i < file_mgr_data->directory_count; i++)
|
|
{
|
|
file_view_data = file_mgr_data->directory_set[i]->file_view_data;
|
|
if (file_view_data == NULL)
|
|
continue;
|
|
|
|
ts = file_mgr_data->directory_set[i]->sub_root->ts;
|
|
if (ts < tsDirs)
|
|
continue; /* this branch is not expanded */
|
|
|
|
for (j = 0; j < file_mgr_data->directory_set[i]->file_count; j++)
|
|
{
|
|
if (file_view_data[j]->filtered &&
|
|
(ts == tsAll || file_view_data[j]->file_data->is_subdir))
|
|
{
|
|
n_hidden++;
|
|
}
|
|
}
|
|
}
|
|
sprintf (buf, (GETMESSAGE(3,6, "%d Hidden")), n_hidden);
|
|
|
|
return False;
|
|
}
|
|
|
|
else
|
|
{
|
|
/*
|
|
* In flat mode, we only show a total count of all files
|
|
* and a count of hidden files.
|
|
*/
|
|
n_files = file_mgr_data->directory_set[0]->file_count;
|
|
if( n_files == 0 )
|
|
sprintf( buf, (GETMESSAGE(11,31, "Error while reading %s")), file_mgr_data->current_directory );
|
|
else if( file_mgr_data == trashFileMgrData )
|
|
{
|
|
n_hidden = file_mgr_data->directory_set[0]->filtered_file_count;
|
|
sprintf (buf, (GETMESSAGE(3,10, "%d Item(s)")),
|
|
n_files - n_hidden);
|
|
}
|
|
else
|
|
{
|
|
n_files -= file_mgr_data->directory_set[0]->invisible_file_count;
|
|
n_hidden = file_mgr_data->directory_set[0]->filtered_file_count -
|
|
file_mgr_data->directory_set[0]->invisible_file_count;
|
|
if (n_files == 1)
|
|
sprintf (buf, (GETMESSAGE(3,12, "%d Item(s) %d Hidden")),
|
|
n_files, n_hidden);
|
|
else
|
|
sprintf (buf, (GETMESSAGE(3,7, "%d Items %d Hidden")),
|
|
n_files, n_hidden);
|
|
}
|
|
|
|
return False;
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* DrawCurrentDirectory
|
|
* Draw the current directory display area, including the hostname,
|
|
* the current directory, any highlighted sub-path of the directory,
|
|
* the file count and the number of selected files.
|
|
*
|
|
************************************************************************/
|
|
|
|
void
|
|
DrawCurrentDirectory(
|
|
Widget w,
|
|
FileMgrRec *file_mgr_rec,
|
|
FileMgrData *file_mgr_data )
|
|
{
|
|
Arg args[8];
|
|
Dimension width, height, highlight, shadow, margin, twidth;
|
|
XFontSetExtents *extents;
|
|
int font_height;
|
|
int font_yoffset;
|
|
int top_margin;
|
|
int left_margin;
|
|
char buf[2*MAX_PATH];
|
|
char msg[21+MAX_PATH];
|
|
Boolean chopped;
|
|
int host_len;
|
|
int host_pixels;
|
|
int prefix_len;
|
|
int prefix_pixels;
|
|
int path_len;
|
|
int path_pixels;
|
|
int draw_x;
|
|
int draw_y;
|
|
int dir_width;
|
|
int msg_width;
|
|
short columns;
|
|
Boolean msg_drawn;
|
|
|
|
/* Get layout values */
|
|
XtSetArg (args[0], XmNwidth, &width);
|
|
XtSetArg (args[1], XmNheight, &height);
|
|
XtSetArg (args[2], XmNhighlightThickness, &highlight);
|
|
XtGetValues (w, args, 3);
|
|
XtSetArg (args[0], XmNshadowThickness, &shadow);
|
|
XtSetArg (args[1], XmNmarginWidth, &margin);
|
|
XtGetValues (file_mgr_rec->current_directory_text, args, 2);
|
|
|
|
if(file_mgr_data->cd_fonttype == XmFONT_IS_FONTSET) {
|
|
extents = XExtentsOfFontSet(file_mgr_data->cd_fontset);
|
|
font_yoffset = -(extents->max_logical_extent.y);
|
|
font_height = extents->max_logical_extent.height;
|
|
}
|
|
else
|
|
{
|
|
font_yoffset = file_mgr_data->cd_font->ascent;
|
|
font_height = file_mgr_data->cd_font->ascent +
|
|
file_mgr_data->cd_font->descent;
|
|
}
|
|
top_margin = (height > (Dimension)font_height)? (Dimension)(height - font_height + 1)/(Dimension)2: 0;
|
|
left_margin = highlight + shadow + margin;
|
|
|
|
/* Ensure the area is cleared out. */
|
|
XClearArea (XtDisplay (w), XtWindow (w),
|
|
highlight, highlight,
|
|
width - 2*highlight, height - 2*highlight,
|
|
False);
|
|
|
|
/*
|
|
* If there is no status line and no iconic path,
|
|
* we will want yo draw the "x Files y Hidden" message here.
|
|
*/
|
|
if (!file_mgr_data->show_iconic_path && !file_mgr_data->show_status_line)
|
|
{
|
|
/*
|
|
* GetStatusMsg() returns True if the status msg is "important".
|
|
* In this case, make sure we leave room for it
|
|
*/
|
|
msg_drawn = GetStatusMsg(file_mgr_data, msg);
|
|
msg_width = get_textwidth (file_mgr_data, msg, strlen(msg));
|
|
}
|
|
else
|
|
msg_drawn = False;
|
|
|
|
draw_x = left_margin;
|
|
if( draw_x < 0 || (Dimension) draw_x > width ) /* Make sure that it's in bound */
|
|
draw_x = 0;
|
|
|
|
draw_y = top_margin + font_yoffset;
|
|
if( draw_y < 0 || (Dimension) draw_y > height ) /* Make sure that it's in bound */
|
|
{
|
|
draw_y = height-5;
|
|
}
|
|
|
|
/* get the text pieces */
|
|
dir_width = width - 2*left_margin;
|
|
if (msg_drawn)
|
|
dir_width -= CUR_DIR_SPACING + msg_width;
|
|
chopped = get_text_pieces(file_mgr_data, dir_width,
|
|
buf, &host_len, &host_pixels, &prefix_len, &prefix_pixels,
|
|
&path_len, &path_pixels);
|
|
|
|
/*
|
|
* go check and change the file_mgr_data->cd_select, make sure its not
|
|
* longer than the file_mgr_data->current_directory.
|
|
*/
|
|
CheckCurrentDirectorySelect(file_mgr_data);
|
|
|
|
/* draw the host and paths */
|
|
if (!file_mgr_data->fast_cd_enabled)
|
|
{
|
|
draw_imagestring (XtDisplay (w), XtWindow (w), file_mgr_data,
|
|
file_mgr_data->cd_normal_gc, draw_x, draw_y,
|
|
buf, host_len + prefix_len + path_len);
|
|
}
|
|
else if (file_mgr_data->restricted_directory)
|
|
{
|
|
draw_imagestring (XtDisplay (w), XtWindow (w), file_mgr_data,
|
|
file_mgr_data->cd_normal_gc, draw_x, draw_y,
|
|
buf, host_len + prefix_len);
|
|
}
|
|
|
|
/*
|
|
* If there is no status line and no iconic path, and we have
|
|
* room left, draw the "x Files y Hidden" message here.
|
|
*/
|
|
if (!file_mgr_data->show_iconic_path && !file_mgr_data->show_status_line)
|
|
{
|
|
/* determine where the message could begin */
|
|
if (!file_mgr_data->fast_cd_enabled)
|
|
draw_x += host_pixels + prefix_pixels + path_pixels;
|
|
else
|
|
{
|
|
XtSetArg(args[0], XmNwidth, &twidth);
|
|
XtGetValues(file_mgr_rec->current_directory_text, args, 1);
|
|
if (file_mgr_data->restricted_directory && !chopped)
|
|
draw_x += host_pixels + prefix_pixels + twidth;
|
|
else
|
|
draw_x += host_pixels + twidth;
|
|
}
|
|
|
|
/* if there is enough space left, draw the message */
|
|
if ((Dimension)(draw_x + CUR_DIR_SPACING + msg_width + left_margin) <= width)
|
|
{
|
|
draw_x = width - left_margin - msg_width;
|
|
draw_imagestring (XtDisplay (w), XtWindow (w), file_mgr_data,
|
|
file_mgr_data->cd_normal_gc, draw_x, draw_y,
|
|
msg, strlen(msg));
|
|
draw_x -= shadow + CUR_DIR_SPACING; /* right edge of shadow */
|
|
msg_drawn = True;
|
|
}
|
|
else
|
|
msg_drawn = False;
|
|
}
|
|
|
|
if (!msg_drawn)
|
|
draw_x = width - (highlight + shadow);
|
|
|
|
/* draw the shadow */
|
|
if (!file_mgr_data->fast_cd_enabled)
|
|
{
|
|
int shadow_width = draw_x - highlight;
|
|
int shadow_height = height - 2*highlight;
|
|
XmTextFieldWidget tf =
|
|
(XmTextFieldWidget)file_mgr_rec->current_directory_text;
|
|
|
|
XmeDrawShadows(XtDisplay(w), XtWindow(w),
|
|
tf->primitive.top_shadow_GC,
|
|
tf->primitive.bottom_shadow_GC,
|
|
highlight, highlight, shadow_width, shadow_height,
|
|
shadow, XmSHADOW_IN);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirChange
|
|
* Callback functions invoked from the current directory dialog's
|
|
* apply button being pressed. This function updates and redisplays
|
|
* the current directory information.
|
|
*
|
|
************************************************************************/
|
|
|
|
static void
|
|
CurrentDirChange(
|
|
XtPointer client_data,
|
|
DialogData *old_dialog_data,
|
|
DialogData *new_dialog_data,
|
|
XtPointer call_data )
|
|
{
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
DialogData * dialog_data;
|
|
FileMgrData * file_mgr_data;
|
|
ChangeDirData * new_change_dir_data;
|
|
ChangeDirData * old_change_dir_data;
|
|
char path[MAX_PATH];
|
|
char host_name[MAX_PATH];
|
|
char * ptr;
|
|
|
|
|
|
/* Get a pointer file manager's data structure, free up the */
|
|
/* old current directory and copy in a new one. Free up the */
|
|
/* old selected sub-path, update the file manager's internal */
|
|
/* data, and redraw the directory. */
|
|
|
|
dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
if (file_mgr_data->cd_select != NULL)
|
|
{
|
|
XtFree (file_mgr_data->cd_select);
|
|
file_mgr_data->cd_select = NULL;
|
|
}
|
|
|
|
old_change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
|
|
new_change_dir_data = (ChangeDirData *) new_dialog_data->data;
|
|
|
|
new_change_dir_data->host_name = XtNewString(old_change_dir_data->host_name);
|
|
new_change_dir_data->file_mgr_rec = old_change_dir_data->file_mgr_rec;
|
|
|
|
_DtHideDialog(old_dialog_data, False);
|
|
|
|
new_change_dir_data->displayed = False;
|
|
|
|
file_mgr_data->change_dir->data = (XtPointer) new_change_dir_data;
|
|
new_dialog_data->data = (XtPointer) old_change_dir_data;
|
|
_DtFreeDialogData (new_dialog_data);
|
|
file_mgr_rec->menuStates |= CHANGEDIR;
|
|
|
|
|
|
/* Process call_data into a hostname and directory name. */
|
|
|
|
ShowNewDirectory (file_mgr_data,
|
|
((ChangeDirData *)file_mgr_data->change_dir->data)->host_name,
|
|
call_data);
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* CurrentDirClose
|
|
* Callback functions invoked from the current directory dialog's
|
|
* close button being pressed. This function resensitizes the
|
|
* Change Directory... menu item.
|
|
*
|
|
************************************************************************/
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
CurrentDirClose(
|
|
XtPointer client_data,
|
|
DialogData *old_dialog_data,
|
|
DialogData *new_dialog_data )
|
|
{
|
|
FileMgrRec * file_mgr_rec = (FileMgrRec *) client_data;
|
|
|
|
_DtFreeDialogData (new_dialog_data);
|
|
file_mgr_rec->menuStates |= CHANGEDIR;
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* CheckCurrentDirectorySelect
|
|
* Before calling DrawCurrentDirectorySelect() this function
|
|
* makes sure that the fm->cd_select isn't longer than the
|
|
* fm->current_directory. If it is it reconfigures fm->cd_select
|
|
* to hold no more than what fm->current_directory is.
|
|
*
|
|
************************************************************************/
|
|
static void
|
|
CheckCurrentDirectorySelect(
|
|
FileMgrData *file_mgr_data )
|
|
{
|
|
int length_cd, length_cd_s;
|
|
char *str, *ptr;
|
|
|
|
if (file_mgr_data == NULL ||
|
|
file_mgr_data->cd_select == NULL ||
|
|
file_mgr_data->current_directory == NULL)
|
|
return;
|
|
|
|
/* get the true lengths of current_directory and current_directory_select */
|
|
length_cd = strlen(file_mgr_data->current_directory);
|
|
length_cd_s = strlen(file_mgr_data->cd_select);
|
|
|
|
/* if cd is larger than cd_select than we have now problem */
|
|
if(length_cd >= length_cd_s)
|
|
return;
|
|
|
|
/* we need to recalculate the cd_select */
|
|
str = XtNewString(file_mgr_data->cd_select);
|
|
while(1)
|
|
{
|
|
ptr = strrchr(str, '/');
|
|
*ptr = '\0';
|
|
length_cd_s = strlen(str);
|
|
if(length_cd > length_cd_s)
|
|
{
|
|
XtFree(file_mgr_data->cd_select);
|
|
file_mgr_data->cd_select = (char *)XtMalloc(strlen(str) + 1);
|
|
strcpy(file_mgr_data->cd_select, str);
|
|
XtFree(str);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* ShowFastChangeDir
|
|
* Post the fast change to text widget.
|
|
*
|
|
***************************************************************************/
|
|
void
|
|
ShowFastChangeDir(
|
|
FileMgrRec *file_mgr_rec,
|
|
FileMgrData *file_mgr_data )
|
|
{
|
|
char *textString;
|
|
Arg args[16];
|
|
Dimension width, height;
|
|
Dimension shadow, highlight, margin;
|
|
char buf[2*MAX_PATH];
|
|
Boolean chopped;
|
|
int host_len;
|
|
int host_pixels;
|
|
int prefix_len;
|
|
int prefix_pixels;
|
|
int path_len;
|
|
int path_pixels;
|
|
int begin_x;
|
|
int left_margin;
|
|
|
|
doubleClick = False;
|
|
|
|
XtRemoveAllCallbacks (file_mgr_rec->current_directory, XmNexposeCallback);
|
|
|
|
XtFree (file_mgr_data->cd_select);
|
|
file_mgr_data->cd_select = NULL;
|
|
|
|
file_mgr_data->fast_cd_enabled = True;
|
|
|
|
/* if not a toolbox, just put the current directory in text widget */
|
|
if (file_mgr_data->restricted_directory == NULL)
|
|
{
|
|
if (strcmp(file_mgr_data->host, home_host_name) == 0)
|
|
textString = XtNewString(file_mgr_data->current_directory);
|
|
else
|
|
textString = DtCreateContextString(file_mgr_data->host,
|
|
file_mgr_data->current_directory,
|
|
NULL);
|
|
}
|
|
else /* is a toolbox, so put the subset of what the toolbox is in the text*/
|
|
{
|
|
char *ptr;
|
|
|
|
ptr = file_mgr_data->current_directory +
|
|
strlen(file_mgr_data->restricted_directory);
|
|
if (strcmp(ptr, "") == 0)
|
|
textString = XtNewString("/");
|
|
else
|
|
textString = XtNewString(ptr);
|
|
}
|
|
begin_x = get_textwidth (file_mgr_data, textString, strlen (textString));
|
|
|
|
/* Get layout values */
|
|
XtSetArg (args[0], XmNwidth, &width);
|
|
XtSetArg (args[1], XmNhighlightThickness, &highlight);
|
|
XtGetValues (file_mgr_rec->current_directory, args, 2);
|
|
XtSetArg (args[0], XmNshadowThickness, &shadow);
|
|
XtSetArg (args[1], XmNmarginWidth, &margin);
|
|
XtGetValues (file_mgr_rec->current_directory_text, args, 2);
|
|
left_margin = highlight + shadow + margin;
|
|
|
|
if(file_mgr_data->restricted_directory == NULL)
|
|
XtSetArg (args[0], XmNleftOffset, 0);
|
|
else
|
|
{
|
|
XtSetArg (args[0], XmNshadowThickness, &shadow);
|
|
XtSetArg (args[1], XmNhighlightThickness, &highlight);
|
|
XtGetValues(file_mgr_rec->current_directory_text, args, 2);
|
|
chopped =
|
|
get_text_pieces(file_mgr_data, width - 2*left_margin,
|
|
buf, &host_len, &host_pixels, &prefix_len, &prefix_pixels,
|
|
&path_len, &path_pixels);
|
|
begin_x = left_margin + host_pixels - shadow - highlight;
|
|
if (!chopped)
|
|
begin_x += prefix_pixels;
|
|
XtSetArg (args[0], XmNleftOffset, begin_x);
|
|
}
|
|
XtSetArg (args[1], XmNvalue, textString);
|
|
XtSetValues(file_mgr_rec->current_directory_text, args, 2);
|
|
XtSetArg (args[0], XmNcursorPosition, strlen(textString));
|
|
XtSetValues(file_mgr_rec->current_directory_text, args, 1);
|
|
|
|
XtSetArg (args[0], XmNallowShellResize, False);
|
|
XtSetValues(file_mgr_rec->shell, args, 1);
|
|
XtManageChild(file_mgr_rec->current_directory_text);
|
|
XtSetArg (args[0], XmNallowShellResize, True);
|
|
XtSetValues(file_mgr_rec->shell, args, 1);
|
|
XRaiseWindow(XtDisplay(file_mgr_rec->current_directory_text),
|
|
XtWindow(file_mgr_rec->current_directory_text));
|
|
XmUpdateDisplay(file_mgr_rec->current_directory_text);
|
|
XmProcessTraversal(file_mgr_rec->current_directory_text,
|
|
XmTRAVERSE_CURRENT);
|
|
XtFree(textString);
|
|
XtAddCallback (file_mgr_rec->current_directory, XmNexposeCallback,
|
|
CurrentDirExposed, file_mgr_rec);
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* TimerEvent - timeout for double click on current Directory line. If
|
|
* we get here we know it was a single click so lets post the
|
|
* fast change to text widget.
|
|
*
|
|
***************************************************************************/
|
|
static void
|
|
TimerEvent(
|
|
XtPointer client_data,
|
|
XtIntervalId *id )
|
|
{
|
|
FileMgrRec *file_mgr_rec = (FileMgrRec *)client_data;
|
|
DialogData * dialog_data;
|
|
FileMgrData *file_mgr_data;
|
|
|
|
doubleClick = False;
|
|
|
|
/* Got an accelerator after we were unposted */
|
|
if ((dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec)) == NULL)
|
|
return;
|
|
file_mgr_data = (FileMgrData *) dialog_data->data;
|
|
|
|
ShowFastChangeDir(file_mgr_rec, file_mgr_data);
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* ResizeFastText - resizes the fast change text widget due to changes
|
|
* in the size of the FileManager window.
|
|
*
|
|
*************************************************************************/
|
|
static void
|
|
ResizeFastText(
|
|
FileMgrRec *file_mgr_rec,
|
|
FileMgrData *file_mgr_data,
|
|
short columns)
|
|
{
|
|
Arg args[2];
|
|
Dimension width;
|
|
int left_offset;
|
|
|
|
/* nothing to do if not managed */
|
|
if (!XtIsManaged(file_mgr_rec->current_directory_text))
|
|
return;
|
|
|
|
/* get width of current directory line */
|
|
XtSetArg (args[0], XmNwidth, &width);
|
|
XtGetValues (file_mgr_rec->current_directory, args, 1);
|
|
|
|
/* get offset of the text widget */
|
|
XtSetArg(args[0], XmNleftOffset, &left_offset);
|
|
XtGetValues(file_mgr_rec->current_directory_text, args, 1);
|
|
|
|
/* set text widget width = current_directory width minus left offset */
|
|
XtSetArg (args[0], XmNwidth, width - left_offset);
|
|
XtSetValues (file_mgr_rec->current_directory_text, args, 1);
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------
|
|
* get_textwidth
|
|
*------------------------------------------------------------------*/
|
|
|
|
/* use Xmb functions if XFontSet is used. */
|
|
static int
|
|
get_textwidth( FileMgrData *fmd,
|
|
char *str,
|
|
int len)
|
|
{
|
|
int w = 0;
|
|
|
|
switch(fmd->cd_fonttype)
|
|
{
|
|
case XmFONT_IS_FONTSET:
|
|
w = XmbTextEscapement(fmd->cd_fontset, str, len);
|
|
break;
|
|
case XmFONT_IS_FONT:
|
|
w = XTextWidth(fmd->cd_font, str, len);
|
|
default:
|
|
break;
|
|
}
|
|
return(w);
|
|
}
|
|
|
|
static void
|
|
draw_imagestring( Display *display,
|
|
Drawable d,
|
|
FileMgrData *fmd,
|
|
GC gc,
|
|
int x, int y,
|
|
char *text,
|
|
int bytes)
|
|
{
|
|
switch(fmd->cd_fonttype)
|
|
{
|
|
case XmFONT_IS_FONTSET:
|
|
XmbDrawImageString(display, d, fmd->cd_fontset, gc, x, y, text,
|
|
bytes);
|
|
break;
|
|
case XmFONT_IS_FONT:
|
|
XDrawImageString(display, d, gc, x, y, text, bytes);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|