mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-26 02:15:31 +02:00
Bug 196337 - Initial contribution of local terminal feature
This commit is contained in:
parent
d336005626
commit
dd398b77bb
41 changed files with 4154 additions and 0 deletions
17
org.eclipse.tm.terminal.local-feature/.project
Normal file
17
org.eclipse.tm.terminal.local-feature/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.tm.terminal.local-feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
15
org.eclipse.tm.terminal.local-feature/build.properties
Normal file
15
org.eclipse.tm.terminal.local-feature/build.properties
Normal file
|
@ -0,0 +1,15 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
bin.includes = feature.xml,\
|
||||
feature.properties,\
|
||||
epl-v10.html,\
|
||||
license.html
|
256
org.eclipse.tm.terminal.local-feature/epl-v10.html
Normal file
256
org.eclipse.tm.terminal.local-feature/epl-v10.html
Normal file
|
@ -0,0 +1,256 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head>
|
||||
|
||||
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Eclipse Public License - Version 1.0</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
size: 8.5in 11.0in;
|
||||
margin: 0.25in 0.5in 0.25in 0.5in;
|
||||
tab-interval: 0.5in;
|
||||
}
|
||||
p {
|
||||
margin-left: auto;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
p.list {
|
||||
margin-left: 0.5in;
|
||||
margin-top: 0.05em;
|
||||
margin-bottom: 0.05em;
|
||||
}
|
||||
</style></head><body lang="EN-US">
|
||||
|
||||
<p align="center"><b>Eclipse Public License - v 1.0</b></p>
|
||||
|
||||
<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
|
||||
PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
|
||||
DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
|
||||
AGREEMENT.</p>
|
||||
|
||||
<p><b>1. DEFINITIONS</b></p>
|
||||
|
||||
<p>"Contribution" means:</p>
|
||||
|
||||
<p class="list">a) in the case of the initial Contributor, the initial
|
||||
code and documentation distributed under this Agreement, and</p>
|
||||
<p class="list">b) in the case of each subsequent Contributor:</p>
|
||||
<p class="list">i) changes to the Program, and</p>
|
||||
<p class="list">ii) additions to the Program;</p>
|
||||
<p class="list">where such changes and/or additions to the Program
|
||||
originate from and are distributed by that particular Contributor. A
|
||||
Contribution 'originates' from a Contributor if it was added to the
|
||||
Program by such Contributor itself or anyone acting on such
|
||||
Contributor's behalf. Contributions do not include additions to the
|
||||
Program which: (i) are separate modules of software distributed in
|
||||
conjunction with the Program under their own license agreement, and (ii)
|
||||
are not derivative works of the Program.</p>
|
||||
|
||||
<p>"Contributor" means any person or entity that distributes
|
||||
the Program.</p>
|
||||
|
||||
<p>"Licensed Patents" mean patent claims licensable by a
|
||||
Contributor which are necessarily infringed by the use or sale of its
|
||||
Contribution alone or when combined with the Program.</p>
|
||||
|
||||
<p>"Program" means the Contributions distributed in accordance
|
||||
with this Agreement.</p>
|
||||
|
||||
<p>"Recipient" means anyone who receives the Program under
|
||||
this Agreement, including all Contributors.</p>
|
||||
|
||||
<p><b>2. GRANT OF RIGHTS</b></p>
|
||||
|
||||
<p class="list">a) Subject to the terms of this Agreement, each
|
||||
Contributor hereby grants Recipient a non-exclusive, worldwide,
|
||||
royalty-free copyright license to reproduce, prepare derivative works
|
||||
of, publicly display, publicly perform, distribute and sublicense the
|
||||
Contribution of such Contributor, if any, and such derivative works, in
|
||||
source code and object code form.</p>
|
||||
|
||||
<p class="list">b) Subject to the terms of this Agreement, each
|
||||
Contributor hereby grants Recipient a non-exclusive, worldwide,
|
||||
royalty-free patent license under Licensed Patents to make, use, sell,
|
||||
offer to sell, import and otherwise transfer the Contribution of such
|
||||
Contributor, if any, in source code and object code form. This patent
|
||||
license shall apply to the combination of the Contribution and the
|
||||
Program if, at the time the Contribution is added by the Contributor,
|
||||
such addition of the Contribution causes such combination to be covered
|
||||
by the Licensed Patents. The patent license shall not apply to any other
|
||||
combinations which include the Contribution. No hardware per se is
|
||||
licensed hereunder.</p>
|
||||
|
||||
<p class="list">c) Recipient understands that although each Contributor
|
||||
grants the licenses to its Contributions set forth herein, no assurances
|
||||
are provided by any Contributor that the Program does not infringe the
|
||||
patent or other intellectual property rights of any other entity. Each
|
||||
Contributor disclaims any liability to Recipient for claims brought by
|
||||
any other entity based on infringement of intellectual property rights
|
||||
or otherwise. As a condition to exercising the rights and licenses
|
||||
granted hereunder, each Recipient hereby assumes sole responsibility to
|
||||
secure any other intellectual property rights needed, if any. For
|
||||
example, if a third party patent license is required to allow Recipient
|
||||
to distribute the Program, it is Recipient's responsibility to acquire
|
||||
that license before distributing the Program.</p>
|
||||
|
||||
<p class="list">d) Each Contributor represents that to its knowledge it
|
||||
has sufficient copyright rights in its Contribution, if any, to grant
|
||||
the copyright license set forth in this Agreement.</p>
|
||||
|
||||
<p><b>3. REQUIREMENTS</b></p>
|
||||
|
||||
<p>A Contributor may choose to distribute the Program in object code
|
||||
form under its own license agreement, provided that:</p>
|
||||
|
||||
<p class="list">a) it complies with the terms and conditions of this
|
||||
Agreement; and</p>
|
||||
|
||||
<p class="list">b) its license agreement:</p>
|
||||
|
||||
<p class="list">i) effectively disclaims on behalf of all Contributors
|
||||
all warranties and conditions, express and implied, including warranties
|
||||
or conditions of title and non-infringement, and implied warranties or
|
||||
conditions of merchantability and fitness for a particular purpose;</p>
|
||||
|
||||
<p class="list">ii) effectively excludes on behalf of all Contributors
|
||||
all liability for damages, including direct, indirect, special,
|
||||
incidental and consequential damages, such as lost profits;</p>
|
||||
|
||||
<p class="list">iii) states that any provisions which differ from this
|
||||
Agreement are offered by that Contributor alone and not by any other
|
||||
party; and</p>
|
||||
|
||||
<p class="list">iv) states that source code for the Program is available
|
||||
from such Contributor, and informs licensees how to obtain it in a
|
||||
reasonable manner on or through a medium customarily used for software
|
||||
exchange.</p>
|
||||
|
||||
<p>When the Program is made available in source code form:</p>
|
||||
|
||||
<p class="list">a) it must be made available under this Agreement; and</p>
|
||||
|
||||
<p class="list">b) a copy of this Agreement must be included with each
|
||||
copy of the Program.</p>
|
||||
|
||||
<p>Contributors may not remove or alter any copyright notices contained
|
||||
within the Program.</p>
|
||||
|
||||
<p>Each Contributor must identify itself as the originator of its
|
||||
Contribution, if any, in a manner that reasonably allows subsequent
|
||||
Recipients to identify the originator of the Contribution.</p>
|
||||
|
||||
<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
|
||||
|
||||
<p>Commercial distributors of software may accept certain
|
||||
responsibilities with respect to end users, business partners and the
|
||||
like. While this license is intended to facilitate the commercial use of
|
||||
the Program, the Contributor who includes the Program in a commercial
|
||||
product offering should do so in a manner which does not create
|
||||
potential liability for other Contributors. Therefore, if a Contributor
|
||||
includes the Program in a commercial product offering, such Contributor
|
||||
("Commercial Contributor") hereby agrees to defend and
|
||||
indemnify every other Contributor ("Indemnified Contributor")
|
||||
against any losses, damages and costs (collectively "Losses")
|
||||
arising from claims, lawsuits and other legal actions brought by a third
|
||||
party against the Indemnified Contributor to the extent caused by the
|
||||
acts or omissions of such Commercial Contributor in connection with its
|
||||
distribution of the Program in a commercial product offering. The
|
||||
obligations in this section do not apply to any claims or Losses
|
||||
relating to any actual or alleged intellectual property infringement. In
|
||||
order to qualify, an Indemnified Contributor must: a) promptly notify
|
||||
the Commercial Contributor in writing of such claim, and b) allow the
|
||||
Commercial Contributor to control, and cooperate with the Commercial
|
||||
Contributor in, the defense and any related settlement negotiations. The
|
||||
Indemnified Contributor may participate in any such claim at its own
|
||||
expense.</p>
|
||||
|
||||
<p>For example, a Contributor might include the Program in a commercial
|
||||
product offering, Product X. That Contributor is then a Commercial
|
||||
Contributor. If that Commercial Contributor then makes performance
|
||||
claims, or offers warranties related to Product X, those performance
|
||||
claims and warranties are such Commercial Contributor's responsibility
|
||||
alone. Under this section, the Commercial Contributor would have to
|
||||
defend claims against the other Contributors related to those
|
||||
performance claims and warranties, and if a court requires any other
|
||||
Contributor to pay any damages as a result, the Commercial Contributor
|
||||
must pay those damages.</p>
|
||||
|
||||
<p><b>5. NO WARRANTY</b></p>
|
||||
|
||||
<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
|
||||
PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
|
||||
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
|
||||
OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement , including but not limited to
|
||||
the risks and costs of program errors, compliance with applicable laws,
|
||||
damage to or loss of data, programs or equipment, and unavailability or
|
||||
interruption of operations.</p>
|
||||
|
||||
<p><b>6. DISCLAIMER OF LIABILITY</b></p>
|
||||
|
||||
<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
|
||||
NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
|
||||
WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
|
||||
DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
|
||||
|
||||
<p><b>7. GENERAL</b></p>
|
||||
|
||||
<p>If any provision of this Agreement is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this Agreement, and without further action
|
||||
by the parties hereto, such provision shall be reformed to the minimum
|
||||
extent necessary to make such provision valid and enforceable.</p>
|
||||
|
||||
<p>If Recipient institutes patent litigation against any entity
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that the
|
||||
Program itself (excluding combinations of the Program with other
|
||||
software or hardware) infringes such Recipient's patent(s), then such
|
||||
Recipient's rights granted under Section 2(b) shall terminate as of the
|
||||
date such litigation is filed.</p>
|
||||
|
||||
<p>All Recipient's rights under this Agreement shall terminate if it
|
||||
fails to comply with any of the material terms or conditions of this
|
||||
Agreement and does not cure such failure in a reasonable period of time
|
||||
after becoming aware of such noncompliance. If all Recipient's rights
|
||||
under this Agreement terminate, Recipient agrees to cease use and
|
||||
distribution of the Program as soon as reasonably practicable. However,
|
||||
Recipient's obligations under this Agreement and any licenses granted by
|
||||
Recipient relating to the Program shall continue and survive.</p>
|
||||
|
||||
<p>Everyone is permitted to copy and distribute copies of this
|
||||
Agreement, but in order to avoid inconsistency the Agreement is
|
||||
copyrighted and may only be modified in the following manner. The
|
||||
Agreement Steward reserves the right to publish new versions (including
|
||||
revisions) of this Agreement from time to time. No one other than the
|
||||
Agreement Steward has the right to modify this Agreement. The Eclipse
|
||||
Foundation is the initial Agreement Steward. The Eclipse Foundation may
|
||||
assign the responsibility to serve as the Agreement Steward to a
|
||||
suitable separate entity. Each new version of the Agreement will be
|
||||
given a distinguishing version number. The Program (including
|
||||
Contributions) may always be distributed subject to the version of the
|
||||
Agreement under which it was received. In addition, after a new version
|
||||
of the Agreement is published, Contributor may elect to distribute the
|
||||
Program (including its Contributions) under the new version. Except as
|
||||
expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
|
||||
rights or licenses to the intellectual property of any Contributor under
|
||||
this Agreement, whether expressly, by implication, estoppel or
|
||||
otherwise. All rights in the Program not expressly granted under this
|
||||
Agreement are reserved.</p>
|
||||
|
||||
<p>This Agreement is governed by the laws of the State of New York and
|
||||
the intellectual property laws of the United States of America. No party
|
||||
to this Agreement will bring a legal action under this Agreement more
|
||||
than one year after the cause of action arose. Each party waives its
|
||||
rights to a jury trial in any resulting litigation.</p>
|
||||
|
||||
</body></html>
|
117
org.eclipse.tm.terminal.local-feature/feature.properties
Normal file
117
org.eclipse.tm.terminal.local-feature/feature.properties
Normal file
|
@ -0,0 +1,117 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
featureName=Target Management Terminal Local Connector
|
||||
description=A local connector implementation for the Terminal.
|
||||
copyright=\
|
||||
Copyright (c) 2008 Mirko Raner and others.\n\
|
||||
All rights reserved. This program and the accompanying materials\n\
|
||||
are made available under the terms of the Eclipse Public License v1.0\n\
|
||||
which accompanies this distribution, and is available at\n\
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
licenseURL=license.html
|
||||
license=\
|
||||
ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
|
||||
March 17, 2005\n\
|
||||
\n\
|
||||
Usage Of Content\n\
|
||||
\n\
|
||||
THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
|
||||
OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
|
||||
USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
|
||||
AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
|
||||
NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
|
||||
AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
|
||||
AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
|
||||
OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
|
||||
TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
|
||||
OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
|
||||
BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
|
||||
\n\
|
||||
Applicable Licenses\n\
|
||||
\n\
|
||||
Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
|
||||
is provided to you under the terms and conditions of the Eclipse Public\n\
|
||||
License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
|
||||
Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
|
||||
For purposes of the EPL, "Program" will mean the Content.\n\
|
||||
\n\
|
||||
Content includes, but is not limited to, source code, object code,\n\
|
||||
documentation and other files maintained in the Eclipse.org CVS\n\
|
||||
repository ("Repository") in CVS modules ("Modules") and made available\n\
|
||||
as downloadable archives ("Downloads").\n\
|
||||
\n\
|
||||
- Content may be structured and packaged into modules to facilitate delivering,\n\
|
||||
extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
|
||||
plug-in fragments ("Fragments"), and features ("Features").\n\
|
||||
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\
|
||||
in a directory named "plugins".\n\
|
||||
- A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
|
||||
Each Feature may be packaged as a sub-directory in a directory named "features".\n\
|
||||
Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
|
||||
numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
|
||||
- Features may also include other Features ("Included Features"). Within a Feature, files\n\
|
||||
named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
|
||||
\n\
|
||||
Features may also include other Features ("Included Features"). Files named\n\
|
||||
"feature.xml" may contain a list of the names and version numbers of\n\
|
||||
Included Features.\n\
|
||||
\n\
|
||||
The terms and conditions governing Plug-ins and Fragments should be\n\
|
||||
contained in files named "about.html" ("Abouts"). The terms and\n\
|
||||
conditions governing Features and Included Features should be contained\n\
|
||||
in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
|
||||
Licenses may be located in any directory of a Download or Module\n\
|
||||
including, but not limited to the following locations:\n\
|
||||
\n\
|
||||
- The top-level (root) directory\n\
|
||||
- Plug-in and Fragment directories\n\
|
||||
- Inside Plug-ins and Fragments packaged as JARs\n\
|
||||
- Sub-directories of the directory named "src" of certain Plug-ins\n\
|
||||
- Feature directories\n\
|
||||
\n\
|
||||
Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
|
||||
Eclipse Update Manager, you must agree to a license ("Feature Update\n\
|
||||
License") during the installation process. If the Feature contains\n\
|
||||
Included Features, the Feature Update License should either provide you\n\
|
||||
with the terms and conditions governing the Included Features or inform\n\
|
||||
you where you can locate them. Feature Update Licenses may be found in\n\
|
||||
the "license" property of files named "feature.properties". Such Abouts,\n\
|
||||
Feature Licenses and Feature Update Licenses contain the terms and\n\
|
||||
conditions (or references to such terms and conditions) that govern your\n\
|
||||
use of the associated Content in that directory.\n\
|
||||
\n\
|
||||
THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
|
||||
TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
|
||||
SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
|
||||
\n\
|
||||
- Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
|
||||
- Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
|
||||
- Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
|
||||
- IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
|
||||
- Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
|
||||
- Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
|
||||
\n\
|
||||
IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
|
||||
TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
|
||||
is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
|
||||
govern that particular Content.\n\
|
||||
\n\
|
||||
Cryptography\n\
|
||||
\n\
|
||||
Content may contain encryption software. The country in which you are\n\
|
||||
currently may have restrictions on the import, possession, and use,\n\
|
||||
and/or re-export to another country, of encryption software. BEFORE\n\
|
||||
using any encryption software, please check the country's laws,\n\
|
||||
regulations and policies concerning the import, possession, or use,\n\
|
||||
and re-export of encryption software, to see if this is permitted.\n\
|
||||
\n\
|
||||
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
|
47
org.eclipse.tm.terminal.local-feature/feature.xml
Normal file
47
org.eclipse.tm.terminal.local-feature/feature.xml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
# Copyright (c) 2008 Mirko Raner and others
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
-->
|
||||
<feature id="org.eclipse.tm.terminal.local"
|
||||
label="%featureName"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="Mirko Raner">
|
||||
|
||||
<description>
|
||||
%description
|
||||
</description>
|
||||
|
||||
<copyright>
|
||||
%copyright
|
||||
</copyright>
|
||||
|
||||
<license url="%licenseURL">
|
||||
%license
|
||||
</license>
|
||||
|
||||
<requires>
|
||||
<import plugin="org.eclipse.tm.terminal" version="2.0.0" match="compatible"/>
|
||||
<import plugin="org.eclipse.cdt.core" version="5.0.0" match="compatible"/>
|
||||
<import plugin="org.eclipse.core.runtime"/>
|
||||
<import plugin="org.eclipse.debug.core"/>
|
||||
<import plugin="org.eclipse.debug.ui"/>
|
||||
<import plugin="org.eclipse.jface"/>
|
||||
<import plugin="org.eclipse.ui"/>
|
||||
<import plugin="org.eclipse.ui.externaltools"/>
|
||||
</requires>
|
||||
|
||||
<plugin id="org.eclipse.tm.terminal.local"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"
|
||||
/>
|
||||
|
||||
</feature>
|
79
org.eclipse.tm.terminal.local-feature/license.html
Normal file
79
org.eclipse.tm.terminal.local-feature/license.html
Normal file
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
|
||||
<title>Eclipse.org Software User Agreement</title>
|
||||
</head>
|
||||
|
||||
<body lang="EN-US" link=blue vlink=purple>
|
||||
<h2>Eclipse Foundation Software User Agreement</h2>
|
||||
<p>March 17, 2005</p>
|
||||
|
||||
<h3>Usage Of Content</h3>
|
||||
|
||||
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
|
||||
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
|
||||
CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
|
||||
OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
|
||||
NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
|
||||
CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
|
||||
|
||||
<h3>Applicable Licenses</h3>
|
||||
|
||||
<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
|
||||
("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS
|
||||
modules ("Modules") and made available as downloadable archives ("Downloads").</p>
|
||||
|
||||
<ul>
|
||||
<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
|
||||
<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
|
||||
<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
|
||||
and/or Fragments associated with that Feature.</li>
|
||||
<li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
|
||||
</ul>
|
||||
|
||||
<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
|
||||
Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
|
||||
including, but not limited to the following locations:</p>
|
||||
|
||||
<ul>
|
||||
<li>The top-level (root) directory</li>
|
||||
<li>Plug-in and Fragment directories</li>
|
||||
<li>Inside Plug-ins and Fragments packaged as JARs</li>
|
||||
<li>Sub-directories of the directory named "src" of certain Plug-ins</li>
|
||||
<li>Feature directories</li>
|
||||
</ul>
|
||||
|
||||
<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the
|
||||
installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
|
||||
inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
|
||||
Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
|
||||
that directory.</p>
|
||||
|
||||
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
|
||||
OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
|
||||
|
||||
<ul>
|
||||
<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
|
||||
<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
|
||||
<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
|
||||
<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>
|
||||
<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
|
||||
<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
|
||||
</ul>
|
||||
|
||||
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
|
||||
contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
|
||||
|
||||
<h3>Cryptography</h3>
|
||||
|
||||
<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
|
||||
another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
|
||||
possession, or use, and re-export of encryption software, to see if this is permitted.</p>
|
||||
|
||||
<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
|
||||
</body>
|
||||
</html>
|
7
org.eclipse.tm.terminal.local/.classpath
Normal file
7
org.eclipse.tm.terminal.local/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
org.eclipse.tm.terminal.local/.project
Normal file
28
org.eclipse.tm.terminal.local/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.tm.terminal.local</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,83 @@
|
|||
#Tue Jul 29 00:26:52 PDT 2008
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.4
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.3
|
20
org.eclipse.tm.terminal.local/META-INF/MANIFEST.MF
Normal file
20
org.eclipse.tm.terminal.local/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,20 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.tm.terminal.local;singleton:=true
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: org.eclipse.tm.internal.terminal.local.LocalTerminalActivator
|
||||
Bundle-Localization: plugin
|
||||
Bundle-Vendor: %providerName
|
||||
Require-Bundle: org.eclipse.tm.terminal;bundle-version="2.0.0",
|
||||
org.eclipse.cdt.core;bundle-version="5.0.0",
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.debug.core,
|
||||
org.eclipse.debug.ui,
|
||||
org.eclipse.jface,
|
||||
org.eclipse.ui,
|
||||
org.eclipse.ui.externaltools
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Eclipse-LazyStart: true
|
||||
Import-Package: org.eclipse.core.variables
|
37
org.eclipse.tm.terminal.local/about.html
Normal file
37
org.eclipse.tm.terminal.local/about.html
Normal file
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<!--
|
||||
# Copyright (c) 2008 Mirko Raner and others
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>About</TITLE>
|
||||
<META HTTP-EQUIV=Content-Type CONTENT="text/html; charset=ISO-8859-1">
|
||||
</HEAD>
|
||||
<BODY LANG="EN-US">
|
||||
<H2>About This Content</H2>
|
||||
<P>
|
||||
August 4, 2008
|
||||
<P>
|
||||
<H3>License</H3>
|
||||
|
||||
Mirko Raner makes available all content in this plug-in ("Content").
|
||||
Unless otherwise indicated below, the Content is provided to you under the terms and conditions of
|
||||
the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available at
|
||||
<A HREF="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>.
|
||||
For purposes of the EPL, "Program" will mean the Content.
|
||||
<P>
|
||||
If you did not receive this Content directly from Mirko Raner, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and
|
||||
conditions may apply to your use of any object code in the Content. Check the Redistributor's
|
||||
license that was provided with the Content. If no such license exists, contact the Redistributor.
|
||||
Unless otherwise indicated below, the terms and conditions of the EPL still apply to any source
|
||||
code in the Content.
|
||||
</BODY>
|
||||
</HTML>
|
13
org.eclipse.tm.terminal.local/about.ini
Normal file
13
org.eclipse.tm.terminal.local/about.ini
Normal file
|
@ -0,0 +1,13 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
featureImage=icons/terminal-local.png
|
||||
aboutText=%feature.information
|
12
org.eclipse.tm.terminal.local/about.mappings
Normal file
12
org.eclipse.tm.terminal.local/about.mappings
Normal file
|
@ -0,0 +1,12 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
0=@build@
|
17
org.eclipse.tm.terminal.local/about.properties
Normal file
17
org.eclipse.tm.terminal.local/about.properties
Normal file
|
@ -0,0 +1,17 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
feature.information=Target Management Terminal Local Connector\n\
|
||||
\n\
|
||||
Version: {featureVersion}\n\
|
||||
\n\
|
||||
(c) Copyright Mirko Raner and others, 2008. All rights reserved.\n\
|
||||
Visit http://www.eclipse.org/dsdp/tm
|
11
org.eclipse.tm.terminal.local/build.properties
Normal file
11
org.eclipse.tm.terminal.local/build.properties
Normal file
|
@ -0,0 +1,11 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = plugin.xml,\
|
||||
plugin.properties,\
|
||||
about.html,\
|
||||
about.ini,\
|
||||
about.mappings,\
|
||||
about.properties,\
|
||||
icons/,\
|
||||
META-INF/,\
|
||||
.
|
BIN
org.eclipse.tm.terminal.local/icons/terminal-launch.gif
Normal file
BIN
org.eclipse.tm.terminal.local/icons/terminal-launch.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 601 B |
BIN
org.eclipse.tm.terminal.local/icons/terminal-local.png
Normal file
BIN
org.eclipse.tm.terminal.local/icons/terminal-local.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
16
org.eclipse.tm.terminal.local/plugin.properties
Normal file
16
org.eclipse.tm.terminal.local/plugin.properties
Normal file
|
@ -0,0 +1,16 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
pluginName=Local Terminal Connector
|
||||
providerName=Mirko Raner
|
||||
terminalLaunch=Terminal
|
||||
terminalLaunchDescription=Run a program in a terminal
|
||||
localConnection=Local program
|
63
org.eclipse.tm.terminal.local/plugin.xml
Normal file
63
org.eclipse.tm.terminal.local/plugin.xml
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.3"?>
|
||||
<!--
|
||||
# Copyright (c) 2008 Mirko Raner and others
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial API and implementation
|
||||
-->
|
||||
<plugin>
|
||||
|
||||
<!-- Terminal connector extension (the primary contribution of this plug-in): -->
|
||||
<!-- -->
|
||||
<extension point="org.eclipse.tm.terminal.terminalConnectors">
|
||||
<connector name="%localConnection"
|
||||
id="org.eclipse.tm.internal.terminal.local.LocalTerminalConnector"
|
||||
class="org.eclipse.tm.internal.terminal.local.LocalTerminalConnector"
|
||||
/>
|
||||
</extension>
|
||||
|
||||
<!-- Process factory for terminal processes (necessary for preventing a standard console from -->
|
||||
<!-- being created): -->
|
||||
<!-- -->
|
||||
<extension point="org.eclipse.debug.core.processFactories">
|
||||
<processFactory id="org.eclipse.tm.terminal.localProcess.factory"
|
||||
class="org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory"
|
||||
/>
|
||||
</extension>
|
||||
|
||||
<!-- Launch configuration type for terminal launches: -->
|
||||
<!-- -->
|
||||
<extension point="org.eclipse.debug.core.launchConfigurationTypes">
|
||||
<launchConfigurationType name="%terminalLaunch"
|
||||
id="org.eclipse.tm.terminal.local.launch"
|
||||
delegate="org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchDelegate"
|
||||
category="org.eclipse.ui.externaltools"
|
||||
modes="run"
|
||||
/>
|
||||
</extension>
|
||||
|
||||
<!-- Launch configuration icon used in the Launch Configuration dialog: -->
|
||||
<!-- -->
|
||||
<extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
|
||||
<launchConfigurationTypeImage id="org.eclipse.tm.terminal.local.launch.icon"
|
||||
configTypeID="org.eclipse.tm.terminal.local.launch"
|
||||
icon="icons/terminal-launch.gif"
|
||||
/>
|
||||
</extension>
|
||||
|
||||
<!-- Launch configuration tab group for configuring workbench launches: -->
|
||||
<!-- -->
|
||||
<extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
|
||||
<launchConfigurationTabGroup type="org.eclipse.tm.terminal.local.launch"
|
||||
id="org.eclipse.tm.terminal.local.launch.tabs"
|
||||
description="%terminalLaunchDescription"
|
||||
class="org.eclipse.tm.internal.terminal.local.launch.ui.LocalTerminalLaunchTabGroup"
|
||||
/>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
|
@ -0,0 +1,75 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.tm.terminal.ssh/ISshSettings
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
|
||||
|
||||
/**
|
||||
* The interface {@link ILocalTerminalSettings} defines the public interface for connector-specific
|
||||
* settings needed by the {@link LocalTerminalConnector}. The interface is implemented by class
|
||||
* {@link LocalTerminalSettings}.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public interface ILocalTerminalSettings {
|
||||
|
||||
/**
|
||||
* The line separator setting CR (carriage return only; for example, used by Mac OS 9).
|
||||
*/
|
||||
public final static String LINE_SEPARATOR_CR = "\\r"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The line separator setting CRLF (carriage return and line feed; for example, used by
|
||||
* Windows).
|
||||
*/
|
||||
public final static String LINE_SEPARATOR_CRLF = "\\r\\n"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The line separator setting LF (line feed only; used by all UNIX-based systems).
|
||||
*/
|
||||
public final static String LINE_SEPARATOR_LF = "\\n"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Loads the settings from a specified {@link ISettingsStore}.
|
||||
*
|
||||
* TODO: the {@link #load(ISettingsStore)} method should probably extracted to a super-interface
|
||||
* as it appears to be common to all customized settings interfaces
|
||||
*
|
||||
* @param store the {@link ISettingsStore} to load the settings from
|
||||
*/
|
||||
public abstract void load(ISettingsStore store);
|
||||
|
||||
/**
|
||||
* Saves the settings to a specified {@link ISettingsStore}.
|
||||
*
|
||||
* TODO: the {@link #save(ISettingsStore)} method should probably extracted to a super-interface
|
||||
* as it appears to be common to all customized settings interfaces
|
||||
*
|
||||
* @param store the {@link ISettingsStore} for storing the settings
|
||||
*/
|
||||
public abstract void save(ISettingsStore store);
|
||||
|
||||
/**
|
||||
* Gets the name of the launch configuration that will be started in the terminal.
|
||||
*
|
||||
* @return the launch configuration name
|
||||
*/
|
||||
public abstract String getLaunchConfigurationName();
|
||||
|
||||
/**
|
||||
* Sets the name of the launch configuration that will be started in the terminal.
|
||||
*
|
||||
* @param configurationName the launch configuration name
|
||||
*/
|
||||
public abstract void setLaunchConfigurationName(String configurationName);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalActivator} is the bundle activator for the Local Terminal
|
||||
* Connector plug-in.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalActivator extends AbstractUIPlugin {
|
||||
|
||||
/**
|
||||
* The plug-in ID of the Local Terminal Connector plug-in.
|
||||
*/
|
||||
public static final String PLUGIN_ID = "org.eclipse.tm.terminal.local"; //$NON-NLS-1$
|
||||
|
||||
private static LocalTerminalActivator plugin;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalActivator}.
|
||||
*/
|
||||
public LocalTerminalActivator() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared plug-in instance.
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static LocalTerminalActivator getDefault() {
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image descriptor for the image file at the given plug-in relative path.
|
||||
*
|
||||
* @param path the path to the image
|
||||
* @return the image descriptor
|
||||
*/
|
||||
public static ImageDescriptor getImageDescriptor(String path) {
|
||||
|
||||
return imageDescriptorFromPlugin(PLUGIN_ID, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the bundle and initializes the shared plug-in reference.
|
||||
*
|
||||
* @param context the {@link BundleContext}
|
||||
*
|
||||
* @see AbstractUIPlugin#start(BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the bundle and resets the the shared plug-in reference.
|
||||
*
|
||||
* @param context the {@link BundleContext}
|
||||
*
|
||||
* @see AbstractUIPlugin#stop(BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] initial implementation; some methods adapted from
|
||||
* org.eclipse.tm.terminal.ssh/SshConnector
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugEvent;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.IDebugEventSetListener;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.debug.core.model.IStreamMonitor;
|
||||
import org.eclipse.debug.core.model.IStreamsProxy;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
|
||||
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory;
|
||||
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessRegistry;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnectorImpl;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalConnector} provides a terminal connector implementation for
|
||||
* connecting to local programs (for example, a locally running <code>bash</code> shell or
|
||||
* <code>vi</code> editor).
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class LocalTerminalConnector extends TerminalConnectorImpl
|
||||
implements IDebugEventSetListener {
|
||||
|
||||
// Shorthand for attribute names:
|
||||
//
|
||||
private final static String ATTR_CAPTURE_IN_CONSOLE = IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE;
|
||||
private final static String ATTR_CAPTURE_OUTPUT = DebugPlugin.ATTR_CAPTURE_OUTPUT;
|
||||
private final static String ATTR_PROCESS_FACTORY_ID = DebugPlugin.ATTR_PROCESS_FACTORY_ID;
|
||||
|
||||
private LocalTerminalOutputStream terminalToLocalProcessStream;
|
||||
private LocalTerminalOutputListener outputListener;
|
||||
private LocalTerminalOutputListener errorListener;
|
||||
private ILocalTerminalSettings settings;
|
||||
private IStreamMonitor outputMonitor;
|
||||
private IStreamMonitor errorMonitor;
|
||||
private IProcess process;
|
||||
private ILaunch launch;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalConnector}. This constructor is invoked by the framework.
|
||||
*/
|
||||
public LocalTerminalConnector() {
|
||||
|
||||
settings = new LocalTerminalSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the connector's settings from the specified store.
|
||||
*
|
||||
* @param store the {@link ISettingsStore}
|
||||
*
|
||||
* @see TerminalConnectorImpl#load(ISettingsStore)
|
||||
*
|
||||
* TODO: the load(ISettingsStore) method should probably be made abstract in
|
||||
* TerminalConnectorImpl, otherwise it is not immediately clear that clients need to
|
||||
* override this method if custom settings are necessary (which they usually are).
|
||||
* Maybe the whole settings store mechanism should be redesigned. The current scheme
|
||||
* requires clients to implement load/save methods in their connector implementation
|
||||
* classes (necessity to override is not immediately obvious) and in the settings store
|
||||
* implementations (not enforced at all; merely expected by convention). Structurally,
|
||||
* all client implementations look more or less the same, and probably could be handled
|
||||
* by the framework in a uniform way. Maybe a configuration mechanism using attributes
|
||||
* (like, for example, ILaunchConfiguration) might be beneficial here.
|
||||
*/
|
||||
public void load(ISettingsStore store) {
|
||||
|
||||
settings.load(store);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the connector's settings into the specified store.
|
||||
* See {@link #load(ISettingsStore)} for additional notes.
|
||||
*
|
||||
* @param store the {@link ISettingsStore}
|
||||
*
|
||||
* @see TerminalConnectorImpl#save(ISettingsStore)
|
||||
*/
|
||||
public void save(ISettingsStore store) {
|
||||
|
||||
settings.save(store);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link ISettingsPage} for the settings of this connector.
|
||||
*
|
||||
* @return a new page that can be used in a dialog to setup this connection, or
|
||||
* <code>null</code> if the connection cannot be customized or configured
|
||||
*
|
||||
* @see TerminalConnectorImpl#makeSettingsPage()
|
||||
*/
|
||||
public ISettingsPage makeSettingsPage() {
|
||||
|
||||
return new LocalTerminalSettingsPage(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that represents the settings of the connection.
|
||||
*
|
||||
* @return the name of the launch configuration that is running in the terminal
|
||||
*
|
||||
* @see TerminalConnectorImpl#getSettingsSummary()
|
||||
* @see ILocalTerminalSettings#getLaunchConfigurationName()
|
||||
*/
|
||||
public String getSettingsSummary() {
|
||||
|
||||
return settings.getLaunchConfigurationName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if local echo is required.
|
||||
*
|
||||
* @return <code>true</code> if the connection settings specify that local echo is enable,
|
||||
* <code>false</code> otherwise
|
||||
*
|
||||
* @see TerminalConnectorImpl#isLocalEcho()
|
||||
* @see LocalTerminalLaunchUtilities#ATTR_LOCAL_ECHO
|
||||
*/
|
||||
public boolean isLocalEcho() {
|
||||
|
||||
return LocalTerminalUtilities.getLocalEcho(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link OutputStream} that writes to the local program's standard input. For the
|
||||
* stream in the other direction (remote to terminal) see
|
||||
* {@link ITerminalControl#getRemoteToTerminalOutputStream()}.
|
||||
*
|
||||
* @return the terminal-to-remote-stream (bytes written to this stream will be sent to the
|
||||
* local program)
|
||||
*/
|
||||
public OutputStream getTerminalToRemoteStream() {
|
||||
|
||||
return terminalToLocalProcessStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a locally launched program to the {@link ITerminalControl}.
|
||||
*
|
||||
* @param control the {@link ITerminalControl} through which the user can interact with the
|
||||
* program
|
||||
*/
|
||||
public void connect(ITerminalControl control) {
|
||||
|
||||
super.connect(control);
|
||||
control.setState(TerminalState.CONNECTING);
|
||||
ILaunchConfigurationWorkingCopy workingCopy = null;
|
||||
ILaunchConfiguration configuration = null;
|
||||
try {
|
||||
|
||||
String configurationName = settings.getLaunchConfigurationName();
|
||||
configuration = LocalTerminalUtilities.findLaunchConfiguration(configurationName);
|
||||
|
||||
// Always set the the process factory ID and enable console output (there is no need
|
||||
// to restore these attributes afterwards; disabling console output does not make
|
||||
// sense for terminal launches and will be overridden when the configuration is
|
||||
// actually launched):
|
||||
//
|
||||
workingCopy = configuration.getWorkingCopy();
|
||||
workingCopy.setAttribute(ATTR_CAPTURE_OUTPUT, true);
|
||||
workingCopy.setAttribute(ATTR_CAPTURE_IN_CONSOLE, true);
|
||||
workingCopy.setAttribute(ATTR_PROCESS_FACTORY_ID, LocalTerminalProcessFactory.ID);
|
||||
configuration = workingCopy.doSave();
|
||||
launch = configuration.launch(ILaunchManager.RUN_MODE, null);
|
||||
|
||||
// To prevent a console from being allocated, the launch will actually not contain a
|
||||
// reference to the runtime process. The process has to be obtained from the
|
||||
// LocalTerminalProcessRegistry instead:
|
||||
//
|
||||
process = LocalTerminalProcessRegistry.getFromLaunch(launch);
|
||||
IStreamsProxy streamsProxy = process.getStreamsProxy();
|
||||
|
||||
// Hook up standard input:
|
||||
//
|
||||
terminalToLocalProcessStream = new LocalTerminalOutputStream(process, settings);
|
||||
|
||||
// Hook up standard output:
|
||||
//
|
||||
outputMonitor = streamsProxy.getOutputStreamMonitor();
|
||||
outputListener = new LocalTerminalOutputListener(control, settings);
|
||||
outputMonitor.addListener(outputListener);
|
||||
outputListener.streamAppended(outputMonitor.getContents(), outputMonitor);
|
||||
|
||||
// Hook up standard error:
|
||||
//
|
||||
errorMonitor = streamsProxy.getErrorStreamMonitor();
|
||||
errorListener = new LocalTerminalOutputListener(control, settings);
|
||||
errorMonitor.addListener(errorListener);
|
||||
errorListener.streamAppended(errorMonitor.getContents(), errorMonitor);
|
||||
//
|
||||
// TODO: add proper synchronization for incoming data from stdout and stderr:
|
||||
// currently, the data gets sometimes processed in the wrong order, for example,
|
||||
// the next prompt (which shells like bash print to stderr) sometimes appears
|
||||
// before the command's proper output that was sent to stdout. For example,
|
||||
// you get:
|
||||
//
|
||||
// $ echo hello
|
||||
// $ hello
|
||||
//
|
||||
// instead of the correct output of:
|
||||
//
|
||||
// $ echo hello
|
||||
// hello
|
||||
// $
|
||||
|
||||
// Listen for process termination and update the terminal state:
|
||||
//
|
||||
DebugPlugin.getDefault().addDebugEventListener(this);
|
||||
control.setState(TerminalState.CONNECTED);
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the connector if it is currently connected or does nothing otherwise. This method
|
||||
* will try to terminate the underlying launched process and will remove all registered
|
||||
* listeners.
|
||||
*/
|
||||
public void doDisconnect() {
|
||||
|
||||
try {
|
||||
|
||||
removeAllListeners();
|
||||
|
||||
// To prevent a console from being allocated, Terminal launches don't have an IProcess
|
||||
// associated with them while they are running. However, to properly terminate a launch
|
||||
// the launch has to contain at least one process that can be terminated (launches
|
||||
// without processes effectively cannot be terminated):
|
||||
//
|
||||
LocalTerminalProcessRegistry.addProcessBackToFinishedLaunch(launch);
|
||||
|
||||
// Now, terminate the process if it hasn't been terminated already:
|
||||
//
|
||||
if (launch.canTerminate()) {
|
||||
|
||||
launch.terminate();
|
||||
//
|
||||
// NOTE: canTerminate() merely indicates that the launch has not been terminated
|
||||
// previously already
|
||||
}
|
||||
}
|
||||
catch (DebugException couldNotTerminate) {
|
||||
|
||||
Logger.logException(couldNotTerminate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for self-induced termination of the launched process. For example, this method will
|
||||
* be notified if a launched shell is terminated by pressing Control-D or by calling
|
||||
* <code>exit</code>, or if a <code>vi</code> editor is terminated by means of a
|
||||
* <code>:q!</code> command.
|
||||
*
|
||||
* @param event the debug events
|
||||
*
|
||||
* @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
|
||||
*/
|
||||
public void handleDebugEvents(DebugEvent[] event) {
|
||||
|
||||
int numberOfEvents = event.length;
|
||||
for (int index = 0; index < numberOfEvents; index++) {
|
||||
|
||||
if (event[index].getSource().equals(process)
|
||||
&& (event[index].getKind() == DebugEvent.TERMINATE)) {
|
||||
|
||||
fControl.setState(TerminalState.CLOSED);
|
||||
removeAllListeners();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any listeners that the {@link LocalTerminalConnector} might have registered in its
|
||||
* {@link #connect(ITerminalControl)} method. This method is necessary for clean-up when a
|
||||
* connection is closed. It prevents that orphaned or meaningless listeners keep accumulating
|
||||
* on certain objects.
|
||||
*/
|
||||
protected void removeAllListeners() {
|
||||
|
||||
if (outputMonitor != null && outputListener != null) {
|
||||
|
||||
outputMonitor.removeListener(outputListener);
|
||||
}
|
||||
if (errorMonitor != null && errorListener != null) {
|
||||
|
||||
errorMonitor.removeListener(errorListener);
|
||||
}
|
||||
DebugPlugin.getDefault().removeDebugEventListener(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.jface.viewers.BaseLabelProvider;
|
||||
import org.eclipse.jface.viewers.ILabelProvider;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalLaunchLabelProvider} is an {@link ILabelProvider} for lists (or
|
||||
* tables) of {@link ILaunchConfiguration}s. It returns a configuration's name as the text label,
|
||||
* and the configuration type's regular icon as the image label.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalLaunchLabelProvider extends BaseLabelProvider implements ILabelProvider {
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalLaunchLabelProvider}.
|
||||
*/
|
||||
public LocalTerminalLaunchLabelProvider() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image for the label of the given element.
|
||||
*
|
||||
* @param element the element for which the image was requested
|
||||
* @return the image, or <code>null</code> if no image could be found
|
||||
*
|
||||
* @see ILabelProvider#getImage(Object)
|
||||
*/
|
||||
public Image getImage(Object element) {
|
||||
|
||||
if (element instanceof ILaunchConfiguration) {
|
||||
|
||||
return LocalTerminalLaunchUtilities.getImage((ILaunchConfiguration)element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for the label of the given element.
|
||||
*
|
||||
* @param element the element for which to provide the label text
|
||||
* @return the text string used to label the element, or <code>null</code> if there is no text
|
||||
* label for the given object
|
||||
*
|
||||
* @see ILabelProvider#getText(Object)
|
||||
*/
|
||||
public String getText(Object element) {
|
||||
|
||||
if (element instanceof ILaunchConfiguration) {
|
||||
|
||||
return ((ILaunchConfiguration)element).getName();
|
||||
}
|
||||
return String.valueOf(element);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationType;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalLaunchListProvider} is a {@link IStructuredContentProvider} that
|
||||
* provides a list of all {@link ILaunchConfiguration}s of the type "External Tools"/"Program".
|
||||
* Those launch configurations can be used to start a new session in the Terminal View.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class LocalTerminalLaunchListProvider implements IStructuredContentProvider {
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalLaunchListProvider}.
|
||||
*/
|
||||
public LocalTerminalLaunchListProvider() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the matching {@link ILaunchConfiguration}s for the given input element. This content
|
||||
* provider does not really use the concept of "input" because the input can only be obtained in
|
||||
* one way (from the {@link ILaunchManager}.
|
||||
*
|
||||
* @param input the input element (not checked or used by this method)
|
||||
* @return the matching {@link ILaunchConfiguration}s
|
||||
*
|
||||
* @see IStructuredContentProvider#getElements(Object)
|
||||
*/
|
||||
public Object[] getElements(Object input) {
|
||||
|
||||
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
|
||||
ILaunchConfigurationType type = LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE;
|
||||
ILaunchConfiguration[] configurations = null;
|
||||
try {
|
||||
|
||||
configurations = launchManager.getLaunchConfigurations(type);
|
||||
}
|
||||
catch (CoreException couldNotObtainLaunchConfigurations) {
|
||||
|
||||
Logger.logException(couldNotObtainLaunchConfigurations);
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of this {@link LocalTerminalLaunchListProvider}. Currently, there is no additional
|
||||
* clean-up necessary, and this method is empty.
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
|
||||
// Does nothing...
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the {@link LocalTerminalLaunchListProvider} that its input has changed. This method
|
||||
* is currently empty because {@link LocalTerminalLaunchListProvider} is not aware of the
|
||||
* concept of "input"
|
||||
*
|
||||
* @see #getElements(Object)
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
|
||||
*/
|
||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||
|
||||
// Does nothing...
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalMessages} provides localization keys to internationalized display
|
||||
* messages used by the Local Terminal Connector.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class LocalTerminalMessages extends NLS {
|
||||
|
||||
static {
|
||||
|
||||
NLS.initializeMessages(LocalTerminalMessages.class.getName(), LocalTerminalMessages.class);
|
||||
}
|
||||
|
||||
private LocalTerminalMessages() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/** The title for the launch configuration selection: "Launch configuration:". */
|
||||
public static String launchConfiguration;
|
||||
|
||||
/** The label for the "New..." button. */
|
||||
public static String labelNew;
|
||||
|
||||
/** The label for the "Edit..." button. */
|
||||
public static String labelEdit;
|
||||
|
||||
/** The label for the "Enable terminal echo" check box. */
|
||||
public static String enableLocalEcho;
|
||||
|
||||
/** The label for the "Send SIGINT when Ctrl-C is pressed" check box. */
|
||||
public static String sendInterruptOnCtrlC;
|
||||
|
||||
/** The line separator option "LF". */
|
||||
public static String lineSeparatorLF;
|
||||
|
||||
/** The line separator option "CR". */
|
||||
public static String lineSeparatorCR;
|
||||
|
||||
/** The line separator option "CRLF". */
|
||||
public static String lineSeparatorCRLF;
|
||||
|
||||
/** The default line separator option. */
|
||||
public static String lineSeparatorDefault;
|
||||
|
||||
/** The base name for new launch configurations. */
|
||||
public static String newTerminalLaunchName;
|
||||
|
||||
/** The error message to be issued if a launch configuration could not be found. */
|
||||
public static String noSuchLaunchConfiguration;
|
||||
|
||||
/** The message displayed while launching a configuration. */
|
||||
public static String launchingConfiguration;
|
||||
|
||||
/** The error message displayed when process creation failed. */
|
||||
public static String couldNotCreateIProcess;
|
||||
|
||||
/** The error message for a missing executable path. */
|
||||
public static String locationNotSpecified;
|
||||
|
||||
/** The error message for a specified but invalid executable path. */
|
||||
public static String invalidLocation;
|
||||
|
||||
/** The error message for an invalid working directory location. */
|
||||
public static String invalidWorkingDirectory;
|
||||
|
||||
/** The title string of the warning displayed when terminal launches are still running. */
|
||||
public static String warningTitleTerminalsStillRunning;
|
||||
|
||||
/** The warning message displayed when terminal launches are still running. */
|
||||
public static String warningMessageTerminalsStillRunning;
|
||||
|
||||
/** The label for the button that quits the workbench anyway. */
|
||||
public static String quitWorkbenchAnyway;
|
||||
|
||||
/** The label for the button that vetoes a shutdown of the workbench. */
|
||||
public static String doNoQuitWorkbench;
|
||||
|
||||
/** The label for a terminal process that was terminated during workbench shut-down. */
|
||||
public static String terminatedProcess;
|
||||
|
||||
/** The name of the launch configuration tab for terminal settings. */
|
||||
public static String terminalTabName;
|
||||
|
||||
/** The group label for the terminal settings on the launch configuration page. */
|
||||
public static String terminalSettings;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
####################################################################################################
|
||||
# Copyright (c) 2008 Mirko Raner.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
####################################################################################################
|
||||
|
||||
launchConfiguration=Launch configuration\:
|
||||
enableLocalEcho=Enable terminal echo
|
||||
sendInterruptOnCtrlC=Send SIGINT when Ctrl-C is pressed
|
||||
lineSeparatorDefault=Program uses default line separator - or\:
|
||||
lineSeparatorCRLF=CRLF
|
||||
lineSeparatorLF=LF
|
||||
lineSeparatorCR=CR
|
||||
labelNew=New...
|
||||
labelEdit=Edit...
|
||||
terminalTabName=Terminal
|
||||
terminalSettings=Terminal settings\:
|
||||
newTerminalLaunchName=New Terminal Launch
|
||||
noSuchLaunchConfiguration=A launch configuration called ''{0}'' does not exist
|
||||
launchingConfiguration=Launching {0}...
|
||||
couldNotCreateIProcess=The IProcess could not be created
|
||||
locationNotSpecified=Executable location was not specified in configuration ''{0}''
|
||||
invalidLocation=Executable does not exist for the external tool named ''{0}''
|
||||
invalidWorkingDirectory=The path {0} is not a directory and cannot be used as working directory \
|
||||
for ''{1}''
|
||||
warningTitleTerminalsStillRunning=Warning: Terminals with active processes are still running
|
||||
warningMessageTerminalsStillRunning=The workbench is about to be shut down even though one or more \
|
||||
terminals with active processes are still running. You may abort the shut-down of the workbench \
|
||||
or you may quit the workbench nonetheless, in which case processes might be terminated in an \
|
||||
unexpected fashion. You may also terminate processes individually. The workbench shut-down will \
|
||||
continue automatically once no more terminal processes are running.
|
||||
quitWorkbenchAnyway=Quit Workbench Anyway
|
||||
doNoQuitWorkbench=Do Not Quit Workbench
|
||||
terminatedProcess={0} <terminated, exit value: {1}>
|
|
@ -0,0 +1,90 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import org.eclipse.debug.core.IStreamListener;
|
||||
import org.eclipse.debug.core.model.IStreamMonitor;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalOutputListener} is an {@link IStreamListener} that transfers output
|
||||
* from a program's standard output and standard error streams to an {@link ITerminalControl}.
|
||||
* It does so by listening for appended text and sending it to the terminal's
|
||||
* {@link ITerminalControl#getRemoteToTerminalOutputStream()}. The class also performs line
|
||||
* separator conversions as specified by the {@link ILocalTerminalSettings}.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalOutputListener implements IStreamListener {
|
||||
|
||||
private PrintStream printStream;
|
||||
private String lineSeparator;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalOutputListener}.
|
||||
*
|
||||
* @param control the {@link ITerminalControl} to which the received output is forwarded
|
||||
* @param settings the {@link ILocalTerminalSettings}
|
||||
*/
|
||||
public LocalTerminalOutputListener(ITerminalControl control, ILocalTerminalSettings settings) {
|
||||
|
||||
printStream = new PrintStream(control.getRemoteToTerminalOutputStream(), true);
|
||||
lineSeparator = LocalTerminalUtilities.getLineSeparator(settings);
|
||||
if (lineSeparator == null) {
|
||||
|
||||
String defaultLS = System.getProperty(LocalTerminalUtilities.LINE_SEPARATOR_PROPERTY);
|
||||
if (LocalTerminalUtilities.CRLF.equals(defaultLS)) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_CRLF;
|
||||
}
|
||||
else if (LocalTerminalUtilities.LF.equals(defaultLS)) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_LF;
|
||||
}
|
||||
else if (LocalTerminalUtilities.CR.equals(defaultLS)) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_CR;
|
||||
}
|
||||
else {
|
||||
|
||||
Logger.log("Unknown default line separator: " + defaultLS); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes new output that was appended to the intercepted stream.
|
||||
*
|
||||
* @param text the new output
|
||||
* @param monitor the {@link IStreamMonitor} from which the output was received (this parameter
|
||||
* is currently not evaluated because each {@link IStreamMonitor} has its own dedicated instance
|
||||
* of {@link LocalTerminalOutputListener} attached)
|
||||
*/
|
||||
public void streamAppended(String text, IStreamMonitor monitor) {
|
||||
|
||||
// The VT100TerminalControl apparently adheres to a strict interpretation of the CR and
|
||||
// LF control codes, i.e., CR moves the caret to the beginning of the line (but does not
|
||||
// move down to the next line), and LF moves down to the next line (but not to the
|
||||
// beginning of the line). Therefore, if the program launched in the terminal does not use
|
||||
// CRLF as its line terminator the line terminators have to be converted to CRLF before
|
||||
// being passed on to the terminal control:
|
||||
//
|
||||
if (!ILocalTerminalSettings.LINE_SEPARATOR_CRLF.equals(lineSeparator)) {
|
||||
|
||||
text = text.replaceAll(lineSeparator, LocalTerminalUtilities.CRLF);
|
||||
}
|
||||
printStream.print(text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.debug.core.model.IStreamsProxy;
|
||||
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcess;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalOutputStream} is an {@link OutputStream} that copies data that is
|
||||
* typed into the terminal to the standard input of the active process. Data that is written to the
|
||||
* stream is directly forwarded to the {@link IStreamsProxy} of the process. CRLF line separators
|
||||
* that are received from the terminal will be automatically converted to the line separator that is
|
||||
* specified in the {@link ILocalTerminalSettings}. The Terminal Control generally sends CR line
|
||||
* separators if the local echo is disabled and CRLF if enabled. The reason for this idiosyncrasy
|
||||
* is not entirely clear right now and the line separator behavior might change in the future.
|
||||
*
|
||||
* TODO: research as to whether the CR/CRLF distinction in VT100TerminalControl.TerminalKeyHandler
|
||||
* (based on the local echo setting) is really necessary
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class LocalTerminalOutputStream extends OutputStream {
|
||||
|
||||
private final static String NOTHING = ""; //$NON-NLS-1$
|
||||
private final static String CRLF = LocalTerminalUtilities.CRLF;
|
||||
private final static char CR = '\r';
|
||||
private final static char LF = '\n';
|
||||
private final static char CTRL_C = '\03';
|
||||
private final static int TERMINAL_SENDS_CR = 0;
|
||||
private final static int TERMINAL_SENDS_CRLF = 1;
|
||||
private final static int PROGRAM_EXPECTS_LF = 0;
|
||||
private final static int PROGRAM_EXPECTS_CRLF = 1;
|
||||
private final static int PROGRAM_EXPECTS_CR = 2;
|
||||
private final static int NO_CHANGE = 0;
|
||||
private final static int CHANGE_CR_TO_LF = 1;
|
||||
private final static int INSERT_LF_AFTER_CR = 2;
|
||||
private final static int REMOVE_CR = 3;
|
||||
private final static int REMOVE_LF = 4;
|
||||
|
||||
// CRLF conversion table:
|
||||
//
|
||||
// Expected line separator --> | LF | CRLF | CR |
|
||||
// ------------------------------------+-----------------+--------------------+----------------+
|
||||
// Local echo off - control sends CR | change CR to LF | insert LF after CR | no change |
|
||||
// ------------------------------------+-----------------+--------------------+----------------+
|
||||
// Local echo on - control sends CRLF | remove CR | no change | remove LF |
|
||||
//
|
||||
private final static int[][] CRLF_REPLACEMENT = {
|
||||
|
||||
{CHANGE_CR_TO_LF, INSERT_LF_AFTER_CR, NO_CHANGE},
|
||||
{REMOVE_CR, NO_CHANGE, REMOVE_LF}
|
||||
};
|
||||
|
||||
private final boolean sendSIGINTOnCtrlC;
|
||||
private IStreamsProxy streamsProxy;
|
||||
private IProcess process;
|
||||
private int replacement;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalOutputStream}.
|
||||
*
|
||||
* @param process the {@link IProcess} object of the terminal process
|
||||
* @param settings the {@link ILocalTerminalSettings} (currently only used for the line
|
||||
* separator settings)
|
||||
*/
|
||||
public LocalTerminalOutputStream(IProcess process, ILocalTerminalSettings settings) {
|
||||
|
||||
this.process = process;
|
||||
streamsProxy = process.getStreamsProxy();
|
||||
sendSIGINTOnCtrlC = LocalTerminalUtilities.getCtrlC(settings);
|
||||
boolean localEcho = LocalTerminalUtilities.getLocalEcho(settings);
|
||||
int terminalSends = localEcho? TERMINAL_SENDS_CRLF:TERMINAL_SENDS_CR;
|
||||
int programExpects;
|
||||
String lineSeparator = LocalTerminalUtilities.getLineSeparator(settings);
|
||||
if (lineSeparator == null) {
|
||||
|
||||
lineSeparator = System.getProperty(LocalTerminalUtilities.LINE_SEPARATOR_PROPERTY);
|
||||
if (LocalTerminalUtilities.CR.equals(lineSeparator)) {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_CR;
|
||||
}
|
||||
else if (LocalTerminalUtilities.LF.equals(lineSeparator)) {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_LF;
|
||||
}
|
||||
else {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_CRLF;
|
||||
}
|
||||
}
|
||||
else if (lineSeparator.equals(ILocalTerminalSettings.LINE_SEPARATOR_LF)) {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_LF;
|
||||
}
|
||||
else if (lineSeparator.equals(ILocalTerminalSettings.LINE_SEPARATOR_CR)) {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_CR;
|
||||
}
|
||||
else {
|
||||
|
||||
programExpects = PROGRAM_EXPECTS_CRLF;
|
||||
}
|
||||
replacement = CRLF_REPLACEMENT[terminalSends][programExpects];
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this output stream.
|
||||
*
|
||||
* @param data the byte
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public void write(int data) throws IOException {
|
||||
|
||||
write(new byte[] {(byte)data}, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a specified number of bytes from the specified byte array starting at a given offset.
|
||||
*
|
||||
* @param data the array containing the data
|
||||
* @param offset the offset into the array
|
||||
* @param length the number of bytes to be written
|
||||
* @throws IOException of an I/O error occurs
|
||||
*/
|
||||
public void write(byte[] data, int offset, int length) throws IOException {
|
||||
|
||||
String text = new String(data, offset, length);
|
||||
//
|
||||
// TODO: check whether this is correct! new String(byte[], int, int) always uses the default
|
||||
// encoding!
|
||||
|
||||
if (replacement == CHANGE_CR_TO_LF) {
|
||||
|
||||
text = text.replace(CR, LF);
|
||||
}
|
||||
else if (replacement == INSERT_LF_AFTER_CR) {
|
||||
|
||||
text = text.replaceAll(ILocalTerminalSettings.LINE_SEPARATOR_CR, CRLF);
|
||||
}
|
||||
else if (replacement == REMOVE_CR) {
|
||||
|
||||
text = text.replaceAll(ILocalTerminalSettings.LINE_SEPARATOR_CR, NOTHING);
|
||||
}
|
||||
else if (replacement == REMOVE_LF) {
|
||||
|
||||
text = text.replaceAll(ILocalTerminalSettings.LINE_SEPARATOR_LF, NOTHING);
|
||||
}
|
||||
|
||||
// Process Ctrl-C in the proper order:
|
||||
//
|
||||
int positionOfCtrlC = -1;
|
||||
while (sendSIGINTOnCtrlC && (positionOfCtrlC = text.indexOf(CTRL_C)) != -1) {
|
||||
|
||||
// Send text up to (and including) the Ctrl-C to the process, then send a SIGINT:
|
||||
//
|
||||
streamsProxy.write(text.substring(0, positionOfCtrlC+1));
|
||||
if (process instanceof LocalTerminalProcess) {
|
||||
|
||||
((LocalTerminalProcess)process).interrupt();
|
||||
}
|
||||
|
||||
// Remove the part of the text that was already sent:
|
||||
//
|
||||
text = text.substring(positionOfCtrlC+1);
|
||||
}
|
||||
if (text.length() > 0) {
|
||||
|
||||
streamsProxy.write(text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.tm.terminal.ssh/SshSettings
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalSettings} is the default implementation of the
|
||||
* {@link ILocalTerminalSettings} interface.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class LocalTerminalSettings implements ILocalTerminalSettings {
|
||||
|
||||
private String launchConfiguration;
|
||||
|
||||
/**
|
||||
* Loads the settings from the given {@link ISettingsStore}.
|
||||
* This method loads the store contents by means of reflection. This is clearly overkill for
|
||||
* the few settings supported by this class, but the code is much more reusable. Pretty much
|
||||
* every implementation of a custom settings store is implemented in the same fashion and
|
||||
* might be replace by a single centralized implementation.
|
||||
*
|
||||
* TODO: check for possibilities to reuse this code!
|
||||
*
|
||||
* @param store the {@link ISettingsStore}
|
||||
* @see ILocalTerminalSettings#load(ISettingsStore)
|
||||
*/
|
||||
public void load(ISettingsStore store) {
|
||||
|
||||
Field[] declaredField = getClass().getDeclaredFields();
|
||||
int numberOfFields = declaredField.length;
|
||||
for (int index = 0; index < numberOfFields; index++) {
|
||||
|
||||
Field field = declaredField[index];
|
||||
Class type = field.getType();
|
||||
Object value = store.get(field.getName());
|
||||
if (type.equals(boolean.class)) {
|
||||
|
||||
value = Boolean.valueOf((String)value);
|
||||
}
|
||||
// TODO: further conversions need to be added as new settings types are introduced
|
||||
try {
|
||||
|
||||
field.set(this, value);
|
||||
}
|
||||
catch (IllegalAccessException illegalAccess) {
|
||||
|
||||
Logger.logException(illegalAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the settings to the specified {@link ISettingsStore}.
|
||||
* See {@link #load(ISettingsStore)} for further implementation notes.
|
||||
*
|
||||
* @param store the {@link ISettingsStore}
|
||||
*
|
||||
* @see ILocalTerminalSettings#save(ISettingsStore)
|
||||
*/
|
||||
public void save(ISettingsStore store) {
|
||||
|
||||
Field[] declaredField = getClass().getDeclaredFields();
|
||||
int numberOfFields = declaredField.length;
|
||||
for (int index = 0; index < numberOfFields; index++) {
|
||||
|
||||
Field field = declaredField[index];
|
||||
try {
|
||||
|
||||
field.setAccessible(true);
|
||||
store.put(field.getName(), String.valueOf(field.get(this)));
|
||||
}
|
||||
catch (IllegalAccessException illegalAccess) {
|
||||
|
||||
Logger.logException(illegalAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ILocalTerminalSettings#getLaunchConfigurationName()
|
||||
*/
|
||||
public String getLaunchConfigurationName() {
|
||||
|
||||
return launchConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ILocalTerminalSettings#setLaunchConfigurationName(String)
|
||||
*/
|
||||
public void setLaunchConfigurationName(String launchConfiguration) {
|
||||
|
||||
this.launchConfiguration = launchConfiguration;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.tm.terminal.ssh/SshSettingsPage
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationType;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.debug.internal.ui.DebugUIPlugin;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.debug.ui.ILaunchGroup;
|
||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.viewers.TableViewer;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Layout;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.Widget;
|
||||
import org.eclipse.tm.internal.terminal.local.ui.DependentHeightComposite;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalSettingsPage} is an implementation {@link ISettingsPage} for
|
||||
* local program connections.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
public class LocalTerminalSettingsPage
|
||||
implements ISettingsPage, ISelectionChangedListener, SelectionListener {
|
||||
|
||||
private ILocalTerminalSettings settings;
|
||||
private TableViewer viewer;
|
||||
private Button buttonEdit;
|
||||
private Button buttonNew;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalSettingsPage} that reflects the settings of the specified
|
||||
* {@link ILocalTerminalSettings} object.
|
||||
*
|
||||
* @param settings the {@link ILocalTerminalSettings}
|
||||
*/
|
||||
public LocalTerminalSettingsPage(ILocalTerminalSettings settings) {
|
||||
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link org.eclipse.swt.widgets.Control} for the settings page.
|
||||
* (NOTE: contrary to the common pattern, this method does not actually return the Control it
|
||||
* created)
|
||||
*
|
||||
* @param parent the parent {@link Composite} into which the control is to be inserted
|
||||
*
|
||||
* @see ISettingsPage#createControl(Composite)
|
||||
*/
|
||||
public void createControl(Composite parent) {
|
||||
|
||||
Composite enclosing = parent.getParent();
|
||||
Layout enclosingLayout = enclosing.getLayout();
|
||||
int extra = 0;
|
||||
if (enclosingLayout instanceof GridLayout) {
|
||||
|
||||
extra = -2*((GridLayout)enclosingLayout).marginHeight-2;
|
||||
}
|
||||
Composite composite = new DependentHeightComposite(parent, SWT.NONE, enclosing, extra);
|
||||
//
|
||||
// TODO: This is a HACK that ensures proper resizing of the settings page inside the
|
||||
// StackLayout of the PageBook. The following code makes implicit assumptions about
|
||||
// the internal layout of surrounding widgets. This is something that should be
|
||||
// properly addressed in the framework (maybe in the PageBook class).
|
||||
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.marginWidth = layout.marginHeight = 0;
|
||||
layout.horizontalSpacing = layout.verticalSpacing = 0;
|
||||
composite.setLayout(layout);
|
||||
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||
Label label = new Label(composite, SWT.NONE);
|
||||
label.setText(LocalTerminalMessages.launchConfiguration);
|
||||
label.setLayoutData(new GridData());
|
||||
|
||||
// Create list of available launch configurations:
|
||||
//
|
||||
Composite tableAndButtons = new Composite(composite, SWT.NONE);
|
||||
tableAndButtons.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||
layout = new GridLayout(2, false);
|
||||
layout.marginWidth = 0;
|
||||
tableAndButtons.setLayout(layout);
|
||||
Table table = new Table(tableAndButtons, SWT.BORDER);
|
||||
viewer = new TableViewer(table);
|
||||
viewer.setLabelProvider(new LocalTerminalLaunchLabelProvider());
|
||||
viewer.setContentProvider(new LocalTerminalLaunchListProvider());
|
||||
viewer.setInput(new Object());
|
||||
viewer.addSelectionChangedListener(this);
|
||||
table.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 0, 2));
|
||||
buttonNew = pushButton(tableAndButtons, LocalTerminalMessages.labelNew, false);
|
||||
buttonEdit = pushButton(tableAndButtons, LocalTerminalMessages.labelEdit, true);
|
||||
buttonEdit.setEnabled(settings.getLaunchConfigurationName() != null);
|
||||
//
|
||||
// NOTE: echo and line separator settings were moved to the launch configuration!
|
||||
|
||||
// NOTE: loadSettings() is actually NOT called by the framework but needs to be called
|
||||
// by the settings page itself
|
||||
// TODO: this should be fixed in the framework; otherwise there is really no point
|
||||
// in having it be a part of the ISettingsPage interface
|
||||
//
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the settings from the internal {@link ILocalTerminalSettings} object.
|
||||
* This method will update the UI to reflect the current settings.
|
||||
*
|
||||
* @see ISettingsPage#loadSettings()
|
||||
*/
|
||||
public void loadSettings() {
|
||||
|
||||
String configurationName = settings.getLaunchConfigurationName();
|
||||
ILaunchConfiguration configuration;
|
||||
try {
|
||||
|
||||
configuration = LocalTerminalUtilities.findLaunchConfiguration(configurationName);
|
||||
}
|
||||
catch (CoreException couldNotFindLaunchConfiguration) {
|
||||
|
||||
configuration = null;
|
||||
}
|
||||
if (settings.getLaunchConfigurationName() != null && configuration != null) {
|
||||
|
||||
viewer.setSelection(new StructuredSelection(configuration), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the settings that are currently displayed in the UI to the internal
|
||||
* {@link ILocalTerminalSettings} object.
|
||||
*
|
||||
* @see ISettingsPage#saveSettings()
|
||||
*/
|
||||
public void saveSettings() {
|
||||
|
||||
if (viewer != null && !viewer.getSelection().isEmpty()) {
|
||||
|
||||
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
|
||||
Object element = selection.getFirstElement();
|
||||
if (element instanceof ILaunchConfiguration) {
|
||||
|
||||
String launchConfiguration = ((ILaunchConfiguration)element).getName();
|
||||
settings.setLaunchConfigurationName(launchConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current settings are valid for starting a terminal session.
|
||||
* This method will only return <code>true</code> if a launch configuration is selected.
|
||||
*
|
||||
* @return <code>true</code> if a launch configuration has been selected, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
public boolean validateSettings() {
|
||||
|
||||
return viewer != null && !viewer.getSelection().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the Edit... button depending on whether a launch configuration is
|
||||
* currently selected in the viewer.
|
||||
*
|
||||
* @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
|
||||
*/
|
||||
public void selectionChanged(SelectionChangedEvent event) {
|
||||
|
||||
buttonEdit.setEnabled(!event.getSelection().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles default button clicks for the Edit... and New.. buttons. This method will simply
|
||||
* pass on the call to {@link #widgetSelected(SelectionEvent)}.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
*
|
||||
* @see SelectionListener#widgetDefaultSelected(SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
|
||||
widgetSelected(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles default button clicks for the Edit... and New.. buttons.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
*
|
||||
* @see SelectionListener#widgetSelected(SelectionEvent)
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
ILaunchConfiguration configuration = null;
|
||||
Widget widget = event.widget;
|
||||
if (widget == null) {
|
||||
|
||||
return;
|
||||
}
|
||||
if (widget.equals(buttonNew)) {
|
||||
|
||||
ILaunchConfigurationWorkingCopy newlyCreatedConfiguration;
|
||||
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
|
||||
String baseName = LocalTerminalMessages.newTerminalLaunchName;
|
||||
String uniqueName = launchManager.generateUniqueLaunchConfigurationNameFrom(baseName);
|
||||
ILaunchConfigurationType type = LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE;
|
||||
try {
|
||||
|
||||
newlyCreatedConfiguration = type.newInstance(null, uniqueName);
|
||||
configuration = newlyCreatedConfiguration.doSave();
|
||||
}
|
||||
catch (CoreException couldNotCreateNewLaunchConfiguration) {
|
||||
|
||||
Logger.logException(couldNotCreateNewLaunchConfiguration);
|
||||
}
|
||||
}
|
||||
if (widget.equals(buttonEdit) || configuration != null) {
|
||||
|
||||
ILaunchGroup group;
|
||||
Shell shell = DebugUIPlugin.getShell();
|
||||
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
|
||||
if (configuration == null) {
|
||||
|
||||
configuration = (ILaunchConfiguration)selection.getFirstElement();
|
||||
}
|
||||
group = DebugUITools.getLaunchGroup(configuration, ILaunchManager.RUN_MODE);
|
||||
String groupID = group.getIdentifier();
|
||||
DebugUITools.openLaunchConfigurationDialog(shell, configuration, groupID, null);
|
||||
//
|
||||
// TODO: handle return value (maybe start terminal right away if "Run" was selected)
|
||||
// - a return value of Window.CANCEL indicates that "Close" was selected
|
||||
// - a return value of Window.OK indicates that "Run" was selected
|
||||
// TODO: prevent "Run" button from launching in the regular console
|
||||
// (maybe tweak process factory settings before opening the configuration in the
|
||||
// dialog?)
|
||||
|
||||
viewer.refresh();
|
||||
viewer.setSelection(new StructuredSelection(configuration), true);
|
||||
//
|
||||
// TODO: handle renamed configurations; setSelection(...) will not work if the user
|
||||
// renamed the configuration in the dialog (apparently, because renaming actually
|
||||
// creates a different ILaunchConfiguration object, rather than just renaming the
|
||||
// existing one)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------ PRIVATE SECTION ---------------------------------------//
|
||||
|
||||
private Button pushButton(Composite parent, String label, boolean grabVertical) {
|
||||
|
||||
GridData layoutData;
|
||||
Button button = new Button(parent, SWT.PUSH);
|
||||
button.setText(label);
|
||||
layoutData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING|GridData.HORIZONTAL_ALIGN_FILL);
|
||||
layoutData.grabExcessVerticalSpace = grabVertical;
|
||||
button.setLayoutData(layoutData);
|
||||
button.addSelectionListener(this);
|
||||
return button;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationType;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchDelegate;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalUtilities} is a collection of commonly used constants and utility
|
||||
* methods.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public class LocalTerminalUtilities {
|
||||
|
||||
private static String NULL = null;
|
||||
private static String LOCAL_TERMINAL = LocalTerminalLaunchDelegate.LAUNCH_CONFIGURATION_TYPE_ID;
|
||||
|
||||
/** The name of the line separator system property (i.e., "<code>line.separator</code>"). */
|
||||
public final static String LINE_SEPARATOR_PROPERTY = "line.separator"; //$NON-NLS-1$
|
||||
|
||||
/** The line separator CRLF (i.e., "<code>\r\n</code>"). */
|
||||
public final static String CRLF = "\r\n"; //$NON-NLS-1$
|
||||
|
||||
/** The line separator CR (i.e., "<code>\r</code>"). */
|
||||
public final static String CR = "\r"; //$NON-NLS-1$
|
||||
|
||||
/** The line separator LF (i.e., "<code>\n</code>"). */
|
||||
public final static String LF = "\n"; //$NON-NLS-1$
|
||||
|
||||
private LocalTerminalUtilities() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/** The {@link DebugPlugin}'s {@link ILaunchManager} instance. */
|
||||
public final static ILaunchManager LAUNCH_MANAGER = DebugPlugin.getDefault().getLaunchManager();
|
||||
|
||||
/**
|
||||
* The {@link ILaunchConfigurationType} for "Program" launches (in the "External Tools"
|
||||
* category).
|
||||
*/
|
||||
public final static ILaunchConfigurationType PROGRAM_LAUNCH_TYPE =
|
||||
LAUNCH_MANAGER.getLaunchConfigurationType(LOCAL_TERMINAL);
|
||||
|
||||
/**
|
||||
* Finds a launch configuration by its name.
|
||||
*
|
||||
* @param name the name of the launch configuration
|
||||
* @return the corresponding {@link ILaunchConfiguration} object or <code>null</code> if the
|
||||
* configuration could not be found
|
||||
* @throws CoreException if there was a general problem accessing launch configurations
|
||||
*/
|
||||
public static ILaunchConfiguration findLaunchConfiguration(String name) throws CoreException {
|
||||
|
||||
ILaunchConfiguration[] configuration;
|
||||
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
|
||||
configuration = manager.getLaunchConfigurations(LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE);
|
||||
int numberOfConfigurations = configuration.length;
|
||||
for (int index = 0; index < numberOfConfigurations; index++) {
|
||||
|
||||
if (configuration[index].getName().equals(name)) {
|
||||
|
||||
return configuration[index];
|
||||
}
|
||||
}
|
||||
String error = NLS.bind(LocalTerminalMessages.noSuchLaunchConfiguration, name);
|
||||
throw new CoreException(new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local echo setting that is stored in the launch configuration for the given
|
||||
* {@link ILocalTerminalSettings}.
|
||||
*
|
||||
* @param settings the {@link ILocalTerminalSettings}
|
||||
* @return <code>true</code> for local echo enabled, <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean getLocalEcho(ILocalTerminalSettings settings) {
|
||||
|
||||
return getBooleanSetting(settings, LocalTerminalLaunchUtilities.ATTR_LOCAL_ECHO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Ctrl-C/SIGINT setting that is stored in the launch configuration for the given
|
||||
* {@link ILocalTerminalSettings}.
|
||||
*
|
||||
* @param settings the {@link ILocalTerminalSettings}
|
||||
* @return <code>true</code> if sending SIGINT for Ctrl-C is enabled,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean getCtrlC(ILocalTerminalSettings settings) {
|
||||
|
||||
return getBooleanSetting(settings, LocalTerminalLaunchUtilities.ATTR_CTRL_C);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the line separator setting that is stored in the launch configuration for the given
|
||||
* {@link ILocalTerminalSettings}.
|
||||
*
|
||||
* @param settings the {@link ILocalTerminalSettings}
|
||||
* @return {@link ILocalTerminalSettings#LINE_SEPARATOR_LF},
|
||||
* {@link ILocalTerminalSettings#LINE_SEPARATOR_CRLF},
|
||||
* {@link ILocalTerminalSettings#LINE_SEPARATOR_CR}, or <code>null</code> for the platform's
|
||||
* default line separator
|
||||
*/
|
||||
public static String getLineSeparator(ILocalTerminalSettings settings) {
|
||||
|
||||
String configurationName = settings.getLaunchConfigurationName();
|
||||
try {
|
||||
|
||||
String ls;
|
||||
ILaunchConfiguration configuration = findLaunchConfiguration(configurationName);
|
||||
ls = configuration.getAttribute(LocalTerminalLaunchUtilities.ATTR_LINE_SEPARATOR, NULL);
|
||||
return ls;
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------- PRIVATE SECTION --------------------------------------//
|
||||
|
||||
private static boolean getBooleanSetting(ILocalTerminalSettings settings, String attribute) {
|
||||
|
||||
String configurationName = settings.getLaunchConfigurationName();
|
||||
try {
|
||||
|
||||
ILaunchConfiguration configuration = findLaunchConfiguration(configurationName);
|
||||
return configuration.getAttribute(attribute, false);
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.ui.externaltools/ProgramLaunchDelegate
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.cdt.utils.pty.PTY;
|
||||
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
|
||||
import org.eclipse.debug.ui.CommonTab;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalLaunchDelegate} provides a launch configuration delegate for local
|
||||
* terminal launches. It is based on the <code>ProgramLaunchDelegate</code> class in the
|
||||
* <code>org.eclipse.ui.externaltools</code> plug-in. In contrast to the original class,
|
||||
* {@link LocalTerminalLaunchDelegate} creates its low-level {@link Process} object using the CDT
|
||||
* {@link ProcessFactory}, which allows the process to run with a pseudo-terminal ({@link PTY}).
|
||||
*
|
||||
* @author Mirko Raner and others
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate {
|
||||
|
||||
private final static String EMPTY = ""; //$NON-NLS-1$
|
||||
private final static String PLUGIN_ID = LocalTerminalActivator.PLUGIN_ID;
|
||||
|
||||
/**
|
||||
* The launch configuration type ID for terminal launches.
|
||||
*/
|
||||
public final static String LAUNCH_CONFIGURATION_TYPE_ID = PLUGIN_ID + ".launch"; //$NON-NLS-1$
|
||||
|
||||
private static LocalTerminalStillRunningListener workbenchCloseListener;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalLaunchDelegate}.
|
||||
*/
|
||||
public LocalTerminalLaunchDelegate() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a new Local Terminal configuration in the specified mode. The launch object has
|
||||
* already been registered with the launch manager.
|
||||
*
|
||||
* @param configuration the {@link ILaunchConfiguration} to launch
|
||||
* @param mode the mode in which to launch; currently, Local Terminal launches only support the
|
||||
* mode {@link org.eclipse.debug.core.ILaunchManager#RUN_MODE}
|
||||
* @param progressMonitor an {@link IProgressMonitor}, or <code>null</code> for no progress
|
||||
* monitoring
|
||||
* @param launch the {@link ILaunch} object
|
||||
* @exception CoreException if launching fails
|
||||
*/
|
||||
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch,
|
||||
IProgressMonitor progressMonitor) throws CoreException {
|
||||
|
||||
// Extract all relevant information from the ILaunchConfiguration; the original
|
||||
// ProgramLaunchDelegate class checks for cancellation again and again after each step,
|
||||
// which is a somewhat suspect pattern; however, for now, LocalTerminalLaunchDelegate
|
||||
// handles cancellation in the same way:
|
||||
//
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
IPath location = LocalTerminalLaunchUtilities.getLocation(configuration);
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
IPath workingDirectory = LocalTerminalLaunchUtilities.getWorkingDirectory(configuration);
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
String[] arguments = LocalTerminalLaunchUtilities.getArguments(configuration);
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
String[] commandLine = new String[arguments != null? arguments.length+1:1];
|
||||
commandLine[0] = location.toOSString();
|
||||
if (arguments != null) {
|
||||
|
||||
System.arraycopy(arguments, 0, commandLine, 1, arguments.length);
|
||||
}
|
||||
File workingDirectoryAsFile = null;
|
||||
if (workingDirectory != null) {
|
||||
|
||||
workingDirectoryAsFile = workingDirectory.toFile();
|
||||
}
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
String[] environment = LocalTerminalUtilities.LAUNCH_MANAGER.getEnvironment(configuration);
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
return;
|
||||
}
|
||||
//
|
||||
// TODO: check if there is a better way of handling cancellation of terminal launches!
|
||||
|
||||
// Install an IWindowListener that checks for left-over terminal processes when the
|
||||
// workbench is closed:
|
||||
//
|
||||
if (workbenchCloseListener == null) {
|
||||
|
||||
workbenchCloseListener = new LocalTerminalStillRunningListener();
|
||||
PlatformUI.getWorkbench().addWorkbenchListener(workbenchCloseListener);
|
||||
}
|
||||
|
||||
// Create the low-level Process object:
|
||||
//
|
||||
Process spawner;
|
||||
try {
|
||||
|
||||
ProcessFactory factory = ProcessFactory.getFactory();
|
||||
if (PTY.isSupported()) {
|
||||
|
||||
spawner = factory.exec(commandLine, environment, workingDirectoryAsFile, new PTY());
|
||||
}
|
||||
else {
|
||||
|
||||
spawner = factory.exec(commandLine, environment, workingDirectoryAsFile);
|
||||
}
|
||||
}
|
||||
catch (IOException exception) {
|
||||
|
||||
Status error;
|
||||
String message = exception.getMessage();
|
||||
error = new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, message, exception);
|
||||
throw new CoreException(error);
|
||||
}
|
||||
|
||||
// Use program name as "process type" attribute:
|
||||
//
|
||||
Map processAttributes = new HashMap();
|
||||
String programName = location.lastSegment();
|
||||
String extension = location.getFileExtension();
|
||||
if (extension != null) {
|
||||
|
||||
programName = programName.substring(0, programName.length()-extension.length()-1);
|
||||
}
|
||||
processAttributes.put(IProcess.ATTR_PROCESS_TYPE, programName.toLowerCase());
|
||||
|
||||
// Create the IProcess:
|
||||
//
|
||||
IProcess process = null;
|
||||
if (spawner != null) {
|
||||
|
||||
String[] configurationName = {configuration.getName()};
|
||||
String task = NLS.bind(LocalTerminalMessages.launchingConfiguration, configurationName);
|
||||
progressMonitor.beginTask(task, IProgressMonitor.UNKNOWN);
|
||||
process = DebugPlugin.newProcess(launch, spawner, commandLine[0], processAttributes);
|
||||
}
|
||||
if (spawner == null || process == null) {
|
||||
|
||||
if (spawner != null) {
|
||||
|
||||
spawner.destroy();
|
||||
}
|
||||
String pluginID = LocalTerminalActivator.PLUGIN_ID;
|
||||
String errorMessage = LocalTerminalMessages.couldNotCreateIProcess;
|
||||
Status error = new Status(IStatus.ERROR, pluginID, IStatus.ERROR, errorMessage, null);
|
||||
throw new CoreException(error);
|
||||
}
|
||||
process.setAttribute(IProcess.ATTR_CMDLINE, generateCommandLine(commandLine));
|
||||
|
||||
// Wait for process termination if necessary (though probably highly unusual for terminal
|
||||
// launches); again, the busy waiting pattern was copied from ProgramLaunchDelegate and is
|
||||
// somewhat suspect:
|
||||
//
|
||||
if (!CommonTab.isLaunchInBackground(configuration)) {
|
||||
|
||||
while (!process.isTerminated()) {
|
||||
|
||||
try {
|
||||
|
||||
if (progressMonitor.isCanceled()) {
|
||||
|
||||
process.terminate();
|
||||
break;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
}
|
||||
catch (InterruptedException interrupt) {
|
||||
|
||||
Logger.logException(interrupt);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// TODO: find a better replacement for the busy waiting loop
|
||||
}
|
||||
|
||||
//------------------------------------- PRIVATE SECTION --------------------------------------//
|
||||
|
||||
private String generateCommandLine(String[] commandLine) {
|
||||
|
||||
if (commandLine.length < 1) {
|
||||
|
||||
return EMPTY;
|
||||
}
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (int element = 0; element < commandLine.length; element++) {
|
||||
|
||||
if (element > 0) {
|
||||
|
||||
buffer.append(' ');
|
||||
}
|
||||
StringBuffer argument = new StringBuffer();
|
||||
char[] characters = commandLine[element].toCharArray();
|
||||
boolean argumentContainsSpace = false;
|
||||
for (int index = 0; index < characters.length; index++) {
|
||||
|
||||
char character = characters[index];
|
||||
if (character == '"') {
|
||||
|
||||
argument.append('\\');
|
||||
}
|
||||
else if (character == ' ') {
|
||||
|
||||
argumentContainsSpace = true;
|
||||
}
|
||||
argument.append(character);
|
||||
}
|
||||
if (argumentContainsSpace) {
|
||||
|
||||
buffer.append('"').append(argument).append('"');
|
||||
}
|
||||
else {
|
||||
|
||||
buffer.append(argument);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.ui.externaltools/ExternalToolsUtil
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch;
|
||||
|
||||
import java.io.File;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalLaunchUtilities} provides some utility methods that are used by the
|
||||
* {@link LocalTerminalLaunchDelegate}. The class is based on the <code>ExternalToolsUtil</code>
|
||||
* class in the <code>org.eclipse.ui.externaltools</code> plug-in. This code had to be duplicated
|
||||
* because the original class is not part of the public API of its plug-in.
|
||||
*
|
||||
* @author Mirko Raner and others
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalLaunchUtilities {
|
||||
|
||||
/** The launch configuration attribute for the local echo setting. */
|
||||
public final static String ATTR_LOCAL_ECHO = LocalTerminalActivator.PLUGIN_ID +
|
||||
".echo"; //$NON-NLS-1$
|
||||
|
||||
/** The launch configuration attribute for the Ctrl-C/SIGINT setting. */
|
||||
public final static String ATTR_CTRL_C = LocalTerminalActivator.PLUGIN_ID +
|
||||
".sigint"; //$NON-NLS-1$
|
||||
|
||||
/** The launch configuration attribute for the line terminator setting. */
|
||||
public final static String ATTR_LINE_SEPARATOR = LocalTerminalActivator.PLUGIN_ID +
|
||||
".lineseparator"; //$NON-NLS-1$
|
||||
|
||||
private final static String[] EMPTY = {};
|
||||
private final static String STRING = null;
|
||||
|
||||
// These constants were copied from IExternalToolConstants to avoid references to internal API:
|
||||
//
|
||||
private final static String XT = "org.eclipse.ui.externaltools"; //$NON-NLS-1$;
|
||||
private final static String ATTR_LOCATION = XT+".ATTR_LOCATION"; //$NON-NLS-1$
|
||||
private final static String ATTR_TOOL_ARGUMENTS = XT+".ATTR_TOOL_ARGUMENTS"; //$NON-NLS-1$
|
||||
private final static String ATTR_WORKING_DIRECTORY = XT+".ATTR_WORKING_DIRECTORY"; //$NON-NLS-1$
|
||||
|
||||
private LocalTerminalLaunchUtilities() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image that should be used for representing the given launch configuration.
|
||||
*
|
||||
* @param configuration the {@link ILaunchConfiguration}
|
||||
* @return an SWT {@link Image} or <code>null</code> if no suitable image was found
|
||||
*/
|
||||
public static Image getImage(ILaunchConfiguration configuration) {
|
||||
|
||||
String identifier;
|
||||
try {
|
||||
|
||||
identifier = configuration.getType().getIdentifier();
|
||||
}
|
||||
catch (CoreException couldNotDetermineConfigurationType) {
|
||||
|
||||
identifier = null;
|
||||
Logger.logException(couldNotDetermineConfigurationType);
|
||||
}
|
||||
if (identifier != null) {
|
||||
|
||||
return DebugUITools.getImage(identifier);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands and returns the location attribute of the given launch configuration. The location is
|
||||
* verified to point to an existing file in the local file system.
|
||||
*
|
||||
* @param configuration the {@link ILaunchConfiguration}
|
||||
* @return an absolute path to a file in the local file system
|
||||
* @throws CoreException if unable to retrieve the associated launch configuration attribute, or
|
||||
* if unable to resolve any variables, or if the resolved location does not point to an existing
|
||||
* file in the local file system
|
||||
*/
|
||||
public static IPath getLocation(ILaunchConfiguration configuration) throws CoreException {
|
||||
|
||||
Object[] configurationName = {configuration.getName()};
|
||||
String location = configuration.getAttribute(ATTR_LOCATION, STRING);
|
||||
if (location == null) {
|
||||
|
||||
abort(NLS.bind(LocalTerminalMessages.locationNotSpecified, configurationName), null, 0);
|
||||
}
|
||||
String expandedLocation = getStringVariableManager().performStringSubstitution(location);
|
||||
if (expandedLocation == null || expandedLocation.length() == 0) {
|
||||
|
||||
abort(NLS.bind(LocalTerminalMessages.invalidLocation, configurationName), null, 0);
|
||||
}
|
||||
File file = new File(expandedLocation);
|
||||
if (!file.isFile()) {
|
||||
|
||||
abort(NLS.bind(LocalTerminalMessages.invalidLocation, configurationName), null, 0);
|
||||
}
|
||||
return new Path(expandedLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands and returns the working directory attribute of the given launch configuration.
|
||||
* Returns <code>null</code> if a working directory is not specified. If specified, the working
|
||||
* directory is guaranteed to point to an existing directory in the local file system.
|
||||
*
|
||||
* @param configuration the {@link ILaunchConfiguration}
|
||||
* @return an absolute path to a directory in the local file system, or <code>null</code> if
|
||||
* no working directory was specified
|
||||
* @throws CoreException if unable to retrieve the associated launch configuration attribute,
|
||||
* or if unable to resolve any variables, or if the resolved location does not point to an
|
||||
* existing directory in the local file system
|
||||
*/
|
||||
public static IPath getWorkingDirectory(ILaunchConfiguration configuration)
|
||||
throws CoreException {
|
||||
|
||||
String location = configuration.getAttribute(ATTR_WORKING_DIRECTORY, STRING);
|
||||
if (location != null) {
|
||||
|
||||
String expandedLocation;
|
||||
expandedLocation = getStringVariableManager().performStringSubstitution(location);
|
||||
if (expandedLocation.length() > 0) {
|
||||
|
||||
File path = new File(expandedLocation);
|
||||
if (!path.isDirectory()) {
|
||||
|
||||
Object[] detail = {expandedLocation, configuration.getName()};
|
||||
abort(NLS.bind(LocalTerminalMessages.invalidWorkingDirectory, detail), null, 0);
|
||||
}
|
||||
}
|
||||
return new Path(expandedLocation);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands and returns the arguments attribute of the given launch configuration. Returns
|
||||
* <code>null</code> if arguments were not specified.
|
||||
*
|
||||
* @param configuration the {@link ILaunchConfiguration}
|
||||
* @return an array of resolved arguments, or <code>null</code> if no arguments were specified
|
||||
* @throws CoreException if unable to retrieve the associated launch configuration attribute,
|
||||
* or if unable to resolve any variables
|
||||
*/
|
||||
public static String[] getArguments(ILaunchConfiguration configuration) throws CoreException {
|
||||
|
||||
String arguments = configuration.getAttribute(ATTR_TOOL_ARGUMENTS, STRING);
|
||||
if (arguments != null) {
|
||||
|
||||
String expanded = getStringVariableManager().performStringSubstitution(arguments);
|
||||
return parseStringIntoList(expanded);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//------------------------------------- PRIVATE SECTION --------------------------------------//
|
||||
|
||||
private static IStringVariableManager getStringVariableManager() {
|
||||
|
||||
return VariablesPlugin.getDefault().getStringVariableManager();
|
||||
}
|
||||
|
||||
private static String[] parseStringIntoList(String arguments) {
|
||||
|
||||
if (arguments == null || arguments.length() == 0) {
|
||||
|
||||
return EMPTY;
|
||||
}
|
||||
return DebugPlugin.parseArguments(arguments);
|
||||
}
|
||||
|
||||
private static void abort(String text, Throwable exception, int code) throws CoreException {
|
||||
|
||||
Status status;
|
||||
status = new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, code, text, exception);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - [196337] Adapted from org.eclipse.ui.externaltools/ProgramLaunchDelegate
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationType;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.ui.LocalTerminalStillRunningDialog;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchListener;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalStillRunningListener} is an {@link IWorkbenchListener} that warns
|
||||
* the user about any terminal launches that are still running when the workbench closes. The user
|
||||
* might want to take specific action to deal with such left-over processes. Typically, this
|
||||
* listener will trigger only on very rare cases because the
|
||||
* {@link org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector} implementation will
|
||||
* terminate left-over launches when the workbench window is closed. However, it is possible that
|
||||
* a terminal launch does not get automatically terminated, for example, if it was started through
|
||||
* an External Tools launch rather than through the terminal.
|
||||
*
|
||||
* The class {@link LocalTerminalStillRunningListener} is inspired by the
|
||||
* <code>ProgramLaunchWindowListener</code> class inside <code>ProgramLaunchDelegate</code> in the
|
||||
* <code>org.eclipse.ui.externaltools</code> plug-in, though it works through a slightly different
|
||||
* mechanism.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class LocalTerminalStillRunningListener implements IWorkbenchListener {
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalStillRunningListener}.
|
||||
*/
|
||||
public LocalTerminalStillRunningListener() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified when the workbench is closed and informs the user about any left-over
|
||||
* terminal launches.
|
||||
*
|
||||
* @param workbench the {@link IWorkbench}
|
||||
* @param forced <code>true</code> if a forced shutdown occurred, <code>false</code> otherwise
|
||||
* @return <code>true</code> to allow the workbench to proceed with shutdown, <code>false</code>
|
||||
* to prevent a shutdown (only for non-forced shutdown)
|
||||
*/
|
||||
public boolean preShutdown(IWorkbench workbench, boolean forced) {
|
||||
|
||||
if (forced) {
|
||||
|
||||
return true;
|
||||
}
|
||||
ILaunchConfigurationType launchType;
|
||||
String launchTypeID = LocalTerminalLaunchDelegate.LAUNCH_CONFIGURATION_TYPE_ID;
|
||||
launchType = LocalTerminalUtilities.LAUNCH_MANAGER.getLaunchConfigurationType(launchTypeID);
|
||||
if (launchType == null) {
|
||||
|
||||
return true;
|
||||
}
|
||||
List notTerminated = new ArrayList();
|
||||
ILaunch launches[] = LocalTerminalUtilities.LAUNCH_MANAGER.getLaunches();
|
||||
ILaunchConfigurationType configurationType;
|
||||
ILaunchConfiguration configuration;
|
||||
for (int launch = 0; launch < launches.length; launch++) {
|
||||
|
||||
try {
|
||||
|
||||
configuration = launches[launch].getLaunchConfiguration();
|
||||
if (configuration == null) {
|
||||
|
||||
continue;
|
||||
}
|
||||
configurationType= configuration.getType();
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
continue;
|
||||
}
|
||||
if (configurationType.equals(launchType) && !launches[launch].isTerminated()) {
|
||||
|
||||
notTerminated.add(launches[launch]);
|
||||
}
|
||||
}
|
||||
if (!notTerminated.isEmpty()) {
|
||||
|
||||
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
|
||||
ILaunch[] launch = (ILaunch[])notTerminated.toArray(new ILaunch[notTerminated.size()]);
|
||||
return LocalTerminalStillRunningDialog.openDialog(window.getShell(), launch);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see IWorkbenchListener#postShutdown(IWorkbench)
|
||||
*/
|
||||
public void postShutdown(IWorkbench workbench) {
|
||||
|
||||
// Not implemented
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch.ui;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
|
||||
import org.eclipse.debug.ui.CommonTab;
|
||||
import org.eclipse.debug.ui.EnvironmentTab;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
|
||||
import org.eclipse.debug.ui.ILaunchConfigurationTab;
|
||||
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalLaunchTabGroup} defines the tabs for the launch configuration
|
||||
* dialog that is used for terminal-based launches. The tab groups consists of the main tab for
|
||||
* a standard program launch (lifted from the <code>org.eclipse.ui.externaltools</code> plug-in), the
|
||||
* custom {@link LocalTerminalSettingsTab}, and the {@link EnvironmentTab} and {@link CommonTab},
|
||||
* which can be publicly accessed from the <code>org.eclipse.debug.ui</code> plug-in.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.1 $
|
||||
**/
|
||||
public class LocalTerminalLaunchTabGroup extends AbstractLaunchConfigurationTabGroup
|
||||
implements IDebugUIConstants {
|
||||
|
||||
private final static String ID = "id"; //$NON-NLS-1$
|
||||
private final static String CLASS = "class"; //$NON-NLS-1$
|
||||
private final static String LC_TAB_GROUPS = EXTENSION_POINT_LAUNCH_CONFIGURATION_TAB_GROUPS;
|
||||
private final static String PROGRAM_TAB_GROUP =
|
||||
"org.eclipse.ui.externaltools.launchConfigurationTabGroup.program"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalLaunchTabGroup}.
|
||||
**/
|
||||
public LocalTerminalLaunchTabGroup() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the tabs contained in the local terminal launch configuration dialog for the specified
|
||||
* launch mode. The tabs control's are not yet created. This is the first method called in the
|
||||
* life-cycle of a tab group.
|
||||
*
|
||||
* @param dialog the launch configuration dialog this tab group is contained in
|
||||
* @param mode the mode the launch configuration dialog was opened in
|
||||
* @see AbstractLaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
|
||||
**/
|
||||
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
|
||||
|
||||
ILaunchConfigurationTab main = getMainTab(dialog, mode);
|
||||
ILaunchConfigurationTab terminal = new LocalTerminalSettingsTab();
|
||||
ILaunchConfigurationTab environment = new EnvironmentTab();
|
||||
ILaunchConfigurationTab common = new CommonTab();
|
||||
ILaunchConfigurationTab[] tabs = {main, terminal, environment, common};
|
||||
setTabs(tabs);
|
||||
}
|
||||
|
||||
//-------------------------------------- PRIVATE SECTION -------------------------------------//
|
||||
|
||||
private ILaunchConfigurationTab getMainTab(ILaunchConfigurationDialog dialog, String mode) {
|
||||
|
||||
// Find the main tab for the external program launch in the registry (a direct search is
|
||||
// only possible for extensions that actually declare a unique ID, which most extensions
|
||||
// don't; the search for the "id" attribute of a configuration element has to be done
|
||||
// manually):
|
||||
//
|
||||
IConfigurationElement[] element;
|
||||
IExtensionRegistry registry = Platform.getExtensionRegistry();
|
||||
element = registry.getConfigurationElementsFor(IDebugUIConstants.PLUGIN_ID, LC_TAB_GROUPS);
|
||||
int numberOfElements = element.length;
|
||||
for (int index = 0; index < numberOfElements; index++) {
|
||||
|
||||
if (element[index].getAttribute(ID).equals(PROGRAM_TAB_GROUP)) {
|
||||
|
||||
try {
|
||||
|
||||
ILaunchConfigurationTabGroup tabGroup;
|
||||
Object executable = element[index].createExecutableExtension(CLASS);
|
||||
tabGroup = (ILaunchConfigurationTabGroup)executable;
|
||||
tabGroup.createTabs(dialog, mode);
|
||||
|
||||
// It's not possible to make assumptions about the class name of the program
|
||||
// main tab (without over-stepping API boundaries), but it's usually the very
|
||||
// first tab in the group (which is an assumption that actually also over-steps
|
||||
// API boundaries, but it's the best possible solution, short of copying the
|
||||
// whole source code):
|
||||
//
|
||||
return tabGroup.getTabs()[0];
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch.ui;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.tm.internal.terminal.local.ILocalTerminalSettings;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchDelegate;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalSettingsTab} provides the UI for custom settings that are specific
|
||||
* to terminal-based launches. Currently, the tab allows the user to control the local echo settings
|
||||
* and the line separator string.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.2 $
|
||||
**/
|
||||
public class LocalTerminalSettingsTab extends AbstractLaunchConfigurationTab
|
||||
implements SelectionListener {
|
||||
|
||||
private final static String NULL = null;
|
||||
|
||||
private Button buttonEcho;
|
||||
private Button buttonCtrlC;
|
||||
private Button separatorDefault;
|
||||
private Button separatorLF;
|
||||
private Button separatorCRLF;
|
||||
private Button separatorCR;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalSettingsTab}.
|
||||
**/
|
||||
public LocalTerminalSettingsTab() {
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the top-level control for this launch configuration tab under the given parent
|
||||
* composite. This method is called once on tab creation.
|
||||
*
|
||||
* @param parent the parent {@link Composite}
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(Composite)
|
||||
**/
|
||||
public void createControl(Composite parent) {
|
||||
|
||||
Composite container = new Composite(parent, SWT.NONE);
|
||||
setControl(container);
|
||||
container.setLayout(new GridLayout());
|
||||
Group composite = new Group(container, SWT.NONE);
|
||||
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
composite.setText(LocalTerminalMessages.terminalSettings);
|
||||
composite.setLayout(new GridLayout());
|
||||
|
||||
// Create echo check box:
|
||||
//
|
||||
buttonEcho = button(composite, LocalTerminalMessages.enableLocalEcho, SWT.CHECK);
|
||||
buttonEcho.setLayoutData(new GridData());
|
||||
|
||||
// Create Ctrl-C/SIGINT check box:
|
||||
//
|
||||
buttonCtrlC = button(composite, LocalTerminalMessages.sendInterruptOnCtrlC, SWT.CHECK);
|
||||
buttonCtrlC.setLayoutData(new GridData());
|
||||
|
||||
// Create radio buttons for line separator settings:
|
||||
//
|
||||
Composite separator = new Composite(composite, SWT.NONE);
|
||||
RowLayout rowLayout = new RowLayout();
|
||||
rowLayout.wrap = false;
|
||||
separator.setLayout(rowLayout);
|
||||
separatorDefault = button(separator, LocalTerminalMessages.lineSeparatorDefault, SWT.RADIO);
|
||||
separatorLF = button(separator, LocalTerminalMessages.lineSeparatorLF, SWT.RADIO);
|
||||
separatorCRLF = button(separator, LocalTerminalMessages.lineSeparatorCRLF, SWT.RADIO);
|
||||
separatorCR = button(separator, LocalTerminalMessages.lineSeparatorCR, SWT.RADIO);
|
||||
separator.setLayoutData(new GridData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this tab.
|
||||
*
|
||||
* @return the name of this tab
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
|
||||
**/
|
||||
public String getName() {
|
||||
|
||||
return LocalTerminalMessages.terminalTabName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image for this tab, or <code>null</code> if none
|
||||
*
|
||||
* @return the image for this tab, or <code>null</code> if none
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
|
||||
**/
|
||||
public Image getImage() {
|
||||
|
||||
return DebugUITools.getImage(LocalTerminalLaunchDelegate.LAUNCH_CONFIGURATION_TYPE_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this tab's controls with values from the given launch configuration. This method
|
||||
* is called when a configuration is selected to view or edit, after the tab's control has been
|
||||
* created.
|
||||
*
|
||||
* @param configuration the launch configuration
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
|
||||
**/
|
||||
public void initializeFrom(ILaunchConfiguration configuration) {
|
||||
|
||||
boolean echo;
|
||||
try {
|
||||
|
||||
echo = configuration.getAttribute(LocalTerminalLaunchUtilities.ATTR_LOCAL_ECHO, false);
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
echo = false;
|
||||
}
|
||||
boolean ctrlC;
|
||||
try {
|
||||
|
||||
ctrlC = configuration.getAttribute(LocalTerminalLaunchUtilities.ATTR_CTRL_C, false);
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
ctrlC = false;
|
||||
}
|
||||
String ls;
|
||||
try {
|
||||
|
||||
ls = configuration.getAttribute(LocalTerminalLaunchUtilities.ATTR_LINE_SEPARATOR, NULL);
|
||||
}
|
||||
catch (CoreException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
ls = null;
|
||||
}
|
||||
buttonEcho.setSelection(echo);
|
||||
buttonCtrlC.setSelection(ctrlC);
|
||||
if (ILocalTerminalSettings.LINE_SEPARATOR_LF.equals(ls)) {
|
||||
|
||||
separatorLF.setSelection(true);
|
||||
}
|
||||
else if (ILocalTerminalSettings.LINE_SEPARATOR_LF.equals(ls)) {
|
||||
|
||||
separatorLF.setSelection(true);
|
||||
}
|
||||
else if (ILocalTerminalSettings.LINE_SEPARATOR_CRLF.equals(ls)) {
|
||||
|
||||
separatorCRLF.setSelection(true);
|
||||
}
|
||||
else if (ILocalTerminalSettings.LINE_SEPARATOR_CR.equals(ls)) {
|
||||
|
||||
separatorCR.setSelection(true);
|
||||
}
|
||||
else {
|
||||
|
||||
separatorDefault.setSelection(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies values from this tab into the given launch configuration.
|
||||
*
|
||||
* @param configuration the launch configuration
|
||||
* @see AbstractLaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
|
||||
**/
|
||||
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
|
||||
|
||||
boolean echo = buttonEcho.getSelection();
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_LOCAL_ECHO, echo);
|
||||
boolean ctrlC = buttonCtrlC.getSelection();
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_CTRL_C, ctrlC);
|
||||
String lineSeparator = null;
|
||||
if (separatorCRLF.getSelection()) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_CRLF;
|
||||
}
|
||||
else if (separatorCR.getSelection()) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_CR;
|
||||
}
|
||||
else if (separatorLF.getSelection()) {
|
||||
|
||||
lineSeparator = ILocalTerminalSettings.LINE_SEPARATOR_LF;
|
||||
}
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_LINE_SEPARATOR, lineSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given launch configuration with default values for this tab. This method is
|
||||
* called when a new launch configuration is created such that the configuration can be
|
||||
* initialized with meaningful values. This method may be called before the tab's control is
|
||||
* created.
|
||||
*
|
||||
* @param configuration the launch configuration
|
||||
* @see AbstractLaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
|
||||
**/
|
||||
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
|
||||
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_LOCAL_ECHO, false);
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_CTRL_C, false);
|
||||
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_LINE_SEPARATOR, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles selection of any of the buttons in the tab.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
* @see SelectionListener#widgetSelected(SelectionEvent)
|
||||
**/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
setDirty(true);
|
||||
getLaunchConfigurationDialog().updateButtons();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles default selection of any of the buttons in the tab.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
* @see SelectionListener#widgetDefaultSelected(SelectionEvent)
|
||||
**/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
|
||||
widgetSelected(event);
|
||||
}
|
||||
|
||||
//-------------------------------------- PRIVATE SECTION -------------------------------------//
|
||||
|
||||
private Button button(Composite parent, String label, int buttonType) {
|
||||
|
||||
Button button = new Button(parent, buttonType);
|
||||
button.addSelectionListener(this);
|
||||
button.setText(label);
|
||||
return button;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.launch.ui;
|
||||
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchesListener2;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.ScrolledComposite;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.ToolBar;
|
||||
import org.eclipse.swt.widgets.ToolItem;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
|
||||
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
|
||||
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessRegistry;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalStillRunningDialog} is a dialog that is shown when the workbench is
|
||||
* about to exit and one or more terminal launches are still running. It gives the user a choice
|
||||
* between aborting the workbench shut-down, proceeding, or terminating the outstanding launches
|
||||
* individually. When no more launches are running the dialog will automatically disappear and
|
||||
* workbench shut-down will proceed.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class LocalTerminalStillRunningDialog extends MessageDialog
|
||||
implements Runnable, SelectionListener, ILaunchesListener2 {
|
||||
|
||||
private final static String TITLE = LocalTerminalMessages.warningTitleTerminalsStillRunning;
|
||||
private final static String MESSAGE = LocalTerminalMessages.warningMessageTerminalsStillRunning;
|
||||
private final static String QUIT_ANYWAY = LocalTerminalMessages.quitWorkbenchAnyway;
|
||||
private final static String DO_NOT_QUIT = LocalTerminalMessages.doNoQuitWorkbench;
|
||||
private final static String[] BUTTONS = {QUIT_ANYWAY, DO_NOT_QUIT};
|
||||
private final static RGB WHITE = new RGB(255, 255, 255);
|
||||
private final static int SCROLLABLE_HEIGHT = 100;
|
||||
|
||||
// Image key copied from IInternalDebugUIConstants:
|
||||
//
|
||||
private final static String IMG_LCL_TERMINATE = "IMG_LCL_TERMINATE"; //$NON-NLS-1$
|
||||
|
||||
private ILaunch[] unterminated;
|
||||
private Composite content;
|
||||
|
||||
private LocalTerminalStillRunningDialog(Shell parentShell, ILaunch[] launches) {
|
||||
|
||||
super(parentShell, TITLE, null, MESSAGE, WARNING, BUTTONS, 0);
|
||||
setShellStyle(SWT.BORDER|SWT.TITLE|SWT.APPLICATION_MODAL|SWT.RESIZE|SWT.MAX);
|
||||
unterminated = launches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a dialog that lists all terminal launches that have not yet terminated.
|
||||
*
|
||||
* @param shell the parent {@link Shell} for the dialog
|
||||
* @param launches the launches that have not yet terminated
|
||||
* @return <code>true</code> to allow the workbench to proceed with shutdown, <code>false</code>
|
||||
* to prevent a shutdown (only for non-forced shutdown)
|
||||
*/
|
||||
public static boolean openDialog(Shell shell, ILaunch[] launches) {
|
||||
|
||||
LocalTerminalStillRunningDialog dialog;
|
||||
dialog = new LocalTerminalStillRunningDialog(shell, launches);
|
||||
dialog.setBlockOnOpen(true);
|
||||
try {
|
||||
|
||||
LocalTerminalUtilities.LAUNCH_MANAGER.addLaunchListener(dialog);
|
||||
return dialog.open() == 0;
|
||||
}
|
||||
finally {
|
||||
|
||||
LocalTerminalUtilities.LAUNCH_MANAGER.removeLaunchListener(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dialog buttons and sets the focus on the default button. This is done because
|
||||
* otherwise the focus might land on one of the stop buttons of the unterminated launches, which
|
||||
* looks somewhat funny.
|
||||
*
|
||||
* @param parent the parent {@link Composite}
|
||||
*/
|
||||
protected void createButtonsForButtonBar(Composite parent) {
|
||||
|
||||
super.createButtonsForButtonBar(parent);
|
||||
getButton(1).forceFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the custom area of the dialog that shows the list of terminal launches that have not
|
||||
* yet been terminated.
|
||||
*
|
||||
* @param parent the parent {@link Composite} into which the custom area is inserted
|
||||
* @return the {@link ScrolledComposite} for the custom area
|
||||
*
|
||||
* @see MessageDialog#createCustomArea(Composite)
|
||||
*/
|
||||
protected Control createCustomArea(Composite parent) {
|
||||
|
||||
ScrolledComposite scrollable = new ScrolledComposite(parent, SWT.BORDER|SWT.V_SCROLL);
|
||||
GridData gridData = new GridData(GridData.FILL_BOTH);
|
||||
gridData.heightHint = SCROLLABLE_HEIGHT;
|
||||
scrollable.setLayoutData(gridData);
|
||||
scrollable.setExpandHorizontal(true);
|
||||
scrollable.setExpandVertical(true);
|
||||
GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.marginWidth = gridLayout.marginHeight = gridLayout.verticalSpacing = 0;
|
||||
content = new Composite(scrollable, SWT.NONE);
|
||||
content.setLayout(gridLayout);
|
||||
content.setBackground(new Color(parent.getDisplay(), WHITE));
|
||||
scrollable.setContent(content);
|
||||
for (int index = 0; index < unterminated.length; index++) {
|
||||
|
||||
Composite item = createItem(content, unterminated[index]);
|
||||
item.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
}
|
||||
content.pack();
|
||||
scrollable.setMinHeight(content.getBounds().height);
|
||||
return scrollable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the {@link SelectionEvent}s that are sent when the user clicks the stop button of a
|
||||
* launch. The stop button will immediately be disabled to indicate that the stop request is
|
||||
* being processed. The actual launch termination will be confirmed in an asynchronous fashion
|
||||
* by the {@link #launchesTerminated(ILaunch[])} method.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
*
|
||||
* @see #launchesTerminated(ILaunch[])
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
|
||||
ToolItem item = (ToolItem)event.widget;
|
||||
ILaunch launch = (ILaunch)item.getParent().getParent().getData();
|
||||
item.setEnabled(false);
|
||||
try {
|
||||
|
||||
LocalTerminalProcessRegistry.addProcessBackToFinishedLaunch(launch);
|
||||
launch.terminate();
|
||||
}
|
||||
catch (DebugException exception) {
|
||||
|
||||
Logger.logException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles default selection events by passing them to {@link #widgetSelected(SelectionEvent)}.
|
||||
*
|
||||
* @param event the {@link SelectionEvent}
|
||||
*
|
||||
* @see #widgetSelected(SelectionEvent)
|
||||
* @see SelectionListener#widgetSelected(SelectionEvent)
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
|
||||
widgetSelected(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes terminated launches from the list displayed by the dialog and closes the dialog once
|
||||
* all outstanding launches have been terminated.
|
||||
*
|
||||
* @see #launchesTerminated(ILaunch[])
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
boolean allLaunchesTerminated = true;
|
||||
Control[] child = content.getChildren();
|
||||
int numberOfChildren = child.length;
|
||||
for (int number = 0; number < numberOfChildren; number++) {
|
||||
|
||||
ILaunch launch = (ILaunch)child[number].getData();
|
||||
if (launch != null && launch.isTerminated()) {
|
||||
|
||||
child[number].setData(null);
|
||||
String exitValue;
|
||||
try {
|
||||
|
||||
exitValue = String.valueOf(launch.getProcesses()[0].getExitValue());
|
||||
}
|
||||
catch (DebugException couldNotGetExitValue) {
|
||||
|
||||
exitValue = '(' + couldNotGetExitValue.getMessage() + ')';
|
||||
}
|
||||
Label label = (Label)((Composite)child[number]).getChildren()[1];
|
||||
String process = label.getText();
|
||||
process = NLS.bind(LocalTerminalMessages.terminatedProcess, process, exitValue);
|
||||
label.setText(process);
|
||||
|
||||
// In case the launch terminated by itself (and not because the user pressed the
|
||||
// stop button) disable the stop button so that no attempt can be made to stop the
|
||||
// process twice:
|
||||
//
|
||||
((Composite)child[number]).getChildren()[2].setEnabled(false);
|
||||
}
|
||||
if (child[number].getData() != null) {
|
||||
|
||||
allLaunchesTerminated = false;
|
||||
}
|
||||
}
|
||||
if (allLaunchesTerminated) {
|
||||
|
||||
setReturnCode(0);
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a recently terminated launch from the list displayed by the dialog. The actual work
|
||||
* needs to be done in the UI thread and is performed by the {@link #run()} method.
|
||||
*
|
||||
* @param terminated a list of terminated launches
|
||||
*
|
||||
* @see #run()
|
||||
*/
|
||||
public void launchesTerminated(ILaunch[] terminated) {
|
||||
|
||||
Display.getDefault().syncExec(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesAdded(ILaunch[])
|
||||
*/
|
||||
public void launchesAdded(ILaunch[] launches) {
|
||||
|
||||
// Not implemented...
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesChanged(ILaunch[])
|
||||
*/
|
||||
public void launchesChanged(ILaunch[] launches) {
|
||||
|
||||
// Not implemented...
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesRemoved(ILaunch[])
|
||||
*/
|
||||
public void launchesRemoved(ILaunch[] launches) {
|
||||
|
||||
// Not implemented...
|
||||
}
|
||||
|
||||
//-------------------------------------- PRIVATE SECTION -------------------------------------//
|
||||
|
||||
private Composite createItem(Composite parent, ILaunch launch) {
|
||||
|
||||
Composite item = new Composite(parent, SWT.NULL);
|
||||
GridLayout gridLayout = new GridLayout(3, false);
|
||||
item.setData(launch);
|
||||
item.setLayout(gridLayout);
|
||||
Image processImage = LocalTerminalLaunchUtilities.getImage(launch.getLaunchConfiguration());
|
||||
Label icon = new Label(item, SWT.NULL);
|
||||
icon.setImage(processImage);
|
||||
Label label = new Label(item, SWT.NULL);
|
||||
label.setText(launch.getLaunchConfiguration().getName());
|
||||
ToolItem stopButton = new ToolItem(new ToolBar(item, SWT.FLAT), SWT.PUSH);
|
||||
stopButton.addSelectionListener(this);
|
||||
Image deleteImage = DebugUITools.getImage(IMG_LCL_TERMINATE);
|
||||
stopButton.setImage(deleteImage);
|
||||
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gridData.verticalAlignment = GridData.CENTER;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
label.setLayoutData(gridData);
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.process;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.debug.core.model.IStreamsProxy;
|
||||
import org.eclipse.debug.core.model.RuntimeProcess;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalProcess} is a customized {@link RuntimeProcess} for use by the
|
||||
* {@link org.eclipse.tm.internal.terminal.local.LocalTerminalConnector}. It serves the purpose of
|
||||
* preventing the {@link org.eclipse.debug.internal.ui.DebugUIPlugin DebugUIPlugin}'s
|
||||
* {@link org.eclipse.debug.internal.ui.views.console.ProcessConsoleManager ProcessConsoleManager}
|
||||
* from allocating a Console view in addition to the Terminal view that serves as the program's main
|
||||
* I/O device. <p>
|
||||
* Unfortunately, the Process Console Manager determines the need for a Console view by checking the
|
||||
* {@link IStreamsProxy} of the process for <code>null</code>. If the process has a non-null
|
||||
* {@link IStreamsProxy} a console will be automatically allocated. This is problematic because
|
||||
* the Local Terminal Connector requires an {@link IStreamsProxy} but obviously not an additional
|
||||
* console view. It would have been better if the Process Console Manager would check the
|
||||
* corresponding attributes in the launch configuration rather than checking the
|
||||
* {@link IStreamsProxy} of the process. The work-around for now is to remove the underlying
|
||||
* process from the launch. No console will be allocated for a launch that doesn't have a process
|
||||
* associated with it. Consequently, a currently running terminal launch will appear in the Debug
|
||||
* view's list of active launches but the view will not show any child elements (and the element
|
||||
* cannot be expanded, either). The {@link LocalTerminalProcessRegistry} keeps track of which
|
||||
* {@link LocalTerminalProcess} is associated with a particular launch. Client code that needs to
|
||||
* find the process of a launch can obtain it through that registry. <p>
|
||||
* However, for a launch to be properly terminated it needs to have at least one process that can
|
||||
* be terminated. Launches that do not have any processes associated with them are not considered
|
||||
* terminated and actually terminating them is not possible. To work around this secondary issue,
|
||||
* the process is added back to its launch just before the launch is terminated. This activity is
|
||||
* performed by {@link LocalTerminalProcessRegistry#addProcessBackToFinishedLaunch(ILaunch)}. To
|
||||
* prevent a console allocation during this last step, the {@link #resetStreamsProxy()} method will
|
||||
* be invoked, which will cause subsequent calls to {@link IProcess#getStreamsProxy()} to return
|
||||
* <code>null</code>. After the launch is terminated it will appear in the Debug view with the
|
||||
* terminated process as its child element. The exit value of the terminal process can also be seen
|
||||
* in that view. <p>
|
||||
*
|
||||
* This solution for preventing standard consoles from being opened does certainly not deserve the
|
||||
* cleanliness award for straightforward coding, but at least it doesn't rely on internal API at
|
||||
* this point. Ideally, the whole issue should be resolved with some sort of console renderer
|
||||
* extension point as proposed in bug 242373 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=242373).
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.3 $
|
||||
*/
|
||||
public final class LocalTerminalProcess extends RuntimeProcess {
|
||||
|
||||
/**
|
||||
* The process type ID of processes produced by this factory.
|
||||
*/
|
||||
public final static String PROCESS_TYPE = "org.eclipse.tm.terminal.localProcess"; //$NON-NLS-1$
|
||||
|
||||
private boolean resetStreamsProxy;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalTerminalProcess}.
|
||||
*
|
||||
* @param launch the current {@link ILaunch}
|
||||
* @param process the underlying low-level {@link Process}
|
||||
* @param name the process name
|
||||
* @param attributes additional attributes of the process
|
||||
*/
|
||||
protected LocalTerminalProcess(ILaunch launch, Process process, String name, Map attributes) {
|
||||
|
||||
super(launch, process, name, setProcessType(attributes));
|
||||
LocalTerminalProcessRegistry.registerWithLaunch(launch, this);
|
||||
launch.removeProcess(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a <code>SIGINT</code> signal to the underlying system {@link Process}. This is roughly
|
||||
* equivalent to the user pressing Ctrl-C.
|
||||
*
|
||||
* @return <code>true</code> if the interrupt signal was sent successfully; <code>false</code>
|
||||
* if the signal was not sent successfully or if no signal was sent because the underlying
|
||||
* process is not a CDT {@link Spawner}
|
||||
*/
|
||||
public boolean interrupt() {
|
||||
|
||||
Process process = getSystemProcess();
|
||||
if (process instanceof Spawner) {
|
||||
|
||||
return ((Spawner)process).interrupt() == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link IStreamsProxy} of the process.
|
||||
*
|
||||
* @return the original result of {@link RuntimeProcess#getStreamsProxy()}, or <code>null</code>
|
||||
* after {@link #resetStreamsProxy()} has been called.
|
||||
*/
|
||||
public IStreamsProxy getStreamsProxy() {
|
||||
|
||||
if (resetStreamsProxy) {
|
||||
|
||||
return null;
|
||||
}
|
||||
return super.getStreamsProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the {@link IStreamsProxy} of this process. After calling this method,
|
||||
* {@link #getStreamsProxy()} will always return <code>null</code>.
|
||||
*/
|
||||
protected void resetStreamsProxy() {
|
||||
|
||||
resetStreamsProxy = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-attaches the process to its launch and completes termination of the process. This ensures
|
||||
* that the launch can properly terminate.
|
||||
*
|
||||
* @see RuntimeProcess#terminated()
|
||||
*/
|
||||
protected void terminated() {
|
||||
|
||||
LocalTerminalProcessRegistry.addProcessBackToFinishedLaunch(getLaunch());
|
||||
super.terminated();
|
||||
}
|
||||
|
||||
//------------------------------------- PRIVATE SECTION --------------------------------------//
|
||||
|
||||
private static Map setProcessType(Map attributes) {
|
||||
|
||||
// The process type used to be set by the LocalTerminalProcessFactory. However, if some
|
||||
// client code managed to instantiate a LocalTerminalProcess directly (instead of going
|
||||
// through the factory) this would result in IProcess objects with an incorrect process type
|
||||
// attribute. A better solution is to set the process type attribute at the time when the
|
||||
// LocalTerminalProcess object is actually created:
|
||||
//
|
||||
if (attributes == null) {
|
||||
|
||||
attributes = new HashMap(1);
|
||||
}
|
||||
attributes.put(IProcess.ATTR_PROCESS_TYPE, PROCESS_TYPE);
|
||||
return attributes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.process;
|
||||
|
||||
import java.util.Map;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.IProcessFactory;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
|
||||
/**
|
||||
* The class {@link LocalTerminalProcessFactory} is an {@link IProcessFactory} that produces
|
||||
* {@link LocalTerminalProcess} objects.
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class LocalTerminalProcessFactory implements IProcessFactory {
|
||||
|
||||
/**
|
||||
* The ID of this factory (as used in <code>plugin.xml</code>).
|
||||
*/
|
||||
public final static String ID = "org.eclipse.tm.terminal.localProcess.factory"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* @see IProcessFactory#newProcess(ILaunch, Process, String, Map)
|
||||
*/
|
||||
public IProcess newProcess(ILaunch launch, Process process, String label, Map attributes) {
|
||||
|
||||
return new LocalTerminalProcess(launch, process, label, attributes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.process;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchesListener2;
|
||||
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
|
||||
|
||||
/**
|
||||
* The {@link LocalTerminalProcessRegistry} keeps a map between {@link ILaunch} objects and the
|
||||
* {@link LocalTerminalProcess} objects that were associated with them. To prevent standard consoles
|
||||
* from being opened, a {@link LocalTerminalProcess} is immediately removed from its {@link ILaunch}
|
||||
* when the process is created (see {@link LocalTerminalProcess} for details).
|
||||
* {@link LocalTerminalProcessRegistry} is a singleton (without lazy initialization).
|
||||
*
|
||||
* @author mirko
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class LocalTerminalProcessRegistry implements ILaunchesListener2 {
|
||||
|
||||
private final static LocalTerminalProcessRegistry INSTANCE = new LocalTerminalProcessRegistry();
|
||||
|
||||
private Map processes;
|
||||
|
||||
private LocalTerminalProcessRegistry() {
|
||||
|
||||
// The ILaunch interface does not make any statements about the suitability of implementing
|
||||
// objects as hash keys. There might be ILaunch implementations that return a different
|
||||
// hash code value if the object changes internally. To be safe in those cases, an
|
||||
// IdentityHashMap is used:
|
||||
//
|
||||
processes = new IdentityHashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link LocalTerminalProcess} that was originally associated with a given
|
||||
* {@link ILaunch} object.
|
||||
*
|
||||
* @param launch the {@link ILaunch} that was used for creating the process
|
||||
* @return the corresponding {@link LocalTerminalProcess}, or <code>null</code> if no process
|
||||
* could be found
|
||||
*/
|
||||
public static LocalTerminalProcess getFromLaunch(ILaunch launch) {
|
||||
|
||||
return (LocalTerminalProcess)INSTANCE.processes.get(launch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link LocalTerminalProcess} object back to its original {@link ILaunch}. This method
|
||||
* will also perform a {@link LocalTerminalProcess#resetStreamsProxy()} on the process.
|
||||
* The {@link #addProcessBackToFinishedLaunch(ILaunch)} method is necessary for properly
|
||||
* terminating the launch of a terminal application (see {@link LocalTerminalProcess} for
|
||||
* details).
|
||||
*
|
||||
* @param launch the {@link ILaunch} whose original process is to be re-attached
|
||||
*/
|
||||
public static void addProcessBackToFinishedLaunch(ILaunch launch) {
|
||||
|
||||
LocalTerminalProcess process = getFromLaunch(launch);
|
||||
if (process == null) {
|
||||
|
||||
// Maybe the process wasn't actually started in a terminal (can happen when a Terminal
|
||||
// is launched from the External Tools menu):
|
||||
//
|
||||
return;
|
||||
}
|
||||
process.resetStreamsProxy();
|
||||
if (launch.getProcesses().length == 0) {
|
||||
|
||||
launch.addProcess(process);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link LocalTerminalProcess} with a given {@link ILaunch} so that the process can
|
||||
* be safely removed from the launch.
|
||||
*
|
||||
* @param launch the {@link ILaunch}
|
||||
* @param process the {@link LocalTerminalProcess} originally associated with that launch
|
||||
*/
|
||||
public static void registerWithLaunch(ILaunch launch, LocalTerminalProcess process) {
|
||||
|
||||
synchronized (INSTANCE) {
|
||||
|
||||
if (INSTANCE.processes.isEmpty()) {
|
||||
|
||||
// Start listening to terminated launches as soon as the first launch/process pair
|
||||
// is registered:
|
||||
//
|
||||
LocalTerminalUtilities.LAUNCH_MANAGER.addLaunchListener(INSTANCE);
|
||||
}
|
||||
INSTANCE.processes.put(launch, process);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the termination of launches. The {@link LocalTerminalProcessRegistry} acts as a
|
||||
* {@link ILaunchesListener2} if there are monitored launches outstanding. It will automatically
|
||||
* de-register itself (as a listener) when the last monitored launch was terminated.
|
||||
*
|
||||
* @param terminated the launches that were terminated
|
||||
*/
|
||||
public void launchesTerminated(ILaunch[] terminated) {
|
||||
|
||||
synchronized (INSTANCE) {
|
||||
|
||||
int numberOfTerminatedLaunches = terminated.length;
|
||||
for (int launch = 0; launch < numberOfTerminatedLaunches; launch++) {
|
||||
|
||||
INSTANCE.processes.remove(terminated[launch]);
|
||||
}
|
||||
if (INSTANCE.processes.isEmpty()) {
|
||||
|
||||
// If there are no more outstanding launches the listener can be removed again:
|
||||
//
|
||||
LocalTerminalUtilities.LAUNCH_MANAGER.removeLaunchListener(INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesAdded(ILaunch[])
|
||||
*/
|
||||
public void launchesAdded(ILaunch[] launches) {
|
||||
|
||||
// Not implemented.
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesRemoved(ILaunch[])
|
||||
*/
|
||||
public void launchesRemoved(ILaunch[] launches) {
|
||||
|
||||
// Not implemented.
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Not implemented</i>.
|
||||
* @see ILaunchesListener2#launchesChanged(ILaunch[])
|
||||
*/
|
||||
public void launchesChanged(ILaunch[] launches) {
|
||||
|
||||
// Not implemented.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************************************
|
||||
* Copyright (c) 2008 Mirko Raner.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Mirko Raner - initial implementation for Eclipse Bug 196337
|
||||
**************************************************************************************************/
|
||||
|
||||
package org.eclipse.tm.internal.terminal.local.ui;
|
||||
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
import org.eclipse.swt.events.ControlListener;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
/**
|
||||
* The class {@link DependentHeightComposite} is a special kind of SWT {@link Composite} whose
|
||||
* height depends on the height of some master {@link Composite} that does not have to be a direct
|
||||
* parent or child of it. This class was introduced as a work-around for UI resizing problems with
|
||||
* the Terminal API's PageBook class (which uses a StackLayout).
|
||||
*
|
||||
* @author Mirko Raner
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class DependentHeightComposite extends Composite implements ControlListener {
|
||||
|
||||
private Composite master;
|
||||
private int preferredHeight = -1;
|
||||
private int extraHeight;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DependentHeightComposite}.
|
||||
*
|
||||
* @param parent the parent {@link Composite}
|
||||
* @param style the SWT style
|
||||
* @param master the master {@link Composite} that determines the height
|
||||
* @param extra the additional height in pixels (may be negative, to create a smaller height
|
||||
* than the master {@link Composite})
|
||||
*/
|
||||
public DependentHeightComposite(Composite parent, int style, Composite master, int extra) {
|
||||
|
||||
super(parent, style);
|
||||
this.master = master;
|
||||
this.extraHeight = extra;
|
||||
master.addControlListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does nothing.
|
||||
*
|
||||
* @see ControlListener#controlMoved(ControlEvent)
|
||||
*/
|
||||
public void controlMoved(ControlEvent event) {
|
||||
|
||||
// Does nothing...
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the {@link DependentHeightComposite} height if the master {@link Composite}'s size
|
||||
* changed.
|
||||
*
|
||||
* @param event the {@link ControlEvent}
|
||||
*/
|
||||
public void controlResized(ControlEvent event) {
|
||||
|
||||
setSize(getSize().x, master.getClientArea().height+extraHeight);
|
||||
preferredHeight = master.getClientArea().height+extraHeight;
|
||||
master.layout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the preferred size of this {@link DependentHeightComposite}.
|
||||
*
|
||||
* @see Composite#computeSize(int, int, boolean)
|
||||
*/
|
||||
public Point computeSize(int widthHint, int heightHint, boolean changed) {
|
||||
|
||||
Point size = super.computeSize(widthHint, heightHint, changed);
|
||||
if (preferredHeight != -1) {
|
||||
|
||||
size.y = preferredHeight;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue