Module: environment-project-wizard Author: Hugh Greene Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// ---*** ISSUES // - Win32-specific code will have to be factored out if/when we port. // - We could probably really do with an "Add thing to project ..." Wizard, // which could cover adding CORBA clients, new modules, new DUIM frame/ // sheet/gadget classes, new collection classes, etc. The set of things // which could be added could be dynamically extensible. // (After writing the next note, I realised that each "thing" might add // different constraints, and some might be incompatible, so you'd have // to check when adding a new "thing". You might also want to warn the // user if they later change project settings and break these constraints.) // - This Wizard is really doing about five different things, which could // probably do with being split up or restructured. // 1) Choose a name and location for the project. // 2) Choose (some of) the project settings. // 3) Choose arbitrary libraries and modules (from the repository). // 4) "Mix in" *one* kind of "project type" functionality, which may // require additional libraries and place constraints on some // settings. (E.g., OLE Control, OLE Type Library Interface, etc.) // 5) Choose template code to include, based on all the above. // - Please, someone, come up with a unified convention for slot/pane names // in this file and project-description.dylan! /// ---*** TO DO // - Finish off the class and friends, so that I // can have nicer help text layout. // - Test template projects, and un-comment-out the UI for them. (They // are implemented but completely untested and I'm out of time.) // - Make all mentions of "Functional Developer" refer to 'release-product-name' // instead of the literal string. // - Use environment{-,-warning,-error}-message instead of notify-user ... // except they're defined in environment-tools, which we don't want to // have to "use" here. /// ---------------------------------------------------------------------- /// MISCELLANEOUS DEFINITIONS define constant :: = one-of(#"exe", #"dll"); /// ---------------------------------------------------------------------- /// PROJECT-WIZARD IMAGE HANDLING define variable $wizard-image :: false-or() = #f; define variable $wizard-frame-icon :: false-or() = #f; define variable *wizard-images-initialized?* = #f; define function initialize-wizard-images () unless (*wizard-images-initialized?*) let _id = as(, "WIZARD"); //---*** Hack the size for now, since DUIM doesn't calculate it correctly. let _bitmap = read-image-as(, _id, #"bitmap", width: 165, height: 250); when (_bitmap) $wizard-image := _bitmap; end; let _id = as(, "AAC"); // Project window icon. let _image = read-image-as(, _id, #"small-icon"); when (_image) $wizard-frame-icon := _image; end; *wizard-images-initialized?* := #t end; end function; /// ---------------------------------------------------------------------- /// PROJECT-WIZARD PERSISTENT OPTIONS define settings () key-name "Wizard"; slot default-location :: = ""; slot default-start-function :: = "main"; slot default-author :: = "The name(s) of the author(s) of the project."; slot default-copyright :: = "(C) YYYY, YOUR-COMPANY. All rights reserved."; slot default-version :: = "A string used by your version control system."; slot default-compilation-mode :: = #"loose"; slot use-templates :: = #f; slot show-synopsis :: = #t; slot show-author :: = #t; slot show-copyright :: = #t; slot show-version :: = #f; end settings ; define constant $project-wizard-settings = make(); define function project-wizard-default-location () => (location :: ) let location = $project-wizard-settings.default-location; if (location.empty?) as(, element(user-projects-path() | #(), 0, default: working-directory())) else location end end function project-wizard-default-location; /// ---------------------------------------------------------------------- /// PROJECT-WIZARD STRINGS /* define table $project-wizard-strings = { #"custom-project-description" => #["A custom project is one created from scratch.", "You must provide a name and location for the project and you can", "change the default version information.", "You can choose which other libraries and modules to use in your project", "You can also provide information for the project and source file headers."], #"template-project-description" => #["A template project is one copied from another project.", "You must provide a new name and location for the copy and you can", "change the default version information."], #"wizard-intro" => vector(pair("This Wizard helps you to create a new %s project.", method () vector(release-product-name()) end)), #"chooser-description" => vector("This page lets you choose libraries your project will use,", pair("from groups of libraries provided with %s,", method () vector(release-product-name()) end), "and which modules to use from those libraries.", "Double-click on an item in one of the lists above to change", "whether it is used. Use the check box below each list", "to change multiple selected items at once."), #"headers-page-description" => #["This page lets you include some standard information", "in the project and source files this Wizard will create.", "To omit any of these keywords, leave their values blank."] }; */ define table $project-type-descriptions = { #"custom" => "A custom project is one created from scratch." " You must provide a name and location for the project and you can" "change the default version information." " You can choose which other libraries and modules to use in your project" " You can also provide information for the project and source file headers.", #"template" => "A template project is one copied from another project." " You must provide a new name and location for the copy and you can" " change the default version information." }; define table $strings-mentioning-environment-name = { #"wizard-intro" => "This Wizard helps you to create a new %s project.", #"chooser-help" => "This page lets you choose libraries your project will use," " from groups of libraries provided with %s, and which" " modules to use from those libraries." " Double-click on an item in one of the lists to change" " whether it is used. You can select multiple items and" " then use the buttons below each list to change several" " at once." }; define variable *wizard-strings-initialized?* = #f; define function initialize-wizard-strings () => () unless (*wizard-strings-initialized?*) for (string keyed-by key in $strings-mentioning-environment-name) $strings-mentioning-environment-name[key] := format-to-string($strings-mentioning-environment-name[key], release-product-name()); end; /* For multi-line text: for (value keyed-by key in $project-wizard-strings) for (i from 0 to size(value)) when (instance?(entry[i], )) let args-generator = tail(maybe-pair); entry[i] := apply(format-to-string(head(maybe-pair), args-generator())) end; end; end; */ *wizard-strings-initialized?* := #t; end; end function; /// ---------------------------------------------------------------------- /// PROJECT-WIZARD SUB-DIALOGS define function make-require-value-callback (value) => (callback :: ) method (gadget :: ) let val = gadget-value(gadget); // Require that there be a value and, if it's a string, it's non-empty. unless (val & (~instance?(val, ) | ~empty?(val))) beep(gadget); gadget-value(gadget) := value; end; end end function make-require-value-callback; /// Advanced Project Settings define sealed frame () // The name fields mustn't be empty. We reset them to the initial name. pane project-library-name-pane (frame) make(); pane project-module-name-pane (frame) make(); // The start function mustn't be empty. We reset it to the initial name. pane project-start-function-name-pane (frame) make(); // The version fields mustn't be empty. We reset them to the initial vals. pane project-major-version-pane (frame) make(, type: , max-width: 8); pane project-minor-version-pane (frame) make(, type: , max-width: 8); pane project-compilation-mode-pane (frame) make(, enabled?: ~(frame.project-compilation-mode-required?), items: #[#["&Interactive development mode", #"loose"], #["&Production mode", #"tight"]], value: #"loose", label-key: first, value-key: second); slot project-compilation-mode-required? :: , required-init-keyword: compilation-mode-required?:; pane project-win32-subsystem-pane (frame) make(, enabled?: ~(frame.project-win32-subsystem-required?) & frame.project-target-type ~= #"dll", items: #[#["Windows GUI", #"gui"], #["Windows Console", #"console"]], label-key: first, value-key: second); slot project-win32-subsystem-required? :: , required-init-keyword: win32-subsystem-required?:; constant slot project-target-type :: , required-init-keyword: target-type:; layout (frame) vertically (y-spacing: 4) grouping ("Library and module names", max-width: $fill) make(, y-spacing: 4, contents: vector(vector(make(