home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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.
- */
- /*
- Outliner.cpp -- Outliner class hack.
- Created: Chris Toshok <toshok@netscape.com>, 7-Aug-96.
- */
-
-
-
- #include "xpassert.h"
- #include "xp_mem.h"
-
- #include "Outliner.h"
- #include "Outlinable.h"
-
- #if defined(USE_MOTIF_DND)
- #include "OutlinerDrop.h"
- #endif /* USE_MOTIF_DND */
-
- #include "xfe.h"
- #include "icondata.h"
- #include "prefapi.h"
- #include "xp_qsort.h"
-
- #include <Xfe/XfeP.h>
-
- #if !defined(USE_MOTIF_DND)
- #include <Xm/Label.h>
- #endif /* USE_MOTIF_DND */
-
- #ifdef DEBUG_toshok
- #define D(x) x
- #else
- #define D(x)
- #endif
-
- extern "C" {
-
- #include "XmL/GridP.h"
-
- };
-
- // please change this if you change any of the *parent.gif images.
- #define PIPEIMAGESIZE 16
-
- #if defined(USE_MOTIF_DND)
- #undef NONMOTIF_DND
- #else
- #define NONMOTIF_DND
- #endif /* USE_MOTIF_DND */
-
- #ifdef FREEIF
- #undef FREEIF
- #endif
- #define FREEIF(obj) do { if (obj) { XP_FREE (obj); obj = 0; }} while (0)
-
- #define MIN_COLUMN_WIDTH 6 /* So that the user can manipulate it -- make it the same as the grid's minimum */
- #define MAX_COLUMN_WIDTH 10000 /* So that we don't overflow any 16-bit
- numbers. */
-
- #ifdef DEBUG_toshok
- #define D(x) x
- #else
- #define D(x)
- #endif
-
- #include "xpgetstr.h"
- extern int XFE_SHOW_COLUMN;
- extern int XFE_HIDE_COLUMN;
-
- fe_icon XFE_Outliner::closedParentIcon = { 0 };
- fe_icon XFE_Outliner::openParentIcon = { 0 };
- fe_icon XFE_Outliner::showColumnIcon = { 0 };
- fe_icon XFE_Outliner::showColumnInsensIcon = { 0 };
- fe_icon XFE_Outliner::hideColumnIcon = { 0 };
- fe_icon XFE_Outliner::hideColumnInsensIcon = { 0 };
-
- #if !defined(USE_MOTIF_DND)
- fe_dnd_Source _xfe_dragsource = {0};
- #endif /* USE_MOTIF_DND */
-
- //
- #if defined(DEBUG_tao_)
- #define XDBG(x) x
- #else
- #define XDBG(x)
- #endif
-
- #if defined(DEBUG_tao)
- #define TRACE(str) printf("\n At %s: %d, %s", __FILE__, __LINE__, str)
- #else
- #define TRACE(str)
- #endif
-
- void
- XFE_Outliner::tip_cb(Widget w, XtPointer clientData, XtPointer cb_data)
- {
- XFE_Outliner *obj = (XFE_Outliner *) clientData;
-
- obj->tipCB(w, cb_data);
- }
-
- void
- XFE_Outliner::tipCB(Widget /* w */, XtPointer cb_data)
- {
- XFE_TipStringCallbackStruct* cbs = (XFE_TipStringCallbackStruct*)cb_data;
- char *strFromView = 0;
- XP_FREEIF(m_doc_msg_buf);
- XP_FREEIF(m_tip_msg_buf);
-
- //
- // cbs->x <= -10 is not really possible to happen!
- //
- if (cbs->x <= -10 ||
- cbs->x >= m_totalLines ||
- cbs->y < 0 ||
- cbs->y >= m_numcolumns)
- return;
-
- int sourcecol = m_columnIndex[cbs->y];
- if (cbs->reason == XFE_DOCSTRING) {
- strFromView = m_outlinable->getCellDocString(cbs->x, sourcecol);
-
- m_doc_msg_buf = XP_STRDUP(strFromView?strFromView:"");
- *cbs->string = m_doc_msg_buf;
- cbs->x = -10;
- cbs->y = -10;
- } else if (cbs->reason == XFE_TIPSTRING) {
- if (cbs->y >= m_numvisible && m_hideColumnsAllowed) {
- if (cbs->x != -1) {
- m_tip_msg_buf = XP_STRDUP("");
- *cbs->string = m_tip_msg_buf;
- return;
- }/* if */
-
- if (cbs->y == m_numvisible) {
- /* show header */
- strFromView = XP_GetString(XFE_SHOW_COLUMN);
- }/* if */
- else {
- /* hide header */
- strFromView = XP_GetString(XFE_HIDE_COLUMN);
- }/* else */
- }/* if */
- else
- strFromView = m_outlinable->getCellTipString(cbs->x, sourcecol);
-
- m_tip_msg_buf = XP_STRDUP(strFromView?strFromView:"");
- *cbs->string = m_tip_msg_buf;
-
- XRectangle rect;
- if (XmLGridRowColumnToXY(m_widget,
- (cbs->x < 0)?XmHEADING:XmCONTENT,
- (cbs->x < 0)?0:cbs->x,
- XmCONTENT,
- cbs->y,
- False,
- &rect) < 0) {
- cbs->x = -10;
- cbs->y = -10;
- }/* if */
- else {
- XDBG(printf("\n tipCB: (total,r,c,w,h)=(%d,%d,%d,%d,%d)\n",
- m_totalLines, cbs->x, cbs->y, rect.width, rect.height));
- cbs->x = rect.x + textStart(cbs->y, rect.width);
- cbs->y = rect.y + rect.height;
- }/* else */
- }
- }
-
- int XFE_Outliner::textStart(int col, int maxX)
- {
- fe_icon *icon;
- int sourcecol = m_columnIndex[col];
- int startX = 0;
- icon = m_outlinable->getColumnIcon(sourcecol);
-
- if (sourcecol == m_pipeColumn) {
- OutlinerAncestorInfo * ancestorInfo;
- int depth;
-
- m_outlinable->getTreeInfo(NULL, NULL, &depth, &ancestorInfo);
-
- for (int i = 0; i < depth; i ++) {
- if ( ( i + 1 ) * PIPEIMAGESIZE <= maxX )
- if (ancestorInfo && ancestorInfo[ i ].has_next) {
- // the the vertical pipe for this line's ancestors.
- startX += PIPEIMAGESIZE;
- }
- else {
- // don't know about this block.. must ask will.
- startX += PIPEIMAGESIZE;
- }
- }/* for i */
-
- if (ancestorInfo)
- startX += PIPEIMAGESIZE;
- }/* if pipeCol */
-
- /* if there's an icon, we need to push the text over. */
- if (icon) {
- startX = startX + icon->width + 4;
- }/* if */
- return startX;
- }
-
- XP_Bool XFE_Outliner::isColTextFit(char *str, int row, int col)
- {
- XDBG(printf("\n XFE_Outliner::isColTextFit, row=%d, col=%d, str=%s\n",
- row, col, str));
- if (str && XP_STRLEN(str)) {
-
- XRectangle rect;
- if (XmLGridRowColumnToXY(m_widget,
- (row < 0)?XmHEADING:XmCONTENT,
- (row < 0)?0:row,
- XmCONTENT,
- col,
- False,
- &rect) < 0) {
- return False;
- }/* if */
- else {
- char *style =
- (row < 0)?
- (char*)styleToTag(m_outlinable->getColumnHeaderStyle(col)):
- (char*)styleToTag(m_outlinable->getColumnStyle(col));
-
- XmString xmstr = XmStringCreate(str, style);
- XmFontList fontList;
- XtVaGetValues(m_widget,
- XmNfontList, &fontList,
- NULL);
- Dimension strWidth = XmStringWidth(fontList, xmstr);
- XmStringFree(xmstr);
- strWidth += textStart(col, rect.width);
- XDBG(printf("\n (str, strWidth, rect.width, row, col)=(%s, %d, %d, %d, %d)\n",
- str, strWidth, rect.width, row, col));
- return (strWidth < (rect.width-1));
- }/* else */
- }/* if */
- else
- return True;
- }/* XFE_Outliner::getStringWidth */
-
- //
-
- XFE_Outliner::XFE_Outliner(const char *name,
- XFE_Outlinable *o,
- XFE_Component *toplevel_component,
- Widget widget_parent,
- Boolean constantSize,
- XP_Bool hasHeadings,
- int num_columns,
- int num_visible,
- int *column_widths,
- char *geom_prefname)
- : XFE_Component(toplevel_component)
- {
- m_lastRow = -2;
- m_lastCol = -2;
- m_inGrid = False;
-
- m_tip_msg_buf = 0;
- m_doc_msg_buf = 0;
-
- Widget outline;
- Arg av[10];
- int ac = 0;
- short avgwidth, avgheight;
- XmFontList fontList;
- int i;
- XP_Bool defaultGeometryOK = FALSE;
-
- m_geominfo = NULL;
- m_prefname = NULL;
-
- if (geom_prefname)
- {
- m_prefname = XP_STRDUP(geom_prefname);
- PREF_CopyCharPref(geom_prefname, &m_geominfo);
- }
-
- m_visibleLine = -1;
- m_DataRow = -1;
- m_draggc = NULL;
- m_dragrow = -1;
-
- #if !defined(USE_MOTIF_DND)
- m_dragtype = FE_DND_NONE;
- #else
- m_dragTargetFunc = NULL;
- m_dropTargetFunc = NULL;
- m_dragIconDataFunc = NULL;
- m_outlinerdrag = NULL;
- #endif /* USE_MOTIF_DND */
-
- m_activity = 0;
- m_lastx = -999;
- m_lasty = -999;
- #if !defined(USE_MOTIF_DND)
- m_lastmotionx = 0;
- m_lastmotiony = 0;
- #endif /* USE_MOTIF_DND */
- m_totalLines = 0;
- m_numcolumns = num_columns;
- m_numvisible = num_visible;
- m_pipeColumn = -1;
- m_sortColumn = -1;
- m_resizeColumn = -1;
- m_visibleTimer = 0;
-
- m_hideColumnsAllowed = False;
- m_descendantSelectAllowed = False;
- m_isFocus = False;
-
- if (constantSize)
- {
- XtSetArg(av[ac], XmNhorizontalSizePolicy, XmCONSTANT); ac++;
- }
- else
- {
- XtSetArg(av[ac], XmNhorizontalSizePolicy, XmVARIABLE); ac++;
- }
-
- XtSetArg(av[ac], XmNautoSelect, False); ac++;
- XtSetArg(av[ac], XmNtraversalOn, False); ac++;
-
- outline = XmLCreateGrid(widget_parent, (char*)name, av, ac);
-
- Pixel bgColor;
- XtVaGetValues(outline, XmNbackground, &bgColor, 0);
- XtVaSetValues(outline,
- XmNborderWidth, 2,
- XmNborderColor, bgColor,
- XmNcellDefaults, True,
- XmNcellLeftBorderType, XmBORDER_NONE,
- XmNcellRightBorderType, XmBORDER_NONE,
- XmNcellTopBorderType, XmBORDER_NONE,
- XmNcellBottomBorderType, XmBORDER_NONE,
- XmNcellAlignment, XmALIGNMENT_LEFT,
- 0);
-
- m_columnwidths = (int*)XP_CALLOC(m_numcolumns, sizeof(int));
-
- // whether or not columns are resizable
- m_columnResizable = (XP_Bool*)XP_CALLOC(m_numcolumns, sizeof(XP_Bool));
- memset(m_columnResizable, True, sizeof(XP_Bool) * m_numcolumns);
-
- m_columnIndex = (int*) XP_ALLOC(sizeof(int) * (m_numcolumns));
-
- #if defined(USE_MOTIF_DND)
- XtAddEventHandler(outline,
- ButtonPressMask | ButtonReleaseMask,
- False,
- buttonEventHandler, this);
- #else
- XtInsertEventHandler(outline, ButtonPressMask | ButtonReleaseMask
- | PointerMotionMask, False,
- buttonEventHandler, this, XtListHead);
- #endif
- XtAddCallback(outline, XmNcellDrawCallback, celldrawCallback, this);
-
- m_buttonfunc_data = XP_NEW_ZAP(OutlineButtonFuncData);
- m_flippyfunc_data = XP_NEW_ZAP(OutlineFlippyFuncData);
-
- #if !defined(USE_MOTIF_DND)
- // initialize the drag/drop stuff
- m_dragtype = FE_DND_NONE;
- m_dragicon = 0;
- m_sourcedropfunc = 0;
- #endif
-
- // initialize the selection stuff
- m_selBlocked = False;
- m_selectedIndices = new int[5];
- m_selectedItems = NULL;
- m_selectedItemCount = 0;
- m_selectedCount = 0;
- m_selectedSize = 5;
- m_firstSelectedIndex = (unsigned int)(1 << 31) - 1; // INT_MAX
- m_lastSelectedIndex = -1;
- m_selectionDirection = 1; // safe default.
-
- // initialize the magic list change (finished, starting) depth.
- m_listChangeDepth = 0;
-
- // keep track of our peer
- m_outlinable = o;
-
- // and set our base widget
- setBaseWidget(outline);
-
- #if defined(USE_MOTIF_DND)
- m_outlinerdrop = new XFE_OutlinerDrop(m_widget, this);
- m_outlinerdrop->enable();
- #endif /* USE_MOTIF_DND */
-
- defaultGeometryOK = setDefaultGeometry();
-
- if (hasHeadings)
- XmLGridAddRows(m_widget, XmHEADING, 0, 1);
-
- if (!defaultGeometryOK)
- {
- int i;
-
- D(printf ("default geometry is NOT OK!\n");)
-
- m_numvisible = num_visible;
- for (i = 0; i < m_numcolumns; i ++)
- m_columnIndex[i] = i;
-
- XtVaGetValues(outline, XmNfontList, &fontList, NULL);
- XmLFontListGetDimensions(fontList, &avgwidth, &avgheight, TRUE);
- }
-
- XmLGridAddColumns(outline, XmCONTENT, -1, m_numvisible);
-
- for (i = 0; i < m_numcolumns; i ++)
- {
- if (!defaultGeometryOK)
- m_columnwidths[i] = column_widths[i] * avgwidth;
-
- if (i < m_numvisible)
- XtVaSetValues(m_widget,
- XmNcolumn, i,
- XmNcolumnSizePolicy, XmCONSTANT,
- XmNcolumnWidth, m_columnwidths[i],
- 0);
- }
-
- if (!defaultGeometryOK)
- {
- // since it wasn't ok before, we can be assured that it is now.
- // Save it so we won't do the above stuff again.
- rememberGeometry();
- }
-
- XtVaSetValues(m_widget, XmNallowColumnResize, True, 0);
-
- XtAddCallback(m_widget, XmNresizeCallback, resizeCallback, this);
-
- // Tooltip
- fe_AddTipStringCallback(outline, XFE_Outliner::tip_cb, this);
-
- // create our icons, if we need to.
- if (!closedParentIcon.pixmap)
- {
- Pixel bg_pixel;
-
- XtVaGetValues(m_widget, XmNbackground, &bg_pixel, 0);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &closedParentIcon,
- NULL,
- cparent.width, cparent.height,
- cparent.mono_bits, cparent.color_bits,
- cparent.mask_bits, FALSE);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &openParentIcon,
- NULL,
- oparent.width, oparent.height,
- oparent.mono_bits, oparent.color_bits,
- oparent.mask_bits, FALSE);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &showColumnIcon,
- NULL,
- showcolumn.width, showcolumn.height,
- showcolumn.mono_bits, showcolumn.color_bits,
- showcolumn.mask_bits, FALSE);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &showColumnInsensIcon,
- NULL,
- showcolumn_i.width, showcolumn_i.height,
- showcolumn_i.mono_bits, showcolumn_i.color_bits,
- showcolumn_i.mask_bits, FALSE);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &hideColumnIcon,
- NULL,
- hidecolumn.width, hidecolumn.height,
- hidecolumn.mono_bits, hidecolumn.color_bits,
- hidecolumn.mask_bits, FALSE);
-
- fe_NewMakeIcon(m_toplevel->getBaseWidget(),
- toplevel_component->getFGPixel(),
- bg_pixel,
- &hideColumnInsensIcon,
- NULL,
- hidecolumn_i.width, hidecolumn_i.height,
- hidecolumn_i.mono_bits, hidecolumn_i.color_bits,
- hidecolumn_i.mask_bits, FALSE);
- }
- }
-
- XFE_Outliner::XFE_Outliner()
- {
- m_selBlocked = False;
- m_outlinable = NULL;
- }
-
- XFE_Outliner::~XFE_Outliner()
- {
- D(printf ("In XFE_Outliner::~XFE_Outliner()\n");)
- FREEIF(m_columnwidths);
- FREEIF(m_columnIndex);
- FREEIF(m_columnResizable);
- FREEIF(m_prefname);
- FREEIF(m_selectedItems);
- FREEIF(m_geominfo);
- //
- XP_FREEIF(m_doc_msg_buf);
- XP_FREEIF(m_tip_msg_buf);
-
- // if our outlinable still has line data allocated,
- // tell it to release it.
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- #if defined(USE_MOTIF_DND)
- if (m_outlinerdrop)
- delete m_outlinerdrop;
- #endif /* USE_MOTIF_DND */
- }
-
- void
- XFE_Outliner::setPipeColumn(int column)
- {
- XP_ASSERT(column >= 0 && column < m_numcolumns);
-
- m_pipeColumn = column;
- }
-
- int
- XFE_Outliner::getPipeColumn()
- {
- return m_pipeColumn;
- }
-
- void
- XFE_Outliner::setSortColumn(int column, EOutlinerSortDirection direction)
- {
- XP_ASSERT(column >= -1 && column < m_numcolumns);
-
- m_sortColumn = column;
- m_sortDirection = direction;
- }
-
- int
- XFE_Outliner::getSortColumn()
- {
- return m_sortColumn;
- }
-
- void
- XFE_Outliner::toggleSortDirection()
- {
- if (m_sortDirection == OUTLINER_SortAscending)
- m_sortDirection = OUTLINER_SortDescending;
- else
- m_sortDirection = OUTLINER_SortAscending;
- }
-
- EOutlinerSortDirection
- XFE_Outliner::getSortDirection()
- {
- return m_sortDirection;
- }
-
- void
- XFE_Outliner::setColumnResizable(int column,
- XP_Bool resizable)
- {
- XP_ASSERT(column >= 0 && column < m_numcolumns);
- int column_index;
-
- for (column_index = 0; column_index < m_numcolumns; column_index ++)
- if (m_columnIndex[ column_index ] == column)
- break;
-
- setColumnResizableByIndex(column_index, resizable);
- }
-
- XP_Bool
- XFE_Outliner::getColumnResizable(int column)
- {
- XP_ASSERT(column >= 0 && column < m_numcolumns);
- int column_index;
-
- for (column_index = 0; column_index < m_numcolumns; column_index ++)
- if (m_columnIndex[ column_index ] == column)
- break;
-
- return getColumnResizableByIndex(column_index);
- }
-
- void
- XFE_Outliner::setColumnWidth(int column,
- int width)
- {
- XP_ASSERT(column >= 0 && column < m_numcolumns);
- int column_index;
-
- for (column_index = 0; column_index < m_numcolumns; column_index ++)
- if (m_columnIndex[ column_index ] == column)
- break;
-
- setColumnWidthByIndex(column_index, width);
- }
-
- int
- XFE_Outliner::getColumnWidth(int column)
- {
- XP_ASSERT(column >= 0 && column < m_numcolumns);
- int column_index;
-
- for (column_index = 0; column_index < m_numcolumns; column_index ++)
- if (m_columnIndex[ column_index ] == column)
- break;
-
- return getColumnWidthByIndex(column_index);
- }
-
-
- // Return the number of visible rows in the grid, including header rows.
- int XFE_Outliner::getNumContextAndHeaderRows()
- {
- XP_ASSERT(m_widget != 0);
-
- int numContentRows = 0;
- int numHeadingRows = 0;
- XtVaGetValues(m_widget,
- XmNrows, &numContentRows,
- XmNheadingRows, &numHeadingRows,
- 0);
-
- return numContentRows + numHeadingRows;
- }
-
-
- /*
- ** Resize the grid to show all rows, but enforce a
- ** minimum and maximum number of rows.
- */
- void XFE_Outliner::showAllRowsWithRange(int minRows, int maxRows)
- {
- XP_ASSERT(m_widget != 0);
-
- int numRows = this->getNumContextAndHeaderRows();
- if((numRows > minRows)&&(numRows < maxRows)) {
- // We are within the range, show them all.
- XtVaSetValues(m_widget,
- XmNvisibleRows, numRows,
- 0);
- } else if(numRows >= maxRows) {
- // Maximum number of rows.
- XtVaSetValues(m_widget,
- XmNvisibleRows, maxRows,
- 0);
- } else if(numRows <= minRows) {
- // Minimum number of rows.
- XtVaSetValues(m_widget,
- XmNvisibleRows, minRows,
- 0);
- } else {
- XP_ASSERT(0);
- }
- }
-
- void
- XFE_Outliner::setBlockSel(XP_Bool b)
- {
- m_selBlocked = b;
- }
-
- void
- XFE_Outliner::scroll2Item(int index)
- {
- if (index >=0 && index < m_totalLines) {
- selectItemExclusive(index);
- makeVisible(index);
- }/* if */
- else
- deselectAllItems();
- }
-
- void
- XFE_Outliner::setMultiSelectAllowed(Boolean flag)
- {
- XP_ASSERT(m_widget != 0);
-
- if (flag)
- {
- XtVaSetValues(m_widget,
- XmNselectionPolicy, XmSELECT_MULTIPLE_ROW,
- 0);
- }
- else
- {
- XtVaSetValues(m_widget,
- XmNselectionPolicy, XmSELECT_BROWSE_ROW,
- 0);
- }
- }
-
- Boolean
- XFE_Outliner::getMultiSelectAllowed()
- {
- unsigned char selectionPolicy;
-
- XP_ASSERT(m_widget != 0);
-
- XtVaGetValues(m_widget,
- XmNselectionPolicy, &selectionPolicy,
- NULL);
-
- return (selectionPolicy == XmSELECT_MULTIPLE_ROW);
- }
-
- void
- XFE_Outliner::setDescendantSelectAllowed(XP_Bool flag)
- {
- m_descendantSelectAllowed = flag;
- }
-
- XP_Bool
- XFE_Outliner::getDescendantSelectAllowed()
- {
- return m_descendantSelectAllowed;
- }
-
- void
- XFE_Outliner::setHideColumnsAllowed(XP_Bool flag)
- {
- if (m_hideColumnsAllowed != flag)
- {
- if (flag)
- {
- // show the hide/show buttons.
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, True,
- NULL);
-
- applyDelta(-1 * (12 + 12));
-
- XmLGridAddColumns(m_widget,XmCONTENT, m_numvisible, 2);
-
- XtVaSetValues(m_widget,
- XmNcolumn, m_numvisible,
- XmNcolumnWidth, 12, //XX magic number alert !!!
- XmNcolumnSizePolicy, XmCONSTANT,
- XmNcolumnResizable, False, // can't resize the show/hide columns.
- NULL);
-
- XtVaSetValues(m_widget,
- XmNcolumn, m_numvisible + 1,
- XmNcolumnWidth, 12, //XX magic number alert !!!
- XmNcolumnSizePolicy, XmCONSTANT,
- XmNcolumnResizable, False, // can't resize the show/hide columns.
- NULL);
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, False,
- NULL);
- }
- else
- {
- // remove the hide/show buttons.
- XmLGridDeleteColumns(m_widget, XmCONTENT, m_numvisible, 2);
-
- applyDelta(12 + 12);
-
- }
-
- m_hideColumnsAllowed = flag;
- }
- }
-
- XP_Bool
- XFE_Outliner::getHideColumnsAllowed()
- {
- return m_hideColumnsAllowed;
- }
-
- #if !defined(USE_MOTIF_DND)
- void
- XFE_Outliner::setDragType(fe_dnd_Type dragtype, fe_icon *dragicon,
- XFE_Component *drag_source, fe_dnd_SourceDropFunc sourcedropfunc)
- {
- m_dragtype = dragtype;
- m_dragicon = dragicon;
- m_source = drag_source;
- m_sourcedropfunc = sourcedropfunc;
- }
-
- fe_dnd_Type
- XFE_Outliner::getDragType()
- {
- return m_dragtype;
- }
-
- fe_icon *
- XFE_Outliner::getDragIcon()
- {
- return m_dragicon;
- }
-
- fe_dnd_SourceDropFunc
- XFE_Outliner::getSourceDropFunc()
- {
- return m_sourcedropfunc;
- }
-
- #else
- void
- XFE_Outliner::enableDragDrop(void *this_ptr,
- FEGetDropTargetFunc drop_target_func,
- FEGetDragTargetFunc drag_target_func,
- FEGetDragIconDataFunc drag_icon_func,
- FEConvertDragDataFunc drag_conv_func,
- FEProcessTargetsFunc process_targets_func)
- {
- m_dragsource = this_ptr;
- m_dropTargetFunc = drop_target_func;
- m_dragTargetFunc = drag_target_func;
- m_dragIconDataFunc = drag_icon_func;
- m_dragConvFunc = drag_conv_func;
- m_processTargetsFunc = process_targets_func;
-
- if (!m_outlinerdrag)
- m_outlinerdrag = new XFE_OutlinerDrag(m_widget, this);
-
- /* update the dropsite's idea of its targets. */
- m_outlinerdrop->update();
- }
-
-
- void
- XFE_Outliner::getDropTargets(Atom **targets,
- int *numtargets)
- {
- if (m_dropTargetFunc == NULL)
- {
- *targets = NULL;
- *numtargets = 0;
- }
- else
- {
- (*m_dropTargetFunc)(m_outlinable, targets, numtargets);
- }
- }
-
- void
- XFE_Outliner::getDragTargets(int row, int column,
- Atom **targets,
- int *numtargets)
- {
- if (m_dragTargetFunc == NULL)
- {
- *targets = NULL;
- *numtargets = 0;
- }
- else
- {
- (*m_dragTargetFunc)(m_dragsource, row, column, targets, numtargets);
- }
- }
-
- fe_icon_data *
- XFE_Outliner::getDragIconData(int row, int column)
- {
- if (m_dragIconDataFunc == NULL)
- return NULL;
- else
- return (*m_dragIconDataFunc)(m_dragsource, row, column);
- }
-
- char *
- XFE_Outliner::dragConvert(Atom atom)
- {
- if (m_dragConvFunc == NULL)
- return NULL;
- else
- return (*m_dragConvFunc)(m_dragsource, atom);
- }
-
-
- int
- XFE_Outliner::processTargets(int row, int col,
- Atom *targets,
- const char **data,
- int numItems)
- {
- if (m_processTargetsFunc == NULL)
- return FALSE;
- else
- return (*m_processTargetsFunc)(m_dragsource, row, col,
- targets, data, numItems);
- }
- #endif /* USE_MOTIF_DND */
-
- XP_Bool
- XFE_Outliner::setDefaultGeometry()
- {
- int i;
- char* ptr;
- char* ptr2;
- char* ptr3;
- int value;
- int width;
- int height = 0;
-
- for (i = 0; i < m_numcolumns; i ++)
- m_columnIndex[i] = i;
-
- ptr = m_geominfo;
-
- // first parse the height of the outliner in pixel
- if (ptr != NULL)
- {
- ptr2 = XP_STRCHR(ptr, 'x');
- if (ptr2) *ptr2 = '\0';
- height = atoi(ptr);
-
- if (height > 0 && height < MAX_COLUMN_WIDTH)
- {
- *ptr2 = 'x';
-
- ptr = ptr2 + 1;
- }
- else
- {
- FREEIF(m_geominfo);
- ptr = m_geominfo;
- }
-
- }
-
- // then parse the number of visible columns
- if (ptr != NULL)
- {
- ptr2 = XP_STRCHR(ptr, ')');
- if (ptr2) *ptr2 = '\0';
- ptr3 = XP_STRCHR(ptr, '(');
- if (ptr3)
- {
- m_numvisible = atoi(ptr3 + 1);
-
- if (m_numvisible <= 0 || m_numvisible > m_numcolumns)
- m_numvisible = m_numcolumns;
-
- *ptr3 = '(';
- *ptr2 = ')';
- ptr = ptr2 + 1;
- }
- else
- {
- FREEIF(m_geominfo);
- ptr = m_geominfo;
- }
- }
-
- for (i=0 ; i<m_numcolumns ; i++)
- {
- if (ptr == NULL)
- {
- FREEIF(m_geominfo);
- break;
- }
-
- ptr2 = XP_STRCHR(ptr, ';');
- if (ptr2) *ptr2 = '\0';
- ptr3 = XP_STRCHR(ptr, ':');
- if (!ptr3)
- {
- FREEIF(m_geominfo);
- break;
- }
- *ptr3 = '\0';
-
- for (value = 0 ; value < m_numcolumns ; value++)
- {
- if (m_outlinable->getColumnName(value) == NULL
- || strcmp(m_outlinable->getColumnName(value), ptr) == 0)
- break;
- }
-
- if (value >= m_numcolumns)
- {
- FREEIF(m_geominfo);
- break;
- }
-
- m_columnIndex[i] = value;
- width = atoi(ptr3 + 1);
- *ptr3 = ':';
-
- if (width < MIN_COLUMN_WIDTH) width = MIN_COLUMN_WIDTH;
- if (width > MAX_COLUMN_WIDTH) width = MAX_COLUMN_WIDTH;
-
- m_columnwidths[ i ] = width;
-
- if (ptr2) *ptr2++ = ';';
- ptr = ptr2;
- }
-
- if (m_geominfo)
- {
- /* Check that every column was mentioned, and no duplicates
- occurred. */
- int* check = (int*)XP_CALLOC(m_numcolumns, sizeof(int));
- for (i=0 ; i<m_numcolumns ; i++) check[i] = 0;
- for (i=0 ; i<m_numcolumns ; i++)
- {
- int w = m_columnIndex[i];
- if (w < 0 || w > m_numcolumns || check[w])
- {
- FREEIF(m_geominfo);
- break;
- }
- check[w] = 1;
- }
- XP_FREE(check);
- }
-
- if (m_geominfo != NULL)
- XtVaSetValues(m_widget,
- XmNheight, height,
- NULL);
-
- return (m_geominfo != NULL);
- }
-
- void
- XFE_Outliner::setInFocus(XP_Bool infocus)
- {
- Pixel bgColor, fgColor;
-
- XtVaGetValues(m_widget,
- XmNbackground, &bgColor,
- XmNforeground, &fgColor, 0);
- if ( infocus )
- XtVaSetValues(m_widget, XmNborderColor,
- fgColor, 0);
- else
- XtVaSetValues(m_widget, XmNborderColor,
- bgColor, 0);
-
- m_isFocus = infocus;
-
- }
-
- XP_Bool
- XFE_Outliner::isFocus()
- {
- return m_isFocus;
- }
-
- void
- XFE_Outliner::selectItem(int index)
- {
- XP_ASSERT(m_widget != 0);
-
- /*
- ** invalidate the line without calling invalidateLine, since
- ** that function calls XmLGridRedrawRow, and we're already
- ** going to redraw it with the selectrow call below.
- */
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = -1;
-
- XmLGridSelectRow(m_widget, index, False);
-
- addSelection(index);
- }
-
-
- void
- XFE_Outliner::selectItemExclusive(int index)
- {
- XP_ASSERT(m_widget != 0);
-
- deselectAllItems();
-
- selectItem(index);
- }
-
- void
- XFE_Outliner::deselectItem(int index)
- {
- XP_ASSERT(m_widget != 0);
-
- /*
- ** invalidate the line without calling invalidateLine, since
- ** that function calls XmLGridRedrawRow, and we're already
- ** going to redraw it with the selectrow call below.
- */
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = -1;
-
- XmLGridDeselectRow(m_widget, index, False);
-
- if (m_selectedCount)
- removeSelection(index);
- }
-
- void
- XFE_Outliner::toggleSelected(int index)
- {
- XP_ASSERT(m_widget != 0);
-
- if (isSelected(index))
- deselectItem(index);
- else
- selectItem(index);
- }
-
- /*
- ** Here, we either expand or contract the selected area by
- ** following rules.
- **
- ** 1) if new_index < first_index, select from new_index to last_index.
- ** 2) if new_index > last_index, select from first_index to new_index.
- ** 3) if new_index > first_index && new_index < last_index
- **
- ** 3a) if new_index > (last_index + first_index) / 2, select
- ** from new_index to last_index.
- ** 3b) if new_index < (last_index + first_index) / 2, select
- ** from first_index to new_index.
- **
- ** funkygroovycool
- */
- void
- XFE_Outliner::trimOrExpandSelection(int new_index)
- {
- // always do something reasonable...
- if (m_selectedCount == 0)
- selectItem(new_index);
- else
- {
- if (m_selectionDirection == -1)
- {
- if (new_index < m_lastSelectedIndex)
- {
- if (new_index < m_firstSelectedIndex)
- selectRangeByIndices(m_firstSelectedIndex, new_index);
- else if (new_index > m_firstSelectedIndex)
- deselectRangeByIndices(new_index - 1, m_firstSelectedIndex);
-
- /* don't need to do anything if
- new_index == m_firstSelectedIndex */
- }
- else
- {
- deselectRangeByIndices(m_lastSelectedIndex - 1, m_firstSelectedIndex);
- selectRangeByIndices(m_lastSelectedIndex, new_index);
- }
- }
- else
- {
- if (new_index > m_firstSelectedIndex)
- {
- if (new_index > m_lastSelectedIndex)
- selectRangeByIndices(m_lastSelectedIndex, new_index);
- else if (new_index < m_lastSelectedIndex)
- deselectRangeByIndices(new_index + 1, m_lastSelectedIndex);
-
- /* don't need to do anything if
- new_index == m_lastSelectedIndex */
- }
- else
- {
- deselectRangeByIndices(m_firstSelectedIndex + 1, m_lastSelectedIndex);
- selectRangeByIndices(m_firstSelectedIndex, new_index);
- }
- }
- }
-
- }
-
- void
- XFE_Outliner::selectAllItems()
- {
- XP_ASSERT(m_widget != 0);
-
- XmLGridSelectAllRows(m_widget, False);
-
- for (int i = 0; i < m_totalLines; i ++)
- {
- selectItem(i);
- }
-
- m_selectionDirection = 1;
- }
-
- void
- XFE_Outliner::deselectAllItems()
- {
- XP_ASSERT(m_widget != 0);
-
- XmLGridDeselectAllRows(m_widget, False);
-
- deselectAll();
- }
-
- void
- XFE_Outliner::makeVisible(int index)
- {
- int firstrow, lastrow;
- Dimension height, shadowthickness;
-
- if (index < 0)
- return;
-
- if (m_visibleTimer)
- {
- m_visibleLine = index;
- return;
- }
-
- XtVaGetValues(m_widget,
- XmNscrollRow, &firstrow,
- XmNheight, &height,
- XmNshadowThickness, &shadowthickness,
- NULL);
-
- height -= shadowthickness;
-
- for (lastrow = firstrow + 1 ; ; lastrow++)
- {
- XRectangle rect;
-
- if (XmLGridRowColumnToXY(m_widget,
- XmCONTENT, lastrow,
- XmCONTENT, 0,
- False, &rect) < 0)
- {
- break;
- }
- if (rect.y + rect.height >= height) break;
- }
-
- if (index >= firstrow && index < lastrow)
- return;
-
- firstrow = index - ((lastrow - firstrow) / 2);
-
- if (firstrow < 0)
- firstrow = 0;
-
- XtVaSetValues(m_widget,
- XmNscrollRow, firstrow,
- NULL);
- }
-
- void
- XFE_Outliner::invalidate()
- {
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = -1;
-
- XmLGridRedrawAll(m_widget);
- }
-
- void
- XFE_Outliner::invalidateLine(int line)
- {
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = -1;
-
- XmLGridRedrawRow(m_widget, XmCONTENT, line);
- }
-
- void
- XFE_Outliner::invalidateLines(int start, int count)
- {
- int i;
-
- for (i = start; i < start + count; i ++)
- invalidateLine(i);
- }
-
- void
- XFE_Outliner::invalidateHeaders()
- {
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = -1;
-
- XmLGridRedrawRow(m_widget, XmHEADING, 0);
- }
-
- int
- XFE_Outliner::numResizableVisibleColumns(int starting_at)
- {
- int i;
- int count = 0;
-
- for (i = starting_at; i < m_numvisible; i ++)
- {
- if (getColumnResizableByIndex(i))
- count ++;
- }
-
- return count;
- }
-
- /*
- ** applyDelta is one of the grossest functions ever, in my opinion.
- **
- ** The idea is that we give it a delta and a column to start applying it at,
- ** and it will start there and divide up the delta evenly (well, using
- ** percentages) across all the resizable columns from the given one to the
- ** right-most one. It will try to resize them all enough to get rid of the
- ** delta, but in the event that it can't distribute the delta entirely, it
- ** returns the amount left over. This is used by resize() method below to fix
- ** up the resized column.
- **
- ** That being said, the way things are done here is icky. We build up an
- ** array of delta_struct's, one for each resizable column we're going to be
- ** dealing with. Then we sort them so that lower indices have smaller widths.
- ** This is so that if we can't apply enough of the delta to a smaller width
- ** column, it'll get pushed off to the larger ones (well, the largest one --
- ** the last one in the array.) We make up for all the multiplicative errors
- ** -- and instances of not being able to fully apply a column delta with the
- ** last column in the array. Since it's the largest, we have the best chance
- ** of doing it there.
- */
- typedef struct delta_struct
- {
- int column_index;
- int column_width;
- } delta_struct;
-
- static int compare_deltas(const void *d1, const void *d2)
- {
- delta_struct *delta1 = (delta_struct *)d1;
- delta_struct *delta2 = (delta_struct *)d2;
-
- return delta1->column_width - delta2->column_width;
- }
-
- int
- XFE_Outliner::applyDelta(int delta, int starting_at)
- {
- int current_column;
- int num_resizable = numResizableVisibleColumns(starting_at);
- int total_resizable_column_width = 0;
- int delta_distributed = 0;
- delta_struct *deltas;
- int i;
-
- D(printf ("Applying a delta of %d from column %d to column %d\n",
- delta,
- starting_at,
- m_numvisible - 1);)
-
- if (num_resizable == 0)
- return delta;
-
- deltas = (delta_struct*)XP_CALLOC(num_resizable, sizeof(delta_struct));
- i = 0;
- for (current_column = starting_at; current_column < m_numvisible; current_column ++)
- if (getColumnResizableByIndex(current_column))
- {
- deltas[i].column_index = current_column;
- deltas[i].column_width = getColumnWidthByIndex(current_column);
- total_resizable_column_width += deltas[i].column_width;
- i++;
- }
-
- XP_ASSERT(total_resizable_column_width > 0);
- if (total_resizable_column_width <= 0)
- {
- XP_FREE(deltas);
- return delta;
- }
-
- XP_QSORT(deltas, num_resizable, sizeof(delta_struct), compare_deltas);
-
- current_column = starting_at;
-
- for (i = 0; i < num_resizable; i ++)
- {
- int orig_column_width = deltas[i].column_width;
- int column_width;
- int column_delta = delta * ((float)orig_column_width / total_resizable_column_width);
-
- D(printf ("Column %d (Before delta = %d). Percentage of delta applied = %f (%d pixels)\n",
- deltas[i].column_index,
- orig_column_width,
- (float)orig_column_width / total_resizable_column_width,
- column_delta);)
-
- if (i == num_resizable - 1)
- {
- /* make up for our cumulative errors with the last column */
- D(printf ("making up for the differences in column %d by adding %d to its width.\n",
- deltas[i].column_index, delta - delta_distributed);)
-
- column_delta += delta - delta_distributed - column_delta;
- }
-
- column_width = orig_column_width + column_delta;
-
- if (column_width < MIN_COLUMN_WIDTH)
- {
- column_width = MIN_COLUMN_WIDTH;
-
- column_delta = column_width - orig_column_width;
- }
- else if (column_width > MAX_COLUMN_WIDTH)
- {
- column_width = MAX_COLUMN_WIDTH;
-
- column_delta = column_width - orig_column_width;
- }
-
- delta_distributed += column_delta;
-
- D(printf ("After delta = %d\n", column_width);)
- setColumnWidthByIndex(deltas[i].column_index, column_width);
- #if defined(DEBUG_tao_)
- printf("\n>>XFE_Outliner::applyDelta:setColumnWidthByIndex(i=%d, ind=%d, wid=%d)",
- i, deltas[i].column_index, column_width);
- #endif
- }
-
- XP_FREE(deltas);
- return delta - delta_distributed;
- }
-
- void
- XFE_Outliner::hideColumn()
- {
- Dimension width;
-
- m_numvisible --;
-
- XP_ASSERT(m_numvisible > 0);
- width = getColumnWidthByIndex(m_numvisible);
-
- D(printf ("I'm hiding a column of width %d\n", width);)
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, True,
- NULL);
-
- XmLGridDeleteColumns(m_widget, XmCONTENT, m_numvisible, 1);
-
- applyDelta(width);
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, False,
- NULL);
-
- rememberGeometry();
- }
-
- void
- XFE_Outliner::showColumn()
- {
- int width;
-
- XP_ASSERT(m_numvisible < m_numcolumns);
-
- width = getColumnWidthByIndex( m_numvisible );
-
- D(printf ("I'm showing a column of width %d\n", width);)
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, True,
- NULL);
-
- if (m_resizeColumn != -1 && m_columnIndex [ m_resizeColumn ] < m_numvisible)
- {
- Dimension column_width;
-
- column_width = getColumnWidthByIndex(m_columnIndex[ m_resizeColumn] );
-
- setColumnWidthByIndex(m_columnIndex[ m_resizeColumn ],
- column_width - width);
- }
- else
- {
- applyDelta(-1 * width);
- }
-
- XmLGridRow rowp;
- XmLGridColumn colp;
-
- rowp = XmLGridGetRow(m_widget, XmHEADING, 0);
- colp = XmLGridGetColumn(m_widget, XmCONTENT, m_numvisible);
-
- Pixel row_cell_bg;
-
- XtVaGetValues(m_widget,
- XmNrowPtr, rowp,
- XmNcolumnPtr, colp,
- XmNcellBackground, &row_cell_bg,
- NULL);
-
- XmLGridAddColumns(m_widget, XmCONTENT, m_numvisible, 1);
-
- XtVaSetValues(m_widget,
- XmNcolumn, m_numvisible,
- XmNcolumnSizePolicy, XmCONSTANT,
- XmNcolumnWidth, width,
- XmNcolumnResizable, m_columnResizable[ m_numvisible ],
- NULL);
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, False,
- NULL);
-
- XtVaSetValues(m_widget,
- XmNrowType, XmHEADING,
- XmNcellBackground, row_cell_bg,
- NULL);
-
- m_numvisible ++;
-
- rememberGeometry();
- }
-
- void
- XFE_Outliner::moveColumn(int column_to_move,
- int destination)
- {
- int delta;
- int tmp;
- int tmp_width;
- XP_Bool tmp_resizable;
- int i;
-
- if (column_to_move < destination)
- delta = 1;
- else
- delta = -1;
-
- /* save off all information about the column number we're moving */
- tmp = m_columnIndex[ column_to_move ];
- tmp_width = m_columnwidths[ column_to_move ];
- tmp_resizable = m_columnResizable[ column_to_move ];
-
- /* move all the other columns out of the way. */
- for (i = column_to_move; i != destination; i += delta)
- {
- m_columnIndex[ i ] = m_columnIndex[ i + delta ];
- m_columnwidths[ i ] = m_columnwidths[ i + delta ];
- m_columnResizable[ i ] = m_columnResizable[ i + delta ];
- }
-
- /* replace the column we moved in the place we moved it to */
- m_columnIndex[ destination ] = tmp;
- m_columnwidths[ destination ] = tmp_width;
- m_columnResizable[ destination ] = tmp_resizable;
-
- XmLGridMoveColumns(m_widget, destination, column_to_move, 1);
-
- rememberGeometry();
- }
-
- int
- XFE_Outliner::getSelection(const int **indices, int *count)
- {
- if (indices)
- *indices = m_selectedIndices;
-
- if (count)
- *count = m_selectedCount;
-
- return m_selectedCount;
- }
-
- int
- XFE_Outliner::getTotalLines()
- {
- return m_totalLines;
- }
-
- int
- XFE_Outliner::XYToRow(int x, int y, XP_Bool *nearbottom)
- {
- int row;
- int column;
- unsigned char rowtype;
- unsigned char coltype;
-
- if (x < 0 || y < 0 ||
- x >= _XfeWidth(m_widget) || y >= _XfeHeight(m_widget))
- {
- return -1;
- }
-
- if (XmLGridXYToRowColumn(m_widget, x, y, &rowtype, &row,
- &coltype, &column) < 0) {
- return -1;
- }
-
- if (rowtype != XmCONTENT || coltype != XmCONTENT)
- return -1;
-
- if (nearbottom) {
- int row2;
- *nearbottom = (XmLGridXYToRowColumn(m_widget, x, y + 5,
- &rowtype, &row2,
- &coltype, &column) >= 0 &&
- row2 > row);
- }
- return row;
- }
-
- void
- XFE_Outliner::addSelection(int selected)
- {
- int i;
-
- // if it's already selected, just return.
- for (i = 0; i < m_selectedCount; i ++)
- {
- if ( m_selectedIndices [ i ] == selected )
- {
- return;
- }
- }
-
- if (i >= m_selectedSize)
- {
- // Resize storage array (exponential growth)
- int *tmp = new int [ m_selectedSize * 2 ];
- memcpy (tmp, m_selectedIndices, m_selectedSize * sizeof(int));
- delete [] m_selectedIndices;
- m_selectedIndices = tmp;
- m_selectedSize *= 2;
- }
-
- m_selectedIndices [ i ] = selected;
- m_selectedCount ++;
-
- if (selected > m_lastSelectedIndex)
- m_lastSelectedIndex = selected;
- if (selected < m_firstSelectedIndex)
- m_firstSelectedIndex = selected;
-
- D(printf ("m_firstSelectedIndex = %d\n", m_firstSelectedIndex);)
- D(printf ("m_lastSelectedIndex = %d\n", m_lastSelectedIndex);)
-
- invalidateLine( selected );
- }
-
- void
- XFE_Outliner::removeSelection(int selected)
- {
- int i, j;
-
- for (i = 0, j = 0; i < m_selectedCount; i ++)
- {
- if (m_selectedIndices [ i ] == selected)
- {
- invalidateLine( selected );
- }
- else
- {
- m_selectedIndices [ j ] = m_selectedIndices [ i ];
- j ++;
- }
- }
-
- m_selectedCount = j;
-
- m_firstSelectedIndex = (unsigned int)(1 << 31) - 1;
- m_lastSelectedIndex = -1;
-
- for (j = 0; j < m_selectedCount; j ++)
- {
- if (m_selectedIndices [ j ] > m_lastSelectedIndex)
- m_lastSelectedIndex = m_selectedIndices [ j ];
- if (m_selectedIndices [ j ] < m_firstSelectedIndex)
- m_firstSelectedIndex = m_selectedIndices [ j ];
- }
-
- D(printf ("m_firstSelectedIndex = %d\n", m_firstSelectedIndex);)
- D(printf ("m_lastSelectedIndex = %d\n", m_lastSelectedIndex);)
- }
-
- void
- XFE_Outliner::deselectAll()
- {
- m_selectedCount = 0;
- m_firstSelectedIndex = (unsigned int)(1 << 31) - 1;
- m_lastSelectedIndex = -1;
- m_selectionDirection = 1;
- }
-
- void
- XFE_Outliner::deselectRangeByIndices(int selection_begin,
- int selection_end)
- {
- int i;
-
- if (selection_begin > selection_end)
- {
- int tmp;
- tmp = selection_end;
- selection_end = selection_begin;
- selection_begin = tmp;
- }
-
- for (i = selection_begin; i <= selection_end; i ++)
- {
- deselectItem(i);
- }
- }
-
- Boolean
- XFE_Outliner::isSelected (int line)
- {
- int i;
-
- for (i = 0; i < m_selectedCount; i ++)
- {
- if ( m_selectedIndices[ i ] == line)
- {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- void
- XFE_Outliner::selectRangeByIndices(int selection_begin, int selection_end)
- {
- int i;
-
- /*
- ** we need to keep track of the direction the user last selected in
- ** whether the first selected item was below or above the newest
- ** selected item.) This comes in handy in the trimOrExpandSelection
- ** routine where we need to know which range to deselect.
- */
- m_selectionDirection = XfeSgn(selection_end - selection_begin);
-
- if (selection_begin > selection_end)
- {
- int tmp;
- tmp = selection_end;
- selection_end = selection_begin;
- selection_begin = tmp;
- }
-
- for (i = selection_begin; i <= selection_end; i ++)
- {
- selectItem(i);
- }
- }
-
- Boolean
- XFE_Outliner::insertLines(int start, int count)
- {
- int i;
- XP_Bool firstSelectedDone = False;
- XP_Bool lastSelectedDone = False;
-
- // shift down the selected items (if they're after the start)
- for (i = 0; i < m_selectedCount; i ++)
- {
- if (m_selectedIndices[ i ] >= start)
- {
- if (!firstSelectedDone &&
- m_selectedIndices[ i ] == m_firstSelectedIndex)
- {
- m_firstSelectedIndex += count;
- firstSelectedDone = True;
- }
-
- if (!lastSelectedDone &&
- m_selectedIndices[ i ] == m_lastSelectedIndex)
- {
- m_lastSelectedIndex += count;
- lastSelectedDone = True;
- }
-
- m_selectedIndices[ i ] += count;
- }
- }
-
- // now invalidate the new lines so they get drawn
- invalidateLines(start, m_totalLines - start + count);
-
- return FALSE;
- }
-
- Boolean
- XFE_Outliner::deleteLines(int start, int count)
- {
- Boolean res = FALSE;
- int i, j;
- XP_Bool firstSelectedDone = False;
- XP_Bool lastSelectedDone = False;
-
-
- for (i = 0, j = 0; i < m_selectedCount; i++)
- {
- if ( m_selectedIndices[i] >= start )
- {
- if (m_selectedIndices[i] < (start + count))
- {
- res = TRUE;
- continue;
- }
- else
- {
- if (!firstSelectedDone &&
- m_selectedIndices[ i ] == m_firstSelectedIndex)
- {
- m_firstSelectedIndex -= count;
- firstSelectedDone = True;
- }
-
- if (!lastSelectedDone &&
- m_selectedIndices[ i ] == m_lastSelectedIndex)
- {
- m_lastSelectedIndex -= count;
- lastSelectedDone = True;
- }
-
- m_selectedIndices[i] -= count; // Shift into gap
- }
- }
- m_selectedIndices[j] = m_selectedIndices[i];
- j++;
- }
-
- invalidateLines(start, m_totalLines - start + count);
-
- return FALSE;
- }
-
- void
- XFE_Outliner::setColumnResizableByIndex(int column_index,
- XP_Bool resizable)
- {
- if (column_index < m_numvisible)
- {
- XtVaSetValues(m_widget,
- XmNcolumn, column_index,
- XmNcolumnResizable, resizable,
- NULL);
- }
-
- m_columnResizable[ column_index ] = resizable;
- }
-
- XP_Bool
- XFE_Outliner::getColumnResizableByIndex(int column_index)
- {
- return m_columnResizable[ column_index ];
- }
-
- void
- XFE_Outliner::setColumnWidthByIndex(int column_index, int width)
- {
- // clamp the width to within acceptable limits.
- if (width < MIN_COLUMN_WIDTH)
- width = MIN_COLUMN_WIDTH;
- else if (width > MAX_COLUMN_WIDTH)
- width = MAX_COLUMN_WIDTH;
-
- if (column_index < m_numvisible)
- {
- XtVaSetValues(m_widget,
- XmNcolumn, column_index,
- XmNcolumnSizePolicy, XmCONSTANT,
- XmNcolumnWidth, width,
- NULL);
- }
-
- m_columnwidths[ column_index ] = width;
- }
-
- int
- XFE_Outliner::getColumnWidthByIndex(int column_index)
- {
- return m_columnwidths[ column_index ];
- }
-
- void
- XFE_Outliner::rememberGeometry()
- {
- int i;
- char *ptr;
- int length;
- Dimension height;
-
- FREEIF(m_geominfo);
-
- length = m_numcolumns * 25 + 40; /* ### got a better size in mind? */
-
- XtVaGetValues(m_widget,
- XmNheight, &height,
- NULL);
-
- m_geominfo = (char*)XP_ALLOC(length);
- ptr = m_geominfo;
-
- PR_snprintf(ptr, m_geominfo + length - ptr,
- "%dx(%d)", height, m_numvisible);
- ptr += strlen(ptr);
-
- for (i = 0; i < m_numcolumns; i ++)
- {
- PR_snprintf(ptr, m_geominfo + length - ptr,
- "%s:%d;",
- m_outlinable->getColumnName(m_columnIndex[i]),
- getColumnWidthByIndex(i));
-
- ptr += strlen(ptr);
- }
-
- if (ptr > m_geominfo) *ptr = '\0';
-
- if (m_prefname)
- {
- D(printf ("PREF[%s] = %s\n", m_prefname, m_geominfo);)
- PREF_SetCharPref(m_prefname, m_geominfo);
- }
-
- FREEIF(m_geominfo);
- }
-
- void
- XFE_Outliner::PixmapDraw(Pixmap pixmap, Pixmap mask,
- int pixmapWidth, int pixmapHeight, unsigned char alignment, GC gc,
- XRectangle *rect, XRectangle *clipRect, Pixel bg_pixel)
- {
- Display *dpy;
- Window win;
- int needsClip;
- int x, y, width, height;
-
- XP_ASSERT(pixmap != (Pixmap)0);
-
- if (pixmap == XmUNSPECIFIED_PIXMAP) return;
- if (rect->width <= 4 || rect->height <= 4) return;
- if (clipRect->width < 3 || clipRect->height < 3) return;
- if (!XtIsRealized(m_widget)) return;
- dpy = XtDisplay(m_widget);
- win = XtWindow(m_widget);
-
- width = pixmapWidth;
- height = pixmapHeight;
- if (!width || !height) {
- alignment = XmALIGNMENT_TOP_LEFT;
- width = clipRect->width - 4;
- height = clipRect->height - 4;
- }
-
- if (alignment == XmNONE)
- {
- x = rect->x;
- }
- else if (alignment == XmALIGNMENT_TOP_LEFT ||
- alignment == XmALIGNMENT_LEFT ||
- alignment == XmALIGNMENT_BOTTOM_LEFT)
- {
- x = rect->x + 2;
- }
- else if (alignment == XmALIGNMENT_TOP ||
- alignment == XmALIGNMENT_CENTER ||
- alignment == XmALIGNMENT_BOTTOM)
- {
- x = rect->x + ((int)rect->width - width) / 2;
- }
- else
- {
- x = rect->x + rect->width - width - 2;
- }
-
- if (alignment == XmNONE)
- {
- y = rect->y;
- }
- if (alignment == XmALIGNMENT_TOP ||
- alignment == XmALIGNMENT_TOP_LEFT ||
- alignment == XmALIGNMENT_TOP_RIGHT)
- {
- y = rect->y + 2;
- }
- else if (alignment == XmALIGNMENT_LEFT ||
- alignment == XmALIGNMENT_CENTER ||
- alignment == XmALIGNMENT_RIGHT)
- {
- y = rect->y + ((int)rect->height - height) / 2;
- }
- else
- {
- y = rect->y + rect->height - height - 2;
- }
-
- needsClip = 1;
- if (clipRect->x <= x &&
- clipRect->y <= y &&
- clipRect->x + clipRect->width >= x + width &&
- clipRect->y + clipRect->height >= y + height) {
- needsClip = 0;
- }
-
- if (needsClip)
- {
- Pixmap tmp_pixmap;
- GC tmp_gc;
- XWindowAttributes attr;
-
- XGetWindowAttributes(dpy, win, &attr);
- tmp_pixmap = XCreatePixmap(dpy, win, clipRect->width, clipRect->height, attr.depth);
- tmp_gc = XCreateGC(dpy, tmp_pixmap, 0, NULL);
-
- XSetForeground(dpy, tmp_gc, bg_pixel);
-
- XFillRectangle(dpy, tmp_pixmap, tmp_gc, 0, 0, clipRect->width + 1, clipRect->height + 1);
-
- if (mask)
- {
- XSetClipMask(dpy, tmp_gc, mask);
- XSetClipOrigin(dpy, tmp_gc, 0, 0);
- }
-
- XCopyArea(dpy, pixmap, tmp_pixmap, tmp_gc, 0, 0, width, height, 0, 0);
-
- XFreeGC(dpy, tmp_gc);
-
- XSetClipRectangles(dpy, gc, 0, 0, clipRect, 1, Unsorted);
-
- XSetGraphicsExposures(dpy, gc, False);
- XCopyArea(dpy, tmp_pixmap, win, gc, 0, 0, width, height, x, y);
- XSetGraphicsExposures(dpy, gc, True);
-
- XSetClipMask(dpy, gc, None);
-
- XFreePixmap(dpy, tmp_pixmap);
- }
- else
- {
- if (mask)
- {
- XSetClipMask(dpy, gc, mask);
- XSetClipOrigin(dpy, gc, x, y);
- }
- XSetGraphicsExposures(dpy, gc, False);
- XCopyArea(dpy, pixmap, win, gc, 0, 0, width, height, x, y);
- XSetGraphicsExposures(dpy, gc, True);
-
- if (mask)
- {
- XSetClipMask(dpy, gc, None);
- }
- }
- }
-
- EOutlinerPipeType
- XFE_Outliner::getPipeType(XP_Bool expandable,
- XP_Bool expanded,
- int depth,
- OutlinerAncestorInfo *ancestorInfo)
- {
- if (expandable)
- {
- if (ancestorInfo->has_prev && ancestorInfo->has_next)
- return (expanded ? PIPE_OPENMIDDLEPARENT : PIPE_CLOSEDMIDDLEPARENT);
- else if (ancestorInfo->has_prev)
- return (expanded ? PIPE_OPENBOTTOMPARENT : PIPE_CLOSEDBOTTOMPARENT);
- else if (ancestorInfo->has_next && depth)
- return (expanded ? PIPE_OPENMIDDLEPARENT : PIPE_CLOSEDMIDDLEPARENT);
- else if (ancestorInfo->has_next)
- return (expanded ? PIPE_OPENTOPPARENT : PIPE_CLOSEDTOPPARENT);
- else if (depth)
- return (expanded ? PIPE_OPENBOTTOMPARENT : PIPE_CLOSEDBOTTOMPARENT);
- else
- return (expanded ? PIPE_OPENSINGLEPARENT : PIPE_CLOSEDSINGLEPARENT);
- }
- else /* !expandable */
- {
- if (ancestorInfo->has_prev && ancestorInfo->has_next)
- return PIPE_MIDDLEITEM;
- else if (ancestorInfo->has_prev)
- return PIPE_BOTTOMITEM;
- else if (ancestorInfo->has_next && depth)
- return PIPE_MIDDLEITEM;
- else if (ancestorInfo->has_next)
- return PIPE_TOPITEM;
- else if (depth)
- return PIPE_BOTTOMITEM;
- }
-
- return PIPE_EMPTYITEM;
- }
-
- void
- XFE_Outliner::drawDottedLine(GC gc,
- XRectangle *clipRect,
- int x1,
- int y1,
- int x2,
- int y2)
- {
- int i, x, y;
- XPoint points[100];
-
- i = 0;
- for (x = x1; x <= x2; x++)
- for (y = y1; y <= y2; y++)
- {
- if (((x & 1) == (y & 1)) ||
- x < clipRect->x ||
- x >= (clipRect->x + (int)clipRect->width) ||
- y < clipRect->y ||
- y >= (clipRect->y + (int)clipRect->height))
- continue;
- points[i].x = x;
- points[i].y = y;
- if (++i < 100)
- continue;
- XDrawPoints(XtDisplay(m_widget), XtWindow(m_widget), gc, points, i, CoordModeOrigin);
- i = 0;
- }
- if (i)
- XDrawPoints(XtDisplay(m_widget), XtWindow(m_widget), gc, points, i, CoordModeOrigin);
- }
-
- void
- XFE_Outliner::pipeDraw(XmLGridCallbackStruct *call)
- {
- /*
- ** we draw the pipes necessary for this line, and adjust the
- ** rectangles within the callback struct to reflect the new,
- ** probably smaller, area.
- */
- XmLGridDrawStruct *draw = call->drawInfo;
- Boolean drawSelected = draw->drawSelected;
- OutlinerAncestorInfo * ancestorInfo;
- int depth;
- int i;
- int maxX = draw->cellRect->width;
- XP_Bool expanded, expandable;
-
- m_outlinable->getTreeInfo(&expandable, &expanded, &depth, &ancestorInfo);
-
- XSetForeground(XtDisplay(m_widget), draw->gc, draw->foreground);
-
- /* save space to draw the descendantselect stuff. */
- if (m_descendantSelectAllowed)
- {
- draw->cellRect->x += PIPEIMAGESIZE; // XXX
- draw->cellRect->width -= PIPEIMAGESIZE;
- }
-
- for (i = 0; i < depth; i ++)
- if ( ( i + 1 ) * PIPEIMAGESIZE <= maxX )
- if (ancestorInfo && ancestorInfo[ i ].has_next)
- {
- // the the vertical pipe for this line's ancestors.
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y + draw->cellRect->height);
-
- draw->cellRect->x += PIPEIMAGESIZE;
- draw->cellRect->width -= PIPEIMAGESIZE;
- }
- else
- {
- // don't know about this block.. must ask will.
- draw->cellRect->x += PIPEIMAGESIZE;
- draw->cellRect->width -= PIPEIMAGESIZE;
- }
-
- if (ancestorInfo)
- {
- fe_icon *parent_icon;
- fe_icon *spool_icon = NULL;
- EOutlinerPipeType pipeType = getPipeType(expandable, expanded, depth, &ancestorInfo[depth]);
-
- if (m_descendantSelectAllowed && depth == 0 /*&& expandable*/)
- spool_icon = m_outlinable->getColumnIcon(-1 /* special super secret column */);
-
- // draw the pipe specific to this line
-
- switch (pipeType)
- {
- case PIPE_OPENTOPPARENT:
- case PIPE_OPENMIDDLEPARENT:
- case PIPE_OPENSINGLEPARENT:
- case PIPE_OPENBOTTOMPARENT:
- parent_icon = &openParentIcon;
- break;
- case PIPE_CLOSEDTOPPARENT:
- case PIPE_CLOSEDMIDDLEPARENT:
- case PIPE_CLOSEDSINGLEPARENT:
- case PIPE_CLOSEDBOTTOMPARENT:
- parent_icon = &closedParentIcon;
- break;
- default:
- parent_icon = 0;
- }
-
- if (pipeType == PIPE_CLOSEDSINGLEPARENT
- || pipeType == PIPE_OPENSINGLEPARENT)
- {
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2,
- draw->cellRect->y + draw->cellRect->height/2,
- draw->cellRect->x + PIPEIMAGESIZE - 2,
- draw->cellRect->y + draw->cellRect->height/2);
- }
-
- if (pipeType == PIPE_TOPITEM
- || pipeType == PIPE_OPENTOPPARENT
- || pipeType == PIPE_CLOSEDTOPPARENT)
- {
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y + draw->cellRect->height/2,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y + draw->cellRect->height);
-
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2,
- draw->cellRect->y + draw->cellRect->height/2,
- draw->cellRect->x + PIPEIMAGESIZE - 2,
- draw->cellRect->y + draw->cellRect->height/2);
-
- }
- else if (pipeType == PIPE_BOTTOMITEM
- || pipeType == PIPE_OPENBOTTOMPARENT
- || pipeType == PIPE_CLOSEDBOTTOMPARENT)
- {
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y + draw->cellRect->height/2);
-
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2,
- draw->cellRect->y + draw->cellRect->height/2,
- draw->cellRect->x + PIPEIMAGESIZE - 2,
- draw->cellRect->y + draw->cellRect->height/2);
- }
- else if (pipeType == PIPE_MIDDLEITEM
- || pipeType == PIPE_OPENMIDDLEPARENT
- || pipeType == PIPE_CLOSEDMIDDLEPARENT)
- {
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y,
- draw->cellRect->x + PIPEIMAGESIZE/2, draw->cellRect->y + draw->cellRect->height);
-
- drawDottedLine(draw->gc,
- call->clipRect,
- draw->cellRect->x + PIPEIMAGESIZE/2,
- draw->cellRect->y + draw->cellRect->height/2,
- draw->cellRect->x + PIPEIMAGESIZE - 2,
- draw->cellRect->y + draw->cellRect->height/2);
- }
-
- if (m_descendantSelectAllowed && spool_icon)
- {
- // take back our saved space.
- draw->cellRect->x -= PIPEIMAGESIZE;
- draw->cellRect->width += PIPEIMAGESIZE;
-
- PixmapDraw(spool_icon->pixmap, spool_icon->mask,
- spool_icon->width, spool_icon->height,
- XmNONE, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
-
- draw->cellRect->x += PIPEIMAGESIZE;
- draw->cellRect->width -= PIPEIMAGESIZE;
- }
-
- if (parent_icon)
- {
- PixmapDraw(parent_icon->pixmap, parent_icon->mask,
- parent_icon->width, parent_icon->height,
- XmNONE, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
- }
-
- #if 0
- if (pipeType != PIPE_EMPTYITEM)
- {
- #endif
- draw->cellRect->x += PIPEIMAGESIZE;
- draw->cellRect->width -= PIPEIMAGESIZE;
- #if 0
- }
- #endif
- }
- }
-
- void
- XFE_Outliner::showHeaderClick()
- {
- D(printf ("trying to show column\n");)
- if (m_numvisible < m_numcolumns)
- {
- showColumn();
- D(printf ("succeeded.\n");)
- }
- }
-
- void
- XFE_Outliner::hideHeaderClick()
- {
- D(printf ("trying to hide column\n");)
- if (m_numvisible > 1)
- {
- hideColumn();
- D(printf ("succeeded.\n");)
- }
- }
-
- void
- XFE_Outliner::showHeaderDraw(XmLGridCallbackStruct *call)
- {
- XmLGridDrawStruct *draw = call->drawInfo;
- Boolean drawSelected = draw->drawSelected;
- fe_icon *icon;
-
- _XmDrawShadows(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmLGridWidget)m_widget)->manager.top_shadow_GC,
- ((XmLGridWidget)m_widget)->manager.bottom_shadow_GC,
- draw->cellRect->x, draw->cellRect->y,
- draw->cellRect->width, draw->cellRect->height,
- 1, XmSHADOW_OUT);
-
- draw->cellRect->x += 1;
- draw->cellRect->width -= 2;
- draw->cellRect->y += 1;
- draw->cellRect->height -= 2;
-
- if (m_numvisible < m_numcolumns)
- icon = &showColumnIcon;
- else
- icon = &showColumnInsensIcon;
- PixmapDraw(icon->pixmap, icon->mask,
- icon->width, icon->height,
- XmALIGNMENT_CENTER, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
- }
-
- void
- XFE_Outliner::hideHeaderDraw(XmLGridCallbackStruct *call)
- {
- XmLGridDrawStruct *draw = call->drawInfo;
- Boolean drawSelected = draw->drawSelected;
- fe_icon *icon;
-
- _XmDrawShadows(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmLGridWidget)m_widget)->manager.top_shadow_GC,
- ((XmLGridWidget)m_widget)->manager.bottom_shadow_GC,
- draw->cellRect->x, draw->cellRect->y,
- draw->cellRect->width, draw->cellRect->height,
- 1, XmSHADOW_OUT);
-
- draw->cellRect->x += 1;
- draw->cellRect->width -= 2;
- draw->cellRect->y += 1;
- draw->cellRect->height -= 2;
-
- if (m_numvisible > 1)
- icon = &hideColumnIcon;
- else
- icon = &hideColumnInsensIcon;
-
- PixmapDraw(icon->pixmap, icon->mask,
- icon->width, icon->height,
- XmALIGNMENT_CENTER, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
- }
-
- void
- XFE_Outliner::headerCellDraw(XmLGridCallbackStruct *call)
- {
- XmLGridDrawStruct *draw = call->drawInfo;
- Boolean drawSelected = draw->drawSelected;
- char *cstr;
- char *style;
- fe_icon *icon;
- int sourcecol;
- XRectangle /*r,*/ textRect;
- XmString xmstr = NULL;
-
- sourcecol = m_columnIndex[call->column];
-
- style = (char*)styleToTag(m_outlinable->getColumnHeaderStyle(sourcecol));
- cstr = m_outlinable->getColumnHeaderText(sourcecol);
- icon = m_outlinable->getColumnHeaderIcon(sourcecol);
-
- /*
- ** This is pretty much a hack for the mail/news stuff.
- ** we need to keep two columns together, one that has an
- ** icon and one that has text, so we just make them one
- ** column, and handle the button clicks specially, and also
- ** draw funky shadows in the case that a header has both
- ** text and an icon.
- */
- if (cstr && icon)
- {
- _XmDrawShadows(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmLGridWidget)m_widget)->manager.top_shadow_GC,
- ((XmLGridWidget)m_widget)->manager.bottom_shadow_GC,
- draw->cellRect->x, draw->cellRect->y,
- icon->width + 2, draw->cellRect->height,
- 1, XmSHADOW_OUT);
- _XmDrawShadows(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmLGridWidget)m_widget)->manager.top_shadow_GC,
- ((XmLGridWidget)m_widget)->manager.bottom_shadow_GC,
- draw->cellRect->x + icon->width + 2,
- draw->cellRect->y,
- draw->cellRect->width - (icon->width + 2),
- draw->cellRect->height,
- 1, XmSHADOW_OUT);
- }
- else
- {
- _XmDrawShadows(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmLGridWidget)m_widget)->manager.top_shadow_GC,
- ((XmLGridWidget)m_widget)->manager.bottom_shadow_GC,
- draw->cellRect->x, draw->cellRect->y,
- draw->cellRect->width, draw->cellRect->height,
- 1, XmSHADOW_OUT);
- }
-
- draw->cellRect->x += 1;
- draw->cellRect->width -= 2;
- draw->cellRect->y += 1;
- draw->cellRect->height -= 2;
-
- if (icon)
- {
- PixmapDraw(icon->pixmap, icon->mask,
- icon->width, icon->height,
- XmALIGNMENT_LEFT, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
-
- textRect.x = draw->cellRect->x + icon->width + 4;
- textRect.y = draw->cellRect->y;
- textRect.width = draw->cellRect->width - icon->width - 4;
- textRect.height = draw->cellRect->height;
- }
- else
- {
- textRect = *draw->cellRect;
- }
-
- if (cstr)
- {
- xmstr = XmStringCreate(cstr, style);
-
- XSetForeground(XtDisplay(m_widget), draw->gc,
- draw->foreground);
-
- XmLStringDraw(m_widget, xmstr, draw->stringDirection, draw->fontList, draw->alignment,
- draw->gc, &textRect, call->clipRect);
- }
-
- if (xmstr) XmStringFree(xmstr);
-
- if (sourcecol == m_sortColumn
- && textRect.width > textRect.height - 4)
- {
- int arrow_direction = (m_sortDirection == OUTLINER_SortAscending
- ? XmARROW_DOWN : XmARROW_UP);
- int arrow_size = textRect.height - 4;
-
- if (arrow_size > 0)
- {
- XSetForeground(XtDisplay(m_widget), draw->gc,
- draw->background);
-
- _XmDrawArrow(XtDisplay(m_widget),
- XtWindow(m_widget),
- ((XmManagerWidget)m_widget)->manager.bottom_shadow_GC,
- ((XmManagerWidget)m_widget)->manager.top_shadow_GC,
- draw->gc,
- textRect.x + textRect.width - arrow_size - 4,
- textRect.y + (textRect.height / 2 - arrow_size / 2),
- arrow_size,
- arrow_size,
- 2,
- arrow_direction);
- }
- }
- }
-
- void
- XFE_Outliner::contentCellDraw(XmLGridCallbackStruct *call)
- {
- XmLGridDrawStruct *draw = call->drawInfo;
- Boolean drawSelected = draw->drawSelected;
- char *cstr;
- XmString xmstr = NULL;
- fe_icon *icon;
- XRectangle textRect;
- int sourcecol;
-
- /*
- ** This function will get called (potentially) many times for
- ** one line -- once per cell. We only do the aquireLineData
- ** once, for the first cell.
- */
- if (call->row != m_DataRow)
- {
- // if the last line was valid, get rid of it.
- if (m_DataRow != -1)
- m_outlinable->releaseLineData();
-
- m_DataRow = call->row;
-
- // get the new line's info.
- if (! m_outlinable->acquireLineData(call->row) )
- {
- m_DataRow = -1;
- return;
- }
- }
-
- sourcecol = m_columnIndex[call->column];
-
- cstr = m_outlinable->getColumnText(sourcecol);
- icon = m_outlinable->getColumnIcon(sourcecol);
-
- if (sourcecol == m_pipeColumn)
- pipeDraw(call);
-
- /* if there's an icon, we need to push the text over. */
- if (icon)
- {
- PixmapDraw(icon->pixmap, icon->mask,
- icon->width, icon->height,
- XmALIGNMENT_LEFT, draw->gc, draw->cellRect,
- call->clipRect,
- drawSelected ? draw->selectBackground : draw->background);
-
- textRect.x = draw->cellRect->x + icon->width + 4;
- textRect.y = draw->cellRect->y;
- textRect.width = draw->cellRect->width - icon->width - 4;
- textRect.height = draw->cellRect->height;
- }
- else
- {
- textRect = *draw->cellRect;
- }
-
- if (cstr)
- if (call->clipRect->width > 4)
- {
- /* Impose some spacing between columns. What a hack. ### */
- call->clipRect->width -= 4;
-
- xmstr = XmStringCreate(cstr, (char*)styleToTag(m_outlinable->getColumnStyle(sourcecol)));
-
- XSetForeground(XtDisplay(m_widget), draw->gc,
- drawSelected ? draw->selectForeground : draw->foreground);
-
- XmLStringDraw(m_widget, xmstr, draw->stringDirection, draw->fontList, draw->alignment,
- draw->gc, &textRect, call->clipRect);
-
- call->clipRect->width += 4;
- }
-
- if (call->row == m_dragrow && sourcecol >= 0)
- {
- int y;
- int x2 = draw->cellRect->x + draw->cellRect->width - 1;
- XP_Bool rightedge = FALSE;
- if (call->column == m_numcolumns - 1)
- {
- rightedge = TRUE;
- #ifdef TERRYS_RIGHT_COLUMN_WIDTH_HACK
- if (xmstr)
- {
- int xx = draw->cellRect->x + XmStringWidth(draw->fontList, xmstr) + 4;
- if (x2 > xx) x2 = xx;
- }
- #endif
- }
-
- if (m_draggc == NULL)
- {
- XGCValues gcv;
- #if 0
- Pixel foreground;
- #endif
- gcv.foreground = drawSelected ? draw->selectForeground : draw->foreground;
-
- m_draggc = XCreateGC(XtDisplay(m_widget), XtWindow(m_widget),
- GCForeground, &gcv);
- }
- y = draw->cellRect->y + draw->cellRect->height - 1;
- XDrawLine(XtDisplay(m_widget), XtWindow(m_widget), m_draggc,
- draw->cellRect->x, y, x2, y);
- if (m_dragrowbox)
- {
- int y0 = draw->cellRect->y;
- if (call->column == 0)
- {
- XDrawLine(XtDisplay(m_widget), XtWindow(m_widget), m_draggc,
- draw->cellRect->x, y0, draw->cellRect->x, y);
- }
- if (rightedge)
- {
- XDrawLine(XtDisplay(m_widget), XtWindow(m_widget), m_draggc,
- x2, y0, x2, y);
- }
- XDrawLine(XtDisplay(m_widget), XtWindow(m_widget), m_draggc,
- draw->cellRect->x, y0, x2, y0);
- }
- }
-
- if (xmstr) XmStringFree(xmstr);
- }
-
- void
- XFE_Outliner::celldraw(XtPointer callData)
- {
- XmLGridCallbackStruct* call = (XmLGridCallbackStruct*) callData;
-
- if (call->rowType == XmHEADING)
- if (m_hideColumnsAllowed
- && call->column >= m_numvisible)
- {
- if (call->column == m_numvisible)
- showHeaderDraw(call);
- else
- hideHeaderDraw(call);
- }
- else
- {
- headerCellDraw(call);
- }
- else /* XmCONTENT */
- if (! m_hideColumnsAllowed
- || call->column < m_numvisible)
- contentCellDraw(call);
- }
-
- void
- XFE_Outliner::resize(XtPointer callData)
- {
- XmLGridCallbackStruct *cbs = (XmLGridCallbackStruct*)callData;
- int i;
- int width_of_visible_columns = 0;
- int width_of_grid = XtWidth(m_widget) - 2 * MGR_ShadowThickness(m_widget);
- int delta;
-
- /*
- ** in the event of a widget resize, we do the following:
- ** o All resizable, visible columns are resized equally.
- **
- ** in the event of a column resize, we do the following:
- ** o resize the leftmost resizable column to the right of the column
- ** that was resized larger or smaller.
- **
- ** we don't allow the right hand side of the right most visible column to
- ** be dragged.
- */
-
- XP_ASSERT(m_widget);
- if(!m_widget)
- return;
-
- for (i = 0; i < m_numvisible + (m_hideColumnsAllowed ? 2 : 0); i ++)
- {
- /*
- ** don't change this to calls to getColumnWidthByIndex. It doesn't
- ** work
- ** correctly in the face of the show/hide buttons.
- */
- XmLGridColumn col;
- Dimension column_width = 0;
-
- col = XmLGridGetColumn(m_widget, XmCONTENT, i);
- XtVaGetValues(m_widget,
- XmNcolumnPtr, col,
- XmNcolumnWidth, &column_width,
- NULL);
-
- width_of_visible_columns += column_width;
- }
-
- delta = width_of_grid - width_of_visible_columns;
-
- if (delta == 0)
- {
- /*
- ** even if the outliner doesn't change in width, we still need to
- ** remember the geometry so that the height will come back the same
- */
- rememberGeometry();
- return;
- }
-
- /*
- ** The grid resize handling is simple. We just figure out the delta and
- ** apply it to all columns of the grid. We also make sure to resize the
- ** columns that are not visible, so that when they are next shown they
- ** don't overwhelm the outliner.
- */
- if (cbs->reason == XmCR_RESIZE_GRID)
- {
- D( printf ("Inside XFE_Outliner::resize(GRID)\n");)
- int num_resizable;
-
- D( printf ("Width of visible columns is %d. Width of outliner is %d\n",
- width_of_visible_columns, width_of_grid); )
-
- num_resizable = numResizableVisibleColumns();
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, True,
- NULL);
-
- // apply the delta to the visible columns.
- applyDelta(delta);
-
- /*
- ** now we resize the hidden columns so when they are unhidden
- ** their size is in line with what we've been doing to the
- ** outliner -- shrinking or expanding. You dig?
- */
- for (i = m_numvisible; i < m_numcolumns; i ++)
- {
- if (getColumnResizableByIndex(i))
- {
- m_columnwidths[ i ] += delta / m_numcolumns;
-
- if (m_columnwidths[ i ] < MIN_COLUMN_WIDTH)
- m_columnwidths[ i ] = MIN_COLUMN_WIDTH;
- if (m_columnwidths[ i ] > MAX_COLUMN_WIDTH)
- m_columnwidths[ i ] = MAX_COLUMN_WIDTH;
- }
- }
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, False,
- NULL);
- }
- /*
- ** The column resize handling is a bit more involved than the grid resize
- ** handling. The grid actually resizes the column before invoking this
- ** callback, so we can figure out the delta the same way we do above. So,
- ** the delta will be negative if the user dragged the column to the right,
- ** and positive if they dragged to the left.
- **
- ** We apply the delta to all the columns to the right of the resized one,
- ** and if their is any residual, unapplied delta we add it to the width of
- ** the resized column.
- */
- else if (cbs->reason == XmCR_RESIZE_COLUMN)
- {
- D( printf ("Inside XFE_Outliner::resize(COLUMN, %d)\n", cbs->column);)
- Dimension resize_column_width;
- int delta_left;
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, True,
- NULL);
-
- delta_left = applyDelta(delta, cbs->column + 1);
-
- D(printf ("delta_left is %d, delta was %d\n", delta_left, delta);)
-
- /*
- ** our m_columnwidths array isn't updated by the grid for the
- ** resized column, so we have to use GetValues to get it. It's
- ** set below (taking into account any unapplied delta.
- */
- {
- XmLGridColumn col;
- Dimension column_width = 0;
-
- col = XmLGridGetColumn(m_widget, XmCONTENT, cbs->column);
- XtVaGetValues(m_widget,
- XmNcolumnPtr, col,
- XmNcolumnWidth, &column_width,
- NULL);
-
- resize_column_width = column_width;
- }
-
- if (delta_left != 0)
- resize_column_width += delta_left;
-
- setColumnWidthByIndex(cbs->column, resize_column_width);
-
- XtVaSetValues(m_widget,
- XmNlayoutFrozen, False,
- NULL);
- }
- else
- {
- XP_ASSERT(0);
- }
-
- rememberGeometry();
- }
-
- void
- XFE_Outliner::outlineLine(int line)
- {
- int old = m_dragrow;
- if (old == line && m_dragrowbox) return;
- m_dragrowbox = TRUE;
- m_dragrow = line;
- if (old >= 0) invalidateLine(old);
- if (line >= 0 && line != old) invalidateLine(line);
- }
-
- void
- XFE_Outliner::underlineLine(int line)
- {
- int old = m_dragrow;
- if (old == line && !m_dragrowbox) return;
- m_dragrowbox = FALSE;
- m_dragrow = line;
- if (old >= 0) invalidateLine(old);
- if (line >= 0 && line != old) invalidateLine(line);
- }
-
- void
- XFE_Outliner::sendClick(XEvent *event,
- Boolean only_if_not_selected)
- {
- int x = event->xbutton.x;
- int y = event->xbutton.y;
- int button = ((XButtonEvent *)event)->button;
- int numclicks = 1;
- unsigned char rowtype;
- unsigned char coltype;
- int row;
- int column;
- unsigned int state = event->xbutton.state;
- int sourcecol;
- XRectangle rect;
-
- if (!only_if_not_selected &&
- abs(x - m_lastx) < 5 && abs(y - m_lasty) < 5 &&
- (m_lastdowntime - m_lastuptime <=
- XtGetMultiClickTime(XtDisplay(m_widget)))) {
- numclicks = 2; /* ### Allow triple clicks? */
- }
- m_lastx = x;
- m_lasty = y;
-
- if (XmLGridXYToRowColumn(m_widget, x, y,
- &rowtype, &row, &coltype, &column) >= 0)
- {
- rect.x = 0;
- rect.y = 0;
- XmLGridRowColumnToXY(m_widget, rowtype, row, coltype, column,
- False, &rect);
-
- if (rowtype == XmHEADING) row = -1;
-
- m_activity = ButtonPressMask;
- m_ignoreevents = True;
-
- if (column >= m_numvisible && m_hideColumnsAllowed)
- {
- if (row != -1)
- return;
-
- if (column == m_numvisible)
- {
- showHeaderClick();
- }
- else
- {
- hideHeaderClick();
- }
- }
- else
- {
- sourcecol = m_columnIndex[column];
-
- /* make the x and y coordinates local to the cell. */
- x -= rect.x;
- y -= rect.y;
-
- if (sourcecol == m_pipeColumn && !only_if_not_selected && row >= 0)
- {
- int depth;
- XP_Bool expandable;
- int flippy_offset = 0;
-
- m_flippyfunc_data->row = row;
- m_flippyfunc_data->do_selection = FALSE;
-
- m_DataRow = row;
- m_outlinable->acquireLineData(m_DataRow);
- m_outlinable->getTreeInfo(&expandable, NULL, &depth, NULL);
- m_outlinable->releaseLineData();
-
- if (m_descendantSelectAllowed)
- flippy_offset += PIPEIMAGESIZE; // XXX
-
- flippy_offset += depth * PIPEIMAGESIZE;
-
- if (expandable)
- if (x >= flippy_offset && x <= flippy_offset + PIPEIMAGESIZE)
- {
- if (numclicks == 1)
- {
- m_outlinable->Flippyfunc(m_flippyfunc_data);
- }
-
- return;
- }
- else if (m_descendantSelectAllowed && x > 0 && x < flippy_offset)
- {
- if (numclicks == 1)
- {
- m_flippyfunc_data->do_selection = TRUE;
- m_outlinable->Flippyfunc(m_flippyfunc_data);
- }
-
- return;
- }
- // else we drop out and hit the buttonfunc stuff.
- }
-
- m_buttonfunc_data->x = x;
- m_buttonfunc_data->y = y;
- m_buttonfunc_data->row = row;
- m_buttonfunc_data->column = sourcecol;
- m_buttonfunc_data->clicks = numclicks;
- m_buttonfunc_data->shift = ((state & ShiftMask) != 0);
- m_buttonfunc_data->ctrl = ((state & ControlMask) != 0);
- m_buttonfunc_data->button = button;
- // alt? how are we supposed to do that?
-
- if (m_selBlocked)
- XBell(XtDisplay(m_widget), 100);
- else
- m_outlinable->Buttonfunc(m_buttonfunc_data);
-
- }
- }
- }
-
- void
- XFE_Outliner::buttonEvent(XEvent *event, Boolean *c)
- {
- int x = event->xbutton.x;
- int y = event->xbutton.y;
- unsigned char rowtype;
- unsigned char coltype;
-
- /* Fix UMR && 83752
- */
- int row = 0;
- int column = 0;
-
- m_ignoreevents = False;
-
- switch (event->type)
- {
- case ButtonPress:
- /* Always ignore btn3. Btn3 is for popups. - dp */
- if (event->xbutton.button == 3) break;
-
- if (XmLGridXYToRowColumn(m_widget, x, y,
- &rowtype, &row, &coltype, &column) >= 0)
- {
- if (rowtype == XmHEADING)
- {
-
- if (XmLGridPosIsResize(m_widget, x, y))
- {
- break;
- }
- }
- m_activity |= ButtonPressMask;
- m_ignoreevents = True;
- #if !defined(USE_MOTIF_DND)
- m_dragcolumn = column;
- #endif /* USE_MOTIF_DND */
- }
-
- #if !defined(USE_MOTIF_DND)
- m_lastmotionx = x;
- m_lastmotiony = y;
-
- // Save this position off so we can create the drag widget
- // in the right place if we're going to drag. Subtract the
- // (row, col) offset first.
- {
- XRectangle hotRect;
- int sourceDepth = 0; // Source icon indented this many times.
- XmLGridRowColumnToXY(m_widget,
- rowtype, row,
- coltype, column,
- False, &hotRect);
-
- // Calculate the outline-indent offset.
- m_DataRow = row;
- m_outlinable->acquireLineData(row);
- m_outlinable->getTreeInfo(NULL, NULL, &sourceDepth, NULL);
- m_outlinable->releaseLineData();
-
- D(printf("sourceDepth = %d\n", sourceDepth);)
-
- // Remember to add one for the flippy.
- m_hotSpot_x = x - hotRect.x - ((sourceDepth+1)*PIPEIMAGESIZE);
- m_hotSpot_y = y - hotRect.y;
- }
-
- #endif /* USE_MOTIF_DND */
- m_lastdowntime = event->xbutton.time;
- break;
-
- case ButtonRelease:
- if (m_activity & ButtonPressMask)
- #if defined(USE_MOTIF_DND)
- sendClick(event, FALSE);
- #else
- {
- if (m_activity & PointerMotionMask)
- {
- /* handle the drop */
- fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_DROP);
- fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_END);
-
- destroyDragWidget();
- }
- else
- {
- sendClick(event, FALSE);
- }
- }
-
- #endif /* USE_MOTIF_DND */
-
- m_lastuptime = event->xbutton.time;
- m_activity = 0;
-
- break;
-
- #if !defined(USE_MOTIF_DND)
- #ifdef NONMOTIF_DND
- case MotionNotify:
- XmLGridXYToRowColumn(m_widget, x, y,
- &rowtype, &row, &coltype, &column);
-
- if (!(m_activity & PointerMotionMask) &&
- (abs(x - m_lastmotionx) < 5 && abs(y - m_lastmotiony) < 5))
- {
- /* We aren't yet dragging, and the mouse hasn't moved enough for
- this to be considered a drag. */
-
- break;
- }
-
- if (m_activity & ButtonPressMask)
- {
- /* The type of stuff we're going to drag. */
- fe_dnd_Type drag_type;
-
- /* ok, the pointer moved while a button was held.
- * we're gonna drag some stuff.
- */
- m_ignoreevents = True;
-
- if (!(m_activity & PointerMotionMask))
- {
- if (m_dragtype == FE_DND_NONE)
- {
- /* We don't do drag'n'drop in this context. Do any any visibility
- scrolling that we may have been putting off til the end of user
- activity. */
- m_activity = 0;
-
- #ifdef notyet
- if (info->visibleLine >= 0 && info->visibleTimer == NULL) {
- fe_OutlineMakeVisible(info->widget, info->visibleLine);
- info->visibleLine = -1;
- }
- #endif
- break;
- }
-
- /* First time. If the item we're pointing at isn't
- selected, deliver a click message for it (which ought to
- select it.) */
-
- if (rowtype == XmCONTENT)
- {
- /* Hack things so we click where the mouse down was, not where
- the first notify event was. Bleah. But, only if the
- item was previously unselected. */
- int actual_row = XYToRow(m_lastmotionx, m_lastmotiony);
-
- if (!isSelected(actual_row))
- {
- event->xbutton.x = m_lastmotionx;
- event->xbutton.y = m_lastmotiony;
- sendClick(event, TRUE);
- }
- drag_type = m_dragtype;
- }
- else // it happened in a column header.
- {
- // don't allow dragging of the show/hide buttons.
- if (m_dragcolumn >= m_numvisible)
- break;
-
- drag_type = FE_DND_COLUMN;
- }
-
-
- // Create a drag source.
- // We want the mouse-down location, not the last one.
- event->xbutton.x = x;
- event->xbutton.y = y;
- makeDragWidget(m_hotSpot_x, m_hotSpot_y, drag_type);
-
- fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_START);
-
- m_activity |= PointerMotionMask;
- }
-
- fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_DRAG);
-
- /* Now, force all the additional mouse motion events that are
- lingering around on the server to come to us, so that Xt can
- compress them away. Yes, XSync really does improve performance
- in this case, not hurt it. */
- XSync(XtDisplay(m_widget), False);
- }
-
- m_lastmotionx = x;
- m_lastmotiony = y;
- break;
- #endif /* NONMOTIF_DND */
- #endif /* !USE_MOTIF_DND */
- }
- if (m_ignoreevents)
- *c = False;
- }
-
- #if !defined(USE_MOTIF_DND)
- void
- XFE_Outliner::makeDragWidget(int x, int y, fe_dnd_Type dnd_type)
- {
- Visual *v = 0;
- Colormap cmap = 0;
- Cardinal depth = 0;
- Widget label;
- // fe_icon *icon;
- Widget shell;
- Pixmap dragPixmap;
-
- D(printf("hot (x,y) = (%d,%d)\n", x, y);)
-
- if (_xfe_dragsource.widget) return;
-
- shell = m_toplevel->getBaseWidget();
-
- XtVaGetValues (shell, XtNvisual, &v, XtNcolormap, &cmap,
- XtNdepth, &depth, 0);
-
- _xfe_dragsource.type = dnd_type;
-
- #if 0
- // This only works if we're dragging from the icon.
- // Dragging from some random part of the line gives some
- // really weird offset for the drag. -mcafee
- _xfe_dragsource.hotx = x;
- _xfe_dragsource.hoty = y;
- #else
- // Trying some fixed offset; offset of zero sucks.
- _xfe_dragsource.hotx = 8;
- _xfe_dragsource.hoty = 8;
- #endif
-
- _xfe_dragsource.closure = dnd_type == FE_DND_COLUMN ? (void*)this : (void*)m_source;
- _xfe_dragsource.func = m_sourcedropfunc;
-
- XP_ASSERT(m_dragicon);
- if (m_dragicon == NULL) return;
-
- // XXX this needs to be something special when type == FE_DND_COLUMN
- dragPixmap = m_dragicon->pixmap;
-
- _xfe_dragsource.widget = XtVaCreateWidget("drag_win",
- overrideShellWidgetClass,
- m_widget,
- XmNwidth, m_dragicon->width,
- XmNheight, m_dragicon->height,
- XmNvisual, v,
- XmNcolormap, cmap,
- XmNdepth, depth,
- XmNborderWidth, 0,
- NULL);
-
- label = XtVaCreateManagedWidget ("label",
- xmLabelWidgetClass,
- _xfe_dragsource.widget,
- XmNlabelType, XmPIXMAP,
- XmNlabelPixmap, dragPixmap,
- NULL);
- }
-
- void
- XFE_Outliner::destroyDragWidget()
- {
- if (!_xfe_dragsource.widget) return;
- XtDestroyWidget (_xfe_dragsource.widget);
- _xfe_dragsource.widget = NULL;
- }
-
- void
- XFE_Outliner::handleDragEvent(XEvent *event,
- fe_dnd_Event type,
- fe_dnd_Source *source)
- {
- // only handle column drags that originated in this outliner.
- if (source->type != FE_DND_COLUMN || source->closure != this) return;
-
- switch (type)
- {
- case FE_DND_DROP:
- {
- unsigned char rowtype;
- unsigned char coltype;
- int row;
- int column;
- int x, y;
-
- D( printf ("Dropping column %d into an outliner\n", m_dragcolumn);)
-
- /* first we make sure that the drop happens within a valid row/column
- pair. */
-
- translateFromRootCoords(event->xbutton.x_root, event->xbutton.y_root, &x, &y);
-
- D( printf (" Drop position is (%d,%d)\n", x, y); )
-
- if (XmLGridXYToRowColumn(m_widget, x, y,
- &rowtype, &row, &coltype, &column) < 0)
- {
- D( printf ("Not dropping in a valid position\n");)
- return;
- }
-
- // don't allow dropping onto the show/hide columns */
- if (column >= m_numvisible)
- return;
-
- /* we only need to actually do anything if they drop on a different
- column than they started with. */
- if (column != m_dragcolumn)
- moveColumn(m_dragcolumn, column);
-
- break;
- }
- }
- }
- #endif /* USE_MOTIF_DND */
-
- void
- XFE_Outliner::celldrawCallback(Widget,
- XtPointer clientData,
- XtPointer callData)
- {
- XFE_Outliner *obj = (XFE_Outliner*)clientData;
-
- obj->celldraw(callData);
- }
-
- void
- XFE_Outliner::resizeCallback(Widget,
- XtPointer clientData,
- XtPointer callData)
- {
- XFE_Outliner *obj = (XFE_Outliner*)clientData;
-
- obj->resize(callData);
- }
-
- void
- XFE_Outliner::buttonEventHandler(Widget,
- XtPointer clientData,
- XEvent *event,
- Boolean *cont)
- {
- XFE_Outliner *obj = (XFE_Outliner*)clientData;
-
- obj->buttonEvent(event, cont);
- }
-
- const char *
- XFE_Outliner::styleToTag(EOutlinerTextStyle style)
- {
- switch (style)
- {
- case OUTLINER_Italic:
- return "ITALIC";
- case OUTLINER_Bold:
- return "BOLD";
- case OUTLINER_Default:
- return XmFONTLIST_DEFAULT_TAG;
- default:
- XP_ASSERT(0);
- return XmFONTLIST_DEFAULT_TAG;
- }
- }
-
- void
- XFE_Outliner::change(int first, int length, int newnumrows)
- {
- if (newnumrows != m_totalLines)
- {
- int old_totalLines = m_totalLines;
-
- // update totalLines here, since adding the rows and
- // redisplaying them might cause the outlinable to ask
- // us how many lines we have, and we should return the
- // new number.
- m_totalLines = newnumrows;
-
- if (newnumrows > old_totalLines)
- {
- XmLGridAddRows(m_widget, XmCONTENT, -1,
- m_totalLines - old_totalLines);
- }
- else
- {
- XmLGridDeleteRows(m_widget, XmCONTENT, m_totalLines,
- old_totalLines - m_totalLines);
- }
-
- length = m_totalLines - first;
- }
-
- if (first == 0 && length == m_totalLines)
- {
- invalidate();
- }
- else
- {
- invalidateLines(first, length);
- }
-
- XFlush(XtDisplay(m_widget));
- }
-
- void
- XFE_Outliner::listChangeStarting(XP_Bool /*asynchronous*/,
- MSG_NOTIFY_CODE notify,
- MSG_ViewIndex /*where*/,
- int32 /*num*/,
- int32 /*totallines*/)
- {
- /* we need to save off the selected items so they can be restored in
- listChangeFinished. we only do this once for a given series of nested
- changes */
- if (m_listChangeDepth == 0
- /* don't need to save selection when items change their contents*/
- && notify != MSG_NotifyChanged)
- {
- saveSelection();
-
- deselectAllItems();
- }
-
- m_listChangeDepth ++;
- }
-
- void
- XFE_Outliner::listChangeFinished(XP_Bool /*asynchronous*/,
- MSG_NOTIFY_CODE notify,
- MSG_ViewIndex where,
- int32 num, int32 totallines)
- {
- m_listChangeDepth--;
-
- XP_ASSERT(m_listChangeDepth >= 0); // should _never_ be negative.
-
- switch (notify) {
- case MSG_NotifyChanged:
- invalidateLines(where, num);
- return;
- case MSG_NotifyNone:
- #if 0
- if (MSG_GetPaneType(pane) == MSG_SEARCHPANE) /* For search dialog */
- if ( CONTEXT_DATA(context)->searchFinishedFunc)
- (*(CONTEXT_DATA(context)->searchFinishedFunc))(context);
- return;
- #endif
- break;
- case MSG_NotifyInsertOrDelete: /* Needed for search */
- break;
- case MSG_NotifyScramble:
- case MSG_NotifyAll:
- where = 0;
- num = totallines;
- break;
- }
-
- change(where, num, totallines);
-
- if (m_listChangeDepth == 0)
- restoreSelection();
- }
-
- int XFE_Outliner::getListChangeDepth() {
- return m_listChangeDepth;
- }
-
- Widget
- XFE_Outliner::getScroller()
- {
- Widget scroller;
-
- XtVaGetValues (m_widget, XmNverticalScrollBar, &scroller, 0);
-
- return scroller;
- }
-
-
- void
- XFE_Outliner::saveSelection()
- {
- if (!m_selectedItems)
- {
- int i;
-
- if (m_selectedCount)
- {
- m_selectedItems = (void**)XP_CALLOC(m_selectedCount,
- sizeof(void*));
-
- for (i = 0; i < m_selectedCount; i ++)
- {
- D( printf ("Saving selecting at index: %d\n",
- m_selectedIndices[ i ]); )
- m_selectedItems[ i ] =
- m_outlinable->ConvFromIndex(m_selectedIndices[i]);
- }
-
- m_selectedItemCount = m_selectedCount;
- }
- }
- }
-
- void
- XFE_Outliner::restoreSelection()
- {
- if (m_selectedItems)
- {
- int i;
-
- for (i = 0; i < m_selectedItemCount; i ++)
- {
- int index = m_outlinable->ConvToIndex(m_selectedItems[i]);
-
- if (index > -1 && index < m_totalLines)
- {
- D( printf ("Restoring selecting at index: %d\n",
- index); )
-
- selectItem(index);
- }
- }
-
- XP_FREE(m_selectedItems);
- m_selectedItemCount = 0;
- m_selectedItems = NULL;
- }
- }
-
- XFE_Outlinable *
- XFE_Outliner::getOutlinable()
- {
- return m_outlinable;
- }
-