codegen.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:37k
- /*
- * codegen.cxx
- *
- * Resource compiler C++ code generator
- *
- * Portable Windows Library
- *
- * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Portable Windows Library.
- *
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
- * All Rights Reserved.
- *
- * Contributor(s): ______________________________________.
- *
- * $Log: codegen.cxx,v $
- * Revision 1.4 2000/06/21 02:15:25 robertj
- * Removed some warnings on compiling colour icons.
- *
- * Revision 1.3 1999/10/18 04:41:09 robertj
- * Added decompile of .BMP and .ICO files and fixed ability to have 64x64 icons
- *
- * Revision 1.2 1998/09/26 01:24:02 robertj
- * Added open source license
- *
- * Revision 1.1 1998/09/26 00:46:21 robertj
- * Initial revision
- *
- * Revision 1.22 1998/09/14 13:45:02 robertj
- * Allowed suppression of some warnings.
- *
- * Revision 1.21 1996/05/23 10:06:38 robertj
- * Fixed bug in OK/Cancel buttons of dialogs not being set as special buttons.
- *
- * Revision 1.20 1996/01/23 13:32:41 robertj
- * More changes for editor
- *
- * Revision 1.19 1995/12/23 03:51:05 robertj
- * Removed multiple classes for Layout types.
- * Added extra collections for editor use.
- *
- * Revision 1.18 1995/12/10 12:11:57 robertj
- * Changes to support graphical resource file editor.
- *
- * Revision 1.17 1995/10/14 15:19:07 robertj
- * Fixed missing font size on font keyword.
- * Changes required by move of standard buttons to PDialog.
- *
- * Revision 1.16 1995/08/24 12:46:38 robertj
- * Removed redundant parent parameter for ConstructEnd().
- *
- * Revision 1.14 1995/07/31 12:30:10 robertj
- * Changed all generated resource IDs to be in the same "number space". This
- * is to avoid problems with IDs being used for more than one type of resource
- * eg a menu item and an image for a toolbar.
- * Fixed the generated #line commands to include a relative path instead of an
- * absolute one.
- *
- * Revision 1.13 1995/04/02 09:28:12 robertj
- * Added "balloon" help.
- *
- * Revision 1.12 1995/02/19 04:19:25 robertj
- * Added dynamically linked command processing.
- *
- // Revision 1.11 1995/02/11 04:13:18 robertj
- // Changed #include generated in .cxx file to not include full path.
- //
- // Revision 1.10 1995/01/27 11:25:38 robertj
- // Added pattern resource.
- //
- */
- #include <ptlib.h>
- #include "pwrc.h"
- extern ResourceFile * current_file;
- /////////////////////////////////////////
- //
- // Line numbers from parser
- //
- ostream & operator<<(ostream & out, const LineNumber & line)
- {
- out << "n#line " << line.number << " "";
- PINDEX i;
- PDirectory dir;
- for (i = 0; i < dir.GetLength(); i++)
- if (dir[i] != line.filename[i])
- break;
- PString filestr = line.filename.Mid(i);
- if (filestr.Find('\') == P_MAX_INDEX)
- out << filestr;
- else {
- for (i = 0; i < filestr.GetLength(); i++) {
- if (filestr[i] != '\')
- out << filestr[i];
- else
- out << "\\";
- }
- }
- return out << ""n";
- }
- /////////////////////////////////////////
- //
- // key code structure
- //
- AccelCode::AccelCode(const PString & resrcStr)
- {
- value = NullValue;
- modifiers = NoModifier;
- PCaselessString code(resrcStr(1, resrcStr.GetLength()-2));
- if (code.IsEmpty())
- return;
- PINDEX pos;
- if ((pos = code.Find("shift+")) != P_MAX_INDEX) {
- code.Delete(pos, 6);
- modifiers |= Shift;
- }
- if ((pos = code.Find("ctrl+")) != P_MAX_INDEX) {
- code.Delete(pos, 5);
- modifiers |= Control;
- }
- if ((pos = code.Find("alt+")) != P_MAX_INDEX) {
- code.Delete(pos, 4);
- modifiers |= Alt;
- }
- if ((pos = code.Find("cmd+")) != P_MAX_INDEX) {
- code.Delete(pos, 4);
- modifiers |= Command;
- }
- if ((pos = code.Find("opt+")) != P_MAX_INDEX) {
- code.Delete(pos, 4);
- modifiers |= Option;
- }
- if ((pos = code.Find("acc1+")) != P_MAX_INDEX) {
- code.Delete(pos, 5);
- modifiers |= Accelerator1;
- }
- if ((pos = code.Find("acc2+")) != P_MAX_INDEX) {
- code.Delete(pos, 5);
- modifiers |= Accelerator2;
- }
- static PCaselessString simpleCode("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
- static PString keypadCode("0123456789+-*/,.");
- switch (code.GetLength()) {
- case 1 :
- if ((pos = simpleCode.Find(code[0])) != P_MAX_INDEX)
- value = (Value)(pos + PKeyCode::A);
- break;
- case 2 :
- if (code(0,0) == "F" && code[1] >= '1' && code[1] <= '9')
- value = (Value)(code[1] - '1' + PKeyCode::F1);
- break;
-
- case 3 :
- if (code(0,1) == "KP" && (pos = keypadCode.Find(code[2])) != P_MAX_INDEX)
- value = (Value)(pos + PKeyCode::KP0);
- else if (code(0,1) == "F1" && code[2] >= '0' && code[2] <= '2')
- value = (Value)(code[2] - '0' + PKeyCode::F10);
- break;
- }
- if (value == NullValue) {
- static char *miscKeys[] = {
- "Up", "Down", "Left", "Right", "PgUp", "PgDn", "Home", "End",
- "Ins", "Del", "Undo", "Cut", "Copy", "Paste", "Clear", "Cancel",
- "Help", "Quit", "BkSp", "Tab", "Ret", "Esc", " "
- };
- for (PINDEX i = 0; i < PARRAYSIZE(miscKeys); i++) {
- if (code == miscKeys[i]) {
- value = (Value)(i + PKeyCode::Up);
- break;
- }
- }
- if (value == NullValue)
- PError << StdError(Fatal) << "Unknown accelerator code " << resrcStr << endl;
- }
- }
- /////////////////////////////////////////
- //
- // point for resource position
- //
- Point::Point(long nx, long ny)
- {
- if (nx < -32767 || nx > 32767 || ny < -32767 || ny > 32767)
- PError << StdError(Warning)
- << "position must be 16 bit, truncating." << endl;
- x = (int)nx;
- y = (int)ny;
- }
- void Point::SetX(long nx)
- {
- if (nx < -32767 || nx > 32767)
- PError << StdError(Warning)
- << "position must be 16 bit, truncating." << endl;
- x = (int)nx;
- }
- void Point::SetY(long ny)
- {
- if (ny < -32767 || ny > 32767)
- PError << StdError(Warning)
- << "position must be 16 bit, truncating." << endl;
- y = (int)ny;
- }
- Point & Point::operator=(const Point & pt)
- {
- x = pt.x;
- y = pt.y;
- return *this;
- }
- /////////////////////////////////////////
- //
- // a resource item which has an id and a string
- //
- ResourceObject::ResourceObject(ResourceID * newId, PString * newText)
- {
- SetID(newId);
- SetText(newText);
- }
- void ResourceObject::SetText(PString * newText)
- {
- if (newText != NULL) {
- textLiteral = *newText;
- delete newText;
- textConverted = PString(PString::Literal, textLiteral);
- if (textConverted.GetLength() > 255) {
- textLiteral = textLiteral(0,254);
- PError << StdError(Warning)
- << "string too long, may be truncated to 255 characters." << endl;
- }
- }
- }
- void ResourceObject::SetID(ResourceID * newId)
- {
- if (newId == NULL)
- id = -1;
- else {
- long num = newId->GetNum();
- if (num < -32767 || num > 65535)
- PError << StdError(Warning)
- << "resource ID must be 16 bit, truncating." << endl;
- id = (int)num;
- identifier = newId->GetIdent();
- delete newId;
- }
- }
- PString ResourceObject::GetIDString() const
- {
- if (identifier.IsEmpty())
- return PString(PString::Unsigned, id);
- return identifier;
- }
- PObject::Comparison ResourceObject::Compare (const PObject & obj) const
- {
- int otherId = ((const ResourceObject &)obj).id;
- if (id < otherId)
- return LessThan;
- if (id > otherId)
- return GreaterThan;
- return EqualTo;
- }
- PINDEX ResourceObject::HashFunction() const
- {
- return PABSINDEX(id)%23;
- }
- /////////////////////////////////////////
- //
- // A resource with a class specification
- //
- ClassedResource::ClassedResource(const char * className)
- : resourceClass(className)
- {
- }
- ClassedResource::ClassedResource(PString * className)
- : resourceClass(*className)
- {
- delete className;
- }
- ClassedResource::ClassedResource(PString * className, PString * ancestorName)
- : resourceClass(*className),
- ancestorClass(*ancestorName)
- {
- delete className;
- delete ancestorName;
- }
- void ClassedResource::SetResClass(const PString & newClassname)
- {
- resourceClass = newClassname;
- classLine.Set();
- }
- /////////////////////////////////////////
- //
- // menu items
- //
- void MenuItem::SetFieldName(PString * newFieldName)
- {
- fieldName = *newFieldName;
- delete newFieldName;
- fieldLine.Set();
- }
- void MenuItem::SetNotify(PString * newNotify)
- {
- notifyName = *newNotify;
- if (notifyName(0,1) == "::")
- PError << StdError(Fatal)
- << "menu item notify cannot be non-member function." << endl;
- delete newNotify;
- notifyLine.Set();
- }
- void MenuItem::SetAccelerators(PStringList * newAcc)
- {
- if (newAcc != NULL) {
- for (PINDEX i = 0; i < newAcc->GetSize(); i++) {
- AccelCode key((*newAcc)[i]);
- if (key.GetValue() != PKeyCode::NullValue)
- accel.Append(new PKeyCode(key));
- }
- delete newAcc;
- }
- }
- BOOL MenuItem::NeedsWindowParameter() const
- {
- return !notifyName.IsEmpty() && notifyName[0] != '"';
- }
- void MenuItem::OutputCode(ostream & hdr_stream,
- ostream & src_stream, MenuBar & mbar)
- {
- hdr_stream << hdr_before;
- src_stream << src_before;
- if (!notifyName.IsEmpty()) {
- PINDEX i;
- for (i = 0; i < mbar.itemDict.GetSize(); i++)
- if (notifyName == mbar.itemDict.GetDataAt(i).notifyName)
- break;
- if (this == &mbar.itemDict.GetDataAt(i)) {
- src_stream << notifyLine << " PNotifier notifier_";
- if (notifyName[0] == '"')
- src_stream << notifyName(1, notifyName.GetLength()-2)
- << " = PCREATE_COMMAND(";
- else {
- src_stream << notifyName << " = PCREATE_NOTIFIER2(wnd, ";
- if (notifyName.Find("::") == P_MAX_INDEX)
- src_stream << mbar.window << "::";
- }
- src_stream << notifyName << ");n";
- }
- src_stream << " keyedItems[" << id << "].SetNotifier(notifier_";
- if (notifyName[0] == '"')
- src_stream << notifyName(1, notifyName.GetLength()-2) << ", TRUE";
- else
- src_stream << notifyName;
- src_stream << ");n";
- }
- if (!fieldName.IsEmpty()) {
- hdr_stream << fieldLine
- << " PMenuItem * " << fieldName << ";n";
- src_stream << fieldLine
- << " " << fieldName << " = GetItemFromKey(" << id << ");n";
- }
- hdr_stream << hdr_after;
- src_stream << src_after;
- }
- /////////////////////////////////////////
- //
- // sub-menus
- //
- Menu::Menu(PString * title, MenuItemList * newItems)
- : MenuItem(NULL),
- items(*newItems)
- {
- delete newItems;
- SetText(title);
- }
- void Menu::SetUniqueItemIDs(MenuItemDict & itemDict)
- {
- for (PINDEX i = 0; i < items.GetSize(); i++) {
- if (items[i].IsClass(Menu::Class()))
- ((Menu&)items[i]).SetUniqueItemIDs(itemDict);
- else {
- if (items[i].GetID() == -1) {
- items[i].SetID(current_file->GetUniqueIdentifierValue(itemDict));
- itemDict.SetAt(items[i].GetID(), &items[i]);
- }
- }
- }
- }
- /////////////////////////////////////////
- //
- // menubar
- //
- MenuBar::MenuBar(ResourceID * newID)
- {
- ancestorClass = "PRootMenu";
- SetID(newID);
- itemDict.DisallowDeleteObjects();
- }
- void MenuBar::SetWindow(PString * newWindow)
- {
- window = *newWindow;
- delete newWindow;
- windowLine.Set();
- }
- void MenuBar::SetMenuList(MenuList * newMenus)
- {
- menus = *newMenus;
- delete newMenus;
- for (PINDEX i = 0; i < menus.GetSize(); i++)
- menus[i].SetUniqueItemIDs(itemDict);
- }
- void MenuBar::OutputCode(ostream & hdr_stream, ostream & src_stream)
- {
- // if the class definition does not contain a class name or window
- // the the generation of any output is supressed
- if (resourceClass.IsEmpty()) {
- PError << StdError(Info, firstLine)
- << "code generation supressed due to omission of class namen";
- return;
- }
- BOOL needsWindowParameter = FALSE;
- PINDEX i;
- for (i = 0; i < itemDict.GetSize(); i++)
- if (itemDict.GetDataAt(i).NeedsWindowParameter()) {
- needsWindowParameter = TRUE;
- break;
- }
- if (needsWindowParameter && window.IsEmpty()) {
- PError << StdError(Info, firstLine)
- << "code generation supressed due to omission of window namen";
- return;
- }
- hdr_stream << hdr_before
- << classLine
- << "PDECLARE_CLASS(" << resourceClass
- << ", " << ancestorClass << ")n"
- << " public:"
- << windowLine
- << " " << resourceClass << '(';
- if (needsWindowParameter)
- hdr_stream << window << " * wnd";
- hdr_stream << ");n";
- src_stream << "nnn// " << resourceClass << "n"
- << src_before
- << classLine
- << resourceClass << "::" << resourceClass << '(';
- if (needsWindowParameter)
- src_stream << windowLine << window << " * wnd";
- src_stream << ")n : " << ancestorClass << '(' << id << ")n{n";
- for (i = 0; i < itemDict.GetSize(); i++)
- itemDict.GetDataAt(i).OutputCode(hdr_stream, src_stream, *this);
- hdr_stream << hdr_after << "};n";
- src_stream << src_after << "}n";
- }
- /////////////////////////////////////////
- //
- // A resource with a class specification and a position
- //
- ComplexResource::ComplexResource(const char * className)
- : ClassedResource(className),
- dim(0, 0)
- {
- dim_set = FALSE;
- }
- void ComplexResource::SetDim(Point * newDim)
- {
- dim = *newDim;
- delete newDim;
- dim_set = TRUE;
- }
- void ComplexResource::SetPos(Point * newPos)
- {
- pos = *newPos;
- delete newPos;
- }
- /////////////////////////////////////////
- //
- // Control
- // The base control type
- //
- Control::Control(const char * className, const char * valType)
- : ComplexResource(className), valueType(valType)
- {
- options = 0;
- iconID = -1;
- }
- void Control::SetValueName(PString * newValuename, PString * newInitialiser)
- {
- if (valueType.IsEmpty())
- PError << StdError(Fatal)
- << "control class " << resourceClass
- << " cannot have a Value attribute." << endl;
- else {
- valueName = *newValuename;
- initialiser = *newInitialiser;
- valueLine.Set();
- }
- delete newValuename;
- delete newInitialiser;
- }
- void Control::SetFieldName(PString * newFieldName)
- {
- fieldName = *newFieldName;
- delete newFieldName;
- fieldLine.Set();
- }
- void Control::SetNotify(PString * newNotify)
- {
- notifyName = *newNotify;
- delete newNotify;
- notifyLine.Set();
- }
- void Control::SetOptions(long)
- {
- PError << StdError(Fatal)
- << "control class " << resourceClass
- << " cannot have an Options attribute." << endl;
- }
- void Control::SetLimits(long, long, long, long)
- {
- PError << StdError(Fatal)
- << "control class " << resourceClass
- << " cannot have a Limits attribute." << endl;
- }
- void Control::SetIcon(long)
- {
- PError << StdError(Fatal)
- << "control class " << resourceClass
- << " cannot have an icon attribute." << endl;
- }
- void Control::SetHelp(PString * newHelp)
- {
- balloonHelp = *newHelp;
- delete newHelp;
- }
- void Control::SetStringList(PStringList *)
- {
- PError << StdError(Fatal)
- << "control class " << resourceClass
- << " does not have an attached string list." << endl;
- }
- void Control::OutputCode(ostream & hdr_stream, ostream & src_stream,
- ostream & save, ostream & restore,
- PString & ok_button, PString & cancel_button,
- PString & help_button, Layout & layout)
- {
- hdr_stream << hdr_before;
- src_stream << src_before;
- // calculate the name and type of the "field" attribute
- // if the field attribute is local, then declare it
- // if it is global or static, then do NOT declare it
- // in any case, add the command to the constructor
- if (fieldName.IsEmpty()) {
- if ((options & OkButtonOption) != 0) {
- fieldName = "ok";
- fieldLine = layout.firstLine;
- }
- else if ((options & CancelButtonOption) != 0) {
- fieldName = "cancel";
- fieldLine = layout.firstLine;
- }
- else if ((options & HelpButtonOption) != 0) {
- fieldName = "help";
- fieldLine = layout.firstLine;
- }
- }
- else if (fieldName.Find("::") == P_MAX_INDEX)
- hdr_stream << fieldLine
- << " public: " << resourceClass << " * " << fieldName << ";n";
- PString idstr(PString::Unsigned, (long)id);
- // add the constructor for the control to the layout constructor string
- src_stream << classLine << " ";
- if (!fieldName.IsEmpty())
- src_stream << fieldName << " = ";
- src_stream << "PNEW " << resourceClass << "(this, " << idstr << ", ";
- // declare and implement the notify function
- if (notifyName.IsEmpty())
- src_stream << "PNotifier(), ";
- else if (notifyName[0] == '"')
- src_stream << "PCREATE_COMMAND(" << notifyName << "), ";
- else {
- src_stream << "PCREATE_NOTIFIER(";
- if (notifyName.Find("::") != P_MAX_INDEX) {
- PString local_notify = "_pnotify_" + idstr;
- hdr_stream << notifyLine
- << " private: PDECLARE_NOTIFIER(" << resourceClass << ", "
- << layout.resourceClass << ", " << local_notify << ")n"
- " { " << notifyName << "(note, extra); }n";
- src_stream << local_notify;
- }
- else {
- PINDEX i;
- for (i = 0; i < layout.itemDict.GetSize(); i++)
- if (notifyName == layout.itemDict.GetDataAt(i).notifyName)
- break;
- if (this == &layout.itemDict.GetDataAt(i))
- hdr_stream << notifyLine
- << " public: PDECLARE_NOTIFIER(" << resourceClass << ", "
- << layout.resourceClass << ", " << notifyName << ");n";
- src_stream << notifyName;
- }
- src_stream << "), ";
- }
- // if there is a value field, output the declaration and
- // add the command to the constructor
- if (valueName.IsEmpty())
- src_stream << "NULL);n";
- else {
- if (valueName.Find("::") == P_MAX_INDEX)
- hdr_stream << valueLine
- << " public: " << valueType << ' ' << valueName << ";n";
- // declare the "undo" buffer
- PString undo_name = "_psave_" + idstr;
- hdr_stream << " protected: " << valueType << ' ' << undo_name << ";n";
- src_stream << '&' << valueName << ");n";
- if (!initialiser.IsEmpty())
- src_stream << " " << valueName << " = " << initialiser << ";n";
- save << " " << undo_name << " = " << valueName << ";n";
- restore << " " << valueName << " = " << undo_name << ";n";
- }
- // grab ok, cancel and help buttons
- if ((options & OkButtonOption) != 0)
- ok_button = fieldName;
- else if ((options & CancelButtonOption) != 0)
- cancel_button = fieldName;
- else if ((options & HelpButtonOption) != 0)
- help_button = fieldName;
- hdr_stream << hdr_after;
- src_stream << src_after;
- }
- /////////////////////////////////////////
- //
- // ListControl
- // The base control type for list controls. This class exists because
- // the AddString and SetOptions functions are overrided from Control
- //
- ListControl::ListControl(const char * className, const char * valueType)
- : Control(className, valueType)
- {
- }
- void ListControl::SetOptions(long new_option)
- {
- if (new_option & ~(SortedOption|MultiSelectOption|MultiColumnOption|Special))
- PError << StdError(Fatal)
- << "invalid option for " << resourceClass << " control." << endl;
- else
- options |= new_option;
- }
- void ListControl::SetStringList(PStringList * newStringList)
- {
- strList = *newStringList; delete newStringList;
- }
- /////////////////////////////////////////
- //
- // LimitControl
- // The base control type for controls that support limits. This class exists
- // because the SetLimits functions is overrided from Control
- //
- LimitControl::LimitControl (const char * className, const char * valueType)
- : Control(className, valueType)
- {
- minimum = 0;
- maximum = 100;
- smallNudge = 1;
- largeNudge = 10;
- }
- void LimitControl::SetLimits(long min, long max, long sml, long lge)
- {
- minimum = min;
- maximum = max;
- smallNudge = sml;
- largeNudge = lge;
- }
- /////////////////////////////////////////
- //
- // control types
- //
- void PushButton::SetOptions(long new_option)
- {
- if (new_option & ~(OkButtonOption|CancelButtonOption|HelpButtonOption|DefaultButtonOption))
- PError << StdError(Fatal)
- << "invalid option for " << resourceClass << " control." << endl;
- else
- options |= new_option;
- }
- BOOL PushButton::Validate()
- {
- if ((options & OkButtonOption) != 0) {
- if (id != -1)
- PError << StdError(Warning)
- << "OK button should be ID 1." << endl;
- else
- id = 1;
- }
- else if ((options & CancelButtonOption) != 0) {
- if (id != -1)
- PError << StdError(Warning)
- << "Cancel button should be ID 2." << endl;
- else
- id = 2;
- }
- else if ((options & HelpButtonOption) != 0) {
- if (id != -1)
- PError << StdError(Warning)
- << "Help button should be ID 3." << endl;
- else
- id = 3;
- }
- return TRUE;
- }
- void StaticIcon::SetIcon(long icon)
- {
- if (icon < -32767 || icon > 65535)
- PError << StdError(Warning)
- << "icon ID must be 16 bit, truncating." << endl;
- iconID = (int)icon;
- }
- BOOL UserControl::Validate()
- {
- if (resourceClass.IsEmpty()) {
- PError << StdError(Fatal)
- << "User controls must have class defined." << endl;
- return FALSE;
- }
- return TRUE;
- }
- /////////////////////////////////////////
- //
- // add a control to a layout
- //
- Layout::Layout(const PString & ancestorName, int type)
- {
- subtype = type;
- fontSize = -1;
- itemDict.DisallowDeleteObjects();
- SetAncestorClass(ancestorName);
- }
- void Layout::SetFontInfo(PString * newFontname, int nsize)
- {
- fontName = *newFontname;
- delete newFontname;
- fontSize = nsize;
- }
- void Layout::SetHeader(PString * newHeader)
- {
- header = *newHeader;
- delete newHeader;
- }
- void Layout::AddControl(Control * newControl)
- {
- if (!newControl->Validate())
- return;
- if (itemDict.GetAt(newControl->GetID()) != NULL) {
- PError << StdError(Warning)
- << "ignoring multiple definition of dialog item "
- << newControl->GetID() << '.' << endl;
- return;
- }
- if (newControl->GetID() != -1)
- itemDict.SetAt(newControl->GetID(), newControl);
- itemList.Append(newControl);
- if (!dim_set) {
- Point ctl_pos = newControl->GetPos();
- Point ctl_dim = newControl->GetDim();
- int tmp = ctl_pos.X()+ctl_dim.X()+10;
- if (dim.X() < tmp)
- dim.SetX(tmp);
- tmp = ctl_pos.Y()+ctl_dim.Y()+10;
- if (dim.Y() < tmp)
- dim.SetY(tmp);
- }
- }
- void Layout::SetUniqueItemIDs()
- {
- for (PINDEX i = 0; i < itemList.GetSize(); i++)
- if (itemList[i].GetID() == -1) {
- itemList[i].SetID(current_file->GetUniqueIdentifierValue(itemDict));
- itemDict.SetAt(itemList[i].GetID(), &itemList[i]);
- }
- }
- void Layout::OutputCode(ostream & hdr_stream, ostream & src_stream)
- {
- // if the class definition does not contain a class name,
- // the the generation of any output is supressed
- if (resourceClass.IsEmpty()) {
- PError << StdError(Info, firstLine)
- << "code generation supressed due to omission of class namen";
- return;
- }
- src_stream << "nnn// " << resourceClass << "nn";
- // output class declaration and constructor code or Construct body
- if (header.IsEmpty()) {
- hdr_stream << classLine
- << "PDECLARE_CLASS(" << resourceClass << ", "
- << ancestorClass << ")n"
- << hdr_before
- << " public:n"
- << " " << resourceClass
- << "(PInteractor *, PRESOURCE_ID id = " << id << ");n";
- src_stream << classLine << resourceClass << "::" << resourceClass
- << "(PInteractor * parent, PRESOURCE_ID id)n"
- " : " << ancestorClass << "(parent, id)n"
- "{n";
- }
- else {
- hdr_stream << "#include " << header << "nn"
- << hdr_before
- << " public:n"
- " void Construct(PRESOURCE_ID id = " << id << ");n";
- src_stream << "void " << resourceClass << "::Construct(PRESOURCE_ID id)n"
- "{n";
- }
- src_stream << src_before;
- PStringStream layout_save, layout_restore;
- PString ok_button, cancel_button, help_button;
- for (PINDEX i = 0; i < itemList.GetSize(); i++)
- itemList[i].OutputCode(hdr_stream, src_stream,
- layout_save, layout_restore,
- ok_button, cancel_button, help_button,
- *this);
- // output public declarations and constructor declaration
- if (!layout_save.IsEmpty())
- hdr_stream << " public:n"
- " void Restore();n"
- " void Save();n";
- // finish class declaration
- hdr_stream << hdr_after << "n};nn";
- if (subtype == 0) {
- if (!ok_button.IsEmpty() || !cancel_button.IsEmpty())
- PError << StdError(Info, firstLine)
- << "layout defined with "Ok" or "Cancel" buttonn";
- }
- else {
- if (subtype == 2 && ok_button.IsEmpty() && cancel_button.IsEmpty())
- PError << StdError(Warning, firstLine)
- << "modal dialog defined without "Ok" or "Cancel" buttonn";
- src_stream << " SetStdButtons(";
- if (ok_button.IsEmpty())
- src_stream << "NULL";
- else
- src_stream << ok_button;
- src_stream << ", ";
- if (cancel_button.IsEmpty())
- src_stream << "NULL";
- else
- src_stream << cancel_button;
- src_stream << ", ";
- if (help_button.IsEmpty())
- src_stream << "NULL";
- else
- src_stream << help_button;
- src_stream << ");n";
- }
- src_stream << " ConstructEnd(id);n"
- << src_after
- << "}nn";
- // output the save and restore functions if there is something in them
- if (!layout_save.IsEmpty())
- src_stream << "void "
- << resourceClass
- << "::Save()n{n"
- << layout_save
- << "n}nnvoid "
- << resourceClass
- << "::Restore()n{n"
- << layout_restore
- << "n}nnn";
- }
- /////////////////////////////////////////
- //
- // holder for assorted binary data items
- //
- BinaryData::BinaryData()
- : PAbstractArray(sizeof(BYTE), 512),
- realSize(0)
- {
- }
- BinaryData::BinaryData(const BinaryData & array)
- : PAbstractArray(array),
- realSize(array.realSize)
- {
- }
- BinaryData & BinaryData::operator=(const BinaryData & array)
- {
- PAbstractArray::operator=(array);
- realSize = array.realSize;
- return *this;
- }
- void BinaryData::Append (int newSize, const BYTE * newData)
- {
- if (realSize + newSize > PAbstractArray::GetSize())
- SetSize((PAbstractArray::GetSize() + newSize+511)&~511);
- memcpy (theArray + realSize, newData, newSize);
- realSize += newSize;
- }
- /////////////////////////////////////////
- //
- // pixel resource objects
- //
- PixelContents::PixelContents()
- {
- haveDimensions = FALSE;
- haveHotSpot = FALSE;
- depth = 1;
- }
- void PixelContents::SetDimensions(long w, long h, long d)
- {
- if (w < -32767 || w > 32767 || h < -32767 || h > 32767)
- PError << StdError(Warning)
- << "image dimensions must be 16 bit, truncating." << endl;
- if (d < 0 || d > 32767)
- PError << StdError(Warning)
- << "image depth must be 16 bit, truncating." << endl;
- width = (int)w;
- height = (int)h;
- depth = (int)d;
- haveDimensions = TRUE;
- }
-
- void PixelContents::SetHotSpot(long hx, long hy)
- {
- if (hx < -32767 || hx > 32767 || hy < -32767 || hy > 32767)
- PError << StdError(Warning)
- << "image position must be 16 bit, truncating." << endl;
- x = (int)hx;
- y = (int)hy;
- haveHotSpot = TRUE;
- }
- void PixelContents::SetClut(BinaryData * data)
- {
- clut = *data;
- delete data;
- }
- void PixelContents::SetAndMask(PixData * data)
- {
- andMask = *data;
- delete data;
- }
- void PixelContents::SetXorMask(PixData * data)
- {
- xorMask = *data;
- delete data;
- }
- void PixelContents::SetPixels(PixData * data)
- {
- pixels = *data;
- delete data;
- }
- void PixelContents::Verify(int dfltWidth, int dfltHeight, const char * resname,
- BOOL masks, BOOL allowScaling)
- {
- if (haveDimensions) {
- if ((dfltWidth != 0 && width != dfltWidth && (!allowScaling || (width != dfltWidth*2 && width != dfltWidth/2))) ||
- (dfltHeight != 0 && height != dfltHeight && (!allowScaling || (height != dfltHeight*2 && height != dfltHeight/2))))
- PError << StdError(Warning)
- << resname << " dimensions should be "
- << dfltWidth << 'x' << dfltHeight << '.' << endl;
- }
- else {
- if (dfltWidth != 0) { // Is Pixmap
- width = dfltWidth;
- height = dfltHeight;
- }
- else {
- PError << StdError(Fatal)
- << resname << " must have a dimension." << endl;
- return;
- }
- }
- if (depth != 1 && depth != 4 && depth != 8 && depth != 24) {
- PError << StdError(Fatal)
- << resname << " should have depth of 1, 4, 8 or 24 bits." << endl;
- return;
- }
- if (clut.GetSize() != 0 || (depth != 1 && depth != 24)) {
- int clutSize = (1 << depth)*3;
- if (clut.GetSize() != (PINDEX)clutSize) {
- PError << StdError(Warning)
- << resname << " should have "
- << clutSize << " bytes of colour data ("
- << clut.GetSize() << " found)." << endl;
- clut.SetSize((PINDEX)clutSize);
- }
- }
- if (clut.GetSize() == 0) {
- int numColours = 1 << depth;
- int inc = (256+numColours-1)/numColours;
- int val = 0;
- for (int col = 0; col < numColours-1; col++) {
- clut.Append((BYTE)val);
- clut.Append((BYTE)val);
- clut.Append((BYTE)val);
- val += inc;
- }
- clut.Append(0xff);
- clut.Append(0xff);
- clut.Append(0xff);
- }
- if (!masks || depth != 1) { // Is Pixmap or colour icon/cursor
- long pixSize = width*height;
- if (depth == 24)
- pixSize *= 3;
- if (pixels.GetSize() != (PINDEX)pixSize) {
- PError << StdError(Warning)
- << resname << " should have "
- << pixSize << " pixels ("
- << pixels.GetSize() << " found)." << endl;
- pixels.SetSize((PINDEX)pixSize);
- }
- }
- if (masks) { // Is Icon or Cursor
- long maskSize = width*height;
- if (andMask.GetSize() != (PINDEX)maskSize) {
- PError << StdError(Warning)
- << resname << " should have "
- << maskSize << " pixels of AND mask data ("
- << andMask.GetSize() << " found)." << endl;
- andMask.SetSize((PINDEX)maskSize);
- }
- if (depth == 1 && xorMask.GetSize() != (PINDEX)maskSize) {
- PError << StdError(Warning)
- << resname << " should have "
- << maskSize << " pixels of XOR mask data ("
- << xorMask.GetSize() << " found)." << endl;
- xorMask.SetSize((PINDEX)maskSize);
- }
- }
- }
- /////////////////////////////////////////
- //
- // pixel based resources
- //
- PixelResource::PixelResource(ResourceID * newId, PixelContents * newContents)
- : ResourceObject(newId, NULL),
- contents(*newContents)
- {
- delete newContents;
- }
- /////////////////////////////////////////
- //
- // icon resources
- //
- Icon::Icon(ResourceID * id, PixelContents * newContents)
- : PixelResource(id, newContents)
- {
- contents.Verify(32, 32, "icon", TRUE, TRUE);
- }
- /////////////////////////////////////////
- //
- // cursor resources
- //
- CursorResource::CursorResource(ResourceID * id, PixelContents * newContents)
- : PixelResource(id, newContents)
- {
- contents.Verify(16, 16, "cursor", TRUE, FALSE);
- if (!contents.haveHotSpot) {
- PError << StdError(Info)
- << "cursor should have a HOTSPOT, assuming 1,1." << endl;
- contents.x = contents.y = 1;
- }
- }
- /////////////////////////////////////////
- //
- // pattern resources
- //
- Pattern::Pattern(ResourceID * id, PixelContents * newContents)
- : PixelResource(id, newContents)
- {
- contents.Verify(8, 8, "pattern", FALSE, FALSE);
- }
- /////////////////////////////////////////
- //
- // image resources
- //
- Image::Image(ResourceID * id, PixelContents * newContents)
- : PixelResource(id, newContents)
- {
- contents.Verify(0, 0, "image", FALSE, FALSE);
- }
- /////////////////////////////////////////
- //
- // arbitrary data resources
- //
- DataResource::DataResource(ResourceID * id,
- PString * newText, BinaryData * newData)
- : ResourceObject(id, NULL), data(*newData)
- {
- delete newData;
- if (newText != NULL) {
- textLiteral = *newText;
- delete newText;
- textConverted = PString(PString::Literal, textLiteral);
- if (textConverted.GetLength() < 4) {
- textConverted += " ";
- textConverted = textConverted(0,3);
- PError << StdError(Info)
- << "resource type name too short, spaced out to 4 characters."
- << endl;
- }
- else if (textConverted.GetLength() > 4) {
- textConverted = textConverted(0,3);
- PError << StdError(Warning)
- << "resource type name too long, truncated to 4 characters."
- << endl;
- }
- }
- }
- /////////////////////////////////////////
- //
- // resource file data
- //
- void ResourceFile::OutputCode(const PFilePath & hdrname,
- ostream & hdr_stream, ostream & src_stream, BOOL suppressFlag)
- {
- src_stream << "//n// Source file generated by PWRCn//nn";
- if (!suppressFlag)
- src_stream << "#include <pwlib.h>n"
- "#include "" << hdrname.GetFileName() << ""nn";
- hdr_stream << "//n// Header file generated by PWRCn//nn"
- << "#ifndef _PWRC_GENERATED_HEADERn"
- << "#define _PWRC_GENERATED_HEADERnn"
- << hdr_inline;
- src_stream << src_inline;
- PINDEX i;
- for (i = 0; i < menubarDict.GetSize(); i++)
- menubarDict.GetDataAt(i).OutputCode(hdr_stream, src_stream);
- for (i = 0; i < dialogDict.GetSize(); i++)
- dialogDict.GetDataAt(i).OutputCode(hdr_stream, src_stream);
- hdr_stream << "n#endifnn";
- }
- ResourceID * ResourceFile::GetAutoIdentifier(PString * identifier,
- const PAbstractDictionary & dict)
- {
- PString ident = *identifier;
- if (defineDict.GetAt(ident) != NULL)
- return PNEW ResourceID(GetIdentifierValue(identifier), ident);
- while (dict.GetAt(nextResourceId) != NULL)
- nextResourceId++;
- hdr_inline << LineNumber()
- << "#define " << ident << ' ' << nextResourceId << 'n';
- AddDefineIdentifier(identifier, new DefineValue(nextResourceId, TRUE));
- return PNEW ResourceID(nextResourceId, ident);
- }
- ResourceID *
- ResourceFile::GetUniqueIdentifierValue(const PAbstractDictionary & dict)
- {
- while (dict.GetAt(nextResourceId) != NULL)
- nextResourceId++;
- return PNEW ResourceID(nextResourceId++);
- }
- void ResourceFile::AddDefineIdentifier(PString * identifer,DefineValue * value)
- {
- if (defineDict.GetAt(*identifer) == NULL)
- defineDict.SetAt(*identifer, value);
- else {
- PError << StdError(Warning)
- << "ignoring redefinition of macro "" << *identifer << ""." << endl;
- delete value;
- }
- delete identifer;
- }
- int ResourceFile::GetIdentifierValue(PString * identifier)
- {
- PString id = *identifier;
- delete identifier;
- if (defineDict.GetAt(id) == NULL) {
- PError << StdError(Fatal)
- << "reference to undefined macro "" << id << ""." << endl;
- return 1;
- }
- if (defineDict[id].IsString()) {
- PError << StdError(Fatal)
- << "macro "" << id << "" of incorrect type." << endl;
- return 1;
- }
- return (int)defineDict[id];
- }
- void ResourceFile::AddResource(ResourceList::ResTypes res,
- ResourceObject * obj, const char * resname)
- {
- if (obj->GetID() == -1)
- obj->SetID(GetUniqueIdentifierValue(*resourceDict[res]));
- if (resourceDict[res]->GetAt(obj->GetID()) == NULL) {
- resourceDict[res]->SetAt(obj->GetID(), obj);
- resources[res].Append(obj);
- }
- else {
- PError << StdError(Warning)
- << "ignoring redefinition of " << resname << " resource number "
- << obj->GetID() << '.' << endl;
- delete obj;
- }
- }
- // End CODEGEN.CXX ////////////////////////////////////////////////////////////