📄 plotsetup.c
字号:
/*------------------------------------------------------------------------------*
* File Name:PlotSetup.c *
* Creation: CPY 6/12/2003 *
* Purpose: OriginC Source C file for Plot Setup dialog *
* Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, *
* All Rights Reserved *
* *
* Modification Log: *
* CPY 7/30/03 PLOT_TYPE_LIST_SEL_SUPPORT *
* CPY 8/17/03 ROW_NUMBER_ROW_ONLY_X_ALLOWED *
* CPY 8/18/03 AUTO_ENTER_EDIT_WHEN_DATAPLOT_SELECTED *
* CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT *
* RVD 8/25/2003 QA70-5042 v7.0674 DATAPLOT_LIMITS_DISPLAY *
* CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP *
* CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES *
* RVD 9/3/2003 QA70-5078 v7.0682 PLOT_RANGE_APPLY *
* CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX *
*------------------------------------------------------------------------------*/
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <origin.h>
/////////////////////////////////////////////////////////////////////////////////////
#include <Dialog.h> // this file is needed for DialogBuilder support
#include "ODlg.h" // resource IDs in ODlg.dll which this dialog is based upon
#include "HelpID.h" // our Dialog's ID is in this file so that it can be connected to our help system
#include "GridControl.h" // wrapper classes for vsFlexGrid control that provides centrlized functions that we should use as base class for all vsFlex grids
#include "ResizeDialog.h" // helper class derived from Dialog class that supports placement and arrangement of controls, and resizing of the dialog
#include <Profiler.h>
////////////////////////////////////////////////////////////////////////////////////////////////
// string localization section
// here we define all the strings that is longer and best to use macro, other strings can
// appear directly inside code using the _L() macro
#define _CAT "Plot Setup" // category for localization table, not always needed, used only for short string that might otherwise be confusing
#define SCP_DLG_TITLE_LEFT_NEW_PLOT _L("Plot Setup: Select Data to Create New Plot")
#define SCP_DLG_TITLE_LEFT_LAYER_CONTENTS _L("Plot Setup: Configure Data Plots in Layer")
#define SCP_DLG_X_ROW_NUM_TITLE _L("Use Row Number as X")
#define SCP_DLG_X_ROW_NUM_LABEL _L("Please enter initial X value and increment")
////////////////////////////////////////////////////////////////////////////////////////////////
// we need to indicate function to be diff from dataset, but there is no such EXIST type in
// Origin, so we will steal another EXIST const that is not being used
#define EXIST_FUNC_PLOT EXIST_PLOT
//
//----- communication by PostMessage between controls and dialog
//WM_USER_ON_CONTROL_CHANGE wParam
enum {ON_CONTROL_CHANGE_COL_DESIGNATIONS = 1};
#define HOUR_GLASS waitCursor junk;
#define PROFILE_HRGLASS HOUR_GLASS //Profiler junk;
//---- CPY 9/9/03 v7.5689 TERNARY_PLOT_USE_2D_TYPES
// this function is needed in several classes, we should not call GetPlotTypeInfo directly, need all these additional fix up
static int get_plot_type_info(int nPlotID, int nPageType, DWORD dwTargetLayer, DWORD& dwAuxTypeInfo, DWORD& dwAuxPlotInfo, string& strColPattern)
{
int nPlotType = 0;
if(nPlotID)
nPlotType = Project.GetPlotTypeInfo(nPlotID, dwAuxTypeInfo, dwAuxPlotInfo, strColPattern);
if(nPageType)
{
if(EXIST_DATA == nPageType || EXIST_FUNC_PLOT == nPageType)
dwAuxTypeInfo &= ~PCD_CAN_ADD_E_H_L;
if(EXIST_FUNC_PLOT == nPageType)
dwAuxTypeInfo |= PCD_NO_X;
}
if (PCD_LAYER_TRI == dwTargetLayer)
{
DWORD dwSaveModifiers = dwAuxTypeInfo & ( PCD_MODIFIER_SIZE | PCD_MODIFIER_COLOR );
dwAuxTypeInfo = PCD_LAYER_TRI | PCD_EXACT_YCOLS | PCD_Z_PREFER_Y | PCD_GROUP_MULTI_YS | PCD_PREFER_X | PCD_CAN_ADD_E_H_L | PCD_HIDE_ERR_BARS;
dwAuxTypeInfo |= dwSaveModifiers;
}
else if (PCD_LAYER_SMITH == dwTargetLayer)
dwAuxTypeInfo |= PCD_HIDE_ERR_BARS;
return nPlotType;
}
//----
#include "ColDesignations.h" // middle pane, PlotDesignations, or Column List, this class supports the control to pick XY checkboxes
#include "WksListControl.h" // top pane, listing of worksheets
#include "PlotTypeListControl.h" // left list control of middle of dialog, manage the plot types
#include "PlotListControl.h" // bottom pane, Layer Contents, and Plots List
//////-------- CPY 7/30/03
// the following are implemented here because of class pointer ColListControl, so menu needs ColListControl, and has to be done outside class declaration
enum {
CLCMENU_APPLY_DESTINATIONS,
CLCMENU_CHECK_ALL_UP,
CLCMENU_CHECK_ALL_DOWN,
CLCMENU_SEPARATOR0,
CLCMENU_CLEAR_ABOVE_DESIGNATIONS,
CLCMENU_CLEAR_BELOW_DESIGNATIONS,
CLCMENU_CLEAR_ALL_DESIGNATIONS,
CLCMENU_SEPARATOR,
CLCMENU_SHOW_ALL_COLS,
CLCMENU_SEPARATOR1,
CLCMENU_ERR_X,
CLCMENU_ERR_Y_POS_NEG,
CLCMENU_SEPARATOR2,
CLCMENU_ROW_AS_X,
CLCMENU_SEPARATOR3,
CLCMENU_INCREASE,
CLCMENU_DECREASE,
CLCMENU_END
};
bool ColListControlMenu::GetCommand(int& nChoice)
{
if(m_nChoice >= CLCMENU_APPLY_DESTINATIONS && m_nChoice < CLCMENU_END)
{
nChoice = m_nChoice;
return true;
}
return false;
}
ColListControlMenu::ColListControlMenu(ColListControl* pCLcntrl, int nRow, int nCol)
{
m_nChoice = -1;
UINT nFlags = 0;
DWORD dwEnable = 0;
// Button btnApplyWks = pCLcntrl->GetItem(IDC_SELCOLS_APPLY_WKS);
// if(btnApplyWks)
// nFlags = btnApplyWks.Check?MF_CHECKED : MF_UNCHECKED;
Add(_L("Apply Designations"), OnMenuItem, nFlags);
nFlags = nRow < 0? MF_DISABLED | MF_GRAYED : MF_ENABLED;
Add(_L("Set All to Top"), OnMenuItem, nFlags);
Add(_L("Set All to Bottom"), OnMenuItem, nFlags);
Add(NULL, OnMenuItem);//--------------- separator
nFlags = pCLcntrl->GetNumDesignationsAssigned()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
if(MF_ENABLED == nFlags && nRow < 0) // outside
nFlags = MF_DISABLED | MF_GRAYED;
Add(_L("Clear All to Top"), OnMenuItem, nFlags);
Add(_L("Clear All to Bottom"), OnMenuItem, nFlags);
// reset
nFlags = pCLcntrl->GetNumDesignationsAssigned()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
Add(_L("Clear All Designations"), OnMenuItem, nFlags);
Add(NULL, OnMenuItem);//--------------- separator
nFlags = pCLcntrl->m_chkShowAllCols.Check? MF_CHECKED : MF_UNCHECKED;
dwEnable = pCLcntrl->IsWorksheetPages()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
Add(_L("Show Disregarded(and hidden) Columns"), OnMenuItem, nFlags | dwEnable); //CLCMENU_SHOW_ALL_COLS
Add(NULL, OnMenuItem);//--------------- separator
dwEnable = pCLcntrl->IsAllowErrbars()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
nFlags = pCLcntrl->m_chkXErrBars.Check?MF_CHECKED : MF_UNCHECKED;
Add(_L("X Error Bars"), OnMenuItem, nFlags | dwEnable);
nFlags = pCLcntrl->m_chkPosNegErrBars.Check?MF_CHECKED : MF_UNCHECKED;
Add(_L("Y Error Bars Plus/Minus"), OnMenuItem, nFlags | dwEnable);
Add(NULL, OnMenuItem);//--------------- separator
dwEnable = pCLcntrl->IsAllowX()? MF_ENABLED : MF_DISABLED | MF_GRAYED;
nFlags = pCLcntrl->m_chkAddRowNumX.Check?MF_CHECKED : MF_UNCHECKED;
Add(_L("Allow Row# as X"), OnMenuItem, nFlags | dwEnable);
Add(NULL, OnMenuItem);//--------------- separator
Add(STR_INCREASE_HEIGHT, OnMenuItem);
Add(STR_DECREASE_HEIGHT, OnMenuItem);
}
void ColListControl::OnBeforeMouseDown(Control cntrl, short nButton, short nShift, float X, float Y, BOOL* pCancel)
{
int nRow = m_flx.MouseRow;
int nCol = m_flx.MouseCol;
if(MK_RBUTTON == nButton && 0 == nShift)
{
int nx = XTwipsToPixels(X);
int ny = YTwipsToPixels(Y);
ClientToScreen(nx, ny);
//printf("nx = %d, ny = %d\n", nx, ny);
ColListControlMenu myMenu(this, nRow, nCol);
myMenu.TrackPopupMenu(0, nx, ny, GetDlgSafeHwnd());
int nCmd;
if(myMenu.GetCommand(nCmd))
{
switch(nCmd)
{
case CLCMENU_APPLY_DESTINATIONS:
ApplyWksColDesignations(true);
break;
break;
case CLCMENU_CLEAR_ALL_DESIGNATIONS:
ClearColDesignations();
break;
case CLCMENU_CLEAR_ABOVE_DESIGNATIONS:
ClearColDesignations(nRow, nCol, false);
break;
case CLCMENU_CLEAR_BELOW_DESIGNATIONS:
ClearColDesignations(nRow, nCol, true);
break;
case CLCMENU_CHECK_ALL_UP:
SetColDesginations(nRow, nCol, false);
break;
case CLCMENU_CHECK_ALL_DOWN:
SetColDesginations(nRow, nCol, true);
break;
case CLCMENU_SHOW_ALL_COLS:
m_chkShowAllCols.Check = m_chkShowAllCols.Check?false:true;
updateShowColsRows();
updateDesignations(true);
break;
case CLCMENU_ERR_X:
m_chkXErrBars.Check = m_chkXErrBars.Check?false:true;
break;
case CLCMENU_ERR_Y_POS_NEG:
m_chkPosNegErrBars.Check = m_chkPosNegErrBars.Check?false:true;
break;
case CLCMENU_ROW_AS_X:
m_chkAddRowNumX.Check = m_chkAddRowNumX.Check?false:true;
break;
case CLCMENU_INCREASE:
PostDlgMessage(WM_USER_RESIZE_CONTROLS, 1 , LPARAM_RESIZE_CONTROLS_INCREASE);
break;
case CLCMENU_DECREASE:
PostDlgMessage(WM_USER_RESIZE_CONTROLS, 1 , LPARAM_RESIZE_CONTROLS_DECREASE);
break;
}
if(CLCMENU_ERR_X == nCmd || CLCMENU_ERR_Y_POS_NEG == nCmd)
OnChangeErrBarOptions();
if(CLCMENU_ROW_AS_X == nCmd)
OnChangeAddRowNumbers();
}
return;
}
//----- CPY 8/17/03 ROW_NUMBER_ROW_ONLY_X_ALLOWED
if(nRow == getRowNumberRow() && !isXCol(nCol))
return;
//-----
GridListControl::OnBeforeMouseDown(nButton, nShift, X, Y, pCancel);
}
//////-------- end CPY 7/30/03
//------ CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT
// void ClearColDesignations(int nRow = -1, int nCol = -1, bool bAllDown = false, bool bKeepX = false, bool bRepaint = true);
void ColListControl::ClearColDesignations(int nRowCurrent, int nCol, bool bAllDown, bool bKeepX, bool bRepaint)// = -1 = -1 = false false true);
{
HOUR_GLASS
int nR1 = m_flx.FixedRows;
int nR2 = m_flx.Rows;
if(nRowCurrent >= nR1)
{
bKeepX = true;
if(bAllDown)
nR1 = nRowCurrent;
else
nR2 = nRowCurrent+1;
}
for(int nRow = nR1; nRow < nR2; nRow++)
{
if(bKeepX && getColDesignation(nRow) == COLDESIG_X)
continue;
setDesignationRadioChoice(nRow, 0);
}
if(bRepaint)
updateDesignations();
notifyDlgOnDesignationChanges();
}
void ColListControl::SetColDesginations(int nRowCurrent, int nCol, bool bAllDown, bool bRepaint)// otherwise all up, = true
{
HOUR_GLASS
int nR1 = m_flx.FixedRows;
int nR2 = m_flx.Rows;
if(bAllDown)
nR1 = nRowCurrent;
else
nR2 = nRowCurrent+1;
for(int nRow = nR1; nRow < nR2; nRow++)
{
setDesignationRadioChoice(nRow, nCol);
}
if(bRepaint)
updateDesignations();
notifyDlgOnDesignationChanges();
}
string ColListControl::getColHeadingTooltips(int nCol)
{
string str;
int nDesignation = getDesignationOfCol(nCol);
if(nDesignation >= 0)
{
switch(nDesignation)
{
case COLDESIG_LABEL:
str = _L("Data Label");
break;
case COLDESIG_SIZE:
str = _L("Symbol Size");
break;
case COLDESIG_COLOR:
str = _L("Symbol Color");
break;
case COLDESIG_VECTOR_ANGLE:
str = _L("Angle");
break;
case COLDESIG_VECTOR_MAGNITUDE:
str = _L("Magnitude");
break;
}
}
return str;
}
//------
#define DBG_TREE_OUT(_tr, _lpcsMsg) //tree_dump(_tr, _lpcsMsg, 4);
///////////// WAIT_FIX, this is needed until we can have class static member function and static data member
static int s_nLeft = -1, s_nTop = -1;
static bool get_n_box_event(TreeNode& myTree, int nRow, int nType, Dialog& dlgGetNBox)
{
if(nRow < 0 && s_nLeft> 0 && s_nTop > 0) // init
{
RECT r1;
Window wnd = dlgGetNBox.GetWindow();
wnd.GetWindowRect(&r1);
OffsetRect(&r1, s_nLeft - r1.left, s_nTop - r1.top);
wnd.MoveWindow(&r1);
s_nLeft = s_nTop = -1;
}
return false;
}
/////////////
#define STR_AVAIL_DATA_CHOICE "AvailData"
#define STR_DATA_PLOTS "DataPlots"
//////////////////////////////
//////////////////////////////
#define STR_LAYER_NODE_NAME_PREFIX "Layer"
#define STR_LAYER_NODE_NAME_DISPLAY _LC("Layer", _CAT)
BOOL init_tree_num_layers(TreeNode &tr, int nNumLayers = 1)
{
if (nNumLayers < 1)
nNumLayers = 1;
tr.RemoveChild(STR_DATA_PLOTS);
TreeNode trRoot = tr.AddNode(STR_DATA_PLOTS);
if (!trRoot.IsValid())
{
ASSERT(FALSE);
return FALSE;
}
for (int ii = 0; ii < nNumLayers; ii++)
{
string strLayerNodeName;
string strLabel;
//strLayerNodeName.Format("Layer%d", ii);
strLayerNodeName.Format("%s%d", STR_LAYER_NODE_NAME_PREFIX, ii);
TreeNode trLayerNode = trRoot.AddNode(strLayerNodeName);
if (trLayerNode.IsValid())
{
strLabel.Format("%s %d", STR_LAYER_NODE_NAME_DISPLAY, ii + 1);
trLayerNode.SetAttribute(STR_LABEL_ATTRIB, strLabel);
// Let the internal code know that this is a branch (since it will
// be empty for now)
trLayerNode.SetAttribute(STR_ID_ATTRIB, ONODETYPE_BRANCH);
}
else
ASSERT(FALSE);
}
return TRUE;
}
static bool is_plot_list_empty(TreeNode &tr)
{
foreach (TreeNode trLayer in tr.Children)
{
if(trLayer.GetNodeCount() > 0)
return false;
}
return true;
}
typedef void (*PFNApplySystemThemeToPage)(OriginObject& obj);
static bool apply_plot_list_tree_to_page(GraphPage &pg, TreeNode &tr, DWORD dwCtrl)
{
if (!pg)
{
ASSERT(FALSE);
return FALSE;
}
HOUR_GLASS
foreach (TreeNode trLayer in tr.Children)
{
string strName = trLayer.tagName;
string strPrefix;
int nIndex = string_to_prefix_end_number(strPrefix.GetBuffer(MAXLINE), strName);
strPrefix.ReleaseBuffer();
if (strPrefix.CompareNoCase(STR_LAYER_NODE_NAME_PREFIX) == 0)
{
GraphLayer grl = pg.Layers(nIndex);
if (grl)
grl.AddPlots(trLayer, dwCtrl);
else
return false; // cannot find the layer
}
else
return false; // there are other nodes?
}
if( dwCtrl & ADDPLOTSFROMTREE_NEW )
{
PFNApplySystemThemeToPage pfn = Project.FindFunction("ApplySystemThemeToPage", "Originlab\\OriginEvents.c");
if( pfn )
pfn(pg);
}
return true;
}
//////////////////////////////
// this function opens the Plot Setup dialog
//when calling from a graph layer, this dialog work with treenodes,
//
// return 0 if user cancel, otherwise, return the DWORD that will be passed into grl.AddPlots
// nExVal = -1 to indicate that we are using template library
static DWORD SelColsPlottingDlg(bool bNewPlot, TreeNode& trPlotList, int nPlotID, int nExVal, HWND hWndParent = NULL)
{
SelColsForPlottingDlg MyDlg(bNewPlot, trPlotList, nPlotID, nExVal);
return MyDlg.DoModalEx(hWndParent);
}
static bool get_gpage_plot_contents_and_check_plot_type(const GraphPage &pg, TreeNode &trPlots, int& nPlotType)
{
HOUR_GLASS
int nTemplatePlotType = gpage_get_plots(pg, trPlots);
if ( 0 == nTemplatePlotType )
return false;
if(0 == nPlotType || IDM_PLOT_UNKNOWN == nPlotType)
{
if(nTemplatePlotType != IDM_PLOT_UNKNOWN)
nPlotType = nTemplatePlotType;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -