Mozilla/mozilla/cmd/xfe/src/RDFTreeView.cpp
ftang%netscape.com 5279660a51 enable UTF8 in RDFTreeView. Reviewed by slamm
git-svn-id: svn://10.0.0.236/trunk@13195 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-20 13:10:39 +00:00

1277 lines
34 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*----------------------------------------------------------------------*/
/* */
/* Name: RDFTreeView.cpp */
/* Description: XFE_RDFTreeView component header file - A class to */
/* encapsulate and rdf tree widget. */
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
/* */
/*----------------------------------------------------------------------*/
#include "RDFTreeView.h"
#include "Command.h"
#include "PopupMenu.h"
#include "RDFImage.h"
#include "RDFUtils.h"
#include "felocale.h" // fe_ConvertToXmString()
#include "xfe2_extern.h"
#include "xpgetstr.h"
#include <XmL/Tree.h>
#include <Xfe/Xfe.h>
#define TREE_NAME "RdfTree"
extern "C" RDF_NCVocab gNavCenter;
#if defined(DEBUG_slamm)||defined(DEBUG_mcafee)
#define D(x) x
#else
#define D(x)
#endif
// pixmaps for use in the bookmark window.
fe_icon XFE_RDFTreeView::bookmark = { 0 };
fe_icon XFE_RDFTreeView::closedFolder = { 0 };
fe_icon XFE_RDFTreeView::openedFolder = { 0 };
#define SECONDS_PER_DAY 86400L
extern int XP_BKMKS_HOURS_AGO;
extern int XP_BKMKS_DAYS_AGO;
extern int XP_BKMKS_LESS_THAN_ONE_HOUR_AGO;
extern "C"
{
extern void treeview_bg_image_cb(XtPointer clientData);
};
//
// Command Handling
//
//
// This acts as an encapsulator for the doCommand() method.
// Sub-classes impliment a reallyDoCommand(), and leave the
// boring maintainence work to this class. This approach
// saves every sub-class from calling super::doCommand(),
// which would really be a drag, now wouldn't it.
//
class XFE_RDFTreeViewCommand : public XFE_ViewCommand
{
public:
XFE_RDFTreeViewCommand(char* name) : XFE_ViewCommand(name) {};
virtual void reallyDoCommand(XFE_RDFTreeView*, XFE_CommandInfo*) = 0;
virtual XP_Bool requiresChromeUpdate() {
return TRUE;
};
void doCommand(XFE_View* v_view, XFE_CommandInfo* info) {
XFE_RDFTreeView* view = (XFE_RDFTreeView*)v_view;
reallyDoCommand(view, info);
if (requiresChromeUpdate()) {
//XXX view->updateChrome();
}
};
};
class XFE_RDFTreeViewAlwaysEnabledCommand : public XFE_RDFTreeViewCommand
{
public:
XFE_RDFTreeViewAlwaysEnabledCommand(char* name) : XFE_RDFTreeViewCommand(name) {};
XP_Bool isEnabled(XFE_View*, XFE_CommandInfo*) {
return True;
};
};
class RdfPopupCommand : public XFE_RDFTreeViewAlwaysEnabledCommand
{
public:
RdfPopupCommand() : XFE_RDFTreeViewAlwaysEnabledCommand(xfeCmdShowPopup) {};
virtual XP_Bool isSlow() {
return FALSE;
};
void reallyDoCommand(XFE_RDFTreeView* view, XFE_CommandInfo* info) {
view->doPopup(info->event);
};
};
// End of Commands
/////////////////////////////////////////////////////////////////////
// FontList Management
//
// Since loading all the necessary fonts for Unicode is expensive,
// we only load when we need them, which mean it will be load
// when the conversion hit the range the font cover.
// Howerver, in the case of list or tree, we want to use the same font
// in the same tree, so... we need to use this font tracer to
// notify the tree when it is necessary to change the font
// The converter will call this tracer when it find out it is necessary
// to change font. It serve as a callback to the converter.
// TreeFontListNotifier - adaptor class to set font list for the tree widget
class TreeFontListNotifier : public FontListNotifier {
public:
TreeFontListNotifier(Widget inTree) { _tree = inTree;};
virtual ~TreeFontListNotifier() {};
virtual void notifyFontListChanged(XmFontList inFontList);
private:
Widget _tree;
};
void TreeFontListNotifier::notifyFontListChanged(XmFontList inFontList)
{
// Set all the rows and columns
XtVaSetValues(_tree,
XmNcellDefaults, True,
XmNcellFontList, inFontList,
NULL);
XtVaSetValues(_tree,
XmNrowType, XmCONTENT,
XmNcolumnType, XmCONTENT,
XmNcellFontList, inFontList,
NULL);
/*
XtVaSetValues(_tree,
XmNrow, 0,
XmNcolumn, 0,
XmNrowType, XmHEADING,
XmNcolumnType, XmCONTENT,
XmNcellType, XmICON_CELL,
XmNcellFontList, inFontList,
NULL);
*/
}
// End of TreeFontListNotifier
/////////////////////////////////////////////////////////////////////
// Start of XFE_RDFTreeView definitions
static XFE_CommandList* my_commands = 0;
XFE_RDFTreeView::XFE_RDFTreeView(XFE_Component * toplevel,
Widget parent,
XFE_View * parent_view,
MWContext * context) :
XFE_View(toplevel, parent_view, context),
XFE_RDFBase(),
_popup(NULL),
_isStandAlone(False)
{
if (!my_commands)
{
registerCommand(my_commands, new RdfPopupCommand);
}
// Main form
Widget rdfMainForm = XtVaCreateWidget("rdfMainForm",
xmFormWidgetClass,
parent,
XmNshadowThickness, 0,
NULL);
setBaseWidget(rdfMainForm);
// createTree();
// doAttachments();
//fe_AddTipStringCallback(outline, XFE_Outliner::tip_cb, this);
}
//////////////////////////////////////////////////////////////////////////
XFE_RDFTreeView::~XFE_RDFTreeView()
{
if (_popup)
{
delete _popup;
}
// Remove yourself from the RDFImage's listener list
XFE_RDFImage::removeListener(this);
}
//////////////////////////////////////////////////////////////////////////
/* virtual */ void
XFE_RDFTreeView::createTree()
{
// Create the tree widget
_tree =
XtVaCreateWidget(TREE_NAME,
xmlTreeWidgetClass,
getTreeParent(),
XmNshadowThickness, 0,
XmNhorizontalSizePolicy, XmRESIZE_IF_POSSIBLE,
XmNallowColumnResize, True,
XmNselectionPolicy, XmSELECT_MULTIPLE_ROW,
XmNheadingRows, 1,
XmNvisibleRows, 14,
XmNhideUnhideButtons, True,
XmNminColumnWidth, 6,
NULL);
XtVaSetValues(_tree, XmNcellAlignment, XmALIGNMENT_LEFT, NULL);
XtVaSetValues(_tree,
XmNcellDefaults, True,
XmNcellAlignment, XmALIGNMENT_LEFT,
NULL);
_tree_fontlist_notifier = new TreeFontListNotifier( _tree );
// fix me ftang: we should pass a default font list to server as a
// template instead of hardcoded "helvetica" 12
_tree_utf8_converter = UTF8ToXmStringConverterFactory::make(
_tree_fontlist_notifier,
UnicodeFontSingleton::Instance( XtDisplay(_tree),
"helvetica",
12) );
init_pixmaps();
XtAddCallback(_tree, XmNexpandCallback, expand_row_cb, this);
XtAddCallback(_tree, XmNcollapseCallback, collapse_row_cb, this);
XtAddCallback(_tree, XmNdeleteCallback, delete_cb, this);
XtAddCallback(_tree, XmNactivateCallback, activate_cb, this);
XtAddCallback(_tree, XmNresizeCallback, resize_cb, this);
XtAddCallback(_tree, XmNeditCallback, edit_cell_cb, this);
XtAddCallback(_tree, XmNselectCallback, select_cb, this);
XtAddCallback(_tree, XmNdeselectCallback, deselect_cb, this);
XtAddCallback(_tree, XmNpopupCallback, popup_cb, this);
XtManageChild(_tree);
}
//////////////////////////////////////////////////////////////////////////
/* virtual */ Widget
XFE_RDFTreeView::getTreeParent()
{
return getBaseWidget();
}
//////////////////////////////////////////////////////////////////////////
/* virtual */ void
XFE_RDFTreeView::doAttachments()
{
if (XfeIsAlive(_tree))
{
XtVaSetValues(_tree,
XmNtopAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
}
}
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::setColumnData(int column, void * token, uint32 token_type)
{
XFE_ColumnData *column_data = getColumnData(column);
if (column_data) {
column_data->token = token;
column_data->token_type = token_type;
} else {
column_data = new XFE_ColumnData(token, token_type);
}
XtVaSetValues(_tree,
XmNcolumn, column,
XmNcolumnUserData, column_data,
NULL);
}
XFE_ColumnData *
XFE_RDFTreeView::getColumnData(int column)
{
XFE_ColumnData * column_data;
XmLGridColumn colp = XmLGridGetColumn(_tree, XmCONTENT, column);
XtVaGetValues(_tree,
XmNcolumnPtr, colp,
XmNcolumnUserData, &column_data,
NULL);
return column_data;
}
/////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::init_pixmaps(void)
{
XP_ASSERT( XfeIsAlive(_tree) );
Pixel bg_pixel;
XtVaGetValues(_tree, XmNbackground, &bg_pixel, 0);
Widget shell = XfeAncestorFindByClass(getToplevel()->getBaseWidget(),
shellWidgetClass,
XfeFIND_ANY);
if (!bookmark.pixmap)
fe_NewMakeIcon(shell,
BlackPixelOfScreen(XtScreen(m_widget)),
bg_pixel,
&bookmark,
NULL,
BM_Bookmark.width, BM_Bookmark.height,
BM_Bookmark.mono_bits, BM_Bookmark.color_bits,
BM_Bookmark.mask_bits, FALSE);
if (!closedFolder.pixmap)
fe_NewMakeIcon(shell,
BlackPixelOfScreen(XtScreen(m_widget)),
bg_pixel,
&closedFolder,
NULL,
BM_Folder.width, BM_Folder.height,
BM_Folder.mono_bits, BM_Folder.color_bits,
BM_Folder.mask_bits, FALSE);
if (!openedFolder.pixmap)
fe_NewMakeIcon(shell,
BlackPixelOfScreen(XtScreen(m_widget)),
bg_pixel,
&openedFolder,
NULL,
BM_FolderO.width, BM_FolderO.height,
BM_FolderO.mono_bits, BM_FolderO.color_bits,
BM_FolderO.mask_bits, FALSE);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::activate_row(int row)
{
HT_Resource node = HT_GetNthItem(_ht_view, row);
XFE_RDFUtils::launchEntry(m_contextData, node);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::resize_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
obj->resize(callData);
}
void
XFE_RDFTreeView::resize(XtPointer callData)
{
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct*)callData;
XP_ASSERT(_tree);
if(!_tree)
return;
if (cbs->reason == XmCR_RESIZE_COLUMN)
{
D(printf("Inside XFE_RDFTreeView::resize(COLUMN, %d)\n", cbs->column););
XmLGridColumn column = XmLGridGetColumn(_tree, XmCONTENT, cbs->column);
XFE_ColumnData *column_data = getColumnData(cbs->column);
int width = 0;
XtVaGetValues(_tree,
XmNcolumnPtr, column,
XmNcolumnWidth, &width,
NULL);
HT_SetColumnWidth(_ht_view, column_data->token, column_data->token_type,
width);
}
}
void
XFE_RDFTreeView::refresh(HT_Resource node)
{
if (!_ht_view) return;
XP_ASSERT(HT_IsContainer(node));
if (!HT_IsContainer(node)) return;
if (HT_IsContainerOpen(node))
{
HT_Resource child;
HT_Cursor child_cursor = HT_NewCursor(node);
while ( (child = HT_GetNextItem(child_cursor)) )
{
add_row(child);
if (HT_IsContainer(child) && HT_IsContainerOpen(child))
refresh(child);
}
HT_DeleteCursor(child_cursor);
}
else
{
int row = HT_GetNodeIndex(_ht_view, node);
XmLTreeDeleteChildren(_tree, row);
}
}
void
XFE_RDFTreeView::edit_cell_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
obj->edit_cell(callData);
}
void
XFE_RDFTreeView::edit_cell(XtPointer callData)
{
XP_ASSERT(_tree);
if(!_tree)
return;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct*)callData;
HT_Resource node = HT_GetNthItem (_ht_view, cbs->row);
if(! node)
return;
Widget inlineedit;
XtVaGetValues(_tree, XmNtextWidget, &inlineedit, NULL);
XP_ASSERT(inlineedit);
XFE_ColumnData *column_data = getColumnData(cbs->column);
switch (cbs->reason)
{
case XmCR_EDIT_CANCEL:
initCell(node, cbs->row, cbs->column);
break;
case XmCR_EDIT_COMPLETE:
{
char* utf8,*widgetText;
widgetText = XmTextGetString(inlineedit);
utf8 = (char*) INTL_ConvertLineWithoutAutoDetect(
INTL_GetCharSetID(INTL_DefaultTextWidgetCsidSel),
CS_UTF8,
(unsigned char*)widgetText, XP_STRLEN(widgetText));
XtFree(widgetText);
HT_SetNodeData (node, column_data->token, column_data->token_type, utf8);
initCell(node, cbs->row, cbs->column);
}
break;
case XmCR_EDIT_BEGIN:
case XmCR_EDIT_INSERT:
{
void* utf8;
char* widgetText;
HT_GetNodeData (node, column_data->token, column_data->token_type, &utf8);
widgetText = (char*) INTL_ConvertLineWithoutAutoDetect(
CS_UTF8,
INTL_GetCharSetID(INTL_DefaultTextWidgetCsidSel),
(unsigned char*)utf8, XP_STRLEN((char*)utf8));
XmTextSetString(inlineedit, widgetText );
XP_FREE(widgetText);
}
break;
}
}
void
XFE_RDFTreeView::select_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
if (cbs->rowType == XmHEADING) {
obj->sort_column(cbs->column);
} else {
obj->select_row(cbs->row);
}
}
void
XFE_RDFTreeView::sort_column(int column)
{
int old_sort_column;
unsigned char old_sort_type;
XmLGridGetSort(_tree, &old_sort_column, &old_sort_type);
unsigned char sort_type = XmSORT_ASCENDING;
if (old_sort_column == column) {
if (old_sort_type == XmSORT_ASCENDING)
sort_type = XmSORT_DESCENDING;
else if (old_sort_type == XmSORT_DESCENDING)
sort_type = XmSORT_NONE;
}
XFE_ColumnData * column_data = getColumnData(column);
if (sort_type == XmSORT_NONE) {
HT_SetSortColumn(_ht_view, NULL, NULL, PR_FALSE);
} else {
XP_ASSERT(column_data);
if (!column_data) return;
HT_SetSortColumn(_ht_view,
column_data->token,
column_data->token_type,
sort_type == XmSORT_DESCENDING ? PR_TRUE : PR_FALSE);
}
XmLGridSetSort(_tree, column, sort_type);
}
void
XFE_RDFTreeView::select_row(int row)
{
HT_Resource node = HT_GetNthItem(_ht_view, row);
if (!node) return;
HT_SetSelection(node);
}
void
XFE_RDFTreeView::deselect_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
D(fprintf(stderr,"deselect_cb(%d)\n",cbs->row););
obj->deselect_row(cbs->row);
}
void
XFE_RDFTreeView::deselect_row(int row)
{
HT_Resource node = HT_GetNthItem(_ht_view, row);
if (!node) return;
HT_SetSelectedState(node,False);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::notify(HT_Resource n, HT_Event whatHappened)
{
D(debugEvent(n, whatHappened,"RTV"););
switch (whatHappened) {
case HT_EVENT_NODE_ADDED:
add_row(n);
break;
case HT_EVENT_NODE_DELETED_NODATA:
{
#ifdef UNDEF
// Is this a container node?
Boolean expands = HT_IsContainer(n);
PRBool isExpanded = False;
// Is the node expanded?
if (expands) {
HT_GetOpenState(n, &isExpanded);
}
int row = HT_GetNodeIndex(_ht_view, n);
delete_row(row);
#endif /* UNDEF */
break;
}
case HT_EVENT_NODE_OPENCLOSE_CHANGED:
{
refresh(n);
Boolean expands = HT_IsContainer(n);
if (expands)
{
PRBool isExpanded = False;
HT_GetOpenState(n, &isExpanded);
int row = HT_GetNodeIndex(_ht_view, n);
if (isExpanded) // The node has been opened
{
// Expand the row
XtVaSetValues(_tree, XmNrow, row,
XmNrowIsExpanded, True, NULL);
}
else
{
// collapse the row
XtVaSetValues(_tree, XmNrow, row,
XmNrowIsExpanded, False, NULL);
}
}
break;
}
case HT_EVENT_VIEW_SELECTED:
{
setHTView(HT_GetView(n));
break;
}
case HT_EVENT_NODE_EDIT:
{
int row = HT_GetNodeIndex(_ht_view, n);
XmLGridEditBegin(_tree, True, row, 0);
break;
}
case HT_EVENT_VIEW_REFRESH:
case HT_EVENT_VIEW_SORTING_CHANGED:
{
int row = HT_GetNodeIndex(_ht_view, n);
PRBool expands = HT_IsContainer(n);
PRBool isExpanded = False;
if (expands)
HT_GetOpenState(n, &isExpanded);
if (expands && isExpanded)
{
if (n == HT_TopNode(_ht_view))
/* It is the top most node. Delete all rows */
XmLGridDeleteAllRows(_tree, XmCONTENT);
else
XmLTreeDeleteChildren(_tree, row);
}
refresh(n);
break;
}
default:
// Fall through and let RDFBase handle the event
break;
}
XFE_RDFBase::notify(n,whatHappened);
}
//////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::updateRoot()
{
fill_tree();
setHTTreeViewProperties(_ht_view);
}
//////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::fill_tree()
{
XP_ASSERT(_tree);
if (!_ht_view || !_tree)
return;
int item_count = HT_GetItemListCount(_ht_view);
//void * data=NULL;
XtVaSetValues(_tree,
XmNlayoutFrozen, True,
XmNcolumns, 1,
NULL);
XmLGridDeleteAllRows(_tree, XmCONTENT);
// Set default values for column headings
// (Should make so that the grid widget has separate defaults
// for headings and content cells)
XtVaSetValues(_tree,
XmNcellDefaults, True,
XmNcellLeftBorderType, XmBORDER_LINE,
XmNcellRightBorderType, XmBORDER_LINE,
XmNcellTopBorderType, XmBORDER_LINE,
XmNcellBottomBorderType, XmBORDER_LINE,
NULL);
// add columns
char *column_name;
uint32 column_width;
void *token;
uint32 token_type;
int ii = 0;
HT_Cursor column_cursor = HT_NewColumnCursor (_ht_view);
while (HT_GetNextColumn(column_cursor, &column_name, &column_width,
&token, &token_type)) {
add_column(ii, column_name, column_width, token, token_type);
ii++;
}
HT_DeleteColumnCursor(column_cursor);
// Set default values for new content cells
XtVaSetValues(_tree,
XmNcellDefaults, True,
XmNcellMarginLeft, 1,
XmNcellMarginRight, 1,
XmNcellLeftBorderType, XmBORDER_NONE,
XmNcellRightBorderType, XmBORDER_NONE,
XmNcellTopBorderType, XmBORDER_NONE,
XmNcellBottomBorderType, XmBORDER_NONE,
NULL);
// add rows
for (ii=0; ii < item_count; ii++) {
add_row(ii);
}
XtVaSetValues(_tree,
XmNlayoutFrozen, False,
NULL);
}
void
XFE_RDFTreeView::destroy_tree()
{
if(_tree_utf8_converter)
{
delete _tree_utf8_converter;
_tree_utf8_converter = NULL;
}
if(_tree_fontlist_notifier)
{
delete _tree_fontlist_notifier;
_tree_fontlist_notifier = NULL;
}
}
void
XFE_RDFTreeView::add_row(int row)
{
HT_Resource node = HT_GetNthItem (_ht_view, row);
add_row(node);
}
void
XFE_RDFTreeView::add_row(HT_Resource node)
{
int row = HT_GetNodeIndex(_ht_view, node);
int depth = HT_GetItemIndentation(node);
Boolean expands = HT_IsContainer(node);
Boolean isExpanded = HT_IsContainerOpen(node);
Pixmap pixmap, mask;
#if DEBUG_mcafeexxx
// Using this for debugging. -mcafee
static PRBool firstRow = PR_TRUE;
if(firstRow) {
printf("First row\n");
firstRow = PR_FALSE;
} else {
printf("Not first row\n");
}
#endif
if (expands && isExpanded) {
pixmap = openedFolder.pixmap;
mask = openedFolder.mask;
} else if (expands && !isExpanded) {
pixmap = closedFolder.pixmap;
mask = closedFolder.mask;
} else {
pixmap = bookmark.pixmap;
mask = bookmark.mask;
}
XmLTreeAddRow(_tree, depth, expands, isExpanded, row, pixmap, mask, NULL);
int column_count;
XtVaGetValues(_tree, XmNcolumns, &column_count, NULL);
for (int ii = 0; ii < column_count; ii++)
{
initCell(node, row, ii);
}
}
// Format the label of a cell
// Also set whether it is editable.
void
XFE_RDFTreeView::initCell(HT_Resource node, int row, int column)
{
XFE_ColumnData *column_data = getColumnData(column);
XP_ASSERT(column_data);
if (!column_data) return;
// Set editing behavior
//
Boolean is_editable = False;
if (isStandAlone())
{
is_editable = HT_IsNodeDataEditable(node, column_data->token,
column_data->token_type);
}
// Set the label.
//
char buffer[1024];
if (column == 0)
{
if(HT_IsSeparator(node))
sprintf(buffer, "-------------------------");
else
sprintf(buffer, "%s", (char*)HT_GetNodeName(node));
}
else
{
void *data;
if (HT_GetNodeData(node, column_data->token, column_data->token_type,
&data) && data)
{
switch (column_data->token_type)
{
case HT_COLUMN_DATE_INT:
case HT_COLUMN_INT:
sprintf(buffer,"%d",(int)data);
break;
case HT_COLUMN_DATE_STRING:
case HT_COLUMN_STRING:
strcpy(buffer, (char*)data);
break;
}
}
else
strcpy(buffer, "");
}
XmString xmstr = _tree_utf8_converter->convertToXmString(buffer);
XtVaSetValues(_tree,
XmNrow, row,
XmNcolumn, column,
XmNcellString, xmstr,
XmNcellEditable, is_editable,
NULL);
XmStringFree(xmstr);
}
void
XFE_RDFTreeView::delete_row(int row)
{
XmLGridDeleteRows(_tree, XmCONTENT, row, 1);
}
void
XFE_RDFTreeView::add_column(int index, char *name, uint32 width,
void *token, uint32 token_type)
{
D( fprintf(stderr,"XFE_RDFTreeView::add_column index(%d) name(%s) width(%d)\n",
index, name,width););
if (index > 0) {
XmLGridAddColumns(_tree, XmCONTENT, index, 1);
}
XtVaSetValues(_tree,
XmNcolumn, index,
XmNcolumnSizePolicy, XmCONSTANT,
XmNcolumnWidth, width,
NULL);
setColumnData(index, token, token_type);
XmString xmstr = _tree_utf8_converter->convertToXmString(name);
XtVaSetValues( _tree,
XmNrow, 0,
XmNcolumn, index,
XmNrowType, XmHEADING,
XmNcellString, xmstr,
NULL);
XmStringFree(xmstr);
}
void
XFE_RDFTreeView::delete_column(HT_Resource /* cursor */)
{
}
void
XFE_RDFTreeView::expand_row_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
D(fprintf(stderr,"expand_row_cb(%d)\n",cbs->row););
obj->expand_row(cbs->row);
}
void
XFE_RDFTreeView::expand_row(int row)
{
HT_Resource node = HT_GetNthItem (_ht_view, row);
HT_SetOpenState (node, (PRBool)TRUE);
}
void
XFE_RDFTreeView::collapse_row_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
D(fprintf(stderr,"collapse_row_cb(%d)\n",cbs->row););
obj->collapse_row(cbs->row);
}
void
XFE_RDFTreeView::collapse_row(int row)
{
HT_Resource node = HT_GetNthItem (_ht_view, row);
HT_SetOpenState (node, (PRBool)FALSE);
}
void
XFE_RDFTreeView::delete_cb(Widget w,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
cbs = (XmLGridCallbackStruct *)callData;
if (cbs->reason != XmCR_DELETE_COLUMN)
return;
XFE_ColumnData * column_data = obj->getColumnData(cbs->column);
if (column_data)
delete column_data;
}
void
XFE_RDFTreeView::activate_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
if (cbs->rowType != XmCONTENT)
return;
obj->activate_row(cbs->row);
}
//
// Popup menu stuff
//
void
XFE_RDFTreeView::popup_cb(Widget,
XtPointer clientData,
XtPointer callData)
{
XFE_RDFTreeView *obj = (XFE_RDFTreeView*)clientData;
XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct *)callData;
if (cbs->rowType != XmCONTENT)
return;
obj->doPopup(cbs->event);
}
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::doPopup(XEvent * event)
{
if (_popup)
{
delete _popup; //destroy the old one first
}
_popup = new XFE_RDFPopupMenu("popup",
//getFrame(),
FE_GetToplevelWidget(),
_ht_view,
FALSE, // not isWorkspace
FALSE); // no background commands for now
_popup->position(event);
_popup->show();
}
//////////////////////////////////////////////////////////////////////////
//
// Toggle the stand alone state
//
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::setStandAlone(XP_Bool stand_alone)
{
XP_ASSERT( XfeIsAlive(_tree) );
_isStandAlone = stand_alone;
#ifdef UNDEF
/*
* We need to set lot more properties based on standalone state.
* We instead call setHTTreeviewProperties to do all that
*/
int visibleColumns = (_isStandAlone ? 0 : 1);
XtVaSetValues(_tree,
XmNvisibleColumns, visibleColumns,
NULL);
#endif /* UNDEF */
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Set the HT View properties to the tree
//////////////////////////////////////////////////////////////////////////
void
XFE_RDFTreeView::setHTTreeViewProperties( HT_View view)
{
Arg av[30];
Cardinal ac=0;
void * data=NULL;
Pixel pixel;
PRBool gotit=False;
//////////////////////////////////////////////////////////////////////////
// Properties common to all views
// Should probably go to a base class
//////////////////////////////////////////////////////////////////////////
/* viewBGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->viewBGColor, HT_COLUMN_STRING, &data);
if (data)
{
gotit = fe_GetPixelFromRGBString(getContext(), (char *) data, &pixel);
if (gotit) {
XtSetArg(av[ac], XmNbackground, pixel); ac++;
}
}
/* viewFGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->viewFGColor, HT_COLUMN_STRING, &data);
if (data)
{
gotit = fe_GetPixelFromRGBString(getContext(), (char *) data, &pixel);
if (gotit) {
XtSetArg(av[ac], XmNforeground, pixel); ac++;
}
}
/* viewBGURL */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->viewBGURL, HT_COLUMN_STRING, &data);
if (data)
{
/* Do the RDFImage thing here */
char * imageURL = (char *)data;
XFE_RDFImage * rdfImage=NULL;
Pixmap image, mask;
rdfImage = XFE_RDFImage::isImageAvailable(imageURL);
if (rdfImage) {
image = rdfImage->getPixmap();
mask = rdfImage->getMask();
XtVaSetValues(_tree, XmNbackgroundPixmap, image, NULL);
}
else {
rdfImage = new XFE_RDFImage(m_toplevel, (void *) this, (char *) data, CONTEXT_DATA(m_contextData)->colormap, _tree);
rdfImage->setCompleteCallback((completeCallbackPtr)treeview_bg_image_cb, (void *) _tree);
rdfImage->loadImage();
}
}
//////////////////////////////////////////////////////////////////////////
// Properties common to all trees
//////////////////////////////////////////////////////////////////////////
/* selectionFGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->selectionFGColor, HT_COLUMN_STRING, &data);
if (data)
{
gotit = fe_GetPixelFromRGBString(getContext(), (char *) data, &pixel);
if (gotit) {
XtSetArg(av[ac], XmNselectForeground, pixel); ac++;
}
}
/* selectionBGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->selectionBGColor, HT_COLUMN_STRING, &data);
if (data)
{
gotit = fe_GetPixelFromRGBString(getContext(), (char *) data, &pixel);
if (gotit) {
XtSetArg(av[ac], XmNselectBackground, pixel); ac++;
}
}
/* treeConnectionColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->treeConnectionFGColor, HT_COLUMN_STRING, &data);
if (data)
{
gotit = fe_GetPixelFromRGBString(getContext(), (char *) data, &pixel);
if (gotit) {
XtSetArg(av[ac], XmNconnectingLineColor, pixel); ac++;
}
}
/* showColumnHeaders */
/* This doesn't work now. showColumnHeaders returns False in docked as well
* as in standalone mode. So we'll use the FE method to figure this, until
* the BE is fixed
*/
/*
HT_GetTemplateData(HT_TopNode(view), gNavCenter->showColumnHeaders, HT_COLUMN_STRING, &data);
if (data)
{
char * answer = (char *) data;
if ((!XP_STRCASECMP(answer, "yes")) || (!XP_STRCASECMP(answer, "1")))
{ }
else if ((!XP_STRCASECMP(answer, "No")) || (!XP_STRCASECMP(answer, "0")))
{ }
*/
if (isStandAlone())
{
/* Management mode */
XtSetArg(av[ac], XmNheadingRows, 1);
ac ++;
XtSetArg(av[ac], XmNhideUnhideButtons, True);
ac++;
XtSetArg(av[ac], XmNsingleClickActivation, False);
ac++;
}
else
{
/* Navigation mode */
XtSetArg(av[ac], XmNheadingRows, 0);
ac ++;
XtSetArg(av[ac], XmNhideUnhideButtons, False);
ac++;
XtSetArg(av[ac], XmNvisibleColumns, 1);
ac++;
XtSetArg(av[ac], XmNsingleClickActivation, True);
ac++;
}
/* useInlineEditing. This doesn't work now for teh same reason as above */
HT_GetTemplateData(getRootFolder(),
gNavCenter->useInlineEditing,
HT_COLUMN_STRING, &data);
if (data)
{
/* Decide if cells are editable */
}
XtSetValues(_tree, av, ac);
#ifdef UNDEF /* Properties that can't be set yet in the tree widget */
/* viewRolloverColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->viewRolloverColor, HT_COLUMN_STRING, &(viewProperties->viewRolloverColor));
/* viewPressedColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->viewPressedColor, HT_COLUMN_STRING, &(viewProperties->viewPressedColor));
/* showTreeConnections */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->showTreeConnections, HT_COLUMN_STRING, &(viewProperties->showTreeConnections));
/* showDividers */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->showDivider, HT_COLUMN_STRING, &(viewProperties->showDivider));
/* dividerColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->dividerColor, HT_COLUMN_STRING, &(viewProperties->dividerColor));
/* useSingleClick */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->useSingleClick, HT_COLUMN_STRING, &(viewProperties->useSingleClick));
/* useSelection */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->useSelection, HT_COLUMN_STRING, &(viewProperties->useSelection));
/* selectedColumnHeaderFGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->selectedColumnHeaderFGColor, HT_COLUMN_STRING, &(viewProperties->selectedColumnHeaderFGColor));
/* selectedColumnHeaderBGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->selectedColumnHeaderBGColor, HT_COLUMN_STRING, &(viewProperties->selectedColumnHeaderBGColor));
/* sortColumnFGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->sortColumnFGColor, HT_COLUMN_STRING, &(viewProperties->sortColumnFGColor));
/* sortColumnBGColor */
HT_GetTemplateData(HT_TopNode(view), gNavCenter->sortColumnBGColor, HT_COLUMN_STRING, &(viewProperties->sortColumnBGColor));
#endif /* UNDEF */
}
extern "C" {
void
treeview_bg_image_cb(XtPointer client_data)
{
callbackClientData * cb = (callbackClientData *) client_data;
Widget tree = (Widget )cb->widget;
//Dimension b_width=0, b_height=0;
XtVaSetValues(tree, XmNbackgroundPixmap, cb->image, NULL);
XP_FREE(cb);
}
}; /* extern C */