2
.gitignore
vendored
@ -6,3 +6,5 @@ po/gaphor.pot
|
||||
html
|
||||
*.swp
|
||||
*.egg
|
||||
env
|
||||
*.bak
|
||||
|
7
.mailmap
Normal file
@ -0,0 +1,7 @@
|
||||
Adam Boduch <adam.boduch@gmail.com> <adam@adam-laptop.(none)>
|
||||
Adam Boduch <adam.boduch@gmail.com> <adam@enomaly.com>
|
||||
Adam Boduch <adam.boduch@gmail.com> adamboduch <adam.boduch@gmail.com>
|
||||
Adam Boduch <adam.boduch@gmail.com> adamboduch <adam@adam-laptop.(none)>
|
||||
Dan Yeaw <dan@yeaw.me> danyeaw <danyeaw@gmail.com>
|
||||
Artur Wroblewski <wrobell@pld-linux.org> wrobell <wrobell@pld-linux.org>
|
||||
Enno Groeper <enno@groeper-berlin.de> Enno Gröper <enno@groeper-berlin.de>
|
27
.update-copyright.conf
Normal file
@ -0,0 +1,27 @@
|
||||
[project]
|
||||
name: Gaphor
|
||||
vcs: Git
|
||||
|
||||
[files]
|
||||
authors: yes
|
||||
files: yes
|
||||
ignored: LICENSE.txt | README.rst | .update-copyright.conf | .git* | *.md | *.txt | MANIFEST.in | NEWS | gaphor.desktop | pylintc | pygtk.vext | tox.ini
|
||||
pyfile: /home/dan/Code/update-copyright-0.6.2/update_copyright/license.py
|
||||
|
||||
[copyright]
|
||||
short: {project} comes with ABSOLUTELY NO WARRANTY and is licensed under the GNU Library General Public License.
|
||||
long: This file is part of {project}.
|
||||
|
||||
{project} is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Library General Public License
|
||||
as published by the Free Software Foundation, either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
{project} 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 Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with {project}. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
16
AUTHORS
@ -1,3 +1,15 @@
|
||||
Arjan Molenaar <a.molenaar@yirdis.nl>
|
||||
Gaphor was written by:
|
||||
Adam Boduch <adam.boduch@gmail.com>
|
||||
Alexis Howells <al@aejh.co.uk>
|
||||
Antonin Delpeuch <wetneb@gmail.com>
|
||||
Antony N. Pavlov <antony@niisi.msk.ru>
|
||||
Arjan Molenaar <gaphor@gmail.com>
|
||||
Artur Wroblewski <wrobell@pld-linux.org>
|
||||
Jeroen Vloothuis <jeroen@vloothuis.net>
|
||||
Christian Hoff <christian_hoff@gmx.net>
|
||||
Dan Yeaw <dan@yeaw.me>
|
||||
Encolpe DEGOUTE <encolpe@colpi.org>
|
||||
Enno Groeper <enno@groeper-berlin.de>
|
||||
Jordi Mallach <jordi@sindominio.net>
|
||||
Ygor Mutti <mamutti@icaju.com>
|
||||
slmm <noreply@example.com>
|
||||
syt <noreply@example.com>
|
||||
|
46
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dan@yeaw.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
@ -3,31 +3,14 @@ Feel free to hack Gaphor. Patches are welcome.
|
||||
Fetching Development Dependencies
|
||||
=================================
|
||||
|
||||
Gaphor uses Easy Install to manage in easy way its dependencies.
|
||||
|
||||
To fetch and install dependencies as non-root user
|
||||
|
||||
1. Create ~/.pydistutils.cfg file
|
||||
|
||||
[install]
|
||||
install_lib = ~/opt/share/python2.5/site-packages
|
||||
install_scripts = ~/opt/bin
|
||||
|
||||
2. Create (or extend) PYTHONPATH variable
|
||||
|
||||
export PYTHONPATH=~/opt/share/python2.5/site-packages
|
||||
|
||||
3. Run setup.py script to fetch and install dependencies
|
||||
|
||||
python setup.py develop
|
||||
|
||||
Prefix ~/opt can be changed to something more suitable for your setup.
|
||||
|
||||
|
||||
Above is based on
|
||||
|
||||
http://peak.telecommunity.com/DevCenter/EasyInstall#traditional-pythonpath-based-installation
|
||||
Gaphor uses pip to manage in easy way its dependencies.
|
||||
|
||||
To fetch and install dependencies as non-root user:
|
||||
In Linux recommend using a virtual environment for installation. Since pyGTK doesn't work well with a virtualenv,
|
||||
install it outside the virtual environment and then start your the virtualenv using the --system-site-packages option:
|
||||
$ virtualenv --system-site-packages venv
|
||||
$ source venv/bin/activate
|
||||
$ pip install gaphor
|
||||
|
||||
Running Tests
|
||||
=============
|
||||
@ -64,4 +47,3 @@ The user interface. This is where most of the work is to be done.
|
||||
misc
|
||||
----
|
||||
Some utility stuff, such as Actions and aspects are put in here.
|
||||
|
@ -1,482 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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 library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, 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 companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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 library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, 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 companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
1
MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
include LICENSE.txt
|
4
NEWS
@ -1,3 +1,7 @@
|
||||
0.17.2
|
||||
------
|
||||
- Improved Python3 compatibility
|
||||
|
||||
0.17.1
|
||||
------
|
||||
- Added Russian translation
|
||||
|
25
README
@ -1,25 +0,0 @@
|
||||
Gaphor - The Pythonic UML modelling tool
|
||||
========================================
|
||||
|
||||
Gaphor is a UML modelling tool, written in Python. This makes it very easy to
|
||||
use (and very easy to extend -- and to write ;-) ).
|
||||
|
||||
Install gaphor simply using easy-install:
|
||||
|
||||
$ easy-install gaphor
|
||||
|
||||
You can find the sources at GitHub:
|
||||
|
||||
http://github.com/amolenaar/gaphor/
|
||||
|
||||
For documentation refer to our project website:
|
||||
|
||||
http://gaphor.sourceforge.net/
|
||||
|
||||
Issue tracking is done at Lighthouse:
|
||||
|
||||
http://gaphor.lighthouseapp.com/
|
||||
|
||||
Have fun,
|
||||
|
||||
Gaphor development team
|
12
README.rst
Normal file
@ -0,0 +1,12 @@
|
||||
Gaphor - The UML and SysML(soon!) Modeling Tool
|
||||
===============================================
|
||||
|
||||
Gaphor is a free/libre/open source UML modeling tool, written in Python and licensed under the LGPLv2.
|
||||
|
||||
Install gaphor simply using pip:
|
||||
|
||||
$ pip install gaphor
|
||||
|
||||
For documentation refer to our project website:
|
||||
|
||||
http://gaphor.readthedocs.io
|
0
doc/.gitignore → docs/.gitignore
vendored
@ -1,100 +1,100 @@
|
||||
Actions, menu items, toolbars and toolboxes
|
||||
===========================================
|
||||
|
||||
The GTK+ structure is like this::
|
||||
|
||||
UIManager
|
||||
|
|
||||
ActionGroup
|
||||
|
|
||||
Action
|
||||
|
||||
The do_activate signal is emitted when an action is activated.
|
||||
|
||||
Where it should lead:
|
||||
* Actions should be coded closer to the object their working on
|
||||
- main actions - not dependent on GUI components (load/save/new/quit)
|
||||
- main actions dependent on GUI component (sub-windows, console)
|
||||
- Item actions, act either on a diagram, the selected or focused item
|
||||
or no item.
|
||||
- diagram actions (zoom, grid) work on active diagram (tab)
|
||||
- menus and actions for diagram items through adapters
|
||||
|
||||
* Actions should behave more like adapters. E.g. when a popup menu is created
|
||||
for an Association item, the menu actions should present themselves in the
|
||||
context of that menu item (with toggles set right).
|
||||
|
||||
- Could be registered as adapters with a name.
|
||||
|
||||
* Each window has its own action group (every item with a menu?)
|
||||
* One toplevel UIManager per window or one per application/gui_manager?
|
||||
* Normal actions can be modeled as functions. If an action is sensitive or
|
||||
visible depends on the state in the action. Hence we require the update()
|
||||
method.
|
||||
|
||||
* create services for for "dynamic" menus (e.g. recent files/stereotypes)
|
||||
|
||||
|
||||
Solution for simple actions
|
||||
---------------------------
|
||||
|
||||
For an action to actually be useful a piece of menu xml is needed.
|
||||
|
||||
Hence an interface IActionProvider has to be defined::
|
||||
|
||||
class IActionProvider(interface.Interface):
|
||||
menu_xml = interface.Attribute("The menu XML")
|
||||
action_group = interface.Attribute("The accompanying ActionGroup")
|
||||
|
||||
Support for actions can be arranged by decorating actions with an :ref:`@action <action_doc>`
|
||||
decorator and let the class create an ActionGroup using some
|
||||
actionGroup factory function (no inheritance needed here).
|
||||
|
||||
Note that ActionGroup is a GTK class and should technically only be used in the
|
||||
gaphor.ui package.
|
||||
|
||||
Autonom controllers can be defined, which provide a piece of functionality.
|
||||
They can register handlers in order to update their state.
|
||||
|
||||
Maybe it's nice to configure those through the egg-info system. I suppose
|
||||
gaphor.service will serve well (as they need to be initialized anyway)
|
||||
|
||||
* also inherit IActionProvider from IService?
|
||||
|
||||
::
|
||||
|
||||
[gaphor.services]
|
||||
xx = gaphor.actions.whatever:SomeActionProviderClass
|
||||
|
||||
----
|
||||
|
||||
.. _action_doc:
|
||||
|
||||
.. autoclass:: gaphor.action.action
|
||||
:members:
|
||||
|
||||
|
||||
Solution for context sensitive menus
|
||||
------------------------------------
|
||||
|
||||
Context sensitive menus, such as popup menus, should be generated and switched
|
||||
on and off on demand.
|
||||
|
||||
Technically they should be enabled through services/action-providers.
|
||||
|
||||
It becomes even tougher when popup menus should act on parts of a diagram item
|
||||
(such as association ends). This should be avoided. It may be a good idea to
|
||||
provide such functionality through a special layer on the canvas, by means of
|
||||
some easy clickable buttons around the "hot spot" (we already have something
|
||||
like that for text around association ends).
|
||||
|
||||
Scheme:
|
||||
|
||||
1. User selects an item and presses the rigth mouse button: a popup menu
|
||||
should be displayed.
|
||||
2. Find the actual item (this may be a composite item of the element drawn).
|
||||
Use an IItemPicker adapter for that (if no such interface is available,
|
||||
use the item itself).
|
||||
3. Find a IActionProvider adapters for the selected (focused) item.
|
||||
4. Update the popup menu context (actions) for the selected item.
|
||||
|
||||
Actions, menu items, toolbars and toolboxes
|
||||
===========================================
|
||||
|
||||
The GTK+ structure is like this::
|
||||
|
||||
UIManager
|
||||
|
|
||||
ActionGroup
|
||||
|
|
||||
Action
|
||||
|
||||
The do_activate signal is emitted when an action is activated.
|
||||
|
||||
Where it should lead:
|
||||
* Actions should be coded closer to the object their working on
|
||||
- main actions - not dependent on GUI components (load/save/new/quit)
|
||||
- main actions dependent on GUI component (sub-windows, console)
|
||||
- Item actions, act either on a diagram, the selected or focused item
|
||||
or no item.
|
||||
- diagram actions (zoom, grid) work on active diagram (tab)
|
||||
- menus and actions for diagram items through adapters
|
||||
|
||||
* Actions should behave more like adapters. E.g. when a popup menu is created
|
||||
for an Association item, the menu actions should present themselves in the
|
||||
context of that menu item (with toggles set right).
|
||||
|
||||
- Could be registered as adapters with a name.
|
||||
|
||||
* Each window has its own action group (every item with a menu?)
|
||||
* One toplevel UIManager per window or one per application/gui_manager?
|
||||
* Normal actions can be modeled as functions. If an action is sensitive or
|
||||
visible depends on the state in the action. Hence we require the update()
|
||||
method.
|
||||
|
||||
* create services for for "dynamic" menus (e.g. recent files/stereotypes)
|
||||
|
||||
|
||||
Solution for simple actions
|
||||
---------------------------
|
||||
|
||||
For an action to actually be useful a piece of menu xml is needed.
|
||||
|
||||
Hence an interface IActionProvider has to be defined::
|
||||
|
||||
class IActionProvider(interface.Interface):
|
||||
menu_xml = interface.Attribute("The menu XML")
|
||||
action_group = interface.Attribute("The accompanying ActionGroup")
|
||||
|
||||
Support for actions can be arranged by decorating actions with an :ref:`@action <action_doc>`
|
||||
decorator and let the class create an ActionGroup using some
|
||||
actionGroup factory function (no inheritance needed here).
|
||||
|
||||
Note that ActionGroup is a GTK class and should technically only be used in the
|
||||
gaphor.ui package.
|
||||
|
||||
Autonom controllers can be defined, which provide a piece of functionality.
|
||||
They can register handlers in order to update their state.
|
||||
|
||||
Maybe it's nice to configure those through the egg-info system. I suppose
|
||||
gaphor.service will serve well (as they need to be initialized anyway)
|
||||
|
||||
* also inherit IActionProvider from IService?
|
||||
|
||||
::
|
||||
|
||||
[gaphor.services]
|
||||
xx = gaphor.actions.whatever:SomeActionProviderClass
|
||||
|
||||
----
|
||||
|
||||
.. _action_doc:
|
||||
|
||||
.. autoclass:: gaphor.action.action
|
||||
:members:
|
||||
|
||||
|
||||
Solution for context sensitive menus
|
||||
------------------------------------
|
||||
|
||||
Context sensitive menus, such as popup menus, should be generated and switched
|
||||
on and off on demand.
|
||||
|
||||
Technically they should be enabled through services/action-providers.
|
||||
|
||||
It becomes even tougher when popup menus should act on parts of a diagram item
|
||||
(such as association ends). This should be avoided. It may be a good idea to
|
||||
provide such functionality through a special layer on the canvas, by means of
|
||||
some easy clickable buttons around the "hot spot" (we already have something
|
||||
like that for text around association ends).
|
||||
|
||||
Scheme:
|
||||
|
||||
1. User selects an item and presses the rigth mouse button: a popup menu
|
||||
should be displayed.
|
||||
2. Find the actual item (this may be a composite item of the element drawn).
|
||||
Use an IItemPicker adapter for that (if no such interface is available,
|
||||
use the item itself).
|
||||
3. Find a IActionProvider adapters for the selected (focused) item.
|
||||
4. Update the popup menu context (actions) for the selected item.
|
||||
|
@ -8,17 +8,17 @@
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
from __future__ import absolute_import
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
@ -31,14 +31,14 @@ templates_path = ['_templates']
|
||||
source_suffix = '.txt'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'contents'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Gaphor'
|
||||
copyright = u'2012, Gaphor development team'
|
||||
copyright = u'2012 Arjan Molenaar, 2017 Dan Yeaw'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@ -51,37 +51,37 @@ release = '0.17.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
@ -93,26 +93,26 @@ html_theme = 'default'
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@ -121,86 +121,85 @@ html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Gaphordoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
# latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
# latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('contents', 'Gaphor.tex', u'Gaphor Documentation',
|
||||
u'Gaphor development team', 'manual'),
|
||||
('index', 'Gaphor.tex', u'Gaphor Documentation',
|
||||
u'Dan Yeaw', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
# latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
@ -208,6 +207,6 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('contents', 'gaphor', u'Gaphor Documentation',
|
||||
[u'Gaphor development team'], 1)
|
||||
('index', 'gaphor', u'Gaphor Documentation',
|
||||
[u'Dan Yeaw and contributors'], 1)
|
||||
]
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@ -1,24 +1,40 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""This script list classes and optionally attributes from UML model
|
||||
created with Gaphor."""
|
||||
# Copyright (C) 2008-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""This script list classes and optionally attributes from UML model created with Gaphor."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import optparse
|
||||
import sys
|
||||
|
||||
from gaphor.UML import uml2
|
||||
from gaphor import Application
|
||||
import gaphor.UML as UML
|
||||
|
||||
#Setup command line options.
|
||||
# Setup command line options.
|
||||
usage = 'usage: %prog [options] file.gaphor'
|
||||
|
||||
parser = optparse.OptionParser(usage=usage)
|
||||
|
||||
parser.add_option('-a',\
|
||||
'--attributes',\
|
||||
dest='attrs',\
|
||||
action='store_true',\
|
||||
help='Print class attributes')
|
||||
parser.add_option('-a', '--attributes', dest='attrs', action='store_true', help='Print class attributes')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
@ -26,26 +42,25 @@ if len(args) != 1:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
#The model file to load.
|
||||
# The model file to load.
|
||||
model = args[0]
|
||||
|
||||
#Create the Gaphor application object.
|
||||
# Create the Gaphor application object.
|
||||
Application.init()
|
||||
|
||||
#Get services we need.
|
||||
# Get services we need.
|
||||
element_factory = Application.get_service('element_factory')
|
||||
file_manager = Application.get_service('file_manager')
|
||||
|
||||
#Load model from file.
|
||||
# Load model from file.
|
||||
file_manager.load(model)
|
||||
|
||||
#Find all classes using factory select.
|
||||
for cls in element_factory.select(lambda e: e.isKindOf(UML.Class)):
|
||||
|
||||
print 'Found class %s' % cls.name
|
||||
|
||||
# Find all classes using factory select.
|
||||
for cls in element_factory.select(lambda e: e.isKindOf(uml2.Class)):
|
||||
|
||||
print('Found class %s' % cls.name)
|
||||
|
||||
if options.attrs:
|
||||
|
||||
|
||||
for attr in cls.ownedAttribute:
|
||||
|
||||
print ' Attribute: %s' % attr.name
|
||||
print(' Attribute: %s' % attr.name)
|
||||
|
284
ez_setup.py
@ -1,284 +0,0 @@
|
||||
#!python
|
||||
"""Bootstrap setuptools installation
|
||||
|
||||
If you want to use setuptools in your package's setup.py, just include this
|
||||
file in the same directory with it, and add this to the top of your setup.py::
|
||||
|
||||
from ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
|
||||
If you want to require a specific version of setuptools, set a download
|
||||
mirror, or use an alternate download directory, you can do so by supplying
|
||||
the appropriate options to ``use_setuptools()``.
|
||||
|
||||
This file can also be run as a script to install or upgrade setuptools.
|
||||
"""
|
||||
import sys
|
||||
DEFAULT_VERSION = "0.6c11"
|
||||
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
|
||||
|
||||
md5_data = {
|
||||
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
|
||||
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
|
||||
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
|
||||
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
|
||||
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
|
||||
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
|
||||
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
|
||||
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
|
||||
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
|
||||
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
|
||||
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
|
||||
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
|
||||
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
|
||||
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
|
||||
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
|
||||
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
|
||||
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
|
||||
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
|
||||
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
|
||||
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
|
||||
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
|
||||
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
|
||||
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
|
||||
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
|
||||
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
|
||||
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
|
||||
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
|
||||
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
|
||||
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
|
||||
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
|
||||
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
|
||||
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
|
||||
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
|
||||
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
|
||||
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
|
||||
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
|
||||
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
|
||||
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
|
||||
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
|
||||
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
|
||||
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
|
||||
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
|
||||
}
|
||||
|
||||
import sys, os
|
||||
try: from hashlib import md5
|
||||
except ImportError: from md5 import md5
|
||||
|
||||
def _validate_md5(egg_name, data):
|
||||
if egg_name in md5_data:
|
||||
digest = md5(data).hexdigest()
|
||||
if digest != md5_data[egg_name]:
|
||||
print >>sys.stderr, (
|
||||
"md5 validation of %s failed! (Possible download problem?)"
|
||||
% egg_name
|
||||
)
|
||||
sys.exit(2)
|
||||
return data
|
||||
|
||||
def use_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||
download_delay=15
|
||||
):
|
||||
"""Automatically find/download setuptools and make it available on sys.path
|
||||
|
||||
`version` should be a valid setuptools version number that is available
|
||||
as an egg for download under the `download_base` URL (which should end with
|
||||
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
|
||||
it is not already available. If `download_delay` is specified, it should
|
||||
be the number of seconds that will be paused before initiating a download,
|
||||
should one be required. If an older version of setuptools is installed,
|
||||
this routine will print a message to ``sys.stderr`` and raise SystemExit in
|
||||
an attempt to abort the calling script.
|
||||
"""
|
||||
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
|
||||
def do_download():
|
||||
egg = download_setuptools(version, download_base, to_dir, download_delay)
|
||||
sys.path.insert(0, egg)
|
||||
import setuptools; setuptools.bootstrap_install_from = egg
|
||||
try:
|
||||
import pkg_resources
|
||||
except ImportError:
|
||||
return do_download()
|
||||
try:
|
||||
pkg_resources.require("setuptools>="+version); return
|
||||
except pkg_resources.VersionConflict, e:
|
||||
if was_imported:
|
||||
print >>sys.stderr, (
|
||||
"The required version of setuptools (>=%s) is not available, and\n"
|
||||
"can't be installed while this script is running. Please install\n"
|
||||
" a more recent version first, using 'easy_install -U setuptools'."
|
||||
"\n\n(Currently using %r)"
|
||||
) % (version, e.args[0])
|
||||
sys.exit(2)
|
||||
else:
|
||||
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||
return do_download()
|
||||
except pkg_resources.DistributionNotFound:
|
||||
return do_download()
|
||||
|
||||
def download_setuptools(
|
||||
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||
delay = 15
|
||||
):
|
||||
"""Download setuptools from a specified location and return its filename
|
||||
|
||||
`version` should be a valid setuptools version number that is available
|
||||
as an egg for download under the `download_base` URL (which should end
|
||||
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||
`delay` is the number of seconds to pause before an actual download attempt.
|
||||
"""
|
||||
import urllib2, shutil
|
||||
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
||||
url = download_base + egg_name
|
||||
saveto = os.path.join(to_dir, egg_name)
|
||||
src = dst = None
|
||||
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||
try:
|
||||
from distutils import log
|
||||
if delay:
|
||||
log.warn("""
|
||||
---------------------------------------------------------------------------
|
||||
This script requires setuptools version %s to run (even to display
|
||||
help). I will attempt to download it for you (from
|
||||
%s), but
|
||||
you may need to enable firewall access for this script first.
|
||||
I will start the download in %d seconds.
|
||||
|
||||
(Note: if this machine does not have network access, please obtain the file
|
||||
|
||||
%s
|
||||
|
||||
and place it in this directory before rerunning this script.)
|
||||
---------------------------------------------------------------------------""",
|
||||
version, download_base, delay, url
|
||||
); from time import sleep; sleep(delay)
|
||||
log.warn("Downloading %s", url)
|
||||
src = urllib2.urlopen(url)
|
||||
# Read/write all in one block, so we don't create a corrupt file
|
||||
# if the download is interrupted.
|
||||
data = _validate_md5(egg_name, src.read())
|
||||
dst = open(saveto,"wb"); dst.write(data)
|
||||
finally:
|
||||
if src: src.close()
|
||||
if dst: dst.close()
|
||||
return os.path.realpath(saveto)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main(argv, version=DEFAULT_VERSION):
|
||||
"""Install or upgrade setuptools and EasyInstall"""
|
||||
try:
|
||||
import setuptools
|
||||
except ImportError:
|
||||
egg = None
|
||||
try:
|
||||
egg = download_setuptools(version, delay=0)
|
||||
sys.path.insert(0,egg)
|
||||
from setuptools.command.easy_install import main
|
||||
return main(list(argv)+[egg]) # we're done here
|
||||
finally:
|
||||
if egg and os.path.exists(egg):
|
||||
os.unlink(egg)
|
||||
else:
|
||||
if setuptools.__version__ == '0.0.1':
|
||||
print >>sys.stderr, (
|
||||
"You have an obsolete version of setuptools installed. Please\n"
|
||||
"remove it from your system entirely before rerunning this script."
|
||||
)
|
||||
sys.exit(2)
|
||||
|
||||
req = "setuptools>="+version
|
||||
import pkg_resources
|
||||
try:
|
||||
pkg_resources.require(req)
|
||||
except pkg_resources.VersionConflict:
|
||||
try:
|
||||
from setuptools.command.easy_install import main
|
||||
except ImportError:
|
||||
from easy_install import main
|
||||
main(list(argv)+[download_setuptools(delay=0)])
|
||||
sys.exit(0) # try to force an exit
|
||||
else:
|
||||
if argv:
|
||||
from setuptools.command.easy_install import main
|
||||
main(argv)
|
||||
else:
|
||||
print "Setuptools version",version,"or greater has been installed."
|
||||
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
|
||||
|
||||
def update_md5(filenames):
|
||||
"""Update our built-in md5 registry"""
|
||||
|
||||
import re
|
||||
|
||||
for name in filenames:
|
||||
base = os.path.basename(name)
|
||||
f = open(name,'rb')
|
||||
md5_data[base] = md5(f.read()).hexdigest()
|
||||
f.close()
|
||||
|
||||
data = [" %r: %r,\n" % it for it in md5_data.items()]
|
||||
data.sort()
|
||||
repl = "".join(data)
|
||||
|
||||
import inspect
|
||||
srcfile = inspect.getsourcefile(sys.modules[__name__])
|
||||
f = open(srcfile, 'rb'); src = f.read(); f.close()
|
||||
|
||||
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
||||
if not match:
|
||||
print >>sys.stderr, "Internal error!"
|
||||
sys.exit(2)
|
||||
|
||||
src = src[:match.start(1)] + repl + src[match.end(1):]
|
||||
f = open(srcfile,'w')
|
||||
f.write(src)
|
||||
f.close()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
|
||||
update_md5(sys.argv[2:])
|
||||
else:
|
||||
main(sys.argv[1:])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,33 @@
|
||||
from gaphor.UML.collection import collection
|
||||
#!/usr/bin/env python
|
||||
|
||||
from gaphor.UML.uml2 import *
|
||||
from gaphor.UML.elementfactory import ElementFactory
|
||||
from gaphor.UML import modelfactory as model
|
||||
from gaphor.UML.umlfmt import format
|
||||
from gaphor.UML.umllex import parse
|
||||
# Copyright (C) 2001-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
# syt <noreply@example.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import absolute_import
|
||||
#from gaphor.UML.collection import collection
|
||||
|
||||
#from gaphor.UML.uml2 import Diagram
|
||||
#from gaphor.UML.elementfactory import ElementFactory
|
||||
#from gaphor.UML import modelfactory as model
|
||||
#from gaphor.UML.umlfmt import format
|
||||
#from gaphor.UML.umllex import parse
|
||||
|
||||
__all__ = ['collection', 'context', 'diagram', 'element', 'elementfactory', 'event', 'interface', 'modelfactory',
|
||||
'properties', 'uml2', 'umlfmt', 'umllex']
|
||||
|
@ -1,10 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2002-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
1:n and n:m relations in the data model are saved using a collection.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import inspect
|
||||
from event import AssociationChangeEvent
|
||||
from gaphor.misc.listmixins import querymixin, recursemixin, recurseproxy, getslicefix
|
||||
|
||||
from gaphor.UML.event import AssociationChangeEvent
|
||||
from gaphor.misc.listmixins import querymixin, recursemixin, getslicefix
|
||||
|
||||
|
||||
class collectionlist(recursemixin, querymixin, getslicefix, list):
|
||||
@ -18,16 +41,16 @@ class collectionlist(recursemixin, querymixin, getslicefix, list):
|
||||
|
||||
It should work with the datamodel too:
|
||||
|
||||
>>> from gaphor.UML import *
|
||||
>>> c = Class()
|
||||
>>> c.ownedOperation = Operation()
|
||||
>>> from gaphor.UML import uml2
|
||||
>>> c = uml2.Class()
|
||||
>>> c.ownedOperation = uml2.Operation()
|
||||
>>> c.ownedOperation # doctest: +ELLIPSIS
|
||||
[<gaphor.UML.uml2.Operation object at 0x...>]
|
||||
>>> c.ownedOperation[0] # doctest: +ELLIPSIS
|
||||
<gaphor.UML.uml2.Operation object at 0x...>
|
||||
>>> c.ownedOperation = Operation()
|
||||
>>> c.ownedOperation[0].formalParameter = Parameter()
|
||||
>>> c.ownedOperation[0].formalParameter = Parameter()
|
||||
>>> c.ownedOperation = uml2.Operation()
|
||||
>>> c.ownedOperation[0].formalParameter = uml2.Parameter()
|
||||
>>> c.ownedOperation[0].formalParameter = uml2.Parameter()
|
||||
>>> c.ownedOperation[0].formalParameter[0].name = 'foo'
|
||||
>>> c.ownedOperation[0].formalParameter[0].name
|
||||
'foo'
|
||||
@ -60,7 +83,7 @@ class collection(object):
|
||||
return len(self.items)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
raise RuntimeError, 'items should not be overwritten.'
|
||||
raise RuntimeError('items should not be overwritten.')
|
||||
|
||||
def __delitem__(self, key):
|
||||
self.remove(key)
|
||||
@ -80,20 +103,19 @@ class collection(object):
|
||||
__repr__ = __str__
|
||||
|
||||
def __nonzero__(self):
|
||||
return self.items!=[]
|
||||
return self.items != []
|
||||
|
||||
def append(self, value):
|
||||
if isinstance(value, self.type):
|
||||
self.property._set(self.object, value)
|
||||
else:
|
||||
raise TypeError, 'Object is not of type %s' % self.type.__name__
|
||||
raise TypeError('Object is not of type %s' % self.type.__name__)
|
||||
|
||||
def remove(self, value):
|
||||
if value in self.items:
|
||||
self.property.__delete__(self.object, value)
|
||||
else:
|
||||
raise ValueError, '%s not in collection' % value
|
||||
|
||||
raise ValueError('%s not in collection' % value)
|
||||
|
||||
def index(self, key):
|
||||
"""
|
||||
@ -102,131 +124,129 @@ class collection(object):
|
||||
"""
|
||||
return self.items.index(key)
|
||||
|
||||
|
||||
# OCL members (from SMW by Ivan Porres, http://www.abo.fi/~iporres/smw)
|
||||
|
||||
def size(self):
|
||||
return len(self.items)
|
||||
|
||||
def includes(self,o):
|
||||
def includes(self, o):
|
||||
return o in self.items
|
||||
|
||||
def excludes(self,o):
|
||||
def excludes(self, o):
|
||||
return not self.includes(o)
|
||||
|
||||
def count(self,o):
|
||||
c=0
|
||||
def count(self, o):
|
||||
c = 0
|
||||
for x in self.items:
|
||||
if x==o:
|
||||
c=c+1
|
||||
if x == o:
|
||||
c += 1
|
||||
return c
|
||||
|
||||
def includesAll(self,c):
|
||||
def includesAll(self, c):
|
||||
for o in c:
|
||||
if o not in self.items:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def excludesAll(self,c):
|
||||
def excludesAll(self, c):
|
||||
for o in c:
|
||||
if o in self.items:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def select(self,f):
|
||||
result=list()
|
||||
def select(self, f):
|
||||
result = list()
|
||||
for v in self.items:
|
||||
if f(v):
|
||||
result.append(v)
|
||||
return result
|
||||
|
||||
def reject(self,f):
|
||||
result=list()
|
||||
def reject(self, f):
|
||||
result = list()
|
||||
for v in self.items:
|
||||
if not f(v):
|
||||
result.append(v)
|
||||
return result
|
||||
|
||||
def collect(self,f):
|
||||
result=list()
|
||||
def collect(self, f):
|
||||
result = list()
|
||||
for v in self.items:
|
||||
result.append(f(v))
|
||||
return result
|
||||
|
||||
def isEmpty(self):
|
||||
return len(self.items)==0
|
||||
return len(self.items) == 0
|
||||
|
||||
def nonEmpty(self):
|
||||
return not self.isEmpty()
|
||||
|
||||
|
||||
def sum(self):
|
||||
r=0
|
||||
r = 0
|
||||
for o in self.items:
|
||||
r=r+o
|
||||
r = r + o
|
||||
return o
|
||||
|
||||
def forAll(self,f):
|
||||
|
||||
def forAll(self, f):
|
||||
if not self.items or not inspect.getargspec(f)[0]:
|
||||
return True
|
||||
|
||||
nargs=len(inspect.getargspec(f)[0])
|
||||
nargs = len(inspect.getargspec(f)[0])
|
||||
if inspect.getargspec(f)[3]:
|
||||
nargs=nargs-len(inspect.getargspec(f)[3])
|
||||
|
||||
assert(nargs>0)
|
||||
nitems=len(self.items)
|
||||
index=[0]*nargs
|
||||
|
||||
nargs -= len(inspect.getargspec(f)[3])
|
||||
|
||||
assert (nargs > 0)
|
||||
nitems = len(self.items)
|
||||
index = [0] * nargs
|
||||
|
||||
while 1:
|
||||
args=[]
|
||||
args = []
|
||||
for x in index:
|
||||
args.append(self.items[x])
|
||||
if not apply(f,args):
|
||||
if not f(*args):
|
||||
return False
|
||||
c=len(index)-1
|
||||
index[c]=index[c]+1
|
||||
while index[c]==nitems:
|
||||
index[c]=0
|
||||
c=c-1
|
||||
if c<0:
|
||||
c = len(index) - 1
|
||||
index[c] += 1
|
||||
while index[c] == nitems:
|
||||
index[c] = 0
|
||||
c = c - 1
|
||||
if c < 0:
|
||||
return True
|
||||
else:
|
||||
index[c]=index[c]+1
|
||||
if index[c]==nitems-1:
|
||||
c=c-1
|
||||
index[c] += 1
|
||||
if index[c] == nitems - 1:
|
||||
c -= 1
|
||||
return False
|
||||
|
||||
def exist(self,f):
|
||||
def exist(self, f):
|
||||
if not self.items or not inspect.getargspec(f)[0]:
|
||||
return False
|
||||
|
||||
nargs=len(inspect.getargspec(f)[0])
|
||||
nargs = len(inspect.getargspec(f)[0])
|
||||
if inspect.getargspec(f)[3]:
|
||||
nargs=nargs-len(inspect.getargspec(f)[3])
|
||||
|
||||
assert(nargs>0)
|
||||
nitems=len(self.items)
|
||||
index=[0]*nargs
|
||||
nargs -= len(inspect.getargspec(f)[3])
|
||||
|
||||
assert (nargs > 0)
|
||||
nitems = len(self.items)
|
||||
index = [0] * nargs
|
||||
while 1:
|
||||
args=[]
|
||||
args = []
|
||||
for x in index:
|
||||
args.append(self.items[x])
|
||||
if apply(f,args):
|
||||
if f(*args):
|
||||
return True
|
||||
c=len(index)-1
|
||||
index[c]=index[c]+1
|
||||
while index[c]==nitems:
|
||||
index[c]=0
|
||||
c=c-1
|
||||
if c<0:
|
||||
c = len(index) - 1
|
||||
index[c] += 1
|
||||
while index[c] == nitems:
|
||||
index[c] = 0
|
||||
c -= 1
|
||||
if c < 0:
|
||||
return False
|
||||
else:
|
||||
index[c]=index[c]+1
|
||||
if index[c]==nitems-1:
|
||||
c=c-1
|
||||
index[c] += 1
|
||||
if index[c] == nitems - 1:
|
||||
c -= 1
|
||||
return False
|
||||
|
||||
|
||||
def swap(self, item1, item2):
|
||||
"""
|
||||
Swap two elements. Return true if swap was successful.
|
||||
@ -241,10 +261,9 @@ class collection(object):
|
||||
if factory:
|
||||
factory._handle(AssociationChangeEvent(self.object, self.property))
|
||||
return True
|
||||
except IndexError, ex:
|
||||
except IndexError as ex:
|
||||
return False
|
||||
except ValueError, ex:
|
||||
except ValueError as ex:
|
||||
return False
|
||||
|
||||
|
||||
# vi:sw=4:et:ai
|
||||
|
@ -1,12 +1,39 @@
|
||||
# vim: sw=4
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2002-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
# syt <noreply@example.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""This module contains a model element Diagram which is the abstract
|
||||
representation of a UML diagram. Diagrams can be visualized and edited.
|
||||
|
||||
The DiagramCanvas class extends the gaphas.Canvas class."""
|
||||
|
||||
import gaphas
|
||||
from __future__ import absolute_import
|
||||
|
||||
import uuid
|
||||
from uml2 import Namespace, PackageableElement
|
||||
|
||||
import gaphas
|
||||
from six.moves import filter
|
||||
|
||||
from gaphor.UML.uml2 import Namespace, PackageableElement
|
||||
|
||||
|
||||
class DiagramCanvas(gaphas.Canvas):
|
||||
"""DiagramCanvas extends the gaphas.Canvas class. Updates to the canvas
|
||||
@ -17,7 +44,7 @@ class DiagramCanvas(gaphas.Canvas):
|
||||
def __init__(self, diagram):
|
||||
"""Initialize the diagram canvas with the supplied diagram. By default,
|
||||
updates are not blocked."""
|
||||
|
||||
|
||||
super(DiagramCanvas, self).__init__()
|
||||
self._diagram = diagram
|
||||
self._block_updates = False
|
||||
@ -27,7 +54,7 @@ class DiagramCanvas(gaphas.Canvas):
|
||||
def _set_block_updates(self, block):
|
||||
"""Sets the block_updates property. If false, the diagram canvas is
|
||||
updated immediately."""
|
||||
|
||||
|
||||
self._block_updates = block
|
||||
if not block:
|
||||
self.update_now()
|
||||
@ -36,14 +63,14 @@ class DiagramCanvas(gaphas.Canvas):
|
||||
|
||||
def update_now(self):
|
||||
"""Update the diagram canvas, unless block_updates is true."""
|
||||
|
||||
|
||||
if self._block_updates:
|
||||
return
|
||||
super(DiagramCanvas, self).update_now()
|
||||
|
||||
def save(self, save_func):
|
||||
"""Apply the supplied save function to all root diagram items."""
|
||||
|
||||
|
||||
for item in self.get_root_items():
|
||||
save_func(None, item)
|
||||
|
||||
@ -54,8 +81,8 @@ class DiagramCanvas(gaphas.Canvas):
|
||||
|
||||
def select(self, expression=lambda e: True):
|
||||
"""Return a list of all canvas items that match expression."""
|
||||
|
||||
return filter(expression, self.get_all_items())
|
||||
|
||||
return list(filter(expression, self.get_all_items()))
|
||||
|
||||
|
||||
class Diagram(Namespace, PackageableElement):
|
||||
@ -65,13 +92,13 @@ class Diagram(Namespace, PackageableElement):
|
||||
def __init__(self, id=None, factory=None):
|
||||
"""Initialize the diagram with an optional id and element factory.
|
||||
The diagram also has a canvas."""
|
||||
|
||||
|
||||
super(Diagram, self).__init__(id, factory)
|
||||
self.canvas = DiagramCanvas(self)
|
||||
|
||||
def save(self, save_func):
|
||||
"""Apply the supplied save function to this diagram and the canvas."""
|
||||
|
||||
|
||||
super(Diagram, self).save(save_func)
|
||||
save_func('canvas', self.canvas)
|
||||
|
||||
@ -85,7 +112,7 @@ class Diagram(Namespace, PackageableElement):
|
||||
a unique ID and it is attached to the diagram's root item. The type
|
||||
parameter is the element class to create. The new element also has an
|
||||
optional parent and subject."""
|
||||
|
||||
|
||||
assert issubclass(type, gaphas.Item)
|
||||
obj = type(str(uuid.uuid1()))
|
||||
if subject:
|
||||
@ -95,7 +122,7 @@ class Diagram(Namespace, PackageableElement):
|
||||
|
||||
def unlink(self):
|
||||
"""Unlink all canvas items then unlink this diagram."""
|
||||
|
||||
|
||||
for item in self.canvas.get_all_items():
|
||||
try:
|
||||
item.unlink()
|
||||
|
@ -1,13 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
# syt <noreply@example.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Base class for UML model elements.
|
||||
"""
|
||||
|
||||
__all__ = [ 'Element' ]
|
||||
from __future__ import absolute_import
|
||||
|
||||
import threading
|
||||
import uuid
|
||||
from properties import umlproperty
|
||||
|
||||
from .properties import umlproperty
|
||||
|
||||
__all__ = ['Element']
|
||||
|
||||
|
||||
class Element(object):
|
||||
@ -33,14 +56,11 @@ class Element(object):
|
||||
self._factory = factory
|
||||
self._unlink_lock = threading.Lock()
|
||||
|
||||
|
||||
id = property(lambda self: self._id, doc='Id')
|
||||
|
||||
|
||||
factory = property(lambda self: self._factory,
|
||||
doc="The factory that created this element")
|
||||
|
||||
|
||||
def umlproperties(self):
|
||||
"""
|
||||
Iterate over all UML properties
|
||||
@ -53,7 +73,6 @@ class Element(object):
|
||||
if isinstance(prop, umlprop):
|
||||
yield prop
|
||||
|
||||
|
||||
def save(self, save_func):
|
||||
"""
|
||||
Save the state by calling save_func(name, value).
|
||||
@ -61,7 +80,6 @@ class Element(object):
|
||||
for prop in self.umlproperties():
|
||||
prop.save(self, save_func)
|
||||
|
||||
|
||||
def load(self, name, value):
|
||||
"""
|
||||
Loads value in name. Make sure that for every load postload()
|
||||
@ -69,13 +87,11 @@ class Element(object):
|
||||
"""
|
||||
try:
|
||||
prop = getattr(type(self), name)
|
||||
except AttributeError, e:
|
||||
raise AttributeError, "'%s' has no property '%s'" % \
|
||||
(type(self).__name__, name)
|
||||
except AttributeError as e:
|
||||
raise AttributeError("'%s' has no property '%s'" % (type(self).__name__, name))
|
||||
else:
|
||||
prop.load(self, value)
|
||||
|
||||
|
||||
def postload(self):
|
||||
"""
|
||||
Fix up the odds and ends.
|
||||
@ -83,26 +99,22 @@ class Element(object):
|
||||
for prop in self.umlproperties():
|
||||
prop.postload(self)
|
||||
|
||||
|
||||
def unlink(self):
|
||||
|
||||
|
||||
"""Unlink the element. All the elements references are destroyed.
|
||||
|
||||
The unlink lock is acquired while unlinking this elements properties
|
||||
to avoid recursion problems."""
|
||||
|
||||
|
||||
if self._unlink_lock.locked():
|
||||
|
||||
return
|
||||
|
||||
|
||||
with self._unlink_lock:
|
||||
|
||||
|
||||
for prop in self.umlproperties():
|
||||
|
||||
prop.unlink(self)
|
||||
|
||||
|
||||
if self._factory:
|
||||
|
||||
self._factory._unlink_element(self)
|
||||
|
||||
# OCL methods: (from SMW by Ivan Porres (http://www.abo.fi/~iporres/smw))
|
||||
@ -113,14 +125,12 @@ class Element(object):
|
||||
"""
|
||||
return isinstance(self, class_)
|
||||
|
||||
|
||||
def isTypeOf(self, other):
|
||||
"""
|
||||
Returns true if the object is of the same type as other.
|
||||
"""
|
||||
return type(self) == type(other)
|
||||
|
||||
|
||||
def __getstate__(self):
|
||||
d = dict(self.__dict__)
|
||||
try:
|
||||
@ -129,7 +139,6 @@ class Element(object):
|
||||
pass
|
||||
return d
|
||||
|
||||
|
||||
def __setstate__(self, state):
|
||||
self._factory = None
|
||||
self.__dict__.update(state)
|
||||
|
@ -1,21 +1,44 @@
|
||||
# vim: sw=4
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2002-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
# syt <noreply@example.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Factory for and registration of model elements.
|
||||
"""
|
||||
|
||||
from zope import interface
|
||||
from zope import component
|
||||
from __future__ import absolute_import
|
||||
|
||||
import uuid
|
||||
from gaphor.core import inject
|
||||
from gaphor.misc import odict
|
||||
from gaphor.interfaces import IService, IEventFilter
|
||||
from gaphor.UML.interfaces import IElementCreateEvent, IElementDeleteEvent, \
|
||||
IFlushFactoryEvent, IModelFactoryEvent, \
|
||||
IElementChangeEvent, IElementEvent
|
||||
from gaphor.UML.event import ElementCreateEvent, ElementDeleteEvent, \
|
||||
FlushFactoryEvent, ModelFactoryEvent
|
||||
from zope import component
|
||||
from zope import interface
|
||||
|
||||
import six
|
||||
|
||||
from gaphor.UML.element import Element
|
||||
from gaphor.UML.diagram import Diagram
|
||||
from gaphor.UML.event import ElementCreateEvent, ElementDeleteEvent, FlushFactoryEvent, ModelFactoryEvent
|
||||
from gaphor.UML.interfaces import IElementChangeEvent
|
||||
from gaphor.UML.uml2 import Diagram
|
||||
from gaphor.core import inject
|
||||
from gaphor.interfaces import IService, IEventFilter
|
||||
from gaphor.misc import odict
|
||||
|
||||
|
||||
class ElementFactory(object):
|
||||
@ -31,6 +54,7 @@ class ElementFactory(object):
|
||||
flush - model is flushed: all element are removed from the factory
|
||||
(element is None)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._elements = odict.odict()
|
||||
self._observers = list()
|
||||
@ -59,13 +83,12 @@ class ElementFactory(object):
|
||||
The element may not be bound to another factory already.
|
||||
"""
|
||||
if hasattr(element, '_factory') and element._factory:
|
||||
raise AttributeError, "element is already bound"
|
||||
raise AttributeError("element is already bound")
|
||||
if self._elements.get(element.id):
|
||||
raise AttributeError, "an element already exists with the same id"
|
||||
raise AttributeError("an element already exists with the same id")
|
||||
|
||||
element._factory = self
|
||||
self._elements[element.id] = element
|
||||
|
||||
|
||||
def size(self):
|
||||
"""
|
||||
@ -73,68 +96,58 @@ class ElementFactory(object):
|
||||
"""
|
||||
return len(self._elements)
|
||||
|
||||
|
||||
def lookup(self, id):
|
||||
"""
|
||||
Find element with a specific id.
|
||||
"""
|
||||
return self._elements.get(id)
|
||||
|
||||
|
||||
__getitem__ = lookup
|
||||
|
||||
|
||||
def __contains__(self, element):
|
||||
return self.lookup(element.id) is element
|
||||
|
||||
|
||||
def select(self, expression=None):
|
||||
"""
|
||||
Iterate elements that comply with expression.
|
||||
"""
|
||||
if expression is None:
|
||||
for e in self._elements.itervalues():
|
||||
for e in six.itervalues(self._elements):
|
||||
yield e
|
||||
else:
|
||||
for e in self._elements.itervalues():
|
||||
for e in six.itervalues(self._elements):
|
||||
if expression(e):
|
||||
yield e
|
||||
|
||||
|
||||
def lselect(self, expression=None):
|
||||
"""
|
||||
Like select(), but returns a list.
|
||||
"""
|
||||
return list(self.select(expression))
|
||||
|
||||
|
||||
def keys(self):
|
||||
"""
|
||||
Return a list with all id's in the factory.
|
||||
"""
|
||||
return self._elements.keys()
|
||||
|
||||
return list(self._elements.keys())
|
||||
|
||||
def iterkeys(self):
|
||||
"""
|
||||
Return a iterator with all id's in the factory.
|
||||
"""
|
||||
return self._elements.iterkeys()
|
||||
|
||||
return six.iterkeys(self._elements)
|
||||
|
||||
def values(self):
|
||||
"""
|
||||
Return a list with all elements in the factory.
|
||||
"""
|
||||
return self._elements.values()
|
||||
|
||||
return list(self._elements.values())
|
||||
|
||||
def itervalues(self):
|
||||
"""
|
||||
Return a iterator with all elements in the factory.
|
||||
"""
|
||||
return self._elements.itervalues()
|
||||
|
||||
return six.itervalues(self._elements)
|
||||
|
||||
def is_empty(self):
|
||||
"""
|
||||
@ -142,19 +155,18 @@ class ElementFactory(object):
|
||||
"""
|
||||
return bool(self._elements)
|
||||
|
||||
|
||||
def flush(self):
|
||||
"""Flush all elements (remove them from the factory).
|
||||
|
||||
Diagram elements are flushed first. This is so that canvas updates
|
||||
are blocked. The remaining elements are then flushed.
|
||||
"""
|
||||
|
||||
|
||||
flush_element = self._flush_element
|
||||
for element in self.lselect(lambda e: isinstance(e, Diagram)):
|
||||
element.canvas.block_updates = True
|
||||
flush_element(element)
|
||||
|
||||
|
||||
for element in self.lselect():
|
||||
flush_element(element)
|
||||
|
||||
@ -171,7 +183,7 @@ class ElementFactory(object):
|
||||
pass
|
||||
|
||||
def swap_element(self, element, new_class):
|
||||
assert element in self._elements.values()
|
||||
assert element in list(self._elements.values())
|
||||
if element.__class__ is not new_class:
|
||||
element.__class__ = new_class
|
||||
|
||||
@ -215,7 +227,7 @@ class ElementFactoryService(ElementFactory):
|
||||
are blocked. The remaining elements are then flushed. Finally,
|
||||
the ElementChangedEventBlocker adapter is unregistered if the factory
|
||||
has an application instance."""
|
||||
|
||||
|
||||
self.component_registry.handle(FlushFactoryEvent(self))
|
||||
self.component_registry.register_subscription_adapter(ElementChangedEventBlocker)
|
||||
|
||||
@ -263,6 +275,4 @@ class ElementChangedEventBlocker(object):
|
||||
"""
|
||||
return 'Blocked by ElementFactory.flush()'
|
||||
|
||||
|
||||
|
||||
# vim:sw=4:et
|
||||
|
@ -1,6 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""The core UML metamodel events."""
|
||||
|
||||
from interfaces import *
|
||||
from __future__ import absolute_import
|
||||
from .interfaces import *
|
||||
from zope import interface
|
||||
|
||||
class AttributeChangeEvent(object):
|
||||
|
@ -1,7 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
UML events emited on a change in the data model.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from zope import interface
|
||||
from gaphor.interfaces import IServiceEvent
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
UML model support functions.
|
||||
|
||||
@ -8,7 +28,7 @@ Functions collected in this module allow to
|
||||
|
||||
"""
|
||||
|
||||
import itertools
|
||||
from __future__ import absolute_import
|
||||
from gaphor.UML.uml2 import *
|
||||
|
||||
# '<<%s>>'
|
||||
|
@ -1,3 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2003-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Properties used to create the UML 2.0 data model.
|
||||
|
||||
@ -24,16 +45,18 @@ methods:
|
||||
save(save_func): send the value of the property to save_func(name, value)
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from six.moves import map
|
||||
__all__ = [ 'attribute', 'enumeration', 'association', 'derivedunion', 'redefine' ]
|
||||
|
||||
from zope import component
|
||||
from collection import collection, collectionlist
|
||||
from event import AttributeChangeEvent, AssociationSetEvent, \
|
||||
from .collection import collection, collectionlist
|
||||
from .event import AttributeChangeEvent, AssociationSetEvent, \
|
||||
AssociationAddEvent, AssociationDeleteEvent
|
||||
from event import DerivedChangeEvent, DerivedSetEvent, \
|
||||
from .event import DerivedChangeEvent, DerivedSetEvent, \
|
||||
DerivedAddEvent, DerivedDeleteEvent
|
||||
from event import RedefineSetEvent, RedefineAddEvent, RedefineDeleteEvent
|
||||
from interfaces import IElementChangeEvent, \
|
||||
from .event import RedefineSetEvent, RedefineAddEvent, RedefineDeleteEvent
|
||||
from .interfaces import IElementChangeEvent, \
|
||||
IAssociationChangeEvent, IAssociationSetEvent, \
|
||||
IAssociationAddEvent, IAssociationDeleteEvent
|
||||
|
||||
@ -129,7 +152,7 @@ class attribute(umlproperty):
|
||||
|
||||
def _set(self, obj, value):
|
||||
if value is not None and not isinstance(value, self.type):
|
||||
raise AttributeError, 'Value should be of type %s' % hasattr(self.type, '__name__') and self.type.__name__ or self.type
|
||||
raise AttributeError('Value should be of type %s' % hasattr(self.type, '__name__') and self.type.__name__ or self.type)
|
||||
|
||||
if value == self._get(obj):
|
||||
return
|
||||
@ -186,12 +209,12 @@ class enumeration(umlproperty):
|
||||
|
||||
def load(self, obj, value):
|
||||
if not value in self.values:
|
||||
raise AttributeError, 'Value should be one of %s' % str(self.values)
|
||||
raise AttributeError('Value should be one of %s' % str(self.values))
|
||||
setattr(obj, self._name, value)
|
||||
|
||||
def _set(self, obj, value):
|
||||
if not value in self.values:
|
||||
raise AttributeError, 'Value should be one of %s' % str(self.values)
|
||||
raise AttributeError('Value should be one of %s' % str(self.values))
|
||||
old = self._get(obj)
|
||||
if value == old:
|
||||
return
|
||||
@ -238,7 +261,7 @@ class association(umlproperty):
|
||||
|
||||
def load(self, obj, value):
|
||||
if not isinstance(value, self.type):
|
||||
raise AttributeError, 'Value for %s should be of type %s (%s)' % (self.name, self.type.__name__, type(value).__name__)
|
||||
raise AttributeError('Value for %s should be of type %s (%s)' % (self.name, self.type.__name__, type(value).__name__))
|
||||
self._set(obj, value, do_notify=False)
|
||||
|
||||
def postload(self, obj):
|
||||
@ -253,7 +276,7 @@ class association(umlproperty):
|
||||
values = [ values ]
|
||||
for value in values:
|
||||
if not isinstance(value, self.type):
|
||||
raise AttributeError, 'Error in postload validation for %s: Value %s should be of type %s' % (self.name, value, self.type.__name__)
|
||||
raise AttributeError('Error in postload validation for %s: Value %s should be of type %s' % (self.name, value, self.type.__name__))
|
||||
|
||||
def __str__(self):
|
||||
if self.lower == self.upper:
|
||||
@ -289,7 +312,7 @@ class association(umlproperty):
|
||||
#print '__set__', self, obj, value, self._get(obj)
|
||||
if not (isinstance(value, self.type) or \
|
||||
(value is None and self.upper == 1)):
|
||||
raise AttributeError, 'Value should be of type %s' % self.type.__name__
|
||||
raise AttributeError('Value should be of type %s' % self.type.__name__)
|
||||
# Remove old value only for uni-directional associations
|
||||
if self.upper == 1:
|
||||
old = self._get(obj)
|
||||
@ -348,7 +371,7 @@ class association(umlproperty):
|
||||
|
||||
if not value:
|
||||
if self.upper > 1:
|
||||
raise Exception, 'Can not delete collections'
|
||||
raise Exception('Can not delete collections')
|
||||
old = value = self._get(obj)
|
||||
if value is None:
|
||||
return
|
||||
@ -419,14 +442,14 @@ class associationstub(umlproperty):
|
||||
|
||||
def __get__(self, obj, class_=None):
|
||||
if obj:
|
||||
raise AssociationStubError, 'getting values not allowed'
|
||||
raise AssociationStubError('getting values not allowed')
|
||||
return self
|
||||
|
||||
def __set__(self, obj, value):
|
||||
raise AssociationStubError, 'setting values not allowed'
|
||||
raise AssociationStubError('setting values not allowed')
|
||||
|
||||
def __delete__(self, obj, value=None):
|
||||
raise AssociationStubError, 'deleting values not allowed'
|
||||
raise AssociationStubError('deleting values not allowed')
|
||||
|
||||
def save(self, obj, save_func):
|
||||
pass
|
||||
@ -493,7 +516,7 @@ class derived(umlproperty):
|
||||
|
||||
|
||||
def load(self, obj, value):
|
||||
raise ValueError, 'Derivedunion: Properties should not be loaded in a derived union %s: %s' % (self.name, value)
|
||||
raise ValueError('Derivedunion: Properties should not be loaded in a derived union %s: %s' % (self.name, value))
|
||||
|
||||
|
||||
def postload(self, obj):
|
||||
@ -504,13 +527,13 @@ class derived(umlproperty):
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return '<derived %s: %s>' % (self.name, str(map(str, self.subsets))[1:-1])
|
||||
return '<derived %s: %s>' % (self.name, str(list(map(str, self.subsets)))[1:-1])
|
||||
|
||||
def filter(self, obj):
|
||||
"""
|
||||
Filter should return something iterable.
|
||||
"""
|
||||
raise NotImplementedError, 'Implement this in the property.'
|
||||
raise NotImplementedError('Implement this in the property.')
|
||||
|
||||
def _update(self, obj):
|
||||
"""
|
||||
@ -523,7 +546,7 @@ class derived(umlproperty):
|
||||
#if len(u) > 1:
|
||||
# log.warning('Derived union %s of item %s should have length 1 %s' % (self.name, obj.id, tuple(u)))
|
||||
if u:
|
||||
u = iter(u).next()
|
||||
u = next(iter(u))
|
||||
else:
|
||||
u = None
|
||||
|
||||
@ -544,11 +567,11 @@ class derived(umlproperty):
|
||||
|
||||
|
||||
def _set(self, obj, value):
|
||||
raise AttributeError, 'Can not set values on a union'
|
||||
raise AttributeError('Can not set values on a union')
|
||||
|
||||
|
||||
def _del(self, obj, value=None):
|
||||
raise AttributeError, 'Can not delete values on a union'
|
||||
raise AttributeError('Can not delete values on a union')
|
||||
|
||||
@component.adapter(IElementChangeEvent)
|
||||
def _association_changed(self, event):
|
||||
@ -669,7 +692,7 @@ class derivedunion(derived):
|
||||
# In an in-between state. Do not emit notifications
|
||||
return
|
||||
if values:
|
||||
new_value = iter(values).next()
|
||||
new_value = next(iter(values))
|
||||
self.handle(DerivedSetEvent(event.element, self, old_value, new_value))
|
||||
else:
|
||||
if IAssociationSetEvent.providedBy(event):
|
||||
@ -752,7 +775,7 @@ class redefine(umlproperty):
|
||||
def __set__(self, obj, value):
|
||||
# No longer needed
|
||||
if not isinstance(value, self.type):
|
||||
raise AttributeError, 'Value should be of type %s' % self.type.__name__
|
||||
raise AttributeError('Value should be of type %s' % self.type.__name__)
|
||||
self.original.__set__(obj, value)
|
||||
|
||||
|
||||
|
@ -1 +1,18 @@
|
||||
# unit tests
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
@ -1,7 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Test if the collection's list supports all trickery.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import unittest
|
||||
from gaphor.UML.collection import collectionlist
|
||||
|
||||
|
@ -1,15 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
import unittest
|
||||
from gaphor.UML import *
|
||||
from gaphor.UML.interfaces import *
|
||||
from gaphor.UML import interfaces
|
||||
from gaphor.UML import elementfactory
|
||||
from gaphor.UML import uml2
|
||||
import gc
|
||||
import weakref, sys
|
||||
|
||||
|
||||
class ElementFactoryTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.factory = ElementFactory()
|
||||
self.factory = elementfactory.ElementFactory()
|
||||
|
||||
def tearDown(self):
|
||||
del self.factory
|
||||
@ -17,34 +36,34 @@ class ElementFactoryTestCase(unittest.TestCase):
|
||||
def testCreate(self):
|
||||
ef = self.factory
|
||||
|
||||
p = ef.create(Parameter)
|
||||
assert len(ef.values()) == 1
|
||||
p = ef.create(uml2.Parameter)
|
||||
assert len(list(ef.values())) == 1
|
||||
|
||||
def testFlush(self):
|
||||
ef = self.factory
|
||||
|
||||
p = ef.create(Parameter)
|
||||
p = ef.create(uml2.Parameter)
|
||||
#wp = weakref.ref(p)
|
||||
assert len(ef.values()) == 1
|
||||
assert len(list(ef.values())) == 1
|
||||
ef.flush()
|
||||
del p
|
||||
|
||||
gc.collect()
|
||||
|
||||
#assert wp() is None
|
||||
assert len(ef.values()) == 0, ef.values()
|
||||
assert len(list(ef.values())) == 0, list(ef.values())
|
||||
|
||||
|
||||
def testWithoutApplication(self):
|
||||
ef = ElementFactory()
|
||||
ef = elementfactory.ElementFactory()
|
||||
|
||||
p = ef.create(Parameter)
|
||||
p = ef.create(uml2.Parameter)
|
||||
assert ef.size() == 1, ef.size()
|
||||
|
||||
ef.flush()
|
||||
assert ef.size() == 0, ef.size()
|
||||
|
||||
p = ef.create(Parameter)
|
||||
p = ef.create(uml2.Parameter)
|
||||
assert ef.size() == 1, ef.size()
|
||||
|
||||
p.unlink()
|
||||
@ -53,23 +72,23 @@ class ElementFactoryTestCase(unittest.TestCase):
|
||||
|
||||
def testUnlink(self):
|
||||
ef = self.factory
|
||||
p = ef.create(Parameter)
|
||||
p = ef.create(uml2.Parameter)
|
||||
|
||||
assert len(ef.values()) == 1
|
||||
assert len(list(ef.values())) == 1
|
||||
|
||||
p.unlink()
|
||||
|
||||
assert len(ef.values()) == 0, ef.values()
|
||||
assert len(list(ef.values())) == 0, list(ef.values())
|
||||
|
||||
p = ef.create(Parameter)
|
||||
p = ef.create(uml2.Parameter)
|
||||
p.defaultValue = 'l'
|
||||
|
||||
assert len(ef.values()) == 1
|
||||
assert len(list(ef.values())) == 1
|
||||
|
||||
p.unlink()
|
||||
del p
|
||||
|
||||
assert len(ef.values()) == 0, ef.values()
|
||||
assert len(list(ef.values())) == 0, list(ef.values())
|
||||
|
||||
|
||||
|
||||
@ -83,7 +102,7 @@ handled = False
|
||||
events = []
|
||||
last_event = None
|
||||
|
||||
@component.adapter(IServiceEvent)
|
||||
@component.adapter(interfaces.IServiceEvent)
|
||||
def handler(event):
|
||||
global handled, events, last_event
|
||||
handled = True
|
||||
@ -113,31 +132,31 @@ class ElementFactoryServiceTestCase(unittest.TestCase):
|
||||
def testCreateEvent(self):
|
||||
ef = self.factory
|
||||
global handled
|
||||
p = ef.create(Parameter)
|
||||
self.assertTrue(IElementCreateEvent.providedBy(last_event) )
|
||||
p = ef.create(uml2.Parameter)
|
||||
self.assertTrue(interfaces.IElementCreateEvent.providedBy(last_event) )
|
||||
self.assertTrue(handled)
|
||||
|
||||
def testRemoveEvent(self):
|
||||
ef = self.factory
|
||||
global handled
|
||||
p = ef.create(Parameter)
|
||||
self.assertTrue(IElementCreateEvent.providedBy(last_event) )
|
||||
p = ef.create(uml2.Parameter)
|
||||
self.assertTrue(interfaces.IElementCreateEvent.providedBy(last_event) )
|
||||
self.assertTrue(handled)
|
||||
self.clearEvents()
|
||||
p.unlink()
|
||||
self.assertTrue(IElementDeleteEvent.providedBy(last_event) )
|
||||
self.assertTrue(interfaces.IElementDeleteEvent.providedBy(last_event) )
|
||||
|
||||
def testModelEvent(self):
|
||||
ef = self.factory
|
||||
global handled
|
||||
ef.notify_model()
|
||||
self.assertTrue(IModelFactoryEvent.providedBy(last_event) )
|
||||
self.assertTrue(interfaces.IModelFactoryEvent.providedBy(last_event) )
|
||||
|
||||
def testFlushEvent(self):
|
||||
ef = self.factory
|
||||
global handled
|
||||
ef.flush()
|
||||
self.assertTrue(IFlushFactoryEvent.providedBy(last_event) )
|
||||
self.assertTrue(interfaces.IFlushFactoryEvent.providedBy(last_event) )
|
||||
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,12 +1,32 @@
|
||||
from gaphor import UML
|
||||
from gaphor.application import Application
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
from gaphor.UML import uml2, modelfactory, elementfactory
|
||||
from gaphor.UML.modelfactory import STEREOTYPE_FMT as fmt
|
||||
|
||||
import unittest
|
||||
|
||||
class TestCaseBase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.factory = UML.ElementFactory()
|
||||
self.factory = elementfactory.ElementFactory()
|
||||
|
||||
|
||||
class StereotypesTestCase(TestCaseBase):
|
||||
@ -14,134 +34,134 @@ class StereotypesTestCase(TestCaseBase):
|
||||
def test_stereotype_name(self):
|
||||
"""Test stereotype name
|
||||
"""
|
||||
stereotype = self.factory.create(UML.Stereotype)
|
||||
stereotype = self.factory.create(uml2.Stereotype)
|
||||
stereotype.name = 'Test'
|
||||
self.assertEquals('test', UML.model.stereotype_name(stereotype))
|
||||
self.assertEquals('test', modelfactory.stereotype_name(stereotype))
|
||||
|
||||
stereotype.name = 'TEST'
|
||||
self.assertEquals('TEST', UML.model.stereotype_name(stereotype))
|
||||
self.assertEquals('TEST', modelfactory.stereotype_name(stereotype))
|
||||
|
||||
stereotype.name = 'T'
|
||||
self.assertEquals('t', UML.model.stereotype_name(stereotype))
|
||||
self.assertEquals('t', modelfactory.stereotype_name(stereotype))
|
||||
|
||||
stereotype.name = ''
|
||||
self.assertEquals('', UML.model.stereotype_name(stereotype))
|
||||
self.assertEquals('', modelfactory.stereotype_name(stereotype))
|
||||
|
||||
stereotype.name = None
|
||||
self.assertEquals('', UML.model.stereotype_name(stereotype))
|
||||
self.assertEquals('', modelfactory.stereotype_name(stereotype))
|
||||
|
||||
|
||||
def test_stereotypes_conversion(self):
|
||||
"""Test stereotypes conversion
|
||||
"""
|
||||
s1 = self.factory.create(UML.Stereotype)
|
||||
s2 = self.factory.create(UML.Stereotype)
|
||||
s3 = self.factory.create(UML.Stereotype)
|
||||
s1 = self.factory.create(uml2.Stereotype)
|
||||
s2 = self.factory.create(uml2.Stereotype)
|
||||
s3 = self.factory.create(uml2.Stereotype)
|
||||
s1.name = 's1'
|
||||
s2.name = 's2'
|
||||
s3.name = 's3'
|
||||
|
||||
cls = self.factory.create(UML.Class)
|
||||
UML.model.apply_stereotype(self.factory, cls, s1)
|
||||
UML.model.apply_stereotype(self.factory, cls, s2)
|
||||
UML.model.apply_stereotype(self.factory, cls, s3)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s1)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s2)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s3)
|
||||
|
||||
self.assertEquals(fmt % 's1, s2, s3', UML.model.stereotypes_str(cls))
|
||||
self.assertEquals(fmt % 's1, s2, s3', modelfactory.stereotypes_str(cls))
|
||||
|
||||
|
||||
def test_no_stereotypes(self):
|
||||
"""Test stereotypes conversion without applied stereotypes
|
||||
"""
|
||||
cls = self.factory.create(UML.Class)
|
||||
self.assertEquals('', UML.model.stereotypes_str(cls))
|
||||
cls = self.factory.create(uml2.Class)
|
||||
self.assertEquals('', modelfactory.stereotypes_str(cls))
|
||||
|
||||
|
||||
def test_additional_stereotypes(self):
|
||||
"""Test additional stereotypes conversion
|
||||
"""
|
||||
s1 = self.factory.create(UML.Stereotype)
|
||||
s2 = self.factory.create(UML.Stereotype)
|
||||
s3 = self.factory.create(UML.Stereotype)
|
||||
s1 = self.factory.create(uml2.Stereotype)
|
||||
s2 = self.factory.create(uml2.Stereotype)
|
||||
s3 = self.factory.create(uml2.Stereotype)
|
||||
s1.name = 's1'
|
||||
s2.name = 's2'
|
||||
s3.name = 's3'
|
||||
|
||||
cls = self.factory.create(UML.Class)
|
||||
UML.model.apply_stereotype(self.factory, cls, s1)
|
||||
UML.model.apply_stereotype(self.factory, cls, s2)
|
||||
UML.model.apply_stereotype(self.factory, cls, s3)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s1)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s2)
|
||||
modelfactory.apply_stereotype(self.factory, cls, s3)
|
||||
|
||||
result = UML.model.stereotypes_str(cls, ('test',))
|
||||
result = modelfactory.stereotypes_str(cls, ('test',))
|
||||
self.assertEquals(fmt % 'test, s1, s2, s3', result)
|
||||
|
||||
|
||||
def test_just_additional_stereotypes(self):
|
||||
"""Test additional stereotypes conversion without applied stereotypes
|
||||
"""
|
||||
cls = self.factory.create(UML.Class)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
|
||||
result = UML.model.stereotypes_str(cls, ('test',))
|
||||
result = modelfactory.stereotypes_str(cls, ('test',))
|
||||
self.assertEquals(fmt % 'test', result)
|
||||
|
||||
|
||||
def test_getting_stereotypes(self):
|
||||
"""Test getting possible stereotypes
|
||||
"""
|
||||
cls = self.factory.create(UML.Class)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
cls.name = 'Class'
|
||||
st1 = self.factory.create(UML.Stereotype)
|
||||
st1 = self.factory.create(uml2.Stereotype)
|
||||
st1.name = 'st1'
|
||||
st2 = self.factory.create(UML.Stereotype)
|
||||
st2 = self.factory.create(uml2.Stereotype)
|
||||
st2.name = 'st2'
|
||||
|
||||
# first extend with st2, to check sorting
|
||||
UML.model.extend_with_stereotype(self.factory, cls, st2)
|
||||
UML.model.extend_with_stereotype(self.factory, cls, st1)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls, st2)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls, st1)
|
||||
|
||||
c1 = self.factory.create(UML.Class)
|
||||
result = tuple(st.name for st in UML.model.get_stereotypes(self.factory, c1))
|
||||
c1 = self.factory.create(uml2.Class)
|
||||
result = tuple(st.name for st in modelfactory.get_stereotypes(self.factory, c1))
|
||||
self.assertEquals(('st1', 'st2'), result)
|
||||
|
||||
|
||||
def test_getting_stereotypes_unique(self):
|
||||
"""Test if possible stereotypes are unique
|
||||
"""
|
||||
cls1 = self.factory.create(UML.Class)
|
||||
cls1 = self.factory.create(uml2.Class)
|
||||
cls1.name = 'Class'
|
||||
cls2 = self.factory.create(UML.Class)
|
||||
cls2 = self.factory.create(uml2.Class)
|
||||
cls2.name = 'Component'
|
||||
st1 = self.factory.create(UML.Stereotype)
|
||||
st1 = self.factory.create(uml2.Stereotype)
|
||||
st1.name = 'st1'
|
||||
st2 = self.factory.create(UML.Stereotype)
|
||||
st2 = self.factory.create(uml2.Stereotype)
|
||||
st2.name = 'st2'
|
||||
|
||||
# first extend with st2, to check sorting
|
||||
UML.model.extend_with_stereotype(self.factory, cls1, st2)
|
||||
UML.model.extend_with_stereotype(self.factory, cls1, st1)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls1, st2)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls1, st1)
|
||||
|
||||
UML.model.extend_with_stereotype(self.factory, cls2, st1)
|
||||
UML.model.extend_with_stereotype(self.factory, cls2, st2)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls2, st1)
|
||||
modelfactory.extend_with_stereotype(self.factory, cls2, st2)
|
||||
|
||||
c1 = self.factory.create(UML.Component)
|
||||
result = tuple(st.name for st in UML.model.get_stereotypes(self.factory, c1))
|
||||
c1 = self.factory.create(uml2.Component)
|
||||
result = tuple(st.name for st in modelfactory.get_stereotypes(self.factory, c1))
|
||||
self.assertEquals(('st1', 'st2'), result)
|
||||
|
||||
|
||||
def test_finding_stereotype_instances(self):
|
||||
"""Test finding stereotype instances
|
||||
"""
|
||||
s1 = self.factory.create(UML.Stereotype)
|
||||
s2 = self.factory.create(UML.Stereotype)
|
||||
s1 = self.factory.create(uml2.Stereotype)
|
||||
s2 = self.factory.create(uml2.Stereotype)
|
||||
s1.name = 's1'
|
||||
s2.name = 's2'
|
||||
|
||||
c1 = self.factory.create(UML.Class)
|
||||
c2 = self.factory.create(UML.Class)
|
||||
UML.model.apply_stereotype(self.factory, c1, s1)
|
||||
UML.model.apply_stereotype(self.factory, c1, s2)
|
||||
UML.model.apply_stereotype(self.factory, c2, s1)
|
||||
c1 = self.factory.create(uml2.Class)
|
||||
c2 = self.factory.create(uml2.Class)
|
||||
modelfactory.apply_stereotype(self.factory, c1, s1)
|
||||
modelfactory.apply_stereotype(self.factory, c1, s2)
|
||||
modelfactory.apply_stereotype(self.factory, c2, s1)
|
||||
|
||||
result = [e.classifier[0].name for e in UML.model.find_instances(self.factory, s1)]
|
||||
result = [e.classifier[0].name for e in modelfactory.find_instances(self.factory, s1)]
|
||||
self.assertEquals(2, len(result))
|
||||
self.assertTrue('s1' in result, result)
|
||||
self.assertFalse('s2' in result, result)
|
||||
@ -155,16 +175,16 @@ class AssociationTestCase(TestCaseBase):
|
||||
def test_creation(self):
|
||||
"""Test association creation
|
||||
"""
|
||||
c1 = self.factory.create(UML.Class)
|
||||
c2 = self.factory.create(UML.Class)
|
||||
assoc = UML.model.create_association(self.factory, c1, c2)
|
||||
c1 = self.factory.create(uml2.Class)
|
||||
c2 = self.factory.create(uml2.Class)
|
||||
assoc = modelfactory.create_association(self.factory, c1, c2)
|
||||
types = [p.type for p in assoc.memberEnd]
|
||||
self.assertTrue(c1 in types, assoc.memberEnd)
|
||||
self.assertTrue(c2 in types, assoc.memberEnd)
|
||||
|
||||
c1 = self.factory.create(UML.Interface)
|
||||
c2 = self.factory.create(UML.Interface)
|
||||
assoc = UML.model.create_association(self.factory, c1, c2)
|
||||
c1 = self.factory.create(uml2.Interface)
|
||||
c2 = self.factory.create(uml2.Interface)
|
||||
assoc = modelfactory.create_association(self.factory, c1, c2)
|
||||
types = [p.type for p in assoc.memberEnd]
|
||||
self.assertTrue(c1 in types, assoc.memberEnd)
|
||||
self.assertTrue(c2 in types, assoc.memberEnd)
|
||||
@ -178,15 +198,15 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
def test_attribute_navigability(self):
|
||||
"""Test navigable attribute of a class or an interface
|
||||
"""
|
||||
c1 = self.factory.create(UML.Class)
|
||||
c2 = self.factory.create(UML.Class)
|
||||
assoc = UML.model.create_association(self.factory, c1, c2)
|
||||
c1 = self.factory.create(uml2.Class)
|
||||
c2 = self.factory.create(uml2.Class)
|
||||
assoc = modelfactory.create_association(self.factory, c1, c2)
|
||||
|
||||
end = assoc.memberEnd[0]
|
||||
assert end.type is c1
|
||||
assert end.type is c1
|
||||
|
||||
UML.model.set_navigability(assoc, end, True)
|
||||
modelfactory.set_navigability(assoc, end, True)
|
||||
|
||||
# class/interface navigablity, Association.navigableOwnedEnd not
|
||||
# involved
|
||||
@ -196,7 +216,7 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
self.assertTrue(end.navigability is True)
|
||||
|
||||
# uknown navigability
|
||||
UML.model.set_navigability(assoc, end, None)
|
||||
modelfactory.set_navigability(assoc, end, None)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end in assoc.ownedEnd)
|
||||
self.assertTrue(end not in c2.ownedAttribute)
|
||||
@ -204,7 +224,7 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
self.assertTrue(end.navigability is None)
|
||||
|
||||
# non-navigability
|
||||
UML.model.set_navigability(assoc, end, False)
|
||||
modelfactory.set_navigability(assoc, end, False)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end not in assoc.ownedEnd)
|
||||
self.assertTrue(end not in c2.ownedAttribute)
|
||||
@ -212,14 +232,14 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
self.assertTrue(end.navigability is False)
|
||||
|
||||
# check other navigability change possibilities
|
||||
UML.model.set_navigability(assoc, end, None)
|
||||
modelfactory.set_navigability(assoc, end, None)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end in assoc.ownedEnd)
|
||||
self.assertTrue(end not in c2.ownedAttribute)
|
||||
self.assertTrue(end.owner is assoc)
|
||||
self.assertTrue(end.navigability is None)
|
||||
|
||||
UML.model.set_navigability(assoc, end, True)
|
||||
modelfactory.set_navigability(assoc, end, True)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end not in assoc.ownedEnd)
|
||||
self.assertTrue(end in c2.ownedAttribute)
|
||||
@ -230,14 +250,14 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
def test_relationship_navigability(self):
|
||||
"""Test navigable relationship of a classifier
|
||||
"""
|
||||
n1 = self.factory.create(UML.Node)
|
||||
n2 = self.factory.create(UML.Node)
|
||||
assoc = UML.model.create_association(self.factory, n1, n2)
|
||||
n1 = self.factory.create(uml2.Node)
|
||||
n2 = self.factory.create(uml2.Node)
|
||||
assoc = modelfactory.create_association(self.factory, n1, n2)
|
||||
|
||||
end = assoc.memberEnd[0]
|
||||
assert end.type is n1
|
||||
|
||||
UML.model.set_navigability(assoc, end, True)
|
||||
modelfactory.set_navigability(assoc, end, True)
|
||||
|
||||
# class/interface navigablity, Association.navigableOwnedEnd not
|
||||
# involved
|
||||
@ -246,24 +266,24 @@ class AssociationEndNavigabilityTestCase(TestCaseBase):
|
||||
self.assertTrue(end.navigability is True)
|
||||
|
||||
# uknown navigability
|
||||
UML.model.set_navigability(assoc, end, None)
|
||||
modelfactory.set_navigability(assoc, end, None)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end in assoc.ownedEnd)
|
||||
self.assertTrue(end.navigability is None)
|
||||
|
||||
# non-navigability
|
||||
UML.model.set_navigability(assoc, end, False)
|
||||
modelfactory.set_navigability(assoc, end, False)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end not in assoc.ownedEnd)
|
||||
self.assertTrue(end.navigability is False)
|
||||
|
||||
# check other navigability change possibilities
|
||||
UML.model.set_navigability(assoc, end, None)
|
||||
modelfactory.set_navigability(assoc, end, None)
|
||||
self.assertTrue(end not in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end in assoc.ownedEnd)
|
||||
self.assertTrue(end.navigability is None)
|
||||
|
||||
UML.model.set_navigability(assoc, end, True)
|
||||
modelfactory.set_navigability(assoc, end, True)
|
||||
self.assertTrue(end in assoc.navigableOwnedEnd)
|
||||
self.assertTrue(end not in assoc.ownedEnd)
|
||||
self.assertTrue(end.navigability is True)
|
||||
@ -277,30 +297,30 @@ class DependencyTypeTestCase(TestCaseBase):
|
||||
def test_usage(self):
|
||||
"""Test automatic dependency: usage
|
||||
"""
|
||||
cls = self.factory.create(UML.Class)
|
||||
iface = self.factory.create(UML.Interface)
|
||||
dt = UML.model.dependency_type(cls, iface)
|
||||
self.assertEquals(UML.Usage, dt)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
iface = self.factory.create(uml2.Interface)
|
||||
dt = modelfactory.dependency_type(cls, iface)
|
||||
self.assertEquals(uml2.Usage, dt)
|
||||
|
||||
|
||||
def test_usage_by_component(self):
|
||||
"""Test automatic dependency: usage (by component)
|
||||
"""
|
||||
c = self.factory.create(UML.Component)
|
||||
iface = self.factory.create(UML.Interface)
|
||||
dt = UML.model.dependency_type(c, iface)
|
||||
c = self.factory.create(uml2.Component)
|
||||
iface = self.factory.create(uml2.Interface)
|
||||
dt = modelfactory.dependency_type(c, iface)
|
||||
# it should be usage not realization (interface is classifier as
|
||||
# well)
|
||||
self.assertEquals(UML.Usage, dt)
|
||||
self.assertEquals(uml2.Usage, dt)
|
||||
|
||||
|
||||
def test_realization(self):
|
||||
"""Test automatic dependency: realization
|
||||
"""
|
||||
c = self.factory.create(UML.Component)
|
||||
cls = self.factory.create(UML.Class)
|
||||
dt = UML.model.dependency_type(c, cls)
|
||||
self.assertEquals(UML.Realization, dt)
|
||||
c = self.factory.create(uml2.Component)
|
||||
cls = self.factory.create(uml2.Class)
|
||||
dt = modelfactory.dependency_type(c, cls)
|
||||
self.assertEquals(uml2.Realization, dt)
|
||||
|
||||
|
||||
class MessageTestCase(TestCaseBase):
|
||||
@ -310,11 +330,11 @@ class MessageTestCase(TestCaseBase):
|
||||
def test_create(self):
|
||||
"""Test message creation
|
||||
"""
|
||||
m = self.factory.create(UML.Message)
|
||||
send = self.factory.create(UML.MessageOccurrenceSpecification)
|
||||
receive = self.factory.create(UML.MessageOccurrenceSpecification)
|
||||
sl = self.factory.create(UML.Lifeline)
|
||||
rl = self.factory.create(UML.Lifeline)
|
||||
m = self.factory.create(uml2.Message)
|
||||
send = self.factory.create(uml2.MessageOccurrenceSpecification)
|
||||
receive = self.factory.create(uml2.MessageOccurrenceSpecification)
|
||||
sl = self.factory.create(uml2.Lifeline)
|
||||
rl = self.factory.create(uml2.Lifeline)
|
||||
|
||||
send.covered = sl
|
||||
receive.covered = rl
|
||||
@ -322,8 +342,8 @@ class MessageTestCase(TestCaseBase):
|
||||
m.sendEvent = send
|
||||
m.receiveEvent = receive
|
||||
|
||||
m1 = UML.model.create_message(self.factory, m, False)
|
||||
m2 = UML.model.create_message(self.factory, m, True)
|
||||
m1 = modelfactory.create_message(self.factory, m, False)
|
||||
m2 = modelfactory.create_message(self.factory, m, True)
|
||||
|
||||
self.assertTrue(m1.sendEvent.covered is sl)
|
||||
self.assertTrue(m1.receiveEvent.covered is rl)
|
||||
|
@ -1,5 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
import unittest
|
||||
from zope import component
|
||||
from gaphor.application import Application
|
||||
@ -85,7 +103,7 @@ class PropertiesTestCase(unittest.TestCase):
|
||||
c = C()
|
||||
try:
|
||||
a.one = c
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
pass #ok print 'exception caught:', e
|
||||
else:
|
||||
assert a.one is not c
|
||||
@ -339,7 +357,7 @@ class PropertiesTestCase(unittest.TestCase):
|
||||
import types
|
||||
class A(Element): pass
|
||||
|
||||
A.a = attribute('a', types.StringType, 'default')
|
||||
A.a = attribute('a', bytes, 'default')
|
||||
|
||||
a = A()
|
||||
assert a.a == 'default', a.a
|
||||
@ -382,7 +400,7 @@ class PropertiesTestCase(unittest.TestCase):
|
||||
self.notified = name
|
||||
|
||||
A.assoc = association('assoc', A)
|
||||
A.attr = attribute('attr', types.StringType, 'default')
|
||||
A.attr = attribute('attr', bytes, 'default')
|
||||
A.enum = enumeration('enum', ('one', 'two'), 'one')
|
||||
|
||||
a = A()
|
||||
|
@ -1,13 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2003-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import unittest
|
||||
|
||||
import gaphor.UML as UML
|
||||
from gaphor.UML import uml2, elementfactory, modelfactory, umllex
|
||||
|
||||
class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.factory = UML.ElementFactory()
|
||||
self.factory = elementfactory.ElementFactory()
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
@ -19,7 +40,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Association)
|
||||
element = self.factory.create(uml2.Association)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -27,8 +48,8 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
self.assertFalse(element.isDerived, 'The isDerived property should default to False - %s' % element.isDerived)
|
||||
|
||||
property1 = self.factory.create(UML.Property)
|
||||
property2 = self.factory.create(UML.Property)
|
||||
property1 = self.factory.create(uml2.Property)
|
||||
property2 = self.factory.create(uml2.Property)
|
||||
|
||||
element.memberEnd = property1
|
||||
element.memberEnd = property2
|
||||
@ -47,7 +68,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
# def test_association_class(self):
|
||||
# try:
|
||||
# element = self.factory.create(UML.AssociationClass)
|
||||
# element = self.factory.create(uml2.AssociationClass)
|
||||
# except AttributeError:
|
||||
# self.fail('AssociationClass elements are not part of the meta-model')
|
||||
|
||||
@ -57,14 +78,14 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Class)
|
||||
element = self.factory.create(uml2.Class)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
self.fail('Class elements are not part of the meta-model')
|
||||
|
||||
property1 = self.factory.create(UML.Property)
|
||||
operation1 = self.factory.create(UML.Operation)
|
||||
property1 = self.factory.create(uml2.Property)
|
||||
operation1 = self.factory.create(uml2.Operation)
|
||||
|
||||
element.ownedAttribute = property1
|
||||
element.ownedOperation = operation1
|
||||
@ -81,7 +102,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Comment)
|
||||
element = self.factory.create(uml2.Comment)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -91,7 +112,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
self.assertTrue(element.body == 'Comment body', 'Incorrect comment body - %s' % element.body)
|
||||
|
||||
annotatedElement = self.factory.create(UML.Class)
|
||||
annotatedElement = self.factory.create(uml2.Class)
|
||||
|
||||
element.annotatedElement = annotatedElement
|
||||
|
||||
@ -103,13 +124,13 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Constraint)
|
||||
element = self.factory.create(uml2.Constraint)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
self.fail('Constraint elements are not part of the meta-model')
|
||||
|
||||
constrainedElement = self.factory.create(UML.Class)
|
||||
constrainedElement = self.factory.create(uml2.Class)
|
||||
|
||||
element.constrainedElement = constrainedElement
|
||||
element.specification = 'Constraint specification'
|
||||
@ -123,14 +144,14 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Dependency)
|
||||
element = self.factory.create(uml2.Dependency)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
self.fail('Dependency elements are not part of the meta-model')
|
||||
|
||||
client = self.factory.create(UML.Package)
|
||||
supplier = self.factory.create(UML.Package)
|
||||
client = self.factory.create(uml2.Package)
|
||||
supplier = self.factory.create(uml2.Package)
|
||||
|
||||
element.client = client
|
||||
element.supplier = supplier
|
||||
@ -142,7 +163,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.ElementImport)
|
||||
element = self.factory.create(uml2.ElementImport)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -152,7 +173,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Enumeration)
|
||||
element = self.factory.create(uml2.Enumeration)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -162,7 +183,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Generalization)
|
||||
element = self.factory.create(uml2.Generalization)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -172,7 +193,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Interface)
|
||||
element = self.factory.create(uml2.Interface)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -182,7 +203,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Namespace)
|
||||
element = self.factory.create(uml2.Namespace)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -192,7 +213,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Operation)
|
||||
element = self.factory.create(uml2.Operation)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -202,7 +223,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Package)
|
||||
element = self.factory.create(uml2.Package)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -212,7 +233,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Parameter)
|
||||
element = self.factory.create(uml2.Parameter)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -222,7 +243,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Property)
|
||||
element = self.factory.create(uml2.Property)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -232,7 +253,7 @@ class ClassesTestCase(unittest.TestCase):
|
||||
|
||||
try:
|
||||
|
||||
element = self.factory.create(UML.Realization)
|
||||
element = self.factory.create(uml2.Realization)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
@ -242,26 +263,26 @@ class ClassesTestCase(unittest.TestCase):
|
||||
class Uml2TestCase(unittest.TestCase):
|
||||
|
||||
def test_ids(self):
|
||||
factory = UML.ElementFactory()
|
||||
c = factory.create(UML.Class)
|
||||
factory = elementfactory.ElementFactory()
|
||||
c = factory.create(uml2.Class)
|
||||
assert c.id
|
||||
p = factory.create_as(UML.Class, id=False)
|
||||
p = factory.create_as(uml2.Class, id=False)
|
||||
assert p.id is False, p.id
|
||||
|
||||
|
||||
def test1(self):
|
||||
factory = UML.ElementFactory()
|
||||
c = factory.create(UML.Class)
|
||||
p = factory.create(UML.Package)
|
||||
factory = elementfactory.ElementFactory()
|
||||
c = factory.create(uml2.Class)
|
||||
p = factory.create(uml2.Package)
|
||||
c.package = p
|
||||
self.assertEquals(c.package, p)
|
||||
self.assertEquals(c.namespace, p)
|
||||
self.failUnless(c in p.ownedElement)
|
||||
|
||||
def testOwnedMember_Unlink(self):
|
||||
factory = UML.ElementFactory()
|
||||
c = factory.create(UML.Class)
|
||||
p = factory.create(UML.Package)
|
||||
factory = elementfactory.ElementFactory()
|
||||
c = factory.create(uml2.Class)
|
||||
p = factory.create(uml2.Package)
|
||||
c.package = p
|
||||
|
||||
c.unlink()
|
||||
@ -291,7 +312,7 @@ class Uml2TestCase(unittest.TestCase):
|
||||
# # TODO: test signal handling
|
||||
|
||||
def test_property_is_composite(self):
|
||||
p = UML.Property()
|
||||
p = uml2.Property()
|
||||
assert p.isComposite == False, p.isComposite
|
||||
p.aggregation = 'shared'
|
||||
assert p.isComposite == False, p.isComposite
|
||||
@ -300,12 +321,12 @@ class Uml2TestCase(unittest.TestCase):
|
||||
|
||||
|
||||
def test_association_endType(self):
|
||||
factory = UML.ElementFactory()
|
||||
c1 = UML.Class()
|
||||
c2 = UML.Class()
|
||||
a = UML.Association()
|
||||
a.memberEnd = UML.Property()
|
||||
a.memberEnd = UML.Property()
|
||||
factory = elementfactory.ElementFactory()
|
||||
c1 = uml2.Class()
|
||||
c2 = uml2.Class()
|
||||
a = uml2.Association()
|
||||
a.memberEnd = uml2.Property()
|
||||
a.memberEnd = uml2.Property()
|
||||
a.memberEnd[0].type = c1
|
||||
a.memberEnd[1].type = c2
|
||||
c1.ownedAttribute = a.memberEnd[0]
|
||||
@ -314,7 +335,7 @@ class Uml2TestCase(unittest.TestCase):
|
||||
assert c1 in a.endType
|
||||
assert c2 in a.endType
|
||||
|
||||
c3 = UML.Class()
|
||||
c3 = uml2.Class()
|
||||
a.memberEnd[1].type = c3
|
||||
|
||||
assert c1 in a.endType
|
||||
@ -323,29 +344,29 @@ class Uml2TestCase(unittest.TestCase):
|
||||
|
||||
|
||||
def test_property_navigability(self):
|
||||
factory = UML.ElementFactory()
|
||||
p = factory.create(UML.Property)
|
||||
factory = elementfactory.ElementFactory()
|
||||
p = factory.create(uml2.Property)
|
||||
assert p.navigability is None
|
||||
|
||||
c1 = factory.create(UML.Class)
|
||||
c2 = factory.create(UML.Class)
|
||||
a = UML.model.create_association(factory, c1, c2)
|
||||
c1 = factory.create(uml2.Class)
|
||||
c2 = factory.create(uml2.Class)
|
||||
a = modelfactory.create_association(factory, c1, c2)
|
||||
assert a.memberEnd[0].navigability is None
|
||||
assert a.memberEnd[1].navigability is None
|
||||
|
||||
UML.model.set_navigability(a, a.memberEnd[0], True)
|
||||
modelfactory.set_navigability(a, a.memberEnd[0], True)
|
||||
assert a.memberEnd[0].navigability is True
|
||||
assert a.memberEnd[1].navigability is None
|
||||
|
||||
UML.model.set_navigability(a, a.memberEnd[0], False)
|
||||
modelfactory.set_navigability(a, a.memberEnd[0], False)
|
||||
assert a.memberEnd[0].navigability is False
|
||||
assert a.memberEnd[1].navigability is None
|
||||
|
||||
def test_namedelement_qualifiedname(self):
|
||||
factory = UML.ElementFactory()
|
||||
p = factory.create(UML.Package)
|
||||
factory = elementfactory.ElementFactory()
|
||||
p = factory.create(uml2.Package)
|
||||
p.name = 'Package'
|
||||
c = factory.create(UML.Class)
|
||||
c = factory.create(uml2.Class)
|
||||
c.name = 'Class'
|
||||
|
||||
self.assertEquals(('Class',), c.qualifiedName)
|
||||
@ -356,42 +377,42 @@ class Uml2TestCase(unittest.TestCase):
|
||||
|
||||
|
||||
def test_extension_metaclass(self):
|
||||
factory = UML.ElementFactory()
|
||||
c = factory.create(UML.Class)
|
||||
factory = elementfactory.ElementFactory()
|
||||
c = factory.create(uml2.Class)
|
||||
c.name = 'Class'
|
||||
s = factory.create(UML.Stereotype)
|
||||
s = factory.create(uml2.Stereotype)
|
||||
s.name = 'Stereotype'
|
||||
|
||||
e = UML.model.create_extension(factory, c, s)
|
||||
e = modelfactory.create_extension(factory, c, s)
|
||||
|
||||
self.assertEquals(c, e.metaclass)
|
||||
|
||||
def test_metaclass_extension(self):
|
||||
factory = UML.ElementFactory()
|
||||
c = factory.create(UML.Class)
|
||||
factory = elementfactory.ElementFactory()
|
||||
c = factory.create(uml2.Class)
|
||||
c.name = 'Class'
|
||||
s = factory.create(UML.Stereotype)
|
||||
s = factory.create(uml2.Stereotype)
|
||||
s.name = 'Stereotype'
|
||||
|
||||
self.assertEquals([], c.extension)
|
||||
self.assertEquals([], s.extension)
|
||||
|
||||
e = UML.model.create_extension(factory, c, s)
|
||||
e = modelfactory.create_extension(factory, c, s)
|
||||
|
||||
print e.memberEnd
|
||||
print(e.memberEnd)
|
||||
self.assertEquals([e], c.extension)
|
||||
self.assertEquals([], s.extension)
|
||||
assert e.ownedEnd.type is s
|
||||
|
||||
def test_operation_parameter_deletion(self):
|
||||
factory = UML.ElementFactory()
|
||||
factory = elementfactory.ElementFactory()
|
||||
self.assertEquals(0, len(factory.lselect()))
|
||||
|
||||
c = factory.create(UML.Class)
|
||||
c = factory.create(uml2.Class)
|
||||
c.name = 'Class'
|
||||
o = factory.create(UML.Operation)
|
||||
o = factory.create(uml2.Operation)
|
||||
c.ownedOperation = o
|
||||
UML.parse(o, 'a(x: int, y: int)')
|
||||
umllex.parse(o, 'a(x: int, y: int)')
|
||||
|
||||
c.unlink()
|
||||
|
||||
|
@ -1,7 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Formatting of UML model elements into text tests.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import unittest
|
||||
|
||||
from gaphor.application import Application
|
||||
|
@ -1,13 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Parsing of UML model elements from string tests.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import unittest
|
||||
from gaphor.application import Application
|
||||
from gaphor.UML.elementfactory import ElementFactory
|
||||
from gaphor.UML.umllex import parse
|
||||
from gaphor.UML.umllex import attribute_pat, operation_pat, parameter_pat
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.UML.umllex import parse
|
||||
|
||||
def dump_prop(prop):
|
||||
m = attribute_pat.match(prop)
|
||||
@ -55,8 +75,8 @@ class AttributeTestCase(unittest.TestCase):
|
||||
def test_parse_property_simple(self):
|
||||
"""Test simple property parsing
|
||||
"""
|
||||
a = factory.create(UML.Property)
|
||||
UML.parse(a, 'myattr')
|
||||
a = factory.create(uml2.Property)
|
||||
parse(a, 'myattr')
|
||||
self.assertFalse(a.isDerived)
|
||||
self.assertEquals('myattr', a.name)
|
||||
self.assertTrue(a.typeValue is None, a.typeValue)
|
||||
@ -68,9 +88,9 @@ class AttributeTestCase(unittest.TestCase):
|
||||
def test_parse_property_complex(self):
|
||||
"""Test complex property parsing
|
||||
"""
|
||||
a = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Property)
|
||||
|
||||
UML.parse(a,'+ / name : str[0..*] = "aap" { static }')
|
||||
parse(a,'+ / name : str[0..*] = "aap" { static }')
|
||||
self.assertEquals('public', a.visibility)
|
||||
self.assertTrue(a.isDerived)
|
||||
self.assertEquals('name', a.name)
|
||||
@ -83,9 +103,9 @@ class AttributeTestCase(unittest.TestCase):
|
||||
def test_parse_property_invalid(self):
|
||||
"""Test parsing property with invalid syntax
|
||||
"""
|
||||
a = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Property)
|
||||
|
||||
UML.parse(a, '+ name = str[*] = "aap" { static }')
|
||||
parse(a, '+ name = str[*] = "aap" { static }')
|
||||
self.assertEquals('+ name = str[*] = "aap" { static }', a.name)
|
||||
self.assertFalse(a.isDerived)
|
||||
self.assertTrue(not a.typeValue)
|
||||
@ -108,11 +128,11 @@ class AssociationEndTestCase(unittest.TestCase):
|
||||
def test_parse_association_end(self):
|
||||
"""Test parsing of association end
|
||||
"""
|
||||
a = factory.create(UML.Association)
|
||||
p = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Association)
|
||||
p = factory.create(uml2.Property)
|
||||
p.association = a
|
||||
|
||||
UML.parse(p, 'end')
|
||||
parse(p, 'end')
|
||||
self.assertEquals('end', p.name)
|
||||
self.assertTrue(not p.typeValue)
|
||||
self.assertTrue(not p.lowerValue)
|
||||
@ -123,10 +143,10 @@ class AssociationEndTestCase(unittest.TestCase):
|
||||
def test_parse_multiplicity(self):
|
||||
"""Test parsing of multiplicity
|
||||
"""
|
||||
a = factory.create(UML.Association)
|
||||
p = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Association)
|
||||
p = factory.create(uml2.Property)
|
||||
p.association = a
|
||||
UML.parse(p, '0..2 { tag }')
|
||||
parse(p, '0..2 { tag }')
|
||||
self.assertTrue(p.name is None)
|
||||
self.assertTrue(not p.typeValue)
|
||||
self.assertEquals('0', p.lowerValue)
|
||||
@ -137,10 +157,10 @@ class AssociationEndTestCase(unittest.TestCase):
|
||||
def test_parse_multiplicity2(self):
|
||||
"""Test parsing of multiplicity with multiline constraints
|
||||
"""
|
||||
a = factory.create(UML.Association)
|
||||
p = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Association)
|
||||
p = factory.create(uml2.Property)
|
||||
p.association = a
|
||||
UML.parse(p, '0..2 { tag1, \ntag2}')
|
||||
parse(p, '0..2 { tag1, \ntag2}')
|
||||
self.assertTrue(p.name is None)
|
||||
self.assertTrue(not p.typeValue)
|
||||
self.assertEquals('0', p.lowerValue)
|
||||
@ -151,10 +171,10 @@ class AssociationEndTestCase(unittest.TestCase):
|
||||
def test_parse_derived_end(self):
|
||||
"""Test parsing derived association end
|
||||
"""
|
||||
a = factory.create(UML.Association)
|
||||
p = factory.create(UML.Property)
|
||||
a = factory.create(uml2.Association)
|
||||
p = factory.create(uml2.Property)
|
||||
p.association = a
|
||||
UML.parse(p, '-/end[*] { mytag}')
|
||||
parse(p, '-/end[*] { mytag}')
|
||||
self.assertEquals('private', p.visibility)
|
||||
self.assertTrue(p.isDerived)
|
||||
self.assertEquals('end', p.name)
|
||||
@ -178,8 +198,8 @@ class OperationTestCase(unittest.TestCase):
|
||||
def test_parse_operation(self):
|
||||
"""Test parsing simple operation
|
||||
"""
|
||||
o = factory.create(UML.Operation)
|
||||
UML.parse(o, 'myfunc()')
|
||||
o = factory.create(uml2.Operation)
|
||||
parse(o, 'myfunc()')
|
||||
self.assertEquals('myfunc', o.name)
|
||||
self.assertTrue(not o.returnResult[0].typeValue)
|
||||
self.assertFalse(o.formalParameter)
|
||||
@ -188,8 +208,8 @@ class OperationTestCase(unittest.TestCase):
|
||||
def test_parse_operation_return(self):
|
||||
"""Test parsing operation with return value
|
||||
"""
|
||||
o = factory.create(UML.Operation)
|
||||
UML.parse(o, '+ myfunc(): int')
|
||||
o = factory.create(uml2.Operation)
|
||||
parse(o, '+ myfunc(): int')
|
||||
self.assertEquals('myfunc', o.name)
|
||||
self.assertEquals('int', o.returnResult[0].typeValue)
|
||||
self.assertEquals('public', o.visibility)
|
||||
@ -199,8 +219,8 @@ class OperationTestCase(unittest.TestCase):
|
||||
def test_parse_operation_2_params(self):
|
||||
"""Test parsing of operation with two parameters
|
||||
"""
|
||||
o = factory.create(UML.Operation)
|
||||
UML.parse(o, '# myfunc2 (a: str, b: int = 3 { static}): float')
|
||||
o = factory.create(uml2.Operation)
|
||||
parse(o, '# myfunc2 (a: str, b: int = 3 { static}): float')
|
||||
self.assertEquals('myfunc2', o.name)
|
||||
self.assertEquals('float', o.returnResult[0].typeValue)
|
||||
self.assertEquals('protected', o.visibility)
|
||||
@ -216,8 +236,8 @@ class OperationTestCase(unittest.TestCase):
|
||||
def test_parse_operation_1_param(self):
|
||||
"""Test parsing of operation with one parameter
|
||||
"""
|
||||
o = factory.create(UML.Operation)
|
||||
UML.parse(o, '- myfunc2 (a: node): double')
|
||||
o = factory.create(uml2.Operation)
|
||||
parse(o, '- myfunc2 (a: node): double')
|
||||
self.assertEquals('myfunc2', o.name)
|
||||
self.assertEquals('double', o.returnResult[0].typeValue)
|
||||
self.assertEquals('private', o.visibility)
|
||||
@ -230,8 +250,8 @@ class OperationTestCase(unittest.TestCase):
|
||||
def test_parse_operation_invalid_syntax(self):
|
||||
"""Test operation parsing with invalid syntax
|
||||
"""
|
||||
o = factory.create(UML.Operation)
|
||||
UML.parse(o, '- myfunc2: myType2')
|
||||
o = factory.create(uml2.Operation)
|
||||
parse(o, '- myfunc2: myType2')
|
||||
self.assertEquals('- myfunc2: myType2', o.name)
|
||||
|
||||
|
||||
|
@ -1,7 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Formatting of UML elements like attributes, operations, stereotypes, etc.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import re
|
||||
from cStringIO import StringIO
|
||||
from simplegeneric import generic
|
||||
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2003-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Lexical analizer for attributes and operations.
|
||||
|
||||
@ -7,15 +27,17 @@ The regular expressions are constructed based on a series of
|
||||
attribute/operation.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from six.moves import map
|
||||
|
||||
__all__ = [
|
||||
'parse_property', 'parse_operation',
|
||||
]
|
||||
'parse_property', 'parse_operation',
|
||||
]
|
||||
|
||||
import re
|
||||
from simplegeneric import generic
|
||||
|
||||
#from gaphor.UML import uml2 as UML
|
||||
import uml2 as UML
|
||||
from gaphor.UML.uml2 import Property, NamedElement, Operation, Parameter
|
||||
|
||||
|
||||
@generic
|
||||
@ -24,7 +46,7 @@ def parse(el, text):
|
||||
Parser for an UML element.
|
||||
"""
|
||||
raise NotImplementedError('Parsing routine for type %s not implemented yet' \
|
||||
% type(el))
|
||||
% type(el))
|
||||
|
||||
|
||||
# Visibility (optional) ::= '+' | '-' | '#'
|
||||
@ -61,16 +83,20 @@ dir_subpat = r'\s*((?P<dir>in|out|inout)\s)?'
|
||||
# Some trailing garbage => no valid syntax...
|
||||
garbage_subpat = r'\s*(?P<garbage>.*)'
|
||||
|
||||
|
||||
def compile(regex):
|
||||
return re.compile(regex, re.MULTILINE | re.S)
|
||||
|
||||
|
||||
# Attribute:
|
||||
# [+-#] [/] name [: type[\[mult\]]] [= default] [{ tagged values }]
|
||||
attribute_pat = compile(r'^' + vis_subpat + derived_subpat + name_subpat + type_subpat + default_subpat + tags_subpat + garbage_subpat)
|
||||
attribute_pat = compile(
|
||||
r'^' + vis_subpat + derived_subpat + name_subpat + type_subpat + default_subpat + tags_subpat + garbage_subpat)
|
||||
|
||||
# Association end name:
|
||||
# [[+-#] [/] name [\[mult\]]] [{ tagged values }]
|
||||
association_end_name_pat = compile(r'^' + '(' + vis_subpat + derived_subpat + name_subpat + mult_subpat + ')?' + tags_subpat + garbage_subpat)
|
||||
association_end_name_pat = compile(
|
||||
r'^' + '(' + vis_subpat + derived_subpat + name_subpat + mult_subpat + ')?' + tags_subpat + garbage_subpat)
|
||||
|
||||
# Association end multiplicity:
|
||||
# [mult] [{ tagged values }]
|
||||
@ -88,6 +114,7 @@ parameter_pat = compile(r'^' + dir_subpat + name_subpat + type_subpat + default_
|
||||
# [name] [: type]
|
||||
lifeline_pat = compile('^' + name_subpat + type_subpat + garbage_subpat)
|
||||
|
||||
|
||||
def _set_visibility(el, vis):
|
||||
if vis == '+':
|
||||
el.visibility = 'public'
|
||||
@ -103,6 +130,7 @@ def _set_visibility(el, vis):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
def parse_attribute(el, s):
|
||||
"""
|
||||
Parse string s in the property. Tagged values, multiplicity and stuff
|
||||
@ -132,8 +160,8 @@ def parse_attribute(el, s):
|
||||
el.upperValue = g('mult_u')
|
||||
el.defaultValue = g('default')
|
||||
# Skip tags: should do something with stereotypes?
|
||||
#tags = g('tags')
|
||||
#if tags:
|
||||
# tags = g('tags')
|
||||
# if tags:
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
@ -164,8 +192,8 @@ def parse_association_end(el, s):
|
||||
g = m.group
|
||||
el.lowerValue = g('mult_l')
|
||||
el.upperValue = g('mult_u')
|
||||
#tags = g('tags')
|
||||
#if tags:
|
||||
# tags = g('tags')
|
||||
# if tags:
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
@ -190,16 +218,17 @@ def parse_association_end(el, s):
|
||||
el.lowerValue = None
|
||||
el.upperValue = g('mult_u')
|
||||
|
||||
#tags = g('tags')
|
||||
#if tags:
|
||||
# while el.taggedValue:
|
||||
# el.taggedValue[0].unlink()
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
# el.taggedValue = tv
|
||||
# tags = g('tags')
|
||||
# if tags:
|
||||
# while el.taggedValue:
|
||||
# el.taggedValue[0].unlink()
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
# el.taggedValue = tv
|
||||
|
||||
@parse.when_type(UML.Property)
|
||||
|
||||
@parse.when_type(Property)
|
||||
def parse_property(el, s):
|
||||
if el.association:
|
||||
parse_association_end(el, s)
|
||||
@ -207,7 +236,7 @@ def parse_property(el, s):
|
||||
parse_attribute(el, s)
|
||||
|
||||
|
||||
@parse.when_type(UML.Operation)
|
||||
@parse.when_type(Operation)
|
||||
def parse_operation(el, s):
|
||||
"""
|
||||
Parse string s in the operation. Tagged values, parameters and
|
||||
@ -217,28 +246,28 @@ def parse_operation(el, s):
|
||||
if not m or m.group('garbage'):
|
||||
el.name = s
|
||||
del el.visibility
|
||||
map(UML.Parameter.unlink, list(el.returnResult))
|
||||
map(UML.Parameter.unlink, list(el.formalParameter))
|
||||
list(map(Parameter.unlink, list(el.returnResult)))
|
||||
list(map(Parameter.unlink, list(el.formalParameter)))
|
||||
else:
|
||||
g = m.group
|
||||
create = el._factory.create
|
||||
_set_visibility(el, g('vis'))
|
||||
el.name = g('name')
|
||||
if not el.returnResult:
|
||||
el.returnResult = create(UML.Parameter)
|
||||
el.returnResult = create(Parameter)
|
||||
p = el.returnResult[0]
|
||||
p.direction = 'return'
|
||||
p.typeValue = g('type')
|
||||
p.lowerValue = g('mult_l')
|
||||
p.upperValue = g('mult_u')
|
||||
# FIXME: Maybe add to Operation.ownedRule?
|
||||
#tags = g('tags')
|
||||
#if tags:
|
||||
# tags = g('tags')
|
||||
# if tags:
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
# p.taggedValue = tv
|
||||
|
||||
|
||||
pindex = 0
|
||||
params = g('params')
|
||||
while params:
|
||||
@ -249,15 +278,15 @@ def parse_operation(el, s):
|
||||
try:
|
||||
p = el.formalParameter[pindex]
|
||||
except IndexError:
|
||||
p = create(UML.Parameter)
|
||||
p = create(Parameter)
|
||||
p.direction = g('dir') or 'in'
|
||||
p.name = g('name')
|
||||
p.typeValue = g('type')
|
||||
p.lowerValue = g('mult_l')
|
||||
p.upperValue = g('mult_u')
|
||||
p.defaultValue = g('default')
|
||||
#tags = g('tags')
|
||||
#if tags:
|
||||
# tags = g('tags')
|
||||
# if tags:
|
||||
# for t in map(str.strip, tags.split(',')):
|
||||
# tv = create(UML.LiteralSpecification)
|
||||
# tv.value = t
|
||||
@ -272,6 +301,7 @@ def parse_operation(el, s):
|
||||
for fp in el.formalParameter[pindex:]:
|
||||
fp.unlink()
|
||||
|
||||
|
||||
def parse_lifeline(el, s):
|
||||
"""
|
||||
Parse string s in a lifeline. If a class is defined and can be found
|
||||
@ -289,9 +319,8 @@ def parse_lifeline(el, s):
|
||||
t = g('type')
|
||||
if t:
|
||||
el.name += ': ' + t
|
||||
# In the near future the data model should be extended with
|
||||
# Lifeline.represents: ConnectableElement
|
||||
|
||||
# In the near future the data model should be extended with
|
||||
# Lifeline.represents: ConnectableElement
|
||||
|
||||
|
||||
def render_lifeline(el):
|
||||
@ -300,12 +329,11 @@ def render_lifeline(el):
|
||||
return el.name
|
||||
|
||||
|
||||
@parse.when_type(UML.NamedElement)
|
||||
@parse.when_type(NamedElement)
|
||||
def parse_namedelement(el, text):
|
||||
"""
|
||||
Parse named element by simply assigning text to its name.
|
||||
"""
|
||||
el.name = text
|
||||
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,16 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""This is Gaphor, a Python+GTK based UML modelling tool.
|
||||
|
||||
# Copyright (C) 2002-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
This module allows Gaphor to be launched from the command line.
|
||||
The main() function sets up the command-line options and arguments and
|
||||
passes them to the main Application instance."""
|
||||
passes them to the main Application instance.
|
||||
"""
|
||||
|
||||
__all__ = [ 'main' ]
|
||||
from __future__ import absolute_import
|
||||
|
||||
from optparse import OptionParser
|
||||
import logging
|
||||
import pygtk
|
||||
from optparse import OptionParser
|
||||
import six.moves.builtins
|
||||
|
||||
from gaphor.application import Application
|
||||
|
||||
@ -18,6 +37,8 @@ pygtk.require('2.0')
|
||||
|
||||
LOG_FORMAT = '%(name)s %(levelname)s %(message)s'
|
||||
|
||||
__all__ = ['main']
|
||||
|
||||
|
||||
def launch(model=None):
|
||||
"""Start the main application by initiating and running Application.
|
||||
@ -44,7 +65,8 @@ def launch(model=None):
|
||||
file_manager.action_new()
|
||||
|
||||
Application.run()
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
"""Start Gaphor from the command line. This function creates an option
|
||||
parser for retrieving arguments and options from the command line. This
|
||||
@ -56,26 +78,19 @@ def main():
|
||||
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option('-p',\
|
||||
'--profiler',\
|
||||
action='store_true',\
|
||||
help='Run in profiler')
|
||||
parser.add_option('-q', "--quiet",
|
||||
dest='quiet', help='Quiet output',
|
||||
default=False, action='store_true')
|
||||
parser.add_option('-v', '--verbose',
|
||||
dest='verbose', help='Verbose output',
|
||||
default=False, action="store_true")
|
||||
|
||||
parser.add_option('-p', '--profiler', action='store_true', help='Run in profiler')
|
||||
parser.add_option('-q', "--quiet", dest='quiet', help='Quiet output', default=False, action='store_true')
|
||||
parser.add_option('-v', '--verbose', dest='verbose', help='Verbose output', default=False, action="store_true")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
|
||||
if options.verbose:
|
||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
|
||||
elif options.quiet:
|
||||
logging.basicConfig(level=logging.WARNING, format=LOG_FORMAT)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
|
||||
|
||||
|
||||
try:
|
||||
model = args[0]
|
||||
except IndexError:
|
||||
@ -86,19 +101,18 @@ def main():
|
||||
import cProfile
|
||||
import pstats
|
||||
|
||||
cProfile.run('import gaphor; gaphor.launch()',\
|
||||
'gaphor.prof')
|
||||
|
||||
cProfile.run('import gaphor; gaphor.launch()', 'gaphor.prof')
|
||||
|
||||
profile_stats = pstats.Stats('gaphor.prof')
|
||||
profile_stats.strip_dirs().sort_stats('time').print_stats(50)
|
||||
|
||||
else:
|
||||
|
||||
|
||||
launch(model)
|
||||
|
||||
# TODO: Remove this.
|
||||
import __builtin__
|
||||
|
||||
__builtin__.__dict__['log'] = logging.getLogger('Gaphor')
|
||||
# TODO: Remove this.
|
||||
|
||||
six.moves.builtins.__dict__['log'] = logging.getLogger('Gaphor')
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,12 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Support for actions in generic files.
|
||||
|
||||
See also gaphor/service/actionmanager.py for the management module.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
from .application import Application
|
||||
from gaphor.application import Application
|
||||
|
||||
|
||||
class action(object):
|
||||
@ -17,7 +36,7 @@ class action(object):
|
||||
>>> class A(object):
|
||||
... @action(name="my_action", label="my action")
|
||||
... def myaction(self):
|
||||
... print 'action called'
|
||||
... print('action called')
|
||||
>>> a = A()
|
||||
>>> a.myaction()
|
||||
action called
|
||||
@ -25,7 +44,7 @@ class action(object):
|
||||
True
|
||||
>>> for method in dir(A):
|
||||
... if is_action(getattr(A, method)):
|
||||
... print method
|
||||
... print(method)
|
||||
myaction
|
||||
>>> A.myaction.__action__.name
|
||||
'my_action'
|
||||
@ -44,13 +63,14 @@ class action(object):
|
||||
def __call__(self, func):
|
||||
func.__action__ = self
|
||||
return func
|
||||
|
||||
|
||||
|
||||
class toggle_action(action):
|
||||
"""
|
||||
A toggle button can be switched on and off.
|
||||
An extra 'active' attribute is provided than gives the initial status.
|
||||
"""
|
||||
|
||||
def __init__(self, name, label=None, tooltip=None, stock_id=None, accel=None, active=False):
|
||||
super(toggle_action, self).__init__(name, label, tooltip, stock_id, accel=accel, active=active)
|
||||
|
||||
@ -62,8 +82,10 @@ class radio_action(action):
|
||||
The callback function should have an extra value property, which is
|
||||
given the index number of the activated radio button action.
|
||||
"""
|
||||
|
||||
def __init__(self, names, labels=None, tooltips=None, stock_ids=None, accels=None, active=0):
|
||||
super(radio_action, self).__init__(names[0], names=names, labels=labels, tooltips=tooltips, stock_ids=stock_ids, accels=accels, active=active)
|
||||
super(radio_action, self).__init__(names[0], names=names, labels=labels, tooltips=tooltips, stock_ids=stock_ids,
|
||||
accels=accels, active=active)
|
||||
|
||||
|
||||
def open_action(name, label=None, tooltip=None, stock_id=None, accel=None, **kwargs):
|
||||
@ -73,7 +95,7 @@ def open_action(name, label=None, tooltip=None, stock_id=None, accel=None, **kwa
|
||||
>>> class A(object):
|
||||
... @open_action(name="my_action", label="my action")
|
||||
... def myaction(self):
|
||||
... print 'action called'
|
||||
... print('action called')
|
||||
>>> a = A()
|
||||
>>> a.myaction()
|
||||
action called
|
||||
@ -81,7 +103,7 @@ def open_action(name, label=None, tooltip=None, stock_id=None, accel=None, **kwa
|
||||
True
|
||||
>>> for method in dir(A):
|
||||
... if is_action(getattr(A, method)):
|
||||
... print method
|
||||
... print(method)
|
||||
myaction
|
||||
>>> A.myaction.__action__.name
|
||||
'my_action'
|
||||
@ -104,12 +126,12 @@ def build_action_group(obj, name=None):
|
||||
|
||||
>>> class A(object):
|
||||
... @action(name='bar')
|
||||
... def bar(self): print 'Say bar'
|
||||
... def bar(self): print('Say bar')
|
||||
... @toggle_action(name='foo')
|
||||
... def foo(self, active): print 'Say foo', active
|
||||
... def foo(self, active): print('Say foo', active)
|
||||
... @radio_action(names=('baz', 'beer'), labels=('Baz', 'Beer'))
|
||||
... def baz(self, value):
|
||||
... print 'Say', value, (value and 'beer' or 'baz')
|
||||
... print('Say', value, (value and "beer" or "baz"))
|
||||
>>> group = build_action_group(A())
|
||||
Say 0 baz
|
||||
>>> len(group.list_actions())
|
||||
@ -141,10 +163,14 @@ def build_action_group(obj, name=None):
|
||||
act = getattr(method, '__action__', None)
|
||||
if isinstance(act, radio_action):
|
||||
actgroup = None
|
||||
if not act.labels: act.labels = [None] * len(act.names)
|
||||
if not act.tooltips: act.tooltips = [None] * len(act.names)
|
||||
if not act.stock_ids: act.stock_ids = [None] * len(act.names)
|
||||
if not act.accels: act.accels = [None] * len(act.names)
|
||||
if not act.labels:
|
||||
act.labels = [None] * len(act.names)
|
||||
if not act.tooltips:
|
||||
act.tooltips = [None] * len(act.names)
|
||||
if not act.stock_ids:
|
||||
act.stock_ids = [None] * len(act.names)
|
||||
if not act.accels:
|
||||
act.accels = [None] * len(act.names)
|
||||
assert len(act.names) == len(act.labels)
|
||||
assert len(act.names) == len(act.tooltips)
|
||||
assert len(act.names) == len(act.stock_ids)
|
||||
@ -173,12 +199,12 @@ def build_action_group(obj, name=None):
|
||||
activate = act.opening and _action_opening or _action_activate
|
||||
except AttributeError:
|
||||
activate = _action_activate
|
||||
|
||||
|
||||
gtkact.connect('activate', activate, obj, attrname)
|
||||
group.add_action_with_accel(gtkact, act.accel)
|
||||
|
||||
elif act is not None:
|
||||
raise TypeError, 'Invalid action type: %s' % action
|
||||
raise TypeError('Invalid action type: %s' % action)
|
||||
return group
|
||||
|
||||
|
||||
@ -210,6 +236,7 @@ def _radio_action_changed(action, current_action, obj, name):
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,4 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
import gaphor.adapters.connectors
|
||||
import gaphor.adapters.editors
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,10 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Flow item adapter connections.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.adapters.connectors import UnaryRelationshipConnect, RelationshipConnect
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
from gaphor.diagram.interfaces import IConnect
|
||||
|
||||
@ -18,8 +39,8 @@ class FlowConnect(UnaryRelationshipConnect):
|
||||
line = self.line
|
||||
subject = self.element.subject
|
||||
|
||||
if handle is line.head and isinstance(subject, UML.FinalNode) \
|
||||
or handle is line.tail and isinstance(subject, UML.InitialNode):
|
||||
if handle is line.head and isinstance(subject, uml2.FinalNode) \
|
||||
or handle is line.tail and isinstance(subject, uml2.InitialNode):
|
||||
return None
|
||||
|
||||
return super(FlowConnect, self).allow(handle, port)
|
||||
@ -51,13 +72,13 @@ class FlowConnect(UnaryRelationshipConnect):
|
||||
c1 = self.get_connected(line.head)
|
||||
c2 = self.get_connected(line.tail)
|
||||
if isinstance(c1, items.ObjectNodeItem) or isinstance(c2, items.ObjectNodeItem):
|
||||
relation = self.relationship_or_new(UML.ObjectFlow,
|
||||
UML.ObjectFlow.source,
|
||||
UML.ObjectFlow.target)
|
||||
relation = self.relationship_or_new(uml2.ObjectFlow,
|
||||
uml2.ObjectFlow.source,
|
||||
uml2.ObjectFlow.target)
|
||||
else:
|
||||
relation = self.relationship_or_new(UML.ControlFlow,
|
||||
UML.ControlFlow.source,
|
||||
UML.ControlFlow.target)
|
||||
relation = self.relationship_or_new(uml2.ControlFlow,
|
||||
uml2.ControlFlow.source,
|
||||
uml2.ControlFlow.target)
|
||||
line.subject = relation
|
||||
opposite = line.opposite(handle)
|
||||
otc = self.get_connected(opposite)
|
||||
@ -125,10 +146,10 @@ class FlowForkDecisionNodeConnect(FlowConnect):
|
||||
join_node = subject
|
||||
|
||||
# determine flow class:
|
||||
if [ f for f in join_node.incoming if isinstance(f, UML.ObjectFlow) ]:
|
||||
flow_class = UML.ObjectFlow
|
||||
if [ f for f in join_node.incoming if isinstance(f, uml2.ObjectFlow) ]:
|
||||
flow_class = uml2.ObjectFlow
|
||||
else:
|
||||
flow_class = UML.ControlFlow
|
||||
flow_class = uml2.ControlFlow
|
||||
|
||||
self.element_factory.swap_element(join_node, join_node_cls)
|
||||
fork_node = self.element_factory.create(fork_node_cls)
|
||||
@ -194,8 +215,8 @@ class FlowForkNodeConnect(FlowForkDecisionNodeConnect):
|
||||
"""
|
||||
component.adapts(items.ForkNodeItem, items.FlowItem)
|
||||
|
||||
fork_node_cls=UML.ForkNode
|
||||
join_node_cls=UML.JoinNode
|
||||
fork_node_cls=uml2.ForkNode
|
||||
join_node_cls=uml2.JoinNode
|
||||
|
||||
component.provideAdapter(FlowForkNodeConnect)
|
||||
|
||||
@ -206,8 +227,8 @@ class FlowDecisionNodeConnect(FlowForkDecisionNodeConnect):
|
||||
"""
|
||||
component.adapts(items.DecisionNodeItem, items.FlowItem)
|
||||
|
||||
fork_node_cls = UML.DecisionNode
|
||||
join_node_cls = UML.MergeNode
|
||||
fork_node_cls = uml2.DecisionNode
|
||||
join_node_cls = uml2.MergeNode
|
||||
|
||||
component.provideAdapter(FlowDecisionNodeConnect)
|
||||
|
||||
|
@ -1,12 +1,32 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Activity partition property page.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import gtk
|
||||
from gaphor.core import _, inject, transactional
|
||||
from gaphor.ui.interfaces import IPropertyPage
|
||||
from gaphor.diagram import items
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.adapters.propertypages import NamedItemPropertyPage
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,9 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Flow item connection adapters tests.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
|
||||
class FlowItemBasicNodesConnectionTestCase(TestCase):
|
||||
@ -14,7 +35,7 @@ class FlowItemBasicNodesConnectionTestCase(TestCase):
|
||||
"""Test flow item glueing to initial node item
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
node = self.create(items.InitialNodeItem, UML.InitialNode)
|
||||
node = self.create(items.InitialNodeItem, uml2.InitialNode)
|
||||
|
||||
# tail may not connect to initial node item
|
||||
allowed = self.allow(flow, flow.tail, node)
|
||||
@ -28,7 +49,7 @@ class FlowItemBasicNodesConnectionTestCase(TestCase):
|
||||
"""Test flow item glueing to flow final node item
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
node = self.create(items.FlowFinalNodeItem, UML.FlowFinalNode)
|
||||
node = self.create(items.FlowFinalNodeItem, uml2.FlowFinalNode)
|
||||
|
||||
# head may not connect to flow final node item
|
||||
allowed = self.allow(flow, flow.head, node)
|
||||
@ -42,7 +63,7 @@ class FlowItemBasicNodesConnectionTestCase(TestCase):
|
||||
"""Test flow item glueing to activity final node item
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
node = self.create(items.ActivityFinalNodeItem, UML.ActivityFinalNode)
|
||||
node = self.create(items.ActivityFinalNodeItem, uml2.ActivityFinalNode)
|
||||
|
||||
# head may not connect to activity final node item
|
||||
glued = self.allow(flow, flow.head, node)
|
||||
@ -60,7 +81,7 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
"""Test glueing to object node
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
onode = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
onode = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
glued = self.allow(flow, flow.head, onode)
|
||||
self.assertTrue(glued)
|
||||
|
||||
@ -69,13 +90,13 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
"""Test connection to object node
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
anode = self.create(items.ActionItem, UML.Action)
|
||||
onode = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
anode = self.create(items.ActionItem, uml2.Action)
|
||||
onode = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
|
||||
self.connect(flow, flow.head, anode)
|
||||
self.connect(flow, flow.tail, onode)
|
||||
self.assertTrue(flow.subject)
|
||||
self.assertTrue(isinstance(flow.subject, UML.ObjectFlow))
|
||||
self.assertTrue(isinstance(flow.subject, uml2.ObjectFlow))
|
||||
|
||||
self.disconnect(flow, flow.head)
|
||||
self.disconnect(flow, flow.tail)
|
||||
@ -84,16 +105,16 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
self.connect(flow, flow.head, onode)
|
||||
self.connect(flow, flow.tail, anode)
|
||||
self.assertTrue(flow.subject)
|
||||
self.assertTrue(isinstance(flow.subject, UML.ObjectFlow))
|
||||
self.assertTrue(isinstance(flow.subject, uml2.ObjectFlow))
|
||||
|
||||
|
||||
def test_reconnection(self):
|
||||
"""Test object flow reconnection
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
o2 = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
o2 = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
|
||||
# connect: a1 -> o1
|
||||
self.connect(flow, flow.head, a1)
|
||||
@ -115,7 +136,7 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
self.assertEquals(1, len(o2.subject.incoming))
|
||||
self.assertEquals(0, len(o2.subject.outgoing))
|
||||
|
||||
self.assertEquals(1, len(self.kindof(UML.ObjectFlow)))
|
||||
self.assertEquals(1, len(self.kindof(uml2.ObjectFlow)))
|
||||
# one guard
|
||||
self.assertEquals('tname', flow.subject.name)
|
||||
self.assertEquals('tguard', flow.subject.guard)
|
||||
@ -125,9 +146,9 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
"""Test control flow becoming object flow due to reconnection
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
|
||||
# connect with control flow: a1 -> a2
|
||||
self.connect(flow, flow.head, a1)
|
||||
@ -149,8 +170,8 @@ class FlowItemObjectNodeTestCase(TestCase):
|
||||
self.assertEquals(1, len(o1.subject.incoming))
|
||||
self.assertEquals(0, len(o1.subject.outgoing))
|
||||
|
||||
self.assertEquals(0, len(self.kindof(UML.ControlFlow)))
|
||||
self.assertEquals(1, len(self.kindof(UML.ObjectFlow)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.ControlFlow)))
|
||||
self.assertEquals(1, len(self.kindof(uml2.ObjectFlow)))
|
||||
# one guard, not changed
|
||||
self.assertEquals('tname', flow.subject.name)
|
||||
self.assertEquals('tguard', flow.subject.guard)
|
||||
@ -165,8 +186,8 @@ class FlowItemActionTestCase(TestCase):
|
||||
"""Test flow item glueing to action items
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
|
||||
glued = self.allow(flow, flow.head, a1)
|
||||
self.assertTrue(glued)
|
||||
@ -181,13 +202,13 @@ class FlowItemActionTestCase(TestCase):
|
||||
"""Test flow item connecting to action items
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
|
||||
self.connect(flow, flow.head, a1)
|
||||
self.connect(flow, flow.tail, a2)
|
||||
|
||||
self.assertTrue(isinstance(flow.subject, UML.ControlFlow))
|
||||
self.assertTrue(isinstance(flow.subject, uml2.ControlFlow))
|
||||
|
||||
self.assertEquals(0, len(a1.subject.incoming))
|
||||
self.assertEquals(1, len(a2.subject.incoming))
|
||||
@ -204,8 +225,8 @@ class FlowItemActionTestCase(TestCase):
|
||||
"""Test flow item disconnection from action items
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
|
||||
self.connect(flow, flow.head, a1)
|
||||
self.connect(flow, flow.tail, a2)
|
||||
@ -222,9 +243,9 @@ class FlowItemActionTestCase(TestCase):
|
||||
"""Test flow item reconnection
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a3 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
a3 = self.create(items.ActionItem, uml2.Action)
|
||||
|
||||
# a1 -> a2
|
||||
self.connect(flow, flow.head, a1)
|
||||
@ -245,7 +266,7 @@ class FlowItemActionTestCase(TestCase):
|
||||
self.assertEquals(1, len(a3.subject.incoming))
|
||||
self.assertEquals(0, len(a3.subject.outgoing))
|
||||
|
||||
self.assertEquals(1, len(self.kindof(UML.ControlFlow)))
|
||||
self.assertEquals(1, len(self.kindof(uml2.ControlFlow)))
|
||||
# one guard
|
||||
self.assertEquals('tname', flow.subject.name)
|
||||
self.assertEquals('tguard', flow.subject.guard)
|
||||
@ -255,9 +276,9 @@ class FlowItemActionTestCase(TestCase):
|
||||
"""Test object flow becoming control flow due to reconnection
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, UML.ObjectNode)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
o1 = self.create(items.ObjectNodeItem, uml2.ObjectNode)
|
||||
|
||||
# connect with control flow: a1 -> o1
|
||||
self.connect(flow, flow.head, a1)
|
||||
@ -279,8 +300,8 @@ class FlowItemActionTestCase(TestCase):
|
||||
self.assertEquals(1, len(a2.subject.incoming))
|
||||
self.assertEquals(0, len(a2.subject.outgoing))
|
||||
|
||||
self.assertEquals(1, len(self.kindof(UML.ControlFlow)))
|
||||
self.assertEquals(0, len(self.kindof(UML.ObjectFlow)))
|
||||
self.assertEquals(1, len(self.kindof(uml2.ControlFlow)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.ObjectFlow)))
|
||||
# one guard, not changed
|
||||
self.assertEquals('tname', flow.subject.name)
|
||||
self.assertEquals('tguard', flow.subject.guard)
|
||||
@ -309,7 +330,7 @@ class FlowItemDesisionAndForkNodes:
|
||||
"""Test decision/fork nodes glue
|
||||
"""
|
||||
flow = self.create(items.FlowItem)
|
||||
action = self.create(items.ActionItem, UML.Action)
|
||||
action = self.create(items.ActionItem, uml2.Action)
|
||||
node = self.create(self.item_cls, self.join_node_cls)
|
||||
|
||||
glued = self.allow(flow, flow.head, node)
|
||||
@ -336,9 +357,9 @@ class FlowItemDesisionAndForkNodes:
|
||||
flow1 = self.create(items.FlowItem)
|
||||
flow2 = self.create(items.FlowItem)
|
||||
flow3 = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a3 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
a3 = self.create(items.ActionItem, uml2.Action)
|
||||
jn = self.create(self.item_cls, self.fork_node_cls)
|
||||
|
||||
assert type(jn.subject) is self.fork_node_cls
|
||||
@ -370,9 +391,9 @@ class FlowItemDesisionAndForkNodes:
|
||||
flow1 = self.create(items.FlowItem)
|
||||
flow2 = self.create(items.FlowItem)
|
||||
flow3 = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a3 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
a3 = self.create(items.ActionItem, uml2.Action)
|
||||
jn = self.create(self.item_cls, self.join_node_cls)
|
||||
|
||||
# connect actions first
|
||||
@ -414,10 +435,10 @@ class FlowItemDesisionAndForkNodes:
|
||||
flow2 = self.create(items.FlowItem)
|
||||
flow3 = self.create(items.FlowItem)
|
||||
flow4 = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a3 = self.create(items.ActionItem, UML.Action)
|
||||
a4 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
a3 = self.create(items.ActionItem, uml2.Action)
|
||||
a4 = self.create(items.ActionItem, uml2.Action)
|
||||
jn = self.create(self.item_cls, self.join_node_cls)
|
||||
|
||||
# connect actions first
|
||||
@ -458,10 +479,10 @@ class FlowItemDesisionAndForkNodes:
|
||||
flow2 = self.create(items.FlowItem)
|
||||
flow3 = self.create(items.FlowItem)
|
||||
flow4 = self.create(items.FlowItem)
|
||||
a1 = self.create(items.ActionItem, UML.Action)
|
||||
a2 = self.create(items.ActionItem, UML.Action)
|
||||
a3 = self.create(items.ActionItem, UML.Action)
|
||||
a4 = self.create(items.ActionItem, UML.Action)
|
||||
a1 = self.create(items.ActionItem, uml2.Action)
|
||||
a2 = self.create(items.ActionItem, uml2.Action)
|
||||
a3 = self.create(items.ActionItem, uml2.Action)
|
||||
a4 = self.create(items.ActionItem, uml2.Action)
|
||||
jn = self.create(self.item_cls, self.join_node_cls)
|
||||
|
||||
# connect actions first
|
||||
@ -479,7 +500,7 @@ class FlowItemDesisionAndForkNodes:
|
||||
# needed for tests below
|
||||
cflow = jn.subject.outgoing[0]
|
||||
cnode = jn.combined
|
||||
assert cflow in self.kindof(UML.ControlFlow)
|
||||
assert cflow in self.kindof(uml2.ControlFlow)
|
||||
assert cnode in self.kindof(self.fork_node_cls)
|
||||
|
||||
# test disconnection
|
||||
@ -487,7 +508,7 @@ class FlowItemDesisionAndForkNodes:
|
||||
assert self.get_connected(flow4.head) is None
|
||||
self.assertTrue(jn.combined is None)
|
||||
|
||||
flows = self.kindof(UML.ControlFlow)
|
||||
flows = self.kindof(uml2.ControlFlow)
|
||||
nodes = self.kindof(self.fork_node_cls)
|
||||
self.assertTrue(cnode not in nodes, '%s in %s' % (cnode, nodes))
|
||||
self.assertTrue(cflow not in flows, '%s in %s' % (cflow, flows))
|
||||
@ -496,15 +517,15 @@ class FlowItemDesisionAndForkNodes:
|
||||
|
||||
class FlowItemForkNodeTestCase(FlowItemDesisionAndForkNodes, TestCase):
|
||||
item_cls = items.ForkNodeItem
|
||||
fork_node_cls = UML.ForkNode
|
||||
join_node_cls = UML.JoinNode
|
||||
fork_node_cls = uml2.ForkNode
|
||||
join_node_cls = uml2.JoinNode
|
||||
|
||||
|
||||
|
||||
class FlowItemDecisionNodeTestCase(FlowItemDesisionAndForkNodes, TestCase):
|
||||
item_cls = items.DecisionNodeItem
|
||||
fork_node_cls = UML.DecisionNode
|
||||
join_node_cls = UML.MergeNode
|
||||
fork_node_cls = uml2.DecisionNode
|
||||
join_node_cls = uml2.MergeNode
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,12 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Classes related (dependency, implementation) adapter connections.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
from zope import component
|
||||
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
from gaphor.adapters.connectors import UnaryRelationshipConnect, RelationshipConnect
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.diagram import items
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class DependencyConnect(RelationshipConnect):
|
||||
"""
|
||||
Connect two NamedItem elements using a Dependency
|
||||
@ -19,12 +45,11 @@ class DependencyConnect(RelationshipConnect):
|
||||
|
||||
# Element should be a NamedElement
|
||||
if not element.subject or \
|
||||
not isinstance(element.subject, UML.NamedElement):
|
||||
return False
|
||||
not isinstance(element.subject, uml2.NamedElement):
|
||||
return False
|
||||
|
||||
return super(DependencyConnect, self).allow(handle, port)
|
||||
|
||||
|
||||
def reconnect(self, handle, port):
|
||||
line = self.line
|
||||
dep = line.subject
|
||||
@ -36,7 +61,6 @@ class DependencyConnect(RelationshipConnect):
|
||||
del dep.client[c]
|
||||
self.reconnect_relationship(handle, line.dependency_type.supplier, line.dependency_type.client)
|
||||
|
||||
|
||||
def connect_subject(self, handle):
|
||||
"""
|
||||
TODO: cleck for existing relationships (use self.relation())
|
||||
@ -53,13 +77,14 @@ class DependencyConnect(RelationshipConnect):
|
||||
else:
|
||||
client = self.element.subject
|
||||
supplier = self.get_connected(opposite).subject
|
||||
line.dependency_type = UML.model.dependency_type(client, supplier)
|
||||
line.dependency_type = modelfactory.dependency_type(client, supplier)
|
||||
|
||||
relation = self.relationship_or_new(line.dependency_type,
|
||||
line.dependency_type.supplier,
|
||||
line.dependency_type.client)
|
||||
line.dependency_type.supplier,
|
||||
line.dependency_type.client)
|
||||
line.subject = relation
|
||||
|
||||
|
||||
component.provideAdapter(DependencyConnect)
|
||||
|
||||
|
||||
@ -70,21 +95,19 @@ class GeneralizationConnect(RelationshipConnect):
|
||||
# FixMe: Both ends of the generalization should be of the same type?
|
||||
component.adapts(items.ClassifierItem, items.GeneralizationItem)
|
||||
|
||||
|
||||
def reconnect(self, handle, port):
|
||||
self.reconnect_relationship(handle, UML.Generalization.general, UML.Generalization.specific)
|
||||
|
||||
self.reconnect_relationship(handle, uml2.Generalization.general, uml2.Generalization.specific)
|
||||
|
||||
def connect_subject(self, handle):
|
||||
log.debug('connect_subject: ' % handle)
|
||||
relation = self.relationship_or_new(UML.Generalization,
|
||||
UML.Generalization.general,
|
||||
UML.Generalization.specific)
|
||||
log.debug('found: ' % relation)
|
||||
log.debug('connect_subject: %s' % handle)
|
||||
relation = self.relationship_or_new(uml2.Generalization,
|
||||
uml2.Generalization.general,
|
||||
uml2.Generalization.specific)
|
||||
log.debug('found: %s' % relation)
|
||||
self.line.subject = relation
|
||||
|
||||
component.provideAdapter(GeneralizationConnect)
|
||||
|
||||
component.provideAdapter(GeneralizationConnect)
|
||||
|
||||
|
||||
class AssociationConnect(UnaryRelationshipConnect):
|
||||
@ -97,7 +120,7 @@ class AssociationConnect(UnaryRelationshipConnect):
|
||||
element = self.element
|
||||
|
||||
# Element should be a Classifier
|
||||
if not isinstance(element.subject, UML.Classifier):
|
||||
if not isinstance(element.subject, uml2.Classifier):
|
||||
return None
|
||||
|
||||
return super(AssociationConnect, self).allow(handle, port)
|
||||
@ -117,11 +140,11 @@ class AssociationConnect(UnaryRelationshipConnect):
|
||||
end1 = line.subject.memberEnd[0]
|
||||
end2 = line.subject.memberEnd[1]
|
||||
if (end1.type is head_type and end2.type is tail_type) \
|
||||
or (end2.type is head_type and end1.type is tail_type):
|
||||
or (end2.type is head_type and end1.type is tail_type):
|
||||
return
|
||||
|
||||
|
||||
# Create new association
|
||||
relation = UML.model.create_association(self.element_factory, head_type, tail_type)
|
||||
relation = modelfactory.create_association(self.element_factory, head_type, tail_type)
|
||||
relation.package = element.canvas.diagram.namespace
|
||||
|
||||
line.head_end.subject = relation.memberEnd[0]
|
||||
@ -144,11 +167,10 @@ class AssociationConnect(UnaryRelationshipConnect):
|
||||
|
||||
nav = oend.subject.navigability
|
||||
|
||||
UML.model.set_navigability(line.subject, end.subject, None) # clear old data
|
||||
modelfactory.set_navigability(line.subject, end.subject, None) # clear old data
|
||||
|
||||
oend.subject.type = c.subject
|
||||
UML.model.set_navigability(line.subject, oend.subject, nav)
|
||||
|
||||
modelfactory.set_navigability(line.subject, oend.subject, nav)
|
||||
|
||||
def disconnect_subject(self, handle):
|
||||
"""
|
||||
@ -173,31 +195,28 @@ class AssociationConnect(UnaryRelationshipConnect):
|
||||
component.provideAdapter(AssociationConnect)
|
||||
|
||||
|
||||
|
||||
class ImplementationConnect(RelationshipConnect):
|
||||
"""
|
||||
Connect Interface and a BehavioredClassifier using an Implementation.
|
||||
"""
|
||||
component.adapts(items.NamedItem, items.ImplementationItem)
|
||||
|
||||
|
||||
def allow(self, handle, port):
|
||||
line = self.line
|
||||
element = self.element
|
||||
|
||||
# Element at the head should be an Interface
|
||||
if handle is line.head and \
|
||||
not isinstance(element.subject, UML.Interface):
|
||||
not isinstance(element.subject, uml2.Interface):
|
||||
return None
|
||||
|
||||
# Element at the tail should be a BehavioredClassifier
|
||||
if handle is line.tail and \
|
||||
not isinstance(element.subject, UML.BehavioredClassifier):
|
||||
not isinstance(element.subject, uml2.BehavioredClassifier):
|
||||
return None
|
||||
|
||||
return super(ImplementationConnect, self).allow(handle, port)
|
||||
|
||||
|
||||
def reconnect(self, handle, port):
|
||||
line = self.line
|
||||
impl = line.subject
|
||||
@ -207,16 +226,15 @@ class ImplementationConnect(RelationshipConnect):
|
||||
elif handle is line.tail:
|
||||
for c in impl.implementatingClassifier:
|
||||
del impl.implementatingClassifier[c]
|
||||
self.reconnect_relationship(handle, UML.Implementation.contract, UML.Implementation.implementatingClassifier)
|
||||
|
||||
self.reconnect_relationship(handle, uml2.Implementation.contract, uml2.Implementation.implementatingClassifier)
|
||||
|
||||
def connect_subject(self, handle):
|
||||
"""
|
||||
Perform implementation relationship connection.
|
||||
"""
|
||||
relation = self.relationship_or_new(UML.Implementation,
|
||||
UML.Implementation.contract,
|
||||
UML.Implementation.implementatingClassifier)
|
||||
relation = self.relationship_or_new(uml2.Implementation,
|
||||
uml2.Implementation.contract,
|
||||
uml2.Implementation.implementatingClassifier)
|
||||
self.line.subject = relation
|
||||
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Interface item related connections.
|
||||
|
||||
@ -6,9 +26,8 @@ to folded interface, see `gaphor.diagram.classes.interface` documentation
|
||||
for details.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from zope import interface, component
|
||||
|
||||
from gaphor import UML
|
||||
from gaphor.diagram import items
|
||||
from gaphor.adapters.classes.classconnect import DependencyConnect, ImplementationConnect
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,20 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Classes related adapter connection tests.
|
||||
"""
|
||||
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor import UML
|
||||
from __future__ import absolute_import
|
||||
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
from gaphor.diagram import items
|
||||
from gaphor.tests import TestCase
|
||||
|
||||
|
||||
class DependencyTestCase(TestCase):
|
||||
"""
|
||||
Dependency item connection adapter tests.
|
||||
"""
|
||||
|
||||
def test_dependency_glue(self):
|
||||
"""Test dependency glue to two actor items
|
||||
"""
|
||||
actor1 = self.create(items.ActorItem, UML.Actor)
|
||||
actor2 = self.create(items.ActorItem, UML.Actor)
|
||||
actor1 = self.create(items.ActorItem, uml2.Actor)
|
||||
actor2 = self.create(items.ActorItem, uml2.Actor)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
glued = self.allow(dep, dep.head, actor1)
|
||||
@ -25,19 +49,18 @@ class DependencyTestCase(TestCase):
|
||||
glued = self.allow(dep, dep.tail, actor2)
|
||||
self.assertTrue(glued)
|
||||
|
||||
|
||||
def test_dependency_connect(self):
|
||||
"""Test dependency connecting to two actor items
|
||||
"""
|
||||
actor1 = self.create(items.ActorItem, UML.Actor)
|
||||
actor2 = self.create(items.ActorItem, UML.Actor)
|
||||
actor1 = self.create(items.ActorItem, uml2.Actor)
|
||||
actor2 = self.create(items.ActorItem, uml2.Actor)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
self.connect(dep, dep.head, actor1)
|
||||
self.connect(dep, dep.tail, actor2)
|
||||
|
||||
self.assertTrue(dep.subject is not None)
|
||||
self.assertTrue(isinstance(dep.subject, UML.Dependency))
|
||||
self.assertTrue(isinstance(dep.subject, uml2.Dependency))
|
||||
self.assertTrue(dep.subject in self.element_factory.select())
|
||||
|
||||
hct = self.get_connected(dep.head)
|
||||
@ -48,13 +71,12 @@ class DependencyTestCase(TestCase):
|
||||
self.assertTrue(actor1.subject in dep.subject.supplier)
|
||||
self.assertTrue(actor2.subject in dep.subject.client)
|
||||
|
||||
|
||||
def test_dependency_reconnection(self):
|
||||
"""Test dependency reconnection
|
||||
"""
|
||||
a1 = self.create(items.ActorItem, UML.Actor)
|
||||
a2 = self.create(items.ActorItem, UML.Actor)
|
||||
a3 = self.create(items.ActorItem, UML.Actor)
|
||||
a1 = self.create(items.ActorItem, uml2.Actor)
|
||||
a2 = self.create(items.ActorItem, uml2.Actor)
|
||||
a3 = self.create(items.ActorItem, uml2.Actor)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
# connect: a1 -> a2
|
||||
@ -73,12 +95,11 @@ class DependencyTestCase(TestCase):
|
||||
self.assertTrue(a3.subject in dep.subject.client)
|
||||
self.assertTrue(a2.subject not in dep.subject.client, dep.subject.client)
|
||||
|
||||
|
||||
def test_dependency_disconnect(self):
|
||||
"""Test dependency disconnecting using two actor items
|
||||
"""
|
||||
actor1 = self.create(items.ActorItem, UML.Actor)
|
||||
actor2 = self.create(items.ActorItem, UML.Actor)
|
||||
actor1 = self.create(items.ActorItem, uml2.Actor)
|
||||
actor2 = self.create(items.ActorItem, uml2.Actor)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
self.connect(dep, dep.head, actor1)
|
||||
@ -93,12 +114,11 @@ class DependencyTestCase(TestCase):
|
||||
self.assertTrue(dep_subj not in actor1.subject.supplierDependency)
|
||||
self.assertTrue(dep_subj not in actor2.subject.clientDependency)
|
||||
|
||||
|
||||
def test_dependency_reconnect(self):
|
||||
"""Test dependency reconnection using two actor items
|
||||
"""
|
||||
actor1 = self.create(items.ActorItem, UML.Actor)
|
||||
actor2 = self.create(items.ActorItem, UML.Actor)
|
||||
actor1 = self.create(items.ActorItem, uml2.Actor)
|
||||
actor2 = self.create(items.ActorItem, uml2.Actor)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
self.connect(dep, dep.head, actor1)
|
||||
@ -111,25 +131,24 @@ class DependencyTestCase(TestCase):
|
||||
self.connect(dep, dep.tail, actor2)
|
||||
|
||||
self.assertTrue(dep.subject is not None)
|
||||
self.assertTrue(dep.subject is not dep_subj) # the old subject has been deleted
|
||||
self.assertTrue(dep.subject is not dep_subj) # the old subject has been deleted
|
||||
self.assertTrue(dep.subject in actor1.subject.supplierDependency)
|
||||
self.assertTrue(dep.subject in actor2.subject.clientDependency)
|
||||
# TODO: test with interface (usage) and component (realization)
|
||||
# TODO: test with multiple diagrams (should reuse existing relationships first)
|
||||
|
||||
|
||||
def test_multi_dependency(self):
|
||||
"""Test multiple dependencies
|
||||
|
||||
Dependency should appear in a new diagram, bound on a new
|
||||
dependency item.
|
||||
"""
|
||||
actoritem1 = self.create(items.ActorItem, UML.Actor)
|
||||
actoritem2 = self.create(items.ActorItem, UML.Actor)
|
||||
actoritem1 = self.create(items.ActorItem, uml2.Actor)
|
||||
actoritem2 = self.create(items.ActorItem, uml2.Actor)
|
||||
actor1 = actoritem1.subject
|
||||
actor2 = actoritem2.subject
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
|
||||
self.connect(dep, dep.head, actoritem1)
|
||||
self.connect(dep, dep.tail, actoritem2)
|
||||
|
||||
@ -141,7 +160,7 @@ class DependencyTestCase(TestCase):
|
||||
|
||||
# Do the same thing, but now on a new diagram:
|
||||
|
||||
diagram2 = self.element_factory.create(UML.Diagram)
|
||||
diagram2 = self.element_factory.create(uml2.Diagram)
|
||||
actoritem3 = diagram2.create(items.ActorItem, subject=actor1)
|
||||
actoritem4 = diagram2.create(items.ActorItem, subject=actor2)
|
||||
dep2 = diagram2.create(items.DependencyItem)
|
||||
@ -159,21 +178,20 @@ class DependencyTestCase(TestCase):
|
||||
|
||||
self.assertSame(dep.subject, dep2.subject)
|
||||
|
||||
|
||||
def test_dependency_type_auto(self):
|
||||
"""Test dependency type automatic determination
|
||||
"""
|
||||
cls = self.create(items.ClassItem, UML.Class)
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
cls = self.create(items.ClassItem, uml2.Class)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
assert dep.auto_dependency
|
||||
|
||||
self.connect(dep, dep.tail, cls) # connect client
|
||||
self.connect(dep, dep.head, iface) # connect supplier
|
||||
self.connect(dep, dep.tail, cls) # connect client
|
||||
self.connect(dep, dep.head, iface) # connect supplier
|
||||
|
||||
self.assertTrue(dep.subject is not None)
|
||||
self.assertTrue(isinstance(dep.subject, UML.Usage), dep.subject)
|
||||
self.assertTrue(isinstance(dep.subject, uml2.Usage), dep.subject)
|
||||
self.assertTrue(dep.subject in self.element_factory.select())
|
||||
|
||||
|
||||
@ -181,12 +199,13 @@ class GeneralizationTestCase(TestCase):
|
||||
"""
|
||||
Generalization item connection adapter tests.
|
||||
"""
|
||||
|
||||
def test_glue(self):
|
||||
"""Test generalization item glueing using two classes
|
||||
"""
|
||||
gen = self.create(items.GeneralizationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
glued = self.allow(gen, gen.tail, c1)
|
||||
self.assertTrue(glued)
|
||||
@ -198,13 +217,12 @@ class GeneralizationTestCase(TestCase):
|
||||
glued = self.allow(gen, gen.head, c2)
|
||||
self.assertTrue(glued)
|
||||
|
||||
|
||||
def test_connection(self):
|
||||
"""Test generalization item connection using two classes
|
||||
"""
|
||||
gen = self.create(items.GeneralizationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(gen, gen.tail, c1)
|
||||
assert self.get_connected(gen.tail) is c1
|
||||
@ -220,8 +238,8 @@ class GeneralizationTestCase(TestCase):
|
||||
On reconnection a new Generalization is created.
|
||||
"""
|
||||
gen = self.create(items.GeneralizationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(gen, gen.tail, c1)
|
||||
assert self.get_connected(gen.tail) is c1
|
||||
@ -232,7 +250,7 @@ class GeneralizationTestCase(TestCase):
|
||||
self.assertTrue(gen.subject.specific is c1.subject)
|
||||
|
||||
# Now do the same on a new diagram:
|
||||
diagram2 = self.element_factory.create(UML.Diagram)
|
||||
diagram2 = self.element_factory.create(uml2.Diagram)
|
||||
c3 = diagram2.create(items.ClassItem, subject=c1.subject)
|
||||
c4 = diagram2.create(items.ClassItem, subject=c2.subject)
|
||||
gen2 = diagram2.create(items.GeneralizationItem)
|
||||
@ -246,16 +264,15 @@ class GeneralizationTestCase(TestCase):
|
||||
self.assertNotSame(gen.subject, gen2.subject)
|
||||
self.assertEquals(1, len(c1.subject.generalization))
|
||||
self.assertSame(c1.subject.generalization[0], gen.subject)
|
||||
#self.assertEquals(1, len(actor2.clientDependency))
|
||||
#self.assertTrue(actor2.clientDependency[0] is dep.subject)
|
||||
|
||||
# self.assertEquals(1, len(actor2.clientDependency))
|
||||
# self.assertTrue(actor2.clientDependency[0] is dep.subject)
|
||||
|
||||
def test_reconnection2(self):
|
||||
"""Test reconnection of generalization
|
||||
"""
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c3 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
c3 = self.create(items.ClassItem, uml2.Class)
|
||||
gen = self.create(items.GeneralizationItem)
|
||||
|
||||
# connect: c1 -> c2
|
||||
@ -277,12 +294,13 @@ class AssociationConnectorTestCase(TestCase):
|
||||
"""
|
||||
Association item connection adapters tests.
|
||||
"""
|
||||
|
||||
def test_glue(self):
|
||||
"""Test association item glue
|
||||
"""
|
||||
asc = self.create(items.AssociationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
glued = self.allow(asc, asc.head, c1)
|
||||
self.assertTrue(glued)
|
||||
@ -292,37 +310,35 @@ class AssociationConnectorTestCase(TestCase):
|
||||
glued = self.allow(asc, asc.tail, c2)
|
||||
self.assertTrue(glued)
|
||||
|
||||
|
||||
def test_connect(self):
|
||||
"""Test association item connection
|
||||
"""
|
||||
asc = self.create(items.AssociationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(asc, asc.head, c1)
|
||||
self.assertTrue(asc.subject is None) # no UML metaclass yet
|
||||
self.assertTrue(asc.subject is None) # no UML metaclass yet
|
||||
|
||||
self.connect(asc, asc.tail, c2)
|
||||
self.assertTrue(asc.subject is not None)
|
||||
|
||||
|
||||
# Diagram, Class *2, Property *2, Association
|
||||
self.assertEquals(6, len(list(self.element_factory.select())))
|
||||
self.assertTrue(asc.head_end.subject is not None)
|
||||
self.assertTrue(asc.tail_end.subject is not None)
|
||||
|
||||
|
||||
def test_reconnect(self):
|
||||
"""Test association item reconnection
|
||||
"""
|
||||
asc = self.create(items.AssociationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c3 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
c3 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(asc, asc.head, c1)
|
||||
self.connect(asc, asc.tail, c2)
|
||||
UML.model.set_navigability(asc.subject, asc.tail_end.subject, True)
|
||||
modelfactory.set_navigability(asc.subject, asc.tail_end.subject, True)
|
||||
|
||||
a = asc.subject
|
||||
|
||||
@ -335,24 +351,22 @@ class AssociationConnectorTestCase(TestCase):
|
||||
self.assertTrue(c2.subject not in ends)
|
||||
self.assertTrue(asc.tail_end.subject.navigability)
|
||||
|
||||
|
||||
def test_disconnect(self):
|
||||
"""Test association item disconnection
|
||||
"""
|
||||
asc = self.create(items.AssociationItem)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(asc, asc.head, c1)
|
||||
self.assertTrue(asc.subject is None) # no UML metaclass yet
|
||||
self.assertTrue(asc.subject is None) # no UML metaclass yet
|
||||
|
||||
self.connect(asc, asc.tail, c2)
|
||||
assert asc.subject is not None
|
||||
|
||||
self.disconnect(asc, asc.head)
|
||||
|
||||
|
||||
# after disconnection: one diagram and two classes
|
||||
self.assertEquals(3, len(list(self.element_factory.select())))
|
||||
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,8 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Test implementation (interface realization) item connectors.
|
||||
"""
|
||||
|
||||
from gaphor import UML
|
||||
from __future__ import absolute_import
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
from gaphor.tests import TestCase
|
||||
|
||||
@ -11,7 +32,7 @@ class ImplementationTestCase(TestCase):
|
||||
"""Test non-interface glueing with implementation
|
||||
"""
|
||||
impl = self.create(items.ImplementationItem)
|
||||
clazz = self.create(items.ClassItem, UML.Class)
|
||||
clazz = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
glued = self.allow(impl, impl.head, clazz)
|
||||
# connecting head to non-interface item is disallowed
|
||||
@ -21,7 +42,7 @@ class ImplementationTestCase(TestCase):
|
||||
def test_interface_glue(self):
|
||||
"""Test interface glueing with implementation
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
impl = self.create(items.ImplementationItem)
|
||||
|
||||
glued = self.allow(impl, impl.head, iface)
|
||||
@ -32,7 +53,7 @@ class ImplementationTestCase(TestCase):
|
||||
"""Test classifier glueing with implementation
|
||||
"""
|
||||
impl = self.create(items.ImplementationItem)
|
||||
clazz = self.create(items.ClassItem, UML.Class)
|
||||
clazz = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
glued = self.allow(impl, impl.tail, clazz)
|
||||
self.assertTrue(glued)
|
||||
@ -41,15 +62,15 @@ class ImplementationTestCase(TestCase):
|
||||
def test_connection(self):
|
||||
"""Test connection of class and interface with implementation
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
impl = self.create(items.ImplementationItem)
|
||||
clazz = self.create(items.ClassItem, UML.Class)
|
||||
clazz = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(impl, impl.head, iface)
|
||||
self.connect(impl, impl.tail, clazz)
|
||||
|
||||
# check the datamodel
|
||||
self.assertTrue(isinstance(impl.subject, UML.Implementation))
|
||||
self.assertTrue(isinstance(impl.subject, uml2.Implementation))
|
||||
ct = self.get_connected(impl.head)
|
||||
self.assertTrue(ct is iface)
|
||||
self.assertTrue(impl.subject is not None)
|
||||
@ -60,9 +81,9 @@ class ImplementationTestCase(TestCase):
|
||||
def test_reconnection(self):
|
||||
"""Test reconnection of class and interface with implementation
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
c1 = self.create(items.ClassItem, UML.Class)
|
||||
c2 = self.create(items.ClassItem, UML.Class)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
c1 = self.create(items.ClassItem, uml2.Class)
|
||||
c2 = self.create(items.ClassItem, uml2.Class)
|
||||
impl = self.create(items.ImplementationItem)
|
||||
|
||||
# connect: iface -> c1
|
||||
|
@ -1,8 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Test connections to folded interface.
|
||||
"""
|
||||
|
||||
from gaphor import UML
|
||||
from __future__ import absolute_import
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
from gaphor.tests import TestCase
|
||||
|
||||
@ -10,7 +30,7 @@ class ImplementationTestCase(TestCase):
|
||||
def test_folded_interface_connection(self):
|
||||
"""Test connecting implementation to folded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
impl = self.create(items.ImplementationItem)
|
||||
|
||||
@ -22,7 +42,7 @@ class ImplementationTestCase(TestCase):
|
||||
def test_folded_interface_disconnection(self):
|
||||
"""Test disconnection implementation from folded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
impl = self.create(items.ImplementationItem)
|
||||
|
||||
@ -38,7 +58,7 @@ class DependencyTestCase(TestCase):
|
||||
def test_folded_interface_connection(self):
|
||||
"""Test connecting dependency to folded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
@ -52,7 +72,7 @@ class DependencyTestCase(TestCase):
|
||||
def test_folded_interface_disconnection(self):
|
||||
"""Test disconnection dependency from folded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
@ -69,7 +89,7 @@ class DependencyTestCase(TestCase):
|
||||
def test_unfolded_interface_disconnection(self):
|
||||
"""Test disconnection dependency from unfolded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
dep = self.create(items.DependencyItem)
|
||||
|
||||
self.connect(dep, dep.head, iface, iface.ports()[0])
|
||||
@ -96,7 +116,7 @@ class FoldedInterfaceMultipleLinesTestCase(TestCase):
|
||||
def setUp(self):
|
||||
super(FoldedInterfaceMultipleLinesTestCase, self).setUp()
|
||||
|
||||
self.iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
self.iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
self.iface.folded = self.iface.FOLDED_PROVIDED
|
||||
|
||||
|
||||
@ -135,7 +155,7 @@ class FoldedInterfaceSingleLineTestCase(TestCase):
|
||||
def test_interface_with_forbidden_lines(self):
|
||||
"""Test glueing forbidden lines to folded interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
|
||||
for cls in LINES[2:]:
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Connector connections.
|
||||
|
||||
@ -5,9 +25,9 @@ Implemented using interface item in assembly connector mode, see
|
||||
`gaphor.diagram.connector` module for details.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from zope import component
|
||||
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
from gaphor.adapters.connectors import AbstractConnect
|
||||
|
||||
@ -82,9 +102,9 @@ class ConnectorConnectBase(AbstractConnect):
|
||||
"""
|
||||
connector.subject = assembly
|
||||
|
||||
end = self.element_factory.create(UML.ConnectorEnd)
|
||||
end = self.element_factory.create(uml2.ConnectorEnd)
|
||||
end.role = iface
|
||||
end.partWithPort = self.element_factory.create(UML.Port)
|
||||
end.partWithPort = self.element_factory.create(uml2.Port)
|
||||
assembly.end = end
|
||||
|
||||
component.subject.ownedPort = end.partWithPort
|
||||
@ -168,7 +188,7 @@ class ConnectorConnectBase(AbstractConnect):
|
||||
break
|
||||
|
||||
if assembly is None:
|
||||
assembly = self.element_factory.create(UML.Connector)
|
||||
assembly = self.element_factory.create(uml2.Connector)
|
||||
assembly.kind = 'assembly'
|
||||
for c in connections:
|
||||
connector = c.item
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,9 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Test connector item connectors.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
from gaphor.adapters.components.connectorconnect import ConnectorConnectBase
|
||||
|
||||
@ -15,7 +36,7 @@ class ComponentConnectTestCase(TestCase):
|
||||
def test_glue(self):
|
||||
"""Test glueing connector to component
|
||||
"""
|
||||
component = self.create(items.ComponentItem, UML.Component)
|
||||
component = self.create(items.ComponentItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
glued = self.allow(line, line.head, component)
|
||||
@ -25,7 +46,7 @@ class ComponentConnectTestCase(TestCase):
|
||||
def test_connection(self):
|
||||
"""Test connecting connector to a component
|
||||
"""
|
||||
component = self.create(items.ComponentItem, UML.Component)
|
||||
component = self.create(items.ComponentItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
self.connect(line, line.head, component)
|
||||
@ -36,8 +57,8 @@ class ComponentConnectTestCase(TestCase):
|
||||
def test_glue_both(self):
|
||||
"""Test glueing connector to component when one is connected
|
||||
"""
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
self.connect(line, line.head, c1)
|
||||
@ -53,7 +74,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_non_folded_glue(self):
|
||||
"""Test non-folded interface glueing
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
glued = self.allow(line, line.head, iface)
|
||||
@ -63,7 +84,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_folded_glue(self):
|
||||
"""Test folded interface glueing
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
iface.folded = iface.FOLDED_REQUIRED
|
||||
@ -74,7 +95,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_glue_when_dependency_connected(self):
|
||||
"""Test interface glueing, when dependency connected
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
dep = self.create(items.DependencyItem)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
@ -88,7 +109,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_glue_when_implementation_connected(self):
|
||||
"""Test interface glueing, when implementation connected
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
impl = self.create(items.ImplementationItem)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
@ -102,7 +123,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_glue_when_connector_connected(self):
|
||||
"""Test interface glueing, when connector connected
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
iface.folded = iface.FOLDED_REQUIRED
|
||||
|
||||
line1 = self.create(items.ConnectorItem)
|
||||
@ -118,7 +139,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_simple_connection(self):
|
||||
"""Test simple connection to an interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
@ -150,7 +171,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_connection_angle_change(self):
|
||||
"""Test angle after connection to an interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
@ -169,7 +190,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_connection_of_two_connectors_one_side(self):
|
||||
"""Test connection of two connectors to required port of an interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
c1 = self.create(items.ConnectorItem)
|
||||
c2 = self.create(items.ConnectorItem)
|
||||
|
||||
@ -199,7 +220,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_connection_of_two_connectors_two_sides(self):
|
||||
"""Test connection of two connectors to required and provided ports of an interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
c1 = self.create(items.ConnectorItem)
|
||||
c2 = self.create(items.ConnectorItem)
|
||||
|
||||
@ -228,7 +249,7 @@ class InterfaceConnectTestCase(TestCase):
|
||||
def test_simple_disconnection(self):
|
||||
"""Test disconnection of simple connection to an interface
|
||||
"""
|
||||
iface = self.create(items.InterfaceItem, UML.Component)
|
||||
iface = self.create(items.InterfaceItem, uml2.Component)
|
||||
line = self.create(items.ConnectorItem)
|
||||
|
||||
iface.folded = iface.FOLDED_PROVIDED
|
||||
@ -264,7 +285,7 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
List of interface names.
|
||||
"""
|
||||
for name in args:
|
||||
interface = self.element_factory.create(UML.Interface)
|
||||
interface = self.element_factory.create(uml2.Interface)
|
||||
interface.name = name
|
||||
yield interface
|
||||
|
||||
@ -273,7 +294,7 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
"""
|
||||
Change component's data so it implements interfaces.
|
||||
"""
|
||||
impl = self.element_factory.create(UML.Implementation)
|
||||
impl = self.element_factory.create(uml2.Implementation)
|
||||
component.implementation = impl
|
||||
impl.contract = interface
|
||||
|
||||
@ -282,7 +303,7 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
"""
|
||||
Change component's data so it requires interface.
|
||||
"""
|
||||
usage = self.element_factory.create(UML.Usage)
|
||||
usage = self.element_factory.create(uml2.Usage)
|
||||
component.clientDependency = usage
|
||||
usage.supplier = interface
|
||||
|
||||
@ -293,8 +314,8 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
# connect component
|
||||
self.connect(conn1, conn1.tail, c1)
|
||||
@ -310,10 +331,10 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -335,7 +356,7 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
self.assertTrue(conn1.subject is conn2.subject,
|
||||
'%s is not %s' % (conn1.subject, conn2.subject))
|
||||
assembly = conn1.subject
|
||||
self.assertTrue(isinstance(assembly, UML.Connector))
|
||||
self.assertTrue(isinstance(assembly, uml2.Connector))
|
||||
self.assertEquals('assembly', assembly.kind)
|
||||
|
||||
# there should be two connector ends
|
||||
@ -366,10 +387,10 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -393,11 +414,11 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
conn3 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c3 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
c3 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -428,9 +449,9 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
"""
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -455,10 +476,10 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -488,11 +509,11 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
conn3 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c3 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
c3 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -543,10 +564,10 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn1 = self.create(items.ConnectorItem)
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -572,9 +593,9 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
self.assertTrue(conn1.subject is None)
|
||||
self.assertTrue(conn2.subject is None)
|
||||
|
||||
self.assertEquals(0, len(self.kindof(UML.Connector)))
|
||||
self.assertEquals(0, len(self.kindof(UML.ConnectorEnd)))
|
||||
self.assertEquals(0, len(self.kindof(UML.Port)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.Connector)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.ConnectorEnd)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.Port)))
|
||||
|
||||
|
||||
def test_disconnection_order(self):
|
||||
@ -584,11 +605,11 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
conn2 = self.create(items.ConnectorItem)
|
||||
conn3 = self.create(items.ConnectorItem)
|
||||
|
||||
c1 = self.create(items.ComponentItem, UML.Component)
|
||||
c2 = self.create(items.ComponentItem, UML.Component)
|
||||
c3 = self.create(items.ComponentItem, UML.Component)
|
||||
c1 = self.create(items.ComponentItem, uml2.Component)
|
||||
c2 = self.create(items.ComponentItem, uml2.Component)
|
||||
c3 = self.create(items.ComponentItem, uml2.Component)
|
||||
|
||||
iface = self.create(items.InterfaceItem, UML.Interface)
|
||||
iface = self.create(items.InterfaceItem, uml2.Interface)
|
||||
iface.folded = iface.FOLDED_ASSEMBLY
|
||||
pport = iface.ports()[0]
|
||||
rport = iface.ports()[2]
|
||||
@ -622,9 +643,9 @@ class AssemblyConnectorTestCase(TestCase):
|
||||
self.assertTrue(conn2.subject is None)
|
||||
self.assertTrue(conn3.subject is None)
|
||||
|
||||
self.assertEquals(0, len(self.kindof(UML.Connector)))
|
||||
self.assertEquals(0, len(self.kindof(UML.ConnectorEnd)))
|
||||
self.assertEquals(0, len(self.kindof(UML.Port)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.Connector)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.ConnectorEnd)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.Port)))
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Adam Boduch <adam.boduch@gmail.com>
|
||||
# Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Connector adapters.
|
||||
|
||||
@ -5,15 +26,16 @@ To register connectors implemented in this module, it is imported in
|
||||
gaphor.adapter package.
|
||||
"""
|
||||
|
||||
from zope import interface, component
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
from logging import getLogger
|
||||
from zope import interface, component
|
||||
|
||||
from gaphas import geometry
|
||||
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.core import inject
|
||||
from gaphor.diagram.interfaces import IConnect
|
||||
from gaphor.diagram import items
|
||||
from gaphor.diagram.interfaces import IConnect
|
||||
|
||||
logger = getLogger('Connector')
|
||||
|
||||
@ -46,30 +68,26 @@ class AbstractConnect(object):
|
||||
|
||||
element_factory = inject('element_factory')
|
||||
|
||||
|
||||
def __init__(self, element, line):
|
||||
self.element = element
|
||||
self.line = line
|
||||
self.canvas = self.element.canvas
|
||||
assert self.canvas == self.element.canvas == self.line.canvas
|
||||
|
||||
|
||||
def get_connection(self, handle):
|
||||
"""
|
||||
Get connection information
|
||||
"""
|
||||
return self.canvas.get_connection(handle)
|
||||
|
||||
return self.canvas.get_connection(handle)
|
||||
|
||||
def get_connected(self, handle):
|
||||
"""
|
||||
Get item connected to a handle.
|
||||
"""
|
||||
cinfo = self.canvas.get_connection(handle)
|
||||
cinfo = self.canvas.get_connection(handle)
|
||||
if cinfo is not None:
|
||||
return cinfo.connected
|
||||
|
||||
|
||||
def get_connected_port(self, handle):
|
||||
"""
|
||||
Get port of item connected to connecting item via specified handle.
|
||||
@ -78,7 +96,6 @@ class AbstractConnect(object):
|
||||
if cinfo is not None:
|
||||
return cinfo.port
|
||||
|
||||
|
||||
def allow(self, handle, port):
|
||||
"""
|
||||
Determine if items can be connected.
|
||||
@ -96,7 +113,6 @@ class AbstractConnect(object):
|
||||
return not count and isinstance(self.line, (items.DependencyItem, items.ImplementationItem))
|
||||
return True
|
||||
|
||||
|
||||
def connect(self, handle, port):
|
||||
"""
|
||||
Connect to an element. Note that at this point the line may
|
||||
@ -107,12 +123,11 @@ class AbstractConnect(object):
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
# def reconnect(self, handle, port):
|
||||
# """
|
||||
# UML model reconnection method.
|
||||
# """
|
||||
# raise NotImplementedError('Reconnection not implemented')
|
||||
# def reconnect(self, handle, port):
|
||||
# """
|
||||
# UML model reconnection method.
|
||||
# """
|
||||
# raise NotImplementedError('Reconnection not implemented')
|
||||
|
||||
|
||||
def disconnect(self, handle):
|
||||
@ -122,7 +137,6 @@ class AbstractConnect(object):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class CommentLineElementConnect(AbstractConnect):
|
||||
"""
|
||||
Connect a comment line to any element item.
|
||||
@ -145,7 +159,7 @@ class CommentLineElementConnect(AbstractConnect):
|
||||
# Same goes for subjects:
|
||||
if connected_to and \
|
||||
(not (connected_to.subject or element.subject)) \
|
||||
and connected_to.subject is element.subject:
|
||||
and connected_to.subject is element.subject:
|
||||
return None
|
||||
|
||||
# One end should be connected to a CommentItem:
|
||||
@ -156,10 +170,10 @@ class CommentLineElementConnect(AbstractConnect):
|
||||
|
||||
# Do not allow to links between the comment and the element
|
||||
if connected_to and element and \
|
||||
((isinstance(connected_to.subject, UML.Comment) and \
|
||||
self.element.subject in connected_to.subject.annotatedElement) or \
|
||||
(isinstance(self.element.subject, UML.Comment) and \
|
||||
connected_to.subject in self.element.subject.annotatedElement)):
|
||||
((isinstance(connected_to.subject, uml2.Comment) and \
|
||||
self.element.subject in connected_to.subject.annotatedElement) or \
|
||||
(isinstance(self.element.subject, uml2.Comment) and \
|
||||
connected_to.subject in self.element.subject.annotatedElement)):
|
||||
return None
|
||||
|
||||
return super(CommentLineElementConnect, self).allow(handle, port)
|
||||
@ -169,7 +183,7 @@ class CommentLineElementConnect(AbstractConnect):
|
||||
opposite = self.line.opposite(handle)
|
||||
connected_to = self.get_connected(opposite)
|
||||
if connected_to:
|
||||
if isinstance(connected_to.subject, UML.Comment):
|
||||
if isinstance(connected_to.subject, uml2.Comment):
|
||||
connected_to.subject.annotatedElement = self.element.subject
|
||||
else:
|
||||
self.element.subject.annotatedElement = connected_to.subject
|
||||
@ -182,15 +196,16 @@ class CommentLineElementConnect(AbstractConnect):
|
||||
if hct and oct:
|
||||
logger.debug('Disconnecting %s and %s' % (hct, oct))
|
||||
try:
|
||||
if hct.subject and isinstance(oct.subject, UML.Comment):
|
||||
if hct.subject and isinstance(oct.subject, uml2.Comment):
|
||||
del oct.subject.annotatedElement[hct.subject]
|
||||
elif hct.subject and oct.subject:
|
||||
del hct.subject.annotatedElement[oct.subject]
|
||||
except ValueError:
|
||||
logger.debug('Invoked CommentLineElementConnect.disconnect() for nonexistant relationship')
|
||||
|
||||
|
||||
super(CommentLineElementConnect, self).disconnect(handle)
|
||||
|
||||
|
||||
component.provideAdapter(CommentLineElementConnect)
|
||||
|
||||
|
||||
@ -204,7 +219,7 @@ class CommentLineLineConnect(AbstractConnect):
|
||||
"""
|
||||
In addition to the normal check, both line ends may not be connected
|
||||
to the same element. Same goes for subjects.
|
||||
One of the ends should be connected to a UML.Comment element.
|
||||
One of the ends should be connected to a uml2.Comment element.
|
||||
"""
|
||||
opposite = self.line.opposite(handle)
|
||||
element = self.element
|
||||
@ -218,10 +233,10 @@ class CommentLineLineConnect(AbstractConnect):
|
||||
# Same goes for subjects:
|
||||
if connected_to and \
|
||||
(not (connected_to.subject or element.subject)) \
|
||||
and connected_to.subject is element.subject:
|
||||
and connected_to.subject is element.subject:
|
||||
return None
|
||||
|
||||
print 'Connecting', element, 'with', element.subject
|
||||
print('Connecting', element, 'with', element.subject)
|
||||
|
||||
# One end should be connected to a CommentItem:
|
||||
cls = items.CommentItem
|
||||
@ -236,7 +251,7 @@ class CommentLineLineConnect(AbstractConnect):
|
||||
opposite = self.line.opposite(handle)
|
||||
c = self.get_connected(opposite)
|
||||
if c and self.element.subject:
|
||||
if isinstance(c.subject, UML.Comment):
|
||||
if isinstance(c.subject, uml2.Comment):
|
||||
c.subject.annotatedElement = self.element.subject
|
||||
else:
|
||||
self.element.subject.annotatedElement = c.subject
|
||||
@ -246,12 +261,13 @@ class CommentLineLineConnect(AbstractConnect):
|
||||
opposite = self.line.opposite(handle)
|
||||
c2 = self.get_connected(opposite)
|
||||
if c1 and c2:
|
||||
if isinstance(c1.subject, UML.Comment):
|
||||
if isinstance(c1.subject, uml2.Comment):
|
||||
del c1.subject.annotatedElement[c2.subject]
|
||||
elif c2.subject:
|
||||
del c2.subject.annotatedElement[c1.subject]
|
||||
super(CommentLineLineConnect, self).disconnect(handle)
|
||||
|
||||
|
||||
component.provideAdapter(CommentLineLineConnect)
|
||||
|
||||
|
||||
@ -269,7 +285,6 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
|
||||
element_factory = inject('element_factory')
|
||||
|
||||
|
||||
def relationship(self, required_type, head, tail):
|
||||
"""
|
||||
Find an existing relationship in the model that meets the
|
||||
@ -287,8 +302,8 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
|
||||
# First check if the right subject is already connected:
|
||||
if line.subject \
|
||||
and getattr(line.subject, head.name) is head_subject \
|
||||
and getattr(line.subject, tail.name) is tail_subject:
|
||||
and getattr(line.subject, head.name) is head_subject \
|
||||
and getattr(line.subject, tail.name) is tail_subject:
|
||||
return line.subject
|
||||
|
||||
# Try to find a relationship, that is already created, but not
|
||||
@ -296,7 +311,7 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
for gen in getattr(tail_subject, tail.opposite):
|
||||
if not isinstance(gen, required_type):
|
||||
continue
|
||||
|
||||
|
||||
gen_head = getattr(gen, head.name)
|
||||
try:
|
||||
if not head_subject in gen_head:
|
||||
@ -327,7 +342,6 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
setattr(relation, tail.name, self.get_connected(line.tail).subject)
|
||||
return relation
|
||||
|
||||
|
||||
def reconnect_relationship(self, handle, head, tail):
|
||||
"""
|
||||
Reconnect relationship for given handle.
|
||||
@ -350,7 +364,6 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
else:
|
||||
raise ValueError('Incorrect handle passed to adapter')
|
||||
|
||||
|
||||
def connect_connected_items(self, connections=None):
|
||||
"""
|
||||
Cause items connected to ``line`` to reconnect, allowing them to
|
||||
@ -366,7 +379,7 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
adapter = component.queryMultiAdapter((line, cinfo.connected), IConnect)
|
||||
assert adapter
|
||||
adapter.connect(cinfo.handle, cinfo.port)
|
||||
|
||||
|
||||
def disconnect_connected_items(self):
|
||||
"""
|
||||
Cause items connected to @line to be disconnected.
|
||||
@ -392,7 +405,7 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
"""
|
||||
Establish the relationship at model level.
|
||||
"""
|
||||
raise NotImplementedError, 'Implement connect_subject() in a subclass'
|
||||
raise NotImplementedError('Implement connect_subject() in a subclass')
|
||||
|
||||
def disconnect_subject(self, handle):
|
||||
"""
|
||||
@ -421,7 +434,6 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
self.connect_connected_items()
|
||||
return True
|
||||
|
||||
|
||||
def disconnect(self, handle):
|
||||
"""
|
||||
Disconnect model element.
|
||||
@ -430,13 +442,13 @@ class UnaryRelationshipConnect(AbstractConnect):
|
||||
opposite = line.opposite(handle)
|
||||
oct = self.get_connected(opposite)
|
||||
hct = self.get_connected(handle)
|
||||
|
||||
|
||||
if hct and oct:
|
||||
# Both sides of line are connected => disconnect
|
||||
old = line.subject
|
||||
|
||||
|
||||
connections = self.disconnect_connected_items()
|
||||
|
||||
|
||||
self.disconnect_subject(handle)
|
||||
if old:
|
||||
self.connect_connected_items(connections)
|
||||
@ -465,10 +477,9 @@ class RelationshipConnect(UnaryRelationshipConnect):
|
||||
# Same goes for subjects:
|
||||
if connected_to and \
|
||||
(not (connected_to.subject or element.subject)) \
|
||||
and connected_to.subject is element.subject:
|
||||
and connected_to.subject is element.subject:
|
||||
return None
|
||||
|
||||
return super(RelationshipConnect, self).allow(handle, port)
|
||||
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -1,13 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Adapters
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from zope import interface, component
|
||||
|
||||
from gaphas.item import NW, SE
|
||||
from gaphas import geometry
|
||||
from gaphas import constraint
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2, umllex
|
||||
from gaphor.core import inject
|
||||
from gaphor.diagram.interfaces import IEditor
|
||||
from gaphor.diagram import items
|
||||
@ -25,7 +46,7 @@ def editable(el):
|
||||
return el
|
||||
|
||||
|
||||
@editable.when_type(UML.Slot)
|
||||
@editable.when_type(uml2.Slot)
|
||||
def editable_slot(el):
|
||||
"""
|
||||
Return editable part of a slot.
|
||||
@ -152,13 +173,13 @@ class CompartmentItemEditor(object):
|
||||
return bool(self._edit and self._edit.subject)
|
||||
|
||||
def get_text(self):
|
||||
return UML.format(editable(self._edit.subject))
|
||||
return format(editable(self._edit.subject))
|
||||
|
||||
def get_bounds(self):
|
||||
return None
|
||||
|
||||
def update_text(self, text):
|
||||
UML.parse(editable(self._edit.subject), text)
|
||||
umllex.parse(editable(self._edit.subject), text)
|
||||
|
||||
def key_pressed(self, pos, key):
|
||||
pass
|
||||
@ -192,14 +213,14 @@ class AssociationItemEditor(object):
|
||||
def get_text(self):
|
||||
if self._edit is self._item:
|
||||
return self._edit.subject.name
|
||||
return UML.format(self._edit.subject, visibility=True,
|
||||
return format(self._edit.subject, visibility=True,
|
||||
is_derived=True, type=True,
|
||||
multiplicity=True, default=True)
|
||||
def get_bounds(self):
|
||||
return None
|
||||
|
||||
def update_text(self, text):
|
||||
UML.parse(self._edit.subject, text)
|
||||
uml2.parse(self._edit.subject, text)
|
||||
|
||||
def key_pressed(self, pos, key):
|
||||
pass
|
||||
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Grouping functionality allows to nest one item within another item (parent
|
||||
item). This is useful in several use cases
|
||||
@ -15,9 +35,10 @@ is about to be created. Therefore `AbstractGroup.can_contain` has
|
||||
to be aware that `AbstractGroup.item` can be null.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from zope import interface, component
|
||||
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.core import inject
|
||||
from gaphor.diagram import items
|
||||
from gaphor.diagram.interfaces import IGroup
|
||||
@ -52,14 +73,14 @@ class AbstractGroup(object):
|
||||
"""
|
||||
Group an item within parent.
|
||||
"""
|
||||
raise NotImplemented, 'This is abstract method'
|
||||
raise NotImplemented('This is abstract method')
|
||||
|
||||
|
||||
def ungroup(self):
|
||||
"""
|
||||
Remove item from parent.
|
||||
"""
|
||||
raise NotImplemented, 'This is abstract method'
|
||||
raise NotImplemented('This is abstract method')
|
||||
|
||||
|
||||
|
||||
@ -107,18 +128,18 @@ class NodeComponentGroup(AbstractGroup):
|
||||
component = self.item.subject
|
||||
|
||||
# node attribute
|
||||
a1 = self.element_factory.create(UML.Property)
|
||||
a1 = self.element_factory.create(uml2.Property)
|
||||
a1.aggregation = 'composite'
|
||||
# component attribute
|
||||
a2 = self.element_factory.create(UML.Property)
|
||||
a2 = self.element_factory.create(uml2.Property)
|
||||
|
||||
e1 = self.element_factory.create(UML.ConnectorEnd)
|
||||
e2 = self.element_factory.create(UML.ConnectorEnd)
|
||||
e1 = self.element_factory.create(uml2.ConnectorEnd)
|
||||
e2 = self.element_factory.create(uml2.ConnectorEnd)
|
||||
|
||||
# create connection between node and component
|
||||
e1.role = a1
|
||||
e2.role = a2
|
||||
connector = self.element_factory.create(UML.Connector)
|
||||
connector = self.element_factory.create(uml2.Connector)
|
||||
connector.end = e1
|
||||
connector.end = e2
|
||||
|
||||
@ -157,7 +178,7 @@ class NodeArtifactGroup(AbstractGroup):
|
||||
artifact = self.item.subject
|
||||
|
||||
# deploy artifact on node
|
||||
deployment = self.element_factory.create(UML.Deployment)
|
||||
deployment = self.element_factory.create(uml2.Deployment)
|
||||
node.deployment = deployment
|
||||
deployment.deployedArtifact = artifact
|
||||
|
||||
@ -208,7 +229,7 @@ class ActivityPartitionsGroup(AbstractGroup):
|
||||
|
||||
def group(self):
|
||||
p = self.parent.subject
|
||||
sp = self.element_factory.create(UML.ActivityPartition)
|
||||
sp = self.element_factory.create(uml2.ActivityPartition)
|
||||
self.item.subject = sp
|
||||
sp.name = 'Swimlane'
|
||||
if p:
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,10 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Message item connection adapters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.adapters.connectors import AbstractConnect
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
|
||||
class MessageLifelineConnect(AbstractConnect):
|
||||
@ -25,7 +46,7 @@ class MessageLifelineConnect(AbstractConnect):
|
||||
"""
|
||||
def get_subject():
|
||||
if not line.subject:
|
||||
message = self.element_factory.create(UML.Message)
|
||||
message = self.element_factory.create(uml2.Message)
|
||||
message.name = 'call()'
|
||||
line.subject = message
|
||||
return line.subject
|
||||
@ -33,14 +54,14 @@ class MessageLifelineConnect(AbstractConnect):
|
||||
if send:
|
||||
message = get_subject()
|
||||
if not message.sendEvent:
|
||||
event = self.element_factory.create(UML.MessageOccurrenceSpecification)
|
||||
event = self.element_factory.create(uml2.MessageOccurrenceSpecification)
|
||||
event.sendMessage = message
|
||||
event.covered = send.subject
|
||||
|
||||
if received:
|
||||
message = get_subject()
|
||||
if not message.receiveEvent:
|
||||
event = self.element_factory.create(UML.MessageOccurrenceSpecification)
|
||||
event = self.element_factory.create(uml2.MessageOccurrenceSpecification)
|
||||
event.receiveMessage = message
|
||||
event.covered = received.subject
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,9 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Message connection adapter tests.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
from gaphor.diagram import items
|
||||
|
||||
class BasicMessageConnectionsTestCase(TestCase):
|
||||
@ -55,8 +76,8 @@ class BasicMessageConnectionsTestCase(TestCase):
|
||||
self.assertTrue(msg.subject is not None)
|
||||
self.assertEquals(msg.subject.messageKind, 'lost')
|
||||
|
||||
messages = self.kindof(UML.Message)
|
||||
occurences = self.kindof(UML.MessageOccurrenceSpecification)
|
||||
messages = self.kindof(uml2.Message)
|
||||
occurences = self.kindof(uml2.MessageOccurrenceSpecification)
|
||||
|
||||
self.assertEquals(1, len(messages))
|
||||
self.assertEquals(1, len(occurences))
|
||||
@ -76,8 +97,8 @@ class BasicMessageConnectionsTestCase(TestCase):
|
||||
self.assertTrue(msg.subject is not None)
|
||||
self.assertEquals(msg.subject.messageKind, 'found')
|
||||
|
||||
messages = self.kindof(UML.Message)
|
||||
occurences = self.kindof(UML.MessageOccurrenceSpecification)
|
||||
messages = self.kindof(uml2.Message)
|
||||
occurences = self.kindof(uml2.MessageOccurrenceSpecification)
|
||||
|
||||
self.assertEquals(1, len(messages))
|
||||
self.assertEquals(1, len(occurences))
|
||||
@ -99,8 +120,8 @@ class BasicMessageConnectionsTestCase(TestCase):
|
||||
self.assertTrue(msg.subject is not None)
|
||||
self.assertEquals(msg.subject.messageKind, 'complete')
|
||||
|
||||
messages = self.kindof(UML.Message)
|
||||
occurences = self.kindof(UML.MessageOccurrenceSpecification)
|
||||
messages = self.kindof(uml2.Message)
|
||||
occurences = self.kindof(uml2.MessageOccurrenceSpecification)
|
||||
|
||||
self.assertEquals(1, len(messages))
|
||||
self.assertEquals(2, len(occurences))
|
||||
@ -245,19 +266,19 @@ class DiagramModeMessageConnectionTestCase(TestCase):
|
||||
assert subject.sendEvent and subject.receiveEvent
|
||||
|
||||
# add some more messages
|
||||
m1 = UML.model.create_message(factory, subject)
|
||||
m2 = UML.model.create_message(factory, subject)
|
||||
m1 = modelfactory.create_message(factory, subject)
|
||||
m2 = modelfactory.create_message(factory, subject)
|
||||
msg.add_message(m1, False)
|
||||
msg.add_message(m2, False)
|
||||
|
||||
# add some inverted messages
|
||||
m3 = UML.model.create_message(factory, subject, True)
|
||||
m4 = UML.model.create_message(factory, subject, True)
|
||||
m3 = modelfactory.create_message(factory, subject, True)
|
||||
m4 = modelfactory.create_message(factory, subject, True)
|
||||
msg.add_message(m3, True)
|
||||
msg.add_message(m4, True)
|
||||
|
||||
messages = list(self.kindof(UML.Message))
|
||||
occurences = set(self.kindof(UML.MessageOccurrenceSpecification))
|
||||
messages = list(self.kindof(uml2.Message))
|
||||
occurences = set(self.kindof(uml2.MessageOccurrenceSpecification))
|
||||
|
||||
# verify integrity of messages
|
||||
self.assertEquals(5, len(messages))
|
||||
@ -278,7 +299,7 @@ class DiagramModeMessageConnectionTestCase(TestCase):
|
||||
|
||||
# no message after full disconnection
|
||||
self.disconnect(msg, msg.tail)
|
||||
self.assertEquals(0, len(self.kindof(UML.Message)))
|
||||
self.assertEquals(0, len(self.kindof(uml2.Message)))
|
||||
|
||||
|
||||
# vim:sw=4:et:ai
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,6 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
from gaphor.adapters.connectors import RelationshipConnect
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
from gaphor.diagram import items
|
||||
|
||||
|
||||
@ -17,10 +38,10 @@ class ExtensionConnect(RelationshipConnect):
|
||||
if handle is line.head:
|
||||
# Element at the head should be a class
|
||||
# (implies stereotype as well)
|
||||
allow = isinstance(subject, UML.Class)
|
||||
allow = isinstance(subject, uml2.Class)
|
||||
elif handle is line.tail:
|
||||
# Element at the tail should be a stereotype
|
||||
allow = isinstance(subject, UML.Stereotype)
|
||||
allow = isinstance(subject, uml2.Stereotype)
|
||||
|
||||
return allow and super(ExtensionConnect, self).allow(handle, port)
|
||||
|
||||
@ -49,7 +70,7 @@ class ExtensionConnect(RelationshipConnect):
|
||||
# Find all associations and determine if the properties on
|
||||
# the association ends have a type that points to the class.
|
||||
for assoc in self.element_factory.select():
|
||||
if isinstance(assoc, UML.Extension):
|
||||
if isinstance(assoc, uml2.Extension):
|
||||
end1 = assoc.memberEnd[0]
|
||||
end2 = assoc.memberEnd[1]
|
||||
if (end1.type is head_type and end2.type is tail_type) \
|
||||
@ -64,7 +85,7 @@ class ExtensionConnect(RelationshipConnect):
|
||||
return
|
||||
else:
|
||||
# Create a new Extension relationship
|
||||
relation = UML.model.extend_with_stereotype(self.element_factory,
|
||||
relation = modelfactory.extend_with_stereotype(self.element_factory,
|
||||
head_type,
|
||||
tail_type)
|
||||
line.subject = relation
|
||||
|
@ -1,7 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Metaclass item editors.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import gtk
|
||||
|
||||
from gaphor.core import _, inject, transactional
|
||||
@ -9,7 +30,7 @@ from gaphor.ui.interfaces import IPropertyPage
|
||||
from zope import interface, component
|
||||
from gaphor.diagram import items
|
||||
from gaphor.adapters.propertypages import create_hbox_label, EventWatcher
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
|
||||
def _issubclass(c, b):
|
||||
try:
|
||||
@ -30,8 +51,8 @@ class MetaclassNameEditor(object):
|
||||
|
||||
NAME_LABEL = _('Name')
|
||||
|
||||
CLASSES = list(sorted(n for n in dir(UML)
|
||||
if _issubclass(getattr(UML, n), UML.Element) and n != 'Stereotype'))
|
||||
CLASSES = list(sorted(n for n in dir(uml2)
|
||||
if _issubclass(getattr(uml2, n), uml2.Element) and n != 'Stereotype'))
|
||||
|
||||
|
||||
def __init__(self, item):
|
||||
|
@ -1,14 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Stereotype property page.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import gtk
|
||||
from gaphor.core import _, inject, transactional
|
||||
from gaphor.ui.interfaces import IPropertyPage
|
||||
from gaphor.diagram import items
|
||||
from gaphor.diagram.diagramitem import StereotypeSupport
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
from gaphor.adapters.propertypages import on_text_cell_edited, on_bool_cell_edited
|
||||
|
||||
class StereotypeAttributes(gtk.TreeStore):
|
||||
@ -26,7 +47,7 @@ class StereotypeAttributes(gtk.TreeStore):
|
||||
def refresh(self):
|
||||
self.clear()
|
||||
subject = self.subject
|
||||
stereotypes = UML.model.get_stereotypes(self.element_factory, subject)
|
||||
stereotypes = modelfactory.get_stereotypes(self.element_factory, subject)
|
||||
instances = self.subject.appliedStereotype
|
||||
|
||||
# shortcut map stereotype -> slot (InstanceSpecification)
|
||||
@ -66,7 +87,7 @@ class StereotypeAttributes(gtk.TreeStore):
|
||||
elif col == 1:
|
||||
self.set_slot_value(iter, value)
|
||||
else:
|
||||
print 'col', col
|
||||
print('col', col)
|
||||
|
||||
def select_stereotype(self, iter):
|
||||
"""
|
||||
@ -81,9 +102,9 @@ class StereotypeAttributes(gtk.TreeStore):
|
||||
|
||||
subject = self.subject
|
||||
if value:
|
||||
UML.model.apply_stereotype(self.element_factory, subject, stereotype)
|
||||
modelfactory.apply_stereotype(self.element_factory, subject, stereotype)
|
||||
else:
|
||||
UML.model.remove_stereotype(subject, stereotype)
|
||||
modelfactory.remove_stereotype(subject, stereotype)
|
||||
|
||||
row[2] = value
|
||||
|
||||
@ -99,7 +120,7 @@ class StereotypeAttributes(gtk.TreeStore):
|
||||
path = self.get_path(iter)
|
||||
row = self[path]
|
||||
name, old_value, is_applied, attr, obj, slot = row
|
||||
if isinstance(attr, UML.Stereotype):
|
||||
if isinstance(attr, uml2.Stereotype):
|
||||
return # don't edit stereotype rows
|
||||
|
||||
log.debug('editing %s' % list(row))
|
||||
@ -108,7 +129,7 @@ class StereotypeAttributes(gtk.TreeStore):
|
||||
return # nothing to do and don't create slot without value
|
||||
|
||||
if slot is None:
|
||||
slot = UML.model.add_slot(self.element_factory, obj, attr)
|
||||
slot = modelfactory.add_slot(self.element_factory, obj, attr)
|
||||
|
||||
assert slot
|
||||
|
||||
@ -149,7 +170,7 @@ def create_stereotype_tree_view(model):
|
||||
#value = model.get_value(iter, 4)
|
||||
#cell.set_property('active', value is not None)
|
||||
value = model.get_value(iter, 3)
|
||||
cell.set_property('visible', isinstance(value, UML.Stereotype))
|
||||
cell.set_property('visible', isinstance(value, uml2.Stereotype))
|
||||
col.set_cell_data_func(renderer, show_checkbox)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
@ -197,11 +218,11 @@ class StereotypePage(object):
|
||||
if subject is None:
|
||||
return None
|
||||
|
||||
stereotypes = UML.model.get_stereotypes(self.element_factory, subject)
|
||||
stereotypes = modelfactory.get_stereotypes(self.element_factory, subject)
|
||||
if not stereotypes:
|
||||
return None
|
||||
|
||||
#applied = set(UML.model.get_applied_stereotypes(subject))
|
||||
#applied = set(modelfactory.get_applied_stereotypes(subject))
|
||||
#for i, stereotype in enumerate(stereotypes):
|
||||
# if (i % 3) == 0:
|
||||
# hbox = gtk.HBox(spacing=20)
|
||||
@ -235,9 +256,9 @@ class StereotypePage(object):
|
||||
#def _on_stereotype_selected(self, button, stereotype):
|
||||
# subject = self.item.subject
|
||||
# if button.get_active():
|
||||
# UML.model.apply_stereotype(self.element_factory, subject, stereotype)
|
||||
# modelfactory.apply_stereotype(self.element_factory, subject, stereotype)
|
||||
# else:
|
||||
# UML.model.remove_stereotype(subject, stereotype)
|
||||
# modelfactory.remove_stereotype(subject, stereotype)
|
||||
# self.model.refresh()
|
||||
|
||||
|
||||
@ -248,7 +269,7 @@ class StereotypePage(object):
|
||||
|
||||
|
||||
component.provideAdapter(StereotypePage,
|
||||
adapts=[UML.Element],
|
||||
adapts=[uml2.Element],
|
||||
name='Stereotypes')
|
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2001-2009 Arjan Molenaar <gaphor@gmail.com>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,9 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2009-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Extension item connection adapter tests.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
from gaphor.diagram import items
|
||||
|
||||
class ExtensionConnectorTestCase(TestCase):
|
||||
@ -14,7 +34,7 @@ class ExtensionConnectorTestCase(TestCase):
|
||||
"""Test extension item glueing to a class
|
||||
"""
|
||||
ext = self.create(items.ExtensionItem)
|
||||
cls = self.create(items.ClassItem, UML.Class)
|
||||
cls = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
# cannot connect extension item tail to a class
|
||||
glued = self.allow(ext, ext.tail, cls)
|
||||
@ -25,10 +45,10 @@ class ExtensionConnectorTestCase(TestCase):
|
||||
"""Test extension item glueing to a stereotype
|
||||
"""
|
||||
ext = self.create(items.ExtensionItem)
|
||||
st = self.create(items.ClassItem, UML.Stereotype)
|
||||
st = self.create(items.ClassItem, uml2.Stereotype)
|
||||
|
||||
# test precondition
|
||||
assert type(st.subject) is UML.Stereotype
|
||||
assert type(st.subject) is uml2.Stereotype
|
||||
|
||||
# can connect extension item head to a Stereotype UML metaclass,
|
||||
# because it derives from Class UML metaclass
|
||||
@ -40,8 +60,8 @@ class ExtensionConnectorTestCase(TestCase):
|
||||
"""Test extension item glue
|
||||
"""
|
||||
ext = self.create(items.ExtensionItem)
|
||||
st = self.create(items.ClassItem, UML.Stereotype)
|
||||
cls = self.create(items.ClassItem, UML.Class)
|
||||
st = self.create(items.ClassItem, uml2.Stereotype)
|
||||
cls = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
glued = self.allow(ext, ext.tail, st)
|
||||
self.assertTrue(glued)
|
||||
@ -56,8 +76,8 @@ class ExtensionConnectorTestCase(TestCase):
|
||||
"""Test extension item connection
|
||||
"""
|
||||
ext = self.create(items.ExtensionItem)
|
||||
st = self.create(items.ClassItem, UML.Stereotype)
|
||||
cls = self.create(items.ClassItem, UML.Class)
|
||||
st = self.create(items.ClassItem, uml2.Stereotype)
|
||||
cls = self.create(items.ClassItem, uml2.Class)
|
||||
|
||||
self.connect(ext, ext.tail, st)
|
||||
self.connect(ext, ext.head, cls)
|
||||
|
@ -1,14 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import absolute_import
|
||||
from gaphor.tests import TestCase
|
||||
from gaphor.adapters.profiles.metaclasseditor import MetaclassNameEditor
|
||||
from gaphor.diagram import items
|
||||
from gaphor import UML
|
||||
from gaphor.UML import uml2
|
||||
import gtk
|
||||
|
||||
class MetaclassEditorTest(TestCase):
|
||||
|
||||
def test_name_selection(self):
|
||||
ci = self.create(items.MetaclassItem, UML.Class)
|
||||
ci = self.create(items.MetaclassItem, uml2.Class)
|
||||
ci.subject.name = 'Class'
|
||||
editor = MetaclassNameEditor(ci)
|
||||
page = editor.construct()
|
||||
|
@ -1,3 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2007-2017 Arjan Molenaar <gaphor@gmail.com>
|
||||
# Artur Wroblewski <wrobell@pld-linux.org>
|
||||
# Dan Yeaw <dan@yeaw.me>
|
||||
#
|
||||
# This file is part of Gaphor.
|
||||
#
|
||||
# Gaphor is free software: you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Library General Public License as published by the Free
|
||||
# Software Foundation, either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Gaphor 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 Library General Public License
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# along with Gaphor. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
Adapters for the Property Editor.
|
||||
|
||||
@ -26,6 +46,8 @@ TODO:
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import gobject
|
||||
import gtk
|
||||
import math
|
||||
@ -34,10 +56,11 @@ from gaphor.services.elementdispatcher import EventWatcher
|
||||
from gaphor.ui.interfaces import IPropertyPage
|
||||
from gaphor.diagram import items
|
||||
from zope import interface, component
|
||||
from gaphor import UML
|
||||
from gaphor.UML.interfaces import IAttributeChangeEvent
|
||||
from gaphor.UML import uml2, modelfactory
|
||||
import gaphas.item
|
||||
from gaphas.decorators import async
|
||||
from six.moves import range
|
||||
from six.moves import zip
|
||||
|
||||
class EditableTreeModel(gtk.ListStore):
|
||||
"""
|
||||
@ -198,11 +221,11 @@ class ClassAttributes(EditableTreeModel):
|
||||
def _get_rows(self):
|
||||
for attr in self._item.subject.ownedAttribute:
|
||||
if not attr.association:
|
||||
yield [UML.format(attr), attr.isStatic, attr]
|
||||
yield [format(attr), attr.isStatic, attr]
|
||||
|
||||
|
||||
def _create_object(self):
|
||||
attr = self.element_factory.create(UML.Property)
|
||||
attr = self.element_factory.create(uml2.Property)
|
||||
self._item.subject.ownedAttribute = attr
|
||||
return attr
|
||||
|
||||
@ -211,14 +234,14 @@ class ClassAttributes(EditableTreeModel):
|
||||
def _set_object_value(self, row, col, value):
|
||||
attr = row[-1]
|
||||
if col == 0:
|
||||
UML.parse(attr, value)
|
||||
row[0] = UML.format(attr)
|
||||
parse(attr, value)
|
||||
row[0] = format(attr)
|
||||
elif col == 1:
|
||||
attr.isStatic = not attr.isStatic
|
||||
row[1] = attr.isStatic
|
||||
elif col == 2:
|
||||
# Value in attribute object changed:
|
||||
row[0] = UML.format(attr)
|
||||
row[0] = format(attr)
|
||||
row[1] = attr.isStatic
|
||||
|
||||
|
||||
@ -234,11 +257,11 @@ class ClassOperations(EditableTreeModel):
|
||||
|
||||
def _get_rows(self):
|
||||
for operation in self._item.subject.ownedOperation:
|
||||
yield [UML.format(operation), operation.isAbstract, operation.isStatic, operation]
|
||||
yield [format(operation), operation.isAbstract, operation.isStatic, operation]
|
||||
|
||||
|
||||
def _create_object(self):
|
||||
operation = self.element_factory.create(UML.Operation)
|
||||
operation = self.element_factory.create(uml2.Operation)
|
||||
self._item.subject.ownedOperation = operation
|
||||
return operation
|
||||
|
||||
@ -247,8 +270,8 @@ class ClassOperations(EditableTreeModel):
|
||||
def _set_object_value(self, row, col, value):
|
||||
operation = row[-1]
|
||||
if col == 0:
|
||||
UML.parse(operation, value)
|
||||
row[0] = UML.format(operation)
|
||||
parse(operation, value)
|
||||
row[0] = format(operation)
|
||||
elif col == 1:
|
||||
operation.isAbstract = not operation.isAbstract
|
||||
row[1] = operation.isAbstract
|
||||
@ -256,7 +279,7 @@ class ClassOperations(EditableTreeModel):
|
||||
operation.isStatic = not operation.isStatic
|
||||
row[2] = operation.isStatic
|
||||
elif col == 3:
|
||||
row[0] = UML.format(operation)
|
||||
row[0] = format(operation)
|
||||
row[1] = operation.isAbstract
|
||||
row[2] = operation.isStatic
|
||||
|
||||
@ -296,7 +319,7 @@ class CommunicationMessageModel(EditableTreeModel):
|
||||
def _create_object(self):
|
||||
item = self._item
|
||||
subject = item.subject
|
||||
message = UML.model.create_message(self.element_factory, subject, self.inverted)
|
||||
message = modelfactory.create_message(self.element_factory, subject, self.inverted)
|
||||
item.add_message(message, self.inverted)
|
||||
return message
|
||||
|
||||
@ -455,7 +478,7 @@ def create_tree_view(model, names, tip='', ro_cols=None):
|
||||
tree_view.set_rules_hint(True)
|
||||
|
||||
n = model.get_n_columns() - 1
|
||||
for name, i in zip(names, range(n)):
|
||||
for name, i in zip(names, list(range(n))):
|
||||
col_type = model.get_column_type(i)
|
||||
if col_type == gobject.TYPE_STRING:
|
||||
renderer = gtk.CellRendererText()
|
||||
@ -491,7 +514,7 @@ class CommentItemPropertyPage(object):
|
||||
Property page for Comments
|
||||
"""
|
||||
interface.implements(IPropertyPage)
|
||||
component.adapts(UML.Comment)
|
||||
component.adapts(uml2.Comment)
|
||||
|
||||
order = 0
|
||||
|
||||
@ -549,14 +572,14 @@ class NamedElementPropertyPage(object):
|
||||
"""
|
||||
|
||||
interface.implements(IPropertyPage)
|
||||
component.adapts(UML.NamedElement)
|
||||
component.adapts(uml2.NamedElement)
|
||||
|
||||
order = 10
|
||||
|
||||
NAME_LABEL = _('Name')
|
||||
|
||||
def __init__(self, subject):
|
||||
assert subject is None or isinstance(subject, UML.NamedElement), '%s' % type(subject)
|
||||
assert subject is None or isinstance(subject, uml2.NamedElement), '%s' % type(subject)
|
||||
self.subject = subject
|
||||
self.watcher = EventWatcher(subject)
|
||||
self.size_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
|
||||
@ -611,7 +634,7 @@ class ClassPropertyPage(NamedElementPropertyPage):
|
||||
Adapter which shows a property page for a class view.
|
||||
"""
|
||||
|
||||
component.adapts(UML.Class)
|
||||
component.adapts(uml2.Class)
|
||||
|
||||
def __init__(self, subject):
|
||||
super(ClassPropertyPage, self).__init__(subject)
|
||||
@ -875,10 +898,10 @@ class DependencyPropertyPage(object):
|
||||
element_factory = inject('element_factory')
|
||||
|
||||
DEPENDENCY_TYPES = (
|
||||
(_('Dependency'), UML.Dependency),
|
||||
(_('Usage'), UML.Usage),
|
||||
(_('Realization'), UML.Realization),
|
||||
(_('Implementation'), UML.Implementation))
|
||||
(_('Dependency'), uml2.Dependency),
|
||||
(_('Usage'), uml2.Usage),
|
||||
(_('Realization'), uml2.Realization),
|
||||
(_('Implementation'), uml2.Implementation))
|
||||
|
||||
def __init__(self, item):
|
||||
super(DependencyPropertyPage, self).__init__()
|
||||
@ -1029,7 +1052,7 @@ class AssociationPropertyPage(NamedItemPropertyPage):
|
||||
for name, adapter in component.getAdapters([item,], IPropertyPage):
|
||||
adaptermap[name] = (adapter.order, name, adapter)
|
||||
|
||||
adapters = adaptermap.values()
|
||||
adapters = list(adaptermap.values())
|
||||
adapters.sort()
|
||||
return adapters
|
||||
|
||||
@ -1057,7 +1080,7 @@ class AssociationPropertyPage(NamedItemPropertyPage):
|
||||
expander.add(page)
|
||||
expander.show_all()
|
||||
vbox.pack_start(expander, expand=False)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
log.error('Could not construct property page for ' + name, exc_info=True)
|
||||
|
||||
component.provideAdapter(AssociationPropertyPage, name='Properties')
|
||||
@ -1069,7 +1092,7 @@ class AssociationEndPropertyPage(object):
|
||||
"""
|
||||
|
||||
interface.implements(IPropertyPage)
|
||||
component.adapts(UML.Property)
|
||||
component.adapts(uml2.Property)
|
||||
|
||||
order = 0
|
||||
|
||||
@ -1083,17 +1106,17 @@ class AssociationEndPropertyPage(object):
|
||||
vbox = gtk.VBox()
|
||||
|
||||
entry = gtk.Entry()
|
||||
#entry.set_text(UML.format(self.subject, visibility=True, is_derived=Truemultiplicity=True) or '')
|
||||
#entry.set_text(format(self.subject, visibility=True, is_derived=Truemultiplicity=True) or '')
|
||||
|
||||
# monitor subject attribute (all, cause it contains many children)
|
||||
changed_id = entry.connect('changed', self._on_end_name_change)
|
||||
def handler(event):
|
||||
if not entry.props.has_focus:
|
||||
entry.handler_block(changed_id)
|
||||
entry.set_text(UML.format(self.subject,
|
||||
entry.set_text(format(self.subject,
|
||||
visibility=True, is_derived=True,
|
||||
multiplicity=True) or '')
|
||||
#entry.set_text(UML.format(self.subject, multiplicity=True) or '')
|
||||
#entry.set_text(format(self.subject, multiplicity=True) or '')
|
||||
entry.handler_unblock(changed_id)
|
||||
handler(None)
|
||||
|
||||
@ -1139,12 +1162,12 @@ Enter attribute name and multiplicity, for example
|
||||
|
||||
@transactional
|
||||
def _on_end_name_change(self, entry):
|
||||
UML.parse(self.subject, entry.get_text())
|
||||
parse(self.subject, entry.get_text())
|
||||
|
||||
@transactional
|
||||
def _on_navigability_change(self, combo):
|
||||
nav = self.NAVIGABILITY[combo.get_active()]
|
||||
UML.model.set_navigability(self.subject.association, self.subject, nav)
|
||||
modelfactory.set_navigability(self.subject.association, self.subject, nav)
|
||||
|
||||
@transactional
|
||||
def _on_aggregation_change(self, combo):
|
||||
@ -1291,7 +1314,7 @@ class JoinNodePropertyPage(NamedItemPropertyPage):
|
||||
hbox = gtk.HBox()
|
||||
page.pack_start(hbox, expand=False)
|
||||
|
||||
if isinstance(subject, UML.JoinNode):
|
||||
if isinstance(subject, uml2.JoinNode):
|
||||
hbox = create_hbox_label(self, page, _('Join specification'))
|
||||
entry = gtk.Entry()
|
||||
entry.set_text(subject.joinSpec or '')
|
||||
@ -1311,7 +1334,7 @@ class JoinNodePropertyPage(NamedItemPropertyPage):
|
||||
@transactional
|
||||
def _on_join_spec_change(self, entry):
|
||||
value = entry.get_text().strip()
|
||||
print 'new joinspec', value
|
||||
print('new joinspec', value)
|
||||
self.subject.joinSpec = value
|
||||
|
||||
def _on_horizontal_change(self, button):
|
||||
@ -1362,10 +1385,10 @@ class FlowPropertyPageAbstract(NamedElementPropertyPage):
|
||||
# fixme: unify ObjectFlowPropertyPage and ControlFlowPropertyPage
|
||||
# after introducing common class for element editors
|
||||
class ControlFlowPropertyPage(FlowPropertyPageAbstract):
|
||||
component.adapts(UML.ControlFlow)
|
||||
component.adapts(uml2.ControlFlow)
|
||||
|
||||
class ObjectFlowPropertyPage(FlowPropertyPageAbstract):
|
||||
component.adapts(UML.ObjectFlow)
|
||||
component.adapts(uml2.ObjectFlow)
|
||||
|
||||
|
||||
component.provideAdapter(ControlFlowPropertyPage, name='Properties')
|
||||
|