📄 helpreswinc.c
字号:
/* * $Id: HelpResWinC.C,v 1.3 2000/08/07 10:58:16 evgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "HelpResWinC.h"#include "WArgList.h"#include "WXmString.h"#include "TextMisc.h"#include "rsrc.h"#include "HalAppC.h"#include "MemMap.h"#include "FieldViewC.h"#include "VItemC.h"#include "ButtonBox.h"#include "HelpC.h"#include "HelpDbC.h"#include "SysErr.h"#include "red.xpm"#include "green.xpm"#include "yellow.xpm"#include <Xm/Form.h>#include <Xm/Label.h>#include <Xm/PushB.h>#include <Xm/Separator.h>#include <Xm/TextF.h>#include <Xm/Frame.h>#include <Xm/RowColumn.h>#include <Xm/ArrowB.h>#include <Xm/MessageB.h>#include <Xm/SelectioB.h>#include <Xm/Protocols.h>#include <Xm/AtomMgr.h>#include <X11/cursorfont.h>#include <X11/IntrinsicP.h>#include <X11/CoreP.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>extern int debuglev;static HelpResWinC *win = NULL;#define BIG_DIST (1<<30)#define QUICK_FIELD 0#define CONT_FIELD 1#define HELP_FIELD 2/*--------------------------------------------------------------- * Function to build a default name for the widget */static voidGetShortName(Widget w, StringC& name){//// Build name of the form "*shell*parent.widget"// Widget par = XtParent(w); Widget shell = par; while ( shell && !XtIsShell(shell) ) shell = XtParent(shell); name.Clear(); if ( shell ) { if ( shell != (Widget)*halApp ) name += "*"; if ( shell != par ) { name += XtName(shell); name += '*'; } } if ( par ) { name += XtName(par); name += '.'; } name += XtName(w);} // End GetShortName/*--------------------------------------------------------------- * Function to build the full name for the widget */static voidGetLongName(Widget w, StringC& name){ name = XtName(w); Widget par = XtParent(w); CharC dot("."); while ( par ) { name = XtName(par) + dot + name; par = XtParent(par); }} // End GetLongName/*--------------------------------------------------------------- * Class to represent down a line in a resource file */class ResEntryC {public: StringC full; // Complete line in resource file CharC rspec; // First part of line including resource CharC wspec; // First part of line without resource CharC res; // Resource part CharC val; // Second part of line char binding; // dot or star ResEntryC() {} ResEntryC(const ResEntryC& re) { *this = re; } ResEntryC(CharC c) { *this = c; } ResEntryC& operator=(const ResEntryC& re) { full = re.full; Parse(); return *this; } ResEntryC& operator=(CharC c) { full = c; Parse(); return *this; } void SetVal(CharC v) { StringC tmp = rspec; tmp += ":\t"; tmp += v; full = tmp; Parse(); } void SetWspec(CharC w) { StringC tmp = w; tmp += binding; tmp += res; tmp += ":\t"; tmp += val; full = tmp; Parse(); } void SetRspec(CharC r) { StringC tmp = r; tmp += ":\t"; tmp += val; full = tmp; Parse(); } void Parse(); Boolean AppliesTo(Widget w, Widget *wsrc=NULL, int *dist=NULL);};/*--------------------------------------------------------------- * Class to show how a resource entry applies to a specific widget */class EntryDataC {public: ResEntryC *entry; // Pointer to resource entry Widget w; // Widget that entry corresponds to (could be ancestor) int dist; // Generations to ancestor EntryDataC() { Clear(); } EntryDataC(const EntryDataC& ed) { *this = ed; } EntryDataC& operator=(const EntryDataC& ed) { entry = ed.entry; w = ed.w; dist = ed.dist; return *this; } void Clear() { entry = NULL; w = NULL; dist = BIG_DIST; } void Reset() {//// Remove entry from any lists// win->quickList2.remove(entry); win->contList2.remove(entry); win->helpList2.remove(entry);//// Delete entry// delete entry; Clear(); } void Init(Widget wid, PtrList2& list);};/*--------------------------------------------------------------- * Class to show how all resource entries apply to a specific widget */class RecDataC {public: EntryDataC quick; // Info for quickHelp resource EntryDataC cont; // Info for contextHelp resource EntryDataC help; // Info for helpcard resource RecDataC() {} RecDataC(const RecDataC& rd) { *this = rd; } RecDataC& operator=(const RecDataC& rd) { quick = rd.quick; cont = rd.cont; help = rd.help; return *this; }};/*--------------------------------------------------------------- * Class to represent a widget in the interface */class WidgetRecC {public: Widget w; // This widget StringC shortName; // *shell*parent.widget StringC longName; // All ancestors VItemC *item; // View item in view box RecDataC orig; // As found in Xrm database RecDataC edit; // As modified by user WidgetRecC() { w = NULL; item = NULL; } WidgetRecC(const WidgetRecC& wr) { item = NULL; *this = wr; } WidgetRecC(Widget w) { item = NULL; *this = w; } WidgetRecC& operator=(const WidgetRecC& wr) { w = wr.w; shortName = wr.shortName; longName = wr.longName; orig = wr.orig; edit = wr.edit; return *this; } WidgetRecC& operator=(Widget wid) { w = wid; GetShortName(w, shortName); GetLongName (w, longName); FindEntries(); UpdateItem(); return *this; } void FindEntries(); void UpdateItem(); ResEntryC *QuickEntry() { return (edit.quick.entry ? edit.quick.entry : orig.quick.entry); } EntryDataC *QuickData() { return (edit.quick.entry ? &edit.quick : &orig.quick); } ResEntryC *ContEntry() { return (edit.cont.entry ? edit.cont.entry : orig.cont.entry); } EntryDataC *ContData() { return (edit.cont.entry ? &edit.cont : &orig.cont); } ResEntryC *HelpEntry() { return (edit.help.entry ? edit.help.entry : orig.help.entry); } EntryDataC *HelpData() { return (edit.help.entry ? &edit.help : &orig.help); } Boolean Modified() { return (edit.quick.entry || edit.cont.entry || edit.help.entry); } void Reset() { edit.quick.Reset(); edit.cont.Reset(); edit.help.Reset(); }};/*--------------------------------------------------------------- * Parse a resource line into its components */voidResEntryC::Parse(){//// Break at colon// int pos = full.PosOf(':'); rspec = full(0,pos); val = full(pos+1, full.size()); val.Trim();//// Remove resource part after last dot or star// int dpos = rspec.RevPosOf('.'); int spos = rspec.RevPosOf('*'); if ( dpos >= 0 && spos >= 0 ) pos = MAX(dpos, spos); else if ( dpos >= 0 ) pos = dpos; else pos = spos; if ( pos >= 0 ) { binding = rspec[pos]; res = rspec(pos+1,rspec.Length()); wspec = rspec(0,pos); } else { wspec = rspec; binding = '.'; }} // End Parse/*--------------------------------------------------------------- * See if a resource line applies to a widget. If it does, return the * widget from which it was inherited and the number of generations * of separation */BooleanResEntryC::AppliesTo(Widget w, Widget *wsrc, int *dist){ if ( wsrc ) *wsrc = NULL; if ( dist ) *dist = 0; char *name = XtName(w); if ( binding == '.' ) {//// Must end with widget name// if ( !wspec.EndsWith(name) ) return False; } else if ( binding == '*' ) {//// Must end with name of an ancestor// while ( w && !wspec.EndsWith(name) ) { if ( dist ) (*dist)++; w = XtParent(w); if ( w ) name = XtName(w); } if ( !w ) return False; } else return False; if ( wsrc ) *wsrc = w;//// Now examine rest of spec to make sure it matches// CharC spec = wspec; spec.CutEnd(strlen(name)); while ( spec.Length() > 0 ) { char sep = spec.LastChar(); if ( sep == '.' ) { spec.CutEnd(1);//// Next component must be immediate parent// w = XtParent(w); if ( !w ) return False; name = XtName(w); if ( !spec.EndsWith(name) ) return False; spec.CutEnd(strlen(name)); } else if ( sep == '*' ) { spec.CutEnd(1);//// Next component must be any ancestor or NULL// if ( spec.Length() == 0 ) return True;//// Extract next component// int dpos = spec.RevPosOf('.'); int spos = spec.RevPosOf('*'); int pos = dpos; if ( pos >= 0 ) pos = MAX(dpos,spos); else pos = spos; CharC comp; if ( pos < 0 ) comp = spec; else comp = spec(pos+1,spec.Length());//// Look for an ancestor widget with this name// Widget par = XtParent(w); while ( par && XtName(par) != comp ) par = XtParent(par); if ( !par ) return False; w = par; spec.CutEnd(comp.Length()); } // End if separator is '*' else return False; } // End for each element in widget spec return True;} // End AppliesTo/*--------------------------------------------------------------- * Look for matching resources for a widget in a resource list */voidEntryDataC::Init(Widget wid, PtrList2& list){ Clear();//// Loop through resource entries// u_int count = list.size(); for (int i=0; i<count; i++) { ResEntryC *ent = (ResEntryC*)list[i]; int wdist; Widget wsrc;//// See if this entry applies// if ( ent->AppliesTo(wid, &wsrc, &wdist) && wdist < dist ) { entry = ent; w = wsrc; dist = wdist; } }} // End EntryDataC::Init/*--------------------------------------------------------------- * Find all resources for our widget */voidWidgetRecC::FindEntries(){//// Look up original entries. If there is a matching entry in the 2 list,// it could come from this widget or from an ancestor. If it comes from// an ancestor, it is not an edit.// edit.quick.Init(w, win->quickList2); orig.quick.Init(w, win->quickList); if ( edit.quick.w != w ) { if ( edit.quick.dist < orig.quick.dist ) orig.quick = edit.quick; edit.quick.Clear(); } edit.cont.Init(w, win->contList2); orig.cont.Init(w, win->contList); if ( edit.cont.w != w ) { if ( edit.cont.dist < orig.cont.dist ) orig.cont = edit.cont; edit.cont.Clear(); } edit.help.Init(w, win->helpList2); orig.help.Init(w, win->helpList); if ( edit.cont.w != w ) { if ( edit.cont.dist < orig.cont.dist ) orig.cont = edit.cont; edit.cont.Clear(); }} // End FindEntries/*--------------------------------------------------------------- * Update the fields in the view item */voidWidgetRecC::UpdateItem(){ if ( !item ) return; item->SetFieldTag(QUICK_FIELD, edit.quick.entry ? "bold" : "plain"); item->SetFieldTag(CONT_FIELD, edit.cont.entry ? "bold" : "plain"); item->SetFieldTag(HELP_FIELD, edit.help.entry ? "bold" : "plain"); static char *no = "No"; static char *na = "N/A"; static char *yes = "Yes"; static char *in = "Inherit"; XpmT pm = green_xpm; char *tmp = no; EntryDataC *data = QuickData(); if ( data->entry ) { if ( data->w == w ) tmp = yes; else tmp = in; } item->Field(QUICK_FIELD, tmp); if ( tmp == no ) pm = red_xpm; tmp = no; data = ContData(); if ( data->entry ) { if ( data->w == w ) tmp = yes; else tmp = in; } item->Field(CONT_FIELD, tmp); if ( tmp == no ) pm = red_xpm; tmp = no; data = HelpData(); if ( data->entry ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -