From 34bed39fc922bb4fcbb7a62d03e5fa57955e634b Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Fri, 13 May 2005 00:25:27 +0000 Subject: [PATCH] New files. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@21224 72102866-910b-0410-8b05-ffd578937521 --- DBModeler/AdaptorsPanel.h | 48 ++ DBModeler/AdaptorsPanel.m | 144 +++++ DBModeler/COPYING | 340 +++++++++++ DBModeler/DefaultColumnProvider.h | 39 ++ DBModeler/DefaultColumnProvider.m | 232 +++++++ DBModeler/EOAdditions.h | 36 ++ DBModeler/EOAdditions.m | 124 ++++ DBModeler/GNUmakefile | 37 ++ .../AttributeInspector.gorm/data.classes | 12 + .../AttributeInspector.gorm/data.info | Bin 0 -> 184 bytes .../AttributeInspector.gorm/objects.gorm | Bin 0 -> 9248 bytes DBModeler/Inspectors/AttributeInspector.h | 10 + DBModeler/Inspectors/AttributeInspector.m | 16 + DBModeler/Inspectors/GNUmakefile | 13 + .../RelationshipInspector.gorm/data.classes | 40 ++ .../RelationshipInspector.gorm/data.info | Bin 0 -> 184 bytes .../RelationshipInspector.gorm/objects.gorm | Bin 0 -> 14227 bytes DBModeler/Inspectors/RelationshipInspector.h | 21 + DBModeler/Inspectors/RelationshipInspector.m | 186 ++++++ DBModeler/KVDataSource.h | 48 ++ DBModeler/KVDataSource.m | 172 ++++++ DBModeler/MainModelEditor.h | 42 ++ DBModeler/MainModelEditor.m | 494 +++++++++++++++ DBModeler/Modeler.h | 40 ++ DBModeler/Modeler.m | 250 ++++++++ DBModeler/ModelerAttributeEditor.h | 49 ++ DBModeler/ModelerAttributeEditor.m | 252 ++++++++ DBModeler/ModelerEntityEditor.h | 54 ++ DBModeler/ModelerEntityEditor.m | 202 +++++++ DBModeler/ModelerTableEmbedibleEditor.h | 53 ++ DBModeler/ModelerTableEmbedibleEditor.m | 149 +++++ DBModeler/Resources/ClassProperty_On.tiff | Bin 0 -> 1352 bytes DBModeler/Resources/Key_On.tiff | Bin 0 -> 1106 bytes DBModeler/Resources/ModelDrag.tiff | Bin 0 -> 3477 bytes DBModeler/main.m | 40 ++ GDL2Palette/ConnectionInspector.h | 27 + GDL2Palette/ConnectionInspector.m | 572 ++++++++++++++++++ GDL2Palette/Foundation+Categories.h | 11 + GDL2Palette/Foundation+Categories.m | 74 +++ .../GDL2ConnectionInspector.gorm/data.classes | 26 + .../GDL2ConnectionInspector.gorm/data.info | Bin 0 -> 184 bytes .../GDL2ConnectionInspector.gorm/objects.gorm | Bin 0 -> 7046 bytes GDL2Palette/GDL2Palette.tiff | Bin 0 -> 1578 bytes GDL2Palette/GNUmakefile | 34 ++ GDL2Palette/IB+Categories.m | 40 ++ GDL2Palette/Palette.h | 9 + GDL2Palette/Palette.m | 13 + GDL2Palette/ResourceManager.h | 14 + GDL2Palette/ResourceManager.m | 93 +++ GDL2Palette/palette.table | 8 + 50 files changed, 4064 insertions(+) create mode 100644 DBModeler/AdaptorsPanel.h create mode 100644 DBModeler/AdaptorsPanel.m create mode 100644 DBModeler/COPYING create mode 100644 DBModeler/DefaultColumnProvider.h create mode 100644 DBModeler/DefaultColumnProvider.m create mode 100644 DBModeler/EOAdditions.h create mode 100644 DBModeler/EOAdditions.m create mode 100644 DBModeler/GNUmakefile create mode 100644 DBModeler/Inspectors/AttributeInspector.gorm/data.classes create mode 100644 DBModeler/Inspectors/AttributeInspector.gorm/data.info create mode 100644 DBModeler/Inspectors/AttributeInspector.gorm/objects.gorm create mode 100644 DBModeler/Inspectors/AttributeInspector.h create mode 100644 DBModeler/Inspectors/AttributeInspector.m create mode 100644 DBModeler/Inspectors/GNUmakefile create mode 100644 DBModeler/Inspectors/RelationshipInspector.gorm/data.classes create mode 100644 DBModeler/Inspectors/RelationshipInspector.gorm/data.info create mode 100644 DBModeler/Inspectors/RelationshipInspector.gorm/objects.gorm create mode 100644 DBModeler/Inspectors/RelationshipInspector.h create mode 100644 DBModeler/Inspectors/RelationshipInspector.m create mode 100644 DBModeler/KVDataSource.h create mode 100644 DBModeler/KVDataSource.m create mode 100644 DBModeler/MainModelEditor.h create mode 100644 DBModeler/MainModelEditor.m create mode 100644 DBModeler/Modeler.h create mode 100644 DBModeler/Modeler.m create mode 100644 DBModeler/ModelerAttributeEditor.h create mode 100644 DBModeler/ModelerAttributeEditor.m create mode 100644 DBModeler/ModelerEntityEditor.h create mode 100644 DBModeler/ModelerEntityEditor.m create mode 100644 DBModeler/ModelerTableEmbedibleEditor.h create mode 100644 DBModeler/ModelerTableEmbedibleEditor.m create mode 100644 DBModeler/Resources/ClassProperty_On.tiff create mode 100644 DBModeler/Resources/Key_On.tiff create mode 100644 DBModeler/Resources/ModelDrag.tiff create mode 100644 DBModeler/main.m create mode 100644 GDL2Palette/ConnectionInspector.h create mode 100644 GDL2Palette/ConnectionInspector.m create mode 100644 GDL2Palette/Foundation+Categories.h create mode 100644 GDL2Palette/Foundation+Categories.m create mode 100644 GDL2Palette/GDL2ConnectionInspector.gorm/data.classes create mode 100644 GDL2Palette/GDL2ConnectionInspector.gorm/data.info create mode 100644 GDL2Palette/GDL2ConnectionInspector.gorm/objects.gorm create mode 100644 GDL2Palette/GDL2Palette.tiff create mode 100644 GDL2Palette/GNUmakefile create mode 100644 GDL2Palette/IB+Categories.m create mode 100644 GDL2Palette/Palette.h create mode 100644 GDL2Palette/Palette.m create mode 100644 GDL2Palette/ResourceManager.h create mode 100644 GDL2Palette/ResourceManager.m create mode 100644 GDL2Palette/palette.table diff --git a/DBModeler/AdaptorsPanel.h b/DBModeler/AdaptorsPanel.h new file mode 100644 index 0000000..f029b67 --- /dev/null +++ b/DBModeler/AdaptorsPanel.h @@ -0,0 +1,48 @@ +#ifndef __AdaptorsPanel_H_ +#define __AdaptorsPanel_H_ + +/* + AdaptorsPanel.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + + +@interface AdaptorsPanel : NSObject +{ + NSWindow *_window; + NSBrowser *brws_adaptors; + NSButton *btn_ok; + NSButton *btn_cancel; + NSBox *_box; + NSTextField *_label; +} + +-(NSString *)runAdaptorsPanel; + +@end + + +#endif // __AdaptorsPanel_H + diff --git a/DBModeler/AdaptorsPanel.m b/DBModeler/AdaptorsPanel.m new file mode 100644 index 0000000..fb861a2 --- /dev/null +++ b/DBModeler/AdaptorsPanel.m @@ -0,0 +1,144 @@ +/** + AdaptorsPanel.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + +#include "AdaptorsPanel.h" +#include +static NSArray *_adaptorNames; + +@implementation AdaptorsPanel + +- (void) dealloc +{ + DESTROY(_window); + DESTROY(_adaptorNames); + /* released by window + _label + brws_adaptors + btn_ok + btn_cancel + */ + [super dealloc]; +} + +- (id) init +{ + if (self = [super init]) + { + _adaptorNames = RETAIN([EOAdaptor availableAdaptorNames]); + /* redo all these numbers so buttons and labels are on the right? */ + _window = [[NSWindow alloc] + initWithContentRect: NSMakeRect(200,200,200,300) + styleMask: NSBorderlessWindowMask | NSTitledWindowMask + backing: NSBackingStoreBuffered + defer: YES]; + + _label = [[NSTextField alloc] initWithFrame: NSMakeRect(5,275,80,20)]; + [_label setStringValue: @"New model"]; + [_label setEditable: NO]; + [_label setSelectable: NO]; + [_label setBezeled: NO]; + [_label setBordered: NO]; + [_label setBackgroundColor: [NSColor windowBackgroundColor]]; + + brws_adaptors = [[NSBrowser alloc] initWithFrame: NSMakeRect(5,30,190,240)]; + [brws_adaptors setDelegate: self]; + [brws_adaptors addColumn]; + [brws_adaptors setTitle: @"Available adaptors" ofColumn: 0]; + [brws_adaptors setAllowsEmptySelection: NO]; + [brws_adaptors setTarget:self]; + [brws_adaptors setDoubleAction:@selector(ok:)]; + + btn_ok = [[NSButton alloc] initWithFrame: NSMakeRect(5,5,50,20)]; + [btn_ok setTitle: @"ok"]; + [btn_ok setTarget: self]; + [btn_ok setAction: @selector(ok:)]; + + btn_cancel = [[NSButton alloc] initWithFrame: NSMakeRect(60,5,50,20)]; + [btn_cancel setTitle: @"cancel"]; + [btn_cancel setTarget: self]; + [btn_cancel setAction: @selector(cancel:)]; + + [[_window contentView] addSubview: _label]; + [[_window contentView] addSubview: brws_adaptors]; + [[_window contentView] addSubview: btn_ok]; + [[_window contentView] addSubview: btn_cancel]; + + RELEASE(_label); + RELEASE(brws_adaptors); + RELEASE(btn_ok); + RELEASE(btn_cancel); + } + return self; +} + +- (NSString *) runAdaptorsPanel +{ + NSString *selection; + BOOL response = NO; + + if ([NSApp runModalForWindow:_window] == NSRunAbortedResponse) + { + selection = nil; + } + else + { + selection = [[brws_adaptors selectedCell] stringValue]; + } + [_window orderOut:self]; + return selection; +} + +/* button actions */ + +- (void) ok: (id)sender +{ + [NSApp stopModalWithCode:NSRunStoppedResponse]; +} + +- (void) cancel: (id)sender +{ + [NSApp stopModalWithCode:NSRunAbortedResponse]; +} + +/* NSBrowser delegate stuff */ + +- (int) browser:(id)sender numberOfRowsInColumn:(int)column +{ + return [_adaptorNames count]; +} + +- (void)browser:(NSBrowser*)sender + willDisplayCell:(NSBrowserCell*)cell + atRow:(int)row + column:(int)column +{ + [cell setLeaf:YES]; + [cell setTitle: [_adaptorNames objectAtIndex:row]]; +} + + + +@end + diff --git a/DBModeler/COPYING b/DBModeler/COPYING new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/DBModeler/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/DBModeler/DefaultColumnProvider.h b/DBModeler/DefaultColumnProvider.h new file mode 100644 index 0000000..f3e53c7 --- /dev/null +++ b/DBModeler/DefaultColumnProvider.h @@ -0,0 +1,39 @@ +#ifndef __DefaultColumnProvider_H_ +#define __DefaultColumnProvider_H_ + +/* + DefaultColumnProvider.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +NSMutableArray *DefaultAttributeColumns; +NSMutableArray *DefaultEntityColumns; +NSMutableArray *DefaultRelationshipColumns; + +@interface DefaultColumnProvider : NSObject +{ + +} +@end + +#endif // __DefaultColumnProvider_H_ diff --git a/DBModeler/DefaultColumnProvider.m b/DBModeler/DefaultColumnProvider.m new file mode 100644 index 0000000..a9c809b --- /dev/null +++ b/DBModeler/DefaultColumnProvider.m @@ -0,0 +1,232 @@ +/** + DefaultColumnProvider.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include "DefaultColumnProvider.h" +#include "ModelerEntityEditor.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define DICTSIZE(dict) (sizeof(dict) / sizeof(dict[0])) +#define uhuh (id)1 +static DefaultColumnProvider *_sharedDefaultColumnProvider; +static NSMutableDictionary *_aspectsAndKeys; + +/* object key default */ +static id attribute_columns[][3] = { + @"allowsNull", @"Allows null", nil, + @"isClassProperty", @"Class property", uhuh, + @"columnName", @"Column name", uhuh, + @"definition", @"Definition", nil, + @"externalType", @"External Type", uhuh, + @"isUsedForLocking", @"Locking", uhuh, + @"name", @"Name", uhuh, + @"precision", @"Precision", nil, + @"isPrimaryKey", @"Primary key", uhuh, + @"readFormat", @"Read format", nil, + @"scale", @"Scale", nil, + @"valueClassName", @"Value class name", uhuh, + @"valueType", @"Value type", nil, + @"width", @"Width", uhuh, + @"writeFormat", @"Write format", nil +}; + +static id relationship_columns[][3]= { + @"isClassProperty", @"Class Property", uhuh, + @"definition", @"Definition", nil, + @"name", @"Name", uhuh, + @"destinationEntity.name", @"Destination Entity", uhuh + +}; + +static id entity_columns[][3] = { + @"name", @"Name", uhuh, + @"className", @"Class name", uhuh, + @"externalName", @"External name", uhuh, + @"externalQuery", @"External query", nil, + @"parentEntity.name", @"Parent", nil + +}; + +@implementation DefaultColumnProvider +/* function to create a NSDictionary out of the c arrays.. + * which looks like + { + Class = { + columnName1 = "aspectKey1"; + columnName2 = "aspectKey2"; + }; + + Class2 = { + otherColumnName = "otherAspectKey"; + }; + } + * or something not sure if id columns[][2] would work as a method so i'll use + * a function.. it _should_ but iirc buggy somewhere (forwarding?) */ +void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableArray *defaultColumnsArray) +{ + id *objects; + id *keys; + int i,c; + size_t size; + NSDictionary *tmp; + size = (count * sizeof(id)); + + objects = (id *)NSZoneMalloc([_sharedDefaultColumnProvider zone], size); + keys = (id *)NSZoneMalloc([_sharedDefaultColumnProvider zone], size); + + for (i = 0; i < count; i++) + { + objects[i] = columns[i][0]; + keys[i] = columns[i][1]; + if (columns[i][2] == uhuh) + { + [defaultColumnsArray addObject:keys[i]]; + } + } + tmp = [NSDictionary dictionaryWithObjects:objects + forKeys:keys + count:count]; + [EOMApp registerColumnNames: [tmp allKeys] + forClass: aClass + provider:_sharedDefaultColumnProvider]; + NSZoneFree([_sharedDefaultColumnProvider zone], objects); + NSZoneFree([_sharedDefaultColumnProvider zone], keys); + + [_aspectsAndKeys setObject: tmp + forKey: aClass]; +} + ++ (void)initialize +{ + + DefaultEntityColumns = [[NSMutableArray alloc] init]; + DefaultAttributeColumns = [[NSMutableArray alloc] init]; + DefaultRelationshipColumns = [[NSMutableArray alloc] init]; + + _sharedDefaultColumnProvider = [[self alloc] init]; + _aspectsAndKeys = [[NSMutableDictionary alloc] init]; + registerColumnsForClass(attribute_columns, + DICTSIZE(attribute_columns), + [EOAttribute class], + DefaultAttributeColumns); + registerColumnsForClass(entity_columns, + DICTSIZE(entity_columns), + [EOEntity class], + DefaultEntityColumns); + registerColumnsForClass(relationship_columns, + DICTSIZE(relationship_columns), + [EORelationship class], + DefaultRelationshipColumns); +} + +- (NSCell *)cellForColumnNamed:(NSString *)name +{ + /* TODO need a switch button for "Locking" and "Allows null" */ + if ([name isEqual:@"Primary key"]) + { + NSButtonCell *cell = [[NSButtonCell alloc] initImageCell:nil]; + + [cell setButtonType:NSSwitchButton]; + [cell setImagePosition:NSImageOnly]; + [cell setBordered:NO]; + [cell setBezeled:NO]; + [cell setAlternateImage:[NSImage imageNamed:@"Key_On"]]; + [cell setControlSize: NSSmallControlSize]; + [cell setEditable:YES]; + return cell; + } + else if ([name isEqual:@"Class property"]) + { + NSButtonCell *cell = [[NSButtonCell alloc] initImageCell:nil]; + + [cell setButtonType:NSSwitchButton]; + [cell setImagePosition:NSImageOnly]; + [cell setBordered:NO]; + [cell setBezeled:NO]; + [cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]]; + [cell setControlSize: NSSmallControlSize]; + [cell setEditable:YES]; + return cell; + } + else if ([name isEqual:@"Locking"]) + { + NSButtonCell *cell = [[NSButtonCell alloc] initImageCell:nil]; + + [cell setButtonType:NSSwitchButton]; + [cell setImagePosition:NSImageOnly]; + [cell setBordered:NO]; + [cell setBezeled:NO]; + [cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]]; + [cell setControlSize: NSSmallControlSize]; + [cell setEditable:YES]; + return cell; + } + else + { + NSTextFieldCell *cell = [[NSTextFieldCell alloc] initTextCell:@""]; + [cell setEnabled:YES]; + [cell setEditable:YES]; + [cell setScrollable: YES]; + return cell; + } +} + +- (void)initColumn:(NSTableColumn *)tc + class:(Class)class + name:(NSString *)columnName + displayGroup:(EODisplayGroup *)displayGroup + document:(EOModelerDocument *)doc +{ + EOColumnAssociation *association; + NSCell *cell; + NSString *aspectKey; + NSString *aspect; + + aspectKey = [[_aspectsAndKeys objectForKey:class] objectForKey:columnName]; + aspect = @"value"; + association = [[EOColumnAssociation alloc] initWithObject:tc]; + [[tc headerCell] setStringValue:columnName]; + cell = [self cellForColumnNamed:columnName]; + [tc setEditable:[cell isEditable]]; + [tc setDataCell:cell]; + [association bindAspect:aspect displayGroup:displayGroup key:aspectKey]; + [association establishConnection]; + [association release]; +} + +@end diff --git a/DBModeler/EOAdditions.h b/DBModeler/EOAdditions.h new file mode 100644 index 0000000..e09db2c --- /dev/null +++ b/DBModeler/EOAdditions.h @@ -0,0 +1,36 @@ +#ifndef __EOAdditions_H_ +#define __EOAdditions_H_ + +/* + EOAdditions.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +/* these use NSNumbers because they are used in key value coding. */ +@interface EOAttribute (ModelerAdditions) +- (NSNumber *) isPrimaryKey; +- (void) setIsPrimaryKey:(NSNumber *)flag; +- (NSNumber *) isClassProperty; +- (void) setIsClassProperty:(NSNumber *)flag; +@end + +#endif // __EOAdditions_H_ diff --git a/DBModeler/EOAdditions.m b/DBModeler/EOAdditions.m new file mode 100644 index 0000000..5fb26f0 --- /dev/null +++ b/DBModeler/EOAdditions.m @@ -0,0 +1,124 @@ +/** + EOAdditions.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + +#include +#include +#include + +#include +#include + +/* this is all stuff for key value coding.. */ +static inline NSNumber * isClassProperty(id self) +{ + return [NSNumber numberWithBool: [[[self entity] classProperties] containsObject:self]]; +} + +static inline void setIsClassProperty(id self, NSNumber *flag) +{ + BOOL isProp = [flag boolValue]; + NSArray *props = RETAIN([[self entity] classProperties]); + + if (isProp) + { + if (![props containsObject:self]) + [[self entity] setClassProperties: [props arrayByAddingObject:self]]; + } + else + { + if ([props containsObject:self]) + { + NSMutableArray *newProps = [NSMutableArray arrayWithArray:props]; + [newProps removeObject: self]; + [[self entity] setClassProperties: newProps]; + } + } + RELEASE(props); +} + +@implementation EOAttribute (ModelerAdditions) + +- (NSNumber *) isPrimaryKey +{ + return [NSNumber numberWithBool: [[[self entity] primaryKeyAttributes] containsObject:self]]; +} + +- (void) setIsPrimaryKey:(NSNumber *)flag +{ + BOOL isKey = [flag boolValue]; + NSArray *pka = RETAIN([[self entity] primaryKeyAttributes]); + + if (isKey) + { + if (![pka containsObject:self]) + [[self entity] setPrimaryKeyAttributes: [pka arrayByAddingObject:self]]; + } + else + { + if ([pka containsObject:self]) + { + NSMutableArray *newPks = [NSMutableArray arrayWithArray:pka]; + [newPks removeObject: self]; + [[self entity] setPrimaryKeyAttributes: newPks]; + + } + } + RELEASE(pka); +} + +- (NSNumber *) isClassProperty +{ + return isClassProperty(self); +} + +- (void) setIsClassProperty:(NSNumber *)flag +{ + return setIsClassProperty(self, flag); +} + +- (NSNumber *) isUsedForLocking +{ + return [NSNumber numberWithBool:NO]; + /* FIXME */ +} + +- (void) setIsUsedForLocking:(NSNumber *)flag +{ + /* FIXME */ +} +@end + + +@implementation EORelationship (ModelerAdditions) +- (NSNumber *) isClassProperty +{ + return isClassProperty(self); +} + +- (void) setIsClassProperty:(NSNumber *)flag +{ + return setIsClassProperty(self, flag); +} +@end diff --git a/DBModeler/GNUmakefile b/DBModeler/GNUmakefile new file mode 100644 index 0000000..8b24f20 --- /dev/null +++ b/DBModeler/GNUmakefile @@ -0,0 +1,37 @@ +include $(GNUSTEP_MAKEFILES)/common.make +include $(GNUSTEP_MAKEFILES)/Auxiliary/gdl2.make + +APP_NAME = DBModeler +DBModeler_SUBPROJECTS=Inspectors + +ADDITIONAL_LIB_DIRS+=-L../EOAccess/$(GNUSTEP_OBJ_DIR) +ADDITIONAL_LIB_DIRS+=-L../EOControl/$(GNUSTEP_OBJ_DIR) + +ifeq ($(FOUNDATION_LIB), apple) +ADDITIONAL_LIB_DIRS+= -F../EOModeler +ADDITIONAL_INCLUDE_DIRS+= -F../EOModeler +else +ADDITIONAL_INCLUDE_DIRS= -I.. +ADDITIONAL_LIB_DIRS= -L../EOModeler/$(GNUSTEP_OBJ_DIR) +endif + +ADDITIONAL_NATIVE_LIBS += EOInterface gnustep-db2modeler + +$(APP_NAME)_RESOURCE_FILES = \ + Resources/Key_On.tiff \ + Resources/ClassProperty_On.tiff \ + Resources/ModelDrag.tiff + +$(APP_NAME)_OBJC_FILES = \ + main.m \ + Modeler.m \ + AdaptorsPanel.m \ + MainModelEditor.m \ + ModelerEntityEditor.m \ + DefaultColumnProvider.m \ + KVDataSource.m \ + ModelerAttributeEditor.m \ + EOAdditions.m \ + ModelerTableEmbedibleEditor.m + +include $(GNUSTEP_MAKEFILES)/application.make diff --git a/DBModeler/Inspectors/AttributeInspector.gorm/data.classes b/DBModeler/Inspectors/AttributeInspector.gorm/data.classes new file mode 100644 index 0000000..c17c810 --- /dev/null +++ b/DBModeler/Inspectors/AttributeInspector.gorm/data.classes @@ -0,0 +1,12 @@ +{ + "## Comment" = "Do NOT change this file, Gorm maintains it"; + EOMInspector = { + Actions = ( + ); + Outlets = ( + view, + window + ); + Super = NSObject; + }; +} \ No newline at end of file diff --git a/DBModeler/Inspectors/AttributeInspector.gorm/data.info b/DBModeler/Inspectors/AttributeInspector.gorm/data.info new file mode 100644 index 0000000000000000000000000000000000000000..a98a343479136e23ceeda9b17c3c5ce4330472fd GIT binary patch literal 184 zcmZ?w3oR~5El@}-O3uhEOEmxjqr@~zD-Z(+j4>DnRtAiQj0_^~`9-;InK`KeMX71U zzKMB>>8V8wKw!wkz~L9{pOlrFTms@Vs4_5cvKlZMGK0i}ONuh{(t)Ck3~E4<4=BmN tDhgsT`6QO47MCc5r4|)u=I0qOZ)66k;DM{)VG5}%NKH`y8j+fq3jme&C@TN} literal 0 HcmV?d00001 diff --git a/DBModeler/Inspectors/AttributeInspector.gorm/objects.gorm b/DBModeler/Inspectors/AttributeInspector.gorm/objects.gorm new file mode 100644 index 0000000000000000000000000000000000000000..731bdb2570aa5d2fc0a5bd53e391bfdf58a37916 GIT binary patch literal 9248 zcmcgy34B~d8J~UGoSQpMN)I5F+l%j|cNJ-N)5M6~Mz*D(B5sn`bW3(O-Rw4rpw@g97QO1ITh~an>W{Yh_09KYzWKhH|9r>1 zne7X28Bbedozc|L_Sh~9@LyMS+uC(R0GQi^FwK?u8h~}+GkvPDFA|OohLVYNG?uVZ zN-3XdsG4wO)8GzkD2?w*fniptws2%)CLJ9dwR&Ph=~yxmO-)gw=~wmPh`UZ5j}6P9 z!mK1ok#s7S7{MAJ*9VS6vaTH;0l(U;EH$aps#nF38dbx}RLj9{R;fTZve}wU_r|Qz zVd`sEtJ-jc2AWEaaz%}*3P;X}SrhzLOFd4v#>bM0VVQ>_MJn6T5eVLj%7V>Gbp%4S zNOoU|WJiFS`QfNG6#n@PAI(5zvruW)sYZM1-KkVmW*tz~;Yi_CCMNoz%B)vSj=_hl zQ5vsdHV{zVj9tFYXExFt3U3OkbCsmnPb04+i2MeDkcAqvi8y<4`dC}Rs{C0VEDe_i zUHGH7d<{>69x|O-UIFKs6|APSP-`~R)I!P8Bw0g+f;t&gi#@0oBOD1w(V=rkQprq0q(DQiS=Z?RGzxpI&0fpwtcvE9 zorWd{3ma0cUu{J5NvMqKM`N;7T&;#?vqjb6%2|m_KaK zCZwLD5uhbNo7qZ;^v9zk7F8j`^utL&Z;d^R8eCa%SKUe& z%m7hF(^BcpD>d6Ptc4>{&r!lzG^r>YE%im1mr>OzjPp#&gk`AgMZ#NYPpZ-gPNl7J z4>LMOx;kyojzMs2j*VLa%6^O-q3b!IpqrKpD1~bFOGiLCE?38X$hHB;=j!1E(dtBp zonF@*5(ht#91TtqrDgo}#nLjLzrKY1^(1&{DQ4u}PJexwur%8%(rolaLYeV&G9DU@ zj*oAQj={@w6$}fUEX?&bbG^}@7$3u2luT`nB`}w@QBpy2I7yM;m8SlM$TCNwk0HqUEWu2)fVC=B45Eo!Sa6gPJbeoH42SDkJ&`=P}tAUWr!5}L%pa()U27 zR+Shglau7vjn0*zU;Y>+eHJ^gyAQ zHUgnlB|;0;#Y+kol(u4rJu>XYg zcLt0eYbX}ScoELT2d$KzU(O`TnG!k9%+#MqTO(Eq-coi#WyW(J$~nJuK0V0{e!#(7 zJ&MsC`bcN4dt1I=7T#W5dBU=%%{EgNXvX_@4Xy&E`SS# zy?ok}kbRK@L_Pu%5D)eU=zT5_-;W@EKy)9jko`eM?&4XI`;a%}vW(ot@Zq_TlaM`K zj2yw|I3;tNpABfS`F+HN+(!|)j~!m*KF-KpGAnYQ@P^zc8M#Z~Q}ZKtsRKE7TtUwE zP&aaRbun_Eb|Lo}MDDYtli-i%L*}oaW9;^ns?GcBW!|v+JY%;9zAzVd;;)xGvD=M7 zFNg=H81$~Dl$%A;b!2N-7i0HD7j{=5c3%?R&Y;&Dr2~bj&bXD{o*ecJB7dtL#K-fM z4B}O@f_Swz5WmbIUIky7AH-`MAj-KnZo3ZNb+2`S_*Dc^i|)e}^m2^cb+aOOy*K2( z#>iaie4 z;m_I3ZWHxoc6YZ+%Y3`LU$B|o2EP>cxpsHI$~D5Th0W<%^cleC4|J=;hY+)z!^x+4 z{z)G%a-_gOomUp<`rR!CI9;8)filL6KH`$WtOZpEYlxM-Qslvby zb-fMllm^$8OPSkRy&UfH#Mz}!gS$O(F4vpk9#5Pr^x3e_6X#038}9YQxk_IIe-uvV z*Ck$vPvHGH+$T+ZJ;9e=^?tQMZNmGXmvDp7toSOJ4)ec#yeDp9g=EOwvhNuM_@kE}`oV z`C&+cuihwtD19#P-+onu<)WSQ!gtPOr*!{24of8BbVU=G^;BP+? z_{)!^nt;FMmgr+JEd3qJJF)x+mQP^$Pb?qC@?Tg!h~>YrybH_!V0kx||HbkiEdPh) zek`BE^3iN|z^9OSj0hhRj}u`a@e~miNIXM?ABlD%Dv?-9L=_VIh^R*5ULtCcxSxnx zBpx854v9yI2q1BQh + + +@interface AttributeInspector : EOMInspector +{ + +} + +@end + diff --git a/DBModeler/Inspectors/AttributeInspector.m b/DBModeler/Inspectors/AttributeInspector.m new file mode 100644 index 0000000..495fee6 --- /dev/null +++ b/DBModeler/Inspectors/AttributeInspector.m @@ -0,0 +1,16 @@ +#include "AttributeInspector.h" + +@implementation AttributeInspector + +- (float) displayOrder +{ + return 0; +} + +- (void) refresh +{ + +} + +@end + diff --git a/DBModeler/Inspectors/GNUmakefile b/DBModeler/Inspectors/GNUmakefile new file mode 100644 index 0000000..067480e --- /dev/null +++ b/DBModeler/Inspectors/GNUmakefile @@ -0,0 +1,13 @@ +include $(GNUSTEP_MAKEFILES)/common.make +SUBPROJECT_NAME=Inspectors +ADDITIONAL_INCLUDE_DIRS+=-I../../ + +Inspectors_HAS_RESOURCE_BUNDLE=yes + +Inspectors_RESOURCE_FILES=RelationshipInspector.gorm +Inspectors_OBJC_FILES=RelationshipInspector.m + +Inspectors_RESOURCE_FILES+=AttributeInspector.gorm +Inspectors_OBJC_FILES+=AttributeInspector.m + +include $(GNUSTEP_MAKEFILES)/subproject.make diff --git a/DBModeler/Inspectors/RelationshipInspector.gorm/data.classes b/DBModeler/Inspectors/RelationshipInspector.gorm/data.classes new file mode 100644 index 0000000..5a2527f --- /dev/null +++ b/DBModeler/Inspectors/RelationshipInspector.gorm/data.classes @@ -0,0 +1,40 @@ +{ + "## Comment" = "Do NOT change this file, Gorm maintains it"; + EOMInspector = { + Actions = ( + ); + Outlets = ( + view, + window + ); + Super = NSObject; + }; + FirstResponder = { + Actions = ( + "cardinalityChanged:", + "connectionChanged:", + "nameChanged:", + "semanticChanged:" + ); + Super = NSObject; + }; + RelationshipInspector = { + Actions = ( + "connectionChanged:", + "cardinalityChanged:", + "nameChanged:", + "semanticChanged:" + ); + Outlets = ( + name_textField, + model_popup, + destEntity_tableView, + joinCardinality_matrix, + joinSemantic_popup, + srcAttrib_tableView, + destAttrib_tableView, + connect_button + ); + Super = EOMInspector; + }; +} \ No newline at end of file diff --git a/DBModeler/Inspectors/RelationshipInspector.gorm/data.info b/DBModeler/Inspectors/RelationshipInspector.gorm/data.info new file mode 100644 index 0000000000000000000000000000000000000000..a98a343479136e23ceeda9b17c3c5ce4330472fd GIT binary patch literal 184 zcmZ?w3oR~5El@}-O3uhEOEmxjqr@~zD-Z(+j4>DnRtAiQj0_^~`9-;InK`KeMX71U zzKMB>>8V8wKw!wkz~L9{pOlrFTms@Vs4_5cvKlZMGK0i}ONuh{(t)Ck3~E4<4=BmN tDhgsT`6QO47MCc5r4|)u=I0qOZ)66k;DM{)VG5}%NKH`y8j+fq3jme&C@TN} literal 0 HcmV?d00001 diff --git a/DBModeler/Inspectors/RelationshipInspector.gorm/objects.gorm b/DBModeler/Inspectors/RelationshipInspector.gorm/objects.gorm new file mode 100644 index 0000000000000000000000000000000000000000..409c50633a796e8098cfff4ea4c5ef5ee843ef1c GIT binary patch literal 14227 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 +#include + +@class EOModel; +@class EOEntity; +@interface RelationshipInspector : EOMInspector +{ + IBOutlet NSTextField *name_textField; + IBOutlet NSPopUpButton *model_popup; + IBOutlet NSMatrix *joinCardinality_matrix; + IBOutlet NSPopUpButton *joinSemantic_popup; + IBOutlet NSTableView *destEntity_tableView; + IBOutlet NSTableView *srcAttrib_tableView; + IBOutlet NSTableView *destAttrib_tableView; + IBOutlet NSButton *connect_button; +} + +- (IBAction) connectionChanged:(id)sender; +- (IBAction) nameChanged:(id)sender; +@end + diff --git a/DBModeler/Inspectors/RelationshipInspector.m b/DBModeler/Inspectors/RelationshipInspector.m new file mode 100644 index 0000000..1b7f56b --- /dev/null +++ b/DBModeler/Inspectors/RelationshipInspector.m @@ -0,0 +1,186 @@ +#include "RelationshipInspector.h" + +#include +#include +#include +#include + +#include +#include + +#include + +@implementation RelationshipInspector +- (void) awakeFromNib +{ + [destEntity_tableView setAllowsEmptySelection:NO]; + [srcAttrib_tableView setAllowsEmptySelection:NO]; + [destAttrib_tableView setAllowsEmptySelection:NO]; +} +- (float) displayOrder +{ + return 0; +} +- (BOOL) canInspectObject:(id)anObject +{ + return [anObject isKindOfClass:[EORelationship class]]; +} + +- (void) refresh +{ + EOModel *activeModel = [[EOMApp activeDocument] model]; + EOEntity *destEntity; + EOAttribute *srcAttrib, *destAttrib; + NSArray *srcAttribs; + NSArray *destAttribs; + unsigned int row; + + + [name_textField setStringValue:[(EORelationship *)[self selectedObject] name]]; + + + + /* it is important that the destEntity has a selected row before the destAttrib tableview + * reloads data */ + [destEntity_tableView reloadData]; + destEntity = [[self selectedObject] destinationEntity]; + if (destEntity) + { + row = [[activeModel entities] indexOfObject:destEntity]; + if (row == NSNotFound) + row = 0; + } + else if ([destEntity_tableView numberOfRows]) + row = 0; + [destEntity_tableView selectRow:row byExtendingSelection:NO]; + + srcAttribs = [[self selectedObject] sourceAttributes]; + if (srcAttribs && [srcAttribs count]) + srcAttrib = [srcAttribs objectAtIndex:0]; + else + srcAttrib = nil; + + [srcAttrib_tableView reloadData]; + if (srcAttrib) + { + // FIXME!!!! when there is no srcAttrib we segfault when calling isEqual: so we use indexOfObjectIdenticalTo: + row = [[[[self selectedObject] entity] attributes] indexOfObject:srcAttrib]; + if (row == NSNotFound) + row = 0; + } + else if ([srcAttrib_tableView numberOfRows]) + row = 0; + [srcAttrib_tableView selectRow:row byExtendingSelection:NO]; + + destAttribs = [[self selectedObject] destinationAttributes]; + if (destAttribs && [destAttribs count]) + destAttrib = [destAttribs objectAtIndex:0]; + else + destAttrib = nil; + [destAttrib_tableView reloadData]; + if (destAttrib) + { + // FIXME!!!! when there is no destAttrib we segfault when calling isEqual: so we use indexOfObjectIdenticalTo: + row = [[[[self selectedObject] destinationEntity] attributes] indexOfObject:destAttrib]; + if (row == NSNotFound) + row = 0; + } + else if ([destAttrib_tableView numberOfRows]) + row = 0; + [destAttrib_tableView selectRow:row byExtendingSelection:NO]; + + [connect_button setState: ([[self selectedObject] destinationEntity] == nil) ? NSOffState : NSOnState]; + + [joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]]; + [joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]]; +} + +- (int) numberOfRowsInTableView:(NSTableView *)tv +{ + EOModel *activeModel = [[EOMApp activeDocument] model]; + if (tv == destEntity_tableView) + return [[activeModel entities] count]; + else if (tv == srcAttrib_tableView) + return [[(EOEntity *)[[self selectedObject] entity] attributes] count]; + else if (tv == destAttrib_tableView) + { + int selectedRow = [destEntity_tableView selectedRow]; + if (selectedRow == -1 || selectedRow == NSNotFound) + return 0; + return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count]; + + } +} + +- (id) tableView:(NSTableView *)tv +objectValueForTableColumn:(NSTableColumn *)tc +row:(int)rowIndex +{ + EOModel *activeModel = [[EOMApp activeDocument] model]; + if (tv == destEntity_tableView) + { + return [(EOEntity *)[[activeModel entities] objectAtIndex:rowIndex] name]; + } + else if (tv == srcAttrib_tableView) + { + return [(EOAttribute *)[[(EOEntity *)[[self selectedObject] entity] attributes] objectAtIndex:rowIndex] name]; + } + else if (tv == destAttrib_tableView) + { + int selectedRow = [destEntity_tableView selectedRow]; + if (selectedRow == NSNotFound) + [destEntity_tableView selectRow:0 byExtendingSelection:NO]; + return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] + attributes] objectAtIndex:rowIndex] name]; + } +} + +- (void) tableViewSelectionDidChange:(NSNotification *)notif +{ + NSTableView *tv = [notif object]; + + if (tv == destEntity_tableView) + { + [destAttrib_tableView reloadData]; + } +} +- (void) connectionChanged:(id)sender +{ + EOEntity *destEntity; + EOAttribute *srcAttrib; + EOAttribute *destAttrib; + EOModel *model; + EOJoin *newJoin; + + model = [[EOMApp activeDocument] model]; + + destEntity = [[model entities] objectAtIndex:[destEntity_tableView selectedRow]]; + destAttrib = [[destEntity attributes] objectAtIndex:[destAttrib_tableView selectedRow]]; + srcAttrib = [[[[self selectedObject] entity] attributes] objectAtIndex:[srcAttrib_tableView selectedRow]]; + + newJoin = [[EOJoin alloc] initWithSourceAttribute:srcAttrib destinationAttribute:destAttrib]; + [[self selectedObject] addJoin:newJoin]; + [newJoin release]; +} + +- (void) nameChanged:(id)sender +{ + NSString *name = [name_textField stringValue]; + + [(EORelationship *)[self selectedObject] setName:name]; +} + +- (void) semanticChanged:(id)sender +{ + /* the tag in the nib must match the values in the EOJoinSemantic enum */ + [[self selectedObject] setJoinSemantic: [[sender selectedItem] tag]]; + +} + +- (void) cardinalityChanged:(id)sender +{ + /* the tag in the nib for to-one must be 0 to-many 1 */ + [[self selectedObject] setToMany: [[sender selectedCell] tag]]; +} +@end + diff --git a/DBModeler/KVDataSource.h b/DBModeler/KVDataSource.h new file mode 100644 index 0000000..0fa22c5 --- /dev/null +++ b/DBModeler/KVDataSource.h @@ -0,0 +1,48 @@ +#ifndef __KVDataSource_H_ +#define __KVDataSource_H_ + +/* + KVDataSource.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +@interface KVDataSource : EODataSource +{ + id _dataObject; + EOEditingContext *_context; + EOClassDescription *_classDescription; + NSString *_key; +} + +- (id) initWithClassDescription: (EOClassDescription *)classDescription + editingContext: (EOEditingContext *) context; +- (void) setDataObject: (id)object; +- (id) dataObject; +- (void) setKey:(NSString *)key; + +/** result of [_dataObject -valueForKey:key] should be an array */ +- (NSString *)key; + +@end + +#endif // __KVDataSource_H_ diff --git a/DBModeler/KVDataSource.m b/DBModeler/KVDataSource.m new file mode 100644 index 0000000..3263207 --- /dev/null +++ b/DBModeler/KVDataSource.m @@ -0,0 +1,172 @@ +/** + KVDataSource.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include "KVDataSource.h" + +@implementation KVDataSource + +- (id) initWithClassDescription: (EOClassDescription *)classDescription + editingContext: (EOEditingContext *)context +{ + if ((self = [super init])) + { + _classDescription = RETAIN(classDescription); + _context = RETAIN(context); + _dataObject = nil; + _key = nil; + } + return self; +} + +- (void) dealloc +{ + DESTROY(_classDescription); + DESTROY(_context); + DESTROY(_dataObject); + DESTROY(_key); + [super dealloc]; +} + +- (void) encodeWithCoder: (NSCoder *)encoder +{ + +} + +- (id) initWithCoder: (NSCoder *)decoder +{ +return self; +} +- (id) createObject +{ +/* id object; + EOEditingContext *edCtxt; + + if ([_key isEqual:@"entities"]) + object = [EOEntity new]; + if ([_key isEqual:@"attributes"]) + object = [EOAttribute new]; + + if (object && (edCtxt = [self editingContext])) + [edCtxt insertObject:object]; + + return AUTORELEASE(object); +*/ + [[NSException exceptionWithName:NSInternalInconsistencyException + reason: [NSString stringWithFormat:@"%@ not supported by %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])] + userInfo:nil] raise]; +} +- (void) insertObject:(id)object +{ +/* + if ([object isKindOfClass:[EOEntity class]]) + { + [_dataObject addEntity:object]; + } + else if ([object isKindOfClass:[EOAttribute class]]) + { + [_dataObject addAttribute:object]; + } +*/ + [[NSException exceptionWithName:NSInternalInconsistencyException + reason: [NSString stringWithFormat:@"%@ not supported by %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])] + userInfo:nil] raise]; +} + +- (void) deleteObject:(id)object +{ + // TODO +} + +- (NSArray *)fetchObjects +{ + return [_dataObject valueForKey:_key]; +} + +- (EOEditingContext *)editingContext +{ + return _context; +} + +- (void) qualifyWithRelationshipKey:(NSString *)key ofObject:(id) sourceObject +{ + +} + +- (EODataSource *) dataSourceQualifiedByKey: (NSString *)key +{ + +} + +- (EOClassDescription *)classDescriptionForObjects +{ + return _classDescription; +} + +- (NSArray *)qualifierBindingKeys +{ + return nil; +} + +- (void) setQualifierBindings:(NSDictionary *)bindings +{ + +} + +- (NSDictionary *)qualifierBindings +{ + return nil; +} + +- (void) setDataObject:(id)object +{ + ASSIGN(_dataObject,object); +} + +- (id) dataObject +{ + return _dataObject; +} + +- (void) setKey:(NSString *)key +{ + ASSIGN(_key,key); +} + +- (NSString *) key +{ + return _key; +} +@end + diff --git a/DBModeler/MainModelEditor.h b/DBModeler/MainModelEditor.h new file mode 100644 index 0000000..0a78358 --- /dev/null +++ b/DBModeler/MainModelEditor.h @@ -0,0 +1,42 @@ +#ifndef __MainModelEditor_H_ +#define __MainModelEditor_H_ + +/* + MainModelerEditor.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include + +@interface MainModelEditor : EOModelerCompoundEditor +{ + NSBox *_box; + NSWindow *_window; + NSOutlineView *_iconPath; +} + +@end + +#endif diff --git a/DBModeler/MainModelEditor.m b/DBModeler/MainModelEditor.m new file mode 100644 index 0000000..add1a24 --- /dev/null +++ b/DBModeler/MainModelEditor.m @@ -0,0 +1,494 @@ +/** + MainModelEditor.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include "MainModelEditor.h" +#include "ModelerEntityEditor.h" + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +//#define DEBUG_STUFF 1 + +@interface ModelerOutlineView : NSOutlineView +@end +@implementation ModelerOutlineView + +- (NSImage *) dragImageForRows:(NSArray *)dragRows + event: (NSEvent *)dragEvent + dragImageOffset: (NSPoint *)dragImageOffset +{ + id foo = [self itemAtRow:[[dragRows objectAtIndex:0] intValue]]; + NSImage *img = nil; + + if ([foo isKindOfClass: [EOEntity class]]) + { + img = [NSImage imageNamed:@"ModelDrag"]; + [img setScalesWhenResized:NO]; + } + return img; +} +@end +@implementation MainModelEditor +- (id) initWithDocument:(EOModelerDocument *)document +{ + if (self = [super initWithDocument:document]) + { + NSTableColumn *_col; + NSSplitView *vSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,400,400)]; + NSScrollView *sv = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,100,400)]; + // NSImageCell *_cell; + + [vSplit setVertical:YES]; + + + _iconPath = [[ModelerOutlineView alloc] initWithFrame:NSMakeRect(0,0,100,400)]; + [_iconPath setIndentationPerLevel:8.0]; + [_iconPath setIndentationMarkerFollowsCell:YES]; + + [_iconPath setDelegate:self]; + [_iconPath setDataSource:self]; + //_cell = [[NSImageCell alloc] init]; + _col = [(NSTableColumn *)[NSTableColumn alloc] initWithIdentifier:@"name"]; + [_iconPath addTableColumn:_col]; + [_iconPath setOutlineTableColumn:AUTORELEASE(_col)]; + //[[_iconPath tableColumnWithIdentifier:@"name"] setDataCell:_cell]; + [_iconPath setAutoresizesAllColumnsToFit:YES]; + [_iconPath sizeToFit]; + + _window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,400,400) + styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask + backing:NSBackingStoreBuffered + defer:YES]; + + [sv setHasHorizontalScroller:YES]; + [sv setHasVerticalScroller:YES]; + [sv setAutoresizingMask: NSViewWidthSizable]; + [_iconPath setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable]; + [sv setDocumentView:_iconPath]; + RELEASE(_iconPath); + [vSplit addSubview:sv]; + RELEASE(sv); + + + _box = [[NSBox alloc] initWithFrame:NSMakeRect(0,0,300,400)]; + [_box setTitle:@""]; + [_box setBorderType:NSNoBorder]; + [_box setAutoresizesSubviews:YES]; + [_box setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [vSplit addSubview: _box]; + RELEASE(_box); + + [vSplit setAutoresizesSubviews:YES]; + [vSplit setAutoresizingMask: NSViewWidthSizable + | NSViewHeightSizable]; + [vSplit adjustSubviews]; + [[_window contentView] addSubview:vSplit]; + RELEASE(vSplit); + + /* so addEntity: addAttribute: ... menu items work */ + [_window setDelegate: document]; + [[NSNotificationCenter defaultCenter] addObserver: self + selector:@selector(ecStuff:) + name: EOObjectsChangedInEditingContextNotification + object: [[self document] editingContext]]; + + [self setViewedObjectPath:[NSArray arrayWithObject:[document model]]]; + } + return self; +} +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver: self]; + RELEASE(_window); + [super dealloc]; +} +- (void) ecStuff:(NSNotification *)notif +{ + if ([[notif object] isKindOfClass:[EOEditingContext class]]) + { + int i,c; + NSArray *objects = [[notif userInfo] objectForKey:EOUpdatedKey]; + + for (i = 0, c = [objects count]; i < c; i++) + [_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES]; +#if 0 + objects = [[notif userInfo] objectForKey:EOInsertedKey]; + for (i = 0, c = [objects count]; i < c; i++) + [_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES]; + + objects = [[notif userInfo] objectForKey:EODeletedKey]; + for (i = 0, c = [objects count]; i < c; i++) + [_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES]; +#endif + + } +} + +- (void)activateEmbeddedEditor:(EOModelerEmbedibleEditor *)editor +{ + NSView *mainView = [editor mainView]; + int i, count; + NSArray *subviews; + + subviews = [mainView subviews]; + count = [subviews count]; + [super activateEmbeddedEditor:editor]; + for (i = 0; i < count; i++) + { + NSView *aView = [subviews objectAtIndex:i]; + + [aView setAutoresizesSubviews:YES]; + [aView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + } + [mainView setAutoresizesSubviews:YES]; + [mainView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [mainView setFrame: [_box frame]]; + + [_box setContentView: mainView]; + [_box setNeedsDisplay:YES]; +} + +- (void)activateEditorWithClass:(Class)embedibleEditorClass +{ + [super activateEditorWithClass:embedibleEditorClass]; + [self activateEmbeddedEditor: + [self embedibleEditorOfClass:embedibleEditorClass]]; + [_iconPath reloadData]; +} + +- (void) activate +{ + if (![_window isVisible] || ![_window isKeyWindow]) + { + [_window makeKeyAndOrderFront:self]; + [self activateEmbeddedEditor: + [self embedibleEditorOfClass: + NSClassFromString(@"ModelerEntityEditor")]]; + + } + [_iconPath reloadData]; + [super activate]; +} + +- (void) viewSelectedObject +{ + id selection; + if ([[self selectionWithinViewedObject] count] == 0) + { + NSLog(@"view count == 0, obj:"); + return; + } + + selection = [[self selectionWithinViewedObject] objectAtIndex:0]; +#if DEBUG_STUFF == 1 + GSPrintf(stderr, @"viewing %@(%@)\n", NSStringFromClass([selection class]), [(EOModel *)selection name]); +#endif + if ([[self activeEditor] canSupportCurrentSelection]) + [self activateEmbeddedEditor: [self activeEditor]]; + else + { + NSArray *friends = [[self activeEditor] friendEditorClasses]; + int editorsCount; + int i,j,c; + + /* first look for instances of our friend classes that can support the + current selection */ + for (i = 0, c = [friends count]; i < c; i++) + { + id friend = [friends objectAtIndex:i]; + for (j = 0,editorsCount = [_editors count]; j < editorsCount; j++) + { + if ([_editors isKindOfClass: friend]) + { + id friendEditor = [_editors objectAtIndex:j]; + + if ([friend canSupportCurrentSelection]) + { + [self activateEmbeddedEditor:friend]; + [super viewSelectedObject]; + return; + } + } + } + } + /* instantiate friends to see if we can support the current selection */ + for (i = 0,c = [friends count]; i < c; i++) + { + id friendClass = [friends objectAtIndex:i]; + id friend = [[friendClass alloc] initWithParentEditor:self]; + { + if ([friend canSupportCurrentSelection]) + { + [self activateEmbeddedEditor:friend]; + [super viewSelectedObject]; + return; + } + else + { + [friend release]; + } + } + } + /* look for any old editor this isn't very nice... + * because it only works with registered editors, and we can only + * register instances of editors, so a) can't load on demand non-friend + * editors, or b) we should register instances of all editors */ + for (i = 0, c = [_editors count]; i < c; i++) + { + id anEditor = [_editors objectAtIndex:i]; + + if ([anEditor canSupportCurrentSelection]) + { + [self activateEmbeddedEditor:anEditor]; + [super viewSelectedObject]; + return; + } + } + + } + [super viewSelectedObject]; +} + +/* NSOutlineView datasource stuff */ +- (BOOL)outlineView: (NSOutlineView *)outlineView + isItemExpandable: (id)item +{ + BOOL ret = NO; + + if (item == nil) + ret = ([[[_document model] entities] count] > 0); + else if ([item isKindOfClass:[EOModel class]]) + ret = ([[item entities] count] > 0); + else if ([item isKindOfClass:[EOEntity class]]) + ret = ([[item relationships] count] > 0); + else if ([item isKindOfClass:[EORelationship class]]) + ret = 0; +#if DEBUG_STUFF == 1 + NSLog(@"isItemExpandable %i", ret); +#endif + return ret; +} + +- (int) outlineView: (NSOutlineView *)outlineView + numberOfChildrenOfItem: (id)item +{ + int ret = 0; + + if (item == nil) + ret = 1; + else if ([item isKindOfClass: [EOModel class]]) + ret = [[item entities] count]; + else if ([item isKindOfClass: [EOEntity class]]) + ret = [[item relationships] count]; + else if ([item isKindOfClass: [EORelationship class]]) + ret = 0; + +#if DEBUG_STUFF == 1 + NSLog(@"num children %i %@", ret, [item class]); +#endif + + return ret; +} + +- (id)outlineView: (NSOutlineView *)outlineView + child: (int)index + ofItem: (id)item +{ + id ret = @"blah."; + + if (item == nil) + ret = [_document model]; + else if ([item isKindOfClass: [EOModel class]]) + ret = [[item entities] objectAtIndex:index]; + else if ([item isKindOfClass: [EOEntity class]]) + ret = [[item relationships] objectAtIndex:index]; + else if ([item isKindOfClass: [EORelationship class]]) + ret = nil; +#if DEBUG_STUFF == 1 + NSLog(@"child %@ atIndex: %i ofItem %@", [ret class], index, [item class]); +#endif + return ret; +} + +- (id) outlineView: (NSOutlineView *)outlineView + objectValueForTableColumn: (NSTableColumn *)tableColumn + byItem: (id)item +{ + id ret; + if (item == nil) + ret = [[_document model] name]; + else + ret = [item valueForKey:@"name"]; +#if DEBUG_STUFF == 1 + NSLog(@"objectValue: %@", ret); +#endif + return ret; +} + +- (void) outlineViewSelectionDidChange:(NSNotification *)notif +{ + NSMutableArray *foo = [[NSMutableArray alloc] init]; + EOModel *bar = [_document model]; + id item = nil; + int selectedRow = [_iconPath selectedRow]; + if (selectedRow == -1) + return; + while (bar != item) + { + if (item == nil) + { + + item = [_iconPath itemAtRow:selectedRow]; + [foo insertObject:[NSArray arrayWithObject:item] atIndex:0]; + } + else if ([item isKindOfClass:[EOEntity class]]) + { + item = [item model]; + [foo insertObject:item atIndex:0]; + } + else if ([item isKindOfClass:[EORelationship class]]) + { + item = [item entity]; + [foo insertObject:item atIndex:0]; + } + } +#if DEBUG_STUFF == 1 + { + int i,c; + NSArray *selpath = [self selectionPath]; + NSLog(@"current selection path"); + for (i = 0, c = [selpath count]; i < c; i++) + { + id obj = [selpath objectAtIndex:i]; + + if ([obj isKindOfClass:[NSArray class]]) + { + int j,d; + for (j = 0, d = [obj count]; j < d; j++) + { + GSPrintf(stderr, @"* %@(%@)\n", [[obj objectAtIndex:j] class], [(EOModel *)[obj objectAtIndex:j] name]); + } + } + else + GSPrintf(stderr, @"%@(%@)\n", [obj class], [(EOModel *)obj name]); + } + NSLog(@"changing to"); + selpath = foo; + for (i = 0, c = [selpath count]; i < c; i++) + { + id obj = [selpath objectAtIndex:i]; + + if ([obj isKindOfClass:[NSArray class]]) + { + int j,d; + for (j = 0, d = [obj count]; j < d; j++) + { + GSPrintf(stderr, @"* %@(%@)\n", [[obj objectAtIndex:j] class], [(EOModel *)[obj objectAtIndex:j] name]); + } + } + else + GSPrintf(stderr, @"%@(%@)\n", [obj class], [(EOModel *)obj name]); + } + } +#endif + [self setSelectionPath:AUTORELEASE(foo)]; + [self viewSelectedObject]; +} + +- (BOOL) outlineView:(NSOutlineView *)view +writeItems:(NSArray *)rows +toPasteboard:(NSPasteboard *)pboard +{ + NSMutableArray *foo = [[NSMutableArray alloc] init]; + EOModel *bar = [_document model]; + int selectedRow = [_iconPath selectedRow]; + id item = [_iconPath itemAtRow:selectedRow]; + + if (selectedRow == -1) + return NO; + while (item != nil) + { + if (item == bar) + { + NSString *modelPath = [item valueForKey:@"path"]; + if (modelPath == nil) + { + NSRunAlertPanel(@"Error", @"Must save before dragging", @"OK",@"Cancel",nil); + return NO; + } + [foo insertObject:modelPath atIndex:0]; + item = nil; + } + else if ([item isKindOfClass:[EOEntity class]]) + { + [foo insertObject:[item valueForKey:@"name"] atIndex:0]; + item = [item model]; + } + else if ([item isKindOfClass:[EORelationship class]]) + { + [foo insertObject:[item valueForKey:@"name"] atIndex:0]; + item = [item entity]; + } + } + [pboard declareTypes: [NSArray arrayWithObject: EOMPropertyPboardType] owner:nil]; + [pboard setPropertyList:foo forType:EOMPropertyPboardType]; + return YES; +} + +#if 0 +- (void) outlineView: (NSOutlineView *)outlineView +willDisplayCell:(NSCell *)cell +forTableColumn:(NSTableColumn *)tc +item:(id)item +{ + //if (![[tc identifier] isEqual:@"name"]) +// return; + if ([item isKindOfClass:[EOModel class]]) + [cell setImage: [NSImage imageNamed:@"Model_small.tiff"]]; + if ([item isKindOfClass:[EOEntity class]]) + [cell setImage: [NSImage imageNamed:@"Entity_small.tiff"]]; + if ([item isKindOfClass:[EORelationship class]]) + [cell setImage: [NSImage imageNamed:@"Relationship_small.tiff"]]; +} +#endif +@end diff --git a/DBModeler/Modeler.h b/DBModeler/Modeler.h new file mode 100644 index 0000000..d92deeb --- /dev/null +++ b/DBModeler/Modeler.h @@ -0,0 +1,40 @@ +#ifndef __Modeler_H_ +#define __Modeler_H_ + +/* + Modeler.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +@class NSObject; + +@interface Modeler : NSObject +{ + + +} + +@end + +#endif // __Modeler_H_ + diff --git a/DBModeler/Modeler.m b/DBModeler/Modeler.m new file mode 100644 index 0000000..a8f7223 --- /dev/null +++ b/DBModeler/Modeler.m @@ -0,0 +1,250 @@ +/** + Modeler.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + +#include "Modeler.h" +#include "AdaptorsPanel.h" +#include "MainModelEditor.h" +#include "ModelerEntityEditor.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +/* TODO validate menu items.. */ +@interface NSMenu (im_lazy) +-(id ) addItemWithTitle: (NSString *)s; +-(id ) addItemWithTitle: (NSString *)s action: (SEL)sel; +@end + +@interface EOModel (foo) +-(void)setCreatesMutableObjects:(BOOL)flag; +@end + +@implementation NSMenu (im_lazy) +-(id ) addItemWithTitle: (NSString *)s +{ + return [self addItemWithTitle: s action: NULL keyEquivalent: nil]; +} + +-(id ) addItemWithTitle: (NSString *)s action: (SEL)sel +{ + return [self addItemWithTitle: s action: sel keyEquivalent: nil]; +} +@end + + +@implementation Modeler +-(void)bundleDidLoad:(NSNotification *)not +{ + /* a place to put breakpoints? */ +} + +- (void) applicationWillFinishLaunching:(NSNotification *)not +{ + int i,c; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSArray *bundlesToLoad = RETAIN([defaults arrayForKey: @"BundlesToLoad"]); + NSMenu *mainMenu,*subMenu; + NSFileManager *fm = [NSFileManager defaultManager]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(bundleDidLoad:) + name:NSBundleDidLoadNotification + object:nil]; + for (i=0, c = [bundlesToLoad count]; i < c; i++) + { + BOOL isDir; + NSString *path = [[bundlesToLoad objectAtIndex:i] stringByExpandingTildeInPath]; + + [fm fileExistsAtPath:path isDirectory:&isDir]; + if (isDir) + { + NSLog(@"loading bundle: %@",path); + + [[[NSBundle bundleWithPath: path] principalClass] class]; //call class so +initialize gets called + } + } + RELEASE(bundlesToLoad); + + /* useful method for setting breakpoints after an adaptor is loaded */ + + mainMenu = [[NSMenu alloc] init]; + subMenu = [[NSMenu alloc] init]; + + [subMenu addItemWithTitle: _(@"Info..") + action: @selector(:orderFrontStandardInfoPanel:)]; + + [subMenu addItemWithTitle: _(@"Preferences...") + action: @selector(openPrefs:)]; + + [mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Info")]]; + [subMenu release]; + subMenu = [[NSMenu alloc] init]; + + [subMenu addItemWithTitle: _(@"New...") + action: @selector(new:) + keyEquivalent: @"n"]; + + [subMenu addItemWithTitle: _(@"Open") + action: @selector(open:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Save") + action: @selector(save:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Save As") + action: @selector(saveAs:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Revert") + action: @selector(revert:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Set Adaptor Info") + action: @selector(setAdaptor:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Switch Adaptor") + action: @selector(switchAdaptor:) + keyEquivalent: @""]; + + [subMenu addItemWithTitle: _(@"Check consistency") + action: @selector(checkConsistency:) + keyEquivalent: @""]; + + [mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle:_(@"Model")]]; + [subMenu release]; + + + subMenu = [[NSMenu alloc] init]; + [subMenu addItemWithTitle:_(@"Inspector") + action: @selector(showInspector:) + keyEquivalent: @"i"]; + [mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Tools")]]; + [subMenu release]; + + subMenu = [[NSMenu alloc] init]; + [subMenu addItemWithTitle: _(@"Add entity") + action: @selector(addEntity:) + keyEquivalent: @"e"]; + + [subMenu addItemWithTitle: _(@"Add attribute") + action: @selector(addAttribute:) + keyEquivalent: @"a"]; + + [subMenu addItemWithTitle: _(@"Add relationship") + action: @selector(addRelationship:) + keyEquivalent: @"r"]; + + [mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Property")]]; + [subMenu release]; + + [mainMenu addItemWithTitle: _(@"Hide") + action: @selector(hide:) + keyEquivalent: @"h"]; + + [mainMenu addItemWithTitle: _(@"Quit...") + action: @selector(terminate:) + keyEquivalent: @"q"]; + + [NSApp setMainMenu: mainMenu]; + /* make this a bundle? */ + [EOModelerDocument setDefaultEditorClass: NSClassFromString(@"MainModelEditor")]; + [[mainMenu window] makeKeyAndOrderFront:self]; +} + +- (void)new:(id)sender +{ + /* this entire function -really- seems to belong somewhere else */ + EOModelerCompoundEditor *editor; + EOModelerDocument *newModelerDoc; + EOModel *newModel = [[EOModel alloc] init]; + EOAdaptor *newAdaptor; + NSString *modelName; + unsigned int nDocs; + + //[newModel setCreateMutableObjects:YES]; + nDocs = [[EOMApp documents] count]; + + modelName=[NSString stringWithFormat:@"Model_%u",++nDocs]; + [newModel setName:modelName]; + [[EOModelGroup defaultGroup] addModel:newModel]; + + newModelerDoc = [[EOModelerDocument alloc] initWithModel: newModel]; + editor = (EOModelerCompoundEditor*)[newModelerDoc addDefaultEditor]; + [EOMApp setCurrentEditor: editor]; + [EOMApp addDocument: newModelerDoc]; + [newModelerDoc activate]; +} + +- (void) setAdaptor:(id)sender +{ + NSString *adaptorName; + EOAdaptor *adaptor; + AdaptorsPanel *adaptorsPanel = [[AdaptorsPanel alloc] init]; + + adaptorName = [adaptorsPanel runAdaptorsPanel]; + RELEASE(adaptorsPanel); + [[[EOMApp activeDocument] model] setAdaptorName: adaptorName]; + adaptor = [EOAdaptor adaptorWithName: adaptorName]; + [[[EOMApp activeDocument] model] setConnectionDictionary:[adaptor runLoginPanel]]; + +} + +- (void) showInspector:(id)sender +{ + [EOMInspectorController showInspector]; +} + +- (void) open:(id)sender +{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + if ([panel runModalForTypes:[NSArray arrayWithObject:@"eomodeld"]] == NSOKButton) + { + NSArray *modelPaths = [panel filenames]; + int i,c; + + for (i = 0, c = [modelPaths count]; i < c; i++) + { + NSString *modelPath = [modelPaths objectAtIndex:i]; + EOModel *model = [[EOModel alloc] initWithContentsOfFile:modelPath]; + EOModelerDocument *newDoc = [[EOModelerDocument alloc] initWithModel:model]; + EOModelerEditor *editor = (EOModelerCompoundEditor*)[newDoc addDefaultEditor]; + [EOMApp setCurrentEditor: editor]; + [EOMApp addDocument: newDoc]; + [newDoc activate]; + } + } +} +@end + diff --git a/DBModeler/ModelerAttributeEditor.h b/DBModeler/ModelerAttributeEditor.h new file mode 100644 index 0000000..99f2724 --- /dev/null +++ b/DBModeler/ModelerAttributeEditor.h @@ -0,0 +1,49 @@ +#ifndef __ModelerAttributeEditor_H_ +#define __ModelerAttributeEditor_H_ + +/* + ModelerAttributeEditor.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ModelerTableEmbedibleEditor.h" +#include + +@class NSSplitView; +@class NSTableView; +@class EODisplayGroup; +@class PlusMinusView; + +@interface ModelerAttributeEditor : ModelerTableEmbedibleEditor +{ + NSSplitView *_mainView; + NSTableView *_attributes_tableView; + NSTableView *_relationships_tableView; + EODisplayGroup *_attributes_dg; + EODisplayGroup *_relationships_dg; + id _entityToObserve; + id _attributeToObserve; +} + +@end + +#endif // __ModelerAttributeEditor_H_ + diff --git a/DBModeler/ModelerAttributeEditor.m b/DBModeler/ModelerAttributeEditor.m new file mode 100644 index 0000000..63a082a --- /dev/null +++ b/DBModeler/ModelerAttributeEditor.m @@ -0,0 +1,252 @@ +/** + ModelerAttributeEditor.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include "DefaultColumnProvider.h" +#include "ModelerAttributeEditor.h" +#include "ModelerEntityEditor.h" +#include "KVDataSource.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + + +@interface NSArray (EOMAdditions) +- (id) firstSelectionOfClass:(Class) aClass; +@end +@implementation ModelerAttributeEditor + +- (id) initWithParentEditor:(id)parentEditor +{ + NSScrollView *scrollView; + KVDataSource *wds1, *wds2; + int i,c; + NSPopUpButton *cornerView; + NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""]; + NSArray *columnNames; + + self = [super initWithParentEditor:parentEditor]; + [DefaultColumnProvider class]; + _mainView = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + /* setup the attributes table view */ + scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + _attributes_tableView = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + [_attributes_tableView setAutoresizesAllColumnsToFit:YES]; + [scrollView setBorderType: NSBezelBorder]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + [scrollView setDocumentView:_attributes_tableView]; + RELEASE(_attributes_tableView); + [_mainView addSubview:scrollView]; + RELEASE(scrollView); + + /* and the tableViews corner view */ + cornerView = [[NSPopUpButton alloc] initWithFrame:[[_attributes_tableView cornerView] bounds] pullsDown:YES]; + [[cornerView cell] setArrowPosition:NSPopUpNoArrow]; + [cornerView setTitle:@"+"]; + [cornerView setPreferredEdge:NSMinYEdge]; + + [[cornerView cell] setUsesItemFromMenu:NO]; + [[cornerView cell] setShowsFirstResponder:NO]; + [[cornerView cell] setMenuItem:mi]; + + [_attributes_tableView setCornerView:cornerView]; + RELEASE(cornerView); + + /* and the attributes tableview's display group */ + wds1 = [[KVDataSource alloc] initWithClassDescription:nil + editingContext:[[self document] editingContext]]; + [wds1 setKey:@"attributes"]; + _attributes_dg = [[EODisplayGroup alloc] init]; + [_attributes_dg setDataSource:wds1]; + RELEASE(wds1); + [_attributes_dg setFetchesOnLoad:YES]; + [_attributes_dg setDelegate:self]; + + [self setupCornerView:cornerView + tableView:_attributes_tableView + displayGroup:_attributes_dg + forClass:[EOAttribute class]]; + [self addDefaultTableColumnsForTableView:_attributes_tableView + displayGroup:_attributes_dg]; + + /* setup the relationships table view */ + scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + [scrollView setBorderType: NSBezelBorder]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + _relationships_tableView = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + [_relationships_tableView setAutoresizesAllColumnsToFit:YES]; + [scrollView setDocumentView:_relationships_tableView]; + RELEASE(_relationships_tableView); + [_mainView addSubview:scrollView]; + RELEASE(scrollView); + + /* and the tableViews corner view */ + cornerView = [[NSPopUpButton alloc] initWithFrame:[[_relationships_tableView cornerView] bounds] pullsDown:YES]; + [cornerView setPreferredEdge:NSMinYEdge]; + [[cornerView cell] setArrowPosition:NSPopUpNoArrow]; + [cornerView setTitle:@"+"]; + [[cornerView cell] setUsesItemFromMenu:NO]; + [[cornerView cell] setShowsFirstResponder:NO]; + [[cornerView cell] setMenuItem:mi]; + + [_relationships_tableView setCornerView:cornerView]; + RELEASE(cornerView); + /* and the relationships display group. */ + wds2 = [[KVDataSource alloc] initWithClassDescription:nil + editingContext:[[self document] editingContext]]; + [wds2 setKey:@"relationships"]; + _relationships_dg = [[EODisplayGroup alloc] init]; + [_relationships_dg setDataSource:wds2]; + RELEASE(wds2); + [_relationships_dg setFetchesOnLoad:YES]; + [_relationships_dg setDelegate:self]; + + [self setupCornerView:cornerView + tableView:_relationships_tableView + displayGroup:_relationships_dg + forClass:[EORelationship class]]; + + [self addDefaultTableColumnsForTableView:_relationships_tableView + displayGroup:_relationships_dg]; + + return self; +} + +- (void) dealloc +{ + if (_entityToObserve) + [EOObserverCenter removeObserver:self forObject:_entityToObserve]; + if (_attributeToObserve) + [EOObserverCenter removeObserver:self forObject:_attributeToObserve]; + RELEASE(_mainView); + RELEASE(_relationships_dg); + RELEASE(_attributes_dg); +} + +- (NSView *)mainView +{ + return _mainView; +} + +- (BOOL) canSupportCurrentSelection +{ + id selection = [self selectionWithinViewedObject]; + BOOL flag; + + if ([selection count] == 0) + return NO; + selection = [selection objectAtIndex:0]; + flag = ([selection isKindOfClass:[EOEntity class]] + || [selection isKindOfClass:[EORelationship class]]); + return flag; +} + + +- (void) activate +{ + if (_entityToObserve) + [EOObserverCenter removeObserver:self forObject:_entityToObserve]; + + _entityToObserve = [[self selectionPath] firstSelectionOfClass:[EOEntity class]]; + [EOObserverCenter addObserver:self forObject:_entityToObserve]; + + [(KVDataSource *)[_attributes_dg dataSource] setDataObject: _entityToObserve]; + [(KVDataSource *)[_relationships_dg dataSource] setDataObject: _entityToObserve]; + [_attributes_dg fetch]; + [_relationships_dg fetch]; +} + +- (NSArray *) friendEditorClasses +{ + return [NSArray arrayWithObjects: [ModelerEntityEditor class], nil]; +} + +- (void) objectWillChange:(id)sender +{ + [[NSRunLoop currentRunLoop] performSelector:@selector(needToFetch:) + target:self + argument:nil + order:999 + modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; +} + +- (void) needToFetch:(id)arg +{ + [_attributes_dg fetch]; + [_relationships_dg fetch]; +} + +- (NSArray *)defaultColumnNamesForClass:(Class)aClass +{ + NSArray *colNames = [super defaultColumnNamesForClass:aClass]; + if (colNames == nil || [colNames count] == 0) + { + if (aClass == [EOAttribute class]) + return DefaultAttributeColumns; + else if (aClass == [EORelationship class]) + return DefaultRelationshipColumns; + else + return nil; + } + + return colNames; +} + +- (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup +{ + NSArray *currentSelection = [_parentEditor selectionWithinViewedObject]; + id theSelection; + int c = [currentSelection count]; + if (c && c == 1 ) + theSelection = [currentSelection objectAtIndex:0]; + + if ([theSelection isKindOfClass:[EOEntity class]]) + { + NSArray *vop; + vop = [_parentEditor viewedObjectPath]; + [self setViewedObjectPath: [vop arrayByAddingObject:theSelection]]; + } + + [self setSelectionWithinViewedObject: [displayGroup selectedObjects]]; +} + +@end + diff --git a/DBModeler/ModelerEntityEditor.h b/DBModeler/ModelerEntityEditor.h new file mode 100644 index 0000000..9f1088e --- /dev/null +++ b/DBModeler/ModelerEntityEditor.h @@ -0,0 +1,54 @@ +#ifndef __ModelerEntityEditor_H_ +#define __ModelerEntityEditor_H_ + +/* + ModelerEntityEditor.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ModelerTableEmbedibleEditor.h" + +#include + +@class NSBox; +@class NSWindow; +@class NSTableView; +@class NSSplitView; +@class EODisplayGroup; +@class PlusMinusView; + +@interface ModelerEntityEditor : ModelerTableEmbedibleEditor +{ + NSTableView *_topTable; + NSTableView *_bottomTable; + NSSplitView *_splitView; + NSWindow *_window; + NSBox *_box; + EODisplayGroup *dg; +} + + +-(void)objectWillChange:(id)anObject; + +@end + +#endif // __ModelerEntityEditor_H_ + diff --git a/DBModeler/ModelerEntityEditor.m b/DBModeler/ModelerEntityEditor.m new file mode 100644 index 0000000..1b8713f --- /dev/null +++ b/DBModeler/ModelerEntityEditor.m @@ -0,0 +1,202 @@ +/** + ModelerEntityEditor.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include "DefaultColumnProvider.h" +#include "ModelerAttributeEditor.h" +#include "ModelerEntityEditor.h" +#include "KVDataSource.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +@interface EOModelerDocument (asdf) +-(void)_setDisplayGroup:(id)displayGroup; +@end + +@interface ModelerEntityEditor (Private) +- (void) _loadColumnsForClass:(Class) aClass; +@end + +@implementation ModelerEntityEditor + +- (BOOL) canSupportCurrentSelection +{ + id selection = [self selectionWithinViewedObject]; + BOOL flag; + + if ([selection count] == 0) + { + flag = NO; + return flag; + } + selection = [selection objectAtIndex:0]; + flag = [selection isKindOfClass:[EOModel class]]; + //NSLog(@"%@ %@ %i", [self class], NSStringFromSelector(_cmd), flag); + return flag; +} + +- (NSArray *) friendEditorClasses +{ + return [NSArray arrayWithObjects: [ModelerAttributeEditor class], nil]; +} + +- (id) initWithParentEditor: (EOModelerCompoundEditor *)parentEditor +{ + if (self = [super initWithParentEditor:parentEditor]) + { + id columnProvider; + NSTableColumn *tc; + EOClassDescription *classDescription = nil; + KVDataSource *wds; + NSArray *columnNames; + int i; + Class editorClass = [EOEntity class]; + NSScrollView *scrollView; + NSPopUpButton *cornerView; + NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""]; + + _splitView = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; + scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + [scrollView setBorderType: NSBezelBorder]; + + _topTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; + _bottomTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; + [_topTable setAutoresizesAllColumnsToFit:YES]; + [scrollView setDocumentView:_topTable]; + [_splitView addSubview:scrollView]; + + scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; + [scrollView setHasHorizontalScroller:YES]; + [scrollView setHasVerticalScroller:YES]; + [scrollView setBorderType: NSBezelBorder]; + [_bottomTable setAutoresizesAllColumnsToFit:YES]; + [scrollView setDocumentView:_bottomTable]; + [_splitView addSubview:scrollView]; + + [DefaultColumnProvider class]; // calls +initialize + + cornerView = [[NSPopUpButton alloc] initWithFrame:[[_topTable cornerView] bounds] pullsDown:YES]; + [cornerView setPreferredEdge:NSMinYEdge]; + [cornerView setTitle:@"+"]; + [[cornerView cell] setArrowPosition:NSPopUpNoArrow]; + //[mi setImage:[NSImage imageNamed:@"plus"]]; + // [mi setOnStateImage:[NSImage imageNamed:@"plus"]]; + // [mi setOffStateImage:[NSImage imageNamed:@"plus"]]; + //[mi setState:NSOnState]; + [[cornerView cell] setUsesItemFromMenu:NO]; + [[cornerView cell] setShowsFirstResponder:NO]; + [[cornerView cell] setShowsStateBy:NSContentsCellMask]; + [[cornerView cell] setMenuItem:mi]; + [[cornerView cell] setImagePosition:NSNoImage]; + + [_topTable setCornerView:cornerView]; + RELEASE(cornerView); + [_topTable setAllowsMultipleSelection:YES]; + + classDescription = nil; + wds = [[KVDataSource alloc] + initWithClassDescription:classDescription + editingContext:[[self document] editingContext]]; + + [wds setDataObject: [[self document] model]]; + [wds setKey:@"entities"]; + dg = [[EODisplayGroup alloc] init]; + [EOObserverCenter addObserver:self forObject:[[self document] model]]; + [dg setDataSource: wds]; + [dg setFetchesOnLoad:YES]; + [dg setDelegate: self]; + + [self setupCornerView:cornerView + tableView:_topTable + displayGroup:dg + forClass:[EOEntity class]]; + + [self addDefaultTableColumnsForTableView:_topTable + displayGroup:dg]; + + + } + return self; +} +- (NSArray *)defaultColumnNamesForClass:(Class)aClass +{ + NSArray *colNames = [super defaultColumnNamesForClass:aClass]; + if (colNames == nil || [colNames count] == 0) + { + if (aClass == [EOEntity class]) + return DefaultEntityColumns; + else return nil; + } + + return colNames; +} + +- (void) activate +{ + [dg fetch]; +} + +- (NSView *)mainView +{ + return _splitView; +} + +- (void) objectWillChange:(id)anObject +{ + [[NSRunLoop currentRunLoop] performSelector:@selector(needToFetch:) target:self argument:nil order:999 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; +} + +- (void) needToFetch:(id)sth +{ + [dg fetch]; + [_topTable reloadData]; +} +@end + +@implementation ModelerEntityEditor (DisplayGroupDelegate) +- (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup +{ + //NSLog(@"didChangeSelection %@ %@",dg,[dg selectedObjects]); + [self setSelectionWithinViewedObject: [displayGroup selectedObjects]]; +} + +@end + diff --git a/DBModeler/ModelerTableEmbedibleEditor.h b/DBModeler/ModelerTableEmbedibleEditor.h new file mode 100644 index 0000000..cbbe649 --- /dev/null +++ b/DBModeler/ModelerTableEmbedibleEditor.h @@ -0,0 +1,53 @@ +#ifndef __ModelerTableEmbedibleEditor_H__ +#define __ModelerTableEmbedibleEditor_H__ + +/* + ModelerTableEmbedibleEditor.h + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +@class EODisplayGroup; +@class NSPopUpButton; +@class NSTableView; +/* base class for the default embedible editors + * mostly takes care of corner views right now.. + */ +@interface ModelerTableEmbedibleEditor : EOModelerEmbedibleEditor + +- (void) setupCornerView:(NSPopUpButton *)cornerView + tableView:(NSTableView *)tableView + displayGroup:(EODisplayGroup *)dg + forClass:(Class)aClass; + +- (void) _cornerAction:(id)sender; +- (NSArray *)defaultColumnNamesForClass:(Class)aClass; +- (void) addDefaultTableColumnsForTableView:(NSTableView *)tv + displayGroup:(EODisplayGroup *)dg; +- (void) addTableColumnForItem:(NSMenuItem *)item + tableView:(NSTableView *)tv; +- (void) removeTableColumnForItem:(NSMenuItem *)menuItem + tableView:(NSTableView *)tv; + +@end + +#endif // __ModelerTableEmbedibleEditor_H__ diff --git a/DBModeler/ModelerTableEmbedibleEditor.m b/DBModeler/ModelerTableEmbedibleEditor.m new file mode 100644 index 0000000..8c7c954 --- /dev/null +++ b/DBModeler/ModelerTableEmbedibleEditor.m @@ -0,0 +1,149 @@ +/** + ModelerTableEmbedibleEditor.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include "ModelerTableEmbedibleEditor.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "EOModeler/EOModelerApp.h" +/* base class with some methods shared among default embedible editors */ +@implementation ModelerTableEmbedibleEditor : EOModelerEmbedibleEditor +- (void) setupCornerView:(NSPopUpButton *)cornerView + tableView:(NSTableView *)tableView + displayGroup:(EODisplayGroup *)dg + forClass:(Class)aClass +{ + NSArray *columnNames = [EOMApp columnNamesForClass:aClass]; + int i, c; + [cornerView setTarget:self]; + [cornerView setAction:@selector(_cornerAction:)]; + [[cornerView cell] setRepresentedObject: aClass]; + + for (i = 0, c = [columnNames count]; i < c; i++) + { + NSString *columnName = [columnNames objectAtIndex:i]; + NSMenuItem *item; + + [cornerView addItemWithTitle:columnName]; + item = (NSMenuItem *)[cornerView itemWithTitle:columnName]; + [item setOnStateImage:[NSImage imageNamed:@"common_2DCheckMark"]]; + [item setState:NSOffState]; + } +} + +/* attempts to find column names from the defaults. + * subclasses should call supers, and return their default columns. + * if it returns nil or an array of count 0 */ +- (NSArray *)defaultColumnNamesForClass:(Class)aClass +{ + return [[[NSUserDefaults standardUserDefaults] dictionaryForKey:NSStringFromClass(aClass)] objectForKey:@"Columns"]; +} + +- (void) addDefaultTableColumnsForTableView:(NSTableView *)tv + displayGroup:(EODisplayGroup *)dg +{ + Class aClass = [[(NSPopUpButton*)[tv cornerView] cell] representedObject]; + NSArray *columnNames = [self defaultColumnNamesForClass:aClass]; + int i, c; + for (i = 0, c = [columnNames count]; i < c; i++) + { + NSString *columnName = [columnNames objectAtIndex:i]; + NSPopUpButton *cv = [tv cornerView]; + NSMenuItem *item; + id provider; + NSTableColumn *tc = [[NSTableColumn alloc] initWithIdentifier:nil]; + + provider = [EOMApp providerForName: columnName class:aClass]; + + /* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */ + [tv addTableColumn:tc]; + + [provider initColumn:tc class:aClass name:columnName + displayGroup:dg document:[self document]]; + + item = (NSMenuItem *)[cv itemWithTitle:columnName]; + [item setRepresentedObject:tc]; + [item setState:NSOnState]; + } + [tv sizeToFit]; +} + +- (void) addTableColumnForItem:(NSMenuItem *)item + tableView:(NSTableView *)tv +{ + NSString *columnName = [item title]; + Class aClass = [[(NSPopUpButton *)[tv cornerView] cell] representedObject]; + id provider = [EOMApp providerForName:columnName class:aClass]; + NSTableColumn *tc = [[NSTableColumn alloc] initWithIdentifier:nil]; // can't rely on ident. + + [item setState:NSOnState]; + [item setRepresentedObject:tc]; + + /* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */ + [tv addTableColumn:tc]; + + /* this requires that the table at least have 1 table column in it... + * so we have to have another method to setup the default table columns */ + [provider initColumn:tc + class:aClass + name:columnName + displayGroup:[[tv delegate] displayGroupForAspect:@"source"] // <-+-^ + document:[self document]]; + + [tv sizeToFit]; +} + +- (void) removeTableColumnForItem:(NSMenuItem *)item + tableView:(NSTableView *)tv +{ + [tv removeTableColumn:[item representedObject]]; + [item setRepresentedObject:nil]; + [item setState:NSOffState]; +} + +- (void) _cornerAction:(id)sender +{ + NSMenuItem *item = (NSMenuItem*)[sender selectedItem]; + NSTableView *tv = [[sender enclosingScrollView] documentView]; + if ([item state] == NSOnState) + { + [self removeTableColumnForItem:item tableView:tv]; + } + else + { + [self addTableColumnForItem:item tableView:tv]; + } +} + +@end + diff --git a/DBModeler/Resources/ClassProperty_On.tiff b/DBModeler/Resources/ClassProperty_On.tiff new file mode 100644 index 0000000000000000000000000000000000000000..b91f10ee1967cf61acadcf573b0fd3f24a1af560 GIT binary patch literal 1352 zcmds1O-sW-5S>k1$wjb&3f3PWf-ZRSSk!|(h*C(eQj@6$woS>V0sm5dl1G1tb!Od# zB{XXNxR@}RH^X~xW-b{Fjv#CUEPwDsQDoFrRV~*I)`A_su9o?Kt>@kRsPFjEd|&5d z-=j(I^H*W#@n7|P->SR0=WgfRbid=&JzU@A&-9Mhlz&stUf&76(d|*c_p5amUZD+w z=;jeEgSV&<9u5f8&jOz5)3SZmY*-u+-V_0hD8CS=E8aars<%DYV?YjL0Op5^n9 zebF&HoOJ+t7WWAscs_>~^W33_sf5tJ@-dsD%*VwvjZvz!#JJS*VYbi(&Siq-u}bf$ uk*HI7d48QGs4$m9)Y&4BQOgT8*7`Qj=9m{xcQ><>BArZlz!e1_Z}J;P=z|de literal 0 HcmV?d00001 diff --git a/DBModeler/Resources/Key_On.tiff b/DBModeler/Resources/Key_On.tiff new file mode 100644 index 0000000000000000000000000000000000000000..6d3d9c542da6c50b554642fd79c4f4f3ac4e3be1 GIT binary patch literal 1106 zcmchW-%7(U6vmTwN^cY=I6=MWrHC5v31kXdbtq!5WwvLw(5=#T8@|#W$t#~k{nBJ5 zbPOxPPHFO;)8F~iKs@h=IW}Y8e=*V^W#xv)cv-K4CNLOo( zSMge6<>Ko<`KpxazW5hreRG&aQblU~GOUWPj7Ot}hNA#!p3JYh&AwQR@j1usQg6ZM zhPI$_S=a{_TgPS2y4Du-2DjK9_D?XI&>iUG7GrI$>O1hajoclrW!;X}=g_;Fmksy$ zS~*V_b@sKsfj%(m9BM6Rkmi(+h|(d6tX~Y{fJ72cD468pbu`WkdJ`c{PLlWqfiO7} zm)%|(QbL({q&yvG0p;SB-kW3E+Y3SBKOMcJ;+wqc;zva`wzUF BqRapQ literal 0 HcmV?d00001 diff --git a/DBModeler/Resources/ModelDrag.tiff b/DBModeler/Resources/ModelDrag.tiff new file mode 100644 index 0000000000000000000000000000000000000000..b7fddd04031483fd76f0d6a6282f3b88fcba5dfe GIT binary patch literal 3477 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 Dh0nB= literal 0 HcmV?d00001 diff --git a/DBModeler/main.m b/DBModeler/main.m new file mode 100644 index 0000000..8845654 --- /dev/null +++ b/DBModeler/main.m @@ -0,0 +1,40 @@ +/** + main.m + + Author: Matt Rice + Date: Apr 2005 + + This file is part of DBModeler. + + + DBModeler 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. + + DBModeler 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. + + You should have received a copy of the GNU General Public License + along with DBModeler; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +**/ + + +#include +#include +#include "Modeler.h" + +int main (int argc, const char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [EOModelerApp sharedApplication]; + [NSApp setDelegate: [[Modeler alloc] init]]; + [NSApp run]; + RELEASE(pool); + return 0; +} diff --git a/GDL2Palette/ConnectionInspector.h b/GDL2Palette/ConnectionInspector.h new file mode 100644 index 0000000..2cc13eb --- /dev/null +++ b/GDL2Palette/ConnectionInspector.h @@ -0,0 +1,27 @@ +#include +@class NSBrowser; +@class NSPopUpButton; + +@interface GDL2ConnectionInspector : IBInspector +{ + NSBrowser *oaBrowser; + NSBrowser *connectionsBrowser; + NSPopUpButton *popUp; + + NSArray *_keys; + NSArray *_signatures; + NSArray *_values; + NSMutableArray *_connectors; + + NSNibConnector *_currentConnector; + +} + +- (void) updateKeys; +- (void) updateValues; +- (void) updateButtons; +- (void) selectedConnector; +- (void) selectedOutletOrAction; +@end + + diff --git a/GDL2Palette/ConnectionInspector.m b/GDL2Palette/ConnectionInspector.m new file mode 100644 index 0000000..81dbd04 --- /dev/null +++ b/GDL2Palette/ConnectionInspector.m @@ -0,0 +1,572 @@ +#include "ConnectionInspector.h" +#include "Foundation+Categories.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include +/* TODO get notifications for IB{Will,Did}RemoveConnectorNotification + * and remove the object from the _objectToAssociation map table if + * there are no more connectors for it */ +static NSMapTable *_objectToAssociation; + +@interface NSApplication(missingStuff) +- (GormClassManager *)classManager; +@end + +@implementation GDL2ConnectionInspector ++ (void) initialize +{ + _objectToAssociation = NSCreateMapTableWithZone(NSObjectMapKeyCallBacks, + NSObjectMapValueCallBacks, + 0, [self zone]); +} + +- (NSButton *)okButton +{ + return nil; +} + +- (id) init +{ + self = [super init]; + + [NSBundle loadNibNamed:@"GDL2ConnectionInspector" owner:self]; + return self; +} + +- (void) awakeFromNib +{ + [oaBrowser setMaxVisibleColumns:2]; + [oaBrowser setAllowsMultipleSelection:NO]; + [oaBrowser setHasHorizontalScroller:NO]; + [oaBrowser setTitled:NO]; + + [connectionsBrowser setTitled:NO]; + [connectionsBrowser setHasHorizontalScroller:NO]; + [connectionsBrowser setMaxVisibleColumns:1]; + [connectionsBrowser setAllowsMultipleSelection:NO]; + + [popUp removeAllItems]; + +} + +- (void) setObject:(id)anObject +{ + NSArray *foo; + int i,c; + + [super setObject:anObject]; + + if (!object) return; + + RELEASE(_connectors); + _connectors = [NSMutableArray new]; + + [_connectors addObjectsFromArray:[[[(id)NSApp activeDocument] + connectorsForSource:object] + arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClasses:) + withObject:[NSArray arrayWithObjects:[NSNibControlConnector class], + [NSNibOutletConnector class], + [EOAspectConnector class], + nil]]]; + + DESTROY(_values); + [self updateKeys]; + [popUp removeAllItems]; + [popUp addItemWithTitle:@"Outlets"]; + + foo = RETAIN([EOAssociation associationClassesForObject:anObject]); + for (i = 0, c = [foo count]; i < c; i++) + { + Class assocSubclass = [foo objectAtIndex:i]; + NSString *title = [assocSubclass displayName]; + [popUp addItemWithTitle:title]; + [[popUp itemWithTitle:title] setRepresentedObject:assocSubclass]; + } + RELEASE(foo); + [connectionsBrowser reloadColumn:0]; + [oaBrowser loadColumnZero]; + [self updateButtons]; +} + +- (void) _popUpAction:(id)sender +{ + [self updateKeys]; + [oaBrowser reloadColumn:0]; + [oaBrowser reloadColumn:1]; + [connectionsBrowser reloadColumn:0]; +} + +- (void) updateKeys +{ + Class repObj = [[popUp selectedItem] representedObject]; + RELEASE(_keys); + RELEASE(_signatures); + + /* outlets.. */ + if (repObj == nil) + { + _keys = RETAIN([[NSApp classManager] allOutletsForObject:object]); + _signatures = nil; + } + else + { + _keys = RETAIN([repObj aspects]); + _signatures = RETAIN([repObj aspectSignatures]); + } +} + +- (void) updateValues +{ + id dest = [NSApp connectDestination]; + int selection = [oaBrowser selectedRowInColumn:0]; + NSString *sig = [_signatures objectAtIndex:selection]; + NSMutableArray *objs = [NSMutableArray new]; + EOEntity *ent = nil; + + sig = [sig uppercaseString]; + if ([dest isKindOfClass:[EODisplayGroup class]]) + ent = [(EODatabaseDataSource *)[(EODisplayGroup *)dest dataSource] entity]; + if ([sig length] && ent) + { + int i,c; + for (i = 0, c = [sig length]; i < c; i++) + { + switch ([sig characterAtIndex:i]) + { + case 'A': + [objs addObjectsFromArray: [ent classAttributes]]; + break; + case '1': + [objs addObjectsFromArray: [ent classToOneRelationships]]; + break; + case 'M': + [objs addObjectsFromArray: [ent classToManyRelationships]]; + break; + } + } + } + RELEASE(_values); + _values = objs; + +} + +- (void) _selectAction:(NSString*)label +{ + [oaBrowser reloadColumn:1]; + if (label != nil) + [oaBrowser selectRow:[_values indexOfObject:label] inColumn:1]; +} + +- (void) _oaBrowserAction:(id)sender +{ + unsigned i,c; + NSNibConnector *conn; + + switch ([sender selectedColumn]) + { + case 0: + { + id dest; + + if ([[popUp selectedItem] representedObject] == nil) + { + if ([[[sender selectedCell] stringValue] isEqual:@"target"]) + { + NSArray *controlConnectors; + controlConnectors = [_connectors arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClass:) + withObject:[NSNibControlConnector class]]; + c = [controlConnectors count]; + conn = c ? [controlConnectors objectAtIndex:0] + : nil; + dest = c ? [conn destination] + : [NSApp connectDestination]; + RELEASE(_values); + _values = RETAIN([[NSApp classManager] allActionsForObject: dest]); + if ([_values count] > 0) + { + conn = [NSNibControlConnector new]; + [conn setSource: object]; + [conn setDestination: [NSApp connectDestination]]; + [conn setLabel: [_values objectAtIndex:0]]; + AUTORELEASE(conn); + } + if (_currentConnector != conn) + ASSIGN(_currentConnector, conn); + [self _selectAction: [conn label]]; + } + else + { + BOOL found = NO; + NSString *title = [[sender selectedCell] stringValue]; + NSArray *outletConnectors; + + outletConnectors = [_connectors arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClass:) + withObject:[NSNibOutletConnector class]]; + for (i = 0, c = [outletConnectors count]; i < c; i++) + { + conn = [outletConnectors objectAtIndex:i]; + if ([conn label] == nil || [[conn label] isEqual:title]) + { + found = YES; + ASSIGN(_currentConnector, conn); + break; + } + } + + if (!found) + { + RELEASE(_currentConnector); + _currentConnector = [NSNibOutletConnector new]; + [_currentConnector setSource:object]; + [_currentConnector setDestination:[NSApp connectDestination]]; + [_currentConnector setLabel:title]; + } + } + [connectionsBrowser loadColumnZero]; + [self selectedOutletOrAction]; + } + else /* association connector */ + { + [self updateValues]; + [oaBrowser reloadColumn:1]; + } + } + break; + case 1: + if ([[popUp selectedItem] representedObject] == nil) + { + BOOL found = NO; + NSString *title = [[sender selectedCell] stringValue]; + NSArray *controlConnectors; + + controlConnectors = [_connectors arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClass:) + withObject:[NSNibControlConnector class]]; + + for (i = 0, c = [controlConnectors count]; i < c; i++) + { + NSNibConnector *con = [controlConnectors objectAtIndex:i]; + NSString *action = [con label]; + if ([action isEqual:title]) + { + ASSIGN(_currentConnector, con); + found = YES; + break; + } + } + if (!found) + { + RELEASE(_currentConnector); + _currentConnector = [NSNibControlConnector new]; + [_currentConnector setSource:object]; + [_currentConnector setDestination:[NSApp connectDestination]]; + [_currentConnector setLabel:title]; + [connectionsBrowser loadColumnZero]; + } + [self selectedOutletOrAction]; + } + else + { + BOOL found = NO; + NSString *aspectName = [[sender selectedCellInColumn:0] stringValue]; + NSString *key = [[sender selectedCell] stringValue]; + NSString *label = [NSString stringWithFormat:@"%@ - %@", aspectName, key]; + NSArray *aspectConnectors; + + aspectConnectors = [_connectors arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClass:) + withObject:[EOAspectConnector class]]; + for (i = 0, c = [aspectConnectors count]; i < c; i++) + { + NSNibConnector *con = [aspectConnectors objectAtIndex:i]; + if ([con source] == object && [[con label] isEqual: label]) + { + ASSIGN(_currentConnector, con); + found = YES; + break; + } + } + if (!found) + { + EOAssociation *assoc; + + assoc = NSMapGet(_objectToAssociation, object); + + if (!assoc) + { + Class assocClass = [[popUp selectedItem] representedObject]; + assoc = [[assocClass alloc] initWithObject:object]; + NSMapInsert(_objectToAssociation, object, assoc); + } + + [assoc bindAspect:aspectName + displayGroup:[NSApp connectDestination] + key:key]; + + RELEASE(_currentConnector); + _currentConnector = [[EOAspectConnector alloc] + initWithAssociation:assoc + aspectName:aspectName]; + [_currentConnector setSource:object]; + [_currentConnector setDestination: [NSApp connectDestination]]; + [_currentConnector setLabel:label]; + } + } + break; + } + [self updateButtons]; +} + +- (void) selectedOutletOrAction +{ + NSString *path; + NSString *name = [[(id )NSApp activeDocument] nameForObject:[_currentConnector destination]]; + path = [@"/" stringByAppendingString:[_currentConnector label]]; + path = [path stringByAppendingFormat:@" (%@)", name]; + [connectionsBrowser setPath:path]; +} + +- (void) updateButtons +{ + + if (!_currentConnector) + { + [okButton setState: NSOffState]; + } + else + { + id src, dest; + id firstResponder = [(GormDocument *)[(id)NSApp activeDocument] firstResponder]; + src = [_currentConnector source]; + dest = [_currentConnector destination]; + if (src && src != firstResponder + && ((dest && dest != firstResponder) + || ![_currentConnector isKindOfClass:[NSNibOutletConnector class]])) + { + BOOL flag; + + flag = [_connectors containsObject:_currentConnector]; + [okButton setState: flag ? NSOnState : NSOffState]; + } + else + { + [okButton setState: NSOnState]; + } + } +} + +- (void) _connectionsBrowserAction:(id)sender +{ + int i,c; + NSNibConnector *con; + NSString *title = [[sender selectedCell] stringValue]; + BOOL found; + + for (i = 0, c = [_connectors count]; i < c; i++) + { + NSString *label; + + con = [_connectors objectAtIndex:i]; + + label = [con label]; + if (label == nil || [title hasPrefix:label]) + { + NSString *name; + id dest; + + dest = [con destination]; + name = [[(id )NSApp activeDocument] nameForObject:dest]; + name = [label stringByAppendingFormat: @" (%@)", name]; + if ([title isEqual:name]) + { + NSString *path; + + ASSIGN(_currentConnector, con); + [self selectedConnector]; + break; + } + } + } + [self updateButtons]; +} + +- (void) selectedConnector +{ + NSString *path; + + path = [@"/" stringByAppendingString:[_currentConnector label]]; + if ([_currentConnector isKindOfClass: [NSNibControlConnector class]]) + { + path = [@"/target" stringByAppendingString:path]; + } + [oaBrowser setPath:path]; + [NSApp displayConnectionBetween:object and:[_currentConnector destination]]; +} + +- (int) browser:(NSBrowser *)browser +numberOfRowsInColumn:(int)column +{ + id repObj = [[popUp selectedItem] representedObject]; + if (browser == oaBrowser) + switch(column) + { + case 0: + return [_keys count]; + break; + case 1: + if (repObj == nil) + { + if ([[[browser selectedCellInColumn:0] stringValue] isEqual:@"target"]) + { + return [_values count]; + } + else return 0; + } + else + { + return [_values count]; + } + break; + default: + [[NSException exceptionWithName:NSInternalInconsistencyException + reason:@"uhhhhh should be column 0 or 1...." + userInfo: nil] raise]; + return 0; + break; + } + else if (browser == connectionsBrowser) + return [_connectors count]; +} + +- (void) browser:(NSBrowser *)sender +willDisplayCell:(id)cell atRow:(int)row column:(int)column +{ + id repObj = [[popUp selectedItem] representedObject]; + if (sender == oaBrowser) + switch (column) + { + case 0: + if (repObj == nil) + { + NSString *name; + name = [_keys objectAtIndex:row]; + [cell setStringValue:name]; + [cell setLeaf: [name isEqual:@"target" ] ? NO : YES]; + [cell setEnabled:YES]; + } + else + { + [cell setStringValue: [_keys objectAtIndex:row]]; + [cell setLeaf:[[_signatures objectAtIndex:row] length] == 0]; + } + break; + case 1: + if (repObj == nil) + { + if ([[[sender selectedCellInColumn:0] stringValue] isEqual:@"target"]) + { + [cell setLeaf:YES]; + [cell setStringValue: [_values objectAtIndex:row]]; + [cell setEnabled:YES]; + } + } + else + { + [cell setLeaf:YES]; // TODO relationships should be NO... + [cell setStringValue: [(EOAttribute *)[_values objectAtIndex:row] name]]; + [cell setEnabled:YES]; + } + break; + } + else if (sender == connectionsBrowser) + { + int i, c; + NSNibConnector *conn; + NSString *name, *dest, *label; + + if (row < 0 || column != 0) return; + + conn = [_connectors objectAtIndex:row]; + label = [conn label]; + dest = [conn destination]; + name = [[(id)NSApp activeDocument] nameForObject: dest]; + [cell setStringValue: [label stringByAppendingFormat:@" (%@)", name]]; + [cell setEnabled:YES]; + [cell setLeaf:YES]; + } + +} + +- (void) ok:(id)sender +{ + if ([_currentConnector destination] == nil || + [_currentConnector source] == nil) + { + NSRunAlertPanel(_(@"Problem making connection"), + _(@"Please select a valid destination."), + _(@"OK"), nil, nil, nil); + } + else if ([_connectors containsObject:_currentConnector] == YES) + { + [[(id)NSApp activeDocument] removeConnector: _currentConnector]; +// [_currentConnector setDestination:nil]; +// [_currentConnector setLabel:nil]; + [_connectors removeObject:_currentConnector]; + [connectionsBrowser loadColumnZero]; + } + else + { + NSString *path; + id dest; + + if ([_currentConnector isKindOfClass:[NSNibControlConnector class]]) + { + int i, c; + NSArray *controlConnectors; + + controlConnectors = [_connectors arrayWithObjectsRespondingYesToSelector:@selector(isKindOfClass:) + withObject:[NSNibControlConnector class]]; + + for (i = 0, c = [controlConnectors count]; i < c; i++) + { + NSNibConnector *con = [controlConnectors objectAtIndex:i]; + [[(id)NSApp activeDocument] removeConnector: con]; + [_connectors removeObject:con]; + } + [_connectors addObject:_currentConnector]; + } + else if ([_currentConnector isKindOfClass:[NSNibOutletConnector class]]) + { + [_connectors addObject:_currentConnector]; + } + else if ([_currentConnector isKindOfClass:[EOAspectConnector class]]) + { + [_connectors addObject:_currentConnector]; + } + + [self _selectAction:[_currentConnector label]]; + [[(id)NSApp activeDocument] addConnector: _currentConnector]; + [connectionsBrowser loadColumnZero]; + [self selectedConnector]; + } + + [[(id)NSApp activeDocument] touch]; + [self updateButtons]; +} +@end + diff --git a/GDL2Palette/Foundation+Categories.h b/GDL2Palette/Foundation+Categories.h new file mode 100644 index 0000000..4c7d996 --- /dev/null +++ b/GDL2Palette/Foundation+Categories.h @@ -0,0 +1,11 @@ +#include +/* since we don't really have blocks and i don't feel like including them.. */ +@interface NSArray (SelectorStuff) +- (NSArray *) arrayWithObjectsRespondingYesToSelector:(SEL)selector; +- (NSArray *) arrayWithObjectsRespondingYesToSelector:(SEL)selector +withObject:(id)argument; +@end + +@interface NSObject(GDL2PaletteAdditions) +- (BOOL) isKindOfClasses:(NSArray *)classes; +@end diff --git a/GDL2Palette/Foundation+Categories.m b/GDL2Palette/Foundation+Categories.m new file mode 100644 index 0000000..0dc13af --- /dev/null +++ b/GDL2Palette/Foundation+Categories.m @@ -0,0 +1,74 @@ +#include "Foundation+Categories.h" + +/* since we don't really have blocks and i don't feel like including them.. */ +@implementation NSArray (GDL2PaletteAdditions) + +- (NSArray *) arrayWithObjectsRespondingYesToSelector:(SEL)selector; +{ + int i,c; + BOOL (*sel_imp)(id, SEL, ...); + NSMutableArray *arr = [[NSMutableArray alloc] init]; + BOOL flag; + + for (i = 0, c = [self count]; i < c; i++) + { + id obj = [self objectAtIndex:i]; + + flag = [obj respondsToSelector:selector]; + + if (flag) + { + sel_imp = (BOOL (*)(id, SEL, ...))[obj methodForSelector:selector]; + flag = (*sel_imp)(obj, selector); + + if (flag) + [arr addObject:obj]; + } + } + return arr; +} + +- (NSArray *) arrayWithObjectsRespondingYesToSelector:(SEL)selector +withObject:(id)argument; +{ + int i,c; + BOOL (*sel_imp)(id, SEL, ...); + NSMutableArray *arr = [[NSMutableArray alloc] init]; + BOOL flag; + + for (i = 0, c = [self count]; i < c; i++) + { + id obj = [self objectAtIndex:i]; + + flag = [obj respondsToSelector:selector]; + + if (flag) + { + sel_imp = (BOOL (*)(id, SEL, ...))[obj methodForSelector:selector]; + flag = (*sel_imp)(obj, selector, argument); + + if (flag) + [arr addObject:obj]; + } + } + return arr; +} + +@end + +@implementation NSObject(GDL2PaletteAdditions) +- (BOOL) isKindOfClasses:(NSArray *)classes +{ + int i,c; + BOOL flag; + + for (i = 0, c = [classes count]; i < c; i++) + { + if ([self isKindOfClass: [classes objectAtIndex:i]]) + return YES; + } + return NO; +} + +@end + diff --git a/GDL2Palette/GDL2ConnectionInspector.gorm/data.classes b/GDL2Palette/GDL2ConnectionInspector.gorm/data.classes new file mode 100644 index 0000000..3973f2f --- /dev/null +++ b/GDL2Palette/GDL2ConnectionInspector.gorm/data.classes @@ -0,0 +1,26 @@ +{ + "## Comment" = "Do NOT change this file, Gorm maintains it"; + FirstResponder = { + Actions = ( + "_connectionsBrowserAction:", + "_oaBrowserAction:", + "_popUpAction:" + ); + Super = NSObject; + }; + GDL2ConnectionInspector = { + Actions = ( + "_connectionsBrowserAction:", + "_oaBrowserAction:", + "_popUpAction:" + ); + Outlets = ( + oaBrowser, + revertButton, + okButton, + popUp, + connectionsBrowser + ); + Super = IBInspector; + }; +} \ No newline at end of file diff --git a/GDL2Palette/GDL2ConnectionInspector.gorm/data.info b/GDL2Palette/GDL2ConnectionInspector.gorm/data.info new file mode 100644 index 0000000000000000000000000000000000000000..ca921cfbc845ba07ac46e72b730bf8b97779b5da GIT binary patch literal 184 zcmZ?w3oR~5El@}-O3uhEOEmxjqr@~zD-Z(+j4>DnRtAiQj0_^~`9-;InK`KeMX71U zzKMB>>8V8wKw!wkz~L9{pOlrFTms@Vs4_5cvKufNGK0i}ONuh{(t)Ck3~E4<4=BmN tDhgsT`6QO47MCc5r4|)u=I0qOZ)66k;DM{)VG5}%NKH`y8j+fq3jmgyC@la0 literal 0 HcmV?d00001 diff --git a/GDL2Palette/GDL2ConnectionInspector.gorm/objects.gorm b/GDL2Palette/GDL2ConnectionInspector.gorm/objects.gorm new file mode 100644 index 0000000000000000000000000000000000000000..86e2eefb510a8c23af1ef965b663fa2f16f2b4f7 GIT binary patch literal 7046 zcmcH;OLrSr`J0jKSeETrPAn&B+9*jAN=uq=+)z>%63a3%rj1gnCZSLo6kAEuNE#u@ zaYHGDXB`MI7$`08H(kzT#gfB{!{K+ZWW|ER2END4X!OE496L%T_kQ=@@BNxPOZkh< zR;ivTHdbzwZRtNs8_&7ol#FtJp~m#^mRTB}&Dl^OtGSSF0* z3m2}wR$6J%8~{x#27B^_^J}f*)k~}aKhTno6nJGL^LLB z#~opWnQ8xw$XI;AWY&aLnf7~_j^n5vHXYopT!4d|$~v zj43@a9-bICm+VHBl+m!)o8*L3)+AfVpE6@@1JEqcbnZ=lz!W5!BFd$5F_3BQmNh$%bEoD{<34MOT}xMdPdB@?n*Afo zyYMfPci|u1@`m7UdH1WlCTrEi1J)kaYOYeQ`&6J!CHo$sX4MjvzcQ7-_fQGIQ7TiU z)rXXd!Bh-9Xzk^YK3}AS_Bun_G-ww1htl{GYV#`X-;@KyJB-yhyfl}wo+jLr6_CWi`CMqY%0`?DDO@=jE)-X8UT@fIHAUoRh%LZJb$>Ko!{Fq+gvYEjjCX*n;5 zKJJMPq%zDCOTKe+w&>&BAvo&XljL|$bU5AzyonvqoFo>?75ir6Fbat)tG4EXc8+il zuvXa{wZci6Yd?r-!+qRm9q@!V#oM(gvgm&H_&1B*n>_+>RCJEHCslMmdz|$4gh->w z;%|NRxe$P(NI6-cuTQkZ+_MAC{gkeZF;QuR#)3$YKvE;0+8!f+u*1ktQ(gFwQipAi zlEBs{?#JDeTO0LMU{ujPp7zo^;C~dk^w&LxTRq0UDrd1)rcIbActHN!l~M&KXA zV#x)~+X8X-QqD|E%=Ogjb{PxKJDbiXKHK4LAGT&-cRO#{m9=V(s8A3X?mqXRsKcGZ zk9ac_I4At(hoPn{;TdH&+PxO)m2!(KAD*@LaUU511hJgsJ~EqOmp;vzUi+1I?(}VA z2rSm2pcJc;ch5&8VeL^_pN3;>>FkaZvbQ|ya4n3du#@$2PoK=*|O$uTjZPBy18NYSN ztF;HW4i_ldoZDtrSvk=*;RRng4*7<8KPHX9C!{jGsOb@0!Ro5Q0;^(%k`0R1g9Z*WZ z+chfXh7&`2v+vxN5IUS9&Z*IU+)H_d&DZB{{cohdPEogR~bh*+EUhW3;|_avrem$;D2) zx!|L;AviSvnfMo(fs+l#=jYT4esj^V9^&`K7wr1Qdiz?g{SKea5c%AFDTM!|VYWBB z1mGwkzGQ25#9Yfd2&oQ2{ymy$Jq&!cSgNfp(<^ZR1zc054vJ7}Fxo#BPVUX*p*Nb6 zT{|D9gSV_l_+F05(HR49-6w;ucPQqzb%<|I0=5`G;OBL3v`8_}84KU=u`oTkV*3x< zkJOG|@b=U5OL39VWDy5gDU zT@t#}=DI{i*PRD`qgMhAA$&_$q}vu0lV%uj8QtT)m6lf#|9#}#!FfpXL%8&PRr8bh z5h;B`kxuXqxp1H03wOFmhbrWu01Gs-VVy47OEj|FEZ)@<(c2%rK8?ha+rV$CXQlYY zEQQ~)GVJjBg@G@NHbz7rjvSzXmw?Z7<{AB`&{1|EJtD4t|#g2?99QVc0A9 zF08dGrB+VwdjqWZ2=Di-Bm8#df2#<;J!qy8Zx(rn<0M^~J|nEMoVZB@Hki`)X>f)p z{lGiy-g8sRtS`YGo*N)}eU&4E~02CkXd%b(a(q!5w2u-Gn*(o#08}@B3(%cPzjfX|~07!arD# g!q`&iJ|+1AW*y^O?7*db*l`%5_iUX=88ck_zYhL7&;S4c literal 0 HcmV?d00001 diff --git a/GDL2Palette/GDL2Palette.tiff b/GDL2Palette/GDL2Palette.tiff new file mode 100644 index 0000000000000000000000000000000000000000..50d447c69a3815f76c32b73819f8f6e4d96bf91d GIT binary patch literal 1578 zcmV+_2G#kAP)6A9KB)0k~z+638Z zViTKcnl{?fXg?HOS*j8ucNUGIX-K0W5P}sIS7I!6S!TB^RABec+^2ucEFEBXc4l{W zVH2NZGI>AFdwz5C-sjx+j!9y&%DLD8W6`9BkCYm0N+xRp*Zp>n@4o>sYsr#XiblO` zHv3xdn{W0_4C3$_^2*0O?^}uG%m0vboX;KUiNStNojP0aCpQu~9QVARH6@cZ6Nh@C zE`X1F-VY4k!ECkQ9|o;w2Tz^)*x*q?pTRG3j`MLmnf&^M5*Nve-6rmND-AXSpN7(% zJslnY95Tqv;>lzSX1@eJb;EFB*Y@q*6U6*~jzRc@=Y0q001ixvM!h3jw`LlbEt?lQ z&QHy35oXho4$17Lp4!^y)!sf3_q@9dHX-e~+;MI_^@*V(kx(+NzcYlp7a|RFRsm`)33_x8O&}zp35yg5BMrGTWe+? z0ryrL{4D&;RB9ox0Qha@_16z3lF6G4+5mT$xZ5;s+IoO62wH(-IL;kK;Bnx`KnpMr zNSaxjnLTM{^Q#K)!fgO1ZOQjK4**k3MoQmpT)zC8f@SUiZZ|W_4=E$*Az(Ie5Ad9% zRlu)-C(W$3YVaXk4JhY0`wRVdmJ#b>wg|xB0C2_3Wy`)+JV8>wq|K7r3hmE&J!lm%~Lco}fIH=RCNQM5E2KxRh)0<&@)=M$jO%w7e)T2a39*(k$BkUIPTWKXQZ8Xq>%Dau@ybI)rMrY@#w7!hk|77awIsh=M z13oAxp`^Ef?*k##fOk%x-W8hN(7kQj-vR3S`=1B)m52)seyH~L0f3C}-={EKQ*Kg8 zn}COb*yz#EtFXmNG&k2VFtC9OZ{9A6ZuBh(sdYK>ZkgQ%Om3 z!!TSW>96Nll@kPwf|Sf2Y4p5Xr<=7L_5DuZ>Ed}!D^^^uSZp&eUuHe_*kkQ#Z4C>< z^=s~5Q@TcsLA!VF&h2@3&m1`KdH$&HcQz%H3v-V1oZ!LZ()SXcw@dK0Nk=fdNpQ2l zb-;gRc2~ytw~QC)NV=d%bZy`M1+XffN~KL&0o-D+gnaQFFlis~8(jBynQhxXnqb~@ zG;D>-`2GvP3ji}ysW}#gS2Q@z{zK{XkWY>mLuHlc-gMfPv}?R!D%G%7dCnxWCxA{# ze;jFUEEZE(STo`d_fT57Bw=O*K|nT}T`%bYB#rn19tE;M^GI`}(WqY9^s@f4;YBqx zG~`qz_4M>~N>WQp%K-2rNoBwKI9>Q&XJ&IMxnLE{EvXqZW*i4Fvk(}7GWR@i7`Pvp zDd}J3Cd_8D;rsjF|8s?$L(0qoN&DVA@ZODsePzK*dZn;HyP17O(r1OXsl-j=IF57b zi&Lw|3SQ7&U_oL=;;h?M`o`>G;P+;BhnY11o6W4%%&x2wU`473UedpT)j%!z)6fmT z&w)?O>~S-zp1qWzijQH1R~T(To0+`=YydV&>I9fFWlHhf@Y-))+g=sYkbWFK?9cUI zH`q0%Go+-uOO3m(>(tcLtQt#>BJBkh%$+-T)O-Gt(xiqT)3zB&)%1DS+#si1A)dYF)7bW#p9eyG;sjc!$ c_=~0g0W;^&MN8R0z5oCK07*qoM6N<$f~2wdsQ>@~ literal 0 HcmV?d00001 diff --git a/GDL2Palette/GNUmakefile b/GDL2Palette/GNUmakefile new file mode 100644 index 0000000..ac861e5 --- /dev/null +++ b/GDL2Palette/GNUmakefile @@ -0,0 +1,34 @@ +include $(GNUSTEP_MAKEFILES)/common.make +include $(GNUSTEP_MAKEFILES)/Auxiliary/gdl2.make + +PALETTE_NAME=GDL2 +GDL2_PRINCIPAL_CLASS = GDL2Palette + +ifeq ($(FOUNDATION_LIB),apple) + ADDITIONAL_INCLUDE_DIRS += -F../EOModeler -F../EOInterface + ADDITIONAL_LIB_DIRS += -F../EOModeler -F../EOInterface +else + ADDITIONAL_INCLUDE_DIRS += -I../ + ADDITIONAL_LIB_DIRS += -L../EOModeler -L../EOInterface +endif + +ADDITIONAL_NATIVE_LIBS+=EOModeler EOInterface +LDFLAGS+=-framework gnustep-db2modeler -framework EOInterface + + +ADDITIONAL_LIB_DIRS= \ +-L../EOAccess/$(GNUSTEP_OBJ_DIR) \ +-L../EOControl/$(GNUSTEP_OBJ_DIR) + +ADDITIONAL_LDFLAGS+=-lgnustep-db2control -lgnustep-db2 + +GDL2_RESOURCE_FILES=GDL2Palette.tiff GDL2ConnectionInspector.gorm palette.table + +GDL2_OBJC_FILES= \ + Palette.m \ + ResourceManager.m \ + ConnectionInspector.m \ + IB+Categories.m \ + Foundation+Categories.m + +include $(GNUSTEP_MAKEFILES)/palette.make diff --git a/GDL2Palette/IB+Categories.m b/GDL2Palette/IB+Categories.m new file mode 100644 index 0000000..95ceee1 --- /dev/null +++ b/GDL2Palette/IB+Categories.m @@ -0,0 +1,40 @@ +#include + +#include +@interface EODisplayGroup (PaletteStuff) +- (NSString *)connectInspectorClassName; +@end + +@implementation EODisplayGroup (PaletteStuff) +- (NSString *)connectInspectorClassName +{ + return @"GDL2ConnectionInspector"; +} +@end + +#include +@interface NSView (PaletteStuff) +- (NSString *)connectInspectorClassName; +@end + +@implementation NSView (PaletteStuff) +- (NSString *)connectInspectorClassName +{ + return @"GDL2ConnectionInspector"; +} +@end + +#include + +@interface NSTableColumn (PaletteStuff) +- (NSString *)connectInspectorClassName; +@end + +@implementation NSTableColumn (PaletteStuff) +- (NSString *)connectInspectorClassName +{ + return @"GDL2ConnectionInspector"; +} + +@end + diff --git a/GDL2Palette/Palette.h b/GDL2Palette/Palette.h new file mode 100644 index 0000000..2d6d0d7 --- /dev/null +++ b/GDL2Palette/Palette.h @@ -0,0 +1,9 @@ +#include + +@interface GDL2Palette : IBPalette +{ + +} + +@end + diff --git a/GDL2Palette/Palette.m b/GDL2Palette/Palette.m new file mode 100644 index 0000000..54d9138 --- /dev/null +++ b/GDL2Palette/Palette.m @@ -0,0 +1,13 @@ +#include "Palette.h" +#include "ResourceManager.h" + + +@implementation GDL2Palette + ++(void) initialize +{ +// NSLog(@"GDL2Palette initialize"); + [IBResourceManager registerResourceManagerClass:[GDL2ResourceManager class]]; +} + +@end diff --git a/GDL2Palette/ResourceManager.h b/GDL2Palette/ResourceManager.h new file mode 100644 index 0000000..e4c1d45 --- /dev/null +++ b/GDL2Palette/ResourceManager.h @@ -0,0 +1,14 @@ +#include + +@class EOEditingContext; +@class EOModelGroup; + + +@interface GDL2ResourceManager : IBResourceManager +{ + EOEditingContext *_defaultEditingContext; + EOModelGroup *modelGroup; +} + +@end + diff --git a/GDL2Palette/ResourceManager.m b/GDL2Palette/ResourceManager.m new file mode 100644 index 0000000..f33be43 --- /dev/null +++ b/GDL2Palette/ResourceManager.m @@ -0,0 +1,93 @@ +#include "ResourceManager.h" + +#include + +#include + +#include +#include + +#include + +#include +#include + +@implementation GDL2ResourceManager +- (id) initWithDocument:(id)doc +{ + self = [super initWithDocument:doc]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didOpenDocument:) + name:IBDidOpenDocumentNotification + object:[self document]]; + return self; +} + +- (void) didOpenDocument:(NSNotification *)notif +{ + NSArray *tmp; + NSMutableArray *modelPaths = [NSMutableArray new]; + NSString *docPath; + int i,c; + docPath = [[[self document] documentPath] stringByDeletingLastPathComponent]; + tmp = [[NSBundle bundleWithPath: docPath] + pathsForResourcesOfType:@"eomodeld" + inDirectory:nil]; + [modelPaths addObjectsFromArray:tmp]; + tmp = [[NSBundle bundleWithPath: docPath] + pathsForResourcesOfType:@"eomodel" + inDirectory:nil]; + + for (i = 0, c = [modelPaths count]; i < c; i++) + { + if (![[EOModelGroup defaultGroup] modelWithPath:[modelPaths objectAtIndex:i]]) + [[EOModelGroup globalModelGroup] + addModelWithFile:[modelPaths objectAtIndex:i]]; + } +} + +- (EOEditingContext *) defaultEditingContext +{ + if (!_defaultEditingContext) + _defaultEditingContext = [[EOEditingContext alloc] init]; + return _defaultEditingContext; +} + +- (BOOL) acceptsResourcesFromPasteboard:(NSPasteboard *)pb +{ + return [[pb types] containsObject:EOMPropertyPboardType]; +} + +- (NSArray *)resourcePasteboardTypes +{ + return [NSArray arrayWithObject: EOMPropertyPboardType]; +} + +- (void) addResourcesFromPasteboard:(NSPasteboard *)pb +{ + NSArray *pList = [pb propertyListForType:EOMPropertyPboardType]; + EODisplayGroup *dg = [[EODisplayGroup alloc] init]; + EOEditingContext *ec = [self defaultEditingContext]; + EODatabaseDataSource *ds; + NSString *modelPath = [pList objectAtIndex:0]; + + int i,c; + + if (![[self document] containsObject:ec]) + { + [[self document] attachObject:ec toParent:nil]; + } + + if (![[EOModelGroup defaultGroup] modelWithPath:modelPath]) + { + [[EOModelGroup defaultGroup] addModelWithFile:modelPath]; + } + ds = [[EODatabaseDataSource alloc] + initWithEditingContext:ec + entityName:[pList objectAtIndex:1]]; + [dg setDataSource:ds]; + [[self document] attachObject:dg toParent:nil]; +} + +@end + diff --git a/GDL2Palette/palette.table b/GDL2Palette/palette.table new file mode 100644 index 0000000..35f203f --- /dev/null +++ b/GDL2Palette/palette.table @@ -0,0 +1,8 @@ +{ + NOTE = "Automatically generated, do not edit!"; + NibFile = ""; + Class = "GDL2Palette"; + Icon = "GDL2Palette"; + ExportClasses = ("EODisplayGroup", "EOEditingContext"); +} +